* cleaned up subsetreg support (put everything in a record)

* prepared support for elements with arbitrary bit length (as opposed
    to a multiple of 8)

git-svn-id: trunk@4324 -
This commit is contained in:
Jonas Maebe 2006-08-01 20:39:53 +00:00
parent 9345d8c7de
commit c25aba7592
7 changed files with 54 additions and 59 deletions

View File

@ -61,6 +61,12 @@ unit cgutils;
{$endif SUPPORT_UNALIGNED}
end;
tsubsetregister = record
subsetreg : tregister;
startbit, bitlen: byte;
subsetregsize: tcgsize;
end;
tlocation = record
loc : TCGLoc;
size : TCGSize;
@ -95,9 +101,7 @@ unit cgutils;
);
LOC_SUBSETREG,
LOC_CSUBSETREG : (
subsetreg : tregister;
startbit: byte;
subsetregsize: tcgsize;
sreg: tsubsetregister;
);
end;

View File

@ -465,7 +465,7 @@ implementation
cg.a_load_loc_reg(current_asmdata.CurrAsmList,left.location.size,right.location,left.location.register);
LOC_SUBSETREG,
LOC_CSUBSETREG :
cg.a_load_loc_subsetreg(current_asmdata.CurrAsmList,left.location.subsetregsize,left.location.size,left.location.startbit,right.location,left.location.subsetreg);
cg.a_load_loc_subsetreg(current_asmdata.CurrAsmList,left.location.size,right.location,left.location.sreg);
else
internalerror(200501311);
end;

View File

@ -613,7 +613,7 @@ implementation
left.location.register,mms_movescalar);
LOC_SUBSETREG,
LOC_CSUBSETREG:
cg.a_load_ref_subsetreg(current_asmdata.CurrAsmList,right.location.size,left.location.subsetregsize,left.location.size,left.location.startbit,right.location.reference,left.location.subsetreg);
cg.a_load_ref_subsetreg(current_asmdata.CurrAsmList,right.location.size,left.location.size,right.location.reference,left.location.sreg);
else
internalerror(200203284);
end;
@ -684,8 +684,7 @@ implementation
LOC_CSUBSETREG:
begin
cg.a_load_subsetreg_loc(current_asmdata.CurrAsmList,
right.location.subsetregsize,right.location.size,right.location.startbit,
right.location.register,left.location);
right.location.size,right.location.sreg,left.location);
end;
LOC_JUMP :
begin

View File

@ -322,12 +322,13 @@ implementation
else
location.loc := LOC_CSUBSETREG;
location.size:=def_cgsize(resulttype.def);
location.subsetreg := left.location.register;
location.subsetregsize := left.location.size;
location.sreg.subsetreg := left.location.register;
location.sreg.subsetregsize := left.location.size;
if (target_info.endian = ENDIAN_BIG) then
location.startbit := (tcgsize2size[location.subsetregsize] - tcgsize2size[location.size] - vs.fieldoffset) * 8
location.sreg.startbit := (tcgsize2size[location.sreg.subsetregsize] - tcgsize2size[location.size] - vs.fieldoffset) * 8
else
location.startbit := (vs.fieldoffset * 8);
location.sreg.startbit := (vs.fieldoffset * 8);
location.sreg.bitlen := tcgsize2size[location.size] * 8;
end;
end;
LOC_SUBSETREG,
@ -335,9 +336,10 @@ implementation
begin
location.size:=def_cgsize(resulttype.def);
if (target_info.endian = ENDIAN_BIG) then
inc(location.startbit, (left.resulttype.def.size - tcgsize2size[location.size] - vs.fieldoffset) * 8)
inc(location.sreg.startbit, (left.resulttype.def.size - tcgsize2size[location.size] - vs.fieldoffset) * 8)
else
inc(location.startbit, vs.fieldoffset * 8);
inc(location.sreg.startbit, vs.fieldoffset * 8);
location.sreg.bitlen := tcgsize2size[location.size] * 8;
end;
else
internalerror(2006031901);

View File

