mirror of
				https://github.com/irmen/prog8.git
				synced 2025-10-31 15:16:13 +00:00 
			
		
		
		
	added more missing codegen for bit shifts
This commit is contained in:
		| @@ -512,86 +512,135 @@ internal class AssignmentAsmGen(private val program: PtProgram, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun optimizedBitshiftExpr(expr: PtBinaryExpression, target: AsmAssignTarget): Boolean { |     private fun optimizedBitshiftExpr(expr: PtBinaryExpression, target: AsmAssignTarget): Boolean { | ||||||
|  |         val signed = expr.left.type in SignedDatatypes | ||||||
|         val shifts = expr.right.asConstInteger() |         val shifts = expr.right.asConstInteger() | ||||||
|         if(shifts!=null) { |         val dt = expr.left.type | ||||||
|             val dt = expr.left.type |         if(shifts==null) { | ||||||
|  |             // bit shifts with variable shifts | ||||||
|  |             when(expr.right.type) { | ||||||
|  |                 in ByteDatatypes -> { | ||||||
|  |                     assignExpressionToRegister(expr.right, RegisterOrPair.A, false) | ||||||
|  |                 } | ||||||
|  |                 in WordDatatypes -> { | ||||||
|  |                     assignExpressionToRegister(expr.right, RegisterOrPair.AY, false) | ||||||
|  |                     asmgen.out(""" | ||||||
|  |                         cpy  #0 | ||||||
|  |                         beq  + | ||||||
|  |                         lda  #127 | ||||||
|  | +""") | ||||||
|  |                 } | ||||||
|  |                 else -> throw AssemblyError("weird shift value type") | ||||||
|  |             } | ||||||
|  |             asmgen.out("  pha") | ||||||
|             if(dt in ByteDatatypes) { |             if(dt in ByteDatatypes) { | ||||||
|                 val signed = dt == DataType.BYTE |  | ||||||
|                 assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) |                 assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) | ||||||
|                 if(shifts in 0..7) { |                 asmgen.out("  ply") | ||||||
|                     require(dt==DataType.UBYTE) |                 if(expr.operator==">>") | ||||||
|                     if (expr.operator == "<<") { |                     if(signed) | ||||||
|                         repeat(shifts) { |                         asmgen.out("  jsr  math.lsr_byte_A") | ||||||
|                             asmgen.out("  asl  a") |                     else | ||||||
|                         } |                         asmgen.out("  jsr  math.lsr_ubyte_A") | ||||||
|                     } else { |                 else | ||||||
|                         if (signed && shifts > 0) { |                     asmgen.out("  jsr  math.asl_byte_A") | ||||||
|                             asmgen.out("  ldy  #$shifts |  jsr  math.lsr_byte_A") |                 assignRegisterByte(target, CpuRegister.A, signed) | ||||||
|                         } else { |                 return true | ||||||
|  |             } else { | ||||||
|  |                 assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed) | ||||||
|  |                 asmgen.out("  plx") | ||||||
|  |                 if(expr.operator==">>") | ||||||
|  |                     if(signed) | ||||||
|  |                         asmgen.out("  jsr  math.lsr_word_AY") | ||||||
|  |                     else | ||||||
|  |                         asmgen.out("  jsr  math.lsr_uword_AY") | ||||||
|  |                 else | ||||||
|  |                     asmgen.out("  jsr  math.asl_word_AY") | ||||||
|  |                 assignRegisterpairWord(target, RegisterOrPair.AY) | ||||||
|  |                 return true | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             // bit shift with constant value | ||||||
|  |             if(dt in ByteDatatypes) { | ||||||
|  |                 assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) | ||||||
|  |                 when (shifts) { | ||||||
|  |                     in 0..7 -> { | ||||||
|  |                         require(dt==DataType.UBYTE) | ||||||
|  |                         if (expr.operator == "<<") { | ||||||
|                             repeat(shifts) { |                             repeat(shifts) { | ||||||
|                                 asmgen.out("  lsr  a") |                                 asmgen.out("  asl  a") | ||||||
|  |                             } | ||||||
|  |                         } else { | ||||||
|  |                             if (signed && shifts > 0) { | ||||||
|  |                                 asmgen.out("  ldy  #$shifts |  jsr  math.lsr_byte_A") | ||||||
|  |                             } else { | ||||||
|  |                                 repeat(shifts) { | ||||||
|  |                                     asmgen.out("  lsr  a") | ||||||
|  |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  |                         assignRegisterByte(target, CpuRegister.A, signed) | ||||||
|  |                         return true | ||||||
|                     } |                     } | ||||||
|                     assignRegisterByte(target, CpuRegister.A, signed) |                     else -> { | ||||||
|                     return true |                         if(signed && expr.operator==">>") { | ||||||
|                 } else { |                             TODO("signed byte >> overshift should have been compiled away?") | ||||||
|                     if(signed && expr.operator==">>") { |                         } else { | ||||||
|                         TODO("signed byte >> overshift should have been compiled away?") |                             asmgen.out("  lda  #0") | ||||||
|                     } else { |                         } | ||||||
|                         asmgen.out("  lda  #0") |                         assignRegisterByte(target, CpuRegister.A, signed) | ||||||
|  |                         return true | ||||||
|                     } |                     } | ||||||
|                     assignRegisterByte(target, CpuRegister.A, signed) |  | ||||||
|                     return true |  | ||||||
|                 } |                 } | ||||||
|             } else if(dt in WordDatatypes) { |             } else if(dt in WordDatatypes) { | ||||||
|                 val signed = dt == DataType.WORD |  | ||||||
|                 assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed) |                 assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed) | ||||||
|                 if(shifts in 0..7) { |                 when (shifts) { | ||||||
|                     if(expr.operator=="<<") { |                     in 0..7 -> { | ||||||
|                         if(shifts>0) { |                         if(expr.operator=="<<") { | ||||||
|                             asmgen.out("  sty  P8ZP_SCRATCH_B1") |  | ||||||
|                             repeat(shifts) { |  | ||||||
|                                 asmgen.out("  asl  a |  rol  P8ZP_SCRATCH_B1") |  | ||||||
|                             } |  | ||||||
|                             asmgen.out("  ldy  P8ZP_SCRATCH_B1") |  | ||||||
|                         } |  | ||||||
|                     } else { |  | ||||||
|                         if(signed && shifts>0) { |  | ||||||
|                             asmgen.out("  ldx  #$shifts |  jsr  math.lsr_word_AY") |  | ||||||
|                         } else { |  | ||||||
|                             if(shifts>0) { |                             if(shifts>0) { | ||||||
|                                 asmgen.out("  sty  P8ZP_SCRATCH_B1") |                                 asmgen.out("  sty  P8ZP_SCRATCH_B1") | ||||||
|                                 repeat(shifts) { |                                 repeat(shifts) { | ||||||
|                                     asmgen.out("  lsr  P8ZP_SCRATCH_B1 |  ror  a") |                                     asmgen.out("  asl  a |  rol  P8ZP_SCRATCH_B1") | ||||||
|                                 } |                                 } | ||||||
|                                 asmgen.out("  ldy  P8ZP_SCRATCH_B1") |                                 asmgen.out("  ldy  P8ZP_SCRATCH_B1") | ||||||
|                             } |                             } | ||||||
|  |                         } else { | ||||||
|  |                             if(signed && shifts>0) { | ||||||
|  |                                 asmgen.out("  ldx  #$shifts |  jsr  math.lsr_word_AY") | ||||||
|  |                             } else { | ||||||
|  |                                 if(shifts>0) { | ||||||
|  |                                     asmgen.out("  sty  P8ZP_SCRATCH_B1") | ||||||
|  |                                     repeat(shifts) { | ||||||
|  |                                         asmgen.out("  lsr  P8ZP_SCRATCH_B1 |  ror  a") | ||||||
|  |                                     } | ||||||
|  |                                     asmgen.out("  ldy  P8ZP_SCRATCH_B1") | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|  |                         assignRegisterpairWord(target, RegisterOrPair.AY) | ||||||
|  |                         return true | ||||||
|                     } |                     } | ||||||
|                     assignRegisterpairWord(target, RegisterOrPair.AY) |                     in 8..15 -> { | ||||||
|                     return true |                         if(expr.operator == "<<") { | ||||||
|                 } else if (shifts in 8..15) { |                             // msb = lsb << (shifts-8),   lsb = 0 | ||||||
|                     if(expr.operator == "<<") { |                             repeat(shifts-8) { | ||||||
|                         // msb = lsb << (shifts-8),   lsb = 0 |                                 asmgen.out("  asl  a") | ||||||
|                         repeat(shifts-8) { |                             } | ||||||
|                             asmgen.out("  asl  a") |                             asmgen.out("  tay |  lda  #0") | ||||||
|  |                         } else { | ||||||
|  |                             asmgen.out("  ldx  #$shifts |  jsr  math.lsr_word_AY") | ||||||
|                         } |                         } | ||||||
|                         asmgen.out("  tay |  lda  #0") |                         assignRegisterpairWord(target, RegisterOrPair.AY) | ||||||
|                     } else { |                         return true | ||||||
|                         asmgen.out("  ldx  #$shifts |  jsr  math.lsr_word_AY") |  | ||||||
|                     } |                     } | ||||||
|                     assignRegisterpairWord(target, RegisterOrPair.AY) |                     else -> { | ||||||
|                     return true |                         if(signed && expr.operator==">>") { | ||||||
|                 } |                             TODO("signed word >> overshift should have been compiled away?") | ||||||
|                 else { |                         } else { | ||||||
|                     if(signed && expr.operator==">>") { |                             asmgen.out("  lda  #0 |  ldy  #0") | ||||||
|                         TODO("signed word >> overshift should have been compiled away?") |                         } | ||||||
|                     } else { |                         assignRegisterpairWord(target, RegisterOrPair.AY) | ||||||
|                         asmgen.out("  lda  #0 |  ldy  #0") |                         return true | ||||||
|                     } |                     } | ||||||
|                     assignRegisterpairWord(target, RegisterOrPair.AY) |  | ||||||
|                     return true |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -751,37 +751,64 @@ mul_word_640	.proc | |||||||
| lsr_byte_A	.proc | lsr_byte_A	.proc | ||||||
| 		; -- lsr signed byte in A times the value in Y (>1) | 		; -- lsr signed byte in A times the value in Y (>1) | ||||||
| 		cmp  #0 | 		cmp  #0 | ||||||
| 		bmi  _negative | 		bpl  lsr_ubyte_A | ||||||
| -		lsr  a | -       	sec | ||||||
| 		dey |  | ||||||
| 		bne  - |  | ||||||
| 		rts |  | ||||||
| _negative	sec |  | ||||||
| 		ror  a | 		ror  a | ||||||
| 		dey | 		dey | ||||||
| 		bne  _negative | 		bne  - | ||||||
| 		rts | 		rts | ||||||
| 		.pend | 		.pend | ||||||
|  |  | ||||||
|  | lsr_ubyte_A	.proc | ||||||
|  | 		; -- lsr unsigned byte in A times the value in Y (>1) | ||||||
|  | -		lsr  a | ||||||
|  | 		dey | ||||||
|  | 		bne  - | ||||||
|  | 		rts | ||||||
|  | 		.pend | ||||||
|  |  | ||||||
|  | asl_byte_A      .proc | ||||||
|  | 		; -- asl any byte in A times the value in Y (>1) | ||||||
|  | -		asl  a | ||||||
|  | 		dey | ||||||
|  | 		bne  - | ||||||
|  | 		rts | ||||||
|  | 		.pend | ||||||
|  |  | ||||||
|  |  | ||||||
| lsr_word_AY     .proc | lsr_word_AY     .proc | ||||||
| 		; -- lsr signed word in AY times the value in X (>1) | 		; -- lsr signed word in AY times the value in X (>1) | ||||||
| 		sta  P8ZP_SCRATCH_B1 | 		cpy  #0 | ||||||
| 		tya | 		bpl  lsr_uword_AY | ||||||
| 		bmi  _negative | 		sty  P8ZP_SCRATCH_B1 | ||||||
| -		lsr  a |  | ||||||
| 		ror  P8ZP_SCRATCH_B1 |  | ||||||
| 		dex |  | ||||||
| 		bne  - |  | ||||||
| 		tay |  | ||||||
| 		lda  P8ZP_SCRATCH_B1 |  | ||||||
| 		rts |  | ||||||
| _negative       sec | _negative       sec | ||||||
| 		ror  a |  | ||||||
| 		ror  P8ZP_SCRATCH_B1 | 		ror  P8ZP_SCRATCH_B1 | ||||||
|  | 		ror  a | ||||||
| 		dex | 		dex | ||||||
| 		bne  _negative | 		bne  _negative | ||||||
| 		tay | 		ldy  P8ZP_SCRATCH_B1 | ||||||
| 		lda  P8ZP_SCRATCH_B1 | 		rts | ||||||
|  | 		.pend | ||||||
|  |  | ||||||
|  | lsr_uword_AY    .proc | ||||||
|  | 		; -- lsr unsigned word in AY times the value in X (>1) | ||||||
|  | 		sty  P8ZP_SCRATCH_B1 | ||||||
|  | -		lsr  P8ZP_SCRATCH_B1 | ||||||
|  | 		ror  a | ||||||
|  | 		dex | ||||||
|  | 		bne  - | ||||||
|  | 		ldy  P8ZP_SCRATCH_B1 | ||||||
|  | 		rts | ||||||
|  | 		.pend | ||||||
|  |  | ||||||
|  | asl_word_AY     .proc | ||||||
|  | 		; -- asl any word in AY times the value in X (>1) | ||||||
|  | 		sty  P8ZP_SCRATCH_B1 | ||||||
|  | -               asl  a | ||||||
|  | 		rol  P8ZP_SCRATCH_B1 | ||||||
|  | 		dex | ||||||
|  | 		bne  - | ||||||
|  | 		ldy  P8ZP_SCRATCH_B1 | ||||||
| 		rts | 		rts | ||||||
| 		.pend | 		.pend | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,9 @@ | |||||||
| TODO | TODO | ||||||
| ==== | ==== | ||||||
|  |  | ||||||
|  | - (branch): fix float expressions codegen, it relied heavily on the evalstack | ||||||
|  | - (branch): improve integer expression codegen even more to support even more cases? | ||||||
|  |  | ||||||
| - IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register. | - IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register. | ||||||
| - IR: reduce the number of branch instructions (gradually), replace with CMP(I) + status branch instruction | - IR: reduce the number of branch instructions (gradually), replace with CMP(I) + status branch instruction | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,15 +5,32 @@ main | |||||||
| { | { | ||||||
|     sub start() |     sub start() | ||||||
|     { |     { | ||||||
|         byte zc = -55 |         uword zc = 54321 | ||||||
|  |         ubyte zb = 123 | ||||||
|  |         ubyte shift = 2 | ||||||
|  |  | ||||||
|         when zc*3 { |         txt.print_uw(zc<<shift) | ||||||
|             123 -> zc++ |         txt.nl() | ||||||
|             124 -> zc++ |         txt.print_uw(zc>>shift) | ||||||
|             125 -> zc++ |         txt.nl() | ||||||
|             121 -> zc++ |         txt.print_ub(zb<<shift) | ||||||
|             120 -> zc++ |         txt.nl() | ||||||
|             else -> zc++ |         txt.print_ub(zb>>shift) | ||||||
|         } |         txt.nl() | ||||||
|  |  | ||||||
|  |         word szc = -12345 | ||||||
|  |         byte szb = -123 | ||||||
|  |         txt.print_w(szc<<shift) | ||||||
|  |         txt.nl() | ||||||
|  |         txt.print_w(szc>>shift) | ||||||
|  |         txt.nl() | ||||||
|  |         txt.print_b(szb<<shift) | ||||||
|  |         txt.nl() | ||||||
|  |         txt.print_b(szb>>shift) | ||||||
|  |         txt.nl() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ;        cx16.r1L = (zc<<shift) as ubyte | ||||||
|  | ;        txt.print_ub(cx16.r1L) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user