mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 06:16:15 +00:00
optimized code for stack eval comparisons with zero
This commit is contained in:
@@ -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)
|
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) {
|
private fun translateSquared(variable: IdentifierReference, dt: DataType) {
|
||||||
val asmVar = asmgen.asmVariableName(variable)
|
val asmVar = asmgen.asmVariableName(variable)
|
||||||
when(dt) {
|
when(dt) {
|
||||||
|
|||||||
@@ -678,3 +678,54 @@ set_array_float .proc
|
|||||||
.pend
|
.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
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
; 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_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)
|
; -- read the byte from the memory address on the top of the stack, return in A (stack remains unchanged)
|
||||||
lda P8ESTACK_LO+1,x
|
lda P8ESTACK_LO+1,x
|
||||||
@@ -683,8 +685,106 @@ shiftright_b .proc
|
|||||||
.pend
|
.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
|
memcopy16_up .proc
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ TODO
|
|||||||
|
|
||||||
For next compiler release (7.7)
|
For next compiler release (7.7)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- why is wormfood 40 bytes larger now since 7.6???
|
- optimize (u)word comparison against 0 to use MSB only if possible
|
||||||
- optimize codegen of pipe operator to avoid needless assigns to temp var
|
|
||||||
- copying floats around: do it with a subroutine rather than 5 lda/sta pairs .
|
- 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.
|
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
|
Need help with
|
||||||
|
|||||||
@@ -5,11 +5,37 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
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
|
if fl< 0 {
|
||||||
floats.print_f(f1)
|
txt.print("wrong fl\n")
|
||||||
txt.nl()
|
}
|
||||||
|
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
|
; 1.234 |> addfloat1
|
||||||
; |> addfloat2 |> addfloat3 |> floats.print_f
|
; |> addfloat2 |> addfloat3 |> floats.print_f
|
||||||
; txt.nl()
|
; txt.nl()
|
||||||
@@ -21,15 +47,15 @@ main {
|
|||||||
; |> txt.print_uw
|
; |> txt.print_uw
|
||||||
; txt.nl()
|
; txt.nl()
|
||||||
|
|
||||||
test_stack.test()
|
; test_stack.test()
|
||||||
; TODO fix that the value is actually returned (398) and that X register is preserved:
|
; ; TODO fix that the value is actually returned (398) and that X register is preserved:
|
||||||
uword @shared uw= 9+3 |> assemblything
|
; uword @shared uw= 9+3 |> assemblything
|
||||||
|> sin8u
|
; |> sin8u
|
||||||
|> add_one
|
; |> add_one
|
||||||
|> times_two
|
; |> times_two
|
||||||
txt.print_uw(uw)
|
; txt.print_uw(uw)
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
test_stack.test()
|
; test_stack.test()
|
||||||
}
|
}
|
||||||
|
|
||||||
sub addfloat1(float fl) -> float {
|
sub addfloat1(float fl) -> float {
|
||||||
|
|||||||
Reference in New Issue
Block a user