mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
Match more patterns to movt.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84751 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5affca0763
commit
2095659a85
@ -1427,6 +1427,43 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ISD::AND: {
|
||||
// (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits
|
||||
// of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits
|
||||
// are entirely contributed by c2 and lower 16-bits are entirely contributed
|
||||
// by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)).
|
||||
// Select it to: "movt x, ((c1 & 0xffff) >> 16)
|
||||
EVT VT = Op.getValueType();
|
||||
if (VT != MVT::i32)
|
||||
break;
|
||||
unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2())
|
||||
? ARM::t2MOVTi16
|
||||
: (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0);
|
||||
if (!Opc)
|
||||
break;
|
||||
SDValue N0 = Op.getOperand(0), N1 = Op.getOperand(1);
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||
if (!N1C)
|
||||
break;
|
||||
if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) {
|
||||
SDValue N2 = N0.getOperand(1);
|
||||
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
|
||||
if (!N2C)
|
||||
break;
|
||||
unsigned N1CVal = N1C->getZExtValue();
|
||||
unsigned N2CVal = N2C->getZExtValue();
|
||||
if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) &&
|
||||
(N1CVal & 0xffffU) == 0xffffU &&
|
||||
(N2CVal & 0xffffU) == 0x0U) {
|
||||
SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16,
|
||||
MVT::i32);
|
||||
SDValue Ops[] = { N0.getOperand(0), Imm16,
|
||||
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
|
||||
return CurDAG->getMachineNode(Opc, dl, VT, Ops, 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARMISD::FMRRD:
|
||||
return CurDAG->getMachineNode(ARM::FMRRD, dl, MVT::i32, MVT::i32,
|
||||
Op.getOperand(0), getAL(CurDAG),
|
||||
|
@ -3022,7 +3022,6 @@ static SDValue PerformSUBCombine(SDNode *N,
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
||||
/// PerformFMRRDCombine - Target-specific dag combine xforms for ARMISD::FMRRD.
|
||||
static SDValue PerformFMRRDCombine(SDNode *N,
|
||||
TargetLowering::DAGCombinerInfo &DCI) {
|
||||
|
@ -980,6 +980,9 @@ def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
|
||||
let Inst{25} = 1;
|
||||
}
|
||||
|
||||
def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
|
||||
Requires<[IsARM, HasV6T2]>;
|
||||
|
||||
let Uses = [CPSR] in
|
||||
def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
|
||||
"mov", " $dst, $src, rrx",
|
||||
|
@ -666,6 +666,8 @@ def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
|
||||
[(set GPR:$dst,
|
||||
(or (and GPR:$src, 0xffff), lo16AllZero:$imm))]>;
|
||||
|
||||
def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Extend Instructions.
|
||||
//
|
||||
|
19
test/CodeGen/ARM/movt.ll
Normal file
19
test/CodeGen/ARM/movt.ll
Normal file
@ -0,0 +1,19 @@
|
||||
; RUN: llc < %s -march=arm -mattr=+thumb2 | FileCheck %s
|
||||
; rdar://7317664
|
||||
|
||||
define i32 @t(i32 %X) nounwind {
|
||||
; CHECK: t:
|
||||
; CHECK: movt r0, #65535
|
||||
entry:
|
||||
%0 = or i32 %X, -65536
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @t2(i32 %X) nounwind {
|
||||
; CHECK: t2:
|
||||
; CHECK: movt r0, #65534
|
||||
entry:
|
||||
%0 = or i32 %X, -131072
|
||||
%1 = and i32 %0, -65537
|
||||
ret i32 %1
|
||||
}
|
@ -2,10 +2,7 @@
|
||||
|
||||
define i32 @t2MOVTi16_ok_1(i32 %a) {
|
||||
; CHECK: t2MOVTi16_ok_1:
|
||||
; CHECK: movs r1, #0
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movw r1, #65535
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movt r0, #1234
|
||||
%1 = and i32 %a, 65535
|
||||
%2 = shl i32 1234, 16
|
||||
%3 = or i32 %1, %2
|
||||
@ -15,10 +12,7 @@ define i32 @t2MOVTi16_ok_1(i32 %a) {
|
||||
|
||||
define i32 @t2MOVTi16_test_1(i32 %a) {
|
||||
; CHECK: t2MOVTi16_test_1:
|
||||
; CHECK: movs r1, #0
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movw r1, #65535
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movt r0, #1234
|
||||
%1 = shl i32 255, 8
|
||||
%2 = shl i32 1234, 8
|
||||
%3 = or i32 %1, 255 ; This give us 0xFFFF in %3
|
||||
@ -31,10 +25,7 @@ define i32 @t2MOVTi16_test_1(i32 %a) {
|
||||
|
||||
define i32 @t2MOVTi16_test_2(i32 %a) {
|
||||
; CHECK: t2MOVTi16_test_2:
|
||||
; CHECK: movs r1, #0
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movw r1, #65535
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movt r0, #1234
|
||||
%1 = shl i32 255, 8
|
||||
%2 = shl i32 1234, 8
|
||||
%3 = or i32 %1, 255 ; This give us 0xFFFF in %3
|
||||
@ -48,10 +39,7 @@ define i32 @t2MOVTi16_test_2(i32 %a) {
|
||||
|
||||
define i32 @t2MOVTi16_test_3(i32 %a) {
|
||||
; CHECK: t2MOVTi16_test_3:
|
||||
; CHECK: movs r1, #0
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movw r1, #65535
|
||||
; CHECK-NEXT: movt r1, #1234
|
||||
; CHECK: movt r0, #1234
|
||||
%1 = shl i32 255, 8
|
||||
%2 = shl i32 1234, 8
|
||||
%3 = or i32 %1, 255 ; This give us 0xFFFF in %3
|
||||
|
Loading…
x
Reference in New Issue
Block a user