Add a new MachineJumpTableInfo entry type, EK_GPRel64BlockAddress, which is

needed to emit a 64-bit gp-relative relocation entry. Make changes necessary
for emitting jump tables which have entries with directive .gpdword. This patch
does not implement the parts needed for direct object emission or JIT.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149668 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka
2012-02-03 04:33:00 +00:00
parent aab2191109
commit 6c2cf8b1fb
14 changed files with 85 additions and 5 deletions

View File

@ -48,6 +48,11 @@ public:
/// .word LBB123 /// .word LBB123
EK_BlockAddress, EK_BlockAddress,
/// EK_GPRel64BlockAddress - Each entry is an address of block, encoded
/// with a relocation as gp-relative, e.g.:
/// .gpdword LBB123
EK_GPRel64BlockAddress,
/// EK_GPRel32BlockAddress - Each entry is an address of block, encoded /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded
/// with a relocation as gp-relative, e.g.: /// with a relocation as gp-relative, e.g.:
/// .gprel32 LBB123 /// .gprel32 LBB123

View File

@ -180,6 +180,11 @@ namespace llvm {
const char *JT32Begin; // Defaults to "$a." const char *JT32Begin; // Defaults to "$a."
bool SupportsDataRegions; bool SupportsDataRegions;
/// GPRel64Directive - if non-null, a directive that is used to emit a word
/// which should be relocated as a 64-bit GP-relative offset, e.g. .gpdword
/// on Mips.
const char *GPRel64Directive; // Defaults to NULL.
/// GPRel32Directive - if non-null, a directive that is used to emit a word /// GPRel32Directive - if non-null, a directive that is used to emit a word
/// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword
/// on Mips or .gprel32 on Alpha. /// on Mips or .gprel32 on Alpha.
@ -376,6 +381,7 @@ namespace llvm {
const char *getData64bitsDirective(unsigned AS = 0) const { const char *getData64bitsDirective(unsigned AS = 0) const {
return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS); return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
} }
const char *getGPRel64Directive() const { return GPRel64Directive; }
const char *getGPRel32Directive() const { return GPRel32Directive; } const char *getGPRel32Directive() const { return GPRel32Directive; }
/// [Code|Data]Begin label name accessors. /// [Code|Data]Begin label name accessors.

View File

@ -441,6 +441,13 @@ namespace llvm {
void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
unsigned AddrSpace = 0); unsigned AddrSpace = 0);
/// EmitGPRel64Value - Emit the expression @p Value into the output as a
/// gprel64 (64-bit GP relative) value.
///
/// This is used to implement assembler directives such as .gpdword on
/// targets that support them.
virtual void EmitGPRel64Value(const MCExpr *Value);
/// EmitGPRel32Value - Emit the expression @p Value into the output as a /// EmitGPRel32Value - Emit the expression @p Value into the output as a
/// gprel32 (32-bit GP relative) value. /// gprel32 (32-bit GP relative) value.
/// ///

View File

@ -1155,6 +1155,15 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
return; return;
} }
case MachineJumpTableInfo::EK_GPRel64BlockAddress: {
// EK_GPRel64BlockAddress - Each entry is an address of block, encoded
// with a relocation as gp-relative, e.g.:
// .gpdword LBB123
MCSymbol *MBBSym = MBB->getSymbol();
OutStreamer.EmitGPRel64Value(MCSymbolRefExpr::Create(MBBSym, OutContext));
return;
}
case MachineJumpTableInfo::EK_LabelDifference32: { case MachineJumpTableInfo::EK_LabelDifference32: {
// EK_LabelDifference32 - Each entry is the address of the block minus // EK_LabelDifference32 - Each entry is the address of the block minus
// the address of the jump table. This is used for PIC jump tables where // the address of the jump table. This is used for PIC jump tables where

View File

@ -530,6 +530,8 @@ unsigned MachineJumpTableInfo::getEntrySize(const TargetData &TD) const {
switch (getEntryKind()) { switch (getEntryKind()) {
case MachineJumpTableInfo::EK_BlockAddress: case MachineJumpTableInfo::EK_BlockAddress:
return TD.getPointerSize(); return TD.getPointerSize();
case MachineJumpTableInfo::EK_GPRel64BlockAddress:
return 8;
case MachineJumpTableInfo::EK_GPRel32BlockAddress: case MachineJumpTableInfo::EK_GPRel32BlockAddress:
case MachineJumpTableInfo::EK_LabelDifference32: case MachineJumpTableInfo::EK_LabelDifference32:
case MachineJumpTableInfo::EK_Custom32: case MachineJumpTableInfo::EK_Custom32:
@ -549,6 +551,8 @@ unsigned MachineJumpTableInfo::getEntryAlignment(const TargetData &TD) const {
switch (getEntryKind()) { switch (getEntryKind()) {
case MachineJumpTableInfo::EK_BlockAddress: case MachineJumpTableInfo::EK_BlockAddress:
return TD.getPointerABIAlignment(); return TD.getPointerABIAlignment();
case MachineJumpTableInfo::EK_GPRel64BlockAddress:
return TD.getABIIntegerTypeAlignment(64);
case MachineJumpTableInfo::EK_GPRel32BlockAddress: case MachineJumpTableInfo::EK_GPRel32BlockAddress:
case MachineJumpTableInfo::EK_LabelDifference32: case MachineJumpTableInfo::EK_LabelDifference32:
case MachineJumpTableInfo::EK_Custom32: case MachineJumpTableInfo::EK_Custom32:

View File

@ -1161,6 +1161,9 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
} }
break; break;
} }
case MachineJumpTableInfo::EK_GPRel64BlockAddress:
assert(false &&
"JT Info emission not implemented for GPRel64BlockAddress yet.");
} }
} }

View File

@ -67,6 +67,7 @@ MCAsmInfo::MCAsmInfo() {
AlignDirective = "\t.align\t"; AlignDirective = "\t.align\t";
AlignmentIsInBytes = true; AlignmentIsInBytes = true;
TextAlignFillValue = 0; TextAlignFillValue = 0;
GPRel64Directive = 0;
GPRel32Directive = 0; GPRel32Directive = 0;
GlobalDirective = "\t.globl\t"; GlobalDirective = "\t.globl\t";
HasSetDirective = true; HasSetDirective = true;

View File

@ -186,6 +186,8 @@ public:
virtual void EmitSLEB128Value(const MCExpr *Value); virtual void EmitSLEB128Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
virtual void EmitGPRel32Value(const MCExpr *Value); virtual void EmitGPRel32Value(const MCExpr *Value);
@ -663,6 +665,12 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
EmitEOL(); EmitEOL();
} }
void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
assert(MAI.getGPRel64Directive() != 0);
OS << MAI.getGPRel64Directive() << *Value;
EmitEOL();
}
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
assert(MAI.getGPRel32Directive() != 0); assert(MAI.getGPRel32Directive() != 0);
OS << MAI.getGPRel32Directive() << *Value; OS << MAI.getGPRel32Directive() << *Value;

View File

@ -128,6 +128,10 @@ void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
AddrSpace); AddrSpace);
} }
void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
report_fatal_error("unsupported directive in streamer");
}
void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
report_fatal_error("unsupported directive in streamer"); report_fatal_error("unsupported directive in streamer");
} }

View File

@ -32,6 +32,7 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Target &T, StringRef TT) {
CommentString = "#"; CommentString = "#";
ZeroDirective = "\t.space\t"; ZeroDirective = "\t.space\t";
GPRel32Directive = "\t.gpword\t"; GPRel32Directive = "\t.gpword\t";
GPRel64Directive = "\t.gpdword\t";
WeakRefDirective = "\t.weak\t"; WeakRefDirective = "\t.weak\t";
SupportsDebugInformation = true; SupportsDebugInformation = true;

View File

@ -2909,3 +2909,10 @@ bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
return false; return false;
return Imm.isZero(); return Imm.isZero();
} }
unsigned MipsTargetLowering::getJumpTableEncoding() const {
if (IsN64)
return MachineJumpTableInfo::EK_GPRel64BlockAddress;
return TargetLowering::getJumpTableEncoding();
}

View File

@ -181,6 +181,8 @@ namespace llvm {
/// materialize the FP immediate as a load from a constant pool. /// materialize the FP immediate as a load from a constant pool.
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
virtual unsigned getJumpTableEncoding() const;
MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
unsigned Size, unsigned BinOpcode, bool Nand = false) const; unsigned Size, unsigned BinOpcode, bool Nand = false) const;
MachineBasicBlock *EmitAtomicBinaryPartword(MachineInstr *MI, MachineBasicBlock *EmitAtomicBinaryPartword(MachineInstr *MI,

View File

@ -469,11 +469,14 @@ unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
MachineBasicBlock::iterator MBBI = FirstMBB.begin(); MachineBasicBlock::iterator MBBI = FirstMBB.begin();
MachineRegisterInfo &RegInfo = MF->getRegInfo(); MachineRegisterInfo &RegInfo = MF->getRegInfo();
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
unsigned GP = IsN64 ? Mips::GP_64 : Mips::GP;
const TargetRegisterClass *RC
= IsN64 ? Mips::CPU64RegsRegisterClass : Mips::CPURegsRegisterClass;
GlobalBaseReg = RegInfo.createVirtualRegister(Mips::CPURegsRegisterClass); GlobalBaseReg = RegInfo.createVirtualRegister(RC);
BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
GlobalBaseReg).addReg(Mips::GP); GlobalBaseReg).addReg(GP);
RegInfo.addLiveIn(Mips::GP); RegInfo.addLiveIn(GP);
MipsFI->setGlobalBaseReg(GlobalBaseReg); MipsFI->setGlobalBaseReg(GlobalBaseReg);
return GlobalBaseReg; return GlobalBaseReg;

View File

@ -15,7 +15,7 @@ entry:
; PIC-O32: sll ${{[0-9]+}}, ${{[0-9]+}}, 2 ; PIC-O32: sll ${{[0-9]+}}, ${{[0-9]+}}, 2
; PIC-N64: ld $[[R0:[0-9]+]], %got_page($JTI0_0) ; PIC-N64: ld $[[R0:[0-9]+]], %got_page($JTI0_0)
; PIC-N64: daddiu ${{[0-9]+}}, $[[R0]], %got_ofst($JTI0_0) ; PIC-N64: daddiu ${{[0-9]+}}, $[[R0]], %got_ofst($JTI0_0)
; PIC-N64: dsll ${{[0-9]+}}, ${{[0-9]+}}, 2 ; PIC-N64: dsll ${{[0-9]+}}, ${{[0-9]+}}, 3
switch i32 %0, label %bb4 [ switch i32 %0, label %bb4 [
i32 0, label %bb5 i32 0, label %bb5
i32 1, label %bb1 i32 1, label %bb1
@ -39,3 +39,23 @@ bb4: ; preds = %entry
bb5: ; preds = %entry bb5: ; preds = %entry
ret i32 1 ret i32 1
} }
; STATIC-O32: .align 2
; STATIC-O32: $JTI0_0:
; STATIC-O32: .4byte
; STATIC-O32: .4byte
; STATIC-O32: .4byte
; STATIC-O32: .4byte
; PIC-O32: .align 2
; PIC-O32: $JTI0_0:
; PIC-O32: .gpword
; PIC-O32: .gpword
; PIC-O32: .gpword
; PIC-O32: .gpword
; PIC-N64: .align 3
; PIC-N64: $JTI0_0:
; PIC-N64: .gpdword
; PIC-N64: .gpdword
; PIC-N64: .gpdword
; PIC-N64: .gpdword