mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 21:29:43 +02:00
* 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:
parent
9345d8c7de
commit
c25aba7592
compiler
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user