mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-07 07:29:49 +00:00
Added a missing fragment and a newline. Added a petscii tester and started strings.h.
This commit is contained in:
parent
68c3c5918c
commit
d7b8f6ae55
6
src/main/fragment/vwuz1=vbuaa_plus_vbuz2.asm
Normal file
6
src/main/fragment/vwuz1=vbuaa_plus_vbuz2.asm
Normal file
@ -0,0 +1,6 @@
|
||||
clc
|
||||
adc {z2}
|
||||
sta {z1}
|
||||
lda #0
|
||||
adc #0
|
||||
sta {z1}+1
|
@ -172,7 +172,7 @@ public class KickC implements Callable<Void> {
|
||||
program = compiler.compile(kcFile.toString());
|
||||
} catch(CompileError e) {
|
||||
// Print the error and exit with compile error
|
||||
System.err.print(e.getMessage());
|
||||
System.err.println(e.getMessage());
|
||||
System.exit(COMPILE_ERROR);
|
||||
}
|
||||
|
||||
|
36
src/main/kc/stdlib/string.kc
Normal file
36
src/main/kc/stdlib/string.kc
Normal file
@ -0,0 +1,36 @@
|
||||
// Standard C strings.h - functions to manipulate C strings and arrays.
|
||||
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
byte* memcpy( byte* destination, byte* source, word num ) {
|
||||
byte* src = source;
|
||||
byte* dst = destination;
|
||||
for( word i=0;i<num; i++) *dst++ = *src++;
|
||||
return destination;
|
||||
}
|
||||
|
||||
// Move block of memory
|
||||
// Copies the values of num bytes from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.
|
||||
byte* memmove( byte* destination, byte* source, word num ) {
|
||||
if((word)destination<(word)source) {
|
||||
// copy forwards
|
||||
byte* src = source;
|
||||
byte* dst = destination;
|
||||
for( word i=0;i<num; i++) *dst++ = *src++;
|
||||
} else {
|
||||
// copy backwards
|
||||
byte* src = source+num;
|
||||
byte* dst = destination+num;
|
||||
for( word i=0;i<num; i++) *--dst = *--src;
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
// Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
|
||||
byte* strcpy( byte* destination, byte* source ) {
|
||||
byte* src = source;
|
||||
byte* dst = destination;
|
||||
while(*src) *dst++ = *src++;
|
||||
*dst = 0;
|
||||
return destination;
|
||||
}
|
@ -45,6 +45,11 @@ public class TestPrograms {
|
||||
compileAndCompare("typedef-0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMedusa() throws IOException, URISyntaxException {
|
||||
compileAndCompare("complex/medusa/medusa");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearscreen() throws IOException, URISyntaxException {
|
||||
compileAndCompare("complex/clearscreen/clearscreen");
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Black Hole at the center of the BASIC screen sucking in letters
|
||||
// Clears start screen throwing around the letters (by turning them into sprites)
|
||||
import "c64"
|
||||
import "multiply"
|
||||
|
||||
|
29
src/test/kc/complex/medusa/medusa.kc
Normal file
29
src/test/kc/complex/medusa/medusa.kc
Normal file
@ -0,0 +1,29 @@
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
|
||||
import "c64"
|
||||
import "string"
|
||||
|
||||
byte* MEDUSA_SCREEN = 0x1000;
|
||||
byte* MEDUSA_COLORS = 0x1400;
|
||||
|
||||
byte* SCREEN = 0x0400;
|
||||
|
||||
kickasm(pc MEDUSA_SCREEN, resource "medusas.prg" ) {{
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
}}
|
||||
|
||||
kickasm(pc MEDUSA_COLORS, resource "medusac.prg" ) {{
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
}}
|
||||
|
||||
void main() {
|
||||
*BGCOL = BLACK;
|
||||
memcpy(SCREEN, MEDUSA_SCREEN, 1000);
|
||||
memcpy(COLS, MEDUSA_COLORS, 1000);
|
||||
while(true) {
|
||||
(*(SCREEN+999)) ^= 0x0e;
|
||||
}
|
||||
}
|
BIN
src/test/kc/complex/medusa/medusac.prg
Normal file
BIN
src/test/kc/complex/medusa/medusac.prg
Normal file
Binary file not shown.
BIN
src/test/kc/complex/medusa/medusas.prg
Normal file
BIN
src/test/kc/complex/medusa/medusas.prg
Normal file
Binary file not shown.
83
src/test/ref/complex/medusa/medusa.asm
Normal file
83
src/test/ref/complex/medusa/medusa.asm
Normal file
@ -0,0 +1,83 @@
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
b1:
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
lda #0
|
||||
sta i
|
||||
sta i+1
|
||||
b1:
|
||||
ldy #0
|
||||
lda (src),y
|
||||
sta (dst),y
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1
|
||||
!:
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
45
src/test/ref/complex/medusa/medusa.cfg
Normal file
45
src/test/ref/complex/medusa/medusa.cfg
Normal file
@ -0,0 +1,45 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
}}
|
||||
kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
}}
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0
|
||||
[7] call memcpy
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main
|
||||
[8] phi()
|
||||
[9] call memcpy
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@1 main::@2
|
||||
[10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e
|
||||
to:main::@1
|
||||
memcpy: scope:[memcpy] from main main::@2
|
||||
[11] (byte*) memcpy::dst#0 ← phi( main/(const byte*) SCREEN#0 main::@2/(const byte*) COLS#0 )
|
||||
[11] (byte*) memcpy::src#0 ← phi( main/(const byte*) MEDUSA_SCREEN#0 main::@2/(const byte*) MEDUSA_COLORS#0 )
|
||||
to:memcpy::@1
|
||||
memcpy::@1: scope:[memcpy] from memcpy memcpy::@1
|
||||
[12] (word) memcpy::i#2 ← phi( memcpy/(byte) 0 memcpy::@1/(word) memcpy::i#1 )
|
||||
[12] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@1/(byte*) memcpy::dst#1 )
|
||||
[12] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@1/(byte*) memcpy::src#1 )
|
||||
[13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
|
||||
[14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
||||
[15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
|
||||
[16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2
|
||||
[17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1
|
||||
to:memcpy::@return
|
||||
memcpy::@return: scope:[memcpy] from memcpy::@1
|
||||
[18] return
|
||||
to:@return
|
948
src/test/ref/complex/medusa/medusa.log
Normal file
948
src/test/ref/complex/medusa/medusa.log
Normal file
@ -0,0 +1,948 @@
|
||||
Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src)
|
||||
Adding pointer type conversion cast (byte*) PROCPORT_DDR in (byte*) PROCPORT_DDR ← (number) 0
|
||||
Adding pointer type conversion cast (byte*) PROCPORT in (byte*) PROCPORT ← (number) 1
|
||||
Adding pointer type conversion cast (byte*) CHARGEN in (byte*) CHARGEN ← (number) $d000
|
||||
Adding pointer type conversion cast (byte*) SPRITES_XPOS in (byte*) SPRITES_XPOS ← (number) $d000
|
||||
Adding pointer type conversion cast (byte*) SPRITES_YPOS in (byte*) SPRITES_YPOS ← (number) $d001
|
||||
Adding pointer type conversion cast (byte*) SPRITES_XMSB in (byte*) SPRITES_XMSB ← (number) $d010
|
||||
Adding pointer type conversion cast (byte*) RASTER in (byte*) RASTER ← (number) $d012
|
||||
Adding pointer type conversion cast (byte*) SPRITES_ENABLE in (byte*) SPRITES_ENABLE ← (number) $d015
|
||||
Adding pointer type conversion cast (byte*) SPRITES_EXPAND_Y in (byte*) SPRITES_EXPAND_Y ← (number) $d017
|
||||
Adding pointer type conversion cast (byte*) SPRITES_PRIORITY in (byte*) SPRITES_PRIORITY ← (number) $d01b
|
||||
Adding pointer type conversion cast (byte*) SPRITES_MC in (byte*) SPRITES_MC ← (number) $d01c
|
||||
Adding pointer type conversion cast (byte*) SPRITES_EXPAND_X in (byte*) SPRITES_EXPAND_X ← (number) $d01d
|
||||
Adding pointer type conversion cast (byte*) BORDERCOL in (byte*) BORDERCOL ← (number) $d020
|
||||
Adding pointer type conversion cast (byte*) BGCOL in (byte*) BGCOL ← (number) $d021
|
||||
Adding pointer type conversion cast (byte*) BGCOL1 in (byte*) BGCOL1 ← (number) $d021
|
||||
Adding pointer type conversion cast (byte*) BGCOL2 in (byte*) BGCOL2 ← (number) $d022
|
||||
Adding pointer type conversion cast (byte*) BGCOL3 in (byte*) BGCOL3 ← (number) $d023
|
||||
Adding pointer type conversion cast (byte*) BGCOL4 in (byte*) BGCOL4 ← (number) $d024
|
||||
Adding pointer type conversion cast (byte*) SPRITES_MC1 in (byte*) SPRITES_MC1 ← (number) $d025
|
||||
Adding pointer type conversion cast (byte*) SPRITES_MC2 in (byte*) SPRITES_MC2 ← (number) $d026
|
||||
Adding pointer type conversion cast (byte*) SPRITES_COLS in (byte*) SPRITES_COLS ← (number) $d027
|
||||
Adding pointer type conversion cast (byte*) VIC_CONTROL in (byte*) VIC_CONTROL ← (number) $d011
|
||||
Adding pointer type conversion cast (byte*) D011 in (byte*) D011 ← (number) $d011
|
||||
Adding pointer type conversion cast (byte*) VIC_CONTROL2 in (byte*) VIC_CONTROL2 ← (number) $d016
|
||||
Adding pointer type conversion cast (byte*) D016 in (byte*) D016 ← (number) $d016
|
||||
Adding pointer type conversion cast (byte*) D018 in (byte*) D018 ← (number) $d018
|
||||
Adding pointer type conversion cast (byte*) VIC_MEMORY in (byte*) VIC_MEMORY ← (number) $d018
|
||||
Adding pointer type conversion cast (byte*) LIGHTPEN_X in (byte*) LIGHTPEN_X ← (number) $d013
|
||||
Adding pointer type conversion cast (byte*) LIGHTPEN_Y in (byte*) LIGHTPEN_Y ← (number) $d014
|
||||
Adding pointer type conversion cast (byte*) IRQ_STATUS in (byte*) IRQ_STATUS ← (number) $d019
|
||||
Adding pointer type conversion cast (byte*) IRQ_ENABLE in (byte*) IRQ_ENABLE ← (number) $d01a
|
||||
Adding pointer type conversion cast (byte*) COLS in (byte*) COLS ← (number) $d800
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_A in (byte*) CIA1_PORT_A ← (number) $dc00
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_B in (byte*) CIA1_PORT_B ← (number) $dc01
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_A_DDR in (byte*) CIA1_PORT_A_DDR ← (number) $dc02
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_B_DDR in (byte*) CIA1_PORT_B_DDR ← (number) $dc03
|
||||
Adding pointer type conversion cast (byte*) CIA1_INTERRUPT in (byte*) CIA1_INTERRUPT ← (number) $dc0d
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_A in (byte*) CIA2_PORT_A ← (number) $dd00
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_B in (byte*) CIA2_PORT_B ← (number) $dd01
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_A_DDR in (byte*) CIA2_PORT_A_DDR ← (number) $dd02
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT_B_DDR ← (number) $dd03
|
||||
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
|
||||
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
|
||||
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
|
||||
Adding pointer type conversion cast (byte*) MEDUSA_SCREEN in (byte*) MEDUSA_SCREEN ← (number) $1000
|
||||
Adding pointer type conversion cast (byte*) MEDUSA_COLORS in (byte*) MEDUSA_COLORS ← (number) $1400
|
||||
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
|
||||
Identified constant variable (byte*) MEDUSA_SCREEN
|
||||
Identified constant variable (byte*) MEDUSA_COLORS
|
||||
Identified constant variable (byte*) SCREEN
|
||||
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
|
||||
Culled Empty Block (label) @1
|
||||
Culled Empty Block (label) @2
|
||||
Culled Empty Block (label) @3
|
||||
Culled Empty Block (label) @4
|
||||
Culled Empty Block (label) memcpy::@3
|
||||
Culled Empty Block (label) @5
|
||||
Culled Empty Block (label) @6
|
||||
Culled Empty Block (label) main::@4
|
||||
Culled Empty Block (label) main::@3
|
||||
Culled Empty Block (label) main::@5
|
||||
Culled Empty Block (label) main::@6
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL#0 ← ((byte*)) (number) $d021
|
||||
(byte*) COLS#0 ← ((byte*)) (number) $d800
|
||||
(byte) BLACK#0 ← (number) 0
|
||||
to:@7
|
||||
memcpy: scope:[memcpy] from main main::@7
|
||||
(word) memcpy::num#3 ← phi( main/(word) memcpy::num#0 main::@7/(word) memcpy::num#1 )
|
||||
(byte*) memcpy::destination#2 ← phi( main/(byte*) memcpy::destination#0 main::@7/(byte*) memcpy::destination#1 )
|
||||
(byte*) memcpy::source#2 ← phi( main/(byte*) memcpy::source#0 main::@7/(byte*) memcpy::source#1 )
|
||||
(byte*) memcpy::src#0 ← (byte*) memcpy::source#2
|
||||
(byte*) memcpy::dst#0 ← (byte*) memcpy::destination#2
|
||||
(word) memcpy::i#0 ← (number) 0
|
||||
to:memcpy::@1
|
||||
memcpy::@1: scope:[memcpy] from memcpy memcpy::@1
|
||||
(byte*) memcpy::destination#4 ← phi( memcpy/(byte*) memcpy::destination#2 memcpy::@1/(byte*) memcpy::destination#4 )
|
||||
(word) memcpy::num#2 ← phi( memcpy/(word) memcpy::num#3 memcpy::@1/(word) memcpy::num#2 )
|
||||
(word) memcpy::i#2 ← phi( memcpy/(word) memcpy::i#0 memcpy::@1/(word) memcpy::i#1 )
|
||||
(byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@1/(byte*) memcpy::dst#1 )
|
||||
(byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@1/(byte*) memcpy::src#1 )
|
||||
*((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
|
||||
(byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
||||
(byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
|
||||
(word) memcpy::i#1 ← ++ (word) memcpy::i#2
|
||||
(bool~) memcpy::$0 ← (word) memcpy::i#1 < (word) memcpy::num#2
|
||||
if((bool~) memcpy::$0) goto memcpy::@1
|
||||
to:memcpy::@2
|
||||
memcpy::@2: scope:[memcpy] from memcpy::@1
|
||||
(byte*) memcpy::destination#3 ← phi( memcpy::@1/(byte*) memcpy::destination#4 )
|
||||
(byte*) memcpy::return#0 ← (byte*) memcpy::destination#3
|
||||
to:memcpy::@return
|
||||
memcpy::@return: scope:[memcpy] from memcpy::@2
|
||||
(byte*) memcpy::return#4 ← phi( memcpy::@2/(byte*) memcpy::return#0 )
|
||||
(byte*) memcpy::return#1 ← (byte*) memcpy::return#4
|
||||
return
|
||||
to:@return
|
||||
@7: scope:[] from @begin
|
||||
(byte*) MEDUSA_SCREEN#0 ← ((byte*)) (number) $1000
|
||||
(byte*) MEDUSA_COLORS#0 ← ((byte*)) (number) $1400
|
||||
(byte*) SCREEN#0 ← ((byte*)) (number) $400
|
||||
kickasm(location (byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
}}
|
||||
kickasm(location (byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
}}
|
||||
to:@8
|
||||
main: scope:[main] from @8
|
||||
*((byte*) BGCOL#0) ← (byte) BLACK#0
|
||||
(byte*) memcpy::destination#0 ← (byte*) SCREEN#0
|
||||
(byte*) memcpy::source#0 ← (byte*) MEDUSA_SCREEN#0
|
||||
(word) memcpy::num#0 ← (number) $3e8
|
||||
call memcpy
|
||||
(byte*) memcpy::return#2 ← (byte*) memcpy::return#1
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main
|
||||
(byte*) memcpy::destination#1 ← (byte*) COLS#0
|
||||
(byte*) memcpy::source#1 ← (byte*) MEDUSA_COLORS#0
|
||||
(word) memcpy::num#1 ← (number) $3e8
|
||||
call memcpy
|
||||
(byte*) memcpy::return#3 ← (byte*) memcpy::return#1
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@7
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@2 main::@8
|
||||
if(true) goto main::@2
|
||||
to:main::@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte*~) main::$2 ← (byte*) SCREEN#0 + (number) $3e7
|
||||
*((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
|
||||
to:main::@1
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@8: scope:[] from @7
|
||||
call main
|
||||
to:@9
|
||||
@9: scope:[] from @8
|
||||
to:@end
|
||||
@end: scope:[] from @9
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @7
|
||||
(label) @8
|
||||
(label) @9
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(byte*) BGCOL#0
|
||||
(byte) BLACK
|
||||
(byte) BLACK#0
|
||||
(byte*) COLS
|
||||
(byte*) COLS#0
|
||||
(byte*) MEDUSA_COLORS
|
||||
(byte*) MEDUSA_COLORS#0
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(byte*) MEDUSA_SCREEN#0
|
||||
(byte*) SCREEN
|
||||
(byte*) SCREEN#0
|
||||
(void()) main()
|
||||
(byte*~) main::$2
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@7
|
||||
(label) main::@8
|
||||
(label) main::@return
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(bool~) memcpy::$0
|
||||
(label) memcpy::@1
|
||||
(label) memcpy::@2
|
||||
(label) memcpy::@return
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::destination#0
|
||||
(byte*) memcpy::destination#1
|
||||
(byte*) memcpy::destination#2
|
||||
(byte*) memcpy::destination#3
|
||||
(byte*) memcpy::destination#4
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0
|
||||
(byte*) memcpy::dst#1
|
||||
(byte*) memcpy::dst#2
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#0
|
||||
(word) memcpy::i#1
|
||||
(word) memcpy::i#2
|
||||
(word) memcpy::num
|
||||
(word) memcpy::num#0
|
||||
(word) memcpy::num#1
|
||||
(word) memcpy::num#2
|
||||
(word) memcpy::num#3
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::return#0
|
||||
(byte*) memcpy::return#1
|
||||
(byte*) memcpy::return#2
|
||||
(byte*) memcpy::return#3
|
||||
(byte*) memcpy::return#4
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::source#0
|
||||
(byte*) memcpy::source#1
|
||||
(byte*) memcpy::source#2
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0
|
||||
(byte*) memcpy::src#1
|
||||
(byte*) memcpy::src#2
|
||||
|
||||
Adding number conversion cast (unumber) 0 in (byte) BLACK#0 ← (number) 0
|
||||
Adding number conversion cast (unumber) 0 in (word) memcpy::i#0 ← (number) 0
|
||||
Adding number conversion cast (unumber) $3e8 in (word) memcpy::num#0 ← (number) $3e8
|
||||
Adding number conversion cast (unumber) $3e8 in (word) memcpy::num#1 ← (number) $3e8
|
||||
Adding number conversion cast (unumber) $3e7 in (byte*~) main::$2 ← (byte*) SCREEN#0 + (number) $3e7
|
||||
Adding number conversion cast (unumber) $e in *((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Inlining cast (byte*) BGCOL#0 ← (byte*)(number) $d021
|
||||
Inlining cast (byte*) COLS#0 ← (byte*)(number) $d800
|
||||
Inlining cast (byte) BLACK#0 ← (unumber)(number) 0
|
||||
Inlining cast (word) memcpy::i#0 ← (unumber)(number) 0
|
||||
Inlining cast (byte*) MEDUSA_SCREEN#0 ← (byte*)(number) $1000
|
||||
Inlining cast (byte*) MEDUSA_COLORS#0 ← (byte*)(number) $1400
|
||||
Inlining cast (byte*) SCREEN#0 ← (byte*)(number) $400
|
||||
Inlining cast (word) memcpy::num#0 ← (unumber)(number) $3e8
|
||||
Inlining cast (word) memcpy::num#1 ← (unumber)(number) $3e8
|
||||
Successful SSA optimization Pass2InlineCast
|
||||
Simplifying constant pointer cast (byte*) 53281
|
||||
Simplifying constant pointer cast (byte*) 55296
|
||||
Simplifying constant integer cast 0
|
||||
Simplifying constant integer cast 0
|
||||
Simplifying constant pointer cast (byte*) 4096
|
||||
Simplifying constant pointer cast (byte*) 5120
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast $3e8
|
||||
Simplifying constant integer cast $3e8
|
||||
Simplifying constant integer cast $3e7
|
||||
Simplifying constant integer cast $e
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (word) $3e8
|
||||
Finalized unsigned number type (word) $3e8
|
||||
Finalized unsigned number type (word) $3e7
|
||||
Finalized unsigned number type (byte) $e
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias (byte*) memcpy::src#0 = (byte*) memcpy::source#2
|
||||
Alias (byte*) memcpy::dst#0 = (byte*) memcpy::destination#2
|
||||
Alias (byte*) memcpy::return#0 = (byte*) memcpy::destination#3 (byte*) memcpy::destination#4 (byte*) memcpy::return#4 (byte*) memcpy::return#1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Self Phi Eliminated (word) memcpy::num#2
|
||||
Self Phi Eliminated (byte*) memcpy::return#0
|
||||
Successful SSA optimization Pass2SelfPhiElimination
|
||||
Identical Phi Values (word) memcpy::num#2 (word) memcpy::num#3
|
||||
Identical Phi Values (byte*) memcpy::return#0 (byte*) memcpy::dst#0
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition (bool~) memcpy::$0 [13] if((word) memcpy::i#1<(word) memcpy::num#3) goto memcpy::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) BGCOL#0 = (byte*) 53281
|
||||
Constant (const byte*) COLS#0 = (byte*) 55296
|
||||
Constant (const byte) BLACK#0 = 0
|
||||
Constant (const word) memcpy::i#0 = 0
|
||||
Constant (const byte*) MEDUSA_SCREEN#0 = (byte*) 4096
|
||||
Constant (const byte*) MEDUSA_COLORS#0 = (byte*) 5120
|
||||
Constant (const byte*) SCREEN#0 = (byte*) 1024
|
||||
Constant (const word) memcpy::num#0 = $3e8
|
||||
Constant (const word) memcpy::num#1 = $3e8
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) memcpy::destination#0 = SCREEN#0
|
||||
Constant (const byte*) memcpy::source#0 = MEDUSA_SCREEN#0
|
||||
Constant (const byte*) memcpy::destination#1 = COLS#0
|
||||
Constant (const byte*) memcpy::source#1 = MEDUSA_COLORS#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
if() condition always true - replacing block destination [35] if(true) goto main::@2
|
||||
Successful SSA optimization Pass2ConstantIfs
|
||||
Eliminating unused variable (byte*) memcpy::return#2 and assignment [12] (byte*) memcpy::return#2 ← (byte*) memcpy::dst#0
|
||||
Eliminating unused variable (byte*) memcpy::return#3 and assignment [14] (byte*) memcpy::return#3 ← (byte*) memcpy::dst#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Removing unused block main::@return
|
||||
Successful SSA optimization Pass2EliminateUnusedBlocks
|
||||
Constant right-side identified [13] (byte*~) main::$2 ← (const byte*) SCREEN#0 + (word) $3e7
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte*) main::$2 = SCREEN#0+$3e7
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Inlining constant with var siblings (const word) memcpy::i#0
|
||||
Inlining constant with var siblings (const word) memcpy::num#0
|
||||
Inlining constant with var siblings (const word) memcpy::num#1
|
||||
Constant inlined memcpy::num#1 = (word) $3e8
|
||||
Constant inlined memcpy::num#0 = (word) $3e8
|
||||
Constant inlined memcpy::source#1 = (const byte*) MEDUSA_COLORS#0
|
||||
Constant inlined main::$2 = (const byte*) SCREEN#0+(word) $3e7
|
||||
Constant inlined memcpy::destination#0 = (const byte*) SCREEN#0
|
||||
Constant inlined memcpy::destination#1 = (const byte*) COLS#0
|
||||
Constant inlined memcpy::source#0 = (const byte*) MEDUSA_SCREEN#0
|
||||
Constant inlined memcpy::i#0 = (byte) 0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Identical Phi Values (word) memcpy::num#3 (word) $3e8
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Added new block during phi lifting memcpy::@4(between memcpy::@1 and memcpy::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @8
|
||||
Adding NOP phi() at start of @9
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main::@7
|
||||
Adding NOP phi() at start of main::@8
|
||||
Adding NOP phi() at start of main::@1
|
||||
Adding NOP phi() at start of memcpy::@2
|
||||
CALL GRAPH
|
||||
Calls in [] to main:4
|
||||
Calls in [main] to memcpy:8 memcpy:10
|
||||
|
||||
Created 5 initial phi equivalence classes
|
||||
Coalesced [15] memcpy::src#3 ← memcpy::src#0
|
||||
Coalesced [16] memcpy::dst#3 ← memcpy::dst#0
|
||||
Coalesced [25] memcpy::src#4 ← memcpy::src#1
|
||||
Coalesced [26] memcpy::dst#4 ← memcpy::dst#1
|
||||
Coalesced [27] memcpy::i#3 ← memcpy::i#1
|
||||
Coalesced down to 3 phi equivalence classes
|
||||
Culled Empty Block (label) @9
|
||||
Culled Empty Block (label) main::@8
|
||||
Culled Empty Block (label) main::@1
|
||||
Culled Empty Block (label) memcpy::@2
|
||||
Culled Empty Block (label) memcpy::@4
|
||||
Renumbering block @7 to @1
|
||||
Renumbering block @8 to @2
|
||||
Renumbering block main::@2 to main::@1
|
||||
Renumbering block main::@7 to main::@2
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main::@2
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
}}
|
||||
kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
}}
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0
|
||||
[7] call memcpy
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main
|
||||
[8] phi()
|
||||
[9] call memcpy
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@1 main::@2
|
||||
[10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e
|
||||
to:main::@1
|
||||
memcpy: scope:[memcpy] from main main::@2
|
||||
[11] (byte*) memcpy::dst#0 ← phi( main/(const byte*) SCREEN#0 main::@2/(const byte*) COLS#0 )
|
||||
[11] (byte*) memcpy::src#0 ← phi( main/(const byte*) MEDUSA_SCREEN#0 main::@2/(const byte*) MEDUSA_COLORS#0 )
|
||||
to:memcpy::@1
|
||||
memcpy::@1: scope:[memcpy] from memcpy memcpy::@1
|
||||
[12] (word) memcpy::i#2 ← phi( memcpy/(byte) 0 memcpy::@1/(word) memcpy::i#1 )
|
||||
[12] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@1/(byte*) memcpy::dst#1 )
|
||||
[12] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@1/(byte*) memcpy::src#1 )
|
||||
[13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
|
||||
[14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
||||
[15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
|
||||
[16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2
|
||||
[17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1
|
||||
to:memcpy::@return
|
||||
memcpy::@return: scope:[memcpy] from memcpy::@1
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(byte*) BGCOL
|
||||
(byte) BLACK
|
||||
(byte*) COLS
|
||||
(byte*) MEDUSA_COLORS
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(byte*) SCREEN
|
||||
(void()) main()
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0 2.0
|
||||
(byte*) memcpy::dst#1 5.5
|
||||
(byte*) memcpy::dst#2 17.5
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#1 16.5
|
||||
(word) memcpy::i#2 5.5
|
||||
(word) memcpy::num
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0 2.0
|
||||
(byte*) memcpy::src#1 7.333333333333333
|
||||
(byte*) memcpy::src#2 11.666666666666666
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
[ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
[ memcpy::i#2 memcpy::i#1 ]
|
||||
Complete equivalence classes
|
||||
[ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
[ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
[ memcpy::i#2 memcpy::i#1 ]
|
||||
Allocated zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
Allocated zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
Allocated zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) .fill fileScreen.getSize(), fileScreen.get(i) }}
|
||||
//SEG6 kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE) .fill fileCols.getSize(), fileCols.get(i) }}
|
||||
//SEG7 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG8 @2
|
||||
b2:
|
||||
//SEG9 [4] call main
|
||||
jsr main
|
||||
//SEG10 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG11 @end
|
||||
bend:
|
||||
//SEG12 main
|
||||
main: {
|
||||
//SEG13 [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
//SEG14 [7] call memcpy
|
||||
//SEG15 [11] phi from main to memcpy [phi:main->memcpy]
|
||||
memcpy_from_main:
|
||||
//SEG16 [11] phi (byte*) memcpy::dst#0 = (const byte*) SCREEN#0 [phi:main->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
//SEG17 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG18 [8] phi from main to main::@2 [phi:main->main::@2]
|
||||
b2_from_main:
|
||||
jmp b2
|
||||
//SEG19 main::@2
|
||||
b2:
|
||||
//SEG20 [9] call memcpy
|
||||
//SEG21 [11] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
||||
memcpy_from_b2:
|
||||
//SEG22 [11] phi (byte*) memcpy::dst#0 = (const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
//SEG23 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
jmp b1
|
||||
//SEG24 main::@1
|
||||
b1:
|
||||
//SEG25 [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
//SEG26 memcpy
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
//SEG27 [12] phi from memcpy to memcpy::@1 [phi:memcpy->memcpy::@1]
|
||||
b1_from_memcpy:
|
||||
//SEG28 [12] phi (word) memcpy::i#2 = (byte) 0 [phi:memcpy->memcpy::@1#0] -- vwuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
lda #0
|
||||
sta i+1
|
||||
//SEG29 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#0 [phi:memcpy->memcpy::@1#1] -- register_copy
|
||||
//SEG30 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#0 [phi:memcpy->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG31 [12] phi from memcpy::@1 to memcpy::@1 [phi:memcpy::@1->memcpy::@1]
|
||||
b1_from_b1:
|
||||
//SEG32 [12] phi (word) memcpy::i#2 = (word) memcpy::i#1 [phi:memcpy::@1->memcpy::@1#0] -- register_copy
|
||||
//SEG33 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#1 [phi:memcpy::@1->memcpy::@1#1] -- register_copy
|
||||
//SEG34 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#1 [phi:memcpy::@1->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG35 memcpy::@1
|
||||
b1:
|
||||
//SEG36 [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda (src),y
|
||||
ldy #0
|
||||
sta (dst),y
|
||||
//SEG37 [14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
//SEG38 [15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
//SEG39 [16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2 -- vwuz1=_inc_vwuz1
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
//SEG40 [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 -- vwuz1_lt_vwuc1_then_la1
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1_from_b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1_from_b1
|
||||
!:
|
||||
jmp breturn
|
||||
//SEG41 memcpy::@return
|
||||
breturn:
|
||||
//SEG42 [18] return
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( main:4 [ ] ) always clobbers reg byte a
|
||||
Statement [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e [ ] ( main:4 [ ] ) always clobbers reg byte a
|
||||
Statement [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src#2 memcpy::dst#2 memcpy::i#2 ] ( main:4::memcpy:7 [ memcpy::src#2 memcpy::dst#2 memcpy::i#2 ] main:4::memcpy:9 [ memcpy::src#2 memcpy::dst#2 memcpy::i#2 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 [ memcpy::src#1 memcpy::dst#1 memcpy::i#1 ] ( main:4::memcpy:7 [ memcpy::src#1 memcpy::dst#1 memcpy::i#1 ] main:4::memcpy:9 [ memcpy::src#1 memcpy::dst#1 memcpy::i#1 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ] : zp ZP_WORD:2 ,
|
||||
Potential registers zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ] : zp ZP_WORD:4 ,
|
||||
Potential registers zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ] : zp ZP_WORD:6 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [memcpy] 25: zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ] 22: zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ] 21: zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [memcpy] best 1649 combination zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ] zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ] zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
Uplifting [main] best 1649 combination
|
||||
Uplifting [] best 1649 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) .fill fileScreen.getSize(), fileScreen.get(i) }}
|
||||
//SEG6 kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE) .fill fileCols.getSize(), fileCols.get(i) }}
|
||||
//SEG7 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG8 @2
|
||||
b2:
|
||||
//SEG9 [4] call main
|
||||
jsr main
|
||||
//SEG10 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG11 @end
|
||||
bend:
|
||||
//SEG12 main
|
||||
main: {
|
||||
//SEG13 [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
//SEG14 [7] call memcpy
|
||||
//SEG15 [11] phi from main to memcpy [phi:main->memcpy]
|
||||
memcpy_from_main:
|
||||
//SEG16 [11] phi (byte*) memcpy::dst#0 = (const byte*) SCREEN#0 [phi:main->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
//SEG17 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG18 [8] phi from main to main::@2 [phi:main->main::@2]
|
||||
b2_from_main:
|
||||
jmp b2
|
||||
//SEG19 main::@2
|
||||
b2:
|
||||
//SEG20 [9] call memcpy
|
||||
//SEG21 [11] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
||||
memcpy_from_b2:
|
||||
//SEG22 [11] phi (byte*) memcpy::dst#0 = (const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
//SEG23 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
jmp b1
|
||||
//SEG24 main::@1
|
||||
b1:
|
||||
//SEG25 [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
//SEG26 memcpy
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
//SEG27 [12] phi from memcpy to memcpy::@1 [phi:memcpy->memcpy::@1]
|
||||
b1_from_memcpy:
|
||||
//SEG28 [12] phi (word) memcpy::i#2 = (byte) 0 [phi:memcpy->memcpy::@1#0] -- vwuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
lda #0
|
||||
sta i+1
|
||||
//SEG29 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#0 [phi:memcpy->memcpy::@1#1] -- register_copy
|
||||
//SEG30 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#0 [phi:memcpy->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG31 [12] phi from memcpy::@1 to memcpy::@1 [phi:memcpy::@1->memcpy::@1]
|
||||
b1_from_b1:
|
||||
//SEG32 [12] phi (word) memcpy::i#2 = (word) memcpy::i#1 [phi:memcpy::@1->memcpy::@1#0] -- register_copy
|
||||
//SEG33 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#1 [phi:memcpy::@1->memcpy::@1#1] -- register_copy
|
||||
//SEG34 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#1 [phi:memcpy::@1->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG35 memcpy::@1
|
||||
b1:
|
||||
//SEG36 [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda (src),y
|
||||
ldy #0
|
||||
sta (dst),y
|
||||
//SEG37 [14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
//SEG38 [15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
//SEG39 [16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2 -- vwuz1=_inc_vwuz1
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
//SEG40 [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 -- vwuz1_lt_vwuc1_then_la1
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1_from_b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1_from_b1
|
||||
!:
|
||||
jmp breturn
|
||||
//SEG41 memcpy::@return
|
||||
breturn:
|
||||
//SEG42 [18] return
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction lda #0
|
||||
Removing instruction ldy #0
|
||||
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||
Replacing label b1_from_b1 with b1
|
||||
Replacing label b1_from_b1 with b1
|
||||
Removing instruction b1:
|
||||
Removing instruction b2_from_b1:
|
||||
Removing instruction b2:
|
||||
Removing instruction bend_from_b2:
|
||||
Removing instruction b2_from_main:
|
||||
Removing instruction memcpy_from_b2:
|
||||
Removing instruction b1_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction memcpy_from_main:
|
||||
Removing instruction b2:
|
||||
Removing instruction b1_from_memcpy:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction jmp b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
|
||||
(byte) BLACK
|
||||
(const byte) BLACK#0 BLACK = (byte) 0
|
||||
(byte*) COLS
|
||||
(const byte*) COLS#0 COLS = (byte*) 55296
|
||||
(byte*) MEDUSA_COLORS
|
||||
(const byte*) MEDUSA_COLORS#0 MEDUSA_COLORS = (byte*) 5120
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(const byte*) MEDUSA_SCREEN#0 MEDUSA_SCREEN = (byte*) 4096
|
||||
(byte*) SCREEN
|
||||
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(label) memcpy::@1
|
||||
(label) memcpy::@return
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0 dst zp ZP_WORD:4 2.0
|
||||
(byte*) memcpy::dst#1 dst zp ZP_WORD:4 5.5
|
||||
(byte*) memcpy::dst#2 dst zp ZP_WORD:4 17.5
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#1 i zp ZP_WORD:6 16.5
|
||||
(word) memcpy::i#2 i zp ZP_WORD:6 5.5
|
||||
(word) memcpy::num
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0 src zp ZP_WORD:2 2.0
|
||||
(byte*) memcpy::src#1 src zp ZP_WORD:2 7.333333333333333
|
||||
(byte*) memcpy::src#2 src zp ZP_WORD:2 11.666666666666666
|
||||
|
||||
zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 1471
|
||||
|
||||
//SEG0 File Comments
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
//SEG3 @begin
|
||||
//SEG4 @1
|
||||
//SEG5 kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) .fill fileScreen.getSize(), fileScreen.get(i) }}
|
||||
//SEG6 kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE) .fill fileCols.getSize(), fileCols.get(i) }}
|
||||
//SEG7 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
//SEG8 @2
|
||||
//SEG9 [4] call main
|
||||
//SEG10 [5] phi from @2 to @end [phi:@2->@end]
|
||||
//SEG11 @end
|
||||
//SEG12 main
|
||||
main: {
|
||||
//SEG13 [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
//SEG14 [7] call memcpy
|
||||
//SEG15 [11] phi from main to memcpy [phi:main->memcpy]
|
||||
//SEG16 [11] phi (byte*) memcpy::dst#0 = (const byte*) SCREEN#0 [phi:main->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
//SEG17 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG18 [8] phi from main to main::@2 [phi:main->main::@2]
|
||||
//SEG19 main::@2
|
||||
//SEG20 [9] call memcpy
|
||||
//SEG21 [11] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
||||
//SEG22 [11] phi (byte*) memcpy::dst#0 = (const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
//SEG23 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG24 main::@1
|
||||
b1:
|
||||
//SEG25 [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
//SEG26 memcpy
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
//SEG27 [12] phi from memcpy to memcpy::@1 [phi:memcpy->memcpy::@1]
|
||||
//SEG28 [12] phi (word) memcpy::i#2 = (byte) 0 [phi:memcpy->memcpy::@1#0] -- vwuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
sta i+1
|
||||
//SEG29 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#0 [phi:memcpy->memcpy::@1#1] -- register_copy
|
||||
//SEG30 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#0 [phi:memcpy->memcpy::@1#2] -- register_copy
|
||||
//SEG31 [12] phi from memcpy::@1 to memcpy::@1 [phi:memcpy::@1->memcpy::@1]
|
||||
//SEG32 [12] phi (word) memcpy::i#2 = (word) memcpy::i#1 [phi:memcpy::@1->memcpy::@1#0] -- register_copy
|
||||
//SEG33 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#1 [phi:memcpy::@1->memcpy::@1#1] -- register_copy
|
||||
//SEG34 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#1 [phi:memcpy::@1->memcpy::@1#2] -- register_copy
|
||||
//SEG35 memcpy::@1
|
||||
b1:
|
||||
//SEG36 [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda (src),y
|
||||
sta (dst),y
|
||||
//SEG37 [14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
//SEG38 [15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
//SEG39 [16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2 -- vwuz1=_inc_vwuz1
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
//SEG40 [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 -- vwuz1_lt_vwuc1_then_la1
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1
|
||||
!:
|
||||
//SEG41 memcpy::@return
|
||||
//SEG42 [18] return
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
||||
|
41
src/test/ref/complex/medusa/medusa.sym
Normal file
41
src/test/ref/complex/medusa/medusa.sym
Normal file
@ -0,0 +1,41 @@
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
|
||||
(byte) BLACK
|
||||
(const byte) BLACK#0 BLACK = (byte) 0
|
||||
(byte*) COLS
|
||||
(const byte*) COLS#0 COLS = (byte*) 55296
|
||||
(byte*) MEDUSA_COLORS
|
||||
(const byte*) MEDUSA_COLORS#0 MEDUSA_COLORS = (byte*) 5120
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(const byte*) MEDUSA_SCREEN#0 MEDUSA_SCREEN = (byte*) 4096
|
||||
(byte*) SCREEN
|
||||
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(label) memcpy::@1
|
||||
(label) memcpy::@return
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0 dst zp ZP_WORD:4 2.0
|
||||
(byte*) memcpy::dst#1 dst zp ZP_WORD:4 5.5
|
||||
(byte*) memcpy::dst#2 dst zp ZP_WORD:4 17.5
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#1 i zp ZP_WORD:6 16.5
|
||||
(word) memcpy::i#2 i zp ZP_WORD:6 5.5
|
||||
(word) memcpy::num
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0 src zp ZP_WORD:2 2.0
|
||||
(byte*) memcpy::src#1 src zp ZP_WORD:2 7.333333333333333
|
||||
(byte*) memcpy::src#2 src zp ZP_WORD:2 11.666666666666666
|
||||
|
||||
zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ]
|
83
src/test/ref/medusa.asm
Normal file
83
src/test/ref/medusa.asm
Normal file
@ -0,0 +1,83 @@
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
b1:
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
lda #0
|
||||
sta i
|
||||
sta i+1
|
||||
b1:
|
||||
ldy #0
|
||||
lda (src),y
|
||||
sta (dst),y
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1
|
||||
!:
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
45
src/test/ref/medusa.cfg
Normal file
45
src/test/ref/medusa.cfg
Normal file
@ -0,0 +1,45 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
}}
|
||||
kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
}}
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0
|
||||
[7] call memcpy
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main
|
||||
[8] phi()
|
||||
[9] call memcpy
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@1 main::@2
|
||||
[10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e
|
||||
to:main::@1
|
||||
memcpy: scope:[memcpy] from main main::@2
|
||||
[11] (byte*) memcpy::dst#0 ← phi( main/(const byte*) SCREEN#0 main::@2/(const byte*) COLS#0 )
|
||||
[11] (byte*) memcpy::src#0 ← phi( main/(const byte*) MEDUSA_SCREEN#0 main::@2/(const byte*) MEDUSA_COLORS#0 )
|
||||
to:memcpy::@1
|
||||
memcpy::@1: scope:[memcpy] from memcpy memcpy::@1
|
||||
[12] (word) memcpy::i#2 ← phi( memcpy/(byte) 0 memcpy::@1/(word) memcpy::i#1 )
|
||||
[12] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@1/(byte*) memcpy::dst#1 )
|
||||
[12] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@1/(byte*) memcpy::src#1 )
|
||||
[13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
|
||||
[14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
||||
[15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
|
||||
[16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2
|
||||
[17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1
|
||||
to:memcpy::@return
|
||||
memcpy::@return: scope:[memcpy] from memcpy::@1
|
||||
[18] return
|
||||
to:@return
|
948
src/test/ref/medusa.log
Normal file
948
src/test/ref/medusa.log
Normal file
@ -0,0 +1,948 @@
|
||||
Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src)
|
||||
Adding pointer type conversion cast (byte*) PROCPORT_DDR in (byte*) PROCPORT_DDR ← (number) 0
|
||||
Adding pointer type conversion cast (byte*) PROCPORT in (byte*) PROCPORT ← (number) 1
|
||||
Adding pointer type conversion cast (byte*) CHARGEN in (byte*) CHARGEN ← (number) $d000
|
||||
Adding pointer type conversion cast (byte*) SPRITES_XPOS in (byte*) SPRITES_XPOS ← (number) $d000
|
||||
Adding pointer type conversion cast (byte*) SPRITES_YPOS in (byte*) SPRITES_YPOS ← (number) $d001
|
||||
Adding pointer type conversion cast (byte*) SPRITES_XMSB in (byte*) SPRITES_XMSB ← (number) $d010
|
||||
Adding pointer type conversion cast (byte*) RASTER in (byte*) RASTER ← (number) $d012
|
||||
Adding pointer type conversion cast (byte*) SPRITES_ENABLE in (byte*) SPRITES_ENABLE ← (number) $d015
|
||||
Adding pointer type conversion cast (byte*) SPRITES_EXPAND_Y in (byte*) SPRITES_EXPAND_Y ← (number) $d017
|
||||
Adding pointer type conversion cast (byte*) SPRITES_PRIORITY in (byte*) SPRITES_PRIORITY ← (number) $d01b
|
||||
Adding pointer type conversion cast (byte*) SPRITES_MC in (byte*) SPRITES_MC ← (number) $d01c
|
||||
Adding pointer type conversion cast (byte*) SPRITES_EXPAND_X in (byte*) SPRITES_EXPAND_X ← (number) $d01d
|
||||
Adding pointer type conversion cast (byte*) BORDERCOL in (byte*) BORDERCOL ← (number) $d020
|
||||
Adding pointer type conversion cast (byte*) BGCOL in (byte*) BGCOL ← (number) $d021
|
||||
Adding pointer type conversion cast (byte*) BGCOL1 in (byte*) BGCOL1 ← (number) $d021
|
||||
Adding pointer type conversion cast (byte*) BGCOL2 in (byte*) BGCOL2 ← (number) $d022
|
||||
Adding pointer type conversion cast (byte*) BGCOL3 in (byte*) BGCOL3 ← (number) $d023
|
||||
Adding pointer type conversion cast (byte*) BGCOL4 in (byte*) BGCOL4 ← (number) $d024
|
||||
Adding pointer type conversion cast (byte*) SPRITES_MC1 in (byte*) SPRITES_MC1 ← (number) $d025
|
||||
Adding pointer type conversion cast (byte*) SPRITES_MC2 in (byte*) SPRITES_MC2 ← (number) $d026
|
||||
Adding pointer type conversion cast (byte*) SPRITES_COLS in (byte*) SPRITES_COLS ← (number) $d027
|
||||
Adding pointer type conversion cast (byte*) VIC_CONTROL in (byte*) VIC_CONTROL ← (number) $d011
|
||||
Adding pointer type conversion cast (byte*) D011 in (byte*) D011 ← (number) $d011
|
||||
Adding pointer type conversion cast (byte*) VIC_CONTROL2 in (byte*) VIC_CONTROL2 ← (number) $d016
|
||||
Adding pointer type conversion cast (byte*) D016 in (byte*) D016 ← (number) $d016
|
||||
Adding pointer type conversion cast (byte*) D018 in (byte*) D018 ← (number) $d018
|
||||
Adding pointer type conversion cast (byte*) VIC_MEMORY in (byte*) VIC_MEMORY ← (number) $d018
|
||||
Adding pointer type conversion cast (byte*) LIGHTPEN_X in (byte*) LIGHTPEN_X ← (number) $d013
|
||||
Adding pointer type conversion cast (byte*) LIGHTPEN_Y in (byte*) LIGHTPEN_Y ← (number) $d014
|
||||
Adding pointer type conversion cast (byte*) IRQ_STATUS in (byte*) IRQ_STATUS ← (number) $d019
|
||||
Adding pointer type conversion cast (byte*) IRQ_ENABLE in (byte*) IRQ_ENABLE ← (number) $d01a
|
||||
Adding pointer type conversion cast (byte*) COLS in (byte*) COLS ← (number) $d800
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_A in (byte*) CIA1_PORT_A ← (number) $dc00
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_B in (byte*) CIA1_PORT_B ← (number) $dc01
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_A_DDR in (byte*) CIA1_PORT_A_DDR ← (number) $dc02
|
||||
Adding pointer type conversion cast (byte*) CIA1_PORT_B_DDR in (byte*) CIA1_PORT_B_DDR ← (number) $dc03
|
||||
Adding pointer type conversion cast (byte*) CIA1_INTERRUPT in (byte*) CIA1_INTERRUPT ← (number) $dc0d
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_A in (byte*) CIA2_PORT_A ← (number) $dd00
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_B in (byte*) CIA2_PORT_B ← (number) $dd01
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_A_DDR in (byte*) CIA2_PORT_A_DDR ← (number) $dd02
|
||||
Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT_B_DDR ← (number) $dd03
|
||||
Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d
|
||||
Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314
|
||||
Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe
|
||||
Adding pointer type conversion cast (byte*) MEDUSA_SCREEN in (byte*) MEDUSA_SCREEN ← (number) $1000
|
||||
Adding pointer type conversion cast (byte*) MEDUSA_COLORS in (byte*) MEDUSA_COLORS ← (number) $1400
|
||||
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
|
||||
Identified constant variable (byte*) MEDUSA_SCREEN
|
||||
Identified constant variable (byte*) MEDUSA_COLORS
|
||||
Identified constant variable (byte*) SCREEN
|
||||
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
|
||||
Culled Empty Block (label) @1
|
||||
Culled Empty Block (label) @2
|
||||
Culled Empty Block (label) @3
|
||||
Culled Empty Block (label) @4
|
||||
Culled Empty Block (label) memcpy::@3
|
||||
Culled Empty Block (label) @5
|
||||
Culled Empty Block (label) @6
|
||||
Culled Empty Block (label) main::@4
|
||||
Culled Empty Block (label) main::@3
|
||||
Culled Empty Block (label) main::@5
|
||||
Culled Empty Block (label) main::@6
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL#0 ← ((byte*)) (number) $d021
|
||||
(byte*) COLS#0 ← ((byte*)) (number) $d800
|
||||
(byte) BLACK#0 ← (number) 0
|
||||
to:@7
|
||||
memcpy: scope:[memcpy] from main main::@7
|
||||
(word) memcpy::num#3 ← phi( main/(word) memcpy::num#0 main::@7/(word) memcpy::num#1 )
|
||||
(byte*) memcpy::destination#2 ← phi( main/(byte*) memcpy::destination#0 main::@7/(byte*) memcpy::destination#1 )
|
||||
(byte*) memcpy::source#2 ← phi( main/(byte*) memcpy::source#0 main::@7/(byte*) memcpy::source#1 )
|
||||
(byte*) memcpy::src#0 ← (byte*) memcpy::source#2
|
||||
(byte*) memcpy::dst#0 ← (byte*) memcpy::destination#2
|
||||
(word) memcpy::i#0 ← (number) 0
|
||||
to:memcpy::@1
|
||||
memcpy::@1: scope:[memcpy] from memcpy memcpy::@1
|
||||
(byte*) memcpy::destination#4 ← phi( memcpy/(byte*) memcpy::destination#2 memcpy::@1/(byte*) memcpy::destination#4 )
|
||||
(word) memcpy::num#2 ← phi( memcpy/(word) memcpy::num#3 memcpy::@1/(word) memcpy::num#2 )
|
||||
(word) memcpy::i#2 ← phi( memcpy/(word) memcpy::i#0 memcpy::@1/(word) memcpy::i#1 )
|
||||
(byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@1/(byte*) memcpy::dst#1 )
|
||||
(byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@1/(byte*) memcpy::src#1 )
|
||||
*((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
|
||||
(byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
||||
(byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
|
||||
(word) memcpy::i#1 ← ++ (word) memcpy::i#2
|
||||
(bool~) memcpy::$0 ← (word) memcpy::i#1 < (word) memcpy::num#2
|
||||
if((bool~) memcpy::$0) goto memcpy::@1
|
||||
to:memcpy::@2
|
||||
memcpy::@2: scope:[memcpy] from memcpy::@1
|
||||
(byte*) memcpy::destination#3 ← phi( memcpy::@1/(byte*) memcpy::destination#4 )
|
||||
(byte*) memcpy::return#0 ← (byte*) memcpy::destination#3
|
||||
to:memcpy::@return
|
||||
memcpy::@return: scope:[memcpy] from memcpy::@2
|
||||
(byte*) memcpy::return#4 ← phi( memcpy::@2/(byte*) memcpy::return#0 )
|
||||
(byte*) memcpy::return#1 ← (byte*) memcpy::return#4
|
||||
return
|
||||
to:@return
|
||||
@7: scope:[] from @begin
|
||||
(byte*) MEDUSA_SCREEN#0 ← ((byte*)) (number) $1000
|
||||
(byte*) MEDUSA_COLORS#0 ← ((byte*)) (number) $1400
|
||||
(byte*) SCREEN#0 ← ((byte*)) (number) $400
|
||||
kickasm(location (byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
}}
|
||||
kickasm(location (byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
}}
|
||||
to:@8
|
||||
main: scope:[main] from @8
|
||||
*((byte*) BGCOL#0) ← (byte) BLACK#0
|
||||
(byte*) memcpy::destination#0 ← (byte*) SCREEN#0
|
||||
(byte*) memcpy::source#0 ← (byte*) MEDUSA_SCREEN#0
|
||||
(word) memcpy::num#0 ← (number) $3e8
|
||||
call memcpy
|
||||
(byte*) memcpy::return#2 ← (byte*) memcpy::return#1
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main
|
||||
(byte*) memcpy::destination#1 ← (byte*) COLS#0
|
||||
(byte*) memcpy::source#1 ← (byte*) MEDUSA_COLORS#0
|
||||
(word) memcpy::num#1 ← (number) $3e8
|
||||
call memcpy
|
||||
(byte*) memcpy::return#3 ← (byte*) memcpy::return#1
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@7
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@2 main::@8
|
||||
if(true) goto main::@2
|
||||
to:main::@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte*~) main::$2 ← (byte*) SCREEN#0 + (number) $3e7
|
||||
*((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
|
||||
to:main::@1
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@8: scope:[] from @7
|
||||
call main
|
||||
to:@9
|
||||
@9: scope:[] from @8
|
||||
to:@end
|
||||
@end: scope:[] from @9
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @7
|
||||
(label) @8
|
||||
(label) @9
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(byte*) BGCOL#0
|
||||
(byte) BLACK
|
||||
(byte) BLACK#0
|
||||
(byte*) COLS
|
||||
(byte*) COLS#0
|
||||
(byte*) MEDUSA_COLORS
|
||||
(byte*) MEDUSA_COLORS#0
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(byte*) MEDUSA_SCREEN#0
|
||||
(byte*) SCREEN
|
||||
(byte*) SCREEN#0
|
||||
(void()) main()
|
||||
(byte*~) main::$2
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@7
|
||||
(label) main::@8
|
||||
(label) main::@return
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(bool~) memcpy::$0
|
||||
(label) memcpy::@1
|
||||
(label) memcpy::@2
|
||||
(label) memcpy::@return
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::destination#0
|
||||
(byte*) memcpy::destination#1
|
||||
(byte*) memcpy::destination#2
|
||||
(byte*) memcpy::destination#3
|
||||
(byte*) memcpy::destination#4
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0
|
||||
(byte*) memcpy::dst#1
|
||||
(byte*) memcpy::dst#2
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#0
|
||||
(word) memcpy::i#1
|
||||
(word) memcpy::i#2
|
||||
(word) memcpy::num
|
||||
(word) memcpy::num#0
|
||||
(word) memcpy::num#1
|
||||
(word) memcpy::num#2
|
||||
(word) memcpy::num#3
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::return#0
|
||||
(byte*) memcpy::return#1
|
||||
(byte*) memcpy::return#2
|
||||
(byte*) memcpy::return#3
|
||||
(byte*) memcpy::return#4
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::source#0
|
||||
(byte*) memcpy::source#1
|
||||
(byte*) memcpy::source#2
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0
|
||||
(byte*) memcpy::src#1
|
||||
(byte*) memcpy::src#2
|
||||
|
||||
Adding number conversion cast (unumber) 0 in (byte) BLACK#0 ← (number) 0
|
||||
Adding number conversion cast (unumber) 0 in (word) memcpy::i#0 ← (number) 0
|
||||
Adding number conversion cast (unumber) $3e8 in (word) memcpy::num#0 ← (number) $3e8
|
||||
Adding number conversion cast (unumber) $3e8 in (word) memcpy::num#1 ← (number) $3e8
|
||||
Adding number conversion cast (unumber) $3e7 in (byte*~) main::$2 ← (byte*) SCREEN#0 + (number) $3e7
|
||||
Adding number conversion cast (unumber) $e in *((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Inlining cast (byte*) BGCOL#0 ← (byte*)(number) $d021
|
||||
Inlining cast (byte*) COLS#0 ← (byte*)(number) $d800
|
||||
Inlining cast (byte) BLACK#0 ← (unumber)(number) 0
|
||||
Inlining cast (word) memcpy::i#0 ← (unumber)(number) 0
|
||||
Inlining cast (byte*) MEDUSA_SCREEN#0 ← (byte*)(number) $1000
|
||||
Inlining cast (byte*) MEDUSA_COLORS#0 ← (byte*)(number) $1400
|
||||
Inlining cast (byte*) SCREEN#0 ← (byte*)(number) $400
|
||||
Inlining cast (word) memcpy::num#0 ← (unumber)(number) $3e8
|
||||
Inlining cast (word) memcpy::num#1 ← (unumber)(number) $3e8
|
||||
Successful SSA optimization Pass2InlineCast
|
||||
Simplifying constant pointer cast (byte*) 53281
|
||||
Simplifying constant pointer cast (byte*) 55296
|
||||
Simplifying constant integer cast 0
|
||||
Simplifying constant integer cast 0
|
||||
Simplifying constant pointer cast (byte*) 4096
|
||||
Simplifying constant pointer cast (byte*) 5120
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast $3e8
|
||||
Simplifying constant integer cast $3e8
|
||||
Simplifying constant integer cast $3e7
|
||||
Simplifying constant integer cast $e
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (word) $3e8
|
||||
Finalized unsigned number type (word) $3e8
|
||||
Finalized unsigned number type (word) $3e7
|
||||
Finalized unsigned number type (byte) $e
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias (byte*) memcpy::src#0 = (byte*) memcpy::source#2
|
||||
Alias (byte*) memcpy::dst#0 = (byte*) memcpy::destination#2
|
||||
Alias (byte*) memcpy::return#0 = (byte*) memcpy::destination#3 (byte*) memcpy::destination#4 (byte*) memcpy::return#4 (byte*) memcpy::return#1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Self Phi Eliminated (word) memcpy::num#2
|
||||
Self Phi Eliminated (byte*) memcpy::return#0
|
||||
Successful SSA optimization Pass2SelfPhiElimination
|
||||
Identical Phi Values (word) memcpy::num#2 (word) memcpy::num#3
|
||||
Identical Phi Values (byte*) memcpy::return#0 (byte*) memcpy::dst#0
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition (bool~) memcpy::$0 [13] if((word) memcpy::i#1<(word) memcpy::num#3) goto memcpy::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) BGCOL#0 = (byte*) 53281
|
||||
Constant (const byte*) COLS#0 = (byte*) 55296
|
||||
Constant (const byte) BLACK#0 = 0
|
||||
Constant (const word) memcpy::i#0 = 0
|
||||
Constant (const byte*) MEDUSA_SCREEN#0 = (byte*) 4096
|
||||
Constant (const byte*) MEDUSA_COLORS#0 = (byte*) 5120
|
||||
Constant (const byte*) SCREEN#0 = (byte*) 1024
|
||||
Constant (const word) memcpy::num#0 = $3e8
|
||||
Constant (const word) memcpy::num#1 = $3e8
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant (const byte*) memcpy::destination#0 = SCREEN#0
|
||||
Constant (const byte*) memcpy::source#0 = MEDUSA_SCREEN#0
|
||||
Constant (const byte*) memcpy::destination#1 = COLS#0
|
||||
Constant (const byte*) memcpy::source#1 = MEDUSA_COLORS#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
if() condition always true - replacing block destination [35] if(true) goto main::@2
|
||||
Successful SSA optimization Pass2ConstantIfs
|
||||
Eliminating unused variable (byte*) memcpy::return#2 and assignment [12] (byte*) memcpy::return#2 ← (byte*) memcpy::dst#0
|
||||
Eliminating unused variable (byte*) memcpy::return#3 and assignment [14] (byte*) memcpy::return#3 ← (byte*) memcpy::dst#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Removing unused block main::@return
|
||||
Successful SSA optimization Pass2EliminateUnusedBlocks
|
||||
Constant right-side identified [13] (byte*~) main::$2 ← (const byte*) SCREEN#0 + (word) $3e7
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte*) main::$2 = SCREEN#0+$3e7
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Inlining constant with var siblings (const word) memcpy::i#0
|
||||
Inlining constant with var siblings (const word) memcpy::num#0
|
||||
Inlining constant with var siblings (const word) memcpy::num#1
|
||||
Constant inlined memcpy::num#1 = (word) $3e8
|
||||
Constant inlined memcpy::num#0 = (word) $3e8
|
||||
Constant inlined memcpy::source#1 = (const byte*) MEDUSA_COLORS#0
|
||||
Constant inlined main::$2 = (const byte*) SCREEN#0+(word) $3e7
|
||||
Constant inlined memcpy::destination#0 = (const byte*) SCREEN#0
|
||||
Constant inlined memcpy::destination#1 = (const byte*) COLS#0
|
||||
Constant inlined memcpy::source#0 = (const byte*) MEDUSA_SCREEN#0
|
||||
Constant inlined memcpy::i#0 = (byte) 0
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Identical Phi Values (word) memcpy::num#3 (word) $3e8
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Added new block during phi lifting memcpy::@4(between memcpy::@1 and memcpy::@1)
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @8
|
||||
Adding NOP phi() at start of @9
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main::@7
|
||||
Adding NOP phi() at start of main::@8
|
||||
Adding NOP phi() at start of main::@1
|
||||
Adding NOP phi() at start of memcpy::@2
|
||||
CALL GRAPH
|
||||
Calls in [] to main:4
|
||||
Calls in [main] to memcpy:8 memcpy:10
|
||||
|
||||
Created 5 initial phi equivalence classes
|
||||
Coalesced [15] memcpy::src#3 ← memcpy::src#0
|
||||
Coalesced [16] memcpy::dst#3 ← memcpy::dst#0
|
||||
Coalesced [25] memcpy::src#4 ← memcpy::src#1
|
||||
Coalesced [26] memcpy::dst#4 ← memcpy::dst#1
|
||||
Coalesced [27] memcpy::i#3 ← memcpy::i#1
|
||||
Coalesced down to 3 phi equivalence classes
|
||||
Culled Empty Block (label) @9
|
||||
Culled Empty Block (label) main::@8
|
||||
Culled Empty Block (label) main::@1
|
||||
Culled Empty Block (label) memcpy::@2
|
||||
Culled Empty Block (label) memcpy::@4
|
||||
Renumbering block @7 to @1
|
||||
Renumbering block @8 to @2
|
||||
Renumbering block main::@2 to main::@1
|
||||
Renumbering block main::@7 to main::@2
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main::@2
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
}}
|
||||
kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
}}
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[3] phi()
|
||||
[4] call main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
[5] phi()
|
||||
main: scope:[main] from @2
|
||||
[6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0
|
||||
[7] call memcpy
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main
|
||||
[8] phi()
|
||||
[9] call memcpy
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::@1 main::@2
|
||||
[10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e
|
||||
to:main::@1
|
||||
memcpy: scope:[memcpy] from main main::@2
|
||||
[11] (byte*) memcpy::dst#0 ← phi( main/(const byte*) SCREEN#0 main::@2/(const byte*) COLS#0 )
|
||||
[11] (byte*) memcpy::src#0 ← phi( main/(const byte*) MEDUSA_SCREEN#0 main::@2/(const byte*) MEDUSA_COLORS#0 )
|
||||
to:memcpy::@1
|
||||
memcpy::@1: scope:[memcpy] from memcpy memcpy::@1
|
||||
[12] (word) memcpy::i#2 ← phi( memcpy/(byte) 0 memcpy::@1/(word) memcpy::i#1 )
|
||||
[12] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@1/(byte*) memcpy::dst#1 )
|
||||
[12] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@1/(byte*) memcpy::src#1 )
|
||||
[13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
|
||||
[14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
||||
[15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
|
||||
[16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2
|
||||
[17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1
|
||||
to:memcpy::@return
|
||||
memcpy::@return: scope:[memcpy] from memcpy::@1
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(byte*) BGCOL
|
||||
(byte) BLACK
|
||||
(byte*) COLS
|
||||
(byte*) MEDUSA_COLORS
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(byte*) SCREEN
|
||||
(void()) main()
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0 2.0
|
||||
(byte*) memcpy::dst#1 5.5
|
||||
(byte*) memcpy::dst#2 17.5
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#1 16.5
|
||||
(word) memcpy::i#2 5.5
|
||||
(word) memcpy::num
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0 2.0
|
||||
(byte*) memcpy::src#1 7.333333333333333
|
||||
(byte*) memcpy::src#2 11.666666666666666
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
[ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
[ memcpy::i#2 memcpy::i#1 ]
|
||||
Complete equivalence classes
|
||||
[ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
[ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
[ memcpy::i#2 memcpy::i#1 ]
|
||||
Allocated zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
Allocated zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
Allocated zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 File Comments
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) .fill fileScreen.getSize(), fileScreen.get(i) }}
|
||||
//SEG6 kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE) .fill fileCols.getSize(), fileCols.get(i) }}
|
||||
//SEG7 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG8 @2
|
||||
b2:
|
||||
//SEG9 [4] call main
|
||||
jsr main
|
||||
//SEG10 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG11 @end
|
||||
bend:
|
||||
//SEG12 main
|
||||
main: {
|
||||
//SEG13 [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
//SEG14 [7] call memcpy
|
||||
//SEG15 [11] phi from main to memcpy [phi:main->memcpy]
|
||||
memcpy_from_main:
|
||||
//SEG16 [11] phi (byte*) memcpy::dst#0 = (const byte*) SCREEN#0 [phi:main->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
//SEG17 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG18 [8] phi from main to main::@2 [phi:main->main::@2]
|
||||
b2_from_main:
|
||||
jmp b2
|
||||
//SEG19 main::@2
|
||||
b2:
|
||||
//SEG20 [9] call memcpy
|
||||
//SEG21 [11] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
||||
memcpy_from_b2:
|
||||
//SEG22 [11] phi (byte*) memcpy::dst#0 = (const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
//SEG23 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
jmp b1
|
||||
//SEG24 main::@1
|
||||
b1:
|
||||
//SEG25 [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
//SEG26 memcpy
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
//SEG27 [12] phi from memcpy to memcpy::@1 [phi:memcpy->memcpy::@1]
|
||||
b1_from_memcpy:
|
||||
//SEG28 [12] phi (word) memcpy::i#2 = (byte) 0 [phi:memcpy->memcpy::@1#0] -- vwuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
lda #0
|
||||
sta i+1
|
||||
//SEG29 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#0 [phi:memcpy->memcpy::@1#1] -- register_copy
|
||||
//SEG30 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#0 [phi:memcpy->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG31 [12] phi from memcpy::@1 to memcpy::@1 [phi:memcpy::@1->memcpy::@1]
|
||||
b1_from_b1:
|
||||
//SEG32 [12] phi (word) memcpy::i#2 = (word) memcpy::i#1 [phi:memcpy::@1->memcpy::@1#0] -- register_copy
|
||||
//SEG33 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#1 [phi:memcpy::@1->memcpy::@1#1] -- register_copy
|
||||
//SEG34 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#1 [phi:memcpy::@1->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG35 memcpy::@1
|
||||
b1:
|
||||
//SEG36 [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda (src),y
|
||||
ldy #0
|
||||
sta (dst),y
|
||||
//SEG37 [14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
//SEG38 [15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
//SEG39 [16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2 -- vwuz1=_inc_vwuz1
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
//SEG40 [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 -- vwuz1_lt_vwuc1_then_la1
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1_from_b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1_from_b1
|
||||
!:
|
||||
jmp breturn
|
||||
//SEG41 memcpy::@return
|
||||
breturn:
|
||||
//SEG42 [18] return
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( main:4 [ ] ) always clobbers reg byte a
|
||||
Statement [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e [ ] ( main:4 [ ] ) always clobbers reg byte a
|
||||
Statement [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src#2 memcpy::dst#2 memcpy::i#2 ] ( main:4::memcpy:7 [ memcpy::src#2 memcpy::dst#2 memcpy::i#2 ] main:4::memcpy:9 [ memcpy::src#2 memcpy::dst#2 memcpy::i#2 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 [ memcpy::src#1 memcpy::dst#1 memcpy::i#1 ] ( main:4::memcpy:7 [ memcpy::src#1 memcpy::dst#1 memcpy::i#1 ] main:4::memcpy:9 [ memcpy::src#1 memcpy::dst#1 memcpy::i#1 ] ) always clobbers reg byte a
|
||||
Potential registers zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ] : zp ZP_WORD:2 ,
|
||||
Potential registers zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ] : zp ZP_WORD:4 ,
|
||||
Potential registers zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ] : zp ZP_WORD:6 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [memcpy] 25: zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ] 22: zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ] 21: zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [memcpy] best 1649 combination zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ] zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ] zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
Uplifting [main] best 1649 combination
|
||||
Uplifting [] best 1649 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 File Comments
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(bbegin)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
//SEG3 @begin
|
||||
bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) .fill fileScreen.getSize(), fileScreen.get(i) }}
|
||||
//SEG6 kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE) .fill fileCols.getSize(), fileCols.get(i) }}
|
||||
//SEG7 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
b2_from_b1:
|
||||
jmp b2
|
||||
//SEG8 @2
|
||||
b2:
|
||||
//SEG9 [4] call main
|
||||
jsr main
|
||||
//SEG10 [5] phi from @2 to @end [phi:@2->@end]
|
||||
bend_from_b2:
|
||||
jmp bend
|
||||
//SEG11 @end
|
||||
bend:
|
||||
//SEG12 main
|
||||
main: {
|
||||
//SEG13 [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
//SEG14 [7] call memcpy
|
||||
//SEG15 [11] phi from main to memcpy [phi:main->memcpy]
|
||||
memcpy_from_main:
|
||||
//SEG16 [11] phi (byte*) memcpy::dst#0 = (const byte*) SCREEN#0 [phi:main->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
//SEG17 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG18 [8] phi from main to main::@2 [phi:main->main::@2]
|
||||
b2_from_main:
|
||||
jmp b2
|
||||
//SEG19 main::@2
|
||||
b2:
|
||||
//SEG20 [9] call memcpy
|
||||
//SEG21 [11] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
||||
memcpy_from_b2:
|
||||
//SEG22 [11] phi (byte*) memcpy::dst#0 = (const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
//SEG23 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
jmp b1
|
||||
//SEG24 main::@1
|
||||
b1:
|
||||
//SEG25 [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
//SEG26 memcpy
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
//SEG27 [12] phi from memcpy to memcpy::@1 [phi:memcpy->memcpy::@1]
|
||||
b1_from_memcpy:
|
||||
//SEG28 [12] phi (word) memcpy::i#2 = (byte) 0 [phi:memcpy->memcpy::@1#0] -- vwuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
lda #0
|
||||
sta i+1
|
||||
//SEG29 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#0 [phi:memcpy->memcpy::@1#1] -- register_copy
|
||||
//SEG30 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#0 [phi:memcpy->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG31 [12] phi from memcpy::@1 to memcpy::@1 [phi:memcpy::@1->memcpy::@1]
|
||||
b1_from_b1:
|
||||
//SEG32 [12] phi (word) memcpy::i#2 = (word) memcpy::i#1 [phi:memcpy::@1->memcpy::@1#0] -- register_copy
|
||||
//SEG33 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#1 [phi:memcpy::@1->memcpy::@1#1] -- register_copy
|
||||
//SEG34 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#1 [phi:memcpy::@1->memcpy::@1#2] -- register_copy
|
||||
jmp b1
|
||||
//SEG35 memcpy::@1
|
||||
b1:
|
||||
//SEG36 [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda (src),y
|
||||
ldy #0
|
||||
sta (dst),y
|
||||
//SEG37 [14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
//SEG38 [15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
//SEG39 [16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2 -- vwuz1=_inc_vwuz1
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
//SEG40 [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 -- vwuz1_lt_vwuc1_then_la1
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1_from_b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1_from_b1
|
||||
!:
|
||||
jmp breturn
|
||||
//SEG41 memcpy::@return
|
||||
breturn:
|
||||
//SEG42 [18] return
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction lda #0
|
||||
Removing instruction ldy #0
|
||||
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||
Replacing label b1_from_b1 with b1
|
||||
Replacing label b1_from_b1 with b1
|
||||
Removing instruction b1:
|
||||
Removing instruction b2_from_b1:
|
||||
Removing instruction b2:
|
||||
Removing instruction bend_from_b2:
|
||||
Removing instruction b2_from_main:
|
||||
Removing instruction memcpy_from_b2:
|
||||
Removing instruction b1_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction bend:
|
||||
Removing instruction memcpy_from_main:
|
||||
Removing instruction b2:
|
||||
Removing instruction b1_from_memcpy:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction jmp b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
|
||||
(byte) BLACK
|
||||
(const byte) BLACK#0 BLACK = (byte) 0
|
||||
(byte*) COLS
|
||||
(const byte*) COLS#0 COLS = (byte*) 55296
|
||||
(byte*) MEDUSA_COLORS
|
||||
(const byte*) MEDUSA_COLORS#0 MEDUSA_COLORS = (byte*) 5120
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(const byte*) MEDUSA_SCREEN#0 MEDUSA_SCREEN = (byte*) 4096
|
||||
(byte*) SCREEN
|
||||
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(label) memcpy::@1
|
||||
(label) memcpy::@return
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0 dst zp ZP_WORD:4 2.0
|
||||
(byte*) memcpy::dst#1 dst zp ZP_WORD:4 5.5
|
||||
(byte*) memcpy::dst#2 dst zp ZP_WORD:4 17.5
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#1 i zp ZP_WORD:6 16.5
|
||||
(word) memcpy::i#2 i zp ZP_WORD:6 5.5
|
||||
(word) memcpy::num
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0 src zp ZP_WORD:2 2.0
|
||||
(byte*) memcpy::src#1 src zp ZP_WORD:2 7.333333333333333
|
||||
(byte*) memcpy::src#2 src zp ZP_WORD:2 11.666666666666666
|
||||
|
||||
zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 1471
|
||||
|
||||
//SEG0 File Comments
|
||||
// Display MEDUSA PETSCII by Buzz_clik
|
||||
// https://csdb.dk/release/?id=178673
|
||||
//SEG1 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG2 Global Constants & labels
|
||||
.label BGCOL = $d021
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
// The colors of the C64
|
||||
.const BLACK = 0
|
||||
.label MEDUSA_SCREEN = $1000
|
||||
.label MEDUSA_COLORS = $1400
|
||||
.label SCREEN = $400
|
||||
//SEG3 @begin
|
||||
//SEG4 @1
|
||||
//SEG5 kickasm(location (const byte*) MEDUSA_SCREEN#0) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) .fill fileScreen.getSize(), fileScreen.get(i) }}
|
||||
//SEG6 kickasm(location (const byte*) MEDUSA_COLORS#0) {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE) .fill fileCols.getSize(), fileCols.get(i) }}
|
||||
//SEG7 [3] phi from @1 to @2 [phi:@1->@2]
|
||||
//SEG8 @2
|
||||
//SEG9 [4] call main
|
||||
//SEG10 [5] phi from @2 to @end [phi:@2->@end]
|
||||
//SEG11 @end
|
||||
//SEG12 main
|
||||
main: {
|
||||
//SEG13 [6] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2
|
||||
lda #BLACK
|
||||
sta BGCOL
|
||||
//SEG14 [7] call memcpy
|
||||
//SEG15 [11] phi from main to memcpy [phi:main->memcpy]
|
||||
//SEG16 [11] phi (byte*) memcpy::dst#0 = (const byte*) SCREEN#0 [phi:main->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<SCREEN
|
||||
sta memcpy.dst
|
||||
lda #>SCREEN
|
||||
sta memcpy.dst+1
|
||||
//SEG17 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_SCREEN
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_SCREEN
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG18 [8] phi from main to main::@2 [phi:main->main::@2]
|
||||
//SEG19 main::@2
|
||||
//SEG20 [9] call memcpy
|
||||
//SEG21 [11] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
||||
//SEG22 [11] phi (byte*) memcpy::dst#0 = (const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pbuz1=pbuc1
|
||||
lda #<COLS
|
||||
sta memcpy.dst
|
||||
lda #>COLS
|
||||
sta memcpy.dst+1
|
||||
//SEG23 [11] phi (byte*) memcpy::src#0 = (const byte*) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pbuz1=pbuc1
|
||||
lda #<MEDUSA_COLORS
|
||||
sta memcpy.src
|
||||
lda #>MEDUSA_COLORS
|
||||
sta memcpy.src+1
|
||||
jsr memcpy
|
||||
//SEG24 main::@1
|
||||
b1:
|
||||
//SEG25 [10] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2
|
||||
lda #$e
|
||||
eor SCREEN+$3e7
|
||||
sta SCREEN+$3e7
|
||||
jmp b1
|
||||
}
|
||||
//SEG26 memcpy
|
||||
// Copy block of memory
|
||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||
memcpy: {
|
||||
.label src = 2
|
||||
.label dst = 4
|
||||
.label i = 6
|
||||
//SEG27 [12] phi from memcpy to memcpy::@1 [phi:memcpy->memcpy::@1]
|
||||
//SEG28 [12] phi (word) memcpy::i#2 = (byte) 0 [phi:memcpy->memcpy::@1#0] -- vwuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
sta i+1
|
||||
//SEG29 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#0 [phi:memcpy->memcpy::@1#1] -- register_copy
|
||||
//SEG30 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#0 [phi:memcpy->memcpy::@1#2] -- register_copy
|
||||
//SEG31 [12] phi from memcpy::@1 to memcpy::@1 [phi:memcpy::@1->memcpy::@1]
|
||||
//SEG32 [12] phi (word) memcpy::i#2 = (word) memcpy::i#1 [phi:memcpy::@1->memcpy::@1#0] -- register_copy
|
||||
//SEG33 [12] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#1 [phi:memcpy::@1->memcpy::@1#1] -- register_copy
|
||||
//SEG34 [12] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#1 [phi:memcpy::@1->memcpy::@1#2] -- register_copy
|
||||
//SEG35 memcpy::@1
|
||||
b1:
|
||||
//SEG36 [13] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
||||
ldy #0
|
||||
lda (src),y
|
||||
sta (dst),y
|
||||
//SEG37 [14] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
||||
inc dst
|
||||
bne !+
|
||||
inc dst+1
|
||||
!:
|
||||
//SEG38 [15] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
||||
inc src
|
||||
bne !+
|
||||
inc src+1
|
||||
!:
|
||||
//SEG39 [16] (word) memcpy::i#1 ← ++ (word) memcpy::i#2 -- vwuz1=_inc_vwuz1
|
||||
inc i
|
||||
bne !+
|
||||
inc i+1
|
||||
!:
|
||||
//SEG40 [17] if((word) memcpy::i#1<(word) $3e8) goto memcpy::@1 -- vwuz1_lt_vwuc1_then_la1
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1
|
||||
!:
|
||||
//SEG41 memcpy::@return
|
||||
//SEG42 [18] return
|
||||
rts
|
||||
}
|
||||
.pc = MEDUSA_SCREEN "MEDUSA_SCREEN"
|
||||
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
|
||||
.fill fileScreen.getSize(), fileScreen.get(i)
|
||||
|
||||
.pc = MEDUSA_COLORS "MEDUSA_COLORS"
|
||||
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
|
||||
.fill fileCols.getSize(), fileCols.get(i)
|
||||
|
||||
|
41
src/test/ref/medusa.sym
Normal file
41
src/test/ref/medusa.sym
Normal file
@ -0,0 +1,41 @@
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
|
||||
(byte) BLACK
|
||||
(const byte) BLACK#0 BLACK = (byte) 0
|
||||
(byte*) COLS
|
||||
(const byte*) COLS#0 COLS = (byte*) 55296
|
||||
(byte*) MEDUSA_COLORS
|
||||
(const byte*) MEDUSA_COLORS#0 MEDUSA_COLORS = (byte*) 5120
|
||||
(byte*) MEDUSA_SCREEN
|
||||
(const byte*) MEDUSA_SCREEN#0 MEDUSA_SCREEN = (byte*) 4096
|
||||
(byte*) SCREEN
|
||||
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(byte*()) memcpy((byte*) memcpy::destination , (byte*) memcpy::source , (word) memcpy::num)
|
||||
(label) memcpy::@1
|
||||
(label) memcpy::@return
|
||||
(byte*) memcpy::destination
|
||||
(byte*) memcpy::dst
|
||||
(byte*) memcpy::dst#0 dst zp ZP_WORD:4 2.0
|
||||
(byte*) memcpy::dst#1 dst zp ZP_WORD:4 5.5
|
||||
(byte*) memcpy::dst#2 dst zp ZP_WORD:4 17.5
|
||||
(word) memcpy::i
|
||||
(word) memcpy::i#1 i zp ZP_WORD:6 16.5
|
||||
(word) memcpy::i#2 i zp ZP_WORD:6 5.5
|
||||
(word) memcpy::num
|
||||
(byte*) memcpy::return
|
||||
(byte*) memcpy::source
|
||||
(byte*) memcpy::src
|
||||
(byte*) memcpy::src#0 src zp ZP_WORD:2 2.0
|
||||
(byte*) memcpy::src#1 src zp ZP_WORD:2 7.333333333333333
|
||||
(byte*) memcpy::src#2 src zp ZP_WORD:2 11.666666666666666
|
||||
|
||||
zp ZP_WORD:2 [ memcpy::src#2 memcpy::src#0 memcpy::src#1 ]
|
||||
zp ZP_WORD:4 [ memcpy::dst#2 memcpy::dst#0 memcpy::dst#1 ]
|
||||
zp ZP_WORD:6 [ memcpy::i#2 memcpy::i#1 ]
|
Loading…
Reference in New Issue
Block a user