* fixed some m68k compilation problems

This commit is contained in:
florian 2004-01-30 12:17:18 +00:00
parent 828fab3da9
commit b80d10cb70
9 changed files with 361 additions and 755 deletions

View File

@ -29,7 +29,7 @@ interface
uses uses
cclasses,aasmtai, cclasses,aasmtai,
aasmbase,globals,verbose, aasmbase,globals,verbose,
cpubase,cpuinfo; cpubase,cpuinfo,cgbase;
const const
@ -65,11 +65,11 @@ type
constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister; _op3 : treference); 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_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_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2: tcpuregisterset);
constructor op_reglist_reg(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: tregister); 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_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2: tcpuregisterset);
constructor op_reglist_ref(op: tasmop; _size : topsize; _op1: Tsupregset; _op2: treference); constructor op_regset_ref(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: treference);
{ this is for Jmp instructions } { this is for Jmp instructions }
constructor op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol); 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); constructor op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
private 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 } procedure init(_size : topsize); { this need to be called by all constructor }
end; 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 begin
if opidx>=ops then allocate_oper(opidx+1);
ops:=opidx+1; with oper[opidx]^ do
with oper[opidx] do
begin begin
registerlist:=r; if typ<>top_regset then
typ:=top_reglist; 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;
end; end;
@ -293,48 +307,46 @@ implementation
end; 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 Begin
inherited create(op);; inherited create(op);;
init(_size); init(_size);
ops:=2; ops:=2;
loadref(0,_op1); loadref(0,_op1);
loadreglist(1,_op2); loadregset(1,_op2);
end; 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 Begin
inherited create(op);; inherited create(op);;
init(_size); init(_size);
ops:=2; ops:=2;
loadreglist(0,_op1); loadregset(0,_op1);
loadref(1,_op2); loadref(1,_op2);
End; 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 Begin
inherited create(op);; inherited create(op);;
init(_size); init(_size);
ops:=2; ops:=2;
loadreg(0,_op1); loadreg(0,_op1);
loadreglist(1,_op2); loadregset(1,_op2);
end; 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 Begin
inherited create(op);; inherited create(op);;
init(_size); init(_size);
ops:=2; ops:=2;
loadreglist(0,_op1); loadregset(0,_op1);
loadreg(1,_op2); loadreg(1,_op2);
End; End;
constructor taicpu.op_sym(op : tasmop;_size : topsize;_op1 : tasmsymbol); constructor taicpu.op_sym(op : tasmop;_size : topsize;_op1 : tasmsymbol);
begin begin
inherited create(op);; inherited create(op);;
@ -414,7 +426,10 @@ implementation
end. end.
{ {
$Log$ $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 * fixed newra cycle for x86
* added constants for indicating source and destination operands of the * added constants for indicating source and destination operands of the
"move reg,reg" instruction to aasmcpu (and use those in rgobj) "move reg,reg" instruction to aasmcpu (and use those in rgobj)

View File

@ -27,29 +27,29 @@ unit cgcpu;
interface interface
uses uses
cginfo,cgbase,cgobj, cgbase,cgobj,
aasmbase,aasmtai,aasmcpu, aasmbase,aasmtai,aasmcpu,
cpubase,cpuinfo,cpupara, cpubase,cpuinfo,cpupara,
node,symconst,cg64f32; node,symconst,symtype,
cg64f32;
type type
tcg68k = class(tcg) tcg68k = class(tcg)
procedure a_call_name(list : taasmoutput;const s : string);override; 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_call_reg(list : taasmoutput;reg : tregister);override;
procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : 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_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_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_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_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_reg_reg(list: taasmoutput;fromsize,tosize : tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle); override;
procedure a_loadmm_ref_reg(list: taasmoutput; const ref: treference; reg: tregister); 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; reg: tregister; const ref: treference); 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; reg: tregister); 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; a: AWord; reg: TRegister); 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_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; procedure a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
l : tasmlabel);override; l : tasmlabel);override;
@ -60,20 +60,14 @@ unit cgcpu;
procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword;delsource,loadref : boolean);override; procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword;delsource,loadref : boolean);override;
{ generates overflow checking code for a node } { generates overflow checking code for a node }
procedure g_overflowcheck(list: taasmoutput; const p: tnode); override; procedure g_overflowcheck(list: taasmoutput; const l:tlocation; def:tdef); override;
procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer); 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_stackframe_entry(list : taasmoutput;localsize : longint);override;
procedure g_restore_frame_pointer(list : taasmoutput);override; procedure g_restore_frame_pointer(list : taasmoutput);override;
procedure g_return_from_proc(list : taasmoutput;parasize : aword);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);override;
procedure g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsupregset);override;
procedure g_save_all_registers(list : taasmoutput);override; procedure g_save_all_registers(list : taasmoutput);override;
procedure g_restore_all_registers(list : taasmoutput;selfused,accused,acchiused:boolean);override; procedure g_restore_all_registers(list : taasmoutput;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;
protected protected
function fixref(list: taasmoutput; var ref: treference): boolean; function fixref(list: taasmoutput; var ref: treference): boolean;
private private
@ -100,16 +94,14 @@ unit cgcpu;
} }
function isvalidrefoffset(const ref: treference): boolean; function isvalidrefoffset(const ref: treference): boolean;
const const
TCGSize2OpSize: Array[tcgsize] of topsize = TCGSize2OpSize: Array[tcgsize] of topsize =
(S_NO,S_B,S_W,S_L,S_L,S_B,S_W,S_L,S_L, (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_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); S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO);
implementation
Implementation
uses uses
globtype,globals,verbose,systems,cutils, globtype,globals,verbose,systems,cutils,
@ -158,9 +150,9 @@ Implementation
function isvalidrefoffset(const ref: treference): boolean; function isvalidrefoffset(const ref: treference): boolean;
begin begin
isvalidrefoffset := true; isvalidrefoffset := true;
if ref.index.enum <> R_NO then if ref.index <> NR_NO then
begin begin
if ref.base.enum <> R_NO then if ref.base <> NR_NO then
internalerror(20020814); internalerror(20020814);
if (ref.offset < low(shortint)) or (ref.offset > high(shortint)) then if (ref.offset < low(shortint)) or (ref.offset > high(shortint)) then
isvalidrefoffset := false isvalidrefoffset := false
@ -172,53 +164,6 @@ Implementation
end; end;
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 } { TCG68K }
@ -233,12 +178,12 @@ Implementation
} }
if (aktoptprocessor <> MC68000) then if (aktoptprocessor <> MC68000) then
exit; exit;
if (ref.base.enum <> R_NO) then if (ref.base<> NR_NO) then
begin begin
if (ref.index.enum <> R_NO) and assigned(ref.symbol) then if (ref.index <> NR_NO) and assigned(ref.symbol) then
internalerror(20020814); internalerror(20020814);
{ base + reg } { base + reg }
if ref.index.enum <> R_NO then if ref.index <> NR_NO then
begin begin
{ base + reg + offset } { base + reg + offset }
if (ref.offset < low(shortint)) or (ref.offset > high(shortint)) then if (ref.offset < low(shortint)) or (ref.offset > high(shortint)) then
@ -270,28 +215,19 @@ Implementation
end; 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); procedure tcg68k.a_call_reg(list : taasmoutput;reg : tregister);
var var
href : treference; href : treference;
begin begin
reference_reset_base(href, reg, 0); reference_reset_base(href, reg, 0);
a_call_ref(list,href); //!!! a_call_ref(list,href);
end; end;
procedure tcg68k.a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister); procedure tcg68k.a_load_const_reg(list : taasmoutput;size : tcgsize;a : aword;register : tregister);
begin begin
if (rg.isaddressregister(register)) then if getregtype(register)=R_ADDRESSREGISTER then
begin begin
list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register)) list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register))
end end
@ -307,14 +243,14 @@ Implementation
end; end;
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 var
href : treference; href : treference;
begin begin
href := ref; href := ref;
fixref(list,href); fixref(list,href);
{ move to destination reference } { 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; end;
procedure tcg68k.a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister); procedure tcg68k.a_load_reg_reg(list : taasmoutput;fromsize,tosize : tcgsize;reg1,reg2 : tregister);
@ -325,15 +261,15 @@ Implementation
sign_extend(list, fromsize, reg2); sign_extend(list, fromsize, reg2);
end; 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 var
href : treference; href : treference;
begin begin
href := ref; href := ref;
fixref(list,href); 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 } { extend the value in the register }
sign_extend(list, size, register); sign_extend(list, tosize, register);
end; end;
@ -341,7 +277,7 @@ Implementation
var var
href : treference; href : treference;
begin begin
if (not rg.isaddressregister(r)) then if getregtype(r)=R_ADDRESSREGISTER then
begin begin
internalerror(2002072901); internalerror(2002072901);
end; end;
@ -350,7 +286,7 @@ Implementation
list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,r)); list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,r));
end; 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 begin
{ in emulation mode, only 32-bit single is supported } { in emulation mode, only 32-bit single is supported }
if cs_fp_emulation in aktmoduleswitches then if cs_fp_emulation in aktmoduleswitches then
@ -393,28 +329,28 @@ Implementation
list.concat(taicpu.op_reg_ref(A_FMOVE,opsize,reg, ref)); list.concat(taicpu.op_reg_ref(A_FMOVE,opsize,reg, ref));
end; 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 begin
internalerror(20020729); internalerror(20020729);
end; 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 begin
internalerror(20020729); internalerror(20020729);
end; 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 begin
internalerror(20020729); internalerror(20020729);
end; 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 begin
internalerror(20020729); internalerror(20020729);
end; 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 var
scratch_reg : tregister; scratch_reg : tregister;
scratch_reg2: tregister; scratch_reg2: tregister;
@ -453,10 +389,8 @@ Implementation
Begin Begin
if aktoptprocessor = MC68000 then if aktoptprocessor = MC68000 then
begin begin
r.enum:=R_INTREGISTER; r:=NR_D0;
r.number:=NR_D0; r2:=NR_D1;
r2.enum:=R_INTREGISTER;
r2.number:=NR_D1;
rg.getexplicitregisterint(list,NR_D0); rg.getexplicitregisterint(list,NR_D0);
rg.getexplicitregisterint(list,NR_D1); rg.getexplicitregisterint(list,NR_D1);
list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, r)); list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, r));
@ -484,9 +418,9 @@ Implementation
Begin Begin
if aktoptprocessor = MC68000 then if aktoptprocessor = MC68000 then
begin begin
r.enum:=R_INTREGISTER; r:=R_INTREGISTER;
r.number:=NR_D0; r.number:=NR_D0;
r2.enum:=R_INTREGISTER; r2:=R_INTREGISTER;
r2.number:=NR_D1; r2.number:=NR_D1;
rg.getexplicitregisterint(list,NR_D0); rg.getexplicitregisterint(list,NR_D0);
rg.getexplicitregisterint(list,NR_D1); rg.getexplicitregisterint(list,NR_D1);
@ -626,10 +560,10 @@ Implementation
list.concat(taicpu.op_reg_reg(topcg2tasmop[op],TCGSize2OpSize[size],hreg1, hreg2)); list.concat(taicpu.op_reg_reg(topcg2tasmop[op],TCGSize2OpSize[size],hreg1, hreg2));
end; end;
if reg1.enum <> hreg1.enum then if reg1 <> hreg1 then
cg.free_scratch_reg(list,hreg1); cg.free_scratch_reg(list,hreg1);
{ move back result into destination register } { move back result into destination register }
if reg2.enum <> hreg2.enum then if reg2 <> hreg2 then
begin begin
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2)); list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2));
cg.free_scratch_reg(list,hreg2); cg.free_scratch_reg(list,hreg2);
@ -649,9 +583,9 @@ Implementation
sign_extend(list, size,reg2); sign_extend(list, size,reg2);
if aktoptprocessor = MC68000 then if aktoptprocessor = MC68000 then
begin begin
r.enum:=R_INTREGISTER; r:=R_INTREGISTER;
r.number:=NR_D0; r.number:=NR_D0;
r2.enum:=R_INTREGISTER; r2:=R_INTREGISTER;
r2.number:=NR_D1; r2.number:=NR_D1;
rg.getexplicitregisterint(list,NR_D0); rg.getexplicitregisterint(list,NR_D0);
rg.getexplicitregisterint(list,NR_D1); rg.getexplicitregisterint(list,NR_D1);
@ -680,10 +614,10 @@ Implementation
list.concat(taicpu.op_reg_reg(A_MULS,S_L,reg1,reg2)); 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); cg.free_scratch_reg(list,hreg1);
{ move back result into destination register } { move back result into destination register }
if reg2.enum <> hreg2.enum then if reg2 <> hreg2 then
begin begin
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2)); list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2));
cg.free_scratch_reg(list,hreg2); cg.free_scratch_reg(list,hreg2);
@ -696,9 +630,9 @@ Implementation
sign_extend(list, size,reg2); sign_extend(list, size,reg2);
if aktoptprocessor = MC68000 then if aktoptprocessor = MC68000 then
begin begin
r.enum:=R_INTREGISTER; r:=R_INTREGISTER;
r.number:=NR_D0; r.number:=NR_D0;
r2.enum:=R_INTREGISTER; r2:=R_INTREGISTER;
r2.number:=NR_D1; r2.number:=NR_D1;
rg.getexplicitregisterint(list,NR_D0); rg.getexplicitregisterint(list,NR_D0);
rg.getexplicitregisterint(list,NR_D1); rg.getexplicitregisterint(list,NR_D1);
@ -747,7 +681,7 @@ Implementation
since the operation will only be done on the result since the operation will only be done on the result
register. register.
} }
if reg1.enum <> R_NO then if reg1 <> NR_NO then
cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,reg1,reg2); cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,reg1,reg2);
if (rg.isaddressregister(reg2)) then if (rg.isaddressregister(reg2)) then
@ -769,7 +703,7 @@ Implementation
list.concat(taicpu.op_reg(topcg2tasmop[op],TCGSize2OpSize[size],hreg2)); list.concat(taicpu.op_reg(topcg2tasmop[op],TCGSize2OpSize[size],hreg2));
end; end;
if reg2.enum <> hreg2.enum then if reg2 <> hreg2 then
begin begin
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2)); list.concat(taicpu.op_reg_reg(A_MOVE,S_L,hreg2,reg2));
cg.free_scratch_reg(list,hreg2); cg.free_scratch_reg(list,hreg2);
@ -1018,10 +952,10 @@ Implementation
{ restore the registers that we have just used olny if they are used! } { restore the registers that we have just used olny if they are used! }
free_scratch_reg(list, iregister); free_scratch_reg(list, iregister);
free_scratch_reg(list, jregister); free_scratch_reg(list, jregister);
if jregister.enum = R_A1 then if jregister = R_A1 then
hp2.base.enum := R_NO; hp2.base := NR_NO;
if iregister.enum = R_A0 then if iregister = R_A0 then
hp1.base.enum := R_NO; hp1.base := NR_NO;
reference_release(list,hp1); reference_release(list,hp1);
reference_release(list,hp2); reference_release(list,hp2);
end; end;
@ -1032,11 +966,11 @@ Implementation
free_scratch_reg(list,hregister); free_scratch_reg(list,hregister);
end; end;
procedure tcg68k.g_overflowcheck(list: taasmoutput; const p: tnode); procedure tcg68k.g_overflowcheck(list: taasmoutput; const l:tlocation; def:tdef);
begin begin
end; 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 begin
end; end;
@ -1045,8 +979,8 @@ Implementation
var r,r2,rsp:Tregister; var r,r2,rsp:Tregister;
begin begin
r.enum:=frame_pointer_reg; r:=frame_pointer_reg;
rsp.enum:=stack_pointer_reg; rsp:=stack_pointer_reg;
if localsize<>0 then if localsize<>0 then
begin begin
{ Not to complicate the code generator too much, and since some } { Not to complicate the code generator too much, and since some }
@ -1058,7 +992,7 @@ Implementation
end { endif localsize <> 0 } end { endif localsize <> 0 }
else else
begin 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,r,r2));
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,rsp,r)); list.concat(taicpu.op_reg_reg(A_MOVE,S_L,rsp,r));
end; end;
@ -1069,7 +1003,7 @@ Implementation
var r:Tregister; var r:Tregister;
begin begin
r.enum:=frame_pointer_reg; r:=frame_pointer_reg;
list.concat(taicpu.op_reg(A_UNLK,S_NO,r)); list.concat(taicpu.op_reg(A_UNLK,S_NO,r));
end; end;
@ -1107,17 +1041,17 @@ Implementation
{ save the PC counter (pop it from the stack) } { save the PC counter (pop it from the stack) }
hregister := get_scratch_reg_address(list); 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)); list.concat(taicpu.op_reg_reg(A_MOVE,S_L,r,hregister));
{ can we do a quick addition ... } { can we do a quick addition ... }
r.enum:=R_SP; r:=R_SP;
if (parasize > 0) and (parasize < 9) then if (parasize > 0) and (parasize < 9) then
list.concat(taicpu.op_const_reg(A_ADDQ,S_L,parasize,r)) list.concat(taicpu.op_const_reg(A_ADDQ,S_L,parasize,r))
else { nope ... } else { nope ... }
list.concat(taicpu.op_const_reg(A_ADD,S_L,parasize,r)); list.concat(taicpu.op_const_reg(A_ADD,S_L,parasize,r));
{ restore the PC counter (push it on the stack) } { 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_reg_reg(A_MOVE,S_L,hregister,r));
list.concat(taicpu.op_none(A_RTS,S_NO)); list.concat(taicpu.op_none(A_RTS,S_NO));
free_scratch_reg(list,hregister); free_scratch_reg(list,hregister);
@ -1135,7 +1069,7 @@ Implementation
tosave:=std_saved_registers; tosave:=std_saved_registers;
{ only save the registers which are not used and must be saved } { only save the registers which are not used and must be saved }
tosave:=tosave*usedinproc; tosave:=tosave*usedinproc;
r.enum:=R_SPPUSH; r:=R_SPPUSH;
if tosave<>[] then if tosave<>[] then
list.concat(taicpu.op_reglist_reg(A_MOVEM,S_L,tosave,r)); list.concat(taicpu.op_reglist_reg(A_MOVEM,S_L,tosave,r));
end; end;
@ -1149,7 +1083,7 @@ Implementation
torestore:=std_saved_registers; torestore:=std_saved_registers;
{ should be intersected with used regs, no ? } { should be intersected with used regs, no ? }
torestore:=torestore*usedinproc; torestore:=torestore*usedinproc;
r.enum:=R_SPPULL; r:=R_SPPULL;
if torestore<>[] then if torestore<>[] then
list.concat(taicpu.op_reg_reglist(A_MOVEM,S_L,r,torestore)); list.concat(taicpu.op_reg_reglist(A_MOVEM,S_L,r,torestore));
end; end;
@ -1158,7 +1092,7 @@ Implementation
begin begin
end; 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 begin
end; end;
@ -1337,7 +1271,10 @@ end.
{ {
$Log$ $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 * aktprocdef renamed to current_procdef
* procinfo renamed to current_procinfo * procinfo renamed to current_procinfo
* procinfo will now be stored in current_module so it can be * procinfo will now be stored in current_module so it can be

View File

@ -29,7 +29,7 @@ unit cpubase;
interface interface
uses uses
strings,cutils,cclasses,aasmbase,cpuinfo,cginfo; strings,cutils,cclasses,aasmbase,cpuinfo,cgbase;
{***************************************************************************** {*****************************************************************************
@ -101,114 +101,49 @@ uses
Registers Registers
*****************************************************************************} *****************************************************************************}
{$packenum 1}
type type
Toldregister = ( { Number of registers used for indexing in tables }
R_NO,R_D0,R_D1,R_D2,R_D3,R_D4,R_D5,R_D6,R_D7, tregisterindex=0..{$i r68knor.inc}-1;
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;
const const
std_reg2str : reg2strtable = { Available Superregisters }
('', 'd0','d1','d2','d3','d4','d5','d6','d7', {$i r68ksup.inc}
'a0','a1','a2','a3','a4','a5','a6','sp',
'-(sp)','(sp)+', { No Subregisters }
'ccr','fp0','fp1','fp2','fp3','fp4','fp5', R_SUBWHOLE = R_SUBNONE;
'fp6','fp7','fpcr','sr','ssp','dfc',
'sfc','vbr','fpsr'); { 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 Conditions
@ -265,34 +200,12 @@ uses
{ reference record } { reference record }
pparareference = ^tparareference; pparareference = ^tparareference;
tparareference = packed record tparareference = record
index : tregister;
offset : longint; offset : longint;
index : tregister;
end; 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 Generic Location
*****************************************************************************} *****************************************************************************}
@ -302,10 +215,10 @@ uses
References are given from the caller's point of view. The usual References are given from the caller's point of view. The usual
TLocation isn't used, because contains a lot of unnessary fields. TLocation isn't used, because contains a lot of unnessary fields.
} }
tparalocation = packed record tparalocation = record
size : TCGSize; size : TCGSize;
loc : TCGLoc; loc : TCGLoc;
sp_fixup : longint; alignment : byte;
case TCGLoc of case TCGLoc of
LOC_REFERENCE : (reference : tparareference); LOC_REFERENCE : (reference : tparareference);
{ segment in reference at the same place as in loc_register } { segment in reference at the same place as in loc_register }
@ -320,7 +233,7 @@ uses
); );
end; end;
tlocation = packed record tlocation = record
loc : TCGLoc; loc : TCGLoc;
size : TCGSize; size : TCGSize;
case TCGLoc of case TCGLoc of
@ -371,119 +284,6 @@ uses
{# maximum number of operands in assembler instruction } {# maximum number of operands in assembler instruction }
max_operands = 4; 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 Default generic sizes
*****************************************************************************} *****************************************************************************}
@ -511,57 +311,47 @@ uses
This is not compatible with the m68k-sun This is not compatible with the m68k-sun
implementation. implementation.
} }
stab_regindex : array[firstreg..lastreg] of shortint = stab_regindex : array[tregisterindex] of shortint =
(-1, { R_NO } (
0,1,2,3,4,5,6,7, { R_D0..R_D7 } {$i r68ksta.inc}
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);
{***************************************************************************** {*****************************************************************************
Generic Register names Generic Register names
*****************************************************************************} *****************************************************************************}
{# Stack pointer register } {# Stack pointer register }
stack_pointer_reg = R_SP; NR_STACK_POINTER_REG = NR_SP;
NR_STACK_POINTER_REG = NR_A7; RS_STACK_POINTER_REG = RS_SP;
RS_STACK_POINTER_REG = RS_A7;
{# Frame pointer register } {# Frame pointer register }
frame_pointer_reg = R_A6;
NR_FRAME_POINTER_REG = NR_A6; NR_FRAME_POINTER_REG = NR_A6;
RS_FRAME_POINTER_REG = RS_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, {# Register for addressing absolute data in a position independant way,
such as in PIC code. The exact meaning is ABI specific. For such as in PIC code. The exact meaning is ABI specific. For
further information look at GCC source : PIC_OFFSET_TABLE_REGNUM further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
} }
pic_offset_reg = R_A5; NR_PIC_OFFSET_REG = NR_A5;
{# Results are returned in this register (32-bit values) } { Results are returned in this register (32-bit values) }
accumulator = R_D0; NR_FUNCTION_RETURN_REG = NR_D0;
NR_ACCUMULATOR = NR_D0; RS_FUNCTION_RETURN_REG = NR_D0;
RS_ACCUMULATOR = RS_D0; { Low part of 64bit return value }
{the return_result_reg, is used inside the called function to store its return NR_FUNCTION_RETURN64_LOW_REG = NR_D0;
value when that is a scalar value otherwise a pointer to the address of the RS_FUNCTION_RETURN64_LOW_REG = RS_D0;
result is placed inside it} { High part of 64bit return value }
return_result_reg = accumulator; NR_FUNCTION_RETURN64_HIGH_REG = NR_D1;
NR_RETURN_RESULT_REG = NR_ACCUMULATOR; RS_FUNCTION_RETURN64_HIGH_REG = RS_D1;
RS_RETURN_RESULT_REG = RS_ACCUMULATOR; { 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 } {# Floating point results will be placed into this register }
FPU_RESULT_REG = R_FP0; NR_FPU_RESULT_REG = NR_FP0;
mmresultreg = R_NO;
{***************************************************************************** {*****************************************************************************
GCC /ABI linking information GCC /ABI linking information
@ -597,14 +387,32 @@ uses
procedure inverse_flags(var r : TResFlags); procedure inverse_flags(var r : TResFlags);
function flags_to_cond(const f: TResFlags) : TAsmCond; function flags_to_cond(const f: TResFlags) : TAsmCond;
procedure convert_register_to_enum(var r:Tregister);
function cgsize2subreg(s:Tcgsize):Tsubregister; 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 implementation
uses 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 Helpers
@ -618,6 +426,7 @@ implementation
is_calljmp := true; is_calljmp := true;
end; end;
procedure inverse_flags(var r: TResFlags); procedure inverse_flags(var r: TResFlags);
const flagsinvers : array[F_E..F_BE] of tresflags = const flagsinvers : array[F_E..F_BE] of tresflags =
(F_NE,F_E, (F_NE,F_E,
@ -650,71 +459,51 @@ implementation
flags_to_cond := flags2cond[f]; flags_to_cond := flags2cond[f];
end; 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; function cgsize2subreg(s:Tcgsize):Tsubregister;
begin
begin case s of
case s of OS_8,OS_S8:
OS_8,OS_S8: cgsize2subreg:=R_SUBL;
cgsize2subreg:=R_SUBL; OS_16,OS_S16:
OS_16,OS_S16: cgsize2subreg:=R_SUBW;
cgsize2subreg:=R_SUBW; OS_32,OS_S32:
OS_32,OS_S32: cgsize2subreg:=R_SUBD;
cgsize2subreg:=R_SUBD; else
else internalerror(200301231);
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;
end; 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. end.
{ {
$Log$ $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 regvars so they work with newra (at least for ppc)
* fixed some volatile register bugs * fixed some volatile register bugs
+ -dnotranslation option for -dnewra, which causes the registers not to + -dnotranslation option for -dnewra, which causes the registers not to

View File

@ -17,6 +17,9 @@ Unit CPUInfo;
Interface Interface
uses
globtype;
Type Type
{ Architecture word - Native unsigned type } { Architecture word - Native unsigned type }
aword = longword; aword = longword;
@ -35,6 +38,7 @@ Type
ts32real = single; ts32real = single;
ts64real = double; ts64real = double;
ts80real = extended; ts80real = extended;
ts128real = type extended;
ts64comp = extended; ts64comp = extended;
pbestreal=^bestreal; pbestreal=^bestreal;
@ -47,6 +51,13 @@ Type
Coldfire Coldfire
); );
tfputype =
(no_fpuprocessor,
fpu_soft,
fpu_libgcc,
fpu_68881
);
Const Const
{# Size of native extended floating point type } {# Size of native extended floating point type }
extended_size = 8; extended_size = 8;
@ -73,15 +84,30 @@ Const
{ the difference to stdcall is only the name mangling } { the difference to stdcall is only the name mangling }
pocall_cppdecl, pocall_cppdecl,
{ this used by the PalmOS port only } { 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 Implementation
end. end.
{ {
$Log$ $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: * Florian's culmutative nr. 1; contains:
- invalid calling conventions for a certain cpu are rejected - invalid calling conventions for a certain cpu are rejected
- arm softfloat calling conventions - arm softfloat calling conventions

View File

@ -29,8 +29,10 @@ unit cpupara;
interface interface
uses uses
cpubase, globtype,
symdef,paramgr; cpubase,
symconst,symdef,
paramgr;
type type
{ Returns the location for the nr-st 32 Bit int parameter { Returns the location for the nr-st 32 Bit int parameter
@ -39,9 +41,8 @@ unit cpupara;
rtl are used. rtl are used.
} }
tm68kparamanager = class(tparamanager) tm68kparamanager = class(tparamanager)
function getintparaloc(nr : longint) : tparalocation;override; function getintparaloc(calloption : tproccalloption;nr : longint) : tparalocation;override;
procedure create_param_loc_info(p : tabstractprocdef);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
function getselflocation(p : tabstractprocdef) : tparalocation;override;
end; end;
implementation implementation
@ -49,12 +50,11 @@ unit cpupara;
uses uses
verbose, verbose,
globals, globals,
globtype,
systems, systems,
cpuinfo,cginfo,cgbase, cpuinfo,cgbase,
defutil; defutil;
function tm68kparamanager.getintparaloc(nr : longint) : tparalocation; function tm68kparamanager.getintparaloc(calloption : tproccalloption;nr : longint) : tparalocation;
begin begin
fillchar(result,sizeof(tparalocation),0); fillchar(result,sizeof(tparalocation),0);
if nr<1 then if nr<1 then
@ -65,49 +65,51 @@ unit cpupara;
WHICH MUST ALWAYS PASS 4-BYTE PARAMETERS!! WHICH MUST ALWAYS PASS 4-BYTE PARAMETERS!!
} }
result.loc:=LOC_REFERENCE; result.loc:=LOC_REFERENCE;
result.reference.index.enum:=frame_pointer_reg; result.reference.index:=NR_STACK_POINTER_REG;
result.reference.offset:=target_info.first_parm_offset result.reference.offset:=target_info.first_parm_offset+nr*4;
+nr*4;
end; end;
end; end;
procedure tm68kparamanager.create_param_loc_info(p : tabstractprocdef);
function tm68kparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
var var
param_offset : integer; param_offset : integer;
hp : tparaitem; hp : tparaitem;
paraloc: tparalocation;
l : longint;
parasize : longint;
begin begin
{ frame pointer for nested procedures? } { frame pointer for nested procedures? }
{ inc(nextintreg); } { inc(nextintreg); }
{ constructor? } { constructor? }
{ destructor? } { destructor? }
param_offset := target_info.first_parm_offset; param_offset := target_info.first_parm_offset;
hp:=tparaitem(p.para.last); hp:=tparaitem(p.para.last);
while assigned(hp) do while assigned(hp) do
begin begin
hp.paraloc.loc:=LOC_REFERENCE; paraloc.size:=def_cgsize(hp.paratype.def);
hp.paraloc.sp_fixup:=0; paraloc.loc:=LOC_REFERENCE;
hp.paraloc.reference.index.enum:=frame_pointer_reg; paraloc.alignment:=4;
hp.paraloc.reference.offset:=param_offset; paraloc.reference.index:=NR_FRAME_POINTER_REG;
inc(param_offset,aktalignment.paraalign); l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
hp.paraloc.size := def_cgsize(hp.paratype.def); paraloc.reference.offset:=parasize;
hp:=tparaitem(hp.previous); parasize:=parasize+l;
hp.paraloc[callerside]:=paraloc;
hp:=tparaitem(hp.next);
end; end;
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 begin
paramanager:=tm68kparamanager.create; paramanager:=tm68kparamanager.create;
end. end.
{ {
$Log$ $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) * Several bugfixes for m68k target (register alloc., opcode emission)
+ VIS target + VIS target
+ Generic add more complete (still not verified) + Generic add more complete (still not verified)

View File

@ -54,7 +54,7 @@ begin
'-' : '-' :
begin begin
initglobalswitches:=initglobalswitches-[cs_optimize,cs_fastoptimize,cs_slowoptimize,cs_littlesize, initglobalswitches:=initglobalswitches-[cs_optimize,cs_fastoptimize,cs_slowoptimize,cs_littlesize,
cs_regalloc,cs_uncertainopts]; cs_regvars,cs_uncertainopts];
FillChar(ParaAlignment,sizeof(ParaAlignment),0); FillChar(ParaAlignment,sizeof(ParaAlignment),0);
end; end;
'a' : 'a' :
@ -66,7 +66,7 @@ begin
'G' : initglobalswitches:=initglobalswitches-[cs_littlesize]; 'G' : initglobalswitches:=initglobalswitches-[cs_littlesize];
'r' : 'r' :
begin begin
initglobalswitches:=initglobalswitches+[cs_regalloc]; initglobalswitches:=initglobalswitches+[cs_regvars];
Simplify_ppu:=false; Simplify_ppu:=false;
end; end;
'u' : initglobalswitches:=initglobalswitches+[cs_uncertainopts]; 'u' : initglobalswitches:=initglobalswitches+[cs_uncertainopts];
@ -107,7 +107,10 @@ initialization
end. end.
{ {
$Log$ $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?()! + m68k problems with cvs fixed?()!
} }

View File

@ -1,27 +1,27 @@
{ don't edit, this file is generated from m68kreg.dat } { don't edit, this file is generated from m68kreg.dat }
NR_NO = $00000000; NR_NO = tregister($00000000);
NR_D0 = $01000000; NR_D0 = tregister($01000000);
NR_D1 = $01000001; NR_D1 = tregister($01000001);
NR_D2 = $01000002; NR_D2 = tregister($01000002);
NR_D3 = $01000003; NR_D3 = tregister($01000003);
NR_D4 = $01000004; NR_D4 = tregister($01000004);
NR_D5 = $01000005; NR_D5 = tregister($01000005);
NR_D6 = $01000006; NR_D6 = tregister($01000006);
NR_D7 = $01000007; NR_D7 = tregister($01000007);
NR_A0 = $01000008; NR_A0 = tregister($01000008);
NR_A1 = $01000009; NR_A1 = tregister($01000009);
NR_A2 = $0100000a; NR_A2 = tregister($0100000a);
NR_A3 = $0100000b; NR_A3 = tregister($0100000b);
NR_A4 = $0100000c; NR_A4 = tregister($0100000c);
NR_A5 = $0100000d; NR_A5 = tregister($0100000d);
NR_A6 = $0100000e; NR_A6 = tregister($0100000e);
NR_SP = $0100000f; NR_SP = tregister($0100000f);
NR_FP0 = $02000000; NR_FP0 = tregister($02000000);
NR_FP1 = $02000001; NR_FP1 = tregister($02000001);
NR_FP2 = $02000002; NR_FP2 = tregister($02000002);
NR_FP3 = $02000003; NR_FP3 = tregister($02000003);
NR_FP4 = $02000004; NR_FP4 = tregister($02000004);
NR_FP5 = $02000005; NR_FP5 = tregister($02000005);
NR_FP6 = $02000006; NR_FP6 = tregister($02000006);
NR_FP7 = $02000007; NR_FP7 = tregister($02000007);
NR_PC = $05000000; NR_PC = tregister($05000000);

View File

@ -1,27 +1,27 @@
{ don't edit, this file is generated from m68kreg.dat } { don't edit, this file is generated from m68kreg.dat }
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)

View File

@ -35,184 +35,18 @@ unit rgcpu;
type type
trgcpu = class(trgobj) 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; end;
implementation 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. end.
{ {
$Log$ $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 * fix m68k compile
Revision 1.8 2003/04/22 10:09:35 daniel Revision 1.8 2003/04/22 10:09:35 daniel