mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-06 04:54:35 +00:00
Struggling with struct return values.
This commit is contained in:
parent
19893e25f6
commit
34a5ca474a
@ -171,7 +171,7 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
* @param stackReturnOffset The offset onto the stack to place the value at
|
||||
* @param source The source line
|
||||
* @param comments The comments
|
||||
* @param stmtIt The statment iterator used to add statements to.
|
||||
* @param stmtIt The statement iterator used to add statements to.
|
||||
*/
|
||||
private void generateStackReturnValues(RValue value, SymbolType returnType, ConstantValue stackReturnOffset, StatementSource source, List<Comment> comments, ListIterator<Statement> stmtIt) {
|
||||
if(!(value instanceof ValueList) || !(returnType instanceof SymbolTypeStruct)) {
|
||||
|
@ -8,8 +8,13 @@ import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.CastValue;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.ValueList;
|
||||
import dk.camelot64.kickc.passes.unwinding.ValueSource;
|
||||
import dk.camelot64.kickc.passes.unwinding.ValueSourceFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
@ -74,7 +79,7 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
||||
if(lValue!=null) {
|
||||
Variable returnVar = procedure.getLocalVariable("return");
|
||||
stmtIt.previous();
|
||||
stmtIt.add(new StatementAssignment(lValue, returnVar.getRef(), call.isInitialAssignment(), source, comments));
|
||||
generateCallFinalize(lValue, returnVar, source, comments, stmtIt, statement);
|
||||
stmtIt.next();
|
||||
}
|
||||
stmtIt.remove();
|
||||
@ -111,4 +116,35 @@ public class Pass1CallVar extends Pass2SsaOptimization {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void generateCallFinalize(LValue lValue, Variable returnVar, StatementSource source, List<Comment> comments, ListIterator<Statement> stmtIt, Statement currentStmt) {
|
||||
final SymbolType returnType = returnVar.getType();
|
||||
if(!(lValue instanceof ValueList) || !(returnType instanceof SymbolTypeStruct)) {
|
||||
// A simple value - add simple assignment
|
||||
final StatementAssignment stackPull = new StatementAssignment(lValue, returnVar.getRef(), false, source, comments);
|
||||
stmtIt.add(stackPull);
|
||||
getLog().append("Calling convention " + Procedure.CallingConvention.VAR_CALL + " adding return value assignment " + stackPull);
|
||||
} else {
|
||||
final CastValue structLValue = new CastValue(returnType, lValue);
|
||||
// A struct to unwind
|
||||
final ValueSource lValueSource = ValueSourceFactory.getValueSource(structLValue, getProgram(), getScope(), currentStmt, stmtIt, null);
|
||||
final ValueSource rValueSource = ValueSourceFactory.getValueSource(returnVar.getRef(), getProgram(), getScope(), currentStmt, stmtIt, null);
|
||||
Pass1UnwindStructValues.copyValues(lValueSource, rValueSource, null, false, currentStmt, null, stmtIt, getProgram());
|
||||
|
||||
|
||||
/*
|
||||
final List<RValue> memberLValues = ((ValueList) lValue).getList();
|
||||
final StructVariableMemberUnwinding structVariableMemberUnwinding = getProgram().getStructVariableMemberUnwinding();
|
||||
final StructVariableMemberUnwinding.VariableUnwinding returnVarUnwinding = structVariableMemberUnwinding.getVariableUnwinding(returnVar.getRef());
|
||||
for(RValue memberLValue : memberLValues) {
|
||||
|
||||
}
|
||||
for(int i = 0; i < structMemberVars.size(); i++) {
|
||||
final Variable memberVar = structMemberVars.get(i);
|
||||
final RValue memberValue = memberLValues.get(i);
|
||||
generateCallFinalize(memberValue, memberVar.getType(), source, comments, stmtIt);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
ValueSource lValueSource = ValueSourceFactory.getValueSource(lValue, getProgram(), getScope(), assignment, stmtIt, currentBlock);
|
||||
ValueSource rValueSource = ValueSourceFactory.getValueSource(rValue, getProgram(), getScope(), assignment, stmtIt, currentBlock);
|
||||
List<RValue> lValueUnwoundList = new ArrayList<>();
|
||||
if(copyValues(lValueSource, rValueSource, lValueUnwoundList, initialAssignment, assignment, currentBlock, stmtIt)) {
|
||||
if(copyValues(lValueSource, rValueSource, lValueUnwoundList, initialAssignment, assignment, currentBlock, stmtIt, getProgram())) {
|
||||
if(lValue instanceof VariableRef) {
|
||||
StructUnwoundPlaceholder unwoundPlaceholder = new StructUnwoundPlaceholder(lValueStructType, lValueUnwoundList);
|
||||
assignment.setrValue2(unwoundPlaceholder);
|
||||
@ -246,20 +246,20 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean copyValues(ValueSource lValueSource, ValueSource rValueSource, List<RValue> lValueUnwoundList, boolean initialAssignment, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator<Statement> stmtIt) {
|
||||
public static boolean copyValues(ValueSource lValueSource, ValueSource rValueSource, List<RValue> lValueUnwoundList, boolean initialAssignment, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator<Statement> stmtIt, Program program) {
|
||||
if(lValueSource == null || rValueSource == null)
|
||||
return false;
|
||||
if(lValueSource.isSimple() && rValueSource.isSimple()) {
|
||||
stmtIt.previous();
|
||||
LValue lValueRef = (LValue) lValueSource.getSimpleValue(getScope());
|
||||
RValue rValueRef = rValueSource.getSimpleValue(getScope());
|
||||
LValue lValueRef = (LValue) lValueSource.getSimpleValue(program.getScope());
|
||||
RValue rValueRef = rValueSource.getSimpleValue(program.getScope());
|
||||
if(lValueUnwoundList != null)
|
||||
lValueUnwoundList.add(lValueRef);
|
||||
Statement copyStmt = new StatementAssignment(lValueRef, rValueRef, initialAssignment, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
stmtIt.add(copyStmt);
|
||||
stmtIt.next();
|
||||
if(getLog().isVerboseStructUnwind())
|
||||
getLog().append("Adding value simple copy " + copyStmt.toString(getProgram(), false));
|
||||
if(program.getLog().isVerboseStructUnwind())
|
||||
program.getLog().append("Adding value simple copy " + copyStmt.toString(program, false));
|
||||
return true;
|
||||
} else if(lValueSource.isBulkCopyable() && rValueSource.isBulkCopyable()) {
|
||||
// Use bulk unwinding for a struct member that is an array
|
||||
@ -267,23 +267,23 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
if(lValueSource.getArraySpec() != null)
|
||||
if(rValueSource.getArraySpec() == null || !lValueSource.getArraySpec().equals(rValueSource.getArraySpec()))
|
||||
throw new RuntimeException("ArraySpec mismatch!");
|
||||
LValue lValueMemberVarRef = lValueSource.getBulkLValue(getScope());
|
||||
RValue rValueBulkUnwinding = rValueSource.getBulkRValue(getScope());
|
||||
LValue lValueMemberVarRef = lValueSource.getBulkLValue(program.getScope());
|
||||
RValue rValueBulkUnwinding = rValueSource.getBulkRValue(program.getScope());
|
||||
if(lValueUnwoundList != null)
|
||||
lValueUnwoundList.add(lValueMemberVarRef);
|
||||
Statement copyStmt = new StatementAssignment(lValueMemberVarRef, rValueBulkUnwinding, initialAssignment, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
stmtIt.add(copyStmt);
|
||||
stmtIt.next();
|
||||
if(getLog().isVerboseStructUnwind())
|
||||
getLog().append("Adding value bulk copy " + copyStmt.toString(getProgram(), false));
|
||||
if(program.getLog().isVerboseStructUnwind())
|
||||
program.getLog().append("Adding value bulk copy " + copyStmt.toString(program, false));
|
||||
return true;
|
||||
} else if(lValueSource.isUnwindable() && rValueSource.isUnwindable()) {
|
||||
if(getLog().isVerboseStructUnwind())
|
||||
getLog().append("Unwinding value copy " + currentStmt.toString(getProgram(), false));
|
||||
for(String memberName : lValueSource.getMemberNames(getScope())) {
|
||||
ValueSource lValueSubSource = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, stmtIt, currentBlock);
|
||||
ValueSource rValueSubSource = rValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, stmtIt, currentBlock);
|
||||
boolean success = copyValues(lValueSubSource, rValueSubSource, lValueUnwoundList, initialAssignment, currentStmt, currentBlock, stmtIt);
|
||||
if(program.getLog().isVerboseStructUnwind())
|
||||
program.getLog().append("Unwinding value copy " + currentStmt.toString(program, false));
|
||||
for(String memberName : lValueSource.getMemberNames(program.getScope())) {
|
||||
ValueSource lValueSubSource = lValueSource.getMemberUnwinding(memberName, program, program.getScope(), currentStmt, stmtIt, currentBlock);
|
||||
ValueSource rValueSubSource = rValueSource.getMemberUnwinding(memberName, program, program.getScope(), currentStmt, stmtIt, currentBlock);
|
||||
boolean success = copyValues(lValueSubSource, rValueSubSource, lValueUnwoundList, initialAssignment, currentStmt, currentBlock, stmtIt, program);
|
||||
if(!success)
|
||||
throw new InternalError("Error during value unwinding copy! ", currentStmt);
|
||||
}
|
||||
|
@ -48,6 +48,11 @@ public class TestPrograms {
|
||||
// compileAndCompare("unknown-var-problem.c", log().verboseParse());
|
||||
//}
|
||||
|
||||
@Test
|
||||
public void testVarCall4() throws IOException, URISyntaxException {
|
||||
compileAndCompare("varcall-4.c", log().verboseStructUnwind().verboseCreateSsa());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVarCall3() throws IOException, URISyntaxException {
|
||||
compileAndCompare("varcall-3.c");
|
||||
|
22
src/test/kc/varcall-4.c
Normal file
22
src/test/kc/varcall-4.c
Normal file
@ -0,0 +1,22 @@
|
||||
// Test __varcall calling convention
|
||||
// Struct parameter & return value
|
||||
|
||||
struct Cols {
|
||||
char border;
|
||||
char bg;
|
||||
};
|
||||
|
||||
struct Cols * const COLS = 0xd020;
|
||||
|
||||
void main() {
|
||||
struct Cols a = { 1, 2 };
|
||||
//*COLS = a;
|
||||
a = plus(a, { 2, 3 } );
|
||||
*COLS = a;
|
||||
//a = plus(a, a);
|
||||
//*COLS = a;
|
||||
}
|
||||
|
||||
__varcall struct Cols plus(struct Cols a, struct Cols b) {
|
||||
return { a.border+b.border, a.bg+b.bg };
|
||||
}
|
Loading…
Reference in New Issue
Block a user