diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -1577,6 +1577,16 @@ def t2LDR_POST_imm : t2AsmPseudo<"ldr${p}.w $Rt, $Rn, $imm", (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; +// A7.7.46 LDRB (immediate) T3 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2LDRB_OFFSET_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2LDRB_PRE_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2LDRB_POST_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110). // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4 class T2IldT type, string opc, InstrItinClass ii> @@ -1743,6 +1753,16 @@ def t2STR_POST_imm : t2AsmPseudo<"str${p}.w $Rt, $Rn, $imm", (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; +// A7.7.163 STRB (immediate) T3 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2STRB_OFFSET_imm : t2AsmPseudo<"strb${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2STRB_PRE_imm : t2AsmPseudo<"strb${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2STRB_POST_imm : t2AsmPseudo<"strb${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly // only. // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4 diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7830,6 +7830,35 @@ } return false; } + + case ARM::t2LDRB_OFFSET_imm: + case ARM::t2LDRB_PRE_imm: + case ARM::t2LDRB_POST_imm: + case ARM::t2STRB_OFFSET_imm: + case ARM::t2STRB_PRE_imm: + case ARM::t2STRB_POST_imm: { + if (Inst.getOpcode() == ARM::t2LDRB_POST_imm || + Inst.getOpcode() == ARM::t2STRB_POST_imm || + Inst.getOpcode() == ARM::t2LDRB_PRE_imm || + Inst.getOpcode() == ARM::t2STRB_PRE_imm) { + int Imm = Inst.getOperand(2).getImm(); + if (Imm > 255 || Imm < -255) + return Error(Operands[5]->getStartLoc(), + "operand must be in range [-255, 255]"); + } else if (Inst.getOpcode() == ARM::t2LDRB_OFFSET_imm || + Inst.getOpcode() == ARM::t2STRB_OFFSET_imm) { + int Imm = Inst.getOperand(2).getImm(); + if (Imm > 0 || Imm < -255) + return Error(Operands[5]->getStartLoc(), + "operand must be in range [0, 255] with a negative sign"); + } + if (Inst.getOperand(0).getReg() == ARM::PC) { + return Error(Operands[3]->getStartLoc(), + "if operand is PC, should call the LDRB (literal)"); + } + return false; + } + case ARM::LDR_PRE_IMM: case ARM::LDR_PRE_REG: case ARM::t2LDR_PRE: @@ -8848,6 +8877,56 @@ Inst = TmpInst; return true; } + // Aliases for imm syntax of LDRB instructions. + case ARM::t2LDRB_OFFSET_imm: { + MCInst TmpInst; + TmpInst.setOpcode(ARM::t2LDRBi8); + TmpInst.addOperand(Inst.getOperand(0)); // Rt + TmpInst.addOperand(Inst.getOperand(1)); // Rn + TmpInst.addOperand(Inst.getOperand(2)); // imm + TmpInst.addOperand(Inst.getOperand(3)); // CondCode + Inst = TmpInst; + return true; + } + case ARM::t2LDRB_PRE_imm: + case ARM::t2LDRB_POST_imm: { + MCInst TmpInst; + TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRB_PRE_imm + ? ARM::t2LDRB_PRE + : ARM::t2LDRB_POST); + TmpInst.addOperand(Inst.getOperand(0)); // Rt + TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn + TmpInst.addOperand(Inst.getOperand(2)); // imm + TmpInst.addOperand(Inst.getOperand(3)); // CondCode + Inst = TmpInst; + return true; + } + // Aliases for imm syntax of STRB instructions. + case ARM::t2STRB_OFFSET_imm: { + MCInst TmpInst; + TmpInst.setOpcode(ARM::t2STRBi8); + TmpInst.addOperand(Inst.getOperand(0)); // Rt + TmpInst.addOperand(Inst.getOperand(1)); // Rn + TmpInst.addOperand(Inst.getOperand(2)); // imm + TmpInst.addOperand(Inst.getOperand(3)); // CondCode + Inst = TmpInst; + return true; + } + case ARM::t2STRB_PRE_imm: + case ARM::t2STRB_POST_imm: { + MCInst TmpInst; + TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm + ? ARM::t2STRB_PRE + : ARM::t2STRB_POST); + TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(0)); // Rt + TmpInst.addOperand(Inst.getOperand(1)); // Rn + TmpInst.addOperand(Inst.getOperand(2)); // imm + TmpInst.addOperand(Inst.getOperand(3)); // CondCode + Inst = TmpInst; + return true; + } // Aliases for alternate PC+imm syntax of LDR instructions. case ARM::t2LDRpcrel: // Select the narrow version if the immediate will fit. diff --git a/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s --- a/llvm/test/MC/ARM/basic-thumb2-instructions.s +++ b/llvm/test/MC/ARM/basic-thumb2-instructions.s @@ -1111,6 +1111,10 @@ ldrb lr, [r3], #255 ldrb r9, [r2], #4 ldrb r3, [sp], #-4 + ldrb.w r5, [r5, #-4] + ldrb.w r5, [r6, #32] + ldrb.w r5, [r8, #255]! + ldrb.w r9, [r2], #4 @ CHECK: ldrb r5, [r5, #-4] @ encoding: [0x15,0xf8,0x04,0x5c] @ CHECK: ldrb.w r5, [r6, #32] @ encoding: [0x96,0xf8,0x20,0x50] @@ -1123,6 +1127,10 @@ @ CHECK: ldrb lr, [r3], #255 @ encoding: [0x13,0xf8,0xff,0xeb] @ CHECK: ldrb r9, [r2], #4 @ encoding: [0x12,0xf8,0x04,0x9b] @ CHECK: ldrb r3, [sp], #-4 @ encoding: [0x1d,0xf8,0x04,0x39] +@ CHECK: ldrb r5, [r5, #-4] @ encoding: [0x15,0xf8,0x04,0x5c] +@ CHECK: ldrb.w r5, [r6, #32] @ encoding: [0x96,0xf8,0x20,0x50] +@ CHECK: ldrb r5, [r8, #255]! @ encoding: [0x18,0xf8,0xff,0x5f] +@ CHECK: ldrb r9, [r2], #4 @ encoding: [0x12,0xf8,0x04,0x9b] @------------------------------------------------------------------------------ @@ -3054,6 +3062,10 @@ strb r3, [sp], #-4 strb r4, [r8, #-0]! strb r1, [r0], #-0 + strb.w r5, [r5, #-4] + strb.w r5, [r6, #32] + strb.w r5, [r8, #255]! + strb.w r9, [r2], #4 @ CHECK: strb r5, [r5, #-4] @ encoding: [0x05,0xf8,0x04,0x5c] @ CHECK: strb.w r5, [r6, #32] @ encoding: [0x86,0xf8,0x20,0x50] @@ -3068,6 +3080,10 @@ @ CHECK: strb r3, [sp], #-4 @ encoding: [0x0d,0xf8,0x04,0x39] @ CHECK: strb r4, [r8, #-0]! @ encoding: [0x08,0xf8,0x00,0x4d] @ CHECK: strb r1, [r0], #-0 @ encoding: [0x00,0xf8,0x00,0x19] +@ CHECK: strb r5, [r5, #-4] @ encoding: [0x05,0xf8,0x04,0x5c] +@ CHECK: strb.w r5, [r6, #32] @ encoding: [0x86,0xf8,0x20,0x50] +@ CHECK: strb r5, [r8, #255]! @ encoding: [0x08,0xf8,0xff,0x5f] +@ CHECK: strb r9, [r2], #4 @ encoding: [0x02,0xf8,0x04,0x9b] @------------------------------------------------------------------------------