From 75579f739fbc99a92a15f3ce75bbd7628ba00f8c Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 29 Nov 2010 22:44:32 +0000 Subject: [PATCH] Provide Thumb2 encodings for basic loads and stores. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120340 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeEmitter.cpp | 6 ++ lib/Target/ARM/ARMInstrThumb2.td | 96 ++++++++++++++++++++++------- lib/Target/ARM/ARMMCCodeEmitter.cpp | 55 +++++++++++++++++ test/MC/ARM/thumb2.s | 15 ++++- 4 files changed, 150 insertions(+), 22 deletions(-) diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 363232df10a..5872fcd8443 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -177,6 +177,12 @@ namespace { const { return 0; } unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getT2AddrModeImm12OpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } + unsigned getT2AddrModeImm8OpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } + unsigned getT2AddrModeSORegOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index fadc7102794..ce4115c2ce3 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -127,6 +127,7 @@ def imm0_255_not : PatLeaf<(i32 imm), [{ def t2addrmode_imm12 : Operand, ComplexPattern { let PrintMethod = "printAddrModeImm12Operand"; + string EncoderMethod = "getT2AddrModeImm12OpValue"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } @@ -134,6 +135,7 @@ def t2addrmode_imm12 : Operand, def t2addrmode_imm8 : Operand, ComplexPattern { let PrintMethod = "printT2AddrModeImm8Operand"; + string EncoderMethod = "getT2AddrModeImm8OpValue"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } @@ -157,6 +159,7 @@ def t2am_imm8s4_offset : Operand { def t2addrmode_so_reg : Operand, ComplexPattern { let PrintMethod = "printT2AddrModeSoRegOperand"; + string EncoderMethod = "getT2AddrModeSORegOpValue"; let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm); } @@ -823,19 +826,26 @@ multiclass T2I_cmp_irs opcod, string opc, /// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns. multiclass T2I_ld opcod, string opc, InstrItinClass iii, InstrItinClass iis, PatFrag opnode> { - def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), iii, - opc, ".w\t$dst, $addr", - [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> { + def i12 : T2Ii12<(outs GPR:$Rt), (ins t2addrmode_imm12:$addr), iii, + opc, ".w\t$Rt, $addr", + [(set GPR:$Rt, (opnode t2addrmode_imm12:$addr))]> { let Inst{31-27} = 0b11111; let Inst{26-25} = 0b00; let Inst{24} = signed; let Inst{23} = 1; let Inst{22-21} = opcod; let Inst{20} = 1; // load + + bits<4> Rt; + let Inst{15-12} = Rt{3-0}; + + bits<16> addr; + let Inst{19-16} = addr{15-12}; // Rn + let Inst{11-0} = addr{11-0}; // imm } - def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), iii, - opc, "\t$dst, $addr", - [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> { + def i8 : T2Ii8 <(outs GPR:$Rt), (ins t2addrmode_imm8:$addr), iii, + opc, "\t$Rt, $addr", + [(set GPR:$Rt, (opnode t2addrmode_imm8:$addr))]> { let Inst{31-27} = 0b11111; let Inst{26-25} = 0b00; let Inst{24} = signed; @@ -846,10 +856,18 @@ multiclass T2I_ld opcod, string opc, // Offset: index==TRUE, wback==FALSE let Inst{10} = 1; // The P bit. let Inst{8} = 0; // The W bit. + + bits<4> Rt; + let Inst{15-12} = Rt{3-0}; + + bits<13> addr; + let Inst{19-16} = addr{12-9}; // Rn + let Inst{9} = addr{8}; // U + let Inst{7-0} = addr{7-0}; // imm } - def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), iis, - opc, ".w\t$dst, $addr", - [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> { + def s : T2Iso <(outs GPR:$Rt), (ins t2addrmode_so_reg:$addr), iis, + opc, ".w\t$Rt, $addr", + [(set GPR:$Rt, (opnode t2addrmode_so_reg:$addr))]> { let Inst{31-27} = 0b11111; let Inst{26-25} = 0b00; let Inst{24} = signed; @@ -857,12 +875,20 @@ multiclass T2I_ld opcod, string opc, let Inst{22-21} = opcod; let Inst{20} = 1; // load let Inst{11-6} = 0b000000; + + bits<4> Rt; + let Inst{15-12} = Rt{3-0}; + + bits<10> addr; + let Inst{19-16} = addr{9-6}; // Rn + let Inst{3-0} = addr{5-2}; // Rm + let Inst{5-4} = addr{1-0}; // imm } // FIXME: Is the pci variant actually needed? - def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), iii, - opc, ".w\t$dst, $addr", - [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> { + def pci : T2Ipc <(outs GPR:$Rt), (ins i32imm:$addr), iii, + opc, ".w\t$Rt, $addr", + [(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> { let isReMaterializable = 1; let Inst{31-27} = 0b11111; let Inst{26-25} = 0b00; @@ -871,23 +897,35 @@ multiclass T2I_ld opcod, string opc, let Inst{22-21} = opcod; let Inst{20} = 1; // load let Inst{19-16} = 0b1111; // Rn + + bits<4> Rt; + bits<12> addr; + let Inst{15-12} = Rt{3-0}; + let Inst{11-0} = addr{11-0}; } } /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns. multiclass T2I_st opcod, string opc, InstrItinClass iii, InstrItinClass iis, PatFrag opnode> { - def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), iii, - opc, ".w\t$src, $addr", - [(opnode GPR:$src, t2addrmode_imm12:$addr)]> { + def i12 : T2Ii12<(outs), (ins GPR:$Rt, t2addrmode_imm12:$addr), iii, + opc, ".w\t$Rt, $addr", + [(opnode GPR:$Rt, t2addrmode_imm12:$addr)]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0001; let Inst{22-21} = opcod; let Inst{20} = 0; // !load + + bits<4> Rt; + let Inst{19-16} = Rt{3-0}; + + bits<16> addr; + let Inst{19-16} = addr{15-12}; // Rn + let Inst{11-0} = addr{11-0}; // imm } - def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), iii, - opc, "\t$src, $addr", - [(opnode GPR:$src, t2addrmode_imm8:$addr)]> { + def i8 : T2Ii8 <(outs), (ins GPR:$Rt, t2addrmode_imm8:$addr), iii, + opc, "\t$Rt, $addr", + [(opnode GPR:$Rt, t2addrmode_imm8:$addr)]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0000; let Inst{22-21} = opcod; @@ -896,15 +934,31 @@ multiclass T2I_st opcod, string opc, // Offset: index==TRUE, wback==FALSE let Inst{10} = 1; // The P bit. let Inst{8} = 0; // The W bit. + + bits<4> Rt; + let Inst{19-16} = Rt{3-0}; + + bits<13> addr; + let Inst{19-16} = addr{12-9}; // Rn + let Inst{9} = addr{8}; // U + let Inst{7-0} = addr{7-0}; // imm } - def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), iis, - opc, ".w\t$src, $addr", - [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> { + def s : T2Iso <(outs), (ins GPR:$Rt, t2addrmode_so_reg:$addr), iis, + opc, ".w\t$Rt, $addr", + [(opnode GPR:$Rt, t2addrmode_so_reg:$addr)]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0000; let Inst{22-21} = opcod; let Inst{20} = 0; // !load let Inst{11-6} = 0b000000; + + bits<4> Rt; + let Inst{15-12} = Rt{3-0}; + + bits<10> addr; + let Inst{19-16} = addr{9-6}; // Rn + let Inst{3-0} = addr{5-2}; // Rm + let Inst{5-4} = addr{1-0}; // imm } } diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 06e7b9d2bc9..b33c32608c0 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -173,6 +173,13 @@ public: return Encoded; } + unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups) const; + unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups) const; + unsigned getT2AddrModeImm12OpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups) const; + /// getSORegOpValue - Return an encoded so_reg shifted register value. unsigned getSORegOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const; @@ -632,6 +639,54 @@ getSORegOpValue(const MCInst &MI, unsigned OpIdx, return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7; } +unsigned ARMMCCodeEmitter:: +getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups) const { + const MCOperand &MO1 = MI.getOperand(OpNum); + const MCOperand &MO2 = MI.getOperand(OpNum+1); + const MCOperand &MO3 = MI.getOperand(OpNum+2); + + // Encoded as [Rn, Rm, imm]. + // FIXME: Needs fixup support. + unsigned Value = getARMRegisterNumbering(MO1.getReg()); + Value <<= 4; + Value |= getARMRegisterNumbering(MO2.getReg()); + Value <<= 2; + Value |= MO3.getImm(); + + return Value; +} + +unsigned ARMMCCodeEmitter:: +getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups) const { + const MCOperand &MO1 = MI.getOperand(OpNum); + const MCOperand &MO2 = MI.getOperand(OpNum+1); + + // FIXME: Needs fixup support. + unsigned Value = getARMRegisterNumbering(MO1.getReg()); + + // Even though the immediate is 8 bits long, we need 9 bits in order + // to represent the (inverse of the) sign bit. + Value <<= 9; + Value |= ((int32_t)MO2.getImm()) & 511; + Value ^= 256; // Invert the sign bit. + return Value; +} + +unsigned ARMMCCodeEmitter:: +getT2AddrModeImm12OpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups) const { + const MCOperand &MO1 = MI.getOperand(OpNum); + const MCOperand &MO2 = MI.getOperand(OpNum+1); + + // FIXME: Needs fixup support. + unsigned Value = getARMRegisterNumbering(MO1.getReg()); + Value <<= 12; + Value |= MO2.getImm() & 4095; + return Value; +} + unsigned ARMMCCodeEmitter:: getT2SORegOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const { diff --git a/test/MC/ARM/thumb2.s b/test/MC/ARM/thumb2.s index 3222fdd044f..410011d1fd6 100644 --- a/test/MC/ARM/thumb2.s +++ b/test/MC/ARM/thumb2.s @@ -101,4 +101,17 @@ @ CHECK: dmb ish @ encoding: [0x5b,0x8f,0xbf,0xf3] dmb ish - \ No newline at end of file +@ CHECK: str.w r0, [r1, #4092] @ encoding: [0xfc,0x0f,0xc1,0xf8] + str.w r0, [r1, #4092] +@ CHECK: str r0, [r1, #-128] @ encoding: [0x80,0x0c,0x41,0xf8] + str r0, [r1, #-128] +@ CHECK: str.w r0, [r1, r2, lsl #2] @ encoding: [0x22,0x00,0x41,0xf8 + str.w r0, [r1, r2, lsl #2] + +@ CHECK: ldr.w r0, [r0, #4092] @ encoding: [0xfc,0x0f,0xd0,0xf8] + ldr.w r0, [r0, #4092] +@ CHECK: ldr r0, [r0, #-128] @ encoding: [0x80,0x0c,0x50,0xf8] + ldr r0, [r0, #-128] +@ CHECK: ldr.w r0, [r0, r1, lsl #2] @ encoding: [0x21,0x00,0x50,0xf8] + ldr.w r0, [r0, r1, lsl #2] + -- 2.34.1