@ -293,7 +293,7 @@ implementation
LOC_SUBSETREG,LOC_CSUBSETREG:
begin
tmpreg := cg.getintregister(list,OS_INT);
cg.a_load_subsetreg_reg(list,p.location.subsetregsize,p.location.size,p.location.startbit,OS_INT,p.location.subsetreg,tmpreg);
cg.a_load_subsetreg_reg(list,p.location.size,OS_INT,p.location.sreg,tmpreg);
cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,current_procinfo.CurrTrueLabel);
cg.a_jmp_always(list,current_procinfo.CurrFalseLabel);
end;
@ -758,7 +758,7 @@ implementation
LOC_CSUBSETREG:
begin
tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r);
cg.a_load_subsetreg_ref(list,l.subsetregsize,l.size,l.startbit,l.size,l.subsetreg,r);
cg.a_load_subsetreg_ref(list,l.size,l.size,l.sreg,r);
location_reset(l,LOC_REFERENCE,l.size);
l.reference:=r;
end;

View File

@ -64,12 +64,10 @@ unit cgcpu;
procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
procedure a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister); override;
procedure a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize,
subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister); override;
procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetregsize, fromsubsetsize: tcgsize; fromstartbit: byte;
tosubsetregsize, tosubsetsize: tcgsize; tostartbit: byte; fromsubsetreg, tosubsetreg: tregister); override;
procedure a_load_subsetreg_reg(list : TAsmList; subsetsize: tcgsize;
tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
procedure a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister); override;
procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister); override;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
@ -555,44 +553,41 @@ const
end;
procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister);
procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister);
begin
if (tcgsize2size[subsetsize] <> sizeof(aint)) then
begin
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,destreg,
subsetreg,(32-startbit) and 31,32-tcgsize2size[subsetsize]*8,31));
sreg.subsetreg,(32-sreg.startbit) and 31,32-sreg.bitlen,31));
a_load_reg_reg(list,tcgsize2unsigned[subsetsize],subsetsize,destreg,destreg);
a_load_reg_reg(list,subsetsize,tosize,destreg,destreg);
end
else
a_load_reg_reg(list,subsetsize,tosize,subsetreg,destreg);
a_load_reg_reg(list,subsetsize,tosize,sreg.subsetreg,destreg);
end;
procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize,
subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister);
procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister);
begin
if ((tcgsize2size[subsetsize]) <> sizeof(aint)) then
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,subsetreg,fromreg,
startbit,32-startbit-tcgsize2size[subsetsize]*8,31-startbit))
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,sreg.subsetreg,fromreg,
sreg.startbit,32-sreg.startbit-sreg.bitlen,31-sreg.startbit))
else
a_load_reg_reg(list,fromsize,subsetsize,fromreg,subsetreg);
a_load_reg_reg(list,fromsize,subsetsize,fromreg,sreg.subsetreg);
end;
procedure tcgppc.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetregsize, fromsubsetsize: tcgsize; fromstartbit: byte;
tosubsetregsize, tosubsetsize: tcgsize; tostartbit: byte; fromsubsetreg, tosubsetreg: tregister);
procedure tcgppc.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister);
begin
if (tcgsize2size[fromsubsetsize] >= tcgsize2size[tosubsetsize]) then
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,tosubsetreg, fromsubsetreg,
(tostartbit-fromstartbit) and 31,
32-tostartbit-tcgsize2size[tosubsetsize]*8,31-tostartbit))
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,tosreg.subsetreg, fromsreg.subsetreg,
(tosreg.startbit-fromsreg.startbit) and 31,
32-tosreg.startbit-tosreg.bitlen,31-tosreg.startbit))
else
inherited a_load_subsetreg_subsetreg(list,fromsubsetregsize,fromsubsetsize,fromstartbit,tosubsetregsize,tosubsetsize,tostartbit,fromsubsetreg,tosubsetreg);
inherited a_load_subsetreg_subsetreg(list,fromsubsetsize,tosubsetsize,fromsreg,tosreg);
end;

View File

