diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index 504ef4b493..882bb65f8f 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -702,6 +702,8 @@ implementation procedure tcg.allocallcpuregisters(list:TAsmList); begin alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); + if uses_registers(R_ADDRESSREGISTER) then + alloccpuregisters(list,R_ADDRESSREGISTER,paramanager.get_volatile_registers_address(pocall_default)); {$if not(defined(i386)) and not(defined(i8086)) and not(defined(avr))} if uses_registers(R_FPUREGISTER) then alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default)); @@ -725,6 +727,8 @@ implementation procedure tcg.deallocallcpuregisters(list:TAsmList); begin dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); + if uses_registers(R_ADDRESSREGISTER) then + dealloccpuregisters(list,R_ADDRESSREGISTER,paramanager.get_volatile_registers_address(pocall_default)); {$if not(defined(i386)) and not(defined(i8086)) and not(defined(avr))} if uses_registers(R_FPUREGISTER) then dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default)); diff --git a/compiler/m68k/cpupara.pas b/compiler/m68k/cpupara.pas index 0660e8f750..5ad649d34b 100644 --- a/compiler/m68k/cpupara.pas +++ b/compiler/m68k/cpupara.pas @@ -50,6 +50,7 @@ unit cpupara; function parseparaloc(p : tparavarsym;const s : string) : boolean;override; function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override; function get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;override; + function get_volatile_registers_address(calloption:tproccalloption):tcpuregisterset;override; private procedure init_values(var curintreg, curfloatreg: tsuperregister; var cur_stack_offset: aword); function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; @@ -495,11 +496,20 @@ unit cpupara; function tm68kparamanager.get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset; begin - { for now we set all int registers as volatile } + { d0 and d1 are considered volatile (ToDo: results in "procedure too + complex when compiling unicodedata.pas) } + //Result:=[RS_D0,RS_D1]; Result:=[RS_D0..RS_D7]; end; + function tm68kparamanager.get_volatile_registers_address(calloption:tproccalloption):tcpuregisterset; + begin + { a0 and a1 are considered volatile } + Result:=[RS_A0,RS_A1]; + end; + + function tm68kparamanager.parseparaloc(p : tparavarsym;const s : string) : boolean; var paraloc : pcgparalocation; diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index 486c515297..9d11ecf89d 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -744,6 +744,7 @@ implementation var name_to_call: shortstring; regs_to_save_int, + regs_to_save_address, regs_to_save_fpu, regs_to_save_mm : Tcpuregisterset; href : treference; @@ -773,6 +774,7 @@ implementation secondpass(tnode(callinitblock)); regs_to_save_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption); + regs_to_save_address:=paramanager.get_volatile_registers_address(procdefinition.proccalloption); regs_to_save_fpu:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption); regs_to_save_mm:=paramanager.get_volatile_registers_mm(procdefinition.proccalloption); @@ -800,6 +802,7 @@ implementation begin case retlocitem^.loc of LOC_REGISTER: + include(regs_to_save_int,getsupreg(retlocitem^.register)); LOC_FPUREGISTER: include(regs_to_save_fpu,getsupreg(retlocitem^.register)); @@ -922,6 +925,8 @@ implementation end; {$endif i8086} cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int); + if cg.uses_registers(R_ADDRESSREGISTER) then + cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address); if cg.uses_registers(R_FPUREGISTER) then cg.alloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu); if cg.uses_registers(R_MMREGISTER) then @@ -950,6 +955,8 @@ implementation end; cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int); + if cg.uses_registers(R_ADDRESSREGISTER) then + cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address); if cg.uses_registers(R_FPUREGISTER) then cg.alloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu); if cg.uses_registers(R_MMREGISTER) then @@ -1008,6 +1015,8 @@ implementation end; cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int); + if cg.uses_registers(R_ADDRESSREGISTER) then + cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address); if cg.uses_registers(R_FPUREGISTER) then cg.alloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu); if cg.uses_registers(R_MMREGISTER) then @@ -1052,7 +1061,10 @@ implementation begin case retlocitem^.loc of LOC_REGISTER: - exclude(regs_to_save_int,getsupreg(retlocitem^.register)); + if getregtype(retlocitem^.register)=R_INTREGISTER then + exclude(regs_to_save_int,getsupreg(retlocitem^.register)) + else + exclude(regs_to_save_address,getsupreg(retlocitem^.register)); LOC_FPUREGISTER: exclude(regs_to_save_fpu,getsupreg(retlocitem^.register)); LOC_MMREGISTER: @@ -1071,6 +1083,8 @@ implementation cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_MMREGISTER,regs_to_save_mm); if cg.uses_registers(R_FPUREGISTER) then cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu); + if cg.uses_registers(R_ADDRESSREGISTER) then + cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address); cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int); {$ifdef SUPPORT_SAFECALL} diff --git a/compiler/paramgr.pas b/compiler/paramgr.pas index 8ca4b330ba..32d43a7e5d 100644 --- a/compiler/paramgr.pas +++ b/compiler/paramgr.pas @@ -76,6 +76,7 @@ unit paramgr; } function get_para_align(calloption : tproccalloption):byte;virtual; function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;virtual; + function get_volatile_registers_address(calloption : tproccalloption):tcpuregisterset;virtual; function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;virtual; function get_volatile_registers_flags(calloption : tproccalloption):tcpuregisterset;virtual; function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;virtual; @@ -255,6 +256,12 @@ implementation end; + function tparamanager.get_volatile_registers_address(calloption : tproccalloption):tcpuregisterset; + begin + result:=[]; + end; + + function tparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset; begin result:=[];