EGCS as m68k-coff cross compiler does not honour -mrtd for builtin functions
Scott Howard
scott@objsw.com
Tue Feb 9 22:05:00 GMT 1999
Hello,
I have a test case attached where EGCS-1.1.1, configured as a
68k-unknown-coff cross compiler, replaces a user-specified call to
strcpy() with a call to bcopy() but then adjusts the stack pointer after
the bcopy() call, even though the -mrtd option was specified.
The test program is as follows:
*********************** start of rtdtest.c
********************************
/* test how gcc calls libgcc.a routines when -mrtd and -mshort used */
#include <stdio.h>
#include <string.h>
#define MESSAGE "bcopy() is called with the wrong calling convention\n"
int main ()
{
char buffer [128];
strcpy (buffer, MESSAGE);
bcopy (MESSAGE, buffer, sizeof (MESSAGE));
fputs (buffer, stdout);
return 0;
}
*********************** end of rtdtest.c
********************************
The call to strcpy() is silently translated into a call to bcopy () by
the compiler, presumably because bcopy () is supposed to be more
efficient.
Below is the listing of the command line activity as well as the
assembly language output. Check line 82 of the output, you will see the
instruction "addq.w #8, %sp" after the compiler-generated call to bcopy
(). In the explicit call to bcopy (), as well as the call to fputs(),
the stack pointer is not adjusted when the call returns; this is the
correct behaviour when compiling with -mrtd.
By the way, the compiler does honour the -mshort flag when generating
these library calls (I didn't bother to put this in the test compilation
below, but I have tested it separately and it works properly).
Would appreciate it if someone could look at this and make the
appropriate fixes to the compiler. The same thing happens on gcc-2.8.1
(and presumably earlier versions of EGCS as well, although I didn't test
any), so it's not something introduced by the EGCS team.
Thanks for your attention to this!
Regards,
Scott Howard
scott@objsw.com
********************************** start of listing
**********************************
Reading specs from c:\xgcc32\68k\egcs-2.91.60\specs
gcc version egcs-2.91.60 19981201 (egcs-1.1.1 release)
c:\xgcc32\68k\egcs-2.91.60\cpp.exe -lang-c -v -iprefix
c:\xgcc32\\68k\egcs-2.91.60\ -undef -D__GNUC__=2 -D__GNUC_MINOR__=91
-Dmc68000 -D__embedded__ -D__mc68000__ -D__embedded__ -D__mc68000
-Asystem(embedded) -Amachine(mc68000) -D__OPTIMIZE__ -g -D__HAVE_68881__
-Dmc68020 -D__mc68020 -D__mc68020__ rtdtest.c rtdtest.i
GNU CPP version egcs-2.91.60 19981201 (egcs-1.1.1 release) (68k,
Motorola syntax)
#include "..." search starts here:
#include <...> search starts here:
c:\xgcc32\\68k\egcs-2.91.60\include
End of search list.
c:\xgcc32\68k\egcs-2.91.60\cc1.exe rtdtest.i -quiet -dumpbase rtdtest.c
-mrtd -g -O2 -version -o rtdtest.s
GNU C version egcs-2.91.60 19981201 (egcs-1.1.1 release) (68k) compiled
by GNU C version egcs-2.91.57 19980901 (egcs-1.1 release).
c:\xgcc32\68k\egcs-2.91.60\as.exe -mc68020 -a -o rtdtest.o rtdtest.s
68K GAS rtdtest.s page 1
1 .file "rtdtest.c"
2 gcc2_compiled.:
3 __gnu_compiled_c:
4 .stabs "C:\\PROJECTS\\rtdtest/",100,0,0,.Ltext0
5 .stabs "rtdtest.c",100,0,0,.Ltext0
6 .text
7 .Ltext0:
8 .stabs
"int:t(0,1)=r(0,1);0020000000000;0017777777777;",128,0,0,0
9 .stabs "char:t(0,2)=r(0,2);0;127;",128,0,0,0
10 .stabs "long
int:t(0,3)=r(0,1);0020000000000;0017777777777;",128,0,0,0
11 .stabs "unsigned
int:t(0,4)=r(0,1);0000000000000;0037777777777;",128,0,0,0
12 .stabs "long unsigned
int:t(0,5)=r(0,1);0000000000000;0037777777777;",128,0,0,0
13 .stabs "long long
int:t(0,6)=r(0,1);01000000000000000000000;0777777777777777777777;",128,0,0,0
14 .stabs "long long unsigned
int:t(0,7)=r(0,1);0000000000000;01777777777777777777777;",128,0,0,0
15 .stabs "short
int:t(0,8)=r(0,8);-32768;32767;",128,0,0,0
16 .stabs "short unsigned
int:t(0,9)=r(0,9);0;65535;",128,0,0,0
17 .stabs "signed
char:t(0,10)=r(0,10);-128;127;",128,0,0,0
18 .stabs "unsigned
char:t(0,11)=r(0,11);0;255;",128,0,0,0
19 .stabs "float:t(0,12)=r(0,1);4;0;",128,0,0,0
20 .stabs "double:t(0,13)=r(0,1);8;0;",128,0,0,0
21 .stabs "long double:t(0,14)=r(0,1);12;0;",128,0,0,0
22 .stabs "complex
int:t(0,15)=s8real:(0,1),0,32;imag:(0,1),32,32;;",128,0,0,0
23 .stabs "complex
float:t(0,16)=r(0,16);4;0;",128,0,0,0
24 .stabs "complex
double:t(0,17)=r(0,17);8;0;",128,0,0,0
25 .stabs "complex long
double:t(0,18)=r(0,18);12;0;",128,0,0,0
26 .stabs "void:t(0,19)=(0,19)",128,0,0,0
27 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdio.h",130,0,0,0
28 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\_ansi.h",130,0,0,0
29 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\sys/config.h",130,0,0,0
30 .stabs "__int32_t:t(3,1)=(0,1)",128,0,92,0
31 .stabs "__uint32_t:t(3,2)=(0,4)",128,0,93,0
32 .stabn 162,0,0,0
33 .stabn 162,0,0,0
34 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h",130,0,0,0
35 .stabs "size_t:t(4,1)=(0,5)",128,0,170,0
36 .stabn 162,0,0,0
37 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdarg.h",130,0,0,0
38 .stabs
"__gnuc_va_list:t(5,1)=(5,2)=*(0,19)",128,0,70,0
39 .stabn 162,0,0,0
40 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\sys/reent.h",130,0,0,0
41 .stabs
"_glue:T(6,1)=s12_next:(6,2)=*(6,1),0,32;_niobs:(0,1),32,32;_iobs:(6,3)=*(6,4)=xs__sFILE:,64
42 .stabs
"_Bigint:T(6,5)=s24_next:(6,6)=*(6,5),0,32;_k:(0,1),32,32;_maxwds:(0,1),64,32;_sign:(0,1),96
43 .stabs
"_atexit:T(6,8)=s136_next:(6,9)=*(6,8),0,32;_ind:(0,1),32,32;_fns:(6,10)=ar(0,1);0;31;(6,11)
44 .stabs
"__sbuf:T(6,13)=s8_base:(6,14)=*(0,11),0,32;_size:(0,1),32,32;;",128,0,0,0
45 .stabs "_fpos_t:t(6,15)=(0,3)",128,0,58,0
46 .stabs
"__sFILE:T(6,4)=s88_p:(6,14),0,32;_r:(0,1),32,32;_w:(0,1),64,32;_flags:(0,8),96,16;_file:(0,
47 .stabs
"_reent:T(6,27)=s746_errno:(0,1),0,32;_stdin:(6,3),32,32;_stdout:(6,3),64,32;_stderr:(6,3),9
48 .stabn 162,0,0,0
49 .stabs "fpos_t:t(1,1)=(6,15)",128,0,51,0
50 .stabs "FILE:t(1,2)=(6,4)",128,0,53,0
51 .stabn 162,0,0,0
52 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\string.h",130,0,0,0
53 .stabs
"c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h",130,0,0,0
54 .stabn 162,0,0,0
55 .stabn 162,0,0,0
56 .LC0:
57 0000 6263 6F70 .ascii "bcopy() is called with the wrong calling
convention\12\0"
68K GAS rtdtest.s page 2
57 7928 2920
57 6973 2063
57 616C 6C65
57 6420 7769
58 0035 00 .even
59 .stabs "main:F(0,1)",36,0,9,main
60 .globl main
61 main:
1:rtdtest.c **** /* test how gcc calls libgcc.a routines when
-mrtd and -mshort used */
2:rtdtest.c ****
3:rtdtest.c **** #include <stdio.h>
4:rtdtest.c **** #include <string.h>
5:rtdtest.c ****
6:rtdtest.c **** #define MESSAGE "bcopy() is called with the
wrong calling convention\n"
7:rtdtest.c ****
8:rtdtest.c **** int main ()
9:rtdtest.c **** {
62 .stabn 68,0,9,.LM1-main
63 .LM1:
64 0036 4E56 FF80 link.w %a6,#-128
65 003a 2F03 move.l %d3,-(%sp)
66 003c 2F02 move.l %d2,-(%sp)
67 003e 4EB9 0000 jsr __main
67 0000
10:rtdtest.c **** char buffer [128];
68 .stabn 68,0,10,.LM2-main
69 .LM2:
70 .LBB2:
11:rtdtest.c ****
12:rtdtest.c **** strcpy (buffer, MESSAGE);
71 .stabn 68,0,12,.LM3-main
72 .LM3:
73 0044 263C 0000 move.l #.LC0,%d3
73 0000
74 004a 7480 moveq.l #-128,%d2
75 004c D48E add.l %a6,%d2
76 004e 4878 0035 pea 53.w
77 0052 2F02 move.l %d2,-(%sp)
78 0054 2F03 move.l %d3,-(%sp)
79 0056 4EB9 0000 jsr bcopy
79 0000
13:rtdtest.c **** bcopy (MESSAGE, buffer, sizeof (MESSAGE));
80 .stabn 68,0,13,.LM4-main
81 .LM4:
82 005c 504F addq.w #8,%sp
83 005e 2EBC 0000 move.l #53,(%sp)
83 0035
84 0064 2F02 move.l %d2,-(%sp)
85 0066 2F03 move.l %d3,-(%sp)
86 0068 4EB9 0000 jsr bcopy
86 0000
14:rtdtest.c **** fputs (buffer, stdout);
87 .stabn 68,0,14,.LM5-main
88 .LM5:
89 006e 2079 0000 move.l _impure_ptr,%a0
89 0000
90 0074 2F28 0008 move.l 8(%a0),-(%sp)
68K GAS rtdtest.s page 3
91 0078 2F02 move.l %d2,-(%sp)
92 007a 4EB9 0000 jsr fputs
92 0000
15:rtdtest.c **** return 0;
93 .stabn 68,0,15,.LM6-main
94 .LM6:
95 0080 4280 clr.l %d0
16:rtdtest.c **** }
96 .stabn 68,0,16,.LM7-main
97 .LM7:
98 .LBE2:
99 0082 242E FF78 move.l -136(%a6),%d2
100 0086 262E FF7C move.l -132(%a6),%d3
101 008a 4E5E unlk %a6
102 008c 4E75 rts
103 .stabs
"buffer:(0,20)=ar(0,1);0;127;(0,2)",128,0,10,-128
104 .stabn 192,0,0,.LBB2-main
105 .stabn 224,0,0,.LBE2-main
106 .Lscope0:
107 .stabs "",36,0,0,.Lscope0-main
108 .text
109 .stabs "",100,0,0,Letext
110 Letext:
68K GAS rtdtest.s page 4
DEFINED SYMBOLS
rtdtest.s:2 e0:00000000 gcc2_compiled.
rtdtest.s:3 e0:00000000 __gnu_compiled_c
rtdtest.s:110 e0:0000008e Letext
e0:00000000 .text
e1:0000008e .data
e2:0000008e .bss
e3:0000008e .stab
e4:0000038e .stabstr
rtdtest.s:61 e0:00000036 main
UNDEFINED SYMBOLS
__main
bcopy
_impure_ptr
fputs
********************************** end of listing
************************************
# 1 "rtdtest.c"
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdio.h" 1 3
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\_ansi.h" 1 3
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\sys/config.h" 1 3
# 14 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\sys/config.h" 3
# 25 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\sys/config.h" 3
# 44 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\sys/config.h" 3
typedef int __int32_t;
typedef unsigned int __uint32_t;
# 15 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\_ansi.h" 2 3
# 61 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\_ansi.h" 3
# 33 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdio.h" 2 3
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 1 3
# 19 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 61 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 131 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
typedef long unsigned int size_t;
# 271 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 283 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 317 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 38 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdio.h" 2 3
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdarg.h" 1 3
typedef void *__gnuc_va_list;
# 116 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdarg.h" 3
# 202 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdarg.h" 3
# 41 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdio.h" 2 3
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\sys/reent.h" 1 3
struct _glue
{
struct _glue *_next;
int _niobs;
struct __sFILE *_iobs;
};
struct _Bigint
{
struct _Bigint *_next;
int _k, _maxwds, _sign, _wds;
unsigned long _x[1];
};
struct _atexit {
struct _atexit *_next;
int _ind;
void (*_fns[32 ])();
};
struct __sbuf {
unsigned char *_base;
int _size;
};
typedef long _fpos_t;
struct __sFILE {
unsigned char *_p;
int _r;
int _w;
short _flags;
short _file;
struct __sbuf _bf;
int _lbfsize;
void * _cookie;
int (*_read) (void * _cookie, char *_buf, int _n) ;
int (*_write) (void * _cookie, const char *_buf, int _n) ;
_fpos_t (*_seek) (void * _cookie, _fpos_t _offset, int _whence) ;
int (*_close) (void * _cookie) ;
struct __sbuf _ub;
unsigned char *_up;
int _ur;
unsigned char _ubuf[3];
unsigned char _nbuf[1];
struct __sbuf _lb;
int _blksize;
int _offset;
struct _reent *_data;
};
struct _reent
{
int _errno;
struct __sFILE *_stdin, *_stdout, *_stderr;
int _inc;
char _emergency[25];
int _current_category;
const char *_current_locale;
int __sdidinit;
void (*__cleanup) (struct _reent *) ;
struct _Bigint *_result;
int _result_k;
struct _Bigint *_p5s;
struct _Bigint **_freelist;
int _cvtlen;
char *_cvtbuf;
unsigned char * _nextf[30 ];
unsigned int _nmalloc[30 ];
struct _atexit *_atexit;
struct _atexit _atexit0;
void (**(_sig_func))();
struct _glue __sglue;
struct __sFILE __sf[3];
};
extern struct _reent *_impure_ptr ;
void _reclaim_reent (struct _reent *) ;
# 49 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdio.h" 2 3
typedef _fpos_t fpos_t;
typedef struct __sFILE FILE;
int remove (const char *) ;
int rename (const char *, const char *) ;
FILE * tmpfile (void) ;
char * tmpnam (char *) ;
int fclose (FILE *) ;
int fflush (FILE *) ;
FILE * freopen (const char *, const char *, FILE *) ;
void setbuf (FILE *, char *) ;
int setvbuf (FILE *, char *, int, size_t) ;
int fprintf (FILE *, const char *, ...) ;
int fscanf (FILE *, const char *, ...) ;
int printf (const char *, ...) ;
int scanf (const char *, ...) ;
int sscanf (const char *, const char *, ...) ;
int vfprintf (FILE *, const char *, __gnuc_va_list ) ;
int vprintf (const char *, __gnuc_va_list ) ;
int vsprintf (char *, const char *, __gnuc_va_list ) ;
int fgetc (FILE *) ;
char * fgets (char *, int, FILE *) ;
int fputc (int, FILE *) ;
int fputs (const char *, FILE *) ;
int getc (FILE *) ;
int getchar (void) ;
char * gets (char *) ;
int putc (int, FILE *) ;
int putchar (int) ;
int puts (const char *) ;
int ungetc (int, FILE *) ;
size_t fread (void * , size_t _size, size_t _n, FILE *) ;
size_t fwrite (const void * , size_t _size, size_t _n, FILE *) ;
int fgetpos (FILE *, fpos_t *) ;
int fseek (FILE *, long, int) ;
int fsetpos (FILE *, const fpos_t *) ;
long ftell ( FILE *) ;
void rewind (FILE *) ;
void clearerr (FILE *) ;
int feof (FILE *) ;
int ferror (FILE *) ;
void perror (const char *) ;
FILE * fopen (const char *_name, const char *_type) ;
int sprintf (char *, const char *, ...) ;
int vfiprintf (FILE *, const char *, __gnuc_va_list ) ;
int iprintf (const char *, ...) ;
int fiprintf (FILE *, const char *, ...) ;
FILE * fdopen (int, const char *) ;
int fileno (FILE *) ;
int getw (FILE *) ;
int pclose (FILE *) ;
FILE * popen (const char *, const char *) ;
int putw (int, FILE *) ;
void setbuffer (FILE *, char *, int) ;
int setlinebuf (FILE *) ;
FILE * _fdopen_r (struct _reent *, int, const char *) ;
FILE * _fopen_r (struct _reent *, const char *, const char *) ;
int _getchar_r (struct _reent *) ;
char * _gets_r (struct _reent *, char *) ;
int _iprintf_r (struct _reent *, const char *, ...) ;
int _mkstemp_r (struct _reent *, char *) ;
char * _mktemp_r (struct _reent *, char *) ;
void _perror_r (struct _reent *, const char *) ;
int _printf_r (struct _reent *, const char *, ...) ;
int _putchar_r (struct _reent *, int) ;
int _puts_r (struct _reent *, const char *) ;
int _remove_r (struct _reent *, const char *) ;
int _rename_r (struct _reent *,
const char *_old, const char *_new) ;
int _scanf_r (struct _reent *, const char *, ...) ;
int _sprintf_r (struct _reent *, char *, const char *, ...) ;
char * _tempnam_r (struct _reent *, char *, char *) ;
FILE * _tmpfile_r (struct _reent *) ;
char * _tmpnam_r (struct _reent *, char *) ;
int _vfprintf_r (struct _reent *, FILE *, const char *, __gnuc_va_list ) ;
int _vprintf_r (struct _reent *, const char *, __gnuc_va_list ) ;
int _vsprintf_r (struct _reent *, char *, const char *, __gnuc_va_list ) ;
int __srget (FILE *) ;
int __swbuf (int, FILE *) ;
FILE * funopen (const void * _cookie,
int (*readfn)(void * _cookie, char *_buf, int _n),
int (*writefn)(void * _cookie, const char *_buf, int _n),
fpos_t (*seekfn)(void * _cookie, fpos_t _off, int _whence),
int (*closefn)(void * _cookie)) ;
# 259 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stdio.h" 3
# 3 "rtdtest.c" 2
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\string.h" 1 3
# 1 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 1 3
# 19 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 61 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 131 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 188 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 271 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 283 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 317 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\stddef.h" 3
# 17 "c:\\xgcc32\\\\68k\\egcs-2.91.60\\include\\string.h" 2 3
void * memchr (const void * , int, size_t) ;
int memcmp (const void * , const void * , size_t) ;
void * memcpy (void * , const void * , size_t) ;
void * memmove (void * , const void * , size_t) ;
void * memset (void * , int, size_t) ;
char * strcat (char *, const char *) ;
char * strchr (const char *, int) ;
int strcmp (const char *, const char *) ;
int strcoll (const char *, const char *) ;
char * strcpy (char *, const char *) ;
size_t strcspn (const char *, const char *) ;
char * strerror (int) ;
size_t strlen (const char *) ;
char * strncat (char *, const char *, size_t) ;
int strncmp (const char *, const char *, size_t) ;
char * strncpy (char *, const char *, size_t) ;
char * strpbrk (const char *, const char *) ;
char * strrchr (const char *, int) ;
size_t strspn (const char *, const char *) ;
char * strstr (const char *, const char *) ;
int ffs (int) ;
char * strtok (char *, const char *) ;
size_t strxfrm (char *, const char *, size_t) ;
char * strtok_r (char *, const char *, char **) ;
int bcmp (const char *, const char *, size_t) ;
void bcopy (const char *, char *, size_t) ;
void bzero (char *, size_t) ;
int ffs (int) ;
char * index (const char *, int) ;
void * memccpy (void * , const void * , int, size_t) ;
char * rindex (const char *, int) ;
int strcasecmp (const char *, const char *) ;
char * strdup (const char *) ;
int strncasecmp (const char *, const char *, size_t) ;
char * strsep (char **, const char *) ;
char * strlwr (char *) ;
char * strupr (char *) ;
# 4 "rtdtest.c" 2
int main ()
{
char buffer [128];
strcpy (buffer, "bcopy() is called with the wrong calling convention\n" );
bcopy ("bcopy() is called with the wrong calling convention\n" , buffer, sizeof ("bcopy() is called with the wrong calling convention\n" ));
fputs (buffer, (_impure_ptr->_stdout) );
return 0;
}
More information about the Gcc-bugs
mailing list