[llvm-commits] CVS: llvm/lib/Target/ARM/ARMAsmPrinter.cpp ARMConstantPoolValue.cpp ARMConstantPoolValue.h ARMISelLowering.cpp ARMISelLowering.h ARMInstrInfo.td ARMInstrThumb.td

Evan Cheng evan.cheng at apple.com
Tue Jan 30 12:37:33 PST 2007



Changes in directory llvm/lib/Target/ARM:

ARMAsmPrinter.cpp updated: 1.54 -> 1.55
ARMConstantPoolValue.cpp updated: 1.1 -> 1.2
ARMConstantPoolValue.h updated: 1.1 -> 1.2
ARMISelLowering.cpp updated: 1.7 -> 1.8
ARMISelLowering.h updated: 1.1 -> 1.2
ARMInstrInfo.td updated: 1.86 -> 1.87
ARMInstrThumb.td updated: 1.9 -> 1.10
---
Log message:

- Fix codegen for pc relative constant (e.g. JT) in thumb mode:
        .set PCRELV0, (LJTI1_0_0-(LPCRELL0+4))
LPCRELL0:
        add r1, pc, #PCRELV0
This is not legal since add r1, pc, #c requires the constant be a multiple of 4.
Do the following instead:
        .set PCRELV0, (LJTI1_0_0-(LPCRELL0+4))
LPCRELL0:
        mov r1, #PCRELV0
        add r1, pc

- In thumb mode, it's not possible to use .set generate a pc relative stub
  address. The stub is ARM code which is in a different section from the thumb
  code. Load the value from a constpool instead.
- Some asm printing clean up.

---
Diffs of the changes:  (+96 -47)

 ARMAsmPrinter.cpp        |   28 ++++++++++++++++++++++------
 ARMConstantPoolValue.cpp |   30 +++++++++++++++++++++++-------
 ARMConstantPoolValue.h   |   21 ++++++++++++++++++---
 ARMISelLowering.cpp      |   36 ++++++++++++++++++++++++++----------
 ARMISelLowering.h        |    2 --
 ARMInstrInfo.td          |    5 ++---
 ARMInstrThumb.td         |   21 +++++----------------
 7 files changed, 96 insertions(+), 47 deletions(-)


Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp
diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.54 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.55
--- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.54	Tue Jan 30 14:08:37 2007
+++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp	Tue Jan 30 14:37:08 2007
@@ -122,10 +122,15 @@
 
       ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV;
       GlobalValue *GV = ACPV->getGV();
-      std::string Name = Mang->getValueName(GV);
+      std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
+      if (!GV)
+        Name += ACPV->getSymbol();
       if (ACPV->isNonLazyPointer()) {
         GVNonLazyPtrs.insert(Name);
         O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
+      } else if (ACPV->isStub()) {
+        FnStubs.insert(Name);
+        O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
       } else
         O << Name;
       if (ACPV->getPCAdjustment() != 0)
@@ -136,7 +141,7 @@
 
       // If the constant pool value is a extern weak symbol, remember to emit
       // the weak reference.
-      if (GV->hasExternalWeakLinkage())
+      if (GV && GV->hasExternalWeakLinkage())
         ExtWeakSymbols.insert(GV);
     }
     
@@ -680,18 +685,29 @@
 void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
 
-  if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY) {
+  int Opc = MI->getOpcode();
+  switch (Opc) {
+  case ARM::CONSTPOOL_ENTRY:
     if (!InCPMode && AFI->isThumbFunction()) {
       EmitAlignment(2);
       InCPMode = true;
     }
-  } else {
+    break;
+  default: {
     if (InCPMode && AFI->isThumbFunction()) {
       EmitAlignment(1);
       InCPMode = false;
     }
-    O << "\t";
-  }
+    switch (Opc) {
+    case ARM::PICADD:
+    case ARM::PICLD:
+    case ARM::tPICADD:
+      break;
+    default:
+      O << "\t";
+      break;
+    }
+  }}
 
   // Call the autogenerated instruction printer routines.
   printInstruction(MI);


Index: llvm/lib/Target/ARM/ARMConstantPoolValue.cpp
diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.1 llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.2
--- llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.1	Fri Jan 19 01:51:42 2007
+++ llvm/lib/Target/ARM/ARMConstantPoolValue.cpp	Tue Jan 30 14:37:08 2007
@@ -14,12 +14,20 @@
 #include "ARMConstantPoolValue.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/GlobalValue.h"
