[llvm-commits] [llvm] r124895 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp lib/MC/MachObjectWriter.cpp lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMFixupKinds.h lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMMCCodeEmitter.cpp test/MC/ARM/arm_fixups.s utils/TableGen/EDEmitter.cpp

Jason W Kim jason.w.kim.2009 at gmail.com
Fri Feb 4 11:47:15 PST 2011


Author: jasonwkim
Date: Fri Feb  4 13:47:15 2011
New Revision: 124895

URL: http://llvm.org/viewvc/llvm-project?rev=124895&view=rev
Log:

Teach ARM/MC/ELF to handle R_ARM_JUMP24 relocation type for conditional jumps.
(yes, this is different from R_ARM_CALL)

- Adds a new method getARMBranchTargetOpValue() which handles the
  necessary distinction between the conditional and unconditional br/bl
  needed for ARM/ELF

At least for ARM mode, the needed fixup for conditional versus unconditional
br/bl is identical, but the ARM docs and existing ARM tools expect this
reloc type...

Added a few FIXME's for future naming fixups in ARMInstrInfo.td



Modified:
    llvm/trunk/lib/MC/ELFObjectWriter.cpp
    llvm/trunk/lib/MC/MachObjectWriter.cpp
    llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
    llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
    llvm/trunk/lib/Target/ARM/ARMFixupKinds.h
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
    llvm/trunk/test/MC/ARM/arm_fixups.s
    llvm/trunk/utils/TableGen/EDEmitter.cpp

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Fri Feb  4 13:47:15 2011
@@ -1503,7 +1503,7 @@
         break;
       }
       break;
-    case ARM::fixup_arm_branch:
+    case ARM::fixup_arm_uncondbranch:
       switch (Modifier) {
       case MCSymbolRefExpr::VK_ARM_PLT:
         Type = ELF::R_ARM_PLT32;
@@ -1513,6 +1513,9 @@
         break;
       }
       break;
+    case ARM::fixup_arm_condbranch:
+      Type = ELF::R_ARM_JUMP24;
+      break;
     case ARM::fixup_arm_movt_hi16:
     case ARM::fixup_arm_movt_hi16_pcrel:
       Type = ELF::R_ARM_MOVT_PREL;
@@ -1565,11 +1568,12 @@
     case ARM::fixup_arm_thumb_br:
       assert(0 && "Unimplemented");
       break;
-    case ARM::fixup_arm_branch:
-      // FIXME: Differentiate between R_ARM_CALL and
-      // R_ARM_JUMP24 (latter used for conditional jumps)
+    case ARM::fixup_arm_uncondbranch:
       Type = ELF::R_ARM_CALL;
       break;
+    case ARM::fixup_arm_condbranch:
+      Type = ELF::R_ARM_JUMP24;
+      break;
     case ARM::fixup_arm_movt_hi16:
       Type = ELF::R_ARM_MOVT_ABS;
       break;

Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MachObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/MachObjectWriter.cpp Fri Feb  4 13:47:15 2011
@@ -940,7 +940,8 @@
     case ARM::fixup_arm_ldst_pcrel_12:
     case ARM::fixup_arm_pcrel_10:
     case ARM::fixup_arm_adr_pcrel_12:
-    case ARM::fixup_arm_branch:
+    case ARM::fixup_arm_condbranch:
+    case ARM::fixup_arm_uncondbranch:
       RelocType = unsigned(macho::RIT_ARM_Branch24Bit);
       // Report as 'long', even though that is not quite accurate.
       Log2Size = llvm::Log2_32(4);

Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Fri Feb  4 13:47:15 2011
@@ -67,7 +67,8 @@
 { "fixup_arm_adr_pcrel_12",  1,            24,  MCFixupKindInfo::FKF_IsPCRel },
 { "fixup_t2_adr_pcrel_12",   0,            32,  MCFixupKindInfo::FKF_IsPCRel |
                                    MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
-{ "fixup_arm_branch",        0,            24,  MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_condbranch",    0,            24,  MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_uncondbranch",  0,            24,  MCFixupKindInfo::FKF_IsPCRel },
 { "fixup_t2_condbranch",     0,            32,  MCFixupKindInfo::FKF_IsPCRel },
 { "fixup_t2_uncondbranch",   0,            32,  MCFixupKindInfo::FKF_IsPCRel },
 { "fixup_arm_thumb_br",      0,            16,  MCFixupKindInfo::FKF_IsPCRel },
@@ -254,7 +255,8 @@
     return swapped;
   }
 
