diff options
author | tom_at_work <tom_at_work@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2005-12-18 22:08:13 +0000 |
---|---|---|
committer | tom_at_work <tom_at_work@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2005-12-18 22:08:13 +0000 |
commit | d2a13fe6cc0f4cffaa7ac14515fc78828ca83f51 (patch) | |
tree | d6d4a8c475e9fca3be7bc35a7ce23960e784fe12 /compiler/powerpc64 | |
parent | 8caebd08f1ff07b0fb0b0cec66feab45b1304715 (diff) | |
download | fpc-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.pas | 9 | ||||
-rw-r--r-- | compiler/powerpc64/cpupara.pas | 34 | ||||
-rw-r--r-- | compiler/powerpc64/nppccal.pas | 12 |
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. |