mirror of
https://github.com/irmen/prog8.git
synced 2026-04-20 11:17:01 +00:00
added sys.waitrasterline() routine like sys.waitvsync() but wait for a given raster line
optimize uword <= $xx00 into msb(uword)<$xx
This commit is contained in:
@@ -427,13 +427,18 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
|
||||
}
|
||||
}
|
||||
|
||||
fun isPowerOfTwo(number: Double): Boolean {
|
||||
// fun isPowerOfTwo(number: Double): Boolean {
|
||||
// val intValue = number.toInt()
|
||||
// return intValue > 0 && (intValue and (intValue - 1)) == 0
|
||||
// }
|
||||
|
||||
fun isFactorOf256(number: Double): Boolean {
|
||||
val intValue = number.toInt()
|
||||
return intValue > 0 && (intValue and (intValue - 1)) == 0
|
||||
return intValue > 0 && (intValue and (intValue shl 8)) == 0
|
||||
}
|
||||
|
||||
if (leftDt.isUnsignedWord && rightVal!=null) {
|
||||
if ((rightVal.number == 255.0 && expr.operator == ">") || (rightVal.number == 256.0 && expr.operator == ">=")) {
|
||||
if (expr.operator == ">" && rightVal.number == 255.0 || expr.operator == ">=" && rightVal.number == 256.0) {
|
||||
// uword > 255 --> msb(value)!=0
|
||||
// uword >= 256 --> msb(value)!=0
|
||||
expr.operator = "!="
|
||||
@@ -441,27 +446,54 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
|
||||
expr.right = NumericLiteral(BaseDataType.UBYTE, 0.0, expr.right.position)
|
||||
expr.linkParents(parent)
|
||||
}
|
||||
else if(expr.operator==">=" && rightVal.number >= 256.0 && isPowerOfTwo(rightVal.number)) {
|
||||
val msbFraction = floor(rightVal.number / 256.0)
|
||||
else if(expr.operator==">=" && isFactorOf256(rightVal.number)) {
|
||||
// uword >= $xx00 --> msb(value)>=xx
|
||||
val msbFraction = floor(rightVal.number / 256.0)
|
||||
expr.operator = ">="
|
||||
expr.left = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.left.position), mutableListOf(expr.left), expr.left.position)
|
||||
expr.right = NumericLiteral(BaseDataType.UBYTE, msbFraction, expr.right.position)
|
||||
expr.linkParents(parent)
|
||||
}
|
||||
else if(expr.operator==">" && rightVal.number >= 255.0 && isPowerOfTwo(rightVal.number+1)) {
|
||||
val msbFraction = floor((rightVal.number+1) / 256.0)
|
||||
// uword > $xxFF --> msb(value)>=xx
|
||||
expr.operator = ">="
|
||||
else if(expr.operator==">" && isFactorOf256(rightVal.number+1)) {
|
||||
// uword > $xxFF --> msb(value)>xx
|
||||
val msbFraction = floor((rightVal.number) / 256.0)
|
||||
expr.operator = ">"
|
||||
expr.left = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.left.position), mutableListOf(expr.left), expr.left.position)
|
||||
expr.right = NumericLiteral(BaseDataType.UBYTE, msbFraction, expr.right.position)
|
||||
expr.linkParents(parent)
|
||||
}
|
||||
else if(expr.operator == "<" && rightVal.number == 256.0 || expr.operator == "<=" && rightVal.number == 255.0) {
|
||||
// uword < 256 --> msb(value)==0
|
||||
// uword <= 255 --> msb(value)==0
|
||||
// OK!
|
||||
expr.operator = "=="
|
||||
expr.left = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.left.position), mutableListOf(expr.left), expr.left.position)
|
||||
expr.right = NumericLiteral(BaseDataType.UBYTE, 0.0, expr.right.position)
|
||||
expr.linkParents(parent)
|
||||
}
|
||||
else if(expr.operator == "<" && isFactorOf256(rightVal.number)) {
|
||||
// uword < $xx00 --> msb(value)<xx
|
||||
val msbFraction = floor(rightVal.number / 256.0)
|
||||
expr.operator = "<"
|
||||
expr.left = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.left.position), mutableListOf(expr.left), expr.left.position)
|
||||
expr.right = NumericLiteral(BaseDataType.UBYTE, msbFraction, expr.right.position)
|
||||
expr.linkParents(parent)
|
||||
}
|
||||
else if(expr.operator=="<=" && isFactorOf256(rightVal.number+1)) {
|
||||
// uword <= $xxFF --> msb(value)<=xx
|
||||
val msbFraction = floor((rightVal.number) / 256.0)
|
||||
expr.operator = "<="
|
||||
expr.left = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.left.position), mutableListOf(expr.left), expr.left.position)
|
||||
expr.right = NumericLiteral(BaseDataType.UBYTE, msbFraction, expr.right.position)
|
||||
expr.linkParents(parent)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
|
||||
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||
if(arrayIndexedExpression.indexer.constIndex()==0) {
|
||||
if(arrayIndexedExpression.plainarrayvar!=null) {
|
||||
|
||||
@@ -704,6 +704,26 @@ _loop lda P8ZP_SCRATCH_W1
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub waitrasterline(uword line @AY) {
|
||||
; -- CPU busy wait until the given raster line is reached
|
||||
%asm {{
|
||||
cpy #0
|
||||
bne _larger
|
||||
- cmp c64.RASTER
|
||||
bne -
|
||||
bit c64.SCROLY
|
||||
bmi -
|
||||
rts
|
||||
_larger
|
||||
cmp c64.RASTER
|
||||
bne _larger
|
||||
bit c64.SCROLY
|
||||
bpl _larger
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
asmsub internal_stringcopy(str source @R0, str target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
|
||||
@@ -713,6 +713,26 @@ _loop lda P8ZP_SCRATCH_W1
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub waitrasterline(uword line @AY) {
|
||||
; -- CPU busy wait until the given raster line is reached
|
||||
%asm {{
|
||||
cpy #0
|
||||
bne _larger
|
||||
- cmp c64.RASTER
|
||||
bne -
|
||||
bit c64.SCROLY
|
||||
bmi -
|
||||
rts
|
||||
_larger
|
||||
cmp c64.RASTER
|
||||
bne _larger
|
||||
bit c64.SCROLY
|
||||
bpl _larger
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
asmsub internal_stringcopy(str source @R0, str target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
|
||||
@@ -1781,6 +1781,26 @@ _loop lda P8ZP_SCRATCH_W1
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub waitrasterline(uword line @AY) {
|
||||
; -- CPU busy wait until the given raster line is reached
|
||||
%asm {{
|
||||
cpy #0
|
||||
bne _larger
|
||||
- cmp cx16.VERA_SCANLINE_L
|
||||
bne -
|
||||
bit cx16.VERA_IEN
|
||||
bvs -
|
||||
rts
|
||||
_larger
|
||||
cmp cx16.VERA_SCANLINE_L
|
||||
bne _larger
|
||||
bit cx16.VERA_IEN
|
||||
bvc _larger
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
asmsub internal_stringcopy(str source @R0, str target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
|
||||
@@ -19,18 +19,18 @@ Structs and Pointers
|
||||
if it is a pointer to a struct type.
|
||||
The compiler tries its best to give a descriptive error message but sometimes there is still a
|
||||
parser limitation that has to be worked around at the moment. For example, this pointer arithmetic
|
||||
indexing syntax is not supported right now and will result in a parse error::
|
||||
indexing syntax is not supported right now *to assign to* and will result in a parse error (note that
|
||||
using it as an expression value does work correctly)::
|
||||
|
||||
^^Node np
|
||||
np[2].field = 9999
|
||||
np[2].field = 9999 ; cannot assign to this yet
|
||||
ubyte value = np[2].field ; this does work though.
|
||||
|
||||
To work around this (and similar) cases you'll have to break up the expression in multiple steps,
|
||||
in this case something like::
|
||||
|
||||
^^Node thirdnode = &&np[2]
|
||||
thirdnode.field = 9999
|
||||
|
||||
*Note: this example is not regular array indexing syntax, it's pointer arithmetic by indexing on the pointer itself. Regular array syntax is supported just fine for arrays containing pointers etc.*
|
||||
^^Node thenode = &&np[2]
|
||||
thenode.field = 9999
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ Libraries
|
||||
Optimizations
|
||||
-------------
|
||||
|
||||
- while c64.RASTER!=lsb(line) or c64.SCROLY&$80==0 { } generates code that really wants to use 1/0 boolean values as intermediates. why? can't that be optimized away? I want it to use th BIT instruction on the msb even
|
||||
- check that expressions such as targetvar = value1 + value2 , targetvar = value1 ^ value2 etc. use the target variable directly and not use needless temp var / registers
|
||||
- Port benchmarks from https://thred.github.io/c-bench-64/ to prog8 and see how it stacks up.
|
||||
- Since fixing the missing zp-var initialization, programs grew in size again because STZ's reappeared. Can we add more intelligent (and correct!) optimizations to remove those STZs that might be redundant again?
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ org.gradle.console=rich
|
||||
org.gradle.parallel=true
|
||||
org.gradle.daemon=true
|
||||
kotlin.code.style=official
|
||||
version=12.0-BETA2
|
||||
version=12.0-BETA3
|
||||
|
||||
Reference in New Issue
Block a user