1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-16 21:07:56 +00:00

Implemented the last asm fragments

This commit is contained in:
jespergravgaard 2017-05-15 18:15:56 +02:00
parent 4e4fee9035
commit 968f51343a
9 changed files with 67 additions and 18 deletions

View File

@ -10,7 +10,7 @@ public abstract class AsmFragmentSignature {
private SymbolTable symbols;
/** Binding of named values in the fragment to values (constants, variables, ...) .*/
private Map<String, RValue> bindings;
private Map<String, Value> bindings;
/** The string signature/name of the asm fragment. */
private String signature;
@ -20,7 +20,7 @@ public abstract class AsmFragmentSignature {
this.bindings = new HashMap<>();
}
public RValue getBinding(String name) {
public Value getBinding(String name) {
return bindings.get(name);
}
@ -41,12 +41,15 @@ public abstract class AsmFragmentSignature {
/** Constant byte indexing. */
private int nextConstByteIdx = 1;
/** Label indexing. */
private int nextLabelIdx = 1;
/**
* Add bindings of a value.
* @param value The value to bind.
* @return The bound name of the value. If the value has already been bound the existing bound name is returned.
*/
public String bind(RValue value) {
public String bind(Value value) {
// Find value if it is already bound
for (String name : bindings.keySet()) {
if (value.equals(bindings.get(name))) {
@ -75,6 +78,10 @@ public abstract class AsmFragmentSignature {
} else {
throw new RuntimeException("Binding of word integers not supported " + intValue);
}
} else if (value instanceof Label) {
String name = "la"+ nextLabelIdx++;
bindings.put(name, value);
return name;
} else {
throw new RuntimeException("Binding of value type not supported " + value);
}

View File

@ -0,0 +1,13 @@
package dk.camelot64.kickc.icl;
/** Assembler Fragment Signature for a conditional jump */
public class AsmFragmentSignatureConditionalJump extends AsmFragmentSignature {
public AsmFragmentSignatureConditionalJump(StatementConditionalJump conditionalJump, SymbolTable symbols) {
super(symbols);
StringBuilder signature = new StringBuilder();
signature.append(bind(conditionalJump.getCondition()));
signature.append("?");
signature.append(bind(conditionalJump.getDestination()));
setSignature(signature.toString());
}
}

View File

@ -34,7 +34,7 @@ public class Pass4CodeGeneration {
// Generate exit
ControlFlowBlock defaultSuccessor = block.getDefaultSuccessor();
if (defaultSuccessor != null) {
if(defaultSuccessor.getPredecessors().size()>1) {
if (defaultSuccessor.getPredecessors().size() > 1) {
String label = defaultSuccessor.getLabel().getName() + "_from_" + block.getLabel().getName();
genAsmJump(asm, label);
} else {
@ -56,7 +56,11 @@ public class Pass4CodeGeneration {
private void genStatement(AsmSequence asm, Statement statement) {
if (statement instanceof StatementAssignment) {
AsmFragmentSignature asmFragmentSignature = new AsmFragmentSignatureAssignment((StatementAssignment) statement, symbols);
asm.addAsm(" // " + statement + " // "+asmFragmentSignature.getSignature());
asm.addAsm(" // " + statement + " // " + asmFragmentSignature.getSignature());
genAsmFragment(asm, asmFragmentSignature);
} else if (statement instanceof StatementConditionalJump) {
AsmFragmentSignature asmFragmentSignature = new AsmFragmentSignatureConditionalJump((StatementConditionalJump) statement, symbols);
asm.addAsm(" // " + statement + " // " + asmFragmentSignature.getSignature());
genAsmFragment(asm, asmFragmentSignature);
} else {
asm.addAsm(" // TODO: " + statement);
@ -99,7 +103,7 @@ public class Pass4CodeGeneration {
*/
private void genAsmMove(AsmSequence asm, RValue rValue, LValue lValue) {
AsmFragmentSignatureAssignment signature = new AsmFragmentSignatureAssignment(lValue, rValue, symbols);
asm.addAsm(" // " + rValue + " = " + lValue + " // "+signature.getSignature());
asm.addAsm(" // " + rValue + " = " + lValue + " // " + signature.getSignature());
genAsmFragment(asm, signature);
}
@ -112,7 +116,7 @@ public class Pass4CodeGeneration {
}
private void genAsmJump(AsmSequence asm, String label) {
asm.addAsm(" jmp " + label.replace('B', '_'));
asm.addAsm(" jmp " + label.replace('@', 'B'));
}
/**
@ -137,7 +141,7 @@ public class Pass4CodeGeneration {
String line;
while ((line = fragmentReader.readLine()) != null) {
Matcher matcher = bindPattern.matcher(line);
if(matcher.matches()) {
if (matcher.matches()) {
String name = matcher.group(1);
String bound = getFragmentBoundValue(name, fragmentSignature);
line = line.replaceFirst("\\{[^}]*}", bound);
@ -154,29 +158,32 @@ public class Pass4CodeGeneration {
/**
* Get the value to replace a bound name with from the fragment signature
* @param boundName The name of the bound value in the fragment
*
* @param boundName The name of the bound value in the fragment
* @param fragmentSignature The fragment signature containing the bindings
* @return The bound value to use in the generated ASM code
*/
private String getFragmentBoundValue(String boundName, AsmFragmentSignature fragmentSignature) {
RValue boundValue = fragmentSignature.getBinding(boundName);
Value boundValue = fragmentSignature.getBinding(boundName);
String bound;
if(boundValue instanceof Variable) {
if (boundValue instanceof Variable) {
RegisterAllocation.Register register = symbols.getRegister((Variable) boundValue);
if(register instanceof RegisterAllocation.RegisterZpByte) {
if (register instanceof RegisterAllocation.RegisterZpByte) {
bound = Integer.toString(((RegisterAllocation.RegisterZpByte) register).getZp());
} else if(register instanceof RegisterAllocation.RegisterZpBool) {
} else if (register instanceof RegisterAllocation.RegisterZpBool) {
bound = Integer.toString(((RegisterAllocation.RegisterZpBool) register).getZp());
} else {
throw new RuntimeException("Register Type not implemented "+register);
throw new RuntimeException("Register Type not implemented " + register);
}
} else if(boundValue instanceof ConstantInteger) {
} else if (boundValue instanceof ConstantInteger) {
ConstantInteger boundInt = (ConstantInteger) boundValue;
if(boundInt.getType().equals(SymbolType.BYTE)) {
if (boundInt.getType().equals(SymbolType.BYTE)) {
bound = Integer.toString(boundInt.getNumber());
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}
} else if (boundValue instanceof Label) {
bound = ((Label) boundValue).getName().replace('@', 'B');
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}

View File

@ -1,5 +1,5 @@
package dk.camelot64.kickc.icl;
/** A value usable as part of a calculation (ib the right side of an assignment)*/
public interface RValue {
public interface RValue extends Value {
}

View File

@ -1,7 +1,7 @@
package dk.camelot64.kickc.icl;
/** A Symbol (variable, jump label, etc.) */
public interface Symbol {
public interface Symbol extends Value {
public String getName();

View File

@ -0,0 +1,5 @@
package dk.camelot64.kickc.icl;
/** Any value (variable, constant, label) */
public interface Value {
}

View File

@ -0,0 +1,7 @@
lda {zpby1}
cmp #{coby1}
bcc !t+
!f: lda #0
jmp !d+
!t: lda #$ff
!d: sta {zpbo1}

View File

@ -0,0 +1,8 @@
lda {zpby1}
cmp #{coby1}
beq !f+
bcs !t+
!f: lda #0
jmp !d+
!t: lda #$ff
!d: sta {zpbo1}

View File

@ -0,0 +1,2 @@
lda {zpbo1}
bne {la1}