|
@@ -50,6 +50,7 @@ unit cpupara;
|
|
|
var sparesinglereg: tregister);
|
|
|
function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
|
|
|
var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint;
|
|
|
+ procedure paradeftointparaloc(paradef: tdef; paracgsize: tcgsize; out paralocdef: tdef; out paralocsize: tcgsize);
|
|
|
end;
|
|
|
|
|
|
implementation
|
|
@@ -435,35 +436,20 @@ unit cpupara;
|
|
|
while paralen>0 do
|
|
|
begin
|
|
|
paraloc:=hp.paraloc[side].add_location;
|
|
|
-
|
|
|
- if (loc=LOC_REGISTER) and (paracgsize in [OS_F32,OS_F64,OS_F80]) then
|
|
|
- case paracgsize of
|
|
|
- OS_F32:
|
|
|
- begin
|
|
|
- paraloc^.size:=OS_32;
|
|
|
- paraloc^.def:=u32inttype;
|
|
|
- end;
|
|
|
- OS_F64:
|
|
|
- begin
|
|
|
- paraloc^.size:=OS_32;
|
|
|
- paraloc^.def:=u32inttype;
|
|
|
- end;
|
|
|
- else
|
|
|
- internalerror(2005082901);
|
|
|
- end
|
|
|
- else if (paracgsize in [OS_NO,OS_64,OS_S64]) then
|
|
|
- begin
|
|
|
- paraloc^.size:=OS_32;
|
|
|
- paraloc^.def:=u32inttype;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- paraloc^.size:=paracgsize;
|
|
|
- paraloc^.def:=get_paraloc_def(paradef,paralen,firstparaloc);
|
|
|
- end;
|
|
|
case loc of
|
|
|
LOC_REGISTER:
|
|
|
begin
|
|
|
+ if paracgsize in [OS_F32,OS_F64,OS_F80] then
|
|
|
+ case paracgsize of
|
|
|
+ OS_F32,
|
|
|
+ OS_F64:
|
|
|
+ begin
|
|
|
+ paraloc^.size:=OS_32;
|
|
|
+ paraloc^.def:=u32inttype;
|
|
|
+ end;
|
|
|
+ else
|
|
|
+ internalerror(2005082901);
|
|
|
+ end;
|
|
|
{ align registers for eabi }
|
|
|
if (target_info.abi in [abi_eabi,abi_eabihf]) and
|
|
|
firstparaloc and
|
|
@@ -474,19 +460,19 @@ unit cpupara;
|
|
|
else if nextintreg>RS_R3 then
|
|
|
stack_offset:=align(stack_offset,8);
|
|
|
end;
|
|
|
- { this is not abi compliant
|
|
|
- why? (FK) }
|
|
|
if nextintreg<=RS_R3 then
|
|
|
begin
|
|
|
+ paradeftointparaloc(paradef,paracgsize,paraloc^.def,paraloc^.size);
|
|
|
paraloc^.loc:=LOC_REGISTER;
|
|
|
paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
|
|
|
inc(nextintreg);
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
- { LOC_REFERENCE always contains everything that's left }
|
|
|
+ { LOC_REFERENCE always contains everything that's left as a multiple of 4 bytes}
|
|
|
paraloc^.loc:=LOC_REFERENCE;
|
|
|
- paraloc^.size:=int_cgsize(paralen);
|
|
|
+ paraloc^.def:=get_paraloc_def(paradef,paralen,firstparaloc);
|
|
|
+ paraloc^.size:=def_cgsize(paraloc^.def);
|
|
|
if (side=callerside) then
|
|
|
paraloc^.reference.index:=NR_STACK_POINTER_REG;
|
|
|
paraloc^.reference.offset:=stack_offset;
|
|
@@ -496,6 +482,8 @@ unit cpupara;
|
|
|
end;
|
|
|
LOC_FPUREGISTER:
|
|
|
begin
|
|
|
+ paraloc^.size:=paracgsize;
|
|
|
+ paraloc^.def:=paradef;
|
|
|
if nextfloatreg<=RS_F3 then
|
|
|
begin
|
|
|
paraloc^.loc:=LOC_FPUREGISTER;
|
|
@@ -523,6 +511,8 @@ unit cpupara;
|
|
|
end;
|
|
|
LOC_MMREGISTER:
|
|
|
begin
|
|
|
+ paraloc^.size:=paracgsize;
|
|
|
+ paraloc^.def:=paradef;
|
|
|
if (nextmmreg<=RS_D7) or
|
|
|
((paraloc^.size = OS_F32) and
|
|
|
(sparesinglereg<>NR_NO)) then
|
|
@@ -569,6 +559,8 @@ unit cpupara;
|
|
|
end;
|
|
|
LOC_REFERENCE:
|
|
|
begin
|
|
|
+ paraloc^.size:=paracgsize;
|
|
|
+ paraloc^.def:=paradef;
|
|
|
if push_addr_param(hp.varspez,paradef,p.proccalloption) then
|
|
|
begin
|
|
|
paraloc^.size:=OS_ADDR;
|
|
@@ -583,7 +575,6 @@ unit cpupara;
|
|
|
(paradef.alignment=8) then
|
|
|
stack_offset:=align(stack_offset,8);
|
|
|
|
|
|
- paraloc^.size:=paracgsize;
|
|
|
paraloc^.loc:=LOC_REFERENCE;
|
|
|
paraloc^.reference.index:=NR_STACK_POINTER_REG;
|
|
|
paraloc^.reference.offset:=stack_offset;
|
|
@@ -626,6 +617,23 @@ unit cpupara;
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ procedure tcpuparamanager.paradeftointparaloc(paradef: tdef; paracgsize: tcgsize; out paralocdef: tdef; out paralocsize: tcgsize);
|
|
|
+ begin
|
|
|
+ if not(paracgsize in [OS_32,OS_S32]) or
|
|
|
+ (paradef.typ in [arraydef,recorddef]) or
|
|
|
+ is_object(paradef) then
|
|
|
+ begin
|
|
|
+ paralocsize:=OS_32;
|
|
|
+ paralocdef:=u32inttype;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ paralocsize:=paracgsize;
|
|
|
+ paralocdef:=paradef;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
function tcpuparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
|
|
|
var
|
|
|
paraloc : pcgparalocation;
|
|
@@ -742,8 +750,7 @@ unit cpupara;
|
|
|
end;
|
|
|
else
|
|
|
begin
|
|
|
- paraloc^.size:=retcgsize;
|
|
|
- paraloc^.def:=result.def;
|
|
|
+ paradeftointparaloc(result.def,result.size,paraloc^.def,paraloc^.size);
|
|
|
end;
|
|
|
end;
|
|
|
end;
|