-  case ARM::fixup_arm_branch:
+  case ARM::fixup_arm_condbranch:
+  case ARM::fixup_arm_uncondbranch:
     // These values don't encode the low two bits since they're always zero.
     // Offset by 8 just as above.
     return 0xffffff & ((Value - 8) >> 2);
@@ -454,7 +456,8 @@
   case ARM::fixup_arm_ldst_pcrel_12:
   case ARM::fixup_arm_pcrel_10:
   case ARM::fixup_arm_adr_pcrel_12:
-  case ARM::fixup_arm_branch:
+  case ARM::fixup_arm_condbranch:
+  case ARM::fixup_arm_uncondbranch:
     return 3;
 
   case FK_Data_4:

Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Fri Feb  4 13:47:15 2011
@@ -187,6 +187,8 @@
       const { return 0; }
     unsigned getUnconditionalBranchTargetOpValue(const MachineInstr &MI,
       unsigned Op) const { return 0; }
+    unsigned getARMBranchTargetOpValue(const MachineInstr &MI, unsigned Op)
+      const { return 0; }
     unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op)
       const { return 0; }
     unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op)

Modified: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h Fri Feb  4 13:47:15 2011
@@ -40,9 +40,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,
+  // fixup_arm_condbranch - 24-bit PC relative relocation for conditional branch
+  // instructions. 
+  fixup_arm_condbranch,
+  // fixup_arm_uncondbranch - 24-bit PC relative relocation for 
+  // branch instructions. (unconditional)
+  fixup_arm_uncondbranch,
   // fixup_t2_condbranch - 20-bit PC relative relocation for Thumb2 direct
   // uconditional branch instructions.
   fixup_t2_condbranch,

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Feb  4 13:47:15 2011
@@ -293,20 +293,36 @@
 //
 
 // Branch target.
+// FIXME: rename brtarget to t2_brtarget
 def brtarget : Operand<OtherVT> {
   let EncoderMethod = "getBranchTargetOpValue";
 }
 
+// FIXME: get rid of this one?
 def uncondbrtarget : Operand<OtherVT> {
   let EncoderMethod = "getUnconditionalBranchTargetOpValue";
 }
 
+// Branch target for ARM. Handles conditional/unconditional
+def br_target : Operand<OtherVT> {
+  let EncoderMethod = "getARMBranchTargetOpValue";
+}
+
 // Call target.
+// FIXME: rename bltarget to t2_bl_target?
 def bltarget : Operand<i32> {
   // Encoded the same as branch targets.
   let EncoderMethod = "getBranchTargetOpValue";
 }
 
+// Call target for ARM. Handles conditional/unconditional
+// FIXME: rename bl_target to t2_bltarget?
+def bl_target : Operand<i32> {
+  // Encoded the same as branch targets.
+  let EncoderMethod = "getARMBranchTargetOpValue";
+}
+
+
 // A list of registers separated by comma. Used by load/store multiple.
 def RegListAsmOperand : AsmOperandClass {
   let Name = "RegList";
@@ -1271,7 +1287,7 @@
           D16, D17, D18, D19, D20, D21, D22, D23,
           D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR],
   Uses = [SP] in {
-  def BL  : ABXI<0b1011, (outs), (ins bltarget:$func, variable_ops),
+  def BL  : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops),
                 IIC_Br, "bl\t$func",
                 [(ARMcall tglobaladdr:$func)]>,
             Requires<[IsARM, IsNotDarwin]> {
@@ -1280,7 +1296,7 @@
     let Inst{23-0} = func;
   }
 
