mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 01:51:49 +01:00 
			
		
		
		
	* handle LOC_(C)SUBSETREG/REF in second_NegNot_assign
* changed the way OP_NEG and OP_NOT are handled in op_reg_ref, in order to be consistent with op_reg_reg * introduced op_reg,op_ref,op_subsetreg,op_subsetref and op_loc for the unary operations only (OP_NEG,OP_NOT) git-svn-id: trunk@45302 -
This commit is contained in:
		
							parent
							
								
									5aaf863d56
								
							
						
					
					
						commit
						0f6ab0de17
					
				| @ -758,12 +758,17 @@ unit cg64f32; | ||||
|       begin | ||||
|         tempreg.reghi:=cg.getintregister(list,OS_32); | ||||
|         tempreg.reglo:=cg.getintregister(list,OS_32); | ||||
|         a_load64_ref_reg(list,ref,tempreg); | ||||
|         if op in [OP_NEG,OP_NOT] then | ||||
|           a_op64_reg_reg(list,op,size,tempreg,tempreg) | ||||
|         else | ||||
|           begin | ||||
|             a_op64_reg_reg(list,op,size,reg,tempreg); | ||||
|             a_load64_reg_ref(list,tempreg,ref); | ||||
|           end | ||||
|         else | ||||
|           begin | ||||
|             a_load64_ref_reg(list,ref,tempreg); | ||||
|             a_op64_reg_reg(list,op,size,reg,tempreg); | ||||
|             a_load64_reg_ref(list,tempreg,ref); | ||||
|           end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -304,10 +304,6 @@ unit cgobj; | ||||
|           procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tcgsize; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual; | ||||
| 
 | ||||
|           { basic arithmetic operations } | ||||
|           { note: for operators which require only one argument (not, neg), use } | ||||
|           { the op_reg_reg, op_reg_ref or op_reg_loc methods and keep in mind   } | ||||
|           { that in this case the *second* operand is used as both source and   } | ||||
|           { destination (JM)                                                    } | ||||
|           procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); virtual; abstract; | ||||
|           procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference); virtual; | ||||
|           procedure a_op_const_loc(list : TAsmList; Op: TOpCG; a: tcgint; const loc: tlocation); | ||||
| @ -326,6 +322,11 @@ unit cgobj; | ||||
|           procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual; | ||||
|           procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual; | ||||
| 
 | ||||
|           { unary operations (not, neg) } | ||||
|           procedure a_op_reg(list : TAsmList; Op: TOpCG; size: TCGSize; reg: TRegister); virtual; | ||||
|           procedure a_op_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); virtual; | ||||
|           procedure a_op_loc(list : TAsmList; Op: TOpCG; const loc: tlocation); | ||||
| 
 | ||||
|           {  comparison operations } | ||||
|           procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;reg : tregister; | ||||
|             l : tasmlabel); virtual; | ||||
| @ -525,6 +526,9 @@ unit cgobj; | ||||
|         procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);virtual; | ||||
|         procedure a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual; | ||||
|         procedure a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual; | ||||
|         procedure a_op64_reg(list : TAsmList;op:TOpCG;size : tcgsize;regdst : tregister64);virtual; | ||||
|         procedure a_op64_ref(list : TAsmList;op:TOpCG;size : tcgsize;const ref : treference);virtual; | ||||
|         procedure a_op64_loc(list : TAsmList;op:TOpCG;size : tcgsize;const l : tlocation);virtual; | ||||
| 
 | ||||
