* fixed register allocation for -gt

+ also trash "out" parameters with -gt (except open arrays)

git-svn-id: trunk@4294 -
This commit is contained in:
Jonas Maebe 2006-07-25 14:04:05 +00:00
parent 7bb3a1fe22
commit f5a902b2ee

View File

@ -882,19 +882,54 @@ implementation
end; end;
{ trash contents of local variables } const
procedure trash_variable(p : tnamedindexitem;arg:pointer);
const
{$ifdef cpu64bit} {$ifdef cpu64bit}
trashintvalues: array[0..nroftrashvalues-1] of aint = ($5555555555555555,aint($AAAAAAAAAAAAAAAA),aint($EFEFEFEFEFEFEFEF),0); trashintvalues: array[0..nroftrashvalues-1] of aint = ($5555555555555555,aint($AAAAAAAAAAAAAAAA),aint($EFEFEFEFEFEFEFEF),0);
{$else cpu64bit} {$else cpu64bit}
trashintvalues: array[0..nroftrashvalues-1] of aint = ($55555555,aint($AAAAAAAA),aint($EFEFEFEF),0); trashintvalues: array[0..nroftrashvalues-1] of aint = ($55555555,aint($AAAAAAAA),aint($EFEFEFEF),0);
{$endif cpu64bit} {$endif cpu64bit}
procedure trash_reference(list: TAsmList; const ref: treference; size: aint);
var var
tmpref: treference;
countreg, valuereg: tregister; countreg, valuereg: tregister;
hl: tasmlabel; hl: tasmlabel;
trashintval: aint; trashintval: aint;
tmpref: treference;
begin
trashintval := trashintvalues[localvartrashing];
case size of
0: ; { empty record }
1: cg.a_load_const_ref(list,OS_8,byte(trashintval),ref);
2: cg.a_load_const_ref(list,OS_16,word(trashintval),ref);
4: cg.a_load_const_ref(list,OS_32,longint(trashintval),ref);
else
begin
countreg := cg.getintregister(list,OS_ADDR);
valuereg := cg.getintregister(list,OS_8);
cg.a_load_const_reg(list,OS_INT,size,countreg);
cg.a_load_const_reg(list,OS_8,byte(trashintval),valuereg);
current_asmdata.getjumplabel(hl);
tmpref := ref;
if (tmpref.index <> NR_NO) then
internalerror(200607201);
tmpref.index := countreg;
dec(tmpref.offset);
cg.a_label(list,hl);
cg.a_load_reg_ref(list,OS_8,OS_8,valuereg,tmpref);
cg.a_op_const_reg(list,OP_SUB,OS_INT,1,countreg);
cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,countreg,hl);
cg.a_reg_sync(list,tmpref.base);
cg.a_reg_sync(list,valuereg);
end;
end;
end;
{ trash contents of local variables }
procedure trash_variable(p : tnamedindexitem;arg:pointer);
var
trashintval: aint;
list: TAsmList absolute arg;
begin begin
trashintval := trashintvalues[localvartrashing]; trashintval := trashintvalues[localvartrashing];
if (tsym(p).typ=localvarsym) then if (tsym(p).typ=localvarsym) then
@ -905,7 +940,7 @@ implementation
{$define overflowon} {$define overflowon}
{$q-} {$q-}
{$endif} {$endif}
cg.a_load_const_reg(TAsmList(arg),reg_cgsize(tlocalvarsym(p).localloc.register), cg.a_load_const_reg(list,reg_cgsize(tlocalvarsym(p).localloc.register),
trashintval and (aint(1) shl (tcgsize2size[reg_cgsize(tlocalvarsym(p).localloc.register)] * 8) - 1), trashintval and (aint(1) shl (tcgsize2size[reg_cgsize(tlocalvarsym(p).localloc.register)] * 8) - 1),
tglobalvarsym(p).localloc.register); tglobalvarsym(p).localloc.register);
{$ifdef overflowon} {$ifdef overflowon}
@ -914,32 +949,8 @@ implementation
{$endif} {$endif}
LOC_REFERENCE : LOC_REFERENCE :
begin begin
case tlocalvarsym(p).getsize of trash_reference(list,tlocalvarsym(p).localloc.reference,
0: ; { empty record } tlocalvarsym(p).getsize);
1: cg.a_load_const_ref(TAsmList(arg),OS_8,byte(trashintval),
tlocalvarsym(p).localloc.reference);
2: cg.a_load_const_ref(TAsmList(arg),OS_16,word(trashintval),
tlocalvarsym(p).localloc.reference);
4: cg.a_load_const_ref(TAsmList(arg),OS_32,longint(trashintval),
tlocalvarsym(p).localloc.reference);
else
begin
countreg := cg.getintregister(TAsmList(arg),OS_ADDR);
valuereg := cg.getintregister(TAsmList(arg),OS_8);
cg.a_load_const_reg(TAsmList(arg),OS_INT,tlocalvarsym(p).getsize,countreg);
cg.a_load_const_reg(TAsmList(arg),OS_8,byte(trashintval),valuereg);
current_asmdata.getjumplabel(hl);
tmpref := tlocalvarsym(p).localloc.reference;
if (tmpref.index <> NR_NO) then
internalerror(200607201);
tmpref.index := countreg;
dec(tmpref.offset);
cg.a_label(TAsmList(arg),hl);
cg.a_load_reg_ref(TAsmList(arg),OS_8,OS_8,valuereg,tmpref);
cg.a_op_const_reg(TAsmList(arg),OP_SUB,OS_INT,1,countreg);
cg.a_cmp_const_reg_label(TAsmList(arg),OS_INT,OC_NE,0,countreg,hl);
end;
end;
end; end;
LOC_CMMREGISTER : LOC_CMMREGISTER :
; ;
@ -1102,24 +1113,37 @@ implementation
href : treference; href : treference;
tmpreg : tregister; tmpreg : tregister;
list : TAsmList; list : TAsmList;
needs_inittable: boolean;
begin begin
list:=TAsmList(arg); list:=TAsmList(arg);
if (tsym(p).typ=paravarsym) and if (tsym(p).typ=paravarsym) then
not is_class_or_interface(tparavarsym(p).vartype.def) and
tparavarsym(p).vartype.def.needs_inittable then
begin begin
needs_inittable :=
not is_class_or_interface(tparavarsym(p).vartype.def) and
tparavarsym(p).vartype.def.needs_inittable;
case tparavarsym(p).varspez of case tparavarsym(p).varspez of
vs_value : vs_value :
begin if needs_inittable then
location_get_data_ref(list,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vartype.def)); begin
cg.g_incrrefcount(list,tparavarsym(p).vartype.def,href); location_get_data_ref(list,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vartype.def));
end; cg.g_incrrefcount(list,tparavarsym(p).vartype.def,href);
end;
vs_out : vs_out :
begin begin
tmpreg:=cg.getaddressregister(list); if (needs_inittable) or
cg.a_load_loc_reg(list,OS_ADDR,tparavarsym(p).localloc,tmpreg); (localvartrashing <> -1) then
reference_reset_base(href,tmpreg,0); begin
cg.g_initialize(list,tparavarsym(p).vartype.def,href); tmpreg:=cg.getaddressregister(list);
cg.a_load_loc_reg(list,OS_ADDR,tparavarsym(p).localloc,tmpreg);
reference_reset_base(href,tmpreg,0);
if (localvartrashing <> -1) and
{ needs separate implementation to trash open arrays }
{ since their size is only known at run time }
not is_special_array(tparavarsym(p).vartype.def) then
trash_reference(list,href,tparavarsym(p).vartype.def.size);
if needs_inittable then
cg.g_initialize(list,tparavarsym(p).vartype.def,href);
end;
end; end;
end; end;
end; end;