From 36e8f10d2b311dd51732fa97a125237337c12b39 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 23 Sep 2023 11:42:58 +0200 Subject: [PATCH] vm: remove BEQR opcode -> CMP + BSTEQ --- .../prog8/codegen/intermediate/IRCodeGen.kt | 53 ++++++++++++++----- examples/test.p8 | 24 ++++++--- .../src/prog8/intermediate/IRInstructions.kt | 4 -- virtualmachine/src/prog8/vm/VirtualMachine.kt | 9 ---- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index cff24e27c..baa49976f 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -566,8 +566,11 @@ class IRCodeGen( result += labelFirstChunk(translateNode(forLoop.statements), loopLabel) if(step==1 || step==-1) { // if endvalue == loopvar, stop loop, else iterate - addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = fromTr.resultReg, labelSymbol = loopvarSymbol), null) - addInstr(result, IRInstruction(Opcode.BEQR, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol = labelAfterFor), null) + result += IRCodeChunk(null, null).also { + it += IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = fromTr.resultReg, labelSymbol = loopvarSymbol) + it += IRInstruction(Opcode.CMP, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg) + it += IRInstruction(Opcode.BSTEQ, labelSymbol = labelAfterFor) + } result += addConstMem(loopvarDtIr, null, loopvarSymbol, step) addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = loopLabel), null) } else { @@ -1114,9 +1117,11 @@ class IRCodeGen( val firstReg: Int val secondReg: Int val opcode: Opcode + var useCmp = false when (condition.operator) { "==" -> { - opcode = Opcode.BEQR + opcode = Opcode.BSTEQ + useCmp = true firstReg = leftTr.resultReg secondReg = rightTr.resultReg } @@ -1149,12 +1154,20 @@ class IRCodeGen( } else -> throw AssemblyError("invalid comparison operator") } - if (goto.address != null) - addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, address = goto.address?.toInt()), null) - else if (goto.generatedLabel != null) - addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, labelSymbol = goto.generatedLabel), null) - else - addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, labelSymbol = goto.identifier!!.name), null) + + if(useCmp) { + result += IRCodeChunk(null, null).also { + it += IRInstruction(Opcode.CMP, irDtLeft, reg1 = firstReg, reg2 = secondReg) + it += branchInstr(goto, opcode) + } + } else { + if (goto.address != null) + addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, address = goto.address?.toInt()), null) + else if (goto.generatedLabel != null) + addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, labelSymbol = goto.generatedLabel), null) + else + addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, labelSymbol = goto.identifier!!.name), null) + } } } } @@ -1388,6 +1401,7 @@ class IRCodeGen( } else { val rightTr = expressionEval.translateExpression(condition.right) val elseBranch: Opcode + var useCmp = false addToResult(result, rightTr, rightTr.resultReg, -1) when (condition.operator) { "==" -> { @@ -1396,7 +1410,8 @@ class IRCodeGen( elseBranchSecondReg = rightTr.resultReg } "!=" -> { - elseBranch = Opcode.BEQR + useCmp = true + elseBranch = Opcode.BSTEQ elseBranchFirstReg = leftTr.resultReg elseBranchSecondReg = rightTr.resultReg } @@ -1431,7 +1446,14 @@ class IRCodeGen( // if and else parts val elseLabel = createLabelName() val afterIfLabel = createLabelName() - addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg, labelSymbol = elseLabel), null) + if(useCmp) { + result += IRCodeChunk(null,null).also { + it += IRInstruction(Opcode.CMP, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg) + it += IRInstruction(elseBranch, labelSymbol = elseLabel) + } + } else { + addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg, labelSymbol = elseLabel), null) + } result += translateNode(ifElse.ifScope) addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null) result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel) @@ -1439,7 +1461,14 @@ class IRCodeGen( } else { // only if part val afterIfLabel = createLabelName() - addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg, labelSymbol = afterIfLabel), null) + if(useCmp) { + result += IRCodeChunk(null,null).also { + it += IRInstruction(Opcode.CMP, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg) + it += IRInstruction(elseBranch, labelSymbol = afterIfLabel) + } + } else { + addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg, labelSymbol = afterIfLabel), null) + } result += translateNode(ifElse.ifScope) result += IRCodeChunk(afterIfLabel, null) } diff --git a/examples/test.p8 b/examples/test.p8 index 37adbbdca..041bfa835 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,12 +3,24 @@ main { sub start() { - float x=10 - float y=20 - bool r = x!=y - txt.print_ub(r) - repeat 4 { - txt.print(".") + ubyte from = 10 + ubyte compare=9 + if from==compare + goto equal + + txt.print("from is not compare\n") +equal: + + ubyte end = 15 + ubyte xx + for xx in from to end { + txt.print_ub(xx) + txt.spc() } + txt.nl() + + ubyte ten=9 + if from!=ten + txt.print("from is not 10\n") } } diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 604e697fe..4f29154ec 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -83,7 +83,6 @@ bstpos address - branch to location if Status bit Negat bstneg address - branch to location if Status bit Negative is set bstvc address - branch to location if Status bit Overflow is clear bstvs address - branch to location if Status bit Overflow is set -beqr reg1, reg2, address - jump to location in program given by location, if reg1 == reg2 bner reg1, reg2, address - jump to location in program given by location, if reg1 != reg2 bgt reg1, value, address - jump to location in program given by location, if reg1 > immediate value (unsigned) bgts reg1, value, address - jump to location in program given by location, if reg1 > immediate value (signed) @@ -259,7 +258,6 @@ enum class Opcode { BSTPOS, BSTVC, BSTVS, - BEQR, BNER, BGTR, BGT, @@ -403,7 +401,6 @@ val OpcodesThatBranch = setOf( Opcode.BSTPOS, Opcode.BSTVC, Opcode.BSTVS, - Opcode.BEQR, Opcode.BNER, Opcode.BGTR, Opcode.BGT, @@ -552,7 +549,6 @@ val instructionFormats = mutableMapOf( Opcode.BSTPOS to InstructionFormat.from("N, InsBSTNEG(ins) Opcode.BSTPOS -> InsBSTPOS(ins) Opcode.BSTVC, Opcode.BSTVS -> TODO("overflow status flag not yet supported in VM (BSTVC,BSTVS)") - Opcode.BEQR -> InsBEQR(ins) Opcode.BNER -> InsBNER(ins) Opcode.BGTR -> InsBGTR(ins) Opcode.BGTSR -> InsBGTSR(ins) @@ -669,14 +668,6 @@ class VirtualMachine(irProgram: IRProgram) { nextPc() } - private fun InsBEQR(i: IRInstruction) { - val (left: Int, right: Int) = getBranchOperands(i) - if(left==right) - branchTo(i) - else - nextPc() - } - private fun InsBNER(i: IRInstruction) { val (left: Int, right: Int) = getBranchOperands(i) if(left!=right)