[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