summaryrefslogtreecommitdiff
path: root/compiler/powerpc64
diff options
context:
space:
mode:
authortom_at_work <tom_at_work@3ad0048d-3df7-0310-abae-a5850022a9f2>2005-12-18 22:08:13 +0000
committertom_at_work <tom_at_work@3ad0048d-3df7-0310-abae-a5850022a9f2>2005-12-18 22:08:13 +0000
commitd2a13fe6cc0f4cffaa7ac14515fc78828ca83f51 (patch)
treed6d4a8c475e9fca3be7bc35a7ce23960e784fe12 /compiler/powerpc64
parent8caebd08f1ff07b0fb0b0cec66feab45b1304715 (diff)
downloadfpc-d2a13fe6cc0f4cffaa7ac14515fc78828ca83f51.tar.gz
* ppc64/linux specific compiler patches to improve C parameter passing compatibility
* passes tcalext3 and tcalext4 test programs git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@1984 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/powerpc64')
-rw-r--r--compiler/powerpc64/cgcpu.pas9
-rw-r--r--compiler/powerpc64/cpupara.pas34
-rw-r--r--compiler/powerpc64/nppccal.pas12
3 files changed, 37 insertions, 18 deletions
diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas
index d6a4bbf4f5..61b9fbddd1 100644
--- a/compiler/powerpc64/cgcpu.pas
+++ b/compiler/powerpc64/cgcpu.pas
@@ -373,7 +373,7 @@ begin
location^.register)
else
{$IFDEF extdebug}
- list.concat(tai_comment.create(strpnew('a_param_ref with OS_NO')));
+ list.concat(tai_comment.create(strpnew('a_param_ref with OS_NO, sizeleft ' + inttostr(sizeleft))));
{$ENDIF extdebug}
{ load non-integral sized memory location into register. This
@@ -430,15 +430,12 @@ begin
{ the block is > 8 bytes, so we have to store any bytes not
a multiple of the register size beginning with the MSB }
adjusttail := true;
- end;
-(*
- { Comment this in (for gcc compat) and be prepared for a whole bunch of errors :/ }
-
+ end;
if (adjusttail) and (sizeleft < tcgsize2size[OS_INT]) then
a_op_const_reg(list, OP_SHL, OS_INT,
(tcgsize2size[OS_INT] - sizeleft) * tcgsize2size[OS_INT],
location^.register);
-*)
+
end;
LOC_REFERENCE:
begin
diff --git a/compiler/powerpc64/cpupara.pas b/compiler/powerpc64/cpupara.pas
index a0eef43692..4c4ec8583b 100644
--- a/compiler/powerpc64/cpupara.pas
+++ b/compiler/powerpc64/cpupara.pas
@@ -264,6 +264,7 @@ function tppcparamanager.create_paraloc_info_intern(p: tabstractprocdef; side:
tcallercallee; paras: tparalist;
var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset:
aword; isVararg : boolean): longint;
+
var
stack_offset: longint;
paralen: aint;
@@ -275,6 +276,8 @@ var
loc: tcgloc;
paracgsize: tcgsize;
+ parashift : byte;
+
begin
{$IFDEF extdebug}
if po_explicitparaloc in p.procoptions then
@@ -288,13 +291,13 @@ begin
stack_offset := cur_stack_offset;
for i := 0 to paras.count - 1 do begin
+ parashift := 0;
+
hp := tparavarsym(paras[i]);
paradef := hp.vartype.def;
- { Syscall for Morphos can have already a paraloc set }
+ { Syscall for Morphos can have already a paraloc set; not supported on ppc64 }
if (vo_has_explicit_paraloc in hp.varoptions) then begin
- if not (vo_is_syscall_lib in hp.varoptions) then
- internalerror(200412153);
- continue;
+ internalerror(200412153);
end;
hp.paraloc[side].reset;
{ currently only support C-style array of const }
@@ -327,8 +330,8 @@ begin
{ non-composite (not array or record), it must be }
{ passed according to the rules of that type. }
if (trecorddef(hp.vartype.def).symtable.symindex.count = 1) and
- (not trecorddef(hp.vartype.def).isunion) and
- (tabstractvarsym(trecorddef(hp.vartype.def).symtable.symindex.search(1)).vartype.def.deftype = floatdef) then begin
+ (not trecorddef(hp.vartype.def).isunion) and
+ (tabstractvarsym(trecorddef(hp.vartype.def).symtable.symindex.search(1)).vartype.def.deftype in [orddef, enumdef, floatdef]) then begin
paradef :=
tabstractvarsym(trecorddef(hp.vartype.def).symtable.symindex.search(1)).vartype.def;
loc := getparaloc(paradef);
@@ -336,6 +339,8 @@ begin
end else begin
loc := LOC_REGISTER;
paracgsize := int_cgsize(paralen);
+ if (paralen in [3,5,6,7]) then
+ parashift := (tcgsize2size[paracgsize]-paralen) * 8;
end;
end else begin
loc := getparaloc(paradef);
@@ -369,17 +374,22 @@ begin
end else
internalerror(2005011310);
{ can become < 0 for e.g. 3-byte records }
+
while (paralen > 0) do begin
paraloc := hp.paraloc[side].add_location;
if (loc = LOC_REGISTER) and (nextintreg <= RS_R10) then begin
paraloc^.loc := loc;
- { make sure we don't lose whether or not the type is signed }
- if (paradef.deftype <> orddef) then
- paracgsize := int_cgsize(paralen);
- if (paracgsize in [OS_NO]) then
- paraloc^.size := OS_INT
+ paraloc^.shiftval := parashift;
+
+ if (paracgsize <> OS_NO) then
+ { make sure we don't lose whether or not the type is signed }
+ if (paradef.deftype <> orddef) then
+ paraloc^.size := int_cgsize(paralen)
+ else
+ paraloc^.size := paracgsize
else
- paraloc^.size := paracgsize;
+ paraloc^.size := OS_INT;
+
paraloc^.register := newreg(R_INTREGISTER, nextintreg, R_SUBNONE);
inc(nextintreg);
dec(paralen, tcgsize2size[paraloc^.size]);
diff --git a/compiler/powerpc64/nppccal.pas b/compiler/powerpc64/nppccal.pas
index b8f947f158..41e1fa53c0 100644
--- a/compiler/powerpc64/nppccal.pas
+++ b/compiler/powerpc64/nppccal.pas
@@ -29,7 +29,12 @@ uses
symdef, node, ncal, ncgcal;
type
+
+ tppccallparanode = class(tcgcallparanode)
+ end;
+
tppccallnode = class(tcgcallnode)
+ procedure do_syscall; override;
end;
implementation
@@ -44,8 +49,15 @@ uses
ncgutil, cgutils, cgobj, tgobj, regvars, rgobj, rgcpu,
cgcpu, cpupi, procinfo;
+procedure tppccallnode.do_syscall;
+begin
+ { no MorphOS style syscalls supported. Only implemented to avoid abstract
+ method not implemented compiler warning. }
+ internalerror(2005120401);
+end;
begin
+ ccallparanode:=tppccallparanode;
ccallnode := tppccallnode;
end.