From 469ac311e0320d2cc40c8ec0fca5c7b6fff10d12 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sat, 4 Nov 2006 16:44:29 +0000 Subject: [PATCH] * fixed r5214 git-svn-id: trunk@5222 - --- compiler/cgobj.pas | 95 +++++++++++++++++++++++------------- compiler/powerpc/cgcpu.pas | 4 +- compiler/powerpc64/cgcpu.pas | 6 ++- 3 files changed, 67 insertions(+), 38 deletions(-) diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index d7fd2894ba..9919feaba2 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -956,19 +956,29 @@ implementation bitmask := not(((aint(1) shl stopbit)-1) xor ((aint(1) shl sreg.startbit)-1)) else bitmask := not(-1 xor ((aint(1) shl sreg.startbit)-1)); - tmpreg:=getintregister(list,sreg.subsetregsize); - a_load_reg_reg(list,fromsize,sreg.subsetregsize,fromreg,tmpreg); - if (slopt <> SL_SETZERO) then + if not(slopt in [SL_SETZERO,SL_SETMAX]) then begin + tmpreg:=getintregister(list,sreg.subsetregsize); + a_load_reg_reg(list,fromsize,sreg.subsetregsize,fromreg,tmpreg); a_op_const_reg(list,OP_SHL,sreg.subsetregsize,sreg.startbit,tmpreg); - if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) then + if (slopt <> SL_REGNOSRCMASK) then a_op_const_reg(list,OP_AND,sreg.subsetregsize,not(bitmask),tmpreg); end; - if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) then + if (slopt <> SL_SETMAX) then a_op_const_reg(list,OP_AND,sreg.subsetregsize,bitmask,sreg.subsetreg); - if (slopt <> SL_SETZERO) then - a_op_reg_reg(list,OP_OR,sreg.subsetregsize,tmpreg,sreg.subsetreg); + case slopt of + SL_SETZERO : ; + SL_SETMAX : + if (sreg.bitlen <> AIntBits) then + a_op_const_reg(list,OP_OR,sreg.subsetregsize, + ((aint(1) shl sreg.bitlen)-1) shl sreg.startbit, + sreg.subsetreg) + else + a_load_const_reg(list,sreg.subsetregsize,-1,sreg.subsetreg); + else + a_op_reg_reg(list,OP_OR,sreg.subsetregsize,tmpreg,sreg.subsetreg); + end; end; @@ -1036,7 +1046,7 @@ implementation bitmask := not(((aint(1) shl stopbit)-1) xor ((aint(1) shl sreg.startbit)-1)) else bitmask := (aint(1) shl sreg.startbit) - 1; - if (((a shl sreg.startbit) and not bitmask) <> bitmask) then + if (((a shl sreg.startbit) and not bitmask) <> not bitmask) then a_op_const_reg(list,OP_AND,sreg.subsetregsize,bitmask,sreg.subsetreg); a_op_const_reg(list,OP_OR,sreg.subsetregsize,(a shl sreg.startbit) and not(bitmask),sreg.subsetreg); end; @@ -1362,17 +1372,7 @@ implementation else tosreg.startbit := sref.startbit; tosreg.bitlen := sref.bitlen; - case slopt of - SL_SETZERO: - a_load_const_subsetreg(list,subsetsize,0,tosreg); - SL_SETMAX: - if (sref.bitlen = AIntBits) then - a_load_const_subsetreg(list,subsetsize,-1,tosreg) - else - a_load_const_subsetreg(list,subsetsize,(aint(1) shl sref.bitlen) - 1,tosreg); - else - a_load_regconst_subsetreg_intern(list,fromsize,subsetsize,fromreg,tosreg,slopt); - end; + a_load_regconst_subsetreg_intern(list,fromsize,subsetsize,fromreg,tosreg,slopt); end else begin @@ -1393,7 +1393,7 @@ implementation end; { zero the bits we have to insert } - if not(slopt in [SL_SETMAX,SL_REGNOSRCMASK]) then + if (slopt <> SL_SETMAX) then begin maskreg := getintregister(list,OS_INT); a_load_const_reg(list,OS_INT,(aint(1) shl sref.bitlen)-1,maskreg); @@ -1406,8 +1406,14 @@ implementation if (slopt <> SL_SETZERO) then begin tmpreg := getintregister(list,OS_INT); - a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg); - a_op_const_reg(list,OP_AND,OS_INT,(aint(1) shl sref.bitlen)-1,tmpreg); + if (slopt <> SL_SETMAX) then + a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg) + else if (sref.bitlen <> AIntBits) then + a_load_const_reg(list,OS_INT,(aint(1) shl sref.bitlen) - 1, tmpreg) + else + a_load_const_reg(list,OS_INT,-1,tmpreg); + if (slopt <> SL_REGNOSRCMASK) then + a_op_const_reg(list,OP_AND,OS_INT,(aint(1) shl sref.bitlen)-1,tmpreg); a_op_reg_reg(list,OP_SHL,OS_INT,tmpindexreg,tmpreg); a_op_reg_reg(list,OP_OR,OS_INT,tmpreg,valuereg); end; @@ -1497,7 +1503,7 @@ implementation internalerror(2006081713); { generate mask to zero the bits we have to insert } - if not (slopt in [SL_REGNOSRCMASK,SL_SETMAX]) then + if (slopt <> SL_SETMAX) then begin maskreg := getintregister(list,OS_INT); if (target_info.endian = endian_big) then @@ -1519,18 +1525,27 @@ implementation if (slopt <> SL_SETZERO) then begin tmpreg := getintregister(list,OS_INT); - a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg); + if (slopt <> SL_SETMAX) then + a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg) + else if (sref.bitlen <> AIntBits) then + a_load_const_reg(list,OS_INT,(aint(1) shl sref.bitlen) - 1, tmpreg) + else + a_load_const_reg(list,OS_INT,-1,tmpreg); if (target_info.endian = endian_big) then begin a_op_const_reg(list,OP_SHL,OS_INT,loadbitsize-sref.bitlen,tmpreg); - if (loadbitsize <> AIntBits) then + if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) and + (loadbitsize <> AIntBits) then { mask left over bits } a_op_const_reg(list,OP_AND,OS_INT,((aint(1) shl sref.bitlen)-1) shl (loadbitsize-sref.bitlen),tmpreg); a_op_reg_reg(list,OP_SHR,OS_INT,sref.bitindexreg,tmpreg); end else begin - a_op_const_reg(list,OP_AND,OS_INT,(aint(1) shl sref.bitlen)-1,tmpreg); + if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) and + (loadbitsize <> AIntBits) then + { mask left over bits } + a_op_const_reg(list,OP_AND,OS_INT,(aint(1) shl sref.bitlen)-1,tmpreg); a_op_reg_reg(list,OP_SHL,OS_INT,sref.bitindexreg,tmpreg); end; a_op_reg_reg(list,OP_OR,OS_INT,tmpreg,valuereg); @@ -1542,12 +1557,20 @@ implementation a_load_ref_reg(list,loadsize,OS_INT,tmpref,extra_value_reg); tmpindexreg := getintregister(list,OS_INT); - { load current array value } - tmpreg := getintregister(list,OS_INT); - a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg); + { load current array value } + if (slopt <> SL_SETZERO) then + begin + tmpreg := getintregister(list,OS_INT); + if (slopt <> SL_SETMAX) then + a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg) + else if (sref.bitlen <> AIntBits) then + a_load_const_reg(list,OS_INT,(aint(1) shl sref.bitlen) - 1, tmpreg) + else + a_load_const_reg(list,OS_INT,-1,tmpreg); + end; { generate mask to zero the bits we have to insert } - if not (slopt in [SL_REGNOSRCMASK,SL_SETMAX]) then + if (slopt <> SL_SETMAX) then begin maskreg := getintregister(list,OS_INT); if (target_info.endian = endian_big) then @@ -1569,12 +1592,13 @@ implementation if (loadbitsize = AIntBits) then begin valuereg := getintregister(list,OS_INT); - { if (tmpreg >= cpu_bit_size) then valuereg := 1 else valuereg := 0 } + { if (tmpindexreg >= cpu_bit_size) then valuereg := 1 else valuereg := 0 } a_op_const_reg_reg(list,OP_SHR,OS_INT,{$ifdef cpu64bit}6{$else}5{$endif},tmpindexreg,valuereg); - { if (tmpreg = cpu_bit_size) then valuereg := 0 else valuereg := -1 } + { if (tmpindexreg = cpu_bit_size) then valuereg := 0 else valuereg := -1 } a_op_const_reg(list,OP_SUB,OS_INT,1,valuereg); - { if (tmpreg = cpu_bit_size) then tmpreg := maskreg := 0 } - a_op_reg_reg(list,OP_AND,OS_INT,valuereg,tmpreg); + { if (tmpindexreg = cpu_bit_size) then tmpreg := maskreg := 0 } + if (slopt <> SL_SETZERO) then + a_op_reg_reg(list,OP_AND,OS_INT,valuereg,tmpreg); a_op_reg_reg(list,OP_AND,OS_INT,valuereg,maskreg); end; {$endif x86} @@ -1590,7 +1614,8 @@ implementation a_op_reg_reg(list,OP_SHL,OS_INT,tmpindexreg,tmpreg) else begin - a_op_const_reg(list,OP_AND,OS_INT,(aint(1) shl sref.bitlen)-1,tmpreg); + if not(slopt in [SL_REGNOSRCMASK,SL_SETMAX]) then + a_op_const_reg(list,OP_AND,OS_INT,(aint(1) shl sref.bitlen)-1,tmpreg); a_op_reg_reg(list,OP_SHR,OS_INT,tmpindexreg,tmpreg); end; a_op_reg_reg(list,OP_OR,OS_INT,tmpreg,extra_value_reg); diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index 8c26d1f2a3..a257603729 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/compiler/powerpc/cgcpu.pas @@ -447,7 +447,9 @@ const procedure tcgppc.a_load_regconst_subsetreg_intern(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt); begin - if (sreg.bitlen <> sizeof(aint) * 8) then + if (slopt in [SL_SETZERO,SL_SETMAX]) then + inherited a_load_regconst_subsetreg_intern(list,fromsize,subsetsize,fromreg,sreg,slopt) + else if (sreg.bitlen <> sizeof(aint) * 8) then 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 diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas index 1ab6e2561b..e77c0d3653 100644 --- a/compiler/powerpc64/cgcpu.pas +++ b/compiler/powerpc64/cgcpu.pas @@ -829,8 +829,10 @@ begin {$ifdef extdebug} 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 (sreg.bitlen <> sizeof(aint)*8) then + if (slopt in [SL_SETZERO,SL_SETMAX]) then + inherited a_load_regconst_subsetreg_intern(list,fromsize,subsetsize,fromreg,sreg,slopt) + else if (sreg.bitlen <> sizeof(aint)*8) then + { simply use the INSRDI instruction } 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, sreg.subsetreg);