mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-25 20:32:25 +00:00
Changed clobber to a value object.
This commit is contained in:
parent
676df5fc02
commit
7e72604cf9
@ -2,104 +2,126 @@ package dk.camelot64.cpufamily6502;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/** Information about what parts of the CPU an ASM instruction clobbers */
|
||||
/** Information about what registers/flags of the CPU an ASM instruction clobbers */
|
||||
public class AsmClobber implements Serializable {
|
||||
|
||||
public static final AsmClobber CLOBBER_ALL = new AsmClobber(true);
|
||||
boolean clobberA;
|
||||
boolean clobberX;
|
||||
boolean clobberY;
|
||||
boolean clobberC;
|
||||
boolean clobberN;
|
||||
boolean clobberZ;
|
||||
boolean clobberV;
|
||||
public static final AsmClobber CLOBBER_ALL = new AsmClobber(true, true, true, true, true, true, true);
|
||||
|
||||
final boolean clobberA;
|
||||
final boolean clobberX;
|
||||
final boolean clobberY;
|
||||
final boolean clobberC;
|
||||
final boolean clobberN;
|
||||
final boolean clobberZ;
|
||||
final boolean clobberV;
|
||||
|
||||
public AsmClobber(boolean clobberA, boolean clobberX, boolean clobberY, boolean clobberC, boolean clobberN, boolean clobberZ, boolean clobberV) {
|
||||
this.clobberA = clobberA;
|
||||
this.clobberX = clobberX;
|
||||
this.clobberY = clobberY;
|
||||
this.clobberC = clobberC;
|
||||
this.clobberN = clobberN;
|
||||
this.clobberZ = clobberZ;
|
||||
this.clobberV = clobberV;
|
||||
}
|
||||
|
||||
public AsmClobber() {
|
||||
this(false, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
AsmClobber(boolean clobberAll) {
|
||||
this.clobberA = clobberAll;
|
||||
this.clobberX = clobberAll;
|
||||
this.clobberY = clobberAll;
|
||||
this.clobberC = clobberAll;
|
||||
this.clobberN = clobberAll;
|
||||
this.clobberV = clobberAll;
|
||||
this.clobberZ = clobberAll;
|
||||
/**
|
||||
* Create clobber from a string containing the names of the clobbered registers/flags. EG. "AX" means that the A and X registers are clobbered.
|
||||
*
|
||||
* @param clobberString The clobber string.
|
||||
*/
|
||||
public AsmClobber(String clobberString) {
|
||||
this(
|
||||
clobberString.contains("A"),
|
||||
clobberString.contains("X"),
|
||||
clobberString.contains("Y"),
|
||||
clobberString.contains("C"),
|
||||
clobberString.contains("N"),
|
||||
clobberString.contains("Z"),
|
||||
clobberString.contains("V")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clobber that adds two clobbers together. The result clobbers anything clobbered by any of the two.
|
||||
*
|
||||
* @param clobber1 One clobber
|
||||
* @param clobber2 Another clobber
|
||||
*/
|
||||
public AsmClobber(AsmClobber clobber1, AsmClobber clobber2) {
|
||||
this(
|
||||
clobber1.clobberA | clobber2.clobberA,
|
||||
clobber1.clobberX | clobber2.clobberX,
|
||||
clobber1.clobberY | clobber2.clobberY,
|
||||
clobber1.clobberC | clobber2.clobberC,
|
||||
clobber1.clobberN | clobber2.clobberN,
|
||||
clobber1.clobberZ | clobber2.clobberZ,
|
||||
clobber1.clobberV | clobber2.clobberV
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public boolean isClobberA() {
|
||||
return clobberA;
|
||||
}
|
||||
|
||||
public void setClobberA(boolean clobberA) {
|
||||
this.clobberA = clobberA;
|
||||
}
|
||||
|
||||
public boolean isClobberX() {
|
||||
return clobberX;
|
||||
}
|
||||
|
||||
public void setClobberX(boolean clobberX) {
|
||||
this.clobberX = clobberX;
|
||||
}
|
||||
|
||||
public boolean isClobberY() {
|
||||
return clobberY;
|
||||
}
|
||||
|
||||
public void setClobberY(boolean clobberY) {
|
||||
this.clobberY = clobberY;
|
||||
}
|
||||
|
||||
public boolean isClobberC() {
|
||||
return clobberC;
|
||||
}
|
||||
|
||||
public void setClobberC(boolean clobberC) {
|
||||
this.clobberC = clobberC;
|
||||
}
|
||||
|
||||
public boolean isClobberN() {
|
||||
return clobberN;
|
||||
}
|
||||
|
||||
public void setClobberN(boolean clobberN) {
|
||||
this.clobberN = clobberN;
|
||||
}
|
||||
|
||||
public boolean isClobberZ() {
|
||||
return clobberZ;
|
||||
}
|
||||
|
||||
public void setClobberZ(boolean clobberZ) {
|
||||
this.clobberZ = clobberZ;
|
||||
}
|
||||
|
||||
public boolean isClobberV() {
|
||||
return clobberV;
|
||||
}
|
||||
|
||||
public void setClobberV(boolean clobberV) {
|
||||
this.clobberV = clobberV;
|
||||
public AsmClobber addClobberA(boolean clobberA) {
|
||||
return new AsmClobber(clobberA, this.clobberX, this.clobberY, this.clobberC, this.clobberN, this.clobberZ, this.clobberV);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds clobber.
|
||||
* Effective updates so this clobber also clobbers anything added
|
||||
*
|
||||
* @param clobber The clobber to add
|
||||
*/
|
||||
public void add(AsmClobber clobber) {
|
||||
clobberA |= clobber.clobberA;
|
||||
clobberX |= clobber.clobberX;
|
||||
clobberY |= clobber.clobberY;
|
||||
clobberC |= clobber.clobberC;
|
||||
clobberN |= clobber.clobberN;
|
||||
clobberZ |= clobber.clobberZ;
|
||||
clobberV |= clobber.clobberV;
|
||||
public AsmClobber addClobberX(boolean clobberX) {
|
||||
return new AsmClobber(this.clobberA, clobberX, this.clobberY, this.clobberC, this.clobberN, this.clobberZ, this.clobberV);
|
||||
}
|
||||
|
||||
public AsmClobber addClobberY(boolean clobberY) {
|
||||
return new AsmClobber(this.clobberA, this.clobberX, clobberY, this.clobberC, this.clobberN, this.clobberZ, this.clobberV);
|
||||
}
|
||||
|
||||
public AsmClobber addClobberC(boolean clobberC) {
|
||||
return new AsmClobber(this.clobberA, this.clobberX, this.clobberY, clobberC, this.clobberN, this.clobberZ, this.clobberV);
|
||||
}
|
||||
|
||||
public AsmClobber addClobberN(boolean clobberN) {
|
||||
return new AsmClobber(this.clobberA, this.clobberX, this.clobberY, this.clobberC, clobberN, this.clobberZ, this.clobberV);
|
||||
}
|
||||
|
||||
public AsmClobber addClobberZ(boolean clobberZ) {
|
||||
return new AsmClobber(this.clobberA, this.clobberX, this.clobberY, this.clobberC, this.clobberN, clobberZ, this.clobberV);
|
||||
}
|
||||
|
||||
public AsmClobber addClobberV(boolean clobberV) {
|
||||
return new AsmClobber(this.clobberA, this.clobberX, this.clobberY, this.clobberC, this.clobberN, this.clobberZ, clobberV);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return
|
||||
@ -112,4 +134,5 @@ public class AsmClobber implements Serializable {
|
||||
(clobberV ? "V" : "");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -282,58 +282,58 @@ public class AsmInstructionSet {
|
||||
|
||||
List<String> jumps = Arrays.asList("jmp", "beq", "bne", "bcc", "bcs", "bvs", "bvc", "bmi", "bpl", "jsr");
|
||||
for(AsmOpcode instruction : instructions) {
|
||||
if(jumps.contains(instruction.getMnemnonic())) {
|
||||
if(jumps.contains(instruction.getMnemonic())) {
|
||||
instruction.setJump(true);
|
||||
}
|
||||
}
|
||||
List<String> cxs = Arrays.asList("dex", "inx", "ldx", "tax", "tsx", "las", "lax", "axs");
|
||||
for(AsmOpcode instruction : instructions) {
|
||||
if(cxs.contains(instruction.getMnemnonic())) {
|
||||
instruction.getClobber().setClobberX(true);
|
||||
if(cxs.contains(instruction.getMnemonic())) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberX(true));
|
||||
}
|
||||
}
|
||||
List<String> cys = Arrays.asList("dey", "iny", "ldy", "tay");
|
||||
for(AsmOpcode instruction : instructions) {
|
||||
if(cys.contains(instruction.getMnemnonic())) {
|
||||
instruction.getClobber().setClobberY(true);
|
||||
if(cys.contains(instruction.getMnemonic())) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberY(true));
|
||||
}
|
||||
}
|
||||
List<String> cas = Arrays.asList("ora", "and", "eor", "adc", "sbc", "lda", "txa", "tya", "pla", "slo", "rla", "sre", "rra", "isc", "anc", "alr", "arr", "xaa", "lax", "las");
|
||||
for(AsmOpcode instruction : instructions) {
|
||||
if(cas.contains(instruction.getMnemnonic())) {
|
||||
instruction.getClobber().setClobberA(true);
|
||||
} else if(instruction.getOpcode()==0x0a) {
|
||||
if(cas.contains(instruction.getMnemonic())) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberA(true));
|
||||
} else if(instruction.hasOpcode(0x0a)) {
|
||||
// Special handling of ASL A
|
||||
instruction.getClobber().setClobberA(true);
|
||||
} else if(instruction.getOpcode()==0x2a) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberA(true));
|
||||
} else if(instruction.hasOpcode(0x2a)) {
|
||||
// Special handling of ROL A
|
||||
instruction.getClobber().setClobberA(true);
|
||||
} else if(instruction.getOpcode()==0x4a) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberA(true));
|
||||
} else if(instruction.hasOpcode(0x4a)) {
|
||||
// Special handling of LSR A
|
||||
instruction.getClobber().setClobberA(true);
|
||||
} else if(instruction.getOpcode()==0x6a) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberA(true));
|
||||
} else if(instruction.hasOpcode(0x6a)) {
|
||||
// Special handling of ROR A
|
||||
instruction.getClobber().setClobberA(true);
|
||||
instruction.setClobber(instruction.getClobber().addClobberA(true));
|
||||
}
|
||||
|
||||
}
|
||||
List<String> ccs = Arrays.asList("adc", "sbc", "cmp", "cpx", "cpy", "asl", "rol", "lsr", "ror", "plp", "rti", "clc", "sec", "slo", "rla", "sre", "rra", "dcp", "isc", "anc", "alr", "arr", "axs");
|
||||
for(AsmOpcode instruction : instructions) {
|
||||
if(ccs.contains(instruction.getMnemnonic())) {
|
||||
instruction.getClobber().setClobberC(true);
|
||||
if(ccs.contains(instruction.getMnemonic())) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberC(true));
|
||||
}
|
||||
}
|
||||
List<String> cvs = Arrays.asList("adc", "sbc", "plp", "rti", "bit", "rra", "isc", "arr");
|
||||
for(AsmOpcode instruction : instructions) {
|
||||
if(cvs.contains(instruction.getMnemnonic())) {
|
||||
instruction.getClobber().setClobberV(true);
|
||||
if(cvs.contains(instruction.getMnemonic())) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberV(true));
|
||||
}
|
||||
}
|
||||
List<String> czs = Arrays.asList("ora", "and", "eor", "adc", "sbc", "cmp", "cpx", "cpy", "dec", "dex", "dey", "inc", "inx", "iny", "asl", "rol", "lsr", "ror", "lda", "ldx", "ldy", "tax", "txa", "tay", "tya", "tsx", "txs", "pla", "plp", "rti", "bit", "slo", "rla", "sre", "rra", "lax", "dcp", "isc", "anc", "alr", "arr", "xaa", "lax", "axs", "las");
|
||||
for(AsmOpcode instruction : instructions) {
|
||||
if(czs.contains(instruction.getMnemnonic())) {
|
||||
instruction.getClobber().setClobberZ(true);
|
||||
instruction.getClobber().setClobberN(true);
|
||||
if(czs.contains(instruction.getMnemonic())) {
|
||||
instruction.setClobber(instruction.getClobber().addClobberZ(true));
|
||||
instruction.setClobber(instruction.getClobber().addClobberN(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -343,13 +343,13 @@ public class AsmInstructionSet {
|
||||
* Add an instruction to the instruction set.
|
||||
* @param opcode The numeric opcode
|
||||
* @param mnemonic The lower case mnemonic
|
||||
* @param addressingmMode The addressing mode
|
||||
* @param addressingMode The addressing mode
|
||||
* @param cycles The number of cycles
|
||||
*/
|
||||
private void add(int opcode, String mnemonic, AsmAddressingMode addressingmMode, double cycles) {
|
||||
AsmOpcode instructionType = new AsmOpcode(opcode, mnemonic, addressingmMode, cycles);
|
||||
instructions.add(instructionType);
|
||||
instructionsMap.put(mnemonic + "_" + addressingmMode.getName(), instructionType);
|
||||
private void add(int opcode, String mnemonic, AsmAddressingMode addressingMode, double cycles) {
|
||||
AsmOpcode asmOpcode = new AsmOpcode(opcode, mnemonic, addressingMode, cycles);
|
||||
instructions.add(asmOpcode);
|
||||
instructionsMap.put(mnemonic + "_" + addressingMode.getName(), asmOpcode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -372,23 +372,23 @@ public class AsmInstructionSet {
|
||||
* @return The opcode, if it exists. If you have requested an absolute addressing mode passed isZp as true the resulting opcode will have zeropage-based addressing the instruction set offers that.
|
||||
*/
|
||||
public static AsmOpcode getOpcode(String mnemonic, AsmAddressingMode mode, boolean isZp) {
|
||||
AsmOpcode type = null;
|
||||
AsmOpcode asmOpcode = null;
|
||||
if(AsmAddressingMode.ABS.equals(mode) && isZp) {
|
||||
type = set.getOpcode(mnemonic, AsmAddressingMode.ZP);
|
||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZP);
|
||||
}
|
||||
if(AsmAddressingMode.ABX.equals(mode) && isZp) {
|
||||
type = set.getOpcode(mnemonic, AsmAddressingMode.ZPX);
|
||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZPX);
|
||||
}
|
||||
if(AsmAddressingMode.ABY.equals(mode) && isZp) {
|
||||
type = set.getOpcode(mnemonic, AsmAddressingMode.ZPY);
|
||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.ZPY);
|
||||
}
|
||||
if(type == null) {
|
||||
type = set.getOpcode(mnemonic, mode);
|
||||
if(asmOpcode == null) {
|
||||
asmOpcode = set.getOpcode(mnemonic, mode);
|
||||
}
|
||||
if(type == null && AsmAddressingMode.ABS.equals(mode)) {
|
||||
type = set.getOpcode(mnemonic, AsmAddressingMode.REL);
|
||||
if(asmOpcode == null && AsmAddressingMode.ABS.equals(mode)) {
|
||||
asmOpcode = set.getOpcode(mnemonic, AsmAddressingMode.REL);
|
||||
}
|
||||
return type;
|
||||
return asmOpcode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,15 +3,21 @@ package dk.camelot64.cpufamily6502;
|
||||
/** A specific opcode in the instruction set of a 6502 family CPU. */
|
||||
public class AsmOpcode {
|
||||
|
||||
/** The opcode of the instruction. */
|
||||
private final int opcode;
|
||||
/** The mnemonic of the instruction. */
|
||||
private final String mnemonic;
|
||||
|
||||
/** The mnemonic of the instruction. */
|
||||
private final String mnemnonic;
|
||||
// TODO: Handle mnemonic aliasing?
|
||||
|
||||
/** The addressing mode of the instruction. */
|
||||
private final AsmAddressingMode addressingMode;
|
||||
|
||||
/**
|
||||
* The byte opcodes of the instruction.
|
||||
* Most instructions only have a single byte instruction, but on the 45GS02 the 32-bit instructions are accessed
|
||||
* using prefix-bytes and thus effectively have multiple byte opcodes.
|
||||
*/
|
||||
private final int[] opcode;
|
||||
|
||||
/**
|
||||
* The number of cycles that executing the instruction takes.
|
||||
* Some instructions use different number of cycles under different calling conditions, in that case this is an
|
||||
@ -27,42 +33,98 @@ public class AsmOpcode {
|
||||
private boolean jump;
|
||||
|
||||
/** Which registers/flags of the CPU are clobbered by the instruction. */
|
||||
private final AsmClobber clobber;
|
||||
private AsmClobber clobber;
|
||||
|
||||
public AsmOpcode(int opcode, String mnemnonic, AsmAddressingMode addressingMode, double cycles) {
|
||||
this.opcode = opcode;
|
||||
this.mnemnonic = mnemnonic;
|
||||
AsmOpcode(int opcode, String mnemonic, AsmAddressingMode addressingMode, double cycles) {
|
||||
this.opcode = new int[]{opcode};
|
||||
this.mnemonic = mnemonic;
|
||||
this.addressingMode = addressingMode;
|
||||
this.cycles = cycles;
|
||||
this.clobber = new AsmClobber();
|
||||
}
|
||||
|
||||
public String getMnemnonic() {
|
||||
return mnemnonic;
|
||||
/**
|
||||
* Get the mnemonic of the instruction
|
||||
*
|
||||
* @return The mnemonic
|
||||
*/
|
||||
public String getMnemonic() {
|
||||
return mnemonic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the addressing mode
|
||||
*
|
||||
* @return The addressing mdoe
|
||||
*/
|
||||
public AsmAddressingMode getAddressingMode() {
|
||||
return addressingMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of CPU cycles that execution of the instruction uses.
|
||||
* Some instructions use different number of cycles under different calling conditions, in that case this is an
|
||||
* estimate of the average cycles cost.
|
||||
*
|
||||
* @return The number of cycles.
|
||||
*/
|
||||
public double getCycles() {
|
||||
return cycles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of bytes the instruction with operands takes up in memory
|
||||
*
|
||||
* @return The number of bytes.
|
||||
*/
|
||||
public int getBytes() {
|
||||
return addressingMode.getBytes();
|
||||
}
|
||||
|
||||
public int getOpcode() {
|
||||
/**
|
||||
* Get the byte opcode bytes of the instruction.
|
||||
* Most instructions only have a single byte instruction, but on the 45GS02 the 32-bit instructions are accessed
|
||||
* using prefix-bytes and thus effectively have multiple byte opcodes.
|
||||
*
|
||||
* @return The opcode bytes of the instruction.
|
||||
*/
|
||||
public int[] getOpcode() {
|
||||
return opcode;
|
||||
}
|
||||
|
||||
public String getAsm(String parameter) {
|
||||
return addressingMode.getAsm(mnemnonic, parameter);
|
||||
/**
|
||||
* Determines if this instruction has a specific single byte opcode
|
||||
* @param opcode The byte opcode to check
|
||||
* @return true if this instruction has a 1-byte opcode that matches the passed value.
|
||||
*/
|
||||
public boolean hasOpcode(int opcode) {
|
||||
return this.opcode.length==1 && this.opcode[0]==(byte)opcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the instruction is a jump or a branch
|
||||
* Get the printed ASM code for the instruction with an operand value.
|
||||
* This prints to the syntax that KickAssembler expects.
|
||||
*
|
||||
* @param operand The operand value
|
||||
* @return The printed ASM code for the instruction
|
||||
*/
|
||||
public String getAsm(String operand) {
|
||||
return addressingMode.getAsm(mnemonic, operand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about which registers/flags of the CPU are clobbered by the instruction
|
||||
*
|
||||
* @return The clobber information
|
||||
*/
|
||||
public AsmClobber getClobber() {
|
||||
return clobber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the instruction is a jump or a branch.
|
||||
* A jump is any instruction that can modify the program counter in a way that is not just incrementing it to the
|
||||
* next instruction in memory. This includes JSR and RTS.
|
||||
*
|
||||
* @return true if the instruction is a jump/branch
|
||||
*/
|
||||
@ -70,12 +132,23 @@ public class AsmOpcode {
|
||||
return jump;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the jump property.
|
||||
* TODO: Remove this setter and initialize using the constructor instead.
|
||||
*
|
||||
* @param jump New jump value
|
||||
*/
|
||||
void setJump(boolean jump) {
|
||||
this.jump = jump;
|
||||
}
|
||||
|
||||
public AsmClobber getClobber() {
|
||||
return clobber;
|
||||
/**
|
||||
* Set the clobber information of the opcode.
|
||||
* TODO: Remove this setter and initialize using the constructor instead.
|
||||
* @param asmClobber The new clobber information
|
||||
*/
|
||||
public void setClobber(AsmClobber asmClobber) {
|
||||
this.clobber = asmClobber;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -174,16 +174,16 @@ public class AsmChunk {
|
||||
if(clobberOverwrite != null) {
|
||||
return clobberOverwrite;
|
||||
}
|
||||
AsmClobber clobber = new AsmClobber();
|
||||
AsmClobber chunkClobber = new AsmClobber();
|
||||
for(AsmLine line : lines) {
|
||||
if(line instanceof AsmInstruction) {
|
||||
AsmInstruction asmInstruction = (AsmInstruction) line;
|
||||
AsmOpcode asmOpcode = asmInstruction.getAsmOpcode();
|
||||
AsmClobber asmClobber = asmOpcode.getClobber();
|
||||
clobber.add(asmClobber);
|
||||
AsmClobber opcodeClobber = asmOpcode.getClobber();
|
||||
chunkClobber = new AsmClobber(chunkClobber, opcodeClobber);
|
||||
}
|
||||
}
|
||||
return clobber;
|
||||
return chunkClobber;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,11 +220,11 @@ public class AsmProgram {
|
||||
* @return The clobbered registers
|
||||
*/
|
||||
public AsmClobber getClobber() {
|
||||
AsmClobber clobber = new AsmClobber();
|
||||
AsmClobber programClobber = new AsmClobber();
|
||||
for(AsmChunk chunk : chunks) {
|
||||
clobber.add(chunk.getClobber());
|
||||
programClobber = new AsmClobber(programClobber, chunk.getClobber());
|
||||
}
|
||||
return clobber;
|
||||
return programClobber;
|
||||
}
|
||||
|
||||
public String toString(AsmPrintState printState, Program program) {
|
||||
|
@ -89,7 +89,7 @@ public class AsmProgramStaticRegisterValues {
|
||||
current = new AsmRegisterValues(current);
|
||||
AsmOpcode asmOpcode = instruction.getAsmOpcode();
|
||||
AsmClobber asmClobber = asmOpcode.getClobber();
|
||||
if(instruction.getAsmOpcode().getMnemnonic().equals("jsr")) {
|
||||
if(instruction.getAsmOpcode().getMnemonic().equals("jsr")) {
|
||||
asmClobber = AsmClobber.CLOBBER_ALL;
|
||||
}
|
||||
if(asmClobber.isClobberA()) {
|
||||
@ -116,7 +116,7 @@ public class AsmProgramStaticRegisterValues {
|
||||
if(asmClobber.isClobberZ()) {
|
||||
current.setZ(null);
|
||||
}
|
||||
String mnemnonic = asmOpcode.getMnemnonic();
|
||||
String mnemnonic = asmOpcode.getMnemonic();
|
||||
AsmAddressingMode addressingMode = asmOpcode.getAddressingMode();
|
||||
if((mnemnonic.equals("inc") || mnemnonic.equals("dec") || mnemnonic.equals("ror") || mnemnonic.equals("rol") || mnemnonic.equals("lsr") || mnemnonic.equals("asl")) && (addressingMode.equals(AsmAddressingMode.ZP) || addressingMode.equals(AsmAddressingMode.ABS))) {
|
||||
String modParam = instruction.getParameter();
|
||||
|
@ -652,10 +652,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
if(!clobberString.matches("[AXY]*")) {
|
||||
throw new CompileError("Error! Illegal clobber value " + clobberString, new StatementSource(ctx));
|
||||
}
|
||||
AsmClobber clobber = new AsmClobber();
|
||||
clobber.setClobberA(clobberString.contains("A"));
|
||||
clobber.setClobberX(clobberString.contains("X"));
|
||||
clobber.setClobberY(clobberString.contains("Y"));
|
||||
AsmClobber clobber = new AsmClobber(clobberString);
|
||||
return new AsmDirectiveClobber(clobber);
|
||||
}
|
||||
|
||||
|
@ -916,7 +916,7 @@ public class Pass4CodeGeneration {
|
||||
for(AsmLine asmLine : currentChunk.getLines()) {
|
||||
if(asmLine instanceof AsmInstruction) {
|
||||
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
|
||||
if(asmInstruction.getAsmOpcode().getMnemnonic().equals("jsr")) {
|
||||
if(asmInstruction.getAsmOpcode().getMnemonic().equals("jsr")) {
|
||||
currentChunk.setClobberOverwrite(AsmClobber.CLOBBER_ALL);
|
||||
}
|
||||
}
|
||||
|
@ -70,15 +70,15 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
||||
|
||||
private AsmClobber getProcedureClobber(Procedure procedure) {
|
||||
AsmProgram asm = getProgram().getAsm();
|
||||
AsmClobber procClobber =new AsmClobber();
|
||||
AsmClobber procClobber = new AsmClobber();
|
||||
for(AsmChunk asmChunk : asm.getChunks()) {
|
||||
if(procedure.getFullName().equals(asmChunk.getScopeLabel())) {
|
||||
if(asmChunk.getSource().contains(Procedure.InterruptType.HARDWARE_CLOBBER.name())) {
|
||||
// Do not count clobber in the entry/exit
|
||||
continue;
|
||||
}
|
||||
AsmClobber asmChunkClobber = asmChunk.getClobber();
|
||||
procClobber.add(asmChunkClobber);
|
||||
AsmClobber chunkClobber = asmChunk.getClobber();
|
||||
procClobber = new AsmClobber(procClobber, chunkClobber);
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ public class Pass4InterruptClobberFix extends Pass2Base {
|
||||
ProcedureRef calledProcRef = new ProcedureRef(calledProcLabel.getFullName());
|
||||
Procedure calledProc = getProgram().getScope().getProcedure(calledProcRef);
|
||||
AsmClobber calledClobber = getProcedureClobber(calledProc);
|
||||
procClobber.add(calledClobber);
|
||||
procClobber = new AsmClobber(procClobber, calledClobber);
|
||||
}
|
||||
|
||||
return procClobber;
|
||||
|
@ -27,7 +27,7 @@ public class Pass5AddMainRts extends Pass5AsmOptimization {
|
||||
AsmLine line = lineIterator.next();
|
||||
if(line instanceof AsmInstruction) {
|
||||
AsmInstruction instruction = (AsmInstruction) line;
|
||||
if(instruction.getAsmOpcode().getMnemnonic().equals("jsr")) {
|
||||
if(instruction.getAsmOpcode().getMnemonic().equals("jsr")) {
|
||||
if(instruction.getParameter().equals(SymbolRef.MAIN_PROC_NAME)) {
|
||||
// Add RTS if it is missing
|
||||
if(!lineIterator.hasNext()) {
|
||||
@ -40,7 +40,7 @@ public class Pass5AddMainRts extends Pass5AsmOptimization {
|
||||
return true;
|
||||
}
|
||||
AsmInstruction nextInstruction = (AsmInstruction) nextLine;
|
||||
if(!nextInstruction.getAsmOpcode().getMnemnonic().equals("rts")) {
|
||||
if(!nextInstruction.getAsmOpcode().getMnemonic().equals("rts")) {
|
||||
addRts(lineIterator);
|
||||
return true;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization {
|
||||
AsmInstruction asmInstruction = (AsmInstruction) line;
|
||||
if(asmInstruction.getAsmOpcode().isJump()) {
|
||||
String immediateJmpTarget = immediateJumps.get(currentScope + "::" + asmInstruction.getParameter());
|
||||
if(immediateJmpTarget == "rts" && asmInstruction.getAsmOpcode().getMnemnonic() == "jmp") {
|
||||
if(immediateJmpTarget == "rts" && asmInstruction.getAsmOpcode().getMnemonic() == "jmp") {
|
||||
getLog().append("Replacing jump to rts with rts in " + asmInstruction.toString());
|
||||
AsmOpcode rtsOpcode = AsmInstructionSet.getOpcode("rts", AsmAddressingMode.NON, false);
|
||||
asmInstruction.setAsmOpcode(rtsOpcode);
|
||||
|
@ -164,7 +164,7 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
|
||||
AsmOpcode inverseAsmOpcode = invertBranch(asmOpcode);
|
||||
if(inverseAsmOpcode != null) {
|
||||
//getLog().append("Inversed branch instruction "+asmInstructionType.getMnemnonic()+" -> "+inverseType.getMnemnonic());
|
||||
getLog().append("Fixing long branch [" + idx + "] " + asmLine.toString() + " to " + inverseAsmOpcode.getMnemnonic());
|
||||
getLog().append("Fixing long branch [" + idx + "] " + asmLine.toString() + " to " + inverseAsmOpcode.getMnemonic());
|
||||
String branchDest = asmInstruction.getParameter();
|
||||
asmInstruction.setAsmOpcode(inverseAsmOpcode);
|
||||
String newLabel = AsmFormat.asmFix("!" + branchDest);
|
||||
@ -181,7 +181,7 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
|
||||
}
|
||||
|
||||
private AsmOpcode invertBranch(AsmOpcode asmOpcode) {
|
||||
switch(asmOpcode.getMnemnonic()) {
|
||||
switch(asmOpcode.getMnemonic()) {
|
||||
case "bcc":
|
||||
return AsmInstructionSet.getOpcode("bcs", AsmAddressingMode.REL, false);
|
||||
case "bcs":
|
||||
|
@ -33,7 +33,7 @@ public class Pass5NextJumpElimination extends Pass5AsmOptimization {
|
||||
if(line instanceof AsmInstruction) {
|
||||
candidate = null;
|
||||
AsmInstruction instruction = (AsmInstruction) line;
|
||||
if(instruction.getAsmOpcode().isJump() && !instruction.getAsmOpcode().getMnemnonic().equals("jsr")) {
|
||||
if(instruction.getAsmOpcode().isJump() && !instruction.getAsmOpcode().getMnemonic().equals("jsr")) {
|
||||
candidate = instruction;
|
||||
}
|
||||
} else if(line instanceof AsmDataString || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmInlineKickAsm ) {
|
||||
|
@ -41,7 +41,7 @@ public class Pass5SkipBegin extends Pass5AsmOptimization {
|
||||
}
|
||||
} else if(line instanceof AsmInstruction) {
|
||||
AsmInstruction instruction = (AsmInstruction) line;
|
||||
if(instruction.getAsmOpcode().getMnemnonic().equals("jsr")) {
|
||||
if(instruction.getAsmOpcode().getMnemonic().equals("jsr")) {
|
||||
if(instruction.getParameter().equals(SymbolRef.MAIN_PROC_NAME)) {
|
||||
lineIterator.remove();
|
||||
optimized = true;
|
||||
|
@ -35,7 +35,7 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
||||
}
|
||||
AsmOpcode asmOpcode = instruction.getAsmOpcode();
|
||||
|
||||
if(asmOpcode.getMnemnonic().equals("lda") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) {
|
||||
if(asmOpcode.getMnemonic().equals("lda") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) {
|
||||
String immValue = instruction.getParameter();
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getA(), immValue)) {
|
||||
@ -50,7 +50,7 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
||||
instruction.setParameter(null);
|
||||
}
|
||||
}
|
||||
if(asmOpcode.getMnemnonic().equals("lda") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) {
|
||||
if(asmOpcode.getMnemonic().equals("lda") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) {
|
||||
String memValue = instruction.getParameter();
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(instructionValues.getaMem() != null && instructionValues.getaMem().equals(memValue)) {
|
||||
@ -65,7 +65,7 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
||||
instruction.setParameter(null);
|
||||
}
|
||||
}
|
||||
if(asmOpcode.getMnemnonic().equals("ldx") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) {
|
||||
if(asmOpcode.getMnemonic().equals("ldx") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) {
|
||||
String immValue = instruction.getParameter();
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getX(), immValue)) {
|
||||
@ -76,7 +76,7 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
||||
instruction.setParameter(null);
|
||||
}
|
||||
}
|
||||
if(asmOpcode.getMnemnonic().equals("ldx") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) {
|
||||
if(asmOpcode.getMnemonic().equals("ldx") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) {
|
||||
String memValue = instruction.getParameter();
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(instructionValues.getxMem() != null && instructionValues.getxMem().equals(memValue)) {
|
||||
@ -87,7 +87,7 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
||||
instruction.setParameter(null);
|
||||
}
|
||||
}
|
||||
if(asmOpcode.getMnemnonic().equals("ldy") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) {
|
||||
if(asmOpcode.getMnemonic().equals("ldy") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) {
|
||||
String immValue = instruction.getParameter();
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getY(), immValue)) {
|
||||
@ -98,7 +98,7 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
||||
instruction.setParameter(null);
|
||||
}
|
||||
}
|
||||
if(asmOpcode.getMnemnonic().equals("ldy") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) {
|
||||
if(asmOpcode.getMnemonic().equals("ldy") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) {
|
||||
String memValue = instruction.getParameter();
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(instructionValues.getyMem() != null && instructionValues.getyMem().equals(memValue)) {
|
||||
@ -109,13 +109,13 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization {
|
||||
instruction.setParameter(null);
|
||||
}
|
||||
}
|
||||
if(asmOpcode.getMnemnonic().equals("clc")) {
|
||||
if(asmOpcode.getMnemonic().equals("clc")) {
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(Boolean.FALSE.equals(instructionValues.getC())) {
|
||||
modified = remove(lineIt);
|
||||
}
|
||||
}
|
||||
if(asmOpcode.getMnemnonic().equals("sec")) {
|
||||
if(asmOpcode.getMnemonic().equals("sec")) {
|
||||
AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction);
|
||||
if(Boolean.TRUE.equals(instructionValues.getC())) {
|
||||
modified = remove(lineIt);
|
||||
|
@ -34,7 +34,7 @@ public class Pass5UnreachableCodeElimination extends Pass5AsmOptimization {
|
||||
optimized = true;
|
||||
} else {
|
||||
AsmInstruction asmInstruction = (AsmInstruction) line;
|
||||
if(asmInstruction.getAsmOpcode().getMnemnonic().equals("rts") || asmInstruction.getAsmOpcode().getMnemnonic().equals("jmp")) {
|
||||
if(asmInstruction.getAsmOpcode().getMnemonic().equals("rts") || asmInstruction.getAsmOpcode().getMnemonic().equals("jmp")) {
|
||||
afterExit = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user