mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-22 21:29:50 +00:00
Implemented the last asm fragments
This commit is contained in:
parent
4e4fee9035
commit
968f51343a
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
5
src/dk/camelot64/kickc/icl/Value.java
Normal file
5
src/dk/camelot64/kickc/icl/Value.java
Normal file
@ -0,0 +1,5 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
/** Any value (variable, constant, label) */
|
||||
public interface Value {
|
||||
}
|
7
src/dk/camelot64/kickc/icl/asm/zpbo1=zpby1<coby1.asm
Normal file
7
src/dk/camelot64/kickc/icl/asm/zpbo1=zpby1<coby1.asm
Normal file
@ -0,0 +1,7 @@
|
||||
lda {zpby1}
|
||||
cmp #{coby1}
|
||||
bcc !t+
|
||||
!f: lda #0
|
||||
jmp !d+
|
||||
!t: lda #$ff
|
||||
!d: sta {zpbo1}
|
8
src/dk/camelot64/kickc/icl/asm/zpbo1=zpby1>coby1.asm
Normal file
8
src/dk/camelot64/kickc/icl/asm/zpbo1=zpby1>coby1.asm
Normal file
@ -0,0 +1,8 @@
|
||||
lda {zpby1}
|
||||
cmp #{coby1}
|
||||
beq !f+
|
||||
bcs !t+
|
||||
!f: lda #0
|
||||
jmp !d+
|
||||
!t: lda #$ff
|
||||
!d: sta {zpbo1}
|
2
src/dk/camelot64/kickc/icl/asm/zpbo1?la1.asm
Normal file
2
src/dk/camelot64/kickc/icl/asm/zpbo1?la1.asm
Normal file
@ -0,0 +1,2 @@
|
||||
lda {zpbo1}
|
||||
bne {la1}
|
Loading…
Reference in New Issue
Block a user