diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-03-20 08:11:30 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-03-20 08:11:30 +0000 |
commit | c70d1849b7b85b06adf7dce856b3b19028fff8f7 (patch) | |
tree | 98bd8a21a234e7713b9dc01b081ee5ee30334b6e /lib/Target/ARM | |
parent | 5603dcf21e3227e457624e9ff895f4893ca81528 (diff) | |
download | external_llvm-c70d1849b7b85b06adf7dce856b3b19028fff8f7.zip external_llvm-c70d1849b7b85b06adf7dce856b3b19028fff8f7.tar.gz external_llvm-c70d1849b7b85b06adf7dce856b3b19028fff8f7.tar.bz2 |
Make two piece constant generation as a single instruction. It's re-materialized as a load from constantpool.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35207 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 37 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 48 |
2 files changed, 55 insertions, 30 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 2073e80..1f052bf 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -82,6 +82,7 @@ namespace { void printOperand(const MachineInstr *MI, int opNum, const char *Modifier = 0); void printSOImmOperand(const MachineInstr *MI, int opNum); + void printSOImm2PartOperand(const MachineInstr *MI, int opNum); void printSORegOperand(const MachineInstr *MI, int opNum); void printAddrMode2Operand(const MachineInstr *MI, int OpNo); void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo); @@ -309,14 +310,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum, } } -/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit -/// immediate in bits 0-7. -void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) { - const MachineOperand &MO = MI->getOperand(OpNum); - assert(MO.isImmediate() && (MO.getImmedValue() < (1 << 12)) && - "Not a valid so_imm value!"); - unsigned Imm = ARM_AM::getSOImmValImm(MO.getImmedValue()); - unsigned Rot = ARM_AM::getSOImmValRot(MO.getImmedValue()); +static void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) { + assert(V < (1 << 12) && "Not a valid so_imm value!"); + unsigned Imm = ARM_AM::getSOImmValImm(V); + unsigned Rot = ARM_AM::getSOImmValRot(V); // Print low-level immediate formation info, per // A5.1.3: "Data-processing operands - Immediate". @@ -329,6 +326,30 @@ void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) { } } +/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit +/// immediate in bits 0-7. +void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) { + const MachineOperand &MO = MI->getOperand(OpNum); + assert(MO.isImmediate() && "Not a valid so_imm value!"); + printSOImm(O, MO.getImmedValue(), TAI); +} + +/// printSOImm2PartOperand - SOImm is broken into two pieces using a mov +/// followed by a or to materialize. +void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) { + const MachineOperand &MO = MI->getOperand(OpNum); + assert(MO.isImmediate() && "Not a valid so_imm value!"); + unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImmedValue()); + unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImmedValue()); + printSOImm(O, ARM_AM::getSOImmVal(V1), TAI); + O << "\n\torr "; + printOperand(MI, 0); + O << ", "; + printOperand(MI, 0); + O << ", "; + printSOImm(O, ARM_AM::getSOImmVal(V2), TAI); +} + // so_reg is a 4-operand unit corresponding to register forms of the A5.1 // "Addressing Mode 1 - Data-processing operands" forms. This includes: // REG 0 0 - e.g. R5 diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 4d2aba7..bb8b61f 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -147,24 +147,6 @@ def sext_16_node : PatLeaf<(i32 GPR:$a), [{ }]>; -// Break so_imm's up into two pieces. This handles immediates with up to 16 -// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to -// get the first/second pieces. -def so_imm2part : PatLeaf<(imm), [{ - return ARM_AM::isSOImmTwoPartVal((unsigned)N->getValue()); -}]>; - -def so_imm2part_1 : SDNodeXForm<imm, [{ - unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getValue()); - return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32); -}]>; - -def so_imm2part_2 : SDNodeXForm<imm, [{ - unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getValue()); - return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32); -}]>; - - //===----------------------------------------------------------------------===// // Operand Definitions. @@ -217,6 +199,25 @@ def so_imm : Operand<i32>, let PrintMethod = "printSOImmOperand"; } +// Break so_imm's up into two pieces. This handles immediates with up to 16 +// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to +// get the first/second pieces. +def so_imm2part : Operand<i32>, + PatLeaf<(imm), + [{ return ARM_AM::isSOImmTwoPartVal((unsigned)N->getValue()); }]> { + let PrintMethod = "printSOImm2PartOperand"; +} + +def so_imm2part_1 : SDNodeXForm<imm, [{ + unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getValue()); + return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32); +}]>; + +def so_imm2part_2 : SDNodeXForm<imm, [{ + unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getValue()); + return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32); +}]>; + // Define ARM specific addressing modes. @@ -371,6 +372,8 @@ class AI4<dag ops, string asm, list<dag> pattern> : I<ops, AddrMode4, Size4Bytes, IndexModeNone, asm, "", pattern>; class AIx2<dag ops, string asm, list<dag> pattern> : I<ops, AddrModeNone, Size8Bytes, IndexModeNone, asm, "", pattern>; +class AI1x2<dag ops, string asm, list<dag> pattern> + : I<ops, AddrMode1, Size8Bytes, IndexModeNone, asm, "", pattern>; // Pre-indexed ops class AI2pr<dag ops, string asm, string cstr, list<dag> pattern> @@ -1064,14 +1067,15 @@ def LEApcrelJT : AI1<(ops GPR:$dst, i32imm:$label, i32imm:$id), def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>; def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), - (LEApcrelJT tjumptable:$dst, imm:$id)>; + (LEApcrelJT tjumptable:$dst, imm:$id)>; // Large immediate handling. // Two piece so_imms. -def : ARMPat<(i32 so_imm2part:$src), - (ORRri (MOVi (so_imm2part_1 imm:$src)), - (so_imm2part_2 imm:$src))>; +let isReMaterializable = 1 in +def MOVi2pieces : AI1x2<(ops GPR:$dst, so_imm2part:$src), + "mov $dst, $src", + [(set GPR:$dst, so_imm2part:$src)]>; def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS), (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)), |