[llvm-commits] [llvm] r121721 - in /llvm/trunk: lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMConstantIslandPass.cpp lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMFixupKinds.h lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/ARMMCCodeEmitter.cpp utils/TableGen/EDEmitter.cpp

Jim Grosbach grosbach at apple.com
Mon Dec 13 15:19:53 PST 2010


Hi Owen,

I don't think you're going to be able to expand these pseudos that early. Note that the label is formed differently in the asm string for LEApcrel and LEApcrelJT. That currently ends up "working" through some egregious luck at MC time even though the symbols are wrong. Better is to keep them as pseudos until MC lowering as part of ARMAsmPrinter, where the symbol can be created and properly (see the ARM versions of these insns for reference, and possibly re-use w/ some opcode tweaking).

-Jim

On Dec 13, 2010, at 2:29 PM, Owen Anderson wrote:

> Author: resistor
> Date: Mon Dec 13 16:29:52 2010
> New Revision: 121721
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=121721&view=rev
> Log:
> Make Thumb2 LEA-like instruction into pseudos, which map down to ADR.  Provide correct fixups for Thumb2 ADR,
> which is _of course_ different from ARM ADR fixups, or any other Thumb2 fixup.
> 
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
>    llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
>    llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
>    llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
>    llvm/trunk/lib/Target/ARM/ARMFixupKinds.h
>    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
>    llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
>    llvm/trunk/utils/TableGen/EDEmitter.cpp
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 16:29:52 2010
> @@ -136,6 +136,25 @@
>     // Encode the immediate and shift the opcode into place.
>     return ARM_AM::getSOImmVal(Value) | (opc << 21);
>   }
> +  
> +  case ARM::fixup_t2_adr_pcrel_12: {
> +    Value -= 4;
> +    unsigned opc = 0;
> +    if ((int64_t)Value < 0) {
> +      Value = -Value;
> +      opc = 5;
> +    }
> +
> +    uint32_t out = (opc << 21);
> +    out |= (Value & 0x800) << 14;
> +    out |= (Value & 0x700) << 4;
> +    out |= (Value & 0x0FF);
> +    
> +    uint64_t swapped = (out & 0xFFFF0000) >> 16;
> +    swapped |= (out & 0x0000FFFF) << 16;
> +    return swapped;
> +  }
> +  
>   case ARM::fixup_arm_branch:
>     // These values don't encode the low two bits since they're always zero.
>     // Offset by 8 just as above.
> @@ -356,6 +375,7 @@
>   case ARM::fixup_t2_condbranch:
>   case ARM::fixup_t2_uncondbranch:
>   case ARM::fixup_t2_pcrel_10:
> +  case ARM::fixup_t2_adr_pcrel_12:
>   case ARM::fixup_arm_thumb_bl:
>   case ARM::fixup_arm_thumb_blx:
>     return 4;
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Dec 13 16:29:52 2010
> @@ -213,6 +213,8 @@
>       const { return 0; }
>     unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op)
>       const { return 0; }
> +    unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op)
> +      const { return 0; }
>     unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op)
>       const { return 0; }
>     unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op)
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 13 16:29:52 2010
> @@ -594,7 +594,7 @@
>             NegOk = true;
>             IsSoImm = true;
>             break;
> -          case ARM::t2LEApcrel:
> +          case ARM::t2ADR:
>             Bits = 12;
>             NegOk = true;
>             break;
> @@ -1555,7 +1555,7 @@
>     unsigned Bits = 0;
>     switch (Opcode) {
>     default: break;
> -    case ARM::t2LEApcrel:
> +    case ARM::t2ADR:
>       if (isARMLowRegister(U.MI->getOperand(0).getReg())) {
>         NewOpc = ARM::tLEApcrel;
>         Bits = 8;
> @@ -1754,16 +1754,16 @@
>       if (!OptOk)
>         continue;
> 
> -      // Now scan back again to find the tLEApcrel or t2LEApcrelJT instruction
> +      // Now scan back again to find the tLEApcrel or t2ADR instruction
>       // that gave us the initial base register definition.
>       for (--PrevI; PrevI != B && !PrevI->definesRegister(BaseReg); --PrevI)
>         ;
> 
> -      // The instruction should be a tLEApcrel or t2LEApcrelJT; we want
> +      // The instruction should be a tLEApcrel or t2ADR; we want
>       // to delete it as well.
>       MachineInstr *LeaMI = PrevI;
>       if ((LeaMI->getOpcode() != ARM::tLEApcrelJT &&
> -           LeaMI->getOpcode() != ARM::t2LEApcrelJT) ||
> +           LeaMI->getOpcode() != ARM::t2ADR) ||
>           LeaMI->getOperand(0).getReg() != BaseReg)
>         OptOk = false;
> 
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon Dec 13 16:29:52 2010
> @@ -763,6 +763,21 @@
>       break;
>     }
> 
> +    case ARM::t2LEApcrel:
> +    case ARM::t2LEApcrelJT: {
> +      bool DstIsDead = MI.getOperand(0).isDead();
> +      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
> +                                TII->get(ARM::t2ADR))
> +        .addReg(MI.getOperand(0).getReg(),
> +                RegState::Define | getDeadRegState(DstIsDead)) // Dst reg
> +        .addOperand(MI.getOperand(1))      // Label
> +        .addOperand(MI.getOperand(2))      // Pred
> +        .addOperand(MI.getOperand(3));
> +      TransferImpOps(MI, MIB, MIB);
> +      MI.eraseFromParent();
> +      return MIB;
> +    }
> +
>     case ARM::MOVi32imm:
>     case ARM::MOVCCi32imm:
>     case ARM::t2MOVi32imm:
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h Mon Dec 13 16:29:52 2010
> @@ -33,6 +33,9 @@
>   // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
>   // instruction.
>   fixup_arm_adr_pcrel_12,
> +  // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR
> +  // instruction.
> +  fixup_t2_adr_pcrel_12,
>   // fixup_arm_branch - 24-bit PC relative relocation for direct branch
>   // instructions.
>   fixup_arm_branch,
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Dec 13 16:29:52 2010
> @@ -131,6 +131,12 @@
>   let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
> }
> 
> +// ADR instruction labels.
> +def t2adrlabel : Operand<i32> {
> +  let EncoderMethod = "getT2AdrLabelOpValue";
> +}
> +
> +
> // t2addrmode_imm8  := reg +/- imm8
> def t2addrmode_imm8 : Operand<i32>,
>                       ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
> @@ -1128,10 +1134,11 @@
> 
> // LEApcrel - Load a pc-relative address into a register without offending the
> // assembler.
> -let neverHasSideEffects = 1 in {
> -let isReMaterializable = 1 in
> -def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi,
> -                      "adr${p}.w\t$Rd, #$label", []> {
> +let neverHasSideEffects = 1, isReMaterializable = 1 in {
> +
> +def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd),
> +              (ins t2adrlabel:$addr, pred:$p),
> +              IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> {
>   let Inst{31-27} = 0b11110;
>   let Inst{25-24} = 0b10;
>   // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
> @@ -1139,20 +1146,22 @@
>   let Inst{20} = 0;
>   let Inst{19-16} = 0b1111; // Rn
>   let Inst{15} = 0;
> -
> -
> +  
> +  bits<4> Rd;
> +  bits<13> addr;
> +  let Inst{11-8} = Rd;
> +  let Inst{23}    = addr{12};
> +  let Inst{21}    = addr{12};
> +  let Inst{26}    = addr{11};
> +  let Inst{14-12} = addr{10-8};
> +  let Inst{7-0}   = addr{7-0};
> }
> -} // neverHasSideEffects
> -def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd),
> +
> +def t2LEApcrel : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p),
> +                            IIC_iALUi, []>;
> +def t2LEApcrelJT : PseudoInst<(outs rGPR:$Rd),
>                         (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
> -                        "adr${p}.w\t$Rd, #${label}_${id}", []> {
> -  let Inst{31-27} = 0b11110;
> -  let Inst{25-24} = 0b10;
> -  // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE)
> -  let Inst{22} = 0;
> -  let Inst{20} = 0;
> -  let Inst{19-16} = 0b1111; // Rn
> -  let Inst{15} = 0;
> +                        []>;
> }
> 
> 
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Mon Dec 13 16:29:52 2010
> @@ -56,6 +56,8 @@
> { "fixup_t2_pcrel_10",       0,            32,  MCFixupKindInfo::FKF_IsPCRel |
>                                                 MCFixupKindInfo::FKF_IsAligned},
> { "fixup_arm_adr_pcrel_12",  1,            24,  MCFixupKindInfo::FKF_IsPCRel },
> +{ "fixup_t2_adr_pcrel_12",   0,            32,  MCFixupKindInfo::FKF_IsPCRel |
> +                                                MCFixupKindInfo::FKF_IsAligned},
> { "fixup_arm_branch",        1,            24,  MCFixupKindInfo::FKF_IsPCRel },
> { "fixup_t2_condbranch",     0,            32,  MCFixupKindInfo::FKF_IsPCRel },
> { "fixup_t2_uncondbranch",   0,            32,  MCFixupKindInfo::FKF_IsPCRel },
> @@ -133,6 +135,9 @@
>   /// ADR label target.
>   uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
>                               SmallVectorImpl<MCFixup> &Fixups) const;
> +  uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> +                              SmallVectorImpl<MCFixup> &Fixups) const;
> +  
> 
>   /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
>   /// operand.
> @@ -544,6 +549,16 @@
>                                   Fixups);
> }
> 
> +/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
> +/// target.
> +uint32_t ARMMCCodeEmitter::
> +getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> +                   SmallVectorImpl<MCFixup> &Fixups) const {
> +  assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
> +  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
> +                                  Fixups);
> +}
> +
> /// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand.
> uint32_t ARMMCCodeEmitter::
> getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
> 
> Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/EDEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/EDEmitter.cpp Mon Dec 13 16:29:52 2010
> @@ -584,6 +584,7 @@
>   IMM("t_imm_s4");
>   IMM("pclabel");
>   IMM("adrlabel");
> +  IMM("t2adrlabel");
>   IMM("shift_imm");
>   IMM("neon_vcvt_imm32");
> 
> 
> 
> _______________________________________________
> 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