1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-27 09:31:18 +00:00

Moved stack call parameter assignments out of pass 0. Added address-of handling for procedures converting them to stack call if they have parameters. #121

This commit is contained in:
jespergravgaard 2021-05-16 10:19:21 +02:00
parent 55e5e6bca2
commit f14dfe4252
25 changed files with 136 additions and 60 deletions

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.symbols;
import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.types.SymbolTypeProcedure;
import dk.camelot64.kickc.model.values.ProcedureRef; import dk.camelot64.kickc.model.values.ProcedureRef;
@ -38,6 +39,8 @@ public class Procedure extends Scope {
private final List<ProcedureRef> constructorRefs; private final List<ProcedureRef> constructorRefs;
/** Is this procedure declared as a constructor procedure. */ /** Is this procedure declared as a constructor procedure. */
private boolean isConstructor; private boolean isConstructor;
/** The source of the procedure definition. */
private StatementSource definitionSource;
/** The names of all legal intrinsic procedures. */ /** The names of all legal intrinsic procedures. */
final public static List<String> INTRINSIC_PROCEDURES = Arrays.asList( final public static List<String> INTRINSIC_PROCEDURES = Arrays.asList(
@ -93,6 +96,14 @@ public class Procedure extends Scope {
this.isConstructor = false; this.isConstructor = false;
} }
public StatementSource getDefinitionSource() {
return definitionSource;
}
public void setDefinitionSource(StatementSource definitionSource) {
this.definitionSource = definitionSource;
}
public CallingConvention getCallingConvention() { public CallingConvention getCallingConvention() {
return callingConvention; return callingConvention;
} }

View File

@ -405,12 +405,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
// Add the body // Add the body
addStatement(new StatementProcedureBegin(procedure.getRef(), StatementSource.procedureBegin(ctx), Comment.NO_COMMENTS)); addStatement(new StatementProcedureBegin(procedure.getRef(), StatementSource.procedureBegin(ctx), Comment.NO_COMMENTS));
// Add parameter assignments
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
for(Variable param : procedure.getParameters()) {
addStatement(new StatementAssignment((LValue) param.getRef(), new ParamValue((VariableRef) param.getRef()), true, StatementSource.procedureEnd(ctx), Comment.NO_COMMENTS));
}
}
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME); Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
if(ctx.stmtSeq() != null) { if(ctx.stmtSeq() != null) {
this.visit(ctx.stmtSeq()); this.visit(ctx.stmtSeq());
@ -471,9 +466,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} }
if(defineProcedure) { if(defineProcedure) {
// Make sure comments and directives are from the definition // Make sure comments, directives and source are from the definition
addDirectives(procedure, varDecl.getDeclDirectives(), statementSource); addDirectives(procedure, varDecl.getDeclDirectives(), statementSource);
procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx))); procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx)));
procedure.setDefinitionSource(statementSource);
// enter the procedure // enter the procedure
scopeStack.push(procedure); scopeStack.push(procedure);
// Add parameter variables... // Add parameter variables...

View File

