From 5df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0ad Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 2 Nov 2010 22:31:46 +0000 Subject: [PATCH] Rename getAddrModeImm12OpValue to getAddrModeImmOpValue and expand it to work with immediates up to 16-bits in size. The same logic is applied to other LDR encodings, e.g. VLDR, but which use a different immediate bit width (8-bits in VLDR's case). Removing the "12" allows it to be more generic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118094 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeEmitter.cpp | 39 ++++++++++++++------------- lib/Target/ARM/ARMInstrInfo.td | 15 ++++++----- lib/Target/ARM/ARMInstrVFP.td | 17 +++++++++--- lib/Target/ARM/ARMMCCodeEmitter.cpp | 41 ++++++++++++++--------------- test/MC/ARM/arm_instructions.s | 9 ++----- test/MC/ARM/simple-fp-encoding.s | 17 ++++++++++++ 6 files changed, 81 insertions(+), 57 deletions(-) diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 0ef65bb23ce..0584dec5146 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -177,26 +177,27 @@ namespace { const { return 0; } unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op) - const { - // {17-13} = reg - // {12} = (U)nsigned (add == '1', sub == '0') - // {11-0} = imm12 - const MachineOperand &MO = MI.getOperand(Op); - const MachineOperand &MO1 = MI.getOperand(Op + 1); - if (!MO.isReg()) { - emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry); - return 0; - } - unsigned Reg = getARMRegisterNumbering(MO.getReg()); - int32_t Imm12 = MO1.getImm(); - uint32_t Binary; - Binary = Imm12 & 0xfff; - if (Imm12 >= 0) - Binary |= (1 << 12); - Binary |= (Reg << 13); - return Binary; + uint32_t getAddrModeImmOpValue(const MachineInstr &MI, unsigned Op) const { + // {20-17} = reg + // {16} = (U)nsigned (add == '1', sub == '0') + // {15-0} = imm + const MachineOperand &MO = MI.getOperand(Op); + const MachineOperand &MO1 = MI.getOperand(Op + 1); + if (!MO.isReg()) { + emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry); + return 0; } + + unsigned Reg = getARMRegisterNumbering(MO.getReg()); + int32_t Imm = MO1.getImm(); + uint32_t Binary; + Binary = Imm & 0xffff; + if (Imm >= 0) + Binary |= (1 << 16); + + Binary |= (Reg << 17); + return Binary; + } unsigned getNEONVcvtImm32OpValue(const MachineInstr &MI, unsigned Op) const { return 0; } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 3c1da1efb65..95ab0f1d8d6 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -398,7 +398,7 @@ def addrmode_imm12 : Operand, // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other // immediate values are as normal. - string EncoderMethod = "getAddrModeImm12OpValue"; + string EncoderMethod = "getAddrModeImmOpValue"; let PrintMethod = "printAddrModeImm12Operand"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } @@ -464,6 +464,7 @@ def addrmode5 : Operand, let PrintMethod = "printAddrMode5Operand"; let MIOperandInfo = (ops GPR:$base, i32imm); let ParserMatchClass = ARMMemMode5AsmOperand; + string EncoderMethod = "getAddrModeImmOpValue"; } // addrmode6 := reg with optional writeback @@ -830,9 +831,9 @@ multiclass AI_ldr1 { bits<4> Rt; - bits<17> addr; - let Inst{23} = addr{12}; // U (add = ('U' == 1)) - let Inst{19-16} = addr{16-13}; // Rn + bits<32> addr; + let Inst{23} = addr{16}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{20-17}; // Rn let Inst{15-12} = Rt; let Inst{11-0} = addr{11-0}; // imm12 } @@ -840,9 +841,9 @@ multiclass AI_ldr1 { bits<4> Rt; - bits<17> shift; - let Inst{23} = shift{12}; // U (add = ('U' == 1)) - let Inst{19-16} = shift{16-13}; // Rn + bits<32> shift; + let Inst{23} = shift{16}; // U (add = ('U' == 1)) + let Inst{19-16} = shift{20-17}; // Rn let Inst{11-0} = shift{11-0}; } } diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index fd0e84b1178..337028d88df 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -53,18 +53,29 @@ def vfp_f64imm : Operand, let canFoldAsLoad = 1, isReMaterializable = 1 in { def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr), IIC_fpLoad64, "vldr", ".64\t$Dd, $addr", - [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]>; + [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]> { + // Instruction operands. + bits<5> Dd; + bits<32> addr; + + // Encode instruction operands. + let Inst{23} = addr{16}; // U (add = (U == '1')) + let Inst{22} = Dd{4}; + let Inst{19-16} = addr{20-17}; // Rn + let Inst{15-12} = Dd{3-0}; + let Inst{7-0} = addr{7-0}; // imm8 +} def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr), IIC_fpLoad32, "vldr", ".32\t$dst, $addr", [(set SPR:$dst, (load addrmode5:$addr))]>; } // canFoldAsLoad -def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr), +def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr), IIC_fpStore64, "vstr", ".64\t$src, $addr", [(store (f64 DPR:$src), addrmode5:$addr)]>; -def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr), +def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr), IIC_fpStore32, "vstr", ".32\t$src, $addr", [(store SPR:$src, addrmode5:$addr)]>; diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 6935974455a..bc16fe04c38 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -49,9 +49,8 @@ public: /// operand requires relocation, record the relocation and return zero. unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO) const; - /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' - /// operand. - unsigned getAddrModeImm12OpValue(const MCInst &MI, unsigned Op) const; + /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. + uint32_t getAddrModeImmOpValue(const MCInst &MI, unsigned Op) const; /// getCCOutOpValue - Return encoding of the 's' bit. unsigned getCCOutOpValue(const MCInst &MI, unsigned Op) const { @@ -170,37 +169,38 @@ unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI, return 0; } -/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' -/// operand. -unsigned ARMMCCodeEmitter::getAddrModeImm12OpValue(const MCInst &MI, - unsigned OpIdx) const { - // {17-13} = reg - // {12} = (U)nsigned (add == '1', sub == '0') - // {11-0} = imm12 +/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. +uint32_t ARMMCCodeEmitter::getAddrModeImmOpValue(const MCInst &MI, + unsigned OpIdx) const { + // {20-17} = reg + // {16} = (U)nsigned (add == '1', sub == '0') + // {15-0} = imm const MCOperand &MO = MI.getOperand(OpIdx); const MCOperand &MO1 = MI.getOperand(OpIdx + 1); uint32_t Binary = 0; // If The first operand isn't a register, we have a label reference. if (!MO.isReg()) { - Binary |= ARM::PC << 13; // Rn is PC. + Binary |= ARM::PC << 17; // Rn is PC. // FIXME: Add a fixup referencing the label. return Binary; } unsigned Reg = getARMRegisterNumbering(MO.getReg()); - int32_t Imm12 = MO1.getImm(); - bool isAdd = Imm12 >= 0; + int32_t Imm = MO1.getImm(); + bool isAdd = Imm >= 0; + // Special value for #-0 - if (Imm12 == INT32_MIN) - Imm12 = 0; + if (Imm == INT32_MIN) + Imm = 0; + // Immediate is always encoded as positive. The 'U' bit controls add vs sub. - if (Imm12 < 0) - Imm12 = -Imm12; - Binary = Imm12 & 0xfff; + if (Imm < 0) Imm = -Imm; + + Binary = Imm & 0xffff; if (isAdd) - Binary |= (1 << 12); - Binary |= (Reg << 13); + Binary |= (1 << 16); + Binary |= (Reg << 17); return Binary; } @@ -320,7 +320,6 @@ unsigned ARMMCCodeEmitter::getAddrMode6OffsetOpValue(const MCInst &MI, return regno.getReg(); } - void ARMMCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups) const { diff --git a/test/MC/ARM/arm_instructions.s b/test/MC/ARM/arm_instructions.s index b82b36a0439..36636341e1e 100644 --- a/test/MC/ARM/arm_instructions.s +++ b/test/MC/ARM/arm_instructions.s @@ -10,13 +10,8 @@ @ CHECK: bx lr @ CHECK: encoding: [0x1e,0xff,0x2f,0xe1] -bx lr + bx lr @ CHECK: vqdmull.s32 q8, d17, d16 @ CHECK: encoding: [0xa0,0x0d,0xe1,0xf2] -vqdmull.s32 q8, d17, d16 - -@ CHECK: vldr.64 d17, [r0] -@ CHECK: encoding: [0x00,0x0b,0x10,0xed] -vldr.64 d17, [r0] - + vqdmull.s32 q8, d17, d16 diff --git a/test/MC/ARM/simple-fp-encoding.s b/test/MC/ARM/simple-fp-encoding.s index 614a497d53a..cd1ccac0f0a 100644 --- a/test/MC/ARM/simple-fp-encoding.s +++ b/test/MC/ARM/simple-fp-encoding.s @@ -157,3 +157,20 @@ @ CHECK: vmov r0, r1, d16 @ encoding: [0x30,0x0b,0x51,0xec] vmov r0, r1, d16 + +@ CHECK: vldr.64 d17, [r0] @ encoding: [0x00,0x1b,0xd0,0xed] + vldr.64 d17, [r0] + +@ CHECK: vldr.64 d1, [r2, #32] @ encoding: [0x08,0x1b,0x92,0xed] + vldr.64 d1, [r2, #32] + + +@ CHECK: vldr.64 d2, [r3] @ encoding: [0x00,0x2b,0x93,0xed] + vldr.64 d2, [r3] + +@ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed] +@ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed] +@ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed] + vldr.64 d3, [pc] + vldr.64 d3, [pc,#0] + vldr.64 d3, [pc,#-0] -- 2.34.1