English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 01 June 2019, 18:59   #1141
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,516
Quote:
Originally Posted by bebbo View Post
If you want it, I'll put it live.
It would be nice. (Why isn't there any official ways to stop the assembler being annoying? Warning would have been fine but refusing to compile without any way to override it..)
Toni Wilen is offline  
Old 01 June 2019, 22:14   #1142
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by Toni Wilen View Post
It would be nice. (Why isn't there any official ways to stop the assembler being annoying? Warning would have been fine but refusing to compile without any way to override it..)

done
bebbo is offline  
Old 02 June 2019, 11:21   #1143
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,516
Thanks, seems to work

--

Some small details I have noticed. Nothing important (I simply prefer as small as possible code ). I guess this must be related to use of volatile. (Yes, this code probably would make more sense in assembler but as an experiment, this time I wanted to code almost everything in C. It was good experiment, it saved a lot of debugging time. Code size naturally was larger.)

has_maprom_aca(), instead of using address register relative, it uses absolute addresses (increases size).

Code:
volatile UBYTE *base = (volatile UBYTE*)0xb00000;
..
base[0x3000] = 0;
base[0x7000] = 0;
base[0xf000] = 0;
base[0xb000] = 0;
becomes

Code:
002191D4 13fc 0000 00b0 3000      MOVE.B #$00,$00b03000
002191DC 13fc 0000 00b0 7000      MOVE.B #$00,$00b07000
002191E4 13fc 0000 00b0 f000      MOVE.B #$00,$00b0f000
002191EC 13fc 0000 00b0 b000      MOVE.B #$00,$00b0b000
EDIT: Or did it decide to do it this way because of +-32k limit?

Sometimes compiler decides to use both methods at the same time with same base address!

Code:
volatile UWORD *base = (volatile UWORD*)0xb8f000;
volatile UWORD dummy = base[0];
// unlock
base[0 / 2] = 0xffff;
base[4 / 2] = 0x0000;
base[8 / 2] = 0xffff;
base[12 / 2] = 0xffff;

0021938A 3039 00b8 f000           MOVE.W $00b8f000,D0
00219390 3f40 0012                MOVE.W D0,(A7,$0012) == $002207fa
00219394 227c 00b8 f000           MOVEA.L #$00b8f000,A1
0021939A 32fc ffff                MOVE.W #$ffff,(A1)+ [0000]
0021939E 207c 00b8 f004           MOVEA.L #$00b8f004,A0
002193A4 3082                     MOVE.W D2,(A0) [002d]
002193A6 337c ffff 0006           MOVE.W #$ffff,(A1,$0006) == $0020f2d2
002193AC 337c ffff 000a           MOVE.W #$ffff,(A1,$000a) == $0020f2d6
002193B2 3010                     MOVE.W (A0),D0
Toni Wilen is offline  
Old 02 June 2019, 15:13   #1144
BastyCDGS
Registered User
 
Join Date: Nov 2015
Location: Freiburg / Germany
Age: 44
Posts: 200
Send a message via ICQ to BastyCDGS
Quote:
Originally Posted by Toni Wilen View Post
Code:
002191D4 13fc 0000 00b0 3000      MOVE.B #$00,$00b03000
002191DC 13fc 0000 00b0 7000      MOVE.B #$00,$00b07000
002191E4 13fc 0000 00b0 f000      MOVE.B #$00,$00b0f000
002191EC 13fc 0000 00b0 b000      MOVE.B #$00,$00b0b000
Just tried on GCC 7.3 of Ubuntu 18.04 with x86-64:
Code:
Dump of assembler code for function main:
=> 0x00005555555544f0 <+0>:     movb   $0x0,0xb03000
   0x00005555555544f8 <+8>:     xor    %eax,%eax
   0x00005555555544fa <+10>:    movb   $0x0,0xb07000
   0x0000555555554502 <+18>:    movb   $0x0,0xb0f000
   0x000055555555450a <+26>:    movb   $0x0,0xb0b000
   0x0000555555554512 <+34>:    retq
xor eax,eax is just from return 0 of my main...

BTW, why it's using move.b #$00 and not clr.b or sf instead? Do they have side effects when accessing hardware registers?
BastyCDGS is offline  
Old 02 June 2019, 16:50   #1145
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,516
Quote:
Originally Posted by BastyCDGS View Post
Just tried on GCC 7.3 of Ubuntu 18.04 with x86-64:
Code:
Dump of assembler code for function main:
=> 0x00005555555544f0 <+0>:     movb   $0x0,0xb03000
   0x00005555555544f8 <+8>:     xor    %eax,%eax
   0x00005555555544fa <+10>:    movb   $0x0,0xb07000
   0x0000555555554502 <+18>:    movb   $0x0,0xb0f000
   0x000055555555450a <+26>:    movb   $0x0,0xb0b000
   0x0000555555554512 <+34>:    retq
xor eax,eax is just from return 0 of my main...

BTW, why it's using move.b #$00 and not clr.b or sf instead? Do they have side effects when accessing hardware registers?
So constant 0 was not replaced with register that already contains zero even when compiling for x86.

This code needs to use move because detected hardware is 68000 based (ACA500/plus), address is access triggered IO space and 68000 CLR does read before zero write. (68020+ CLR does only write)
Toni Wilen is offline  
Old 07 June 2019, 14:17   #1146
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by Toni Wilen View Post
Thanks, seems to work

--

Some small details I have noticed. Nothing important (I simply prefer as small as possible code ). I guess this must be related to use of volatile. (Yes, this code probably would make more sense in assembler but as an experiment, this time I wanted to code almost everything in C. It was good experiment, it saved a lot of debugging time. Code size naturally was larger.)

has_maprom_aca(), instead of using address register relative, it uses absolute addresses (increases size).

Code:
volatile UBYTE *base = (volatile UBYTE*)0xb00000;
..
base[0x3000] = 0;
base[0x7000] = 0;
base[0xf000] = 0;
base[0xb000] = 0;
becomes

Code:
002191D4 13fc 0000 00b0 3000      MOVE.B #$00,$00b03000
002191DC 13fc 0000 00b0 7000      MOVE.B #$00,$00b07000
002191E4 13fc 0000 00b0 f000      MOVE.B #$00,$00b0f000
002191EC 13fc 0000 00b0 b000      MOVE.B #$00,$00b0b000
EDIT: Or did it decide to do it this way because of +-32k limit?

Sometimes compiler decides to use both methods at the same time with same base address!

Code:
volatile UWORD *base = (volatile UWORD*)0xb8f000;
volatile UWORD dummy = base[0];
// unlock
base[0 / 2] = 0xffff;
base[4 / 2] = 0x0000;
base[8 / 2] = 0xffff;
base[12 / 2] = 0xffff;

0021938A 3039 00b8 f000           MOVE.W $00b8f000,D0
00219390 3f40 0012                MOVE.W D0,(A7,$0012) == $002207fa
00219394 227c 00b8 f000           MOVEA.L #$00b8f000,A1
0021939A 32fc ffff                MOVE.W #$ffff,(A1)+ [0000]
0021939E 207c 00b8 f004           MOVEA.L #$00b8f004,A0
002193A4 3082                     MOVE.W D2,(A0) [002d]
002193A6 337c ffff 0006           MOVE.W #$ffff,(A1,$0006) == $0020f2d2
002193AC 337c ffff 000a           MOVE.W #$ffff,(A1,$000a) == $0020f2d6
002193B2 3010                     MOVE.W (A0),D0

sometimes my peephole optimizer adds an address base. it's not yet smart emough to check, if there is a register already providing that value. And since a0 is used later, a1 is not renamed to a0 - then the value would have been detected...


... there is still room for enhancements.
bebbo is offline  
Old 07 June 2019, 14:22   #1147
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
feature alarm!

the current gcc version is now emitting asm code using indirect memory access, e.g.:

Code:
...
    move.l ([_xy],8),-(sp)
...
useful or not? It's live
bebbo is offline  
Old 22 June 2019, 01:05   #1148
Ledfoot
Registered User
 
Join Date: Oct 2018
Location: Cherry Hill, NJ USA
Posts: 85
Quick question - anyone planning on trying to include support for the Vampire's 68080 CPU core and the AMMX instructions? I've been looking at what's involved to add this into GCC and having never done this sort of thing it's way beyond me.

Just wondering if anyone is capable and willing to tackle this to get the most out of the Vampire...
Ledfoot is offline  
Old 22 June 2019, 05:25   #1149
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,187
Quote:
Originally Posted by Ledfoot View Post
Quick question - anyone planning on trying to include support for the Vampire's 68080 CPU core and the AMMX instructions? I've been looking at what's involved to add this into GCC and having never done this sort of thing it's way beyond me.

Just wondering if anyone is capable and willing to tackle this to get the most out of the Vampire...
The full Apollo Core supports 16 address registers in addition to the 24 vector registers and the eight 64-bit wide data registers. I'm not sure if AROS even is patched to use all of those registers let alone support an ABI that includes them. The Kickstart in the Vampire is patched already though. It would definitely be nice to vectorize C code automatically as well.
Samurai_Crow is offline  
Old 22 June 2019, 14:03   #1150
Ledfoot
Registered User
 
Join Date: Oct 2018
Location: Cherry Hill, NJ USA
Posts: 85
Quote:
Originally Posted by Samurai_Crow View Post
The full Apollo Core supports 16 address registers in addition to the 24 vector registers and the eight 64-bit wide data registers. I'm not sure if AROS even is patched to use all of those registers let alone support an ABI that includes them. The Kickstart in the Vampire is patched already though. It would definitely be nice to vectorize C code automatically as well.
Hence the need to get the compiler To produce code for the 080. Otherwise we won’t ever be able to really leverage the full Capabilities of the 080. It would be like saying “hey, there is this new 68060 chip but since it supports 68000 backwards compatibility there is no need to compile for the 060. Will it work, sure. Will you get all the capabilities the hardware provides? No.

I see getting the compiler to take advantage of the hardware as the first step to getting AROS optimized for Vampire. The vectorization stuff would also make it easier to take advantage of AMMX for graphics and such applications. Think Rivaplayer optimized - how much better/more efficient it could be. Etc.
Ledfoot is offline  
Old 23 June 2019, 14:45   #1151
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by Ledfoot View Post
Quick question - anyone planning on trying to include support for the Vampire's 68080 CPU core and the AMMX instructions? I've been looking at what's involved to add this into GCC and having never done this sort of thing it's way beyond me.

Just wondering if anyone is capable and willing to tackle this to get the most out of the Vampire...

first the binutils must support the 68080 instructions...
bebbo is offline  
Old 17 September 2019, 18:25   #1152
_dante_
Registered User
 
Join Date: Feb 2018
Location: Poland
Posts: 12
I've found annoying bug in GCC 6.5.0b release as the argv (a second argument of "main" function) is not correctly populated with pointers to argument values (at least while debugging executable built using this version).

As you can see on the "GDB session hello-6.5.0b.exe" below, direct access to argv array element doesn't show correct value in GDB, as argv[0] always should contain the name of executable file. However, after assignment of argv to args variable, element pointers of args array are correctly populated so printed value of args[0] is correct.

It seems that code generated to populate elements of argv is somehow broken in GCC 6.5.0b, but code generated to handle assignments of argv is correct and uses proper element pointers.

This issue doesn't exists in executables built using GCC 6.4.1b - see "GDB session hello-6.4.1b.exe".

6.5.0 is meant to be the last version of the GCC 6, so if it is something that could be fixed I would love that, especially that 6.4.1 doesn't have this issue - unfortunately I'm too lame to do such fix to GCC by my own

hello.c contains following C code:
Code:
int main(int argc, char *argv[]) {	
	char **args = argv;
	char *a = argv[0];

	return 0;
}
hello.o objdump disassembly looks exactly the same for object file built using GCC 6.5.0b and GCC 6.4.1b (latest m68k-amigaos-objdump tool version i.e. 2.32.51.190831-181535):
Code:
00000000 _main:
int main(int argc, char *argv[]) {
   0:	4e55 fff8      	link.w a5,#-8
	char **args = argv;
   4:	2b6d 000c fffc 	move.l 12(a5),-4(a5)
	char *a = argv[0];
   a:	206d 000c      	movea.l 12(a5),a0
   e:	2b50 fff8      	move.l (a0),-8(a5)

	return 0;
  12:	7000           	moveq #0,d0
  14:	4e5d           	unlk a5
  16:	4e75           	rts
GDB session hello-6.5.0b.exe (latest m68k-amigaos-gdb version i.e. 8.3.50.190831-181535, bgdbserver 1.3):
Code:
Breakpoint 1, main (argc=1, argv=0x68047868) at src/hello.c:2
2		char **args = argv;
(gdb) n
3		char *a = argv[0];
(gdb) n
5		return 0;

(gdb) p argv
$1 = (char **) 0x68047868
(gdb) p argv[0]
$2 = 0x2f400004 ""
(gdb) x/1xw 0x68047868
0x68047868:	0x2f400004
(gdb) x/1s 0x2f400004
0x2f400004:	""

(gdb) p args
$3 = (char **) 0x680254a4
(gdb) p args[0]
$4 = 0x680254b4 "hello.exe"
(gdb) x/1xw 0x680254a4
0x680254a4:	0x680254b4
(gdb) x/1s 0x680254b4
0x680254b4:	"hello.exe"

(gdb) p a
$5 = 0x680254b4 "hello.exe"
GDB session hello-6.4.1b.exe (latest m68k-amigaos-gdb version i.e. 8.3.50.190831-181535, bgdbserver 1.3):
Code:
Breakpoint 1, main (argc=1, argv=0x68023b7c) at src/hello.c:2
2		char **args = argv;
(gdb) n
3		char *a = argv[0];
(gdb) n
5		return 0;

(gdb) p argv
$1 = (char **) 0x68023b7c
(gdb) p argv[0]
$2 = 0x68023f4c "hello.exe"
(gdb) x/1xw 0x68023b7c
0x68023b7c:	0x68023f4c
(gdb) x/1s 0x68023f4c
0x68023f4c:	"hello.exe"

(gdb) p args
$3 = (char **) 0x68023b7c
(gdb) p args[0]
$4 = 0x68023f4c "hello.exe"
(gdb) x/1xw 0x68023b7c
0x68023b7c:	0x68023f4c
(gdb) x/1s 0x68023f4c
0x68023f4c:	"hello.exe"

(gdb) p a
$5 = 0x68023f4c "hello.exe"
_dante_ is offline  
Old 17 September 2019, 19:43   #1153
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Here is an update to the current state:

1. After a tough struggle I was able to persuade gcc to use double indirect addressing.

Now instructions like
Code:
move.l (28,a1),([-24,a2],d0.l)
are emitted when appropriate.
Although there are some arguments against this mode, I have implemented it, because the cost-based approach of gcc ensures that the expensive double indirect addressing is only used when it is worth it.

2. Stability
I'm sure there's always trouble, but there's less of it atm. Your testing and feedback is mandatory. And I'll always try to fix the issues.

3. 68080 Support
I added some support for the 68080, so the code looks better now. Not all experimental features are contained in the current version, since gcc is quite fragile... butterfly's wings...

One new feature can be enabled with -fprune-stack-vars (for all cpu's), which eases the result of an infinite number of variables: gcc likes to cache values in registers and those might end up on the stack. The effect can be reviewed here: https://franke.ms/cex/z/ryfwdY - note: only few functions are affected.

4. gcc-10
I also started to port the gcc-6 features to gcc-10. You may select gcc-10 at https://franke.ms/cex

Guess I could write more, but there's time, words, ...
bebbo is offline  
Old 17 September 2019, 19:50   #1154
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by _dante_ View Post
I've found annoying bug in GCC 6.5.0b release as the argv (a second argument of "main" function) is not correctly populated with pointers to argument values (at least while debugging executable built using this version).
bgdbserver needs to poke the executable name into the Task/Proces...


which crt is used? none? libnix? clib2?
bebbo is offline  
Old 17 September 2019, 20:19   #1155
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,187
@bebbo
Thanks for your hard work!
Samurai_Crow is offline  
Old 17 September 2019, 21:34   #1156
_dante_
Registered User
 
Join Date: Feb 2018
Location: Poland
Posts: 12
Quote:
Originally Posted by bebbo View Post
bgdbserver needs to poke the executable name into the Task/Proces...


which crt is used? none? libnix? clib2?
I tried all of crts i.e. none (newlib), libnix13, libnix20, clib2. No differences. If code is compiled using GCC 6.5.0b the issue is there, if code is compiled using GCC 6.4.1b there is no issue.

I'm sure that bgdbserver is poking correctly the executable name and other command-line arguments into Task/Process. They are there but if code was compiled using GCC 6.5.0b they are not accessible from GDB through argv array. After assigning argv to other variable - in my example the variable named args - GDB can access these values through this new variable.

However, if I compile the same code using GCC 6.4.1b then using the same GBD and the same bgdbserver all is working fine. Executable file name and other command-line arguments are accessible through argv array from GDB without the need of additional assignment of argv to other variable.

Probalbly it was confusing that in my example I mentioned only executable file name (as argv[0]) but i did that only for simplicity. In fact, if code is compiled using GCC 6.5.0b and executable is launched with command-line arguments provided, GDB still cannot access any of them through argv array. bgdbserver is poking them correctly into Process as they are accessible from GDB if additional assignment is made e.g. char **args = argv; then GDB commands p args[0], p args[1], p args[x] (depending on argument count) prints correct values while p argv[0], p argv[1], p argv[x] prints garbage.
_dante_ is offline  
Old 17 September 2019, 21:48   #1157
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by _dante_ View Post
I tried all of crts i.e. none (newlib), libnix13, libnix20, clib2. No differences. If code is compiled using GCC 6.5.0b the issue is there, if code is compiled using GCC 6.4.1b there is no issue.

I'm sure that bgdbserver is poking correctly the executable name and other command-line arguments into Task/Process. They are there but if code was compiled using GCC 6.5.0b they are not accessible from GDB through argv array. After assigning argv to other variable - in my example the variable named args - GDB can access these values through this new variable.

However, if I compile the same code using GCC 6.4.1b then using the same GBD and the same bgdbserver all is working fine. Executable file name and other command-line arguments are accessible through argv array from GDB without the need of additional assignment of argv to other variable.

Probalbly it was confusing that in my example I mentioned only executable file name (as argv[0]) but i did that only for simplicity. In fact, if code is compiled using GCC 6.5.0b and executable is launched with command-line arguments provided, GDB still cannot access any of them through argv array. bgdbserver is poking them correctly into Process as they are accessible from GDB if additional assignment is made e.g. char **args = argv; then GDB commands p args[0], p args[1], p args[x] (depending on argument count) prints correct values while p argv[0], p argv[1], p argv[x] prints garbage.

there might be a difference in the generated debug info.
Is there a difference in the asm file if -g is added?
bebbo is offline  
Old 17 September 2019, 22:36   #1158
_dante_
Registered User
 
Join Date: Feb 2018
Location: Poland
Posts: 12
Quote:
Originally Posted by bebbo View Post
there might be a difference in the generated debug info.
Is there a difference in the asm file if -g is added?
Both are built only with -g and -mcrt=nix20.

There are no differences in the asm of the "main" function, but binaries and asm generated by objdump for the whole exe are much different.

There is also significant difference in executable size:
- hello-6.4.1b.exe is ~ 10 KB
- hello-6.5.0b.exe is ~ 3,7 KB

Please find these files attached.
Attached Files
File Type: zip hello-6.4.1b.exe.zip (5.7 KB, 57 views)
File Type: txt hello-6.4.1b-objdump.txt (71.1 KB, 66 views)
File Type: zip hello-6.5.0b.exe.zip (2.1 KB, 59 views)
File Type: txt hello-6.5.0b-objdump.txt (14.2 KB, 63 views)
_dante_ is offline  
Old 17 September 2019, 23:14   #1159
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by _dante_ View Post
Both are built only with -g and -mcrt=nix20.

There are no differences in the asm of the "main" function, but binaries and asm generated by objdump for the whole exe are much different.

There is also significant difference in executable size:
- hello-6.4.1b.exe is ~ 10 KB
- hello-6.5.0b.exe is ~ 3,7 KB

Please find these files attached.

please compile the test file with -S and have a look at the .stabs at end.
Guess these differ.
bebbo is offline  
Old 17 September 2019, 23:34   #1160
_dante_
Registered User
 
Join Date: Feb 2018
Location: Poland
Posts: 12
Quote:
Originally Posted by bebbo View Post
please compile the test file with -S and have a look at the .stabs at end.
Guess these differ.
You are right, there is a difference in .stabs of argv.

GCC 6.4.1b:
Code:
	.stabs	"argv:p18=*19=*2",160,0,1,12
GCC 6.5.0b:
Code:
	.stabs	"argv:p18=*19=*2",160,0,1,4
Entire files attached.
Attached Files
File Type: txt hello-6.4.1b.txt (1.7 KB, 60 views)
File Type: txt hello-6.5.0b.txt (1.8 KB, 57 views)
_dante_ is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 00:26.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.13016 seconds with 14 queries