|         procedure a_op64_const_subsetref(list : TAsmList; Op : TOpCG; size : TCGSize; a : int64; const sref: tsubsetreference); | ||||
|         procedure a_op64_reg_subsetref(list : TAsmList; Op : TOpCG; size : TCGSize; reg: tregister64; const sref: tsubsetreference); | ||||
| @ -2013,17 +2017,19 @@ implementation | ||||
|           end | ||||
|         else | ||||
|           tmpref:=ref; | ||||
|         tmpreg:=getintregister(list,size); | ||||
|         a_load_ref_reg(list,size,size,tmpref,tmpreg); | ||||
|         if op in [OP_NEG,OP_NOT] then | ||||
|           begin | ||||
|             if reg<>NR_NO then | ||||
|               internalerror(2017040901); | ||||
|             a_op_reg_reg(list,op,size,tmpreg,tmpreg); | ||||
|           end | ||||
|         else | ||||
|             tmpreg:=getintregister(list,size); | ||||
|             a_op_reg_reg(list,op,size,reg,tmpreg); | ||||
|             a_load_reg_ref(list,size,size,tmpreg,tmpref); | ||||
|           end | ||||
|         else | ||||
|           begin | ||||
|             tmpreg:=getintregister(list,size); | ||||
|             a_load_ref_reg(list,size,size,tmpref,tmpreg); | ||||
|             a_op_reg_reg(list,op,size,reg,tmpreg); | ||||
|             a_load_reg_ref(list,size,size,tmpreg,tmpref); | ||||
|           end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
| @ -2224,6 +2230,49 @@ implementation | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg.a_op_reg(list: TAsmList; Op: TOpCG; size: TCGSize; reg: TRegister); | ||||
|       begin | ||||
|         if not (Op in [OP_NOT,OP_NEG]) then | ||||
|           internalerror(2020050701); | ||||
|         a_op_reg_reg(list,op,size,reg,reg); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg.a_op_ref(list: TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); | ||||
|       var | ||||
|         tmpreg: TRegister; | ||||
|         tmpref: treference; | ||||
|       begin | ||||
|         if not (Op in [OP_NOT,OP_NEG]) then | ||||
|           internalerror(2020050701); | ||||
|         if assigned(ref.symbol) then | ||||
|           begin | ||||
|             tmpreg:=getaddressregister(list); | ||||
|             a_loadaddr_ref_reg(list,ref,tmpreg); | ||||
|             reference_reset_base(tmpref,tmpreg,0,ref.temppos,ref.alignment,[]); | ||||
|           end | ||||
|         else | ||||
|           tmpref:=ref; | ||||
|         tmpreg:=getintregister(list,size); | ||||
|         a_load_ref_reg(list,size,size,tmpref,tmpreg); | ||||
|         a_op_reg_reg(list,op,size,tmpreg,tmpreg); | ||||
|         a_load_reg_ref(list,size,size,tmpreg,tmpref); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg.a_op_loc(list: TAsmList; Op: TOpCG; const loc: tlocation); | ||||
|       begin | ||||
|         case loc.loc of | ||||
|           LOC_REGISTER, LOC_CREGISTER: | ||||
|             a_op_reg(list,op,loc.size,loc.register); | ||||
|           LOC_REFERENCE, LOC_CREFERENCE: | ||||
|             a_op_ref(list,op,loc.size,loc.reference); | ||||
|           else | ||||
|             internalerror(2020050702); | ||||
|         end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg.a_cmp_const_reg_label(list: TAsmList; size: tcgsize; | ||||
|       cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); | ||||
|       var | ||||
| @ -3080,6 +3129,41 @@ implementation | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg64.a_op64_reg(list: TAsmList; op: TOpCG; size: tcgsize; regdst: tregister64); | ||||
|       begin | ||||
|         if not (op in [OP_NOT,OP_NEG]) then | ||||
|           internalerror(2020050706); | ||||
|         a_op64_reg_reg(list,op,size,regdst,regdst); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg64.a_op64_ref(list: TAsmList; op: TOpCG; size: tcgsize; const ref: treference); | ||||
|       var | ||||
|         tempreg: tregister64; | ||||
|       begin | ||||
|         if not (op in [OP_NOT,OP_NEG]) then | ||||
|           internalerror(2020050706); | ||||
|         tempreg.reghi:=cg.getintregister(list,OS_32); | ||||
|         tempreg.reglo:=cg.getintregister(list,OS_32); | ||||
|         a_load64_ref_reg(list,ref,tempreg); | ||||
|         a_op64_reg_reg(list,op,size,tempreg,tempreg); | ||||
|         a_load64_reg_ref(list,tempreg,ref); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg64.a_op64_loc(list: TAsmList; op: TOpCG; size: tcgsize; const l: tlocation); | ||||
|       begin | ||||
|         case l.loc of | ||||
|           LOC_REFERENCE, LOC_CREFERENCE: | ||||
|             a_op64_ref(list,op,size,l.reference); | ||||
|           LOC_REGISTER,LOC_CREGISTER: | ||||
|             a_op64_reg(list,op,size,l.register64); | ||||
|           else | ||||
|             internalerror(2020050707); | ||||
|         end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg64.a_load64_loc_subsetref(list : TAsmList;const l: tlocation; const sref : tsubsetreference); | ||||
|       begin | ||||
|         case l.loc of | ||||
|  | ||||
| @ -221,6 +221,11 @@ unit hlcg2ll; | ||||
|           procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); override; | ||||
|           procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); override; | ||||
| 
 | ||||
