don't allow ~ on booleans, also introduce SZ and SNZ instructions in IR to complete the conditional-set instruction list.

This commit is contained in:
Irmen de Jong 2022-12-28 21:19:38 +01:00
parent 1e6fa77633
commit a7df094ff4
5 changed files with 52 additions and 37 deletions

View File

@ -72,27 +72,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
result
}
is PtTypeCast -> {
translate(expr, resultRegister, resultFpRegister)
}
is PtPrefix -> {
translate(expr, resultRegister, resultFpRegister)
}
is PtArrayIndexer -> {
translate(expr, resultRegister, resultFpRegister)
}
is PtBinaryExpression -> {
translate(expr, resultRegister, resultFpRegister)
}
is PtBuiltinFunctionCall -> {
codeGen.translateBuiltinFunc(expr, resultRegister)
}
is PtFunctionCall -> {
translate(expr, resultRegister, resultFpRegister)
}
is PtContainmentCheck -> {
translate(expr, resultRegister, resultFpRegister)
}
is PtTypeCast -> translate(expr, resultRegister, resultFpRegister)
is PtPrefix -> translate(expr, resultRegister, resultFpRegister)
is PtArrayIndexer -> translate(expr, resultRegister, resultFpRegister)
is PtBinaryExpression -> translate(expr, resultRegister, resultFpRegister)
is PtBuiltinFunctionCall -> codeGen.translateBuiltinFunc(expr, resultRegister)
is PtFunctionCall -> translate(expr, resultRegister, resultFpRegister)
is PtContainmentCheck -> translate(expr, resultRegister, resultFpRegister)
is PtRange,
is PtArray,
is PtString -> throw AssemblyError("range/arrayliteral/string should no longer occur as expression")
@ -430,11 +416,17 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
it += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value = 1)
}
} else {
val rightResultReg = codeGen.registers.nextFree()
result += translateExpression(binExpr.left, resultRegister, -1)
result += translateExpression(binExpr.right, rightResultReg, -1)
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
if(constValue(binExpr.right)==0.0) {
result += translateExpression(binExpr.left, resultRegister, -1)
val opcode = if (notEquals) Opcode.SNZ else Opcode.SZ
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = resultRegister), null)
} else {
val rightResultReg = codeGen.registers.nextFree()
result += translateExpression(binExpr.left, resultRegister, -1)
result += translateExpression(binExpr.right, rightResultReg, -1)
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
}
}
}
return result

View File

@ -835,6 +835,8 @@ internal class AstChecker(private val program: Program,
else if(expr.operator == "~") {
if(dt !in IntegerDatatypes)
errors.err("can only use bitwise invert on integer types", expr.position)
if(dt==DataType.BOOL)
errors.err("bitwise invert is for integer types, use 'not' on booleans", expr.position)
}
super.visit(expr)
}

View File

@ -6,7 +6,6 @@ For next release
- make sure bool value is always 0 or 1 (all casts should convert), then:
- rewrite bool=bool^1 into bool=not bool
- should solve: bool bb = not bb -> larger code than bool bb ^= 1
- should solve: bool xx = ~xx -> larger code than xx ^= 1
...

View File

@ -85,16 +85,18 @@ bgts reg1, reg2, address - jump to location in program given by l
bge reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (unsigned)
bges reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (signed)
( NOTE: there are no blt/ble instructions because these are equivalent to bgt/bge with the operands swapped around.)
seq reg1, reg2 - set reg=1 if reg1 == reg2, otherwise set reg1=0
sne reg1, reg2 - set reg=1 if reg1 != reg2, otherwise set reg1=0
slt reg1, reg2 - set reg=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
slts reg1, reg2 - set reg=1 if reg1 < reg2 (signed), otherwise set reg1=0
sle reg1, reg2 - set reg=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
sles reg1, reg2 - set reg=1 if reg1 <= reg2 (signed), otherwise set reg1=0
sgt reg1, reg2 - set reg=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
sgts reg1, reg2 - set reg=1 if reg1 > reg2 (signed), otherwise set reg1=0
sge reg1, reg2 - set reg=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
sges reg1, reg2 - set reg=1 if reg1 >= reg2 (signed), otherwise set reg1=0
sz reg1, reg2 - set reg1=1 if reg2==0, otherwise set reg1=0
snz reg1, reg2 - set reg1=1 if reg2!=0, otherwise set reg1=0
seq reg1, reg2 - set reg1=1 if reg1 == reg2, otherwise set reg1=0
sne reg1, reg2 - set reg1=1 if reg1 != reg2, otherwise set reg1=0
slt reg1, reg2 - set reg1=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
slts reg1, reg2 - set reg1=1 if reg1 < reg2 (signed), otherwise set reg1=0
sle reg1, reg2 - set reg1=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
sles reg1, reg2 - set reg1=1 if reg1 <= reg2 (signed), otherwise set reg1=0
sgt reg1, reg2 - set reg1=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
sgts reg1, reg2 - set reg1=1 if reg1 > reg2 (signed), otherwise set reg1=0
sge reg1, reg2 - set reg1=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
sges reg1, reg2 - set reg1=1 if reg1 >= reg2 (signed), otherwise set reg1=0
ARITHMETIC
@ -253,6 +255,8 @@ enum class Opcode {
BGTS,
BGE,
BGES,
SZ,
SNZ,
SEQ,
SNE,
SLT,
@ -569,6 +573,8 @@ val instructionFormats = mutableMapOf(
Opcode.BGTS to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BGE to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.BGES to InstructionFormat.from("BW,<r1,<r2,<v"),
Opcode.SZ to InstructionFormat.from("BW,>r1,<r2"),
Opcode.SNZ to InstructionFormat.from("BW,>r1,<r2"),
Opcode.SEQ to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.SNE to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.SLT to InstructionFormat.from("BW,<>r1,<r2"),

View File

@ -186,6 +186,8 @@ class VirtualMachine(irProgram: IRProgram) {
Opcode.BGTS -> InsBGTS(ins)
Opcode.BGE -> InsBGEU(ins)
Opcode.BGES -> InsBGES(ins)
Opcode.SZ -> InsSZ(ins)
Opcode.SNZ -> InsSNZ(ins)
Opcode.SEQ -> InsSEQ(ins)
Opcode.SNE -> InsSNE(ins)
Opcode.SLT -> InsSLT(ins)
@ -782,6 +784,20 @@ class VirtualMachine(irProgram: IRProgram) {
nextPc()
}
private fun InsSZ(i: IRInstruction) {
val (_: Int, right: Int) = getSetOnConditionOperands(i)
val value = if(right==0) 1 else 0
setResultReg(i.reg1!!, value, i.type!!)
nextPc()
}
private fun InsSNZ(i: IRInstruction) {
val (_: Int, right: Int) = getSetOnConditionOperands(i)
val value = if(right!=0) 1 else 0
setResultReg(i.reg1!!, value, i.type!!)
nextPc()
}
private fun InsSEQ(i: IRInstruction) {
val (left: Int, right: Int) = getSetOnConditionOperands(i)
val value = if(left==right) 1 else 0