mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 03:09:11 +02:00
* basics for x86 register calling
This commit is contained in:
parent
49e539ac8d
commit
3a3d710c47
@ -813,7 +813,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ object pascal objects }
|
{ object pascal objects }
|
||||||
if (def_from.deftype=objectdef) and
|
if (def_from.deftype=objectdef) and
|
||||||
tobjectdef(def_from).is_related(tobjectdef(def_to)) then
|
(tobjectdef(def_from).is_related(tobjectdef(def_to)) or
|
||||||
|
tobjectdef(def_to).is_related(tobjectdef(def_from))) then
|
||||||
begin
|
begin
|
||||||
doconv:=tc_equal;
|
doconv:=tc_equal;
|
||||||
eq:=te_convert_l1;
|
eq:=te_convert_l1;
|
||||||
@ -1209,7 +1210,10 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.27 2003-06-03 21:02:08 peter
|
Revision 1.28 2003-09-09 21:03:17 peter
|
||||||
|
* basics for x86 register calling
|
||||||
|
|
||||||
|
Revision 1.27 2003/06/03 21:02:08 peter
|
||||||
* allow pointer(int64) in all modes
|
* allow pointer(int64) in all modes
|
||||||
|
|
||||||
Revision 1.26 2003/05/26 21:17:17 peter
|
Revision 1.26 2003/05/26 21:17:17 peter
|
||||||
|
@ -51,6 +51,10 @@ unit cpupara;
|
|||||||
function getparaloc(p : tdef) : tcgloc;
|
function getparaloc(p : tdef) : tcgloc;
|
||||||
procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);override;
|
procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);override;
|
||||||
function getselflocation(p : tabstractprocdef) : tparalocation;override;
|
function getselflocation(p : tabstractprocdef) : tparalocation;override;
|
||||||
|
private
|
||||||
|
procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||||
|
procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||||
|
procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -174,29 +178,10 @@ unit cpupara;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
procedure ti386paramanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||||
var
|
var
|
||||||
hp : tparaitem;
|
|
||||||
paraloc : tparalocation;
|
paraloc : tparalocation;
|
||||||
begin
|
begin
|
||||||
hp:=tparaitem(p.para.first);
|
|
||||||
while assigned(hp) do
|
|
||||||
begin
|
|
||||||
if hp.paratyp in [vs_var,vs_out] then
|
|
||||||
paraloc.size:=OS_ADDR
|
|
||||||
else
|
|
||||||
paraloc.size:=def_cgsize(hp.paratype.def);
|
|
||||||
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:=tvarsym(hp.parasym).adjusted_address;
|
|
||||||
hp.paraloc[side]:=paraloc;
|
|
||||||
{$warning callerparaloc shall not be the same as calleeparaloc}
|
|
||||||
hp:=tparaitem(hp.next);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ Function return }
|
{ Function return }
|
||||||
fillchar(paraloc,sizeof(tparalocation),0);
|
fillchar(paraloc,sizeof(tparalocation),0);
|
||||||
paraloc.size:=def_cgsize(p.rettype.def);
|
paraloc.size:=def_cgsize(p.rettype.def);
|
||||||
@ -231,6 +216,89 @@ unit cpupara;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure ti386paramanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||||
|
var
|
||||||
|
hp : tparaitem;
|
||||||
|
paraloc : tparalocation;
|
||||||
|
begin
|
||||||
|
hp:=tparaitem(p.para.first);
|
||||||
|
while assigned(hp) do
|
||||||
|
begin
|
||||||
|
if hp.paratyp in [vs_var,vs_out] then
|
||||||
|
paraloc.size:=OS_ADDR
|
||||||
|
else
|
||||||
|
paraloc.size:=def_cgsize(hp.paratype.def);
|
||||||
|
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:=tvarsym(hp.parasym).adjusted_address;
|
||||||
|
hp.paraloc[side]:=paraloc;
|
||||||
|
{$warning callerparaloc shall not be the same as calleeparaloc}
|
||||||
|
hp:=tparaitem(hp.next);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure ti386paramanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||||
|
var
|
||||||
|
hp : tparaitem;
|
||||||
|
paraloc : tparalocation;
|
||||||
|
sr : tsuperregister;
|
||||||
|
subreg : tsubregister;
|
||||||
|
begin
|
||||||
|
sr:=RS_EAX;
|
||||||
|
hp:=tparaitem(p.para.first);
|
||||||
|
while assigned(hp) do
|
||||||
|
begin
|
||||||
|
if hp.paratyp in [vs_var,vs_out] then
|
||||||
|
paraloc.size:=OS_ADDR
|
||||||
|
else
|
||||||
|
paraloc.size:=def_cgsize(hp.paratype.def);
|
||||||
|
{
|
||||||
|
EAX
|
||||||
|
EDX
|
||||||
|
ECX
|
||||||
|
Stack
|
||||||
|
Stack
|
||||||
|
}
|
||||||
|
if sr<=NR_ECX then
|
||||||
|
begin
|
||||||
|
paraloc.loc:=LOC_REGISTER;
|
||||||
|
if paraloc.size=OS_NO then
|
||||||
|
subreg:=R_SUBWHOLE
|
||||||
|
else
|
||||||
|
subreg:=cgsize2subreg(paraloc.size);
|
||||||
|
paraloc.register:=newreg(R_INTREGISTER,sr,subreg);
|
||||||
|
inc(sr);
|
||||||
|
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:=tvarsym(hp.parasym).adjusted_address;
|
||||||
|
end;
|
||||||
|
hp.paraloc[side]:=paraloc;
|
||||||
|
{$warning callerparaloc shall not be the same as calleeparaloc}
|
||||||
|
hp:=tparaitem(hp.next);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||||
|
begin
|
||||||
|
if p.proccalloption=pocall_register then
|
||||||
|
create_register_paraloc_info(p,side)
|
||||||
|
else
|
||||||
|
create_stdcall_paraloc_info(p,side);
|
||||||
|
create_funcret_paraloc_info(p,side);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ti386paramanager.getselflocation(p : tabstractprocdef) : tparalocation;
|
function ti386paramanager.getselflocation(p : tabstractprocdef) : tparalocation;
|
||||||
var
|
var
|
||||||
hsym : tvarsym;
|
hsym : tvarsym;
|
||||||
@ -250,7 +318,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.26 2003-09-09 15:55:05 peter
|
Revision 1.27 2003-09-09 21:03:17 peter
|
||||||
|
* basics for x86 register calling
|
||||||
|
|
||||||
|
Revision 1.26 2003/09/09 15:55:05 peter
|
||||||
* winapi doesn't like pushing 8 byte record
|
* winapi doesn't like pushing 8 byte record
|
||||||
|
|
||||||
Revision 1.25 2003/09/08 18:28:51 peter
|
Revision 1.25 2003/09/08 18:28:51 peter
|
||||||
|
@ -35,6 +35,7 @@ unit cpupi;
|
|||||||
ti386procinfo = class(tcgprocinfo)
|
ti386procinfo = class(tcgprocinfo)
|
||||||
procedure allocate_interrupt_parameter;override;
|
procedure allocate_interrupt_parameter;override;
|
||||||
procedure allocate_framepointer_reg;override;
|
procedure allocate_framepointer_reg;override;
|
||||||
|
procedure handle_body_start;override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -64,12 +65,21 @@ unit cpupi;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure ti386procinfo.handle_body_start;
|
||||||
|
begin
|
||||||
|
inherited handle_body_start;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cprocinfo:=ti386procinfo;
|
cprocinfo:=ti386procinfo;
|
||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.10 2003-09-03 15:55:01 peter
|
Revision 1.11 2003-09-09 21:03:17 peter
|
||||||
|
* basics for x86 register calling
|
||||||
|
|
||||||
|
Revision 1.10 2003/09/03 15:55:01 peter
|
||||||
* NEWRA branch merged
|
* NEWRA branch merged
|
||||||
|
|
||||||
Revision 1.9.2.1 2003/08/31 15:46:26 peter
|
Revision 1.9.2.1 2003/08/31 15:46:26 peter
|
||||||
|
@ -1699,7 +1699,8 @@ const
|
|||||||
end;
|
end;
|
||||||
pocall_register :
|
pocall_register :
|
||||||
begin
|
begin
|
||||||
Message1(parser_w_proc_directive_ignored,'REGISTER');
|
{ Adjust alignment to match cdecl or stdcall }
|
||||||
|
pd.parast.dataalignment:=std_param_align;
|
||||||
end;
|
end;
|
||||||
pocall_far16 :
|
pocall_far16 :
|
||||||
begin
|
begin
|
||||||
@ -1758,6 +1759,11 @@ const
|
|||||||
var
|
var
|
||||||
currpara : tparaitem;
|
currpara : tparaitem;
|
||||||
st : tsymtable;
|
st : tsymtable;
|
||||||
|
{$ifdef i386}
|
||||||
|
orgs : stringid;
|
||||||
|
vs : tvarsym;
|
||||||
|
n : integer;
|
||||||
|
{$endif i386}
|
||||||
begin
|
begin
|
||||||
{ insert hidden high parameters }
|
{ insert hidden high parameters }
|
||||||
insert_hidden_para(pd);
|
insert_hidden_para(pd);
|
||||||
@ -1766,6 +1772,41 @@ const
|
|||||||
{ insert funcret parameter if required }
|
{ insert funcret parameter if required }
|
||||||
insert_funcret_para(pd);
|
insert_funcret_para(pd);
|
||||||
|
|
||||||
|
{$ifdef i386}
|
||||||
|
{ Move first 3 register parameters in localst }
|
||||||
|
if (pd.deftype=procdef) and
|
||||||
|
(pd.proccalloption=pocall_register) and
|
||||||
|
not(po_assembler in pd.procoptions) and
|
||||||
|
assigned(pd.para.first) then
|
||||||
|
begin
|
||||||
|
{ insert copy in localst }
|
||||||
|
if not assigned(tprocdef(pd).localst) then
|
||||||
|
tprocdef(pd).insert_localst;
|
||||||
|
n:=0;
|
||||||
|
currpara:=tparaitem(pd.para.first);
|
||||||
|
while assigned(currpara) and (n<3) do
|
||||||
|
begin
|
||||||
|
orgs:=currpara.parasym.realname;
|
||||||
|
if not(assigned(currpara.parasym) and (currpara.parasym.typ=varsym)) then
|
||||||
|
internalerror(200304232);
|
||||||
|
{ rename parameter in parast }
|
||||||
|
pd.parast.rename(currpara.parasym.name,'reg'+currpara.parasym.name);
|
||||||
|
include(tvarsym(currpara.parasym).varoptions,vo_is_reg_para);
|
||||||
|
vs:=tvarsym.create(orgs,currpara.paratyp,currpara.paratype);
|
||||||
|
vs.varoptions:=tvarsym(currpara.parasym).varoptions;
|
||||||
|
include(vs.varoptions,vo_is_reg_para);
|
||||||
|
tprocdef(pd).localst.insert(vs);
|
||||||
|
tprocdef(pd).localst.insertvardata(vs);
|
||||||
|
{ update currpara }
|
||||||
|
currpara.parasym:=vs;
|
||||||
|
{ next }
|
||||||
|
currpara:=tparaitem(currpara.next);
|
||||||
|
inc(n);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$endif i386}
|
||||||
|
|
||||||
if (pd.deftype=procdef) then
|
if (pd.deftype=procdef) then
|
||||||
begin
|
begin
|
||||||
{ rename value parameters that need a local copy to valXXX,
|
{ rename value parameters that need a local copy to valXXX,
|
||||||
@ -1796,7 +1837,8 @@ const
|
|||||||
begin
|
begin
|
||||||
if not(assigned(currpara.parasym) and (currpara.parasym.typ=varsym)) then
|
if not(assigned(currpara.parasym) and (currpara.parasym.typ=varsym)) then
|
||||||
internalerror(200304232);
|
internalerror(200304232);
|
||||||
st.insertvardata(currpara.parasym);
|
if not(vo_is_reg_para in tvarsym(currpara.parasym).varoptions) then
|
||||||
|
st.insertvardata(currpara.parasym);
|
||||||
currpara:=tparaitem(currpara.next);
|
currpara:=tparaitem(currpara.next);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2148,7 +2190,10 @@ const
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.132 2003-09-09 15:54:10 peter
|
Revision 1.133 2003-09-09 21:03:17 peter
|
||||||
|
* basics for x86 register calling
|
||||||
|
|
||||||
|
Revision 1.132 2003/09/09 15:54:10 peter
|
||||||
* calling convention fix
|
* calling convention fix
|
||||||
|
|
||||||
Revision 1.131 2003/09/07 22:09:35 peter
|
Revision 1.131 2003/09/07 22:09:35 peter
|
||||||
|
@ -256,7 +256,8 @@ type
|
|||||||
vo_is_funcret,
|
vo_is_funcret,
|
||||||
vo_is_self,
|
vo_is_self,
|
||||||
vo_is_vmt,
|
vo_is_vmt,
|
||||||
vo_is_result { special result variable }
|
vo_is_result, { special result variable }
|
||||||
|
vo_is_reg_para { register parameter, no space allocation in parast, but in localst }
|
||||||
);
|
);
|
||||||
tvaroptions=set of tvaroption;
|
tvaroptions=set of tvaroption;
|
||||||
|
|
||||||
@ -373,7 +374,10 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.62 2003-09-09 15:54:10 peter
|
Revision 1.63 2003-09-09 21:03:17 peter
|
||||||
|
* basics for x86 register calling
|
||||||
|
|
||||||
|
Revision 1.62 2003/09/09 15:54:10 peter
|
||||||
* calling convention fix
|
* calling convention fix
|
||||||
|
|
||||||
Revision 1.61 2003/09/07 22:09:35 peter
|
Revision 1.61 2003/09/07 22:09:35 peter
|
||||||
|
@ -356,24 +356,33 @@ unit cgx86;
|
|||||||
procedure tcgx86.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
|
procedure tcgx86.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
|
||||||
begin
|
begin
|
||||||
check_register_size(size,r);
|
check_register_size(size,r);
|
||||||
case size of
|
case locpara.loc of
|
||||||
OS_8,OS_S8,
|
LOC_REGISTER :
|
||||||
OS_16,OS_S16:
|
cg.a_load_reg_reg(list,size,locpara.size,r,locpara.register);
|
||||||
|
LOC_REFERENCE :
|
||||||
begin
|
begin
|
||||||
if target_info.alignment.paraalign = 2 then
|
case size of
|
||||||
r:=rg.makeregsize(r,OS_16)
|
OS_8,OS_S8,
|
||||||
else
|
OS_16,OS_S16:
|
||||||
r:=rg.makeregsize(r,OS_32);
|
begin
|
||||||
list.concat(taicpu.op_reg(A_PUSH,S_L,r));
|
if target_info.alignment.paraalign = 2 then
|
||||||
|
r:=rg.makeregsize(r,OS_16)
|
||||||
|
else
|
||||||
|
r:=rg.makeregsize(r,OS_32);
|
||||||
|
list.concat(taicpu.op_reg(A_PUSH,S_L,r));
|
||||||
|
end;
|
||||||
|
OS_32,OS_S32:
|
||||||
|
begin
|
||||||
|
if getsubreg(r)<>R_SUBD then
|
||||||
|
internalerror(7843);
|
||||||
|
list.concat(taicpu.op_reg(A_PUSH,S_L,r));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
internalerror(2002032212);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
OS_32,OS_S32:
|
|
||||||
begin
|
|
||||||
if getsubreg(r)<>R_SUBD then
|
|
||||||
internalerror(7843);
|
|
||||||
list.concat(taicpu.op_reg(A_PUSH,S_L,r));
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
internalerror(2002032212);
|
internalerror(200309082);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -381,18 +390,27 @@ unit cgx86;
|
|||||||
procedure tcgx86.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
|
procedure tcgx86.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
case size of
|
case locpara.loc of
|
||||||
OS_8,OS_S8,OS_16,OS_S16:
|
LOC_REGISTER :
|
||||||
|
cg.a_load_const_reg(list,locpara.size,a,locpara.register);
|
||||||
|
LOC_REFERENCE :
|
||||||
begin
|
begin
|
||||||
if target_info.alignment.paraalign = 2 then
|
case size of
|
||||||
list.concat(taicpu.op_const(A_PUSH,S_W,a))
|
OS_8,OS_S8,OS_16,OS_S16:
|
||||||
else
|
begin
|
||||||
list.concat(taicpu.op_const(A_PUSH,S_L,a));
|
if target_info.alignment.paraalign = 2 then
|
||||||
|
list.concat(taicpu.op_const(A_PUSH,S_W,a))
|
||||||
|
else
|
||||||
|
list.concat(taicpu.op_const(A_PUSH,S_L,a));
|
||||||
|
end;
|
||||||
|
OS_32,OS_S32:
|
||||||
|
list.concat(taicpu.op_const(A_PUSH,S_L,a));
|
||||||
|
else
|
||||||
|
internalerror(2002032213);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
OS_32,OS_S32:
|
|
||||||
list.concat(taicpu.op_const(A_PUSH,S_L,a));
|
|
||||||
else
|
else
|
||||||
internalerror(2002032213);
|
internalerror(200309082);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -404,58 +422,91 @@ unit cgx86;
|
|||||||
tmpreg : tregister;
|
tmpreg : tregister;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
case size of
|
case locpara.loc of
|
||||||
OS_8,OS_S8,
|
LOC_REGISTER :
|
||||||
OS_16,OS_S16:
|
cg.a_load_ref_reg(list,size,locpara.size,r,locpara.register);
|
||||||
|
LOC_REFERENCE :
|
||||||
begin
|
begin
|
||||||
if target_info.alignment.paraalign = 2 then
|
case size of
|
||||||
pushsize:=OS_16
|
OS_8,OS_S8,
|
||||||
else
|
OS_16,OS_S16:
|
||||||
pushsize:=OS_32;
|
begin
|
||||||
tmpreg:=rg.getregisterint(list,pushsize);
|
if target_info.alignment.paraalign = 2 then
|
||||||
a_load_ref_reg(list,size,pushsize,r,tmpreg);
|
pushsize:=OS_16
|
||||||
list.concat(taicpu.op_reg(A_PUSH,TCgsize2opsize[pushsize],tmpreg));
|
else
|
||||||
rg.ungetregisterint(list,tmpreg);
|
pushsize:=OS_32;
|
||||||
|
tmpreg:=rg.getregisterint(list,pushsize);
|
||||||
|
a_load_ref_reg(list,size,pushsize,r,tmpreg);
|
||||||
|
list.concat(taicpu.op_reg(A_PUSH,TCgsize2opsize[pushsize],tmpreg));
|
||||||
|
rg.ungetregisterint(list,tmpreg);
|
||||||
|
end;
|
||||||
|
OS_32,OS_S32:
|
||||||
|
list.concat(taicpu.op_ref(A_PUSH,S_L,r));
|
||||||
|
{$ifdef cpu64bit}
|
||||||
|
OS_64,OS_S64:
|
||||||
|
list.concat(taicpu.op_ref(A_PUSH,S_Q,r));
|
||||||
|
{$endif cpu64bit}
|
||||||
|
else
|
||||||
|
internalerror(2002032214);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
OS_32,OS_S32:
|
|
||||||
list.concat(taicpu.op_ref(A_PUSH,S_L,r));
|
|
||||||
OS_64,OS_S64:
|
|
||||||
list.concat(taicpu.op_ref(A_PUSH,S_Q,r));
|
|
||||||
else
|
else
|
||||||
internalerror(2002032214);
|
internalerror(200309083);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgx86.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
|
procedure tcgx86.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
|
||||||
var
|
var
|
||||||
tmpreg: tregister;
|
tmpreg : tregister;
|
||||||
baseno,indexno:boolean;
|
|
||||||
begin
|
begin
|
||||||
if (r.segment<>NR_NO) then
|
if (r.segment<>NR_NO) then
|
||||||
CGMessage(cg_e_cant_use_far_pointer_there);
|
CGMessage(cg_e_cant_use_far_pointer_there);
|
||||||
baseno:=(r.base=NR_NO);
|
case locpara.loc of
|
||||||
indexno:=(r.index=NR_NO);
|
LOC_REGISTER :
|
||||||
if baseno and indexno then
|
begin
|
||||||
begin
|
if (r.base=NR_NO) and (r.index=NR_NO) then
|
||||||
if assigned(r.symbol) then
|
begin
|
||||||
list.concat(Taicpu.Op_sym_ofs(A_PUSH,S_L,r.symbol,r.offset))
|
if assigned(r.symbol) then
|
||||||
else
|
list.concat(Taicpu.Op_sym_ofs_reg(A_MOV,S_L,r.symbol,r.offset,locpara.register))
|
||||||
list.concat(Taicpu.Op_const(A_PUSH,S_L,r.offset));
|
else
|
||||||
end
|
a_load_const_reg(list,OS_INT,r.offset,locpara.register);
|
||||||
else if baseno and not indexno and
|
end
|
||||||
(r.offset=0) and (r.scalefactor=0) and (r.symbol=nil) then
|
else if (r.base=NR_NO) and (r.index<>NR_NO) and
|
||||||
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r.index))
|
(r.offset=0) and (r.scalefactor=0) and (r.symbol=nil) then
|
||||||
else if not baseno and indexno and
|
a_load_reg_reg(list,OS_INT,OS_INT,r.index,locpara.register)
|
||||||
(r.offset=0) and (r.symbol=nil) then
|
else if (r.base<>NR_NO) and (r.index=NR_NO) and
|
||||||
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r.base))
|
(r.offset=0) and (r.symbol=nil) then
|
||||||
else
|
a_load_reg_reg(list,OS_INT,OS_INT,r.base,locpara.register)
|
||||||
begin
|
else
|
||||||
tmpreg:=rg.getaddressregister(list);
|
a_loadaddr_ref_reg(list,r,locpara.register);
|
||||||
a_loadaddr_ref_reg(list,r,tmpreg);
|
end;
|
||||||
list.concat(taicpu.op_reg(A_PUSH,S_L,tmpreg));
|
LOC_REFERENCE :
|
||||||
rg.ungetregisterint(list,tmpreg);
|
begin
|
||||||
end;
|
if (r.base=NR_NO) and (r.index=NR_NO) then
|
||||||
|
begin
|
||||||
|
if assigned(r.symbol) then
|
||||||
|
list.concat(Taicpu.Op_sym_ofs(A_PUSH,S_L,r.symbol,r.offset))
|
||||||
|
else
|
||||||
|
list.concat(Taicpu.Op_const(A_PUSH,S_L,r.offset));
|
||||||
|
end
|
||||||
|
else if (r.base=NR_NO) and (r.index<>NR_NO) and
|
||||||
|
(r.offset=0) and (r.scalefactor=0) and (r.symbol=nil) then
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r.index))
|
||||||
|
else if (r.base<>NR_NO) and (r.index=NR_NO) and
|
||||||
|
(r.offset=0) and (r.symbol=nil) then
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r.base))
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
tmpreg:=rg.getaddressregister(list);
|
||||||
|
a_loadaddr_ref_reg(list,r,tmpreg);
|
||||||
|
list.concat(taicpu.op_reg(A_PUSH,S_L,tmpreg));
|
||||||
|
rg.ungetregisterint(list,tmpreg);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(200309084);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1572,7 +1623,10 @@ unit cgx86;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.62 2003-09-09 20:59:27 daniel
|
Revision 1.63 2003-09-09 21:03:17 peter
|
||||||
|
* basics for x86 register calling
|
||||||
|
|
||||||
|
Revision 1.62 2003/09/09 20:59:27 daniel
|
||||||
* Adding register allocation order
|
* Adding register allocation order
|
||||||
|
|
||||||
Revision 1.61 2003/09/07 22:09:35 peter
|
Revision 1.61 2003/09/07 22:09:35 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user