|           { unary operations (not, neg) } | ||||
|           procedure a_op_reg(list : TAsmList; Op: TOpCG; size: tdef; reg: TRegister); override; | ||||
|           procedure a_op_ref(list : TAsmList; Op: TOpCG; size: tdef; const ref: TReference); override; | ||||
|           procedure a_op_loc(list : TAsmList; Op: TOpCG; size: tdef;  const loc: tlocation); override; | ||||
| 
 | ||||
|           {  comparison operations } | ||||
|           procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister; | ||||
|             l : tasmlabel);override; | ||||
| @ -863,6 +868,31 @@ implementation | ||||
|       cg.a_op_reg_reg_reg_checkoverflow(list,op,def_cgsize(size),src1,src2,dst,setflags,ovloc); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcg2ll.a_op_reg(list: TAsmList; Op: TOpCG; size: tdef; reg: TRegister); | ||||
|     begin | ||||
|       cg.a_op_reg(list,op,def_cgsize(size),reg); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcg2ll.a_op_ref(list: TAsmList; Op: TOpCG; size: tdef; const ref: TReference); | ||||
|     begin | ||||
|       cg.a_op_ref(list,op,def_cgsize(size),ref); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcg2ll.a_op_loc(list: TAsmList; Op: TOpCG; size: tdef; const loc: tlocation); | ||||
|     begin | ||||
| {$ifdef extdebug} | ||||
|       if def_cgsize(size)<>loc.size then | ||||
|         internalerror(2020050704); | ||||
| {$endif} | ||||
|       case loc.loc of | ||||
|         LOC_SUBSETREG,LOC_CSUBSETREG, | ||||
|         LOC_SUBSETREF,LOC_CSUBSETREF: | ||||
|           inherited | ||||
|         else | ||||
|           cg.a_op_loc(list,op,loc); | ||||
|       end; | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcg2ll.a_cmp_const_reg_label(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); | ||||
|     begin | ||||
|       cg.a_cmp_const_reg_label(list,def_cgsize(size),cmp_op,a,reg,l); | ||||
|  | ||||
| @ -340,10 +340,6 @@ unit hlcgobj; | ||||
|           procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tdef; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual; abstract; | ||||
| 
 | ||||
|           { basic arithmetic operations } | ||||
|           { note: for operators which require only one argument (not, neg), use } | ||||
|           { the op_reg_reg, op_reg_ref or op_reg_loc methods and keep in mind   } | ||||
|           { that in this case the *second* operand is used as both source and   } | ||||
|           { destination (JM)                                                    } | ||||
|           procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: tdef; a: tcgint; reg: TRegister); virtual; abstract; | ||||
|           procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: tdef; a: tcgint; const ref: TReference); virtual; | ||||
|           procedure a_op_const_subsetreg(list : TAsmList; Op : TOpCG; size, subsetsize : tdef; a : tcgint; const sreg: tsubsetregister); virtual; | ||||
| @ -365,6 +361,13 @@ unit hlcgobj; | ||||
|           procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual; | ||||
|           procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual; | ||||
| 
 | ||||
|           { unary operations (not, neg) } | ||||
|           procedure a_op_reg(list : TAsmList; Op: TOpCG; size: tdef; reg: TRegister); virtual; | ||||
|           procedure a_op_ref(list : TAsmList; Op: TOpCG; size: tdef; const ref: TReference); virtual; | ||||
|           procedure a_op_subsetreg(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sreg: tsubsetregister); virtual; | ||||
|           procedure a_op_subsetref(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sref: tsubsetreference); virtual; | ||||
|           procedure a_op_loc(list : TAsmList; Op: TOpCG; size: tdef;  const loc: tlocation); virtual; | ||||
| 
 | ||||
