mirror of
https://github.com/irmen/prog8.git
synced 2025-12-20 12:19:39 +00:00
fix byte subtract from long
fix IR register check error for %ir segments
This commit is contained in:
@@ -916,30 +916,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
else -> {
|
else -> {
|
||||||
if(value in 1..255) {
|
if(value in 1..255) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $variable
|
|
||||||
sec
|
sec
|
||||||
|
lda $variable
|
||||||
sbc #$value
|
sbc #$value
|
||||||
sta $variable
|
sta $variable
|
||||||
bcs +
|
bcs +++
|
||||||
dec $variable+1
|
|
||||||
bne +
|
|
||||||
dec $variable+2
|
|
||||||
bne +
|
|
||||||
dec $variable+3
|
|
||||||
+""")
|
|
||||||
} else if(value in 1..65535) {
|
|
||||||
asmgen.out("""
|
|
||||||
lda $variable
|
|
||||||
sec
|
|
||||||
sbc #<$value
|
|
||||||
sta $variable
|
|
||||||
lda $variable+1
|
lda $variable+1
|
||||||
sbc #>$value
|
bne ++
|
||||||
sta $variable+1
|
lda $variable+2
|
||||||
bcs +
|
|
||||||
dec $variable+2
|
|
||||||
bne +
|
bne +
|
||||||
dec $variable+3
|
dec $variable+3
|
||||||
|
+ dec $variable+2
|
||||||
|
+ dec $variable+1
|
||||||
+""")
|
+""")
|
||||||
} else {
|
} else {
|
||||||
val hex = value.toLongHex()
|
val hex = value.toLongHex()
|
||||||
|
|||||||
@@ -66,7 +66,9 @@ Future Things and Ideas
|
|||||||
|
|
||||||
IR/VM
|
IR/VM
|
||||||
-----
|
-----
|
||||||
- optimize float<0 float==0 float>0 to use SGN instruction? Check what code is generated for other data types.
|
- replace LOADIX/STOREIX with LOADFIELD/STOREFIELD
|
||||||
|
- extend the index range from 0-255 to 0-32767 in the LOADX, STOREX, LOADFIELD, STOREFIELD etc instructions (not compatible with 8 bit 6502, but the 68000 can use that)
|
||||||
|
- if float<0 / if word<0 uses sgn or load, but still use a bgt etc instruction after that with a #0 operand even though the sgn and load instructions sets the status bits already, so just use bstneg etc
|
||||||
- add and sub instructions should modify the status flags so an explicit compare to zero can be avoided for example: if cx16.r0sL + cx16.r1sL <= 0 now compiles into: addr.b r10,r11 / bgts.b r10,#0,label
|
- add and sub instructions should modify the status flags so an explicit compare to zero can be avoided for example: if cx16.r0sL + cx16.r1sL <= 0 now compiles into: addr.b r10,r11 / bgts.b r10,#0,label
|
||||||
- getting it in shape for code generation: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
- getting it in shape for code generation: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!)
|
||||||
- fix call() return value handling (... what's wrong with it again?)
|
- fix call() return value handling (... what's wrong with it again?)
|
||||||
@@ -102,7 +104,6 @@ IR/VM
|
|||||||
- implement more TODOs in AssignmentGen
|
- implement more TODOs in AssignmentGen
|
||||||
- do something with the 'split' tag on split word arrays
|
- do something with the 'split' tag on split word arrays
|
||||||
- add more optimizations in IRPeepholeOptimizer, implement the TODOs in there at least
|
- add more optimizations in IRPeepholeOptimizer, implement the TODOs in there at least
|
||||||
- extend the index range from 0-255 to 0-32767 in the LOADX, STOREX, LOADFIELD, STOREFIELD etc instructions (not compatible with 8 bit 6502, but the 68000 can use that)
|
|
||||||
- idea: replace all scalar variables that are not @shared by an allocated register. Keep a table of the variable to register mapping (including the datatype)
|
- idea: replace all scalar variables that are not @shared by an allocated register. Keep a table of the variable to register mapping (including the datatype)
|
||||||
global initialization values are simply a list of LOAD instructions.
|
global initialization values are simply a list of LOAD instructions.
|
||||||
Variables replaced include all subroutine parameters? Or not? So the only variables that remain as variables are arrays and strings.
|
Variables replaced include all subroutine parameters? Or not? So the only variables that remain as variables are arrays and strings.
|
||||||
@@ -122,6 +123,7 @@ Libraries
|
|||||||
Optimizations
|
Optimizations
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
- peek(address + offset) and poke(address + offset, value) generate quite large asm segments. Optimize into subroutines for "indexed memory peek/pokes"?
|
||||||
- (6502) optimize if sgn(value)<0: still does a compare with 0 even though SGN sets all status bits.
|
- (6502) optimize if sgn(value)<0: still does a compare with 0 even though SGN sets all status bits.
|
||||||
- longvar = lptr^^ , lptr2^^=lptr^^ now go via temporary registers, optimize this to avoid using temps. (seems like it is dereferencing the pointer first and then assigning the intermediate value)
|
- longvar = lptr^^ , lptr2^^=lptr^^ now go via temporary registers, optimize this to avoid using temps. (seems like it is dereferencing the pointer first and then assigning the intermediate value)
|
||||||
- optimize inplaceLongShiftRight() for byte aligned cases
|
- optimize inplaceLongShiftRight() for byte aligned cases
|
||||||
|
|||||||
@@ -1,20 +1,61 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
|
||||||
sub start() {
|
|
||||||
long @shared zz = 12345
|
|
||||||
|
|
||||||
zz <<= 9
|
main {
|
||||||
txt.print_l(zz)
|
|
||||||
txt.nl()
|
long longvar = $100
|
||||||
zz = 12345
|
|
||||||
zz <<= 17
|
sub start() {
|
||||||
txt.print_l(zz)
|
|
||||||
txt.nl()
|
longvar -= 5
|
||||||
zz = 12
|
txt.print_ulhex(longvar, true)
|
||||||
zz <<= 25
|
|
||||||
txt.print_l(zz)
|
|
||||||
txt.nl()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
;main {
|
||||||
|
; sub start() {
|
||||||
|
; ubyte[256] @shared array1
|
||||||
|
; ubyte[256] @shared array2
|
||||||
|
; ubyte[256] @shared array3
|
||||||
|
;
|
||||||
|
; setvalues()
|
||||||
|
; readvalues()
|
||||||
|
; printvalues()
|
||||||
|
;
|
||||||
|
; sub setvalues() {
|
||||||
|
; poke(&array2 + 255, 99)
|
||||||
|
; poke(&array2 + 256, 88)
|
||||||
|
; poke(&array2 + $3000, 77)
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
; sub readvalues() {
|
||||||
|
; %ir {{
|
||||||
|
;loadm.b r1007,main.start.array2+255
|
||||||
|
;storem.b r1007,$ff02
|
||||||
|
;load.w r1009,main.start.array2
|
||||||
|
;add.w r1009,#$0100
|
||||||
|
;loadi.b r1008,r1009
|
||||||
|
;storem.b r1008,$ff04
|
||||||
|
;load.w r1011,main.start.array2
|
||||||
|
;add.w r1011,#$3000
|
||||||
|
;loadi.b r1010,r1011
|
||||||
|
;storem.b r1010,$ff06
|
||||||
|
;return
|
||||||
|
; }}
|
||||||
|
;; cx16.r0L = array2[255]
|
||||||
|
;; cx16.r1L = @(&array2 + 256)
|
||||||
|
;; cx16.r2L = @(&array2 + $3000)
|
||||||
|
; }
|
||||||
|
;
|
||||||
|
; sub printvalues() {
|
||||||
|
; txt.print_ub(cx16.r0L)
|
||||||
|
; txt.spc()
|
||||||
|
; txt.print_ub(cx16.r1L)
|
||||||
|
; txt.spc()
|
||||||
|
; txt.print_ub(cx16.r2L)
|
||||||
|
; }
|
||||||
|
; }
|
||||||
|
;}
|
||||||
|
|||||||
@@ -642,9 +642,11 @@ class RegistersUsed(
|
|||||||
|
|
||||||
fun validate(allowed: Map<Int, IRDataType>, chunk: IRCodeChunkBase?) {
|
fun validate(allowed: Map<Int, IRDataType>, chunk: IRCodeChunkBase?) {
|
||||||
for((reg, type) in regsTypes) {
|
for((reg, type) in regsTypes) {
|
||||||
if(allowed[reg]==null)
|
val allowedType = allowed[reg]
|
||||||
throw IllegalArgumentException("Reg type mismatch for register $reg type $type: no type known. CodeChunk=$chunk label ${chunk?.label}")
|
// can't do this check because %ir {{ .. }} segments may contain registers that the compiler doesn't know about yet.
|
||||||
if(allowed[reg]!=type)
|
// if(allowedType==null)
|
||||||
|
// throw IllegalArgumentException("Reg type mismatch for register $reg type $type: no type known. CodeChunk=$chunk label ${chunk?.label}")
|
||||||
|
if(allowedType!=null && allowedType!=type)
|
||||||
throw IllegalArgumentException("Reg type mismatch for register $reg type $type: expected ${allowed[reg]}. CodeChunk=$chunk label ${chunk?.label}")
|
throw IllegalArgumentException("Reg type mismatch for register $reg type $type: expected ${allowed[reg]}. CodeChunk=$chunk label ${chunk?.label}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user