OSDN Git Service

* config/xtensa/xtensa.c (xtensa_va_arg): Fix to handle arguments
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / dpx2.h
1 /* Definitions of target machine for GNU compiler.  
2    Bull DPX/2 200 and 300 systems (m68k, SysVr3).
3    Copyright (C) 1987, 1993, 1994, 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
4    Contributed by Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr).
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23
24 #ifndef USE_GAS
25 #define MOTOROLA           /* Use Motorola syntax rather than "MIT" */
26 #define SGS_NO_LI          /* Suppress jump table label usage */
27 #define VERSADOS           /* This is the name of the assembler we have */
28 #endif
29
30 #include "m68k/m68k.h"
31 #undef SELECT_RTX_SECTION
32 #include "svr3.h"
33
34 #undef INT_OP_GROUP
35 #define INT_OP_GROUP INT_OP_DC
36
37 /* We use collect2 instead of ctors_section constructors.  */
38 #undef INIT_SECTION_ASM_OP
39 #undef FINI_SECTION_ASM_OP
40 #undef DTORS_SECTION_ASM_OP
41 #undef DO_GLOBAL_CTORS_BODY
42
43 /* Remove handling for a separate constant data section.  We put
44    constant data in text_section, which is the default.  */
45 #undef SELECT_SECTION
46 #undef SELECT_RTX_SECTION
47 #undef EXTRA_SECTIONS
48 #undef EXTRA_SECTION_FUNCTIONS
49 #undef CONST_SECTION_ASM_OP
50 #undef READONLY_DATA_SECTION
51
52 #define DPX2
53
54 /* See m68k.h.  7 means 68020 with 68881.
55  * We really have 68030 and 68882,
56  * but this will get us going.  
57  */
58 #ifndef TARGET_DEFAULT
59 #define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020)
60 #endif
61
62 #define OBJECT_FORMAT_COFF
63
64 #ifdef CPP_PREDEFINES
65 #undef CPP_PREDEFINES
66 #endif
67 /*
68  * define all the things the compiler should
69  */
70 #ifdef ncl_mr
71 # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_mr=1 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem=unix -Asystem=svr3  -Acpu=m68k -Amachine=m68k"
72 #else
73 # ifdef ncl_el
74 # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_el -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem=unix -Asystem=svr3  -Acpu=m68k -Amachine=m68k"
75 # else
76 #   define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem=unix -Asystem=svr3  -Acpu=m68k -Amachine=m68k"
77 # endif
78 #endif
79
80 #undef  CPP_SPEC
81 /*
82  * you can't get a DPX/2 without a 68882 but allow it
83  * to be ignored...
84  */
85 # define __HAVE_68881__ 1
86 # define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__ }"
87
88 #undef DO_GLOBAL_CTORS_BODY             /* don't use svr3.h version */
89 #undef DO_GLOBAL_DTORS_BODY
90
91 #ifndef USE_GAS
92 /*
93  * handle the native MOTOROLA VERSAdos assembler.
94  */
95
96 /* See m68k.h.  3 means 68020 with 68881 and no bitfield
97  * bitfield instructions do not seem to work a clean way.
98  */
99 #undef TARGET_DEFAULT
100 #define TARGET_DEFAULT (MASK_68881|MASK_68020)
101
102 /* The native assembler doesn't support fmovecr.  */
103 #define NO_ASM_FMOVECR
104
105 #undef TEXT_SECTION_ASM_OP
106 #define TEXT_SECTION_ASM_OP     "\tsection 10"
107 #undef DATA_SECTION_ASM_OP
108 #define DATA_SECTION_ASM_OP     "\tsection 15"
109 #define BSS_SECTION_ASM_OP      "\tsection 14"
110
111
112 /* Don't try using XFmode.  */
113 #undef LONG_DOUBLE_TYPE_SIZE
114 #define LONG_DOUBLE_TYPE_SIZE 64
115
116 #undef ASM_OUTPUT_SOURCE_FILENAME
117 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NA)    \
118   do { fprintf ((FILE), "\t.file\t'%s'\n", (NA)); } while (0)
119
120 /* 
121  * we don't seem to support any of:
122  * .globl
123  * .even
124  * .align
125  * .ascii
126  */
127 #undef ASM_OUTPUT_SKIP
128 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
129   fprintf (FILE, "\tdcb.b %u,0\n", (SIZE))
130
131 #undef GLOBAL_ASM_OP 
132 #define GLOBAL_ASM_OP "\txdef\t"
133
134 #undef ASM_OUTPUT_ALIGN
135 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
136   if ((LOG) >= 1)                       \
137     fprintf (FILE, "\tds.w 0\n");
138
139
140 #define STRING_LIMIT    (0)
141 #undef ASM_APP_ON
142 #define ASM_APP_ON ""
143 #undef ASM_APP_OFF
144 #define ASM_APP_OFF ""
145 /*
146  * dc.b 'hello, world!'
147  * dc.b 10,0
148  * is how we have to output "hello, world!\n"
149  */
150 #undef ASM_OUTPUT_ASCII
151 #define ASM_OUTPUT_ASCII(asm_out_file, p, thissize)             \
152   do { register int i, c, f=0, len=0;                           \
153   for (i = 0; i < thissize; i++) {                              \
154     c = p[i];                                                   \
155     if (c == '\'' || c < ' ' || c > 127) {                      \
156       switch(f) {                                               \
157       case 0: /* need to output dc.b etc */                     \
158         fprintf(asm_out_file, "\tdc.b %d", c);                  \
159         f=1;                                                    \
160         break;                                                  \
161       case 1:                                                   \
162         fprintf(asm_out_file, ",%d", c);                        \
163         break;                                                  \
164       default:                                                  \
165         /* close a string */                                    \
166         fprintf(asm_out_file, "'\n\tdc.b %d", c);               \
167         f=1;                                                    \
168         break;                                                  \
169       }                                                         \
170     } else {                                                    \
171       switch(f) {                                               \
172       case 0:                                                   \
173         fprintf(asm_out_file, "\tdc.b '%c", c);                 \
174         f=2;                                                    \
175         break;                                                  \
176       case 2:                                                   \
177         if (len >= 79) {                                        \
178           fprintf(asm_out_file, "'\n\tdc.b '%c", c);            \
179           len = 0; }                                            \
180         else                                                    \
181           fprintf(asm_out_file, "%c", c);                       \
182         break;                                                  \
183       default:                                                  \
184         len = 0;                                                \
185         fprintf(asm_out_file, "\n\tdc.b '%c", c);               \
186         f=2;                                                    \
187         break;                                                  \
188       }                                                         \
189     }                                                           \
190     len++;                                                      \
191   }                                                             \
192   if (f==2)                                                     \
193     putc('\'', asm_out_file);                                   \
194   putc('\n', asm_out_file); } while (0)
195
196 /* This is how to output an insn to push a register on the stack.
197    It need not be very fast code.  */
198
199 #undef ASM_OUTPUT_REG_PUSH
200 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
201   fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
202
203 /* This is how to output an insn to pop a register from the stack.
204    It need not be very fast code.  */
205
206 #undef ASM_OUTPUT_REG_POP
207 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
208   fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
209
210
211 #define PUT_SDB_FUNCTION_START(LINE)            \
212   fprintf (asm_out_file,                        \
213            "\t.def\t.bf%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
214            SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
215
216 #define PUT_SDB_FUNCTION_END(LINE)              \
217   fprintf (asm_out_file,                        \
218            "\t.def\t.ef%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
219            SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
220
221 #define PUT_SDB_BLOCK_START(LINE)               \
222   fprintf (asm_out_file,                        \
223            "\t.def\t.bb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
224            SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
225
226 #define PUT_SDB_BLOCK_END(LINE)                 \
227   fprintf (asm_out_file,                        \
228            "\t.def\t.eb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n",  \
229            SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
230
231 #define PUT_SDB_EPILOGUE_END(NAME)      
232
233 /* Output type in decimal not in octal as done in sdbout.c */   
234 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%d%s", a, SDB_DELIM)
235                 
236 /* Translate Motorola opcodes such as `jbeq'
237    into VERSAdos opcodes such as `beq'.
238    Change `fbeq' to `fbseq', `fbne' to `fbsneq'.
239 */
240
241 #undef ASM_OUTPUT_OPCODE
242 #define ASM_OUTPUT_OPCODE(FILE, PTR)                    \
243 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')               \
244     { ++(PTR);                                          \
245       while (*(PTR) != ' ')                             \
246         { putc (*(PTR), (FILE)); ++(PTR); }             \
247     }                                                   \
248   else if ((PTR)[0] == 'f')                             \
249     {                                                   \
250       if (!strncmp ((PTR), "fbeq", 4))                  \
251         { fprintf ((FILE), "fbseq"); (PTR) += 4; }      \
252       else if (!strncmp ((PTR), "fbne", 4))             \
253         { fprintf ((FILE), "fbsneq"); (PTR) += 4; }     \
254     }                                                   \
255   else if ((PTR)[0] == 'b' && (PTR)[1] == 'f')          \
256     {                                                   \
257       char *s;                                          \
258       if ((s = (char*)strchr ((PTR), '{')))             \
259         while (*s != '}') {                             \
260           if (*s == 'b')                                \
261             /* hack, I replace it with R ie nothing */  \
262             *s = '0';                                   \
263           s++; }                                        \
264     }                                                   \
265 }
266
267 /* This is how to output an element of a case-vector that is absolute.
268    (The 68000 does not use such vectors,
269    but we must define this macro anyway.)  */
270 #undef ASM_OUTPUT_ADDR_VEC_ELT
271 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
272   asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
273
274 /* This is how to output an element of a case-vector that is relative.  */
275 #undef ASM_OUTPUT_ADDR_DIFF_ELT
276 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)  \
277   asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
278
279 /* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
280    keep switch tables in the text section.  */
281 #define JUMP_TABLES_IN_TEXT_SECTION 1
282
283 /* Output a float value (represented as a C double) as an immediate operand.
284    This macro is a 68k-specific macro.  */
285 #undef ASM_OUTPUT_FLOAT_OPERAND
286 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)               \
287  do {                                                           \
288       if (CODE == 'f')                                          \
289         {                                                       \
290           char dstr[30];                                        \
291           REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr);          \
292           asm_fprintf ((FILE), "%I%s", dstr);                   \
293         }                                                       \
294       else                                                      \
295         {                                                       \
296           long l;                                               \
297           REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);               \
298           if (sizeof (int) == sizeof (long))                    \
299             asm_fprintf ((FILE), "%I$%x", (int) l);             \
300           else                                                  \
301             asm_fprintf ((FILE), "%I$%lx", l);                  \
302         }                                                       \
303      } while (0)
304
305 /* Output a double value (represented as a C double) as an immediate operand.
306    This macro is a 68k-specific macro.  */
307 #undef ASM_OUTPUT_DOUBLE_OPERAND 
308 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                           \
309  do { char dstr[30];                                                    \
310       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);                     \
311       asm_fprintf (FILE, "%I%s", dstr);                                 \
312     } while (0)
313
314 /* Note, long double immediate operands are not actually
315    generated by m68k.md.  */
316 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
317 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE)                      \
318  do { char dstr[30];                                                    \
319       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);                     \
320       asm_fprintf (FILE, "%I%s", dstr);                                 \
321     } while (0)
322
323 #undef ASM_OUTPUT_COMMON
324 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
325 ( fputs ("\t.comm ", (FILE)),                   \
326   assemble_name ((FILE), (NAME)),               \
327   fprintf ((FILE), ",%u\n", (ROUNDED)))
328
329 #undef ASM_OUTPUT_LOCAL
330 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)     \
331   do {                                                  \
332     int align = exact_log2 (ROUNDED);                   \
333     /*fprintf ((FILE), "\tsection 14\n");  */               \
334     data_section ();                                    \
335     ASM_OUTPUT_ALIGN ((FILE), align)                    \
336     ASM_OUTPUT_LABEL ((FILE), (NAME));                  \
337     fprintf ((FILE), "\tdcb.b %u,0\n", (ROUNDED));      \
338     /* fprintf ((FILE), "\tsection 10\n"); */             \
339   } while (0)
340
341 #undef PRINT_OPERAND_ADDRESS
342 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
343 { register rtx reg1, reg2, breg, ireg;                                  \
344   register rtx addr = ADDR;                                             \
345   rtx offset;                                                           \
346   switch (GET_CODE (addr))                                              \
347     {                                                                   \
348     case REG:                                                           \
349       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);                  \
350       break;                                                            \
351     case PRE_DEC:                                                       \
352       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);       \
353       break;                                                            \
354     case POST_INC:                                                      \
355       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);       \
356       break;                                                            \
357     case PLUS:                                                          \
358       reg1 = 0; reg2 = 0;                                               \
359       ireg = 0; breg = 0;                                               \
360       offset = 0;                                                       \
361       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                          \
362         {                                                               \
363           offset = XEXP (addr, 0);                                      \
364           addr = XEXP (addr, 1);                                        \
365         }                                                               \
366       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))                     \
367         {                                                               \
368           offset = XEXP (addr, 1);                                      \
369           addr = XEXP (addr, 0);                                        \
370         }                                                               \
371       if (GET_CODE (addr) != PLUS) ;                                    \
372       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)                \
373         {                                                               \
374           reg1 = XEXP (addr, 0);                                        \
375           addr = XEXP (addr, 1);                                        \
376         }                                                               \
377       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)                \
378         {                                                               \
379           reg1 = XEXP (addr, 1);                                        \
380           addr = XEXP (addr, 0);                                        \
381         }                                                               \
382       else if (GET_CODE (XEXP (addr, 0)) == MULT)                       \
383         {                                                               \
384           reg1 = XEXP (addr, 0);                                        \
385           addr = XEXP (addr, 1);                                        \
386         }                                                               \
387       else if (GET_CODE (XEXP (addr, 1)) == MULT)                       \
388         {                                                               \
389           reg1 = XEXP (addr, 1);                                        \
390           addr = XEXP (addr, 0);                                        \
391         }                                                               \
392       else if (GET_CODE (XEXP (addr, 0)) == REG)                        \
393         {                                                               \
394           reg1 = XEXP (addr, 0);                                        \
395           addr = XEXP (addr, 1);                                        \
396         }                                                               \
397       else if (GET_CODE (XEXP (addr, 1)) == REG)                        \
398         {                                                               \
399           reg1 = XEXP (addr, 1);                                        \
400           addr = XEXP (addr, 0);                                        \
401         }                                                               \
402       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT             \
403           || GET_CODE (addr) == SIGN_EXTEND)                            \
404         { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }     \
405 /*  for OLD_INDEXING                                                    \
406       else if (GET_CODE (addr) == PLUS)                                 \
407         {                                                               \
408           if (GET_CODE (XEXP (addr, 0)) == REG)                         \
409             {                                                           \
410               reg2 = XEXP (addr, 0);                                    \
411               addr = XEXP (addr, 1);                                    \
412             }                                                           \
413           else if (GET_CODE (XEXP (addr, 1)) == REG)                    \
414             {                                                           \
415               reg2 = XEXP (addr, 1);                                    \
416               addr = XEXP (addr, 0);                                    \
417             }                                                           \
418         }                                                               \
419   */                                                                    \
420       if (offset != 0) { if (addr != 0) abort (); addr = offset; }      \
421       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND                      \
422                     || GET_CODE (reg1) == MULT))                        \
423           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))         \
424         { breg = reg2; ireg = reg1; }                                   \
425       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))         \
426         { breg = reg1; ireg = reg2; }                                   \
427       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)       \
428         { int scale = 1;                                                \
429           if (GET_CODE (ireg) == MULT)                                  \
430             { scale = INTVAL (XEXP (ireg, 1));                          \
431               ireg = XEXP (ireg, 0); }                                  \
432           if (GET_CODE (ireg) == SIGN_EXTEND)                           \
433             fprintf (FILE, "(.L%d,pc,%s.w",                             \
434                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
435                      reg_names[REGNO (XEXP (ireg, 0))]);                \
436           else                                                          \
437             fprintf (FILE, "(.L%d,pc,%s.l",                             \
438                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
439                      reg_names[REGNO (ireg)]);                          \
440           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
441           putc (')', FILE);                                             \
442           break; }                                                      \
443         if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF      \
444             && ! (flag_pic && breg == pic_offset_table_rtx))            \
445           {                                                             \
446             fprintf (FILE, "(.L%d,pc,%s.l",                             \
447                          CODE_LABEL_NUMBER (XEXP (addr, 0)),            \
448                          reg_names[REGNO (breg)]);                      \
449             putc (')', FILE);                                           \
450             break; }                                                    \
451       if (ireg != 0 || breg != 0)                                       \
452         { int scale = 1;                                                \
453           if (breg == 0)                                                \
454             abort ();                                                   \
455           putc ('(', FILE);                                             \
456           if (addr != 0)                                                \
457             {                                                           \
458               output_addr_const (FILE, addr);                           \
459               putc (',', FILE);                                         \
460             }                                                           \
461           fprintf (FILE, "%s", reg_names[REGNO (breg)]);                \
462           if (ireg != 0)                                                \
463             putc (',', FILE);                                           \
464           if (ireg != 0 && GET_CODE (ireg) == MULT)                     \
465             { scale = INTVAL (XEXP (ireg, 1));                          \
466               ireg = XEXP (ireg, 0); }                                  \
467           if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)              \
468             fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);  \
469           else if (ireg != 0)                                           \
470             fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);            \
471           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
472           putc (')', FILE);                                             \
473           break;                                                        \
474         }                                                               \
475       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)               \
476         { fprintf (FILE, "(.L%d,pc,%s.w)",                              \
477                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
478                    reg_names[REGNO (reg1)]);                            \
479           break; }                                                      \
480     default:                                                            \
481       if (GET_CODE (addr) == CONST_INT                                  \
482           && INTVAL (addr) < 0x8000                                     \
483           && INTVAL (addr) >= -0x8000)                                  \
484         fprintf (FILE, "%d.w", INTVAL (addr));                          \
485       else                                                              \
486         output_addr_const (FILE, addr);                                 \
487     }}
488
489
490 #endif /* ! use gas */