diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-10-13 19:56:10 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-10-13 19:56:10 +0000 |
commit | b35ad41fef5d1edd9495f708fb7eae1a0a94ef9d (patch) | |
tree | 8d089cf4102930124cb74fb4fa58955d0013d78d | |
parent | e822f9450992774a2058163d0572538375e74051 (diff) | |
download | external_llvm-b35ad41fef5d1edd9495f708fb7eae1a0a94ef9d.zip external_llvm-b35ad41fef5d1edd9495f708fb7eae1a0a94ef9d.tar.gz external_llvm-b35ad41fef5d1edd9495f708fb7eae1a0a94ef9d.tar.bz2 |
Add ARM mode encoding for [SU]XT[BH] and [SU]XTA[BH] instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116421 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 6 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 77 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 10 | ||||
-rw-r--r-- | test/MC/ARM/simple-encoding.ll | 10 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 2 |
6 files changed, 76 insertions, 31 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index d49a79d..b86c8c9 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -170,6 +170,8 @@ namespace { const { return 0; } unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } /// getMovi32Value - Return binary encoding of operand for movw/movt. If the /// machine operand requires relocation, record the relocation and return diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 06ddbae..49f382d 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -933,7 +933,13 @@ class AExtI<bits<8> opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, itin, opc, asm, "", pattern> { + // All AExtI instructions have Rd and Rm register operands. + bits<4> Rd; + bits<4> Rm; + let Inst{15-12} = Rd; + let Inst{3-0} = Rm; let Inst{7-4} = 0b0111; + let Inst{9-8} = 0b00; let Inst{27-20} = opcod; } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index e086aae..544754d 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -199,12 +199,6 @@ def so_imm_not_XFORM : SDNodeXForm<imm, [{ return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32); }]>; -// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24. -def rot_imm : PatLeaf<(i32 imm), [{ - int32_t v = (int32_t)N->getZExtValue(); - return v == 8 || v == 16 || v == 24; -}]>; - /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15]. def imm1_15 : PatLeaf<(i32 imm), [{ return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16; @@ -302,6 +296,13 @@ def pclabel : Operand<i32> { let PrintMethod = "printPCLabel"; } +// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24. +def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{ + int32_t v = (int32_t)N->getZExtValue(); + return v == 8 || v == 16 || v == 24; }]> { + string EncoderMethod = "getRotImmOpValue"; +} + // shift_imm: An integer that encodes a shift amount and the type of shift // (currently either asr or lsl) using the same encoding used for the // immediates in so_reg operands. @@ -609,33 +610,37 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, /// register and one whose operand is a register rotated by 8/16/24. /// FIXME: Remove the 'r' variant. Its rot_imm is zero. multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> { - def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src), - IIC_iEXTr, opc, "\t$dst, $src", - [(set GPR:$dst, (opnode GPR:$src))]>, + def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm), + IIC_iEXTr, opc, "\t$Rd, $Rm", + [(set GPR:$Rd, (opnode GPR:$Rm))]>, Requires<[IsARM, HasV6]> { let Inst{11-10} = 0b00; let Inst{19-16} = 0b1111; } - def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot), - IIC_iEXTr, opc, "\t$dst, $src, ror $rot", - [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>, + def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot), + IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot", + [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>, Requires<[IsARM, HasV6]> { + bits<2> rot; + let Inst{11-10} = rot; let Inst{19-16} = 0b1111; } } multiclass AI_ext_rrot_np<bits<8> opcod, string opc> { - def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src), - IIC_iEXTr, opc, "\t$dst, $src", + def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm), + IIC_iEXTr, opc, "\t$Rd, $Rm", [/* For disassembly only; pattern left blank */]>, Requires<[IsARM, HasV6]> { let Inst{11-10} = 0b00; let Inst{19-16} = 0b1111; } - def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot), - IIC_iEXTr, opc, "\t$dst, $src, ror $rot", + def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot), + IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot", [/* For disassembly only; pattern left blank */]>, Requires<[IsARM, HasV6]> { + bits<2> rot; + let Inst{11-10} = rot; let Inst{19-16} = 0b1111; } } @@ -643,33 +648,43 @@ multiclass AI_ext_rrot_np<bits<8> opcod, string opc> { /// AI_exta_rrot - A binary operation with two forms: one whose operand is a /// register and one whose operand is a register rotated by 8/16/24. multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> { - def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), - IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS", - [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>, + def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), + IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm", + [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>, Requires<[IsARM, HasV6]> { let Inst{11-10} = 0b00; } - def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, - i32imm:$rot), - IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot", - [(set GPR:$dst, (opnode GPR:$LHS, - (rotr GPR:$RHS, rot_imm:$rot)))]>, - Requires<[IsARM, HasV6]>; + def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, + rot_imm:$rot), + IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot", + [(set GPR:$Rd, (opnode GPR:$Rn, + (rotr GPR:$Rm, rot_imm:$rot)))]>, + Requires<[IsARM, HasV6]> { + bits<4> Rn; + bits<2> rot; + let Inst{19-16} = Rn; + let Inst{11-10} = rot; + } } // For disassembly only. multiclass AI_exta_rrot_np<bits<8> opcod, string opc> { - def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), - IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS", + def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), + IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm", [/* For disassembly only; pattern left blank */]>, Requires<[IsARM, HasV6]> { let Inst{11-10} = 0b00; } - def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, - i32imm:$rot), - IIC_iEXTAr, opc, "\t$dst, $LHS, $RHS, ror $rot", + def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, + rot_imm:$rot), + IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot", [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM, HasV6]>; + Requires<[IsARM, HasV6]> { + bits<4> Rn; + bits<2> rot; + let Inst{19-16} = Rn; + let Inst{11-10} = rot; + } } /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 6d9a459..5b20676 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -74,6 +74,16 @@ public: /// getSORegOpValue - Return an encoded so_reg shifted register value. unsigned getSORegOpValue(const MCInst &MI, unsigned Op) const; + unsigned getRotImmOpValue(const MCInst &MI, unsigned Op) const { + switch (MI.getOperand(Op).getImm()) { + default: assert (0 && "Not a valid rot_imm value!"); + case 0: return 0; + case 8: return 1; + case 16: return 2; + case 24: return 3; + } + } + unsigned getNumFixupKinds() const { assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented."); return 0; diff --git a/test/MC/ARM/simple-encoding.ll b/test/MC/ARM/simple-encoding.ll index 01e9c98..05ecb96 100644 --- a/test/MC/ARM/simple-encoding.ll +++ b/test/MC/ARM/simple-encoding.ll @@ -64,4 +64,14 @@ entry: %add = add nsw i64 %b, %a ret i64 %add } + +define i32 @f7(i32 %a, i32 %b) nounwind readnone optsize ssp { +entry: +; CHECK: f7 +; CHECK: uxtab r0, r0, r1 @ encoding: [0x71,0x00,0xe0,0xe6] + %and = and i32 %b, 255 + %add = add i32 %and, %a + ret i32 %add +} + declare void @llvm.trap() nounwind diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 90ef192..a4cac55 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -585,6 +585,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I MISC("t2_so_reg", "kOperandTypeThumb2SoReg"); // R, I MISC("so_imm", "kOperandTypeARMSoImm"); // I + MISC("rot_imm", "kOperandTypeARMRotImm"); // I MISC("t2_so_imm", "kOperandTypeThumb2SoImm"); // I MISC("so_imm2part", "kOperandTypeARMSoImm2Part"); // I MISC("pred", "kOperandTypeARMPredicate"); // I, R @@ -801,6 +802,7 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) { operandTypes.addEntry("kOperandTypeARMBranchTarget"); operandTypes.addEntry("kOperandTypeARMSoReg"); operandTypes.addEntry("kOperandTypeARMSoImm"); + operandTypes.addEntry("kOperandTypeARMRotImm"); operandTypes.addEntry("kOperandTypeARMSoImm2Part"); operandTypes.addEntry("kOperandTypeARMPredicate"); operandTypes.addEntry("kOperandTypeARMAddrMode2"); |