* fixed ARM for new reg. allocation scheme

This commit is contained in:
florian 2003-11-02 14:30:03 +00:00
parent 31ff6f25cb
commit a9d9a15e20
14 changed files with 421 additions and 285 deletions

View File

@ -29,7 +29,7 @@ interface
uses
cclasses,aasmtai,
aasmbase,globals,verbose,
cpubase,cpuinfo,cginfo;
cpubase,cpuinfo,cgbase;
const
{ "mov reg,reg" source operand number }
@ -42,7 +42,7 @@ uses
oppostfix : TOpPostfix;
roundingmode : troundingmode;
procedure loadshifterop(opidx:longint;const so:tshifterop);
procedure loadregset(opidx:longint;const s:tsuperregisterset);
procedure loadregset(opidx:longint;const s:tcpuregisterset);
constructor op_none(op : tasmop);
constructor op_reg(op : tasmop;_op1 : tregister);
@ -52,7 +52,7 @@ uses
constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
constructor op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
constructor op_ref_regset(op:tasmop; _op1: treference; _op2: tsuperregisterset);
constructor op_ref_regset(op:tasmop; _op1: treference; _op2: tcpuregisterset);
constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
@ -98,9 +98,8 @@ implementation
procedure taicpu.loadshifterop(opidx:longint;const so:tshifterop);
begin
if opidx>=ops then
ops:=opidx+1;
with oper[opidx] do
allocate_oper(opidx+1);
with oper[opidx]^ do
begin
if typ<>top_shifterop then
begin
@ -113,15 +112,15 @@ implementation
end;
procedure taicpu.loadregset(opidx:longint;const s:tsuperregisterset);
procedure taicpu.loadregset(opidx:longint;const s:tcpuregisterset);
begin
if opidx>=ops then
ops:=opidx+1;
with oper[opidx] do
allocate_oper(opidx+1);
with oper[opidx]^ do
begin
if typ<>top_regset then
clearop(opidx);
regset:=s;
new(regset);
regset^:=s;
typ:=top_regset;
end;
end;
@ -171,7 +170,7 @@ implementation
end;
constructor taicpu.op_ref_regset(op:tasmop; _op1: treference; _op2: tsuperregisterset);
constructor taicpu.op_ref_regset(op:tasmop; _op1: treference; _op2: tcpuregisterset);
begin
inherited create(op);
ops:=2;
@ -366,7 +365,10 @@ implementation
end.
{
$Log$
Revision 1.12 2003-09-11 11:54:59 florian
Revision 1.13 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.12 2003/09/11 11:54:59 florian
* improved arm code generation
* move some protected and private field around
* the temp. register for register parameters/arguments are now released

View File

@ -32,8 +32,7 @@ unit agarmgas;
uses
aasmtai,
aggas,
cpubase,
cginfo;
cpubase;
type
PARMGNUAssembler=^TARMGNUAssembler;
@ -161,7 +160,7 @@ unit agarmgas;
getopstr:='{';
first:=true;
for r:=RS_R0 to RS_R15 do
if r in o.regset then
if r in o.regset^ then
begin
if not(first) then
getopstr:=getopstr+',';
@ -226,7 +225,10 @@ begin
end.
{
$Log$
Revision 1.11 2003-09-06 11:21:49 florian
Revision 1.12 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.11 2003/09/06 11:21:49 florian
* fixed stm and ldm to be usable with preindex operand
Revision 1.10 2003/09/05 23:57:01 florian

View File

@ -32,21 +32,33 @@ unit cgcpu;
symtype,
cgbase,cgobj,
aasmbase,aasmcpu,aasmtai,
cpubase,cpuinfo,node,cg64f32,cginfo;
cpubase,cpuinfo,node,cg64f32,rgcpu;
type
tcgarm = class(tcg)
rgint,
rgmm,
rgfpu : trgcpu;
procedure init_register_allocators;override;
procedure done_register_allocators;override;
function getintregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
procedure ungetregister(list:Taasmoutput;r:Tregister);override;
procedure add_move_instruction(instr:Taicpu);override;
procedure do_register_allocation(list:Taasmoutput;headertai:tai);override;
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);override;
procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);override;
procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
procedure a_call_name(list : taasmoutput;const s : string);override;
procedure a_call_reg(list : taasmoutput;reg: tregister); override;
procedure a_call_ref(list : taasmoutput;const ref : treference);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; src, dst: TRegister); override;
@ -88,8 +100,8 @@ unit cgcpu;
procedure g_overflowcheck(list: taasmoutput; const l: tlocation; def: tdef); override;
procedure g_save_standard_registers(list : taasmoutput; usedinproc : tsuperregisterset);override;
procedure g_restore_standard_registers(list : taasmoutput; usedinproc : tsuperregisterset);override;
procedure g_save_standard_registers(list : taasmoutput);override;
procedure g_restore_standard_registers(list : taasmoutput);override;
procedure g_save_all_registers(list : taasmoutput);override;
procedure g_restore_all_registers(list : taasmoutput;accused,acchiused:boolean);override;
@ -115,18 +127,130 @@ unit cgcpu;
uses
globtype,globals,verbose,systems,cutils,symconst,symdef,symsym,rgobj,rgcpu,tgobj,cpupi;
globtype,globals,verbose,systems,cutils,
symconst,symdef,symsym,
tgobj,
procinfo,cpupi;
procedure tcgarm.init_register_allocators;
begin
rg:=trgcpu.create(11,#0#1#2#3#4#5#6#7#8#9#10);
rgint:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,
[RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
RS_R9,RS_R10,RS_R12],first_int_imreg,[]);
rgfpu:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
[RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7],first_fpu_imreg,[]);
rgmm:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
[RS_S0..RS_S31],first_mm_imreg,[]);
end;
procedure tcgarm.done_register_allocators;
begin
rg.free;
rgint.free;
rgfpu.free;
rgmm.free;
end;
function tcgarm.getintregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin
result:=rgint.getregister(list,cgsize2subreg(size));
end;
function tcgarm.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin
result:=rgfpu.getregister(list,R_SUBWHOLE);
end;
function tcgarm.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin
result:=rgmm.getregister(list,R_SUBNONE);
end;
procedure tcgarm.getexplicitregister(list:Taasmoutput;r:Tregister);
begin
case getregtype(r) of
R_INTREGISTER :
rgint.getexplicitregister(list,r);
R_MMREGISTER :
rgmm.getexplicitregister(list,r);
R_FPUREGISTER :
rgfpu.getexplicitregister(list,r);
else
internalerror(200310091);
end;
end;
procedure tcgarm.ungetregister(list:Taasmoutput;r:Tregister);
begin
case getregtype(r) of
R_INTREGISTER :
rgint.ungetregister(list,r);
R_FPUREGISTER :
rgfpu.ungetregister(list,r);
R_MMREGISTER :
rgmm.ungetregister(list,r);
else
internalerror(200310091);
end;
end;
procedure tcgarm.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
begin
case rt of
R_INTREGISTER :
rgint.allocexplicitregisters(list,r);
R_FPUREGISTER :
rgfpu.allocexplicitregisters(list,r);
R_MMREGISTER :
rgmm.allocexplicitregisters(list,r);
else
internalerror(200310092);
end;
end;
procedure tcgarm.deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
begin
case rt of
R_INTREGISTER :
rgint.deallocexplicitregisters(list,r);
R_FPUREGISTER :
rgfpu.deallocexplicitregisters(list,r);
R_MMREGISTER :
rgmm.deallocexplicitregisters(list,r);
else
internalerror(200310093);
end;
end;
procedure tcgarm.add_move_instruction(instr:Taicpu);
begin
rgint.add_move_instruction(instr);
end;
procedure tcgarm.do_register_allocation(list:Taasmoutput;headertai:tai);
begin
{ Int }
rgint.check_unreleasedregs;
rgint.do_register_allocation(list,headertai);
rgint.translate_registers(list);
{ FPU }
rgfpu.check_unreleasedregs;
rgfpu.do_register_allocation(list,headertai);
rgfpu.translate_registers(list);
{ MM }
rgmm.check_unreleasedregs;
rgmm.do_register_allocation(list,headertai);
rgmm.translate_registers(list);
end;
@ -147,7 +271,7 @@ unit cgcpu;
else
internalerror(2002081101);
end;
if locpara.sp_fixup<>0 then
if locpara.alignment<>0 then
internalerror(2002081102);
end;
@ -165,10 +289,10 @@ unit cgcpu;
reference_reset(ref);
ref.base:=locpara.reference.index;
ref.offset:=locpara.reference.offset;
tmpreg := rg.getregisterint(list,size);
tmpreg := getintregister(list,size);
a_load_ref_reg(list,size,size,r,tmpreg);
a_load_reg_ref(list,size,size,tmpreg,ref);
rg.ungetregisterint(list,tmpreg);
ungetregister(list,tmpreg);
end;
LOC_FPUREGISTER,LOC_CFPUREGISTER:
case size of
@ -180,7 +304,7 @@ unit cgcpu;
else
internalerror(2002081103);
end;
if locpara.sp_fixup<>0 then
if locpara.alignment<>0 then
internalerror(2002081104);
end;
@ -198,10 +322,10 @@ unit cgcpu;
reference_reset(ref);
ref.base := locpara.reference.index;
ref.offset := locpara.reference.offset;
tmpreg := rg.getregisterint(list,OS_ADDR);
tmpreg := getintregister(list,OS_ADDR);
a_loadaddr_ref_reg(list,r,tmpreg);
a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
rg.ungetregisterint(list,tmpreg);
ungetregister(list,tmpreg);
end;
else
internalerror(2002080701);
@ -227,16 +351,6 @@ unit cgcpu;
end;
procedure tcgarm.a_call_ref(list : taasmoutput;const ref : treference);
var
r : tregister;
begin
a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,NR_PC);
if not(pi_do_call in current_procinfo.flags) then
internalerror(2003060705);
end;
procedure tcgarm.a_op_const_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; reg: TRegister);
begin
a_op_const_reg_reg(list,op,size,a,reg,reg);
@ -315,10 +429,10 @@ unit cgcpu;
a_op_reg_reg(list,OP_NEG,size,src,dst)
else
begin
tmpreg:=rg.getregisterint(list,size);
tmpreg:=getintregister(list,size);
a_load_const_reg(list,size,a,tmpreg);
a_op_reg_reg_reg(list,op,size,tmpreg,src,dst);
rg.ungetregisterint(list,tmpreg);
ungetregister(list,tmpreg);
end;
end;
end;
@ -363,21 +477,21 @@ unit cgcpu;
begin
if dst<>src1 then
begin
rg.add_edge(dst,src1);
rgint.add_edge(dst,src1);
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src1,src2));
end
else
begin
tmpreg:=rg.getregisterint(list,size);
tmpreg:=getintregister(list,size);
a_load_reg_reg(list,size,size,src2,dst);
rg.add_edge(dst,tmpreg);
rg.ungetregister(list,tmpreg);
rgint.add_edge(dst,tmpreg);
ungetregister(list,tmpreg);
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,tmpreg,src1));
end;
end
else
begin
rg.add_edge(dst,src2);
rgint.add_edge(dst,src2);
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src2,src1));
end;
end;
@ -486,7 +600,7 @@ unit cgcpu;
current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
{ load consts entry }
tmpreg:=rg.getregisterint(list,OS_INT);
tmpreg:=getintregister(list,OS_INT);
reference_reset(tmpref);
tmpref.symbol:=l;
tmpref.base:=NR_R15;
@ -541,7 +655,7 @@ unit cgcpu;
end
else
begin
tmpreg:=rg.getregisterint(list,OS_INT);
tmpreg:=getintregister(list,OS_INT);
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.base,ref.index));
ref.base:=tmpreg;
ref.index:=NR_NO;
@ -549,7 +663,7 @@ unit cgcpu;
end;
list.concat(setoppostfix(taicpu.op_reg_ref(op,reg,ref),oppostfix));
if (tmpreg<>NR_NO) then
rg.ungetregisterint(list,tmpreg);
ungetregister(list,tmpreg);
end;
@ -645,7 +759,7 @@ unit cgcpu;
OS_32,OS_S32:
begin
instr:=taicpu.op_reg_reg(A_MOV,reg2,reg1);
rg.add_move_instruction(instr);
add_move_instruction(instr);
list.concat(instr);
end;
else internalerror(2002090901);
@ -711,10 +825,10 @@ unit cgcpu;
list.concat(taicpu.op_reg_const(A_CMN,reg,not(a)))
else
begin
tmpreg:=rg.getregisterint(list,size);
tmpreg:=getintregister(list,size);
a_load_const_reg(list,size,a,tmpreg);
list.concat(taicpu.op_reg_reg(A_CMP,reg,tmpreg));
rg.ungetregisterint(list,tmpreg);
ungetregister(list,tmpreg);
end;
a_jmp_cond(list,cmp_op,l);
end;
@ -772,10 +886,10 @@ unit cgcpu;
reference_reset(ref);
ref.index:=NR_STACK_POINTER_REG;
ref.addressmode:=AM_PREINDEXED;
list.concat(setoppostfix(taicpu.op_ref_regset(A_STM,ref,rg.used_in_proc_int-[RS_R0..RS_R3]+[RS_R11,RS_R12,RS_R15]),PF_FD));
list.concat(setoppostfix(taicpu.op_ref_regset(A_STM,ref,rgint.used_in_proc-[RS_R0..RS_R3]+[RS_R11,RS_R12,RS_R15]),PF_FD));
list.concat(taicpu.op_reg_reg_const(A_SUB,NR_FRAME_POINTER_REG,NR_R12,4));
a_reg_alloc(list,NR_R12);
a_reg_dealloc(list,NR_R12);
{ allocate necessary stack size }
list.concat(taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
@ -793,7 +907,7 @@ unit cgcpu;
{ restore int registers and return }
reference_reset(ref);
ref.index:=NR_FRAME_POINTER_REG;
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,rg.used_in_proc_int-[RS_R0..RS_R3]+[RS_R11,RS_R13,RS_R15]),PF_EA));
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,rgint.used_in_proc-[RS_R0..RS_R3]+[RS_R11,RS_R13,RS_R15]),PF_EA));
end;
end;
@ -840,7 +954,7 @@ unit cgcpu;
else
begin
instr:=taicpu.op_reg_reg(A_MOV,r,tmpref.base);
rg.add_move_instruction(instr);
add_move_instruction(instr);
list.concat(instr);
end;
end;
@ -878,7 +992,7 @@ unit cgcpu;
{ load consts entry }
reference_reset(tmpref);
tmpreg:=rg.getregisterint(list,OS_INT);
tmpreg:=getintregister(list,OS_INT);
tmpref.symbol:=l;
tmpref.base:=NR_PC;
list.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
@ -927,10 +1041,10 @@ unit cgcpu;
dstref.addressmode:=AM_POSTINDEXED;
srcref.offset:=size;
dstref.offset:=size;
r:=rg.getregisterint(list,size2opsize[size]);
r:=getintregister(list,size2opsize[size]);
a_load_ref_reg(list,size2opsize[size],size2opsize[size],srcref,r);
a_load_reg_ref(list,size2opsize[size],size2opsize[size],r,dstref);
rg.ungetregisterint(list,r);
ungetregister(list,r);
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_SUB,countreg,countreg,1),PF_S));
list.concat(setcondition(taicpu.op_sym(A_B,l),C_NE));
end;
@ -958,30 +1072,30 @@ unit cgcpu;
cgsize:=OS_16;
end;
dec(len,copysize);
r:=rg.getregisterint(list,cgsize);
r:=getintregister(list,cgsize);
a_load_ref_reg(list,cgsize,cgsize,srcref,r);
if (len=0) and delsource then
reference_release(list,source);
a_load_reg_ref(list,cgsize,cgsize,r,dstref);
inc(srcref.offset,copysize);
inc(dstref.offset,copysize);
rg.ungetregisterint(list,r);
ungetregister(list,r);
end;
end
else
begin
destreg:=rg.getregisterint(list,OS_ADDR);
destreg:=getintregister(list,OS_ADDR);
a_loadaddr_ref_reg(list,dest,destreg);
if delsource then
reference_release(list,srcref);
srcreg:=rg.getregisterint(list,OS_ADDR);
srcreg:=getintregister(list,OS_ADDR);
if loadref then
a_load_ref_reg(list,OS_ADDR,OS_ADDR,source,srcreg)
else
a_loadaddr_ref_reg(list,source,srcreg);
srcref.
// srcref.
countreg:=rg.getregisterint(list,OS_32);
countreg:=getintregister(list,OS_32);
// if cs_littlesize in aktglobalswitches then
genloop(len,1);
@ -1006,9 +1120,9 @@ unit cgcpu;
list.concat(Taicpu.op_none(A_MOVSB,S_NO));
end;
}
rg.ungetregisterint(list,countreg);
rg.ungetregisterint(list,srcreg);
rg.ungetregisterint(list,destreg);
ungetregister(list,countreg);
ungetregister(list,srcreg);
ungetregister(list,destreg);
end;
if delsource then
tg.ungetiftemp(list,source);
@ -1020,13 +1134,13 @@ unit cgcpu;
end;
procedure tcgarm.g_save_standard_registers(list : taasmoutput; usedinproc : tsuperregisterset);
procedure tcgarm.g_save_standard_registers(list : taasmoutput);
begin
{ we support only ARM standard calling conventions so this procedure has no use on the ARM }
end;
procedure tcgarm.g_restore_standard_registers(list : taasmoutput; usedinproc : tsuperregisterset);
procedure tcgarm.g_restore_standard_registers(list : taasmoutput);
begin
{ we support only ARM standard calling conventions so this procedure has no use on the ARM }
end;
@ -1094,20 +1208,20 @@ unit cgcpu;
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_ADD,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
begin
tmpreg:=rg.getregisterint(list,OS_32);
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADD,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
rg.ungetregisterint(list,tmpreg);
cg.ungetregister(list,tmpreg);
end;
if is_shifter_const(hi(value),b) then
list.concat(taicpu.op_reg_reg_const(A_ADC,regdst.reghi,regsrc.reghi,hi(value)))
else
begin
tmpreg:=rg.getregisterint(list,OS_32);
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(taicpu.op_reg_reg_reg(A_ADC,regdst.reghi,regsrc.reghi,tmpreg));
rg.ungetregisterint(list,tmpreg);
cg.ungetregister(list,tmpreg);
end;
end;
OP_SUB:
@ -1116,20 +1230,20 @@ unit cgcpu;
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_SUB,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
begin
tmpreg:=rg.getregisterint(list,OS_32);
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
rg.ungetregisterint(list,tmpreg);
cg.ungetregister(list,tmpreg);
end;
if is_shifter_const(hi(value),b) then
list.concat(taicpu.op_reg_reg_const(A_SBC,regdst.reghi,regsrc.reghi,hi(value)))
else
begin
tmpreg:=rg.getregisterint(list,OS_32);
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(taicpu.op_reg_reg_reg(A_SBC,regdst.reghi,regsrc.reghi,tmpreg));
rg.ungetregisterint(list,tmpreg);
cg.ungetregister(list,tmpreg);
end;
end;
else
@ -1168,7 +1282,10 @@ begin
end.
{
$Log$
Revision 1.20 2003-10-11 16:06:42 florian
Revision 1.21 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.20 2003/10/11 16:06:42 florian
* fixed some MMX<->SSE
* started to fix ppc, needs an overhaul
+ stabs info improve for spilling, not sure if it works correctly/completly

View File

@ -35,7 +35,7 @@ unit cpubase;
globtype,globals,
cpuinfo,
aasmbase,
cginfo
cgbase
{$ifdef delphi}
,dmisc
{$endif}
@ -99,25 +99,16 @@ unit cpubase;
NR_PC = NR_R15;
{ Integer Super registers first and last }
{$warning Supreg shall be $00-$1f}
first_int_supreg = RS_R0;
last_int_supreg = RS_R15;
first_int_imreg = $20;
last_int_imreg = $fe;
first_int_imreg = $10;
{ Float Super register first and last }
first_fpu_supreg = $00;
last_fpu_supreg = $07;
first_fpu_imreg = $20;
last_fpu_imreg = $fe;
first_fpu_supreg = RS_F0;
first_fpu_imreg = $08;
{ MM Super register first and last }
first_mmx_supreg = RS_INVALID;
last_mmx_supreg = RS_INVALID;
first_mmx_imreg = RS_INVALID;
last_mmx_imreg = RS_INVALID;
first_mm_supreg = RS_S0;
first_mm_imreg = $20;
{$warning TODO Calculate bsstart}
regnumber_count_bsstart = 64;
@ -239,9 +230,6 @@ unit cpubase;
Operands
*****************************************************************************}
{ Types of operand }
toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_regset,top_shifterop);
tupdatereg = (UR_None,UR_Update);
pshifterop = ^tshifterop;
@ -252,17 +240,6 @@ unit cpubase;
shiftimm : byte;
end;
toper = record
case typ : toptype of
top_none : ();
top_reg : (reg:tregister;update:tupdatereg);
top_ref : (ref:preference);
top_const : (val:aword);
top_symbol : (sym:tasmsymbol;symofs:longint);
top_regset : (regset:tsuperregisterset);
top_shifterop : (shifterop : pshifterop);
end;
{*****************************************************************************
Generic Location
*****************************************************************************}
@ -275,10 +252,12 @@ unit cpubase;
tparalocation = packed 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 }
LOC_MMREGISTER,LOC_CMMREGISTER,
LOC_FPUREGISTER,LOC_CFPUREGISTER,
LOC_REGISTER,LOC_CREGISTER : (
case longint of
1 : (register,registerhigh : tregister);
@ -288,8 +267,6 @@ unit cpubase;
3 : (reg64 : tregister64);
4 : (register64 : tregister64);
);
{ it's only for better handling }
LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
end;
tlocation = packed record
@ -587,7 +564,10 @@ unit cpubase;
end.
{
$Log$
Revision 1.16 2003-10-31 08:40:51 mazen
Revision 1.17 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.16 2003/10/31 08:40:51 mazen
* rgHelper renamed to rgBase
* using findreg_by_<name|number>_table directly to decrease heap overheading

View File

@ -35,17 +35,18 @@ unit cpupara;
type
tarmparamanager = class(tparamanager)
function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
// procedure freeintparaloc(list: taasmoutput; nr : longint); override;
procedure create_paraloc_info(p : tabstractprocdef; side: tcallercallee);override;
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
end;
implementation
uses
verbose,systems,
cpuinfo,cginfo,cgbase,
cpuinfo,cgbase,
rgobj,
defutil,symsym;
@ -139,28 +140,34 @@ unit cpupara;
end;
end;
function tarmparamanager.push_addr_param(def : tdef;calloption : tproccalloption) : boolean;
function tarmparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
begin
if varspez in [vs_var,vs_out] then
begin
result:=true;
exit;
end;
case def.deftype of
recorddef:
push_addr_param:=true;
result:=true;
arraydef:
push_addr_param:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
setdef :
push_addr_param:=(tsetdef(def).settype<>smallset);
result:=(tsetdef(def).settype<>smallset);
stringdef :
push_addr_param:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
result:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
procvardef :
push_addr_param:=po_methodpointer in tprocvardef(def).procoptions;
result:=po_methodpointer in tprocvardef(def).procoptions;
else
push_addr_param:=inherited push_addr_param(def,calloption);
result:=inherited push_addr_param(varspez,def,calloption);
end;
end;
procedure tarmparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee);
function tarmparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
var
nextintreg,nextfloatreg,nextmmreg : tregister;
@ -190,142 +197,149 @@ unit cpupara;
end;
begin
{ zero alignment bytes }
fillchar(nextintreg,sizeof(nextintreg),0);
fillchar(nextfloatreg,sizeof(nextfloatreg),0);
fillchar(nextmmreg,sizeof(nextmmreg),0);
nextintreg:=RS_R0;
nextfloatreg:=RS_F0;
nextmmreg:=RS_D0;
stack_offset:=0;
result:=0;
{ zero alignment bytes }
fillchar(nextintreg,sizeof(nextintreg),0);
fillchar(nextfloatreg,sizeof(nextfloatreg),0);
fillchar(nextmmreg,sizeof(nextmmreg),0);
nextintreg:=RS_R0;
nextfloatreg:=RS_F0;
nextmmreg:=RS_D0;
stack_offset:=0;
{ frame pointer for nested procedures? }
{ inc(nextintreg); }
{ constructor? }
{ destructor? }
hp:=tparaitem(p.para.first);
while assigned(hp) do
begin
if (hp.paratyp in [vs_var,vs_out]) then
begin
paradef := voidpointertype.def;
loc := LOC_REGISTER;
end
else
begin
paradef := hp.paratype.def;
loc:=getparaloc(paradef);
end;
{ make sure all alignment bytes are 0 as well }
fillchar(paraloc,sizeof(paraloc),0);
case loc of
LOC_REGISTER:
begin
paraloc.size := def_cgsize(paradef);
{ for things like formaldef }
if paraloc.size = OS_NO then
paraloc.size := OS_ADDR;
is_64bit := paraloc.size in [OS_64,OS_S64];
if nextintreg<=(RS_R3-ord(is_64bit)) then
begin
paraloc.loc:=LOC_REGISTER;
{ frame pointer for nested procedures? }
{ inc(nextintreg); }
{ constructor? }
{ destructor? }
hp:=tparaitem(p.para.first);
while assigned(hp) do
begin
if (hp.paratyp in [vs_var,vs_out]) then
begin
paradef := voidpointertype.def;
loc := LOC_REGISTER;
end
else
begin
paradef := hp.paratype.def;
loc:=getparaloc(paradef);
end;
{ make sure all alignment bytes are 0 as well }
fillchar(paraloc,sizeof(paraloc),0);
case loc of
LOC_REGISTER:
begin
paraloc.size := def_cgsize(paradef);
{ for things like formaldef }
if paraloc.size = OS_NO then
paraloc.size := OS_ADDR;
is_64bit := paraloc.size in [OS_64,OS_S64];
if nextintreg<=(RS_R3-ord(is_64bit)) then
begin
paraloc.loc:=LOC_REGISTER;
if is_64bit then
begin
paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);;
inc(nextintreg);
end;
paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);;
inc(nextintreg);
end
else
begin
nextintreg:=RS_R4;
paraloc.loc:=LOC_REFERENCE;
paraloc.reference.index:=NR_STACK_POINTER_REG;
paraloc.reference.offset:=stack_offset;
if not is_64bit then
inc(stack_offset,4)
else
inc(stack_offset,8);
end;
end;
LOC_FPUREGISTER:
begin
paraloc.size:=def_cgsize(paradef);
if nextfloatreg<=RS_F3 then
begin
paraloc.loc:=LOC_FPUREGISTER;
paraloc.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
inc(nextfloatreg);
end
else
begin
{!!!!!!!}
paraloc.size:=def_cgsize(paradef);
internalerror(2002071004);
end;
end;
LOC_REFERENCE:
begin
paraloc.size:=OS_ADDR;
if push_addr_param(paradef,p.proccalloption) or
is_open_array(paradef) or
is_array_of_const(paradef) then
assignintreg
else
begin
paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);;
inc(nextintreg);
end;
paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);;
inc(nextintreg);
end
else
begin
nextintreg:=RS_R4;
paraloc.loc:=LOC_REFERENCE;
paraloc.reference.index:=NR_STACK_POINTER_REG;
paraloc.reference.offset:=stack_offset;
inc(stack_offset,hp.paratype.def.size);
end;
end;
else
internalerror(2002071002);
end;
if side=calleeside then
begin
if (paraloc.loc = LOC_REFERENCE) then
paraloc.reference.offset := tvarsym(hp.parasym).adjusted_address;
end;
hp.paraloc[side]:=paraloc;
hp:=tparaitem(hp.next);
end;
{ Function return }
fillchar(paraloc,sizeof(tparalocation),0);
paraloc.size:=def_cgsize(p.rettype.def);
{ Return in FPU register? }
if p.rettype.def.deftype=floatdef then
begin
paraloc.loc:=LOC_FPUREGISTER;
paraloc.register:=NR_FPU_RESULT_REG;
end
else
{ Return in register? }
if not ret_in_param(p.rettype.def,p.proccalloption) then
begin
paraloc.loc:=LOC_REGISTER;
if paraloc.size in [OS_64,OS_S64] then
begin
paraloc.register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
paraloc.register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
end
else
paraloc.register:=NR_FUNCTION_RETURN_REG;
end
else
begin
paraloc.loc:=LOC_REFERENCE;
if not is_64bit then
inc(stack_offset,4)
else
inc(stack_offset,8);
end;
end;
LOC_FPUREGISTER:
begin
paraloc.size:=def_cgsize(paradef);
if nextfloatreg<=RS_F3 then
begin
paraloc.loc:=LOC_FPUREGISTER;
paraloc.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
inc(nextfloatreg);
end
else
begin
{!!!!!!!}
paraloc.size:=def_cgsize(paradef);
internalerror(2002071004);
end;
end;
LOC_REFERENCE:
begin
paraloc.size:=OS_ADDR;
if push_addr_param(hp.paratyp,paradef,p.proccalloption) or
is_open_array(paradef) or
is_array_of_const(paradef) then
assignintreg
else
begin
paraloc.loc:=LOC_REFERENCE;
paraloc.reference.index:=NR_STACK_POINTER_REG;
paraloc.reference.offset:=stack_offset;
inc(stack_offset,hp.paratype.def.size);
end;
end;
else
internalerror(2002071002);
end;
if side=calleeside then
begin
{$warning FIXME Calleeside offset needs to be calculated}
{!!!!!!
if (paraloc.loc = LOC_REFERENCE) then
paraloc.reference.offset := tvarsym(hp.parasym).adjusted_address;
}
end;
hp.paraloc[side]:=paraloc;
hp:=tparaitem(hp.next);
end;
p.funcret_paraloc[side]:=paraloc;
end;
{ Function return }
fillchar(paraloc,sizeof(tparalocation),0);
paraloc.size:=def_cgsize(p.rettype.def);
{ Return in FPU register? }
if p.rettype.def.deftype=floatdef then
begin
paraloc.loc:=LOC_FPUREGISTER;
paraloc.register:=NR_FPU_RESULT_REG;
end
else
{ Return in register? }
if not ret_in_param(p.rettype.def,p.proccalloption) then
begin
paraloc.loc:=LOC_REGISTER;
if paraloc.size in [OS_64,OS_S64] then
begin
paraloc.register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
paraloc.register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
end
else
paraloc.register:=NR_FUNCTION_RETURN_REG;
end
else
begin
paraloc.loc:=LOC_REFERENCE;
end;
p.funcret_paraloc[side]:=paraloc;
end;
begin
paramanager:=tarmparamanager.create;
end.
{
$Log$
Revision 1.7 2003-09-11 11:55:00 florian
Revision 1.8 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.7 2003/09/11 11:55:00 florian
* improved arm code generation
* move some protected and private field around
* the temp. register for register parameters/arguments are now released

View File

@ -30,15 +30,15 @@ unit cpupi;
uses
cutils,
cgbase,cpuinfo,psub;
procinfo,cpuinfo,psub;
type
tarmprocinfo = class(tcgprocinfo)
{ max. of space need for parameters, currently used by the PowerPC port only }
maxpushedparasize : aword;
constructor create(aparent:tprocinfo);override;
procedure handle_body_start;override;
procedure after_pass1;override;
// procedure handle_body_start;override;
// procedure after_pass1;override;
procedure allocate_push_parasize(size: longint);override;
function calc_stackframe_size:longint;override;
end;
@ -60,7 +60,7 @@ unit cpupi;
maxpushedparasize:=0;
end;
(*
procedure tarmprocinfo.handle_body_start;
var
ofs : aword;
@ -81,7 +81,6 @@ unit cpupi;
inherited handle_body_start;
end;
procedure tarmprocinfo.after_pass1;
begin
if not(po_assembler in procdef.procoptions) then
@ -102,6 +101,7 @@ unit cpupi;
inherited after_pass1;
end;
end;
*)
procedure tarmprocinfo.allocate_push_parasize(size:longint);
@ -126,7 +126,10 @@ begin
end.
{
$Log$
Revision 1.1 2003-08-20 15:50:13 florian
Revision 1.2 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.1 2003/08/20 15:50:13 florian
* more arm stuff
}

View File

@ -27,7 +27,7 @@ unit itarmgas;
interface
uses
cginfo,cpubase;
cpubase,cgbase;
const
@ -113,6 +113,9 @@ implementation
end.
{
$Log$
Revision 1.1 2003-09-04 00:15:29 florian
Revision 1.2 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.1 2003/09/04 00:15:29 florian
* first bunch of adaptions of arm compiler for new register type
}

View File

@ -27,7 +27,7 @@ unit narmadd;
interface
uses
node,ncgadd,cpubase,cginfo;
node,ncgadd,cpubase;
type
tarmaddnode = class(tcgaddnode)
@ -260,11 +260,11 @@ interface
exprasmlist.concat(taicpu.op_reg_const(A_CMP,left.location.register,right.location.value))
else
begin
tmpreg:=rg.getregisterint(exprasmlist,location.size);
tmpreg:=cg.getintregister(exprasmlist,location.size);
cg.a_load_const_reg(exprasmlist,OS_INT,
aword(right.location.value),tmpreg);
exprasmlist.concat(taicpu.op_reg_reg(A_CMP,left.location.register,tmpreg));
rg.ungetregisterint(exprasmlist,tmpreg);
cg.ungetregister(exprasmlist,tmpreg);
end;
end
else
@ -281,7 +281,10 @@ begin
end.
{
$Log$
Revision 1.4 2003-09-01 15:11:16 florian
Revision 1.5 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.4 2003/09/01 15:11:16 florian
* fixed reference handling
* fixed operand postfix for floating point instructions
* fixed wrong shifter constant handling

View File

@ -31,7 +31,7 @@ interface
type
tarmcallnode = class(tcgcallnode)
procedure push_framepointer;override;
// procedure push_framepointer;override;
end;
implementation
@ -39,19 +39,22 @@ implementation
uses
paramgr;
(*
procedure tarmcallnode.push_framepointer;
begin
framepointer_paraloc:=paramanager.getintparaloc(procdefinition.proccalloption,1);
end;
*)
begin
ccallnode:=tarmcallnode;
end.
{
$Log$
Revision 1.2 2003-09-11 11:55:00 florian
Revision 1.3 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.2 2003/09/11 11:55:00 florian
* improved arm code generation
* move some protected and private field around
* the temp. register for register parameters/arguments are now released

View File

@ -66,7 +66,7 @@ implementation
ncon,ncal,
ncgutil,
cpubase,aasmcpu,
rgobj,tgobj,cgobj,cginfo;
rgobj,tgobj,cgobj;
{*****************************************************************************
@ -112,7 +112,7 @@ implementation
begin
location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
location_force_reg(exprasmlist,left.location,OS_32,true);
location.register:=rg.getregisterfpu(exprasmlist,location.size);
location.register:=cg.getfpuregister(exprasmlist,location.size);
instr:=taicpu.op_reg_reg(A_FLT,location.register,left.location.register);
instr.oppostfix:=cgsize2fpuoppostfix[def_cgsize(resulttype.def)];
exprasmlist.concat(instr);
@ -184,7 +184,10 @@ begin
end.
{
$Log$
Revision 1.4 2003-09-01 15:11:16 florian
Revision 1.5 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.4 2003/09/01 15:11:16 florian
* fixed reference handling
* fixed operand postfix for floating point instructions
* fixed wrong shifter constant handling

View File

@ -49,7 +49,7 @@ implementation
cutils,verbose,globals,fmodule,
symconst,symdef,
aasmbase,aasmtai,aasmcpu,
cginfo,cgbase,pass_1,pass_2,
cgbase,pass_1,pass_2,
cpubase,paramgr,
nbas,ncon,ncal,ncnv,nld,
tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu;
@ -65,7 +65,7 @@ implementation
location_copy(location,left.location);
if left.location.loc=LOC_CFPUREGISTER then
begin
location.register:=rg.getregisterfpu(exprasmlist,location.size);
location.register:=cg.getfpuregister(exprasmlist,location.size);
location.loc := LOC_FPUREGISTER;
end;
end;
@ -123,6 +123,9 @@ begin
end.
{
$Log$
Revision 1.1 2003-08-28 00:05:29 florian
Revision 1.2 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.1 2003/08/28 00:05:29 florian
* today's arm patches
}

View File

@ -44,7 +44,7 @@ implementation
defutil,
cgbase,cgobj,pass_1,pass_2,
ncon,
cpubase,cpuinfo,cginfo,
cpubase,cpuinfo,
ncgutil,cgcpu,cg64f32,rgobj;
{*****************************************************************************
@ -102,6 +102,9 @@ begin
end.
{
$Log$
Revision 1.3 2003-08-27 00:27:56 florian
Revision 1.4 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.3 2003/08/27 00:27:56 florian
+ same procedure as very day: today's work on arm
}

View File

@ -51,8 +51,7 @@ interface
{ parser }
scanner,
{ codegen }
cginfo,
cgbase,
cgbase,procinfo,
{ constants }
itarmgas,
cpubase
@ -181,11 +180,10 @@ interface
hs:=tvarsym(sym).mangledname
else
begin
if (tvarsym(sym).reg<>NR_NO) then
hs:=std_regname(framereg)
if (tvarsym(sym).localloc.loc=LOC_REGISTER) then
hs:=gas_regname(tvarsym(sym).localloc.register)
else
hs:=tostr(tvarsym(sym).address)+
'('+std_regname(framereg)+')';
hs:='%%'+tvarsym(sym).name;
end;
end
else
@ -203,11 +201,7 @@ interface
begin
if sym.typ=varsym then
begin
l:=tvarsym(sym).address;
{ set offset }
inc(l,current_procinfo.procdef.parast.address_fixup);
// hs:=tostr(l)+'('+gas_reg2str[procinfo.framepointer.enum]+')';
hs:=tostr(l)+'('+std_regname(framereg)+')';
hs:='%%'+tvarsym(sym).name;
if pos(',',s) > 0 then
tvarsym(sym).varstate:=vs_used;
end;
@ -336,7 +330,10 @@ initialization
end.
{
$Log$
Revision 1.4 2003-09-04 00:15:29 florian
Revision 1.5 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.4 2003/09/04 00:15:29 florian
* first bunch of adaptions of arm compiler for new register type
Revision 1.3 2003/09/01 15:11:17 florian

View File

@ -30,7 +30,7 @@ unit rgcpu;
uses
aasmbase,aasmtai,
cginfo,
cgbase,
cpubase,
rgobj;
@ -97,7 +97,10 @@ end.
{
$Log$
Revision 1.4 2003-09-11 11:55:00 florian
Revision 1.5 2003-11-02 14:30:03 florian
* fixed ARM for new reg. allocation scheme
Revision 1.4 2003/09/11 11:55:00 florian
* improved arm code generation
* move some protected and private field around
* the temp. register for register parameters/arguments are now released