-  def BL_pred : ABI<0b1011, (outs), (ins bltarget:$func, variable_ops),
+  def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops),
                    IIC_Br, "bl", "\t$func",
                    [(ARMcall_pred tglobaladdr:$func)]>,
                 Requires<[IsARM, IsNotDarwin]> {
@@ -1456,7 +1472,7 @@
 
   // FIXME: should be able to write a pattern for ARMBrcond, but can't use
   // a two-value operand where a dag node expects two operands. :(
-  def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
+  def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
                IIC_Br, "b", "\t$target",
                [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
     bits<24> target;

Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Fri Feb  4 13:47:15 2011
@@ -99,6 +99,10 @@
   uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
                                   SmallVectorImpl<MCFixup> &Fixups) const;
   
+  /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
+  /// branch target.
+  uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
+                                     SmallVectorImpl<MCFixup> &Fixups) const;
 
   /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
   /// ADR label target.
@@ -473,6 +477,23 @@
   return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups);
 }
 
+/// Return true if this branch has a non-always predication
+static bool HasConditionalBranch(const MCInst &MI) {
+  int NumOp = MI.getNumOperands();
+  if (NumOp >= 2) {
+    for (int i = 0; i < NumOp-1; ++i) {
+      const MCOperand &MCOp1 = MI.getOperand(i);
+      const MCOperand &MCOp2 = MI.getOperand(i + 1);
+      if (MCOp1.isImm() && MCOp2.isReg() && 
+          (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
+        if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) 
+          return true;
+      }
+    }
+  }
+  return false;
+}
+
 /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
 /// target.
 uint32_t ARMMCCodeEmitter::
@@ -483,9 +504,24 @@
   if (Subtarget->isThumb2())
     return
       ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
-  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_branch, Fixups);
+  return getARMBranchTargetOpValue(MI, OpIdx, Fixups);
+}
+
+/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
+/// target.
+uint32_t ARMMCCodeEmitter::
+getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
+                          SmallVectorImpl<MCFixup> &Fixups) const {
+  if (HasConditionalBranch(MI)) 
+    return ::getBranchTargetOpValue(MI, OpIdx,
+                                    ARM::fixup_arm_condbranch, Fixups);
+  return ::getBranchTargetOpValue(MI, OpIdx, 
+                                  ARM::fixup_arm_uncondbranch, Fixups);
 }
 
+
+
+
 /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
 /// immediate branch target.
 uint32_t ARMMCCodeEmitter::

Modified: llvm/trunk/test/MC/ARM/arm_fixups.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_fixups.s?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/arm_fixups.s (original)
+++ llvm/trunk/test/MC/ARM/arm_fixups.s Fri Feb  4 13:47:15 2011
@@ -2,6 +2,6 @@
 // RUN: FileCheck < %t %s
 
 // CHECK: bl _printf @ encoding: [A,A,A,0xeb]
-// CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_branch
+// CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbranch
 bl _printf
         
\ No newline at end of file

Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=124895&r1=124894&r2=124895&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/EDEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/EDEmitter.cpp Fri Feb  4 13:47:15 2011
@@ -325,6 +325,9 @@
   PCR("uncondbrtarget");
   PCR("bltarget");
 
+  // all I, ARM mode only, conditional/unconditional
+  PCR("br_target");
+  PCR("bl_target");
   return 1;
 }
 
@@ -600,6 +603,10 @@
   MISC("t_bcctarget", "kOperandTypeARMBranchTarget");             // ?
   MISC("t_cbtarget", "kOperandTypeARMBranchTarget");              // ?
   MISC("bltarget", "kOperandTypeARMBranchTarget");                // ?
+
+  MISC("br_target", "kOperandTypeARMBranchTarget");                // ?
+  MISC("bl_target", "kOperandTypeARMBranchTarget");                // ?
+
   MISC("t_bltarget", "kOperandTypeARMBranchTarget");              // ?
   MISC("t_blxtarget", "kOperandTypeARMBranchTarget");             // ?
   MISC("so_reg", "kOperandTypeARMSoReg");                         // R, R, I





More information about the llvm-commits mailing list