summaryrefslogtreecommitdiff
path: root/compiler/sparc
diff options
context:
space:
mode:
authorsergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-12-25 08:13:10 +0000
committersergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-12-25 08:13:10 +0000
commit45d698779d2698e9e197fa6b8d599264eed6491b (patch)
treebe58daf5d1eb48a4bd6cf407f658cfd9c7bcfbc6 /compiler/sparc
parent9c9fe7ca810218053310e67adbe6dd8a4f6a6a47 (diff)
downloadfpc-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.pas28
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;