diff --git a/lib/cretonne/meta/isa/intel/encodings.py b/lib/cretonne/meta/isa/intel/encodings.py index 52a56a514d..4e4ebc229c 100644 --- a/lib/cretonne/meta/isa/intel/encodings.py +++ b/lib/cretonne/meta/isa/intel/encodings.py @@ -2,7 +2,7 @@ Intel Encodings. """ from __future__ import absolute_import -from cdsl.predicates import IsUnsignedInt, Not +from cdsl.predicates import IsUnsignedInt, Not, And from base import instructions as base from base.formats import UnaryImm from .defs import I32, I64 @@ -11,7 +11,7 @@ from . import settings as cfg from . import instructions as x86 from .legalize import intel_expand from base.legalize import narrow, expand -from base.settings import allones_funcaddrs +from base.settings import allones_funcaddrs, is_pic from .settings import use_sse41 try: @@ -281,25 +281,33 @@ enc_both(base.regspill.f64, r.frsp32, 0x66, 0x0f, 0xd6) I32.enc(base.func_addr.i32, *r.fnaddr4(0xb8), isap=Not(allones_funcaddrs)) I64.enc(base.func_addr.i64, *r.fnaddr8.rex(0xb8, w=1), - isap=Not(allones_funcaddrs)) + isap=And(Not(allones_funcaddrs), Not(is_pic))) I32.enc(base.func_addr.i32, *r.allones_fnaddr4(0xb8), isap=allones_funcaddrs) I64.enc(base.func_addr.i64, *r.allones_fnaddr8.rex(0xb8, w=1), - isap=allones_funcaddrs) + isap=And(allones_funcaddrs, Not(is_pic))) + +I64.enc(base.func_addr.i64, *r.got_fnaddr8.rex(0x8b, w=1), + isap=is_pic) # # Global addresses. # I32.enc(base.globalsym_addr.i32, *r.gvaddr4(0xb8)) -I64.enc(base.globalsym_addr.i64, *r.gvaddr8.rex(0xb8, w=1)) +I64.enc(base.globalsym_addr.i64, *r.gvaddr8.rex(0xb8, w=1), + isap=Not(is_pic)) + +I64.enc(base.globalsym_addr.i64, *r.got_gvaddr8.rex(0x8b, w=1), + isap=is_pic) # # Call/return # I32.enc(base.call, *r.call_id(0xe8)) -I64.enc(base.call, *r.call_id(0xe8)) +I64.enc(base.call, *r.call_id(0xe8), isap=Not(is_pic)) +I64.enc(base.call, *r.call_plt_id(0xe8), isap=is_pic) I32.enc(base.call_indirect.i32, *r.call_r(0xff, rrr=2)) I64.enc(base.call_indirect.i64, *r.call_r.rex(0xff, rrr=2)) diff --git a/lib/cretonne/meta/isa/intel/recipes.py b/lib/cretonne/meta/isa/intel/recipes.py index 2afd7be588..b9b7a4ec59 100644 --- a/lib/cretonne/meta/isa/intel/recipes.py +++ b/lib/cretonne/meta/isa/intel/recipes.py @@ -558,6 +558,19 @@ allones_fnaddr8 = TailRecipe( sink.put8(!0); ''') +got_fnaddr8 = TailRecipe( + 'got_fnaddr8', FuncAddr, size=5, ins=(), outs=GPR, + # rex2 is a hack at the moment to get one that sets the `r` bit in rex + # rm for modrm_rm is 5 to get RIP-relative addressing + emit=''' + PUT_OP(bits, rex2(0, out_reg0), sink); + modrm_rm(5, out_reg0, sink); + sink.reloc_external(Reloc::IntelGotPCRel4, + &func.dfg.ext_funcs[func_ref].name); + sink.put4(0); + ''') + + # XX+rd id with Abs4 globalsym relocation. gvaddr4 = TailRecipe( 'gvaddr4', UnaryGlobalVar, size=4, ins=(), outs=GPR, @@ -578,6 +591,18 @@ gvaddr8 = TailRecipe( sink.put8(0); ''') +# XX+rd iq with Abs8 globalsym relocation. +got_gvaddr8 = TailRecipe( + 'got_gvaddr8', UnaryGlobalVar, size=5, ins=(), outs=GPR, + emit=''' + PUT_OP(bits, rex2(0, out_reg0), sink); + modrm_rm(5, out_reg0, sink); + sink.reloc_external(Reloc::IntelGotPCRel4, + &func.global_vars[global_var].symbol_name()); + sink.put4(0); + ''') + + # # Store recipes. # @@ -853,6 +878,15 @@ call_id = TailRecipe( sink.put4(0); ''') +call_plt_id = TailRecipe( + 'call_plt_id', Call, size=4, ins=(), outs=(), + emit=''' + PUT_OP(bits, BASE_REX, sink); + sink.reloc_external(Reloc::IntelPLTRel4, + &func.dfg.ext_funcs[func_ref].name); + sink.put4(0); + ''') + call_r = TailRecipe( 'call_r', IndirectCall, size=1, ins=GPR, outs=(), emit='''