mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-25 11:32:07 +00:00
Added support fro 45GS02 CPU addressing modes and instructions. Added a few 45GS02 optimized fragments.
This commit is contained in:
parent
1a436a67a3
commit
f27fe1a75c
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE 155084773d
|
//KICKC FRAGMENT CACHE 15bc71afc6
|
||||||
//FRAGMENT vbsz1=_deref_pbsc1
|
//FRAGMENT vbsz1=_deref_pbsc1
|
||||||
lda {c1}
|
lda {c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
|
44
src/main/fragment/cache/fragment-cache-mega45gs02.asm
vendored
Normal file
44
src/main/fragment/cache/fragment-cache-mega45gs02.asm
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//KICKC FRAGMENT CACHE 15bc71afc6
|
||||||
|
//FRAGMENT vduz1=vduc1
|
||||||
|
lda #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
sta {z1}+1
|
||||||
|
lda #<{c1}>>$10
|
||||||
|
sta {z1}+2
|
||||||
|
lda #>{c1}>>$10
|
||||||
|
sta {z1}+3
|
||||||
|
//FRAGMENT vbuz1=vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1_lt_vbuc1_then_la1
|
||||||
|
lda {z1}
|
||||||
|
cmp #{c1}
|
||||||
|
bcc {la1}
|
||||||
|
//FRAGMENT _deref_pduc1=vduz1
|
||||||
|
ldq {z1}
|
||||||
|
stq {c1}
|
||||||
|
//FRAGMENT vduz1=vduz1_plus_vduz2
|
||||||
|
clc
|
||||||
|
ldq {z1}
|
||||||
|
adcq {z2}
|
||||||
|
stq {z1}
|
||||||
|
//FRAGMENT vduz1=vduz1_plus_vbuz2
|
||||||
|
lda {z2}
|
||||||
|
clc
|
||||||
|
adc {z1}
|
||||||
|
sta {z1}
|
||||||
|
lda {z1}+1
|
||||||
|
adc #0
|
||||||
|
sta {z1}+1
|
||||||
|
lda {z1}+2
|
||||||
|
adc #0
|
||||||
|
sta {z1}+2
|
||||||
|
lda {z1}+3
|
||||||
|
adc #0
|
||||||
|
sta {z1}+3
|
||||||
|
//FRAGMENT vbuz1=_inc_vbuz1
|
||||||
|
inc {z1}
|
||||||
|
//FRAGMENT vbuaa_lt_vbuc1_then_la1
|
||||||
|
cmp #{c1}
|
||||||
|
bcc {la1}
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE 155084773d
|
//KICKC FRAGMENT CACHE 15bc71afc6
|
||||||
//FRAGMENT vbuz1=vbuc1
|
//FRAGMENT vbuz1=vbuc1
|
||||||
lda #{c1}
|
lda #{c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE 155084773d
|
//KICKC FRAGMENT CACHE 15bc71afc6
|
||||||
//FRAGMENT vbuz1=vbuc1
|
//FRAGMENT vbuz1=vbuc1
|
||||||
lda #{c1}
|
lda #{c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE 155084773d
|
//KICKC FRAGMENT CACHE 15bc71afc6
|
||||||
//FRAGMENT vbuz1=_deref_pbuc1
|
//FRAGMENT vbuz1=_deref_pbuc1
|
||||||
lda {c1}
|
lda {c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
ldq {m1}
|
||||||
|
stq {c1}
|
@ -0,0 +1,4 @@
|
|||||||
|
clc
|
||||||
|
ldq {m1}
|
||||||
|
adcq {m2}
|
||||||
|
stq {m1}
|
@ -1,13 +1,16 @@
|
|||||||
package dk.camelot64.cpufamily6502;
|
package dk.camelot64.cpufamily6502;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 6502 family CPU. The CPU has an instruction set.
|
* A 6502 family CPU. The CPU has an instruction set.
|
||||||
*/
|
*/
|
||||||
public class Cpu65xx {
|
public class Cpu65xx {
|
||||||
|
|
||||||
/** The CPU name. */
|
/** The CPU name. */
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
/** All opcodes in the instruction set. */
|
/** All opcodes in the instruction set. */
|
||||||
@ -40,8 +43,19 @@ public class Cpu65xx {
|
|||||||
* @param cycles The number of cycles
|
* @param cycles The number of cycles
|
||||||
*/
|
*/
|
||||||
protected void addOpcode(int opcode, String mnemonic, CpuAddressingMode addressingMode, double cycles, String clobberString) {
|
protected void addOpcode(int opcode, String mnemonic, CpuAddressingMode addressingMode, double cycles, String clobberString) {
|
||||||
CpuOpcode cpuOpcode = new CpuOpcode(opcode, mnemonic, addressingMode, cycles, clobberString);
|
addOpcode(new int[opcode], mnemonic, addressingMode, cycles, clobberString);
|
||||||
addOpcode(cpuOpcode);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an instruction opcode to the instruction set.
|
||||||
|
*
|
||||||
|
* @param opcode The numeric opcodes
|
||||||
|
* @param mnemonic The lower case mnemonic
|
||||||
|
* @param addressingMode The addressing mode
|
||||||
|
* @param cycles The number of cycles
|
||||||
|
*/
|
||||||
|
protected void addOpcode(int[] opcode, String mnemonic, CpuAddressingMode addressingMode, double cycles, String clobberString) {
|
||||||
|
addOpcode(new CpuOpcode(opcode, mnemonic, addressingMode, cycles, clobberString));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,8 +26,8 @@ public class CpuOpcode {
|
|||||||
/** Which registers/flags of the CPU are clobbered by the instruction. */
|
/** Which registers/flags of the CPU are clobbered by the instruction. */
|
||||||
private final CpuClobber clobber;
|
private final CpuClobber clobber;
|
||||||
|
|
||||||
CpuOpcode(int opcode, String mnemonic, CpuAddressingMode addressingMode, double cycles, String clobberString) {
|
CpuOpcode(int[] opcode, String mnemonic, CpuAddressingMode addressingMode, double cycles, String clobberString) {
|
||||||
this.opcode = new int[]{opcode};
|
this.opcode = opcode;
|
||||||
this.mnemonic = mnemonic;
|
this.mnemonic = mnemonic;
|
||||||
this.addressingMode = addressingMode;
|
this.addressingMode = addressingMode;
|
||||||
this.cycles = cycles;
|
this.cycles = cycles;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package dk.camelot64.cpufamily6502.cpus;
|
package dk.camelot64.cpufamily6502.cpus;
|
||||||
|
|
||||||
import dk.camelot64.cpufamily6502.Cpu65xx;
|
import dk.camelot64.cpufamily6502.Cpu65xx;
|
||||||
|
import dk.camelot64.cpufamily6502.CpuAddressingMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The 45GS02 instruction set.
|
* The 45GS02 instruction set.
|
||||||
@ -16,8 +17,88 @@ public class Cpu45GS02 extends Cpu65xx {
|
|||||||
|
|
||||||
public Cpu45GS02() {
|
public Cpu45GS02() {
|
||||||
super(NAME, Cpu65CE02.INSTANCE);
|
super(NAME, Cpu65CE02.INSTANCE);
|
||||||
// TODO: Add 45GS02 instructions
|
addOpcode(new int[]{0x42, 0x42, 0x5}, "orq", CpuAddressingMode.ZP, 8, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x6}, "aslq", CpuAddressingMode.ZP, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xA}, "aslq", CpuAddressingMode.NON, 3, "AXYZcnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xD}, "orq", CpuAddressingMode.ABS, 9, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xE}, "aslq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x12}, "orq", CpuAddressingMode.INZ, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x16}, "aslq", CpuAddressingMode.ZPX, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x1A}, "inq", CpuAddressingMode.NON, 3, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x1E}, "aslq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x24}, "bitq", CpuAddressingMode.ZP, 8, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x25}, "andq", CpuAddressingMode.ZP, 8, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x26}, "rolq", CpuAddressingMode.ZP, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x2A}, "rolq", CpuAddressingMode.NON, 3, "AXYZcnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x2C}, "bitq", CpuAddressingMode.ABS, 8, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x2D}, "andq", CpuAddressingMode.ABS, 9, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x2E}, "rolq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x32}, "andq", CpuAddressingMode.INZ, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x36}, "rolq", CpuAddressingMode.ZPX, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x3A}, "deq", CpuAddressingMode.NON, 3, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x3E}, "rolq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x43}, "asrq", CpuAddressingMode.NON, 3, "AXYZcnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x44}, "asrq", CpuAddressingMode.ZP, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x45}, "eorq", CpuAddressingMode.ZP, 8, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x46}, "lsrq", CpuAddressingMode.ZP, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x4A}, "lsrq", CpuAddressingMode.NON, 3, "AXYZcnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x4D}, "eorq", CpuAddressingMode.ABS, 9, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x4E}, "lsrq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x52}, "eorq", CpuAddressingMode.INZ, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x54}, "asrq", CpuAddressingMode.ZPX, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x56}, "lsrq", CpuAddressingMode.ZPX, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x5E}, "lsrq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x65}, "adcq", CpuAddressingMode.ZP, 8, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x66}, "rorq", CpuAddressingMode.ZP, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x6A}, "rorq", CpuAddressingMode.NON, 3, "AXYZcnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x6D}, "adcq", CpuAddressingMode.ABS, 9, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x6E}, "rorq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x72}, "adcq", CpuAddressingMode.INZ, 10, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x76}, "rorq", CpuAddressingMode.ZPX, 12, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x7E}, "rorq", CpuAddressingMode.ABS, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x82}, "stq", CpuAddressingMode.ISY, 10, "");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x85}, "stq", CpuAddressingMode.ZP, 8, "");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x8D}, "stq", CpuAddressingMode.ABS, 9, "");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0x92}, "stq", CpuAddressingMode.INZ, 10, "");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xA1}, "ldq", CpuAddressingMode.ISY, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xA5}, "ldq", CpuAddressingMode.ZP, 8, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xAD}, "ldq", CpuAddressingMode.ABS, 9, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xB1}, "ldq", CpuAddressingMode.INZ, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xB2}, "ldq", CpuAddressingMode.INZ, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xB5}, "ldq", CpuAddressingMode.ZPX, 9, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xB9}, "ldq", CpuAddressingMode.ABS, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xBD}, "ldq", CpuAddressingMode.ABS, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xC5}, "cpq", CpuAddressingMode.ZP, 8, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xC6}, "deq", CpuAddressingMode.ZP, 12, "nz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xCD}, "cpq", CpuAddressingMode.ABS, 9, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xCE}, "deq", CpuAddressingMode.ABS, 13, "nz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xD2}, "cpq", CpuAddressingMode.INZ, 10, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xD6}, "deq", CpuAddressingMode.ZPX, 12, "nz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xDE}, "deq", CpuAddressingMode.ABS, 13, "nz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xE2}, "ldq", CpuAddressingMode.ISY, 10, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xE5}, "sbcq", CpuAddressingMode.ZP, 8, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xE6}, "inq", CpuAddressingMode.ZP, 13, "nz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0x12}, "orq", CpuAddressingMode.LIN, 13, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0x32}, "andq", CpuAddressingMode.LIN, 13, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0x52}, "eorq", CpuAddressingMode.LIN, 13, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0x72}, "adcq", CpuAddressingMode.LIN, 13, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0x92}, "stq", CpuAddressingMode.LIN, 13, "");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0xB2}, "ldq", CpuAddressingMode.LIN, 13, "AXYZnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0xD2}, "cpq", CpuAddressingMode.LIN, 13, "cnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xea, 0xF2}, "sbcq", CpuAddressingMode.LIN, 13, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xED}, "sbcq", CpuAddressingMode.ABS, 9, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xEE}, "inq", CpuAddressingMode.ABS, 14, "nz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xF2}, "sbcq", CpuAddressingMode.INZ, 10, "AXYZcvnz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xF6}, "inq", CpuAddressingMode.ZPX, 13, "nz");
|
||||||
|
addOpcode(new int[]{0x42, 0x42, 0xFE}, "inq", CpuAddressingMode.ABS, 14, "nz");
|
||||||
|
addOpcode(new int[]{0xea, 0x12}, "ora", CpuAddressingMode.LIZ, 7, "Anz");
|
||||||
|
addOpcode(new int[]{0xea, 0x32}, "and", CpuAddressingMode.LIZ, 7, "Anz");
|
||||||
|
addOpcode(new int[]{0xea, 0x52}, "eor", CpuAddressingMode.LIZ, 7, "Anz");
|
||||||
|
addOpcode(new int[]{0xea, 0x72}, "adc", CpuAddressingMode.LIZ, 7, "Acvnz");
|
||||||
|
addOpcode(new int[]{0xea, 0x92}, "sta", CpuAddressingMode.LIZ, 8, "");
|
||||||
|
addOpcode(new int[]{0xea, 0xB2}, "lda", CpuAddressingMode.LIZ, 7, "Anz");
|
||||||
|
addOpcode(new int[]{0xea, 0xD2}, "cmp", CpuAddressingMode.LIZ, 7, "cnz");
|
||||||
|
addOpcode(new int[]{0xea, 0xF2}, "sbc", CpuAddressingMode.LIZ, 8, "Acvnz");
|
||||||
// TODO: Disable NOP?
|
// TODO: Disable NOP?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ public class AsmFragmentInstance {
|
|||||||
String operand1 = param1 == null ? null : param1.getParam();
|
String operand1 = param1 == null ? null : param1.getParam();
|
||||||
String operand2 = param2 == null ? null : param2.getParam();
|
String operand2 = param2 == null ? null : param2.getParam();
|
||||||
if(cpuOpcode == null) {
|
if(cpuOpcode == null) {
|
||||||
throw new InternalError("Error in " + name + ".asm line " + instructionCtx.getStart().getLine() + " - Instruction type not supported " + addressingMode.getAsm(mnemonic, operand1, operand2));
|
throw new InternalError("Error in " + name + ".asm line " + instructionCtx.getStart().getLine() + " - Instruction type not supported " + addressingMode.getAsm(mnemonic, operand1, operand2) +" by CPU "+this.fragmentInstance.fragmentTemplate.getTargetCpu().getName());
|
||||||
}
|
}
|
||||||
return new AsmInstruction(cpuOpcode, operand1, operand2);
|
return new AsmInstruction(cpuOpcode, operand1, operand2);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,8 @@ ASM_MNEMONIC:
|
|||||||
'bbr2'| 'bbr3'| 'bbr4'| 'bbr5'| 'bbr6'| 'bbr7'| 'bbs0'| 'bbs1'| 'bbs2'| 'bbs3'| 'bbs4'| 'bbs5'| 'bbs6'| 'bbs7'| 'bra' | 'phx' | 'phy' | 'plx' | 'ply' |
|
'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' |
|
'rmb0'| 'rmb1'| 'rmb2'| 'rmb3'| 'rmb4'| 'rmb5'| 'rmb6'| 'rmb7'| 'smb0'| 'smb1'| 'smb2'| 'smb3'| 'smb4'| 'smb5'| 'smb6'| 'smb7'| 'stp' | 'stz' | 'trb' |
|
||||||
'tsb' | 'wai' | 'cle' | 'see' | 'tsy' | 'lbpl'| 'inz' | 'tys' | 'lbmi'| 'dez' | 'neg' | 'asr' | 'taz' | 'lbvc'| 'tab' | 'map' | 'rtn' | 'lbsr'| 'tza' |
|
'tsb' | 'wai' | 'cle' | 'see' | 'tsy' | 'lbpl'| 'inz' | 'tys' | 'lbmi'| 'dez' | 'neg' | 'asr' | 'taz' | 'lbvc'| 'tab' | 'map' | 'rtn' | 'lbsr'| 'tza' |
|
||||||
'lbvs'| 'tba' | 'lbra'| 'lbcc'| 'ldz' | 'lbcs'| 'cpz' | 'dew' | 'asw' | 'lbne'| 'phz' | 'inw' | 'row' | 'lbeq'| 'phw' | 'plz' | 'eom'
|
'lbvs'| 'tba' | 'lbra'| 'lbcc'| 'ldz' | 'lbcs'| 'cpz' | 'dew' | 'asw' | 'lbne'| 'phz' | 'inw' | 'row' | 'lbeq'| 'phw' | 'plz' | 'eom' | 'adcq'| 'andq'|
|
||||||
|
'aslq'| 'asrq'| 'bitq'| 'cpq' | 'deq' | 'eorq'| 'inq' | 'ldq' | 'lsrq'| 'orq' | 'rolq'| 'rorq'| 'sbcq'| 'stq'
|
||||||
;
|
;
|
||||||
|
|
||||||
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
@ -42,6 +42,11 @@ public class TestPrograms {
|
|||||||
public TestPrograms() {
|
public TestPrograms() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCpu45GS02AddressingModes() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("cpu-45gs02-addressing-modes.c");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCpu65CE02AddressingModes() throws IOException, URISyntaxException {
|
public void testCpu65CE02AddressingModes() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("cpu-65ce02-addressing-modes.c");
|
compileAndCompare("cpu-65ce02-addressing-modes.c");
|
||||||
@ -58,13 +63,13 @@ public class TestPrograms {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMega65C65ce02() throws IOException, URISyntaxException {
|
public void testCpu45GS02() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("cpu-45gs02.c");
|
compileAndCompare("cpu-45gs02.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCpu65CE02() throws IOException, URISyntaxException {
|
public void testCpu65CE02() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("cpu-65ce02.c", log());
|
compileAndCompare("cpu-65ce02.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
57
src/test/kc/cpu-45gs02-addressing-modes.c
Normal file
57
src/test/kc/cpu-45gs02-addressing-modes.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Tests the different ASM addressing modes
|
||||||
|
|
||||||
|
#pragma cpu(mega45gs02)
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
asm {
|
||||||
|
// 6502:impl
|
||||||
|
inx
|
||||||
|
// 6502:imm
|
||||||
|
lda #$12
|
||||||
|
// 65CE02:immword
|
||||||
|
phw #$1234
|
||||||
|
// 6502:zp
|
||||||
|
lda $12
|
||||||
|
// 6502:zp,x
|
||||||
|
lda $12,x
|
||||||
|
// 6502:zp,y
|
||||||
|
ldx $12,y
|
||||||
|
// 65C02: (zp)
|
||||||
|
//ora ($12)
|
||||||
|
// 6502:(zp,x)
|
||||||
|
lda ($12,x)
|
||||||
|
// 6502:(zp),y
|
||||||
|
lda ($12),y
|
||||||
|
// 65CE02: (zp),z
|
||||||
|
ora ($12),z
|
||||||
|
// 65CE02: Stack Pointer Indirect Indexed
|
||||||
|
lda ($12,sp),y
|
||||||
|
// 6502:absolute
|
||||||
|
lda $1234
|
||||||
|
// 6502:abs,x
|
||||||
|
lda $1234,x
|
||||||
|
// 6502:abs,y
|
||||||
|
lda $1234,y
|
||||||
|
// 6502:relative
|
||||||
|
beq lbl1
|
||||||
|
// 65CE02:word relative
|
||||||
|
lbeq far
|
||||||
|
// 65C02: $12, rel
|
||||||
|
bbr0 $12,lbl2
|
||||||
|
lbl1:
|
||||||
|
// 6502:(abs)
|
||||||
|
jmp ($1234)
|
||||||
|
lbl2:
|
||||||
|
// 65C02: ($1234,X)
|
||||||
|
jmp ($1234,x)
|
||||||
|
lbl3:
|
||||||
|
// 45GS02: Indirect Long,Z
|
||||||
|
lda (($12)),z
|
||||||
|
// 45GS02: Indirect Long
|
||||||
|
ldq (($12))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__address(0x2000) char far[] = { 0x60 };
|
@ -1,11 +1,16 @@
|
|||||||
// Tests compiling inline C65CE02/45GS02 Assembler
|
// Test the 45GS02 CPU
|
||||||
|
// A program that uses 45GS02 instructions
|
||||||
|
|
||||||
#pragma cpu(MEGA45GS02)
|
#pragma cpu(MEGA45GS02)
|
||||||
|
|
||||||
|
unsigned long* SCREEN = 0x0400;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
kickasm {{
|
unsigned long sum = 0;
|
||||||
ldz #2
|
unsigned long addend = 123456;
|
||||||
stz $0800
|
for(char i=0;i<100;i++) {
|
||||||
adcq ($2)
|
sum += addend; // will utilize ADQ/STQ
|
||||||
}}
|
addend += i;
|
||||||
|
}
|
||||||
|
*SCREEN = sum; // will utilize LDQ/STQ
|
||||||
}
|
}
|
@ -37,19 +37,6 @@ void main() {
|
|||||||
lbl2:
|
lbl2:
|
||||||
// 65C02: ($1234,X)
|
// 65C02: ($1234,X)
|
||||||
jmp ($1234,x)
|
jmp ($1234,x)
|
||||||
|
|
||||||
// TODO Stack Pointer Indirect Indexed
|
|
||||||
//lda ($12,sp),y
|
|
||||||
|
|
||||||
// TODO Indirect,Z
|
|
||||||
//lda ($12),z
|
|
||||||
|
|
||||||
// TODO Indirect Long,Z
|
|
||||||
//lda (($12)),z
|
|
||||||
|
|
||||||
// TODO Indirect Long
|
|
||||||
//lda (($12))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -45,13 +45,6 @@ void main() {
|
|||||||
lbl2:
|
lbl2:
|
||||||
// 65C02: ($1234,X)
|
// 65C02: ($1234,X)
|
||||||
jmp ($1234,x)
|
jmp ($1234,x)
|
||||||
|
|
||||||
// TODO Indirect Long,Z
|
|
||||||
//lda (($12)),z
|
|
||||||
|
|
||||||
// TODO Indirect Long
|
|
||||||
//lda (($12))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
35
src/test/ref/cpu-45gs02-addressing-modes.asm
Normal file
35
src/test/ref/cpu-45gs02-addressing-modes.asm
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Tests the different ASM addressing modes
|
||||||
|
.cpu _45gs02
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
main: {
|
||||||
|
// asm
|
||||||
|
inx
|
||||||
|
lda #$12
|
||||||
|
phw #$1234
|
||||||
|
lda.z $12
|
||||||
|
lda.z $12,x
|
||||||
|
ldx.z $12,y
|
||||||
|
lda ($12,x)
|
||||||
|
lda ($12),y
|
||||||
|
ora.z ($12),z
|
||||||
|
lda.z ($12,sp),y
|
||||||
|
lda $1234
|
||||||
|
lda $1234,x
|
||||||
|
lda $1234,y
|
||||||
|
beq lbl1
|
||||||
|
lbeq far
|
||||||
|
bbr0 $12,lbl2
|
||||||
|
lbl1:
|
||||||
|
jmp ($1234)
|
||||||
|
lbl2:
|
||||||
|
jmp ($1234,x)
|
||||||
|
lbl3:
|
||||||
|
lda.z (($12)),z
|
||||||
|
ldq.z (($12))
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
.pc = $2000 "far"
|
||||||
|
far: .byte $60
|
8
src/test/ref/cpu-45gs02-addressing-modes.cfg
Normal file
8
src/test/ref/cpu-45gs02-addressing-modes.cfg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from
|
||||||
|
asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) lbl3: lda(($12)),z ldq(($12)) }
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
[1] return
|
||||||
|
to:@return
|
218
src/test/ref/cpu-45gs02-addressing-modes.log
Normal file
218
src/test/ref/cpu-45gs02-addressing-modes.log
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
Resolved forward reference far to (const byte*) far
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from __start
|
||||||
|
asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) lbl3: lda(($12)),z ldq(($12)) }
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
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
|
||||||
|
(const byte*) far[] = { (byte) $60 }
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
|
||||||
|
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
|
||||||
|
CALL GRAPH
|
||||||
|
|
||||||
|
Created 0 initial phi equivalence classes
|
||||||
|
Coalesced down to 0 phi equivalence classes
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
|
||||||
|
(void()) main()
|
||||||
|
main: scope:[main] from
|
||||||
|
asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) lbl3: lda(($12)),z ldq(($12)) }
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
[1] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
(void()) main()
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
Complete equivalence classes
|
||||||
|
|
||||||
|
INITIAL ASM
|
||||||
|
Target platform is c64basic / MEGA45GS02
|
||||||
|
// File Comments
|
||||||
|
// Tests the different ASM addressing modes
|
||||||
|
// Upstart
|
||||||
|
.cpu _45gs02
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) lbl3: lda(($12)),z ldq(($12)) }
|
||||||
|
inx
|
||||||
|
lda #$12
|
||||||
|
phw #$1234
|
||||||
|
lda.z $12
|
||||||
|
lda.z $12,x
|
||||||
|
ldx.z $12,y
|
||||||
|
lda ($12,x)
|
||||||
|
lda ($12),y
|
||||||
|
ora.z ($12),z
|
||||||
|
lda.z ($12,sp),y
|
||||||
|
lda $1234
|
||||||
|
lda $1234,x
|
||||||
|
lda $1234,y
|
||||||
|
beq lbl1
|
||||||
|
lbeq far
|
||||||
|
bbr0 $12,lbl2
|
||||||
|
lbl1:
|
||||||
|
jmp ($1234)
|
||||||
|
lbl2:
|
||||||
|
jmp ($1234,x)
|
||||||
|
lbl3:
|
||||||
|
lda.z (($12)),z
|
||||||
|
ldq.z (($12))
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [1] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
.pc = $2000 "far"
|
||||||
|
far: .byte $60
|
||||||
|
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) lbl3: lda(($12)),z ldq(($12)) } always clobbers reg byte a reg byte x reg byte y
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [main]
|
||||||
|
Uplift Scope []
|
||||||
|
|
||||||
|
Uplifting [main] best 106 combination
|
||||||
|
Uplifting [] best 106 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
// File Comments
|
||||||
|
// Tests the different ASM addressing modes
|
||||||
|
// Upstart
|
||||||
|
.cpu _45gs02
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) lbl3: lda(($12)),z ldq(($12)) }
|
||||||
|
inx
|
||||||
|
lda #$12
|
||||||
|
phw #$1234
|
||||||
|
lda.z $12
|
||||||
|
lda.z $12,x
|
||||||
|
ldx.z $12,y
|
||||||
|
lda ($12,x)
|
||||||
|
lda ($12),y
|
||||||
|
ora.z ($12),z
|
||||||
|
lda.z ($12,sp),y
|
||||||
|
lda $1234
|
||||||
|
lda $1234,x
|
||||||
|
lda $1234,y
|
||||||
|
beq lbl1
|
||||||
|
lbeq far
|
||||||
|
bbr0 $12,lbl2
|
||||||
|
lbl1:
|
||||||
|
jmp ($1234)
|
||||||
|
lbl2:
|
||||||
|
jmp ($1234,x)
|
||||||
|
lbl3:
|
||||||
|
lda.z (($12)),z
|
||||||
|
ldq.z (($12))
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [1] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
.pc = $2000 "far"
|
||||||
|
far: .byte $60
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
(const byte*) far[] = { (byte) $60 }
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 103
|
||||||
|
|
||||||
|
// File Comments
|
||||||
|
// Tests the different ASM addressing modes
|
||||||
|
// Upstart
|
||||||
|
.cpu _45gs02
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
// Global Constants & labels
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
// asm
|
||||||
|
// asm { inx lda#$12 phw#$1234 lda$12 lda$12,x ldx$12,y lda($12,x) lda($12),y ora($12),z lda($12,sp),y lda$1234 lda$1234,x lda$1234,y beqlbl1 lbeqfar bbr0$12,lbl2 lbl1: jmp($1234) lbl2: jmp($1234,x) lbl3: lda(($12)),z ldq(($12)) }
|
||||||
|
inx
|
||||||
|
lda #$12
|
||||||
|
phw #$1234
|
||||||
|
lda.z $12
|
||||||
|
lda.z $12,x
|
||||||
|
ldx.z $12,y
|
||||||
|
lda ($12,x)
|
||||||
|
lda ($12),y
|
||||||
|
ora.z ($12),z
|
||||||
|
lda.z ($12,sp),y
|
||||||
|
lda $1234
|
||||||
|
lda $1234,x
|
||||||
|
lda $1234,y
|
||||||
|
beq lbl1
|
||||||
|
lbeq far
|
||||||
|
bbr0 $12,lbl2
|
||||||
|
lbl1:
|
||||||
|
jmp ($1234)
|
||||||
|
lbl2:
|
||||||
|
jmp ($1234,x)
|
||||||
|
lbl3:
|
||||||
|
lda.z (($12)),z
|
||||||
|
ldq.z (($12))
|
||||||
|
// main::@return
|
||||||
|
// }
|
||||||
|
// [1] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
.pc = $2000 "far"
|
||||||
|
far: .byte $60
|
||||||
|
|
4
src/test/ref/cpu-45gs02-addressing-modes.sym
Normal file
4
src/test/ref/cpu-45gs02-addressing-modes.sym
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
(const byte*) far[] = { (byte) $60 }
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
|
@ -1,14 +1,63 @@
|
|||||||
// Tests compiling inline C65CE02/45GS02 Assembler
|
// Test the 45GS02 CPU
|
||||||
|
// A program that uses 45GS02 instructions
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.pc = $801 "Basic"
|
.pc = $801 "Basic"
|
||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
|
.label SCREEN = $400
|
||||||
main: {
|
main: {
|
||||||
// kickasm
|
.label sum = 3
|
||||||
ldz #2
|
.label addend = 7
|
||||||
stz $0800
|
.label i = 2
|
||||||
adcq ($2)
|
lda #<$1e240
|
||||||
|
sta.z addend
|
||||||
|
lda #>$1e240
|
||||||
|
sta.z addend+1
|
||||||
|
lda #<$1e240>>$10
|
||||||
|
sta.z addend+2
|
||||||
|
lda #>$1e240>>$10
|
||||||
|
sta.z addend+3
|
||||||
|
lda #<0
|
||||||
|
sta.z sum
|
||||||
|
sta.z sum+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z sum+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z sum+3
|
||||||
|
lda #0
|
||||||
|
sta.z i
|
||||||
|
__b1:
|
||||||
|
// for(char i=0;i<100;i++)
|
||||||
|
lda.z i
|
||||||
|
cmp #$64
|
||||||
|
bcc __b2
|
||||||
|
// *SCREEN = sum
|
||||||
|
ldq.z sum
|
||||||
|
stq SCREEN
|
||||||
// }
|
// }
|
||||||
rts
|
rts
|
||||||
|
__b2:
|
||||||
|
// sum += addend
|
||||||
|
clc
|
||||||
|
ldq.z sum
|
||||||
|
adcq.z addend
|
||||||
|
stq.z sum
|
||||||
|
// addend += i
|
||||||
|
// will utilize ADQ/STQ
|
||||||
|
lda.z i
|
||||||
|
clc
|
||||||
|
adc.z addend
|
||||||
|
sta.z addend
|
||||||
|
lda.z addend+1
|
||||||
|
adc #0
|
||||||
|
sta.z addend+1
|
||||||
|
lda.z addend+2
|
||||||
|
adc #0
|
||||||
|
sta.z addend+2
|
||||||
|
lda.z addend+3
|
||||||
|
adc #0
|
||||||
|
sta.z addend+3
|
||||||
|
// for(char i=0;i<100;i++)
|
||||||
|
inc.z i
|
||||||
|
jmp __b1
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
|
|
||||||
(void()) main()
|
(void()) main()
|
||||||
main: scope:[main] from
|
main: scope:[main] from
|
||||||
kickasm() {{ ldz #2
|
[0] phi()
|
||||||
stz $0800
|
to:main::@1
|
||||||
adcq ($2)
|
main::@1: scope:[main] from main main::@2
|
||||||
}}
|
[1] (dword) main::addend#2 ← phi( main/(dword) $1e240 main::@2/(dword) main::addend#1 )
|
||||||
|
[1] (dword) main::sum#2 ← phi( main/(dword) 0 main::@2/(dword) main::sum#1 )
|
||||||
|
[1] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
|
||||||
|
[2] if((byte) main::i#2<(byte) $64) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
[3] *((const dword*) SCREEN) ← (dword) main::sum#2
|
||||||
to:main::@return
|
to:main::@return
|
||||||
main::@return: scope:[main] from main
|
main::@return: scope:[main] from main::@3
|
||||||
[1] return
|
[4] return
|
||||||
to:@return
|
to:@return
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
[5] (dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2
|
||||||
|
[6] (dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#2
|
||||||
|
[7] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||||
|
to:main::@1
|
||||||
|
@ -1,157 +1,497 @@
|
|||||||
|
Inlined call call __init
|
||||||
|
|
||||||
CONTROL FLOW GRAPH SSA
|
CONTROL FLOW GRAPH SSA
|
||||||
|
|
||||||
(void()) main()
|
(void()) main()
|
||||||
main: scope:[main] from __start
|
main: scope:[main] from __start::@1
|
||||||
kickasm() {{ ldz #2
|
(dword) main::sum#0 ← (dword) 0
|
||||||
stz $0800
|
(dword) main::addend#0 ← (dword) $1e240
|
||||||
adcq ($2)
|
(byte) main::i#0 ← (byte) 0
|
||||||
}}
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@2
|
||||||
|
(dword) main::addend#3 ← phi( main/(dword) main::addend#0 main::@2/(dword) main::addend#1 )
|
||||||
|
(dword) main::sum#4 ← phi( main/(dword) main::sum#0 main::@2/(dword) main::sum#1 )
|
||||||
|
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@2/(byte) main::i#1 )
|
||||||
|
(bool~) main::$0 ← (byte) main::i#2 < (number) $64
|
||||||
|
if((bool~) main::$0) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
|
||||||
|
(dword) main::addend#2 ← phi( main::@1/(dword) main::addend#3 )
|
||||||
|
(dword) main::sum#2 ← phi( main::@1/(dword) main::sum#4 )
|
||||||
|
(dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2
|
||||||
|
(dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#3
|
||||||
|
(byte) main::i#1 ← ++ (byte) main::i#3
|
||||||
|
to:main::@1
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
(dword) main::sum#3 ← phi( main::@1/(dword) main::sum#4 )
|
||||||
|
*((const dword*) SCREEN) ← (dword) main::sum#3
|
||||||
to:main::@return
|
to:main::@return
|
||||||
main::@return: scope:[main] from main
|
main::@return: scope:[main] from main::@3
|
||||||
return
|
return
|
||||||
to:@return
|
to:@return
|
||||||
|
|
||||||
(void()) __start()
|
(void()) __start()
|
||||||
__start: scope:[__start] from
|
__start: scope:[__start] from
|
||||||
call main
|
to:__start::__init1
|
||||||
|
__start::__init1: scope:[__start] from __start
|
||||||
to:__start::@1
|
to:__start::@1
|
||||||
__start::@1: scope:[__start] from __start
|
__start::@1: scope:[__start] from __start::__init1
|
||||||
|
call main
|
||||||
|
to:__start::@2
|
||||||
|
__start::@2: scope:[__start] from __start::@1
|
||||||
to:__start::@return
|
to:__start::@return
|
||||||
__start::@return: scope:[__start] from __start::@1
|
__start::@return: scope:[__start] from __start::@2
|
||||||
return
|
return
|
||||||
to:@return
|
to:@return
|
||||||
|
|
||||||
SYMBOL TABLE SSA
|
SYMBOL TABLE SSA
|
||||||
|
(const dword*) SCREEN = (dword*)(number) $400
|
||||||
(void()) __start()
|
(void()) __start()
|
||||||
(label) __start::@1
|
(label) __start::@1
|
||||||
|
(label) __start::@2
|
||||||
(label) __start::@return
|
(label) __start::@return
|
||||||
|
(label) __start::__init1
|
||||||
(void()) main()
|
(void()) main()
|
||||||
|
(bool~) main::$0
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@3
|
||||||
(label) main::@return
|
(label) main::@return
|
||||||
|
(dword) main::addend
|
||||||
|
(dword) main::addend#0
|
||||||
|
(dword) main::addend#1
|
||||||
|
(dword) main::addend#2
|
||||||
|
(dword) main::addend#3
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#0
|
||||||
|
(byte) main::i#1
|
||||||
|
(byte) main::i#2
|
||||||
|
(byte) main::i#3
|
||||||
|
(dword) main::sum
|
||||||
|
(dword) main::sum#0
|
||||||
|
(dword) main::sum#1
|
||||||
|
(dword) main::sum#2
|
||||||
|
(dword) main::sum#3
|
||||||
|
(dword) main::sum#4
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) $64 in (bool~) main::$0 ← (byte) main::i#2 < (number) $64
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Simplifying constant pointer cast (dword*) 1024
|
||||||
|
Simplifying constant integer cast $64
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (byte) $64
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Alias main::sum#2 = main::sum#4 main::sum#3
|
||||||
|
Alias main::addend#2 = main::addend#3
|
||||||
|
Alias main::i#2 = main::i#3
|
||||||
|
Successful SSA optimization Pass2AliasElimination
|
||||||
|
Simple Condition (bool~) main::$0 [5] if((byte) main::i#2<(byte) $64) goto main::@2
|
||||||
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||||
|
Constant (const dword) main::sum#0 = 0
|
||||||
|
Constant (const dword) main::addend#0 = $1e240
|
||||||
|
Constant (const byte) main::i#0 = 0
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
Removing unused procedure __start
|
Removing unused procedure __start
|
||||||
Removing unused procedure block __start
|
Removing unused procedure block __start
|
||||||
|
Removing unused procedure block __start::__init1
|
||||||
Removing unused procedure block __start::@1
|
Removing unused procedure block __start::@1
|
||||||
|
Removing unused procedure block __start::@2
|
||||||
Removing unused procedure block __start::@return
|
Removing unused procedure block __start::@return
|
||||||
Successful SSA optimization PassNEliminateEmptyStart
|
Successful SSA optimization PassNEliminateEmptyStart
|
||||||
|
Inlining constant with var siblings (const dword) main::sum#0
|
||||||
|
Inlining constant with var siblings (const dword) main::addend#0
|
||||||
|
Inlining constant with var siblings (const byte) main::i#0
|
||||||
|
Constant inlined main::i#0 = (byte) 0
|
||||||
|
Constant inlined main::addend#0 = (dword) $1e240
|
||||||
|
Constant inlined main::sum#0 = (dword) 0
|
||||||
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
Adding NOP phi() at start of main
|
||||||
CALL GRAPH
|
CALL GRAPH
|
||||||
|
|
||||||
Created 0 initial phi equivalence classes
|
Created 3 initial phi equivalence classes
|
||||||
Coalesced down to 0 phi equivalence classes
|
Coalesced [8] main::i#4 ← main::i#1
|
||||||
|
Coalesced [9] main::sum#5 ← main::sum#1
|
||||||
|
Coalesced [10] main::addend#4 ← main::addend#1
|
||||||
|
Coalesced down to 3 phi equivalence classes
|
||||||
|
Adding NOP phi() at start of main
|
||||||
|
|
||||||
FINAL CONTROL FLOW GRAPH
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
|
||||||
(void()) main()
|
(void()) main()
|
||||||
main: scope:[main] from
|
main: scope:[main] from
|
||||||
kickasm() {{ ldz #2
|
[0] phi()
|
||||||
stz $0800
|
to:main::@1
|
||||||
adcq ($2)
|
main::@1: scope:[main] from main main::@2
|
||||||
}}
|
[1] (dword) main::addend#2 ← phi( main/(dword) $1e240 main::@2/(dword) main::addend#1 )
|
||||||
|
[1] (dword) main::sum#2 ← phi( main/(dword) 0 main::@2/(dword) main::sum#1 )
|
||||||
|
[1] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
|
||||||
|
[2] if((byte) main::i#2<(byte) $64) goto main::@2
|
||||||
|
to:main::@3
|
||||||
|
main::@3: scope:[main] from main::@1
|
||||||
|
[3] *((const dword*) SCREEN) ← (dword) main::sum#2
|
||||||
to:main::@return
|
to:main::@return
|
||||||
main::@return: scope:[main] from main
|
main::@return: scope:[main] from main::@3
|
||||||
[1] return
|
[4] return
|
||||||
to:@return
|
to:@return
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
[5] (dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2
|
||||||
|
[6] (dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#2
|
||||||
|
[7] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||||
|
to:main::@1
|
||||||
|
|
||||||
|
|
||||||
VARIABLE REGISTER WEIGHTS
|
VARIABLE REGISTER WEIGHTS
|
||||||
(void()) main()
|
(void()) main()
|
||||||
|
(dword) main::addend
|
||||||
|
(dword) main::addend#1 11.0
|
||||||
|
(dword) main::addend#2 11.0
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#1 22.0
|
||||||
|
(byte) main::i#2 11.0
|
||||||
|
(dword) main::sum
|
||||||
|
(dword) main::sum#1 7.333333333333333
|
||||||
|
(dword) main::sum#2 12.0
|
||||||
|
|
||||||
Initial phi equivalence classes
|
Initial phi equivalence classes
|
||||||
|
[ main::i#2 main::i#1 ]
|
||||||
|
[ main::sum#2 main::sum#1 ]
|
||||||
|
[ main::addend#2 main::addend#1 ]
|
||||||
Complete equivalence classes
|
Complete equivalence classes
|
||||||
|
[ main::i#2 main::i#1 ]
|
||||||
|
[ main::sum#2 main::sum#1 ]
|
||||||
|
[ main::addend#2 main::addend#1 ]
|
||||||
|
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Allocated zp[4]:3 [ main::sum#2 main::sum#1 ]
|
||||||
|
Allocated zp[4]:7 [ main::addend#2 main::addend#1 ]
|
||||||
|
|
||||||
INITIAL ASM
|
INITIAL ASM
|
||||||
Target platform is c64basic / MEGA45GS02
|
Target platform is c64basic / MEGA45GS02
|
||||||
// File Comments
|
// File Comments
|
||||||
// Tests compiling inline C65CE02/45GS02 Assembler
|
// Test the 45GS02 CPU
|
||||||
|
// A program that uses 45GS02 instructions
|
||||||
// Upstart
|
// Upstart
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.pc = $801 "Basic"
|
.pc = $801 "Basic"
|
||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
// main
|
// main
|
||||||
main: {
|
main: {
|
||||||
// kickasm() {{ ldz #2 stz $0800 adcq ($2) }}
|
.label sum = 3
|
||||||
ldz #2
|
.label addend = 7
|
||||||
stz $0800
|
.label i = 2
|
||||||
adcq ($2)
|
// [1] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
__b1_from_main:
|
||||||
|
// [1] phi (dword) main::addend#2 = (dword) $1e240 [phi:main->main::@1#0] -- vduz1=vduc1
|
||||||
|
lda #<$1e240
|
||||||
|
sta.z addend
|
||||||
|
lda #>$1e240
|
||||||
|
sta.z addend+1
|
||||||
|
lda #<$1e240>>$10
|
||||||
|
sta.z addend+2
|
||||||
|
lda #>$1e240>>$10
|
||||||
|
sta.z addend+3
|
||||||
|
// [1] phi (dword) main::sum#2 = (dword) 0 [phi:main->main::@1#1] -- vduz1=vduc1
|
||||||
|
lda #<0
|
||||||
|
sta.z sum
|
||||||
|
lda #>0
|
||||||
|
sta.z sum+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z sum+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z sum+3
|
||||||
|
// [1] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#2] -- vbuz1=vbuc1
|
||||||
|
lda #0
|
||||||
|
sta.z i
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [2] if((byte) main::i#2<(byte) $64) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||||
|
lda.z i
|
||||||
|
cmp #$64
|
||||||
|
bcc __b2
|
||||||
|
jmp __b3
|
||||||
|
// main::@3
|
||||||
|
__b3:
|
||||||
|
// [3] *((const dword*) SCREEN) ← (dword) main::sum#2 -- _deref_pduc1=vduz1
|
||||||
|
ldq.z sum
|
||||||
|
stq SCREEN
|
||||||
jmp __breturn
|
jmp __breturn
|
||||||
// main::@return
|
// main::@return
|
||||||
__breturn:
|
__breturn:
|
||||||
// [1] return
|
// [4] return
|
||||||
rts
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// [5] (dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2 -- vduz1=vduz1_plus_vduz2
|
||||||
|
clc
|
||||||
|
ldq.z sum
|
||||||
|
adcq.z addend
|
||||||
|
stq.z sum
|
||||||
|
// [6] (dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#2 -- vduz1=vduz1_plus_vbuz2
|
||||||
|
// will utilize ADQ/STQ
|
||||||
|
lda.z i
|
||||||
|
clc
|
||||||
|
adc.z addend
|
||||||
|
sta.z addend
|
||||||
|
lda.z addend+1
|
||||||
|
adc #0
|
||||||
|
sta.z addend+1
|
||||||
|
lda.z addend+2
|
||||||
|
adc #0
|
||||||
|
sta.z addend+2
|
||||||
|
lda.z addend+3
|
||||||
|
adc #0
|
||||||
|
sta.z addend+3
|
||||||
|
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||||
|
inc.z i
|
||||||
|
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
__b1_from___b2:
|
||||||
|
// [1] phi (dword) main::addend#2 = (dword) main::addend#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
// [1] phi (dword) main::sum#2 = (dword) main::sum#1 [phi:main::@2->main::@1#1] -- register_copy
|
||||||
|
// [1] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#2] -- register_copy
|
||||||
|
jmp __b1
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
|
|
||||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [3] *((const dword*) SCREEN) ← (dword) main::sum#2 [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y
|
||||||
|
Statement [5] (dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2 [ main::i#2 main::addend#2 main::sum#1 ] ( [ main::i#2 main::addend#2 main::sum#1 ] { } ) always clobbers reg byte a reg byte x reg byte y
|
||||||
|
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Statement [6] (dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#2 [ main::i#2 main::sum#1 main::addend#1 ] ( [ main::i#2 main::sum#1 main::addend#1 ] { } ) always clobbers reg byte a
|
||||||
|
Statement [2] if((byte) main::i#2<(byte) $64) goto main::@2 [ main::i#2 main::sum#2 main::addend#2 ] ( [ main::i#2 main::sum#2 main::addend#2 ] { } ) always clobbers reg byte a
|
||||||
|
Statement [3] *((const dword*) SCREEN) ← (dword) main::sum#2 [ ] ( [ ] { } ) always clobbers reg byte a reg byte x reg byte y
|
||||||
|
Statement [5] (dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2 [ main::i#2 main::addend#2 main::sum#1 ] ( [ main::i#2 main::addend#2 main::sum#1 ] { } ) always clobbers reg byte a reg byte x reg byte y
|
||||||
|
Statement [6] (dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#2 [ main::i#2 main::sum#1 main::addend#1 ] ( [ main::i#2 main::sum#1 main::addend#1 ] { } ) always clobbers reg byte a
|
||||||
|
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 ,
|
||||||
|
Potential registers zp[4]:3 [ main::sum#2 main::sum#1 ] : zp[4]:3 ,
|
||||||
|
Potential registers zp[4]:7 [ main::addend#2 main::addend#1 ] : zp[4]:7 ,
|
||||||
|
|
||||||
REGISTER UPLIFT SCOPES
|
REGISTER UPLIFT SCOPES
|
||||||
Uplift Scope [main]
|
Uplift Scope [main] 33: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[4]:7 [ main::addend#2 main::addend#1 ] 19.33: zp[4]:3 [ main::sum#2 main::sum#1 ]
|
||||||
Uplift Scope []
|
Uplift Scope []
|
||||||
|
|
||||||
Uplifting [main] best 265 combination
|
Uplifting [main] best 1301 combination zp[1]:2 [ main::i#2 main::i#1 ] zp[4]:7 [ main::addend#2 main::addend#1 ] zp[4]:3 [ main::sum#2 main::sum#1 ]
|
||||||
Uplifting [] best 265 combination
|
Uplifting [] best 1301 combination
|
||||||
|
Attempting to uplift remaining variables inzp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Uplifting [main] best 1301 combination zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
|
||||||
ASSEMBLER BEFORE OPTIMIZATION
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
// File Comments
|
// File Comments
|
||||||
// Tests compiling inline C65CE02/45GS02 Assembler
|
// Test the 45GS02 CPU
|
||||||
|
// A program that uses 45GS02 instructions
|
||||||
// Upstart
|
// Upstart
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.pc = $801 "Basic"
|
.pc = $801 "Basic"
|
||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
// main
|
// main
|
||||||
main: {
|
main: {
|
||||||
// kickasm() {{ ldz #2 stz $0800 adcq ($2) }}
|
.label sum = 3
|
||||||
ldz #2
|
.label addend = 7
|
||||||
stz $0800
|
.label i = 2
|
||||||
adcq ($2)
|
// [1] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
__b1_from_main:
|
||||||
|
// [1] phi (dword) main::addend#2 = (dword) $1e240 [phi:main->main::@1#0] -- vduz1=vduc1
|
||||||
|
lda #<$1e240
|
||||||
|
sta.z addend
|
||||||
|
lda #>$1e240
|
||||||
|
sta.z addend+1
|
||||||
|
lda #<$1e240>>$10
|
||||||
|
sta.z addend+2
|
||||||
|
lda #>$1e240>>$10
|
||||||
|
sta.z addend+3
|
||||||
|
// [1] phi (dword) main::sum#2 = (dword) 0 [phi:main->main::@1#1] -- vduz1=vduc1
|
||||||
|
lda #<0
|
||||||
|
sta.z sum
|
||||||
|
lda #>0
|
||||||
|
sta.z sum+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z sum+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z sum+3
|
||||||
|
// [1] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#2] -- vbuz1=vbuc1
|
||||||
|
lda #0
|
||||||
|
sta.z i
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [2] if((byte) main::i#2<(byte) $64) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||||
|
lda.z i
|
||||||
|
cmp #$64
|
||||||
|
bcc __b2
|
||||||
|
jmp __b3
|
||||||
|
// main::@3
|
||||||
|
__b3:
|
||||||
|
// [3] *((const dword*) SCREEN) ← (dword) main::sum#2 -- _deref_pduc1=vduz1
|
||||||
|
ldq.z sum
|
||||||
|
stq SCREEN
|
||||||
jmp __breturn
|
jmp __breturn
|
||||||
// main::@return
|
// main::@return
|
||||||
__breturn:
|
__breturn:
|
||||||
// [1] return
|
// [4] return
|
||||||
rts
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// [5] (dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2 -- vduz1=vduz1_plus_vduz2
|
||||||
|
clc
|
||||||
|
ldq.z sum
|
||||||
|
adcq.z addend
|
||||||
|
stq.z sum
|
||||||
|
// [6] (dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#2 -- vduz1=vduz1_plus_vbuz2
|
||||||
|
// will utilize ADQ/STQ
|
||||||
|
lda.z i
|
||||||
|
clc
|
||||||
|
adc.z addend
|
||||||
|
sta.z addend
|
||||||
|
lda.z addend+1
|
||||||
|
adc #0
|
||||||
|
sta.z addend+1
|
||||||
|
lda.z addend+2
|
||||||
|
adc #0
|
||||||
|
sta.z addend+2
|
||||||
|
lda.z addend+3
|
||||||
|
adc #0
|
||||||
|
sta.z addend+3
|
||||||
|
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||||
|
inc.z i
|
||||||
|
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
__b1_from___b2:
|
||||||
|
// [1] phi (dword) main::addend#2 = (dword) main::addend#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
// [1] phi (dword) main::sum#2 = (dword) main::sum#1 [phi:main::@2->main::@1#1] -- register_copy
|
||||||
|
// [1] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#2] -- register_copy
|
||||||
|
jmp __b1
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
|
|
||||||
ASSEMBLER OPTIMIZATIONS
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __b3
|
||||||
Removing instruction jmp __breturn
|
Removing instruction jmp __breturn
|
||||||
Succesful ASM optimization Pass5NextJumpElimination
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction lda #>0
|
||||||
|
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||||
|
Removing instruction __b1_from_main:
|
||||||
|
Removing instruction __b3:
|
||||||
Removing instruction __breturn:
|
Removing instruction __breturn:
|
||||||
|
Removing instruction __b1_from___b2:
|
||||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
FINAL SYMBOL TABLE
|
FINAL SYMBOL TABLE
|
||||||
|
(const dword*) SCREEN = (dword*) 1024
|
||||||
(void()) main()
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@3
|
||||||
(label) main::@return
|
(label) main::@return
|
||||||
|
(dword) main::addend
|
||||||
|
(dword) main::addend#1 addend zp[4]:7 11.0
|
||||||
|
(dword) main::addend#2 addend zp[4]:7 11.0
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#1 i zp[1]:2 22.0
|
||||||
|
(byte) main::i#2 i zp[1]:2 11.0
|
||||||
|
(dword) main::sum
|
||||||
|
(dword) main::sum#1 sum zp[4]:3 7.333333333333333
|
||||||
|
(dword) main::sum#2 sum zp[4]:3 12.0
|
||||||
|
|
||||||
|
zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
zp[4]:3 [ main::sum#2 main::sum#1 ]
|
||||||
|
zp[4]:7 [ main::addend#2 main::addend#1 ]
|
||||||
|
|
||||||
|
|
||||||
FINAL ASSEMBLER
|
FINAL ASSEMBLER
|
||||||
Score: 262
|
Score: 1218
|
||||||
|
|
||||||
// File Comments
|
// File Comments
|
||||||
// Tests compiling inline C65CE02/45GS02 Assembler
|
// Test the 45GS02 CPU
|
||||||
|
// A program that uses 45GS02 instructions
|
||||||
// Upstart
|
// Upstart
|
||||||
.cpu _45gs02
|
.cpu _45gs02
|
||||||
.pc = $801 "Basic"
|
.pc = $801 "Basic"
|
||||||
:BasicUpstart(main)
|
:BasicUpstart(main)
|
||||||
.pc = $80d "Program"
|
.pc = $80d "Program"
|
||||||
// Global Constants & labels
|
// Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
// main
|
// main
|
||||||
main: {
|
main: {
|
||||||
// kickasm
|
.label sum = 3
|
||||||
// kickasm() {{ ldz #2 stz $0800 adcq ($2) }}
|
.label addend = 7
|
||||||
ldz #2
|
.label i = 2
|
||||||
stz $0800
|
// [1] phi from main to main::@1 [phi:main->main::@1]
|
||||||
adcq ($2)
|
// [1] phi (dword) main::addend#2 = (dword) $1e240 [phi:main->main::@1#0] -- vduz1=vduc1
|
||||||
|
lda #<$1e240
|
||||||
|
sta.z addend
|
||||||
|
lda #>$1e240
|
||||||
|
sta.z addend+1
|
||||||
|
lda #<$1e240>>$10
|
||||||
|
sta.z addend+2
|
||||||
|
lda #>$1e240>>$10
|
||||||
|
sta.z addend+3
|
||||||
|
// [1] phi (dword) main::sum#2 = (dword) 0 [phi:main->main::@1#1] -- vduz1=vduc1
|
||||||
|
lda #<0
|
||||||
|
sta.z sum
|
||||||
|
sta.z sum+1
|
||||||
|
lda #<0>>$10
|
||||||
|
sta.z sum+2
|
||||||
|
lda #>0>>$10
|
||||||
|
sta.z sum+3
|
||||||
|
// [1] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#2] -- vbuz1=vbuc1
|
||||||
|
lda #0
|
||||||
|
sta.z i
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// for(char i=0;i<100;i++)
|
||||||
|
// [2] if((byte) main::i#2<(byte) $64) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||||
|
lda.z i
|
||||||
|
cmp #$64
|
||||||
|
bcc __b2
|
||||||
|
// main::@3
|
||||||
|
// *SCREEN = sum
|
||||||
|
// [3] *((const dword*) SCREEN) ← (dword) main::sum#2 -- _deref_pduc1=vduz1
|
||||||
|
ldq.z sum
|
||||||
|
stq SCREEN
|
||||||
// main::@return
|
// main::@return
|
||||||
// }
|
// }
|
||||||
// [1] return
|
// [4] return
|
||||||
rts
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// sum += addend
|
||||||
|
// [5] (dword) main::sum#1 ← (dword) main::sum#2 + (dword) main::addend#2 -- vduz1=vduz1_plus_vduz2
|
||||||
|
clc
|
||||||
|
ldq.z sum
|
||||||
|
adcq.z addend
|
||||||
|
stq.z sum
|
||||||
|
// addend += i
|
||||||
|
// [6] (dword) main::addend#1 ← (dword) main::addend#2 + (byte) main::i#2 -- vduz1=vduz1_plus_vbuz2
|
||||||
|
// will utilize ADQ/STQ
|
||||||
|
lda.z i
|
||||||
|
clc
|
||||||
|
adc.z addend
|
||||||
|
sta.z addend
|
||||||
|
lda.z addend+1
|
||||||
|
adc #0
|
||||||
|
sta.z addend+1
|
||||||
|
lda.z addend+2
|
||||||
|
adc #0
|
||||||
|
sta.z addend+2
|
||||||
|
lda.z addend+3
|
||||||
|
adc #0
|
||||||
|
sta.z addend+3
|
||||||
|
// for(char i=0;i<100;i++)
|
||||||
|
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
||||||
|
inc.z i
|
||||||
|
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
// [1] phi (dword) main::addend#2 = (dword) main::addend#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
// [1] phi (dword) main::sum#2 = (dword) main::sum#1 [phi:main::@2->main::@1#1] -- register_copy
|
||||||
|
// [1] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@2->main::@1#2] -- register_copy
|
||||||
|
jmp __b1
|
||||||
}
|
}
|
||||||
// File Data
|
// File Data
|
||||||
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
(const dword*) SCREEN = (dword*) 1024
|
||||||
(void()) main()
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@3
|
||||||
(label) main::@return
|
(label) main::@return
|
||||||
|
(dword) main::addend
|
||||||
|
(dword) main::addend#1 addend zp[4]:7 11.0
|
||||||
|
(dword) main::addend#2 addend zp[4]:7 11.0
|
||||||
|
(byte) main::i
|
||||||
|
(byte) main::i#1 i zp[1]:2 22.0
|
||||||
|
(byte) main::i#2 i zp[1]:2 11.0
|
||||||
|
(dword) main::sum
|
||||||
|
(dword) main::sum#1 sum zp[4]:3 7.333333333333333
|
||||||
|
(dword) main::sum#2 sum zp[4]:3 12.0
|
||||||
|
|
||||||
|
zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
zp[4]:3 [ main::sum#2 main::sum#1 ]
|
||||||
|
zp[4]:7 [ main::addend#2 main::addend#1 ]
|
||||||
|
Loading…
Reference in New Issue
Block a user