mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-12 18:33:22 +00:00
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
This commit is contained in:
parent
81550dc0a8
commit
e07cd5e40a
@ -174,7 +174,8 @@ class ARMFastISel : public FastISel {
|
|||||||
private:
|
private:
|
||||||
bool isTypeLegal(Type *Ty, MVT &VT);
|
bool isTypeLegal(Type *Ty, MVT &VT);
|
||||||
bool isLoadTypeLegal(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 ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr);
|
||||||
bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr);
|
bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr);
|
||||||
bool ARMComputeAddress(const Value *Obj, 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;
|
if (ARMPred == ARMCC::AL) return false;
|
||||||
|
|
||||||
// Emit the compare.
|
// Emit the compare.
|
||||||
if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1)))
|
if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
|
unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
|
||||||
@ -1189,19 +1190,19 @@ bool ARMFastISel::SelectBranch(const Instruction *I) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value) {
|
bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
|
||||||
MVT VT;
|
bool isZExt) {
|
||||||
Type *Ty = Src1Value->getType();
|
Type *Ty = Src1Value->getType();
|
||||||
if (!isTypeLegal(Ty, VT))
|
EVT SrcVT = TLI.getValueType(Ty, true);
|
||||||
return false;
|
if (!SrcVT.isSimple()) return false;
|
||||||
|
|
||||||
bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy());
|
bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy());
|
||||||
if (isFloat && !Subtarget->hasVFP2())
|
if (isFloat && !Subtarget->hasVFP2())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned CmpOpc;
|
unsigned CmpOpc;
|
||||||
switch (VT.SimpleTy) {
|
bool needsExt = false;
|
||||||
// TODO: Add support for non-legal types (i.e., i1, i8, i16).
|
switch (SrcVT.getSimpleVT().SimpleTy) {
|
||||||
default: return false;
|
default: return false;
|
||||||
// TODO: Verify compares.
|
// TODO: Verify compares.
|
||||||
case MVT::f32:
|
case MVT::f32:
|
||||||
@ -1210,19 +1211,36 @@ bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value) {
|
|||||||
case MVT::f64:
|
case MVT::f64:
|
||||||
CmpOpc = ARM::VCMPED;
|
CmpOpc = ARM::VCMPED;
|
||||||
break;
|
break;
|
||||||
|
case MVT::i1:
|
||||||
|
case MVT::i8:
|
||||||
|
case MVT::i16:
|
||||||
|
needsExt = true;
|
||||||
|
// Intentional fall-through.
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
|
CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Src1 = getRegForValue(Src1Value);
|
unsigned SrcReg1 = getRegForValue(Src1Value);
|
||||||
if (Src1 == 0) return false;
|
if (SrcReg1 == 0) return false;
|
||||||
|
|
||||||
unsigned Src2 = getRegForValue(Src2Value);
|
unsigned SrcReg2 = getRegForValue(Src2Value);
|
||||||
if (Src2 == 0) return false;
|
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))
|
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
|
// For floating point we need to move the result to a comparison register
|
||||||
// that we can then use for branches.
|
// that we can then use for branches.
|
||||||
@ -1243,7 +1261,7 @@ bool ARMFastISel::SelectCmp(const Instruction *I) {
|
|||||||
if (ARMPred == ARMCC::AL) return false;
|
if (ARMPred == ARMCC::AL) return false;
|
||||||
|
|
||||||
// Emit the compare.
|
// Emit the compare.
|
||||||
if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1)))
|
if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Now set a register based on the comparison. Explicitly set the predicates
|
// 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);
|
static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMFastISel::SelectTrunc(const Instruction *I) {
|
bool ARMFastISel::SelectTrunc(const Instruction *I) {
|
||||||
|
47
test/CodeGen/ARM/fast-isel-icmp.ll
Normal file
47
test/CodeGen/ARM/fast-isel-icmp.ll
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-darwin | FileCheck %s --check-prefix=ARM
|
||||||
|
; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefix=THUMB
|
||||||
|
|
||||||
|
define i32 @icmp_i16_unsigned(i16 %a, i16 %b) nounwind {
|
||||||
|
entry:
|
||||||
|
; ARM: icmp_i16_unsigned
|
||||||
|
; ARM: uxth r0, r0
|
||||||
|
; ARM: uxth r1, r1
|
||||||
|
; ARM: cmp r0, r1
|
||||||
|
; THUMB: icmp_i16_unsigned
|
||||||
|
; THUMB: uxth r0, r0
|
||||||
|
; THUMB: uxth r1, r1
|
||||||
|
; THUMB: cmp r0, r1
|
||||||
|
%cmp = icmp ult i16 %a, %b
|
||||||
|
%conv2 = zext i1 %cmp to i32
|
||||||
|
ret i32 %conv2
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @icmp_i8_signed(i8 %a, i8 %b) nounwind {
|
||||||
|
entry:
|
||||||
|
; ARM: icmp_i8_signed
|
||||||
|
; ARM: sxtb r0, r0
|
||||||
|
; ARM: sxtb r1, r1
|
||||||
|
; ARM: cmp r0, r1
|
||||||
|
; THUMB: icmp_i8_signed
|
||||||
|
; THUMB: sxtb r0, r0
|
||||||
|
; THUMB: sxtb r1, r1
|
||||||
|
; THUMB: cmp r0, r1
|
||||||
|
%cmp = icmp sgt i8 %a, %b
|
||||||
|
%conv2 = zext i1 %cmp to i32
|
||||||
|
ret i32 %conv2
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @icmp_i1_unsigned(i1 %a, i1 %b) nounwind {
|
||||||
|
entry:
|
||||||
|
; ARM: icmp_i1_unsigned
|
||||||
|
; ARM: and r0, r0, #1
|
||||||
|
; ARM: and r1, r1, #1
|
||||||
|
; ARM: cmp r0, r1
|
||||||
|
; THUMB: icmp_i1_unsigned
|
||||||
|
; THUMB: and r0, r0, #1
|
||||||
|
; THUMB: and r1, r1, #1
|
||||||
|
; THUMB: cmp r0, r1
|
||||||
|
%cmp = icmp ult i1 %a, %b
|
||||||
|
%conv2 = zext i1 %cmp to i32
|
||||||
|
ret i32 %conv2
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user