fix VM indexed instructions to only use lsb part of the index

This commit is contained in:
Irmen de Jong 2023-09-06 02:44:04 +02:00
parent 0bbbb12ed2
commit bde4be8231
4 changed files with 15 additions and 16 deletions

View File

@ -549,6 +549,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcLsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
return exprGen.translateExpression(call.args.single())
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
// TODO to be more strict, maybe we *should* introduce a new result register that is of type .b?
}
private fun funcMsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {

View File

@ -1,8 +1,6 @@
TODO
====
- fix ir/vm when running bench8/sieve-bit, it produces wrong result
- prefix prog8 subroutines with p8s_ instead of p8_ to not let them clash with variables in the asm??
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction

View File

@ -37,16 +37,16 @@ All have type b or w or f.
load reg1, value - load immediate value into register. If you supply a symbol, loads the *address* of the symbol! (variable values are loaded from memory via the loadm instruction)
loadm reg1, address - load reg1 with value at memory address
loadi reg1, reg2 - load reg1 with value at memory indirect, memory pointed to by reg2
loadx reg1, reg2, address - load reg1 with value at memory address indexed by value in reg2
loadix reg1, reg2, pointeraddr - load reg1 with value at memory indirect, pointed to by pointeraddr indexed by value in reg2
loadx reg1, reg2, address - load reg1 with value at memory address indexed by value in reg2 (only the lsb part used for indexing)
loadix reg1, reg2, pointeraddr - load reg1 with value at memory indirect, pointed to by pointeraddr indexed by value in reg2 (only the lsb part used for indexing)
loadr reg1, reg2 - load reg1 with value in register reg2
storem reg1, address - store reg1 at memory address
storei reg1, reg2 - store reg1 at memory indirect, memory pointed to by reg2
storex reg1, reg2, address - store reg1 at memory address, indexed by value in reg2
storeix reg1, reg2, pointeraddr - store reg1 at memory indirect, pointed to by pointeraddr indexed by value in reg2
storex reg1, reg2, address - store reg1 at memory address, indexed by value in reg2 (only the lsb part used for indexing)
storeix reg1, reg2, pointeraddr - store reg1 at memory indirect, pointed to by pointeraddr indexed by value in reg2 (only the lsb part used for indexing)
storezm address - store zero at memory address
storezi reg1 - store zero at memory pointed to by reg1
storezx reg1, address - store zero at memory address, indexed by value in reg
storezx reg1, address - store zero at memory address, indexed by value in reg1 (only the lsb part used for indexing)
CONTROL FLOW

View File

@ -435,18 +435,18 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsLOADX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> {
val value = memory.getUB(i.address!! + registers.getUW(i.reg2!!).toInt())
val value = memory.getUB(i.address!! + registers.getUB(i.reg2!!).toInt())
registers.setUB(i.reg1!!, value)
statusZero = value==0.toUByte()
statusNegative = value>=0x80u
}
IRDataType.WORD -> {
val value = memory.getUW(i.address!! + registers.getUW(i.reg2!!).toInt())
val value = memory.getUW(i.address!! + registers.getUB(i.reg2!!).toInt())
registers.setUW(i.reg1!!, value)
statusZero = value== 0.toUShort()
statusNegative = value>=0x8000u
}
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!! + registers.getUW(i.reg1!!).toInt()))
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!! + registers.getUB(i.reg1!!).toInt()))
}
nextPc()
}
@ -514,9 +514,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSTOREX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt() + i.address!!, registers.getUB(i.reg1!!))
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt() + i.address!!, registers.getUW(i.reg1!!))
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.address!!, registers.getFloat(i.fpReg1!!))
IRDataType.BYTE -> memory.setUB(i.address!! + registers.getUB(i.reg2!!).toInt(), registers.getUB(i.reg1!!))
IRDataType.WORD -> memory.setUW(i.address!! + registers.getUB(i.reg2!!).toInt(), registers.getUW(i.reg1!!))
IRDataType.FLOAT -> memory.setFloat(i.address!! + registers.getUB(i.reg1!!).toInt(), registers.getFloat(i.fpReg1!!))
}
nextPc()
}
@ -559,9 +559,9 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSTOREZX(i: IRInstruction) {
when (i.type!!) {
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt() + i.address!!, 0u)
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt() + i.address!!, 0u)
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.address!!, 0f)
IRDataType.BYTE -> memory.setUB(i.address!! + registers.getUB(i.reg1!!).toInt(), 0u)
IRDataType.WORD -> memory.setUW(i.address!! + registers.getUB(i.reg1!!).toInt(), 0u)
IRDataType.FLOAT -> memory.setFloat(i.address!! + registers.getUB(i.reg1!!).toInt(), 0f)
}
nextPc()
}