diff options
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 49 | ||||
-rw-r--r-- | lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 50 | ||||
-rw-r--r-- | lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/thumb2.txt | 16 |
4 files changed, 77 insertions, 40 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index da296dcd8a..8e19d32aca 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -176,11 +176,10 @@ def t2adrlabel : Operand<i32> { let PrintMethod = "printAdrLabelOperand"; } - // t2addrmode_posimm8 := reg + imm8 def MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";} def t2addrmode_posimm8 : Operand<i32> { - let PrintMethod = "printT2AddrModeImm8Operand"; + let PrintMethod = "printT2AddrModeImm8Operand<false>"; let EncoderMethod = "getT2AddrModeImm8OpValue"; let DecoderMethod = "DecodeT2AddrModeImm8"; let ParserMatchClass = MemPosImm8OffsetAsmOperand; @@ -191,7 +190,7 @@ def t2addrmode_posimm8 : Operand<i32> { def MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";} def t2addrmode_negimm8 : Operand<i32>, ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { - let PrintMethod = "printT2AddrModeImm8Operand"; + let PrintMethod = "printT2AddrModeImm8Operand<false>"; let EncoderMethod = "getT2AddrModeImm8OpValue"; let DecoderMethod = "DecodeT2AddrModeImm8"; let ParserMatchClass = MemNegImm8OffsetAsmOperand; @@ -200,15 +199,22 @@ def t2addrmode_negimm8 : Operand<i32>, // t2addrmode_imm8 := reg +/- imm8 def MemImm8OffsetAsmOperand : AsmOperandClass { let Name = "MemImm8Offset"; } -def t2addrmode_imm8 : Operand<i32>, - ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { - let PrintMethod = "printT2AddrModeImm8Operand"; +class T2AddrMode_Imm8 : Operand<i32>, + ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { let EncoderMethod = "getT2AddrModeImm8OpValue"; let DecoderMethod = "DecodeT2AddrModeImm8"; let ParserMatchClass = MemImm8OffsetAsmOperand; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } +def t2addrmode_imm8 : T2AddrMode_Imm8 { + let PrintMethod = "printT2AddrModeImm8Operand<false>"; +} + +def t2addrmode_imm8_pre : T2AddrMode_Imm8 { + let PrintMethod = "printT2AddrModeImm8Operand<true>"; +} + def t2am_imm8_offset : Operand<i32>, ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", [], [SDNPWantRoot]> { @@ -219,14 +225,21 @@ def t2am_imm8_offset : Operand<i32>, // t2addrmode_imm8s4 := reg +/- (imm8 << 2) def MemImm8s4OffsetAsmOperand : AsmOperandClass {let Name = "MemImm8s4Offset";} -def t2addrmode_imm8s4 : Operand<i32> { - let PrintMethod = "printT2AddrModeImm8s4Operand"; +class T2AddrMode_Imm8s4 : Operand<i32> { let EncoderMethod = "getT2AddrModeImm8s4OpValue"; let DecoderMethod = "DecodeT2AddrModeImm8s4"; let ParserMatchClass = MemImm8s4OffsetAsmOperand; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } +def t2addrmode_imm8s4 : T2AddrMode_Imm8s4 { + let PrintMethod = "printT2AddrModeImm8s4Operand<false>"; +} + +def t2addrmode_imm8s4_pre : T2AddrMode_Imm8s4 { + let PrintMethod = "printT2AddrModeImm8s4Operand<true>"; +} + def t2am_imm8s4_offset_asmoperand : AsmOperandClass { let Name = "Imm8s4"; } def t2am_imm8s4_offset : Operand<i32> { let PrintMethod = "printT2AddrModeImm8s4OffsetOperand"; @@ -1300,7 +1313,7 @@ def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)), let mayLoad = 1, neverHasSideEffects = 1 in { def t2LDR_PRE : T2Ipreldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), - (ins t2addrmode_imm8:$addr), + (ins t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_iu, "ldr", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { @@ -1313,7 +1326,7 @@ def t2LDR_POST : T2Ipostldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), "ldr", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; def t2LDRB_PRE : T2Ipreldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), - (ins t2addrmode_imm8:$addr), + (ins t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { @@ -1325,7 +1338,7 @@ def t2LDRB_POST : T2Ipostldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), "ldrb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; def t2LDRH_PRE : T2Ipreldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), - (ins t2addrmode_imm8:$addr), + (ins t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { @@ -1337,7 +1350,7 @@ def t2LDRH_POST : T2Ipostldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), "ldrh", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; def t2LDRSB_PRE : T2Ipreldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), - (ins t2addrmode_imm8:$addr), + (ins t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { @@ -1349,7 +1362,7 @@ def t2LDRSB_POST : T2Ipostldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), "ldrsb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; def t2LDRSH_PRE : T2Ipreldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), - (ins t2addrmode_imm8:$addr), + (ins t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { @@ -1407,14 +1420,14 @@ def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs), let mayStore = 1, neverHasSideEffects = 1 in { def t2STR_PRE : T2Ipreldst<0, 0b10, 0, 1, (outs GPRnopc:$Rn_wb), - (ins GPRnopc:$Rt, t2addrmode_imm8:$addr), + (ins GPRnopc:$Rt, t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iStore_iu, "str", "\t$Rt, $addr!", "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8"; } def t2STRH_PRE : T2Ipreldst<0, 0b01, 0, 1, (outs GPRnopc:$Rn_wb), - (ins rGPR:$Rt, t2addrmode_imm8:$addr), + (ins rGPR:$Rt, t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iStore_iu, "strh", "\t$Rt, $addr!", "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { @@ -1422,7 +1435,7 @@ def t2STRH_PRE : T2Ipreldst<0, 0b01, 0, 1, (outs GPRnopc:$Rn_wb), } def t2STRB_PRE : T2Ipreldst<0, 0b00, 0, 1, (outs GPRnopc:$Rn_wb), - (ins rGPR:$Rt, t2addrmode_imm8:$addr), + (ins rGPR:$Rt, t2addrmode_imm8_pre:$addr), AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu, "strb", "\t$Rt, $addr!", "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { @@ -1514,7 +1527,7 @@ def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>; // For disassembly only. def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), - (ins t2addrmode_imm8s4:$addr), IIC_iLoad_d_ru, + (ins t2addrmode_imm8s4_pre:$addr), IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, $addr!", "$addr.base = $wb", []> { let AsmMatchConverter = "cvtT2LdrdPre"; let DecoderMethod = "DecodeT2LDRDPreInstruction"; @@ -1526,7 +1539,7 @@ def t2LDRD_POST : T2Ii8s4post<0, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), "$addr.base = $wb", []>; def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs GPR:$wb), - (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4:$addr), + (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4_pre:$addr), IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, $addr!", "$addr.base = $wb", []> { let AsmMatchConverter = "cvtT2StrdPre"; diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 0931e597d3..62394faa68 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -1079,6 +1079,7 @@ void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, O << "]" << markup(">"); } +template<bool AlwaysPrintImm0> void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { @@ -1089,22 +1090,25 @@ void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, printRegName(O, MO1.getReg()); int32_t OffImm = (int32_t)MO2.getImm(); + bool isSub = OffImm < 0; // Don't print +0. - if (OffImm != 0) - O << ", "; - if (OffImm != 0 && UseMarkup) - O << "<imm:"; if (OffImm == INT32_MIN) - O << "#-0"; - else if (OffImm < 0) - O << "#-" << -OffImm; - else if (OffImm > 0) - O << "#" << OffImm; - if (OffImm != 0 && UseMarkup) - O << ">"; + OffImm = 0; + if (isSub) { + O << ", " + << markup("<imm:") + << "#-" << -OffImm + << markup(">"); + } else if (AlwaysPrintImm0 || OffImm > 0) { + O << ", " + << markup("<imm:") + << "#" << OffImm + << markup(">"); + } O << "]" << markup(">"); } +template<bool AlwaysPrintImm0> void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { @@ -1120,22 +1124,24 @@ void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, printRegName(O, MO1.getReg()); int32_t OffImm = (int32_t)MO2.getImm(); + bool isSub = OffImm < 0; assert(((OffImm & 0x3) == 0) && "Not a valid immediate!"); // Don't print +0. - if (OffImm != 0) - O << ", "; - if (OffImm != 0 && UseMarkup) - O << "<imm:"; if (OffImm == INT32_MIN) - O << "#-0"; - else if (OffImm < 0) - O << "#-" << -OffImm; - else if (OffImm > 0) - O << "#" << OffImm; - if (OffImm != 0 && UseMarkup) - O << ">"; + OffImm = 0; + if (isSub) { + O << ", " + << markup("<imm:") + << "#-" << -OffImm + << markup(">"); + } else if (AlwaysPrintImm0 || OffImm > 0) { + O << ", " + << markup("<imm:") + << "#" << OffImm + << markup(">"); + } O << "]" << markup(">"); } diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index 5a6434886c..a3ea6401c5 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -97,8 +97,10 @@ public: template<bool AlwaysPrintImm0> void printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + template<bool AlwaysPrintImm0> void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + template<bool AlwaysPrintImm0> void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printT2AddrModeImm0_1020s4Operand(const MCInst *MI, unsigned OpNum, diff --git a/test/MC/Disassembler/ARM/thumb2.txt b/test/MC/Disassembler/ARM/thumb2.txt index eb1e112d4f..482cca8bbc 100644 --- a/test/MC/Disassembler/ARM/thumb2.txt +++ b/test/MC/Disassembler/ARM/thumb2.txt @@ -576,6 +576,7 @@ # CHECK: ldr r2, [r4, #255]! # CHECK: ldr r8, [sp, #4]! # CHECK: ldr lr, [sp, #-4]! +# CHECK: ldr lr, [sp, #0]! # CHECK: ldr r2, [r4], #255 # CHECK: ldr r8, [sp], #4 # CHECK: ldr lr, [sp], #-4 @@ -590,6 +591,7 @@ 0x54 0xf8 0xff 0x2f 0x5d 0xf8 0x04 0x8f 0x5d 0xf8 0x04 0xed +0x5d 0xf8 0x00 0xef 0x54 0xf8 0xff 0x2b 0x5d 0xf8 0x04 0x8b 0x5d 0xf8 0x04 0xe9 @@ -623,6 +625,7 @@ # CHECK: ldrb r5, [r8, #255]! # CHECK: ldrb r2, [r5, #4]! # CHECK: ldrb r1, [r4, #-4]! +# CHECK: ldrb r1, [r4, #0]! # CHECK: ldrb lr, [r3], #255 # CHECK: ldrb r9, [r2], #4 # CHECK: ldrb r3, [sp], #-4 @@ -636,6 +639,7 @@ 0x18 0xf8 0xff 0x5f 0x15 0xf8 0x04 0x2f 0x14 0xf8 0x04 0x1d +0x14 0xf8 0x00 0x1f 0x13 0xf8 0xff 0xeb 0x12 0xf8 0x04 0x9b 0x1d 0xf8 0x04 0x39 @@ -677,6 +681,7 @@ # CHECK: ldrd r8, r1, [r3] # CHECK: ldrd r0, r1, [r2], #-0 # CHECK: ldrd r0, r1, [r2, #-0]! +# CHECK: ldrd r0, r1, [r2, #0]! # CHECK: ldrd r0, r1, [r2, #-0] 0xd6 0xe9 0x06 0x35 @@ -687,6 +692,7 @@ 0xd3 0xe9 0x00 0x81 0x72 0xe8 0x00 0x01 0x72 0xe9 0x00 0x01 +0xf2 0xe9 0x00 0x01 0x52 0xe9 0x00 0x01 @@ -741,6 +747,7 @@ # CHECK: ldrh r5, [r8, #255]! # CHECK: ldrh r2, [r5, #4]! # CHECK: ldrh r1, [r4, #-4]! +# CHECK: ldrh r1, [r4, #0]! # CHECK: ldrh lr, [r3], #255 # CHECK: ldrh r9, [r2], #4 # CHECK: ldrh r3, [sp], #-4 @@ -754,6 +761,7 @@ 0x38 0xf8 0xff 0x5f 0x35 0xf8 0x04 0x2f 0x34 0xf8 0x04 0x1d +0x34 0xf8 0x00 0x1f 0x33 0xf8 0xff 0xeb 0x32 0xf8 0x04 0x9b 0x3d 0xf8 0x04 0x39 @@ -798,6 +806,7 @@ # CHECK: ldrsb r5, [r8, #255]! # CHECK: ldrsb r2, [r5, #4]! # CHECK: ldrsb r1, [r4, #-4]! +# CHECK: ldrsb r1, [r4, #0]! # CHECK: ldrsb lr, [r3], #255 # CHECK: ldrsb r9, [r2], #4 # CHECK: ldrsb r3, [sp], #-4 @@ -811,6 +820,7 @@ 0x18 0xf9 0xff 0x5f 0x15 0xf9 0x04 0x2f 0x14 0xf9 0x04 0x1d +0x14 0xf9 0x00 0x1f 0x13 0xf9 0xff 0xeb 0x12 0xf9 0x04 0x9b 0x1d 0xf9 0x04 0x39 @@ -870,6 +880,7 @@ # CHECK: ldrsh r5, [r8, #255]! # CHECK: ldrsh r2, [r5, #4]! # CHECK: ldrsh r1, [r4, #-4]! +# CHECK: ldrsh r1, [r4, #0]! # CHECK: ldrsh lr, [r3], #255 # CHECK: ldrsh r9, [r2], #4 # CHECK: ldrsh r3, [sp], #-4 @@ -883,6 +894,7 @@ 0x38 0xf9 0xff 0x5f 0x35 0xf9 0x04 0x2f 0x34 0xf9 0x04 0x1d +0x34 0xf9 0x00 0x1f 0x33 0xf9 0xff 0xeb 0x32 0xf9 0x04 0x9b 0x3d 0xf9 0x04 0x39 @@ -1896,12 +1908,14 @@ # CHECK: strd r8, r5, [r5], #-0 # CHECK: strd r7, r4, [r5], #-4 # CHECK: strd r0, r1, [r2, #-0]! +# CHECK: strd r0, r1, [r2, #0]! # CHECK: strd r0, r1, [r2, #-0] 0x65 0xe8 0x02 0x63 0x65 0xe8 0x00 0x85 0x65 0xe8 0x01 0x74 0x62 0xe9 0x00 0x01 +0xe2 0xe9 0x00 0x01 0x42 0xe9 0x00 0x01 #------------------------------------------------------------------------------ @@ -1933,6 +1947,7 @@ # CHECK: strh r5, [r8, #255]! # CHECK: strh r2, [r5, #4]! # CHECK: strh r1, [r4, #-4]! +# CHECK: strh r1, [r4, #0]! # CHECK: strh lr, [r3], #255 # CHECK: strh r9, [r2], #4 # CHECK: strh r3, [sp], #-4 @@ -1945,6 +1960,7 @@ 0x28 0xf8 0xff 0x5f 0x25 0xf8 0x04 0x2f 0x24 0xf8 0x04 0x1d +0x24 0xf8 0x00 0x1f 0x23 0xf8 0xff 0xeb 0x22 0xf8 0x04 0x9b 0x2d 0xf8 0x04 0x39 |