forked from OSchip/llvm-project
make pcrel immediate values relative to the start of the field,
not the end of the field, fixing rdar://7651978 llvm-svn: 96330
This commit is contained in:
parent
77904f1d5b
commit
4964ef88c2
|
@ -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,
|
// If this is a simple integer displacement that doesn't require a relocation,
|
||||||
// emit it now.
|
// emit it now.
|
||||||
if (DispOp.isImm()) {
|
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);
|
EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have an immoffset, add it to the expression.
|
// If we have an immoffset, add it to the expression.
|
||||||
const MCExpr *Expr = DispOp.getExpr();
|
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)
|
if (ImmOffset)
|
||||||
Expr = MCBinaryExpr::CreateAdd(Expr,MCConstantExpr::Create(ImmOffset, Ctx),
|
Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(ImmOffset, Ctx),
|
||||||
Ctx);
|
Ctx);
|
||||||
|
|
||||||
// Emit a symbolic constant as a fixup and 4 zeros.
|
// 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
|
// the size of the immediate field. If we have this case, add it into the
|
||||||
// expression to emit.
|
// expression to emit.
|
||||||
int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0;
|
int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0;
|
||||||
|
|
||||||
EmitImmediate(Disp, 4, MCFixupKind(X86::reloc_riprel_4byte),
|
EmitImmediate(Disp, 4, MCFixupKind(X86::reloc_riprel_4byte),
|
||||||
CurByte, OS, Fixups, -ImmSize);
|
CurByte, OS, Fixups, -ImmSize);
|
||||||
return;
|
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
|
// If there is a remaining operand, it must be a trailing immediate. Emit it
|
||||||
// according to the right size for the instruction.
|
// 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)
|
if (CurOp != NumOps)
|
||||||
EmitImmediate(MI.getOperand(CurOp++),
|
EmitImmediate(MI.getOperand(CurOp++),
|
||||||
X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
|
X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
movl foo(%rip), %eax
|
movl foo(%rip), %eax
|
||||||
// CHECK: movl foo(%rip), %eax
|
// CHECK: movl foo(%rip), %eax
|
||||||
// CHECK: encoding: [0x8b,0x05,A,A,A,A]
|
// CHECK: encoding: [0x8b,0x05,A,A,A,A]
|
||||||
// CHECK: fixup A - offset: 2, value: foo, kind: reloc_riprel_4byte
|
// CHECK: fixup A - offset: 2, value: foo-4, kind: reloc_riprel_4byte
|
||||||
|
|
||||||
movb $12, foo(%rip)
|
movb $12, foo(%rip)
|
||||||
// CHECK: movb $12, foo(%rip)
|
// CHECK: movb $12, foo(%rip)
|
||||||
// CHECK: encoding: [0xc6,0x05,A,A,A,A,0x0c]
|
// CHECK: encoding: [0xc6,0x05,A,A,A,A,0x0c]
|
||||||
// CHECK: fixup A - offset: 2, value: foo-1, kind: reloc_riprel_4byte
|
// CHECK: fixup A - offset: 2, value: foo-5, kind: reloc_riprel_4byte
|
||||||
|
|
||||||
movw $12, foo(%rip)
|
movw $12, foo(%rip)
|
||||||
// CHECK: movw $12, foo(%rip)
|
// CHECK: movw $12, foo(%rip)
|
||||||
// CHECK: encoding: [0x66,0xc7,0x05,A,A,A,A,0x0c,0x00]
|
// CHECK: encoding: [0x66,0xc7,0x05,A,A,A,A,0x0c,0x00]
|
||||||
// CHECK: fixup A - offset: 3, value: foo-2, kind: reloc_riprel_4byte
|
// CHECK: fixup A - offset: 3, value: foo-6, kind: reloc_riprel_4byte
|
||||||
|
|
||||||
movl $12, foo(%rip)
|
movl $12, foo(%rip)
|
||||||
// CHECK: movl $12, foo(%rip)
|
// CHECK: movl $12, foo(%rip)
|
||||||
// CHECK: encoding: [0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
|
// CHECK: encoding: [0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
|
||||||
// CHECK: fixup A - offset: 2, value: foo-4, kind: reloc_riprel_4byte
|
// CHECK: fixup A - offset: 2, value: foo-8, kind: reloc_riprel_4byte
|
||||||
|
|
||||||
movq $12, foo(%rip)
|
movq $12, foo(%rip)
|
||||||
// CHECK: movq $12, foo(%rip)
|
// CHECK: movq $12, foo(%rip)
|
||||||
// CHECK: encoding: [0x48,0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
|
// CHECK: encoding: [0x48,0xc7,0x05,A,A,A,A,0x0c,0x00,0x00,0x00]
|
||||||
// CHECK: fixup A - offset: 3, value: foo-4, kind: reloc_riprel_4byte
|
// CHECK: fixup A - offset: 3, value: foo-8, kind: reloc_riprel_4byte
|
||||||
|
|
Loading…
Reference in New Issue