mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +00:00
vm: remove BEQ opcode -> CMPI + BSTEQ
This commit is contained in:
parent
eb55da63ef
commit
eb64d92333
@ -562,14 +562,17 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val resultRegister = codeGen.registers.nextFree()
|
val resultRegister = codeGen.registers.nextFree()
|
||||||
val valueReg = codeGen.registers.nextFree()
|
val valueReg = codeGen.registers.nextFree()
|
||||||
val label = codeGen.createLabelName()
|
val label = codeGen.createLabelName()
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 1), null)
|
result += IRCodeChunk(null, null).also {
|
||||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=valueReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 1)
|
||||||
if (notEquals) {
|
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=valueReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg)
|
||||||
addInstr(result, IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=valueReg, immediate = 0, labelSymbol = label), null)
|
if (notEquals) {
|
||||||
} else {
|
it += IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=valueReg, immediate = 0, labelSymbol = label)
|
||||||
addInstr(result, IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1=valueReg, immediate = 0, labelSymbol = label), null)
|
} else {
|
||||||
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=valueReg, immediate = 0)
|
||||||
|
it += IRInstruction(Opcode.BSTEQ, labelSymbol = label)
|
||||||
|
}
|
||||||
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 0)
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 0), null)
|
|
||||||
result += IRCodeChunk(label, null)
|
result += IRCodeChunk(label, null)
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||||
} else {
|
} else {
|
||||||
|
@ -415,13 +415,19 @@ class IRCodeGen(
|
|||||||
if(choice.statements.children.isEmpty()) {
|
if(choice.statements.children.isEmpty()) {
|
||||||
// no statements for this choice value, jump to the end immediately
|
// no statements for this choice value, jump to the end immediately
|
||||||
choice.values.children.map { it as PtNumber }.sortedBy { it.number }.forEach { value ->
|
choice.values.children.map { it as PtNumber }.sortedBy { it.number }.forEach { value ->
|
||||||
addInstr(result, IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt(), labelSymbol = endLabel), null)
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.CMPI, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt())
|
||||||
|
it += IRInstruction(Opcode.BSTEQ, labelSymbol = endLabel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val choiceLabel = createLabelName()
|
val choiceLabel = createLabelName()
|
||||||
choices.add(choiceLabel to choice)
|
choices.add(choiceLabel to choice)
|
||||||
choice.values.children.map { it as PtNumber }.sortedBy { it.number }.forEach { value ->
|
choice.values.children.map { it as PtNumber }.sortedBy { it.number }.forEach { value ->
|
||||||
addInstr(result, IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt(), labelSymbol = choiceLabel), null)
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.CMPI, valueDt, reg1=valueTr.resultReg, immediate = value.number.toInt())
|
||||||
|
it += IRInstruction(Opcode.BSTEQ, labelSymbol = choiceLabel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -464,7 +470,8 @@ class IRCodeGen(
|
|||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = 0), null)
|
||||||
result += IRCodeChunk(loopLabel, null).also {
|
result += IRCodeChunk(loopLabel, null).also {
|
||||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = tmpReg, reg2 = indexReg, labelSymbol = iterable.name)
|
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = tmpReg, reg2 = indexReg, labelSymbol = iterable.name)
|
||||||
it += IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1 = tmpReg, immediate = 0, labelSymbol = endLabel)
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = tmpReg, immediate = 0)
|
||||||
|
it += IRInstruction(Opcode.BSTEQ, labelSymbol = endLabel)
|
||||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tmpReg, labelSymbol = loopvarSymbol)
|
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tmpReg, labelSymbol = loopvarSymbol)
|
||||||
}
|
}
|
||||||
result += translateNode(forLoop.statements)
|
result += translateNode(forLoop.statements)
|
||||||
@ -960,21 +967,30 @@ class IRCodeGen(
|
|||||||
fpReg1 = leftTr.resultFpReg,
|
fpReg1 = leftTr.resultFpReg,
|
||||||
fpReg2 = rightTr.resultFpReg
|
fpReg2 = rightTr.resultFpReg
|
||||||
)
|
)
|
||||||
val gotoOpcode = when (condition.operator) {
|
when(condition.operator) {
|
||||||
"==" -> Opcode.BEQ
|
// TODO: the converted list of operators
|
||||||
"!=" -> Opcode.BNE
|
"==" -> {
|
||||||
"<" -> Opcode.BLTS
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = compResultReg, immediate = 0)
|
||||||
">" -> Opcode.BGTS
|
it += branchInstr(goto, Opcode.BSTEQ)
|
||||||
"<=" -> Opcode.BLES
|
}
|
||||||
">=" -> Opcode.BGES
|
else -> {
|
||||||
else -> throw AssemblyError("weird operator")
|
// TODO: the old list of operators, still to be converted
|
||||||
|
val gotoOpcode = when (condition.operator) {
|
||||||
|
"!=" -> Opcode.BNE
|
||||||
|
"<" -> Opcode.BLTS
|
||||||
|
">" -> Opcode.BGTS
|
||||||
|
"<=" -> Opcode.BLES
|
||||||
|
">=" -> Opcode.BGES
|
||||||
|
else -> throw AssemblyError("weird operator")
|
||||||
|
}
|
||||||
|
it += if (goto.address != null)
|
||||||
|
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, address = goto.address?.toInt())
|
||||||
|
else if (goto.generatedLabel != null)
|
||||||
|
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = goto.generatedLabel)
|
||||||
|
else
|
||||||
|
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = goto.identifier!!.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it += if (goto.address != null)
|
|
||||||
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, address = goto.address?.toInt())
|
|
||||||
else if (goto.generatedLabel != null)
|
|
||||||
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = goto.generatedLabel)
|
|
||||||
else
|
|
||||||
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = goto.identifier!!.name)
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
} else {
|
} else {
|
||||||
@ -989,6 +1005,14 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO use this everywhere
|
||||||
|
private fun branchInstr(goto: PtJump, branchOpcode: Opcode) = if (goto.address != null)
|
||||||
|
IRInstruction(branchOpcode, address = goto.address?.toInt())
|
||||||
|
else if (goto.generatedLabel != null)
|
||||||
|
IRInstruction(branchOpcode, labelSymbol = goto.generatedLabel)
|
||||||
|
else
|
||||||
|
IRInstruction(branchOpcode, labelSymbol = goto.identifier!!.name)
|
||||||
|
|
||||||
private fun ifZeroIntThenJump(
|
private fun ifZeroIntThenJump(
|
||||||
result: MutableList<IRCodeChunkBase>,
|
result: MutableList<IRCodeChunkBase>,
|
||||||
ifElse: PtIfElse,
|
ifElse: PtIfElse,
|
||||||
@ -999,21 +1023,30 @@ class IRCodeGen(
|
|||||||
val condition = ifElse.condition as PtBinaryExpression
|
val condition = ifElse.condition as PtBinaryExpression
|
||||||
val leftTr = expressionEval.translateExpression(condition.left)
|
val leftTr = expressionEval.translateExpression(condition.left)
|
||||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||||
val opcode = when (condition.operator) {
|
when(condition.operator) {
|
||||||
"==" -> Opcode.BEQ
|
// TODO: converted list of operators
|
||||||
"!=" -> Opcode.BNE
|
"==" -> {
|
||||||
"<" -> if (signed) Opcode.BLTS else Opcode.BLT
|
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = leftTr.resultReg, immediate = 0), null)
|
||||||
">" -> if (signed) Opcode.BGTS else Opcode.BGT
|
addInstr(result, branchInstr(goto, Opcode.BSTEQ), null)
|
||||||
"<=" -> if (signed) Opcode.BLES else Opcode.BLE
|
}
|
||||||
">=" -> if (signed) Opcode.BGES else Opcode.BGE
|
else -> {
|
||||||
else -> throw AssemblyError("invalid comparison operator")
|
// TODO: to-be converted operators
|
||||||
|
val opcode = when (condition.operator) {
|
||||||
|
"!=" -> Opcode.BNE
|
||||||
|
"<" -> if (signed) Opcode.BLTS else Opcode.BLT
|
||||||
|
">" -> if (signed) Opcode.BGTS else Opcode.BGT
|
||||||
|
"<=" -> if (signed) Opcode.BLES else Opcode.BLE
|
||||||
|
">=" -> if (signed) Opcode.BGES else Opcode.BGE
|
||||||
|
else -> throw AssemblyError("invalid comparison operator")
|
||||||
|
}
|
||||||
|
if (goto.address != null)
|
||||||
|
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, immediate = 0, address = goto.address?.toInt()), null)
|
||||||
|
else if (goto.generatedLabel != null)
|
||||||
|
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, immediate = 0, labelSymbol = goto.generatedLabel), null)
|
||||||
|
else
|
||||||
|
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, immediate = 0, labelSymbol = goto.identifier!!.name), null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (goto.address != null)
|
|
||||||
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, immediate = 0, address = goto.address?.toInt()), null)
|
|
||||||
else if (goto.generatedLabel != null)
|
|
||||||
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, immediate = 0, labelSymbol = goto.generatedLabel), null)
|
|
||||||
else
|
|
||||||
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = leftTr.resultReg, immediate = 0, labelSymbol = goto.identifier!!.name), null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ifNonZeroIntThenJump(
|
private fun ifNonZeroIntThenJump(
|
||||||
@ -1036,30 +1069,39 @@ class IRCodeGen(
|
|||||||
} else {
|
} else {
|
||||||
val leftTr = expressionEval.translateExpression(condition.left)
|
val leftTr = expressionEval.translateExpression(condition.left)
|
||||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||||
val opcode: Opcode
|
|
||||||
val number = (condition.right as? PtNumber)?.number?.toInt()
|
val number = (condition.right as? PtNumber)?.number?.toInt()
|
||||||
if(number!=null) {
|
if(number!=null) {
|
||||||
val firstReg = leftTr.resultReg
|
val firstReg = leftTr.resultReg
|
||||||
opcode = when (condition.operator) {
|
when(condition.operator) {
|
||||||
"==" -> Opcode.BEQ
|
// TODO: the converted operators
|
||||||
"!=" -> Opcode.BNE
|
"==" -> {
|
||||||
"<" -> if(signed) Opcode.BLTS else Opcode.BLT
|
addInstr(result, IRInstruction(Opcode.CMPI, irDtLeft, reg1 = firstReg, immediate = number), null)
|
||||||
">" -> if(signed) Opcode.BGTS else Opcode.BGT
|
addInstr(result, branchInstr(goto, Opcode.BSTEQ), null)
|
||||||
"<=" -> if(signed) Opcode.BLES else Opcode.BLE
|
}
|
||||||
">=" -> if(signed) Opcode.BGES else Opcode.BGE
|
else -> {
|
||||||
else -> throw AssemblyError("invalid comparison operator")
|
// TODO: to-be converted operators
|
||||||
|
val opcode = when (condition.operator) {
|
||||||
|
"!=" -> Opcode.BNE
|
||||||
|
"<" -> if(signed) Opcode.BLTS else Opcode.BLT
|
||||||
|
">" -> if(signed) Opcode.BGTS else Opcode.BGT
|
||||||
|
"<=" -> if(signed) Opcode.BLES else Opcode.BLE
|
||||||
|
">=" -> if(signed) Opcode.BGES else Opcode.BGE
|
||||||
|
else -> throw AssemblyError("invalid comparison operator")
|
||||||
|
}
|
||||||
|
if (goto.address != null)
|
||||||
|
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, immediate = number, address = goto.address?.toInt()), null)
|
||||||
|
else if (goto.generatedLabel != null)
|
||||||
|
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, immediate = number, labelSymbol = goto.generatedLabel), null)
|
||||||
|
else
|
||||||
|
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, immediate = number, labelSymbol = goto.identifier!!.name), null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (goto.address != null)
|
|
||||||
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, immediate = number, address = goto.address?.toInt()), null)
|
|
||||||
else if (goto.generatedLabel != null)
|
|
||||||
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, immediate = number, labelSymbol = goto.generatedLabel), null)
|
|
||||||
else
|
|
||||||
addInstr(result, IRInstruction(opcode, irDtLeft, reg1 = firstReg, immediate = number, labelSymbol = goto.identifier!!.name), null)
|
|
||||||
} else {
|
} else {
|
||||||
val rightTr = expressionEval.translateExpression(condition.right)
|
val rightTr = expressionEval.translateExpression(condition.right)
|
||||||
addToResult(result, rightTr, rightTr.resultReg, -1)
|
addToResult(result, rightTr, rightTr.resultReg, -1)
|
||||||
val firstReg: Int
|
val firstReg: Int
|
||||||
val secondReg: Int
|
val secondReg: Int
|
||||||
|
val opcode: Opcode
|
||||||
when (condition.operator) {
|
when (condition.operator) {
|
||||||
"==" -> {
|
"==" -> {
|
||||||
opcode = Opcode.BEQR
|
opcode = Opcode.BEQR
|
||||||
@ -1108,6 +1150,7 @@ class IRCodeGen(
|
|||||||
private fun translateIfElseZeroComparison(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
|
private fun translateIfElseZeroComparison(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val elseBranch: Opcode
|
val elseBranch: Opcode
|
||||||
|
var useCmpi = false // for the branch opcodes that have been converted to CMPI + BSTxx form already
|
||||||
val compResultReg: Int
|
val compResultReg: Int
|
||||||
val branchDt: IRDataType
|
val branchDt: IRDataType
|
||||||
val condition = ifElse.condition as PtBinaryExpression
|
val condition = ifElse.condition as PtBinaryExpression
|
||||||
@ -1121,13 +1164,16 @@ class IRCodeGen(
|
|||||||
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, immediateFp = 0f)
|
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, immediateFp = 0f)
|
||||||
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightFpReg)
|
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightFpReg)
|
||||||
}
|
}
|
||||||
elseBranch = when (condition.operator) {
|
when (condition.operator) {
|
||||||
"==" -> Opcode.BNE
|
"==" -> elseBranch = Opcode.BNE
|
||||||
"!=" -> Opcode.BEQ
|
"!=" -> {
|
||||||
"<" -> Opcode.BGES
|
elseBranch = Opcode.BSTEQ
|
||||||
">" -> Opcode.BLES
|
useCmpi = true
|
||||||
"<=" -> Opcode.BGTS
|
}
|
||||||
">=" -> Opcode.BLTS
|
"<" -> elseBranch = Opcode.BGES
|
||||||
|
">" -> elseBranch = Opcode.BLES
|
||||||
|
"<=" -> elseBranch = Opcode.BGTS
|
||||||
|
">=" -> elseBranch = Opcode.BLTS
|
||||||
else -> throw AssemblyError("weird operator")
|
else -> throw AssemblyError("weird operator")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1136,13 +1182,16 @@ class IRCodeGen(
|
|||||||
val tr = expressionEval.translateExpression(condition.left)
|
val tr = expressionEval.translateExpression(condition.left)
|
||||||
compResultReg = tr.resultReg
|
compResultReg = tr.resultReg
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
elseBranch = when (condition.operator) {
|
when (condition.operator) {
|
||||||
"==" -> Opcode.BNE
|
"==" -> elseBranch = Opcode.BNE
|
||||||
"!=" -> Opcode.BEQ
|
"!=" -> {
|
||||||
"<" -> if (signed) Opcode.BGES else Opcode.BGE
|
elseBranch = Opcode.BSTEQ
|
||||||
">" -> if (signed) Opcode.BLES else Opcode.BLE
|
useCmpi = true
|
||||||
"<=" -> if (signed) Opcode.BGTS else Opcode.BGT
|
}
|
||||||
">=" -> if (signed) Opcode.BLTS else Opcode.BLT
|
"<" -> elseBranch = if (signed) Opcode.BGES else Opcode.BGE
|
||||||
|
">" -> elseBranch = if (signed) Opcode.BLES else Opcode.BLE
|
||||||
|
"<=" -> elseBranch = if (signed) Opcode.BGTS else Opcode.BGT
|
||||||
|
">=" -> elseBranch = if (signed) Opcode.BLTS else Opcode.BLT
|
||||||
else -> throw AssemblyError("weird operator")
|
else -> throw AssemblyError("weird operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1150,14 +1199,26 @@ class IRCodeGen(
|
|||||||
if(ifElse.elseScope.children.isEmpty()) {
|
if(ifElse.elseScope.children.isEmpty()) {
|
||||||
// just if
|
// just if
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(elseBranch, branchDt, reg1=compResultReg, immediate = 0, labelSymbol = afterIfLabel), null)
|
if(useCmpi) {
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.CMPI, branchDt, reg1=compResultReg, immediate = 0)
|
||||||
|
it += IRInstruction(elseBranch, labelSymbol = afterIfLabel)
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
addInstr(result, IRInstruction(elseBranch, branchDt, reg1=compResultReg, immediate = 0, labelSymbol = afterIfLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
result += IRCodeChunk(afterIfLabel, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
} else {
|
} else {
|
||||||
// if and else
|
// if and else
|
||||||
val elseLabel = createLabelName()
|
val elseLabel = createLabelName()
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(elseBranch, branchDt, reg1=compResultReg, immediate = 0, labelSymbol = elseLabel), null)
|
if(useCmpi) {
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.CMPI, branchDt, reg1=compResultReg, immediate = 0)
|
||||||
|
it += IRInstruction(elseBranch, labelSymbol = elseLabel)
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
addInstr(result, IRInstruction(elseBranch, branchDt, reg1=compResultReg, immediate = 0, 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)
|
||||||
@ -1168,31 +1229,39 @@ class IRCodeGen(
|
|||||||
|
|
||||||
private fun translateIfElseNonZeroComparison(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
|
private fun translateIfElseNonZeroComparison(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val elseBranchOpcode: Opcode
|
|
||||||
val elseBranchFirstReg: Int
|
val elseBranchFirstReg: Int
|
||||||
val elseBranchSecondReg: Int
|
val elseBranchSecondReg: Int
|
||||||
val branchDt: IRDataType
|
val branchDt: IRDataType
|
||||||
val condition = ifElse.condition as? PtBinaryExpression
|
val condition = ifElse.condition as? PtBinaryExpression
|
||||||
if(condition==null) {
|
if(condition==null) {
|
||||||
if(irDtLeft==IRDataType.FLOAT)
|
throw AssemblyError("if-else condition is not a binaryexpression, should have been converted?")
|
||||||
throw AssemblyError("condition value should not be float")
|
// if(irDtLeft==IRDataType.FLOAT)
|
||||||
val tr = expressionEval.translateExpression(ifElse.condition)
|
// throw AssemblyError("condition value should not be float")
|
||||||
result += tr.chunks
|
// val tr = expressionEval.translateExpression(ifElse.condition)
|
||||||
if(ifElse.elseScope.children.isNotEmpty()) {
|
// result += tr.chunks
|
||||||
val elseLabel = createLabelName()
|
// if(ifElse.elseScope.children.isNotEmpty()) {
|
||||||
val afterIfLabel = createLabelName()
|
// val elseLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(Opcode.BEQ, irDtLeft, reg1=tr.resultReg, immediate = 0, labelSymbol = elseLabel), null)
|
// result += IRCodeChunk(null, null).also {
|
||||||
result += translateNode(ifElse.ifScope)
|
// it += IRInstruction(Opcode.CMPI, irDtLeft, reg1=tr.resultReg, immediate = 0)
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
|
// it += IRInstruction(Opcode.BSTEQ, labelSymbol = elseLabel)
|
||||||
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
|
// TODO("test this")
|
||||||
result += IRCodeChunk(afterIfLabel, null)
|
// }
|
||||||
} else {
|
// result += translateNode(ifElse.ifScope)
|
||||||
val afterIfLabel = createLabelName()
|
// val afterIfLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(Opcode.BEQ, irDtLeft, reg1=tr.resultReg, immediate = 0, labelSymbol = afterIfLabel), null)
|
// addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
// result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
|
||||||
result += IRCodeChunk(afterIfLabel, null)
|
// result += IRCodeChunk(afterIfLabel, null)
|
||||||
}
|
// } else {
|
||||||
return result
|
// val afterIfLabel = createLabelName()
|
||||||
|
// result += IRCodeChunk(null, null).also {
|
||||||
|
// it += IRInstruction(Opcode.CMPI, irDtLeft, reg1=tr.resultReg, immediate = 0)
|
||||||
|
// it += IRInstruction(Opcode.BSTEQ, labelSymbol = afterIfLabel)
|
||||||
|
// TODO("test this")
|
||||||
|
// }
|
||||||
|
// result += translateNode(ifElse.ifScope)
|
||||||
|
// result += IRCodeChunk(afterIfLabel, null)
|
||||||
|
// }
|
||||||
|
// return result
|
||||||
} else {
|
} else {
|
||||||
if (irDtLeft == IRDataType.FLOAT) {
|
if (irDtLeft == IRDataType.FLOAT) {
|
||||||
val leftTr = expressionEval.translateExpression(condition.left)
|
val leftTr = expressionEval.translateExpression(condition.left)
|
||||||
@ -1200,35 +1269,32 @@ class IRCodeGen(
|
|||||||
val rightTr = expressionEval.translateExpression(condition.right)
|
val rightTr = expressionEval.translateExpression(condition.right)
|
||||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||||
val compResultReg = registers.nextFree()
|
val compResultReg = registers.nextFree()
|
||||||
addInstr(
|
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1 = compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
|
||||||
result,
|
val elseBranch: Opcode
|
||||||
IRInstruction(
|
var useCmpi = false // for the branch opcodes that have been converted to CMPI + BSTxx form already
|
||||||
Opcode.FCOMP,
|
when (condition.operator) {
|
||||||
IRDataType.FLOAT,
|
"==" -> elseBranch = Opcode.BNE
|
||||||
reg1 = compResultReg,
|
"!=" -> {
|
||||||
fpReg1 = leftTr.resultFpReg,
|
elseBranch = Opcode.BSTEQ
|
||||||
fpReg2 = rightTr.resultFpReg
|
useCmpi = true
|
||||||
),
|
}
|
||||||
null
|
"<" -> elseBranch = Opcode.BGES
|
||||||
)
|
">" -> elseBranch = Opcode.BLES
|
||||||
val elseBranch = when (condition.operator) {
|
"<=" -> elseBranch = Opcode.BGTS
|
||||||
"==" -> Opcode.BNE
|
">=" -> elseBranch = Opcode.BLTS
|
||||||
"!=" -> Opcode.BEQ
|
|
||||||
"<" -> Opcode.BGES
|
|
||||||
">" -> Opcode.BLES
|
|
||||||
"<=" -> Opcode.BGTS
|
|
||||||
">=" -> Opcode.BLTS
|
|
||||||
else -> throw AssemblyError("weird operator")
|
else -> throw AssemblyError("weird operator")
|
||||||
}
|
}
|
||||||
if (ifElse.elseScope.children.isNotEmpty()) {
|
if (ifElse.elseScope.children.isNotEmpty()) {
|
||||||
// if and else parts
|
// if and else parts
|
||||||
val elseLabel = createLabelName()
|
val elseLabel = createLabelName()
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(
|
if(useCmpi) {
|
||||||
result,
|
result += IRCodeChunk(null, null).also {
|
||||||
IRInstruction(elseBranch, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = elseLabel),
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = compResultReg, immediate = 0)
|
||||||
null
|
it += IRInstruction(elseBranch, labelSymbol = elseLabel)
|
||||||
)
|
}
|
||||||
|
} else
|
||||||
|
addInstr(result, IRInstruction(elseBranch, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, 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)
|
||||||
@ -1236,11 +1302,13 @@ class IRCodeGen(
|
|||||||
} else {
|
} else {
|
||||||
// only if part
|
// only if part
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(
|
if(useCmpi) {
|
||||||
result,
|
result += IRCodeChunk(null, null).also {
|
||||||
IRInstruction(elseBranch, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = afterIfLabel),
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = compResultReg, immediate = 0)
|
||||||
null
|
it += IRInstruction(elseBranch, labelSymbol = afterIfLabel)
|
||||||
)
|
}
|
||||||
|
} else
|
||||||
|
addInstr(result, IRInstruction(elseBranch, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = afterIfLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
result += IRCodeChunk(afterIfLabel, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
}
|
}
|
||||||
@ -1251,26 +1319,31 @@ class IRCodeGen(
|
|||||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||||
val number = (condition.right as? PtNumber)?.number?.toInt()
|
val number = (condition.right as? PtNumber)?.number?.toInt()
|
||||||
if (number!=null) {
|
if (number!=null) {
|
||||||
elseBranchOpcode = when (condition.operator) {
|
val elseBranch: Opcode
|
||||||
"==" -> Opcode.BNE
|
var useCmpi = false // for the branch opcodes that have been converted to CMPI + BSTxx form already
|
||||||
"!=" -> Opcode.BEQ
|
when (condition.operator) {
|
||||||
"<" -> if(signed) Opcode.BGES else Opcode.BGE
|
"==" -> elseBranch = Opcode.BNE
|
||||||
">" -> if(signed) Opcode.BLES else Opcode.BLE
|
"!=" -> {
|
||||||
"<=" -> if(signed) Opcode.BGTS else Opcode.BGT
|
elseBranch = Opcode.BSTEQ
|
||||||
">=" -> if(signed) Opcode.BLTS else Opcode.BLT
|
useCmpi = true
|
||||||
|
}
|
||||||
|
"<" -> elseBranch = if(signed) Opcode.BGES else Opcode.BGE
|
||||||
|
">" -> elseBranch = if(signed) Opcode.BLES else Opcode.BLE
|
||||||
|
"<=" -> elseBranch = if(signed) Opcode.BGTS else Opcode.BGT
|
||||||
|
">=" -> elseBranch = if(signed) Opcode.BLTS else Opcode.BLT
|
||||||
else -> throw AssemblyError("invalid comparison operator")
|
else -> throw AssemblyError("invalid comparison operator")
|
||||||
}
|
}
|
||||||
if (ifElse.elseScope.children.isNotEmpty()) {
|
if (ifElse.elseScope.children.isNotEmpty()) {
|
||||||
// if and else parts
|
// if and else parts
|
||||||
val elseLabel = createLabelName()
|
val elseLabel = createLabelName()
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(
|
if(useCmpi) {
|
||||||
result, IRInstruction(
|
result += IRCodeChunk(null, null).also {
|
||||||
elseBranchOpcode, branchDt,
|
it += IRInstruction(Opcode.CMPI, branchDt, reg1 = leftTr.resultReg, immediate = number)
|
||||||
reg1 = leftTr.resultReg, immediate = number,
|
it += IRInstruction(elseBranch, labelSymbol = elseLabel)
|
||||||
labelSymbol = elseLabel
|
}
|
||||||
), null
|
} else
|
||||||
)
|
addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = leftTr.resultReg, immediate = number, 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)
|
||||||
@ -1278,52 +1351,53 @@ class IRCodeGen(
|
|||||||
} else {
|
} else {
|
||||||
// only if part
|
// only if part
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(
|
if(useCmpi) {
|
||||||
result, IRInstruction(
|
result += IRCodeChunk(null, null).also {
|
||||||
elseBranchOpcode, branchDt,
|
it += IRInstruction(Opcode.CMPI, branchDt, reg1 = leftTr.resultReg, immediate = number)
|
||||||
reg1 = leftTr.resultReg, immediate = number,
|
it += IRInstruction(elseBranch, labelSymbol = afterIfLabel)
|
||||||
labelSymbol = afterIfLabel
|
}
|
||||||
), null
|
} else
|
||||||
)
|
addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = leftTr.resultReg, immediate = number, labelSymbol = afterIfLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
result += IRCodeChunk(afterIfLabel, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val rightTr = expressionEval.translateExpression(condition.right)
|
val rightTr = expressionEval.translateExpression(condition.right)
|
||||||
|
val elseBranch: Opcode
|
||||||
addToResult(result, rightTr, rightTr.resultReg, -1)
|
addToResult(result, rightTr, rightTr.resultReg, -1)
|
||||||
when (condition.operator) {
|
when (condition.operator) {
|
||||||
"==" -> {
|
"==" -> {
|
||||||
elseBranchOpcode = Opcode.BNER
|
elseBranch = Opcode.BNER
|
||||||
elseBranchFirstReg = leftTr.resultReg
|
elseBranchFirstReg = leftTr.resultReg
|
||||||
elseBranchSecondReg = rightTr.resultReg
|
elseBranchSecondReg = rightTr.resultReg
|
||||||
}
|
}
|
||||||
"!=" -> {
|
"!=" -> {
|
||||||
elseBranchOpcode = Opcode.BEQR
|
elseBranch = Opcode.BEQR
|
||||||
elseBranchFirstReg = leftTr.resultReg
|
elseBranchFirstReg = leftTr.resultReg
|
||||||
elseBranchSecondReg = rightTr.resultReg
|
elseBranchSecondReg = rightTr.resultReg
|
||||||
}
|
}
|
||||||
"<" -> {
|
"<" -> {
|
||||||
// else part when left >= right
|
// else part when left >= right
|
||||||
elseBranchOpcode = if (signed) Opcode.BGESR else Opcode.BGER
|
elseBranch = if (signed) Opcode.BGESR else Opcode.BGER
|
||||||
elseBranchFirstReg = leftTr.resultReg
|
elseBranchFirstReg = leftTr.resultReg
|
||||||
elseBranchSecondReg = rightTr.resultReg
|
elseBranchSecondReg = rightTr.resultReg
|
||||||
}
|
}
|
||||||
">" -> {
|
">" -> {
|
||||||
// else part when left <= right --> right >= left
|
// else part when left <= right --> right >= left
|
||||||
elseBranchOpcode = if (signed) Opcode.BGESR else Opcode.BGER
|
elseBranch = if (signed) Opcode.BGESR else Opcode.BGER
|
||||||
elseBranchFirstReg = rightTr.resultReg
|
elseBranchFirstReg = rightTr.resultReg
|
||||||
elseBranchSecondReg = leftTr.resultReg
|
elseBranchSecondReg = leftTr.resultReg
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
// else part when left > right
|
// else part when left > right
|
||||||
elseBranchOpcode = if (signed) Opcode.BGTSR else Opcode.BGTR
|
elseBranch = if (signed) Opcode.BGTSR else Opcode.BGTR
|
||||||
elseBranchFirstReg = leftTr.resultReg
|
elseBranchFirstReg = leftTr.resultReg
|
||||||
elseBranchSecondReg = rightTr.resultReg
|
elseBranchSecondReg = rightTr.resultReg
|
||||||
}
|
}
|
||||||
|
|
||||||
">=" -> {
|
">=" -> {
|
||||||
// else part when left < right --> right > left
|
// else part when left < right --> right > left
|
||||||
elseBranchOpcode = if (signed) Opcode.BGTSR else Opcode.BGTR
|
elseBranch = if (signed) Opcode.BGTSR else Opcode.BGTR
|
||||||
elseBranchFirstReg = rightTr.resultReg
|
elseBranchFirstReg = rightTr.resultReg
|
||||||
elseBranchSecondReg = leftTr.resultReg
|
elseBranchSecondReg = leftTr.resultReg
|
||||||
}
|
}
|
||||||
@ -1333,13 +1407,7 @@ class IRCodeGen(
|
|||||||
// if and else parts
|
// if and else parts
|
||||||
val elseLabel = createLabelName()
|
val elseLabel = createLabelName()
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(
|
addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg, labelSymbol = elseLabel), null)
|
||||||
result, IRInstruction(
|
|
||||||
elseBranchOpcode, 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)
|
||||||
@ -1347,13 +1415,7 @@ class IRCodeGen(
|
|||||||
} else {
|
} else {
|
||||||
// only if part
|
// only if part
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(
|
addInstr(result, IRInstruction(elseBranch, branchDt, reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg, labelSymbol = afterIfLabel), null)
|
||||||
result, IRInstruction(
|
|
||||||
elseBranchOpcode, branchDt,
|
|
||||||
reg1 = elseBranchFirstReg, reg2 = elseBranchSecondReg,
|
|
||||||
labelSymbol = afterIfLabel
|
|
||||||
), null
|
|
||||||
)
|
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
result += IRCodeChunk(afterIfLabel, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
}
|
}
|
||||||
@ -1524,7 +1586,10 @@ class IRCodeGen(
|
|||||||
addToResult(result, countTr, countTr.resultReg, -1)
|
addToResult(result, countTr, countTr.resultReg, -1)
|
||||||
if(constIntValue(repeat.count)==null) {
|
if(constIntValue(repeat.count)==null) {
|
||||||
// check if the counter is already zero
|
// check if the counter is already zero
|
||||||
addInstr(result, IRInstruction(Opcode.BEQ, irDt, reg1=countTr.resultReg, immediate = 0, labelSymbol = skipRepeatLabel), null)
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.CMPI, irDt, reg1=countTr.resultReg, immediate = 0)
|
||||||
|
it += IRInstruction(Opcode.BSTEQ, labelSymbol = skipRepeatLabel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
|
@ -1,20 +1,12 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
%import floats
|
||||||
|
|
||||||
main {
|
main {
|
||||||
ubyte begin = 10
|
|
||||||
ubyte end = 20
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte xx
|
float xx = 10.1
|
||||||
for xx in begin to end step 3 {
|
ubyte yy= xx==10.1
|
||||||
txt.print_ub(xx)
|
txt.print_ub(yy)
|
||||||
txt.spc()
|
if xx==10.1
|
||||||
}
|
txt.print("equal")
|
||||||
txt.nl()
|
|
||||||
for xx in end to begin step -3 {
|
|
||||||
txt.print_ub(xx)
|
|
||||||
txt.spc()
|
|
||||||
}
|
|
||||||
txt.nl()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,6 @@ bstneg address - branch to location if Status bit Negat
|
|||||||
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
|
beqr reg1, reg2, address - jump to location in program given by location, if reg1 == reg2
|
||||||
beq reg1, value, address - jump to location in program given by location, if reg1 == immediate value
|
|
||||||
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
|
||||||
bne reg1, value, address - jump to location in program given by location, if reg1 != immediate value
|
bne reg1, value, address - jump to location in program given by location, if reg1 != immediate value
|
||||||
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)
|
||||||
@ -262,7 +261,6 @@ enum class Opcode {
|
|||||||
BSTVC,
|
BSTVC,
|
||||||
BSTVS,
|
BSTVS,
|
||||||
BEQR,
|
BEQR,
|
||||||
BEQ,
|
|
||||||
BNER,
|
BNER,
|
||||||
BNE,
|
BNE,
|
||||||
BGTR,
|
BGTR,
|
||||||
@ -408,7 +406,6 @@ val OpcodesThatBranch = setOf(
|
|||||||
Opcode.BSTVC,
|
Opcode.BSTVC,
|
||||||
Opcode.BSTVS,
|
Opcode.BSTVS,
|
||||||
Opcode.BEQR,
|
Opcode.BEQR,
|
||||||
Opcode.BEQ,
|
|
||||||
Opcode.BNER,
|
Opcode.BNER,
|
||||||
Opcode.BNE,
|
Opcode.BNE,
|
||||||
Opcode.BGTR,
|
Opcode.BGTR,
|
||||||
@ -559,7 +556,6 @@ val instructionFormats = mutableMapOf(
|
|||||||
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.BEQR to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||||
Opcode.BEQ to InstructionFormat.from("BW,<r1,<i,<a"),
|
|
||||||
Opcode.BNER to InstructionFormat.from("BW,<r1,<r2,<a"),
|
Opcode.BNER to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||||
Opcode.BNE to InstructionFormat.from("BW,<r1,<i,<a"),
|
Opcode.BNE to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||||
Opcode.BGTR to InstructionFormat.from("BW,<r1,<r2,<a"),
|
Opcode.BGTR to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||||
|
@ -23,10 +23,10 @@ class TestInstructions: FunSpec({
|
|||||||
}
|
}
|
||||||
|
|
||||||
test("with value") {
|
test("with value") {
|
||||||
val ins = IRInstruction(Opcode.BEQ, IRDataType.BYTE, reg1=42, immediate = 0, address = 99)
|
val ins = IRInstruction(Opcode.ADD, IRDataType.BYTE, reg1=42, immediate = 0, address = 99)
|
||||||
ins.opcode shouldBe Opcode.BEQ
|
ins.opcode shouldBe Opcode.ADD
|
||||||
ins.type shouldBe IRDataType.BYTE
|
ins.type shouldBe IRDataType.BYTE
|
||||||
ins.reg1direction shouldBe OperandDirection.READ
|
ins.reg1direction shouldBe OperandDirection.READWRITE
|
||||||
ins.fpReg1direction shouldBe OperandDirection.UNUSED
|
ins.fpReg1direction shouldBe OperandDirection.UNUSED
|
||||||
ins.reg1 shouldBe 42
|
ins.reg1 shouldBe 42
|
||||||
ins.reg2 shouldBe null
|
ins.reg2 shouldBe null
|
||||||
@ -34,14 +34,14 @@ class TestInstructions: FunSpec({
|
|||||||
ins.immediate shouldBe 0
|
ins.immediate shouldBe 0
|
||||||
ins.immediateFp shouldBe null
|
ins.immediateFp shouldBe null
|
||||||
ins.labelSymbol shouldBe null
|
ins.labelSymbol shouldBe null
|
||||||
ins.toString() shouldBe "beq.b r42,0,$63"
|
ins.toString() shouldBe "add.b r42,0,$63"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("with label") {
|
test("with label") {
|
||||||
val ins = IRInstruction(Opcode.BEQ, IRDataType.WORD, reg1=11, immediate = 0, labelSymbol = "a.b.c")
|
val ins = IRInstruction(Opcode.ADD, IRDataType.WORD, reg1=11, immediate = 0, labelSymbol = "a.b.c")
|
||||||
ins.opcode shouldBe Opcode.BEQ
|
ins.opcode shouldBe Opcode.ADD
|
||||||
ins.type shouldBe IRDataType.WORD
|
ins.type shouldBe IRDataType.WORD
|
||||||
ins.reg1direction shouldBe OperandDirection.READ
|
ins.reg1direction shouldBe OperandDirection.READWRITE
|
||||||
ins.fpReg1direction shouldBe OperandDirection.UNUSED
|
ins.fpReg1direction shouldBe OperandDirection.UNUSED
|
||||||
ins.reg1 shouldBe 11
|
ins.reg1 shouldBe 11
|
||||||
ins.reg2 shouldBe null
|
ins.reg2 shouldBe null
|
||||||
@ -49,7 +49,7 @@ class TestInstructions: FunSpec({
|
|||||||
ins.immediate shouldBe 0
|
ins.immediate shouldBe 0
|
||||||
ins.immediateFp shouldBe null
|
ins.immediateFp shouldBe null
|
||||||
ins.labelSymbol shouldBe "a.b.c"
|
ins.labelSymbol shouldBe "a.b.c"
|
||||||
ins.toString() shouldBe "beq.w r11,0,a.b.c"
|
ins.toString() shouldBe "add.w r11,0,a.b.c"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("with output registers") {
|
test("with output registers") {
|
||||||
@ -106,19 +106,19 @@ class TestInstructions: FunSpec({
|
|||||||
|
|
||||||
test("missing type should fail") {
|
test("missing type should fail") {
|
||||||
shouldThrow<IllegalArgumentException> {
|
shouldThrow<IllegalArgumentException> {
|
||||||
IRInstruction(Opcode.BEQ, reg1=42, address=99)
|
IRInstruction(Opcode.ADD, reg1=42, address=99)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("missing registers should fail") {
|
test("missing registers should fail") {
|
||||||
shouldThrowWithMessage<IllegalArgumentException>("missing reg1") {
|
shouldThrowWithMessage<IllegalArgumentException>("missing reg1") {
|
||||||
IRInstruction(Opcode.BEQ, IRDataType.BYTE, immediate = 0, address=99)
|
IRInstruction(Opcode.ADD, IRDataType.BYTE, immediate = 0, address=99)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("missing address should fail") {
|
test("missing address should fail") {
|
||||||
shouldThrowWithMessage<IllegalArgumentException>("missing an address or labelsymbol") {
|
shouldThrowWithMessage<IllegalArgumentException>("missing an address or labelsymbol") {
|
||||||
IRInstruction(Opcode.BEQ, IRDataType.BYTE, immediate = 0, reg1=42)
|
IRInstruction(Opcode.INCM, IRDataType.BYTE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +197,6 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
Opcode.BGTSR -> InsBGTSR(ins)
|
Opcode.BGTSR -> InsBGTSR(ins)
|
||||||
Opcode.BGER -> InsBGER(ins)
|
Opcode.BGER -> InsBGER(ins)
|
||||||
Opcode.BGESR -> InsBGESR(ins)
|
Opcode.BGESR -> InsBGESR(ins)
|
||||||
Opcode.BEQ -> InsBEQ(ins)
|
|
||||||
Opcode.BNE -> InsBNE(ins)
|
Opcode.BNE -> InsBNE(ins)
|
||||||
Opcode.BGT -> InsBGT(ins)
|
Opcode.BGT -> InsBGT(ins)
|
||||||
Opcode.BLT -> InsBLT(ins)
|
Opcode.BLT -> InsBLT(ins)
|
||||||
@ -679,14 +678,6 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
nextPc()
|
nextPc()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsBEQ(i: IRInstruction) {
|
|
||||||
val (left: UInt, right: UInt) = getBranchOperandsImmU(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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user