[llvm-commits] [llvm] r118094 - in /llvm/trunk: lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrVFP.td lib/Target/ARM/ARMMCCodeEmitter.cpp test/MC/ARM/arm_instructions.s test/MC/ARM/simple-fp-encoding.s

Bill Wendling isanbard at gmail.com
Tue Nov 2 18:41:51 PDT 2010


Thanks. :-)

I ran into another problem^Wfeature where address mode 5 negative offsets weren't being handled correctly with the MC stuff. So I ended up having to refactor this code and use the ARM_AM addressing mode functions to get it to work properly. So it will go back to the same encoding, but the main way register and immediate information is retrieved is the same. :)

-bw

On Nov 2, 2010, at 6:26 PM, Jim Grosbach wrote:

> Hey Bill,
> 
> Hmmm.... So you're looking to reuse the encoder method for other complex operands that need the same basic information (register/offset pair)? That makes a lot more sense and I don't see any reason why that's a bad thing (quite the opposite). Where we need to be careful is in re-using the operand definitions themselves, as those have the matchers, printers, and such that will be different. Sounds like we're on the same page there and I was just a bit confused.
> 
> Thanks!
> 
> -Jim
> 
> On Nov 2, 2010, at 4:02 PM, Bill Wendling wrote:
> 
>> Hi Jim,
>> 
>> I might not have explained my change very well. I wanted to convert the getAddrModeImm12OpValue into a generic function that gets the register and address information, and encodes that into an i32 to be used by the MC encoding stuff. The immediate isn't necessarily 16-bits in size (though it can be). In fact, for the VLDR stuff it's expecting an 8-bit immediate.
>> 
>> The reason why I didn't create a getAddrModeImm8OpValue method was because it had the exact same code as getAddrModeImm12OpValue, just that the offsets of the values were different (the U bit was at {8} instead of {12}, etc.). :-)
>> 
>> I'll be happy to rework this and create an imm8-specific method if that's desirable. It would be easy to refactor the original code to do that.
>> 
>> -bw
>> 
>> On Nov 2, 2010, at 3:51 PM, Jim Grosbach wrote:
>> 
>>> Hi Bill,
>>> 
>>> We should add a new addrmode_i16 for this rather than re-using the current one. How many bits are legal is part of the semantics, and is enforced by the selection dag stuff  (SelectAddrModeImm12() in this case).  For a parallel example, see the Thumb2 t2addrmode_imm12 and t2addrmode_imm8 modes in ARMInstrThumb2.td.
>>> 
>>> -Jim
>>> 
>>> On Nov 2, 2010, at 3:31 PM, Bill Wendling wrote:
>>> 
>>>> Author: void
>>>> Date: Tue Nov  2 17:31:46 2010
>>>> New Revision: 118094
>>>> 
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=118094&view=rev
>>>> Log:
>>>> 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.
>>>> 
>>>> Modified:
>>>> llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
>>>> llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
>>>> llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
>>>> llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
>>>> llvm/trunk/test/MC/ARM/arm_instructions.s
>>>> llvm/trunk/test/MC/ARM/simple-fp-encoding.s
>>>> 
>>>> Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=118094&r1=118093&r2=118094&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
>>>> +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Nov  2 17:31:46 2010
>>>> @@ -177,26 +177,27 @@
>>>>    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; }
>>>> 
>>>> 
>>>> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=118094&r1=118093&r2=118094&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
>>>> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Nov  2 17:31:46 2010
>>>> @@ -398,7 +398,7 @@
>>>> // #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 @@
>>>> let PrintMethod = "printAddrMode5Operand";
>>>> let MIOperandInfo = (ops GPR:$base, i32imm);
>>>> let ParserMatchClass = ARMMemMode5AsmOperand;
>>>> +  string EncoderMethod = "getAddrModeImmOpValue";
>>>> }
>>>> 
>>>> // addrmode6 := reg with optional writeback
>>>> @@ -830,9 +831,9 @@
>>>>                 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
>>>>                [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
>>>>  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 @@
>>>>                AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
>>>>               [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
>>>>  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};
>>>> }
>>>> }
>>>> 
>>>> Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=118094&r1=118093&r2=118094&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original)
>>>> +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Nov  2 17:31:46 2010
>>>> @@ -53,18 +53,29 @@
>>>> 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)]>;
>>>> 
>>>> 
>>>> Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=118094&r1=118093&r2=118094&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
>>>> +++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Tue Nov  2 17:31:46 2010
>>>> @@ -49,9 +49,8 @@
>>>> /// 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 @@
>>>> 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 @@
>>>> return regno.getReg();
>>>> }
>>>> 
>>>> -
>>>> void ARMMCCodeEmitter::
>>>> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>>>>                SmallVectorImpl<MCFixup> &Fixups) const {
>>>> 
>>>> Modified: llvm/trunk/test/MC/ARM/arm_instructions.s
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_instructions.s?rev=118094&r1=118093&r2=118094&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/test/MC/ARM/arm_instructions.s (original)
>>>> +++ llvm/trunk/test/MC/ARM/arm_instructions.s Tue Nov  2 17:31:46 2010
>>>> @@ -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
>>>> 
>>>> Modified: llvm/trunk/test/MC/ARM/simple-fp-encoding.s
>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/simple-fp-encoding.s?rev=118094&r1=118093&r2=118094&view=diff
>>>> ==============================================================================
>>>> --- llvm/trunk/test/MC/ARM/simple-fp-encoding.s (original)
>>>> +++ llvm/trunk/test/MC/ARM/simple-fp-encoding.s Tue Nov  2 17:31:46 2010
>>>> @@ -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]
>>>> 
>>>> 
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>> 
>> 
> 





More information about the llvm-commits mailing list