mirror of
https://github.com/irmen/prog8.git
synced 2024-10-01 22:56:10 +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) {
|
when(target.register) {
|
||||||
RegisterOrPair.A,
|
RegisterOrPair.A,
|
||||||
RegisterOrPair.X,
|
RegisterOrPair.X,
|
||||||
RegisterOrPair.Y -> {
|
RegisterOrPair.Y -> {
|
||||||
// 'cast' an ubyte value to a byte register; no cast needed at all
|
// '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.AX,
|
||||||
RegisterOrPair.AY,
|
RegisterOrPair.AY,
|
||||||
RegisterOrPair.XY,
|
RegisterOrPair.XY,
|
||||||
in Cx16VirtualRegisters -> {
|
in Cx16VirtualRegisters -> {
|
||||||
assignExpressionToRegister(value, RegisterOrPair.A, false)
|
assignExpressionToRegister(value, RegisterOrPair.A, false)
|
||||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
assignRegisterByte(target, CpuRegister.A, valueDt in SignedDatatypes, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
@ -2124,7 +2124,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
RegisterOrPair.XY,
|
RegisterOrPair.XY,
|
||||||
in Cx16VirtualRegisters -> {
|
in Cx16VirtualRegisters -> {
|
||||||
// 'cast' uword into a 16 bits register, just assign it
|
// '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 -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
@ -626,10 +626,25 @@ class ExpressionSimplifier(private val program: Program,
|
|||||||
return expr.left
|
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 -> {
|
in powersOfTwo -> {
|
||||||
if (leftDt==DataType.UBYTE || leftDt==DataType.UWORD) {
|
if (leftDt==DataType.UBYTE || leftDt==DataType.UWORD) {
|
||||||
// Unsigned number divided by a power of two => shift right
|
// 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.
|
// so we leave that as is and let the code generator deal with it.
|
||||||
val numshifts = log2(cv).toInt()
|
val numshifts = log2(cv).toInt()
|
||||||
return BinaryExpression(expr.left, ">>", NumericLiteral.optimalInteger(numshifts, expr.position), expr.position)
|
return BinaryExpression(expr.left, ">>", NumericLiteral.optimalInteger(numshifts, expr.position), expr.position)
|
||||||
@ -791,8 +806,8 @@ class ExpressionSimplifier(private val program: Program,
|
|||||||
}
|
}
|
||||||
DataType.UWORD -> {
|
DataType.UWORD -> {
|
||||||
if (amount >= 16) {
|
if (amount >= 16) {
|
||||||
errors.warn("shift always results in 0", expr.position)
|
errors.err("useless to shift by more than 15 bits", expr.position)
|
||||||
return NumericLiteral.optimalInteger(0, expr.position)
|
return null
|
||||||
}
|
}
|
||||||
else if(amount==8) {
|
else if(amount==8) {
|
||||||
// shift right by 8 bits is just a byte operation: msb(X) as uword
|
// 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 -> {
|
DataType.WORD -> {
|
||||||
// bit-shifting a signed value shouldn't be allowed by the compiler but here we go...
|
if (amount >= 16) {
|
||||||
if (amount > 16) {
|
errors.err("useless to shift by more than 15 bits", expr.position)
|
||||||
expr.right = NumericLiteral.optimalInteger(16, expr.right.position)
|
|
||||||
return null
|
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 -> {
|
else -> {
|
||||||
}
|
}
|
||||||
|
@ -679,6 +679,29 @@ main {
|
|||||||
stmts.size shouldBe 3
|
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") {
|
test("add missing & to function arguments") {
|
||||||
val text="""
|
val text="""
|
||||||
main {
|
main {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
%import textio
|
||||||
%import syslib
|
%import syslib
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%import conv
|
%import conv
|
||||||
@ -29,7 +30,7 @@ main {
|
|||||||
draw_lines_hiddenremoval()
|
draw_lines_hiddenremoval()
|
||||||
; draw_lines()
|
; draw_lines()
|
||||||
|
|
||||||
anglex += 217
|
anglex += 317
|
||||||
angley -= 505
|
angley -= 505
|
||||||
anglez += 452
|
anglez += 452
|
||||||
|
|
||||||
@ -58,25 +59,10 @@ main {
|
|||||||
cx16.GRAPH_put_next_char(c)
|
cx16.GRAPH_put_next_char(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub print_number_gfx(ubyte num @ A) clobbers(A,X,Y) {
|
sub print_number_gfx(ubyte num) {
|
||||||
%asm {{
|
conv.str_ub(num)
|
||||||
jsr conv.ubyte2decimal
|
for cx16.r9L in conv.string_out
|
||||||
phx
|
cx16.GRAPH_put_next_char(cx16.r9L)
|
||||||
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
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uword screen_width = 320
|
const uword screen_width = 320
|
||||||
|
@ -1,42 +1,56 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import string
|
%import math
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword @shared uw = $3f2f
|
|
||||||
|
|
||||||
if uw & $0800
|
ubyte @shared bb = 255
|
||||||
txt.print("ok1\n")
|
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
|
bb= 30
|
||||||
txt.print("ok2\n")
|
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
|
; expected results:
|
||||||
txt.print("fail1\n")
|
; -96
|
||||||
|
; -96
|
||||||
|
; 947
|
||||||
|
; 947
|
||||||
|
|
||||||
if uw & $0800 !=0
|
word @shared wcosa = 1111
|
||||||
txt.print("ok3\n")
|
word @shared wsinb = -22
|
||||||
|
|
||||||
if uw & 8 ==0
|
txt.print_w(wcosa*wsinb / 256)
|
||||||
txt.print("fail2\n")
|
txt.nl()
|
||||||
|
txt.print_w((wcosa*wsinb) >>8)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
if uw & 8 !=0
|
word[] rotatedz = [-11111,-12222,-13333,-14444,-15555]
|
||||||
txt.print("ok4\n")
|
|
||||||
|
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…
Reference in New Issue
Block a user