summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2011-11-02 18:08:25 +0000
committerChad Rosier <mcrosier@apple.com>2011-11-02 18:08:25 +0000
commite07cd5e40ac06fabfb9d33ea7c79542f138f45ce (patch)
tree0c5a59347cb4e87079b41bbd6ed1830161fb738c /lib
parent81550dc0a866e27a1efbc5de616fb366ebb547cd (diff)
downloadllvm-e07cd5e40ac06fabfb9d33ea7c79542f138f45ce.tar.gz
llvm-e07cd5e40ac06fabfb9d33ea7c79542f138f45ce.tar.bz2
llvm-e07cd5e40ac06fabfb9d33ea7c79542f138f45ce.tar.xz
Add support for comparing integer non-legal types.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143559 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp49
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp
index 97d813da21..78bda6c0d3 100644
--- a/lib/Target/ARM/ARMFastISel.cpp
+++ b/lib/Target/ARM/ARMFastISel.cpp
@@ -174,7 +174,8 @@ class ARMFastISel : public FastISel {
private:
bool isTypeLegal(Type *Ty, MVT &VT);
bool isLoadTypeLegal(Type *Ty, MVT &VT);
- bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value);
+ bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
+ bool isZExt);
bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr);
bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr);
bool ARMComputeAddress(const Value *Obj, Address &Addr);
@@ -1119,7 +1120,7 @@ bool ARMFastISel::SelectBranch(const Instruction *I) {
if (ARMPred == ARMCC::AL) return false;
// Emit the compare.
- if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1)))
+ if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
return false;
unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
@@ -1189,19 +1190,19 @@ bool ARMFastISel::SelectBranch(const Instruction *I) {
return true;
}
-bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value) {
- MVT VT;
+bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
+ bool isZExt) {
Type *Ty = Src1Value->getType();
- if (!isTypeLegal(Ty, VT))
- return false;
+ EVT SrcVT = TLI.getValueType(Ty, true);
+ if (!SrcVT.isSimple()) return false;
bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy());
if (isFloat && !Subtarget->hasVFP2())
return false;
unsigned CmpOpc;
- switch (VT.SimpleTy) {
- // TODO: Add support for non-legal types (i.e., i1, i8, i16).
+ bool needsExt = false;
+ switch (SrcVT.getSimpleVT().SimpleTy) {
default: return false;
// TODO: Verify compares.
case MVT::f32:
@@ -1210,19 +1211,36 @@ bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value) {
case MVT::f64:
CmpOpc = ARM::VCMPED;
break;
+ case MVT::i1:
+ case MVT::i8:
+ case MVT::i16:
+ needsExt = true;
+ // Intentional fall-through.
case MVT::i32:
CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
break;
}
- unsigned Src1 = getRegForValue(Src1Value);
- if (Src1 == 0) return false;
-
- unsigned Src2 = getRegForValue(Src2Value);
- if (Src2 == 0) return false;
+ unsigned SrcReg1 = getRegForValue(Src1Value);
+ if (SrcReg1 == 0) return false;
+
+ unsigned SrcReg2 = getRegForValue(Src2Value);
+ if (SrcReg2 == 0) return false;
+
+ // We have i1, i8, or i16, we need to either zero extend or sign extend.
+ if (needsExt) {
+ unsigned ResultReg;
+ EVT DestVT = MVT::i32;
+ ResultReg = ARMEmitIntExt(SrcVT, SrcReg1, DestVT, isZExt);
+ if (ResultReg == 0) return false;
+ SrcReg1 = ResultReg;
+ ResultReg = ARMEmitIntExt(SrcVT, SrcReg2, DestVT, isZExt);
+ if (ResultReg == 0) return false;
+ SrcReg2 = ResultReg;
+ }
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
- .addReg(Src1).addReg(Src2));
+ .addReg(SrcReg1).addReg(SrcReg2));
// For floating point we need to move the result to a comparison register
// that we can then use for branches.
@@ -1243,7 +1261,7 @@ bool ARMFastISel::SelectCmp(const Instruction *I) {
if (ARMPred == ARMCC::AL) return false;
// Emit the compare.
- if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1)))
+ if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
return false;
// Now set a register based on the comparison. Explicitly set the predicates
@@ -1962,7 +1980,6 @@ bool ARMFastISel::SelectCall(const Instruction *I) {
static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
return true;
-
}
bool ARMFastISel::SelectTrunc(const Instruction *I) {