mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
ir: remove SL* opcodes
This commit is contained in:
parent
e2882d37bf
commit
af7930d494
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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"),
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user