add codegen support for <<= and >>=.

llvm-svn: 39713
This commit is contained in:
Chris Lattner 2007-06-29 17:26:27 +00:00
parent b25a94383a
commit 47c247e7bf
3 changed files with 45 additions and 22 deletions

View File

@ -724,6 +724,14 @@ EmitCompoundAssignmentOperands(const CompoundAssignOperator *E,
QualType RHSTy;
RHS = EmitExprWithUsualUnaryConversions(E->getRHS(), RHSTy);
// Shift operands do the usual unary conversions, but do not do the binary
// conversions.
if (E->isShiftAssignOp()) {
// FIXME: This is broken. Implicit conversions should be made explicit,
// so that this goes away. This causes us to reload the LHS.
LHS = EmitExprWithUsualUnaryConversions(E->getLHS(), LHSTy);
}
// Convert the LHS and RHS to the common evaluation type.
LHS = EmitConversion(LHS, LHSTy, E->getComputationType());
RHS = EmitConversion(RHS, RHSTy, E->getComputationType());
@ -772,8 +780,12 @@ RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) {
// FIXME: This doesn't handle ptr-int etc yet.
EmitUsualArithmeticConversions(E, LHS, RHS);
return EmitSub(LHS, RHS, E->getType());
case BinaryOperator::Shl: return EmitBinaryShl(E);
case BinaryOperator::Shr: return EmitBinaryShr(E);
case BinaryOperator::Shl:
EmitShiftOperands(E, LHS, RHS);
return EmitShl(LHS, RHS, E->getType());
case BinaryOperator::Shr:
EmitShiftOperands(E, LHS, RHS);
return EmitShr(LHS, RHS, E->getType());
case BinaryOperator::And:
EmitUsualArithmeticConversions(E, LHS, RHS);
return EmitAnd(LHS, RHS, E->getType());
@ -847,6 +859,20 @@ RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) {
LHS = EmitSub(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::ShlAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
LHS = EmitShl(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::ShrAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
LHS = EmitShr(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::AndAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
@ -932,17 +958,19 @@ RValue CodeGenFunction::EmitSub(RValue LHS, RValue RHS, QualType ResTy) {
assert(0 && "FIXME: This doesn't handle complex operands yet");
}
RValue CodeGenFunction::EmitBinaryShl(const BinaryOperator *E) {
void CodeGenFunction::EmitShiftOperands(const BinaryOperator *E,
RValue &LHS, RValue &RHS) {
// For shifts, integer promotions are performed, but the usual arithmetic
// conversions are not. The LHS and RHS need not have the same type.
QualType ResTy;
llvm::Value *LHS =
EmitExprWithUsualUnaryConversions(E->getLHS(), ResTy).getVal();
llvm::Value *RHS =
EmitExprWithUsualUnaryConversions(E->getRHS(), ResTy).getVal();
LHS = EmitExprWithUsualUnaryConversions(E->getLHS(), ResTy);
RHS = EmitExprWithUsualUnaryConversions(E->getRHS(), ResTy);
}
RValue CodeGenFunction::EmitShl(RValue LHSV, RValue RHSV, QualType ResTy) {
llvm::Value *LHS = LHSV.getVal(), *RHS = RHSV.getVal();
// LLVM requires the LHS and RHS to be the same type, promote or truncate the
// RHS to the same size as the LHS.
if (LHS->getType() != RHS->getType())
@ -951,22 +979,15 @@ RValue CodeGenFunction::EmitBinaryShl(const BinaryOperator *E) {
return RValue::get(Builder.CreateShl(LHS, RHS, "shl"));
}
RValue CodeGenFunction::EmitBinaryShr(const BinaryOperator *E) {
// For shifts, integer promotions are performed, but the usual arithmetic
// conversions are not. The LHS and RHS need not have the same type.
QualType ResTy;
llvm::Value *LHS =
EmitExprWithUsualUnaryConversions(E->getLHS(), ResTy).getVal();
llvm::Value *RHS =
EmitExprWithUsualUnaryConversions(E->getRHS(), ResTy).getVal();
RValue CodeGenFunction::EmitShr(RValue LHSV, RValue RHSV, QualType ResTy) {
llvm::Value *LHS = LHSV.getVal(), *RHS = RHSV.getVal();
// LLVM requires the LHS and RHS to be the same type, promote or truncate the
// RHS to the same size as the LHS.
if (LHS->getType() != RHS->getType())
RHS = Builder.CreateIntCast(RHS, LHS->getType(), false, "sh_prom");
if (E->getType()->isUnsignedIntegerType())
if (ResTy->isUnsignedIntegerType())
return RValue::get(Builder.CreateLShr(LHS, RHS, "shr"));
else
return RValue::get(Builder.CreateAShr(LHS, RHS, "shr"));

View File

@ -270,7 +270,8 @@ public:
RValue EmitExprWithUsualUnaryConversions(const Expr *E, QualType &ResTy);
QualType EmitUsualArithmeticConversions(const BinaryOperator *E,
RValue &LHS, RValue &RHS);
void EmitShiftOperands(const BinaryOperator *E, RValue &LHS, RValue &RHS);
void EmitCompoundAssignmentOperands(const CompoundAssignOperator *CAO,
LValue &LHSLV, RValue &LHS, RValue &RHS);
RValue EmitCompoundAssignmentResult(const CompoundAssignOperator *E,
@ -304,8 +305,8 @@ public:
RValue EmitRem(RValue LHS, RValue RHS, QualType EltTy);
RValue EmitAdd(RValue LHS, RValue RHS, QualType EltTy);
RValue EmitSub(RValue LHS, RValue RHS, QualType EltTy);
RValue EmitBinaryShl(const BinaryOperator *E);
RValue EmitBinaryShr(const BinaryOperator *E);
RValue EmitShl(RValue LHS, RValue RHS, QualType ResTy);
RValue EmitShr(RValue LHS, RValue RHS, QualType ResTy);
RValue EmitBinaryCompare(const BinaryOperator *E, unsigned UICmpOpc,
unsigned SICmpOpc, unsigned FCmpOpc);
RValue EmitAnd(RValue LHS, RValue RHS, QualType EltTy);

View File

@ -504,6 +504,7 @@ public:
bool isLogicalOp() const { return Opc == LAnd || Opc == LOr; }
bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {