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.

llvm-svn: 149668
This commit is contained in:
Akira Hatanaka 2012-02-03 04:33:00 +00:00
parent 07f0f77629
commit f0b08445f6
14 changed files with 85 additions and 5 deletions

View File

@ -47,7 +47,12 @@ public:
/// EK_BlockAddress - Each entry is a plain address of block, e.g.:
/// .word LBB123
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
/// with a relocation as gp-relative, e.g.:
/// .gprel32 LBB123

View File

@ -180,6 +180,11 @@ namespace llvm {
const char *JT32Begin; // Defaults to "$a."
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
/// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword
/// on Mips or .gprel32 on Alpha.
@ -376,6 +381,7 @@ namespace llvm {
const char *getData64bitsDirective(unsigned AS = 0) const {
return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
}
const char *getGPRel64Directive() const { return GPRel64Directive; }
const char *getGPRel32Directive() const { return GPRel32Directive; }
/// [Code|Data]Begin label name accessors.

View File

@ -441,6 +441,13 @@ namespace llvm {
void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
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
/// gprel32 (32-bit GP relative) value.
///

View File

@ -1155,6 +1155,15 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
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: {
// 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

View File

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

View File

@ -1161,6 +1161,9 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
}
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";
AlignmentIsInBytes = true;
TextAlignFillValue = 0;
GPRel64Directive = 0;
GPRel32Directive = 0;
GlobalDirective = "\t.globl\t";
HasSetDirective = true;

View File

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

View File

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

View File

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

View File

@ -2909,3 +2909,10 @@ bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
return false;
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.
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
virtual unsigned getJumpTableEncoding() const;
MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
unsigned Size, unsigned BinOpcode, bool Nand = false) const;
MachineBasicBlock *EmitAtomicBinaryPartword(MachineInstr *MI,

View File

@ -469,11 +469,14 @@ unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
MachineRegisterInfo &RegInfo = MF->getRegInfo();
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),
GlobalBaseReg).addReg(Mips::GP);
RegInfo.addLiveIn(Mips::GP);
GlobalBaseReg).addReg(GP);
RegInfo.addLiveIn(GP);
MipsFI->setGlobalBaseReg(GlobalBaseReg);
return GlobalBaseReg;

View File

@ -15,7 +15,7 @@ entry:
; PIC-O32: sll ${{[0-9]+}}, ${{[0-9]+}}, 2
; PIC-N64: ld $[[R0:[0-9]+]], %got_page($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 [
i32 0, label %bb5
i32 1, label %bb1
@ -39,3 +39,23 @@ bb4: ; preds = %entry
bb5: ; preds = %entry
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