optimized calls for float *10 and +0.5

This commit is contained in:
Irmen de Jong 2023-12-06 01:15:29 +01:00
parent 3844bf1f72
commit 28c1b208c1
5 changed files with 173 additions and 26 deletions

View File

@ -2744,16 +2744,23 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
val constValueName = allocator.getFloatAsmConst(value)
when (operator) {
"+" -> {
if (value == 0.0)
return
asmgen.out("""
lda #<$name
ldy #>$name
jsr floats.MOVFM
lda #<$constValueName
ldy #>$constValueName
jsr floats.FADD
""")
when (value) {
0.0 -> return
0.5 -> asmgen.out("""
lda #<$name
ldy #>$name
jsr floats.MOVFM
jsr floats.FADDH
""")
else -> asmgen.out("""
lda #<$name
ldy #>$name
jsr floats.MOVFM
lda #<$constValueName
ldy #>$constValueName
jsr floats.FADD
""")
}
}
"-" -> {
if (value == 0.0)
@ -2769,14 +2776,23 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
"*" -> {
// assume that code optimization is already done on the AST level for special cases such as 0, 1, 2...
asmgen.out("""
lda #<$name
ldy #>$name
jsr floats.MOVFM
lda #<$constValueName
ldy #>$constValueName
jsr floats.FMULT
""")
if(value==10.0) {
asmgen.out("""
lda #<$name
ldy #>$name
jsr floats.MOVFM
jsr floats.MUL10
""")
} else {
asmgen.out("""
lda #<$name
ldy #>$name
jsr floats.MOVFM
lda #<$constValueName
ldy #>$constValueName
jsr floats.FMULT
""")
}
}
"/" -> {
if (value == 0.0)

View File

@ -53,7 +53,7 @@ romsub $bddd = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, ad
romsub $b849 = FADDH() clobbers(A,X,Y) ; fac1 += 0.5, for rounding- call this before INT
romsub $bae2 = MUL10() clobbers(A,X,Y) ; fac1 *= 10
romsub $bafe = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive!
romsub $bafe = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! You have to fix sign manually!
romsub $bc5b = FCOMP(uword mflpt @ AY) clobbers(X,Y) -> ubyte @ A ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than
romsub $b86a = FADDT() clobbers(A,X,Y) ; fac1 += fac2

View File

@ -15,7 +15,10 @@ there are also larger pieces of software written using Prog8. Here's a list.
`Image viewer <https://github.com/irmen/cx16imageviewer>`_
Multi-format image viewer for the Commander X16.
Can display C64 Koala, BMP, PCX and Amiga IFF images, including color cycling.
Can display cx16 BMX, C64 Koala, C64 Doodle, BMP, PCX and Amiga IFF images, including color cycling.
`Paint program <https://github.com/irmen/x16paint>`_
Bitmap image paint program for the Commander X16, work in progress.
`Petaxian <https://github.com/cyborgar/Petaxian>`_
Galaga type shoot em up game using only petscii graphics. Runs on C64 and Commander X16.

View File

@ -2,8 +2,6 @@
TODO
====
- add more projects such as Paint to the Software written in Prog8 list
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
...
@ -80,6 +78,7 @@ What if we were to re-introduce Structs in prog8? Some thoughts:
Other language/syntax features to think about
---------------------------------------------
- module directive to set the text encoding for that whole file (iso, petscii, etc.)
- chained assignments `x=y=z=99`
- declare multiple variables `ubyte x,y,z` (if init value present, all get that init value)
- chained comparisons `10<x<20` , `x==y==z` (desugars to `10<x and x<20`, `x==y and y==z`)

View File

@ -1,10 +1,139 @@
%import floats
%import textio
%import string
%zeropage basicsafe
main {
; float parsing prototype
sub start() {
ubyte knäckebröt = 99
cx16.r0L = knäckebröt
ubyte นี่คือตัวอักษรภาษาไท = 3
cx16.r0L = นี่คือตัวอักษรภาษาไท
f("")
f("0")
f("-0")
f(".0")
f("-.0")
f("0.0")
f("0.1")
f("+1.1")
f("-1.1")
f("-.1")
f("-.9")
f("-99.9")
f("99.9")
f("123456789.888888")
f("123.456789123456")
f("-123.")
f("-123.456789123456")
f("123.45e20")
f("+123.45e+20")
f("123.45e-20")
f("123.45e20")
f("-123.45e+20")
f("-123.45e-20")
f(" - 1 23. 45e - 36 ")
f(" - 1 23. 4Z 5e - 20 ")
f(" - 1 23!. 4Z 5e - 20 ")
f("1.7014118345e+38") ; TODO fix overflow error
f("-1.7014118345e+38") ; TODO fix overflow error
}
sub f(str string) {
cbm.SETTIM(0,0,0)
repeat 100
float value1 = floats.parse_f(string)
txt.print("1=")
txt.print_uw(cbm.RDTIM16())
txt.spc()
cbm.SETTIM(0,0,0)
repeat 100
float value2 = parse(string)
txt.print("2=")
txt.print_uw(cbm.RDTIM16())
txt.nl()
floats.print_f(value1)
txt.spc()
txt.spc()
floats.print_f(value2)
txt.nl()
}
sub parse(uword stringptr) -> float {
if @(stringptr)==0
return 0.0
float result
byte exponent
bool negative
repeat {
cx16.r0L = @(stringptr)
when cx16.r0L {
0 -> goto done
'-' -> negative=true
'+', ' ' -> { /* skip */ }
else -> {
if string.isdigit(cx16.r0L) {
result *= 10
result += cx16.r0L - '0'
} else
break
}
}
stringptr++
}
if cx16.r0L=='.' {
; read decimals
repeat {
stringptr++
cx16.r0L = @(stringptr)
if cx16.r0L==' '
continue
else if string.isdigit(cx16.r0L) {
exponent--
result *= 10
result += cx16.r0L - '0'
} else
break
}
}
if cx16.r0L=='e' or cx16.r0L=='E' {
; read exponent
bool neg_exponent
byte exp_value
repeat {
stringptr++
cx16.r0L = @(stringptr)
when cx16.r0L {
0 -> break
'+', ' ' -> { /* skip */ }
'-' -> neg_exponent=true
else -> {
if string.isdigit(cx16.r0L) {
exp_value *= 10
exp_value += cx16.r0L - '0'
} else
break
}
}
}
if neg_exponent
exponent -= exp_value
else
exponent += exp_value
}
done:
if exponent
result *= floats.pow(10, exponent)
if negative
result = -result
return floats.normalize(result)
}
}