mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 05:11:34 +01:00 
			
		
		
		
	+ optimized division by negative power of 2 constants in the i8086 code
generator as well git-svn-id: trunk@37004 -
This commit is contained in:
		
							parent
							
								
									6634141bf4
								
							
						
					
					
						commit
						aa415bfc6b
					
				| @ -103,6 +103,7 @@ implementation | ||||
|         e : smallint; | ||||
|         d,l,r,s,m,a,n,t : word; | ||||
|         m_low,m_high,j,k : dword; | ||||
|         invertsign: Boolean; | ||||
|       begin | ||||
|         secondpass(left); | ||||
|         if codegenerror then | ||||
| @ -121,13 +122,14 @@ implementation | ||||
| 
 | ||||
|         if (nodetype=divn) and (right.nodetype=ordconstn) then | ||||
|           begin | ||||
|             if ispowerof2(tordconstnode(right).value.svalue,power) then | ||||
|             if isabspowerof2(tordconstnode(right).value,power) then | ||||
|               begin | ||||
|                 { for signed numbers, the numerator must be adjusted before the | ||||
|                   shift instruction, but not wih unsigned numbers! Otherwise, | ||||
|                   "Cardinal($ffffffff) div 16" overflows! (JM) } | ||||
|                 if is_signed(left.resultdef) Then | ||||
|                   begin | ||||
|                     invertsign:=tordconstnode(right).value<0; | ||||
|                     if (current_settings.optimizecputype > cpu_386) and | ||||
|                        not(cs_opt_size in current_settings.optimizerswitches) then | ||||
|                       { use a sequence without jumps, saw this in | ||||
| @ -136,17 +138,17 @@ implementation | ||||
|                         { no jumps, but more operations } | ||||
|                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); | ||||
|                         emit_reg_reg(A_MOV,S_W,hreg1,hreg2); | ||||
|                         if tordconstnode(right).value=2 then | ||||
|                         if power=1 then | ||||
|                           begin | ||||
|                             {If the left value is negative, hreg2=(right value-1)=1, otherwise 0.} | ||||
|                             {If the left value is negative, hreg2=(1 shl power)-1=1, otherwise 0.} | ||||
|                             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,15,hreg2); | ||||
|                           end | ||||
|                         else | ||||
|                           begin | ||||
|                             {If the left value is negative, hreg2=$ffff, otherwise 0.} | ||||
|                             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,15,hreg2); | ||||
|                             {If negative, hreg2=right value-1, otherwise 0.} | ||||
|                             emit_const_reg(A_AND,S_W,tordconstnode(right).value.svalue-1,hreg2); | ||||
|                             {If negative, hreg2=(1 shl power)-1, otherwise 0.} | ||||
|                             emit_const_reg(A_AND,S_W,(aint(1) shl power)-1,hreg2); | ||||
|                           end; | ||||
|                         { add to the left value } | ||||
|                         emit_reg_reg(A_ADD,S_W,hreg2,hreg1); | ||||
| @ -162,10 +164,12 @@ implementation | ||||
|                         if power=1 then | ||||
|                           emit_reg(A_INC,S_W,hreg1) | ||||
|                         else | ||||
|                           emit_const_reg(A_ADD,S_W,tordconstnode(right).value.svalue-1,hreg1); | ||||
|                           emit_const_reg(A_ADD,S_W,(aint(1) shl power)-1,hreg1); | ||||
|                         cg.a_label(current_asmdata.CurrAsmList,hl); | ||||
|                         cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,power,hreg1); | ||||
|                       end | ||||
|                       end; | ||||
|                     if invertsign then | ||||
|                       emit_reg(A_NEG,S_W,hreg1); | ||||
|                   end | ||||
|                 else | ||||
|                   cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,power,hreg1); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 nickysn
						nickysn