mirror of
https://github.com/irmen/prog8.git
synced 2024-10-16 03:24:05 +00:00
improved asm generation for conditions that compare ubyte/uword to zero
This commit is contained in:
parent
2df0c9503c
commit
2388359a99
@ -59,7 +59,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rightConstVal!=null && rightConstVal.number.toDouble() == 0.0)
|
if (rightConstVal!=null && rightConstVal.number.toDouble() == 0.0)
|
||||||
jumpIfZeroOrNot(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
jumpIfZeroOrNot(left, operator, jumpIfFalseLabel)
|
||||||
else
|
else
|
||||||
jumpIfComparison(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
jumpIfComparison(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
||||||
}
|
}
|
||||||
@ -67,71 +67,46 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
private fun jumpIfZeroOrNot(
|
private fun jumpIfZeroOrNot(
|
||||||
left: Expression,
|
left: Expression,
|
||||||
operator: String,
|
operator: String,
|
||||||
right: Expression,
|
jumpIfFalseLabel: String
|
||||||
jumpIfFalseLabel: String,
|
|
||||||
leftConstVal: NumericLiteralValue?,
|
|
||||||
rightConstVal: NumericLiteralValue?
|
|
||||||
) {
|
) {
|
||||||
when(left.inferType(program).getOr(DataType.UNDEFINED)) {
|
when(val dt = left.inferType(program).getOr(DataType.UNDEFINED)) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {
|
DataType.UBYTE, DataType.UWORD -> {
|
||||||
asmgen.assignExpressionToRegister(left, RegisterOrPair.A)
|
if(operator=="<") {
|
||||||
if (left is FunctionCall && !left.isSimple)
|
asmgen.out(" jmp $jumpIfFalseLabel")
|
||||||
asmgen.out(" cmp #0")
|
return
|
||||||
|
} else if(operator==">=") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(dt==DataType.UBYTE) {
|
||||||
|
asmgen.assignExpressionToRegister(left, RegisterOrPair.A)
|
||||||
|
if (left is FunctionCall && !left.isSimple)
|
||||||
|
asmgen.out(" cmp #0")
|
||||||
|
} else {
|
||||||
|
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
|
||||||
|
asmgen.out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1")
|
||||||
|
}
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"==" -> {
|
"==" -> asmgen.out(" bne $jumpIfFalseLabel")
|
||||||
asmgen.out(" bne $jumpIfFalseLabel")
|
"!=" -> asmgen.out(" beq $jumpIfFalseLabel")
|
||||||
}
|
">" -> asmgen.out(" beq $jumpIfFalseLabel")
|
||||||
"!=" -> {
|
"<=" -> asmgen.out(" bne $jumpIfFalseLabel")
|
||||||
asmgen.out(" beq $jumpIfFalseLabel")
|
else -> throw AssemblyError("invalid comparison operator $operator")
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// TODO optimize byte other operators
|
|
||||||
jumpIfComparison(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.BYTE, DataType.WORD -> {
|
||||||
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
|
TODO("signed BYTE/UWORD comparison $operator")
|
||||||
asmgen.out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1")
|
|
||||||
when (operator) {
|
|
||||||
"==" -> {
|
|
||||||
asmgen.out(" bne $jumpIfFalseLabel")
|
|
||||||
}
|
|
||||||
"!=" -> {
|
|
||||||
asmgen.out(" beq $jumpIfFalseLabel")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// TODO optimize word other operators
|
|
||||||
jumpIfComparison(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1)
|
asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1)
|
||||||
asmgen.out(" jsr floats.SIGN")
|
asmgen.out(" jsr floats.SIGN") // SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"==" -> {
|
"==" -> asmgen.out(" bne $jumpIfFalseLabel")
|
||||||
// SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive
|
"!=" -> asmgen.out(" beq $jumpIfFalseLabel")
|
||||||
asmgen.out(" bne $jumpIfFalseLabel")
|
">" -> asmgen.out(" bmi $jumpIfFalseLabel | beq $jumpIfFalseLabel")
|
||||||
}
|
"<" -> asmgen.out(" bpl $jumpIfFalseLabel")
|
||||||
"!=" -> {
|
">=" -> asmgen.out(" bmi $jumpIfFalseLabel")
|
||||||
asmgen.out(" beq $jumpIfFalseLabel")
|
"<=" -> asmgen.out(" cmp #1 | beq $jumpIfFalseLabel")
|
||||||
}
|
else -> throw AssemblyError("invalid comparison operator $operator")
|
||||||
">" -> {
|
|
||||||
asmgen.out(" bmi $jumpIfFalseLabel | beq $jumpIfFalseLabel")
|
|
||||||
}
|
|
||||||
"<" -> {
|
|
||||||
asmgen.out(" bpl $jumpIfFalseLabel")
|
|
||||||
}
|
|
||||||
">=" -> {
|
|
||||||
asmgen.out(" bmi $jumpIfFalseLabel")
|
|
||||||
}
|
|
||||||
"<=" -> {
|
|
||||||
asmgen.out(" cmp #1 | beq $jumpIfFalseLabel")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
throw AssemblyError("invalid comparison operator $operator")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
%import floats
|
|
||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
@ -6,76 +5,75 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte xx
|
ubyte xx
|
||||||
float ff
|
|
||||||
|
|
||||||
ff=0
|
xx=0
|
||||||
|
|
||||||
if ff>=0 {
|
if xx>=0 {
|
||||||
txt.print("ff>=0\n")
|
txt.print("xx>=0\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("error1\n")
|
txt.print("error1\n")
|
||||||
}
|
}
|
||||||
if ff<=0 {
|
if xx<=0 {
|
||||||
txt.print("ff<=0\n")
|
txt.print("xx<=0\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("error1\n")
|
txt.print("error1\n")
|
||||||
}
|
}
|
||||||
if ff>0 {
|
if xx>0 {
|
||||||
txt.print("ff>0 error\n")
|
txt.print("xx>0 error\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("ok1\n")
|
txt.print("ok1\n")
|
||||||
}
|
}
|
||||||
if ff<0 {
|
if xx<0 {
|
||||||
txt.print("ff<0 error\n")
|
txt.print("xx<0 error\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("ok1\n")
|
txt.print("ok1\n")
|
||||||
}
|
}
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
ff=0.22
|
xx=22
|
||||||
if ff>=0 {
|
if xx>=0 {
|
||||||
txt.print("ff>=0\n")
|
txt.print("xx>=0\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("error2\n")
|
txt.print("error2\n")
|
||||||
}
|
}
|
||||||
if ff<=0 {
|
if xx<=0 {
|
||||||
txt.print("ff<=0 error\n")
|
txt.print("xx<=0 error\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("ok2\n")
|
txt.print("ok2\n")
|
||||||
}
|
}
|
||||||
if ff>0 {
|
if xx>0 {
|
||||||
txt.print("ff>0\n")
|
txt.print("xx>0\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("error2\n")
|
txt.print("error2\n")
|
||||||
}
|
}
|
||||||
if ff<0 {
|
if xx<0 {
|
||||||
txt.print("ff<0 error\n")
|
txt.print("xx<0 error\n")
|
||||||
} else {
|
} else {
|
||||||
txt.print("ok2\n")
|
txt.print("ok2\n")
|
||||||
}
|
}
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
ff=-1.11
|
; xx=-11
|
||||||
if ff>=0 {
|
; if xx>=0 {
|
||||||
txt.print("ff>=0 error\n")
|
; txt.print("xx>=0 error\n")
|
||||||
} else {
|
; } else {
|
||||||
txt.print("ok3\n")
|
; txt.print("ok3\n")
|
||||||
}
|
; }
|
||||||
if ff<=0 {
|
; if xx<=0 {
|
||||||
txt.print("ff<=0\n")
|
; txt.print("xx<=0\n")
|
||||||
} else {
|
; } else {
|
||||||
txt.print("error3\n")
|
; txt.print("error3\n")
|
||||||
}
|
; }
|
||||||
if ff>0 {
|
; if xx>0 {
|
||||||
txt.print("ff>0 error\n")
|
; txt.print("xx>0 error\n")
|
||||||
} else {
|
; } else {
|
||||||
txt.print("ok3\n")
|
; txt.print("ok3\n")
|
||||||
}
|
; }
|
||||||
if ff<0 {
|
; if xx<0 {
|
||||||
txt.print("ff<0\n")
|
; txt.print("xx<0\n")
|
||||||
} else {
|
; } else {
|
||||||
txt.print("error3\n")
|
; txt.print("error3\n")
|
||||||
}
|
; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user