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)
}
DataType.BYTE -> {
val andReg = codeGen.vmRegisters.nextFree()
val notNegativeLabel = codeGen.createLabelName()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=andReg, value=0x80)
code += VmCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=andReg, reg2=resultRegister)
code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=andReg, labelSymbol = notNegativeLabel)
val compareReg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=compareReg, reg2=resultRegister)
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.EXT, VmDataType.BYTE, reg1=resultRegister)
code += VmCodeLabel(notNegativeLabel)
}
DataType.WORD -> {
val andReg = codeGen.vmRegisters.nextFree()
val notNegativeLabel = codeGen.createLabelName()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=andReg, value=0x8000)
code += VmCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=andReg, reg2=resultRegister)
code += VmCodeInstruction(Opcode.BZ, VmDataType.WORD, reg1=andReg, labelSymbol = notNegativeLabel)
val compareReg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOADR, VmDataType.WORD, reg1=compareReg, reg2=resultRegister)
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 += VmCodeLabel(notNegativeLabel)
}

View File

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

View File

@ -3,7 +3,8 @@ TODO
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 floats
%zeropage basicsafe
main {
sub start() {
bool @shared zz
ubyte xx
ubyte yy
while xx<42 {
xx = yy+99
xx = yy*5
}
txt.print_ub(xx)
float fl
fl = -3.14
floats.print_f(abs(fl)) ; WHY IS THIS GETTING A BOOLEAN CAST???
txt.nl()
}
}

View File

@ -126,9 +126,12 @@ LOGICAL/BITWISE
---------------
All have type b or w.
and reg1, reg2 - reg1 = reg1 bitwise and reg2
or reg1, reg2 - reg1 = reg1 bitwise or reg2
xor reg1, reg2 - reg1 = reg1 bitwise xor reg2
andr reg1, reg2 - reg1 = reg1 bitwise and reg2
and reg1, value - reg1 = reg1 bitwise and value
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)
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
@ -265,10 +268,13 @@ enum class Opcode {
EXT,
EXTS,
ANDR,
AND,
ANDM,
ORR,
OR,
ORM,
XORR,
XOR,
XORM,
INV,
@ -567,11 +573,14 @@ val instructionFormats = mutableMapOf(
Opcode.CMP to InstructionFormat.from("BW,r1,r2"),
Opcode.EXT 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.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.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.INV to InstructionFormat.from("BW,r1"),
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.EXT -> InsEXT(ins)
Opcode.EXTS -> InsEXTS(ins)
Opcode.ANDR -> InsANDR(ins)
Opcode.AND -> InsAND(ins)
Opcode.ANDM -> InsANDM(ins)
Opcode.ORR -> InsORR(ins)
Opcode.OR -> InsOR(ins)
Opcode.ORM -> InsORM(ins)
Opcode.XORR -> InsXORR(ins)
Opcode.XOR -> InsXOR(ins)
Opcode.XORM ->InsXORM(ins)
Opcode.INV -> InsINV(ins)
@ -1295,7 +1298,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++
}
private fun InsAND(i: Instruction) {
private fun InsANDR(i: Instruction) {
val (left: UInt, right: UInt) = getLogicalOperandsU(i)
when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, (left and right).toUByte())
@ -1305,6 +1308,15 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
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) {
val address = i.value!!
when(i.type!!) {
@ -1323,7 +1335,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++
}
private fun InsOR(i: Instruction) {
private fun InsORR(i: Instruction) {
val (left: UInt, right: UInt) = getLogicalOperandsU(i)
when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, (left or right).toUByte())
@ -1333,6 +1345,15 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
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) {
val address = i.value!!
when(i.type!!) {
@ -1351,7 +1372,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++
}
private fun InsXOR(i: Instruction) {
private fun InsXORR(i: Instruction) {
val (left: UInt, right: UInt) = getLogicalOperandsU(i)
when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, (left xor right).toUByte())
@ -1361,6 +1382,15 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
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) {
val address = i.value!!
when(i.type!!) {