mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-03-07 11:30:29 +00:00
Added boolean pointer test and a test that modifying a constant results in an error.
This commit is contained in:
parent
ad54c264c4
commit
80f57ed5f1
@ -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();
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
lda #{c1}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
13
src/test/java/dk/camelot64/kickc/test/kc/bool-pointer.kc
Normal file
13
src/test/java/dk/camelot64/kickc/test/kc/bool-pointer.kc
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// Test that modifying constant pointers fail
|
||||
|
||||
void main() {
|
||||
const byte* screen = $400;
|
||||
screen[0] = 'c';
|
||||
screen++;
|
||||
screen[0] = 'm';
|
||||
}
|
20
src/test/java/dk/camelot64/kickc/test/ref/bool-pointer.asm
Normal file
20
src/test/java/dk/camelot64/kickc/test/ref/bool-pointer.asm
Normal 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
|
||||
}
|
21
src/test/java/dk/camelot64/kickc/test/ref/bool-pointer.cfg
Normal file
21
src/test/java/dk/camelot64/kickc/test/ref/bool-pointer.cfg
Normal 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
|
409
src/test/java/dk/camelot64/kickc/test/ref/bool-pointer.log
Normal file
409
src/test/java/dk/camelot64/kickc/test/ref/bool-pointer.log
Normal 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
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(boolean*) main::bscreen
|
||||
|
Loading…
x
Reference in New Issue
Block a user