|           {  comparison operations } | ||||
|           procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister; | ||||
|             l : tasmlabel);virtual; | ||||
| @ -3107,6 +3110,65 @@ implementation | ||||
|         internalerror(2010122911); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcgobj.a_op_reg(list: TAsmList; Op: TOpCG; size: tdef; reg: TRegister); | ||||
|     begin | ||||
|       if not (Op in [OP_NOT,OP_NEG]) then | ||||
|         internalerror(2020050701); | ||||
|       a_op_reg_reg(list,op,size,reg,reg); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcgobj.a_op_ref(list: TAsmList; Op: TOpCG; size: tdef; const ref: TReference); | ||||
|     var | ||||
|       tmpreg: TRegister; | ||||
|     begin | ||||
|       if not (Op in [OP_NOT,OP_NEG]) then | ||||
|         internalerror(2020050701); | ||||
|       tmpreg:=getintregister(list,size); | ||||
|       a_load_ref_reg(list,size,size,ref,tmpreg); | ||||
|       a_op_reg_reg(list,op,size,tmpreg,tmpreg); | ||||
|       a_load_reg_ref(list,size,size,tmpreg,ref); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcgobj.a_op_subsetreg(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sreg: tsubsetregister); | ||||
|     var | ||||
|       tmpreg: tregister; | ||||
|       subsetregdef: torddef; | ||||
|     begin | ||||
|       subsetregdef:=cgsize_orddef(sreg.subsetregsize); | ||||
|       tmpreg:=getintregister(list,subsetregdef); | ||||
|       a_load_subsetreg_reg(list,destsubsetsize,subsetregdef,sreg,tmpreg); | ||||
|       a_op_reg(list,op,subsetregdef,tmpreg); | ||||
|       a_load_reg_subsetreg(list,subsetregdef,destsubsetsize,tmpreg,sreg); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcgobj.a_op_subsetref(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sref: tsubsetreference); | ||||
|     var | ||||
|       tmpreg: tregister; | ||||
|       subsetregdef: torddef; | ||||
|     begin | ||||
|       subsetregdef:=cgsize_orddef(def_cgsize(destsubsetsize)); | ||||
|       tmpreg:=getintregister(list,subsetregdef); | ||||
|       a_load_subsetref_reg(list,destsubsetsize,subsetregdef,sref,tmpreg); | ||||
|       a_op_reg(list,op,subsetregdef,tmpreg); | ||||
|       a_load_reg_subsetref(list,subsetregdef,destsubsetsize,tmpreg,sref); | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcgobj.a_op_loc(list: TAsmList; Op: TOpCG; size: tdef; const loc: tlocation); | ||||
|     begin | ||||
|       case loc.loc of | ||||
|         LOC_REGISTER, LOC_CREGISTER: | ||||
|           a_op_reg(list,op,size,loc.register); | ||||
|         LOC_REFERENCE, LOC_CREFERENCE: | ||||
|           a_op_ref(list,op,size,loc.reference); | ||||
|         LOC_SUBSETREG, LOC_CSUBSETREG: | ||||
|           a_op_subsetreg(list,op,size,loc.sreg); | ||||
|         LOC_SUBSETREF, LOC_CSUBSETREF: | ||||
|           a_op_subsetref(list,op,size,loc.sref); | ||||
|         else | ||||
|           internalerror(2020050703); | ||||
|       end; | ||||
|     end; | ||||
| 
 | ||||
