wrd and wrdhi functions added for byte-word conversion, more constant folding optimizations

This commit is contained in:
Irmen de Jong 2018-10-06 00:10:30 +02:00
parent d13ced6d95
commit a7abc32368
7 changed files with 174 additions and 15 deletions

View File

@ -39,7 +39,7 @@
_vm_gfx_text(14, 5, 5, "Spin to Win !!!") _vm_gfx_text(14, 5, 5, "Spin to Win !!!")
for i in 0 to width//10 { for i in 0 to width//10 {
_vm_gfx_line(i*2+width//2-width//10, 130, i*10, 199, 6) _vm_gfx_line(i*2+width//2-width//10, 130, i*10.w, 199, 6)
} }
rotate_vertices(flt(irq.global_time) / 30.0) rotate_vertices(flt(irq.global_time) / 30.0)

View File

@ -25,9 +25,9 @@
} }
sub screenx(x: float) -> word { sub screenx(x: float) -> word {
return floor(x * flt(width)/4.1) + width // 2 ; @todo const-fold x*y/z return floor(x * flt(width)/4.1) + width // 2
} }
sub screeny(y: float) -> word { sub screeny(y: float) -> word {
return floor(y * flt(height)/4.1) + height // 2 ; @todo const-fold x*y/z return floor(y * flt(height)/4.1) + height // 2
} }
} }

View File

@ -6,16 +6,18 @@
sub start() { sub start() {
const byte b1 = 20//7 const float c1 = 11.11
const word w1 = 20//7 const float c2 = 22.22
const float f1 = 20/7 float v
float r
byte x
word w
r=flt(x)
w=wrd(x)
w=wrdhi(x)
_vm_write_num(b1)
_vm_write_char('\n')
_vm_write_num(w1)
_vm_write_char('\n')
_vm_write_num(f1)
_vm_write_char('\n')
return return
} }

View File

