mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-19 11:31:57 +00:00
Added lexer support for all mnemonics used in CPU 65C02. Added Cpu65C02 instruction set.
This commit is contained in:
parent
a454ee2cdd
commit
ba9f99059a
@ -313,33 +313,33 @@ public class AsmInstructionSet {
|
|||||||
* This will try to find a zeropage-based addressing mode if you indicate that you are interested in that.
|
* This will try to find a zeropage-based addressing mode if you indicate that you are interested in that.
|
||||||
*
|
*
|
||||||
* @param mnemonic The mnemonic
|
* @param mnemonic The mnemonic
|
||||||
* @param mode The addressing mode you want.
|
* @param addressingMode The addressing mode you want.
|
||||||
* @param isZp Indicates whether you are interested in a zeropage-based opcode.
|
* @param isOperandZp Indicates whether the operand is <256 meaning the opcode could be zeropage-based.
|
||||||
* @return The opcode, if it exists. If you have requested an absolute addressing mode passed isZp as true the
|
* @return The opcode, if it exists. If you have requested an absolute addressing mode and pass isOperandZp as true the
|
||||||
* resulting opcode will have zeropage-based addressing the instruction set offers that.
|
* resulting opcode will have zeropage-based addressing if the instruction set offers that.
|
||||||
*/
|
*/
|
||||||
public static AsmOpcode getOpcode(String mnemonic, AsmAddressingMode mode, boolean isZp) {
|
public static AsmOpcode getOpcode(String mnemonic, AsmAddressingMode addressingMode, boolean isOperandZp) {
|
||||||
AsmOpcode asmOpcode = null;
|
AsmOpcode asmOpcode = null;
|
||||||
if(AsmAddressingMode.ABS.equals(mode) && isZp) {
|
if(AsmAddressingMode.ABS.equals(addressingMode) && isOperandZp) {
|
||||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZP);
|
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZP);
|
||||||
}
|
}
|
||||||
if(AsmAddressingMode.ABX.equals(mode) && isZp) {
|
if(AsmAddressingMode.ABX.equals(addressingMode) && isOperandZp) {
|
||||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZPX);
|
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZPX);
|
||||||
}
|
}
|
||||||
if(AsmAddressingMode.ABY.equals(mode) && isZp) {
|
if(AsmAddressingMode.ABY.equals(addressingMode) && isOperandZp) {
|
||||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZPY);
|
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZPY);
|
||||||
}
|
}
|
||||||
if(AsmAddressingMode.IND.equals(mode) && isZp) {
|
if(AsmAddressingMode.IND.equals(addressingMode) && isOperandZp) {
|
||||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.INZ);
|
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.INZ);
|
||||||
}
|
}
|
||||||
if(AsmAddressingMode.IAX.equals(mode) && isZp) {
|
if(AsmAddressingMode.IAX.equals(addressingMode) && isOperandZp) {
|
||||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.IZX);
|
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.IZX);
|
||||||
}
|
}
|
||||||
if(asmOpcode == null) {
|
if(asmOpcode == null) {
|
||||||
// If the ZP-variation does not exist use the ABS-variation
|
// If the ZP-form does not exist use the ABS-variation
|
||||||
asmOpcode = set.getOpcode(mnemonic, mode);
|
asmOpcode = set.getOpcode(mnemonic, addressingMode);
|
||||||
}
|
}
|
||||||
if(asmOpcode == null && AsmAddressingMode.ABS.equals(mode)) {
|
if(asmOpcode == null && AsmAddressingMode.ABS.equals(addressingMode)) {
|
||||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.REL);
|
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.REL);
|
||||||
}
|
}
|
||||||
return asmOpcode;
|
return asmOpcode;
|
||||||
|
@ -9,10 +9,10 @@ import dk.camelot64.cpufamily6502.AsmCpu;
|
|||||||
*/
|
*/
|
||||||
public class Cpu6502Illegal extends AsmCpu {
|
public class Cpu6502Illegal extends AsmCpu {
|
||||||
|
|
||||||
/** The 6502 with illegal CPU name. */
|
/** The 6502 with illegal instructions CPU name. */
|
||||||
public final static String NAME = "6502x";
|
public final static String NAME = "6502x";
|
||||||
|
|
||||||
/** The 6502 with illegal CPU. */
|
/** The 6502 with illegal instructions CPU. */
|
||||||
public final static Cpu6502Illegal INSTANCE = new Cpu6502Illegal();
|
public final static Cpu6502Illegal INSTANCE = new Cpu6502Illegal();
|
||||||
|
|
||||||
public Cpu6502Illegal() {
|
public Cpu6502Illegal() {
|
||||||
|
85
src/main/java/dk/camelot64/cpufamily6502/cpus/Cpu65C02.java
Normal file
85
src/main/java/dk/camelot64/cpufamily6502/cpus/Cpu65C02.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package dk.camelot64.cpufamily6502.cpus;
|
||||||
|
|
||||||
|
import dk.camelot64.cpufamily6502.AsmAddressingMode;
|
||||||
|
import dk.camelot64.cpufamily6502.AsmCpu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 65C02 instruction set.
|
||||||
|
* https://eater.net/datasheets/w65c02s.pdf
|
||||||
|
*/
|
||||||
|
public class Cpu65C02 extends AsmCpu {
|
||||||
|
|
||||||
|
/** The 65C02 CPU name. */
|
||||||
|
public final static String NAME = "65c02";
|
||||||
|
|
||||||
|
/** The 65C02 with illegal CPU. */
|
||||||
|
public final static Cpu65C02 INSTANCE = new Cpu65C02();
|
||||||
|
|
||||||
|
public Cpu65C02() {
|
||||||
|
super(NAME, Cpu6502Official.INSTANCE);
|
||||||
|
addOpcode(0x4,"tsb",AsmAddressingMode.ZP,5,"z");
|
||||||
|
addOpcode(0x7,"rmb0",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0xC,"tsb",AsmAddressingMode.ABS,6,"z");
|
||||||
|
addOpcode(0xF,"bbr0",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x12,"ora",AsmAddressingMode.INZ,5,"Anz");
|
||||||
|
addOpcode(0x14,"trb",AsmAddressingMode.ZP,5,"z");
|
||||||
|
addOpcode(0x17,"rmb1",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x1A,"inc",AsmAddressingMode.NON,2,"Anz");
|
||||||
|
addOpcode(0x1C,"trb",AsmAddressingMode.ABS,6,"z");
|
||||||
|
addOpcode(0x1F,"bbr1",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x27,"rmb2",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x2F,"bbr2",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x32,"and",AsmAddressingMode.INZ,5,"Anz");
|
||||||
|
addOpcode(0x34,"bit",AsmAddressingMode.ZPX,4,"nvz");
|
||||||
|
addOpcode(0x37,"rmb3",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x3A,"dec",AsmAddressingMode.NON,2,"Anz");
|
||||||
|
addOpcode(0x3C,"bit",AsmAddressingMode.ZPX,4.5,"nvz");
|
||||||
|
addOpcode(0x3F,"bbr3",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x47,"rmb4",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x4F,"bbr4",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x52,"eor",AsmAddressingMode.INZ,5,"Anz");
|
||||||
|
addOpcode(0x57,"rmb5",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x5A,"phy",AsmAddressingMode.NON,3,"");
|
||||||
|
addOpcode(0x5F,"bbr5",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x64,"stz",AsmAddressingMode.ZP,3,"");
|
||||||
|
addOpcode(0x67,"rmb6",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x6F,"bbr6",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x72,"adc",AsmAddressingMode.INZ,5,"Acvnz");
|
||||||
|
addOpcode(0x74,"stz",AsmAddressingMode.ZPX,4,"");
|
||||||
|
addOpcode(0x77,"rmb7",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x7A,"ply",AsmAddressingMode.NON,4,"Ynz");
|
||||||
|
addOpcode(0x7C,"jmp",AsmAddressingMode.IAX,6,"");
|
||||||
|
addOpcode(0x7F,"bbr7",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x80,"bra",AsmAddressingMode.NON,3,"");
|
||||||
|
addOpcode(0x87,"smb0",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x89,"bit",AsmAddressingMode.IAX,2,"z");
|
||||||
|
addOpcode(0x8F,"bbs0",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0x92,"sta",AsmAddressingMode.INZ,5,"");
|
||||||
|
addOpcode(0x97,"smb1",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0x9C,"stz",AsmAddressingMode.ABS,4,"");
|
||||||
|
addOpcode(0x9E,"stz",AsmAddressingMode.ZPX,5,"");
|
||||||
|
addOpcode(0x9F,"bbs1",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0xA7,"smb2",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0xAF,"bbs2",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0xB2,"lda",AsmAddressingMode.INZ,5,"Anz");
|
||||||
|
addOpcode(0xB7,"smb3",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0xBF,"bbs3",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0xC7,"smb4",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0xCB,"wai",AsmAddressingMode.NON,3,"");
|
||||||
|
addOpcode(0xCF,"bbs4",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0xD2,"cmp",AsmAddressingMode.INZ,5,"cnz");
|
||||||
|
addOpcode(0xD7,"smb5",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0xDA,"phx",AsmAddressingMode.NON,3,"");
|
||||||
|
addOpcode(0xDB,"stp",AsmAddressingMode.NON,3,"");
|
||||||
|
addOpcode(0xDF,"bbs5",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0xE7,"smb6",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0xEF,"bbs6",AsmAddressingMode.REZ,5,"");
|
||||||
|
addOpcode(0xF2,"sbc",AsmAddressingMode.INZ,5,"Acvnz");
|
||||||
|
addOpcode(0xF7,"smb7",AsmAddressingMode.ZP,5,"");
|
||||||
|
addOpcode(0xFA,"plx",AsmAddressingMode.NON,4,"Xnz");
|
||||||
|
addOpcode(0xFF,"bbs7",AsmAddressingMode.REZ,5,"");
|
||||||
|
|
||||||
|
// TODO: Cycle differences for ASL LSR ROL ROR abs,X - http://6502.org/tutorials/65c02opcodes.html
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -173,7 +173,10 @@ ASM_MNEMONIC:
|
|||||||
'brk' | 'ora' | 'kil' | 'slo' | 'nop' | 'asl' | 'php' | 'anc' | 'bpl' | 'clc' | 'jsr' | 'and' | 'rla' | 'bit' | 'rol' | 'pla' | 'plp' | 'bmi' | 'sec' |
|
'brk' | 'ora' | 'kil' | 'slo' | 'nop' | 'asl' | 'php' | 'anc' | 'bpl' | 'clc' | 'jsr' | 'and' | 'rla' | 'bit' | 'rol' | 'pla' | 'plp' | 'bmi' | 'sec' |
|
||||||
'rti' | 'eor' | 'sre' | 'lsr' | 'pha' | 'alr' | 'jmp' | 'bvc' | 'cli' | 'rts' | 'adc' | 'rra' | 'bvs' | 'sei' | 'sax' | 'sty' | 'sta' | 'stx' | 'dey' |
|
'rti' | 'eor' | 'sre' | 'lsr' | 'pha' | 'alr' | 'jmp' | 'bvc' | 'cli' | 'rts' | 'adc' | 'rra' | 'bvs' | 'sei' | 'sax' | 'sty' | 'sta' | 'stx' | 'dey' |
|
||||||
'txa' | 'xaa' | 'bcc' | 'ahx' | 'tya' | 'txs' | 'tas' | 'shy' | 'shx' | 'ldy' | 'lda' | 'ldx' | 'lax' | 'tay' | 'tax' | 'bcs' | 'clv' | 'tsx' | 'las' |
|
'txa' | 'xaa' | 'bcc' | 'ahx' | 'tya' | 'txs' | 'tas' | 'shy' | 'shx' | 'ldy' | 'lda' | 'ldx' | 'lax' | 'tay' | 'tax' | 'bcs' | 'clv' | 'tsx' | 'las' |
|
||||||
'cpy' | 'cmp' | 'cpx' | 'dcp' | 'dec' | 'inc' | 'axs' | 'bne' | 'cld' | 'sbc' | 'isc' | 'inx' | 'beq' | 'sed' | 'dex' | 'iny' | 'ror'
|
'cpy' | 'cmp' | 'cpx' | 'dcp' | 'dec' | 'inc' | 'axs' | 'bne' | 'cld' | 'sbc' | 'isc' | 'inx' | 'beq' | 'sed' | 'dex' | 'iny' | 'ror' | 'bbr0'| 'bbr1'|
|
||||||
|
'bbr2'| 'bbr3'| 'bbr4'| 'bbr5'| 'bbr6'| 'bbr7'| 'bbs0'| 'bbs1'| 'bbs2'| 'bbs3'| 'bbs4'| 'bbs5'| 'bbs6'| 'bbs7'| 'bra' | 'phx' | 'phy' | 'plx' | 'ply' |
|
||||||
|
'rmb0'| 'rmb1'| 'rmb2'| 'rmb3'| 'rmb4'| 'rmb5'| 'rmb6'| 'rmb7'| 'smb0'| 'smb1'| 'smb2'| 'smb3'| 'smb4'| 'smb5'| 'smb6'| 'smb7'| 'stp' | 'stz' | 'trb' |
|
||||||
|
'tsb'| 'wai'
|
||||||
;
|
;
|
||||||
|
|
||||||
ASM_IMM : '#' ;
|
ASM_IMM : '#' ;
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -43,8 +43,23 @@ public class TestPrograms {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAsmAddressingModes() throws IOException, URISyntaxException {
|
public void testCpuAddressingModes() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("asm-addressing-modes.c");
|
compileAndCompare("cpu-addressing-modes.c");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMega65C65ce02() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("cpu-45gs02.c");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCpu65C02() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("cpu-65c02.c");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCpu6502() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("cpu-6502.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -949,21 +964,6 @@ public class TestPrograms {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMega65C65ce02() throws IOException, URISyntaxException {
|
|
||||||
compileAndCompare("cpu-45gs02.c");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCpu65C02() throws IOException, URISyntaxException {
|
|
||||||
compileAndCompare("cpu-65c02.c");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCpu6502() throws IOException, URISyntaxException {
|
|
||||||
compileAndCompare("cpu-6502.c");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testZpCode() throws IOException, URISyntaxException {
|
public void testZpCode() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("examples/zpcode/zpcode.c");
|
compileAndCompare("examples/zpcode/zpcode.c");
|
||||||
@ -4058,6 +4058,11 @@ public class TestPrograms {
|
|||||||
compileAndCompare("incd020.c");
|
compileAndCompare("incd020.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIncD0202() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("incd020-2.c", log());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOverlapAllocation2() throws IOException, URISyntaxException {
|
public void testOverlapAllocation2() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("overlap-allocation-2.c");
|
compileAndCompare("overlap-allocation-2.c");
|
||||||
|
@ -8,12 +8,12 @@ void main() {
|
|||||||
// Indirect
|
// Indirect
|
||||||
jmp ($1234)
|
jmp ($1234)
|
||||||
|
|
||||||
|
// TODO Indirect Zeropage
|
||||||
|
// ora ($12)
|
||||||
|
|
||||||
// TODO: Indirect ABS,x
|
// TODO: Indirect ABS,x
|
||||||
// jmp ($1234,x)
|
// jmp ($1234,x)
|
||||||
|
|
||||||
// TODO Indirect Zeropage
|
|
||||||
//jmp ($12)
|
|
||||||
|
|
||||||
// TODO test relative
|
// TODO test relative
|
||||||
// lda $12, $1234
|
// lda $12, $1234
|
||||||
|
|
7
src/test/kc/incd020-2.c
Normal file
7
src/test/kc/incd020-2.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
do {
|
||||||
|
(*(unsigned char *)(53280))++;
|
||||||
|
} while ( (*(unsigned char *)(53280)) < 255);
|
||||||
|
}
|
14
src/test/ref/incd020-2.asm
Normal file
14
src/test/ref/incd020-2.asm
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
main: {
|
||||||
|
__b1:
|
||||||
|
// (*(unsigned char *)(53280))++;
|
||||||
|
inc $d020
|
||||||
|
// while ( (*(unsigned char *)(53280)) < 255)
|
||||||
|
lda $d020
|
||||||
|
cmp #$ff
|
||||||
|
bcc __b1
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
}
|
12
src/test/ref/incd020-2.cfg
Normal file
12
src/test/ref/incd020-2.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from
|
||||||
|
[0] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@1
|
||||||
|
[1] *((byte*) 53280) ← ++ *((byte*) 53280)
|
||||||
|
[2] if(*((byte*) 53280)<(byte) $ff) goto main::@1
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[3] return
|
||||||
|
to:@return
|
183
src/test/ref/incd020-2.log
Normal file
183
src/test/ref/incd020-2.log
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from __start
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@1
|
||||||
|
*((byte*)(number) $d020) ← ++ *((byte*)(number) $d020)
|
||||||
|
(bool~) main::$1 ← *((byte*)(number) $d020) < (number) $ff
|
||||||
|
if((bool~) main::$1) goto main::@1
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
(void()) __start()
|
||||||
|
__start: scope:[__start] from
|
||||||
|
call main
|
||||||
|
to:__start::@1
|
||||||
|
__start::@1: scope:[__start] from __start
|
||||||
|
to:__start::@return
|
||||||
|
__start::@return: scope:[__start] from __start::@1
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
SYMBOL TABLE SSA
|
||||||
|
(void()) __start()
|
||||||
|
(label) __start::@1
|
||||||
|
(label) __start::@return
|
||||||
|
(void()) main()
|
||||||
|
(bool~) main::$1
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@return
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) $ff in (bool~) main::$1 ← *((byte*)(number) $d020) < (number) $ff
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Simplifying constant pointer cast (byte*) 53280
|
||||||
|
Simplifying constant pointer cast (byte*) 53280
|
||||||
|
Simplifying constant pointer cast (byte*) 53280
|
||||||
|
Simplifying constant integer cast $ff
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (byte) $ff
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Simple Condition (bool~) main::$1 [2] if(*((byte*) 53280)<(byte) $ff) goto main::@1
|
||||||
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||||
|
Removing unused procedure __start
|
||||||
|
Removing unused procedure block __start
|
||||||
|
Removing unused procedure block __start::@1
|
||||||
|
Removing unused procedure block __start::@return
|
||||||
|
Successful SSA optimization PassNEliminateEmptyStart
|
||||||
|
Adding NOP phi() at start of main
|
||||||
|
CALL GRAPH
|
||||||
|
|
||||||
|
Created 0 initial phi equivalence classes
|
||||||
|
Coalesced down to 0 phi equivalence classes
|
||||||
|
Adding NOP phi() at start of main
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from
|
||||||
|
[0] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@1
|
||||||
|
[1] *((byte*) 53280) ← ++ *((byte*) 53280)
|
||||||
|
[2] if(*((byte*) 53280)<(byte) $ff) goto main::@1
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[3] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
(void()) main()
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
Complete equivalence classes
|
||||||
|
|
||||||
|
INITIAL ASM
|
||||||
|
Target platform is c64basic / MOS6502X
|
||||||
|
// File Comments
|
||||||
|
// Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [1] *((byte*) 53280) ← ++ *((byte*) 53280) -- _deref_pbuc1=_inc__deref_pbuc1
|
||||||
|
inc $d020
|
||||||
|
// [2] if(*((byte*) 53280)<(byte) $ff) goto main::@1 -- _deref_pbuc1_lt_vbuc2_then_la1
|
||||||
|
lda $d020
|
||||||
|
cmp #$ff
|
||||||
|
bcc __b1
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [3] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [2] if(*((byte*) 53280)<(byte) $ff) goto main::@1 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [main]
|
||||||
|
Uplift Scope []
|
||||||
|
|
||||||
|
Uplifting [main] best 211 combination
|
||||||
|
Uplifting [] best 211 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
// File Comments
|
||||||
|
// Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [1] *((byte*) 53280) ← ++ *((byte*) 53280) -- _deref_pbuc1=_inc__deref_pbuc1
|
||||||
|
inc $d020
|
||||||
|
// [2] if(*((byte*) 53280)<(byte) $ff) goto main::@1 -- _deref_pbuc1_lt_vbuc2_then_la1
|
||||||
|
lda $d020
|
||||||
|
cmp #$ff
|
||||||
|
bcc __b1
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [3] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 151
|
||||||
|
|
||||||
|
// File Comments
|
||||||
|
// Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// (*(unsigned char *)(53280))++;
|
||||||
|
// [1] *((byte*) 53280) ← ++ *((byte*) 53280) -- _deref_pbuc1=_inc__deref_pbuc1
|
||||||
|
inc $d020
|
||||||
|
// while ( (*(unsigned char *)(53280)) < 255)
|
||||||
|
// [2] if(*((byte*) 53280)<(byte) $ff) goto main::@1 -- _deref_pbuc1_lt_vbuc2_then_la1
|
||||||
|
lda $d020
|
||||||
|
cmp #$ff
|
||||||
|
bcc __b1
|
||||||
|
// main::@return
|
||||||
|
// }
|
||||||
|
// [3] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
4
src/test/ref/incd020-2.sym
Normal file
4
src/test/ref/incd020-2.sym
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@return
|
||||||
|
|
Loading…
Reference in New Issue
Block a user