|
@@ -33,15 +33,38 @@ interface
|
|
const
|
|
const
|
|
MIPS_MAX_OFFSET = 20;
|
|
MIPS_MAX_OFFSET = 20;
|
|
MIPS_MAX_REGISTERS_USED_IN_CALL = 6;
|
|
MIPS_MAX_REGISTERS_USED_IN_CALL = 6;
|
|
|
|
+
|
|
|
|
+ { All ABI seem to start with $4 i.e. $a0 }
|
|
MIPS_FIRST_REGISTER_USED_IN_CALL = RS_R4;
|
|
MIPS_FIRST_REGISTER_USED_IN_CALL = RS_R4;
|
|
|
|
+ { O32 ABI uses $a0 to $a3, i.e R4 to R7 }
|
|
|
|
+ MIPS_LAST_REGISTER_USED_IN_CALL_ABI_O32 = RS_R7;
|
|
|
|
+ { N32 ABI uses also R8 and R9 }
|
|
|
|
+ MIPS_LAST_REGISTER_USED_IN_CALL_ABI_N32 = RS_R9;
|
|
|
|
+ { The calculation below is based on the assumption
|
|
|
|
+ that all registers used for ABI calls are
|
|
|
|
+ ordered and follow each other }
|
|
|
|
+ MIPS_NB_REGISTERS_USED_IN_CALL_O32 =
|
|
|
|
+ MIPS_LAST_REGISTER_USED_IN_CALL_ABI_O32
|
|
|
|
+ - MIPS_FIRST_REGISTER_USED_IN_CALL + 1;
|
|
|
|
+ MIPS_NB_REGISTERS_USED_IN_CALL_N32 =
|
|
|
|
+ MIPS_LAST_REGISTER_USED_IN_CALL_ABI_N32
|
|
|
|
+ - MIPS_FIRST_REGISTER_USED_IN_CALL + 1;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ { Set O32 ABI as default }
|
|
|
|
+ const
|
|
|
|
+ mips_nb_used_registers = MIPS_NB_REGISTERS_USED_IN_CALL_O32;
|
|
|
|
+
|
|
|
|
+ { Might need to be changed if we support N64 ABI later }
|
|
|
|
+ mips_sizeof_register_param = 4;
|
|
|
|
+
|
|
type
|
|
type
|
|
tparasupregs = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of tsuperregister;
|
|
tparasupregs = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of tsuperregister;
|
|
tparasupregsused = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of boolean;
|
|
tparasupregsused = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of boolean;
|
|
tparasupregsoffset = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of longint;
|
|
tparasupregsoffset = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of longint;
|
|
- pparasupregs = ^tparasupregs;
|
|
|
|
|
|
+
|
|
const
|
|
const
|
|
- paraoutsupregs : tparasupregs = (RS_R4, RS_R5, RS_R6, RS_R7, RS_R8, RS_R9);
|
|
|
|
- parainsupregs : tparasupregs = (RS_R4, RS_R5, RS_R6, RS_R7, RS_R8, RS_R9);
|
|
|
|
|
|
+ parasupregs : tparasupregs = (RS_R4, RS_R5, RS_R6, RS_R7, RS_R8, RS_R9);
|
|
|
|
|
|
type
|
|
type
|
|
TMIPSParaManager=class(TParaManager)
|
|
TMIPSParaManager=class(TParaManager)
|
|
@@ -75,13 +98,15 @@ implementation
|
|
|
|
|
|
function TMIPSParaManager.get_volatile_registers_int(calloption : tproccalloption):TCpuRegisterSet;
|
|
function TMIPSParaManager.get_volatile_registers_int(calloption : tproccalloption):TCpuRegisterSet;
|
|
begin
|
|
begin
|
|
|
|
+ { O32 ABI values }
|
|
result:=[RS_R1..RS_R15,RS_R24..RS_R25,RS_R31];
|
|
result:=[RS_R1..RS_R15,RS_R24..RS_R25,RS_R31];
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
function TMIPSParaManager.get_volatile_registers_fpu(calloption : tproccalloption):TCpuRegisterSet;
|
|
function TMIPSParaManager.get_volatile_registers_fpu(calloption : tproccalloption):TCpuRegisterSet;
|
|
begin
|
|
begin
|
|
- result:=[RS_F0..RS_F19,RS_F31];
|
|
|
|
|
|
+ { O32 ABI values }
|
|
|
|
+ result:=[RS_F0..RS_F19];
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -98,16 +123,17 @@ implementation
|
|
paraloc:=cgpara.add_location;
|
|
paraloc:=cgpara.add_location;
|
|
with paraloc^ do
|
|
with paraloc^ do
|
|
begin
|
|
begin
|
|
- { The six first parameters are passed into registers } {MIPS first four}
|
|
|
|
|
|
+ { MIPS: ABI dependent number of first parameters
|
|
|
|
+ are passed into registers }
|
|
dec(nr);
|
|
dec(nr);
|
|
- if nr<MIPS_MAX_REGISTERS_USED_IN_CALL then //MIPSEL nr<6
|
|
|
|
|
|
+ if nr<mips_nb_used_registers then
|
|
begin
|
|
begin
|
|
loc:=LOC_REGISTER;
|
|
loc:=LOC_REGISTER;
|
|
- register:=newreg(R_INTREGISTER,paraoutsupregs[nr],R_SUBWHOLE);
|
|
|
|
|
|
+ register:=newreg(R_INTREGISTER,parasupregs[nr],R_SUBWHOLE);
|
|
if assigned(current_procinfo) then
|
|
if assigned(current_procinfo) then
|
|
begin
|
|
begin
|
|
TMIPSProcInfo(current_procinfo).register_used[nr]:=true;
|
|
TMIPSProcInfo(current_procinfo).register_used[nr]:=true;
|
|
- TMIPSProcInfo(current_procinfo).register_offset[nr]:=nr*4;
|
|
|
|
|
|
+ TMIPSProcInfo(current_procinfo).register_offset[nr]:=nr*mips_sizeof_register_param;
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
@@ -115,7 +141,7 @@ implementation
|
|
{ The other parameters are passed on the stack }
|
|
{ The other parameters are passed on the stack }
|
|
loc:=LOC_REFERENCE;
|
|
loc:=LOC_REFERENCE;
|
|
reference.index:=NR_STACK_POINTER_REG;
|
|
reference.index:=NR_STACK_POINTER_REG;
|
|
- reference.offset:={92+(nr-6)*4;} nr*4;
|
|
|
|
|
|
+ reference.offset:=nr*mips_sizeof_register_param;
|
|
end;
|
|
end;
|
|
size:=OS_INT;
|
|
size:=OS_INT;
|
|
end;
|
|
end;
|
|
@@ -132,11 +158,18 @@ implementation
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
case def.typ of
|
|
case def.typ of
|
|
- recorddef,
|
|
|
|
- arraydef,
|
|
|
|
|
|
+ recorddef:
|
|
|
|
+ result:=true;
|
|
|
|
+ { According to 032 ABI we should have
|
|
|
|
+ result:=false; buut this cmpletely fails }
|
|
|
|
+ arraydef:
|
|
|
|
+ result:=true; {(tarraydef(def).highrange>=tarraydef(def).lowrange) or
|
|
|
|
+ is_open_array(def) or
|
|
|
|
+ is_array_of_const(def) or
|
|
|
|
+ is_array_constructor(def);}
|
|
variantdef,
|
|
variantdef,
|
|
formaldef :
|
|
formaldef :
|
|
- push_addr_param:=true;
|
|
|
|
|
|
+ result:=true;
|
|
objectdef :
|
|
objectdef :
|
|
result:=is_object(def);
|
|
result:=is_object(def);
|
|
stringdef :
|
|
stringdef :
|
|
@@ -220,7 +253,7 @@ implementation
|
|
else
|
|
else
|
|
{ Return in register }
|
|
{ Return in register }
|
|
begin
|
|
begin
|
|
-{$ifndef cpu64bitaddr}
|
|
|
|
|
|
+{$ifndef cpu64bitalu}
|
|
if retcgsize in [OS_64,OS_S64] then
|
|
if retcgsize in [OS_64,OS_S64] then
|
|
begin
|
|
begin
|
|
{ low }
|
|
{ low }
|
|
@@ -240,7 +273,7 @@ implementation
|
|
paraloc^.size:=OS_32;
|
|
paraloc^.size:=OS_32;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
-{$endif cpu64bitaddr}
|
|
|
|
|
|
+{$endif cpu64bitalu}
|
|
begin
|
|
begin
|
|
paraloc^.loc:=LOC_REGISTER;
|
|
paraloc^.loc:=LOC_REGISTER;
|
|
paraloc^.size:=retcgsize;
|
|
paraloc^.size:=retcgsize;
|
|
@@ -259,22 +292,26 @@ implementation
|
|
i : integer;
|
|
i : integer;
|
|
hp : tparavarsym;
|
|
hp : tparavarsym;
|
|
paracgsize : tcgsize;
|
|
paracgsize : tcgsize;
|
|
- hparasupregs : pparasupregs;
|
|
|
|
paralen : longint;
|
|
paralen : longint;
|
|
|
|
+ paradef : tdef;
|
|
|
|
+ fpparareg : integer;
|
|
|
|
+ can_use_float : boolean;
|
|
|
|
+ reg : tsuperregister;
|
|
|
|
+ alignment : longint;
|
|
|
|
+ tmp : longint;
|
|
begin
|
|
begin
|
|
- if side=callerside then
|
|
|
|
- hparasupregs:=@paraoutsupregs
|
|
|
|
- else
|
|
|
|
- hparasupregs:=@parainsupregs;
|
|
|
|
|
|
+ fpparareg := 0;
|
|
|
|
+ can_use_float := true;
|
|
for i:=0 to paras.count-1 do
|
|
for i:=0 to paras.count-1 do
|
|
begin
|
|
begin
|
|
if i<=MIPS_MAX_OFFSET then
|
|
if i<=MIPS_MAX_OFFSET then
|
|
param_offset[i] := Nil;
|
|
param_offset[i] := Nil;
|
|
hp:=tparavarsym(paras[i]);
|
|
hp:=tparavarsym(paras[i]);
|
|
- { currently only support C-style array of const,
|
|
|
|
- there should be no location assigned to the vararg array itself }
|
|
|
|
- if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
|
|
|
|
- is_array_of_const(hp.vardef) then
|
|
|
|
|
|
+ paradef := hp.vardef;
|
|
|
|
+
|
|
|
|
+ { currently only support C-style array of const }
|
|
|
|
+ if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
|
|
|
|
+ is_array_of_const(paradef) then
|
|
begin
|
|
begin
|
|
paraloc:=hp.paraloc[side].add_location;
|
|
paraloc:=hp.paraloc[side].add_location;
|
|
{ hack: the paraloc must be valid, but is not actually used }
|
|
{ hack: the paraloc must be valid, but is not actually used }
|
|
@@ -284,25 +321,56 @@ implementation
|
|
break;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
|
|
- if push_addr_param(hp.varspez,hp.vardef,p.proccalloption) then
|
|
|
|
- paracgsize:=OS_ADDR
|
|
|
|
|
|
+ if (push_addr_param(hp.varspez,paradef,p.proccalloption)) then
|
|
|
|
+ begin
|
|
|
|
+ paracgsize := OS_ADDR;
|
|
|
|
+ paralen := tcgsize2size[paracgsize];
|
|
|
|
+ end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- paracgsize:=def_cgSize(hp.vardef);
|
|
|
|
- if paracgsize=OS_NO then
|
|
|
|
- paracgsize:=OS_ADDR;
|
|
|
|
|
|
+ paracgsize := def_cgsize(paradef);
|
|
|
|
+ { for things like formaldef }
|
|
|
|
+ if (paracgsize=OS_NO) then
|
|
|
|
+ begin
|
|
|
|
+ paracgsize:=OS_ADDR;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if not is_special_array(paradef) then
|
|
|
|
+ paralen := paradef.size
|
|
|
|
+ else
|
|
|
|
+ paralen := tcgsize2size[paracgsize];
|
|
end;
|
|
end;
|
|
|
|
+
|
|
|
|
+ if (paracgsize in [OS_64, OS_S64, OS_F64]) or (hp.vardef.alignment = 8) then
|
|
|
|
+ alignment := 8
|
|
|
|
+ else
|
|
|
|
+ alignment := 4;
|
|
hp.paraloc[side].reset;
|
|
hp.paraloc[side].reset;
|
|
- hp.paraloc[side].size:=paracgsize;
|
|
|
|
- hp.paraloc[side].Alignment:=std_param_align;
|
|
|
|
|
|
+ hp.paraloc[side].Alignment:=alignment;
|
|
paralen:=tcgsize2size[paracgsize];
|
|
paralen:=tcgsize2size[paracgsize];
|
|
hp.paraloc[side].intsize:=paralen;
|
|
hp.paraloc[side].intsize:=paralen;
|
|
|
|
+ hp.paraloc[side].size:=paracgsize;
|
|
|
|
+ { check the alignment, mips O32ABI require a nature alignment }
|
|
|
|
+ tmp := align(parasize, alignment) - parasize;
|
|
|
|
+ while tmp > 0 do
|
|
|
|
+ begin
|
|
|
|
+ inc(intparareg);
|
|
|
|
+ inc(parasize,4);
|
|
|
|
+ dec(tmp,4);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ { any non-float args will disable the use the floating regs }
|
|
|
|
+ { up to two fp args }
|
|
|
|
+ if (not(paracgsize in [OS_F32, OS_F64])) or (fpparareg = 2) then
|
|
|
|
+ can_use_float := false;
|
|
|
|
+
|
|
while paralen>0 do
|
|
while paralen>0 do
|
|
begin
|
|
begin
|
|
paraloc:=hp.paraloc[side].add_location;
|
|
paraloc:=hp.paraloc[side].add_location;
|
|
- { Floats are passed in int registers,
|
|
|
|
- We can allocate at maximum 32 bits per register }
|
|
|
|
- if paracgsize in [OS_64,OS_S64,OS_F32,OS_F64] then
|
|
|
|
|
|
+ { We can allocate at maximum 32 bits per register }
|
|
|
|
+ if (paracgsize in [OS_64,OS_S64]) or
|
|
|
|
+ ((paracgsize in [OS_F32,OS_F64]) and
|
|
|
|
+ not(can_use_float)) then
|
|
paraloc^.size:=OS_32
|
|
paraloc^.size:=OS_32
|
|
else
|
|
else
|
|
paraloc^.size:=paracgsize;
|
|
paraloc^.size:=paracgsize;
|
|
@@ -320,12 +388,19 @@ implementation
|
|
if side=callerside then
|
|
if side=callerside then
|
|
begin
|
|
begin
|
|
paraloc^.loc:=LOC_REGISTER;
|
|
paraloc^.loc:=LOC_REGISTER;
|
|
- paraloc^.register:=newreg(R_INTREGISTER,hparasupregs^[0],R_SUBWHOLE);
|
|
|
|
|
|
+ paraloc^.register:=newreg(R_INTREGISTER,parasupregs[0],R_SUBWHOLE);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
paraloc^.loc:=LOC_REFERENCE;
|
|
paraloc^.loc:=LOC_REFERENCE;
|
|
- paraloc^.reference.index := NR_FRAME_POINTER_REG;
|
|
|
|
|
|
+ if (po_nostackframe in p.procoptions) then
|
|
|
|
+ paraloc^.reference.index := NR_STACK_POINTER_REG
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ paraloc^.reference.index := NR_FRAME_POINTER_REG;
|
|
|
|
+ if assigned(current_procinfo) then
|
|
|
|
+ TMIPSProcinfo(current_procinfo).needs_frame_pointer := true;
|
|
|
|
+ end;
|
|
paraloc^.reference.offset:=0;
|
|
paraloc^.reference.offset:=0;
|
|
if i<=MIPS_MAX_OFFSET then
|
|
if i<=MIPS_MAX_OFFSET then
|
|
param_offset[i] := @paraloc^.reference.offset;
|
|
param_offset[i] := @paraloc^.reference.offset;
|
|
@@ -334,63 +409,89 @@ implementation
|
|
end
|
|
end
|
|
{ In case of po_delphi_nested_cc, the parent frame pointer
|
|
{ In case of po_delphi_nested_cc, the parent frame pointer
|
|
is always passed on the stack. }
|
|
is always passed on the stack. }
|
|
- else if (intparareg<=high(tparasupregs)) and
|
|
|
|
|
|
+ else if (intparareg<mips_nb_used_registers) and
|
|
(not(vo_is_parentfp in hp.varoptions) or
|
|
(not(vo_is_parentfp in hp.varoptions) or
|
|
not(po_delphi_nested_cc in p.procoptions)) then
|
|
not(po_delphi_nested_cc in p.procoptions)) then
|
|
begin
|
|
begin
|
|
- if assigned(current_procinfo) then
|
|
|
|
- begin
|
|
|
|
- TMIPSProcInfo(current_procinfo).register_used[intparareg]:=true;
|
|
|
|
- TMIPSProcInfo(current_procinfo).register_offset[intparareg]:=intparareg*4;
|
|
|
|
- end;
|
|
|
|
- if side=callerside then
|
|
|
|
|
|
+ if (can_use_float) then
|
|
begin
|
|
begin
|
|
- paraloc^.loc:=LOC_REGISTER;
|
|
|
|
- paraloc^.register:=newreg(R_INTREGISTER,hparasupregs^[intparareg],R_SUBWHOLE);
|
|
|
|
|
|
+ paraloc^.loc:=LOC_FPUREGISTER;
|
|
|
|
+ if (fpparareg = 0) then
|
|
|
|
+ reg := RS_F12
|
|
|
|
+ else
|
|
|
|
+ reg := RS_F14;
|
|
|
|
+ if (paraloc^.size = OS_F64) then
|
|
|
|
+ begin
|
|
|
|
+ paraloc^.register:=newreg(R_FPUREGISTER, reg, R_SUBFD);
|
|
|
|
+ inc(fpparareg);
|
|
|
|
+ inc(intparareg);
|
|
|
|
+ inc(intparareg);
|
|
|
|
+ inc(parasize,8);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ paraloc^.register:=newreg(R_FPUREGISTER, reg, R_SUBFS);
|
|
|
|
+ inc(fpparareg);
|
|
|
|
+ inc(intparareg);
|
|
|
|
+ inc(parasize,sizeof(aint));
|
|
|
|
+ end;
|
|
end
|
|
end
|
|
- else
|
|
|
|
- begin
|
|
|
|
- paraloc^.loc:=LOC_REFERENCE;
|
|
|
|
- //if assigned(current_procinfo) then
|
|
|
|
- // paraloc^.reference.index := current_procinfo.framepointer
|
|
|
|
- //else
|
|
|
|
- paraloc^.reference.index := NR_FRAME_POINTER_REG;
|
|
|
|
- paraloc^.reference.offset:=intparareg*sizeof(aint);
|
|
|
|
- end;
|
|
|
|
- inc(intparareg);
|
|
|
|
- inc(parasize,align(tcgsize2size[paraloc^.size],sizeof(aint)));
|
|
|
|
|
|
+ else { not can use float }
|
|
|
|
+ begin
|
|
|
|
+ if assigned(current_procinfo) then
|
|
|
|
+ begin
|
|
|
|
+ TMIPSProcInfo(current_procinfo).register_used[intparareg]:=true;
|
|
|
|
+ TMIPSProcInfo(current_procinfo).register_offset[intparareg]:=intparareg*mips_sizeof_register_param;
|
|
|
|
+ end;
|
|
|
|
+ if side=callerside then
|
|
|
|
+ begin
|
|
|
|
+ paraloc^.loc:=LOC_REGISTER;
|
|
|
|
+ paraloc^.register:=newreg(R_INTREGISTER,parasupregs[intparareg],R_SUBWHOLE);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ paraloc^.loc:=LOC_REFERENCE;
|
|
|
|
+ if (po_nostackframe in p.procoptions) then
|
|
|
|
+ paraloc^.reference.index := NR_STACK_POINTER_REG
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ paraloc^.reference.index := NR_FRAME_POINTER_REG;
|
|
|
|
+ if assigned(current_procinfo) then
|
|
|
|
+ TMIPSProcinfo(current_procinfo).needs_frame_pointer := true;
|
|
|
|
+ end;
|
|
|
|
+ paraloc^.reference.offset:=intparareg*mips_sizeof_register_param;
|
|
|
|
+ end;
|
|
|
|
+ inc(intparareg);
|
|
|
|
+ inc(parasize,align(tcgsize2size[paraloc^.size],mips_sizeof_register_param));
|
|
|
|
+ end;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
paraloc^.loc:=LOC_REFERENCE;
|
|
paraloc^.loc:=LOC_REFERENCE;
|
|
if side=callerside then
|
|
if side=callerside then
|
|
begin
|
|
begin
|
|
- paraloc^.reference.index := {NR_R17;//}NR_STACK_POINTER_REG;
|
|
|
|
|
|
+ paraloc^.reference.index := NR_STACK_POINTER_REG;
|
|
paraloc^.reference.offset:=parasize;
|
|
paraloc^.reference.offset:=parasize;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- //if assigned(current_procinfo) then
|
|
|
|
- // paraloc^.reference.index := current_procinfo.framepointer
|
|
|
|
- //else
|
|
|
|
- paraloc^.reference.index := {NR_R18;//}NR_FRAME_POINTER_REG;
|
|
|
|
|
|
+ if (po_nostackframe in p.procoptions) then
|
|
|
|
+ paraloc^.reference.index := NR_STACK_POINTER_REG
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ paraloc^.reference.index := NR_FRAME_POINTER_REG;
|
|
|
|
+ if assigned(current_procinfo) then
|
|
|
|
+ TMIPSProcinfo(current_procinfo).needs_frame_pointer := true;
|
|
|
|
+ end;
|
|
paraloc^.reference.offset:=parasize;
|
|
paraloc^.reference.offset:=parasize;
|
|
if i<=MIPS_MAX_OFFSET then
|
|
if i<=MIPS_MAX_OFFSET then
|
|
param_offset[i] := @paraloc^.reference.offset;
|
|
param_offset[i] := @paraloc^.reference.offset;
|
|
end;
|
|
end;
|
|
- { Parameters are aligned at 4 bytes }
|
|
|
|
- inc(parasize,align(tcgsize2size[paraloc^.size],sizeof(aint)));
|
|
|
|
|
|
+ inc(parasize,align(tcgsize2size[paraloc^.size],mips_sizeof_register_param));
|
|
end;
|
|
end;
|
|
dec(paralen,tcgsize2size[paraloc^.size]);
|
|
dec(paralen,tcgsize2size[paraloc^.size]);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
- {
|
|
|
|
- for i:=0 to paras.count-1 do
|
|
|
|
- begin
|
|
|
|
- if (side = calleeside) and (param_offset[i] <> nil) then
|
|
|
|
- param_offset[i]^ := param_offset[i]^ + parasize - 8;
|
|
|
|
- end;
|
|
|
|
- }
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -404,6 +505,11 @@ implementation
|
|
create_paraloc_info_intern(p,callerside,p.paras);
|
|
create_paraloc_info_intern(p,callerside,p.paras);
|
|
{ append the varargs }
|
|
{ append the varargs }
|
|
create_paraloc_info_intern(p,callerside,varargspara);
|
|
create_paraloc_info_intern(p,callerside,varargspara);
|
|
|
|
+ { At least 16 bytes must be reserved for parameter
|
|
|
|
+ area in O32 ABI, this can be used by called function,
|
|
|
|
+ even if it has less parameter }
|
|
|
|
+ if (parasize < 16) then
|
|
|
|
+ parasize := 16;
|
|
result:=parasize;
|
|
result:=parasize;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -417,6 +523,11 @@ implementation
|
|
create_funcretloc_info(p,side);
|
|
create_funcretloc_info(p,side);
|
|
create_paraloc_info_intern(p,side,p.paras);
|
|
create_paraloc_info_intern(p,side,p.paras);
|
|
{ We need to return the size allocated on the stack }
|
|
{ We need to return the size allocated on the stack }
|
|
|
|
+ { At least 16 bytes must be reserved for parameter
|
|
|
|
+ area in O32 ABI, this can be used by called function,
|
|
|
|
+ even if it has less parameter }
|
|
|
|
+ if (parasize < 16) then
|
|
|
|
+ parasize := 16;
|
|
result:=parasize;
|
|
result:=parasize;
|
|
end;
|
|
end;
|
|
|
|
|