diff --git a/src/main/fragment/vduz1=vduz2_plus_1.asm b/src/main/fragment/vduz1=vduz2_plus_1.asm new file mode 100644 index 000000000..4925d2818 --- /dev/null +++ b/src/main/fragment/vduz1=vduz2_plus_1.asm @@ -0,0 +1,13 @@ +lda {z2} +clc +adc #1 +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 diff --git a/src/main/kc/stdlib/fastmultiply.kc b/src/main/kc/stdlib/fastmultiply.kc index 3adcb1743..36b2c297c 100644 --- a/src/main/kc/stdlib/fastmultiply.kc +++ b/src/main/kc/stdlib/fastmultiply.kc @@ -171,3 +171,17 @@ _dd: lda #0 } return *memR; } + +// Fast multiply two signed words to a signed double word result +// Done in assembler to utilize fast addition A+X +signed dword mulf16s(signed word a, signed word b) { + dword m = mulf16u((word)a, (word)b); + if(a<0) { + >m = (>m)-(word)b; + } + if(b<0) { + >m = (>m)-(word)a; + m = m + 1; + } + return (signed dword)m; +} diff --git a/src/test/kc/test-multiply-16bit.kc b/src/test/kc/test-multiply-16bit.kc index eb63ff652..c7e05f6bb 100644 --- a/src/test/kc/test-multiply-16bit.kc +++ b/src/test/kc/test-multiply-16bit.kc @@ -97,13 +97,17 @@ void mul16s_compare() { b=b+4093; signed dword ms = muls16s(a, b); signed dword mn = mul16s(a,b); + signed dword mf = mulf16s(a,b); byte ok = 1; + if(ms!=mf) { + ok = 0; + } if(ms!=mn) { ok = 0; } if(ok==0) { *BGCOL = 2; - mul16s_error(a,b, ms, mn); + mul16s_error(a,b, ms, mn, mf); return; } } @@ -113,7 +117,7 @@ void mul16s_compare() { print_ln(); } -void mul16s_error(signed word a, signed word b, signed dword ms, signed dword mn) { +void mul16s_error(signed word a, signed word b, signed dword ms, signed dword mn, signed dword mf) { print_str("signed word multiply mismatch @"); print_sword(a); print_str("*@"); @@ -122,5 +126,7 @@ void mul16s_error(signed word a, signed word b, signed dword ms, signed dword mn print_sdword(ms); print_str(" / normal:@"); print_sdword(mn); + print_str(" / fast:@"); + print_sdword(mf); print_ln(); } diff --git a/src/test/ref/test-multiply-16bit.cfg b/src/test/ref/test-multiply-16bit.cfg index 24cb04d96..f65c18afe 100644 --- a/src/test/ref/test-multiply-16bit.cfg +++ b/src/test/ref/test-multiply-16bit.cfg @@ -1,13 +1,13 @@ @begin: scope:[] from [0] phi() [ ] ( ) - to:@30 -@30: scope:[] from @begin + to:@31 +@31: scope:[] from @begin [1] phi() [ ] ( ) [2] call main [ ] ( ) to:@end -@end: scope:[] from @30 +@end: scope:[] from @31 [3] phi() [ ] ( ) -main: scope:[main] from @30 +main: scope:[main] from @31 [4] *((const byte*) BGCOL#0) ← (byte/signed byte/word/signed word/dword/signed dword) 5 [ ] ( main:2 [ ] ) [5] call print_cls [ ] ( main:2 [ ] ) to:main::@1 diff --git a/src/test/ref/test-multiply-16bit.log b/src/test/ref/test-multiply-16bit.log index 56caf4e68..991fc87a8 100644 --- a/src/test/ref/test-multiply-16bit.log +++ b/src/test/ref/test-multiply-16bit.log @@ -348,7 +348,7 @@ mul16s::@return: scope:[mul16s] from mul16s::@2 (byte[512]) mulf_sqr1_hi#0 ← { fill( 512, 0) } (byte[512]) mulf_sqr2_lo#0 ← { fill( 512, 0) } (byte[512]) mulf_sqr2_hi#0 ← { fill( 512, 0) } - to:@23 + to:@24 mulf_init: scope:[mulf_init] from main::@1 (word) mulf_init::sqr#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 (byte) mulf_init::x_2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 @@ -462,17 +462,17 @@ mulf16u::@return: scope:[mulf16u] from mulf16u (dword) mulf16u::return#1 ← (dword) mulf16u::return#3 return to:@return -@23: scope:[] from @19 +@24: scope:[] from @19 (byte*) print_screen#6 ← phi( @19/(byte*) print_screen#7 ) (byte*) print_char_cursor#153 ← phi( @19/(byte*) print_char_cursor#154 ) (byte*) print_line_cursor#61 ← phi( @19/(byte*) print_line_cursor#62 ) (byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53281 - to:@30 -main: scope:[main] from @30 - (byte*) print_char_cursor#133 ← phi( @30/(byte*) print_char_cursor#143 ) - (byte*) print_line_cursor#44 ← phi( @30/(byte*) print_line_cursor#54 ) - (byte*) print_screen#4 ← phi( @30/(byte*) print_screen#5 ) - (byte*) BGCOL#1 ← phi( @30/(byte*) BGCOL#4 ) + to:@31 +main: scope:[main] from @31 + (byte*) print_char_cursor#133 ← phi( @31/(byte*) print_char_cursor#143 ) + (byte*) print_line_cursor#44 ← phi( @31/(byte*) print_line_cursor#54 ) + (byte*) print_screen#4 ← phi( @31/(byte*) print_screen#5 ) + (byte*) BGCOL#1 ← phi( @31/(byte*) BGCOL#4 ) *((byte*) BGCOL#1) ← (byte/signed byte/word/signed word/dword/signed dword) 5 call print_cls to:main::@1 @@ -1233,28 +1233,28 @@ mul16s_error::@return: scope:[mul16s_error] from mul16s_error::@9 (byte*) print_line_cursor#20 ← (byte*) print_line_cursor#41 return to:@return -@30: scope:[] from @23 - (byte*) print_screen#5 ← phi( @23/(byte*) print_screen#6 ) - (byte*) print_char_cursor#143 ← phi( @23/(byte*) print_char_cursor#153 ) - (byte*) print_line_cursor#54 ← phi( @23/(byte*) print_line_cursor#61 ) - (byte*) BGCOL#4 ← phi( @23/(byte*) BGCOL#0 ) +@31: scope:[] from @24 + (byte*) print_screen#5 ← phi( @24/(byte*) print_screen#6 ) + (byte*) print_char_cursor#143 ← phi( @24/(byte*) print_char_cursor#153 ) + (byte*) print_line_cursor#54 ← phi( @24/(byte*) print_line_cursor#61 ) + (byte*) BGCOL#4 ← phi( @24/(byte*) BGCOL#0 ) call main - to:@31 -@31: scope:[] from @30 - (byte*) print_char_cursor#123 ← phi( @30/(byte*) print_char_cursor#27 ) - (byte*) print_line_cursor#42 ← phi( @30/(byte*) print_line_cursor#8 ) + to:@32 +@32: scope:[] from @31 + (byte*) print_char_cursor#123 ← phi( @31/(byte*) print_char_cursor#27 ) + (byte*) print_line_cursor#42 ← phi( @31/(byte*) print_line_cursor#8 ) (byte*) print_line_cursor#21 ← (byte*) print_line_cursor#42 (byte*) print_char_cursor#62 ← (byte*) print_char_cursor#123 to:@end -@end: scope:[] from @31 +@end: scope:[] from @32 SYMBOL TABLE SSA (const string) $0 = (string) "0123456789abcdef" (label) @10 (label) @19 -(label) @23 -(label) @30 +(label) @24 (label) @31 +(label) @32 (label) @begin (label) @end (byte*) BGCOL @@ -2816,7 +2816,7 @@ Culled Empty Block (label) print_cls::@2 Culled Empty Block (label) mul16u::@3 Culled Empty Block (label) @19 Culled Empty Block (label) mulf_init::@6 -Culled Empty Block (label) @23 +Culled Empty Block (label) @24 Culled Empty Block (label) main::@4 Culled Empty Block (label) muls16u::@3 Culled Empty Block (label) muls16s::@1 @@ -2830,7 +2830,7 @@ Culled Empty Block (label) mul16s_compare::@10 Culled Empty Block (label) mul16s_compare::@13 Culled Empty Block (label) mul16s_compare::@16 Culled Empty Block (label) mul16s_error::@9 -Culled Empty Block (label) @31 +Culled Empty Block (label) @32 Successful SSA optimization Pass2CullEmptyBlocks Self Phi Eliminated (byte*) BGCOL#21 Self Phi Eliminated (byte*) print_line_cursor#89 @@ -2967,7 +2967,7 @@ Added new block during phi lifting mulf_init::@11(between mulf_init::@4 and mulf Added new block during phi lifting mulf_init::@12(between mulf_init::@3 and mulf_init::@4) Added new block during phi lifting print_cls::@3(between print_cls::@1 and print_cls::@1) Adding NOP phi() at start of @begin -Adding NOP phi() at start of @30 +Adding NOP phi() at start of @31 Adding NOP phi() at start of @end Adding NOP phi() at start of main::@1 Adding NOP phi() at start of main::@2 @@ -3143,7 +3143,7 @@ Culled Empty Block (label) mulf_init::@9 Culled Empty Block (label) mulf_init::@10 Culled Empty Block (label) print_cls::@3 Adding NOP phi() at start of @begin -Adding NOP phi() at start of @30 +Adding NOP phi() at start of @31 Adding NOP phi() at start of @end Adding NOP phi() at start of main::@1 Adding NOP phi() at start of main::@2 @@ -3176,14 +3176,14 @@ Adding NOP phi() at start of print_cls FINAL CONTROL FLOW GRAPH @begin: scope:[] from [0] phi() [ ] ( ) - to:@30 -@30: scope:[] from @begin + to:@31 +@31: scope:[] from @begin [1] phi() [ ] ( ) [2] call main [ ] ( ) to:@end -@end: scope:[] from @30 +@end: scope:[] from @31 [3] phi() [ ] ( ) -main: scope:[main] from @30 +main: scope:[main] from @31 [4] *((const byte*) BGCOL#0) ← (byte/signed byte/word/signed word/dword/signed dword) 5 [ ] ( main:2 [ ] ) [5] call print_cls [ ] ( main:2 [ ] ) to:main::@1 @@ -4256,15 +4256,15 @@ INITIAL ASM .label print_line_cursor = 9 //SEG2 @begin bbegin: -//SEG3 [1] phi from @begin to @30 [phi:@begin->@30] -b30_from_bbegin: - jmp b30 -//SEG4 @30 -b30: +//SEG3 [1] phi from @begin to @31 [phi:@begin->@31] +b31_from_bbegin: + jmp b31 +//SEG4 @31 +b31: //SEG5 [2] call main [ ] ( ) jsr main -//SEG6 [3] phi from @30 to @end [phi:@30->@end] -bend_from_b30: +//SEG6 [3] phi from @31 to @end [phi:@31->@end] +bend_from_b31: jmp bend //SEG7 @end bend: @@ -6920,15 +6920,15 @@ ASSEMBLER BEFORE OPTIMIZATION .label print_line_cursor = 6 //SEG2 @begin bbegin: -//SEG3 [1] phi from @begin to @30 [phi:@begin->@30] -b30_from_bbegin: - jmp b30 -//SEG4 @30 -b30: +//SEG3 [1] phi from @begin to @31 [phi:@begin->@31] +b31_from_bbegin: + jmp b31 +//SEG4 @31 +b31: //SEG5 [2] call main [ ] ( ) jsr main -//SEG6 [3] phi from @30 to @end [phi:@30->@end] -bend_from_b30: +//SEG6 [3] phi from @31 to @end [phi:@31->@end] +bend_from_b31: jmp bend //SEG7 @end bend: @@ -8882,7 +8882,7 @@ print_cls: { mulf_sqr2_hi: .fill $200, 0 ASSEMBLER OPTIMIZATIONS -Removing instruction jmp b30 +Removing instruction jmp b31 Removing instruction jmp bend Removing instruction jmp b1 Removing instruction jmp b2 @@ -9034,8 +9034,8 @@ Replacing label b3_from_b4 with b3 Replacing label b1_from_b1 with b1 Replacing label b1_from_b1 with b1 Removing instruction bbegin: -Removing instruction b30_from_bbegin: -Removing instruction bend_from_b30: +Removing instruction b31_from_bbegin: +Removing instruction bend_from_b31: Removing instruction b1_from_main: Removing instruction mulf_init_from_b1: Removing instruction b2_from_b1: @@ -9113,7 +9113,7 @@ Removing instruction b12_from_b3: Removing instruction b4_from_b12: Removing instruction b1_from_b1: Succesful ASM optimization Pass5RedundantLabelElimination -Removing instruction b30: +Removing instruction b31: Removing instruction bend: Removing instruction print_cls_from_main: Removing instruction b1: @@ -9257,7 +9257,7 @@ Succesful ASM optimization Pass5UnreachableCodeElimination Fixing long branch [596] bne b1 to beq FINAL SYMBOL TABLE -(label) @30 +(label) @31 (label) @begin (label) @end (byte*) BGCOL @@ -9689,11 +9689,11 @@ Score: 441007 .label print_char_cursor = $e .label print_line_cursor = 6 //SEG2 @begin -//SEG3 [1] phi from @begin to @30 [phi:@begin->@30] -//SEG4 @30 +//SEG3 [1] phi from @begin to @31 [phi:@begin->@31] +//SEG4 @31 //SEG5 [2] call main [ ] ( ) jsr main -//SEG6 [3] phi from @30 to @end [phi:@30->@end] +//SEG6 [3] phi from @31 to @end [phi:@31->@end] //SEG7 @end //SEG8 main main: { diff --git a/src/test/ref/test-multiply-16bit.sym b/src/test/ref/test-multiply-16bit.sym index 206b30956..c32bd319a 100644 --- a/src/test/ref/test-multiply-16bit.sym +++ b/src/test/ref/test-multiply-16bit.sym @@ -1,4 +1,4 @@ -(label) @30 +(label) @31 (label) @begin (label) @end (byte*) BGCOL