* 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:
nickysn 2013-04-21 13:26:12 +00:00
parent 5caadbbc40
commit a5c5b05362
6 changed files with 184 additions and 50 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);