@ -826,6 +826,8 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
} }
"msb" -> stackvmProg.instr(Opcode.MSB) "msb" -> stackvmProg.instr(Opcode.MSB)
"lsb" -> stackvmProg.instr(Opcode.LSB) "lsb" -> stackvmProg.instr(Opcode.LSB)
"wrd" -> stackvmProg.instr(Opcode.B2WORD)
"wrdhi" -> stackvmProg.instr(Opcode.MSB2WORD)
"lsl" -> { "lsl" -> {
val arg = args.single() val arg = args.single()
when (arg.resultingDatatype(namespace, heap)) { when (arg.resultingDatatype(namespace, heap)) {

View File

@ -47,6 +47,8 @@ val BuiltinFunctions = mapOf(
"lsb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }}, "lsb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
"msb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}}, "msb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE, DataType.WORD))), DataType.FLOAT, ::builtinFlt), "flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE, DataType.WORD))), DataType.FLOAT, ::builtinFlt),
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.WORD, ::builtinWrd),
"wrdhi" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.WORD, ::builtinWrdHi),
"rnd" to FunctionSignature(true, emptyList(), DataType.BYTE), "rnd" to FunctionSignature(true, emptyList(), DataType.BYTE),
"rndw" to FunctionSignature(true, emptyList(), DataType.WORD), "rndw" to FunctionSignature(true, emptyList(), DataType.WORD),
"rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT), "rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT),
@ -266,6 +268,28 @@ private fun builtinFlt(args: List<IExpression>, position: Position, namespace:IN
return LiteralValue(DataType.FLOAT, floatvalue = number.toDouble(), position = position) return LiteralValue(DataType.FLOAT, floatvalue = number.toDouble(), position = position)
} }
private fun builtinWrd(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
// 1 byte arg, convert to word
if(args.size!=1)
throw SyntaxError("wrd requires one numeric argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
if(constval.type!=DataType.BYTE)
throw SyntaxError("wrd requires one byte argument", position)
return LiteralValue(DataType.WORD, wordvalue = constval.bytevalue!!.toInt(), position = position)
}
private fun builtinWrdHi(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
// 1 byte arg, convert to word (in hi byte)
if(args.size!=1)
throw SyntaxError("wrdhi requires one numeric argument", position)
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
if(constval.type!=DataType.BYTE)
throw SyntaxError("wrdhi requires one byte argument", position)
return LiteralValue(DataType.WORD, wordvalue = constval.bytevalue!!.toInt() shl 8, position = position)
}
private fun builtinAbs(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue { private fun builtinAbs(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
// 1 arg, type = float or int, result type= same as argument type // 1 arg, type = float or int, result type= same as argument type
if(args.size!=1) if(args.size!=1)

View File

@ -278,11 +278,134 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
} }
return expr return expr
} }
// todo: other cases where both operators are identical
return expr return expr
} else { } else {
// todo: other combinations of operators and constants (with different operator in subexpr)
if(expr.operator=="/" && subExpr.operator=="*") {
optimizationsDone++
if(leftIsConst) {
return if(subleftIsConst) {
// C1/(C2*V) -> (C1/C2)/V
BinaryExpression(
BinaryExpression(expr.left, "/", subExpr.left, subExpr.position),
"/",
subExpr.right, expr.position)
} else {
// C1/(V*C2) -> (C1/C2)/V
BinaryExpression(
BinaryExpression(expr.left, "/", subExpr.right, subExpr.position),
"/",
subExpr.left, expr.position)
}
} else {
return if(subleftIsConst) {
// (C1*V)/C2 -> (C1/C2)*V
BinaryExpression(
BinaryExpression(subExpr.left, "/", expr.right, subExpr.position),
"*",
subExpr.right, expr.position)
} else {
// (V*C1)/C2 -> (C1/C2)*V
BinaryExpression(
BinaryExpression(subExpr.right, "/", expr.right, subExpr.position),
"*",
subExpr.left, expr.position)
}
}
} else if(expr.operator=="*" && subExpr.operator=="/") {
optimizationsDone++
if(leftIsConst) {
return if(subleftIsConst) {
// C1*(C2/V) -> (C1*C2)/V
BinaryExpression(
BinaryExpression(expr.left, "*", subExpr.left, subExpr.position),
"/",
subExpr.right, expr.position)
} else {
// C1*(V/C2) -> (C1/C2)*V
BinaryExpression(
BinaryExpression(expr.left, "/", subExpr.right, subExpr.position),
"*",
subExpr.left, expr.position)
}
} else {
return if(subleftIsConst) {
// (C1/V)*C2 -> (C1*C2)/V
BinaryExpression(
BinaryExpression(subExpr.left, "*", expr.right, subExpr.position),
"/",
subExpr.right, expr.position)
} else {
// (V/C1)*C2 -> (C2/C1)*V
BinaryExpression(
BinaryExpression(subExpr.right, "/", expr.right, subExpr.position),
"*",
subExpr.left, expr.position)
}
}
} else if(expr.operator=="+" && subExpr.operator=="-") {
if(leftIsConst){
return if(subleftIsConst){
// c1+(c2-v) -> (c1+c2)-v
BinaryExpression(
BinaryExpression(expr.left, "+", subExpr.left, subExpr.position),
"-",
subExpr.right, expr.position)
} else {
// c1+(v-c2) -> v+(c1-c2)
BinaryExpression(
BinaryExpression(expr.left, "-", subExpr.right, subExpr.position),
"+",
subExpr.left, expr.position)
}
} else {
return if(subleftIsConst) {
// (c1-v)+c2 -> (c1+c2)-v
BinaryExpression(
BinaryExpression(subExpr.left, "+", expr.right, subExpr.position),
"-",
subExpr.right, expr.position)
} else {
// (v-c1)+c2 -> v+(c2-c1)
BinaryExpression(
BinaryExpression(expr.right, "-", subExpr.right, subExpr.position),
"+",
subExpr.left, expr.position)
}
}
} else if(expr.operator=="-" && subExpr.operator=="+") {
if(leftIsConst) {
return if(subleftIsConst) {
// c1-(c2+v) -> (c1-c2)-v
BinaryExpression(
BinaryExpression(expr.left, "-", subExpr.left, subExpr.position),
"-",
subExpr.right, expr.position)
} else {
// c1-(v+c2) -> (c1-c2)-v
BinaryExpression(
BinaryExpression(expr.left, "-", subExpr.right, subExpr.position),
"-",
subExpr.left, expr.position)
}
} else {
return if(subleftIsConst) {
// (c1+v)-c2 -> v+(c1-c2)
BinaryExpression(
BinaryExpression(subExpr.left, "-", expr.right, subExpr.position),
"+",
subExpr.right, expr.position)
} else {
// (v+c1)-c2 -> v+(c1-c2)
BinaryExpression(
BinaryExpression(subExpr.right, "-", expr.right, subExpr.position),
"+",
subExpr.left, expr.position)
}
}
}
return expr return expr
} }
} }

View File

@ -561,6 +561,14 @@ flt(x)
Explicitly convert the number x to a floating point number. Explicitly convert the number x to a floating point number.
This is required if you want calculations to have floating point precision when the values aren't float already. This is required if you want calculations to have floating point precision when the values aren't float already.
wrd(x)
Explicitly convert the byte x to a word.
This is required if you want calculations to have word precision when the values are bytes.
wrdhi(x)
Explicitly convert the byte x to a word, where x will be the high byte (msb) in the word.
This can be useful in calculations with word precision when the values are bytes.
any(x) any(x)
1 ('true') if any of the values in the non-scalar (array or matrix) value x is 'true' (not zero), else 0 ('false') 1 ('true') if any of the values in the non-scalar (array or matrix) value x is 'true' (not zero), else 0 ('false')