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 !!!")
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)

View File

@ -25,9 +25,9 @@
}
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 {
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() {
const byte b1 = 20//7
const word w1 = 20//7
const float f1 = 20/7
const float c1 = 11.11
const float c2 = 22.22
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
}

View File

@ -826,6 +826,8 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
}
"msb" -> stackvmProg.instr(Opcode.MSB)
"lsb" -> stackvmProg.instr(Opcode.LSB)
"wrd" -> stackvmProg.instr(Opcode.B2WORD)
"wrdhi" -> stackvmProg.instr(Opcode.MSB2WORD)
"lsl" -> {
val arg = args.single()
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 }},
"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),
"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),
"rndw" to FunctionSignature(true, emptyList(), DataType.WORD),
"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)
}
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 {
// 1 arg, type = float or int, result type= same as argument type
if(args.size!=1)

View File

@ -278,11 +278,134 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
}
return expr
}
// todo: other cases where both operators are identical
return expr
} 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
}
}

View File

@ -561,6 +561,14 @@ flt(x)
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.
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)
1 ('true') if any of the values in the non-scalar (array or matrix) value x is 'true' (not zero), else 0 ('false')