optimize /256 more, and fixed a unsigned byte word cast error

This commit is contained in:
Irmen de Jong 2024-01-07 00:01:00 +01:00
parent 7dd758a753
commit d85c347a6c
6 changed files with 103 additions and 55 deletions

View File

@ -2092,20 +2092,20 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
}
if(valueDt==DataType.UBYTE || valueDt==DataType.BOOL) {
if(valueDt in ByteDatatypes) {
when(target.register) {
RegisterOrPair.A,
RegisterOrPair.X,
RegisterOrPair.Y -> {
// 'cast' an ubyte value to a byte register; no cast needed at all
return assignExpressionToRegister(value, target.register, false)
return assignExpressionToRegister(value, target.register, valueDt in SignedDatatypes)
}
RegisterOrPair.AX,
RegisterOrPair.AY,
RegisterOrPair.XY,
in Cx16VirtualRegisters -> {
assignExpressionToRegister(value, RegisterOrPair.A, false)
assignRegisterByte(target, CpuRegister.A, false, true)
assignRegisterByte(target, CpuRegister.A, valueDt in SignedDatatypes, true)
return
}
else -> {}
@ -2124,7 +2124,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.XY,
in Cx16VirtualRegisters -> {
// 'cast' uword into a 16 bits register, just assign it
return assignExpressionToRegister(value, target.register!!, false)
return assignExpressionToRegister(value, target.register!!, targetDt in SignedDatatypes)
}
else -> {}
}

View File

@ -626,10 +626,25 @@ class ExpressionSimplifier(private val program: Program,
return expr.left
}
}
256.0 -> {
when(leftDt) {
DataType.UBYTE -> return NumericLiteral(DataType.UBYTE, 0.0, expr.position)
DataType.BYTE -> return null // is either 0 or -1 we cannot tell here
DataType.UWORD, DataType.WORD -> {
// just use: msb(value) as type
val msb = BuiltinFunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
return if(leftDt==DataType.WORD)
TypecastExpression(msb, DataType.BYTE, true, expr.position)
else
TypecastExpression(msb, DataType.UWORD, true, expr.position)
}
else -> return null
}
}
in powersOfTwo -> {
if (leftDt==DataType.UBYTE || leftDt==DataType.UWORD) {
// Unsigned number divided by a power of two => shift right
// Signed number can't simply be bitshifted in this case (due to rounding issues for negative values),
// Signed number can't simply be bitshifted in this case (due to rounding issues for negative values), TODO is this correct???
// so we leave that as is and let the code generator deal with it.
val numshifts = log2(cv).toInt()
return BinaryExpression(expr.left, ">>", NumericLiteral.optimalInteger(numshifts, expr.position), expr.position)
@ -791,8 +806,8 @@ class ExpressionSimplifier(private val program: Program,
}
DataType.UWORD -> {
if (amount >= 16) {
errors.warn("shift always results in 0", expr.position)
return NumericLiteral.optimalInteger(0, expr.position)
errors.err("useless to shift by more than 15 bits", expr.position)
return null
}
else if(amount==8) {
// shift right by 8 bits is just a byte operation: msb(X) as uword
@ -806,11 +821,20 @@ class ExpressionSimplifier(private val program: Program,
}
}
DataType.WORD -> {
// bit-shifting a signed value shouldn't be allowed by the compiler but here we go...
if (amount > 16) {
expr.right = NumericLiteral.optimalInteger(16, expr.right.position)
if (amount >= 16) {
errors.err("useless to shift by more than 15 bits", expr.position)
return null
}
else if(amount == 8) {
// shift right by 8 bits is just a byte operation: msb(X) as byte
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
return TypecastExpression(msb, DataType.BYTE, true, expr.position)
}
else if(amount > 8) {
// same as above but with residual shifts.
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
return TypecastExpression(BinaryExpression(msb, ">>", NumericLiteral.optimalInteger(amount - 8, expr.position), expr.position), DataType.BYTE, true, expr.position)
}
}
else -> {
}

View File

@ -679,6 +679,29 @@ main {
stmts.size shouldBe 3
}
test("ubyte to word casts") {
var src="""
main {
sub start() {
ubyte @shared bb = 255
cx16.r0s = (bb as byte) as word ; should result in -1 word value
cx16.r1s = (bb as word) ; should result in 255 word value
}
}"""
val result = compileText(C64Target(), true, src, writeAssembly = false)!!
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 4
val assign1tc = (stmts[2] as Assignment).value as TypecastExpression
val assign2tc = (stmts[3] as Assignment).value as TypecastExpression
assign1tc.type shouldBe DataType.WORD
assign2tc.type shouldBe DataType.WORD
assign2tc.expression shouldBe instanceOf<IdentifierReference>()
val assign1subtc = (assign1tc.expression as TypecastExpression)
assign1subtc.type shouldBe DataType.BYTE
assign1subtc.expression shouldBe instanceOf<IdentifierReference>()
}
test("add missing & to function arguments") {
val text="""
main {

View File

@ -1,6 +1,7 @@
TODO
====
...

View File

@ -1,3 +1,4 @@
%import textio
%import syslib
%import test_stack
%import conv
@ -29,7 +30,7 @@ main {
draw_lines_hiddenremoval()
; draw_lines()
anglex += 217
anglex += 317
angley -= 505
anglez += 452
@ -58,25 +59,10 @@ main {
cx16.GRAPH_put_next_char(c)
}
asmsub print_number_gfx(ubyte num @ A) clobbers(A,X,Y) {
%asm {{
jsr conv.ubyte2decimal
phx
pha
cpy #'0'
beq +
tya
jsr cx16.GRAPH_put_char
pla
jsr cx16.GRAPH_put_char
bra _ones
+ pla
cmp #'0'
beq _ones
jsr cx16.GRAPH_put_char
_ones pla
jmp cx16.GRAPH_put_char
}}
sub print_number_gfx(ubyte num) {
conv.str_ub(num)
for cx16.r9L in conv.string_out
cx16.GRAPH_put_next_char(cx16.r9L)
}
const uword screen_width = 320

View File

@ -1,42 +1,56 @@
%import textio
%import string
%import math
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
uword @shared uw = $3f2f
if uw & $0800
txt.print("ok1\n")
ubyte @shared bb = 255
txt.print_w((bb as byte) as word) ; should print -1 !
txt.nl()
txt.print_w((bb as word)) ; should print 255 !
txt.nl()
txt.nl()
if uw & 8
txt.print("ok2\n")
bb= 30
word @shared offset=1000
cx16.r2s = (math.sin8u(bb) as word) + offset ; 1213
txt.print_w(cx16.r2s)
txt.nl()
txt.nl()
if uw & $0800 ==0
txt.print("fail1\n")
; expected results:
; -96
; -96
; 947
; 947
if uw & $0800 !=0
txt.print("ok3\n")
word @shared wcosa = 1111
word @shared wsinb = -22
if uw & 8 ==0
txt.print("fail2\n")
txt.print_w(wcosa*wsinb / 256)
txt.nl()
txt.print_w((wcosa*wsinb) >>8)
txt.nl()
if uw & 8 !=0
txt.print("ok4\n")
word[] rotatedz = [-11111,-12222,-13333,-14444,-15555]
word @shared persp1 = 1000 + rotatedz[2]/256
txt.print_w(persp1)
txt.nl()
persp1 = 1000 + (rotatedz[2]>>8)
txt.print_w(persp1)
txt.nl()
; ubyte[3] cycle_reverseflags
;
; ubyte @shared flags=2
; bool @shared b1
; bool @shared b2
;
; cycle_reverseflags[1]= b1 and b2 ; flags & 2 != 0 as bool
if uw & $ff00 == $3f00
txt.print("ok5\n")
if uw & $ff00 != $3f00
txt.print("fail5\n")
if uw & $00ff == $002f
txt.print("ok6\n")
if uw & $00ff != $002f
txt.print("fail6\n")
}
}