![]() |
![]() |
#21 | |
bye
Join Date: Jun 2016
Location: Some / Where
Posts: 690
|
Quote:
You need the patched binutil-2.14 which is in the toolchain: Code:
./toolchain-m68k --gcc 6 --binutils 2.14 Bebbo |
|
![]() |
![]() |
#22 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 729
|
Can we see some generated code?
For reference here is a small function strcpy.c Code:
char *strcpy(char *dst, const char *src) { char *ret = dst; while(*dst++=*src++) ; return ret; } Code:
m68k-amigaos-gcc -fno-builtin -S strcpy.c -c -fverbose-asm -fomit-frame-pointer -O3 Code:
_strcpy: movel sp@(4),a0 ;# dst, dst movel sp@(8),a1 ;# src, src movel a0,d1 ;# dst, ret .even L2: moveb a1@+,d0 ;#, tmp36 moveb d0,a0@+ ;# tmp36, jne L2 ;# movel d1,d0 ;# ret, <result> rts Code:
strcpy: move.l %a2,-(%sp) |, move.l 8(%sp),%a0 | dst, dst move.l 12(%sp),%a2 | src, src move.l %a0,%a1 | dst, ivtmp.12 .L2: move.b (%a2)+,%d0 | MEM[base: src_8, offset: 4294967295B], D.1040 move.b %d0,(%a1)+ | D.1040, MEM[base: _14, offset: 0B] jne .L2 | move.l %a0,%d0 |, move.l (%sp)+,%a2 |, rts Thanks. |
![]() |
![]() |
#23 |
Amigan
![]() Join Date: Feb 2012
Location: London
Posts: 1,323
|
I don't have libnix built yet but GCC 6.2.1 produces this:
Code:
_strcpy: move.l a2,-(sp) |, move.l a0,d0 | dst, dst move.l a0,a2 | dst, ivtmp.11 .L2: move.b (a1)+,d1 | MEM[base: src_8, offset: 4294967295B], _9 move.b d1,(a2)+ | _9, MEM[base: _14, offset: 0B] jne .L2 | move.l (sp)+,a2 |, rts |
![]() |
![]() |
#24 | |
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
Quote:
The code is flawed of course (as usual with GCC) and should probably be the following using register arguments as above with a0=dst a1=src (inlining would be better where possible). Code:
_strcpy: move.l a0,d0 .L2: move.b (a1)+,(a0)+ jne .L2 rts |
|
![]() |
![]() |
#25 |
Amigan
![]() Join Date: Feb 2012
Location: London
Posts: 1,323
|
|
![]() |
![]() |
#26 | |
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
Quote:
|
|
![]() |
![]() |
#27 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 729
|
|
![]() |
![]() |
#28 |
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
The code generation is flawed in comparison to what modern compilers are capable of.
Vbcc uses assembler inlines by default giving the following code for strcpy(). Code:
move.l a0,d0 .l1: move.b (a1)+,(a0)+ bne .l1 Code:
strcpy: movem.l a2-a3,-(sp) movea.l ($10,sp),a3 movea.l ($c,sp),a2 move.l a2,d0 movea.l a3,a1 addq.l #1,a3 movea.l a2,a0 addq.l #1,a2 move.b (a1),(a0) beq.b .l2 .l1: movea.l a3,a1 addq.l #1,a3 movea.l a2,a0 addq.l #1,a2 move.b (a1),(a0) bne.b .l1 .l2: movem.l (sp)+,a2-a3 rts |
![]() |
![]() |
#29 |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,945
|
Wow, that's bad. I don't think even old compilers like SAS/C produce that kind of code. Just wow
![]() I certainly know which compiler to avoid now. What a shame ![]() Last edited by Thorham; 20 January 2017 at 01:59. |
![]() |
![]() |
#30 | |
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
Quote:
![]() |
|
![]() |
![]() |
#31 |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,945
|
At least that means SAS/C isn't useless
![]() Here's what SAS/C produces, for those who are interested. Code:
SECTION text,CODE __code: @strcopy: MOVE.L A2,-(A7) ;2f0a ___strcopy__1: MOVE.L A1,A2 ;2449 ___strcopy__2: MOVE.B (A0)+,D0 ;1018 MOVE.B D0,(A1)+ ;12c0 BNE.B ___strcopy__2 ;66fa ___strcopy__3: MOVE.L A2,D0 ;200a ___strcopy__4: MOVE.L (A7)+,A2 ;245f RTS ;4e75 __const: __strings: XDEF @strcopy END |
![]() |
![]() |
#32 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 729
|
Seems like the gcc-3.4.0 produces the most efficient code then, as it avoids saving/restoring a register to stack.
|
![]() |
![]() |
#33 | |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,945
|
Quote:
Code:
strcpy move.l a0,d0 .loop move.b (a0)+,(a1)+ bne.s .loop rts Code:
strcpy move.l a0,d0 .loop move.b (a0)+,(a1)+ beq.s .end move.b (a0)+,(a1)+ beq.s .end move.b (a0)+,(a1)+ beq.s .end move.b (a0)+,(a1)+ bne.s .loop .end rts |
|
![]() |
![]() |
#34 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 729
|
Well, with
Code:
m68k-amigaos-gcc -S -O3 strcpy.c -fomit-frame-pointer -funroll-all-loops Code:
_strcpy: movel sp@(4),a1 movel sp@(8),a0 movel a1,d1 L2: moveb a0@+,d0 moveb d0,a1@+ jeq L12 moveb a0@+,d0 moveb d0,a1@+ jeq L12 moveb a0@+,d0 moveb d0,a1@+ jeq L12 moveb a0@+,d0 moveb d0,a1@+ jeq L12 moveb a0@+,d0 moveb d0,a1@+ jeq L12 moveb a0@+,d0 moveb d0,a1@+ jeq L12 moveb a0@+,d0 moveb d0,a1@+ jeq L12 moveb a0@+,d0 moveb d0,a1@+ jne L2 .even L12: movel d1,d0 rts Code:
moveb a0@+,d0 moveb d0,a1@+ |
![]() |
![]() |
#35 |
Registered User
Join Date: Aug 2007
Location: berlin/germany
Posts: 1,054
|
not that i understand much but for the sake of it, results of both aros68k compilers im currently using:
strcpy: move.l 4(%sp),%d0 | dst, dst move.l 8(%sp),%a1 | src, src move.l %d0,%a0 | dst, ivtmp.11 .L2: move.b (%a1)+,%d1 | MEM[base: src_8, offset: 4294967295B], _9 move.b %d1,(%a0)+ | _9, MEM[base: _14, offset: 0B] jne .L2 | rts .size strcpy, .-strcpy .ident "GCC: (GNU) 6.1.0" strcpy: move.l 4(%sp),%d0 | dst, dst move.l 8(%sp),%a1 | src, ivtmp.9 move.l %d0,%a0 | dst, dst .L2: move.b (%a1)+,%d1 | MEM[base: D.779_19, offset: 0B], D.759 move.b %d1,(%a0)+ | D.759, MEM[base: dst_1, offset: 0B] jne .L2 | rts .size strcpy, .-strcpy .ident "GCC: (GNU) 4.6.4" |
![]() |
![]() |
#36 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,659
|
|
![]() |
![]() |
#37 |
Registered User
Join Date: Sep 2007
Location: Stockholm
Posts: 4,374
|
|
![]() |
![]() |
#38 |
Total Chaos forever!
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,223
|
|
![]() |
![]() |
#39 | ||
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,945
|
Quote:
Quote:
D0 is the return value. On 68020s and 68030s taken branches are 8 cycles, not taken byte branches are 4 cycles. |
||
![]() |
![]() |
#40 | ||
Banned
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
|
Quote:
Quote:
@wawa The aros68k GCC compiler is doing a good job here. It should be able to merge 2 lines inside the loop but overall good. strcpy() returns a pointer to the destination. The return is rarely used because it is already available and doesn't change but that is how it is defined. Code:
char *strcpy(char *dst, const char *src); Code:
char *stpcpy(char *dst, const char *src); char *stpcpy(char *dst, const char *src) { while (*dst++ = *src++); return (dst-1); } Last edited by matthey; 20 January 2017 at 18:34. |
||
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
New GCC based dev toolchain for AmigaOS 3.x | cla | Coders. Releases | 8 | 24 December 2017 10:18 |
Issue with photon/xxxx WinUAE Toolchain | arpz | Coders. Asm / Hardware | 2 | 26 September 2015 22:33 |
New 68k gcc toolchain | arti | Coders. C/C++ | 17 | 31 July 2015 03:59 |
Hannibal's WinUAE Demo Toolchain 5 | Bobic | Amiga scene | 1 | 23 July 2015 21:04 |
From gcc to vbcc. | Cowcat | Coders. General | 9 | 06 June 2014 14:45 |
|
|