1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Added boolean pointer test and a test that modifying a constant results in an error.

This commit is contained in:
jespergravgaard 2018-04-27 14:49:35 +02:00
parent ad54c264c4
commit 80f57ed5f1
15 changed files with 578 additions and 3 deletions

View File

@ -20,7 +20,7 @@ public class CompileLog {
/**
* Should fragment synthesis be verbose.
*/
private boolean verboseFragmentLog = false;
private boolean verboseFragmentLog = true;
/**
* Should ASM optimization be verbose.
@ -35,7 +35,7 @@ public class CompileLog {
/**
* Should the log be output to System.out while being built
*/
private boolean sysOut = false;
private boolean sysOut = true;
public CompileLog() {
this.log = new StringBuilder();

View File

@ -28,6 +28,8 @@ public class AsmFormat {
return getAsmParamName(constantVar.getScope().getRef(), asmName, codeScope);
} else if(value instanceof ConstantInteger) {
return getAsmNumber(((ConstantInteger) value).getValue());
} else if(value instanceof ConstantBool) {
return getAsmBool(((ConstantBool) value).getBool());
} else if(value instanceof ConstantChar) {
return "'" + ((ConstantChar) value).getValue() + "'";
} else if(value instanceof ConstantString) {
@ -76,7 +78,7 @@ public class AsmFormat {
} else {
return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xff), Operators.BOOL_AND, operand), outerPrecedence, codeScope);
}
} else if(Operators.CAST_WORD.equals(operator) || Operators.CAST_SWORD.equals(operator) || Operators.CAST_PTRBY.equals(operator)) {
} else if(Operators.CAST_WORD.equals(operator) || Operators.CAST_SWORD.equals(operator) || Operators.CAST_PTRBY.equals(operator)|| Operators.CAST_PTRBO.equals(operator)) {
SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand);
if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || SymbolType.isByte(operandType) || SymbolType.isSByte(operandType) || operandType instanceof SymbolTypePointer) {
// No cast needed
@ -124,6 +126,7 @@ public class AsmFormat {
}
}
public static String getAsmNumber(Number number) {
if(number instanceof Long || number instanceof Integer) {
if(number.longValue() >= 0L && number.longValue() <= 9L) {
@ -135,6 +138,19 @@ public class AsmFormat {
throw new RuntimeException("Unsupported number type " + number);
}
/**
* Get the ASM code for a boolean value
* @param bool the boolean vallue
* @return "0" / "1"
*/
private static String getAsmBool(Boolean bool) {
if(bool) {
return "1";
} else {
return "0";
}
}
/**
* Get the ASM parameter for a specific bound constant/ variable
*

View File

@ -315,6 +315,8 @@ public class AsmFragmentInstanceSpec {
return "pwu";
} else if(SymbolType.isSWord(elementType)) {
return "pws";
} else if(SymbolType.BOOLEAN.equals(elementType)) {
return "pbo";
} else {
throw new RuntimeException("Not implemented " + type);
}

View File

@ -0,0 +1 @@
lda #{c1}

View File

@ -0,0 +1,31 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantPointer;
/** Unary Cast to boolean operator ( (byte) x ) */
public class OperatorCastBool extends OperatorUnary {
public OperatorCastBool(int precedence) {
super("((boolean))", "_bool_", precedence);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
if(value instanceof ConstantInteger) {
return new ConstantInteger(0x1 & ((ConstantInteger) value).getValue());
} else if(value instanceof ConstantPointer) {
return new ConstantInteger(0x1 & ((ConstantPointer) value).getLocation());
}
throw new CompileError("Calculation not implemented " + getOperator() + " " + value );
}
@Override
public SymbolType inferType(SymbolTypeSimple operandType) {
return SymbolType.BOOLEAN;
}
}

View File

@ -0,0 +1,30 @@
package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeSimple;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantPointer;
/** Unary Cast to boolean pointer operator ( (boolean*) x ) */
public class OperatorCastPtrBool extends OperatorUnary {
public OperatorCastPtrBool(int precedence) {
super("((boolean*))", "_ptrbo_", precedence);
}
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral value) {
if(value instanceof ConstantInteger) {
return new ConstantPointer(((ConstantInteger) value).getInteger(), SymbolType.BOOLEAN);
}
throw new CompileError("Calculation not implemented " + getOperator() + " " + value );
}
@Override
public SymbolType inferType(SymbolTypeSimple operandType) {
return new SymbolTypePointer(SymbolType.BOOLEAN);
}
}

View File

@ -26,6 +26,8 @@ public class Operators {
public static final OperatorUnary CAST_DWORD = new OperatorCastDWord(2);
public static final OperatorUnary CAST_SDWORD = new OperatorCastSDWord(2);
public static final OperatorUnary CAST_PTRBY = new OperatorCastPtrByte(2);
public static final OperatorUnary CAST_PTRBO = new OperatorCastPtrBool(2);
public static final OperatorUnary CAST_BOOL= new OperatorCastBool(2);
public static final OperatorBinary MULTIPLY = new OperatorMultiply(3);
public static final OperatorBinary DIVIDE = new OperatorDivide(3);
public static final OperatorBinary PLUS = new OperatorPlus(4);
@ -133,8 +135,12 @@ public class Operators {
return CAST_DWORD;
} else if(SymbolType.SDWORD.equals(castType)) {
return CAST_SDWORD;
} else if(SymbolType.BOOLEAN.equals(castType)) {
return CAST_BOOL;
} else if(castType instanceof SymbolTypePointer && SymbolType.BYTE.equals(((SymbolTypePointer) castType).getElementType())) {
return CAST_PTRBY;
} else if(castType instanceof SymbolTypePointer && SymbolType.BOOLEAN.equals(((SymbolTypePointer) castType).getElementType())) {
return CAST_PTRBO;
} else {
throw new RuntimeException("Unknown cast type " + castType);

View File

@ -235,6 +235,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
case "((dword))":
case "((signed dword))":
case "((byte*))":
case "((boolean*))":
case "!":
return new ConstantUnary(operator, c);
case "*": { // pointer dereference - not constant

View File

@ -119,6 +119,11 @@ public class TestPrograms {
compileAndCompare("bool-function");
}
@Test
public void testBoolPointer() throws IOException, URISyntaxException {
compileAndCompare("bool-pointer");
}
@Test
public void testC64DtvBlitterMin() throws IOException, URISyntaxException {
compileAndCompare("c64dtv-blittermin");
@ -754,6 +759,10 @@ public class TestPrograms {
assertError("recursion-error-complex", "Recursion");
}
@Test
public void testConstPointerModifyError() throws IOException, URISyntaxException {
assertError("const-pointer-modify", "Constants can not be modified");
}
private void assertError(String kcFile, String expectError) throws IOException, URISyntaxException {
try {

View File

@ -0,0 +1,13 @@
// Tests a pointer to a boolean
void main() {
boolean* bscreen = $400;
bscreen[0] = true;
bscreen[1] = false;
bscreen = bscreen+2;
*bscreen = true;
if(*bscreen) {
*(++bscreen)= true;
}
}

View File

@ -0,0 +1,8 @@
// Test that modifying constant pointers fail
void main() {
const byte* screen = $400;
screen[0] = 'c';
screen++;
screen[0] = 'm';
}

View File

@ -0,0 +1,20 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
jsr main
main: {
lda #1
sta $400+0
lda #0
sta $400+1
lda #1
sta $400+2
cmp #0
bne b2
breturn:
rts
b2:
lda #1
sta $400+2+1
jmp breturn
}

View File

@ -0,0 +1,21 @@
@begin: scope:[] from
[0] phi() [ ] ( )
to:@1
@1: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main param-assignment [ ] ( )
to:@end
@end: scope:[] from @1
[3] phi() [ ] ( )
main: scope:[main] from @1
[4] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 0) ← true [ ] ( main:2 [ ] )
[5] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 1) ← false [ ] ( main:2 [ ] )
[6] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] )
[7] if(*(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2)) goto main::@2 [ ] ( main:2 [ ] )
to:main::@return
main::@return: scope:[main] from main main::@2
[8] return [ ] ( main:2 [ ] )
to:@return
main::@2: scope:[main] from main
[9] *(++((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] )
to:main::@return

View File

@ -0,0 +1,409 @@
PARSING src/test/java/dk/camelot64/kickc/test/kc/bool-pointer.kc
// Tests a pointer to a boolean
void main() {
boolean* bscreen = $400;
bscreen[0] = true;
bscreen[1] = false;
bscreen = bscreen+2;
*bscreen = true;
if(*bscreen) {
*(++bscreen)= true;
}
}
Adding pre/post-modifier (boolean*) main::bscreen ← ++ (boolean*) main::bscreen
SYMBOLS
(label) @1
(label) @begin
(label) @end
(void()) main()
(boolean*~) main::$0
(boolean~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
(boolean*) main::bscreen
Promoting word/signed word/dword/signed dword to boolean* in main::bscreen ← ((boolean*)) 1024
INITIAL CONTROL FLOW GRAPH
@begin: scope:[] from
to:@1
main: scope:[main] from
(boolean*) main::bscreen ← ((boolean*)) (word/signed word/dword/signed dword) 1024
*((boolean*) main::bscreen + (byte/signed byte/word/signed word/dword/signed dword) 0) ← true
*((boolean*) main::bscreen + (byte/signed byte/word/signed word/dword/signed dword) 1) ← false
(boolean*~) main::$0 ← (boolean*) main::bscreen + (byte/signed byte/word/signed word/dword/signed dword) 2
(boolean*) main::bscreen ← (boolean*~) main::$0
*((boolean*) main::bscreen) ← true
(boolean~) main::$1 ← ! *((boolean*) main::bscreen)
if((boolean~) main::$1) goto main::@1
to:main::@2
main::@1: scope:[main] from main main::@2
to:main::@return
main::@2: scope:[main] from main
(boolean*) main::bscreen ← ++ (boolean*) main::bscreen
*((boolean*) main::bscreen) ← true
to:main::@1
main::@return: scope:[main] from main::@1
return
to:@return
@1: scope:[] from @begin
call main
to:@end
@end: scope:[] from @1
PROCEDURE MODIFY VARIABLE ANALYSIS
Completing Phi functions...
CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
@begin: scope:[] from
to:@1
main: scope:[main] from @1
(boolean*) main::bscreen#0 ← ((boolean*)) (word/signed word/dword/signed dword) 1024
*((boolean*) main::bscreen#0 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← true
*((boolean*) main::bscreen#0 + (byte/signed byte/word/signed word/dword/signed dword) 1) ← false
(boolean*~) main::$0 ← (boolean*) main::bscreen#0 + (byte/signed byte/word/signed word/dword/signed dword) 2
(boolean*) main::bscreen#1 ← (boolean*~) main::$0
*((boolean*) main::bscreen#1) ← true
(boolean~) main::$1 ← ! *((boolean*) main::bscreen#1)
if((boolean~) main::$1) goto main::@1
to:main::@2
main::@1: scope:[main] from main
to:main::@return
main::@2: scope:[main] from main
(boolean*) main::bscreen#3 ← phi( main/(boolean*) main::bscreen#1 )
(boolean*) main::bscreen#2 ← ++ (boolean*) main::bscreen#3
*((boolean*) main::bscreen#2) ← true
to:main::@return
main::@return: scope:[main] from main::@1 main::@2
return
to:@return
@1: scope:[] from @begin
call main param-assignment
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(void()) main()
(boolean*~) main::$0
(boolean~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
(boolean*) main::bscreen
(boolean*) main::bscreen#0
(boolean*) main::bscreen#1
(boolean*) main::bscreen#2
(boolean*) main::bscreen#3
OPTIMIZING CONTROL FLOW GRAPH
Culled Empty Block (label) main::@1
Culled Empty Block (label) @2
Succesful SSA optimization Pass2CullEmptyBlocks
Alias (boolean*) main::bscreen#1 = (boolean*~) main::$0 (boolean*) main::bscreen#3
Succesful SSA optimization Pass2AliasElimination
Rewriting ! if()-condition to reversed if() (boolean~) main::$1 ← ! *((boolean*) main::bscreen#1)
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Constant (const boolean*) main::bscreen#0 = ((boolean*))1024
Succesful SSA optimization Pass2ConstantIdentification
Constant (const boolean*) main::bscreen#1 = main::bscreen#0+2
Succesful SSA optimization Pass2ConstantIdentification
Constant (const boolean*) main::bscreen#2 = ++main::bscreen#1
Succesful SSA optimization Pass2ConstantIdentification
Consolidated array index constant in *(main::bscreen#0+0)
Consolidated array index constant in *(main::bscreen#0+1)
Succesful SSA optimization Pass2ConstantAdditionElimination
OPTIMIZING CONTROL FLOW GRAPH
Inlining constant with different constant siblings (const boolean*) main::bscreen#0
Inlining constant with different constant siblings (const boolean*) main::bscreen#0
Inlining constant with different constant siblings (const boolean*) main::bscreen#1
Inlining constant with different constant siblings (const boolean*) main::bscreen#1
Inlining constant with different constant siblings (const boolean*) main::bscreen#2
Inlining constant with different constant siblings (const boolean*) main::bscreen#2
Constant inlined main::bscreen#2 = ++((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2
Constant inlined main::bscreen#0 = ((boolean*))(word/signed word/dword/signed dword) 1024
Constant inlined main::bscreen#1 = ((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2
Succesful SSA optimization Pass2ConstantInlining
Block Sequence Planned @begin @1 @end main main::@return main::@2
Block Sequence Planned @begin @1 @end main main::@return main::@2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Propagating live ranges...
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Block Sequence Planned @begin @1 @end main main::@return main::@2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Propagating live ranges...
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi() [ ] ( )
to:@1
@1: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main param-assignment [ ] ( )
to:@end
@end: scope:[] from @1
[3] phi() [ ] ( )
main: scope:[main] from @1
[4] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 0) ← true [ ] ( main:2 [ ] )
[5] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 1) ← false [ ] ( main:2 [ ] )
[6] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] )
[7] if(*(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2)) goto main::@2 [ ] ( main:2 [ ] )
to:main::@return
main::@return: scope:[main] from main main::@2
[8] return [ ] ( main:2 [ ] )
to:@return
main::@2: scope:[main] from main
[9] *(++((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] )
to:main::@return
DOMINATORS
@begin dominated by @begin
@1 dominated by @1 @begin
@end dominated by @1 @begin @end
main dominated by @1 @begin main
main::@return dominated by main::@return @1 @begin main
main::@2 dominated by @1 @begin main::@2 main
NATURAL LOOPS
NATURAL LOOPS WITH DEPTH
Found 0 loops in scope []
Found 0 loops in scope [main]
VARIABLE REGISTER WEIGHTS
(void()) main()
(boolean*) main::bscreen
Initial phi equivalence classes
Complete equivalence classes
New fragment synthesis _deref_pboc1=vboc2
New fragment synthesis _deref_pboc1=vboc2 - sub-option vboaa=vboc1
New fragment synthesis vboaa=vboc1
New fragment synthesis vboaa=vboc1 - Successfully loaded vboaa=vboc1.asm
Fragment synthesis vboaa=vboc1 - New best, scheduling parent _deref_pboc1=vboc2
Fragment synthesis _deref_pboc1=vboc2 - Successfully synthesized from vboaa=vboc1
Found best fragment _deref_pboc1=vboc2 < vboaa=vboc1 score: 6.5
New fragment synthesis _deref_pboc1_then_la1
New fragment synthesis _deref_pboc1_then_la1 - sub-option vboaa_then_la1
New fragment synthesis _deref_pboc1_then_la1 - sub-option vboxx_then_la1
New fragment synthesis _deref_pboc1_then_la1 - sub-option vboyy_then_la1
New fragment synthesis vboaa_then_la1
New fragment synthesis vboaa_then_la1 - Successfully loaded vboaa_then_la1.asm
New fragment synthesis vboaa_then_la1 - sub-option vboxx_then_la1
New fragment synthesis vboaa_then_la1 - sub-option vboyy_then_la1
New fragment synthesis vboxx_then_la1
New fragment synthesis vboxx_then_la1 - Successfully loaded vboxx_then_la1.asm
New fragment synthesis vboxx_then_la1 - sub-option vboaa_then_la1
New fragment synthesis vboyy_then_la1
New fragment synthesis vboyy_then_la1 - Successfully loaded vboyy_then_la1.asm
New fragment synthesis vboyy_then_la1 - sub-option vboaa_then_la1
Fragment synthesis vboyy_then_la1 - New best, scheduling parent vboaa_then_la1
Fragment synthesis vboyy_then_la1 - New best, scheduling parent _deref_pboc1_then_la1
Fragment synthesis vboxx_then_la1 - New best, scheduling parent vboaa_then_la1
Fragment synthesis vboxx_then_la1 - New best, scheduling parent _deref_pboc1_then_la1
Fragment synthesis vboaa_then_la1 - Successfully synthesized from vboxx_then_la1
Fragment synthesis vboaa_then_la1 - Successfully synthesized from vboyy_then_la1
Fragment synthesis vboaa_then_la1 - New best, scheduling parent vboxx_then_la1
Fragment synthesis vboaa_then_la1 - New best, scheduling parent vboyy_then_la1
Fragment synthesis vboaa_then_la1 - New best, scheduling parent _deref_pboc1_then_la1
Fragment synthesis vboyy_then_la1 - Successfully synthesized from vboaa_then_la1
Fragment synthesis vboxx_then_la1 - Successfully synthesized from vboaa_then_la1
Fragment synthesis _deref_pboc1_then_la1 - Successfully synthesized from vboaa_then_la1
Fragment synthesis _deref_pboc1_then_la1 - Successfully synthesized from vboxx_then_la1
Fragment synthesis _deref_pboc1_then_la1 - Successfully synthesized from vboyy_then_la1
Found best fragment _deref_pboc1_then_la1 < vboaa_then_la1 score: 9.0
INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG4 @1
b1:
//SEG5 [2] call main param-assignment [ ] ( )
jsr main
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
//SEG9 [4] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 0) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+0
//SEG10 [5] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 1) ← false [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #0
sta $400+1
//SEG11 [6] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+2
//SEG12 [7] if(*(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2)) goto main::@2 [ ] ( main:2 [ ] ) -- _deref_pboc1_then_la1
lda $400+2
cmp #0
bne b2
jmp breturn
//SEG13 main::@return
breturn:
//SEG14 [8] return [ ] ( main:2 [ ] )
rts
//SEG15 main::@2
b2:
//SEG16 [9] *(++((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+2+1
jmp breturn
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 0) ← true [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 1) ← false [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] if(*(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2)) goto main::@2 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [9] *(++((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 56 combination
Uplifting [] best 56 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG4 @1
b1:
//SEG5 [2] call main param-assignment [ ] ( )
jsr main
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
//SEG9 [4] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 0) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+0
//SEG10 [5] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 1) ← false [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #0
sta $400+1
//SEG11 [6] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+2
//SEG12 [7] if(*(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2)) goto main::@2 [ ] ( main:2 [ ] ) -- _deref_pboc1_then_la1
lda $400+2
cmp #0
bne b2
jmp breturn
//SEG13 main::@return
breturn:
//SEG14 [8] return [ ] ( main:2 [ ] )
rts
//SEG15 main::@2
b2:
//SEG16 [9] *(++((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+2+1
jmp breturn
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda $400+2
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction bbegin:
Removing instruction b1_from_bbegin:
Removing instruction bend_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b1:
Removing instruction bend:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(void()) main()
(label) main::@2
(label) main::@return
(boolean*) main::bscreen
FINAL ASSEMBLER
Score: 43
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
//SEG2 @begin
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
//SEG4 @1
//SEG5 [2] call main param-assignment [ ] ( )
jsr main
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
//SEG7 @end
//SEG8 main
main: {
//SEG9 [4] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 0) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+0
//SEG10 [5] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 1) ← false [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #0
sta $400+1
//SEG11 [6] *(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+2
//SEG12 [7] if(*(((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2)) goto main::@2 [ ] ( main:2 [ ] ) -- _deref_pboc1_then_la1
cmp #0
bne b2
//SEG13 main::@return
breturn:
//SEG14 [8] return [ ] ( main:2 [ ] )
rts
//SEG15 main::@2
b2:
//SEG16 [9] *(++((boolean*))(word/signed word/dword/signed dword) 1024+(byte/signed byte/word/signed word/dword/signed dword) 2) ← true [ ] ( main:2 [ ] ) -- _deref_pboc1=vboc2
lda #1
sta $400+2+1
jmp breturn
}

View File

@ -0,0 +1,8 @@
(label) @1
(label) @begin
(label) @end
(void()) main()
(label) main::@2
(label) main::@return
(boolean*) main::bscreen