mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-25 11:32:07 +00:00
Implemented syntax for composing word from two bytes word w = { b1, b2 };
Optimizer still needs to attempt to (and allow) placing the two byte variables directly at the lo/hi-vars of the word wo minimize moving data around. Closes #37
This commit is contained in:
parent
bd3c26b5ec
commit
e3353acbc9
@ -105,24 +105,26 @@ public class Compiler {
|
||||
}
|
||||
|
||||
private Program pass1GenerateSSA() {
|
||||
|
||||
new Pass1FixLvalueLoHi(program).execute();
|
||||
new Pass1TypeInference(program).execute();
|
||||
|
||||
getLog().append("PROGRAM");
|
||||
getLog().append(program.getStatementSequence().toString(program));
|
||||
getLog().append("SYMBOLS");
|
||||
getLog().append(program.getScope().getSymbolTableContents(program));
|
||||
new Pass1GenerateControlFlowGraph(program).execute();
|
||||
|
||||
new Pass1GenerateControlFlowGraph(program).execute();
|
||||
new Pass1AddTypePromotions(program).execute();
|
||||
|
||||
getLog().append("INITIAL CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
|
||||
new Pass1AssertReturn(program).execute();
|
||||
new Pass1AssertUsedVars(program).execute();
|
||||
new Pass1ExtractInlineStrings(program).execute();
|
||||
new Pass1EliminateUncalledProcedures(program).execute();
|
||||
new Pass1EliminateUnusedVars(program).execute();
|
||||
new Pass1ExtractInlineStrings(program).execute();
|
||||
new Pass1FixWordConstructors(program).execute();
|
||||
|
||||
new Pass1EliminateEmptyBlocks(program).execute();
|
||||
getLog().append("CONTROL FLOW GRAPH");
|
||||
|
@ -146,6 +146,7 @@ public class AsmFragmentManager {
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_vbuz1", ".*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2_vbuaa", null, mapZ));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_vbsz1", ".*=.*aa.*|.*z1.*z1.*", "lda {z1}\n", "$1=$2_vbsaa", null, mapZ));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_vbuz2", ".*=.*aa.*|.*z2.*z2.*", "lda {z2}\n", "$1=$2_vbuaa", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_vbuz3", ".*=.*aa.*|.*z3.*z3.*", "lda {z3}\n", "$1=$2_vbuaa", null, null));
|
||||
|
||||
synths.add(new FragmentSynthesis("vbuz1=vbuz1(.*)", ".*=.*vb.aa.*|.*z1.*z1.*z1.*", "lda {z1}\n", "vbuaa=vbuaa$1", "sta {z1}\n", mapZ));
|
||||
synths.add(new FragmentSynthesis("vbsz1=vbsz1(.*)", ".*=.*vb.aa.*|.*z1.*z1.*z1.*", "lda {z1}\n", "vbsaa=vbsaa$1", "sta {z1}\n", mapZ));
|
||||
|
@ -0,0 +1,2 @@
|
||||
sta {z1}
|
||||
sta {z1}+1
|
@ -0,0 +1,2 @@
|
||||
sta {z1}+1
|
||||
stx {z1}
|
@ -0,0 +1,2 @@
|
||||
sta {z1}+1
|
||||
sty {z1}
|
@ -0,0 +1,3 @@
|
||||
sta {z1}+1
|
||||
lda {z2}
|
||||
sta {z1}
|
@ -0,0 +1,2 @@
|
||||
stx {z1}+1
|
||||
sta {z1}
|
@ -0,0 +1,2 @@
|
||||
stx {z1}+1
|
||||
sty {z1}
|
@ -0,0 +1,2 @@
|
||||
sty {z1}+1
|
||||
sta {z1}
|
@ -0,0 +1,2 @@
|
||||
sty {z1}+1
|
||||
stx {z1}
|
@ -0,0 +1,3 @@
|
||||
sta {z1}
|
||||
lda {z2}
|
||||
sta {z1}+1
|
@ -120,8 +120,7 @@ public class Operator {
|
||||
public static final Operator BOOL_NOT = new Operator("~", "_not_", Type.UNARY, 2);
|
||||
public static final Operator NOT = new Operator("!", "_not_", Type.UNARY, 2);
|
||||
public static final Operator DEREF = new Operator("*", "_deref_", Type.UNARY, 2);
|
||||
public static final Operator LOWBYTE = new Operator("<", "_lo_", Type.UNARY, 2);
|
||||
public static final Operator HIBYTE = new Operator(">", "_hi_", Type.UNARY, 2);
|
||||
public static final Operator WORD = new Operator("w=", "_word_", Type.BINARY, 2);
|
||||
public static final Operator DEREF_IDX = new Operator("*idx", "_derefidx_", Type.BINARY, 2);
|
||||
public static final Operator SET_LOWBYTE = new Operator("lo=", "_setlo_", Type.BINARY, 2);
|
||||
public static final Operator SET_HIBYTE = new Operator("hi=", "_sethi_", Type.BINARY, 2);
|
||||
@ -136,17 +135,19 @@ public class Operator {
|
||||
public static final Operator MINUS = new Operator("-", "_minus_", Type.BINARY, 4);
|
||||
public static final Operator SHIFT_LEFT = new Operator("<<", "_rol_", Type.BINARY, 5);
|
||||
public static final Operator SHIFT_RIGHT = new Operator(">>", "_ror_", Type.BINARY, 5);
|
||||
public static final Operator LT = new Operator("<", "_lt_", Type.BINARY, 6);
|
||||
public static final Operator LE = new Operator("<=", "_le_", Type.BINARY, 6);
|
||||
public static final Operator GT = new Operator(">", "_gt_", Type.BINARY, 6);
|
||||
public static final Operator GE = new Operator(">=", "_ge_", Type.BINARY, 6);
|
||||
public static final Operator EQ = new Operator("==", "_eq_", Type.BINARY, 7);
|
||||
public static final Operator NEQ = new Operator("!=", "_neq_", Type.BINARY, 7);
|
||||
public static final Operator BOOL_AND = new Operator("&", "_band_", Type.BINARY, 8);
|
||||
public static final Operator BOOL_XOR = new Operator("^", "_bxor_", Type.BINARY, 9);
|
||||
public static final Operator BOOL_OR = new Operator("|", "_bor_", Type.BINARY, 10);
|
||||
public static final Operator LOGIC_AND = new Operator("&&", "_and_", Type.BINARY, 11);
|
||||
public static final Operator LOGIC_OR = new Operator("||", "_or_", Type.BINARY, 12);
|
||||
public static final Operator LOWBYTE = new Operator("<", "_lo_", Type.UNARY, 6);
|
||||
public static final Operator HIBYTE = new Operator(">", "_hi_", Type.UNARY, 6);
|
||||
public static final Operator LT = new Operator("<", "_lt_", Type.BINARY, 7);
|
||||
public static final Operator LE = new Operator("<=", "_le_", Type.BINARY, 7);
|
||||
public static final Operator GT = new Operator(">", "_gt_", Type.BINARY, 7);
|
||||
public static final Operator GE = new Operator(">=", "_ge_", Type.BINARY, 7);
|
||||
public static final Operator EQ = new Operator("==", "_eq_", Type.BINARY, 8);
|
||||
public static final Operator NEQ = new Operator("!=", "_neq_", Type.BINARY, 8);
|
||||
public static final Operator BOOL_AND = new Operator("&", "_band_", Type.BINARY, 9);
|
||||
public static final Operator BOOL_XOR = new Operator("^", "_bxor_", Type.BINARY, 10);
|
||||
public static final Operator BOOL_OR = new Operator("|", "_bor_", Type.BINARY, 11);
|
||||
public static final Operator LOGIC_AND = new Operator("&&", "_and_", Type.BINARY, 12);
|
||||
public static final Operator LOGIC_OR = new Operator("||", "_or_", Type.BINARY, 13);
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
|
@ -67,11 +67,11 @@ public class SymbolTypeInference {
|
||||
throw new RuntimeException("Type error: Dereferencing a non-pointer " + subType);
|
||||
}
|
||||
} else if (Operator.LOWBYTE.equals(operator)) {
|
||||
if (subType instanceof SymbolTypePointer || SymbolType.WORD.equals(subType) || SymbolType.WORD.equals(subType)) {
|
||||
if (subType instanceof SymbolTypePointer || SymbolType.isWord(subType) || SymbolType.isSWord(subType)) {
|
||||
return SymbolType.BYTE;
|
||||
}
|
||||
} else if (Operator.HIBYTE.equals(operator)) {
|
||||
if (subType instanceof SymbolTypePointer || SymbolType.WORD.equals(subType) || SymbolType.SWORD.equals(subType)) {
|
||||
if (subType instanceof SymbolTypePointer || SymbolType.isWord(subType) || SymbolType.isSWord(subType) ) {
|
||||
return SymbolType.BYTE;
|
||||
}
|
||||
} else if (Operator.CAST_BYTE.equals(operator)) {
|
||||
@ -98,6 +98,8 @@ public class SymbolTypeInference {
|
||||
return type1;
|
||||
} else if (Operator.SET_LOWBYTE.equals(operator)) {
|
||||
return type1;
|
||||
} else if (Operator.WORD.equals(operator)) {
|
||||
return SymbolType.WORD;
|
||||
}
|
||||
|
||||
String op = operator.getOperator();
|
||||
|
@ -83,11 +83,12 @@ expr
|
||||
| '(' typeDecl ')' expr #exprCast
|
||||
| expr '[' expr ']' #exprArray
|
||||
| ('--' | '++' ) expr #exprPreMod
|
||||
| expr ('--' | '++' )#exprPostMod
|
||||
| ('+' | '-' | '!' | '&' | '*' | '~' | '<' | '>') expr #exprUnary
|
||||
| expr ('--' | '++' ) #exprPostMod
|
||||
| ('+' | '-' | '!' | '&' | '*' | '~') expr #exprUnary
|
||||
| expr ('>>' | '<<' ) expr #exprBinary
|
||||
| expr ('*' | '/' | '%' ) expr #exprBinary
|
||||
| expr ( '+' | '-') expr #exprBinary
|
||||
| ('<' | '>') expr #exprUnary
|
||||
| expr ( '==' | '!=' | '<>' | '<' | '<=' | '=<' | '>=' | '=>' | '>' ) expr #exprBinary
|
||||
| expr ( '&' ) expr #exprBinary
|
||||
| expr ( '^' ) expr #exprBinary
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Generated from C:/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.parser;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Generated from C:/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.parser;
|
||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Generated from C:/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.parser;
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Generated from C:/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.parser;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
// Generated from C:/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.parser;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||
|
||||
|
@ -5,7 +5,7 @@ import dk.camelot64.kickc.model.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Eliminate uncalled methods
|
||||
* All inline strings in the code are extracted into constants.
|
||||
*/
|
||||
public class Pass1ExtractInlineStrings extends Pass1Base {
|
||||
|
||||
@ -22,43 +22,44 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
|
||||
Statement statement = stmtIt.next();
|
||||
if (statement instanceof StatementCall) {
|
||||
StatementCall call = (StatementCall) statement;
|
||||
ListIterator<RValue> parIt = call.getParameters().listIterator();
|
||||
int parNum = 0;
|
||||
while (parIt.hasNext()) {
|
||||
RValue parameter = parIt.next();
|
||||
if (parameter instanceof ConstantString) {
|
||||
Procedure procedure = getProgram().getScope().getProcedure(call.getProcedure());
|
||||
String parameterName = procedure.getParameterNames().get(parNum);
|
||||
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) parameter, parameterName);
|
||||
parIt.set(strConst.getRef());
|
||||
}
|
||||
parNum++;
|
||||
Procedure procedure = getProgram().getScope().getProcedure(call.getProcedure());
|
||||
List<RValue> parameters = call.getParameters();
|
||||
int size = parameters.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
String parameterName = procedure.getParameterNames().get(i);
|
||||
execute(new VariableReplacer.ReplacableCallParameter(call, i), blockScope, parameterName);
|
||||
}
|
||||
} else if (statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if(assignment.getrValue1() instanceof ConstantString && assignment.getrValue2() instanceof ConstantString) {
|
||||
if(assignment.getrValue1()==null && assignment.getOperator()==null && assignment.getrValue2() instanceof ConstantString) {
|
||||
// This will be picked up later as a constant - the temporary constant variable is not needed
|
||||
continue;
|
||||
}
|
||||
if (assignment.getrValue1() instanceof ConstantString) {
|
||||
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) assignment.getrValue1(), null);
|
||||
assignment.setrValue1(strConst.getRef());
|
||||
}
|
||||
if (assignment.getrValue2() instanceof ConstantString && assignment.getOperator() != null) {
|
||||
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) assignment.getrValue2(), null);
|
||||
assignment.setrValue2(strConst.getRef());
|
||||
if(assignment.getrValue1() instanceof ConstantString && assignment.getrValue2() instanceof ConstantString) {
|
||||
// This will be picked up later as a constant - the temporary constant variable is not needed
|
||||
continue;
|
||||
}
|
||||
execute(new VariableReplacer.ReplacableRValue1(assignment), blockScope, null);
|
||||
execute(new VariableReplacer.ReplacableRValue2(assignment), blockScope, null);
|
||||
} else if (statement instanceof StatementReturn) {
|
||||
StatementReturn statementReturn = (StatementReturn) statement;
|
||||
if (statementReturn.getValue() instanceof ConstantString) {
|
||||
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) statementReturn.getValue(), null);
|
||||
statementReturn.setValue(strConst.getRef());
|
||||
}
|
||||
execute(new VariableReplacer.ReplacableReturn((StatementReturn) statement), blockScope, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void execute(VariableReplacer.ReplacableValue replacable, Scope blockScope, String nameHint) {
|
||||
RValue value = replacable.get();
|
||||
if(value instanceof ConstantString) {
|
||||
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) replacable.get(), nameHint);
|
||||
replacable.set(strConst.getRef());
|
||||
}
|
||||
for (VariableReplacer.ReplacableValue subValue : replacable.getSubValues()) {
|
||||
execute(subValue, blockScope, nameHint);
|
||||
}
|
||||
}
|
||||
|
||||
private ConstantVar createStringConstantVar(Scope blockScope, ConstantString constantString, String nameHint) {
|
||||
String name;
|
||||
if (nameHint == null) {
|
||||
|
@ -0,0 +1,46 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
|
||||
/**
|
||||
* The syntax for word constructors <code>word w = { b1, b2 };</code>
|
||||
* is turned into a binary operator <code>word w = b1 _toword_ b2 ;</code>
|
||||
*/
|
||||
public class Pass1FixWordConstructors extends Pass1Base {
|
||||
|
||||
public Pass1FixWordConstructors(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean executeStep() {
|
||||
ProgramScope programScope = getProgram().getScope();
|
||||
for (ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
for (Statement statement : block.getStatements()) {
|
||||
if (statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
if(assignment.getrValue1()==null && assignment.getOperator()==null) {
|
||||
if(assignment.getrValue2() instanceof ValueList) {
|
||||
ValueList list = (ValueList) assignment.getrValue2();
|
||||
if(list.getList().size()==2) {
|
||||
// We have a simple assignment of a length 2 value list to a variable
|
||||
SymbolType lType = SymbolTypeInference.inferType(programScope, assignment.getlValue());
|
||||
SymbolType elmType1 = SymbolTypeInference.inferType(programScope, list.getList().get(0));
|
||||
SymbolType elmType2 = SymbolTypeInference.inferType(programScope, list.getList().get(1));
|
||||
if(SymbolType.isWord(lType) && SymbolType.isByte(elmType1) && SymbolType.isByte(elmType2)) {
|
||||
// Types are word = { byte, byte } - perform the modification
|
||||
assignment.setrValue1(list.getList().get(0));
|
||||
assignment.setOperator(Operator.WORD);
|
||||
assignment.setrValue2(list.getList().get(1));
|
||||
getLog().append("Fixing word constructor with " + assignment.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -106,11 +106,18 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
||||
*/
|
||||
private Map<ConstantRef, ConstantValue> findAliasConstants() {
|
||||
Map<ConstantRef, ConstantValue> aliases = new HashMap<>();
|
||||
Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true);
|
||||
ProgramScope programScope = getProgram().getScope();
|
||||
Collection<ConstantVar> allConstants = programScope.getAllConstants(true);
|
||||
for (ConstantVar constant : allConstants) {
|
||||
ConstantValue constantValue = constant.getValue();
|
||||
if(constantValue instanceof ConstantRef) {
|
||||
aliases.put(constant.getRef(), constant.getValue());
|
||||
if(((ConstantRef) constantValue).isIntermediate()) {
|
||||
// The value is an intermediate constant - replace all uses of the intermediate with uses of the referer instead.
|
||||
aliases.put((ConstantRef) constant.getValue(), constant.getRef());
|
||||
constant.setValue(programScope.getConstant((ConstantRef) constantValue).getValue());
|
||||
} else {
|
||||
aliases.put(constant.getRef(), constant.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return aliases;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const byte* SCREEN = $400;
|
||||
|
||||
void main() {
|
||||
byte[] his = { >SCREEN, >SCREEN+1 };
|
||||
byte[] his = { >SCREEN, >SCREEN+$100 };
|
||||
for( byte h: 0..1) {
|
||||
for (byte l: 4..7) {
|
||||
word w = { his[h], l };
|
||||
|
@ -105,10 +105,10 @@ print::@return: scope:[print] from print::@3
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
Creating constant string variable for inline (const byte[]) main::msg "message 3 @"
|
||||
Eliminating unused variable - keeping the call (void~) main::$0
|
||||
Eliminating unused variable - keeping the call (void~) main::$1
|
||||
Eliminating unused variable - keeping the call (void~) main::$2
|
||||
Creating constant string variable for inline (const byte[]) main::msg "message 3 @"
|
||||
Removing empty block print::@4
|
||||
Removing empty block print::@3
|
||||
Removing empty block print::@5
|
||||
|
34
src/main/java/dk/camelot64/kickc/test/ref/inline-word.asm
Normal file
34
src/main/java/dk/camelot64/kickc/test/ref/inline-word.asm
Normal file
@ -0,0 +1,34 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SCREEN = $400
|
||||
jsr main
|
||||
main: {
|
||||
.label w = 3
|
||||
.label sc = 5
|
||||
.label l = 2
|
||||
ldx #0
|
||||
b1:
|
||||
lda #4
|
||||
sta l
|
||||
b2:
|
||||
lda his,x
|
||||
sta w+1
|
||||
lda l
|
||||
sta w
|
||||
sta sc
|
||||
lda w+1
|
||||
sta sc+1
|
||||
ldy #0
|
||||
lda #'*'
|
||||
sta (sc),y
|
||||
inc l
|
||||
lda l
|
||||
cmp #8
|
||||
bne b2
|
||||
inx
|
||||
cpx #2
|
||||
bne b1
|
||||
rts
|
||||
his: .byte >SCREEN, >SCREEN+$100
|
||||
}
|
31
src/main/java/dk/camelot64/kickc/test/ref/inline-word.cfg
Normal file
31
src/main/java/dk/camelot64/kickc/test/ref/inline-word.cfg
Normal file
@ -0,0 +1,31 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main param-assignment [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
[5] (byte) main::h#4 ← phi( main/(byte/signed byte/word/signed word) 0 main::@3/(byte) main::h#1 ) [ main::h#4 ] ( main:2 [ main::h#4 ] )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1 main::@2
|
||||
[6] (byte) main::l#2 ← phi( main::@1/(byte/signed byte/word/signed word) 4 main::@2/(byte) main::l#1 ) [ main::h#4 main::l#2 ] ( main:2 [ main::h#4 main::l#2 ] )
|
||||
[7] (byte~) main::$3 ← (const byte[]) main::his#0 *idx (byte) main::h#4 [ main::h#4 main::l#2 main::$3 ] ( main:2 [ main::h#4 main::l#2 main::$3 ] )
|
||||
[8] (word) main::w#0 ← (byte~) main::$3 w= (byte) main::l#2 [ main::h#4 main::l#2 main::w#0 ] ( main:2 [ main::h#4 main::l#2 main::w#0 ] )
|
||||
[9] (byte*) main::sc#0 ← ((byte*)) (word) main::w#0 [ main::h#4 main::l#2 main::sc#0 ] ( main:2 [ main::h#4 main::l#2 main::sc#0 ] )
|
||||
[10] *((byte*) main::sc#0) ← (byte) '*' [ main::h#4 main::l#2 ] ( main:2 [ main::h#4 main::l#2 ] )
|
||||
[11] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::h#4 main::l#1 ] ( main:2 [ main::h#4 main::l#1 ] )
|
||||
[12] if((byte) main::l#1!=(byte/signed byte/word/signed word) 8) goto main::@2 [ main::h#4 main::l#1 ] ( main:2 [ main::h#4 main::l#1 ] )
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2
|
||||
[13] (byte) main::h#1 ← ++ (byte) main::h#4 [ main::h#1 ] ( main:2 [ main::h#1 ] )
|
||||
[14] if((byte) main::h#1!=(byte/signed byte/word/signed word) 2) goto main::@1 [ main::h#1 ] ( main:2 [ main::h#1 ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[15] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
1652
src/main/java/dk/camelot64/kickc/test/ref/inline-word.log
Normal file
1652
src/main/java/dk/camelot64/kickc/test/ref/inline-word.log
Normal file
File diff suppressed because it is too large
Load Diff
29
src/main/java/dk/camelot64/kickc/test/ref/inline-word.sym
Normal file
29
src/main/java/dk/camelot64/kickc/test/ref/inline-word.sym
Normal file
@ -0,0 +1,29 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) SCREEN
|
||||
(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word) 1024
|
||||
(void()) main()
|
||||
(byte~) main::$3 reg byte a 202.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@return
|
||||
(byte) main::h
|
||||
(byte) main::h#1 reg byte x 16.5
|
||||
(byte) main::h#4 reg byte x 15.375
|
||||
(byte[]) main::his
|
||||
(const byte[]) main::his#0 his = { >(const byte*) SCREEN#0, >(const byte*) SCREEN#0+(word/signed word) 256 }
|
||||
(byte) main::l
|
||||
(byte) main::l#1 l zp ZP_BYTE:2 151.5
|
||||
(byte) main::l#2 l zp ZP_BYTE:2 60.599999999999994
|
||||
(byte*) main::sc
|
||||
(byte*) main::sc#0 sc zp ZP_WORD:5 202.0
|
||||
(word) main::w
|
||||
(word) main::w#0 w zp ZP_WORD:3 202.0
|
||||
|
||||
reg byte x [ main::h#4 main::h#1 ]
|
||||
zp ZP_BYTE:2 [ main::l#2 main::l#1 ]
|
||||
reg byte a [ main::$3 ]
|
||||
zp ZP_WORD:3 [ main::w#0 ]
|
||||
zp ZP_WORD:5 [ main::sc#0 ]
|
Loading…
Reference in New Issue
Block a user