+#include "llvm/Type.h"
 using namespace llvm;
 
 ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id,
-                                         bool isNonLazy, unsigned char PCAdj)
+                                           ARMCP::ARMCPKind k,
+                                           unsigned char PCAdj)
   : MachineConstantPoolValue((const Type*)gv->getType()),
-    GV(gv), LabelId(id), isNonLazyPtr(isNonLazy), PCAdjust(PCAdj) {}
+    GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj) {}
+
+ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id,
+                                           ARMCP::ARMCPKind k,
+                                           unsigned char PCAdj)
+  : MachineConstantPoolValue((const Type*)Type::Int32Ty),
+    GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj) {}
 
 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
                                                     unsigned Alignment) {
@@ -30,8 +38,11 @@
         (Constants[i].Offset & AlignMask) == 0) {
       ARMConstantPoolValue *CPV =
         (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
-      if (CPV->GV == GV && CPV->LabelId == LabelId &&
-          CPV->isNonLazyPtr == isNonLazyPtr)
+      if (CPV->GV == GV &&
+          CPV->S == S &&
+          CPV->LabelId == LabelId &&
+          CPV->Kind == Kind &&
+          CPV->PCAdjust == PCAdjust)
         return i;
     }
   }
@@ -42,14 +53,19 @@
 void
 ARMConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) {
   ID.AddPointer(GV);
+  ID.AddPointer(S);
   ID.AddInteger(LabelId);
-  ID.AddInteger((unsigned)isNonLazyPtr);
+  ID.AddInteger((unsigned)Kind);
   ID.AddInteger(PCAdjust);
 }
 
 void ARMConstantPoolValue::print(std::ostream &O) const {
-  O << GV->getName();
-  if (isNonLazyPtr) O << "$non_lazy_ptr";
+  if (GV)
+    O << GV->getName();
+  else
+    O << S;
+  if (isNonLazyPointer()) O << "$non_lazy_ptr";
+  else if (isStub()) O << "$stub";
   if (PCAdjust != 0) O << "-(LPIC" << LabelId << "+"
                        << (unsigned)PCAdjust << ")";
 }


Index: llvm/lib/Target/ARM/ARMConstantPoolValue.h
diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.1 llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.2
--- llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.1	Fri Jan 19 01:51:42 2007
+++ llvm/lib/Target/ARM/ARMConstantPoolValue.h	Tue Jan 30 14:37:08 2007
@@ -18,23 +18,38 @@
 
 namespace llvm {
 
+namespace ARMCP {
+  enum ARMCPKind {
+    CPValue,
+    CPNonLazyPtr,
+    CPStub
+  };
+}
+
 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to
 /// represent PC relative displacement between the address of the load
 /// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)).
 class ARMConstantPoolValue : public MachineConstantPoolValue {
   GlobalValue *GV;         // GlobalValue being loaded.
+  const char *S;           // ExtSymbol being loaded.
   unsigned LabelId;        // Label id of the load.
-  bool isNonLazyPtr;       // True if loading a Mac OS X non_lazy_ptr stub.
+  ARMCP::ARMCPKind Kind;   // non_lazy_ptr or stub?
   unsigned char PCAdjust;  // Extra adjustment if constantpool is pc relative.
                            // 8 for ARM, 4 for Thumb.
 
 public:
-  ARMConstantPoolValue(GlobalValue *gv, unsigned id, bool isNonLazy = false,
+  ARMConstantPoolValue(GlobalValue *gv, unsigned id,
+                       ARMCP::ARMCPKind Kind = ARMCP::CPValue,
+                       unsigned char PCAdj = 0);
+  ARMConstantPoolValue(const char *s, unsigned id,
+                       ARMCP::ARMCPKind Kind = ARMCP::CPValue,
                        unsigned char PCAdj = 0);
 
   GlobalValue *getGV() const { return GV; }
+  const char *getSymbol() const { return S; }
   unsigned getLabelId() const { return LabelId; }
-  bool isNonLazyPointer() const { return isNonLazyPtr; }
+  bool isNonLazyPointer() const { return Kind == ARMCP::CPNonLazyPtr; }
+  bool isStub() const { return Kind == ARMCP::CPStub; }
   unsigned char getPCAdjustment() const { return PCAdjust; }
 
   virtual int getExistingMachineCPValue(MachineConstantPool *CP,


Index: llvm/lib/Target/ARM/ARMISelLowering.cpp
diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.7 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.8
--- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.7	Tue Jan 30 14:08:37 2007
+++ llvm/lib/Target/ARM/ARMISelLowering.cpp	Tue Jan 30 14:37:08 2007
@@ -230,7 +230,6 @@
   switch (Opcode) {
   default: return 0;
   case ARMISD::Wrapper:       return "ARMISD::Wrapper";
-  case ARMISD::WrapperCall:   return "ARMISD::WrapperCall";
   case ARMISD::WrapperJT:     return "ARMISD::WrapperJT";
   case ARMISD::CALL:          return "ARMISD::CALL";
   case ARMISD::CALL_NOLINK:   return "ARMISD::CALL_NOLINK";
@@ -465,25 +464,40 @@
   bool isARMFunc = false;
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
     GlobalValue *GV = G->getGlobal();
-    Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
     isDirect = true;
     bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
                   GV->hasLinkOnceLinkage());
     bool isStub = (isExt && Subtarget->isTargetDarwin()) &&
                    getTargetMachine().getRelocationModel() != Reloc::Static;
     isARMFunc = !Subtarget->isThumb() || isStub;
-    // Wrap it since tBX takes a register source operand.
-    if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps())
-      Callee = DAG.getNode(ARMISD::WrapperCall, MVT::i32, Callee);
+    // tBX takes a register source operand.
+    if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) {
+      ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex,
+                                                           ARMCP::CPStub, 4);
+      SDOperand CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 2);
+      CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr);
+      Callee = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), CPAddr, NULL, 0); 
+      SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+      Callee = DAG.getNode(ARMISD::PIC_ADD, getPointerTy(), Callee, PICLabel);
+   } else
+      Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
-    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
     isDirect = true;
     bool isStub = Subtarget->isTargetDarwin() &&
                   getTargetMachine().getRelocationModel() != Reloc::Static;
     isARMFunc = !Subtarget->isThumb() || isStub;
