|
@@ -85,8 +85,8 @@ unit cgcpu;
|
|
|
procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
|
|
|
procedure g_proc_exit(list : TAsmList;parasize:longint;nostackframe:boolean);override;
|
|
|
|
|
|
-// procedure g_restore_frame_pointer(list : TAsmList);override;
|
|
|
-// procedure g_return_from_proc(list : TAsmList;parasize : tcgint);override;
|
|
|
+ procedure g_save_registers(list:TAsmList);override;
|
|
|
+ procedure g_restore_registers(list:TAsmList);override;
|
|
|
|
|
|
procedure g_adjust_self_value(list:TAsmList;procdef:tprocdef;ioffset:tcgint);override;
|
|
|
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
|
|
@@ -1752,6 +1752,114 @@ unit cgcpu;
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ procedure tcg68k.g_save_registers(list:TAsmList);
|
|
|
+ var
|
|
|
+ dataregs: tcpuregisterset;
|
|
|
+ addrregs: tcpuregisterset;
|
|
|
+ href : treference;
|
|
|
+ hreg : tregister;
|
|
|
+ size : longint;
|
|
|
+ r : integer;
|
|
|
+ begin
|
|
|
+ { The code generated by the section below, particularly the movem.l
|
|
|
+ instruction is known to cause an issue when compiled by some GNU
|
|
|
+ assembler versions (I had it with 2.17, while 2.24 seems OK.)
|
|
|
+ when you run into this problem, just call inherited here instead
|
|
|
+ to skip the movem.l generation. But better just use working GNU
|
|
|
+ AS version instead. (KB) }
|
|
|
+ dataregs:=[];
|
|
|
+ addrregs:=[];
|
|
|
+
|
|
|
+ { calculate temp. size }
|
|
|
+ size:=0;
|
|
|
+ for r:=low(saved_standard_registers) to high(saved_standard_registers) do
|
|
|
+ if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
|
|
|
+ begin
|
|
|
+ hreg:=newreg(R_INTREGISTER,saved_address_registers[r],R_SUBWHOLE);
|
|
|
+ inc(size,sizeof(aint));
|
|
|
+ dataregs:=dataregs + [saved_standard_registers[r]];
|
|
|
+ end;
|
|
|
+ if uses_registers(R_ADDRESSREGISTER) then
|
|
|
+ for r:=low(saved_address_registers) to high(saved_address_registers) do
|
|
|
+ if saved_address_registers[r] in rg[R_ADDRESSREGISTER].used_in_proc then
|
|
|
+ begin
|
|
|
+ hreg:=newreg(R_ADDRESSREGISTER,saved_address_registers[r],R_SUBWHOLE);
|
|
|
+ inc(size,sizeof(aint));
|
|
|
+ addrregs:=addrregs + [saved_address_registers[r]];
|
|
|
+ end;
|
|
|
+
|
|
|
+ { 68k has no MM registers }
|
|
|
+ if uses_registers(R_MMREGISTER) then
|
|
|
+ internalerror(2014030201);
|
|
|
+
|
|
|
+ if size>0 then
|
|
|
+ begin
|
|
|
+ tg.GetTemp(list,size,sizeof(aint),tt_noreuse,current_procinfo.save_regs_ref);
|
|
|
+ include(current_procinfo.flags,pi_has_saved_regs);
|
|
|
+
|
|
|
+ { Copy registers to temp }
|
|
|
+ href:=current_procinfo.save_regs_ref;
|
|
|
+ if size = sizeof(aint) then
|
|
|
+ a_load_reg_ref(list, OS_32, OS_32, hreg, href)
|
|
|
+ else
|
|
|
+ list.concat(taicpu.op_regset_ref(A_MOVEM,S_L,dataregs,addrregs,href));
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tcg68k.g_restore_registers(list:TAsmList);
|
|
|
+ var
|
|
|
+ dataregs: tcpuregisterset;
|
|
|
+ addrregs: tcpuregisterset;
|
|
|
+ href : treference;
|
|
|
+ r : integer;
|
|
|
+ hreg : tregister;
|
|
|
+ size : longint;
|
|
|
+ begin
|
|
|
+ { see the remark about buggy GNU AS versions in g_save_registers() (KB) }
|
|
|
+ dataregs:=[];
|
|
|
+ addrregs:=[];
|
|
|
+
|
|
|
+ if not(pi_has_saved_regs in current_procinfo.flags) then
|
|
|
+ exit;
|
|
|
+ { Copy registers from temp }
|
|
|
+ size:=0;
|
|
|
+ for r:=low(saved_standard_registers) to high(saved_standard_registers) do
|
|
|
+ if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
|
|
|
+ begin
|
|
|
+ inc(size,sizeof(aint));
|
|
|
+ hreg:=newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE);
|
|
|
+ { Allocate register so the optimizer does not remove the load }
|
|
|
+ a_reg_alloc(list,hreg);
|
|
|
+ dataregs:=dataregs + [saved_standard_registers[r]];
|
|
|
+ end;
|
|
|
+
|
|
|
+ if uses_registers(R_ADDRESSREGISTER) then
|
|
|
+ for r:=low(saved_address_registers) to high(saved_address_registers) do
|
|
|
+ if saved_address_registers[r] in rg[R_ADDRESSREGISTER].used_in_proc then
|
|
|
+ begin
|
|
|
+ inc(size,sizeof(aint));
|
|
|
+ hreg:=newreg(R_ADDRESSREGISTER,saved_address_registers[r],R_SUBWHOLE);
|
|
|
+ { Allocate register so the optimizer does not remove the load }
|
|
|
+ a_reg_alloc(list,hreg);
|
|
|
+ addrregs:=addrregs + [saved_address_registers[r]];
|
|
|
+ end;
|
|
|
+
|
|
|
+ { 68k has no MM registers }
|
|
|
+ if uses_registers(R_MMREGISTER) then
|
|
|
+ internalerror(2014030202);
|
|
|
+
|
|
|
+ { Restore registers from temp }
|
|
|
+ href:=current_procinfo.save_regs_ref;
|
|
|
+ if size = sizeof(aint) then
|
|
|
+ a_load_ref_reg(list, OS_32, OS_32, href, hreg)
|
|
|
+ else
|
|
|
+ list.concat(taicpu.op_ref_regset(A_MOVEM,S_L,href,dataregs,addrregs));
|
|
|
+
|
|
|
+ tg.UnGetTemp(list,current_procinfo.save_regs_ref);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
procedure tcg68k.sign_extend(list: TAsmList;_oldsize : tcgsize; reg: tregister);
|
|
|
begin
|
|
|
case _oldsize of
|