mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-30 15:31:17 +00:00
Moved handling of banked param/return to pass 1.
This commit is contained in:
parent
8193688eec
commit
d4040e30a0
@ -224,6 +224,7 @@ public class Compiler {
|
||||
new Pass1Procedures(program).execute();
|
||||
new PassNTypeInference(program).execute();
|
||||
new PassNFixIntermediateMemoryArea(program).execute();
|
||||
new Pass1FixProcedureParamSegment(program).execute();
|
||||
new PassNTypeIdSimplification(program).execute();
|
||||
new Pass1StructTypeSizeFix(program).execute();
|
||||
new Pass1PrintfIntrinsicRewrite(program).execute();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -583,30 +583,6 @@ public class Pass4CodeGeneration {
|
||||
if (registerMainMem.getAddress() == null) {
|
||||
// Generate into the data 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);
|
||||
// Add any comments
|
||||
generateComments(asm, variable.getComments());
|
||||
|
@ -1583,7 +1583,7 @@ public class TestProgramsFast extends TestPrograms {
|
||||
|
||||
@Test
|
||||
public void testBankedPhiMemvars() throws IOException {
|
||||
compileAndCompare("call-banked-phi-memvars.c", log());
|
||||
compileAndCompare("call-banked-phi-memvars.c");
|
||||
}
|
||||
|
||||
|
||||
|
@ -93,8 +93,8 @@ main: {
|
||||
iny
|
||||
jmp __b1
|
||||
.segment Data
|
||||
.label __1 = plus.return
|
||||
.label __3 = plus.return
|
||||
.label __1 = plus.b
|
||||
.label __3 = plus.b
|
||||
}
|
||||
.segment RAM_Bank1
|
||||
// __mem() int plus(__mem() int a, __mem() int b)
|
||||
@ -125,18 +125,18 @@ plus: {
|
||||
adc a+1
|
||||
sta r+1
|
||||
// r += b
|
||||
lda r
|
||||
clc
|
||||
adc b
|
||||
lda return
|
||||
adc r
|
||||
sta return
|
||||
lda r+1
|
||||
adc b+1
|
||||
lda return+1
|
||||
adc r+1
|
||||
sta return+1
|
||||
// }
|
||||
rts
|
||||
.segment Data
|
||||
b: .word 0
|
||||
return: .word 0
|
||||
.label return = b
|
||||
.segment RAM_Bank1
|
||||
r: .word 0
|
||||
.segment Data
|
||||
|
@ -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::$2
|
||||
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
|
||||
|
||||
@ -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 ]
|
||||
Limited combination testing to 100 combinations of 144 possible.
|
||||
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 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::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
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
@ -498,8 +502,8 @@ main: {
|
||||
// [1] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#0] -- register_copy
|
||||
jmp __b1
|
||||
.segment Data
|
||||
.label __1 = plus.return
|
||||
.label __3 = plus.return
|
||||
.label __1 = plus.b
|
||||
.label __3 = plus.b
|
||||
}
|
||||
.segment RAM_Bank1
|
||||
// plus
|
||||
@ -530,13 +534,13 @@ plus: {
|
||||
lda r+1
|
||||
adc a+1
|
||||
sta r+1
|
||||
// [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm3
|
||||
lda r
|
||||
// [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm1
|
||||
clc
|
||||
adc b
|
||||
lda return
|
||||
adc r
|
||||
sta return
|
||||
lda r+1
|
||||
adc b+1
|
||||
lda return+1
|
||||
adc r+1
|
||||
sta return+1
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
@ -545,7 +549,7 @@ plus: {
|
||||
rts
|
||||
.segment Data
|
||||
b: .word 0
|
||||
return: .word 0
|
||||
.label return = b
|
||||
.segment RAM_Bank1
|
||||
r: .word 0
|
||||
.segment Data
|
||||
@ -599,8 +603,7 @@ int plus::return#2 // return mem[2] 30.75
|
||||
|
||||
reg byte y [ main::i#2 main::i#1 ]
|
||||
mem[2] [ plus::a#2 ]
|
||||
mem[2] [ plus::b#2 plus::b#0 plus::b#1 ]
|
||||
mem[2] [ plus::return#0 main::$1 plus::return#2 plus::return#1 main::$3 ]
|
||||
mem[2] [ plus::b#2 plus::b#0 plus::b#1 plus::return#2 plus::return#0 main::$1 plus::return#1 main::$3 ]
|
||||
reg byte x [ main::$4 ]
|
||||
reg byte x [ main::$2 ]
|
||||
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
|
||||
jmp __b1
|
||||
.segment Data
|
||||
.label __1 = plus.return
|
||||
.label __3 = plus.return
|
||||
.label __1 = plus.b
|
||||
.label __3 = plus.b
|
||||
}
|
||||
.segment RAM_Bank1
|
||||
// plus
|
||||
@ -776,13 +779,13 @@ plus: {
|
||||
adc a+1
|
||||
sta r+1
|
||||
// r += b
|
||||
// [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm3
|
||||
lda r
|
||||
// [22] plus::return#2 = plus::r#3 + plus::b#2 -- vwsm1=vwsm2_plus_vwsm1
|
||||
clc
|
||||
adc b
|
||||
lda return
|
||||
adc r
|
||||
sta return
|
||||
lda r+1
|
||||
adc b+1
|
||||
lda return+1
|
||||
adc r+1
|
||||
sta return+1
|
||||
// plus::@return
|
||||
// }
|
||||
@ -790,7 +793,7 @@ plus: {
|
||||
rts
|
||||
.segment Data
|
||||
b: .word 0
|
||||
return: .word 0
|
||||
.label return = b
|
||||
.segment RAM_Bank1
|
||||
r: .word 0
|
||||
.segment Data
|
||||
|
@ -26,8 +26,7 @@ int plus::return#2 // return mem[2] 30.75
|
||||
|
||||
reg byte y [ main::i#2 main::i#1 ]
|
||||
mem[2] [ plus::a#2 ]
|
||||
mem[2] [ plus::b#2 plus::b#0 plus::b#1 ]
|
||||
mem[2] [ plus::return#0 main::$1 plus::return#2 plus::return#1 main::$3 ]
|
||||
mem[2] [ plus::b#2 plus::b#0 plus::b#1 plus::return#2 plus::return#0 main::$1 plus::return#1 main::$3 ]
|
||||
reg byte x [ main::$4 ]
|
||||
reg byte x [ main::$2 ]
|
||||
reg byte x [ main::$5 ]
|
||||
|
Loading…
Reference in New Issue
Block a user