From 7b8f46cf9e31d730acc25be771462e2a6a1a1dfb Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Thu, 11 Aug 2011 21:17:22 +0000 Subject: [PATCH] ARM STRH assembly parsing and encoding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137353 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 12 ++++-- lib/Target/ARM/ARMInstrInfo.td | 50 ++++++++++++++++------- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 16 ++++++++ test/MC/ARM/arm-memory-instructions.s | 34 +++++++++++++++ 4 files changed, 94 insertions(+), 18 deletions(-) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 8e326cfa7c5..4f18ce37d0d 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -5311,9 +5311,15 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return BB; } case ARM::STRr_preidx: - case ARM::STRBr_preidx: { - unsigned NewOpc = MI->getOpcode() == ARM::STRr_preidx ? - ARM::STR_PRE_REG : ARM::STRB_PRE_REG; + case ARM::STRBr_preidx: + case ARM::STRH_preidx: { + unsigned NewOpc; + switch (MI->getOpcode()) { + default: llvm_unreachable("unexpected opcode!"); + case ARM::STRr_preidx: NewOpc = ARM::STR_PRE_REG; break; + case ARM::STRBr_preidx: NewOpc = ARM::STRB_PRE_REG; break; + case ARM::STRH_preidx: NewOpc = ARM::STRH_PRE; break; + } MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc)); for (unsigned i = 0; i < MI->getNumOperands(); ++i) MIB.addOperand(MI->getOperand(i)); diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 2b7fac2e756..39b95c5ca67 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -2351,23 +2351,43 @@ def STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), 4, IIC_iStore_ru, [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; +def STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p), + 4, IIC_iStore_ru, + [(set GPR:$Rn_wb, + (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; +} + + + +def STRH_PRE : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addrmode3:$addr), IndexModePre, + StMiscFrm, IIC_iStore_bh_ru, + "strh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { + bits<14> addr; + let Inst{23} = addr{8}; // U bit + let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm + let Inst{19-16} = addr{12-9}; // Rn + let Inst{11-8} = addr{7-4}; // imm7_4/zero + let Inst{3-0} = addr{3-0}; // imm3_0/Rm + let AsmMatchConverter = "cvtStWriteBackRegAddrMode3"; } -def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am3offset:$offset), - IndexModePre, StMiscFrm, IIC_iStore_ru, - "strh", "\t$Rt, [$Rn, $offset]!", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, - (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; - -def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am3offset:$offset), - IndexModePost, StMiscFrm, IIC_iStore_bh_ru, - "strh", "\t$Rt, [$Rn], $offset", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, - GPR:$Rn, am3offset:$offset))]>; +def STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset), + IndexModePost, StMiscFrm, IIC_iStore_bh_ru, + "strh", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", + [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, + addr_offset_none:$addr, + am3offset:$offset))]> { + bits<10> offset; + bits<4> addr; + let Inst{23} = offset{8}; // U bit + let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm + let Inst{19-16} = addr; + let Inst{11-8} = offset{7-4}; // imm7_4/zero + let Inst{3-0} = offset{3-0}; // imm3_0/Rm +} let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { def STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb), diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index fc8a4847014..39f873c8beb 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -123,6 +123,8 @@ class ARMAsmParser : public MCTargetAsmParser { const SmallVectorImpl &); bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); + bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, @@ -2132,6 +2134,20 @@ cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, return true; } +/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. +/// Needed here because the Asm Gen Matcher can't handle properly tied operands +/// when they refer multiple MIOperands inside a single one. +bool ARMAsmParser:: +cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); + ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + /// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. /// Needed here because the Asm Gen Matcher can't handle properly tied operands /// when they refer multiple MIOperands inside a single one. diff --git a/test/MC/ARM/arm-memory-instructions.s b/test/MC/ARM/arm-memory-instructions.s index 49b4216f888..ae88482e937 100644 --- a/test/MC/ARM/arm-memory-instructions.s +++ b/test/MC/ARM/arm-memory-instructions.s @@ -428,3 +428,37 @@ _func: @ CHECK: strd r6, r7, [r5], r8 @ encoding: [0xf8,0x60,0x85,0xe0] @ CHECK: strd r5, r6, [r12], -r10 @ encoding: [0xfa,0x50,0x0c,0xe0] + +@------------------------------------------------------------------------------ +@ STRH (immediate) +@------------------------------------------------------------------------------ + strh r3, [r4] + strh r2, [r7, #4] + strh r1, [r8, #64]! + strh r12, [sp], #4 + +@ CHECK: strh r3, [r4] @ encoding: [0xb0,0x30,0xc4,0xe1] +@ CHECK: strh r2, [r7, #4] @ encoding: [0xb4,0x20,0xc7,0xe1] +@ CHECK: strh r1, [r8, #64]! @ encoding: [0xb0,0x14,0xe8,0xe1] +@ CHECK: strh r12, [sp], #4 @ encoding: [0xb4,0xc0,0xcd,0xe0] + + +@------------------------------------------------------------------------------ +@ FIXME: STRH (label) +@------------------------------------------------------------------------------ + + +@------------------------------------------------------------------------------ +@ STRH (register) +@------------------------------------------------------------------------------ + strh r6, [r5, r4] + strh r3, [r8, r11]! + strh r1, [r2, -r1]! + strh r9, [r7], r2 + strh r4, [r3], -r2 + +@ CHECK: strh r6, [r5, r4] @ encoding: [0xb4,0x60,0x85,0xe1] +@ CHECK: strh r3, [r8, r11]! @ encoding: [0xbb,0x30,0xa8,0xe1] +@ CHECK: strh r1, [r2, -r1]! @ encoding: [0xb1,0x10,0x22,0xe1] +@ CHECK: strh r9, [r7], r2 @ encoding: [0xb2,0x90,0x87,0xe0] +@ CHECK: strh r4, [r3], -r2 @ encoding: [0xb2,0x40,0x03,0xe0] -- 2.34.1