mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
fix IR translateIfElseZeroComparison for ints + floats
This commit is contained in:
parent
fd07ae5225
commit
95f498ba9b
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user