-    // Wrap it since tBX takes a register source operand.
-    if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps())
-      Callee = DAG.getNode(ARMISD::WrapperCall, MVT::i32, Callee);
+    // tBX takes a register source operand.
+    const char *Sym = S->getSymbol();
+    if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) {
+      ARMConstantPoolValue *CPV = new ARMConstantPoolValue(Sym, ARMPCLabelIndex,
+                                                           ARMCP::CPStub, 4);
+      SDOperand CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 2);
+      CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr);
+      Callee = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), CPAddr, NULL, 0); 
+      SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+      Callee = DAG.getNode(ARMISD::PIC_ADD, getPointerTy(), Callee, PICLabel);
+    } else
+      Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy());
   }
 
   std::vector<MVT::ValueType> NodeTys;
@@ -647,8 +661,10 @@
   else {
     unsigned PCAdj = (RelocM != Reloc::PIC_)
       ? 0 : (Subtarget->isThumb() ? 4 : 8);
+    ARMCP::ARMCPKind Kind = IsIndirect ? ARMCP::CPNonLazyPtr
+      : ARMCP::CPValue;
     ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex,
-                                                         IsIndirect, PCAdj);
+                                                         Kind, PCAdj);
     CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 2);
   }
   CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr);


Index: llvm/lib/Target/ARM/ARMISelLowering.h
diff -u llvm/lib/Target/ARM/ARMISelLowering.h:1.1 llvm/lib/Target/ARM/ARMISelLowering.h:1.2
--- llvm/lib/Target/ARM/ARMISelLowering.h:1.1	Fri Jan 19 01:51:42 2007
+++ llvm/lib/Target/ARM/ARMISelLowering.h	Tue Jan 30 14:37:08 2007
@@ -31,8 +31,6 @@
 
       Wrapper,      // Wrapper - A wrapper node for TargetConstantPool,
                     // TargetExternalSymbol, and TargetGlobalAddress.
-      WrapperCall,  // WrapperCall - Same as wrapper, but mark the wrapped
-                    // node as call operand.
       WrapperJT,    // WrapperJT - A wrapper node for TargetJumpTable
       
       CALL,         // Function call.