@ -5,13 +5,15 @@ import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary; import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeStruct; import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.ConstantSymbolPointer; import dk.camelot64.kickc.model.values.ConstantSymbolPointer;
import dk.camelot64.kickc.model.values.RValue; import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.SymbolVariableRef; import dk.camelot64.kickc.model.values.SymbolRef;
import dk.camelot64.kickc.model.values.Value; import dk.camelot64.kickc.model.values.Value;
/** /**
@ -29,51 +31,56 @@ public class Pass1AddressOfHandling extends Pass2SsaOptimization {
ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> {
if(Operators.ADDRESS_OF.equals(programExpression.getOperator())) { if(Operators.ADDRESS_OF.equals(programExpression.getOperator())) {
RValue rValue = ((ProgramExpressionUnary) programExpression).getOperand(); RValue rValue = ((ProgramExpressionUnary) programExpression).getOperand();
if(rValue instanceof SymbolVariableRef) { updateAddressOfValue(rValue, currentStmt);
Symbol toSymbol = getScope().getSymbol((SymbolVariableRef) rValue);
if(toSymbol instanceof Variable) {
final Variable variable = (Variable) toSymbol;
final String stmtStr = currentStmt.toString(getProgram(), false);
updateAddressOfVariable(variable, stmtStr);
}
}
} }
}); });
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue.get() instanceof ConstantSymbolPointer) { if(programValue.get() instanceof ConstantSymbolPointer) {
// Values containing constant pointers // Values containing constant pointers
Value value = ((ConstantSymbolPointer) programValue.get()).getToSymbol(); Value value = ((ConstantSymbolPointer) programValue.get()).getToSymbol();
if(value instanceof SymbolVariableRef) { updateAddressOfValue(value, currentStmt);
Symbol toSymbol = getScope().getSymbol((SymbolVariableRef) value);
if(toSymbol instanceof Variable) {
final Variable variable = (Variable) toSymbol;
if(!variable.isNoModify() && !variable.isVolatile()) {
final String stmtStr = currentStmt == null ? toSymbol.toString(getProgram()) : currentStmt.toString(getProgram(), false);
updateAddressOfVariable(variable, stmtStr);
}
}
}
} }
}); });
return false; return false;
} }
private void updateAddressOfVariable(Variable variable, String stmtStr) { /**
if(variable.getArraySpec()!=null) * Modify variable/procedure affected by address-of
return; *
* @param value The value affected by address-of
* @param currentStmt The current statement
*/
private void updateAddressOfValue(Value value, Statement currentStmt) {
if(value instanceof SymbolRef) {
Symbol toSymbol = getScope().getSymbol((SymbolRef) value);
final String stmtStr = currentStmt == null ? toSymbol.toString(getProgram()) : currentStmt.toString(getProgram(), false);
if(toSymbol instanceof Variable) {
final Variable variable = (Variable) toSymbol;
if(!variable.isNoModify() && !variable.isVolatile()) {
if(variable.getArraySpec() != null)
return;
if(variable.getType() instanceof SymbolTypeStruct) { if(variable.getType() instanceof SymbolTypeStruct) {
variable.setKind(Variable.Kind.LOAD_STORE); variable.setKind(Variable.Kind.LOAD_STORE);
SymbolType typeQualified = variable.getType().getQualified(true, variable.getType().isNomodify()); SymbolType typeQualified = variable.getType().getQualified(true, variable.getType().isNomodify());
variable.setType(typeQualified); variable.setType(typeQualified);
getLog().append("Setting struct to load/store in variable affected by address-of " + stmtStr); getLog().append("Setting struct to load/store in variable affected by address-of " + stmtStr);
//getLog().append("Setting struct to load/store in variable affected by address-of: " + variable.toString() + " in " + stmtStr); //getLog().append("Setting struct to load/store in variable affected by address-of: " + variable.toString() + " in " + stmtStr);
} else { } else {
variable.setKind(Variable.Kind.LOAD_STORE); variable.setKind(Variable.Kind.LOAD_STORE);
SymbolType typeQualified = variable.getType().getQualified(true, variable.getType().isNomodify()); SymbolType typeQualified = variable.getType().getQualified(true, variable.getType().isNomodify());
variable.setType(typeQualified); variable.setType(typeQualified);
getLog().append("Setting inferred volatile on symbol affected by address-of " + stmtStr); getLog().append("Setting inferred volatile on symbol affected by address-of " + stmtStr);
//getLog().append("Setting inferred volatile on symbol affected by address-of: " + variable.toString() + " in " + stmtStr); //getLog().append("Setting inferred volatile on symbol affected by address-of: " + variable.toString() + " in " + stmtStr);
}
}
} else if(toSymbol instanceof Procedure) {
if(((Procedure) toSymbol).getParameters().size() > 0) {
((Procedure) toSymbol).setCallingConvention(Procedure.CallingConvention.STACK_CALL);
getLog().append("Setting inferred __stackcall on procedure affected by address-of " + toSymbol.toString(getProgram()) + " caused by statement " + stmtStr);
;
}
}
} }
} }

View File

