mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-22 16:33:48 +00:00
Added support for sizeof without parenthesis. Closes #695
This commit is contained in:
parent
1deb381c57
commit
f60e1240e2
@ -222,8 +222,8 @@ expr
|
||||
| expr DOT NAME #exprDot
|
||||
| expr '->' NAME #exprArrow
|
||||
| expr PAR_BEGIN parameterList? PAR_END #exprCall
|
||||
| SIZEOF PAR_BEGIN ( expr | typeName ) PAR_END #exprSizeOf
|
||||
| TYPEID PAR_BEGIN ( expr | typeName ) PAR_END #exprTypeId
|
||||
| SIZEOF ( expr | PAR_BEGIN typeName PAR_END ) #exprSizeOf
|
||||
| TYPEID ( expr | PAR_BEGIN typeName PAR_END ) #exprTypeId
|
||||
| DEFINED PAR_BEGIN? NAME PAR_END? #exprDefined
|
||||
| expr BRACKET_BEGIN commaExpr BRACKET_END #exprArray
|
||||
| PAR_BEGIN typeName PAR_END expr #exprCast
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -199,6 +199,11 @@ public class TestProgramsFast extends TestPrograms {
|
||||
compileAndCompare("procedure-declare-0.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSizeNoParen() throws IOException {
|
||||
compileAndCompare("sizeof-noparen.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSizeOfProblem() throws IOException {
|
||||
compileAndCompare("sizeof-problem.c");
|
||||
|
18
src/test/kc/sizeof-noparen.c
Normal file
18
src/test/kc/sizeof-noparen.c
Normal file
@ -0,0 +1,18 @@
|
||||
// Tests the sizeof operator without parenthesis
|
||||
|
||||
char* const SCREEN = (char*)0x400;
|
||||
|
||||
void main() {
|
||||
char idx = 0;
|
||||
|
||||
// Simple types
|
||||
char b = 0;
|
||||
int w = 0;
|
||||
|
||||
SCREEN[idx++] = '0'+sizeof 0;
|
||||
SCREEN[idx++] = '0'+sizeof b;
|
||||
SCREEN[idx++] = '0'+sizeof w;
|
||||
SCREEN[idx++] = '0'+sizeof (char);
|
||||
SCREEN[idx++] = '0'+sizeof (int);
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
// Test labels/goto
|
||||
// goto a nested label
|
||||
// goto a label nested in a loop
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="labelgoto-5.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
|
@ -1,291 +1,3 @@
|
||||
PARSING /Users/jespergravgaard/c64/kickc/src/test/kc/labelgoto-5.c
|
||||
// Test labels/goto
|
||||
// goto a nested label
|
||||
|
||||
void main() {
|
||||
char * const SCREEN = (char*)0x0400;
|
||||
char i = 0;
|
||||
goto first;
|
||||
for(;i<10;i++) {
|
||||
SCREEN[i] = '*';
|
||||
first:
|
||||
SCREEN[40]++;
|
||||
}
|
||||
}
|
||||
Adding pre/post-modifier main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
Adding pre/post-modifier main::i = ++ main::i
|
||||
FIRST CONTROL FLOW GRAPH
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
main::i = 0
|
||||
to:main::first
|
||||
main::first: scope:[main] from main main:::1::@2
|
||||
main:::1::$1 = main::SCREEN[$28]
|
||||
main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
main::i = ++ main::i
|
||||
to:main:::1::@1
|
||||
main::@1: scope:[main] from
|
||||
to:main:::1::@1
|
||||
main:::1::@1: scope:[main] from main::@1 main::first
|
||||
main:::1::$0 = main::i < $a
|
||||
if(main:::1::$0) goto main:::1::@2
|
||||
to:main:::1::@4
|
||||
main:::1::@2: scope:[main] from main:::1::@1 main:::1::@5
|
||||
main::SCREEN[main::i] = '*'
|
||||
to:main::first
|
||||
main:::1::@4: scope:[main] from main:::1::@1
|
||||
to:main:::1::@3
|
||||
main:::1::@3: scope:[main] from main:::1::@4 main::@2
|
||||
to:main::@return
|
||||
main:::1::@5: scope:[main] from
|
||||
to:main:::1::@2
|
||||
main::@2: scope:[main] from
|
||||
to:main:::1::@3
|
||||
main::@return: scope:[main] from main:::1::@3
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start
|
||||
return
|
||||
to:@return
|
||||
|
||||
SYMBOLS
|
||||
void __start()
|
||||
void main()
|
||||
bool~ main::$0
|
||||
byte~ main::$1
|
||||
constant byte* const main::SCREEN = (byte*)$400
|
||||
byte main::i
|
||||
|
||||
CONTROL FLOW GRAPH BEFORE SIZEOF FIX
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
main::i = 0
|
||||
to:main::first
|
||||
main::first: scope:[main] from main main::@4
|
||||
main::$1 = main::SCREEN[$28]
|
||||
main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
main::i = ++ main::i
|
||||
to:main::@3
|
||||
main::@1: scope:[main] from
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1 main::first
|
||||
main::$0 = main::i < $a
|
||||
if(main::$0) goto main::@4
|
||||
to:main::@6
|
||||
main::@4: scope:[main] from main::@3 main::@7
|
||||
main::SCREEN[main::i] = '*'
|
||||
to:main::first
|
||||
main::@6: scope:[main] from main::@3
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@2 main::@6
|
||||
to:main::@return
|
||||
main::@7: scope:[main] from
|
||||
to:main::@4
|
||||
main::@2: scope:[main] from
|
||||
to:main::@5
|
||||
main::@return: scope:[main] from main::@5
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start
|
||||
return
|
||||
to:@return
|
||||
|
||||
CONTROL FLOW GRAPH AFTER UNWIND
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
main::i = 0
|
||||
to:main::first
|
||||
main::first: scope:[main] from main main::@4
|
||||
main::$1 = main::SCREEN[$28]
|
||||
main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
main::i = ++ main::i
|
||||
to:main::@3
|
||||
main::@1: scope:[main] from
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1 main::first
|
||||
main::$0 = main::i < $a
|
||||
if(main::$0) goto main::@4
|
||||
to:main::@6
|
||||
main::@4: scope:[main] from main::@3 main::@7
|
||||
main::SCREEN[main::i] = '*'
|
||||
to:main::first
|
||||
main::@6: scope:[main] from main::@3
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@2 main::@6
|
||||
to:main::@return
|
||||
main::@7: scope:[main] from
|
||||
to:main::@4
|
||||
main::@2: scope:[main] from
|
||||
to:main::@5
|
||||
main::@return: scope:[main] from main::@5
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start
|
||||
return
|
||||
to:@return
|
||||
|
||||
CONTROL FLOW GRAPH BEFORE INLINING
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
main::i = 0
|
||||
to:main::first
|
||||
main::first: scope:[main] from main main::@4
|
||||
main::$1 = main::SCREEN[$28]
|
||||
main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
main::i = ++ main::i
|
||||
to:main::@3
|
||||
main::@1: scope:[main] from
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1 main::first
|
||||
main::$0 = main::i < $a
|
||||
if(main::$0) goto main::@4
|
||||
to:main::@6
|
||||
main::@4: scope:[main] from main::@3 main::@7
|
||||
main::SCREEN[main::i] = '*'
|
||||
to:main::first
|
||||
main::@6: scope:[main] from main::@3
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@2 main::@6
|
||||
to:main::@return
|
||||
main::@7: scope:[main] from
|
||||
to:main::@4
|
||||
main::@2: scope:[main] from
|
||||
to:main::@5
|
||||
main::@return: scope:[main] from main::@5
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start
|
||||
return
|
||||
to:@return
|
||||
|
||||
INITIAL CONTROL FLOW GRAPH
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
[0] main::i = 0
|
||||
to:main::first
|
||||
main::first: scope:[main] from main main::@4
|
||||
[1] main::$1 = main::SCREEN[$28]
|
||||
[2] main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
[3] main::i = ++ main::i
|
||||
to:main::@3
|
||||
main::@1: scope:[main] from
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1 main::first
|
||||
[4] main::$0 = main::i < $a
|
||||
[5] if(main::$0) goto main::@4
|
||||
to:main::@6
|
||||
main::@4: scope:[main] from main::@3 main::@7
|
||||
[6] main::SCREEN[main::i] = '*'
|
||||
to:main::first
|
||||
main::@6: scope:[main] from main::@3
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@2 main::@6
|
||||
to:main::@return
|
||||
main::@7: scope:[main] from
|
||||
to:main::@4
|
||||
main::@2: scope:[main] from
|
||||
to:main::@5
|
||||
main::@return: scope:[main] from main::@5
|
||||
[7] return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
[8] call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
Eliminating unused variable main::$1 and assignment [1] main::$1 = main::SCREEN[$28]
|
||||
PROCEDURE MODIFY VARIABLE ANALYSIS
|
||||
|
||||
PROCEDURE CALLS
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
main::i = 0
|
||||
to:main::first
|
||||
main::first: scope:[main] from main main::@2
|
||||
main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
main::i = ++ main::i
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::first
|
||||
main::$0 = main::i < $a
|
||||
if(main::$0) goto main::@2
|
||||
to:main::@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
main::SCREEN[main::i] = '*'
|
||||
to:main::first
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start
|
||||
return
|
||||
to:@return
|
||||
|
||||
PROCEDURE PARAMETERS
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start
|
||||
main::i = 0
|
||||
to:main::first
|
||||
main::first: scope:[main] from main main::@2
|
||||
main::SCREEN[$28] = ++ main::SCREEN[$28]
|
||||
main::i = ++ main::i
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main::first
|
||||
main::$0 = main::i < $a
|
||||
if(main::$0) goto main::@2
|
||||
to:main::@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
main::SCREEN[main::i] = '*'
|
||||
to:main::first
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
Completing Phi functions...
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
@ -420,7 +132,7 @@ Uplifting [] best 341 combination
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Test labels/goto
|
||||
// goto a nested label
|
||||
// goto a label nested in a loop
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="labelgoto-5.prg", type="prg", segments="Program"]
|
||||
@ -495,7 +207,7 @@ Score: 251
|
||||
|
||||
// File Comments
|
||||
// Test labels/goto
|
||||
// goto a nested label
|
||||
// goto a label nested in a loop
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="labelgoto-5.prg", type="prg", segments="Program"]
|
||||
|
33
src/test/ref/sizeof-noparen.asm
Normal file
33
src/test/ref/sizeof-noparen.asm
Normal file
@ -0,0 +1,33 @@
|
||||
// Tests the sizeof operator without parenthesis
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="sizeof-noparen.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segment Basic
|
||||
:BasicUpstart(main)
|
||||
.const SIZEOF_BYTE = 1
|
||||
.const SIZEOF_SIGNED_WORD = 2
|
||||
.const SIZEOF_NUMBER = -1
|
||||
.label SCREEN = $400
|
||||
.segment Code
|
||||
main: {
|
||||
// SCREEN[idx++] = '0'+sizeof 0
|
||||
lda #'0'+SIZEOF_NUMBER
|
||||
sta SCREEN
|
||||
// SCREEN[idx++] = '0'+sizeof b
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
sta SCREEN+1
|
||||
// SCREEN[idx++] = '0'+sizeof w
|
||||
lda #'0'+SIZEOF_SIGNED_WORD
|
||||
sta SCREEN+2
|
||||
// SCREEN[idx++] = '0'+sizeof (char)
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
sta SCREEN+3
|
||||
// SCREEN[idx++] = '0'+sizeof (int)
|
||||
lda #'0'+SIZEOF_SIGNED_WORD
|
||||
sta SCREEN+4
|
||||
// }
|
||||
rts
|
||||
}
|
12
src/test/ref/sizeof-noparen.cfg
Normal file
12
src/test/ref/sizeof-noparen.cfg
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
[0] *SCREEN = '0'+SIZEOF_NUMBER
|
||||
[1] *(SCREEN+1) = '0'+SIZEOF_BYTE
|
||||
[2] *(SCREEN+2) = '0'+SIZEOF_SIGNED_WORD
|
||||
[3] *(SCREEN+3) = '0'+SIZEOF_BYTE
|
||||
[4] *(SCREEN+4) = '0'+SIZEOF_SIGNED_WORD
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return
|
||||
to:@return
|
280
src/test/ref/sizeof-noparen.log
Normal file
280
src/test/ref/sizeof-noparen.log
Normal file
@ -0,0 +1,280 @@
|
||||
Resolving sizeof() main::$2 = sizeof main::b
|
||||
Resolving sizeof() main::$4 = sizeof main::w
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start
|
||||
main::idx#0 = 0
|
||||
main::$0 = sizeof 0
|
||||
main::$1 = '0' + main::$0
|
||||
SCREEN[main::idx#0] = main::$1
|
||||
main::idx#1 = ++ main::idx#0
|
||||
main::$2 = SIZEOF_BYTE
|
||||
main::$3 = '0' + main::$2
|
||||
SCREEN[main::idx#1] = main::$3
|
||||
main::idx#2 = ++ main::idx#1
|
||||
main::$4 = SIZEOF_SIGNED_WORD
|
||||
main::$5 = '0' + main::$4
|
||||
SCREEN[main::idx#2] = main::$5
|
||||
main::idx#3 = ++ main::idx#2
|
||||
SCREEN[main::idx#3] = '0'+SIZEOF_BYTE
|
||||
main::idx#4 = ++ main::idx#3
|
||||
SCREEN[main::idx#4] = '0'+SIZEOF_SIGNED_WORD
|
||||
main::idx#5 = ++ main::idx#4
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
constant byte* const SCREEN = (byte*)$400
|
||||
constant byte SIZEOF_BYTE = 1
|
||||
constant byte SIZEOF_SIGNED_WORD = 2
|
||||
void __start()
|
||||
void main()
|
||||
word~ main::$0
|
||||
word~ main::$1
|
||||
word~ main::$2
|
||||
word~ main::$3
|
||||
word~ main::$4
|
||||
word~ main::$5
|
||||
byte main::idx
|
||||
byte main::idx#0
|
||||
byte main::idx#1
|
||||
byte main::idx#2
|
||||
byte main::idx#3
|
||||
byte main::idx#4
|
||||
byte main::idx#5
|
||||
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Constant right-side identified [1] main::$0 = sizeof 0
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant main::idx#0 = 0
|
||||
Constant main::$0 = sizeof 0
|
||||
Constant main::$2 = SIZEOF_BYTE
|
||||
Constant main::$4 = SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Simplifying expression containing zero SCREEN in [3] SCREEN[main::idx#0] = main::$1
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused variable main::idx#5 and assignment [12] main::idx#5 = ++ main::idx#4
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Removing unused procedure __start
|
||||
Removing unused procedure block __start
|
||||
Removing unused procedure block __start::@1
|
||||
Removing unused procedure block __start::@return
|
||||
Successful SSA optimization PassNEliminateEmptyStart
|
||||
Resolving sizeof() sizeof 0
|
||||
Successful SSA optimization PassNSizeOfSimplification
|
||||
Constant right-side identified [0] main::$1 = '0' + main::$0
|
||||
Constant right-side identified [2] main::idx#1 = ++ main::idx#0
|
||||
Constant right-side identified [3] main::$3 = '0' + main::$2
|
||||
Constant right-side identified [6] main::$5 = '0' + main::$4
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant main::$1 = '0'+main::$0
|
||||
Constant main::idx#1 = ++main::idx#0
|
||||
Constant main::$3 = '0'+main::$2
|
||||
Constant main::$5 = '0'+main::$4
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant right-side identified [2] main::idx#2 = ++ main::idx#1
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant main::idx#2 = ++main::idx#1
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant right-side identified [3] main::idx#3 = ++ main::idx#2
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant main::idx#3 = ++main::idx#2
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant right-side identified [4] main::idx#4 = ++ main::idx#3
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant main::idx#4 = ++main::idx#3
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Inlining constant with different constant siblings main::idx#0
|
||||
Inlining constant with different constant siblings main::idx#1
|
||||
Inlining constant with different constant siblings main::idx#2
|
||||
Inlining constant with different constant siblings main::idx#3
|
||||
Inlining constant with different constant siblings main::idx#4
|
||||
Constant inlined main::idx#0 = 0
|
||||
Constant inlined main::idx#1 = ++0
|
||||
Constant inlined main::idx#2 = ++++0
|
||||
Constant inlined main::$1 = '0'+SIZEOF_NUMBER
|
||||
Constant inlined main::idx#3 = ++++++0
|
||||
Constant inlined main::$2 = SIZEOF_BYTE
|
||||
Constant inlined main::idx#4 = ++++++++0
|
||||
Constant inlined main::$0 = SIZEOF_NUMBER
|
||||
Constant inlined main::$5 = '0'+SIZEOF_SIGNED_WORD
|
||||
Constant inlined main::$3 = '0'+SIZEOF_BYTE
|
||||
Constant inlined main::$4 = SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Consolidated array index constant in *(SCREEN+++0)
|
||||
Consolidated array index constant in *(SCREEN+++++0)
|
||||
Consolidated array index constant in *(SCREEN+++++++0)
|
||||
Consolidated array index constant in *(SCREEN+++++++++0)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Simplifying constant integer increment ++0
|
||||
Simplifying constant integer increment ++0
|
||||
Simplifying constant integer increment ++1
|
||||
Simplifying constant integer increment ++2
|
||||
Successful SSA optimization Pass2ConstantSimplification
|
||||
Simplifying constant integer increment ++1
|
||||
Simplifying constant integer increment ++2
|
||||
Simplifying constant integer increment ++3
|
||||
Successful SSA optimization Pass2ConstantSimplification
|
||||
CALL GRAPH
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
[0] *SCREEN = '0'+SIZEOF_NUMBER
|
||||
[1] *(SCREEN+1) = '0'+SIZEOF_BYTE
|
||||
[2] *(SCREEN+2) = '0'+SIZEOF_SIGNED_WORD
|
||||
[3] *(SCREEN+3) = '0'+SIZEOF_BYTE
|
||||
[4] *(SCREEN+4) = '0'+SIZEOF_SIGNED_WORD
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
void main()
|
||||
byte main::idx
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [0] *SCREEN = '0'+SIZEOF_NUMBER [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
Statement [1] *(SCREEN+1) = '0'+SIZEOF_BYTE [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
Statement [2] *(SCREEN+2) = '0'+SIZEOF_SIGNED_WORD [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
Statement [3] *(SCREEN+3) = '0'+SIZEOF_BYTE [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
Statement [4] *(SCREEN+4) = '0'+SIZEOF_SIGNED_WORD [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 39 combination
|
||||
Uplifting [] best 39 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Tests the sizeof operator without parenthesis
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="sizeof-noparen.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segment Basic
|
||||
:BasicUpstart(main)
|
||||
// Global Constants & labels
|
||||
.const SIZEOF_BYTE = 1
|
||||
.const SIZEOF_SIGNED_WORD = 2
|
||||
.const SIZEOF_NUMBER = -1
|
||||
.label SCREEN = $400
|
||||
.segment Code
|
||||
// main
|
||||
main: {
|
||||
// [0] *SCREEN = '0'+SIZEOF_NUMBER -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_NUMBER
|
||||
sta SCREEN
|
||||
// [1] *(SCREEN+1) = '0'+SIZEOF_BYTE -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
sta SCREEN+1
|
||||
// [2] *(SCREEN+2) = '0'+SIZEOF_SIGNED_WORD -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_SIGNED_WORD
|
||||
sta SCREEN+2
|
||||
// [3] *(SCREEN+3) = '0'+SIZEOF_BYTE -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
sta SCREEN+3
|
||||
// [4] *(SCREEN+4) = '0'+SIZEOF_SIGNED_WORD -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_SIGNED_WORD
|
||||
sta SCREEN+4
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [5] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
constant byte* const SCREEN = (byte*) 1024
|
||||
constant byte SIZEOF_BYTE = 1
|
||||
constant byte SIZEOF_NUMBER = -1
|
||||
constant byte SIZEOF_SIGNED_WORD = 2
|
||||
void main()
|
||||
byte main::idx
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 36
|
||||
|
||||
// File Comments
|
||||
// Tests the sizeof operator without parenthesis
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="sizeof-noparen.prg", type="prg", segments="Program"]
|
||||
.segmentdef Program [segments="Basic, Code, Data"]
|
||||
.segmentdef Basic [start=$0801]
|
||||
.segmentdef Code [start=$80d]
|
||||
.segmentdef Data [startAfter="Code"]
|
||||
.segment Basic
|
||||
:BasicUpstart(main)
|
||||
// Global Constants & labels
|
||||
.const SIZEOF_BYTE = 1
|
||||
.const SIZEOF_SIGNED_WORD = 2
|
||||
.const SIZEOF_NUMBER = -1
|
||||
.label SCREEN = $400
|
||||
.segment Code
|
||||
// main
|
||||
main: {
|
||||
// SCREEN[idx++] = '0'+sizeof 0
|
||||
// [0] *SCREEN = '0'+SIZEOF_NUMBER -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_NUMBER
|
||||
sta SCREEN
|
||||
// SCREEN[idx++] = '0'+sizeof b
|
||||
// [1] *(SCREEN+1) = '0'+SIZEOF_BYTE -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
sta SCREEN+1
|
||||
// SCREEN[idx++] = '0'+sizeof w
|
||||
// [2] *(SCREEN+2) = '0'+SIZEOF_SIGNED_WORD -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_SIGNED_WORD
|
||||
sta SCREEN+2
|
||||
// SCREEN[idx++] = '0'+sizeof (char)
|
||||
// [3] *(SCREEN+3) = '0'+SIZEOF_BYTE -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
sta SCREEN+3
|
||||
// SCREEN[idx++] = '0'+sizeof (int)
|
||||
// [4] *(SCREEN+4) = '0'+SIZEOF_SIGNED_WORD -- _deref_pbuc1=vbuc2
|
||||
lda #'0'+SIZEOF_SIGNED_WORD
|
||||
sta SCREEN+4
|
||||
// main::@return
|
||||
// }
|
||||
// [5] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
7
src/test/ref/sizeof-noparen.sym
Normal file
7
src/test/ref/sizeof-noparen.sym
Normal file
@ -0,0 +1,7 @@
|
||||
constant byte* const SCREEN = (byte*) 1024
|
||||
constant byte SIZEOF_BYTE = 1
|
||||
constant byte SIZEOF_NUMBER = -1
|
||||
constant byte SIZEOF_SIGNED_WORD = 2
|
||||
void main()
|
||||
byte main::idx
|
||||
|
Loading…
Reference in New Issue
Block a user