|   procedure thlcgobj.a_cmp_const_reg_label(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); | ||||
|     var | ||||
|       tmpreg: tregister; | ||||
|  | ||||
| @ -56,6 +56,7 @@ unit cgcpu; | ||||
|         procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override; | ||||
|         procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override; | ||||
|         procedure a_op64_const_ref(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;const ref : treference);override; | ||||
|         procedure a_op64_ref(list : TAsmList;op:TOpCG;size : tcgsize;const ref: treference);override; | ||||
|       private | ||||
|         procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp); | ||||
|       end; | ||||
| @ -671,27 +672,8 @@ unit cgcpu; | ||||
|         l1, l2: TAsmLabel; | ||||
|       begin | ||||
|         case op of | ||||
|           OP_NOT: | ||||
|             begin | ||||
|               tempref:=ref; | ||||
|               tcgx86(cg).make_simple_ref(list,tempref); | ||||
|               list.concat(taicpu.op_ref(A_NOT,S_L,tempref)); | ||||
|               inc(tempref.offset,4); | ||||
|               list.concat(taicpu.op_ref(A_NOT,S_L,tempref)); | ||||
|             end; | ||||
|           OP_NEG: | ||||
|             begin | ||||
|               tempref:=ref; | ||||
|               tcgx86(cg).make_simple_ref(list,tempref); | ||||
|               inc(tempref.offset,4); | ||||
|               list.concat(taicpu.op_ref(A_NOT,S_L,tempref)); | ||||
|               cg.a_reg_alloc(list,NR_DEFAULTFLAGS); | ||||
|               dec(tempref.offset,4); | ||||
|               list.concat(taicpu.op_ref(A_NEG,S_L,tempref)); | ||||
|               inc(tempref.offset,4); | ||||
|               list.concat(taicpu.op_const_ref(A_SBB,S_L,-1,tempref)); | ||||
|               cg.a_reg_dealloc(list,NR_DEFAULTFLAGS); | ||||
|             end; | ||||
|           OP_NOT,OP_NEG: | ||||
|             inherited; | ||||
|           OP_SHR,OP_SHL,OP_SAR: | ||||
|             begin | ||||
|               { load right operators in a register } | ||||
| @ -1154,6 +1136,39 @@ unit cgcpu; | ||||
|         end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg64f386.a_op64_ref(list: TAsmList; op: TOpCG; size: tcgsize; const ref: treference); | ||||
|       var | ||||
|         tempref : treference; | ||||
|       begin | ||||
|         case op of | ||||
|           OP_NOT: | ||||
|             begin | ||||
|               tempref:=ref; | ||||
|               tcgx86(cg).make_simple_ref(list,tempref); | ||||
|               list.concat(taicpu.op_ref(A_NOT,S_L,tempref)); | ||||
|               inc(tempref.offset,4); | ||||
|               list.concat(taicpu.op_ref(A_NOT,S_L,tempref)); | ||||
|             end; | ||||
|           OP_NEG: | ||||
|             begin | ||||
|               tempref:=ref; | ||||
|               tcgx86(cg).make_simple_ref(list,tempref); | ||||
|               inc(tempref.offset,4); | ||||
|               list.concat(taicpu.op_ref(A_NOT,S_L,tempref)); | ||||
|               cg.a_reg_alloc(list,NR_DEFAULTFLAGS); | ||||
|               dec(tempref.offset,4); | ||||
|               list.concat(taicpu.op_ref(A_NEG,S_L,tempref)); | ||||
|               inc(tempref.offset,4); | ||||
|               list.concat(taicpu.op_const_ref(A_SBB,S_L,-1,tempref)); | ||||
|               cg.a_reg_dealloc(list,NR_DEFAULTFLAGS); | ||||
|             end; | ||||
|           else | ||||
|             internalerror(2020050708); | ||||
|         end; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure create_codegen; | ||||
|       begin | ||||
|         cg := tcg386.create; | ||||
|  | ||||
| @ -53,6 +53,7 @@ unit cgcpu; | ||||
|         procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override; | ||||
|         procedure a_op_ref_reg(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override; | ||||
|         procedure a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override; | ||||
|         procedure a_op_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); override; | ||||
| 
 | ||||
|         procedure push_const(list:TAsmList;size:tcgsize;a:tcgint); | ||||
| 
 | ||||
