diff options
author | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-12-25 08:13:10 +0000 |
---|---|---|
committer | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-12-25 08:13:10 +0000 |
commit | 45d698779d2698e9e197fa6b8d599264eed6491b (patch) | |
tree | be58daf5d1eb48a4bd6cf407f658cfd9c7bcfbc6 /compiler/sparc | |
parent | 9c9fe7ca810218053310e67adbe6dd8a4f6a6a47 (diff) | |
download | fpc-45d698779d2698e9e197fa6b8d599264eed6491b.tar.gz |
* SPARC: fixed PIC interface wrappers for non-virtual methods. The fix uses branching with 8 MB distance limit, but in particular case of interface wrappers this limit applies to code size of a single unit, not to entire program, and is therefore hard enough to reach.
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@26279 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/sparc')
-rw-r--r-- | compiler/sparc/cgcpu.pas | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/compiler/sparc/cgcpu.pas b/compiler/sparc/cgcpu.pas index 8f189ccfbf..50fcd16c50 100644 --- a/compiler/sparc/cgcpu.pas +++ b/compiler/sparc/cgcpu.pas @@ -1569,29 +1569,19 @@ implementation list.concat(taicpu.op_ref_reg(A_LD,href,NR_G1)); list.concat(taicpu.op_reg(A_JMP,NR_G1)); g1_used:=false; + { Delay slot } + list.Concat(TAiCpu.Op_none(A_NOP)); end else begin - reference_reset_symbol(href,current_asmdata.RefAsmSymbol(procdef.mangledname),0,sizeof(pint)); - href.refaddr := addr_high; - list.concat(taicpu.op_ref_reg(A_SETHI,href,NR_G1)); - g1_used:=true; - href.refaddr := addr_low; - list.concat(taicpu.op_reg_ref_reg(A_OR,NR_G1,href,NR_G1)); - { FIXME: this assumes for now that %l7 already has the correct value } - if (cs_create_pic in current_settings.moduleswitches) then - begin - list.concat(taicpu.op_reg_reg_reg(A_ADD,NR_G1,NR_L7,NR_G1)); - reference_reset_base(href,NR_G1,0,sizeof(pint)); - list.concat(taicpu.op_ref_reg(A_LD,href,NR_G1)); - end; - - list.concat(taicpu.op_reg(A_JMP,NR_G1)); - g1_used:=false; + { Emit a branch, which is PIC-safe, but limited to 8 MByte range on SPARC. + Since interface wrappers are always located in the same unit with + their target methods, this limit applies (roughly) to code size of single + unit, not to entire program. It looks like a reasonable tradeoff. + If distance limit is ever exceeded, consider changing high-level compiler + logic to emit wrappers near target methods, not at the end of unit. } + a_jmp_name(list,procdef.mangledname); end; - { Delay slot } - list.Concat(TAiCpu.Op_none(A_NOP)); - List.concat(Tai_symbol_end.Createname(labelname)); end; |