1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-01 16:51:12 +00:00

Moved handling of banked param/return to pass 1.

This commit is contained in:
jespergravgaard 2023-04-24 00:36:36 +02:00
parent 8193688eec
commit d4040e30a0
7 changed files with 79 additions and 54 deletions

View File

@ -224,6 +224,7 @@ public class Compiler {
new Pass1Procedures(program).execute(); new Pass1Procedures(program).execute();
new PassNTypeInference(program).execute(); new PassNTypeInference(program).execute();
new PassNFixIntermediateMemoryArea(program).execute(); new PassNFixIntermediateMemoryArea(program).execute();
new Pass1FixProcedureParamSegment(program).execute();
new PassNTypeIdSimplification(program).execute(); new PassNTypeIdSimplification(program).execute();
new Pass1StructTypeSizeFix(program).execute(); new Pass1StructTypeSizeFix(program).execute();
new Pass1PrintfIntrinsicRewrite(program).execute(); new Pass1PrintfIntrinsicRewrite(program).execute();

View File

@ -0,0 +1,46 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.Registers;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import java.util.Collection;
import java.util.List;
/**
* Ensure banked procedure parameters/return values in main memory are placed in the default data segment.
* This is needed to support banking, since it is otherwise impossible to access them across bank boundaries during calls.
*/
public class Pass1FixProcedureParamSegment extends Pass2SsaOptimization {
public Pass1FixProcedureParamSegment(Program program) {
super(program);
}
@Override
public boolean step() {
final Collection<Variable> allVariables = getScope().getAllVariables(true);
for(Variable variable : allVariables) {
if(variable.isKindLoadStore() || variable.isKindPhiMaster() || variable.isKindIntermediate()) {
if(variable.getRegister() instanceof Registers.RegisterMainMem registerMainMem && registerMainMem.isAddressHardcoded())
continue;
if(variable.getDataSegment().equals(Scope.SEGMENT_DATA_DEFAULT))
continue;
final Scope scope = variable.getScope();
if(scope instanceof Procedure procedure) {
if(!procedure.getBank().isCommon()) {
List<Variable> parameters = procedure.getParameters();
if(parameters.contains(variable) || variable.getLocalName().equals("return")) {
variable.setDataSegment(Scope.SEGMENT_DATA_DEFAULT);
getLog().append("Fixing banked procedure parameter/return value to default segment " + variable.getFullName());
}
}
}
}
}
return false;
}
}

View File

@ -583,30 +583,6 @@ public class Pass4CodeGeneration {
if (registerMainMem.getAddress() == null) { if (registerMainMem.getAddress() == null) {
// Generate into the data segment // Generate into the data segment
// Set segment // Set segment
// We check first the bank of the variable. Only local variables can be stored in the bank.
// Parameters must be stored in main memory.
if(!variable.getDataSegment().equals(Scope.SEGMENT_DATA_DEFAULT)) {
if(scope instanceof Procedure) {
Procedure procedure = (Procedure) scope;
List<Variable> parameters = procedure.getParameters();
if (variable.isKindPhiVersion()) {
Variable master = variable.getPhiMaster();
if (master != null) {
if (parameters.contains(master) || master.getLocalName().equals("return")) {
variable.setDataSegment(Scope.SEGMENT_DATA_DEFAULT);
}
}
}
}
}
// Intermediate variables are placed at the banked data segment, but parameters and return values are kept untouched.
if (variable.isKindIntermediate()) {
if (scope instanceof Procedure) {
Procedure procedure = (Procedure) scope;
variable.setDataSegment(procedure.getSegmentData());
}
}
setCurrentSegment(variable.getDataSegment(), asm); setCurrentSegment(variable.getDataSegment(), asm);
// Add any comments // Add any comments
generateComments(asm, variable.getComments()); generateComments(asm, variable.getComments());

View File

@ -1583,7 +1583,7 @@ public class TestProgramsFast extends TestPrograms {
@Test @Test
public void testBankedPhiMemvars() throws IOException { public void testBankedPhiMemvars() throws IOException {
compileAndCompare("call-banked-phi-memvars.c", log()); compileAndCompare("call-banked-phi-memvars.c");
} }

View File

@ -93,8 +93,8 @@ main: {
iny iny
jmp __b1 jmp __b1
.segment Data .segment Data
.label __1 = plus.return .label __1 = plus.b
.label __3 = plus.return .label __3 = plus.b
} }
.segment RAM_Bank1 .segment RAM_Bank1
// __mem() int plus(__mem() int a, __mem() int b) // __mem() int plus(__mem() int a, __mem() int b)
@ -125,18 +125,18 @@ plus: {
adc a+1 adc a+1
sta r+1 sta r+1
// r += b // r += b
lda r
clc clc
adc b lda return
adc r
sta return sta return
lda r+1 lda return+1
adc b+1 adc r+1
sta return+1 sta return+1
// } // }
rts rts
.segment Data .segment Data
b: .word 0 b: .word 0
return: .word 0 .label return = b
.segment RAM_Bank1 .segment RAM_Bank1
r: .word 0 r: .word 0
.segment Data .segment Data

View File

@ -3,6 +3,9 @@ Updating intermediate variable memory area to MAIN_MEMORY main::$0
Updating intermediate variable memory area to MAIN_MEMORY main::$1 Updating intermediate variable memory area to MAIN_MEMORY main::$1
Updating intermediate variable memory area to MAIN_MEMORY main::$2 Updating intermediate variable memory area to MAIN_MEMORY main::$2
Updating intermediate variable memory area to MAIN_MEMORY main::$3 Updating intermediate variable memory area to MAIN_MEMORY main::$3
Fixing banked procedure parameter/return value to default segment plus::a
Fixing banked procedure parameter/return value to default segment plus::b
Fixing banked procedure parameter/return value to default segment plus::return
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@ -359,11 +362,12 @@ Uplifting [plus] best 2226 combination mem[2] [ plus::r#1 ] mem[2] [ plus::r#2 ]
Uplifting [main] best 1866 combination reg byte y [ main::i#2 main::i#1 ] reg byte x [ main::$4 ] reg byte x [ main::$5 ] mem[2] [ main::$1 ] mem[2] [ main::$3 ] reg byte x [ main::$2 ] Uplifting [main] best 1866 combination reg byte y [ main::i#2 main::i#1 ] reg byte x [ main::$4 ] reg byte x [ main::$5 ] mem[2] [ main::$1 ] mem[2] [ main::$3 ] reg byte x [ main::$2 ]
Limited combination testing to 100 combinations of 144 possible. Limited combination testing to 100 combinations of 144 possible.
Uplifting [] best 1866 combination Uplifting [] best 1866 combination
Coalescing zero page register [ mem[2] [ plus::b#2 plus::b#0 plus::b#1 ] ] with [ mem[2] [ plus::return#2 ] ] - score: 1
Coalescing zero page register [ mem[2] [ plus::return#0 ] ] with [ mem[2] [ main::$1 ] ] - score: 1 Coalescing zero page register [ mem[2] [ plus::return#0 ] ] with [ mem[2] [ main::$1 ] ] - score: 1
Coalescing zero page register [ mem[2] [ plus::return#0 main::$1 ] ] with [ mem[2] [ plus::return#2 ] ] - score: 1
Coalescing zero page register [ mem[2] [ plus::return#1 ] ] with [ mem[2] [ main::$3 ] ] - score: 1 Coalescing zero page register [ mem[2] [ plus::return#1 ] ] with [ mem[2] [ main::$3 ] ] - score: 1
Coalescing zero page register [ mem[2] [ plus::r#1 ] ] with [ mem[2] [ plus::r#2 ] ] - score: 1 Coalescing zero page register [ mem[2] [ plus::r#1 ] ] with [ mem[2] [ plus::r#2 ] ] - score: 1
Coalescing zero page register [ mem[2] [ plus::return#0 main::$1 plus::return#2 ] ] with [ mem[2] [ plus::return#1 main::$3 ] ] - score: 1 Coalescing zero page register [ mem[2] [ plus::b#2 plus::b#0 plus::b#1 plus::return#2 ] ] with [ mem[2] [ plus::return#0 main::$1 ] ] - score: 1
Coalescing zero page register [ mem[2] [ plus::b#2 plus::b#0 plus::b#1 plus::return#2 plus::return#0 main::$1 ] ] with [ mem[2] [ plus::return#1 main::$3 ] ] - score: 1
Coalescing zero page register [ mem[2] [ plus::r#1 plus::r#2 ] ] with [ mem[2] [ plus::r#3 ] ] - score: 1 Coalescing zero page register [ mem[2] [ plus::r#1 plus::r#2 ] ] with [ mem[2] [ plus::r#3 ] ] - score: 1
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
@ -498,8 +502,8 @@ main: {
// [1] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy // [1] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy
jmp __b1 jmp __b1
.segment Data .segment Data
.label __1 = plus.return .label __1 = plus.b
.label __3 = plus.return .label __3 = plus.b
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
@ -530,13 +534,13 @@ plus: {
lda r+1 lda r+1
adc a+1 adc a+1
sta r+1 sta r+1
// [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm3 // [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm1
lda r
clc clc
adc b lda return
adc r
sta return sta return
lda r+1 lda return+1
adc b+1 adc r+1
sta return+1 sta return+1
jmp __breturn jmp __breturn
// plus::@return // plus::@return
@ -545,7 +549,7 @@ plus: {
rts rts
.segment Data .segment Data
b: .word 0 b: .word 0
return: .word 0 .label return = b
.segment RAM_Bank1 .segment RAM_Bank1
r: .word 0 r: .word 0
.segment Data .segment Data
@ -599,8 +603,7 @@ int plus::return#2 // return mem[2] 30.75
reg byte y [ main::i#2 main::i#1 ] reg byte y [ main::i#2 main::i#1 ]
mem[2] [ plus::a#2 ] mem[2] [ plus::a#2 ]
mem[2] [ plus::b#2 plus::b#0 plus::b#1 ] mem[2] [ plus::b#2 plus::b#0 plus::b#1 plus::return#2 plus::return#0 main::$1 plus::return#1 main::$3 ]
mem[2] [ plus::return#0 main::$1 plus::return#2 plus::return#1 main::$3 ]
reg byte x [ main::$4 ] reg byte x [ main::$4 ]
reg byte x [ main::$2 ] reg byte x [ main::$2 ]
reg byte x [ main::$5 ] reg byte x [ main::$5 ]
@ -740,8 +743,8 @@ main: {
// [1] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy // [1] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy
jmp __b1 jmp __b1
.segment Data .segment Data
.label __1 = plus.return .label __1 = plus.b
.label __3 = plus.return .label __3 = plus.b
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
@ -776,13 +779,13 @@ plus: {
adc a+1 adc a+1
sta r+1 sta r+1
// r += b // r += b
// [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm3 // [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm1
lda r
clc clc
adc b lda return
adc r
sta return sta return
lda r+1 lda return+1
adc b+1 adc r+1
sta return+1 sta return+1
// plus::@return // plus::@return
// } // }
@ -790,7 +793,7 @@ plus: {
rts rts
.segment Data .segment Data
b: .word 0 b: .word 0
return: .word 0 .label return = b
.segment RAM_Bank1 .segment RAM_Bank1
r: .word 0 r: .word 0
.segment Data .segment Data

View File

@ -26,8 +26,7 @@ int plus::return#2 // return mem[2] 30.75
reg byte y [ main::i#2 main::i#1 ] reg byte y [ main::i#2 main::i#1 ]
mem[2] [ plus::a#2 ] mem[2] [ plus::a#2 ]
mem[2] [ plus::b#2 plus::b#0 plus::b#1 ] mem[2] [ plus::b#2 plus::b#0 plus::b#1 plus::return#2 plus::return#0 main::$1 plus::return#1 main::$3 ]
mem[2] [ plus::return#0 main::$1 plus::return#2 plus::return#1 main::$3 ]
reg byte x [ main::$4 ] reg byte x [ main::$4 ]
reg byte x [ main::$2 ] reg byte x [ main::$2 ]
reg byte x [ main::$5 ] reg byte x [ main::$5 ]