fix byte subtract from long

fix IR register check error for %ir segments
This commit is contained in:
Irmen de Jong
2025-12-06 13:56:23 +01:00
parent 0f433055a7
commit c693be0dd6
4 changed files with 70 additions and 37 deletions

View File

@@ -916,30 +916,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
else -> {
if(value in 1..255) {
asmgen.out("""
lda $variable
sec
lda $variable
sbc #$value
sta $variable
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
bcs +++
lda $variable+1
sbc #>$value
sta $variable+1
bcs +
dec $variable+2
bne ++
lda $variable+2
bne +
dec $variable+3
+ dec $variable+2
+ dec $variable+1
+""")
} else {
val hex = value.toLongHex()

View File

@@ -66,7 +66,9 @@ Future Things and Ideas
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
- 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?)
@@ -102,7 +104,6 @@ IR/VM
- implement more TODOs in AssignmentGen
- do something with the 'split' tag on split word arrays
- 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)
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.
@@ -122,6 +123,7 @@ Libraries
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.
- 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

View File

@@ -1,20 +1,61 @@
%import textio
%zeropage basicsafe
main {
sub start() {
long @shared zz = 12345
zz <<= 9
txt.print_l(zz)
txt.nl()
zz = 12345
zz <<= 17
txt.print_l(zz)
txt.nl()
zz = 12
zz <<= 25
txt.print_l(zz)
txt.nl()
main {
long longvar = $100
sub start() {
longvar -= 5
txt.print_ulhex(longvar, true)
}
}
;
;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)
; }
; }
;}

View File

@@ -642,9 +642,11 @@ class RegistersUsed(
fun validate(allowed: Map<Int, IRDataType>, chunk: IRCodeChunkBase?) {
for((reg, type) in regsTypes) {
if(allowed[reg]==null)
throw IllegalArgumentException("Reg type mismatch for register $reg type $type: no type known. CodeChunk=$chunk label ${chunk?.label}")
if(allowed[reg]!=type)
val allowedType = allowed[reg]
// can't do this check because %ir {{ .. }} segments may contain registers that the compiler doesn't know about yet.
// 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}")
}
}