@ -1,14 +1,21 @@
package dk.camelot64.kickc.passes; package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.ParamValue;
import dk.camelot64.kickc.model.values.VariableRef; import dk.camelot64.kickc.model.values.VariableRef;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set; import java.util.Set;
/** Handle calling conventions {@link Procedure.CallingConvention#STACK_CALL} {@link Procedure.CallingConvention#VAR_CALL} by converting to call-prepare, call-execute, call-finalize */ /** Handle calling conventions {@link Procedure.CallingConvention#STACK_CALL} by converting parameters, return values and modified variables to load/store and by adding parameter assignemtn statements to procedures*/
public class Pass1CallStackVarPrepare extends Pass2SsaOptimization { public class Pass1CallStackVarPrepare extends Pass2SsaOptimization {
public Pass1CallStackVarPrepare(Program program) { public Pass1CallStackVarPrepare(Program program) {
@ -47,6 +54,20 @@ public class Pass1CallStackVarPrepare extends Pass2SsaOptimization {
} }
} }
// Add parameter assignments at start of procedure in STACK_CALL procedures
for(Procedure procedure : getScope().getAllProcedures(true)) {
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
final ControlFlowBlock procedureBlock = getGraph().getBlock(procedure.getLabel().getRef());
final ArrayList<Variable> params = new ArrayList<>(procedure.getParameters());
Collections.reverse(params);
for(Variable param : params) {
final StatementAssignment paramAssignment = new StatementAssignment((LValue) param.getRef(), new ParamValue((VariableRef) param.getRef()), true, null, Comment.NO_COMMENTS);
procedureBlock.getStatements().add(0, paramAssignment);
getLog().append("Adding parameter assignment in "+procedure.getCallingConvention().getName()+" procedure "+paramAssignment.toString(getProgram(), false));
}
}
}
return false; return false;
} }

View File