Index: llvm/lib/Target/ARM/ARMInstrInfo.td
diff -u llvm/lib/Target/ARM/ARMInstrInfo.td:1.86 llvm/lib/Target/ARM/ARMInstrInfo.td:1.87
--- llvm/lib/Target/ARM/ARMInstrInfo.td:1.86	Fri Jan 26 08:34:51 2007
+++ llvm/lib/Target/ARM/ARMInstrInfo.td	Tue Jan 30 14:37:08 2007
@@ -41,7 +41,6 @@
 
 // Node definitions.
 def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
-def ARMWrapperCall   : SDNode<"ARMISD::WrapperCall", SDTIntUnaryOp>;
 def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
 
 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeq,
@@ -514,11 +513,11 @@
            [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
 
 def PICADD : AI1<(ops GPR:$dst, GPR:$a, pclabel:$cp),
-                  "\n$cp:\n\tadd $dst, pc, $a",
+                  "$cp:\n\tadd $dst, pc, $a",
                   [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
 let AddedComplexity = 10 in
 def PICLD : AI2<(ops GPR:$dst, addrmodepc:$addr),
-                  "\n${addr:label}:\n\tldr $dst, $addr",
+                  "${addr:label}:\n\tldr $dst, $addr",
                   [(set GPR:$dst, (load addrmodepc:$addr))]>;
 
 //===----------------------------------------------------------------------===//


Index: llvm/lib/Target/ARM/ARMInstrThumb.td
diff -u llvm/lib/Target/ARM/ARMInstrThumb.td:1.9 llvm/lib/Target/ARM/ARMInstrThumb.td:1.10
--- llvm/lib/Target/ARM/ARMInstrThumb.td:1.9	Mon Jan 29 20:35:32 2007
+++ llvm/lib/Target/ARM/ARMInstrThumb.td	Tue Jan 30 14:37:08 2007
@@ -158,7 +158,7 @@
 //
 
 def tPICADD : TIt<(ops GPR:$dst, GPR:$lhs, pclabel:$cp),
-                  "\n$cp:\n\tadd $dst, pc",
+                  "$cp:\n\tadd $dst, pc",
                   [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>;
 
 //===----------------------------------------------------------------------===//
@@ -475,25 +475,18 @@
 
 // tLEApcrel - Load a pc-relative address into a register without offending the
 // assembler.
-def tLEApcrel : TI<(ops GPR:$dst, i32imm:$label),
+def tLEApcrel : TIx2<(ops GPR:$dst, i32imm:$label),
                     !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
                                           "${:private}PCRELL${:uid}+4))\n"),
                                !strconcat("${:private}PCRELL${:uid}:\n\t",
-                                          "add $dst, pc, #PCRELV${:uid}")),
+                                   "mov $dst, #PCRELV${:uid}\n\tadd $dst, pc")),
                     []>;
 
-def tLEApcrelCall : TI<(ops GPR:$dst, i32imm:$label),
-                   !strconcat(!strconcat(".set PCRELV${:uid}, (${label:call}-(",
-                                         "${:private}PCRELL${:uid}+4))\n"),
-                              !strconcat("${:private}PCRELL${:uid}:\n\t",
-                                         "add $dst, pc, #PCRELV${:uid}")),
-                   []>;
-
-def tLEApcrelJT : TI<(ops GPR:$dst, i32imm:$label, i32imm:$id),
+def tLEApcrelJT : TIx2<(ops GPR:$dst, i32imm:$label, i32imm:$id),
           !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
                                          "${:private}PCRELL${:uid}+4))\n"),
                               !strconcat("${:private}PCRELL${:uid}:\n\t",
-                                         "add $dst, pc, #PCRELV${:uid}")),
+                                   "mov $dst, #PCRELV${:uid}\n\tadd $dst, pc")),
                    []>;
 
 //===----------------------------------------------------------------------===//
@@ -503,10 +496,6 @@
 // ConstantPool, GlobalAddress
 def : ThumbPat<(ARMWrapper  tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
 def : ThumbPat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
-def : ThumbPat<(ARMWrapperCall tglobaladdr :$dst),
-               (tLEApcrelCall  tglobaladdr :$dst)>;
-def : ThumbPat<(ARMWrapperCall texternalsym:$dst),
-               (tLEApcrelCall  texternalsym:$dst)>;
 
 // JumpTable
 def : ThumbPat<(ARMWrapperJT tjumptable:$dst, imm:$id),






More information about the llvm-commits mailing list