@ -75,12 +75,9 @@ type
procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1,
reg2: tregister); override;
procedure a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister); override;
procedure a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize,
subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister); override;
procedure a_load_const_subsetreg(list: TAsmlist; subsetregsize, subsetsize: tcgsize;
startbit: byte; a: aint; subsetreg: tregister); override;
procedure a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
procedure a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister); override;
procedure a_load_const_subsetreg(list: TAsmlist; subsetsize: tcgsize; a: aint; const sreg: tsubsetregister); override;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
@ -879,52 +876,50 @@ begin
rg[R_INTREGISTER].add_move_instruction(instr);
end;
procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister);
procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister);
var
extrdi_startbit : byte;
begin
{$ifdef extdebug}
list.concat(tai_comment.create(strpnew('a_load_subsetreg_reg subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(startbit) + ' tosize = ' + cgsize2string(tosize))));
list.concat(tai_comment.create(strpnew('a_load_subsetreg_reg subsetregsize = ' + cgsize2string(sreg.subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(sreg.startbit) + ' tosize = ' + cgsize2string(tosize))));
{$endif}
{ calculate the correct startbit for the extrdi instruction, do the extraction if required and then
extend the sign correctly. (The latter is actually required only for signed subsets and if that
subset is not >= the tosize). }
extrdi_startbit := 64 - (tcgsize2size[subsetsize]*8 + startbit);
if (startbit <> 0) then begin
list.concat(taicpu.op_reg_reg_const_const(A_EXTRDI, destreg, subsetreg, tcgsize2size[subsetsize]*8, extrdi_startbit));
a_load_reg_reg(list, tcgsize2unsigned[subsetregsize], subsetsize, destreg, destreg);
extrdi_startbit := 64 - (sreg.bitlen + sreg.startbit);
if (sreg.startbit <> 0) then begin
list.concat(taicpu.op_reg_reg_const_const(A_EXTRDI, destreg, sreg.subsetreg, sreg.bitlen, extrdi_startbit));
a_load_reg_reg(list, tcgsize2unsigned[sreg.subsetregsize], subsetsize, destreg, destreg);
end else begin
a_load_reg_reg(list, tcgsize2unsigned[subsetregsize], subsetsize, subsetreg, destreg);
a_load_reg_reg(list, tcgsize2unsigned[sreg.subsetregsize], subsetsize, sreg.subsetreg, destreg);
end;
end;
procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize,
subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister);
procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister);
begin
{$ifdef extdebug}
list.concat(tai_comment.create(strpnew('a_load_reg_subsetreg fromsize = ' + cgsize2string(fromsize) + ' subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + IntToStr(startbit))));
list.concat(tai_comment.create(strpnew('a_load_reg_subsetreg fromsize = ' + cgsize2string(fromsize) + ' subsetregsize = ' + cgsize2string(sreg.subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + IntToStr(sreg.startbit))));
{$endif}
{ simply use the INSRDI instruction }
if (tcgsize2size[subsetsize] <> sizeof(aint)) then
list.concat(taicpu.op_reg_reg_const_const(A_INSRDI, subsetreg, fromreg, tcgsize2size[subsetsize]*8, (64 - (startbit + tcgsize2size[subsetsize]*8)) and 63))
list.concat(taicpu.op_reg_reg_const_const(A_INSRDI, sreg.subsetreg, fromreg, sreg.bitlen, (64 - (sreg.startbit + sreg.bitlen)) and 63))
else
a_load_reg_reg(list, fromsize, subsetsize, fromreg, subsetreg);
a_load_reg_reg(list, fromsize, subsetsize, fromreg, sreg.subsetreg);
end;
procedure tcgppc.a_load_const_subsetreg(list: TAsmlist; subsetregsize, subsetsize: tcgsize;
startbit: byte; a: aint; subsetreg: tregister);
procedure tcgppc.a_load_const_subsetreg(list: TAsmlist; subsetsize: tcgsize;
a: aint; const sreg: tsubsetregister);
var
tmpreg : TRegister;
begin
{$ifdef extdebug}
list.concat(tai_comment.create(strpnew('a_load_const_subsetreg subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(startbit) + ' a = ' + intToStr(a))));
list.concat(tai_comment.create(strpnew('a_load_const_subsetreg subsetregsize = ' + cgsize2string(sreg.subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(sreg.startbit) + ' a = ' + intToStr(a))));
{$endif}
{ loading the constant into the lowest bits of a temp register and then inserting is
better than loading some usually large constants and do some masking and shifting on ppc64 }
tmpreg := getintregister(list,subsetsize);
a_load_const_reg(list,subsetsize,a,tmpreg);
a_load_reg_subsetreg(list, subsetsize, subsetregsize, subsetsize, startbit, tmpreg, subsetreg);
a_load_reg_subsetreg(list, subsetsize, subsetsize, tmpreg, sreg);
end;
procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize;