mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 02:09:33 +01:00
* initial support for system procs that use calling conventions that push left to right on i8086 or i386
git-svn-id: branches/i8086@24282 -
This commit is contained in:
parent
5caadbbc40
commit
a5c5b05362
@ -2100,8 +2100,16 @@ implementation
|
||||
paramanager.getintparaloc(pd,1,cgpara1);
|
||||
paramanager.getintparaloc(pd,2,cgpara2);
|
||||
reference_reset_symbol(hrefvmt,current_asmdata.RefAsmSymbol(objdef.vmt_mangledname),0,sizeof(pint));
|
||||
a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
|
||||
a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
|
||||
a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
|
||||
a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
allocallcpuregisters(list);
|
||||
|
||||
@ -2829,9 +2829,18 @@ implementation
|
||||
paramanager.getintparaloc(pd,1,cgpara1);
|
||||
paramanager.getintparaloc(pd,2,cgpara2);
|
||||
paramanager.getintparaloc(pd,3,cgpara3);
|
||||
a_loadaddr_ref_cgpara(list,strdef,dest,cgpara3);
|
||||
a_loadaddr_ref_cgpara(list,strdef,source,cgpara2);
|
||||
a_load_const_cgpara(list,s32inttype,strdef.len,cgpara1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
a_load_const_cgpara(list,s32inttype,strdef.len,cgpara1);
|
||||
a_loadaddr_ref_cgpara(list,strdef,source,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,strdef,dest,cgpara3);
|
||||
end
|
||||
else
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,strdef,dest,cgpara3);
|
||||
a_loadaddr_ref_cgpara(list,strdef,source,cgpara2);
|
||||
a_load_const_cgpara(list,s32inttype,strdef.len,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara3);
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
@ -2851,8 +2860,16 @@ implementation
|
||||
cgpara2.init;
|
||||
paramanager.getintparaloc(pd,1,cgpara1);
|
||||
paramanager.getintparaloc(pd,2,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,vardef,dest,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,vardef,source,cgpara1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,vardef,source,cgpara1);
|
||||
a_loadaddr_ref_cgpara(list,vardef,dest,cgpara2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,vardef,dest,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,vardef,source,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
g_call_system_proc(list,pd,nil);
|
||||
@ -2904,8 +2921,16 @@ implementation
|
||||
if is_open_array(t) then
|
||||
InternalError(201103054);
|
||||
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
g_call_system_proc(list,pd,nil);
|
||||
@ -2944,8 +2969,16 @@ implementation
|
||||
paramanager.getintparaloc(pd,1,cgpara1);
|
||||
paramanager.getintparaloc(pd,2,cgpara2);
|
||||
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
g_call_system_proc(list,pd,nil);
|
||||
@ -2986,8 +3019,16 @@ implementation
|
||||
paramanager.getintparaloc(pd,1,cgpara1);
|
||||
paramanager.getintparaloc(pd,2,cgpara2);
|
||||
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
g_call_system_proc(list,pd,nil);
|
||||
@ -3019,6 +3060,14 @@ implementation
|
||||
paramanager.getintparaloc(pd,2,cgpara2);
|
||||
paramanager.getintparaloc(pd,3,cgpara3);
|
||||
|
||||
{ if calling convention is left to right, push parameters 1 and 2 }
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
end;
|
||||
|
||||
{ push parameter 3 }
|
||||
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
|
||||
if highloc.loc=LOC_CONSTANT then
|
||||
a_load_const_cgpara(list,ptrsinttype,highloc.value+1,cgpara3)
|
||||
@ -3037,8 +3086,12 @@ implementation
|
||||
a_load_reg_cgpara(list,ptrsinttype,lenreg,cgpara3);
|
||||
end;
|
||||
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
{ if calling convention is right to left, push parameters 2 and 1 }
|
||||
if not pd.is_pushleftright then
|
||||
begin
|
||||
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
|
||||
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
paramanager.freecgpara(list,cgpara3);
|
||||
@ -3308,12 +3361,24 @@ implementation
|
||||
paramanager.getintparaloc(pd,1,cgpara1);
|
||||
paramanager.getintparaloc(pd,2,cgpara2);
|
||||
paramanager.getintparaloc(pd,3,cgpara3);
|
||||
{ load size }
|
||||
a_load_reg_cgpara(list,ptrsinttype,sizereg,cgpara3);
|
||||
{ load destination }
|
||||
a_load_reg_cgpara(list,ptrarrdef,destreg,cgpara2);
|
||||
{ load source }
|
||||
a_load_reg_cgpara(list,ptrarrdef,sourcereg,cgpara1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
{ load source }
|
||||
a_load_reg_cgpara(list,ptrarrdef,sourcereg,cgpara1);
|
||||
{ load destination }
|
||||
a_load_reg_cgpara(list,ptrarrdef,destreg,cgpara2);
|
||||
{ load size }
|
||||
a_load_reg_cgpara(list,ptrsinttype,sizereg,cgpara3);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ load size }
|
||||
a_load_reg_cgpara(list,ptrsinttype,sizereg,cgpara3);
|
||||
{ load destination }
|
||||
a_load_reg_cgpara(list,ptrarrdef,destreg,cgpara2);
|
||||
{ load source }
|
||||
a_load_reg_cgpara(list,ptrarrdef,sourcereg,cgpara1);
|
||||
end;
|
||||
paramanager.freecgpara(list,cgpara3);
|
||||
paramanager.freecgpara(list,cgpara2);
|
||||
paramanager.freecgpara(list,cgpara1);
|
||||
|
||||
@ -986,31 +986,64 @@ implementation
|
||||
exit;
|
||||
|
||||
{ Push parameters }
|
||||
if assigned(right) then
|
||||
{ ugly code repetition follows for left to right and right to left calling conventions }
|
||||
{ TODO: refactor this somehow }
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
{ frame tree }
|
||||
if assigned(third) then
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,third.location,paraloc3)
|
||||
else
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc3);
|
||||
{ push address }
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
if assigned(right) then
|
||||
begin
|
||||
{ push address }
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
{ frame tree }
|
||||
if assigned(third) then
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,third.location,paraloc3)
|
||||
else
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc3);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ get current address }
|
||||
current_asmdata.getaddrlabel(a);
|
||||
cg.a_label(current_asmdata.CurrAsmList,a);
|
||||
reference_reset_symbol(href2,a,0,1);
|
||||
{ push current address }
|
||||
if target_info.system <> system_powerpc_macos then
|
||||
cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc2)
|
||||
else
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc2);
|
||||
{ push current frame }
|
||||
cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ get current address }
|
||||
current_asmdata.getaddrlabel(a);
|
||||
cg.a_label(current_asmdata.CurrAsmList,a);
|
||||
reference_reset_symbol(href2,a,0,1);
|
||||
{ push current frame }
|
||||
cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
|
||||
{ push current address }
|
||||
if target_info.system <> system_powerpc_macos then
|
||||
cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc2)
|
||||
else
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc2);
|
||||
if assigned(right) then
|
||||
begin
|
||||
{ frame tree }
|
||||
if assigned(third) then
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,third.location,paraloc3)
|
||||
else
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc3);
|
||||
{ push address }
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ get current address }
|
||||
current_asmdata.getaddrlabel(a);
|
||||
cg.a_label(current_asmdata.CurrAsmList,a);
|
||||
reference_reset_symbol(href2,a,0,1);
|
||||
{ push current frame }
|
||||
cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
|
||||
{ push current address }
|
||||
if target_info.system <> system_powerpc_macos then
|
||||
cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc2)
|
||||
else
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc2);
|
||||
end;
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
end;
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc3);
|
||||
|
||||
@ -304,6 +304,7 @@ implementation
|
||||
paraloc1 : tcgpara;
|
||||
opsize : tcgsize;
|
||||
opdef : tdef;
|
||||
pd: tprocdef;
|
||||
begin
|
||||
secondpass(left);
|
||||
if codegenerror then
|
||||
@ -384,7 +385,8 @@ implementation
|
||||
current_asmdata.getjumplabel(hl);
|
||||
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,0,hdenom,hl);
|
||||
paraloc1.init;
|
||||
paramanager.getintparaloc(search_system_proc('fpc_handleerror'),1,paraloc1);
|
||||
pd:=search_system_proc('fpc_handleerror');
|
||||
paramanager.getintparaloc(pd,1,paraloc1);
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_S32,aint(200),paraloc1);
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
|
||||
cg.a_call_name(current_asmdata.CurrAsmList,'FPC_HANDLEERROR',false);
|
||||
|
||||
@ -721,8 +721,16 @@ implementation
|
||||
pd:=search_system_proc('fpc_dynarray_rangecheck');
|
||||
paramanager.getintparaloc(pd,1,paraloc1);
|
||||
paramanager.getintparaloc(pd,2,paraloc2);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
end;
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
|
||||
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
|
||||
@ -755,8 +763,16 @@ implementation
|
||||
pd:=search_system_proc(helpername);
|
||||
paramanager.getintparaloc(pd,1,paraloc1);
|
||||
paramanager.getintparaloc(pd,2,paraloc2);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
|
||||
end;
|
||||
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
|
||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
|
||||
|
||||
@ -439,10 +439,20 @@ implementation
|
||||
paramanager.getintparaloc(pd,1,paraloc1);
|
||||
paramanager.getintparaloc(pd,2,paraloc2);
|
||||
paramanager.getintparaloc(pd,3,paraloc3);
|
||||
cg.a_loadaddr_ref_cgpara(list,t.envbuf,paraloc3);
|
||||
cg.a_loadaddr_ref_cgpara(list,t.jmpbuf,paraloc2);
|
||||
{ push type of exceptionframe }
|
||||
cg.a_load_const_cgpara(list,pushexceptaddr_frametype_cgsize,1,paraloc1);
|
||||
if pd.is_pushleftright then
|
||||
begin
|
||||
{ push type of exceptionframe }
|
||||
cg.a_load_const_cgpara(list,pushexceptaddr_frametype_cgsize,1,paraloc1);
|
||||
cg.a_loadaddr_ref_cgpara(list,t.jmpbuf,paraloc2);
|
||||
cg.a_loadaddr_ref_cgpara(list,t.envbuf,paraloc3);
|
||||
end
|
||||
else
|
||||
begin
|
||||
cg.a_loadaddr_ref_cgpara(list,t.envbuf,paraloc3);
|
||||
cg.a_loadaddr_ref_cgpara(list,t.jmpbuf,paraloc2);
|
||||
{ push type of exceptionframe }
|
||||
cg.a_load_const_cgpara(list,pushexceptaddr_frametype_cgsize,1,paraloc1);
|
||||
end;
|
||||
paramanager.freecgpara(list,paraloc3);
|
||||
paramanager.freecgpara(list,paraloc2);
|
||||
paramanager.freecgpara(list,paraloc1);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user