| @ -1138,7 +1139,7 @@ unit cgcpu; | ||||
|       begin | ||||
|         tmpref:=ref; | ||||
|         make_simple_ref(list,tmpref); | ||||
|         if not (op in [OP_NEG,OP_NOT,OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then | ||||
|         if not (op in [OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then | ||||
|           check_register_size(size,reg); | ||||
| 
 | ||||
|         if size in [OS_64, OS_S64] then | ||||
| @ -1147,27 +1148,8 @@ unit cgcpu; | ||||
|         if size in [OS_32, OS_S32] then | ||||
|           begin | ||||
|             case op of | ||||
|               OP_NEG: | ||||
|                 begin | ||||
|                   if reg<>NR_NO then | ||||
|                     internalerror(200109237); | ||||
|                   inc(tmpref.offset, 2); | ||||
|                   list.concat(taicpu.op_ref(A_NOT, S_W, tmpref)); | ||||
|                   dec(tmpref.offset, 2); | ||||
|                   cg.a_reg_alloc(list,NR_DEFAULTFLAGS); | ||||
|                   list.concat(taicpu.op_ref(A_NEG, S_W, tmpref)); | ||||
|                   inc(tmpref.offset, 2); | ||||
|                   list.concat(taicpu.op_const_ref(A_SBB, S_W,-1, tmpref)); | ||||
|                   cg.a_reg_dealloc(list,NR_DEFAULTFLAGS); | ||||
|                 end; | ||||
|               OP_NOT: | ||||
|                 begin | ||||
|                   if reg<>NR_NO then | ||||
|                     internalerror(200109237); | ||||
|                   list.concat(taicpu.op_ref(A_NOT, S_W, tmpref)); | ||||
|                   inc(tmpref.offset, 2); | ||||
|                   list.concat(taicpu.op_ref(A_NOT, S_W, tmpref)); | ||||
|                 end; | ||||
|               OP_NEG,OP_NOT: | ||||
|                 inherited; | ||||
|               OP_IMUL: | ||||
|                 begin | ||||
|                   { this one needs a load/imul/store, which is the default } | ||||
| @ -1260,6 +1242,46 @@ unit cgcpu; | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg8086.a_op_ref(list: TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); | ||||
|       begin | ||||
|         var | ||||
|           tmpref: treference; | ||||
|         begin | ||||
|           tmpref:=ref; | ||||
|           make_simple_ref(list,tmpref); | ||||
| 
 | ||||
|           if size in [OS_64, OS_S64] then | ||||
|             internalerror(2013050803); | ||||
| 
 | ||||
|           if size in [OS_32, OS_S32] then | ||||
|             begin | ||||
|               case op of | ||||
|                 OP_NEG: | ||||
|                   begin | ||||
|                     inc(tmpref.offset, 2); | ||||
|                     list.concat(taicpu.op_ref(A_NOT, S_W, tmpref)); | ||||
|                     dec(tmpref.offset, 2); | ||||
|                     cg.a_reg_alloc(list,NR_DEFAULTFLAGS); | ||||
|                     list.concat(taicpu.op_ref(A_NEG, S_W, tmpref)); | ||||
|                     inc(tmpref.offset, 2); | ||||
|                     list.concat(taicpu.op_const_ref(A_SBB, S_W,-1, tmpref)); | ||||
|                     cg.a_reg_dealloc(list,NR_DEFAULTFLAGS); | ||||
|                   end; | ||||
|                 OP_NOT: | ||||
|                   begin | ||||
|                     list.concat(taicpu.op_ref(A_NOT, S_W, tmpref)); | ||||
|                     inc(tmpref.offset, 2); | ||||
|                     list.concat(taicpu.op_ref(A_NOT, S_W, tmpref)); | ||||
|                   end; | ||||
|                 else | ||||
|                   internalerror(2020050709); | ||||
|               end; | ||||
|             end | ||||
|           else | ||||
|             inherited a_op_reg_ref(list,Op,size,reg,tmpref); | ||||
|       end; | ||||
| 
 | ||||
| 
 | ||||
|     procedure tcg8086.push_const(list: TAsmList; size: tcgsize; a: tcgint); | ||||
|       var | ||||
|         tmpreg: TRegister; | ||||
|  | ||||
| @ -613,36 +613,18 @@ implementation | ||||
|       procedure tcginlinenode.second_NegNot_assign; | ||||
|         const | ||||
|           negnotop:array[in_neg_assign_x..in_not_assign_x] of TOpCG=(OP_NEG,OP_NOT); | ||||
| {$ifndef cpu64bitalu} | ||||
|         var | ||||
|           NR_NO64: tregister64=(reglo:NR_NO;reghi:NR_NO); | ||||
| {$endif not cpu64bitalu} | ||||
|         begin | ||||
|           { load parameter, must be a reference } | ||||
|           secondpass(left); | ||||
| 
 | ||||
|           location_reset(location,LOC_VOID,OS_NO); | ||||
| 
 | ||||
|           if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then | ||||
|             begin | ||||
| {$ifndef cpu64bitalu} | ||||
|               if def_cgsize(left.resultdef) in [OS_64,OS_S64] then | ||||
|                 cg64.a_op64_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],def_cgsize(left.resultdef),left.location.register64,left.location) | ||||
|           if (def_cgsize(left.resultdef) in [OS_64,OS_S64]) and (left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE]) then | ||||
|             cg64.a_op64_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],def_cgsize(left.resultdef),left.location) | ||||
|           else | ||||
| {$endif not cpu64bitalu} | ||||
|                 hlcg.a_op_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],left.resultdef,left.location.register,left.location); | ||||
|             end | ||||
|           else if left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then | ||||
|             begin | ||||
| {$ifndef cpu64bitalu} | ||||
|               if def_cgsize(left.resultdef) in [OS_64,OS_S64] then | ||||
|                 cg64.a_op64_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],def_cgsize(left.resultdef),NR_NO64,left.location) | ||||
|               else | ||||
| {$endif not cpu64bitalu} | ||||
|                 hlcg.a_op_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],left.resultdef,NR_NO,left.location); | ||||
|             end | ||||
|           else | ||||
|             internalerror(2017040701); | ||||
|             hlcg.a_op_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],left.resultdef,left.location); | ||||
|         end; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -68,6 +68,7 @@ unit cgx86; | ||||
|         procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override; | ||||
|         procedure a_op_ref_reg(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override; | ||||
|         procedure a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override; | ||||
|         procedure a_op_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); override; | ||||
| 
 | ||||
