From e53159699bcb945d1d26ce44ea5b652c7427fb83 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 10 Aug 2019 00:22:57 +0200 Subject: [PATCH] Implemented Xmega65 SYSCALLS. --- src/test/kc/complex/xmega65/xmega65.kc | 12 +-- src/test/ref/complex/xmega65/xmega65.asm | 11 +-- src/test/ref/complex/xmega65/xmega65.log | 115 +++++++++-------------- src/test/ref/complex/xmega65/xmega65.sym | 2 +- 4 files changed, 57 insertions(+), 83 deletions(-) diff --git a/src/test/kc/complex/xmega65/xmega65.kc b/src/test/kc/complex/xmega65/xmega65.kc index ccdd53bbb..fcd31ddd2 100644 --- a/src/test/kc/complex/xmega65/xmega65.kc +++ b/src/test/kc/complex/xmega65/xmega65.kc @@ -1,13 +1,12 @@ -// Example showing how to perform linking using a linker-file -// The linker file is created using KickAssembler segments. -// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/ -// Specifying the linker script file is done using the #pragma link() -// It can also be specified using kickc command line option -T +// XMega65 Kernal Development Template +// Each function of the kernal is a no-args function +// The functions are placed in the SYSCALLS table surrounded by JMP and NOP #pragma link("xmega65.ld") void main() { char i=0; + // Call functions one at a time while(true) { unsigned int fn = CALLS[i*2]; void()* f = (void()*)fn; @@ -33,8 +32,7 @@ const char NOP = 0xea; char[] SYSCALLS = { JMP, <&fn1, >&fn1, NOP, - JMP, <&fn2, >&fn2, NOP, - JMP, <&main, >&main, NOP + JMP, <&fn2, >&fn2, NOP }; const unsigned int* CALLS = (unsigned int*)(SYSCALLS+1); diff --git a/src/test/ref/complex/xmega65/xmega65.asm b/src/test/ref/complex/xmega65/xmega65.asm index c3fb5ba48..840849ca9 100644 --- a/src/test/ref/complex/xmega65/xmega65.asm +++ b/src/test/ref/complex/xmega65/xmega65.asm @@ -1,8 +1,6 @@ -// Example showing how to perform linking using a linker-file -// The linker file is created using KickAssembler segments. -// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/ -// Specifying the linker script file is done using the #pragma link() -// It can also be specified using kickc command line option -T +// XMega65 Kernal Development Template +// Each function of the kernal is a no-args function +// The functions are placed in the SYSCALLS table surrounded by JMP and NOP .file [name="xmega65.bin", type="bin", segments="XMega65Bin"] .segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"] .segmentdef Syscall [start=$8000, max=$81ff] @@ -20,6 +18,7 @@ main: { b1: lda #0 sta.z i + // Call functions one at a time b2: lda.z i asl @@ -49,4 +48,4 @@ fn1: { rts } .segment Syscall - SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP, JMP, main, NOP + SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP diff --git a/src/test/ref/complex/xmega65/xmega65.log b/src/test/ref/complex/xmega65/xmega65.log index f0cbb032f..9f7ba7f8d 100644 --- a/src/test/ref/complex/xmega65/xmega65.log +++ b/src/test/ref/complex/xmega65/xmega65.log @@ -63,14 +63,10 @@ fn2::@return: scope:[fn2] from fn2 (byte~) $5 ← < (void()*~) $4 (void()*~) $6 ← & (void()) fn2() (byte~) $7 ← > (void()*~) $6 - (void()*~) $8 ← & (void()) main() - (byte~) $9 ← < (void()*~) $8 - (void()*~) $10 ← & (void()) main() - (byte~) $11 ← > (void()*~) $10 - (byte[]) SYSCALLS#0 ← { (byte) JMP#0, (byte~) $1, (byte~) $3, (byte) NOP#0, (byte) JMP#0, (byte~) $5, (byte~) $7, (byte) NOP#0, (byte) JMP#0, (byte~) $9, (byte~) $11, (byte) NOP#0 } - (byte*~) $12 ← (byte[]) SYSCALLS#0 + (number) 1 - (word*~) $13 ← ((word*)) (byte*~) $12 - (word*) CALLS#0 ← (word*~) $13 + (byte[]) SYSCALLS#0 ← { (byte) JMP#0, (byte~) $1, (byte~) $3, (byte) NOP#0, (byte) JMP#0, (byte~) $5, (byte~) $7, (byte) NOP#0 } + (byte*~) $8 ← (byte[]) SYSCALLS#0 + (number) 1 + (word*~) $9 ← ((word*)) (byte*~) $8 + (word*) CALLS#0 ← (word*~) $9 call main to:@4 @4: scope:[] from @3 @@ -80,18 +76,14 @@ fn2::@return: scope:[fn2] from fn2 SYMBOL TABLE SSA (void()*~) $0 (byte~) $1 -(void()*~) $10 -(byte~) $11 -(byte*~) $12 -(word*~) $13 (void()*~) $2 (byte~) $3 (void()*~) $4 (byte~) $5 (void()*~) $6 (byte~) $7 -(void()*~) $8 -(byte~) $9 +(byte*~) $8 +(word*~) $9 (label) @3 (label) @4 (label) @begin @@ -142,7 +134,7 @@ Adding number conversion cast (unumber) 2 in (bool~) main::$3 ← (byte) main::i Adding number conversion cast (unumber) 0 in (byte) main::i#2 ← (number) 0 Adding number conversion cast (unumber) $4c in (byte) JMP#0 ← (number) $4c Adding number conversion cast (unumber) $ea in (byte) NOP#0 ← (number) $ea -Adding number conversion cast (unumber) 1 in (byte*~) $12 ← (byte[]) SYSCALLS#0 + (number) 1 +Adding number conversion cast (unumber) 1 in (byte*~) $8 ← (byte[]) SYSCALLS#0 + (number) 1 Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (byte) main::i#0 ← (unumber)(number) 0 Inlining cast (void()*~) main::$1 ← (void()*)(word) main::fn#0 @@ -151,7 +143,7 @@ Inlining cast (byte*) fn1::BORDERCOL#0 ← (byte*)(number) $d020 Inlining cast (byte*) fn2::BGCOL#0 ← (byte*)(number) $d021 Inlining cast (byte) JMP#0 ← (unumber)(number) $4c Inlining cast (byte) NOP#0 ← (unumber)(number) $ea -Inlining cast (word*~) $13 ← (word*)(byte*~) $12 +Inlining cast (word*~) $9 ← (word*)(byte*~) $8 Successful SSA optimization Pass2InlineCast Simplifying constant integer cast 0 Simplifying constant integer cast 2 @@ -177,17 +169,15 @@ Inversing boolean not [12] (bool~) main::$4 ← (byte) main::i#1 != (byte) 2 fro Successful SSA optimization Pass2UnaryNotSimplification Alias (byte) main::i#3 = (byte) main::i#4 Alias (void()*) main::f#0 = (void()*~) main::$1 -Alias (word*) CALLS#0 = (word*~) $13 +Alias (word*) CALLS#0 = (word*~) $9 Successful SSA optimization Pass2AliasElimination Identified duplicate assignment right side [26] (void()*~) $2 ← & (void()) fn1() Identified duplicate assignment right side [30] (void()*~) $6 ← & (void()) fn2() -Identified duplicate assignment right side [34] (void()*~) $10 ← & (void()) main() Successful SSA optimization Pass2DuplicateRValueIdentification Simple Condition (bool~) main::$4 [13] if((byte) main::i#1!=(byte) 2) goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification Constant right-side identified [24] (void()*~) $0 ← & (void()) fn1() Constant right-side identified [28] (void()*~) $4 ← & (void()) fn2() -Constant right-side identified [32] (void()*~) $8 ← & (void()) main() Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) main::i#0 = 0 Constant (const byte) main::i#2 = 0 @@ -197,11 +187,9 @@ Constant (const byte) JMP#0 = $4c Constant (const byte) NOP#0 = $ea Constant (const void()*) $0 = &fn1 Constant (const void()*) $4 = &fn2 -Constant (const void()*) $8 = &main Successful SSA optimization Pass2ConstantIdentification Constant (const void()*) $2 = $0 Constant (const void()*) $6 = $4 -Constant (const void()*) $10 = $8 Successful SSA optimization Pass2ConstantIdentification if() condition always true - replacing block destination [2] if(true) goto main::@2 Successful SSA optimization Pass2ConstantIfs @@ -211,27 +199,23 @@ Constant right-side identified [12] (byte~) $1 ← < (const void()*) $0 Constant right-side identified [13] (byte~) $3 ← > (const void()*) $2 Constant right-side identified [14] (byte~) $5 ← < (const void()*) $4 Constant right-side identified [15] (byte~) $7 ← > (const void()*) $6 -Constant right-side identified [16] (byte~) $9 ← < (const void()*) $8 -Constant right-side identified [17] (byte~) $11 ← > (const void()*) $10 Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) $1 = <$0 Constant (const byte) $3 = >$2 Constant (const byte) $5 = <$4 Constant (const byte) $7 = >$6 -Constant (const byte) $9 = <$8 -Constant (const byte) $11 = >$10 Successful SSA optimization Pass2ConstantIdentification -Identified constant from value list (byte[]) { (const byte) JMP#0, (const byte) $1, (const byte) $3, (const byte) NOP#0, (const byte) JMP#0, (const byte) $5, (const byte) $7, (const byte) NOP#0, (const byte) JMP#0, (const byte) $9, (const byte) $11, (const byte) NOP#0 } +Identified constant from value list (byte[]) { (const byte) JMP#0, (const byte) $1, (const byte) $3, (const byte) NOP#0, (const byte) JMP#0, (const byte) $5, (const byte) $7, (const byte) NOP#0 } Successful SSA optimization Pass2ConstantInitializerValueLists -Constant (const byte[]) SYSCALLS#0 = { JMP#0, $1, $3, NOP#0, JMP#0, $5, $7, NOP#0, JMP#0, $9, $11, NOP#0 } +Constant (const byte[]) SYSCALLS#0 = { JMP#0, $1, $3, NOP#0, JMP#0, $5, $7, NOP#0 } Successful SSA optimization Pass2ConstantIdentification -Constant right-side identified [12] (byte*~) $12 ← (const byte[]) SYSCALLS#0 + (byte) 1 +Constant right-side identified [12] (byte*~) $8 ← (const byte[]) SYSCALLS#0 + (byte) 1 Successful SSA optimization Pass2ConstantRValueConsolidation -Constant (const byte*) $12 = SYSCALLS#0+1 +Constant (const byte*) $8 = SYSCALLS#0+1 Successful SSA optimization Pass2ConstantIdentification -Constant value identified (word*)$12 in [13] (word*) CALLS#0 ← (word*)(const byte*) $12 +Constant value identified (word*)$8 in [13] (word*) CALLS#0 ← (word*)(const byte*) $8 Successful SSA optimization Pass2ConstantValues -Constant (const word*) CALLS#0 = (word*)$12 +Constant (const word*) CALLS#0 = (word*)$8 Successful SSA optimization Pass2ConstantIdentification Inlining Noop Cast [4] (void()*) main::f#0 ← (void()*)(word) main::fn#0 keeping main::fn#0 Successful SSA optimization Pass2NopCastInlining @@ -240,21 +224,17 @@ Rewriting multiplication to use shift [2] (byte~) main::$5 ← (byte~) main::$0 Successful SSA optimization Pass2MultiplyToShiftRewriting Inlining constant with var siblings (const byte) main::i#0 Inlining constant with var siblings (const byte) main::i#2 -Constant inlined $10 = &(void()) main() -Constant inlined $11 = >&(void()) main() -Constant inlined $12 = (const byte[]) SYSCALLS#0+(byte) 1 -Constant inlined $0 = &(void()) fn1() -Constant inlined $1 = <&(void()) fn1() -Constant inlined $2 = &(void()) fn1() -Constant inlined $3 = >&(void()) fn1() Constant inlined $4 = &(void()) fn2() Constant inlined $5 = <&(void()) fn2() Constant inlined $6 = &(void()) fn2() Constant inlined $7 = >&(void()) fn2() -Constant inlined $8 = &(void()) main() -Constant inlined $9 = <&(void()) main() +Constant inlined $8 = (const byte[]) SYSCALLS#0+(byte) 1 Constant inlined main::i#0 = (byte) 0 Constant inlined main::i#2 = (byte) 0 +Constant inlined $0 = &(void()) fn1() +Constant inlined $1 = <&(void()) fn1() +Constant inlined $2 = &(void()) fn1() +Constant inlined $3 = >&(void()) fn1() Successful SSA optimization Pass2ConstantInlining Eliminating unused constant (const byte) SIZEOF_WORD Successful SSA optimization PassNEliminateUnusedVars @@ -359,11 +339,9 @@ Allocated zp ZP_WORD:5 [ main::fn#0 ] INITIAL ASM Target platform is custom // File Comments -// Example showing how to perform linking using a linker-file -// The linker file is created using KickAssembler segments. -// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/ -// Specifying the linker script file is done using the #pragma link() -// It can also be specified using kickc command line option -T +// XMega65 Kernal Development Template +// Each function of the kernal is a no-args function +// The functions are placed in the SYSCALLS table surrounded by JMP and NOP // Upstart .file [name="xmega65.bin", type="bin", segments="XMega65Bin"] .segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"] @@ -406,6 +384,7 @@ main: { lda #0 sta.z i jmp b1 + // Call functions one at a time // main::@1 b1: jmp b2 @@ -470,22 +449,22 @@ fn1: { } // File Data .segment Syscall - SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP, JMP, main, NOP + SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP REGISTER UPLIFT POTENTIAL REGISTERS -Statement [6] (byte~) main::$0 ← (byte) main::i#3 << (byte) 1 [ main::i#3 main::$0 ] ( [ main::i#3 main::$0 ] main:2 [ main::i#3 main::$0 ] ) always clobbers reg byte a +Statement [6] (byte~) main::$0 ← (byte) main::i#3 << (byte) 1 [ main::i#3 main::$0 ] ( main:2 [ main::i#3 main::$0 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#3 main::i#1 ] -Statement [7] (byte~) main::$5 ← (byte~) main::$0 << (byte) 1 [ main::i#3 main::$5 ] ( [ main::i#3 main::$5 ] main:2 [ main::i#3 main::$5 ] ) always clobbers reg byte a -Statement [8] (word) main::fn#0 ← *((const word*) CALLS#0 + (byte~) main::$5) [ main::i#3 main::fn#0 ] ( [ main::i#3 main::fn#0 ] main:2 [ main::i#3 main::fn#0 ] ) always clobbers reg byte a -Statement [9] call *((void()*)(word) main::fn#0) [ main::i#3 ] ( [ main::i#3 ] main:2 [ main::i#3 ] ) always clobbers reg byte a reg byte x reg byte y +Statement [7] (byte~) main::$5 ← (byte~) main::$0 << (byte) 1 [ main::i#3 main::$5 ] ( main:2 [ main::i#3 main::$5 ] ) always clobbers reg byte a +Statement [8] (word) main::fn#0 ← *((const word*) CALLS#0 + (byte~) main::$5) [ main::i#3 main::fn#0 ] ( main:2 [ main::i#3 main::fn#0 ] ) always clobbers reg byte a +Statement [9] call *((void()*)(word) main::fn#0) [ main::i#3 ] ( main:2 [ main::i#3 ] ) always clobbers reg byte a reg byte x reg byte y Removing always clobbered register reg byte x as potential for zp ZP_BYTE:2 [ main::i#3 main::i#1 ] Removing always clobbered register reg byte y as potential for zp ZP_BYTE:2 [ main::i#3 main::i#1 ] -Statement [11] if((byte) main::i#1!=(byte) 2) goto main::@3 [ main::i#1 ] ( [ main::i#1 ] main:2 [ main::i#1 ] ) always clobbers reg byte a -Statement [6] (byte~) main::$0 ← (byte) main::i#3 << (byte) 1 [ main::i#3 main::$0 ] ( [ main::i#3 main::$0 ] main:2 [ main::i#3 main::$0 ] ) always clobbers reg byte a -Statement [7] (byte~) main::$5 ← (byte~) main::$0 << (byte) 1 [ main::i#3 main::$5 ] ( [ main::i#3 main::$5 ] main:2 [ main::i#3 main::$5 ] ) always clobbers reg byte a -Statement [8] (word) main::fn#0 ← *((const word*) CALLS#0 + (byte~) main::$5) [ main::i#3 main::fn#0 ] ( [ main::i#3 main::fn#0 ] main:2 [ main::i#3 main::fn#0 ] ) always clobbers reg byte a -Statement [9] call *((void()*)(word) main::fn#0) [ main::i#3 ] ( [ main::i#3 ] main:2 [ main::i#3 ] ) always clobbers reg byte a reg byte x reg byte y -Statement [11] if((byte) main::i#1!=(byte) 2) goto main::@3 [ main::i#1 ] ( [ main::i#1 ] main:2 [ main::i#1 ] ) always clobbers reg byte a +Statement [11] if((byte) main::i#1!=(byte) 2) goto main::@3 [ main::i#1 ] ( main:2 [ main::i#1 ] ) always clobbers reg byte a +Statement [6] (byte~) main::$0 ← (byte) main::i#3 << (byte) 1 [ main::i#3 main::$0 ] ( main:2 [ main::i#3 main::$0 ] ) always clobbers reg byte a +Statement [7] (byte~) main::$5 ← (byte~) main::$0 << (byte) 1 [ main::i#3 main::$5 ] ( main:2 [ main::i#3 main::$5 ] ) always clobbers reg byte a +Statement [8] (word) main::fn#0 ← *((const word*) CALLS#0 + (byte~) main::$5) [ main::i#3 main::fn#0 ] ( main:2 [ main::i#3 main::fn#0 ] ) always clobbers reg byte a +Statement [9] call *((void()*)(word) main::fn#0) [ main::i#3 ] ( main:2 [ main::i#3 ] ) always clobbers reg byte a reg byte x reg byte y +Statement [11] if((byte) main::i#1!=(byte) 2) goto main::@3 [ main::i#1 ] ( main:2 [ main::i#1 ] ) always clobbers reg byte a Potential registers zp ZP_BYTE:2 [ main::i#3 main::i#1 ] : zp ZP_BYTE:2 , Potential registers zp ZP_BYTE:3 [ main::$0 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , Potential registers zp ZP_BYTE:4 [ main::$5 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , @@ -507,11 +486,9 @@ Allocated (was zp ZP_WORD:5) zp ZP_WORD:3 [ main::fn#0 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments -// Example showing how to perform linking using a linker-file -// The linker file is created using KickAssembler segments. -// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/ -// Specifying the linker script file is done using the #pragma link() -// It can also be specified using kickc command line option -T +// XMega65 Kernal Development Template +// Each function of the kernal is a no-args function +// The functions are placed in the SYSCALLS table surrounded by JMP and NOP // Upstart .file [name="xmega65.bin", type="bin", segments="XMega65Bin"] .segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"] @@ -552,6 +529,7 @@ main: { lda #0 sta.z i jmp b1 + // Call functions one at a time // main::@1 b1: jmp b2 @@ -613,7 +591,7 @@ fn1: { } // File Data .segment Syscall - SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP, JMP, main, NOP + SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP ASSEMBLER OPTIMIZATIONS Removing instruction jmp b1 @@ -662,7 +640,7 @@ FINAL SYMBOL TABLE (byte) NOP (const byte) NOP#0 NOP = (byte) $ea (byte[]) SYSCALLS -(const byte[]) SYSCALLS#0 SYSCALLS = { (const byte) JMP#0, <&(void()) fn1(), >&(void()) fn1(), (const byte) NOP#0, (const byte) JMP#0, <&(void()) fn2(), >&(void()) fn2(), (const byte) NOP#0, (const byte) JMP#0, <&(void()) main(), >&(void()) main(), (const byte) NOP#0 } +(const byte[]) SYSCALLS#0 SYSCALLS = { (const byte) JMP#0, <&(void()) fn1(), >&(void()) fn1(), (const byte) NOP#0, (const byte) JMP#0, <&(void()) fn2(), >&(void()) fn2(), (const byte) NOP#0 } (void()) fn1() (label) fn1::@return (byte*) fn1::BORDERCOL @@ -694,11 +672,9 @@ FINAL ASSEMBLER Score: 5574 // File Comments -// Example showing how to perform linking using a linker-file -// The linker file is created using KickAssembler segments. -// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/ -// Specifying the linker script file is done using the #pragma link() -// It can also be specified using kickc command line option -T +// XMega65 Kernal Development Template +// Each function of the kernal is a no-args function +// The functions are placed in the SYSCALLS table surrounded by JMP and NOP // Upstart .file [name="xmega65.bin", type="bin", segments="XMega65Bin"] .segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"] @@ -728,6 +704,7 @@ main: { // [5] phi (byte) main::i#3 = (byte) 0 [phi:main/main::@2->main::@1#0] -- vbuz1=vbuc1 lda #0 sta.z i + // Call functions one at a time // main::@1 // main::@2 b2: @@ -786,5 +763,5 @@ fn1: { } // File Data .segment Syscall - SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP, JMP, main, NOP + SYSCALLS: .byte JMP, fn1, NOP, JMP, fn2, NOP diff --git a/src/test/ref/complex/xmega65/xmega65.sym b/src/test/ref/complex/xmega65/xmega65.sym index d06b98891..3832f8159 100644 --- a/src/test/ref/complex/xmega65/xmega65.sym +++ b/src/test/ref/complex/xmega65/xmega65.sym @@ -8,7 +8,7 @@ (byte) NOP (const byte) NOP#0 NOP = (byte) $ea (byte[]) SYSCALLS -(const byte[]) SYSCALLS#0 SYSCALLS = { (const byte) JMP#0, <&(void()) fn1(), >&(void()) fn1(), (const byte) NOP#0, (const byte) JMP#0, <&(void()) fn2(), >&(void()) fn2(), (const byte) NOP#0, (const byte) JMP#0, <&(void()) main(), >&(void()) main(), (const byte) NOP#0 } +(const byte[]) SYSCALLS#0 SYSCALLS = { (const byte) JMP#0, <&(void()) fn1(), >&(void()) fn1(), (const byte) NOP#0, (const byte) JMP#0, <&(void()) fn2(), >&(void()) fn2(), (const byte) NOP#0 } (void()) fn1() (label) fn1::@return (byte*) fn1::BORDERCOL