* 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} {$endif SUPPORT_UNALIGNED}
end; end;
tsubsetregister = record
subsetreg : tregister;
startbit, bitlen: byte;
subsetregsize: tcgsize;
end;
tlocation = record tlocation = record
loc : TCGLoc; loc : TCGLoc;
size : TCGSize; size : TCGSize;
@ -95,9 +101,7 @@ unit cgutils;
); );
LOC_SUBSETREG, LOC_SUBSETREG,
LOC_CSUBSETREG : ( LOC_CSUBSETREG : (
subsetreg : tregister; sreg: tsubsetregister;
startbit: byte;
subsetregsize: tcgsize;
); );
end; end;

View File

@ -465,7 +465,7 @@ implementation
cg.a_load_loc_reg(current_asmdata.CurrAsmList,left.location.size,right.location,left.location.register); cg.a_load_loc_reg(current_asmdata.CurrAsmList,left.location.size,right.location,left.location.register);
LOC_SUBSETREG, LOC_SUBSETREG,
LOC_CSUBSETREG : 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 else
internalerror(200501311); internalerror(200501311);
end; end;

View File

@ -613,7 +613,7 @@ implementation
left.location.register,mms_movescalar); left.location.register,mms_movescalar);
LOC_SUBSETREG, LOC_SUBSETREG,
LOC_CSUBSETREG: 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 else
internalerror(200203284); internalerror(200203284);
end; end;
@ -684,8 +684,7 @@ implementation
LOC_CSUBSETREG: LOC_CSUBSETREG:
begin begin
cg.a_load_subsetreg_loc(current_asmdata.CurrAsmList, cg.a_load_subsetreg_loc(current_asmdata.CurrAsmList,
right.location.subsetregsize,right.location.size,right.location.startbit, right.location.size,right.location.sreg,left.location);
right.location.register,left.location);
end; end;
LOC_JUMP : LOC_JUMP :
begin begin

View File

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

View File

@ -293,7 +293,7 @@ implementation
LOC_SUBSETREG,LOC_CSUBSETREG: LOC_SUBSETREG,LOC_CSUBSETREG:
begin begin
tmpreg := cg.getintregister(list,OS_INT); 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_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,current_procinfo.CurrTrueLabel);
cg.a_jmp_always(list,current_procinfo.CurrFalseLabel); cg.a_jmp_always(list,current_procinfo.CurrFalseLabel);
end; end;
@ -758,7 +758,7 @@ implementation
LOC_CSUBSETREG: LOC_CSUBSETREG:
begin begin
tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r); 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); location_reset(l,LOC_REFERENCE,l.size);
l.reference:=r; l.reference:=r;
end; 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_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_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
procedure a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize; procedure a_load_subsetreg_reg(list : TAsmList; subsetsize: tcgsize;
startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister); override; tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
procedure a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, procedure a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister); override;
subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister); override; procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister); override;
procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetregsize, fromsubsetsize: tcgsize; fromstartbit: byte;
tosubsetregsize, tosubsetsize: tcgsize; tostartbit: byte; fromsubsetreg, tosubsetreg: tregister); override;
{ fpu move instructions } { fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override; procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
@ -555,44 +553,41 @@ const
end; end;
procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize; procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister);
startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister);
begin begin
if (tcgsize2size[subsetsize] <> sizeof(aint)) then if (tcgsize2size[subsetsize] <> sizeof(aint)) then
begin begin
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,destreg, 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,tcgsize2unsigned[subsetsize],subsetsize,destreg,destreg);
a_load_reg_reg(list,subsetsize,tosize,destreg,destreg); a_load_reg_reg(list,subsetsize,tosize,destreg,destreg);
end end
else else
a_load_reg_reg(list,subsetsize,tosize,subsetreg,destreg); a_load_reg_reg(list,subsetsize,tosize,sreg.subsetreg,destreg);
end; end;
procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister);
subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister);
begin begin
if ((tcgsize2size[subsetsize]) <> sizeof(aint)) then if ((tcgsize2size[subsetsize]) <> sizeof(aint)) then
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,subsetreg,fromreg, list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,sreg.subsetreg,fromreg,
startbit,32-startbit-tcgsize2size[subsetsize]*8,31-startbit)) sreg.startbit,32-sreg.startbit-sreg.bitlen,31-sreg.startbit))
else else
a_load_reg_reg(list,fromsize,subsetsize,fromreg,subsetreg); a_load_reg_reg(list,fromsize,subsetsize,fromreg,sreg.subsetreg);
end; end;
procedure tcgppc.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetregsize, fromsubsetsize: tcgsize; fromstartbit: byte; procedure tcgppc.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister);
tosubsetregsize, tosubsetsize: tcgsize; tostartbit: byte; fromsubsetreg, tosubsetreg: tregister);
begin begin
if (tcgsize2size[fromsubsetsize] >= tcgsize2size[tosubsetsize]) then if (tcgsize2size[fromsubsetsize] >= tcgsize2size[tosubsetsize]) then
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,tosubsetreg, fromsubsetreg, list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,tosreg.subsetreg, fromsreg.subsetreg,
(tostartbit-fromstartbit) and 31, (tosreg.startbit-fromsreg.startbit) and 31,
32-tostartbit-tcgsize2size[tosubsetsize]*8,31-tostartbit)) 32-tosreg.startbit-tosreg.bitlen,31-tosreg.startbit))
else 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; end;

View File

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