ir: remove SL* opcodes

This commit is contained in:
Irmen de Jong 2024-12-27 19:14:52 +01:00
parent e2882d37bf
commit af7930d494
4 changed files with 62 additions and 89 deletions

View File

@ -429,14 +429,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
BaseDataType.BOOL -> {
when {
valueDt.isByte -> {
// loadStatusAsBooleanResult(Opcode.BSTNE, result)
actualResultReg2 = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.SNZ, IRDataType.BYTE, reg1=actualResultReg2, reg2=tr.resultReg), null)
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=tr.resultReg, immediate = 0), null)
actualResultReg2 = loadStatusAsBooleanResult(Opcode.BSTNE, result)
}
valueDt.isWord -> {
// loadStatusAsBooleanResult(Opcode.BSTNE, result)
actualResultReg2 = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.SNZ, IRDataType.WORD, reg1=actualResultReg2, reg2=tr.resultReg), null)
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.WORD, reg1=tr.resultReg, immediate = 0), null)
actualResultReg2 =loadStatusAsBooleanResult(Opcode.BSTNE, result)
}
valueDt.isFloat -> {
actualResultReg2 = codeGen.registers.nextFree()
@ -914,7 +912,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
lessEquals: Boolean
): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val cmpResultRegister = codeGen.registers.nextFree()
if(vmDt==IRDataType.FLOAT) {
val leftTr = translateExpression(binExpr.left)
addToResult(result, leftTr, -1, leftTr.resultFpReg)
@ -922,15 +919,29 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, rightTr, -1, rightTr.resultFpReg)
val resultRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
val zeroRegister = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, immediate = 0), null)
val ins = if (signed) {
if (lessEquals) Opcode.SLES else Opcode.SLTS
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=resultRegister, immediate = 0), null)
val other = codeGen.createLabelName()
val after = codeGen.createLabelName()
val resultReg = codeGen.registers.nextFree()
// TODO can this be done more efficiently?
if(lessEquals) {
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.BSTNEG, labelSymbol = other)
it += IRInstruction(Opcode.BSTEQ, labelSymbol = other)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultReg, immediate = 0)
it += IRInstruction(Opcode.JUMP, labelSymbol = after)
}
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultReg, immediate = 1), other)
} else {
if (lessEquals) Opcode.SLE else Opcode.SLT
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.BSTNEG, labelSymbol = other)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultReg, immediate = 0)
it += IRInstruction(Opcode.JUMP, labelSymbol = after)
}
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultReg, immediate = 1), other)
}
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1=cmpResultRegister, reg2 = resultRegister, reg3 = zeroRegister), null)
return ExpressionCodeResult(result, IRDataType.BYTE, cmpResultRegister, -1)
result += IRCodeChunk(after, null)
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
} else {
if(binExpr.left.type.isString || binExpr.right.type.isString) {
throw AssemblyError("str compares should have been replaced with builtin function call to do the compare")
@ -939,13 +950,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
addToResult(result, leftTr, leftTr.resultReg, -1)
val rightTr = translateExpression(binExpr.right)
addToResult(result, rightTr, rightTr.resultReg, -1)
val ins = if (signed) {
if (lessEquals) Opcode.SLES else Opcode.SLTS
val branch = if (signed) {
if (lessEquals) Opcode.BGESR else Opcode.BGTSR
} else {
if (lessEquals) Opcode.SLE else Opcode.SLT
if (lessEquals) Opcode.BGER else Opcode.BGTR
}
addInstr(result, IRInstruction(ins, vmDt, reg1=cmpResultRegister, reg2 = leftTr.resultReg, reg3 = rightTr.resultReg), null)
return ExpressionCodeResult(result, IRDataType.BYTE, cmpResultRegister, -1)
val resultReg = compareRegisterAsBooleanResult(branch, leftTr.dt, rightTr.resultReg, leftTr.resultReg, result)
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
}
}
}
@ -968,7 +979,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
IRInstruction(Opcode.BSTEQ, labelSymbol = label)
else
IRInstruction(Opcode.BSTNE, labelSymbol = label)
it += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=resultRegister)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 1)
}
result += IRCodeChunk(label, null)
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
@ -1011,6 +1022,21 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return resultReg
}
private fun compareRegisterAsBooleanResult(branchForTrue: Opcode, dt: IRDataType, reg1: Int, reg2: Int, result: MutableList<IRCodeChunkBase>): Int {
// TODO this used to be a single instruction like SCC, SCS, SZ etc but those were problematic
val other = codeGen.createLabelName()
val after = codeGen.createLabelName()
val resultReg = codeGen.registers.nextFree()
result += IRCodeChunk(null, null).also {
it += IRInstruction(branchForTrue, dt, reg1=reg1, reg2=reg2, labelSymbol = other)
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultReg, immediate = 0)
it += IRInstruction(Opcode.JUMP, labelSymbol = after)
}
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultReg, immediate = 1), other)
result += IRCodeChunk(after, null)
return resultReg
}
private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
return if(codeGen.isOne(binExpr.right)) {

View File

@ -10,10 +10,22 @@ main {
float @shared f1,f2
txt.nl()
derp = cx16.r0L as bool
cx16.r0++
derp = cx16.r0 as bool
cx16.r0 = $aaaa
cx16.r1 = $2222
f1 = 9999
cx16.r0=9999
txt.print_bool(f1 < 8000)
txt.spc()
txt.print_bool(f1 < 10000)
txt.spc()
txt.print_bool(f1 < 20000)
txt.nl()
txt.print_bool(cx16.r0 < 8000)
txt.spc()
txt.print_bool(cx16.r0 < 10000)
txt.spc()
txt.print_bool(cx16.r0 < 20000)
txt.nl()
cx16.r0L=0
derp=true

View File

@ -123,11 +123,6 @@ bles reg1, value, address - jump to location in program given by l
bgesr reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (signed)
'blesr' reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (signed) ==> use bgesr with swapped operands
snz reg1, reg2 - set reg1=1 if reg2!=0, else 0
slt reg1, reg2, reg3 - set reg1=1 if reg2 < reg3 (unsigned), else 0
slts reg1, reg2, reg3 - set reg1=1 if reg2 < reg3 (signed), else 0
sle reg1, reg2, reg3 - set reg1=1 if reg2 <= reg3 (unsigned), else 0
sles reg1, reg2, reg3 - set reg1=1 if reg2 <= reg3 (signed), else 0
sgt reg1, reg2, reg3 - set reg1=1 if reg2 > reg3 (unsigned), else 0
sgts reg1, reg2, reg3 - set reg1=1 if reg2 > reg3 (signed), else 0
sge reg1, reg2, reg3 - set reg1=1 if reg2 >= reg3 (unsigned), else 0
@ -318,13 +313,8 @@ enum class Opcode {
BGESR,
BGES,
BLES,
SNZ,
SLT,
SLTS,
SGT,
SGTS,
SLE,
SLES,
SGE,
SGES,
@ -516,13 +506,8 @@ val OpcodesThatDependOnCarry = arrayOf(
)
val OpcodesThatSetRegFromStatusbits = arrayOf(
Opcode.SNZ,
Opcode.SLT,
Opcode.SLTS,
Opcode.SGT,
Opcode.SGTS,
Opcode.SLE,
Opcode.SLES,
Opcode.SGE,
Opcode.SGES
)
@ -677,13 +662,8 @@ val instructionFormats = mutableMapOf(
Opcode.BGESR to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BGES to InstructionFormat.from("BW,<r1,<i,<a"),
Opcode.BLES to InstructionFormat.from("BW,<r1,<i,<a"),
Opcode.SNZ to InstructionFormat.from("BW,>r1,<r2"),
Opcode.SLT to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.SLTS to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.SGT to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.SGTS to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.SLE to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.SLES to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.SGE to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.SGES to InstructionFormat.from("BW,<>r1,<r2,<r3"),
Opcode.INC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),

View File

@ -236,13 +236,8 @@ class VirtualMachine(irProgram: IRProgram) {
Opcode.BLE -> InsBLE(ins)
Opcode.BGES -> InsBGES(ins)
Opcode.BLES -> InsBLES(ins)
Opcode.SNZ -> InsSNZ(ins)
Opcode.SLT -> InsSLT(ins)
Opcode.SLTS -> InsSLTS(ins)
Opcode.SGT -> InsSGT(ins)
Opcode.SGTS -> InsSGTS(ins)
Opcode.SLE -> InsSLE(ins)
Opcode.SLES -> InsSLES(ins)
Opcode.SGE -> InsSGE(ins)
Opcode.SGES -> InsSGES(ins)
Opcode.INC -> InsINC(ins)
@ -890,32 +885,6 @@ class VirtualMachine(irProgram: IRProgram) {
nextPc()
}
private fun InsSNZ(i: IRInstruction) {
val right = when(i.type) {
IRDataType.BYTE -> registers.getSB(i.reg2!!).toInt()
IRDataType.WORD -> registers.getSW(i.reg2!!).toInt()
IRDataType.FLOAT -> throw IllegalArgumentException("can't use float here")
null -> throw IllegalArgumentException("need type for branch instruction")
}
val value = if(right!=0) 1 else 0
setResultReg(i.reg1!!, value, i.type!!)
nextPc()
}
private fun InsSLT(i: IRInstruction) {
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left<right) 1 else 0
setResultReg(i.reg1!!, value, i.type!!)
nextPc()
}
private fun InsSLTS(i: IRInstruction) {
val (left, right) = getSetOnConditionOperands(i)
val value = if(left<right) 1 else 0
setResultReg(i.reg1!!, value, i.type!!)
nextPc()
}
private fun InsSGT(i: IRInstruction) {
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left>right) 1 else 0
@ -930,20 +899,6 @@ class VirtualMachine(irProgram: IRProgram) {
nextPc()
}
private fun InsSLE(i: IRInstruction) {
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left<=right) 1 else 0
setResultReg(i.reg1!!, value, i.type!!)
nextPc()
}
private fun InsSLES(i: IRInstruction) {
val (left, right) = getSetOnConditionOperands(i)
val value = if(left<=right) 1 else 0
setResultReg(i.reg1!!, value, i.type!!)
nextPc()
}
private fun InsSGE(i: IRInstruction) {
val (left, right) = getSetOnConditionOperandsU(i)
val value = if(left>=right) 1 else 0