mirror of
https://github.com/irmen/prog8.git
synced 2025-11-24 06:17:39 +00:00
implement 6502 codegen for casting long to float
This commit is contained in:
@@ -3077,7 +3077,14 @@ $endLabel""")
|
|||||||
BaseDataType.BYTE -> asmgen.out(" jsr floats.cast_as_w_into_ay | sta $targetAsmVarName")
|
BaseDataType.BYTE -> asmgen.out(" jsr floats.cast_as_w_into_ay | sta $targetAsmVarName")
|
||||||
BaseDataType.UWORD -> asmgen.out(" jsr floats.cast_as_uw_into_ya | sty $targetAsmVarName | sta $targetAsmVarName+1")
|
BaseDataType.UWORD -> asmgen.out(" jsr floats.cast_as_uw_into_ya | sty $targetAsmVarName | sta $targetAsmVarName+1")
|
||||||
BaseDataType.WORD -> asmgen.out(" jsr floats.cast_as_w_into_ay | sta $targetAsmVarName | sty $targetAsmVarName+1")
|
BaseDataType.WORD -> asmgen.out(" jsr floats.cast_as_w_into_ay | sta $targetAsmVarName | sty $targetAsmVarName+1")
|
||||||
BaseDataType.LONG -> TODO("cast float to long")
|
BaseDataType.LONG -> {
|
||||||
|
asmgen.out("""
|
||||||
|
sta cx16.r0L
|
||||||
|
sty cx16.r0H
|
||||||
|
lda #<$targetAsmVarName
|
||||||
|
ldy #>$targetAsmVarName
|
||||||
|
jsr floats.internal_cast_as_long""")
|
||||||
|
}
|
||||||
else -> throw AssemblyError("weird type")
|
else -> throw AssemblyError("weird type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3087,6 +3094,15 @@ $endLabel""")
|
|||||||
asmgen.out(" lda $sourceAsmVarName | sta $targetAsmVarName")
|
asmgen.out(" lda $sourceAsmVarName | sta $targetAsmVarName")
|
||||||
} else if(targetDt.isWord || targetDt.isPointer) {
|
} else if(targetDt.isWord || targetDt.isPointer) {
|
||||||
asmgen.out(" lda $sourceAsmVarName | sta $targetAsmVarName | lda $sourceAsmVarName+1 | sta $targetAsmVarName+1")
|
asmgen.out(" lda $sourceAsmVarName | sta $targetAsmVarName | lda $sourceAsmVarName+1 | sta $targetAsmVarName+1")
|
||||||
|
} else if(targetDt.isFloat) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$targetAsmVarName
|
||||||
|
ldy #>$targetAsmVarName
|
||||||
|
sta cx16.r0L
|
||||||
|
sty cx16.r0H
|
||||||
|
lda #<$sourceAsmVarName
|
||||||
|
ldy #>$sourceAsmVarName
|
||||||
|
jsr floats.internal_cast_from_long""")
|
||||||
} else
|
} else
|
||||||
throw AssemblyError("weird type")
|
throw AssemblyError("weird type")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,4 +302,58 @@ sub interpolate(float v, float inputMin, float inputMax, float outputMin, float
|
|||||||
return v * (outputMax - outputMin) + outputMin
|
return v * (outputMax - outputMin) + outputMin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
asmsub internal_cast_from_long(^^long lptr_src @AY, ^^float fptr_target @R0) {
|
||||||
|
%asm {{
|
||||||
|
; convert long pointed to by AY into a float pointed to by R0
|
||||||
|
; algorithm: (msw(l) as word) as float * 65536.0 + (lsw(l) as float)
|
||||||
|
; TODO optimize this by manipuliating the float memory bits directly
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
ldy #3
|
||||||
|
lda (P8ZP_SCRATCH_W1),y
|
||||||
|
sta P8ZP_SCRATCH_REG
|
||||||
|
dey
|
||||||
|
lda (P8ZP_SCRATCH_W1),y
|
||||||
|
ldy P8ZP_SCRATCH_REG
|
||||||
|
jsr GIVAYFAY
|
||||||
|
lda #<FL_65536_const
|
||||||
|
ldy #>FL_65536_const
|
||||||
|
jsr CONUPK
|
||||||
|
jsr FMULTT
|
||||||
|
jsr pushFAC1
|
||||||
|
ldy #1
|
||||||
|
lda (P8ZP_SCRATCH_W1),y
|
||||||
|
sta P8ZP_SCRATCH_REG
|
||||||
|
dey
|
||||||
|
lda (P8ZP_SCRATCH_W1),y
|
||||||
|
ldy P8ZP_SCRATCH_REG
|
||||||
|
jsr GIVUAYFAY
|
||||||
|
jsr MOVEF
|
||||||
|
clc
|
||||||
|
jsr popFAC
|
||||||
|
jsr FADDT
|
||||||
|
ldx cx16.r0L
|
||||||
|
ldy cx16.r0H
|
||||||
|
jmp MOVMF
|
||||||
|
|
||||||
|
FL_65536_const .byte $91, $00, $00, $00, $00 ; 65536.0
|
||||||
|
; !notreached!
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub internal_cast_as_long(^^float fptr_src @R0, ^^long lptr_target @AY) {
|
||||||
|
%asm {{
|
||||||
|
; TODO actually implement this
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
lda #0
|
||||||
|
ldy #3
|
||||||
|
- sta (P8ZP_SCRATCH_W1),y
|
||||||
|
dey
|
||||||
|
bpl -
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -497,8 +497,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
errors.err("parameter '${param.first.name}' should be (u)byte or bool", param.first.position)
|
errors.err("parameter '${param.first.name}' should be (u)byte or bool", param.first.position)
|
||||||
}
|
}
|
||||||
else if(param.second.registerOrPair in arrayOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) {
|
else if(param.second.registerOrPair in arrayOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) {
|
||||||
if (!param.first.type.isWord && !param.first.type.isString && !param.first.type.isArray && param.first.type!=DataType.pointer(BaseDataType.UBYTE)) {
|
if (!param.first.type.isWord && !param.first.type.isString && !param.first.type.isArray && !param.first.type.isPointer) {
|
||||||
err("parameter '${param.first.name}' should be (u)word, str or ^^ubyte")
|
err("parameter '${param.first.name}' should be (u)word, str or a pointer")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(param.second.statusflag!=null) {
|
else if(param.second.statusflag!=null) {
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- implement float to long casting and vice versa (6502)
|
||||||
- IR BUG: bool negative = sgn(f)<0 register type error
|
- IR BUG: bool negative = sgn(f)<0 register type error
|
||||||
|
- 6502 codegen: lptr_target^^ = -lptr_target^^ then put that into internal_cast_as_long()
|
||||||
- before final release: test all examples and programs again with final version of the compiler!
|
- before final release: test all examples and programs again with final version of the compiler!
|
||||||
|
|
||||||
|
|
||||||
Future Things and Ideas
|
Future Things and Ideas
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- implement float to long casting and vice versa (6502)
|
|
||||||
- make $8000000 a valid long integer (-2147483648) this is more involved than you think. To make this work: long \|= $80000000
|
- make $8000000 a valid long integer (-2147483648) this is more involved than you think. To make this work: long \|= $80000000
|
||||||
|
- add cx16.r0r1sL, r2r3sL, ... etc to map signed longs on the virtual registers?
|
||||||
- implement rest of long comparisons in IfElseAsmGen compareLongValues(): expressions operands that might clobber the R14-R15 registers...
|
- implement rest of long comparisons in IfElseAsmGen compareLongValues(): expressions operands that might clobber the R14-R15 registers...
|
||||||
- struct/ptr: implement the remaining TODOs in PointerAssignmentsGen.
|
- struct/ptr: implement the remaining TODOs in PointerAssignmentsGen.
|
||||||
- struct/ptr: optimize deref in PointerAssignmentsGen: optimize 'forceTemporary' to only use a temporary when the offset is >0
|
- struct/ptr: optimize deref in PointerAssignmentsGen: optimize 'forceTemporary' to only use a temporary when the offset is >0
|
||||||
@@ -117,6 +119,7 @@ Optimizations
|
|||||||
|
|
||||||
- change float<0, float==0, float>0 to use sgn(float) instead? (also see IR)
|
- change float<0, float==0, float>0 to use sgn(float) instead? (also see IR)
|
||||||
- optimize inplaceLongShiftRight() for byte aligned cases
|
- optimize inplaceLongShiftRight() for byte aligned cases
|
||||||
|
- optimize floats.internal_cast_from_long and floats.internal_cast_as_long
|
||||||
- more optimized operator handling of different types, for example uword a ^ byte b now does a type cast of b to word first
|
- more optimized operator handling of different types, for example uword a ^ byte b now does a type cast of b to word first
|
||||||
- optimize longEqualsValue() for const and variable operands to not assign needlessly to R0-R3.
|
- optimize longEqualsValue() for const and variable operands to not assign needlessly to R0-R3.
|
||||||
- optimize optimizedBitwiseExpr() for const and variable operands to not assign needlessly to R0-R3.
|
- optimize optimizedBitwiseExpr() for const and variable operands to not assign needlessly to R0-R3.
|
||||||
|
|||||||
170
examples/test.p8
170
examples/test.p8
@@ -1,63 +1,131 @@
|
|||||||
|
%import floats
|
||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
repeat test()
|
manual()
|
||||||
|
casts()
|
||||||
}
|
}
|
||||||
|
|
||||||
sub test() {
|
sub manual() {
|
||||||
txt.cls()
|
txt.print("\nwith conversion function:\n")
|
||||||
txt.plot(10, 10)
|
long lv
|
||||||
txt.print("enter four digit access code:")
|
float f
|
||||||
txt.plot(20, 12)
|
lv = 123456789
|
||||||
txt.print("╭──────╮")
|
txt.print_l(lv)
|
||||||
txt.plot(20, 13)
|
txt.spc()
|
||||||
txt.print("│ │")
|
floats.internal_cast_from_long(&lv, &f)
|
||||||
txt.plot(20, 14)
|
txt.print_f(f)
|
||||||
txt.print("╰──────╯")
|
txt.spc()
|
||||||
|
internal_cast_as_long(&f, &lv)
|
||||||
|
txt.print_l(lv)
|
||||||
txt.plot(22, 13)
|
txt.nl()
|
||||||
cx16.blink_enable(true)
|
lv = -987654321
|
||||||
str code = "????"
|
txt.print_l(lv)
|
||||||
|
txt.spc()
|
||||||
ubyte numbers = 0
|
floats.internal_cast_from_long(&lv, &f)
|
||||||
repeat {
|
txt.print_f(f)
|
||||||
ubyte char = txt.waitkey()
|
txt.spc()
|
||||||
when char {
|
internal_cast_as_long(&f, &lv)
|
||||||
'0' to '9' -> {
|
txt.print_l(lv)
|
||||||
if numbers<4 {
|
txt.nl()
|
||||||
cx16.blink_enable(false)
|
lv = -$111101
|
||||||
txt.chrout(char)
|
txt.print_l(lv)
|
||||||
cx16.blink_enable(true)
|
txt.spc()
|
||||||
code[numbers] = char
|
txt.print_ulhex(lv, true)
|
||||||
numbers++
|
txt.spc()
|
||||||
}
|
floats.internal_cast_from_long(&lv, &f)
|
||||||
}
|
txt.print_f(f)
|
||||||
'\r' -> {
|
txt.spc()
|
||||||
if numbers==4 {
|
internal_cast_as_long(&f, &lv)
|
||||||
cx16.blink_enable(false)
|
txt.print_l(lv)
|
||||||
break
|
txt.nl()
|
||||||
}
|
|
||||||
}
|
|
||||||
20, 25 -> {
|
|
||||||
if numbers>0 {
|
|
||||||
cx16.blink_enable(false)
|
|
||||||
txt.chrout(157) ; cursor left
|
|
||||||
txt.spc() ; clear digit
|
|
||||||
txt.chrout(157) ; cursor left
|
|
||||||
cx16.blink_enable(true)
|
|
||||||
numbers--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txt.print("\n\n\ncode entered: ")
|
sub casts() {
|
||||||
txt.print(code)
|
txt.print("\nwith casting:\n")
|
||||||
|
long lv
|
||||||
|
float f
|
||||||
|
lv = 123456789
|
||||||
|
txt.print_l(lv)
|
||||||
|
txt.spc()
|
||||||
|
f = lv as float
|
||||||
|
txt.print_f(f)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_l(f as long)
|
||||||
|
txt.nl()
|
||||||
|
lv = -987654321
|
||||||
|
txt.print_l(lv)
|
||||||
|
txt.spc()
|
||||||
|
f = lv as float
|
||||||
|
txt.print_f(f)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_l(f as long)
|
||||||
|
txt.nl()
|
||||||
|
lv = -$111101
|
||||||
|
txt.print_l(lv)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ulhex(lv, true)
|
||||||
|
txt.spc()
|
||||||
|
f = lv as float
|
||||||
|
txt.print_f(f)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_l(f as long)
|
||||||
|
txt.nl()
|
||||||
|
}
|
||||||
|
|
||||||
sys.wait(120)
|
|
||||||
|
sub internal_cast_as_long(^^float fptr_src, ^^long lptr_target) {
|
||||||
|
; clobbers R0-R3
|
||||||
|
float @nozp f = fptr_src^^
|
||||||
|
alias sign = cx16.r3sL
|
||||||
|
sign = sgn(f)
|
||||||
|
if sign<0
|
||||||
|
f = abs(f)
|
||||||
|
cx16.r2 = (f / 65536.0) as uword
|
||||||
|
&long result = &cx16.r0
|
||||||
|
result = mklong2(cx16.r2, (f - 65536.0 * (cx16.r2 as float)) as uword)
|
||||||
|
if sign<0
|
||||||
|
result = -result
|
||||||
|
lptr_target^^ = result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sub start2() {
|
||||||
|
uword uw
|
||||||
|
word sw
|
||||||
|
long lv
|
||||||
|
float fl
|
||||||
|
|
||||||
|
|
||||||
|
uw = 44555
|
||||||
|
fl = uw as float
|
||||||
|
txt.print_f(fl)
|
||||||
|
txt.nl()
|
||||||
|
fl /= 2
|
||||||
|
uw = fl as uword
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
sw = -8888
|
||||||
|
fl = sw as float
|
||||||
|
txt.print_f(fl)
|
||||||
|
txt.nl()
|
||||||
|
fl /= 2
|
||||||
|
sw = fl as word
|
||||||
|
txt.print_w(sw)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
lv = -99886666
|
||||||
|
fl = lv as float
|
||||||
|
txt.print_f(fl)
|
||||||
|
txt.nl()
|
||||||
|
fl /= 2
|
||||||
|
lv = fl as long
|
||||||
|
txt.print_l(lv)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user