mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 19:29:26 +02:00
* fixed some m68k compilation problems
This commit is contained in:
parent
828fab3da9
commit
b80d10cb70
@ -29,7 +29,7 @@ interface
|
||||
uses
|
||||
cclasses,aasmtai,
|
||||
aasmbase,globals,verbose,
|
||||
cpubase,cpuinfo;
|
||||
cpubase,cpuinfo,cgbase;
|
||||
|
||||
|
||||
const
|
||||
@ -65,11 +65,11 @@ type
|
||||
constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister; _op3 : treference);
|
||||
constructor op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : treference);
|
||||
|
||||
constructor op_reg_reglist(op: tasmop; _size : topsize; _op1: tregister;_op2: Tsupregset);
|
||||
constructor op_reglist_reg(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: tregister);
|
||||
constructor op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2: tcpuregisterset);
|
||||
constructor op_regset_reg(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: tregister);
|
||||
|
||||
constructor op_ref_reglist(op: tasmop; _size : topsize; _op1: treference;_op2: Tsupregset);
|
||||
constructor op_reglist_ref(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: treference);
|
||||
constructor op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2: tcpuregisterset);
|
||||
constructor op_regset_ref(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: treference);
|
||||
|
||||
{ this is for Jmp instructions }
|
||||
constructor op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol);
|
||||
@ -83,7 +83,7 @@ type
|
||||
constructor op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
|
||||
|
||||
private
|
||||
procedure loadreglist(opidx:longint;r:Tsupregset);
|
||||
procedure loadregset(opidx:longint;const s:tcpuregisterset);
|
||||
procedure init(_size : topsize); { this need to be called by all constructor }
|
||||
end;
|
||||
|
||||
@ -105,14 +105,28 @@ implementation
|
||||
|
||||
|
||||
|
||||
procedure taicpu.loadreglist(opidx:longint;r:Tsupregset);
|
||||
procedure taicpu.loadregset(opidx:longint;const s:tcpuregisterset);
|
||||
var
|
||||
i : byte;
|
||||
begin
|
||||
if opidx>=ops then
|
||||
ops:=opidx+1;
|
||||
with oper[opidx] do
|
||||
allocate_oper(opidx+1);
|
||||
with oper[opidx]^ do
|
||||
begin
|
||||
registerlist:=r;
|
||||
typ:=top_reglist;
|
||||
if typ<>top_regset then
|
||||
clearop(opidx);
|
||||
new(regset);
|
||||
regset^:=s;
|
||||
typ:=top_regset;
|
||||
for i:=RS_D0 to RS_D7 do
|
||||
begin
|
||||
if assigned(add_reg_instruction_hook) and (i in regset^) then
|
||||
add_reg_instruction_hook(self,newreg(R_INTREGISTER,i,R_SUBWHOLE));
|
||||
end;
|
||||
for i:=RS_A0 to RS_SP do
|
||||
begin
|
||||
if assigned(add_reg_instruction_hook) and (i in regset^) then
|
||||
add_reg_instruction_hook(self,newreg(R_ADDRESSREGISTER,i,R_SUBWHOLE));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -293,48 +307,46 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
constructor taicpu.op_ref_reglist(op: tasmop; _size : topsize; _op1: treference;_op2: Tsupregset);
|
||||
constructor taicpu.op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2: tcpuregisterset);
|
||||
Begin
|
||||
inherited create(op);;
|
||||
init(_size);
|
||||
ops:=2;
|
||||
loadref(0,_op1);
|
||||
loadreglist(1,_op2);
|
||||
loadregset(1,_op2);
|
||||
end;
|
||||
|
||||
constructor taicpu.op_reglist_ref(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: treference);
|
||||
constructor taicpu.op_regset_ref(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: treference);
|
||||
Begin
|
||||
inherited create(op);;
|
||||
init(_size);
|
||||
ops:=2;
|
||||
loadreglist(0,_op1);
|
||||
loadregset(0,_op1);
|
||||
loadref(1,_op2);
|
||||
End;
|
||||
|
||||
|
||||
|
||||
constructor taicpu.op_reg_reglist(op: tasmop; _size : topsize; _op1: tregister;_op2: Tsupregset);
|
||||
constructor taicpu.op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2: tcpuregisterset);
|
||||
Begin
|
||||
inherited create(op);;
|
||||
init(_size);
|
||||
ops:=2;
|
||||
loadreg(0,_op1);
|
||||
loadreglist(1,_op2);
|
||||
loadregset(1,_op2);
|
||||
end;
|
||||
|
||||
|
||||
constructor taicpu.op_reglist_reg(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: tregister);
|
||||
constructor taicpu.op_regset_reg(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: tregister);
|
||||
Begin
|
||||
inherited create(op);;
|
||||
init(_size);
|
||||
ops:=2;
|
||||
loadreglist(0,_op1);
|
||||
loadregset(0,_op1);
|
||||
loadreg(1,_op2);
|
||||
End;
|
||||
|
||||
|
||||
|
||||
|
||||
constructor taicpu.op_sym(op : tasmop;_size : topsize;_op1 : tasmsymbol);
|
||||
begin
|
||||
inherited create(op);;
|
||||
@ -414,7 +426,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.9 2003-06-14 14:53:50 jonas
|
||||
Revision 1.10 2004-01-30 12:17:18 florian
|
||||
* fixed some m68k compilation problems
|
||||
|
||||
Revision 1.9 2003/06/14 14:53:50 jonas
|
||||
* fixed newra cycle for x86
|
||||
* added constants for indicating source and destination operands of the
|
||||
"move reg,reg" instruction to aasmcpu (and use those in rgobj)
|
||||
|
@ -27,29 +27,29 @@ unit cgcpu;
|
||||
interface
|
||||
|
||||
uses
|
||||
cginfo,cgbase,cgobj,
|
||||
cgbase,cgobj,
|
||||
aasmbase,aasmtai,aasmcpu,
|
||||
cpubase,cpuinfo,cpupara,
|
||||
node,symconst,cg64f32;
|
||||
node,symconst,symtype,
|
||||
cg64f32;
|
||||
|
||||
type
|
||||
tcg68k = class(tcg)
|
||||
procedure a_call_name(list : taasmoutput;const s : string);override;
|
||||
procedure a_call_ref(list : taasmoutput;const ref : treference);override;
|
||||
procedure a_call_reg(list : taasmoutput;reg : tregister);override;
|
||||
procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister);override;
|
||||
procedure a_load_reg_ref(list : taasmoutput;size : tcgsize;register : tregister;const ref : treference);override;
|
||||
procedure a_load_reg_ref(list : taasmoutput;fromsize,tosize : tcgsize;register : tregister;const ref : treference);override;
|
||||
procedure a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister);override;
|
||||
procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;register : tregister);override;
|
||||
procedure a_load_ref_reg(list : taasmoutput;fromsize,tosize : tcgsize;const ref : treference;register : tregister);override;
|
||||
procedure a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);override;
|
||||
procedure a_loadfpu_reg_reg(list: taasmoutput; reg1, reg2: tregister); override;
|
||||
procedure a_loadfpu_reg_reg(list: taasmoutput; size: tcgsize; reg1, reg2: tregister); override;
|
||||
procedure a_loadfpu_ref_reg(list: taasmoutput; size: tcgsize; const ref: treference; reg: tregister); override;
|
||||
procedure a_loadfpu_reg_ref(list: taasmoutput; size: tcgsize; reg: tregister; const ref: treference); override;
|
||||
procedure a_loadmm_reg_reg(list: taasmoutput; reg1, reg2: tregister); override;
|
||||
procedure a_loadmm_ref_reg(list: taasmoutput; const ref: treference; reg: tregister); override;
|
||||
procedure a_loadmm_reg_ref(list: taasmoutput; reg: tregister; const ref: treference); override;
|
||||
procedure a_parammm_reg(list: taasmoutput; reg: tregister); override;
|
||||
procedure a_op_const_reg(list : taasmoutput; Op: TOpCG; a: AWord; reg: TRegister); override;
|
||||
procedure a_loadmm_reg_reg(list: taasmoutput;fromsize,tosize : tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle); override;
|
||||
procedure a_loadmm_ref_reg(list: taasmoutput;fromsize,tosize : tcgsize; const ref: treference; reg: tregister;shuffle : pmmshuffle); override;
|
||||
procedure a_loadmm_reg_ref(list: taasmoutput;fromsize,tosize : tcgsize; reg: tregister; const ref: treference;shuffle : pmmshuffle); override;
|
||||
procedure a_parammm_reg(list: taasmoutput; size: tcgsize; reg: tregister;const locpara : tparalocation;shuffle : pmmshuffle); override;
|
||||
procedure a_op_const_reg(list : taasmoutput; Op: TOpCG; size: tcgsize; a: AWord; reg: TRegister); override;
|
||||
procedure a_op_reg_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister); override;
|
||||
procedure a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
|
||||
l : tasmlabel);override;
|
||||
@ -60,20 +60,14 @@ unit cgcpu;
|
||||
|
||||
procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword;delsource,loadref : boolean);override;
|
||||
{ generates overflow checking code for a node }
|
||||
procedure g_overflowcheck(list: taasmoutput; const p: tnode); override;
|
||||
procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer); override;
|
||||
procedure g_overflowcheck(list: taasmoutput; const l:tlocation; def:tdef); override;
|
||||
procedure g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword); override;
|
||||
procedure g_stackframe_entry(list : taasmoutput;localsize : longint);override;
|
||||
procedure g_restore_frame_pointer(list : taasmoutput);override;
|
||||
procedure g_return_from_proc(list : taasmoutput;parasize : aword);override;
|
||||
procedure g_save_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
|
||||
procedure g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
|
||||
procedure g_restore_standard_registers(list:Taasmoutput);override;
|
||||
procedure g_save_all_registers(list : taasmoutput);override;
|
||||
procedure g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);override;
|
||||
{ for address register allocation }
|
||||
function get_scratch_reg_address(list : taasmoutput) : tregister;override;
|
||||
function get_scratch_reg_int(list:Taasmoutput;size:Tcgsize):Tregister; override;
|
||||
|
||||
|
||||
procedure g_restore_all_registers(list : taasmoutput;accused,acchiused:boolean);override;
|
||||
protected
|
||||
function fixref(list: taasmoutput; var ref: treference): boolean;
|
||||
private
|
||||
@ -100,16 +94,14 @@ unit cgcpu;
|
||||
}
|
||||
function isvalidrefoffset(const ref: treference): boolean;
|
||||
|
||||
const
|
||||
const
|
||||
TCGSize2OpSize: Array[tcgsize] of topsize =
|
||||
(S_NO,S_B,S_W,S_L,S_L,S_B,S_W,S_L,S_L,
|
||||
S_FS,S_FD,S_FX,S_NO,S_NO,
|
||||
S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO);
|
||||
|
||||
|
||||
|
||||
|
||||
Implementation
|
||||
implementation
|
||||
|
||||
uses
|
||||
globtype,globals,verbose,systems,cutils,
|
||||
@ -158,9 +150,9 @@ Implementation
|
||||
function isvalidrefoffset(const ref: treference): boolean;
|
||||
begin
|
||||
isvalidrefoffset := true;
|
||||
if ref.index.enum <> R_NO then
|
||||
if ref.index <> NR_NO then
|
||||
begin
|
||||
if ref.base.enum <> R_NO then
|
||||
if ref.base <> NR_NO then
|
||||
internalerror(20020814);
|
||||
if (ref.offset < low(shortint)) or (ref.offset > high(shortint)) then
|
||||
isvalidrefoffset := false
|
||||
@ -172,53 +164,6 @@ Implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
function tcg68k.get_scratch_reg_int(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
|
||||
var r:Tregister;
|
||||
rs:Tsuperregister;
|
||||
|
||||
begin
|
||||
if unusedscratchregisters=[] then
|
||||
internalerror(68996);
|
||||
|
||||
if RS_D0 in unusedscratchregisters then
|
||||
rs:=RS_D0
|
||||
else if RS_D1 in unusedscratchregisters then
|
||||
rs:=RS_D1
|
||||
else
|
||||
internalerror(10);
|
||||
r.enum:=R_INTREGISTER;
|
||||
r.number:=rs shl 8 or cgsize2subreg(size);
|
||||
|
||||
exclude(unusedscratchregisters,rs);
|
||||
a_reg_alloc(list,r);
|
||||
get_scratch_reg_int:=r;
|
||||
end;
|
||||
|
||||
|
||||
function tcg68k.get_scratch_reg_address(list:Taasmoutput):Tregister;
|
||||
|
||||
var r:Tregister;
|
||||
rs:Tsuperregister;
|
||||
|
||||
begin
|
||||
if unusedscratchregisters=[] then
|
||||
internalerror(68996);
|
||||
|
||||
if RS_A0 in unusedscratchregisters then
|
||||
rs:=RS_A0
|
||||
else if RS_A1 in unusedscratchregisters then
|
||||
rs:=RS_A1
|
||||
else
|
||||
internalerror(10);
|
||||
r.enum:=R_INTREGISTER;
|
||||
r.number:=rs shl 8 or R_SUBWHOLE;
|
||||
|
||||
exclude(unusedscratchregisters,rs);
|
||||
a_reg_alloc(list,r);
|
||||
get_scratch_reg_address:=r;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************}
|
||||
{ TCG68K }
|
||||
@ -233,12 +178,12 @@ Implementation
|
||||
}
|
||||
if (aktoptprocessor <> MC68000) then
|
||||
exit;
|
||||
if (ref.base.enum <> R_NO) then
|
||||
if (ref.base<> NR_NO) then
|
||||
begin
|
||||
if (ref.index.enum <> R_NO) and assigned(ref.symbol) then
|
||||
if (ref.index <> NR_NO) and assigned(ref.symbol) then
|
||||
internalerror(20020814);
|
||||
{ base + reg }
|
||||
if ref.index.enum <> R_NO then
|
||||
if ref.index <> NR_NO then
|
||||
begin
|
||||
{ base + reg + offset }
|
||||
if (ref.offset < low(shortint)) or (ref.offset > high(shortint)) then
|
||||
@ -270,28 +215,19 @@ Implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg68k.a_call_ref(list : taasmoutput;const ref : treference);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
href := ref;
|
||||
fixref(list,href);
|
||||
list.concat(taicpu.op_ref(A_JSR,S_NO,href));
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_call_reg(list : taasmoutput;reg : tregister);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
reference_reset_base(href, reg, 0);
|
||||
a_call_ref(list,href);
|
||||
//!!! a_call_ref(list,href);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure tcg68k.a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister);
|
||||
begin
|
||||
if (rg.isaddressregister(register)) then
|
||||
if getregtype(register)=R_ADDRESSREGISTER then
|
||||
begin
|
||||
list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register))
|
||||
end
|
||||
@ -307,14 +243,14 @@ Implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_load_reg_ref(list : taasmoutput;size : tcgsize;register : tregister;const ref : treference);
|
||||
procedure tcg68k.a_load_reg_ref(list : taasmoutput;fromsize,tosize : tcgsize;register : tregister;const ref : treference);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
href := ref;
|
||||
fixref(list,href);
|
||||
{ move to destination reference }
|
||||
list.concat(taicpu.op_reg_ref(A_MOVE,TCGSize2OpSize[size],register,href));
|
||||
list.concat(taicpu.op_reg_ref(A_MOVE,TCGSize2OpSize[fromsize],register,href));
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister);
|
||||
@ -325,15 +261,15 @@ Implementation
|
||||
sign_extend(list, fromsize, reg2);
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref : treference;register : tregister);
|
||||
procedure tcg68k.a_load_ref_reg(list : taasmoutput;fromsize,tosize : tcgsize;const ref : treference;register : tregister);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
href := ref;
|
||||
fixref(list,href);
|
||||
list.concat(taicpu.op_ref_reg(A_MOVE,TCGSize2OpSize[size],href,register));
|
||||
list.concat(taicpu.op_ref_reg(A_MOVE,TCGSize2OpSize[fromsize],href,register));
|
||||
{ extend the value in the register }
|
||||
sign_extend(list, size, register);
|
||||
sign_extend(list, tosize, register);
|
||||
end;
|
||||
|
||||
|
||||
@ -341,7 +277,7 @@ Implementation
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
if (not rg.isaddressregister(r)) then
|
||||
if getregtype(r)=R_ADDRESSREGISTER then
|
||||
begin
|
||||
internalerror(2002072901);
|
||||
end;
|
||||
@ -350,7 +286,7 @@ Implementation
|
||||
list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,r));
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_loadfpu_reg_reg(list: taasmoutput; reg1, reg2: tregister);
|
||||
procedure tcg68k.a_loadfpu_reg_reg(list: taasmoutput; size: tcgsize; reg1, reg2: tregister);
|
||||
begin
|
||||
{ in emulation mode, only 32-bit single is supported }
|
||||
if cs_fp_emulation in aktmoduleswitches then
|
||||
@ -393,28 +329,28 @@ Implementation
|
||||
list.concat(taicpu.op_reg_ref(A_FMOVE,opsize,reg, ref));
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_loadmm_reg_reg(list: taasmoutput; reg1, reg2: tregister);
|
||||
procedure tcg68k.a_loadmm_reg_reg(list: taasmoutput;fromsize,tosize : tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle);
|
||||
begin
|
||||
internalerror(20020729);
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_loadmm_ref_reg(list: taasmoutput; const ref: treference; reg: tregister);
|
||||
procedure tcg68k.a_loadmm_ref_reg(list: taasmoutput;fromsize,tosize : tcgsize; const ref: treference; reg: tregister;shuffle : pmmshuffle);
|
||||
begin
|
||||
internalerror(20020729);
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_loadmm_reg_ref(list: taasmoutput; reg: tregister; const ref: treference);
|
||||
procedure tcg68k.a_loadmm_reg_ref(list: taasmoutput;fromsize,tosize : tcgsize; reg: tregister; const ref: treference;shuffle : pmmshuffle);
|
||||
begin
|
||||
internalerror(20020729);
|
||||
end;
|
||||
|
||||
procedure tcg68k.a_parammm_reg(list: taasmoutput; reg: tregister);
|
||||
procedure tcg68k.a_parammm_reg(list: taasmoutput; size: tcgsize; reg: tregister;const locpara : tparalocation;shuffle : pmmshuffle);
|
||||
begin
|
||||
internalerror(20020729);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg68k.a_op_const_reg(list : taasmoutput; Op: TOpCG; a: AWord; reg: TRegister);
|
||||
procedure tcg68k.a_op_const_reg(list : taasmoutput; Op: TOpCG; size: tcgsize; a: AWord; reg: TRegister);
|
||||
var
|
||||
scratch_reg : tregister;
|
||||
scratch_reg2: tregister;
|
||||
@ -453,10 +389,8 @@ Implementation
|
||||
Begin
|
||||
if aktoptprocessor = MC68000 then
|
||||
begin
|
||||
r.enum:=R_INTREGISTER;
|
||||
r.number:=NR_D0;
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=NR_D1;
|
||||
r:=NR_D0;
|
||||
r2:=NR_D1;
|
||||
rg.getexplicitregisterint(list,NR_D0);
|
||||
rg.getexplicitregisterint(list,NR_D1);
|
||||
list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, r));
|
||||
@ -484,9 +418,9 @@ Implementation
|
||||
Begin
|
||||
if aktoptprocessor = MC68000 then
|
||||
begin
|
||||
r.enum:=R_INTREGISTER;
|
||||
r:=R_INTREGISTER;
|
||||
r.number:=NR_D0;
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2:=R_INTREGISTER;
|
||||
r2.number:=NR_D1;
|
||||
rg.getexplicitregisterint(list,NR_D0);
|
||||
rg.getexplicitregisterint(list,NR_D1);
|
||||
@ -626,10 +560,10 @@ Implementation
|
||||
list.concat(taicpu.op_reg_reg(topcg2tasmop[op],TCGSize2OpSize[size],hreg1, hreg2));
|
||||
end;
|
||||
|
||||
if reg1.enum <> hreg1.enum then
|
||||
if reg1 <> hreg1 then
|
||||
cg.free_scratch_reg(list,hreg1);
|
||||
{ move back result into destination register }
|
||||
if reg2.enum <> hreg2.enum then
|
||||
if reg2 <> hreg2 then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2));
|
||||
cg.free_scratch_reg(list,hreg2);
|
||||
@ -649,9 +583,9 @@ Implementation
|
||||
sign_extend(list, size,reg2);
|
||||
if aktoptprocessor = MC68000 then
|
||||
begin
|
||||
r.enum:=R_INTREGISTER;
|
||||
r:=R_INTREGISTER;
|
||||
r.number:=NR_D0;
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2:=R_INTREGISTER;
|
||||
r2.number:=NR_D1;
|
||||
rg.getexplicitregisterint(list,NR_D0);
|
||||
rg.getexplicitregisterint(list,NR_D1);
|
||||
@ -680,10 +614,10 @@ Implementation
|
||||
|
||||
list.concat(taicpu.op_reg_reg(A_MULS,S_L,reg1,reg2));
|
||||
|
||||
if reg1.enum <> hreg1.enum then
|
||||
if reg1 <> hreg1 then
|
||||
cg.free_scratch_reg(list,hreg1);
|
||||
{ move back result into destination register }
|
||||
if reg2.enum <> hreg2.enum then
|
||||
if reg2 <> hreg2 then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2));
|
||||
cg.free_scratch_reg(list,hreg2);
|
||||
@ -696,9 +630,9 @@ Implementation
|
||||
sign_extend(list, size,reg2);
|
||||
if aktoptprocessor = MC68000 then
|
||||
begin
|
||||
r.enum:=R_INTREGISTER;
|
||||
r:=R_INTREGISTER;
|
||||
r.number:=NR_D0;
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2:=R_INTREGISTER;
|
||||
r2.number:=NR_D1;
|
||||
rg.getexplicitregisterint(list,NR_D0);
|
||||
rg.getexplicitregisterint(list,NR_D1);
|
||||
@ -747,7 +681,7 @@ Implementation
|
||||
since the operation will only be done on the result
|
||||
register.
|
||||
}
|
||||
if reg1.enum <> R_NO then
|
||||
if reg1 <> NR_NO then
|
||||
cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,reg1,reg2);
|
||||
|
||||
if (rg.isaddressregister(reg2)) then
|
||||
@ -769,7 +703,7 @@ Implementation
|
||||
list.concat(taicpu.op_reg(topcg2tasmop[op],TCGSize2OpSize[size],hreg2));
|
||||
end;
|
||||
|
||||
if reg2.enum <> hreg2.enum then
|
||||
if reg2 <> hreg2 then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2));
|
||||
cg.free_scratch_reg(list,hreg2);
|
||||
@ -1018,10 +952,10 @@ Implementation
|
||||
{ restore the registers that we have just used olny if they are used! }
|
||||
free_scratch_reg(list, iregister);
|
||||
free_scratch_reg(list, jregister);
|
||||
if jregister.enum = R_A1 then
|
||||
hp2.base.enum := R_NO;
|
||||
if iregister.enum = R_A0 then
|
||||
hp1.base.enum := R_NO;
|
||||
if jregister = R_A1 then
|
||||
hp2.base := NR_NO;
|
||||
if iregister = R_A0 then
|
||||
hp1.base := NR_NO;
|
||||
reference_release(list,hp1);
|
||||
reference_release(list,hp2);
|
||||
end;
|
||||
@ -1032,11 +966,11 @@ Implementation
|
||||
free_scratch_reg(list,hregister);
|
||||
end;
|
||||
|
||||
procedure tcg68k.g_overflowcheck(list: taasmoutput; const p: tnode);
|
||||
procedure tcg68k.g_overflowcheck(list: taasmoutput; const l:tlocation; def:tdef);
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure tcg68k.g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);
|
||||
procedure tcg68k.g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword);
|
||||
begin
|
||||
end;
|
||||
|
||||
@ -1045,8 +979,8 @@ Implementation
|
||||
var r,r2,rsp:Tregister;
|
||||
|
||||
begin
|
||||
r.enum:=frame_pointer_reg;
|
||||
rsp.enum:=stack_pointer_reg;
|
||||
r:=frame_pointer_reg;
|
||||
rsp:=stack_pointer_reg;
|
||||
if localsize<>0 then
|
||||
begin
|
||||
{ Not to complicate the code generator too much, and since some }
|
||||
@ -1058,7 +992,7 @@ Implementation
|
||||
end { endif localsize <> 0 }
|
||||
else
|
||||
begin
|
||||
r2.enum:=R_SPPUSH;
|
||||
r2:=R_SPPUSH;
|
||||
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,r,r2));
|
||||
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,rsp,r));
|
||||
end;
|
||||
@ -1069,7 +1003,7 @@ Implementation
|
||||
var r:Tregister;
|
||||
|
||||
begin
|
||||
r.enum:=frame_pointer_reg;
|
||||
r:=frame_pointer_reg;
|
||||
list.concat(taicpu.op_reg(A_UNLK,S_NO,r));
|
||||
end;
|
||||
|
||||
@ -1107,17 +1041,17 @@ Implementation
|
||||
|
||||
{ save the PC counter (pop it from the stack) }
|
||||
hregister := get_scratch_reg_address(list);
|
||||
r.enum:=R_SPPULL;
|
||||
r:=R_SPPULL;
|
||||
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,r,hregister));
|
||||
{ can we do a quick addition ... }
|
||||
r.enum:=R_SP;
|
||||
r:=R_SP;
|
||||
if (parasize > 0) and (parasize < 9) then
|
||||
list.concat(taicpu.op_const_reg(A_ADDQ,S_L,parasize,r))
|
||||
else { nope ... }
|
||||
list.concat(taicpu.op_const_reg(A_ADD,S_L,parasize,r));
|
||||
|
||||
{ restore the PC counter (push it on the stack) }
|
||||
r.enum:=R_SPPUSH;
|
||||
r:=R_SPPUSH;
|
||||
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hregister,r));
|
||||
list.concat(taicpu.op_none(A_RTS,S_NO));
|
||||
free_scratch_reg(list,hregister);
|
||||
@ -1135,7 +1069,7 @@ Implementation
|
||||
tosave:=std_saved_registers;
|
||||
{ only save the registers which are not used and must be saved }
|
||||
tosave:=tosave*usedinproc;
|
||||
r.enum:=R_SPPUSH;
|
||||
r:=R_SPPUSH;
|
||||
if tosave<>[] then
|
||||
list.concat(taicpu.op_reglist_reg(A_MOVEM,S_L,tosave,r));
|
||||
end;
|
||||
@ -1149,7 +1083,7 @@ Implementation
|
||||
torestore:=std_saved_registers;
|
||||
{ should be intersected with used regs, no ? }
|
||||
torestore:=torestore*usedinproc;
|
||||
r.enum:=R_SPPULL;
|
||||
r:=R_SPPULL;
|
||||
if torestore<>[] then
|
||||
list.concat(taicpu.op_reg_reglist(A_MOVEM,S_L,r,torestore));
|
||||
end;
|
||||
@ -1158,7 +1092,7 @@ Implementation
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure tcg68k.g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);
|
||||
procedure tcg68k.g_restore_all_registers(list : taasmoutput;accused,acchiused:boolean);
|
||||
begin
|
||||
end;
|
||||
|
||||
@ -1337,7 +1271,10 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.20 2003-04-27 11:21:36 peter
|
||||
Revision 1.21 2004-01-30 12:17:18 florian
|
||||
* fixed some m68k compilation problems
|
||||
|
||||
Revision 1.20 2003/04/27 11:21:36 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -29,7 +29,7 @@ unit cpubase;
|
||||
interface
|
||||
|
||||
uses
|
||||
strings,cutils,cclasses,aasmbase,cpuinfo,cginfo;
|
||||
strings,cutils,cclasses,aasmbase,cpuinfo,cgbase;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
@ -101,114 +101,49 @@ uses
|
||||
Registers
|
||||
*****************************************************************************}
|
||||
|
||||
{$packenum 1}
|
||||
type
|
||||
Toldregister = (
|
||||
R_NO,R_D0,R_D1,R_D2,R_D3,R_D4,R_D5,R_D6,R_D7,
|
||||
R_A0,R_A1,R_A2,R_A3,R_A4,R_A5,R_A6,R_SP,
|
||||
{ PUSH/PULL- quick and dirty hack }
|
||||
R_SPPUSH,R_SPPULL,
|
||||
{ misc. }
|
||||
R_CCR,R_FP0,R_FP1,R_FP2,R_FP3,R_FP4,R_FP5,R_FP6,
|
||||
R_FP7,R_FPCR,R_SR,R_SSP,R_DFC,R_SFC,R_VBR,R_FPSR,
|
||||
R_INTREGISTER,R_FLOATREGISTER);
|
||||
|
||||
Tnewregister=word;
|
||||
|
||||
Tregister=record
|
||||
enum:Toldregister;
|
||||
number:word;
|
||||
end;
|
||||
|
||||
Tsuperregister=byte;
|
||||
Tsubregister=byte;
|
||||
|
||||
{# Set type definition for registers }
|
||||
tregisterset = set of Toldregister;
|
||||
Tsupregset = set of Tsuperregister;
|
||||
{$packenum normal}
|
||||
|
||||
{ A type to store register locations for 64 Bit values. }
|
||||
tregister64 = packed record
|
||||
reglo,reghi : tregister;
|
||||
end;
|
||||
|
||||
{ alias for compact code }
|
||||
treg64 = tregister64;
|
||||
|
||||
|
||||
{New register coding:}
|
||||
|
||||
{Special registers:}
|
||||
const
|
||||
NR_NO = $0000; {Invalid register}
|
||||
|
||||
{Normal registers:}
|
||||
|
||||
{General purpose registers:}
|
||||
NR_D0 = $0100; NR_D1 = $0200; NR_D2 = $0300;
|
||||
NR_D3 = $0400; NR_D4 = $0500; NR_D5 = $0600;
|
||||
NR_D6 = $0700; NR_D7 = $0800; NR_A0 = $0900;
|
||||
NR_A1 = $0A00; NR_A2 = $0B00; NR_A3 = $0C00;
|
||||
NR_A4 = $0D00; NR_A5 = $0E00; NR_A6 = $0F00;
|
||||
NR_A7 = $1000;
|
||||
|
||||
{Super registers.}
|
||||
RS_D0 = $01; RS_D1 = $02; RS_D2 = $03;
|
||||
RS_D3 = $04; RS_D4 = $05; RS_D5 = $06;
|
||||
RS_D6 = $07; RS_D7 = $08; RS_A0 = $09;
|
||||
RS_A1 = $0A; RS_A2 = $0B; RS_A3 = $0C;
|
||||
RS_A4 = $0D; RS_A5 = $0E; RS_A6 = $0F;
|
||||
RS_A7 = $10;
|
||||
|
||||
{Sub register numbers:}
|
||||
R_SUBL = $00; {8 bits}
|
||||
R_SUBW = $01; {16 bits}
|
||||
R_SUBD = $02; {32 bits}
|
||||
|
||||
{The subregister that specifies the entire register.}
|
||||
R_SUBWHOLE = R_SUBD; {i386}
|
||||
{R_SUBWHOLE = R_SUBQ;} {Hammer}
|
||||
|
||||
{Number of first and last superregister.}
|
||||
first_supreg = $01;
|
||||
last_supreg = $10;
|
||||
|
||||
{$warning FIXME!!!}
|
||||
{ integer registers which may be destroyed by calls }
|
||||
VOLATILE_INTREGISTERS = [first_supreg..last_supreg];
|
||||
{$warning FIXME!!!}
|
||||
{ fpu registers which may be destroyed by calls }
|
||||
VOLATILE_FPUREGISTERS = [first_supreg..last_supreg];
|
||||
|
||||
first_imreg = $11;
|
||||
last_imreg = $ff;
|
||||
|
||||
{# First register in the tregister enumeration }
|
||||
firstreg = low(Toldregister);
|
||||
{# Last register in the tregister enumeration }
|
||||
lastreg = R_FPSR;
|
||||
|
||||
type
|
||||
{# Type definition for the array of string of register nnames }
|
||||
reg2strtable = array[firstreg..lastreg] of string[7];
|
||||
regname2regnumrec = record
|
||||
name:string[6];
|
||||
number:Tnewregister;
|
||||
end;
|
||||
{ Number of registers used for indexing in tables }
|
||||
tregisterindex=0..{$i r68knor.inc}-1;
|
||||
|
||||
const
|
||||
std_reg2str : reg2strtable =
|
||||
('', 'd0','d1','d2','d3','d4','d5','d6','d7',
|
||||
'a0','a1','a2','a3','a4','a5','a6','sp',
|
||||
'-(sp)','(sp)+',
|
||||
'ccr','fp0','fp1','fp2','fp3','fp4','fp5',
|
||||
'fp6','fp7','fpcr','sr','ssp','dfc',
|
||||
'sfc','vbr','fpsr');
|
||||
{ Available Superregisters }
|
||||
{$i r68ksup.inc}
|
||||
|
||||
{ No Subregisters }
|
||||
R_SUBWHOLE = R_SUBNONE;
|
||||
|
||||
{ Available Registers }
|
||||
{$i r68kcon.inc}
|
||||
|
||||
{ Integer Super registers first and last }
|
||||
first_int_supreg = RS_SP;
|
||||
first_int_imreg = RS_SP+1;
|
||||
|
||||
{ Float Super register first and last }
|
||||
first_fpu_supreg = RS_FP7;
|
||||
first_fpu_imreg = RS_FP7+1;
|
||||
|
||||
{ MM Super register first and last }
|
||||
first_mm_supreg = 0;
|
||||
first_mm_imreg = 0;
|
||||
|
||||
regnumber_count_bsstart = 64;
|
||||
|
||||
regnumber_table : array[tregisterindex] of tregister = (
|
||||
{$i r68knum.inc}
|
||||
);
|
||||
|
||||
regstabs_table : array[tregisterindex] of shortint = (
|
||||
{$i r68ksta.inc}
|
||||
);
|
||||
|
||||
{ registers which may be destroyed by calls }
|
||||
VOLATILE_INTREGISTERS = [];
|
||||
VOLATILE_FPUREGISTERS = [];
|
||||
|
||||
type
|
||||
totherregisterset = set of tregisterindex;
|
||||
|
||||
{*****************************************************************************
|
||||
Conditions
|
||||
*****************************************************************************}
|
||||
|
||||
{*****************************************************************************
|
||||
Conditions
|
||||
@ -265,34 +200,12 @@ uses
|
||||
|
||||
{ reference record }
|
||||
pparareference = ^tparareference;
|
||||
tparareference = packed record
|
||||
index : tregister;
|
||||
tparareference = record
|
||||
offset : longint;
|
||||
index : tregister;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Operands
|
||||
*****************************************************************************}
|
||||
|
||||
{ Types of operand }
|
||||
toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_reglist);
|
||||
|
||||
tregisterlist = set of Toldregister;
|
||||
|
||||
toper=record
|
||||
ot : longint;
|
||||
case typ : toptype of
|
||||
top_none : ();
|
||||
top_reg : (reg:tregister);
|
||||
top_ref : (ref:preference);
|
||||
top_const : (val:aword);
|
||||
top_symbol : (sym:tasmsymbol;symofs:longint);
|
||||
{ used for pushing/popping multiple registers }
|
||||
top_reglist : (registerlist:Tsupregset);
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
Generic Location
|
||||
*****************************************************************************}
|
||||
@ -302,10 +215,10 @@ uses
|
||||
References are given from the caller's point of view. The usual
|
||||
TLocation isn't used, because contains a lot of unnessary fields.
|
||||
}
|
||||
tparalocation = packed record
|
||||
tparalocation = record
|
||||
size : TCGSize;
|
||||
loc : TCGLoc;
|
||||
sp_fixup : longint;
|
||||
alignment : byte;
|
||||
case TCGLoc of
|
||||
LOC_REFERENCE : (reference : tparareference);
|
||||
{ segment in reference at the same place as in loc_register }
|
||||
@ -320,7 +233,7 @@ uses
|
||||
);
|
||||
end;
|
||||
|
||||
tlocation = packed record
|
||||
tlocation = record
|
||||
loc : TCGLoc;
|
||||
size : TCGSize;
|
||||
case TCGLoc of
|
||||
@ -371,119 +284,6 @@ uses
|
||||
{# maximum number of operands in assembler instruction }
|
||||
max_operands = 4;
|
||||
|
||||
lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,LOC_CREGISTER];
|
||||
|
||||
general_registers = [R_D0..R_D7];
|
||||
general_superregisters = [RS_D0..RS_D7];
|
||||
|
||||
{# low and high of the available maximum width integer general purpose }
|
||||
{ registers }
|
||||
LoGPReg = R_D0;
|
||||
HiGPReg = R_D7;
|
||||
|
||||
{# low and high of every possible width general purpose register (same as }
|
||||
{ above on most architctures apart from the 80x86) }
|
||||
LoReg = LoGPReg;
|
||||
HiReg = HiGPReg;
|
||||
|
||||
{ Table of registers which can be allocated by the code generator
|
||||
internally, when generating the code.
|
||||
|
||||
legend:
|
||||
xxxregs = set of all possibly used registers of that type in the code
|
||||
generator
|
||||
usableregsxxx = set of all 32bit components of registers that can be
|
||||
possible allocated to a regvar or using getregisterxxx (this
|
||||
excludes registers which can be only used for parameter
|
||||
passing on ABI's that define this)
|
||||
c_countusableregsxxx = amount of registers in the usableregsxxx set }
|
||||
|
||||
maxintregs = 8;
|
||||
{ to determine how many registers to use for regvars }
|
||||
maxintscratchregs = 1;
|
||||
intregs = [R_D0..R_D7];
|
||||
usableregsint = [RS_D2..RS_D7];
|
||||
c_countusableregsint = 6;
|
||||
|
||||
maxfpuregs = 8;
|
||||
fpuregs = [R_FP0..R_FP7];
|
||||
usableregsfpu = [R_FP2..R_FP7];
|
||||
c_countusableregsfpu = 6;
|
||||
|
||||
mmregs = [];
|
||||
usableregsmm = [];
|
||||
c_countusableregsmm = 0;
|
||||
|
||||
maxaddrregs = 8;
|
||||
addrregs = [R_A0..R_SP];
|
||||
usableregsaddr = [RS_A2..RS_A4];
|
||||
c_countusableregsaddr = 3;
|
||||
|
||||
|
||||
{ The first register in the usableregsint array }
|
||||
firstsaveintreg = RS_D2;
|
||||
{ The last register in the usableregsint array }
|
||||
lastsaveintreg = RS_D7;
|
||||
{ The first register in the usableregsfpu array }
|
||||
firstsavefpureg = R_FP2;
|
||||
{ The last register in the usableregsfpu array }
|
||||
lastsavefpureg = R_FP7;
|
||||
|
||||
{ these constants are m68k specific }
|
||||
{ The first register in the usableregsaddr array }
|
||||
firstsaveaddrreg = RS_A2;
|
||||
{ The last register in the usableregsaddr array }
|
||||
lastsaveaddrreg = RS_A4;
|
||||
|
||||
firstsavemmreg = R_NO;
|
||||
lastsavemmreg = R_NO;
|
||||
|
||||
{
|
||||
Defines the maxinum number of integer registers which can be used as variable registers
|
||||
}
|
||||
maxvarregs = 6;
|
||||
{ Array of integer registers which can be used as variable registers }
|
||||
varregs : Array [1..maxvarregs] of Toldregister =
|
||||
(R_D2,R_D3,R_D4,R_D5,R_D6,R_D7);
|
||||
|
||||
{
|
||||
Defines the maxinum number of float registers which can be used as variable registers
|
||||
}
|
||||
maxfpuvarregs = 6;
|
||||
{ Array of float registers which can be used as variable registers }
|
||||
fpuvarregs : Array [1..maxfpuvarregs] of Toldregister =
|
||||
(R_FP2,R_FP3,R_FP4,R_FP5,R_FP6,R_FP7);
|
||||
|
||||
{
|
||||
Defines the number of integer registers which are used in the ABI to pass parameters
|
||||
(might be empty on systems which use the stack to pass parameters)
|
||||
}
|
||||
max_param_regs_int = 0;
|
||||
{param_regs_int: Array[1..max_param_regs_int] of tregister =
|
||||
(R_3,R_4,R_5,R_6,R_7,R_8,R_9,R_10);}
|
||||
|
||||
{
|
||||
Defines the number of float registers which are used in the ABI to pass parameters
|
||||
(might be empty on systems which use the stack to pass parameters)
|
||||
}
|
||||
max_param_regs_fpu = 0;
|
||||
{param_regs_fpu: Array[1..max_param_regs_fpu] of tregister =
|
||||
(R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,R_F13);}
|
||||
|
||||
{
|
||||
Defines the number of mmx registers which are used in the ABI to pass parameters
|
||||
(might be empty on systems which use the stack to pass parameters)
|
||||
}
|
||||
max_param_regs_mm = 0;
|
||||
{param_regs_mm: Array[1..max_param_regs_mm] of tregister =
|
||||
(R_M1,R_M2,R_M3,R_M4,R_M5,R_M6,R_M7,R_M8,R_M9,R_M10,R_M11,R_M12,R_M13);}
|
||||
|
||||
{# Registers which are defined as scratch integer and no need to save across
|
||||
routine calls or in assembler blocks.
|
||||
}
|
||||
max_scratch_regs = 4;
|
||||
scratch_regs: Array[1..max_scratch_regs] of Tsuperregister = (RS_D0,RS_D1,RS_A0,RS_A1);
|
||||
|
||||
{*****************************************************************************
|
||||
Default generic sizes
|
||||
*****************************************************************************}
|
||||
@ -511,57 +311,47 @@ uses
|
||||
This is not compatible with the m68k-sun
|
||||
implementation.
|
||||
}
|
||||
stab_regindex : array[firstreg..lastreg] of shortint =
|
||||
(-1, { R_NO }
|
||||
0,1,2,3,4,5,6,7, { R_D0..R_D7 }
|
||||
8,9,10,11,12,13,14,15, { R_A0..R_A7 }
|
||||
-1,-1,-1, { R_SPPUSH, R_SPPULL, R_CCR }
|
||||
18,19,20,21,22,23,24,25, { R_FP0..R_FP7 }
|
||||
-1,-1,-1,-1,-1,-1,-1);
|
||||
stab_regindex : array[tregisterindex] of shortint =
|
||||
(
|
||||
{$i r68ksta.inc}
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
Generic Register names
|
||||
*****************************************************************************}
|
||||
|
||||
{# Stack pointer register }
|
||||
stack_pointer_reg = R_SP;
|
||||
NR_STACK_POINTER_REG = NR_A7;
|
||||
RS_STACK_POINTER_REG = RS_A7;
|
||||
NR_STACK_POINTER_REG = NR_SP;
|
||||
RS_STACK_POINTER_REG = RS_SP;
|
||||
{# Frame pointer register }
|
||||
frame_pointer_reg = R_A6;
|
||||
NR_FRAME_POINTER_REG = NR_A6;
|
||||
RS_FRAME_POINTER_REG = RS_A6;
|
||||
{# Self pointer register : contains the instance address of an
|
||||
object or class. }
|
||||
self_pointer_reg = R_A5;
|
||||
NR_SELF_POINTER_REG = NR_A5;
|
||||
RS_SELF_POINTER_REG = RS_A5;
|
||||
{# Register for addressing absolute data in a position independant way,
|
||||
such as in PIC code. The exact meaning is ABI specific. For
|
||||
further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
|
||||
}
|
||||
pic_offset_reg = R_A5;
|
||||
{# Results are returned in this register (32-bit values) }
|
||||
accumulator = R_D0;
|
||||
NR_ACCUMULATOR = NR_D0;
|
||||
RS_ACCUMULATOR = RS_D0;
|
||||
{the return_result_reg, is used inside the called function to store its return
|
||||
value when that is a scalar value otherwise a pointer to the address of the
|
||||
result is placed inside it}
|
||||
return_result_reg = accumulator;
|
||||
NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
|
||||
RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
|
||||
NR_PIC_OFFSET_REG = NR_A5;
|
||||
{ Results are returned in this register (32-bit values) }
|
||||
NR_FUNCTION_RETURN_REG = NR_D0;
|
||||
RS_FUNCTION_RETURN_REG = NR_D0;
|
||||
{ Low part of 64bit return value }
|
||||
NR_FUNCTION_RETURN64_LOW_REG = NR_D0;
|
||||
RS_FUNCTION_RETURN64_LOW_REG = RS_D0;
|
||||
{ High part of 64bit return value }
|
||||
NR_FUNCTION_RETURN64_HIGH_REG = NR_D1;
|
||||
RS_FUNCTION_RETURN64_HIGH_REG = RS_D1;
|
||||
{ The value returned from a function is available in this register }
|
||||
NR_FUNCTION_RESULT_REG = NR_FUNCTION_RETURN_REG;
|
||||
RS_FUNCTION_RESULT_REG = RS_FUNCTION_RETURN_REG;
|
||||
{ The lowh part of 64bit value returned from a function }
|
||||
NR_FUNCTION_RESULT64_LOW_REG = NR_FUNCTION_RETURN64_LOW_REG;
|
||||
RS_FUNCTION_RESULT64_LOW_REG = RS_FUNCTION_RETURN64_LOW_REG;
|
||||
{ The high part of 64bit value returned from a function }
|
||||
NR_FUNCTION_RESULT64_HIGH_REG = NR_FUNCTION_RETURN64_HIGH_REG;
|
||||
RS_FUNCTION_RESULT64_HIGH_REG = RS_FUNCTION_RETURN64_HIGH_REG;
|
||||
|
||||
{the function_result_reg contains the function result after a call to a scalar
|
||||
function othewise it contains a pointer to the returned result}
|
||||
function_result_reg = accumulator;
|
||||
{# Hi-Results are returned in this register (64-bit value high register) }
|
||||
accumulatorhigh = R_D1;
|
||||
NR_ACCUMULATORHIGH = NR_D1;
|
||||
RS_ACCUMULATORHIGH = RS_D1;
|
||||
{# Floating point results will be placed into this register }
|
||||
FPU_RESULT_REG = R_FP0;
|
||||
mmresultreg = R_NO;
|
||||
NR_FPU_RESULT_REG = NR_FP0;
|
||||
|
||||
{*****************************************************************************
|
||||
GCC /ABI linking information
|
||||
@ -597,14 +387,32 @@ uses
|
||||
|
||||
procedure inverse_flags(var r : TResFlags);
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
procedure convert_register_to_enum(var r:Tregister);
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function supreg_name(r:Tsuperregister):string;
|
||||
|
||||
function findreg_by_number(r:Tregister):tregisterindex;
|
||||
function std_regnum_search(const s:string):Tregister;
|
||||
function std_regname(r:Tregister):string;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose;
|
||||
verbose,
|
||||
rgbase;
|
||||
|
||||
|
||||
const
|
||||
std_regname_table : array[tregisterindex] of string[7] = (
|
||||
{$i r68kstd.inc}
|
||||
);
|
||||
|
||||
regnumber_index : array[tregisterindex] of tregisterindex = (
|
||||
{$i r68krni.inc}
|
||||
);
|
||||
|
||||
std_regname_index : array[tregisterindex] of tregisterindex = (
|
||||
{$i r68ksri.inc}
|
||||
);
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Helpers
|
||||
@ -618,6 +426,7 @@ implementation
|
||||
is_calljmp := true;
|
||||
end;
|
||||
|
||||
|
||||
procedure inverse_flags(var r: TResFlags);
|
||||
const flagsinvers : array[F_E..F_BE] of tresflags =
|
||||
(F_NE,F_E,
|
||||
@ -650,71 +459,51 @@ implementation
|
||||
flags_to_cond := flags2cond[f];
|
||||
end;
|
||||
|
||||
procedure convert_register_to_enum(var r:Tregister);
|
||||
|
||||
begin
|
||||
if r.enum = R_INTREGISTER then
|
||||
case r.number of
|
||||
NR_NO: r.enum:= R_NO;
|
||||
NR_D0: r.enum:= R_D0;
|
||||
NR_D1: r.enum:= R_D1;
|
||||
NR_D2: r.enum:= R_D2;
|
||||
NR_D3: r.enum:= R_D3;
|
||||
NR_D4: r.enum:= R_D4;
|
||||
NR_D5: r.enum:= R_D5;
|
||||
NR_D6: r.enum:= R_D6;
|
||||
NR_D7: r.enum:= R_D7;
|
||||
NR_A0: r.enum:= R_A0;
|
||||
NR_A1: r.enum:= R_A1;
|
||||
NR_A2: r.enum:= R_A2;
|
||||
NR_A3: r.enum:= R_A3;
|
||||
NR_A4: r.enum:= R_A4;
|
||||
NR_A5: r.enum:= R_A5;
|
||||
NR_A6: r.enum:= R_A6;
|
||||
NR_A7: r.enum:= R_SP;
|
||||
else
|
||||
internalerror(200301082);
|
||||
end;
|
||||
end;
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
|
||||
begin
|
||||
case s of
|
||||
OS_8,OS_S8:
|
||||
cgsize2subreg:=R_SUBL;
|
||||
OS_16,OS_S16:
|
||||
cgsize2subreg:=R_SUBW;
|
||||
OS_32,OS_S32:
|
||||
cgsize2subreg:=R_SUBD;
|
||||
else
|
||||
internalerror(200301231);
|
||||
end;
|
||||
end;
|
||||
|
||||
function supreg_name(r:Tsuperregister):string;
|
||||
|
||||
var s:string[4];
|
||||
|
||||
const supreg_names:array[0..last_supreg] of string[4]=
|
||||
('INV',
|
||||
'd0','d1','d2','d3','d4','d5','d6','d7',
|
||||
'a0','a1','a2','a3','a4','a5','a6','sp');
|
||||
|
||||
begin
|
||||
if r in [0..last_supreg] then
|
||||
supreg_name:=supreg_names[r]
|
||||
else
|
||||
begin
|
||||
str(r,s);
|
||||
supreg_name:='reg'+s;
|
||||
begin
|
||||
case s of
|
||||
OS_8,OS_S8:
|
||||
cgsize2subreg:=R_SUBL;
|
||||
OS_16,OS_S16:
|
||||
cgsize2subreg:=R_SUBW;
|
||||
OS_32,OS_S32:
|
||||
cgsize2subreg:=R_SUBD;
|
||||
else
|
||||
internalerror(200301231);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function findreg_by_number(r:Tregister):tregisterindex;
|
||||
begin
|
||||
result:=findreg_by_number_table(r,regnumber_index);
|
||||
end;
|
||||
|
||||
|
||||
function std_regnum_search(const s:string):Tregister;
|
||||
begin
|
||||
result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)];
|
||||
end;
|
||||
|
||||
|
||||
function std_regname(r:Tregister):string;
|
||||
var
|
||||
p : tregisterindex;
|
||||
begin
|
||||
p:=findreg_by_number_table(r,regnumber_index);
|
||||
if p<>0 then
|
||||
result:=std_regname_table[p]
|
||||
else
|
||||
result:=generic_regname(r);
|
||||
end;
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.23 2003-08-17 16:59:20 jonas
|
||||
Revision 1.24 2004-01-30 12:17:18 florian
|
||||
* fixed some m68k compilation problems
|
||||
|
||||
Revision 1.23 2003/08/17 16:59:20 jonas
|
||||
* fixed regvars so they work with newra (at least for ppc)
|
||||
* fixed some volatile register bugs
|
||||
+ -dnotranslation option for -dnewra, which causes the registers not to
|
||||
|
@ -17,6 +17,9 @@ Unit CPUInfo;
|
||||
|
||||
Interface
|
||||
|
||||
uses
|
||||
globtype;
|
||||
|
||||
Type
|
||||
{ Architecture word - Native unsigned type }
|
||||
aword = longword;
|
||||
@ -35,6 +38,7 @@ Type
|
||||
ts32real = single;
|
||||
ts64real = double;
|
||||
ts80real = extended;
|
||||
ts128real = type extended;
|
||||
ts64comp = extended;
|
||||
|
||||
pbestreal=^bestreal;
|
||||
@ -47,6 +51,13 @@ Type
|
||||
Coldfire
|
||||
);
|
||||
|
||||
tfputype =
|
||||
(no_fpuprocessor,
|
||||
fpu_soft,
|
||||
fpu_libgcc,
|
||||
fpu_68881
|
||||
);
|
||||
|
||||
Const
|
||||
{# Size of native extended floating point type }
|
||||
extended_size = 8;
|
||||
@ -73,15 +84,30 @@ Const
|
||||
{ the difference to stdcall is only the name mangling }
|
||||
pocall_cppdecl,
|
||||
{ this used by the PalmOS port only }
|
||||
pocall_syscall
|
||||
pocall_palmossyscall
|
||||
];
|
||||
|
||||
processorsstr : array[tprocessors] of string[5] = ('',
|
||||
'68000',
|
||||
'68020',
|
||||
'COLDFIRE'
|
||||
);
|
||||
|
||||
fputypestr : array[tfputype] of string[6] = ('',
|
||||
'SOFT',
|
||||
'LIBGCC',
|
||||
'68881'
|
||||
);
|
||||
|
||||
Implementation
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.7 2003-11-07 15:58:32 florian
|
||||
Revision 1.8 2004-01-30 12:17:18 florian
|
||||
* fixed some m68k compilation problems
|
||||
|
||||
Revision 1.7 2003/11/07 15:58:32 florian
|
||||
* Florian's culmutative nr. 1; contains:
|
||||
- invalid calling conventions for a certain cpu are rejected
|
||||
- arm softfloat calling conventions
|
||||
|
@ -29,8 +29,10 @@ unit cpupara;
|
||||
interface
|
||||
|
||||
uses
|
||||
cpubase,
|
||||
symdef,paramgr;
|
||||
globtype,
|
||||
cpubase,
|
||||
symconst,symdef,
|
||||
paramgr;
|
||||
|
||||
type
|
||||
{ Returns the location for the nr-st 32 Bit int parameter
|
||||
@ -39,9 +41,8 @@ unit cpupara;
|
||||
rtl are used.
|
||||
}
|
||||
tm68kparamanager = class(tparamanager)
|
||||
function getintparaloc(nr : longint) : tparalocation;override;
|
||||
procedure create_param_loc_info(p : tabstractprocdef);override;
|
||||
function getselflocation(p : tabstractprocdef) : tparalocation;override;
|
||||
function getintparaloc(calloption : tproccalloption;nr : longint) : tparalocation;override;
|
||||
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -49,12 +50,11 @@ unit cpupara;
|
||||
uses
|
||||
verbose,
|
||||
globals,
|
||||
globtype,
|
||||
systems,
|
||||
cpuinfo,cginfo,cgbase,
|
||||
cpuinfo,cgbase,
|
||||
defutil;
|
||||
|
||||
function tm68kparamanager.getintparaloc(nr : longint) : tparalocation;
|
||||
function tm68kparamanager.getintparaloc(calloption : tproccalloption;nr : longint) : tparalocation;
|
||||
begin
|
||||
fillchar(result,sizeof(tparalocation),0);
|
||||
if nr<1 then
|
||||
@ -65,49 +65,51 @@ unit cpupara;
|
||||
WHICH MUST ALWAYS PASS 4-BYTE PARAMETERS!!
|
||||
}
|
||||
result.loc:=LOC_REFERENCE;
|
||||
result.reference.index.enum:=frame_pointer_reg;
|
||||
result.reference.offset:=target_info.first_parm_offset
|
||||
+nr*4;
|
||||
result.reference.index:=NR_STACK_POINTER_REG;
|
||||
result.reference.offset:=target_info.first_parm_offset+nr*4;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tm68kparamanager.create_param_loc_info(p : tabstractprocdef);
|
||||
|
||||
function tm68kparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
||||
var
|
||||
param_offset : integer;
|
||||
param_offset : integer;
|
||||
hp : tparaitem;
|
||||
paraloc: tparalocation;
|
||||
l : longint;
|
||||
parasize : longint;
|
||||
begin
|
||||
{ frame pointer for nested procedures? }
|
||||
{ inc(nextintreg); }
|
||||
{ constructor? }
|
||||
{ destructor? }
|
||||
param_offset := target_info.first_parm_offset;
|
||||
param_offset := target_info.first_parm_offset;
|
||||
hp:=tparaitem(p.para.last);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
hp.paraloc.loc:=LOC_REFERENCE;
|
||||
hp.paraloc.sp_fixup:=0;
|
||||
hp.paraloc.reference.index.enum:=frame_pointer_reg;
|
||||
hp.paraloc.reference.offset:=param_offset;
|
||||
inc(param_offset,aktalignment.paraalign);
|
||||
hp.paraloc.size := def_cgsize(hp.paratype.def);
|
||||
hp:=tparaitem(hp.previous);
|
||||
paraloc.size:=def_cgsize(hp.paratype.def);
|
||||
paraloc.loc:=LOC_REFERENCE;
|
||||
paraloc.alignment:=4;
|
||||
paraloc.reference.index:=NR_FRAME_POINTER_REG;
|
||||
l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
|
||||
paraloc.reference.offset:=parasize;
|
||||
parasize:=parasize+l;
|
||||
hp.paraloc[callerside]:=paraloc;
|
||||
hp:=tparaitem(hp.next);
|
||||
end;
|
||||
end;
|
||||
|
||||
function tm68kparamanager.getselflocation(p : tabstractprocdef) : tparalocation;
|
||||
begin
|
||||
getselflocation.loc:=LOC_REFERENCE;
|
||||
getselflocation.reference.index.enum:=R_SP;
|
||||
getselflocation.reference.offset:=4;
|
||||
end;
|
||||
|
||||
begin
|
||||
paramanager:=tm68kparamanager.create;
|
||||
paramanager:=tm68kparamanager.create;
|
||||
end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.4 2003-02-02 19:25:54 carl
|
||||
Revision 1.5 2004-01-30 12:17:18 florian
|
||||
* fixed some m68k compilation problems
|
||||
|
||||
Revision 1.4 2003/02/02 19:25:54 carl
|
||||
* Several bugfixes for m68k target (register alloc., opcode emission)
|
||||
+ VIS target
|
||||
+ Generic add more complete (still not verified)
|
||||
|
@ -54,7 +54,7 @@ begin
|
||||
'-' :
|
||||
begin
|
||||
initglobalswitches:=initglobalswitches-[cs_optimize,cs_fastoptimize,cs_slowoptimize,cs_littlesize,
|
||||
cs_regalloc,cs_uncertainopts];
|
||||
cs_regvars,cs_uncertainopts];
|
||||
FillChar(ParaAlignment,sizeof(ParaAlignment),0);
|
||||
end;
|
||||
'a' :
|
||||
@ -66,7 +66,7 @@ begin
|
||||
'G' : initglobalswitches:=initglobalswitches-[cs_littlesize];
|
||||
'r' :
|
||||
begin
|
||||
initglobalswitches:=initglobalswitches+[cs_regalloc];
|
||||
initglobalswitches:=initglobalswitches+[cs_regvars];
|
||||
Simplify_ppu:=false;
|
||||
end;
|
||||
'u' : initglobalswitches:=initglobalswitches+[cs_uncertainopts];
|
||||
@ -107,7 +107,10 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.6 2002-08-13 18:51:29 carl
|
||||
Revision 1.7 2004-01-30 12:17:18 florian
|
||||
* fixed some m68k compilation problems
|
||||
|
||||
Revision 1.6 2002/08/13 18:51:29 carl
|
||||
+ m68k problems with cvs fixed?()!
|
||||
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
{ don't edit, this file is generated from m68kreg.dat }
|
||||
NR_NO = $00000000;
|
||||
NR_D0 = $01000000;
|
||||
NR_D1 = $01000001;
|
||||
NR_D2 = $01000002;
|
||||
NR_D3 = $01000003;
|
||||
NR_D4 = $01000004;
|
||||
NR_D5 = $01000005;
|
||||
NR_D6 = $01000006;
|
||||
NR_D7 = $01000007;
|
||||
NR_A0 = $01000008;
|
||||
NR_A1 = $01000009;
|
||||
NR_A2 = $0100000a;
|
||||
NR_A3 = $0100000b;
|
||||
NR_A4 = $0100000c;
|
||||
NR_A5 = $0100000d;
|
||||
NR_A6 = $0100000e;
|
||||
NR_SP = $0100000f;
|
||||
NR_FP0 = $02000000;
|
||||
NR_FP1 = $02000001;
|
||||
NR_FP2 = $02000002;
|
||||
NR_FP3 = $02000003;
|
||||
NR_FP4 = $02000004;
|
||||
NR_FP5 = $02000005;
|
||||
NR_FP6 = $02000006;
|
||||
NR_FP7 = $02000007;
|
||||
NR_PC = $05000000;
|
||||
NR_NO = tregister($00000000);
|
||||
NR_D0 = tregister($01000000);
|
||||
NR_D1 = tregister($01000001);
|
||||
NR_D2 = tregister($01000002);
|
||||
NR_D3 = tregister($01000003);
|
||||
NR_D4 = tregister($01000004);
|
||||
NR_D5 = tregister($01000005);
|
||||
NR_D6 = tregister($01000006);
|
||||
NR_D7 = tregister($01000007);
|
||||
NR_A0 = tregister($01000008);
|
||||
NR_A1 = tregister($01000009);
|
||||
NR_A2 = tregister($0100000a);
|
||||
NR_A3 = tregister($0100000b);
|
||||
NR_A4 = tregister($0100000c);
|
||||
NR_A5 = tregister($0100000d);
|
||||
NR_A6 = tregister($0100000e);
|
||||
NR_SP = tregister($0100000f);
|
||||
NR_FP0 = tregister($02000000);
|
||||
NR_FP1 = tregister($02000001);
|
||||
NR_FP2 = tregister($02000002);
|
||||
NR_FP3 = tregister($02000003);
|
||||
NR_FP4 = tregister($02000004);
|
||||
NR_FP5 = tregister($02000005);
|
||||
NR_FP6 = tregister($02000006);
|
||||
NR_FP7 = tregister($02000007);
|
||||
NR_PC = tregister($05000000);
|
||||
|
@ -1,27 +1,27 @@
|
||||
{ don't edit, this file is generated from m68kreg.dat }
|
||||
NR_NO,
|
||||
NR_D0,
|
||||
NR_D1,
|
||||
NR_D2,
|
||||
NR_D3,
|
||||
NR_D4,
|
||||
NR_D5,
|
||||
NR_D6,
|
||||
NR_D7,
|
||||
NR_A0,
|
||||
NR_A1,
|
||||
NR_A2,
|
||||
NR_A3,
|
||||
NR_A4,
|
||||
NR_A5,
|
||||
NR_A6,
|
||||
NR_SP,
|
||||
NR_FP0,
|
||||
NR_FP1,
|
||||
NR_FP2,
|
||||
NR_FP3,
|
||||
NR_FP4,
|
||||
NR_FP5,
|
||||
NR_FP6,
|
||||
NR_FP7,
|
||||
NR_PC
|
||||
tregister($00000000),
|
||||
tregister($01000000),
|
||||
tregister($01000001),
|
||||
tregister($01000002),
|
||||
tregister($01000003),
|
||||
tregister($01000004),
|
||||
tregister($01000005),
|
||||
tregister($01000006),
|
||||
tregister($01000007),
|
||||
tregister($01000008),
|
||||
tregister($01000009),
|
||||
tregister($0100000a),
|
||||
tregister($0100000b),
|
||||
tregister($0100000c),
|
||||
tregister($0100000d),
|
||||
tregister($0100000e),
|
||||
tregister($0100000f),
|
||||
tregister($02000000),
|
||||
tregister($02000001),
|
||||
tregister($02000002),
|
||||
tregister($02000003),
|
||||
tregister($02000004),
|
||||
tregister($02000005),
|
||||
tregister($02000006),
|
||||
tregister($02000007),
|
||||
tregister($05000000)
|
||||
|
@ -35,184 +35,18 @@ unit rgcpu;
|
||||
|
||||
type
|
||||
trgcpu = class(trgobj)
|
||||
procedure saveStateForInline(var state: pointer);override;
|
||||
procedure restoreStateAfterInline(var state: pointer);override;
|
||||
procedure saveUnusedState(var state: pointer);override;
|
||||
procedure restoreUnusedState(var state: pointer);override;
|
||||
function isaddressregister(reg: tregister): boolean; override;
|
||||
function getaddressregister(list: taasmoutput): tregister; override;
|
||||
procedure ungetaddressregister(list: taasmoutput; r: tregister); override;
|
||||
procedure resetusableregisters;override;
|
||||
procedure restoreusedintregisters(list:Taasmoutput;
|
||||
const saved:Tpushedsavedint);override;
|
||||
procedure saveusedintregisters(list:Taasmoutput;
|
||||
var saved:Tpushedsavedint;
|
||||
const s:Tsupregset);override;
|
||||
procedure cleartempgen;override;
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
cgobj,tgobj,cpuinfo;
|
||||
|
||||
procedure trgcpu.ungetaddressregister(list: taasmoutput; r: tregister);
|
||||
begin
|
||||
ungetregistergenint(list,r,usableregsaddr,unusedregsaddr,
|
||||
countunusedregsaddr);
|
||||
end;
|
||||
|
||||
|
||||
function trgcpu.getaddressregister(list: taasmoutput): tregister;
|
||||
|
||||
begin
|
||||
result:=getregistergenint(list,
|
||||
R_SUBWHOLE,
|
||||
firstsaveaddrreg,
|
||||
lastsaveaddrreg,
|
||||
usedintbyproc,
|
||||
usedintinproc,
|
||||
unusedregsint,
|
||||
countunusedregsint);
|
||||
|
||||
end;
|
||||
|
||||
function trgcpu.isaddressregister(reg: tregister): boolean;
|
||||
|
||||
begin
|
||||
isaddressregister := reg.enum in addrregs;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.resetusableregisters;
|
||||
|
||||
begin
|
||||
inherited resetusableregisters;
|
||||
{ initialize fields with constant values from cpubase }
|
||||
countusableregsaddr := cpubase.c_countusableregsaddr;
|
||||
usableregsaddr := cpubase.usableregsaddr;
|
||||
end;
|
||||
|
||||
|
||||
procedure Trgcpu.restoreusedintregisters(list:Taasmoutput;
|
||||
const saved:Tpushedsavedint);
|
||||
var r:Tsuperregister;
|
||||
r2,r3:Tregister;
|
||||
hr:Treference;
|
||||
|
||||
begin
|
||||
inherited restoreusedintregisters(list, saved);
|
||||
|
||||
for r:=lastsaveaddrreg downto firstsaveaddrreg do
|
||||
begin
|
||||
if saved[r].ofs<>reg_not_saved then
|
||||
begin
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=NR_FRAME_POINTER_REG;
|
||||
reference_reset_base(hr,r2,saved[r].ofs);
|
||||
r3.enum:=R_INTREGISTER;
|
||||
r3.number:=r shl 8 or R_SUBWHOLE;
|
||||
cg.a_reg_alloc(list,r3);
|
||||
cg.a_load_ref_reg(list,OS_ADDR,hr,r3);
|
||||
if not (r in unusedregsaddr) then
|
||||
{ internalerror(10)
|
||||
in n386cal we always save/restore the reg *state*
|
||||
using save/restoreunusedstate -> the current state
|
||||
may not be real (JM) }
|
||||
else
|
||||
begin
|
||||
dec(countunusedregsaddr);
|
||||
exclude(unusedregsaddr,r);
|
||||
end;
|
||||
tg.ungettemp(list,hr);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Trgcpu.saveusedintregisters(list:Taasmoutput;
|
||||
var saved:Tpushedsavedint;
|
||||
const s:Tsupregset);
|
||||
var r:Tsuperregister;
|
||||
r2:Tregister;
|
||||
hr:Treference;
|
||||
|
||||
begin
|
||||
inherited saveusedintregisters(list,saved,s);
|
||||
for r:=firstsaveaddrreg to lastsaveaddrreg do
|
||||
begin
|
||||
saved[r].ofs:=reg_not_saved;
|
||||
{ if the register is used by the calling subroutine and if }
|
||||
{ it's not a regvar (those are handled separately) }
|
||||
if not(r in is_reg_var_int) and (r in s) and
|
||||
{ and is present in use }
|
||||
not(r in unusedregsaddr) then
|
||||
begin
|
||||
{ then save it }
|
||||
tg.gettemp(list,pointer_size,tt_persistant,hr);
|
||||
saved[r].ofs:=hr.offset;
|
||||
r2.enum:=R_INTREGISTER;
|
||||
r2.number:=r shl 8 or R_SUBWHOLE;
|
||||
cg.a_load_reg_ref(list,OS_ADDR,r2,hr);
|
||||
cg.a_reg_dealloc(list,r2);
|
||||
include(unusedregsaddr,r);
|
||||
inc(countunusedregsaddr);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure trgcpu.saveStateForInline(var state: pointer);
|
||||
begin
|
||||
inherited savestateforinline(state);
|
||||
psavedstate(state)^.unusedregsaddr := unusedregsaddr;
|
||||
psavedstate(state)^.usableregsaddr := usableregsaddr;
|
||||
psavedstate(state)^.countunusedregsaddr := countunusedregsaddr;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.restoreStateAfterInline(var state: pointer);
|
||||
begin
|
||||
unusedregsaddr := psavedstate(state)^.unusedregsaddr;
|
||||
usableregsaddr := psavedstate(state)^.usableregsaddr;
|
||||
countunusedregsaddr := psavedstate(state)^.countunusedregsaddr;
|
||||
inherited restoreStateAfterInline(state);
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.saveUnusedState(var state: pointer);
|
||||
begin
|
||||
inherited saveUnusedState(state);
|
||||
punusedstate(state)^.unusedregsaddr := unusedregsaddr;
|
||||
punusedstate(state)^.countunusedregsaddr := countunusedregsaddr;
|
||||
end;
|
||||
|
||||
|
||||
procedure trgcpu.restoreUnusedState(var state: pointer);
|
||||
begin
|
||||
unusedregsaddr := punusedstate(state)^.unusedregsaddr;
|
||||
countunusedregsaddr := punusedstate(state)^.countunusedregsaddr;
|
||||
inherited restoreUnusedState(state);
|
||||
end;
|
||||
|
||||
procedure trgcpu.cleartempgen;
|
||||
|
||||
begin
|
||||
inherited cleartempgen;
|
||||
countunusedregsaddr:=countusableregsaddr;
|
||||
unusedregsaddr:=usableregsaddr;
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
rg := trgcpu.create(16);
|
||||
end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.9 2003-04-23 13:40:33 peter
|
||||
Revision 1.10 2004-01-30 12:17:18 florian
|
||||
* fixed some m68k compilation problems
|
||||
|
||||
Revision 1.9 2003/04/23 13:40:33 peter
|
||||
* fix m68k compile
|
||||
|
||||
Revision 1.8 2003/04/22 10:09:35 daniel
|
||||
|
Loading…
Reference in New Issue
Block a user