OSDN Git Service

* toplev.c (output_lang_identify): Delete.
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / hp320.h
1 /* Definitions of target machine for GNU compiler.  HP-UX 68000/68020 version.
2    Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1999, 2000
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 /* Define USE_GAS if GCC is supposed to work with the GNU assembler,
23    GNU linker and GNU debugger using DBX debugging information.
24    (In other words, much of HPUX has been cast aside.)
25    Undefine USE_GAS if you want GCC to feed the HP assembler.  */
26
27 /* #define USE_GAS */  /* Use hp320g.h if you want this.  */
28
29 /* Control assembler-syntax conditionals in m68k.md.  */
30
31 #ifndef USE_GAS
32 #define MOTOROLA                /* Use Motorola syntax rather than "MIT" */
33 #define SGS                     /* Uses SGS assembler */
34 #define SGS_CMP_ORDER           /* Takes cmp operands in reverse order */
35 #define HPUX_ASM
36
37 #if !defined (CROSS_COMPILE) && !defined (NO_BUGS)
38 /* The assembler on HP 9k3xx machines running HPUX 8.0 doesn't translate
39    floating point constants behind some operands.  The workaround is to
40    use hex constants.  Reported by Thomas Nau (nau@medizin.uni-ulm.de).  */
41 #define AS_BUG_FLOATING_CONSTANT
42 /* The assembler on HP 9k3xx machines running HPUX 8.0 doesn't accept
43    labels followed by a text, data, or other section directive.  Reported
44    by Thomas Nau (nau@medizin.uni-ulm.de).  */
45 #define AS_BUG_TRAILING_LABEL
46 #endif
47
48 #endif /* not USE_GAS */
49
50 /* gcc.c should find libgcc.a itself rather than expecting linker to.  */
51 #define LINK_LIBGCC_SPECIAL
52 /* The arguments of -L must be a separate argv element.  */
53 #define SPACE_AFTER_L_OPTION
54 /* HP/UX doesn't have libg.a.  */
55 #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
56
57 /* Be compatible with system stddef.h.  */
58 #define SIZE_TYPE "unsigned int"
59
60 #include "m68k/m68k.h"
61
62 /* See m68k.h.  7 means 68020 with 68881.  */
63
64 #ifndef TARGET_DEFAULT
65 #define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020)
66 #endif
67
68 /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified.
69    This will control the use of inline 68881 insns in certain macros.  */
70
71 #ifdef HPUX_ASM
72
73 #define ASM_SPEC "%{m68000:+X}%{mc68000:+X}"
74
75 #define NO_DOT_IN_LABEL
76
77 #if TARGET_DEFAULT & MASK_68881  /* -m68881 is the default */
78
79 /* These definitions differ from those used for GAS by defining __HPUX_ASM__.
80    This is needed because some programs, particularly GDB, need to
81    know which assembler is being used so that the correct `asm'
82    instructions can be used. */
83
84 #define CPP_SPEC \
85 "%{!msoft-float:-D__HAVE_68881__ }\
86 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE} -D__HPUX_ASM__"
87
88 #else /* default is -msoft-float */
89
90 #define CPP_SPEC \
91 "%{m68881:-D__HAVE_68881__ }\
92 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE} -D__HPUX_ASM__"
93
94 #endif /* default is -msoft-float */
95
96 #else /* not HPUX_ASM */
97
98 #if TARGET_DEFAULT & MASK_68881  /* -m68881 is the default */
99
100 #define CPP_SPEC \
101 "%{!msoft-float:-D__HAVE_68881__ }\
102 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE}"
103
104 #else /* default is -msoft-float */
105
106 #define CPP_SPEC \
107 "%{m68881:-D__HAVE_68881__ }\
108 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE}"
109
110 #endif /* default is -msoft-float */
111
112
113 /* -m68000 requires special flags to the assembler.  */
114 #define ASM_SPEC \
115  "%{m68000:-mc68000}%{mc68000:-mc68000}%{!mc68000:%{!m68000:-mc68020}}"
116
117 /* Tell GCC to put a space after -L when generating such options.  */
118 #define SPACE_AFTER_L_OPTION
119
120 #endif /* Not HPUX_ASM */
121
122 /* Translate -static for HPUX linker.  */
123 #define LINK_SPEC "%{static:-a archive}"
124
125 /* Names to predefine in the preprocessor for this target machine
126    (for non-strict-ANSI programs only).  */
127 /* These are the ones defined by HPUX cc, plus mc68000 for uniformity with
128    GCC on other 68000 systems.  */
129
130 #define CPP_PREDEFINES "-Dhp9000s200 -Dhp9000s300 -DPWB -Dhpux -Dunix -D__hp9000s300 -D__hp9000s200 -D__PWB -D__hpux -D__unix -D__motorola__ -Asystem=unix -Asystem=hpux -Acpu=m68k -Amachine=m68k"
131
132 /* Every structure or union's size must be a multiple of 2 bytes.  */
133
134 #define STRUCTURE_SIZE_BOUNDARY 16
135
136 /* hpux doesn't use static area for struct returns. */
137 #undef PCC_STATIC_STRUCT_RETURN
138
139 /* Generate calls to memcpy, memcmp and memset.  */
140 #define TARGET_MEM_FUNCTIONS
141
142 #if 0  /* No longer correct in HPUX version 6.5.  */
143 /* Function calls don't save any fp registers on hpux.  */
144 #undef CALL_USED_REGISTERS
145 #define CALL_USED_REGISTERS                                             \
146  {1, 1, 0, 0, 0, 0, 0, 0,                                               \
147   1, 1, 0, 0, 0, 0, 0, 1,                                               \
148   1, 1, 1, 1, 1, 1, 1, 1}
149 #endif /* 0 */
150
151 #ifdef HPUX_ASM
152
153 /* Override parts of m68k.h to fit the HPUX assembler.  */
154
155 #undef TARGET_VERSION
156 #undef REGISTER_NAMES
157 #undef ASM_OUTPUT_REG_PUSH
158 #undef ASM_OUTPUT_REG_POP
159 #undef ASM_FILE_START
160 #undef ASM_APP_ON
161 #undef ASM_APP_OFF
162 #undef TEXT_SECTION_ASM_OP
163 #undef DATA_SECTION_ASM_OP
164 #undef READONLY_DATA_SECTION
165 #undef ASM_OUTPUT_DOUBLE
166 #undef ASM_OUTPUT_FLOAT
167 #undef ASM_OUTPUT_INT
168 #undef ASM_OUTPUT_SHORT
169 #undef ASM_OUTPUT_CHAR
170 #undef ASM_OUTPUT_BYTE
171 #undef ASM_OUTPUT_ADDR_VEC_ELT
172 #undef ASM_OUTPUT_ADDR_DIFF_ELT
173 #undef ASM_OUTPUT_ALIGN
174 #undef ASM_OUTPUT_SKIP
175 #undef ASM_OUTPUT_COMMON
176 #undef ASM_OUTPUT_LOCAL
177 #undef ASM_FORMAT_PRIVATE_NAME
178 #undef FUNCTION_PROFILER
179 #undef ASM_OUTPUT_INTERNAL_LABEL
180 #undef GLOBAL_ASM_OP
181 #undef IMMEDIATE_PREFIX
182 #undef REGISTER_PREFIX
183
184 #define TARGET_VERSION fprintf (stderr, " (68k, SGS/hpux syntax)");
185
186 #define REGISTER_NAMES \
187 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",        \
188  "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",        \
189  "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7"}
190
191 #define IMMEDIATE_PREFIX        "&"
192 #define REGISTER_PREFIX         "%"
193
194 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
195    fprintf (FILE, "\tmov.l &LP%d,%%a0\n\tjsr mcount\n", (LABEL_NO));
196
197 /* This is how to output an insn to push a register on the stack.
198    It need not be very fast code.  */
199
200 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
201   fprintf (FILE, "\tmov.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 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
207   fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
208
209 /* For HPUX versions before 6.5, define this macro as empty.  */
210 #define ASM_FILE_START(FILE)                                            \
211   if (TARGET_68020)                                                     \
212     {                                                                   \
213       if (TARGET_68881)                                                 \
214          fprintf (FILE, "\tversion 3\n"); /* 68020 fp regs saved */     \
215       else                                                              \
216          fprintf (FILE, "\tversion 2\n"); /* 68020 no fp regs saved */  \
217     }                                                                   \
218   else                                                                  \
219     fprintf (FILE, "\tversion 1\n");    /* 68010 */
220
221 #define ASM_APP_ON ""
222
223 #define ASM_APP_OFF ""
224
225 #ifdef AS_BUG_TRAILING_LABEL
226 #define TEXT_SECTION_ASM_OP "\tlalign\t1\ntext"
227 #define DATA_SECTION_ASM_OP "\tlalign\t1\ndata"
228 #else
229 #define TEXT_SECTION_ASM_OP "text"
230 #define DATA_SECTION_ASM_OP "data"
231 #endif
232 #define ASCII_DATA_ASM_OP "\tbyte\t"
233  
234 /* This is the command to make the user-level label named NAME
235    defined for reference from other files.  */
236
237 #define GLOBAL_ASM_OP "\tglobal\t"
238
239 /* This says how to output an assembler line
240    to define a global common symbol.  */
241
242 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
243 ( fputs ("\tcomm ", (FILE)),                    \
244   assemble_name ((FILE), (NAME)),               \
245   fprintf ((FILE), ",%u\n", (ROUNDED)))
246
247 /* This says how to output an assembler line
248    to define a local common symbol.  */
249
250 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
251 ( fputs ("\tlcomm ", (FILE)),                   \
252   assemble_name ((FILE), (NAME)),               \
253   fprintf ((FILE), ",%u,2\n", (ROUNDED)))
254
255 /* Store in OUTPUT a string (made with alloca) containing
256    an assembler-name for a local static variable named NAME.
257    LABELNO is an integer which is different for each call.  */
258
259 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
260 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12),    \
261   sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
262
263 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)      \
264 do{  if (PREFIX[0] == 'L' && PREFIX[1] == 'I')          \
265     fprintf(FILE, "\tset %s%d,.+2\n", PREFIX, NUM);     \
266   else                                                  \
267     fprintf (FILE, "%s%d:\n", PREFIX, NUM);             \
268 } while(0)
269
270 #define ASM_OUTPUT_DOUBLE(FILE, VALUE)                  \
271   do { char dstr[30];                                   \
272        REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);    \
273        fprintf (FILE, "\tdouble 0f%s\n", dstr);         \
274      } while (0)
275
276 #define ASM_OUTPUT_FLOAT(FILE, VALUE)                   \
277   do { char dstr[30];                                   \
278        REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr);     \
279        fprintf (FILE, "\tfloat 0f%s\n", dstr);          \
280      } while (0)
281
282 #undef ASM_OUTPUT_LONG_DOUBLE
283 #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)                              \
284 do { long l[3];                                                         \
285      REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l);                       \
286      fprintf (FILE, "\tlong 0x%x,0x%x,0x%x\n", l[0], l[1], l[2]);       \
287    } while (0)
288   
289 /* This is how to output an assembler line defining an `int' constant.  */
290
291 #define ASM_OUTPUT_INT(FILE,VALUE)  \
292 ( fprintf (FILE, "\tlong "),                    \
293   output_addr_const (FILE, (VALUE)),            \
294   fprintf (FILE, "\n"))
295
296 /* Likewise for `char' and `short' constants.  */
297
298 #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
299 ( fprintf (FILE, "\tshort "),                   \
300   output_addr_const (FILE, (VALUE)),            \
301   fprintf (FILE, "\n"))
302
303 #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
304 ( fprintf (FILE, "\tbyte "),                    \
305   output_addr_const (FILE, (VALUE)),            \
306   fprintf (FILE, "\n"))
307
308 /* This is how to output an assembler line for a numeric constant byte.  */
309
310 #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
311   fprintf (FILE, "\tbyte 0x%x\n", (VALUE))
312
313 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
314   fprintf (FILE, "\tlong L%d\n", VALUE)
315
316 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)  \
317   fprintf (FILE, "\tshort L%d-L%d\n", VALUE, REL)
318
319 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
320   if ((LOG) == 1)                       \
321     fprintf (FILE, "\tlalign 2\n");     \
322   else if ((LOG) != 0)                  \
323     abort ();
324
325 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
326   fprintf (FILE, "\tspace %u\n", (SIZE))
327
328 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME)
329 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO)
330
331 /* Output a float value (represented as a C double) as an immediate operand.
332    This macro is a 68k-specific macro.  */
333
334 #undef ASM_OUTPUT_FLOAT_OPERAND
335 #ifdef AS_BUG_FLOATING_CONSTANT
336 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)               \
337  do { long l;                                                   \
338       REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);                   \
339       fprintf ((FILE), "&0x%lx", l);                            \
340      } while (0)
341 #else
342 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)               \
343  do {                                                           \
344       if (CODE == 'f')                                          \
345         {                                                       \
346           char dstr[30];                                        \
347           REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr);          \
348           fprintf ((FILE), "&0f%s", dstr);                      \
349         }                                                       \
350       else                                                      \
351         {                                                       \
352           long l;                                               \
353           REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);               \
354           fprintf ((FILE), "&0x%lx", l);                        \
355         }                                                       \
356      } while (0)
357 #endif /* AS_BUG_FLOATING_CONSTANT */
358
359 /* Output a double value (represented as a C double) as an immediate operand.
360    This macro is a 68k-specific macro.  */
361 #undef ASM_OUTPUT_DOUBLE_OPERAND
362 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                           \
363  do { char dstr[30];                                                    \
364       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);                     \
365       fprintf (FILE, "&0f%s", dstr);                                    \
366     } while (0)
367
368 /* Note, long double immediate operands are not actually
369    generated by m68k.md.  */
370 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
371 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE)                      \
372  do { char dstr[30];                                                    \
373       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);                     \
374       fprintf (FILE, "&0f%s", dstr);                                    \
375     } while (0)
376
377 #if 0
378 #undef PRINT_OPERAND
379 #define PRINT_OPERAND(FILE, X, CODE)  \
380 { if (CODE == '.') fprintf (FILE, ".");                                 \
381   else if (CODE == '#') fprintf (FILE, "&");                            \
382   else if (CODE == '-') fprintf (FILE, "-(%%sp)");                      \
383   else if (CODE == '+') fprintf (FILE, "(%%sp)+");                      \
384   else if (CODE == '@') fprintf (FILE, "(%%sp)");                       \
385   else if (CODE == '!') fprintf (FILE, "%%fpcr");                       \
386   else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
387   else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
388   else if (CODE == '/')                                                 \
389     fprintf (FILE, "%%");                                               \
390   else if (GET_CODE (X) == REG)                                         \
391     fprintf (FILE, "%s", reg_names[REGNO (X)]);                         \
392   else if (GET_CODE (X) == MEM)                                         \
393     output_address (XEXP (X, 0));                                       \
394   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)      \
395     { REAL_VALUE_TYPE r;  long l;                                       \
396       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
397       PRINT_OPERAND_FLOAT (CODE, FILE, r, l); }                         \
398   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode)      \
399     { REAL_VALUE_TYPE r;  char dstr[30];                                \
400       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
401       REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);                         \
402       fprintf (FILE, "&0f%s", dstr); }                                  \
403   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode)      \
404     { REAL_VALUE_TYPE r;  char dstr[30];                                \
405       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
406       REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);                         \
407       fprintf (FILE, "&0f%s", dstr); }                                  \
408   else { putc ('&', FILE); output_addr_const (FILE, X); }}
409 #endif
410
411 #undef PRINT_OPERAND_ADDRESS
412 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
413 { register rtx reg1, reg2, breg, ireg;                                  \
414   register rtx addr = ADDR;                                             \
415   rtx offset;                                                           \
416   switch (GET_CODE (addr))                                              \
417     {                                                                   \
418     case REG:                                                           \
419       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);                  \
420       break;                                                            \
421     case PRE_DEC:                                                       \
422       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);       \
423       break;                                                            \
424     case POST_INC:                                                      \
425       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);       \
426       break;                                                            \
427     case PLUS:                                                          \
428       reg1 = 0; reg2 = 0;                                               \
429       ireg = 0; breg = 0;                                               \
430       offset = 0;                                                       \
431       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                          \
432         {                                                               \
433           offset = XEXP (addr, 0);                                      \
434           addr = XEXP (addr, 1);                                        \
435         }                                                               \
436       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))                     \
437         {                                                               \
438           offset = XEXP (addr, 1);                                      \
439           addr = XEXP (addr, 0);                                        \
440         }                                                               \
441       if (GET_CODE (addr) != PLUS) ;                                    \
442       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)                \
443         {                                                               \
444           reg1 = XEXP (addr, 0);                                        \
445           addr = XEXP (addr, 1);                                        \
446         }                                                               \
447       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)                \
448         {                                                               \
449           reg1 = XEXP (addr, 1);                                        \
450           addr = XEXP (addr, 0);                                        \
451         }                                                               \
452       else if (GET_CODE (XEXP (addr, 0)) == MULT)                       \
453         {                                                               \
454           reg1 = XEXP (addr, 0);                                        \
455           addr = XEXP (addr, 1);                                        \
456         }                                                               \
457       else if (GET_CODE (XEXP (addr, 1)) == MULT)                       \
458         {                                                               \
459           reg1 = XEXP (addr, 1);                                        \
460           addr = XEXP (addr, 0);                                        \
461         }                                                               \
462       else if (GET_CODE (XEXP (addr, 0)) == REG)                        \
463         {                                                               \
464           reg1 = XEXP (addr, 0);                                        \
465           addr = XEXP (addr, 1);                                        \
466         }                                                               \
467       else if (GET_CODE (XEXP (addr, 1)) == REG)                        \
468         {                                                               \
469           reg1 = XEXP (addr, 1);                                        \
470           addr = XEXP (addr, 0);                                        \
471         }                                                               \
472       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT             \
473           || GET_CODE (addr) == SIGN_EXTEND)                            \
474         { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }     \
475 /*  for OLD_INDEXING                                                    \
476       else if (GET_CODE (addr) == PLUS)                                 \
477         {                                                               \
478           if (GET_CODE (XEXP (addr, 0)) == REG)                         \
479             {                                                           \
480               reg2 = XEXP (addr, 0);                                    \
481               addr = XEXP (addr, 1);                                    \
482             }                                                           \
483           else if (GET_CODE (XEXP (addr, 1)) == REG)                    \
484             {                                                           \
485               reg2 = XEXP (addr, 1);                                    \
486               addr = XEXP (addr, 0);                                    \
487             }                                                           \
488         }                                                               \
489   */                                                                    \
490       if (offset != 0) { if (addr != 0) abort (); addr = offset; }      \
491       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND                      \
492                     || GET_CODE (reg1) == MULT))                        \
493           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))         \
494         { breg = reg2; ireg = reg1; }                                   \
495       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))         \
496         { breg = reg1; ireg = reg2; }                                   \
497       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)       \
498         { int scale = 1;                                                \
499           if (GET_CODE (ireg) == MULT)                                  \
500             { scale = INTVAL (XEXP (ireg, 1));                          \
501               ireg = XEXP (ireg, 0); }                                  \
502           if (GET_CODE (ireg) == SIGN_EXTEND)                           \
503             fprintf (FILE, "L%d-LI%d(%%pc,%s.w",                        \
504                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
505                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
506                      reg_names[REGNO (XEXP (ireg, 0))]);                \
507           else                                                          \
508             fprintf (FILE, "L%d-LI%d(%%pc,%s.l",                        \
509                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
510                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
511                      reg_names[REGNO (ireg)]);                          \
512           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
513           putc (')', FILE);                                             \
514           break; }                                                      \
515       if (ireg != 0 || breg != 0)                                       \
516         { int scale = 1;                                                \
517           if (breg == 0)                                                \
518             abort ();                                                   \
519           if (addr != 0)                                                \
520             output_addr_const (FILE, addr);                             \
521           fprintf (FILE, "(%s", reg_names[REGNO (breg)]);               \
522           if (ireg != 0)                                                \
523             putc (',', FILE);                                           \
524           if (ireg != 0 && GET_CODE (ireg) == MULT)                     \
525             { scale = INTVAL (XEXP (ireg, 1));                          \
526               ireg = XEXP (ireg, 0); }                                  \
527           if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)              \
528             fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);  \
529           else if (ireg != 0)                                           \
530             fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);            \
531           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
532           putc (')', FILE);                                             \
533           break;                                                        \
534         }                                                               \
535       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)               \
536         { fprintf (FILE, "L%d-LI%d(%%pc,%s.w)",                         \
537                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
538                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
539                    reg_names[REGNO (reg1)]);                            \
540           break; }                                                      \
541     default:                                                            \
542       if (GET_CODE (addr) == CONST_INT                                  \
543           && INTVAL (addr) < 0x8000                                     \
544           && INTVAL (addr) >= -0x8000)                                  \
545         fprintf (FILE, "%d.w", INTVAL (addr));                          \
546       else                                                              \
547         output_addr_const (FILE, addr);                                 \
548     }}
549
550 #define ASM_OUTPUT_ASCII(f, p, size)    \
551 do { register int i;                    \
552   int inside;                           \
553   inside = FALSE;                       \
554   for (i = 0; i < (size); i++) {        \
555     if (i % 8 == 0) {                   \
556       if (i != 0) {                     \
557         if (inside)                     \
558           putc('"', (f));               \
559         putc('\n', (f));                \
560         inside = FALSE;                 \
561       }                                 \
562       fprintf((f), "%s", ASCII_DATA_ASM_OP);    \
563     }                                   \
564     if ((p)[i] < 32 || (p)[i] == '\\' || (p)[i] == '"' || (p)[i] == 127) {      \
565       if (inside) {                     \
566         putc('"', (f));                 \
567         inside = FALSE;                 \
568       }                                 \
569       if (i % 8 != 0)                   \
570         putc(',', (f));                 \
571       fprintf((f), "%d", (p)[i]);       \
572     } else {                            \
573       if (!inside) {                    \
574         if (i % 8 != 0)                 \
575           putc(',', (f));               \
576         putc('"', (f));                 \
577         inside = TRUE;                  \
578       }                                 \
579       putc((p)[i], (f));                \
580     }                                   \
581   }                                     \
582   if (inside)                           \
583     putc('"', (f));                     \
584   putc('\n', (f));                      \
585 } while (0)
586
587 /* Translate Motorola opcodes such as `jbeq'
588    into SGS opcodes such as `beq.w'.
589    Delete the `e' in `move...' and `fmove'.
590    Change `ftst' to `ftest'.  */
591
592 #define ASM_OUTPUT_OPCODE(FILE, PTR)                    \
593 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')               \
594     { ++(PTR);                                          \
595       while (*(PTR) != ' ')                             \
596         { putc (*(PTR), (FILE)); ++(PTR); }             \
597       fprintf ((FILE), ".w"); }                         \
598   else if ((PTR)[0] == 'f')                             \
599     {                                                   \
600       if (!strncmp ((PTR), "fmove", 5))                 \
601         { fprintf ((FILE), "fmov"); (PTR) += 5; }       \
602       else if (!strncmp ((PTR), "ftst", 4))             \
603         { fprintf ((FILE), "ftest"); (PTR) += 4; }      \
604     }                                                   \
605   else if ((PTR)[0] == 'm' && (PTR)[1] == 'o'           \
606            && (PTR)[2] == 'v' && (PTR)[3] == 'e')       \
607     { fprintf ((FILE), "mov"); (PTR) += 4; }            \
608 }
609
610 #else /* not HPUX_ASM */
611
612 #undef FUNCTION_PROFILER
613
614 /* HP-UX needs the call to mcount before the link instruction.
615    Copy the return address onto the stack before the call to fake it out.  */
616 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
617   fprintf (FILE, \
618            "\tmovel a6@(4),sp@-\n\tmovl #LP%d,a0\n\tjsr mcount\n\taddqw #4,sp\n", \
619            (LABEL_NO));
620
621 #endif /* not HPUX_ASM */
622
623 /* In m68k svr4, a symbol_ref rtx can be a valid PIC operand if it is an
624    operand of a function call. */
625 #undef LEGITIMATE_PIC_OPERAND_P
626 #define LEGITIMATE_PIC_OPERAND_P(X) \
627   ((! symbolic_operand (X, VOIDmode) \
628     && ! (GET_CODE (X) == CONST_DOUBLE && CONST_DOUBLE_MEM (X)  \
629           && GET_CODE (CONST_DOUBLE_MEM (X)) == MEM             \
630           && symbolic_operand (XEXP (CONST_DOUBLE_MEM (X), 0), VOIDmode))) \
631    || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X))       \
632    || PCREL_GENERAL_OPERAND_OK)
633
634 /* hpux8 and later have C++ compatible include files, so do not
635    pretend they are `extern "C"'.  */
636 #define NO_IMPLICIT_EXTERN_C