mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 03:54:27 +00:00
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:
parent
1e6fa77633
commit
a7df094ff4
@ -72,27 +72,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
is PtTypeCast -> {
|
is PtTypeCast -> translate(expr, resultRegister, resultFpRegister)
|
||||||
translate(expr, resultRegister, resultFpRegister)
|
is PtPrefix -> translate(expr, resultRegister, resultFpRegister)
|
||||||
}
|
is PtArrayIndexer -> translate(expr, resultRegister, resultFpRegister)
|
||||||
is PtPrefix -> {
|
is PtBinaryExpression -> translate(expr, resultRegister, resultFpRegister)
|
||||||
translate(expr, resultRegister, resultFpRegister)
|
is PtBuiltinFunctionCall -> codeGen.translateBuiltinFunc(expr, resultRegister)
|
||||||
}
|
is PtFunctionCall -> translate(expr, resultRegister, resultFpRegister)
|
||||||
is PtArrayIndexer -> {
|
is PtContainmentCheck -> translate(expr, resultRegister, resultFpRegister)
|
||||||
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 PtRange,
|
||||||
is PtArray,
|
is PtArray,
|
||||||
is PtString -> throw AssemblyError("range/arrayliteral/string should no longer occur as expression")
|
is PtString -> throw AssemblyError("range/arrayliteral/string should no longer occur as expression")
|
||||||
@ -429,6 +415,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
it += IRInstruction(Opcode.INV, vmDt, reg1 = resultRegister)
|
it += IRInstruction(Opcode.INV, vmDt, reg1 = resultRegister)
|
||||||
it += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value = 1)
|
it += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value = 1)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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 {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
@ -437,6 +428,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,6 +835,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
else if(expr.operator == "~") {
|
else if(expr.operator == "~") {
|
||||||
if(dt !in IntegerDatatypes)
|
if(dt !in IntegerDatatypes)
|
||||||
errors.err("can only use bitwise invert on integer types", expr.position)
|
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)
|
super.visit(expr)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ For next release
|
|||||||
- make sure bool value is always 0 or 1 (all casts should convert), then:
|
- make sure bool value is always 0 or 1 (all casts should convert), then:
|
||||||
- rewrite bool=bool^1 into bool=not bool
|
- rewrite bool=bool^1 into bool=not bool
|
||||||
- should solve: bool bb = not bb -> larger code than bool bb ^= 1
|
- should solve: bool bb = not bb -> larger code than bool bb ^= 1
|
||||||
- should solve: bool xx = ~xx -> larger code than xx ^= 1
|
|
||||||
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -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)
|
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)
|
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.)
|
( 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
|
sz reg1, reg2 - set reg1=1 if reg2==0, otherwise set reg1=0
|
||||||
sne reg1, reg2 - set reg=1 if reg1 != reg2, otherwise set reg1=0
|
snz reg1, reg2 - set reg1=1 if reg2!=0, otherwise set reg1=0
|
||||||
slt reg1, reg2 - set reg=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
|
seq reg1, reg2 - set reg1=1 if reg1 == reg2, otherwise set reg1=0
|
||||||
slts reg1, reg2 - set reg=1 if reg1 < reg2 (signed), otherwise set reg1=0
|
sne reg1, reg2 - set reg1=1 if reg1 != reg2, otherwise set reg1=0
|
||||||
sle reg1, reg2 - set reg=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
|
slt reg1, reg2 - set reg1=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
|
||||||
sles reg1, reg2 - set reg=1 if reg1 <= reg2 (signed), otherwise set reg1=0
|
slts reg1, reg2 - set reg1=1 if reg1 < reg2 (signed), otherwise set reg1=0
|
||||||
sgt reg1, reg2 - set reg=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
|
sle reg1, reg2 - set reg1=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
|
||||||
sgts reg1, reg2 - set reg=1 if reg1 > reg2 (signed), otherwise set reg1=0
|
sles reg1, reg2 - set reg1=1 if reg1 <= reg2 (signed), otherwise set reg1=0
|
||||||
sge reg1, reg2 - set reg=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
|
sgt reg1, reg2 - set reg1=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
|
||||||
sges reg1, reg2 - set reg=1 if reg1 >= reg2 (signed), 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
|
ARITHMETIC
|
||||||
@ -253,6 +255,8 @@ enum class Opcode {
|
|||||||
BGTS,
|
BGTS,
|
||||||
BGE,
|
BGE,
|
||||||
BGES,
|
BGES,
|
||||||
|
SZ,
|
||||||
|
SNZ,
|
||||||
SEQ,
|
SEQ,
|
||||||
SNE,
|
SNE,
|
||||||
SLT,
|
SLT,
|
||||||
@ -569,6 +573,8 @@ val instructionFormats = mutableMapOf(
|
|||||||
Opcode.BGTS to InstructionFormat.from("BW,<r1,<r2,<v"),
|
Opcode.BGTS to InstructionFormat.from("BW,<r1,<r2,<v"),
|
||||||
Opcode.BGE 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.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.SEQ to InstructionFormat.from("BW,<>r1,<r2"),
|
||||||
Opcode.SNE to InstructionFormat.from("BW,<>r1,<r2"),
|
Opcode.SNE to InstructionFormat.from("BW,<>r1,<r2"),
|
||||||
Opcode.SLT to InstructionFormat.from("BW,<>r1,<r2"),
|
Opcode.SLT to InstructionFormat.from("BW,<>r1,<r2"),
|
||||||
|
@ -186,6 +186,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
Opcode.BGTS -> InsBGTS(ins)
|
Opcode.BGTS -> InsBGTS(ins)
|
||||||
Opcode.BGE -> InsBGEU(ins)
|
Opcode.BGE -> InsBGEU(ins)
|
||||||
Opcode.BGES -> InsBGES(ins)
|
Opcode.BGES -> InsBGES(ins)
|
||||||
|
Opcode.SZ -> InsSZ(ins)
|
||||||
|
Opcode.SNZ -> InsSNZ(ins)
|
||||||
Opcode.SEQ -> InsSEQ(ins)
|
Opcode.SEQ -> InsSEQ(ins)
|
||||||
Opcode.SNE -> InsSNE(ins)
|
Opcode.SNE -> InsSNE(ins)
|
||||||
Opcode.SLT -> InsSLT(ins)
|
Opcode.SLT -> InsSLT(ins)
|
||||||
@ -782,6 +784,20 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
nextPc()
|
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) {
|
private fun InsSEQ(i: IRInstruction) {
|
||||||
val (left: Int, right: Int) = getSetOnConditionOperands(i)
|
val (left: Int, right: Int) = getSetOnConditionOperands(i)
|
||||||
val value = if(left==right) 1 else 0
|
val value = if(left==right) 1 else 0
|
||||||
|
Loading…
Reference in New Issue
Block a user