From c25aba75922a12d56ac3c7d367e4de23d8eeb5d0 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Tue, 1 Aug 2006 20:39:53 +0000 Subject: [PATCH] * 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 - --- compiler/cgutils.pas | 10 ++++++--- compiler/ncgflw.pas | 2 +- compiler/ncgld.pas | 5 ++--- compiler/ncgmem.pas | 14 ++++++------ compiler/ncgutil.pas | 4 ++-- compiler/powerpc/cgcpu.pas | 37 ++++++++++++++------------------ compiler/powerpc64/cgcpu.pas | 41 ++++++++++++++++-------------------- 7 files changed, 54 insertions(+), 59 deletions(-) diff --git a/compiler/cgutils.pas b/compiler/cgutils.pas index 26b3206a2d..192c9e7e34 100644 --- a/compiler/cgutils.pas +++ b/compiler/cgutils.pas @@ -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; diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index 42e98e107f..e1adf16200 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -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; diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 38f35d60e0..f22f4643c9 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -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 diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 6c7c4401e7..5049acd1c6 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -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); diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index d389d2370d..eb30af7a45 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -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; diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index d61f5c5445..cb444229fe 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/compiler/powerpc/cgcpu.pas @@ -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; diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas index accf71b056..7f09d603d3 100644 --- a/compiler/powerpc64/cgcpu.pas +++ b/compiler/powerpc64/cgcpu.pas @@ -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;