mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-22 18:37:29 +00:00
Fixed problems with versioned constant call parameters being mixed up and with missing scope name on constant references across scopes.
This commit is contained in:
parent
6097d80b91
commit
4de433730f
@ -7,6 +7,7 @@ Known Problems
|
||||
- (useuninitialized.kc) Using an uninitialized variable fails in the optimizer phase. It should fail much earlier.
|
||||
|
||||
Features
|
||||
- Inline contants that are only call parameters used once (eg. x0#0 and x0#1 in callconstparam.kc)
|
||||
- Move the main code into a main() function, and disallow code outside functions. The main function per default has no parameters and exits with RTS.
|
||||
- Improve locality of block sequence for if(cond) { stmt1; } else { stmt2; } to if(!cond) goto @else stmt1; jmp @end; @else: stmt2; @end:
|
||||
- Optimize if/else by swapping if & else if cond is easier to evaluate than !cond.
|
||||
@ -31,6 +32,12 @@ Features
|
||||
- Add UpliftRemains support for attempting to uplift potentials to ALU (requires modifying two registers: 1. the ALU potential to ALU - the one added to the ALU potential to A.)
|
||||
- Support array-initializer syntax as literal word syntax. byte* plotter = { lo, hi };
|
||||
|
||||
Word Math
|
||||
- Support Word table lookup (through 2 byte-tables)
|
||||
- Support word math operations (addition, subtraction)
|
||||
- Implement a word-ALU
|
||||
- Usage: word[] plotter_x; word[] plotter_y; byte* plotter = plotter_x[x] + plotter_y[y]; -> lda plotter_x_lo,x; clc; adc plotter_y_lo,y; sta plotter; lda plotter_x_hi,x; adc plotter_y_hi,y; sta plotter+1
|
||||
|
||||
Arrays / Strings / Inline data
|
||||
- New semantic: Arrays are always allocated inline (and must therefore have a size). Pointers are never.
|
||||
- Allow complex array expressions in lValues eg. (SCREEN+$100)[idx]
|
||||
@ -72,6 +79,8 @@ Register Allocation
|
||||
- Improve combination testing by finding live range overlaps and not creating combinations that would create an overlap conflict.
|
||||
- Combinations should be created in a tree-structure instead of just doing all combinations
|
||||
- Example: For equivalence classes a, b, c if a&c have overlapping live ranges they can never have the same register. Therefore the combination iterator should not create combinations where C has the same register as a.
|
||||
- Optimize registers in local windows - creating smaller sets of combinations. Currently some programs easily has millions of possible combinations.
|
||||
|
||||
|
||||
Process/Code Structure Improvement
|
||||
- Eliminate copy visitor
|
||||
@ -149,4 +158,6 @@ Done
|
||||
+ Make each phase return a separate object graph (allowing for keeeping the history in memory & performing rollbacks)
|
||||
+ Remove "string" keyword (if it exists).
|
||||
+ Support hi/lo-byte lvalues - <plotter = plot_xlo[x]+plot_ylo[y]; >plotter = plot_xhi[x]+plot_yhi[y];
|
||||
+ Add ALU support for lo/hi operators on pointers - to avoid unnecessary zp-variable holding for cases like byte v = y&$7 | <yoffs;
|
||||
+ Add ALU support for lo/hi operators on pointers - to avoid unnecessary zp-variable holding for cases like byte v = y&$7 | <yoffs;
|
||||
+ (callconstparam.kc) Constant parameters to multiple calls are mixed together because their versioned names (x0#0, X0#1) are shortened to not include the version and only one version is output in the ASM.
|
||||
+ (callconstparam.kc) Constant call parameters are stored as values in the called function - not at the call. The reference from the call to the constant does not include the function name, so the result is an unknown symbol error when compiling the ASM.
|
||||
|
@ -27,7 +27,7 @@ public class AsmFragment {
|
||||
/**
|
||||
* The scope containing the fragment. Used when referencing symbols defined in other scopes.
|
||||
*/
|
||||
private ScopeRef scope;
|
||||
private ScopeRef codeScopeRef;
|
||||
|
||||
/**
|
||||
* The string signature/name of the fragment fragment.
|
||||
@ -39,7 +39,7 @@ public class AsmFragment {
|
||||
ControlFlowBlock block,
|
||||
Program program,
|
||||
ControlFlowGraph graph) {
|
||||
this.scope = program.getGraph().getBlockFromStatementIdx(conditionalJump.getIndex()).getScope();
|
||||
this.codeScopeRef = program.getGraph().getBlockFromStatementIdx(conditionalJump.getIndex()).getScope();
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.program = program;
|
||||
String conditionalJumpSignature = conditionalJumpSignature(conditionalJump, block, graph);
|
||||
@ -47,7 +47,7 @@ public class AsmFragment {
|
||||
}
|
||||
|
||||
public AsmFragment(StatementAssignment assignment, Program program) {
|
||||
this.scope = program.getGraph().getBlockFromStatementIdx(assignment.getIndex()).getScope();
|
||||
this.codeScopeRef = program.getGraph().getBlockFromStatementIdx(assignment.getIndex()).getScope();
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.program = program;
|
||||
setSignature(assignmentSignature(
|
||||
@ -57,65 +57,22 @@ public class AsmFragment {
|
||||
assignment.getrValue2()));
|
||||
}
|
||||
|
||||
public AsmFragment(LValue lValue, RValue rValue, Program program, ScopeRef scope) {
|
||||
this.scope = scope;
|
||||
public AsmFragment(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) {
|
||||
this.codeScopeRef = codeScopeRef;
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.program = program;
|
||||
setSignature(assignmentSignature(lValue, null, null, rValue));
|
||||
}
|
||||
|
||||
public AsmFragment(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) {
|
||||
this.scope = program.getGraph().getBlockFromStatementIdx(assignment.getIndex()).getScope();
|
||||
this.codeScopeRef = program.getGraph().getBlockFromStatementIdx(assignment.getIndex()).getScope();
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.program = program;
|
||||
setSignature(assignmentWithAluSignature(assignment, assignmentAlu));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ASM code for a constant value
|
||||
*
|
||||
* @param value The constant value
|
||||
* @param precedence The precedence of the outer expression operator. Used to generate perenthesis when needed.
|
||||
*
|
||||
* @return The ASM string representing the constant value
|
||||
*/
|
||||
public static String getAsmConstant(Program program, ConstantValue value, int precedence) {
|
||||
if (value instanceof ConstantRef) {
|
||||
ConstantVar constantVar = program.getScope().getConstant((ConstantRef) value);
|
||||
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||
return asmName.replace("#", "_").replace("$", "_");
|
||||
} else if (value instanceof ConstantInteger) {
|
||||
return getAsmNumber(((ConstantInteger) value).getNumber());
|
||||
} else if (value instanceof ConstantChar) {
|
||||
return "'"+((ConstantChar) value).getValue()+"'";
|
||||
} else if (value instanceof ConstantString) {
|
||||
return "\""+((ConstantString) value).getValue()+"\"";
|
||||
} else if (value instanceof ConstantUnary) {
|
||||
ConstantUnary unary = (ConstantUnary) value;
|
||||
Operator operator = unary.getOperator();
|
||||
boolean parenthesis = operator.getPrecedence()>precedence;
|
||||
return
|
||||
(parenthesis ? "(" : "") +
|
||||
operator.getOperator() +
|
||||
getAsmConstant(program, unary.getOperand(), operator.getPrecedence()) +
|
||||
(parenthesis? ")" : "");
|
||||
} else if (value instanceof ConstantBinary) {
|
||||
ConstantBinary binary = (ConstantBinary) value;
|
||||
Operator operator = binary.getOperator();
|
||||
boolean parenthesis = operator.getPrecedence()>precedence;
|
||||
return
|
||||
(parenthesis? "(" : "") +
|
||||
getAsmConstant(program, binary.getLeft(), operator.getPrecedence()) +
|
||||
operator.getOperator() +
|
||||
getAsmConstant(program, binary.getRight(), operator.getPrecedence()) +
|
||||
(parenthesis? ")" : "");
|
||||
} else {
|
||||
throw new RuntimeException("Constant type not supported " + value);
|
||||
}
|
||||
}
|
||||
|
||||
private String assignmentWithAluSignature(StatementAssignment assignment, StatementAssignment assignmentAlu) {
|
||||
this.scope = program.getGraph().getBlockFromStatementIdx(assignment.getIndex()).getScope();
|
||||
this.codeScopeRef = program.getGraph().getBlockFromStatementIdx(assignment.getIndex()).getScope();
|
||||
if (!(assignment.getrValue2() instanceof VariableRef)) {
|
||||
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
|
||||
}
|
||||
@ -291,6 +248,11 @@ public class AsmFragment {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
private Scope getCodeScope() {
|
||||
return program.getScope().getScope(codeScopeRef);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Zero page register name indexing.
|
||||
*/
|
||||
@ -436,18 +398,18 @@ public class AsmFragment {
|
||||
Variable boundVar = (Variable) boundValue;
|
||||
Registers.Register register = boundVar.getAllocation();
|
||||
if (register != null && register instanceof Registers.RegisterZp) {
|
||||
return new AsmParameter(getAsmParameter(boundVar), true);
|
||||
return new AsmParameter(getAsmParamName(boundVar), true);
|
||||
} else {
|
||||
throw new RuntimeException("Register Type not implemented " + register);
|
||||
}
|
||||
} else if (boundValue instanceof ConstantVar) {
|
||||
ConstantVar constantVar = (ConstantVar) boundValue;
|
||||
String constantValueAsm = getAsmConstant(program, constantVar.getRef(), 99);
|
||||
String constantValueAsm = getAsmConstant(program, constantVar.getRef(), 99, getCodeScope());
|
||||
boolean constantValueZp = SymbolTypeBasic.BYTE.equals(constantVar.getType(program.getScope()));
|
||||
return new AsmParameter(constantValueAsm, constantValueZp);
|
||||
} else if (boundValue instanceof ConstantValue) {
|
||||
ConstantValue boundConst = (ConstantValue) boundValue;
|
||||
String constantValueAsm = getAsmConstant(program, boundConst, 99);
|
||||
String constantValueAsm = getAsmConstant(program, boundConst, 99, getCodeScope());
|
||||
boolean constantValueZp = SymbolTypeBasic.BYTE.equals(boundConst.getType(program.getScope()));
|
||||
return new AsmParameter(constantValueAsm, constantValueZp);
|
||||
} else if (boundValue instanceof Label) {
|
||||
@ -458,6 +420,50 @@ public class AsmFragment {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ASM code for a constant value
|
||||
*
|
||||
* @param value The constant value
|
||||
* @param precedence The precedence of the outer expression operator. Used to generate perenthesis when needed.
|
||||
* @param codeScope The scope containing the code being generated. Used for adding scope to the name when needed (eg. line.x1 when referencing x1 variable inside line scope from outside line scope).
|
||||
*
|
||||
* @return The ASM string representing the constant value
|
||||
*/
|
||||
public static String getAsmConstant(Program program, ConstantValue value, int precedence, Scope codeScope) {
|
||||
if (value instanceof ConstantRef) {
|
||||
ConstantVar constantVar = program.getScope().getConstant((ConstantRef) value);
|
||||
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||
return getAsmParamName(constantVar.getScope(), asmName, codeScope);
|
||||
} else if (value instanceof ConstantInteger) {
|
||||
return getAsmNumber(((ConstantInteger) value).getNumber());
|
||||
} else if (value instanceof ConstantChar) {
|
||||
return "'"+((ConstantChar) value).getValue()+"'";
|
||||
} else if (value instanceof ConstantString) {
|
||||
return "\""+((ConstantString) value).getValue()+"\"";
|
||||
} else if (value instanceof ConstantUnary) {
|
||||
ConstantUnary unary = (ConstantUnary) value;
|
||||
Operator operator = unary.getOperator();
|
||||
boolean parenthesis = operator.getPrecedence()>precedence;
|
||||
return
|
||||
(parenthesis ? "(" : "") +
|
||||
operator.getOperator() +
|
||||
getAsmConstant(program, unary.getOperand(), operator.getPrecedence(), codeScope) +
|
||||
(parenthesis? ")" : "");
|
||||
} else if (value instanceof ConstantBinary) {
|
||||
ConstantBinary binary = (ConstantBinary) value;
|
||||
Operator operator = binary.getOperator();
|
||||
boolean parenthesis = operator.getPrecedence()>precedence;
|
||||
return
|
||||
(parenthesis? "(" : "") +
|
||||
getAsmConstant(program, binary.getLeft(), operator.getPrecedence(), codeScope) +
|
||||
operator.getOperator() +
|
||||
getAsmConstant(program, binary.getRight(), operator.getPrecedence(), codeScope) +
|
||||
(parenthesis? ")" : "");
|
||||
} else {
|
||||
throw new RuntimeException("Constant type not supported " + value);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAsmNumber(Number number) {
|
||||
if(number instanceof Integer) {
|
||||
if(number.intValue()>=0 && number.intValue()<=9) {
|
||||
@ -474,31 +480,33 @@ public class AsmFragment {
|
||||
* @param boundVar The variable
|
||||
* @return The ASM parameter to use in the ASM code
|
||||
*/
|
||||
private String getAsmParameter(Variable boundVar) {
|
||||
private String getAsmParamName(Variable boundVar) {
|
||||
Scope varScope = boundVar.getScope();
|
||||
String asmName = boundVar.getAsmName() == null ? boundVar.getLocalName() : boundVar.getAsmName();
|
||||
return getAsmParameter(varScope, asmName);
|
||||
return getAsmParamName(varScope, asmName, getCodeScope());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the ASM parameter for a specific bound constant
|
||||
* @param boundVar The constant
|
||||
* @return The ASM parameter to use in the ASM code
|
||||
*/
|
||||
private String getAsmParameter(ConstantVar boundVar) {
|
||||
private String getAsmParamName(ConstantVar boundVar) {
|
||||
Scope varScope = boundVar.getScope();
|
||||
String asmName = boundVar.getAsmName() == null ? boundVar.getLocalName() : boundVar.getAsmName();
|
||||
return getAsmParameter(varScope, asmName);
|
||||
return getAsmParamName(varScope, asmName, getCodeScope());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ASM parameter for a specific bound constant/ variable
|
||||
* @param varScope The scope containing the var/const
|
||||
* @param asmName The ASM name of the variable (local name or specific ASM name).
|
||||
* @param codeScope The scope containing the code being generated. Used for adding scope to the name when needed (eg. line.x1 when referencing x1 variable inside line scope from outside line scope).
|
||||
* @return The ASM parameter to use in the ASM code
|
||||
*/
|
||||
private String getAsmParameter(Scope varScope, String asmName) {
|
||||
if (!varScope.getRef().equals(scope) && varScope.getRef().getFullName().length() > 0) {
|
||||
private static String getAsmParamName(Scope varScope, String asmName, Scope codeScope) {
|
||||
if (!varScope.equals(codeScope) && varScope.getRef().getFullName().length() > 0) {
|
||||
String param = varScope.getFullName() + "." + asmName
|
||||
.replace('@', 'b')
|
||||
.replace(':', '_')
|
||||
|
@ -0,0 +1,3 @@
|
||||
stx $ff
|
||||
cmp $ff
|
||||
bcc {la1}
|
@ -236,6 +236,13 @@ public class Registers {
|
||||
|
||||
/** Special register used for constants. Has no corresponding CPU register. */
|
||||
public static class RegisterConstant implements Register {
|
||||
|
||||
private ConstantValue constantValue;
|
||||
|
||||
public RegisterConstant(ConstantValue constantValue) {
|
||||
this.constantValue = constantValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisterType getType() {
|
||||
return RegisterType.CONSTANT;
|
||||
@ -246,20 +253,28 @@ public class Registers {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ConstantValue getConstantValue() {
|
||||
return constantValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Program program) {
|
||||
return "const";
|
||||
return "const "+constantValue.toString(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31;
|
||||
return constantValue != null ? constantValue.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof RegisterConstant;
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
RegisterConstant that = (RegisterConstant) o;
|
||||
return constantValue != null ? constantValue.equals(that.constantValue) : that.constantValue == null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class Pass4CodeGeneration {
|
||||
if(! (constantVar.getValue() instanceof ConstantArray || constantVar.getValue() instanceof ConstantString)) {
|
||||
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||
if (asmName != null && !added.contains(asmName)) {
|
||||
asm.addConstant(asmName.replace("#", "_").replace("$", "_"), AsmFragment.getAsmConstant(program, constantVar.getValue(), 99));
|
||||
asm.addConstant(asmName.replace("#", "_").replace("$", "_"), AsmFragment.getAsmConstant(program, constantVar.getValue(), 99, scope));
|
||||
added.add(asmName);
|
||||
}
|
||||
}
|
||||
@ -119,7 +119,7 @@ public class Pass4CodeGeneration {
|
||||
if (asmName != null && !added.contains(asmName)) {
|
||||
List<String> asmElements = new ArrayList<>();
|
||||
for (ConstantValue element : constantArray.getElements()) {
|
||||
String asmElement = AsmFragment.getAsmConstant(program, element, 99);
|
||||
String asmElement = AsmFragment.getAsmConstant(program, element, 99, scope);
|
||||
asmElements.add(asmElement);
|
||||
}
|
||||
if(SymbolTypeBasic.BYTE.equals(constantArray.getElementType())) {
|
||||
|
@ -74,7 +74,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
|
||||
for (ConstantVar constantVar : scope.getAllConstants(false)) {
|
||||
String asmName = constantVar.getAsmName();
|
||||
Registers.Register allocation = new Registers.RegisterConstant();
|
||||
Registers.Register allocation = new Registers.RegisterConstant(constantVar.getValue());
|
||||
if (asmName.contains("#")) {
|
||||
String shortName = asmName.substring(0, asmName.indexOf("#"));
|
||||
if (shortNames.get(shortName) == null || shortNames.get(shortName).equals(allocation)) {
|
||||
|
@ -53,11 +53,6 @@ public class TestErrors extends TestCase {
|
||||
compileAndCompare(filename);
|
||||
}
|
||||
|
||||
public void testCallConstParamProblem() throws IOException, URISyntaxException {
|
||||
String filename = "callconstparamproblem";
|
||||
compileAndCompare(filename);
|
||||
}
|
||||
|
||||
private void compileAndCompare(String filename) throws IOException, URISyntaxException {
|
||||
TestErrors tester = new TestErrors();
|
||||
tester.testFile(filename);
|
||||
|
@ -28,6 +28,12 @@ public class TestPrograms extends TestCase {
|
||||
compileAndCompare("bitmap-bresenham");
|
||||
}
|
||||
|
||||
public void testCallConstParam() throws IOException, URISyntaxException {
|
||||
String filename = "callconstparam";
|
||||
compileAndCompare(filename);
|
||||
}
|
||||
|
||||
|
||||
public void testScrollClobber() throws IOException, URISyntaxException {
|
||||
compileAndCompare("scroll-clobber");
|
||||
}
|
||||
|
@ -93,6 +93,8 @@ void plot(byte x, byte y) {
|
||||
<plotter = plot_xlo[x]+plot_ylo[y];
|
||||
>plotter = plot_xhi[x]+plot_yhi[y];
|
||||
// TODO: <plotter can overflow - and carry must then be added to the >plotter part. Requires new logic?
|
||||
// TODO: New logic needed is 1) word-table lookup (split into two byte-tables) 2) word-addition 3) ALU-capable word-addition
|
||||
|
||||
*plotter = *plotter | plot_bit[x];
|
||||
}
|
||||
|
||||
|
@ -30,18 +30,18 @@ main: {
|
||||
sta D018
|
||||
jsr initscreen
|
||||
jsr initplottables
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
ldx #$a
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
lda #$14
|
||||
sta line.x1
|
||||
jsr line
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
ldx #$28
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
lda #$28
|
||||
sta line.x1
|
||||
@ -51,6 +51,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label xd = 8
|
||||
.label yd = 9
|
||||
.label x = 3
|
||||
|
@ -93,6 +93,8 @@ void plot(byte x, byte y) {
|
||||
<plotter = plot_xlo[x]+plot_ylo[y];
|
||||
>plotter = plot_xhi[x]+plot_yhi[y];
|
||||
// TODO: <plotter can overflow - and carry must then be added to the >plotter part. Requires new logic?
|
||||
// TODO: New logic needed is 1) word-table lookup (split into two byte-tables) 2) word-addition 3) ALU-capable word-addition
|
||||
|
||||
*plotter = *plotter | plot_bit[x];
|
||||
}
|
||||
|
||||
@ -5900,13 +5902,13 @@ main: {
|
||||
//SEG17 [10] phi from main::@2 to line [phi:main::@2->line]
|
||||
line_from_b2:
|
||||
//SEG18 [10] phi (byte) line::y#0 = (const byte) line::y0#0 [phi:main::@2->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
//SEG19 [10] phi (byte) line::y1#2 = (byte) 10 [phi:main::@2->line#1] -- zpby1=coby1
|
||||
lda #$a
|
||||
sta line.y1
|
||||
//SEG20 [10] phi (byte) line::x#0 = (const byte) line::x0#0 [phi:main::@2->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
//SEG21 [10] phi (byte) line::x1#2 = (byte) 20 [phi:main::@2->line#3] -- zpby1=coby1
|
||||
lda #$14
|
||||
@ -5919,13 +5921,13 @@ main: {
|
||||
//SEG24 [10] phi from main::@3 to line [phi:main::@3->line]
|
||||
line_from_b3:
|
||||
//SEG25 [10] phi (byte) line::y#0 = (const byte) line::y0#1 [phi:main::@3->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
//SEG26 [10] phi (byte) line::y1#2 = (byte) 40 [phi:main::@3->line#1] -- zpby1=coby1
|
||||
lda #$28
|
||||
sta line.y1
|
||||
//SEG27 [10] phi (byte) line::x#0 = (const byte) line::x0#1 [phi:main::@3->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
//SEG28 [10] phi (byte) line::x1#2 = (byte) 40 [phi:main::@3->line#3] -- zpby1=coby1
|
||||
lda #$28
|
||||
@ -5941,6 +5943,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label _10 = 20
|
||||
.label xd = 16
|
||||
.label yd = 17
|
||||
@ -6567,12 +6571,12 @@ main: {
|
||||
//SEG17 [10] phi from main::@2 to line [phi:main::@2->line]
|
||||
line_from_b2:
|
||||
//SEG18 [10] phi (byte) line::y#0 = (const byte) line::y0#0 [phi:main::@2->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
//SEG19 [10] phi (byte) line::y1#2 = (byte) 10 [phi:main::@2->line#1] -- xby=coby1
|
||||
ldx #$a
|
||||
//SEG20 [10] phi (byte) line::x#0 = (const byte) line::x0#0 [phi:main::@2->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
//SEG21 [10] phi (byte) line::x1#2 = (byte) 20 [phi:main::@2->line#3] -- zpby1=coby1
|
||||
lda #$14
|
||||
@ -6584,12 +6588,12 @@ main: {
|
||||
//SEG24 [10] phi from main::@3 to line [phi:main::@3->line]
|
||||
line_from_b3:
|
||||
//SEG25 [10] phi (byte) line::y#0 = (const byte) line::y0#1 [phi:main::@3->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
//SEG26 [10] phi (byte) line::y1#2 = (byte) 40 [phi:main::@3->line#1] -- xby=coby1
|
||||
ldx #$28
|
||||
//SEG27 [10] phi (byte) line::x#0 = (const byte) line::x0#1 [phi:main::@3->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
//SEG28 [10] phi (byte) line::x1#2 = (byte) 40 [phi:main::@3->line#3] -- zpby1=coby1
|
||||
lda #$28
|
||||
@ -6604,6 +6608,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label xd = 8
|
||||
.label yd = 9
|
||||
.label x = 3
|
||||
@ -6969,12 +6975,12 @@ main: {
|
||||
//SEG17 [10] phi from main::@2 to line [phi:main::@2->line]
|
||||
line_from_b2:
|
||||
//SEG18 [10] phi (byte) line::y#0 = (const byte) line::y0#0 [phi:main::@2->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
//SEG19 [10] phi (byte) line::y1#2 = (byte) 10 [phi:main::@2->line#1] -- xby=coby1
|
||||
ldx #$a
|
||||
//SEG20 [10] phi (byte) line::x#0 = (const byte) line::x0#0 [phi:main::@2->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
//SEG21 [10] phi (byte) line::x1#2 = (byte) 20 [phi:main::@2->line#3] -- zpby1=coby1
|
||||
lda #$14
|
||||
@ -6986,12 +6992,12 @@ main: {
|
||||
//SEG24 [10] phi from main::@3 to line [phi:main::@3->line]
|
||||
line_from_b3:
|
||||
//SEG25 [10] phi (byte) line::y#0 = (const byte) line::y0#1 [phi:main::@3->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
//SEG26 [10] phi (byte) line::y1#2 = (byte) 40 [phi:main::@3->line#1] -- xby=coby1
|
||||
ldx #$28
|
||||
//SEG27 [10] phi (byte) line::x#0 = (const byte) line::x0#1 [phi:main::@3->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
//SEG28 [10] phi (byte) line::x1#2 = (byte) 40 [phi:main::@3->line#3] -- zpby1=coby1
|
||||
lda #$28
|
||||
@ -7006,6 +7012,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label xd = 8
|
||||
.label yd = 9
|
||||
.label x = 3
|
||||
@ -7387,12 +7395,12 @@ main: {
|
||||
//SEG16 [7] call line param-assignment [ ]
|
||||
//SEG17 [10] phi from main::@2 to line [phi:main::@2->line]
|
||||
//SEG18 [10] phi (byte) line::y#0 = (const byte) line::y0#0 [phi:main::@2->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
//SEG19 [10] phi (byte) line::y1#2 = (byte) 10 [phi:main::@2->line#1] -- xby=coby1
|
||||
ldx #$a
|
||||
//SEG20 [10] phi (byte) line::x#0 = (const byte) line::x0#0 [phi:main::@2->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
//SEG21 [10] phi (byte) line::x1#2 = (byte) 20 [phi:main::@2->line#3] -- zpby1=coby1
|
||||
lda #$14
|
||||
@ -7403,12 +7411,12 @@ main: {
|
||||
//SEG23 [8] call line param-assignment [ ]
|
||||
//SEG24 [10] phi from main::@3 to line [phi:main::@3->line]
|
||||
//SEG25 [10] phi (byte) line::y#0 = (const byte) line::y0#1 [phi:main::@3->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
//SEG26 [10] phi (byte) line::y1#2 = (byte) 40 [phi:main::@3->line#1] -- xby=coby1
|
||||
ldx #$28
|
||||
//SEG27 [10] phi (byte) line::x#0 = (const byte) line::x0#1 [phi:main::@3->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
//SEG28 [10] phi (byte) line::x1#2 = (byte) 40 [phi:main::@3->line#3] -- zpby1=coby1
|
||||
lda #$28
|
||||
@ -7423,6 +7431,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label xd = 8
|
||||
.label yd = 9
|
||||
.label x = 3
|
||||
@ -7783,12 +7793,12 @@ main: {
|
||||
//SEG16 [7] call line param-assignment [ ]
|
||||
//SEG17 [10] phi from main::@2 to line [phi:main::@2->line]
|
||||
//SEG18 [10] phi (byte) line::y#0 = (const byte) line::y0#0 [phi:main::@2->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
//SEG19 [10] phi (byte) line::y1#2 = (byte) 10 [phi:main::@2->line#1] -- xby=coby1
|
||||
ldx #$a
|
||||
//SEG20 [10] phi (byte) line::x#0 = (const byte) line::x0#0 [phi:main::@2->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
//SEG21 [10] phi (byte) line::x1#2 = (byte) 20 [phi:main::@2->line#3] -- zpby1=coby1
|
||||
lda #$14
|
||||
@ -7798,12 +7808,12 @@ main: {
|
||||
//SEG23 [8] call line param-assignment [ ]
|
||||
//SEG24 [10] phi from main::@3 to line [phi:main::@3->line]
|
||||
//SEG25 [10] phi (byte) line::y#0 = (const byte) line::y0#1 [phi:main::@3->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
//SEG26 [10] phi (byte) line::y1#2 = (byte) 40 [phi:main::@3->line#1] -- xby=coby1
|
||||
ldx #$28
|
||||
//SEG27 [10] phi (byte) line::x#0 = (const byte) line::x0#1 [phi:main::@3->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
//SEG28 [10] phi (byte) line::x1#2 = (byte) 40 [phi:main::@3->line#3] -- zpby1=coby1
|
||||
lda #$28
|
||||
@ -7817,6 +7827,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label xd = 8
|
||||
.label yd = 9
|
||||
.label x = 3
|
||||
@ -8150,12 +8162,12 @@ main: {
|
||||
//SEG16 [7] call line param-assignment [ ]
|
||||
//SEG17 [10] phi from main::@2 to line [phi:main::@2->line]
|
||||
//SEG18 [10] phi (byte) line::y#0 = (const byte) line::y0#0 [phi:main::@2->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
//SEG19 [10] phi (byte) line::y1#2 = (byte) 10 [phi:main::@2->line#1] -- xby=coby1
|
||||
ldx #$a
|
||||
//SEG20 [10] phi (byte) line::x#0 = (const byte) line::x0#0 [phi:main::@2->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
//SEG21 [10] phi (byte) line::x1#2 = (byte) 20 [phi:main::@2->line#3] -- zpby1=coby1
|
||||
lda #$14
|
||||
@ -8165,12 +8177,12 @@ main: {
|
||||
//SEG23 [8] call line param-assignment [ ]
|
||||
//SEG24 [10] phi from main::@3 to line [phi:main::@3->line]
|
||||
//SEG25 [10] phi (byte) line::y#0 = (const byte) line::y0#1 [phi:main::@3->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
//SEG26 [10] phi (byte) line::y1#2 = (byte) 40 [phi:main::@3->line#1] -- xby=coby1
|
||||
ldx #$28
|
||||
//SEG27 [10] phi (byte) line::x#0 = (const byte) line::x0#1 [phi:main::@3->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
//SEG28 [10] phi (byte) line::x1#2 = (byte) 40 [phi:main::@3->line#3] -- zpby1=coby1
|
||||
lda #$28
|
||||
@ -8184,6 +8196,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label xd = 8
|
||||
.label yd = 9
|
||||
.label x = 3
|
||||
@ -8549,7 +8563,7 @@ FINAL SYMBOL TABLE
|
||||
(byte) line::x#2 x zp ZP_BYTE:3 8.75
|
||||
(byte) line::x0
|
||||
(const byte) line::x0#0 x0 = (byte) 0
|
||||
(const byte) line::x0#1 x0 = (byte) 10
|
||||
(const byte) line::x0#1 x0#1 = (byte) 10
|
||||
(byte) line::x1
|
||||
(byte) line::x1#2 x1 zp ZP_BYTE:2 0.8125
|
||||
(byte) line::xd
|
||||
@ -8561,7 +8575,7 @@ FINAL SYMBOL TABLE
|
||||
(byte) line::y#4 y zp ZP_BYTE:4 11.0
|
||||
(byte) line::y0
|
||||
(const byte) line::y0#0 y0 = (byte) 0
|
||||
(const byte) line::y0#1 y0 = (byte) 20
|
||||
(const byte) line::y0#1 y0#1 = (byte) 20
|
||||
(byte) line::y1
|
||||
(byte) line::y1#2 reg byte x 1.0
|
||||
(byte) line::yd
|
||||
@ -8679,12 +8693,12 @@ main: {
|
||||
//SEG16 [7] call line param-assignment [ ]
|
||||
//SEG17 [10] phi from main::@2 to line [phi:main::@2->line]
|
||||
//SEG18 [10] phi (byte) line::y#0 = (const byte) line::y0#0 [phi:main::@2->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0
|
||||
sta line.y
|
||||
//SEG19 [10] phi (byte) line::y1#2 = (byte) 10 [phi:main::@2->line#1] -- xby=coby1
|
||||
ldx #$a
|
||||
//SEG20 [10] phi (byte) line::x#0 = (const byte) line::x0#0 [phi:main::@2->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0
|
||||
sta line.x
|
||||
//SEG21 [10] phi (byte) line::x1#2 = (byte) 20 [phi:main::@2->line#3] -- zpby1=coby1
|
||||
lda #$14
|
||||
@ -8694,12 +8708,12 @@ main: {
|
||||
//SEG23 [8] call line param-assignment [ ]
|
||||
//SEG24 [10] phi from main::@3 to line [phi:main::@3->line]
|
||||
//SEG25 [10] phi (byte) line::y#0 = (const byte) line::y0#1 [phi:main::@3->line#0] -- zpby1=coby1
|
||||
lda #y0
|
||||
lda #line.y0_1
|
||||
sta line.y
|
||||
//SEG26 [10] phi (byte) line::y1#2 = (byte) 40 [phi:main::@3->line#1] -- xby=coby1
|
||||
ldx #$28
|
||||
//SEG27 [10] phi (byte) line::x#0 = (const byte) line::x0#1 [phi:main::@3->line#2] -- zpby1=coby1
|
||||
lda #x0
|
||||
lda #line.x0_1
|
||||
sta line.x
|
||||
//SEG28 [10] phi (byte) line::x1#2 = (byte) 40 [phi:main::@3->line#3] -- zpby1=coby1
|
||||
lda #$28
|
||||
@ -8713,6 +8727,8 @@ main: {
|
||||
line: {
|
||||
.const x0 = 0
|
||||
.const y0 = 0
|
||||
.const x0_1 = $a
|
||||
.const y0_1 = $14
|
||||
.label xd = 8
|
||||
.label yd = 9
|
||||
.label x = 3
|
||||
|
@ -90,7 +90,7 @@
|
||||
(byte) line::x#2 x zp ZP_BYTE:3 8.75
|
||||
(byte) line::x0
|
||||
(const byte) line::x0#0 x0 = (byte) 0
|
||||
(const byte) line::x0#1 x0 = (byte) 10
|
||||
(const byte) line::x0#1 x0#1 = (byte) 10
|
||||
(byte) line::x1
|
||||
(byte) line::x1#2 x1 zp ZP_BYTE:2 0.8125
|
||||
(byte) line::xd
|
||||
@ -102,7 +102,7 @@
|
||||
(byte) line::y#4 y zp ZP_BYTE:4 11.0
|
||||
(byte) line::y0
|
||||
(const byte) line::y0#0 y0 = (byte) 0
|
||||
(const byte) line::y0#1 y0 = (byte) 20
|
||||
(const byte) line::y0#1 y0#1 = (byte) 20
|
||||
(byte) line::y1
|
||||
(byte) line::y1#2 reg byte x 1.0
|
||||
(byte) line::yd
|
||||
|
34
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.asm
Normal file
34
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.asm
Normal file
@ -0,0 +1,34 @@
|
||||
.label screen = 3
|
||||
jsr main
|
||||
main: {
|
||||
lda #2
|
||||
sta line.x1
|
||||
lda #<$400
|
||||
sta screen
|
||||
lda #>$400
|
||||
sta screen+1
|
||||
ldx #line.x0
|
||||
jsr line
|
||||
lda #5
|
||||
sta line.x1
|
||||
ldx #line.x0_1
|
||||
jsr line
|
||||
rts
|
||||
}
|
||||
line: {
|
||||
.const x0 = 1
|
||||
.const x0_1 = 3
|
||||
.label x1 = 2
|
||||
b1:
|
||||
txa
|
||||
ldy #0
|
||||
sta (screen),y
|
||||
inc screen
|
||||
bne !+
|
||||
inc screen+1
|
||||
!:
|
||||
inx
|
||||
cpx x1
|
||||
bcc b1
|
||||
rts
|
||||
}
|
30
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.cfg
Normal file
30
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.cfg
Normal file
@ -0,0 +1,30 @@
|
||||
@begin: scope:[] from
|
||||
[0] call main param-assignment [ ]
|
||||
to:@end
|
||||
@end: scope:[] from @begin
|
||||
main: scope:[main] from @begin
|
||||
[1] phi() [ ]
|
||||
[2] call line param-assignment [ ]
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main
|
||||
[3] call line param-assignment [ ]
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[4] return [ ]
|
||||
to:@return
|
||||
line: scope:[line] from main main::@1
|
||||
[5] (byte) line::x1#2 ← phi( main/(byte) 2 main::@1/(byte) 5 ) [ line::x#0 screen#14 line::x1#2 ]
|
||||
[5] (byte*) screen#14 ← phi( main/(word) 1024 main::@1/(byte*) screen#1 ) [ line::x#0 screen#14 line::x1#2 ]
|
||||
[5] (byte) line::x#0 ← phi( main/(const byte) line::x0#0 main::@1/(const byte) line::x0#1 ) [ line::x#0 screen#14 line::x1#2 ]
|
||||
to:line::@1
|
||||
line::@1: scope:[line] from line line::@1
|
||||
[6] (byte*) screen#11 ← phi( line/(byte*) screen#14 line::@1/(byte*) screen#1 ) [ line::x1#2 line::x#2 screen#11 ]
|
||||
[6] (byte) line::x#2 ← phi( line/(byte) line::x#0 line::@1/(byte) line::x#1 ) [ line::x1#2 line::x#2 screen#11 ]
|
||||
[7] *((byte*) screen#11) ← (byte) line::x#2 [ line::x1#2 line::x#2 screen#11 ]
|
||||
[8] (byte*) screen#1 ← ++ (byte*) screen#11 [ line::x1#2 line::x#2 screen#1 ]
|
||||
[9] (byte) line::x#1 ← ++ (byte) line::x#2 [ line::x1#2 line::x#1 screen#1 ]
|
||||
[10] if((byte) line::x#1<(byte) line::x1#2) goto line::@1 [ line::x1#2 line::x#1 screen#1 ]
|
||||
to:line::@return
|
||||
line::@return: scope:[line] from line::@1
|
||||
[11] return [ ]
|
||||
to:@return
|
1241
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.log
Normal file
1241
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.log
Normal file
File diff suppressed because it is too large
Load Diff
25
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.sym
Normal file
25
src/main/java/dk/camelot64/kickc/test/ref/callconstparam.sym
Normal file
@ -0,0 +1,25 @@
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) line((byte) line::x0 , (byte) line::x1)
|
||||
(label) line::@1
|
||||
(label) line::@return
|
||||
(byte) line::x
|
||||
(byte) line::x#0 reg byte x 2.0
|
||||
(byte) line::x#1 reg byte x 16.5
|
||||
(byte) line::x#2 reg byte x 11.666666666666666
|
||||
(byte) line::x0
|
||||
(const byte) line::x0#0 x0 = (byte) 1
|
||||
(const byte) line::x0#1 x0#1 = (byte) 3
|
||||
(byte) line::x1
|
||||
(byte) line::x1#2 x1 zp ZP_BYTE:2 1.8333333333333333
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte*) screen
|
||||
(byte*) screen#1 screen zp ZP_PTR_BYTE:3 8.0
|
||||
(byte*) screen#11 screen zp ZP_PTR_BYTE:3 17.5
|
||||
(byte*) screen#14 screen zp ZP_PTR_BYTE:3 4.0
|
||||
|
||||
zp ZP_BYTE:2 [ line::x1#2 ]
|
||||
reg byte x [ line::x#2 line::x#0 line::x#1 ]
|
||||
zp ZP_PTR_BYTE:3 [ screen#11 screen#14 screen#1 ]
|
Loading…
x
Reference in New Issue
Block a user