From 8abe32af38b66bf4577526b23b6af6ec7eb6c155 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 15 Oct 2010 17:15:16 +0000 Subject: [PATCH] ARM mode encoding information for UBFX and SBFX instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116588 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeEmitter.cpp | 2 ++ lib/Target/ARM/ARMInstrInfo.td | 35 ++++++++++++++++++++++++----- lib/Target/ARM/ARMMCCodeEmitter.cpp | 4 ++++ test/MC/ARM/simple-encoding.ll | 15 +++++++++++++ utils/TableGen/EDEmitter.cpp | 1 + 5 files changed, 51 insertions(+), 6 deletions(-) diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index b5f534f36a8..910e438f0f5 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -172,6 +172,8 @@ namespace { const { return 0; } unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getImmMinusOneOpValue(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/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6e168d5b7aa..832b1363fba 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -367,6 +367,13 @@ def imm0_31 : Operand, PatLeaf<(imm), [{ return (int32_t)N->getZExtValue() < 32; }]>; +/// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'. +def imm0_31_m1 : Operand, PatLeaf<(imm), [{ + return (int32_t)N->getZExtValue() < 32; +}]> { + string EncoderMethod = "getImmMinusOneOpValue"; +} + // Define ARM specific addressing modes. // addrmode2base := reg +/- imm12 @@ -1761,22 +1768,38 @@ defm UXTAH : AI_exta_rrot<0b01101111, "uxtah", defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; -def SBFX : I<(outs GPR:$dst), - (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), +def SBFX : I<(outs GPR:$Rd), + (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width), AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, - "sbfx", "\t$dst, $src, $lsb, $width", "", []>, + "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>, Requires<[IsARM, HasV6T2]> { + bits<4> Rd; + bits<4> Rn; + bits<5> lsb; + bits<5> width; let Inst{27-21} = 0b0111101; let Inst{6-4} = 0b101; + let Inst{20-16} = width; + let Inst{15-12} = Rd; + let Inst{11-7} = lsb; + let Inst{3-0} = Rn; } -def UBFX : I<(outs GPR:$dst), - (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), +def UBFX : I<(outs GPR:$Rd), + (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width), AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, - "ubfx", "\t$dst, $src, $lsb, $width", "", []>, + "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>, Requires<[IsARM, HasV6T2]> { + bits<4> Rd; + bits<4> Rn; + bits<5> lsb; + bits<5> width; let Inst{27-21} = 0b0111111; let Inst{6-4} = 0b101; + let Inst{20-16} = width; + let Inst{15-12} = Rd; + let Inst{11-7} = lsb; + let Inst{3-0} = Rn; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index cafd3f235c3..6132d6df7f3 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -84,6 +84,10 @@ public: } } + unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op) const { + return MI.getOperand(Op).getImm() - 1; + } + 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 3d6358188cc..650990bfc49 100644 --- a/test/MC/ARM/simple-encoding.ll +++ b/test/MC/ARM/simple-encoding.ll @@ -99,4 +99,19 @@ entry: ret i64 %shr } +define i32 @f11([1 x i32] %A.coerce0, [1 x i32] %B.coerce0) nounwind readnone ssp { +entry: +; CHECK: f11 +; CHECK: ubfx r1, r1, #8, #5 @ encoding: [0x51,0x14,0xe4,0xe7] +; CHECK: sbfx r0, r0, #13, #7 @ encoding: [0xd0,0x06,0xa6,0xe7] + %tmp11 = extractvalue [1 x i32] %A.coerce0, 0 + %tmp4 = extractvalue [1 x i32] %B.coerce0, 0 + %0 = shl i32 %tmp11, 12 + %bf.val.sext = ashr i32 %0, 25 + %1 = lshr i32 %tmp4, 8 + %bf.clear2 = and i32 %1, 31 + %mul = mul nsw i32 %bf.val.sext, %bf.clear2 + ret i32 %mul +} + declare void @llvm.trap() nounwind diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 8435bb4144d..678ec6a8c6f 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -575,6 +575,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("msr_mask"); IMM("neg_zero"); IMM("imm0_31"); + IMM("imm0_31_m1"); IMM("nModImm"); IMM("imm0_4095"); IMM("jt2block_operand"); -- 2.34.1