mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 05:08:06 +02:00
* Stack setup for MIPS and MIPSEL
git-svn-id: trunk@21537 -
This commit is contained in:
parent
4d8ebe5d1e
commit
22eae1b337
@ -30,8 +30,25 @@ interface
|
||||
cpubase,cpuinfo,
|
||||
symconst,symbase,symsym,symtype,symdef,paramgr,parabase,cgbase;
|
||||
|
||||
const
|
||||
MIPS_MAX_OFFSET = 20;
|
||||
MIPS_MAX_REGISTERS_USED_IN_CALL = 6;
|
||||
MIPS_FIRST_REGISTER_USED_IN_CALL = RS_R4;
|
||||
type
|
||||
tparasupregs = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of tsuperregister;
|
||||
tparasupregsused = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of boolean;
|
||||
tparasupregsoffset = array[0..MIPS_MAX_REGISTERS_USED_IN_CALL-1] of longint;
|
||||
pparasupregs = ^tparasupregs;
|
||||
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);
|
||||
|
||||
type
|
||||
TMIPSParaManager=class(TParaManager)
|
||||
var
|
||||
param_offset:array[0..MIPS_MAX_OFFSET] of ^Aint;
|
||||
intparareg,
|
||||
parasize : longint;
|
||||
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
|
||||
function get_volatile_registers_int(calloption : tproccalloption):TCpuRegisterSet;override;
|
||||
function get_volatile_registers_fpu(calloption : tproccalloption):TCpuRegisterSet;override;
|
||||
@ -44,23 +61,16 @@ interface
|
||||
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
|
||||
private
|
||||
procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||
procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
|
||||
var intparareg,parasize:longint);
|
||||
procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
cutils,verbose,systems,
|
||||
defutil,
|
||||
defutil, cpupi, procinfo,
|
||||
cgutils,cgobj;
|
||||
|
||||
type
|
||||
tparasupregs = array[0..5] of tsuperregister;
|
||||
pparasupregs = ^tparasupregs;
|
||||
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);
|
||||
|
||||
|
||||
function TMIPSParaManager.get_volatile_registers_int(calloption : tproccalloption):TCpuRegisterSet;
|
||||
@ -90,17 +100,22 @@ implementation
|
||||
begin
|
||||
{ The six first parameters are passed into registers } {MIPS first four}
|
||||
dec(nr);
|
||||
if nr<6 then //MIPSEL nr<6
|
||||
if nr<MIPS_MAX_REGISTERS_USED_IN_CALL then //MIPSEL nr<6
|
||||
begin
|
||||
loc:=LOC_REGISTER;
|
||||
register:=newreg(R_INTREGISTER,(RS_R4+nr),R_SUBWHOLE);
|
||||
register:=newreg(R_INTREGISTER,paraoutsupregs[nr],R_SUBWHOLE);
|
||||
if assigned(current_procinfo) then
|
||||
begin
|
||||
TMIPSProcInfo(current_procinfo).register_used[nr]:=true;
|
||||
TMIPSProcInfo(current_procinfo).register_offset[nr]:=nr*4;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ The other parameters are passed on the stack }
|
||||
loc:=LOC_REFERENCE;
|
||||
reference.index:=NR_STACK_POINTER_REG;
|
||||
reference.offset:=92+(nr-6)*4;
|
||||
reference.offset:={92+(nr-6)*4;} nr*4;
|
||||
end;
|
||||
size:=OS_INT;
|
||||
end;
|
||||
@ -169,12 +184,26 @@ implementation
|
||||
result.intsize:=def.size;
|
||||
end;
|
||||
result.size:=retcgsize;
|
||||
{ Return is passed as var parameter }
|
||||
{ Return is passed as var parameter,
|
||||
in this case we use the first register R4 for it }
|
||||
if ret_in_param(def,p.proccalloption) then
|
||||
begin
|
||||
paraloc:=result.add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=retcgsize;
|
||||
{ Reserve first register for ret_in_param }
|
||||
if intparareg=0 then
|
||||
inc(intparareg);
|
||||
if side=calleeside then
|
||||
begin
|
||||
paraloc:=result.add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG;
|
||||
{ return is at offset zero }
|
||||
paraloc^.reference.offset:=0;
|
||||
paraloc^.size:=retcgsize;
|
||||
end
|
||||
else
|
||||
begin
|
||||
getIntParaLoc(p.proccalloption,1,result);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
@ -223,11 +252,8 @@ implementation
|
||||
end
|
||||
end;
|
||||
|
||||
var
|
||||
param_offset:array[0..20] of ^Aint;
|
||||
|
||||
procedure TMIPSParaManager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
|
||||
var intparareg,parasize:longint);
|
||||
procedure TMIPSParaManager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist);
|
||||
var
|
||||
paraloc : pcgparalocation;
|
||||
i : integer;
|
||||
@ -242,8 +268,8 @@ implementation
|
||||
hparasupregs:=@parainsupregs;
|
||||
for i:=0 to paras.count-1 do
|
||||
begin
|
||||
|
||||
param_offset[i] := Nil;
|
||||
if i<=MIPS_MAX_OFFSET then
|
||||
param_offset[i] := Nil;
|
||||
hp:=tparavarsym(paras[i]);
|
||||
{ currently only support C-style array of const,
|
||||
there should be no location assigned to the vararg array itself }
|
||||
@ -283,17 +309,26 @@ implementation
|
||||
{ ret in param? }
|
||||
if vo_is_funcret in hp.varoptions then
|
||||
begin
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
{ This should be the first parameter }
|
||||
if assigned(current_procinfo) then
|
||||
begin
|
||||
TMIPSProcInfo(current_procinfo).register_used[0]:=true;
|
||||
TMIPSProcInfo(current_procinfo).register_offset[0]:=0;
|
||||
end;
|
||||
//if (intparareg<>1) then
|
||||
// Comment(V_Warning,'intparareg should be one for funcret in TMipsParaManager.create_paraloc_info_intern');
|
||||
if side=callerside then
|
||||
begin
|
||||
paraloc^.reference.index := NR_STACK_POINTER_REG;
|
||||
paraloc^.reference.offset:=parasize;
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
paraloc^.register:=newreg(R_INTREGISTER,hparasupregs^[0],R_SUBWHOLE);
|
||||
end
|
||||
else
|
||||
begin
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.reference.index := NR_FRAME_POINTER_REG;
|
||||
paraloc^.reference.offset:=target_info.first_parm_offset+parasize;
|
||||
param_offset[i] := @paraloc^.reference.offset;
|
||||
paraloc^.reference.offset:=0;
|
||||
if i<=MIPS_MAX_OFFSET then
|
||||
param_offset[i] := @paraloc^.reference.offset;
|
||||
end;
|
||||
inc(parasize,align(tcgsize2size[paraloc^.size],sizeof(aint)));
|
||||
end
|
||||
@ -303,9 +338,27 @@ implementation
|
||||
(not(vo_is_parentfp in hp.varoptions) or
|
||||
not(po_delphi_nested_cc in p.procoptions)) then
|
||||
begin
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
paraloc^.register:=newreg(R_INTREGISTER,hparasupregs^[intparareg],R_SUBWHOLE);
|
||||
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
|
||||
begin
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
paraloc^.register:=newreg(R_INTREGISTER,hparasupregs^[intparareg],R_SUBWHOLE);
|
||||
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)));
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -317,9 +370,13 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
paraloc^.reference.index := {NR_R18;//}NR_FRAME_POINTER_REG;
|
||||
paraloc^.reference.offset:=target_info.first_parm_offset+parasize;
|
||||
param_offset[i] := @paraloc^.reference.offset;
|
||||
//if assigned(current_procinfo) then
|
||||
// paraloc^.reference.index := current_procinfo.framepointer
|
||||
//else
|
||||
paraloc^.reference.index := {NR_R18;//}NR_FRAME_POINTER_REG;
|
||||
paraloc^.reference.offset:=parasize;
|
||||
if i<=MIPS_MAX_OFFSET then
|
||||
param_offset[i] := @paraloc^.reference.offset;
|
||||
end;
|
||||
{ Parameters are aligned at 4 bytes }
|
||||
inc(parasize,align(tcgsize2size[paraloc^.size],sizeof(aint)));
|
||||
@ -338,31 +395,27 @@ implementation
|
||||
|
||||
|
||||
function TMIPSParaManager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
|
||||
var
|
||||
intparareg,
|
||||
parasize : longint;
|
||||
begin
|
||||
intparareg:=0;
|
||||
parasize:=0;
|
||||
{ Create Function result paraloc }
|
||||
create_funcretloc_info(p,callerside);
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_paraloc_info_intern(p,callerside,p.paras,intparareg,parasize);
|
||||
create_paraloc_info_intern(p,callerside,p.paras);
|
||||
{ append the varargs }
|
||||
create_paraloc_info_intern(p,callerside,varargspara,intparareg,parasize);
|
||||
create_paraloc_info_intern(p,callerside,varargspara);
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function TMIPSParaManager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
||||
var
|
||||
intparareg,
|
||||
parasize : longint;
|
||||
begin
|
||||
intparareg:=0;
|
||||
parasize:=0;
|
||||
create_paraloc_info_intern(p,side,p.paras,intparareg,parasize);
|
||||
{ Create Function result paraloc }
|
||||
create_funcretloc_info(p,side);
|
||||
create_paraloc_info_intern(p,side,p.paras);
|
||||
{ We need to return the size allocated on the stack }
|
||||
result:=parasize;
|
||||
end;
|
||||
|
@ -28,7 +28,7 @@ interface
|
||||
uses
|
||||
cutils,
|
||||
globtype,
|
||||
procinfo,cpuinfo,
|
||||
procinfo,cpuinfo,cpupara,
|
||||
psub;
|
||||
|
||||
type
|
||||
@ -40,6 +40,8 @@ interface
|
||||
floatregstart : aint;
|
||||
intregssave,
|
||||
floatregssave : byte;
|
||||
register_used : tparasupregsused;
|
||||
register_offset : tparasupregsoffset;
|
||||
constructor create(aparent:tprocinfo);override;
|
||||
function calc_stackframe_size:longint;override;
|
||||
procedure set_first_temp_offset;override;
|
||||
@ -53,8 +55,16 @@ implementation
|
||||
tgobj,paramgr,symconst;
|
||||
|
||||
constructor TMIPSProcInfo.create(aparent: tprocinfo);
|
||||
var
|
||||
i : longint;
|
||||
begin
|
||||
inherited create(aparent);
|
||||
for i:=low(tparasupregs) to high(tparasupregs) do
|
||||
begin
|
||||
register_used[i]:=false;
|
||||
register_offset[i]:=-1;
|
||||
end;
|
||||
|
||||
floatregssave:=11;
|
||||
intregssave:=10;
|
||||
end;
|
||||
@ -81,6 +91,7 @@ implementation
|
||||
floatregstart:=result;
|
||||
inc(result,floatregssave*4);
|
||||
intregstart:=result;
|
||||
inc(result,intregssave*4);
|
||||
result:=Align(tg.lasttemp,max(current_settings.alignment.localalignmin,8));
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user