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:
parent
8193688eec
commit
d4040e30a0
@ -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();
|
||||||
|
@ -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) {
|
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());
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 ]
|
||||||
|
Loading…
Reference in New Issue
Block a user