mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
optimize /256 more, and fixed a unsigned byte word cast error
This commit is contained in:
parent
7dd758a753
commit
d85c347a6c
@ -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 -> {}
|
||||
}
|
||||
|
@ -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 -> {
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -1,6 +1,7 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user