optimized float var equality comparison without translateExpression()

This commit is contained in:
Irmen de Jong 2020-11-22 13:56:23 +01:00
parent 8efe4c6267
commit 49db10539a
3 changed files with 126 additions and 66 deletions

View File

@ -380,6 +380,36 @@ neg_f .proc
rts rts
.pend .pend
vars_equal_f .proc
; -- are the mflpt5 numbers in P8ZP_SCRATCH_W1 and AY identical?
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1
ldy #0
lda (P8ZP_SCRATCH_W1),y
cmp (P8ZP_SCRATCH_W2),y
bne _false
iny
lda (P8ZP_SCRATCH_W1),y
cmp (P8ZP_SCRATCH_W2),y
bne _false
iny
lda (P8ZP_SCRATCH_W1),y
cmp (P8ZP_SCRATCH_W2),y
bne _false
iny
lda (P8ZP_SCRATCH_W1),y
cmp (P8ZP_SCRATCH_W2),y
bne _false
iny
lda (P8ZP_SCRATCH_W1),y
cmp (P8ZP_SCRATCH_W2),y
bne _false
lda #1
rts
_false lda #0
rts
.pend
equal_f .proc equal_f .proc
; -- are the two mflpt5 numbers on the stack identical? ; -- are the two mflpt5 numbers on the stack identical?
inx inx

View File

@ -136,72 +136,44 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
"<" -> { "<" -> {
when(dt) { when(dt) {
DataType.UBYTE -> translateUbyteLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UBYTE -> translateUbyteLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.BYTE -> translateByteLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.BYTE -> translateByteLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.UWORD -> translateUwordLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UWORD -> translateUwordLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.WORD -> translateWordLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.FLOAT -> { DataType.FLOAT -> translateFloatLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
// todo via func args
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '<' at ${left.position}") // TODO float
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.less_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
DataType.STR -> translateStringLessJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) DataType.STR -> translateStringLessJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel)
else -> throw AssemblyError("weird operand datatype") else -> throw AssemblyError("weird operand datatype")
} }
} }
"<=" -> { "<=" -> {
when(dt) { when(dt) {
DataType.UBYTE -> translateUbyteLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UBYTE -> translateUbyteLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.BYTE -> translateByteLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.BYTE -> translateByteLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.UWORD -> translateUwordLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UWORD -> translateUwordLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.WORD -> translateWordLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.FLOAT -> { DataType.FLOAT -> translateFloatLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
// todo via func args
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '<=' at ${left.position}") // TODO float
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.lesseq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
DataType.STR -> translateStringLessOrEqualJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) DataType.STR -> translateStringLessOrEqualJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel)
else -> throw AssemblyError("weird operand datatype") else -> throw AssemblyError("weird operand datatype")
} }
} }
">" -> { ">" -> {
when(dt) { when(dt) {
DataType.UBYTE -> translateUbyteGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UBYTE -> translateUbyteGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.BYTE -> translateByteGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.BYTE -> translateByteGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.UWORD -> translateUwordGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UWORD -> translateUwordGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.WORD -> translateWordGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.FLOAT -> { DataType.FLOAT -> translateFloatGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
// todo via func args
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '>' at ${left.position}") // TODO float
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.greater_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
DataType.STR -> translateStringGreaterJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) DataType.STR -> translateStringGreaterJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel)
else -> throw AssemblyError("weird operand datatype") else -> throw AssemblyError("weird operand datatype")
} }
} }
">=" -> { ">=" -> {
when(dt) { when(dt) {
DataType.UBYTE -> translateUbyteGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UBYTE -> translateUbyteGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.BYTE -> translateByteGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.BYTE -> translateByteGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.UWORD -> translateUwordGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.UWORD -> translateUwordGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.WORD -> translateWordGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
DataType.FLOAT -> { DataType.FLOAT -> translateFloatGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
// todo via func args
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '>=' at ${left.position}") // TODO float
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.greatereq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
DataType.STR -> translateStringGreaterOrEqualJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) DataType.STR -> translateStringGreaterOrEqualJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel)
else -> throw AssemblyError("weird operand datatype") else -> throw AssemblyError("weird operand datatype")
} }
@ -209,6 +181,38 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
private fun translateFloatLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '<' at ${left.position}") // TODO float via func args?
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.less_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
private fun translateFloatLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '<=' at ${left.position}") // TODO float via func args?
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.lesseq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
private fun translateFloatGreaterJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '>' at ${left.position}") // TODO float via func args?
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.greater_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
private fun translateFloatGreaterOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e1): '>=' at ${left.position}") // TODO float via func args
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.greatereq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
private fun translateUbyteLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateUbyteLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(rightConstVal!=null) { if(rightConstVal!=null) {
if(leftConstVal!=null) { if(leftConstVal!=null) {
@ -946,12 +950,25 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
// todo via func args if(left is IdentifierReference && right is IdentifierReference) {
if(asmgen.options.slowCodegenWarnings) val leftName = asmgen.asmVariableName(left)
println("warning: slow stack evaluation used (e22): '==' at ${left.position}") // TODO float val rightName = asmgen.asmVariableName(right)
translateExpression(left) asmgen.out("""
translateExpression(right) lda #<$leftName
asmgen.out(" jsr floats.equal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") ldy #>$leftName
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<$rightName
ldy #>$rightName
jsr floats.vars_equal_f
beq $jumpIfFalseLabel""")
} else {
if (asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e22): '==' at ${left.position}") // TODO float via func args?
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.equal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
} }
private fun translateFloatNotEqualsJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateFloatNotEqualsJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
@ -995,12 +1012,25 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
// todo via func args if(left is IdentifierReference && right is IdentifierReference) {
if(asmgen.options.slowCodegenWarnings) val leftName = asmgen.asmVariableName(left)
println("warning: slow stack evaluation used (e23): '!=' at ${left.position}") // TODO float val rightName = asmgen.asmVariableName(right)
translateExpression(left) asmgen.out("""
translateExpression(right) lda #<$leftName
asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") ldy #>$leftName
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<$rightName
ldy #>$rightName
jsr floats.vars_equal_f
bne $jumpIfFalseLabel""")
} else {
if (asmgen.options.slowCodegenWarnings)
println("warning: slow stack evaluation used (e23): '!=' at ${left.position}") // TODO float via func args?
translateExpression(left)
translateExpression(right)
asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
}
} }
private fun translateStringEqualsJump(left: IdentifierReference, right: IdentifierReference, jumpIfFalseLabel: String) { private fun translateStringEqualsJump(left: IdentifierReference, right: IdentifierReference, jumpIfFalseLabel: String) {

View File

@ -11,13 +11,13 @@ main {
byte ub2 byte ub2
byte bb1 byte bb1
byte bb2 byte bb2
uword uw1 float uw1
uword uw2 float uw2
word ww1 word ww1
word ww2 word ww2
uw1 = $1000 uw1 = 1.1
uw2 = $1100 uw2 = 2.2
if uw1<uw2 if uw1<uw2
txt.chrout('.') txt.chrout('.')
else else
@ -46,8 +46,8 @@ main {
txt.chrout(' ') txt.chrout(' ')
uw1 = $1000 uw1 = -1.1
uw2 = $1000 uw2 = -1.1
if uw1<uw2 if uw1<uw2
txt.chrout('!') txt.chrout('!')