@ -3020,6 +3020,11 @@ public class TestProgramsFast extends TestPrograms {
compileAndCompare("function-pointer-param-workaround.c"); compileAndCompare("function-pointer-param-workaround.c");
} }
//@Test
//public void testFunctionPointerParam0() throws IOException {
// compileAndCompare("function-pointer-param-0.c", log().verboseParse().verboseCreateSsa());
//}
@Test @Test
public void testFunctionPointerNoargCall14() throws IOException { public void testFunctionPointerNoargCall14() throws IOException {
compileAndCompare("function-pointer-noarg-call-14.c"); compileAndCompare("function-pointer-noarg-call-14.c");

View File

@ -0,0 +1,35 @@
// Test function pointers with parameters
// Currently the parameter is not transferred properly
void main() {
// A pointer to a function taking a single char param
void(*f)(char);
for(char i=0;i<160;i++) {
if((i&1)==0) {
fn3(i);
continue;
}
if((i&3)==1) {
f = &fn1;
} else {
f = &fn2;
}
(*f)(i);
}
}
char* const SCREEN = (char*)0x400;
void fn1(char c) {
SCREEN[c] = 'a';
}
void fn2(char d) {
SCREEN[d] = 'b';
}
__stackcall void fn3(char e) {
SCREEN[e] = 'c';
}

View File

@ -1,4 +1,6 @@
Loading link script "rom.ld" Loading link script "rom.ld"
Adding parameter assignment in __stackcall procedure call1::param2 = param(call1::param2)
Adding parameter assignment in __stackcall procedure call1::param1 = param(call1::param1)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call call1 1 2 Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call call1 1 2
Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call call1 3 4 Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call call1 3 4
Calling convention STACK_CALL replacing param(call1::param1) with stackidx(byte,call1::OFFSET_STACK_PARAM1) Calling convention STACK_CALL replacing param(call1::param1) with stackidx(byte,call1::OFFSET_STACK_PARAM1)

View File

@ -16,7 +16,6 @@ plus: {
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 2 .label a = 2
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
sta.z a sta.z a

View File

@ -1,3 +1,5 @@
Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7 Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B) Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B)
@ -300,7 +302,6 @@ plus: {
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 2 .label a = 2
// }
// [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 // [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x

View File

@ -16,7 +16,6 @@ plus: {
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 2 .label a = 2
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
sta.z a sta.z a

View File

@ -1,3 +1,5 @@
Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7 Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B) Calling convention STACK_CALL replacing param(plus::b) with stackidx(byte,plus::OFFSET_STACK_B)
@ -300,7 +302,6 @@ plus: {
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 2 .label a = 2
// }
// [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 // [0] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x

View File

@ -24,7 +24,6 @@ __start: {
print: { print: {
.const OFFSET_STACK_P_X = 1 .const OFFSET_STACK_P_X = 1
.const OFFSET_STACK_P_Y = 0 .const OFFSET_STACK_P_Y = 0
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_P_X,x lda STACK_BASE+OFFSET_STACK_P_X,x
tay tay

View File

@ -1,4 +1,6 @@
Converting variable modified inside __stackcall procedure main() to load/store idx Converting variable modified inside __stackcall procedure main() to load/store idx
Adding parameter assignment in __stackcall procedure get::i = param(get::i)
Adding parameter assignment in __stackcall procedure print::p = param(print::p)
Inlined call call __init Inlined call call __init
Eliminating unused variable with no statement main::$1 Eliminating unused variable with no statement main::$1
Calling convention __stackcall adding prepare/execute/finalize for { main::$1_x, main::$1_y } = call get main::i Calling convention __stackcall adding prepare/execute/finalize for { main::$1_x, main::$1_y } = call get main::i
@ -635,7 +637,6 @@ __start: {
print: { print: {
.const OFFSET_STACK_P_X = 1 .const OFFSET_STACK_P_X = 1
.const OFFSET_STACK_P_Y = 0 .const OFFSET_STACK_P_Y = 0
// }
// [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1 // [5] print::p_x#0 = stackidx(byte,print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_P_X,x lda STACK_BASE+OFFSET_STACK_P_X,x

View File

@ -29,7 +29,6 @@ print: {
.const OFFSET_STACK_V_P2_Y = 0 .const OFFSET_STACK_V_P2_Y = 0
.label v_p1_y = 4 .label v_p1_y = 4
.label v_p2_x = 5 .label v_p2_x = 5
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_V_P1_X,x lda STACK_BASE+OFFSET_STACK_V_P1_X,x
tay tay

View File

@ -1,4 +1,6 @@
Converting variable modified inside __stackcall procedure main() to load/store idx Converting variable modified inside __stackcall procedure main() to load/store idx
Adding parameter assignment in __stackcall procedure get::i = param(get::i)
Adding parameter assignment in __stackcall procedure print::v = param(print::v)
Inlined call call __init Inlined call call __init
Eliminating unused variable with no statement main::$1 Eliminating unused variable with no statement main::$1
Eliminating unused variable with no statement main::$1_p1 Eliminating unused variable with no statement main::$1_p1
@ -941,7 +943,6 @@ print: {
.const OFFSET_STACK_V_P2_Y = 0 .const OFFSET_STACK_V_P2_Y = 0
.label v_p1_y = 4 .label v_p1_y = 4
.label v_p2_x = 5 .label v_p2_x = 5
// }
// [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) -- vbuyy=_stackidxbyte_vbuc1 // [5] print::v_p1_x#0 = stackidx(byte,print::OFFSET_STACK_V_P1_X) -- vbuyy=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_V_P1_X,x lda STACK_BASE+OFFSET_STACK_V_P1_X,x

View File

@ -25,7 +25,6 @@ print: {
.const OFFSET_STACK_SPACING = 0 .const OFFSET_STACK_SPACING = 0
.label str = 2 .label str = 2
.label spacing = 5 .label spacing = 5
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_STR,x lda STACK_BASE+OFFSET_STACK_STR,x
sta.z str sta.z str

View File

@ -1,4 +1,6 @@
Converting variable modified inside __stackcall procedure main() to load/store idx Converting variable modified inside __stackcall procedure main() to load/store idx
Adding parameter assignment in __stackcall procedure print::spacing = param(print::spacing)
Adding parameter assignment in __stackcall procedure print::str = param(print::str)
Inlined call call __init Inlined call call __init
Calling convention __stackcall adding prepare/execute/finalize for call print main::str 1 Calling convention __stackcall adding prepare/execute/finalize for call print main::str 1
Calling convention __stackcall adding prepare/execute/finalize for call print main::str1 2 Calling convention __stackcall adding prepare/execute/finalize for call print main::str1 2
@ -556,7 +558,6 @@ print: {
.const OFFSET_STACK_SPACING = 0 .const OFFSET_STACK_SPACING = 0
.label str = 2 .label str = 2
.label spacing = 5 .label spacing = 5
// }
// [5] print::str#0 = stackidx(byte*,print::OFFSET_STACK_STR) -- pbuz1=_stackidxptr_vbuc1 // [5] print::str#0 = stackidx(byte*,print::OFFSET_STACK_STR) -- pbuz1=_stackidxptr_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_STR,x lda STACK_BASE+OFFSET_STACK_STR,x

View File

@ -15,7 +15,6 @@
pow2: { pow2: {
.const OFFSET_STACK_N = 0 .const OFFSET_STACK_N = 0
.const OFFSET_STACK_RETURN = 0 .const OFFSET_STACK_RETURN = 0
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_N,x lda STACK_BASE+OFFSET_STACK_N,x
// if (n == 0) // if (n == 0)

View File

@ -1,3 +1,4 @@
Adding parameter assignment in __stackcall procedure pow2::n = param(pow2::n)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call pow2 6 Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call pow2 6
Calling convention __stackcall adding prepare/execute/finalize for pow2::$2 = call pow2 pow2::$1 Calling convention __stackcall adding prepare/execute/finalize for pow2::$2 = call pow2 pow2::$1
Calling convention STACK_CALL replacing param(pow2::n) with stackidx(byte,pow2::OFFSET_STACK_N) Calling convention STACK_CALL replacing param(pow2::n) with stackidx(byte,pow2::OFFSET_STACK_N)
@ -349,7 +350,6 @@ Score: 72
pow2: { pow2: {
.const OFFSET_STACK_N = 0 .const OFFSET_STACK_N = 0
.const OFFSET_STACK_RETURN = 0 .const OFFSET_STACK_RETURN = 0
// }
// [0] pow2::n#0 = stackidx(byte,pow2::OFFSET_STACK_N) -- vbuaa=_stackidxbyte_vbuc1 // [0] pow2::n#0 = stackidx(byte,pow2::OFFSET_STACK_N) -- vbuaa=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_N,x lda STACK_BASE+OFFSET_STACK_N,x

View File

@ -18,7 +18,6 @@ plus: {
.label a = 4 .label a = 4
.label b = 2 .label b = 2
.label return = 4 .label return = 4
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
sta.z a sta.z a

View File

@ -1,3 +1,5 @@
Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus $1234 $2345 Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus $1234 $2345
Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B) Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B)
@ -338,7 +340,6 @@ plus: {
.label a = 4 .label a = 4
.label b = 2 .label b = 2
.label return = 4 .label return = 4
// }
// [0] plus::a#0 = stackidx(word,plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 // [0] plus::a#0 = stackidx(word,plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x

View File

@ -21,7 +21,6 @@ plus: {
.label a = 4 .label a = 4
.label b = 2 .label b = 2
.label return = 4 .label return = 4
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
sta.z a sta.z a

View File

@ -1,3 +1,5 @@
Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7 Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus '0' 7
Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::a) with stackidx(word,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B) Calling convention STACK_CALL replacing param(plus::b) with stackidx(word,plus::OFFSET_STACK_B)
@ -340,7 +342,6 @@ plus: {
.label a = 4 .label a = 4
.label b = 2 .label b = 2
.label return = 4 .label return = 4
// }
// [0] plus::a#0 = stackidx(word,plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 // [0] plus::a#0 = stackidx(word,plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x

View File

@ -25,7 +25,6 @@ plus: {
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 4 .label a = 4
// }
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
sta.z a sta.z a

View File

@ -1,4 +1,6 @@
Converting variable modified inside __stackcall procedure plus() to load/store i Converting variable modified inside __stackcall procedure plus() to load/store i
Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Inlined call call __init Inlined call call __init
Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call plus '0' main::v Calling convention __stackcall adding prepare/execute/finalize for main::$1 = call plus '0' main::v
Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param(plus::a) with stackidx(byte,plus::OFFSET_STACK_A)
@ -517,7 +519,6 @@ plus: {
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 4 .label a = 4
// }
// [5] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 // [5] plus::a#0 = stackidx(byte,plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x