From: Chris Lattner Date: Fri, 12 Feb 2010 22:36:47 +0000 (+0000) Subject: start producing reloc_pcrel_4byte/reloc_pcrel_1byte for calls. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=cf65339b52e09be5d329e45d3847a8e3a2ee08bd;p=oota-llvm.git start producing reloc_pcrel_4byte/reloc_pcrel_1byte for calls. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96028 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp index b573cc2a204..3d98f6f1a47 100644 --- a/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/X86MCCodeEmitter.cpp @@ -80,7 +80,8 @@ public: } } - void EmitImmediate(const MCOperand &Disp, unsigned ImmSize, + void EmitImmediate(const MCOperand &Disp, + unsigned ImmSize, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, SmallVectorImpl &Fixups) const; @@ -132,8 +133,25 @@ static bool isDisp8(int Value) { return Value == (signed char)Value; } +/// getImmFixupKind - Return the appropriate fixup kind to use for an immediate +/// in an instruction with the specified TSFlags. +static MCFixupKind getImmFixupKind(unsigned TSFlags) { + unsigned Size = X86II::getSizeOfImm(TSFlags); + bool isPCRel = X86II::isImmPCRel(TSFlags); + + // FIXME: Pass in the relocation type, this is just a hack.. + switch (Size) { + default: assert(0 && "Unknown immediate size"); + case 1: return isPCRel ? MCFixupKind(X86::reloc_pcrel_1byte) : FK_Data_1; + case 4: return isPCRel ? MCFixupKind(X86::reloc_pcrel_4byte) : FK_Data_4; + case 2: assert(!isPCRel); return FK_Data_2; + case 8: assert(!isPCRel); return FK_Data_8; + } +} + + void X86MCCodeEmitter:: -EmitImmediate(const MCOperand &DispOp, unsigned Size, +EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, SmallVectorImpl &Fixups) const { // If this is a simple integer displacement that doesn't require a relocation, @@ -143,22 +161,8 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, return; } - // FIXME: Pass in the relocation type, this is just a hack.. - unsigned FixupKind; - if (Size == 1) - FixupKind = FK_Data_1; - else if (Size == 2) - FixupKind = FK_Data_2; - else if (Size == 4) - FixupKind = FK_Data_4; - else { - assert(Size == 8 && "Unknown immediate size"); - FixupKind = FK_Data_8; - } - // Emit a symbolic constant as a fixup and 4 zeros. - Fixups.push_back(MCFixup::Create(CurByte, DispOp.getExpr(), - MCFixupKind(FixupKind))); + Fixups.push_back(MCFixup::Create(CurByte, DispOp.getExpr(), FixupKind)); EmitConstant(0, Size, CurByte, OS); } @@ -195,7 +199,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, if (BaseReg == 0 || // [disp32] in X86-32 mode BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); - EmitImmediate(Disp, 4, CurByte, OS, Fixups); + EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups); return; } @@ -211,13 +215,13 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // Otherwise, if the displacement fits in a byte, encode as [REG+disp8]. if (Disp.isImm() && isDisp8(Disp.getImm())) { EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); - EmitImmediate(Disp, 1, CurByte, OS, Fixups); + EmitImmediate(Disp, 1, FK_Data_1, CurByte, OS, Fixups); return; } // Otherwise, emit the most general non-SIB encoding: [REG+disp32] EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS); - EmitImmediate(Disp, 4, CurByte, OS, Fixups); + EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups); return; } @@ -272,9 +276,9 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // Do we need to output a displacement? if (ForceDisp8) - EmitImmediate(Disp, 1, CurByte, OS, Fixups); + EmitImmediate(Disp, 1, FK_Data_1, CurByte, OS, Fixups); else if (ForceDisp32 || Disp.getImm() != 0) - EmitImmediate(Disp, 4, CurByte, OS, Fixups); + EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups); } /// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64 @@ -587,7 +591,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, // FIXME: This should pass in whether the value is pc relative or not. This // information should be aquired from TSFlags as well. if (CurOp != NumOps) - EmitImmediate(MI.getOperand(CurOp++), X86II::getSizeOfImm(TSFlags), + EmitImmediate(MI.getOperand(CurOp++), + X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), CurByte, OS, Fixups); #ifndef NDEBUG