| {$ifndef i8086} | ||||
|         procedure a_op_const_reg_reg(list : TAsmList; op : Topcg; size : Tcgsize; a : tcgint; src,dst : Tregister); override; | ||||
| @ -2340,8 +2341,6 @@ unit cgx86; | ||||
|         tmpref:=ref; | ||||
|         make_simple_ref(list,tmpref); | ||||
|         { we don't check the register size for some operations, for the following reasons: | ||||
|           NEG,NOT: | ||||
|             reg isn't used in these operations (they are unary and use only ref) | ||||
|           SHR,SHL,SAR,ROL,ROR: | ||||
|             We allow the register size to differ from the destination size. | ||||
|             This allows generating better code when performing, for example, a | ||||
| @ -2352,17 +2351,13 @@ unit cgx86; | ||||
|                 EDX have 8-bit subregisters) | ||||
|               - avoids partial register writes, which can cause various | ||||
|                 performance issues on modern out-of-order execution x86 CPUs } | ||||
|         if not (op in [OP_NEG,OP_NOT,OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then | ||||
|         if not (op in [OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then | ||||
|           check_register_size(size,reg); | ||||
|         if (op=OP_MUL) and not (cs_check_overflow in current_settings.localswitches) then | ||||
|           op:=OP_IMUL; | ||||
|         case op of | ||||
|           OP_NEG,OP_NOT: | ||||
|             begin | ||||
|               if reg<>NR_NO then | ||||
|                 internalerror(200109237); | ||||
|               list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],tmpref)); | ||||
|             end; | ||||
|             inherited; | ||||
|           OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR: | ||||
|             begin | ||||
|               { Use ecx to load the value, that allows better coalescing } | ||||
| @ -2387,6 +2382,17 @@ unit cgx86; | ||||
|         end; | ||||
|       end; | ||||
| 
 | ||||
|     procedure tcgx86.a_op_ref(list: TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); | ||||
|       var | ||||
|         tmpref: treference; | ||||
|       begin | ||||
|         if not (Op in [OP_NOT,OP_NEG]) then | ||||
|           internalerror(2020050705); | ||||
|         tmpref:=ref; | ||||
|         make_simple_ref(list,tmpref); | ||||
|         list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],tmpref)); | ||||
|       end; | ||||
| 
 | ||||
|      procedure tcgx86.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister); | ||||
|      var | ||||
|        tmpreg: tregister; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 nickysn
						nickysn