OSDN Git Service

* dwarf2out.c (dwarf2out_finish): Don't abort because of orphan
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / news.h
1 /* Definitions of target machine for GNU compiler.  SONY NEWS-OS 4 version.
2    Copyright (C) 1987, 1989, 1993, 1994, 1996, 1997, 1998, 1999
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #ifndef USE_GAS
23 /* This controls conditionals in m68k.h.  */
24 #define MOTOROLA                /* Use Motorola syntax rather than "MIT" */
25 #define SGS_NO_LI               /* Suppress jump table label usage */
26 #endif
27
28 #define NEWS
29 #define NO_DOLLAR_IN_LABEL
30 #define NO_DOT_IN_LABEL
31
32 #include "m68k/m68k.h"
33
34 /* See m68k.h.  7 means 68020 with 68881.  */
35
36 #define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020)
37
38 /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified.
39    This will control the use of inline 68881 insns in certain macros.  */
40
41 #define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__}"
42
43 /* Names to predefine in the preprocessor for this target machine.  */
44 /* These are the ones defined by Sony, plus mc68000 for uniformity with
45    GCC on other 68000 systems.  */
46
47 #ifdef MOTOROLA
48 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700 -D__motorola__ -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
49 #else
50 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700 -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
51 #endif
52
53 /* These conditionals tested for different submodels,
54    but they were incorrect since they tested the host rather than the target.
55    The choice of model shouldn't actually matter.  */
56
57 #if 0
58 #ifdef news800
59 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews800 -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
60 #endif
61 #ifdef news900
62 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews900 -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
63 #endif
64 #ifdef news1500
65 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1500 -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
66 #endif
67 #ifdef news1700
68 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1700 -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
69 #endif
70 #ifdef news1800
71 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1800 -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
72 #endif
73 #ifdef news1900
74 #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1900 -Asystem=unix -Asystem=bsd -Acpu=m68k -Amachine=m68k"
75 #endif
76 #endif
77
78 /* Link with libg.a when debugging, for dbx's sake.  */
79
80 #define LIB_SPEC "%{g:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} "
81
82 /* This is BSD, so it wants DBX format.  */
83
84 #define DBX_DEBUGGING_INFO
85
86 #if 0
87 /* This is to be compatible with types.h.
88    It was found to be necessary with Newsos 3.  */
89
90 #define SIZE_TYPE "long int"
91 #endif
92 \f
93 /* Override parts of m68k.h to fit Sony's assembler syntax.  */
94
95 #undef BIGGEST_ALIGNMENT
96 #undef CALL_USED_REGISTERS
97 #undef FUNCTION_VALUE
98 #undef LIBCALL_VALUE
99 #undef FUNCTION_PROFILER
100
101 #ifdef MOTOROLA
102 #undef REGISTER_NAMES
103 #undef ASM_OUTPUT_REG_PUSH
104 #undef ASM_OUTPUT_REG_POP
105 #undef ASM_OUTPUT_DOUBLE
106 #undef ASM_OUTPUT_SKIP
107 #undef ASM_FORMAT_PRIVATE_NAME
108 #endif  
109
110 #undef ASM_OUTPUT_ALIGN
111
112 /* There is no point aligning anything to a rounder boundary than this.  */
113 #define BIGGEST_ALIGNMENT 32
114
115 /* A bitfield declared as `int' forces `int' alignment for the struct.  */
116 #define PCC_BITFIELD_TYPE_MATTERS 1
117   
118 /* NEWS makes d2, d3, fp2 and fp3 unsaved registers, unlike the Sun system.  */
119   
120 #define CALL_USED_REGISTERS \
121  {1, 1, 1, 1, 0, 0, 0, 0, \
122   1, 1, 0, 0, 0, 0, 0, 1, \
123   1, 1, 1, 1, 0, 0, 0, 0}
124
125 /* NEWS returns floats and doubles in fp0, not d0/d1.  */
126
127 #define FUNCTION_VALUE(VALTYPE,FUNC) LIBCALL_VALUE (TYPE_MODE (VALTYPE))
128
129 #define LIBCALL_VALUE(MODE)                                     \
130  gen_rtx_REG ((MODE),                                           \
131               ((TARGET_68881                                    \
132                 && ((MODE) == SFmode || (MODE) == DFmode        \
133                     || (MODE) == XFmode))                       \
134                ? 16 : 0))
135
136 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
137   fprintf (FILE, "\t.align %d\n", (LOG))
138 \f
139 #ifdef MOTOROLA
140
141 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
142    fprintf (FILE, "\tmove.l #LP%d,d0\n\tjsr mcount\n", (LABEL_NO));
143
144 /* Difference from m68k.h is in `fp' instead of `a6'.  */
145
146 #define REGISTER_NAMES \
147 {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",        \
148  "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp",        \
149  "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7"}
150
151 /* This is how to output an insn to push a register on the stack.
152    It need not be very fast code.  */
153
154 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
155   fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
156
157 /* This is how to output an insn to pop a register from the stack.
158    It need not be very fast code.  */
159
160 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
161   fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
162   
163 #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
164 do { char dstr[30];                                     \
165      REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr);    \
166      fprintf (FILE, "\t.double 0d%s\n", dstr);          \
167    } while (0)
168
169 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
170   fprintf (FILE, "\t.space %u\n", (SIZE))
171
172 #if 0
173 /* The NEWS assembler in version 3.4 complains about fmove.d, but this
174    macro proved not to work right.  3.4 is old, so forget about it.  */
175 #define ASM_OUTPUT_OPCODE(FILE, STRING) \
176 {                                               \
177   if (!strncmp (STRING, "fmove.d", 7)           \
178       && CONSTANT_P (operands[1]))              \
179     {                                           \
180       fprintf (FILE, "fmove.x");                \
181       STRING += 7;                              \
182     }                                           \
183 }
184 #endif
185
186 /* Store in OUTPUT a string (made with alloca) containing
187    an assembler-name for a local static variable named NAME.
188    LABELNO is an integer which is different for each call.  */
189
190 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
191 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 13),    \
192   sprintf ((OUTPUT), "%s$$$%d", (NAME), (LABELNO)))
193
194 /* Output a float value (represented as a C double) as an immediate operand.
195    This macro is a 68k-specific macro.  */
196
197 #undef ASM_OUTPUT_FLOAT_OPERAND
198 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)                       \
199  do {                                                                   \
200       if (CODE == 'f')                                                  \
201         {                                                               \
202           char dstr[30];                                                \
203           REAL_VALUE_TO_DECIMAL (VALUE, "%.9e", dstr);                  \
204           if (REAL_VALUE_ISINF (VALUE) || REAL_VALUE_ISNAN (VALUE))     \
205             {                                                           \
206               if (REAL_VALUE_NEGATIVE (VALUE))                          \
207                 fprintf (FILE, "#0f-99e999");                           \
208               else                                                      \
209                 fprintf (FILE, "#0f99e999");                            \
210             }                                                           \
211           else if (REAL_VALUE_MINUS_ZERO (VALUE))                       \
212             fprintf (FILE, "#0f-0.0");                                  \
213           else                                                          \
214             fprintf (FILE, "#0f%s", dstr);                              \
215         }                                                               \
216       else                                                              \
217         {                                                               \
218           long l;                                                       \
219           REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);                       \
220           fprintf (FILE, "#0x%lx", l);                                  \
221         }                                                               \
222      } while (0)
223
224 /* Output a double value (represented as a C double) as an immediate operand.
225    This macro is a 68k-specific macro.  */
226 #undef ASM_OUTPUT_DOUBLE_OPERAND
227 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                           \
228  do { char dstr[30];                                                    \
229       REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", dstr );                    \
230       if (REAL_VALUE_ISINF (VALUE) || REAL_VALUE_ISNAN (VALUE))         \
231         {                                                               \
232         if (REAL_VALUE_NEGATIVE (VALUE))                                \
233           fprintf (FILE, "#0d-99e999");                                 \
234         else                                                            \
235           fprintf (FILE, "#0d99e999");                                  \
236         }                                                               \
237       else if (REAL_VALUE_MINUS_ZERO (VALUE))                           \
238           fprintf (FILE, "#0d-0.0");                                    \
239       else                                                              \
240           fprintf (FILE, "#0d%s", dstr);                                \
241     } while (0)
242
243 /* Note, long double immediate operands are not actually
244    generated by m68k.md.  */
245 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
246 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE)                      \
247  do { char dstr[30];                                                    \
248       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);                     \
249       asm_fprintf (FILE, "%I0r%s", dstr);                               \
250     } while (0)
251
252 #if 0
253 #undef PRINT_OPERAND
254 #define PRINT_OPERAND(FILE, X, CODE)  \
255 { if (CODE == '.') fprintf (FILE, ".");                                 \
256   else if (CODE == '#') fprintf (FILE, "#");                            \
257   else if (CODE == '-') fprintf (FILE, "-(sp)");                        \
258   else if (CODE == '+') fprintf (FILE, "(sp)+");                        \
259   else if (CODE == '@') fprintf (FILE, "(sp)");                         \
260   else if (CODE == '!') fprintf (FILE, "fpcr");                         \
261   else if (CODE == '$') {if (TARGET_68040_ONLY) fprintf (FILE, "s");}   \
262   else if (CODE == '&') {if (TARGET_68040_ONLY) fprintf (FILE, "d");}   \
263   else if (CODE == '/')                                                 \
264     ;                                                                   \
265   else if (GET_CODE (X) == REG)                                         \
266     fprintf (FILE, "%s", reg_names[REGNO (X)]);                         \
267   else if (GET_CODE (X) == MEM)                                         \
268     output_address (XEXP (X, 0));                                       \
269   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)      \
270     { REAL_VALUE_TYPE r;                                                \
271       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
272       if (CODE == 'f')                                                  \
273         { char dstr[30];                                                \
274           REAL_VALUE_TO_DECIMAL (r, "%.9e", dstr);                      \
275           if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r)) {           \
276             if (REAL_VALUE_NEGATIVE (r))                                \
277               fprintf (FILE, "#0f-99e999");                             \
278             else                                                        \
279               fprintf (FILE, "#0f99e999"); }                            \
280           else if (REAL_VALUE_MINUS_ZERO (r))                           \
281             fprintf (FILE, "#0f-0.0");                                  \
282           else                                                          \
283             fprintf (FILE, "#0f%s", dstr);                              \
284         }                                                               \
285       else                                                              \
286         { long l;                                                       \
287           REAL_VALUE_TO_TARGET_SINGLE (r, l);                           \
288           fprintf (FILE, "#0x%lx", l);                                  \
289         }}                                                              \
290   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode)      \
291     { REAL_VALUE_TYPE r;                                                \
292       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
293       ASM_OUTPUT_LONG_DOUBLE_OPERAND (FILE, r); }                       \
294   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode)      \
295     { REAL_VALUE_TYPE r; char dstr[30];                                 \
296       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
297       REAL_VALUE_TO_DECIMAL (r, "%.20e", dstr );                        \
298       if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r)) {               \
299         if (REAL_VALUE_NEGATIVE (r))                                    \
300           fprintf (FILE, "#0d-99e999");                                 \
301         else                                                            \
302           fprintf (FILE, "#0d99e999"); }                                \
303       else if (REAL_VALUE_MINUS_ZERO (r))                               \
304           fprintf (FILE, "#0d-0.0");                                    \
305       else                                                              \
306           fprintf (FILE, "#0d%s", dstr); }                              \
307   else if (CODE == 'b') output_addr_const (FILE, X);                    \
308   else { putc ('#', FILE); output_addr_const (FILE, X); }}
309 #endif
310
311 #undef PRINT_OPERAND_ADDRESS
312 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
313 { register rtx reg1, reg2, breg, ireg;                                  \
314   register rtx addr = ADDR;                                             \
315   rtx offset;                                                           \
316   switch (GET_CODE (addr))                                              \
317     {                                                                   \
318     case REG:                                                           \
319       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);                  \
320       break;                                                            \
321     case PRE_DEC:                                                       \
322       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);       \
323       break;                                                            \
324     case POST_INC:                                                      \
325       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);       \
326       break;                                                            \
327     case PLUS:                                                          \
328       reg1 = 0; reg2 = 0;                                               \
329       ireg = 0; breg = 0;                                               \
330       offset = 0;                                                       \
331       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                          \
332         {                                                               \
333           offset = XEXP (addr, 0);                                      \
334           addr = XEXP (addr, 1);                                        \
335         }                                                               \
336       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))                     \
337         {                                                               \
338           offset = XEXP (addr, 1);                                      \
339           addr = XEXP (addr, 0);                                        \
340         }                                                               \
341       if (GET_CODE (addr) != PLUS) ;                                    \
342       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)                \
343         {                                                               \
344           reg1 = XEXP (addr, 0);                                        \
345           addr = XEXP (addr, 1);                                        \
346         }                                                               \
347       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)                \
348         {                                                               \
349           reg1 = XEXP (addr, 1);                                        \
350           addr = XEXP (addr, 0);                                        \
351         }                                                               \
352       else if (GET_CODE (XEXP (addr, 0)) == MULT)                       \
353         {                                                               \
354           reg1 = XEXP (addr, 0);                                        \
355           addr = XEXP (addr, 1);                                        \
356         }                                                               \
357       else if (GET_CODE (XEXP (addr, 1)) == MULT)                       \
358         {                                                               \
359           reg1 = XEXP (addr, 1);                                        \
360           addr = XEXP (addr, 0);                                        \
361         }                                                               \
362       else if (GET_CODE (XEXP (addr, 0)) == REG)                        \
363         {                                                               \
364           reg1 = XEXP (addr, 0);                                        \
365           addr = XEXP (addr, 1);                                        \
366         }                                                               \
367       else if (GET_CODE (XEXP (addr, 1)) == REG)                        \
368         {                                                               \
369           reg1 = XEXP (addr, 1);                                        \
370           addr = XEXP (addr, 0);                                        \
371         }                                                               \
372       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT             \
373           || GET_CODE (addr) == SIGN_EXTEND)                            \
374         { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }     \
375       if (offset != 0) { if (addr != 0) abort (); addr = offset; }      \
376       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND                      \
377                     || GET_CODE (reg1) == MULT))                        \
378           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))         \
379         { breg = reg2; ireg = reg1; }                                   \
380       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))         \
381         { breg = reg1; ireg = reg2; }                                   \
382       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)       \
383         { int scale = 1;                                                \
384           if (GET_CODE (ireg) == MULT)                                  \
385             { scale = INTVAL (XEXP (ireg, 1));                          \
386               ireg = XEXP (ireg, 0); }                                  \
387           if (GET_CODE (ireg) == SIGN_EXTEND)                           \
388             fprintf (FILE, "(L%d.b,pc,%s.w",                            \
389                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
390                      reg_names[REGNO (XEXP (ireg, 0))]);                \
391           else                                                          \
392             fprintf (FILE, "(L%d.b,pc,%s.l",                            \
393                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
394                      reg_names[REGNO (ireg)]);                          \
395           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
396           putc (')', FILE);                                             \
397           break; }                                                      \
398       if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF)       \
399         { fprintf (FILE, "(L%d.b,pc,%s.l",                              \
400                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
401                    reg_names[REGNO (breg)]);                            \
402           putc (')', FILE);                                             \
403           break; }                                                      \
404       if (ireg != 0 || breg != 0)                                       \
405         { int scale = 1;                                                \
406           if (breg == 0)                                                \
407             abort ();                                                   \
408           if (addr && GET_CODE (addr) == LABEL_REF) abort ();           \
409           fprintf (FILE, "(");                                          \
410           if (addr != 0) {                                              \
411             output_addr_const (FILE, addr);                             \
412             putc (',', FILE); }                                         \
413           fprintf (FILE, "%s", reg_names[REGNO (breg)]);                \
414           if (ireg != 0)                                                \
415             putc (',', FILE);                                           \
416           if (ireg != 0 && GET_CODE (ireg) == MULT)                     \
417             { scale = INTVAL (XEXP (ireg, 1));                          \
418               ireg = XEXP (ireg, 0); }                                  \
419           if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)              \
420             fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);  \
421           else if (ireg != 0)                                           \
422             fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);            \
423           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
424           putc (')', FILE);                                             \
425           break;                                                        \
426         }                                                               \
427       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)               \
428         { fprintf (FILE, "(L%d.b,pc,%s.l)",                             \
429                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
430                    reg_names[REGNO (reg1)]);                            \
431           break; }                                                      \
432     default:                                                            \
433       if (GET_CODE (addr) == CONST_INT                                  \
434           && INTVAL (addr) < 0x8000                                     \
435           && INTVAL (addr) >= -0x8000)                                  \
436         fprintf (FILE, "%d.w", INTVAL (addr));                          \
437       else                                                              \
438         output_addr_const (FILE, addr);                                 \
439     }}
440
441 #else /* Using GAS, which uses the MIT assembler syntax, like a Sun.  */
442
443 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
444    fprintf (FILE, "\tmovl #LP%d,d0\n\tjsr mcount\n", (LABEL_NO));
445
446 #endif /* MOTOROLA */