diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-02-16 05:03:17 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-02-16 05:03:17 +0000 |
| commit | 4964ef88c255af2f5c1f464520da5e7c5566bb77 (patch) | |
| tree | cf8c6e91ab7c3a2011b5472e02c25fe7bfd31e95 /llvm/lib | |
| parent | 77904f1d5b03a453b116c3fe73437549c900f889 (diff) | |
| download | bcm5719-llvm-4964ef88c255af2f5c1f464520da5e7c5566bb77.tar.gz bcm5719-llvm-4964ef88c255af2f5c1f464520da5e7c5566bb77.zip | |
make pcrel immediate values relative to the start of the field,
not the end of the field, fixing rdar://7651978
llvm-svn: 96330
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86MCCodeEmitter.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/X86MCCodeEmitter.cpp index d0ec0de6913..3f18696d855 100644 --- a/llvm/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/X86MCCodeEmitter.cpp @@ -153,14 +153,25 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind, // If this is a simple integer displacement that doesn't require a relocation, // emit it now. if (DispOp.isImm()) { + // FIXME: is this right for pc-rel encoding?? Probably need to emit this as + // a fixup if so. EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS); return; } // If we have an immoffset, add it to the expression. const MCExpr *Expr = DispOp.getExpr(); + + // If the fixup is pc-relative, we need to bias the value to be relative to + // the start of the field, not the end of the field. + if (FixupKind == MCFixupKind(X86::reloc_pcrel_4byte) || + FixupKind == MCFixupKind(X86::reloc_riprel_4byte)) + ImmOffset -= 4; + if (FixupKind == MCFixupKind(X86::reloc_pcrel_1byte)) + ImmOffset -= 1; + if (ImmOffset) - Expr = MCBinaryExpr::CreateAdd(Expr,MCConstantExpr::Create(ImmOffset, Ctx), + Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(ImmOffset, Ctx), Ctx); // Emit a symbolic constant as a fixup and 4 zeros. @@ -192,6 +203,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // 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; @@ -616,8 +628,6 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, // If there is a remaining operand, it must be a trailing immediate. Emit it // according to the right size for the instruction. - // 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), getImmFixupKind(TSFlags), |

