m68k: implemented t68kvecnode.update_reference_reg_packed. same as the generic one, but allocates int registers instead of address registers, because on 68k IMUL,SHR/SHL and AND can't work on address registers, which results in a lot of register shuffling

git-svn-id: trunk@30267 -
This commit is contained in:
Károly Balogh 2015-03-21 20:09:35 +00:00
parent 5ca1740bee
commit ad301f8fa1

View File

@ -34,6 +34,7 @@ interface
type
t68kvecnode = class(tcgvecnode)
procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); override;
procedure update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l:aint); override;
//procedure pass_generate_code;override;
end;
@ -45,7 +46,8 @@ implementation
symdef,paramgr,
aasmtai,aasmdata,
nld,ncon,nadd,
cgutils,cgobj;
cgutils,cgobj,
defutil;
{*****************************************************************************
@ -123,6 +125,62 @@ implementation
location.reference.alignment:=newalignment(location.reference.alignment,l);
end;
{ see remarks for tcgvecnode.update_reference_reg_mul above }
procedure t68kvecnode.update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l:aint);
var
sref: tsubsetreference;
offsetreg, hreg: tregister;
alignpower: aint;
temp : longint;
begin
{ only orddefs are bitpacked. Even then we only need special code in }
{ case the bitpacked *byte size* is not a power of two, otherwise }
{ everything can be handled using the the regular array code. }
if ((l mod 8) = 0) and
(ispowerof2(l div 8,temp) or
not is_ordinal(resultdef)
{$ifndef cpu64bitalu}
or is_64bitint(resultdef)
{$endif not cpu64bitalu}
) then
begin
update_reference_reg_mul(maybe_const_reg,regsize,l div 8);
exit;
end;
if (l > 8*sizeof(aint)) then
internalerror(200608051);
sref.ref := location.reference;
hreg := cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_INT,tarraydef(left.resultdef).lowrange,maybe_const_reg,hreg);
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_IMUL,OS_INT,l,hreg);
{ keep alignment for index }
sref.ref.alignment := left.resultdef.alignment;
if not ispowerof2(packedbitsloadsize(l),temp) then
internalerror(2006081201);
alignpower:=temp;
offsetreg := cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_ADDR,3+alignpower,hreg,offsetreg);
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHL,OS_ADDR,alignpower,offsetreg);
if (sref.ref.base = NR_NO) then
sref.ref.base := offsetreg
else if (sref.ref.index = NR_NO) then
sref.ref.index := offsetreg
else
begin
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,sref.ref.base,offsetreg);
sref.ref.base := offsetreg;
end;
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,OS_INT,(1 shl (3+alignpower))-1,hreg);
sref.bitindexreg := hreg;
sref.startbit := 0;
sref.bitlen := resultdef.packedbitsize;
if (left.location.loc = LOC_REFERENCE) then
location.loc := LOC_SUBSETREF
else
location.loc := LOC_CSUBSETREF;
location.sref := sref;
end;
{procedure t68kvecnode.pass_generate_code;
begin
inherited pass_generate_code;