mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-27 06:34:19 +00:00
Started implementing register uplift with clobber checks. Added a bunch of missing fragments. Added a few failing tests of errors that should give a nice error message.
This commit is contained in:
parent
3a14d2ef5b
commit
18bbde8a44
@ -145,7 +145,6 @@ public class Compiler {
|
||||
log.append(program.getScope().getSymbolTableContents(Variable.class));
|
||||
|
||||
new Pass3RegistersFinalize(program, log).allocate();
|
||||
|
||||
new Pass3AssertNoCpuClobber(program, log).check();
|
||||
|
||||
new Pass3RegisterUplifting(program, log).uplift();
|
||||
@ -156,7 +155,7 @@ public class Compiler {
|
||||
new Pass3ZeroPageCoalesce(program, log).allocate();
|
||||
new Pass3AssertNoCpuClobber(program, log).check();
|
||||
|
||||
//new Pass3CustomRegisters(program).allocate();
|
||||
//new Pass3CustomRegisters(program).setRegister();
|
||||
//new Pass3AssertNoCpuClobber(program, log).check();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
sty {cowo1}
|
@ -0,0 +1,2 @@
|
||||
clc
|
||||
adc #1
|
@ -0,0 +1,2 @@
|
||||
sec
|
||||
sbc #{coby1}
|
@ -0,0 +1,2 @@
|
||||
cmp #{coby1}
|
||||
bcs {la1}
|
@ -0,0 +1,2 @@
|
||||
cpx #{coby1}
|
||||
bcs {la1}
|
@ -0,0 +1,3 @@
|
||||
tax
|
||||
lda {zpby1}
|
||||
sta {cowo1},x
|
@ -0,0 +1,3 @@
|
||||
txa
|
||||
ldx {zpby1}
|
||||
sta {cowo1},x
|
@ -0,0 +1,3 @@
|
||||
tya
|
||||
ldy {zpby1}
|
||||
sta {cowo1},y
|
@ -0,0 +1,2 @@
|
||||
lda {cowo1},x
|
||||
tax
|
@ -0,0 +1,3 @@
|
||||
ldx {zpby1}
|
||||
lda {cowo1},x
|
||||
tax
|
@ -0,0 +1,4 @@
|
||||
txa
|
||||
clc
|
||||
adc #{coby1}
|
||||
tax
|
@ -0,0 +1,4 @@
|
||||
txa
|
||||
clc
|
||||
adc {zpby1}
|
||||
tax
|
@ -0,0 +1,2 @@
|
||||
lda {cowo1},y
|
||||
tay
|
@ -0,0 +1,3 @@
|
||||
ldy {zpby1}
|
||||
lda {cowo1},y
|
||||
tay
|
@ -0,0 +1,4 @@
|
||||
tya
|
||||
clc
|
||||
adc {zpby1}
|
||||
tay
|
@ -0,0 +1,4 @@
|
||||
txa
|
||||
clc
|
||||
adc #{coby1}
|
||||
sta {zpby1}
|
@ -0,0 +1,4 @@
|
||||
tya
|
||||
clc
|
||||
adc #{coby1}
|
||||
sta {zpby1}
|
@ -0,0 +1,3 @@
|
||||
tay
|
||||
lda {zpby1}
|
||||
sta ({zpptrby1}),y
|
@ -0,0 +1,4 @@
|
||||
txa
|
||||
tay
|
||||
lda {zpby1}
|
||||
sta ({zpptrby1}),y
|
@ -0,0 +1,2 @@
|
||||
lda {zpby1}
|
||||
sta ({zpptrby1}),y
|
@ -61,4 +61,16 @@ public class LiveRangeEquivalenceClassSet {
|
||||
equivalenceClasses.remove(equivalenceClass);
|
||||
}
|
||||
|
||||
public RegisterAllocation createRegisterAllocation() {
|
||||
RegisterAllocation allocation = new RegisterAllocation();
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : getEquivalenceClasses()) {
|
||||
RegisterAllocation.Register register = equivalenceClass.getRegister();
|
||||
for (VariableRef variable : equivalenceClass.getVariables()) {
|
||||
allocation.setRegister(variable, register);
|
||||
}
|
||||
}
|
||||
return allocation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class RegisterAllocation {
|
||||
}
|
||||
|
||||
|
||||
public void allocate(VariableRef variable, Register register) {
|
||||
public void setRegister(VariableRef variable, Register register) {
|
||||
if(variable!=null) {
|
||||
allocation.put(variable, register);
|
||||
}
|
||||
|
@ -30,11 +30,19 @@ public class Pass3AssertNoCpuClobber {
|
||||
|
||||
/** Check that no statement clobbers a CPU register used by an alive variable */
|
||||
public void check() {
|
||||
LiveRangeVariables liveRangeVariables = program.getScope().getLiveRangeVariables();
|
||||
if(hasClobberProblem()) {
|
||||
throw new RuntimeException("CLOBBER ERROR! See log for more info.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether any statement in the program clobbers a CPU register used by an alive variable
|
||||
* @return true if there is a clobber problem in the program
|
||||
*/
|
||||
public boolean hasClobberProblem() {
|
||||
RegisterAllocation allocation = program.getScope().getAllocation();
|
||||
|
||||
LiveRangeVariables liveRangeVariables = program.getScope().getLiveRangeVariables();
|
||||
boolean error = false;
|
||||
|
||||
for (ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||
for (Statement statement : block.getStatements()) {
|
||||
|
||||
@ -66,11 +74,7 @@ public class Pass3AssertNoCpuClobber {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(error) {
|
||||
throw new RuntimeException("CLOBBER ERROR! See log for more info.");
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@ -133,5 +137,4 @@ public class Pass3AssertNoCpuClobber {
|
||||
return asm;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,96 +18,96 @@ public class Pass3CustomRegisters {
|
||||
RegisterAllocation allocation = program.getScope().getAllocation();
|
||||
|
||||
// Register allocation for loopnest.kc
|
||||
allocation.allocate(new VariableRef("nest2::j#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("nest2::j#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("nest2::i#2"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("nest2::i#1"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("nest2::j#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("nest2::j#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("nest2::i#2"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("nest2::i#1"), RegisterAllocation.getRegisterY());
|
||||
|
||||
|
||||
// Register allocation for fibmem.kc
|
||||
/*
|
||||
allocation.allocate(new VariableRef("i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("$1"), new RegisterAllocation.RegisterAByte());
|
||||
allocation.allocate(new VariableRef("$3"), new RegisterAllocation.RegisterALUByte());
|
||||
allocation.allocate(new VariableRef("$4"), new RegisterAllocation.RegisterAByte());
|
||||
allocation.setRegister(new VariableRef("i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("$1"), new RegisterAllocation.RegisterAByte());
|
||||
allocation.setRegister(new VariableRef("$3"), new RegisterAllocation.RegisterALUByte());
|
||||
allocation.setRegister(new VariableRef("$4"), new RegisterAllocation.RegisterAByte());
|
||||
*/
|
||||
|
||||
// Registers for postinc.kc
|
||||
/*
|
||||
allocation.allocate(new VariableRef("c#0"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("c#1"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("c#2"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("b#0"), new RegisterAllocation.RegisterZpByte(102));
|
||||
allocation.allocate(new VariableRef("b#1"), new RegisterAllocation.RegisterZpByte(102));
|
||||
allocation.allocate(new VariableRef("b#2"), new RegisterAllocation.RegisterZpByte(102));
|
||||
allocation.allocate(new VariableRef("$1"), new RegisterAllocation.RegisterZpByte(101));
|
||||
allocation.allocate(new VariableRef("a#0"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.allocate(new VariableRef("a#1"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.allocate(new VariableRef("a#2"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.allocate(new VariableRef("$0"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("c#0"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("c#1"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("c#2"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("b#0"), new RegisterAllocation.RegisterZpByte(102));
|
||||
allocation.setRegister(new VariableRef("b#1"), new RegisterAllocation.RegisterZpByte(102));
|
||||
allocation.setRegister(new VariableRef("b#2"), new RegisterAllocation.RegisterZpByte(102));
|
||||
allocation.setRegister(new VariableRef("$1"), new RegisterAllocation.RegisterZpByte(101));
|
||||
allocation.setRegister(new VariableRef("a#0"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.setRegister(new VariableRef("a#1"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.setRegister(new VariableRef("a#2"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.setRegister(new VariableRef("$0"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("i#2"), RegisterAllocation.getRegisterX());
|
||||
*/
|
||||
|
||||
// Optimal Registers for flipper-rex2.kc
|
||||
/*
|
||||
allocation.allocate(new VariableRef("plot::i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("plot::i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("plot::i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("plot::i#3"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("plot::i#4"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("plot::x#0"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("plot::x#1"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("plot::x#2"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("plot::y#0"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.allocate(new VariableRef("plot::y#1"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.allocate(new VariableRef("plot::y#2"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.allocate(new VariableRef("plot::y#3"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.allocate(new VariableRef("plot::y#4"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.allocate(new VariableRef("plot::line#0"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.allocate(new VariableRef("plot::line#1"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.allocate(new VariableRef("plot::line#2"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.allocate(new VariableRef("plot::line#3"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.allocate(new VariableRef("plot::line#4"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.allocate(new VariableRef("plot::$3"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("prepare::i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("prepare::i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("prepare::i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::srcIdx#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::srcIdx#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::srcIdx#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::srcIdx#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::srcIdx#3"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::srcIdx#4"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::dstIdx#0"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("flip::dstIdx#1"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("flip::dstIdx#2"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("flip::dstIdx#3"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("flip::dstIdx#4"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("flip::dstIdx#5"), RegisterAllocation.getRegisterY());
|
||||
allocation.allocate(new VariableRef("flip::c#0"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.allocate(new VariableRef("flip::c#1"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.allocate(new VariableRef("flip::c#2"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.allocate(new VariableRef("flip::r#0"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.allocate(new VariableRef("flip::r#1"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.allocate(new VariableRef("flip::r#2"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.allocate(new VariableRef("flip::r#3"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.allocate(new VariableRef("flip::r#4"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.allocate(new VariableRef("flip::i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("flip::$0"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("flip::$8"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("flip::$4"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("main::$1"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("main::$3"), RegisterAllocation.getRegisterA());
|
||||
allocation.allocate(new VariableRef("main::c#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("main::c#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("main::c#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("main::c#3"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(new VariableRef("main::c#4"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("plot::i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("plot::i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("plot::i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("plot::i#3"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("plot::i#4"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("plot::x#0"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("plot::x#1"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("plot::x#2"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("plot::y#0"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.setRegister(new VariableRef("plot::y#1"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.setRegister(new VariableRef("plot::y#2"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.setRegister(new VariableRef("plot::y#3"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.setRegister(new VariableRef("plot::y#4"), new RegisterAllocation.RegisterZpByte(100));
|
||||
allocation.setRegister(new VariableRef("plot::line#0"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.setRegister(new VariableRef("plot::line#1"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.setRegister(new VariableRef("plot::line#2"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.setRegister(new VariableRef("plot::line#3"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.setRegister(new VariableRef("plot::line#4"), new RegisterAllocation.RegisterZpPointerByte(101));
|
||||
allocation.setRegister(new VariableRef("plot::$3"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("prepare::i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("prepare::i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("prepare::i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::srcIdx#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::srcIdx#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::srcIdx#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::srcIdx#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::srcIdx#3"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::srcIdx#4"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::dstIdx#0"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("flip::dstIdx#1"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("flip::dstIdx#2"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("flip::dstIdx#3"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("flip::dstIdx#4"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("flip::dstIdx#5"), RegisterAllocation.getRegisterY());
|
||||
allocation.setRegister(new VariableRef("flip::c#0"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.setRegister(new VariableRef("flip::c#1"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.setRegister(new VariableRef("flip::c#2"), new RegisterAllocation.RegisterZpByte(103));
|
||||
allocation.setRegister(new VariableRef("flip::r#0"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.setRegister(new VariableRef("flip::r#1"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.setRegister(new VariableRef("flip::r#2"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.setRegister(new VariableRef("flip::r#3"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.setRegister(new VariableRef("flip::r#4"), new RegisterAllocation.RegisterZpByte(104));
|
||||
allocation.setRegister(new VariableRef("flip::i#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::i#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("flip::$0"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("flip::$8"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("flip::$4"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("main::$1"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("main::$3"), RegisterAllocation.getRegisterA());
|
||||
allocation.setRegister(new VariableRef("main::c#0"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("main::c#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("main::c#2"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("main::c#3"), RegisterAllocation.getRegisterX());
|
||||
allocation.setRegister(new VariableRef("main::c#4"), RegisterAllocation.getRegisterX());
|
||||
*/
|
||||
|
||||
|
||||
@ -121,16 +121,16 @@ public class Pass3CustomRegisters {
|
||||
} else if (symbol instanceof VariableIntermediate || symbol instanceof VariableVersion) {
|
||||
Variable var = (Variable) symbol;
|
||||
if (symbol.getType().equals(SymbolTypeBasic.BYTE)) {
|
||||
allocation.allocate(var.getRef(), new RegisterAllocation.RegisterZpByte(currentZp++));
|
||||
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpByte(currentZp++));
|
||||
} else if (symbol.getType().equals(SymbolTypeBasic.WORD)) {
|
||||
allocation.allocate(var.getRef(), new RegisterAllocation.RegisterZpWord(currentZp));
|
||||
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpWord(currentZp));
|
||||
currentZp = currentZp + 2;
|
||||
} else if (symbol.getType().equals(SymbolTypeBasic.BOOLEAN)) {
|
||||
allocation.allocate(var.getRef(), new RegisterAllocation.RegisterZpBool(currentZp++));
|
||||
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpBool(currentZp++));
|
||||
} else if (symbol.getType().equals(SymbolTypeBasic.VOID)) {
|
||||
// No need to allocate register for VOID value
|
||||
// No need to setRegister register for VOID value
|
||||
} else if (symbol.getType() instanceof SymbolTypePointer) {
|
||||
allocation.allocate(var.getRef(), new RegisterAllocation.RegisterZpPointerByte(currentZp));
|
||||
allocation.setRegister(var.getRef(), new RegisterAllocation.RegisterZpPointerByte(currentZp));
|
||||
currentZp = currentZp + 2;
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled variable type " + symbol);
|
||||
|
@ -5,7 +5,10 @@ import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.asm.parser.AsmClobber;
|
||||
import dk.camelot64.kickc.icl.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/*** Uplift one variable into the A register - and check if the program still works */
|
||||
public class Pass3RegisterUplifting {
|
||||
@ -30,31 +33,56 @@ public class Pass3RegisterUplifting {
|
||||
* Uplift one variable
|
||||
*/
|
||||
public void uplift() {
|
||||
|
||||
VariableRegisterWeights variableRegisterWeights = program.getScope().getVariableRegisterWeights();
|
||||
LiveRangeEquivalenceClassSet equivalenceClassSet = program.getScope().getLiveRangeEquivalenceClassSet();
|
||||
|
||||
double maxWeight = 0.0;
|
||||
Variable maxVar = null;
|
||||
LiveRangeEquivalenceClass maxEquivalenceClass = null;
|
||||
|
||||
Collection<Variable> allVars = program.getScope().getAllVariables(true);
|
||||
RegisterAllocation allocation = program.getScope().getAllocation();
|
||||
|
||||
for (Variable variable : allVars) {
|
||||
RegisterAllocation.Register currentRegister = allocation.getRegister(variable.getRef());
|
||||
if (currentRegister!=null && currentRegister.isZp()) {
|
||||
Double w = variableRegisterWeights.getWeight(variable.getRef());
|
||||
if (w != null && w > maxWeight) {
|
||||
maxWeight = w;
|
||||
maxVar = variable;
|
||||
}
|
||||
// Find the live range equivalence class with the highest total weight
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClassSet.getEquivalenceClasses()) {
|
||||
double totalWeight = 0.0;
|
||||
List<VariableRef> vars = equivalenceClass.getVariables();
|
||||
for (VariableRef var : vars) {
|
||||
Double varWeight = variableRegisterWeights.getWeight(var);
|
||||
totalWeight += varWeight;
|
||||
}
|
||||
if (maxWeight < totalWeight) {
|
||||
maxEquivalenceClass = equivalenceClass;
|
||||
maxWeight = totalWeight;
|
||||
}
|
||||
}
|
||||
// Found max variable!
|
||||
if(maxVar!=null) {
|
||||
log.append("Uplifting of variable " + maxVar + " to A");
|
||||
allocation.allocate(maxVar.getRef(), new RegisterAllocation.RegisterAByte());
|
||||
|
||||
if (maxEquivalenceClass != null) {
|
||||
log.append("Uplifting max weight " + maxWeight + " live range equivalence class " + maxEquivalenceClass);
|
||||
// Try the A register first
|
||||
List<RegisterAllocation.Register> registers =
|
||||
Arrays.asList(
|
||||
RegisterAllocation.getRegisterA(),
|
||||
RegisterAllocation.getRegisterX(),
|
||||
RegisterAllocation.getRegisterY());
|
||||
for (RegisterAllocation.Register register : registers) {
|
||||
attemptUplift(maxEquivalenceClass, register);
|
||||
}
|
||||
}
|
||||
|
||||
RegisterAllocation allocation = program.getScope().getLiveRangeEquivalenceClassSet().createRegisterAllocation();
|
||||
program.getScope().setAllocation(allocation);
|
||||
|
||||
}
|
||||
|
||||
private void attemptUplift(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) {
|
||||
RegisterAllocation allocation = program.getScope().getLiveRangeEquivalenceClassSet().createRegisterAllocation();
|
||||
for (VariableRef var : equivalenceClass.getVariables()) {
|
||||
allocation.setRegister(var, register);
|
||||
}
|
||||
program.getScope().setAllocation(allocation);
|
||||
Pass3AssertNoCpuClobber clobber = new Pass3AssertNoCpuClobber(program, log);
|
||||
if (clobber.hasClobberProblem()) {
|
||||
log.append("Uplift to " + register + " resulted in clobber.");
|
||||
} else {
|
||||
log.append("Uplift to " + register + " succesfull.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,8 +19,17 @@ public class Pass3RegistersFinalize {
|
||||
|
||||
public void allocate() {
|
||||
LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet = program.getScope().getLiveRangeEquivalenceClassSet();
|
||||
reallocateZp(liveRangeEquivalenceClassSet);
|
||||
RegisterAllocation allocation = liveRangeEquivalenceClassSet.createRegisterAllocation();
|
||||
program.getScope().setAllocation(allocation);
|
||||
}
|
||||
|
||||
RegisterAllocation allocation = new RegisterAllocation();
|
||||
/**
|
||||
* Reallocate all ZP registers to minimize ZP usage
|
||||
*
|
||||
* @param liveRangeEquivalenceClassSet The
|
||||
*/
|
||||
private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||
RegisterAllocation.Register register = equivalenceClass.getRegister();
|
||||
if(register.isZp()) {
|
||||
@ -28,14 +37,12 @@ public class Pass3RegistersFinalize {
|
||||
VariableRef variable = equivalenceClass.getVariables().get(0);
|
||||
Variable symbol = program.getScope().getVariable(variable);
|
||||
register = allocateNewRegisterZp(symbol.getType());
|
||||
log.append("Re-allocated ZP register from "+before+" to "+register.toString());
|
||||
}
|
||||
for (VariableRef variable : equivalenceClass.getVariables()) {
|
||||
allocation.allocate(variable, register);
|
||||
equivalenceClass.setRegister(register);
|
||||
if(!before.equals(register.toString())) {
|
||||
log.append("Re-allocated ZP register from " + before + " to " + register.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
program.getScope().setAllocation(allocation);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +68,7 @@ public class Pass3RegistersFinalize {
|
||||
} else if (varType.equals(SymbolTypeBasic.BOOLEAN)) {
|
||||
return new RegisterAllocation.RegisterZpBool(currentZp++);
|
||||
} else if (varType.equals(SymbolTypeBasic.VOID)) {
|
||||
// No need to allocate register for VOID value
|
||||
// No need to setRegister register for VOID value
|
||||
return null;
|
||||
} else if (varType instanceof SymbolTypePointer) {
|
||||
RegisterAllocation.RegisterZpPointerByte registerZpPointerByte =
|
||||
|
@ -178,7 +178,7 @@ public class Pass3ZeroPageAllocation {
|
||||
} else if (varType.equals(SymbolTypeBasic.BOOLEAN)) {
|
||||
return new RegisterAllocation.RegisterZpBool(currentZp++);
|
||||
} else if (varType.equals(SymbolTypeBasic.VOID)) {
|
||||
// No need to allocate register for VOID value
|
||||
// No need to setRegister register for VOID value
|
||||
return null;
|
||||
} else if (varType instanceof SymbolTypePointer) {
|
||||
RegisterAllocation.RegisterZpPointerByte registerZpPointerByte =
|
||||
|
@ -23,56 +23,63 @@ public class TestCompilationOutput extends TestCase {
|
||||
}
|
||||
|
||||
public void testFlipper() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("flipper-rex2");
|
||||
compileAndCompare("flipper-rex2");
|
||||
}
|
||||
|
||||
public void testBresenham() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("bresenham");
|
||||
compileAndCompare("bresenham");
|
||||
}
|
||||
|
||||
public void testMinus() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("minus");
|
||||
compileAndCompare("minus");
|
||||
}
|
||||
|
||||
public void testLoopMin() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("loopmin");
|
||||
compileAndCompare("loopmin");
|
||||
}
|
||||
|
||||
public void testSumMin() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("summin");
|
||||
compileAndCompare("summin");
|
||||
}
|
||||
|
||||
public void testLoopSplit() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("loopsplit");
|
||||
compileAndCompare("loopsplit");
|
||||
}
|
||||
|
||||
public void testLoopNest() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("loopnest");
|
||||
compileAndCompare("loopnest");
|
||||
}
|
||||
|
||||
public void testLoopNest2() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("loopnest2");
|
||||
compileAndCompare("loopnest2");
|
||||
}
|
||||
|
||||
public void testFibMem() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("fibmem");
|
||||
compileAndCompare("fibmem");
|
||||
}
|
||||
|
||||
public void testPtrTest() throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile("ptrtest");
|
||||
compileAndCompare("ptrtest");
|
||||
}
|
||||
|
||||
public void testUseGlobal() throws IOException, URISyntaxException {
|
||||
compileAndCompare("useglobal");
|
||||
}
|
||||
|
||||
public void testUseUninitialized() throws IOException, URISyntaxException {
|
||||
String filename = "useuninitialized";
|
||||
compileAndCompare(filename);
|
||||
}
|
||||
|
||||
public void testUseUndeclared() throws IOException, URISyntaxException {
|
||||
compileAndCompare("useundeclared");
|
||||
}
|
||||
|
||||
|
||||
private void compileAndCompare(String filename) throws IOException, URISyntaxException {
|
||||
TestCompilationOutput tester = new TestCompilationOutput();
|
||||
tester.testFile(filename);
|
||||
}
|
||||
|
||||
private void testFile(String fileName) throws IOException, URISyntaxException {
|
||||
String inputPath = testPath + fileName + ".kc";
|
||||
|
6
src/main/java/dk/camelot64/kickc/test/useglobal.kc
Normal file
6
src/main/java/dk/camelot64/kickc/test/useglobal.kc
Normal file
@ -0,0 +1,6 @@
|
||||
// Tests procedures using global variables (should not fail)
|
||||
byte* SCREEN = $0400;
|
||||
main();
|
||||
void main() {
|
||||
*SCREEN = 1;
|
||||
}
|
5
src/main/java/dk/camelot64/kickc/test/useundeclared.kc
Normal file
5
src/main/java/dk/camelot64/kickc/test/useundeclared.kc
Normal file
@ -0,0 +1,5 @@
|
||||
// Uses an undeclared variable - should fail gracefully
|
||||
main();
|
||||
void main() {
|
||||
byte s = b+1;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
// Use an uninitialized variable - should fail gracefully!
|
||||
|
||||
main();
|
||||
void main() {
|
||||
byte b;
|
||||
byte s=b+1;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user