OSDN Git Service

* clipper/clix.h (ASM_OUTPUT_ASCII): Avoid signed/unsigned
[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%lx,0x%lx,0x%lx\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", (int)(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 do {                                    \
321   if ((LOG) == 1)                       \
322     fprintf (FILE, "\tlalign 2\n");     \
323   else if ((LOG) != 0)                  \
324     abort ();                           \
325 } while (0)
326
327 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
328   fprintf (FILE, "\tspace %u\n", (SIZE))
329
330 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME)
331 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO)
332
333 /* Output a float value (represented as a C double) as an immediate operand.
334    This macro is a 68k-specific macro.  */
335
336 #undef ASM_OUTPUT_FLOAT_OPERAND
337 #ifdef AS_BUG_FLOATING_CONSTANT
338 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)               \
339  do { long l;                                                   \
340       REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);                   \
341       fprintf ((FILE), "&0x%lx", l);                            \
342      } while (0)
343 #else
344 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)               \
345  do {                                                           \
346       if (CODE == 'f')                                          \
347         {                                                       \
348           char dstr[30];                                        \
349           REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr);          \
350           fprintf ((FILE), "&0f%s", dstr);                      \
351         }                                                       \
352       else                                                      \
353         {                                                       \
354           long l;                                               \
355           REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);               \
356           fprintf ((FILE), "&0x%lx", l);                        \
357         }                                                       \
358      } while (0)
359 #endif /* AS_BUG_FLOATING_CONSTANT */
360
361 /* Output a double value (represented as a C double) as an immediate operand.
362    This macro is a 68k-specific macro.  */
363 #undef ASM_OUTPUT_DOUBLE_OPERAND
364 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                           \
365  do { char dstr[30];                                                    \
366       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);                     \
367       fprintf (FILE, "&0f%s", dstr);                                    \
368     } while (0)
369
370 /* Note, long double immediate operands are not actually
371    generated by m68k.md.  */
372 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
373 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE)                      \
374  do { char dstr[30];                                                    \
375       REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);                     \
376       fprintf (FILE, "&0f%s", dstr);                                    \
377     } while (0)
378
379 #if 0
380 #undef PRINT_OPERAND
381 #define PRINT_OPERAND(FILE, X, CODE)  \
382 { if (CODE == '.') fprintf (FILE, ".");                                 \
383   else if (CODE == '#') fprintf (FILE, "&");                            \
384   else if (CODE == '-') fprintf (FILE, "-(%%sp)");                      \
385   else if (CODE == '+') fprintf (FILE, "(%%sp)+");                      \
386   else if (CODE == '@') fprintf (FILE, "(%%sp)");                       \
387   else if (CODE == '!') fprintf (FILE, "%%fpcr");                       \
388   else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
389   else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
390   else if (CODE == '/')                                                 \
391     fprintf (FILE, "%%");                                               \
392   else if (GET_CODE (X) == REG)                                         \
393     fprintf (FILE, "%s", reg_names[REGNO (X)]);                         \
394   else if (GET_CODE (X) == MEM)                                         \
395     output_address (XEXP (X, 0));                                       \
396   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)      \
397     { REAL_VALUE_TYPE r;  long l;                                       \
398       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
399       PRINT_OPERAND_FLOAT (CODE, FILE, r, l); }                         \
400   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode)      \
401     { REAL_VALUE_TYPE r;  char dstr[30];                                \
402       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
403       REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);                         \
404       fprintf (FILE, "&0f%s", dstr); }                                  \
405   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode)      \
406     { REAL_VALUE_TYPE r;  char dstr[30];                                \
407       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
408       REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);                         \
409       fprintf (FILE, "&0f%s", dstr); }                                  \
410   else { putc ('&', FILE); output_addr_const (FILE, X); }}
411 #endif
412
413 #undef PRINT_OPERAND_ADDRESS
414 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
415 { register rtx reg1, reg2, breg, ireg;                                  \
416   register rtx addr = ADDR;                                             \
417   rtx offset;                                                           \
418   switch (GET_CODE (addr))                                              \
419     {                                                                   \
420     case REG:                                                           \
421       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);                  \
422       break;                                                            \
423     case PRE_DEC:                                                       \
424       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);       \
425       break;                                                            \
426     case POST_INC:                                                      \
427       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);       \
428       break;                                                            \
429     case PLUS:                                                          \
430       reg1 = 0; reg2 = 0;                                               \
431       ireg = 0; breg = 0;                                               \
432       offset = 0;                                                       \
433       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                          \
434         {                                                               \
435           offset = XEXP (addr, 0);                                      \
436           addr = XEXP (addr, 1);                                        \
437         }                                                               \
438       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))                     \
439         {                                                               \
440           offset = XEXP (addr, 1);                                      \
441           addr = XEXP (addr, 0);                                        \
442         }                                                               \
443       if (GET_CODE (addr) != PLUS) ;                                    \
444       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)                \
445         {                                                               \
446           reg1 = XEXP (addr, 0);                                        \
447           addr = XEXP (addr, 1);                                        \
448         }                                                               \
449       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)                \
450         {                                                               \
451           reg1 = XEXP (addr, 1);                                        \
452           addr = XEXP (addr, 0);                                        \
453         }                                                               \
454       else if (GET_CODE (XEXP (addr, 0)) == MULT)                       \
455         {                                                               \
456           reg1 = XEXP (addr, 0);                                        \
457           addr = XEXP (addr, 1);                                        \
458         }                                                               \
459       else if (GET_CODE (XEXP (addr, 1)) == MULT)                       \
460         {                                                               \
461           reg1 = XEXP (addr, 1);                                        \
462           addr = XEXP (addr, 0);                                        \
463         }                                                               \
464       else if (GET_CODE (XEXP (addr, 0)) == REG)                        \
465         {                                                               \
466           reg1 = XEXP (addr, 0);                                        \
467           addr = XEXP (addr, 1);                                        \
468         }                                                               \
469       else if (GET_CODE (XEXP (addr, 1)) == REG)                        \
470         {                                                               \
471           reg1 = XEXP (addr, 1);                                        \
472           addr = XEXP (addr, 0);                                        \
473         }                                                               \
474       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT             \
475           || GET_CODE (addr) == SIGN_EXTEND)                            \
476         { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }     \
477 /*  for OLD_INDEXING                                                    \
478       else if (GET_CODE (addr) == PLUS)                                 \
479         {                                                               \
480           if (GET_CODE (XEXP (addr, 0)) == REG)                         \
481             {                                                           \
482               reg2 = XEXP (addr, 0);                                    \
483               addr = XEXP (addr, 1);                                    \
484             }                                                           \
485           else if (GET_CODE (XEXP (addr, 1)) == REG)                    \
486             {                                                           \
487               reg2 = XEXP (addr, 1);                                    \
488               addr = XEXP (addr, 0);                                    \
489             }                                                           \
490         }                                                               \
491   */                                                                    \
492       if (offset != 0) { if (addr != 0) abort (); addr = offset; }      \
493       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND                      \
494                     || GET_CODE (reg1) == MULT))                        \
495           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))         \
496         { breg = reg2; ireg = reg1; }                                   \
497       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))         \
498         { breg = reg1; ireg = reg2; }                                   \
499       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)       \
500         { int scale = 1;                                                \
501           if (GET_CODE (ireg) == MULT)                                  \
502             { scale = INTVAL (XEXP (ireg, 1));                          \
503               ireg = XEXP (ireg, 0); }                                  \
504           if (GET_CODE (ireg) == SIGN_EXTEND)                           \
505             fprintf (FILE, "L%d-LI%d(%%pc,%s.w",                        \
506                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
507                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
508                      reg_names[REGNO (XEXP (ireg, 0))]);                \
509           else                                                          \
510             fprintf (FILE, "L%d-LI%d(%%pc,%s.l",                        \
511                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
512                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
513                      reg_names[REGNO (ireg)]);                          \
514           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
515           putc (')', FILE);                                             \
516           break; }                                                      \
517       if (ireg != 0 || breg != 0)                                       \
518         { int scale = 1;                                                \
519           if (breg == 0)                                                \
520             abort ();                                                   \
521           if (addr != 0)                                                \
522             output_addr_const (FILE, addr);                             \
523           fprintf (FILE, "(%s", reg_names[REGNO (breg)]);               \
524           if (ireg != 0)                                                \
525             putc (',', FILE);                                           \
526           if (ireg != 0 && GET_CODE (ireg) == MULT)                     \
527             { scale = INTVAL (XEXP (ireg, 1));                          \
528               ireg = XEXP (ireg, 0); }                                  \
529           if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)              \
530             fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);  \
531           else if (ireg != 0)                                           \
532             fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);            \
533           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
534           putc (')', FILE);                                             \
535           break;                                                        \
536         }                                                               \
537       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)               \
538         { fprintf (FILE, "L%d-LI%d(%%pc,%s.w)",                         \
539                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
540                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
541                    reg_names[REGNO (reg1)]);                            \
542           break; }                                                      \
543     default:                                                            \
544       if (GET_CODE (addr) == CONST_INT                                  \
545           && INTVAL (addr) < 0x8000                                     \
546           && INTVAL (addr) >= -0x8000)                                  \
547         fprintf (FILE, "%d.w", INTVAL (addr));                          \
548       else                                                              \
549         output_addr_const (FILE, addr);                                 \
550     }}
551
552 #define ASM_OUTPUT_ASCII(f, p, SIZE)    \
553 do { size_t i, limit = (SIZE);          \
554   int inside;                           \
555   inside = FALSE;                       \
556   for (i = 0; i < limit; i++) { \
557     if (i % 8 == 0) {                   \
558       if (i != 0) {                     \
559         if (inside)                     \
560           putc('"', (f));               \
561         putc('\n', (f));                \
562         inside = FALSE;                 \
563       }                                 \
564       fprintf((f), "%s", ASCII_DATA_ASM_OP);    \
565     }                                   \
566     if ((p)[i] < 32 || (p)[i] == '\\' || (p)[i] == '"' || (p)[i] == 127) {      \
567       if (inside) {                     \
568         putc('"', (f));                 \
569         inside = FALSE;                 \
570       }                                 \
571       if (i % 8 != 0)                   \
572         putc(',', (f));                 \
573       fprintf((f), "%d", (p)[i]);       \
574     } else {                            \
575       if (!inside) {                    \
576         if (i % 8 != 0)                 \
577           putc(',', (f));               \
578         putc('"', (f));                 \
579         inside = TRUE;                  \
580       }                                 \
581       putc((p)[i], (f));                \
582     }                                   \
583   }                                     \
584   if (inside)                           \
585     putc('"', (f));                     \
586   putc('\n', (f));                      \
587 } while (0)
588
589 /* Translate Motorola opcodes such as `jbeq'
590    into SGS opcodes such as `beq.w'.
591    Delete the `e' in `move...' and `fmove'.
592    Change `ftst' to `ftest'.  */
593
594 #define ASM_OUTPUT_OPCODE(FILE, PTR)                    \
595 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')               \
596     { ++(PTR);                                          \
597       while (*(PTR) != ' ')                             \
598         { putc (*(PTR), (FILE)); ++(PTR); }             \
599       fprintf ((FILE), ".w"); }                         \
600   else if ((PTR)[0] == 'f')                             \
601     {                                                   \
602       if (!strncmp ((PTR), "fmove", 5))                 \
603         { fprintf ((FILE), "fmov"); (PTR) += 5; }       \
604       else if (!strncmp ((PTR), "ftst", 4))             \
605         { fprintf ((FILE), "ftest"); (PTR) += 4; }      \
606     }                                                   \
607   else if ((PTR)[0] == 'm' && (PTR)[1] == 'o'           \
608            && (PTR)[2] == 'v' && (PTR)[3] == 'e')       \
609     { fprintf ((FILE), "mov"); (PTR) += 4; }            \
610 }
611
612 #else /* not HPUX_ASM */
613
614 #undef FUNCTION_PROFILER
615
616 /* HP-UX needs the call to mcount before the link instruction.
617    Copy the return address onto the stack before the call to fake it out.  */
618 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
619   fprintf (FILE, \
620            "\tmovel a6@(4),sp@-\n\tmovl #LP%d,a0\n\tjsr mcount\n\taddqw #4,sp\n", \
621            (LABEL_NO));
622
623 #endif /* not HPUX_ASM */
624
625 /* In m68k svr4, a symbol_ref rtx can be a valid PIC operand if it is an
626    operand of a function call.  */
627 #undef LEGITIMATE_PIC_OPERAND_P
628 #define LEGITIMATE_PIC_OPERAND_P(X) \
629   ((! symbolic_operand (X, VOIDmode) \
630     && ! (GET_CODE (X) == CONST_DOUBLE && mem_for_const_double (X) != 0 \
631           && GET_CODE (mem_for_const_double (X)) == MEM                 \
632           && symbolic_operand (XEXP (mem_for_const_double (X), 0),      \
633                                VOIDmode)))                              \
634    || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X))               \
635    || PCREL_GENERAL_OPERAND_OK)
636
637 /* hpux8 and later have C++ compatible include files, so do not
638    pretend they are `extern "C"'.  */
639 #define NO_IMPLICIT_EXTERN_C