vm: remove BEQR opcode -> CMP + BSTEQ

This commit is contained in:
Irmen de Jong 2023-09-23 11:42:58 +02:00
parent cdf5a8f20f
commit 36e8f10d2b
4 changed files with 59 additions and 31 deletions

View File

@ -566,8 +566,11 @@ class IRCodeGen(
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel) result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
if(step==1 || step==-1) { if(step==1 || step==-1) {
// if endvalue == loopvar, stop loop, else iterate // if endvalue == loopvar, stop loop, else iterate
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = fromTr.resultReg, labelSymbol = loopvarSymbol), null) result += IRCodeChunk(null, null).also {
addInstr(result, IRInstruction(Opcode.BEQR, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol = labelAfterFor), null) 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) result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = loopLabel), null) addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = loopLabel), null)
} else { } else {
@ -1114,9 +1117,11 @@ class IRCodeGen(
val firstReg: Int val firstReg: Int
val secondReg: Int val secondReg: Int
val opcode: Opcode val opcode: Opcode
var useCmp = false
when (condition.operator) { when (condition.operator) {
"==" -> { "==" -> {
opcode = Opcode.BEQR opcode = Opcode.BSTEQ
useCmp = true
firstReg = leftTr.resultReg firstReg = leftTr.resultReg
secondReg = rightTr.resultReg secondReg = rightTr.resultReg
} }
@ -1149,12 +1154,20 @@ class IRCodeGen(
} }
else -> throw AssemblyError("invalid comparison operator") else -> throw AssemblyError("invalid comparison operator")
} }
if (goto.address != null)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, address = goto.address?.toInt()), null) if(useCmp) {
else if (goto.generatedLabel != null) result += IRCodeChunk(null, null).also {
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, labelSymbol = goto.generatedLabel), null) it += IRInstruction(Opcode.CMP, irDtLeft, reg1 = firstReg, reg2 = secondReg)
else it += branchInstr(goto, opcode)
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, reg2 = secondReg, labelSymbol = goto.identifier!!.name), null) }
} 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 { } else {
val rightTr = expressionEval.translateExpression(condition.right) val rightTr = expressionEval.translateExpression(condition.right)
val elseBranch: Opcode val elseBranch: Opcode
var useCmp = false
addToResult(result, rightTr, rightTr.resultReg, -1) addToResult(result, rightTr, rightTr.resultReg, -1)
when (condition.operator) { when (condition.operator) {
"==" -> { "==" -> {
@ -1396,7 +1410,8 @@ class IRCodeGen(
elseBranchSecondReg = rightTr.resultReg elseBranchSecondReg = rightTr.resultReg
} }
"!=" -> { "!=" -> {
elseBranch = Opcode.BEQR useCmp = true
elseBranch = Opcode.BSTEQ
elseBranchFirstReg = leftTr.resultReg elseBranchFirstReg = leftTr.resultReg
elseBranchSecondReg = rightTr.resultReg elseBranchSecondReg = rightTr.resultReg
} }
@ -1431,7 +1446,14 @@ class IRCodeGen(
// if and else parts // if and else parts
val elseLabel = createLabelName() val elseLabel = createLabelName()
val afterIfLabel = 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) result += translateNode(ifElse.ifScope)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null) addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel) result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
@ -1439,7 +1461,14 @@ class IRCodeGen(
} else { } else {
// only if part // only if part
val afterIfLabel = createLabelName() 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 += translateNode(ifElse.ifScope)
result += IRCodeChunk(afterIfLabel, null) result += IRCodeChunk(afterIfLabel, null)
} }

View File

@ -3,12 +3,24 @@
main { main {
sub start() { sub start() {
float x=10 ubyte from = 10
float y=20 ubyte compare=9
bool r = x!=y if from==compare
txt.print_ub(r) goto equal
repeat 4 {
txt.print(".") 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")
} }
} }

View File

@ -83,7 +83,6 @@ bstpos address - branch to location if Status bit Negat
bstneg address - branch to location if Status bit Negative is set bstneg address - branch to location if Status bit Negative is set
bstvc address - branch to location if Status bit Overflow is clear bstvc address - branch to location if Status bit Overflow is clear
bstvs address - branch to location if Status bit Overflow is set 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 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) 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) 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, BSTPOS,
BSTVC, BSTVC,
BSTVS, BSTVS,
BEQR,
BNER, BNER,
BGTR, BGTR,
BGT, BGT,
@ -403,7 +401,6 @@ val OpcodesThatBranch = setOf(
Opcode.BSTPOS, Opcode.BSTPOS,
Opcode.BSTVC, Opcode.BSTVC,
Opcode.BSTVS, Opcode.BSTVS,
Opcode.BEQR,
Opcode.BNER, Opcode.BNER,
Opcode.BGTR, Opcode.BGTR,
Opcode.BGT, Opcode.BGT,
@ -552,7 +549,6 @@ val instructionFormats = mutableMapOf(
Opcode.BSTPOS to InstructionFormat.from("N,<a"), Opcode.BSTPOS to InstructionFormat.from("N,<a"),
Opcode.BSTVC to InstructionFormat.from("N,<a"), Opcode.BSTVC to InstructionFormat.from("N,<a"),
Opcode.BSTVS to InstructionFormat.from("N,<a"), Opcode.BSTVS to InstructionFormat.from("N,<a"),
Opcode.BEQR to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BNER to InstructionFormat.from("BW,<r1,<r2,<a"), Opcode.BNER to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BGTR to InstructionFormat.from("BW,<r1,<r2,<a"), Opcode.BGTR to InstructionFormat.from("BW,<r1,<r2,<a"),
Opcode.BGT to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BGT to InstructionFormat.from("BW,<r1,<i,<a"),

View File

@ -191,7 +191,6 @@ class VirtualMachine(irProgram: IRProgram) {
Opcode.BSTNEG -> InsBSTNEG(ins) Opcode.BSTNEG -> InsBSTNEG(ins)
Opcode.BSTPOS -> InsBSTPOS(ins) Opcode.BSTPOS -> InsBSTPOS(ins)
Opcode.BSTVC, Opcode.BSTVS -> TODO("overflow status flag not yet supported in VM (BSTVC,BSTVS)") Opcode.BSTVC, Opcode.BSTVS -> TODO("overflow status flag not yet supported in VM (BSTVC,BSTVS)")
Opcode.BEQR -> InsBEQR(ins)
Opcode.BNER -> InsBNER(ins) Opcode.BNER -> InsBNER(ins)
Opcode.BGTR -> InsBGTR(ins) Opcode.BGTR -> InsBGTR(ins)
Opcode.BGTSR -> InsBGTSR(ins) Opcode.BGTSR -> InsBGTSR(ins)
@ -669,14 +668,6 @@ class VirtualMachine(irProgram: IRProgram) {
nextPc() 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) { private fun InsBNER(i: IRInstruction) {
val (left: Int, right: Int) = getBranchOperands(i) val (left: Int, right: Int) = getBranchOperands(i)
if(left!=right) if(left!=right)