added immediate value vm logical instructions because these are so common

This commit is contained in:
Irmen de Jong 2022-07-12 15:54:35 +02:00
parent 314398ba4c
commit ff1fc28287
6 changed files with 92 additions and 46 deletions

View File

@ -111,21 +111,21 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister) code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
} }
DataType.BYTE -> { DataType.BYTE -> {
val andReg = codeGen.vmRegisters.nextFree()
val notNegativeLabel = codeGen.createLabelName() val notNegativeLabel = codeGen.createLabelName()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=andReg, value=0x80) val compareReg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=andReg, reg2=resultRegister) code += VmCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=compareReg, reg2=resultRegister)
code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=andReg, labelSymbol = notNegativeLabel) code += VmCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=compareReg, value=0x80)
code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
code += VmCodeInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister) code += VmCodeInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister)
code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister) code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
code += VmCodeLabel(notNegativeLabel) code += VmCodeLabel(notNegativeLabel)
} }
DataType.WORD -> { DataType.WORD -> {
val andReg = codeGen.vmRegisters.nextFree()
val notNegativeLabel = codeGen.createLabelName() val notNegativeLabel = codeGen.createLabelName()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=andReg, value=0x8000) val compareReg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=andReg, reg2=resultRegister) code += VmCodeInstruction(Opcode.LOADR, VmDataType.WORD, reg1=compareReg, reg2=resultRegister)
code += VmCodeInstruction(Opcode.BZ, VmDataType.WORD, reg1=andReg, labelSymbol = notNegativeLabel) code += VmCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=compareReg, value=0x8000)
code += VmCodeInstruction(Opcode.BZ, VmDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
code += VmCodeInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister) code += VmCodeInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister)
code += VmCodeLabel(notNegativeLabel) code += VmCodeLabel(notNegativeLabel)
} }

View File

@ -149,10 +149,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += VmCodeInstruction(Opcode.NEG, vmDt, reg1=resultRegister) code += VmCodeInstruction(Opcode.NEG, vmDt, reg1=resultRegister)
} }
"~" -> { "~" -> {
val regMask = codeGen.vmRegisters.nextFree()
val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=regMask, value=mask) code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, value=mask)
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=regMask)
} }
else -> throw AssemblyError("weird prefix operator") else -> throw AssemblyError("weird prefix operator")
} }
@ -390,9 +388,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
code += translate(comparisonCall, resultRegister, -1) code += translate(comparisonCall, resultRegister, -1)
if(!notEquals) if(!notEquals)
code += VmCodeInstruction(Opcode.INV, vmDt, reg1=resultRegister) code += VmCodeInstruction(Opcode.INV, vmDt, reg1=resultRegister)
val maskReg = codeGen.vmRegisters.nextFree() code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, value=1)
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=maskReg, value=1)
code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, reg2=maskReg)
} else { } else {
val rightResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.left, resultRegister, -1)
@ -462,10 +458,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
private fun operatorXor(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { private fun operatorXor(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
val rightResultReg = codeGen.vmRegisters.nextFree() if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=rightResultReg) } else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.XORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code return code
} }
@ -479,10 +480,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
val rightResultReg = codeGen.vmRegisters.nextFree() if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, reg2=rightResultReg) } else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.ANDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code return code
} }
@ -496,10 +502,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
private fun operatorOr(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { private fun operatorOr(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
val rightResultReg = codeGen.vmRegisters.nextFree() if(binExpr.right is PtNumber) {
code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.OR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
code += VmCodeInstruction(Opcode.OR, vmDt, reg1=resultRegister, reg2=rightResultReg) } else {
val rightResultReg = codeGen.vmRegisters.nextFree()
code += translateExpression(binExpr.left, resultRegister, -1)
code += translateExpression(binExpr.right, rightResultReg, -1)
code += VmCodeInstruction(Opcode.ORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
}
return code return code
} }

View File

@ -3,7 +3,8 @@ TODO
For next release For next release
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
- vm: add logical instructions taking immediate value as well - fix compiler crash (abs(fl)) ; WHY IS THIS GETTING A BOOLEAN CAST???
- vm why is bb = bb2 and true generating so large code?
... ...

View File

@ -1,18 +1,13 @@
%import textio %import textio
%import floats
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
bool @shared zz float fl
ubyte xx fl = -3.14
ubyte yy floats.print_f(abs(fl)) ; WHY IS THIS GETTING A BOOLEAN CAST???
txt.nl()
while xx<42 {
xx = yy+99
xx = yy*5
}
txt.print_ub(xx)
} }
} }

View File

@ -126,9 +126,12 @@ LOGICAL/BITWISE
--------------- ---------------
All have type b or w. All have type b or w.
and reg1, reg2 - reg1 = reg1 bitwise and reg2 andr reg1, reg2 - reg1 = reg1 bitwise and reg2
or reg1, reg2 - reg1 = reg1 bitwise or reg2 and reg1, value - reg1 = reg1 bitwise and value
xor reg1, reg2 - reg1 = reg1 bitwise xor reg2 orr reg1, reg2 - reg1 = reg1 bitwise or reg2
or reg1, value - reg1 = reg1 bitwise or value
xorr reg1, reg2 - reg1 = reg1 bitwise xor reg2
xor reg1, value - reg1 = reg1 bitwise xor value
inv reg1 - reg1 = bitwise invert of reg1 (all bits flipped) inv reg1 - reg1 = bitwise invert of reg1 (all bits flipped)
lsrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits + set Carry to shifted bit lsrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits + set Carry to shifted bit
asrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits (signed) + set Carry to shifted bit asrn reg1, reg2 - reg1 = multi-shift reg1 right by reg2 bits (signed) + set Carry to shifted bit
@ -265,10 +268,13 @@ enum class Opcode {
EXT, EXT,
EXTS, EXTS,
ANDR,
AND, AND,
ANDM, ANDM,
ORR,
OR, OR,
ORM, ORM,
XORR,
XOR, XOR,
XORM, XORM,
INV, INV,
@ -567,11 +573,14 @@ val instructionFormats = mutableMapOf(
Opcode.CMP to InstructionFormat.from("BW,r1,r2"), Opcode.CMP to InstructionFormat.from("BW,r1,r2"),
Opcode.EXT to InstructionFormat.from("BW,r1"), Opcode.EXT to InstructionFormat.from("BW,r1"),
Opcode.EXTS to InstructionFormat.from("BW,r1"), Opcode.EXTS to InstructionFormat.from("BW,r1"),
Opcode.AND to InstructionFormat.from("BW,r1,r2"), Opcode.ANDR to InstructionFormat.from("BW,r1,r2"),
Opcode.AND to InstructionFormat.from("BW,r1,v"),
Opcode.ANDM to InstructionFormat.from("BW,r1,v"), Opcode.ANDM to InstructionFormat.from("BW,r1,v"),
Opcode.OR to InstructionFormat.from("BW,r1,r2"), Opcode.ORR to InstructionFormat.from("BW,r1,r2"),
Opcode.OR to InstructionFormat.from("BW,r1,v"),
Opcode.ORM to InstructionFormat.from("BW,r1,v"), Opcode.ORM to InstructionFormat.from("BW,r1,v"),
Opcode.XOR to InstructionFormat.from("BW,r1,r2"), Opcode.XORR to InstructionFormat.from("BW,r1,r2"),
Opcode.XOR to InstructionFormat.from("BW,r1,v"),
Opcode.XORM to InstructionFormat.from("BW,r1,v"), Opcode.XORM to InstructionFormat.from("BW,r1,v"),
Opcode.INV to InstructionFormat.from("BW,r1"), Opcode.INV to InstructionFormat.from("BW,r1"),
Opcode.INVM to InstructionFormat.from("BW,v"), Opcode.INVM to InstructionFormat.from("BW,v"),

View File

@ -163,10 +163,13 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
Opcode.SQRT -> InsSQRT(ins) Opcode.SQRT -> InsSQRT(ins)
Opcode.EXT -> InsEXT(ins) Opcode.EXT -> InsEXT(ins)
Opcode.EXTS -> InsEXTS(ins) Opcode.EXTS -> InsEXTS(ins)
Opcode.ANDR -> InsANDR(ins)
Opcode.AND -> InsAND(ins) Opcode.AND -> InsAND(ins)
Opcode.ANDM -> InsANDM(ins) Opcode.ANDM -> InsANDM(ins)
Opcode.ORR -> InsORR(ins)
Opcode.OR -> InsOR(ins) Opcode.OR -> InsOR(ins)
Opcode.ORM -> InsORM(ins) Opcode.ORM -> InsORM(ins)
Opcode.XORR -> InsXORR(ins)
Opcode.XOR -> InsXOR(ins) Opcode.XOR -> InsXOR(ins)
Opcode.XORM ->InsXORM(ins) Opcode.XORM ->InsXORM(ins)
Opcode.INV -> InsINV(ins) Opcode.INV -> InsINV(ins)
@ -1295,7 +1298,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++ pc++
} }
private fun InsAND(i: Instruction) { private fun InsANDR(i: Instruction) {
val (left: UInt, right: UInt) = getLogicalOperandsU(i) val (left: UInt, right: UInt) = getLogicalOperandsU(i)
when(i.type!!) { when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, (left and right).toUByte()) VmDataType.BYTE -> registers.setUB(i.reg1!!, (left and right).toUByte())
@ -1305,6 +1308,15 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++ pc++
} }
private fun InsAND(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1) and i.value!!.toUByte())
VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1) and i.value!!.toUShort())
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
pc++
}
private fun InsANDM(i: Instruction) { private fun InsANDM(i: Instruction) {
val address = i.value!! val address = i.value!!
when(i.type!!) { when(i.type!!) {
@ -1323,7 +1335,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++ pc++
} }
private fun InsOR(i: Instruction) { private fun InsORR(i: Instruction) {
val (left: UInt, right: UInt) = getLogicalOperandsU(i) val (left: UInt, right: UInt) = getLogicalOperandsU(i)
when(i.type!!) { when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, (left or right).toUByte()) VmDataType.BYTE -> registers.setUB(i.reg1!!, (left or right).toUByte())
@ -1333,6 +1345,15 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++ pc++
} }
private fun InsOR(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1) or i.value!!.toUByte())
VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1) or i.value!!.toUShort())
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
pc++
}
private fun InsORM(i: Instruction) { private fun InsORM(i: Instruction) {
val address = i.value!! val address = i.value!!
when(i.type!!) { when(i.type!!) {
@ -1351,7 +1372,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++ pc++
} }
private fun InsXOR(i: Instruction) { private fun InsXORR(i: Instruction) {
val (left: UInt, right: UInt) = getLogicalOperandsU(i) val (left: UInt, right: UInt) = getLogicalOperandsU(i)
when(i.type!!) { when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, (left xor right).toUByte()) VmDataType.BYTE -> registers.setUB(i.reg1!!, (left xor right).toUByte())
@ -1361,6 +1382,15 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++ pc++
} }
private fun InsXOR(i: Instruction) {
when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1) xor i.value!!.toUByte())
VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1) xor i.value!!.toUShort())
VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
}
pc++
}
private fun InsXORM(i: Instruction) { private fun InsXORM(i: Instruction) {
val address = i.value!! val address = i.value!!
when(i.type!!) { when(i.type!!) {