mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-20 02:32:36 +00:00
Fixed issue with const/label.
This commit is contained in:
parent
ecf4181ce1
commit
29aa5322b2
@ -51,7 +51,7 @@ public class Pass4CodeGeneration {
|
||||
generateComments(asm, program.getFileComments());
|
||||
|
||||
Number programPc;
|
||||
if(program.getProgramPc()!=null) {
|
||||
if(program.getProgramPc() != null) {
|
||||
programPc = program.getProgramPc();
|
||||
} else {
|
||||
programPc = 0x080d;
|
||||
@ -306,40 +306,38 @@ public class Pass4CodeGeneration {
|
||||
Collection<Integer> constRefStatements = program.getVariableReferenceInfos().getConstRefStatements(constantVar.getRef());
|
||||
if(constRefStatements != null) {
|
||||
for(Integer constRefStmtIdx : constRefStatements) {
|
||||
Statement statement = program.getStatementInfos().getStatement(constRefStmtIdx);
|
||||
ScopeRef refScope = program.getStatementInfos().getBlock(constRefStmtIdx).getScope();
|
||||
if(!refScope.equals(scopeRef)) {
|
||||
Statement statement = program.getStatementInfos().getStatement(constRefStmtIdx);
|
||||
if(statement instanceof StatementPhiBlock) {
|
||||
// Const reference in PHI block - examine if the only predecessor is current scope
|
||||
boolean found = false;
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
RValue phiRRValue = phiRValue.getrValue();
|
||||
Collection<ConstantRef> phiRValueConstRefs = PassNVariableReferenceInfos.getReferencedConsts(phiRRValue);
|
||||
for(ConstantRef phiRValueConstRef : phiRValueConstRefs) {
|
||||
if(phiRValueConstRef.equals(constantVar.getRef())) {
|
||||
found = true;
|
||||
// Found the constant
|
||||
LabelRef pred = phiRValue.getPredecessor();
|
||||
ControlFlowBlock predBlock = program.getGraph().getBlock(pred);
|
||||
ScopeRef predScope = predBlock.getScope();
|
||||
if(!predScope.equals(scopeRef)) {
|
||||
// Scopes in PHI RValue differs from const scope - generate label
|
||||
useLabel = true;
|
||||
}
|
||||
if(statement instanceof StatementPhiBlock) {
|
||||
// Const reference in PHI block - examine if the only predecessor is current scope
|
||||
boolean found = false;
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
RValue phiRRValue = phiRValue.getrValue();
|
||||
Collection<ConstantRef> phiRValueConstRefs = PassNVariableReferenceInfos.getReferencedConsts(phiRRValue);
|
||||
for(ConstantRef phiRValueConstRef : phiRValueConstRefs) {
|
||||
if(phiRValueConstRef.equals(constantVar.getRef())) {
|
||||
found = true;
|
||||
// Found the constant
|
||||
LabelRef pred = phiRValue.getPredecessor();
|
||||
ControlFlowBlock predBlock = program.getGraph().getBlock(pred);
|
||||
ScopeRef predScope = predBlock.getScope();
|
||||
if(!predScope.equals(scopeRef)) {
|
||||
// Scopes in PHI RValue differs from const scope - generate label
|
||||
useLabel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
// PHI-reference is complex - generate label
|
||||
program.getLog().append("Warning: Complex PHI-value using constant. Using .label as fallback. " + statement);
|
||||
useLabel = true;
|
||||
}
|
||||
} else {
|
||||
// Used in a non-PHI statement in another scope - generate label
|
||||
}
|
||||
if(!found) {
|
||||
// PHI-reference is complex - generate label
|
||||
program.getLog().append("Warning: Complex PHI-value using constant. Using .label as fallback. " + statement);
|
||||
useLabel = true;
|
||||
}
|
||||
} else if(!refScope.equals(scopeRef)) {
|
||||
// Used in a non-PHI statement in another scope - generate label
|
||||
useLabel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,11 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRobozzleLabelProblem() throws IOException, URISyntaxException {
|
||||
compileAndCompare("robozzle64-label-problem", log());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGlobalPc() throws IOException, URISyntaxException {
|
||||
compileAndCompare("global-pc");
|
||||
|
11
src/test/kc/robozzle64-label-problem.kc
Normal file
11
src/test/kc/robozzle64-label-problem.kc
Normal file
@ -0,0 +1,11 @@
|
||||
import "multiply.kc"
|
||||
|
||||
void main() {
|
||||
word* screen = 0x0400;
|
||||
for( byte y: 0..5) {
|
||||
word z1 = mul8u(y,40);
|
||||
*screen++ = z1;
|
||||
word z2 = mul8u(y,40);
|
||||
*screen++ = z2;
|
||||
}
|
||||
}
|
87
src/test/ref/robozzle64-label-problem.asm
Normal file
87
src/test/ref/robozzle64-label-problem.asm
Normal file
@ -0,0 +1,87 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_WORD = 2
|
||||
main: {
|
||||
.label z1 = 5
|
||||
.label screen = 3
|
||||
.label z2 = 5
|
||||
.label y = 2
|
||||
lda #<$400
|
||||
sta screen
|
||||
lda #>$400
|
||||
sta screen+1
|
||||
lda #0
|
||||
sta y
|
||||
b1:
|
||||
ldx y
|
||||
lda #mul8u.b
|
||||
sta mul8u.mb
|
||||
lda #0
|
||||
sta mul8u.mb+1
|
||||
jsr mul8u
|
||||
ldy #0
|
||||
lda z1
|
||||
sta (screen),y
|
||||
iny
|
||||
lda z1+1
|
||||
sta (screen),y
|
||||
ldx y
|
||||
lda #mul8u.b
|
||||
sta mul8u.mb
|
||||
lda #0
|
||||
sta mul8u.mb+1
|
||||
jsr mul8u
|
||||
ldy #SIZEOF_WORD
|
||||
lda z2
|
||||
sta (screen),y
|
||||
iny
|
||||
lda z2+1
|
||||
sta (screen),y
|
||||
lda #SIZEOF_WORD+SIZEOF_WORD
|
||||
clc
|
||||
adc screen
|
||||
sta screen
|
||||
bcc !+
|
||||
inc screen+1
|
||||
!:
|
||||
inc y
|
||||
lda #6
|
||||
cmp y
|
||||
bne b1
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
|
||||
// mul8u(byte register(X) a)
|
||||
mul8u: {
|
||||
.label b = $28
|
||||
.label mb = 7
|
||||
.label res = 5
|
||||
.label return = 5
|
||||
lda #0
|
||||
sta res
|
||||
sta res+1
|
||||
b1:
|
||||
cpx #0
|
||||
bne b2
|
||||
rts
|
||||
b2:
|
||||
txa
|
||||
and #1
|
||||
cmp #0
|
||||
beq b3
|
||||
lda res
|
||||
clc
|
||||
adc mb
|
||||
sta res
|
||||
lda res+1
|
||||
adc mb+1
|
||||
sta res+1
|
||||
b3:
|
||||
txa
|
||||
lsr
|
||||
tax
|
||||
asl mb
|
||||
rol mb+1
|
||||
jmp b1
|
||||
}
|
61
src/test/ref/robozzle64-label-problem.cfg
Normal file
61
src/test/ref/robozzle64-label-problem.cfg
Normal file
@ -0,0 +1,61 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
[5] (word*) main::screen#1 ← phi( main/(word*) 1024 main::@3/(word*) main::screen#2 )
|
||||
[5] (byte) main::y#2 ← phi( main/(byte) 0 main::@3/(byte) main::y#1 )
|
||||
[6] (byte) mul8u::a#1 ← (byte) main::y#2
|
||||
[7] call mul8u
|
||||
[8] (word) mul8u::return#2 ← (word) mul8u::res#2
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[9] (word) main::z1#0 ← (word) mul8u::return#2
|
||||
[10] *((word*) main::screen#1) ← (word) main::z1#0
|
||||
[11] (byte) mul8u::a#2 ← (byte) main::y#2
|
||||
[12] call mul8u
|
||||
[13] (word) mul8u::return#3 ← (word) mul8u::res#2
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2
|
||||
[14] (word) main::z2#0 ← (word) mul8u::return#3
|
||||
[15] *((word*) main::screen#1 + (const byte) SIZEOF_WORD) ← (word) main::z2#0
|
||||
[16] (word*) main::screen#2 ← (word*) main::screen#1 + (const byte) SIZEOF_WORD+(const byte) SIZEOF_WORD
|
||||
[17] (byte) main::y#1 ← ++ (byte) main::y#2
|
||||
[18] if((byte) main::y#1!=(byte) 6) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[19] return
|
||||
to:@return
|
||||
mul8u: scope:[mul8u] from main::@1 main::@2
|
||||
[20] (byte) mul8u::a#6 ← phi( main::@1/(byte) mul8u::a#1 main::@2/(byte) mul8u::a#2 )
|
||||
[20] (word) mul8u::mb#0 ← phi( main::@1/(const byte) mul8u::b#0 main::@2/(const byte) mul8u::b#1 )
|
||||
to:mul8u::@1
|
||||
mul8u::@1: scope:[mul8u] from mul8u mul8u::@3
|
||||
[21] (word) mul8u::mb#2 ← phi( mul8u/(word) mul8u::mb#0 mul8u::@3/(word) mul8u::mb#1 )
|
||||
[21] (word) mul8u::res#2 ← phi( mul8u/(byte) 0 mul8u::@3/(word) mul8u::res#6 )
|
||||
[21] (byte) mul8u::a#3 ← phi( mul8u/(byte) mul8u::a#6 mul8u::@3/(byte) mul8u::a#0 )
|
||||
[22] if((byte) mul8u::a#3!=(byte) 0) goto mul8u::@2
|
||||
to:mul8u::@return
|
||||
mul8u::@return: scope:[mul8u] from mul8u::@1
|
||||
[23] return
|
||||
to:@return
|
||||
mul8u::@2: scope:[mul8u] from mul8u::@1
|
||||
[24] (byte~) mul8u::$1 ← (byte) mul8u::a#3 & (byte) 1
|
||||
[25] if((byte~) mul8u::$1==(byte) 0) goto mul8u::@3
|
||||
to:mul8u::@4
|
||||
mul8u::@4: scope:[mul8u] from mul8u::@2
|
||||
[26] (word) mul8u::res#1 ← (word) mul8u::res#2 + (word) mul8u::mb#2
|
||||
to:mul8u::@3
|
||||
mul8u::@3: scope:[mul8u] from mul8u::@2 mul8u::@4
|
||||
[27] (word) mul8u::res#6 ← phi( mul8u::@2/(word) mul8u::res#2 mul8u::@4/(word) mul8u::res#1 )
|
||||
[28] (byte) mul8u::a#0 ← (byte) mul8u::a#3 >> (byte) 1
|
||||
[29] (word) mul8u::mb#1 ← (word) mul8u::mb#2 << (byte) 1
|
||||
to:mul8u::@1
|
1148
src/test/ref/robozzle64-label-problem.log
Normal file
1148
src/test/ref/robozzle64-label-problem.log
Normal file
File diff suppressed because it is too large
Load Diff
1
src/test/ref/robozzle64-label-problem.sym
Normal file
1
src/test/ref/robozzle64-label-problem.sym
Normal file
@ -0,0 +1 @@
|
||||
program
|
Loading…
Reference in New Issue
Block a user