optimized code for stack eval comparisons with zero

This commit is contained in:
Irmen de Jong
2022-01-09 01:33:30 +01:00
parent 6fa3f0b6cd
commit c1a39c269e
5 changed files with 263 additions and 16 deletions

View File

@@ -540,6 +540,13 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
}
}
in ComparisonOperators -> {
if(leftDt in NumericDatatypes && rightDt in NumericDatatypes) {
val rightVal = expr.right.constValue(program)?.number?.toInt()
if(rightVal==0)
return translateComparisonWithZero(expr.left, leftDt, expr.operator)
}
}
}
if((leftDt in ByteDatatypes && rightDt !in ByteDatatypes)
@@ -562,6 +569,69 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
}
private fun translateComparisonWithZero(expr: Expression, dt: DataType, operator: String) {
translateExpressionInternal(expr)
when(operator) {
"==" -> {
when(dt) {
DataType.UBYTE, DataType.BYTE -> asmgen.out(" jsr prog8_lib.equalzero_b")
DataType.UWORD, DataType.WORD -> asmgen.out(" jsr prog8_lib.equalzero_w")
DataType.FLOAT -> asmgen.out(" jsr floats.equal_zero")
else -> throw AssemblyError("wrong dt")
}
}
"!=" -> {
when(dt) {
DataType.UBYTE, DataType.BYTE -> asmgen.out(" jsr prog8_lib.notequalzero_b")
DataType.UWORD, DataType.WORD -> asmgen.out(" jsr prog8_lib.notequalzero_w")
DataType.FLOAT -> asmgen.out(" jsr floats.notequal_zero")
else -> throw AssemblyError("wrong dt")
}
}
"<" -> {
if(dt==DataType.UBYTE || dt==DataType.UWORD)
return translateExpressionInternal(NumericLiteralValue.fromBoolean(false, expr.position))
when(dt) {
DataType.BYTE -> asmgen.out(" jsr prog8_lib.lesszero_b")
DataType.WORD -> asmgen.out(" jsr prog8_lib.lesszero_w")
DataType.FLOAT -> asmgen.out(" jsr floats.less_zero")
else -> throw AssemblyError("wrong dt")
}
}
">" -> {
when(dt) {
DataType.UBYTE -> asmgen.out(" jsr prog8_lib.greaterzero_ub")
DataType.BYTE -> asmgen.out(" jsr prog8_lib.greaterzero_sb")
DataType.UWORD -> asmgen.out(" jsr prog8_lib.greaterzero_uw")
DataType.WORD -> asmgen.out(" jsr prog8_lib.greaterzero_sw")
DataType.FLOAT -> asmgen.out(" jsr floats.greater_zero")
else -> throw AssemblyError("wrong dt")
}
}
"<=" -> {
when(dt) {
DataType.UBYTE -> asmgen.out(" jsr prog8_lib.equalzero_b")
DataType.BYTE -> asmgen.out(" jsr prog8_lib.lessequalzeros_b")
DataType.UWORD -> asmgen.out(" jsr prog8_lib.equalzero_w")
DataType.WORD -> asmgen.out(" jsr prog8_lib.lessequalzero_sw")
DataType.FLOAT -> asmgen.out(" jsr floats.lessequal_zero")
else -> throw AssemblyError("wrong dt")
}
}
">=" -> {
if(dt==DataType.UBYTE || dt==DataType.UWORD)
return translateExpressionInternal(NumericLiteralValue.fromBoolean(true, expr.position))
when(dt) {
DataType.BYTE -> asmgen.out(" jsr prog8_lib.greaterequalzero_sb")
DataType.WORD -> asmgen.out(" jsr prog8_lib.greaterequalzero_sw")
DataType.FLOAT -> asmgen.out(" jsr floats.greaterequal_zero")
else -> throw AssemblyError("wrong dt")
}
}
else -> throw AssemblyError("invalid comparison operator")
}
}
private fun translateSquared(variable: IdentifierReference, dt: DataType) {
val asmVar = asmgen.asmVariableName(variable)
when(dt) {

View File

@@ -678,3 +678,54 @@ set_array_float .proc
.pend
equal_zero .proc
jsr floats.pop_float_fac1
jsr floats.SIGN
beq _true
bne _false
_true lda #1
sta P8ESTACK_LO,x
dex
rts
_false lda #0
sta P8ESTACK_LO,x
dex
rts
.pend
notequal_zero .proc
jsr floats.pop_float_fac1
jsr floats.SIGN
bne equal_zero._true
beq equal_zero._false
.pend
greater_zero .proc
jsr floats.pop_float_fac1
jsr floats.SIGN
beq equal_zero._false
bpl equal_zero._true
jmp equal_zero._false
.pend
less_zero .proc
jsr floats.pop_float_fac1
jsr floats.SIGN
bmi equal_zero._true
jmp equal_zero._false
.pend
greaterequal_zero .proc
jsr floats.pop_float_fac1
jsr floats.SIGN
bpl equal_zero._true
jmp equal_zero._false
.pend
lessequal_zero .proc
jsr floats.pop_float_fac1
jsr floats.SIGN
beq equal_zero._true
bmi equal_zero._true
jmp equal_zero._false
.pend

View File

@@ -4,6 +4,8 @@
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
orig_stackpointer .byte 0 ; stores the Stack pointer register at program start
read_byte_from_address_on_stack .proc
; -- read the byte from the memory address on the top of the stack, return in A (stack remains unchanged)
lda P8ESTACK_LO+1,x
@@ -683,8 +685,106 @@ shiftright_b .proc
.pend
orig_stackpointer .byte 0 ; stores the Stack pointer register at program start
equalzero_b .proc
lda P8ESTACK_LO+1,x
beq _true
bne _false
_true lda #1
sta P8ESTACK_LO+1,x
rts
_false lda #0
sta P8ESTACK_LO+1,x
rts
.pend
equalzero_w .proc
lda P8ESTACK_LO+1,x
ora P8ESTACK_HI+1,x
beq equalzero_b._true
bne equalzero_b._false
.pend
notequalzero_b .proc
lda P8ESTACK_LO+1,x
beq equalzero_b._false
bne equalzero_b._true
.pend
notequalzero_w .proc
lda P8ESTACK_LO+1,x
ora P8ESTACK_HI+1,x
beq equalzero_b._false
bne equalzero_b._true
.pend
lesszero_b .proc
lda P8ESTACK_LO+1,x
bmi equalzero_b._true
jmp equalzero_b._false
.pend
lesszero_w .proc
lda P8ESTACK_HI+1,x
bmi equalzero_b._true
jmp equalzero_b._false
.pend
greaterzero_ub .proc
lda P8ESTACK_LO+1,x
bne equalzero_b._true
beq equalzero_b._false
.pend
greaterzero_sb .proc
lda P8ESTACK_LO+1,x
beq equalzero_b._false
bpl equalzero_b._true
bmi equalzero_b._false
.pend
greaterzero_uw .proc
lda P8ESTACK_LO+1,x
ora P8ESTACK_HI+1,x
bne equalzero_b._true
beq equalzero_b._false
.pend
greaterzero_sw .proc
lda P8ESTACK_HI+1,x
bmi equalzero_b._false
ora P8ESTACK_LO+1,x
beq equalzero_b._false
bne equalzero_b._true
.pend
lessequalzero_sb .proc
lda P8ESTACK_LO+1,x
bmi equalzero_b._true
beq equalzero_b._true
bne equalzero_b._false
.pend
lessequalzero_sw .proc
lda P8ESTACK_HI+1,x
bmi equalzero_b._true
ora P8ESTACK_LO+1,x
beq equalzero_b._true
bne equalzero_b._false
.pend
greaterequalzero_sb .proc
lda P8ESTACK_LO+1,x
bpl equalzero_b._true
bmi equalzero_b._false
.pend
greaterequalzero_sw .proc
lda P8ESTACK_HI+1,x
bmi equalzero_b._false
ora P8ESTACK_LO+1,x
beq equalzero_b._true
bne equalzero_b._false
.pend
memcopy16_up .proc

View File

@@ -3,10 +3,10 @@ TODO
For next compiler release (7.7)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- why is wormfood 40 bytes larger now since 7.6???
- optimize codegen of pipe operator to avoid needless assigns to temp var
- optimize (u)word comparison against 0 to use MSB only if possible
- copying floats around: do it with a subroutine rather than 5 lda/sta pairs .
is slower but floats are very slow already anyway and this should take a lot less program size.
- optimize codegen of pipe operator to avoid needless assigns to temp var
Need help with

View File

@@ -5,11 +5,37 @@
main {
sub start() {
float @shared f1
byte bb = 0
word ww = 0
float fl = 0
f1 = 1.234 |> addfloat1 |> addfloat2 |> addfloat3 ; TODO fix that the value is actually returned
floats.print_f(f1)
txt.nl()
if fl< 0 {
txt.print("wrong fl\n")
}
fl=-1.111
if 0>fl or fl==2 {
txt.print("good fl\n")
}
if ww< 0 {
txt.print("wrong ww\n")
}
if bb<0 {
txt.print("wrong bb\n")
}
bb = -1
ww = -1111
if 0>ww or ww==2 {
txt.print("good ww\n")
}
if 0>bb or bb==2 {
txt.print("good bb\n")
}
; float @shared f1
;
; f1 = 1.234 |> addfloat1 |> addfloat2 |> addfloat3 ; TODO fix that the value is actually returned
; floats.print_f(f1)
; txt.nl()
; 1.234 |> addfloat1
; |> addfloat2 |> addfloat3 |> floats.print_f
; txt.nl()
@@ -21,15 +47,15 @@ main {
; |> txt.print_uw
; txt.nl()
test_stack.test()
; TODO fix that the value is actually returned (398) and that X register is preserved:
uword @shared uw= 9+3 |> assemblything
|> sin8u
|> add_one
|> times_two
txt.print_uw(uw)
txt.nl()
test_stack.test()
; test_stack.test()
; ; TODO fix that the value is actually returned (398) and that X register is preserved:
; uword @shared uw= 9+3 |> assemblything
; |> sin8u
; |> add_one
; |> times_two
; txt.print_uw(uw)
; txt.nl()
; test_stack.test()
}
sub addfloat1(float fl) -> float {