mirror of
https://github.com/irmen/prog8.git
synced 2025-12-19 20:17:17 +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 -> {
|
||||
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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
; }
|
||||
; }
|
||||
;}
|
||||
|
||||
@@ -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}")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user