fix IR translateIfElseZeroComparison for ints + floats

This commit is contained in:
Irmen de Jong 2023-03-07 21:26:34 +01:00
parent fd07ae5225
commit 95f498ba9b
2 changed files with 48 additions and 31 deletions

View File

@ -961,42 +961,59 @@ 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 elseBranch: Opcode
val compResultReg: Int
if(irDtLeft==IRDataType.FLOAT) { if(irDtLeft==IRDataType.FLOAT) {
TODO("float zero compare via fcomp instruction") val leftFpReg = registers.nextFreeFloat()
val rightFpReg = registers.nextFreeFloat()
compResultReg = registers.nextFree()
result += expressionEval.translateExpression(ifElse.condition.left, -1, leftFpReg)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, fpValue = 0f)
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
}
elseBranch = when (ifElse.condition.operator) {
"==" -> Opcode.BNZ
"!=" -> Opcode.BZ
"<" -> Opcode.BGEZS
">" -> Opcode.BLEZS
"<=" -> Opcode.BGZS
">=" -> Opcode.BLZS
else -> throw AssemblyError("weird operator")
}
} else { } else {
// integer comparisons // integer comparisons
fun equalOrNotEqualZero(elseBranch: Opcode): IRCodeChunks { compResultReg = registers.nextFree()
val result = mutableListOf<IRCodeChunkBase>() result += expressionEval.translateExpression(ifElse.condition.left, compResultReg, -1)
val leftReg = registers.nextFree() elseBranch = when (ifElse.condition.operator) {
result += expressionEval.translateExpression(ifElse.condition.left, leftReg, -1) "==" -> Opcode.BNZ
if(ifElse.elseScope.children.isNotEmpty()) { "!=" -> Opcode.BZ
// if and else parts "<" -> if (signed) Opcode.BGEZS else throw AssemblyError("unsigned < 0 shouldn't occur in codegen")
val elseLabel = createLabelName() ">" -> if (signed) Opcode.BLEZS else throw AssemblyError("unsigned > 0 shouldn't occur in codegen")
val afterIfLabel = createLabelName() "<=" -> if (signed) Opcode.BGZS else throw AssemblyError("unsigned <= 0 shouldn't occur in codegen")
addInstr(result, IRInstruction(elseBranch, irDtLeft, reg1=leftReg, labelSymbol = elseLabel), null) ">=" -> if (signed) Opcode.BLZS else throw AssemblyError("unsigned >= 0 shouldn't occur in codegen")
result += translateNode(ifElse.ifScope)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
result += IRCodeChunk(afterIfLabel, null)
} else {
// only if part
val afterIfLabel = createLabelName()
addInstr(result, IRInstruction(elseBranch, irDtLeft, reg1=leftReg, labelSymbol = afterIfLabel), null)
result += translateNode(ifElse.ifScope)
result += IRCodeChunk(afterIfLabel, null)
}
return result
}
return when (ifElse.condition.operator) {
"==" -> equalOrNotEqualZero(Opcode.BNZ)
"!=" -> equalOrNotEqualZero(Opcode.BZ)
"<" -> if (signed) equalOrNotEqualZero(Opcode.BGEZS) else throw AssemblyError("unsigned < 0 shouldn't occur in codegen")
">" -> if (signed) equalOrNotEqualZero(Opcode.BLEZS) else throw AssemblyError("unsigned > 0 shouldn't occur in codegen")
"<=" -> if (signed) equalOrNotEqualZero(Opcode.BGZS) else throw AssemblyError("unsigned <= 0 shouldn't occur in codegen")
">=" -> if (signed) equalOrNotEqualZero(Opcode.BLZS) else throw AssemblyError("unsigned >= 0 shouldn't occur in codegen")
else -> throw AssemblyError("weird operator") else -> throw AssemblyError("weird operator")
} }
} }
if(ifElse.elseScope.children.isEmpty()) {
// just if
val afterIfLabel = createLabelName()
addInstr(result, IRInstruction(elseBranch, IRDataType.BYTE, reg1=compResultReg, labelSymbol = afterIfLabel), null)
result += translateNode(ifElse.ifScope)
result += IRCodeChunk(afterIfLabel, null)
} else {
// if and else
val elseLabel = createLabelName()
val afterIfLabel = createLabelName()
addInstr(result, IRInstruction(elseBranch, IRDataType.BYTE, reg1=compResultReg, labelSymbol = elseLabel), null)
result += translateNode(ifElse.ifScope)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
result += IRCodeChunk(afterIfLabel, null)
}
return result
} }
private fun translateIfElseNonZeroComparison(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks { private fun translateIfElseNonZeroComparison(ifElse: PtIfElse, irDtLeft: IRDataType, signed: Boolean): IRCodeChunks {

View File

@ -184,7 +184,7 @@ ftouw reg1, fpreg1 - reg1 = fpreg1 as unsigned word
ftosw reg1, fpreg1 - reg1 = fpreg1 as signed word ftosw reg1, fpreg1 - reg1 = fpreg1 as signed word
fpow fpreg1, fpreg2 - fpreg1 = fpreg1 to the power of fpreg2 fpow fpreg1, fpreg2 - fpreg1 = fpreg1 to the power of fpreg2
fabs fpreg1, fpreg2 - fpreg1 = abs(fpreg2) fabs fpreg1, fpreg2 - fpreg1 = abs(fpreg2)
fcomp reg1, fpreg1, fpreg2 - reg1 = result of comparison of fpreg1 and fpreg2: 0=equal, 1=fpreg1 is greater, -1=fpreg1 is smaller fcomp reg1, fpreg1, fpreg2 - reg1 = result of comparison of fpreg1 and fpreg2: 0.b=equal, 1.b=fpreg1 is greater, -1.b=fpreg1 is smaller
fsin fpreg1, fpreg2 - fpreg1 = sin(fpreg2) fsin fpreg1, fpreg2 - fpreg1 = sin(fpreg2)
fcos fpreg1, fpreg2 - fpreg1 = cos(fpreg2) fcos fpreg1, fpreg2 - fpreg1 = cos(fpreg2)
ftan fpreg1, fpreg2 - fpreg1 = tan(fpreg2) ftan fpreg1, fpreg2 - fpreg1 = tan(fpreg2)