[llvm-commits] [llvm] r96036 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.h X86MCCodeEmitter.cpp

Chris Lattner sabre at nondot.org
Fri Feb 12 15:00:36 PST 2010


Author: lattner
Date: Fri Feb 12 17:00:36 2010
New Revision: 96036

URL: http://llvm.org/viewvc/llvm-project?rev=96036&view=rev
Log:
implement infrastructure to support fixups for rip-rel 
addressing.  This isn't complete because I need an MCContext
to generate new MCExprs.

Modified:
    llvm/trunk/lib/Target/X86/X86InstrInfo.h
    llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=96036&r1=96035&r2=96036&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Fri Feb 12 17:00:36 2010
@@ -405,6 +405,10 @@
     return TSFlags >> X86II::OpcodeShift;
   }
   
+  static inline bool hasImm(unsigned TSFlags) {
+    return (TSFlags & X86II::ImmMask) != 0;
+  }
+  
   /// getSizeOfImm - Decode the "size of immediate" field from the TSFlags field
   /// of the specified instruction.
   static inline unsigned getSizeOfImm(unsigned TSFlags) {

Modified: llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp?rev=96036&r1=96035&r2=96036&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp Fri Feb 12 17:00:36 2010
@@ -24,7 +24,8 @@
 namespace X86 {
 enum Fixups {
   reloc_pcrel_4byte = FirstTargetFixupKind,  // 32-bit pcrel, e.g. a branch.
-  reloc_pcrel_1byte                          // 8-bit pcrel, e.g. branch_1
+  reloc_pcrel_1byte,                         // 8-bit pcrel, e.g. branch_1
+  reloc_riprel_4byte                         // 32-bit rip-relative   
 };
 }
 }
@@ -45,13 +46,14 @@
   ~X86MCCodeEmitter() {}
 
   unsigned getNumFixupKinds() const {
-    return 2;
+    return 3;
   }
 
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
     const static MCFixupKindInfo Infos[] = {
       { "reloc_pcrel_4byte", 0, 4 * 8 },
-      { "reloc_pcrel_1byte", 0, 1 * 8 }
+      { "reloc_pcrel_1byte", 0, 1 * 8 },
+      { "reloc_riprel_4byte", 0, 4 * 8 }
     };
     
     if (Kind < FirstTargetFixupKind)
@@ -83,7 +85,8 @@
   void EmitImmediate(const MCOperand &Disp, 
                      unsigned ImmSize, MCFixupKind FixupKind,
                      unsigned &CurByte, raw_ostream &OS,
-                     SmallVectorImpl<MCFixup> &Fixups) const;
+                     SmallVectorImpl<MCFixup> &Fixups,
+                     int ImmOffset = 0) const;
   
   inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
                                         unsigned RM) {
@@ -105,7 +108,7 @@
   
   void EmitMemModRMByte(const MCInst &MI, unsigned Op,
                         unsigned RegOpcodeField, 
-                        unsigned &CurByte, raw_ostream &OS,
+                        unsigned TSFlags, unsigned &CurByte, raw_ostream &OS,
                         SmallVectorImpl<MCFixup> &Fixups) const;
   
   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
@@ -152,23 +155,27 @@
 void X86MCCodeEmitter::
 EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
               unsigned &CurByte, raw_ostream &OS,
-              SmallVectorImpl<MCFixup> &Fixups) const {
+              SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const {
   // If this is a simple integer displacement that doesn't require a relocation,
   // emit it now.
   if (DispOp.isImm()) {
-    EmitConstant(DispOp.getImm(), Size, CurByte, OS);
+    EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS);
     return;
   }
 
+  // If we have an immoffset, add it to the expression.
+  const MCExpr *Expr = DispOp.getExpr();
+  // FIXME: NO CONTEXT.
+  
   // Emit a symbolic constant as a fixup and 4 zeros.
-  Fixups.push_back(MCFixup::Create(CurByte, DispOp.getExpr(), FixupKind));
+  Fixups.push_back(MCFixup::Create(CurByte, Expr, FixupKind));
   EmitConstant(0, Size, CurByte, OS);
 }
 
 
 void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
                                         unsigned RegOpcodeField,
-                                        unsigned &CurByte,
+                                        unsigned TSFlags, unsigned &CurByte,
                                         raw_ostream &OS,
                                         SmallVectorImpl<MCFixup> &Fixups) const{
   const MCOperand &Disp     = MI.getOperand(Op+3);
@@ -182,7 +189,15 @@
     assert(IndexReg.getReg() == 0 && Is64BitMode &&
            "Invalid rip-relative address");
     EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
-    EmitImmediate(Disp, 4, FK_Data_4, CurByte, OS, Fixups);
+    
+    // rip-relative addressing is actually relative to the *next* instruction.
+    // Since an immediate can follow the mod/rm byte for an instruction, this
+    // means that we need to bias the immediate field of the instruction with
+    // the size of the immediate field.  If we have this case, add it into the
+    // expression to emit.
+    int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0;
+    EmitImmediate(Disp, 4, MCFixupKind(X86::reloc_riprel_4byte),
+                  CurByte, OS, Fixups, -ImmSize);
     return;
   }
   
@@ -514,7 +529,7 @@
     EmitByte(BaseOpcode, CurByte, OS);
     EmitMemModRMByte(MI, CurOp,
                      GetX86RegNum(MI.getOperand(CurOp + X86AddrNumOperands)),
-                     CurByte, OS, Fixups);
+                     TSFlags, CurByte, OS, Fixups);
     CurOp += X86AddrNumOperands + 1;
     break;
       
@@ -537,7 +552,7 @@
       AddrOperands = X86AddrNumOperands;
     
     EmitMemModRMByte(MI, CurOp+1, GetX86RegNum(MI.getOperand(CurOp)),
-                     CurByte, OS, Fixups);
+                     TSFlags, CurByte, OS, Fixups);
     CurOp += AddrOperands + 1;
     break;
   }
@@ -567,7 +582,7 @@
   case X86II::MRM6m: case X86II::MRM7m:
     EmitByte(BaseOpcode, CurByte, OS);
     EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m,
-                     CurByte, OS, Fixups);
+                     TSFlags, CurByte, OS, Fixups);
     CurOp += X86AddrNumOperands;
     break;
   case X86II::MRM_C1:





More information about the llvm-commits mailing list