OSDN Git Service

(READONLY_DATA_SECTION): Remove definition.
[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 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /* Define USE_GAS if GCC is supposed to work with the GNU assembler,
21    GNU linker and GNU debugger using DBX debugging information.
22    (In other words, much of HPUX has been cast aside.)
23    Undefine USE_GAS if you want GCC to feed the HP assembler.  */
24
25 /* #define USE_GAS */  /* Use hp320g.h if you want this.  */
26
27 /* Control assembler-syntax conditionals in m68k.md.  */
28
29 #ifndef USE_GAS
30 #define MOTOROLA                /* Use Motorola syntax rather than "MIT" */
31 #define SGS                     /* Uses SGS assembler */
32 #define SGS_CMP_ORDER           /* Takes cmp operands in reverse order */
33 #define HPUX_ASM
34
35 #if !defined (CROSS_COMPILE) && !defined (NO_BUGS)
36 /* The assembler on HP 9k3xx machines running HPUX 8.0 doesn't translate
37    floating point constants behind some operands.  The workaround is to
38    use hex constants.  Reported by Thomas Nau (nau@medizin.uni-ulm.de).  */
39 #define AS_BUG_FLOATING_CONSTANT
40 /* The assembler on HP 9k3xx machines running HPUX 8.0 doesn't accept
41    labels followed by a text, data, or other section directive.  Reported
42    by Thomas Nau (nau@medizin.uni-ulm.de).  */
43 #define AS_BUG_TRAILING_LABEL
44 #endif
45
46 #endif /* not USE_GAS */
47
48 /* gcc.c should find libgcc.a itself rather than expecting linker to.  */
49 #define LINK_LIBGCC_SPECIAL
50 /* The arguments of -L must be a separate argv element.  */
51 #define SPACE_AFTER_L_OPTION
52 /* HP/UX doesn't have libg.a.  */
53 #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
54
55 /* Be compatible with system stddef.h.  */
56 #define SIZE_TYPE "unsigned int"
57
58 /* Use atexit for static constructors/destructors, instead of defining
59    our own exit function.  */
60 #define HAVE_ATEXIT
61
62 #include "m68k/m68k.h"
63
64 /* See m68k.h.  7 means 68020 with 68881.  */
65
66 #ifndef TARGET_DEFAULT
67 #define TARGET_DEFAULT 7
68 #endif
69
70 /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified.
71    This will control the use of inline 68881 insns in certain macros.  */
72
73 #ifdef HPUX_ASM
74
75 #define ASM_SPEC "%{m68000:+X}%{mc68000:+X}"
76
77 #if TARGET_DEFAULT & 02  /* -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 & 02  /* -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 FUNCTION_PROLOGUE
158 #undef FUNCTION_EPILOGUE
159 #undef ASM_OUTPUT_REG_PUSH
160 #undef ASM_OUTPUT_REG_POP
161 #undef ASM_FILE_START
162 #undef ASM_APP_ON
163 #undef ASM_APP_OFF
164 #undef TEXT_SECTION_ASM_OP
165 #undef DATA_SECTION_ASM_OP
166 #undef READONLY_DATA_SECTION
167 #undef ASM_OUTPUT_DOUBLE
168 #undef ASM_OUTPUT_FLOAT
169 #undef ASM_OUTPUT_INT
170 #undef ASM_OUTPUT_SHORT
171 #undef ASM_OUTPUT_CHAR
172 #undef ASM_OUTPUT_BYTE
173 #undef ASM_OUTPUT_ADDR_VEC_ELT
174 #undef ASM_OUTPUT_ADDR_DIFF_ELT
175 #undef ASM_OUTPUT_ALIGN
176 #undef ASM_OUTPUT_SKIP
177 #undef ASM_OUTPUT_COMMON
178 #undef ASM_OUTPUT_LOCAL
179 #undef ASM_FORMAT_PRIVATE_NAME
180 #undef PRINT_OPERAND
181 #undef PRINT_OPERAND_ADDRESS
182 #undef FUNCTION_PROFILER
183 #undef ASM_OUTPUT_INTERNAL_LABEL
184 #undef GLOBAL_ASM_OP
185
186 #define TARGET_VERSION fprintf (stderr, " (68k, SGS/hpux syntax)");
187
188 #define REGISTER_NAMES \
189 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",        \
190  "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",        \
191  "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7"}
192
193 #define FUNCTION_PROLOGUE(FILE, SIZE)     \
194 { register int regno;                                           \
195   register int mask = 0;                                        \
196   extern char call_used_regs[];                                 \
197   int fsize = (SIZE);                                           \
198   if (frame_pointer_needed)                                     \
199     { if (fsize < 0x8000)                                       \
200         fprintf (FILE, "\tlink.w %%a6,&%d\n", -fsize);          \
201       else if (TARGET_68020)                                    \
202         fprintf (FILE, "\tlink.l %%a6,&%d\n", -fsize);          \
203       else                                                      \
204         fprintf (FILE, "\tlink.w %%a6,&0\n\tsub.l &%d,%%sp\n", fsize); }  \
205   for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)      \
206     if (regs_ever_live[regno] && ! call_used_regs[regno])       \
207        mask |= 1 << (regno - 16);                               \
208   if (mask != 0)                                                \
209     fprintf (FILE, "\tfmovem &0x%x,-(%%sp)\n", mask & 0xff);       \
210   mask = 0;                                                     \
211   for (regno = 0; regno < 16; regno++)                          \
212     if (regs_ever_live[regno] && ! call_used_regs[regno])       \
213        mask |= 1 << (15 - regno);                               \
214   if (frame_pointer_needed)                                     \
215     mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));                 \
216   if (exact_log2 (mask) >= 0)                                   \
217     fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[15 - exact_log2 (mask)]);  \
218   else if (mask) fprintf (FILE, "\tmovm.l &0x%x,-(%%sp)\n", mask); }\
219   if (flag_pic && current_function_uses_pic_offset_table)       \
220     {                                                           \
221       fprintf (FILE, "\tmov.l &DLT, %s\n",\
222                    reg_names[PIC_OFFSET_TABLE_REGNUM]);         \
223       fprintf (FILE, "\tlea.l -0x6(%%pc,%s.l),%s\n",          \
224                    reg_names[PIC_OFFSET_TABLE_REGNUM],          \
225                    reg_names[PIC_OFFSET_TABLE_REGNUM]);         \
226     }
227
228 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
229    fprintf (FILE, "\tmov.l &LP%d,%%a0\n\tjsr mcount\n", (LABEL_NO));
230
231 #define FUNCTION_EPILOGUE(FILE, SIZE) \
232 { register int regno;                                           \
233   register int mask, fmask;                                     \
234   register int nregs;                                           \
235   int offset, foffset;                                          \
236   extern char call_used_regs[];                                 \
237   int fsize = (SIZE);                                           \
238   int big = 0;                                                  \
239   nregs = 0;  fmask = 0;                                        \
240   for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)      \
241     if (regs_ever_live[regno] && ! call_used_regs[regno])       \
242       { nregs++; fmask |= 1 << (23 - regno); }                  \
243   foffset = nregs * 12;                                         \
244   nregs = 0;  mask = 0;                                         \
245   if (frame_pointer_needed) regs_ever_live[FRAME_POINTER_REGNUM] = 0; \
246   for (regno = 0; regno < 16; regno++)                          \
247     if (regs_ever_live[regno] && ! call_used_regs[regno])       \
248       { nregs++; mask |= 1 << regno; }                          \
249   offset = foffset + nregs * 4;                                 \
250   if (offset + fsize >= 0x8000 && frame_pointer_needed)         \
251     { fprintf (FILE, "\tmov.l &%d,%%a0\n", -fsize);             \
252       fsize = 0, big = 1; }                                     \
253   if (exact_log2 (mask) >= 0) {                                 \
254     if (big)                                                    \
255       fprintf (FILE, "\tmov.l -%d(%%a6,%%a0.l),%s\n",           \
256                offset + fsize, reg_names[exact_log2 (mask)]);   \
257     else if (! frame_pointer_needed)                            \
258       fprintf (FILE, "\tmov.l (%%sp)+,%s\n",                    \
259                reg_names[exact_log2 (mask)]);                   \
260     else                                                        \
261       fprintf (FILE, "\tmov.l -%d(%%a6),%s\n",                  \
262                offset + fsize, reg_names[exact_log2 (mask)]); } \
263   else if (mask) {                                              \
264     if (big)                                                    \
265       fprintf (FILE, "\tmovm.l -%d(%%a6,%%a0.l),&0x%x\n",       \
266                offset + fsize, mask);                           \
267     else if (! frame_pointer_needed)                            \
268       fprintf (FILE, "\tmovm.l (%%sp)+,&0x%x\n", mask);         \
269     else                                                        \
270       fprintf (FILE, "\tmovm.l -%d(%%a6),&0x%x\n",              \
271                offset + fsize, mask); }                         \
272   if (fmask) {                                                  \
273     if (big)                                                    \
274       fprintf (FILE, "\tfmovem -%d(%%a6,%%a0.l),&0x%x\n",       \
275                foffset + fsize, fmask);                         \
276     else if (! frame_pointer_needed)                            \
277       fprintf (FILE, "\tfmovem (%%sp)+,&0x%x\n", fmask);        \
278     else                                                        \
279       fprintf (FILE, "\tfmovem -%d(%%a6),&0x%x\n",              \
280                foffset + fsize, fmask); }                       \
281   if (frame_pointer_needed)                                     \
282     fprintf (FILE, "\tunlk %%a6\n");                            \
283   if (current_function_pops_args)                               \
284     fprintf (FILE, "\trtd &%d\n", current_function_pops_args);  \
285   else fprintf (FILE, "\trts\n"); }
286
287 /* This is how to output an insn to push a register on the stack.
288    It need not be very fast code.  */
289
290 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
291   fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
292
293 /* This is how to output an insn to pop a register from the stack.
294    It need not be very fast code.  */
295
296 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
297   fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
298
299 /* For HPUX versions before 6.5, define this macro as empty.  */
300 #define ASM_FILE_START(FILE)                                            \
301   if (TARGET_68020)                                                     \
302     {                                                                   \
303       if (TARGET_68881)                                                 \
304          fprintf (FILE, "\tversion 3\n"); /* 68020 fp regs saved */     \
305       else                                                              \
306          fprintf (FILE, "\tversion 2\n"); /* 68020 no fp regs saved */  \
307     }                                                                   \
308   else                                                                  \
309     fprintf (FILE, "\tversion 1\n");    /* 68010 */
310
311 #define ASM_APP_ON ""
312
313 #define ASM_APP_OFF ""
314
315 #ifdef AS_BUG_TRAILING_LABEL
316 #define TEXT_SECTION_ASM_OP "\tlalign\t1\ntext"
317 #define DATA_SECTION_ASM_OP "\tlalign\t1\ndata"
318 #else
319 #define TEXT_SECTION_ASM_OP "text"
320 #define DATA_SECTION_ASM_OP "data"
321 #endif
322 #define ASCII_DATA_ASM_OP "byte"
323  
324 /* This is the command to make the user-level label named NAME
325    defined for reference from other files.  */
326
327 #define GLOBAL_ASM_OP "global"
328
329 /* This says how to output an assembler line
330    to define a global common symbol.  */
331
332 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
333 ( fputs ("\tcomm ", (FILE)),                    \
334   assemble_name ((FILE), (NAME)),               \
335   fprintf ((FILE), ",%u\n", (ROUNDED)))
336
337 /* This says how to output an assembler line
338    to define a local common symbol.  */
339
340 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
341 ( fputs ("\tlcomm ", (FILE)),                   \
342   assemble_name ((FILE), (NAME)),               \
343   fprintf ((FILE), ",%u,2\n", (ROUNDED)))
344
345 /* Store in OUTPUT a string (made with alloca) containing
346    an assembler-name for a local static variable named NAME.
347    LABELNO is an integer which is different for each call.  */
348
349 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
350 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12),    \
351   sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
352
353 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)      \
354 do{  if (PREFIX[0] == 'L' && PREFIX[1] == 'I')          \
355     fprintf(FILE, "\tset %s%d,.+2\n", PREFIX, NUM);     \
356   else                                                  \
357     fprintf (FILE, "%s%d:\n", PREFIX, NUM);             \
358 } while(0)
359
360 #define ASM_OUTPUT_DOUBLE(FILE, VALUE)                  \
361   do { char dstr[30];                                   \
362        REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr);    \
363        fprintf (FILE, "\tdouble 0f%s\n", dstr);         \
364      } while (0)
365
366 #define ASM_OUTPUT_FLOAT(FILE, VALUE)                   \
367   do { char dstr[30];                                   \
368        REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr);     \
369        fprintf (FILE, "\tfloat 0f%s\n", dstr);          \
370      } while (0)
371
372 #undef ASM_OUTPUT_LONG_DOUBLE
373 #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)                              \
374 do { long l[3];                                                         \
375      REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l);                       \
376      fprintf (FILE, "\tlong 0x%x,0x%x,0x%x\n", l[0], l[1], l[2]);       \
377    } while (0)
378   
379 /* This is how to output an assembler line defining an `int' constant.  */
380
381 #define ASM_OUTPUT_INT(FILE,VALUE)  \
382 ( fprintf (FILE, "\tlong "),                    \
383   output_addr_const (FILE, (VALUE)),            \
384   fprintf (FILE, "\n"))
385
386 /* Likewise for `char' and `short' constants.  */
387
388 #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
389 ( fprintf (FILE, "\tshort "),                   \
390   output_addr_const (FILE, (VALUE)),            \
391   fprintf (FILE, "\n"))
392
393 #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
394 ( fprintf (FILE, "\tbyte "),                    \
395   output_addr_const (FILE, (VALUE)),            \
396   fprintf (FILE, "\n"))
397
398 /* This is how to output an assembler line for a numeric constant byte.  */
399
400 #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
401   fprintf (FILE, "\tbyte 0x%x\n", (VALUE))
402
403 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
404   fprintf (FILE, "\tlong L%d\n", VALUE)
405
406 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
407   fprintf (FILE, "\tshort L%d-L%d\n", VALUE, REL)
408
409 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
410   if ((LOG) == 1)                       \
411     fprintf (FILE, "\tlalign 2\n");     \
412   else if ((LOG) != 0)                  \
413     abort ();
414
415 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
416   fprintf (FILE, "\tspace %u\n", (SIZE))
417
418 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME)
419 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO)
420
421 #ifdef AS_BUG_FLOATING_CONSTANT
422 #define PRINT_OPERAND_FLOAT(CODE,FILE,VALUE,INT)        \
423  do { REAL_VALUE_TO_TARGET_SINGLE (VALUE, INT);         \
424       fprintf (FILE, "&0x%x", INT); } while (0)
425 #else
426 #define PRINT_OPERAND_FLOAT(CODE,FILE,VALUE,INT)        \
427  do { if (CODE == 'f')                                  \
428         { char dstr[30];                                \
429           REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr);  \
430           fprintf (FILE, "&0f%s", dstr);                \
431         }                                               \
432       else                                              \
433         {                                               \
434           REAL_VALUE_TO_TARGET_SINGLE (VALUE, INT);     \
435           fprintf (FILE, "&0x%x", INT); } } while (0)
436 #endif /* AS_BUG_FLOATING_CONSTANT */
437
438 #define PRINT_OPERAND(FILE, X, CODE)  \
439 { if (CODE == '.') fprintf (FILE, ".");                                 \
440   else if (CODE == '#') fprintf (FILE, "&");                            \
441   else if (CODE == '-') fprintf (FILE, "-(%%sp)");                      \
442   else if (CODE == '+') fprintf (FILE, "(%%sp)+");                      \
443   else if (CODE == '@') fprintf (FILE, "(%%sp)");                       \
444   else if (CODE == '!') fprintf (FILE, "%%fpcr");                       \
445   else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
446   else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
447   else if (CODE == '/')                                                 \
448     fprintf (FILE, "%%");                                               \
449   else if (GET_CODE (X) == REG)                                         \
450     fprintf (FILE, "%s", reg_names[REGNO (X)]);                         \
451   else if (GET_CODE (X) == MEM)                                         \
452     output_address (XEXP (X, 0));                                       \
453   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)      \
454     { REAL_VALUE_TYPE r;  long l;                                       \
455       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
456       PRINT_OPERAND_FLOAT (CODE, FILE, r, l); }                         \
457   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode)      \
458     { REAL_VALUE_TYPE r;  char dstr[30];                                \
459       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
460       REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);                         \
461       fprintf (FILE, "&0f%s", dstr); }                                  \
462   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == XFmode)      \
463     { REAL_VALUE_TYPE r;  char dstr[30];                                \
464       REAL_VALUE_FROM_CONST_DOUBLE (r, X);                              \
465       REAL_VALUE_TO_DECIMAL (r, "%.20g", dstr);                         \
466       fprintf (FILE, "&0f%s", dstr); }                                  \
467   else { putc ('&', FILE); output_addr_const (FILE, X); }}
468
469 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
470 { register rtx reg1, reg2, breg, ireg;                                  \
471   register rtx addr = ADDR;                                             \
472   rtx offset;                                                           \
473   switch (GET_CODE (addr))                                              \
474     {                                                                   \
475     case REG:                                                           \
476       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);                  \
477       break;                                                            \
478     case PRE_DEC:                                                       \
479       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);       \
480       break;                                                            \
481     case POST_INC:                                                      \
482       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);       \
483       break;                                                            \
484     case PLUS:                                                          \
485       reg1 = 0; reg2 = 0;                                               \
486       ireg = 0; breg = 0;                                               \
487       offset = 0;                                                       \
488       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                          \
489         {                                                               \
490           offset = XEXP (addr, 0);                                      \
491           addr = XEXP (addr, 1);                                        \
492         }                                                               \
493       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))                     \
494         {                                                               \
495           offset = XEXP (addr, 1);                                      \
496           addr = XEXP (addr, 0);                                        \
497         }                                                               \
498       if (GET_CODE (addr) != PLUS) ;                                    \
499       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)                \
500         {                                                               \
501           reg1 = XEXP (addr, 0);                                        \
502           addr = XEXP (addr, 1);                                        \
503         }                                                               \
504       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)                \
505         {                                                               \
506           reg1 = XEXP (addr, 1);                                        \
507           addr = XEXP (addr, 0);                                        \
508         }                                                               \
509       else if (GET_CODE (XEXP (addr, 0)) == MULT)                       \
510         {                                                               \
511           reg1 = XEXP (addr, 0);                                        \
512           addr = XEXP (addr, 1);                                        \
513         }                                                               \
514       else if (GET_CODE (XEXP (addr, 1)) == MULT)                       \
515         {                                                               \
516           reg1 = XEXP (addr, 1);                                        \
517           addr = XEXP (addr, 0);                                        \
518         }                                                               \
519       else if (GET_CODE (XEXP (addr, 0)) == REG)                        \
520         {                                                               \
521           reg1 = XEXP (addr, 0);                                        \
522           addr = XEXP (addr, 1);                                        \
523         }                                                               \
524       else if (GET_CODE (XEXP (addr, 1)) == REG)                        \
525         {                                                               \
526           reg1 = XEXP (addr, 1);                                        \
527           addr = XEXP (addr, 0);                                        \
528         }                                                               \
529       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT             \
530           || GET_CODE (addr) == SIGN_EXTEND)                            \
531         { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }     \
532 /*  for OLD_INDEXING                                                    \
533       else if (GET_CODE (addr) == PLUS)                                 \
534         {                                                               \
535           if (GET_CODE (XEXP (addr, 0)) == REG)                         \
536             {                                                           \
537               reg2 = XEXP (addr, 0);                                    \
538               addr = XEXP (addr, 1);                                    \
539             }                                                           \
540           else if (GET_CODE (XEXP (addr, 1)) == REG)                    \
541             {                                                           \
542               reg2 = XEXP (addr, 1);                                    \
543               addr = XEXP (addr, 0);                                    \
544             }                                                           \
545         }                                                               \
546   */                                                                    \
547       if (offset != 0) { if (addr != 0) abort (); addr = offset; }      \
548       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND                      \
549                     || GET_CODE (reg1) == MULT))                        \
550           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))         \
551         { breg = reg2; ireg = reg1; }                                   \
552       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))         \
553         { breg = reg1; ireg = reg2; }                                   \
554       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)       \
555         { int scale = 1;                                                \
556           if (GET_CODE (ireg) == MULT)                                  \
557             { scale = INTVAL (XEXP (ireg, 1));                          \
558               ireg = XEXP (ireg, 0); }                                  \
559           if (GET_CODE (ireg) == SIGN_EXTEND)                           \
560             fprintf (FILE, "L%d-LI%d(%%pc,%s.w",                        \
561                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
562                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
563                      reg_names[REGNO (XEXP (ireg, 0))]);                \
564           else                                                          \
565             fprintf (FILE, "L%d-LI%d(%%pc,%s.l",                        \
566                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
567                      CODE_LABEL_NUMBER (XEXP (addr, 0)),                \
568                      reg_names[REGNO (ireg)]);                          \
569           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
570           putc (')', FILE);                                             \
571           break; }                                                      \
572       if (ireg != 0 || breg != 0)                                       \
573         { int scale = 1;                                                \
574           if (breg == 0)                                                \
575             abort ();                                                   \
576           if (addr != 0)                                                \
577             output_addr_const (FILE, addr);                             \
578           fprintf (FILE, "(%s", reg_names[REGNO (breg)]);               \
579           if (ireg != 0)                                                \
580             putc (',', FILE);                                           \
581           if (ireg != 0 && GET_CODE (ireg) == MULT)                     \
582             { scale = INTVAL (XEXP (ireg, 1));                          \
583               ireg = XEXP (ireg, 0); }                                  \
584           if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)              \
585             fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);  \
586           else if (ireg != 0)                                           \
587             fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);            \
588           if (scale != 1) fprintf (FILE, "*%d", scale);                 \
589           putc (')', FILE);                                             \
590           break;                                                        \
591         }                                                               \
592       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)               \
593         { fprintf (FILE, "L%d-LI%d(%%pc,%s.w)",                         \
594                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
595                    CODE_LABEL_NUMBER (XEXP (addr, 0)),                  \
596                    reg_names[REGNO (reg1)]);                            \
597           break; }                                                      \
598     default:                                                            \
599       if (GET_CODE (addr) == CONST_INT                                  \
600           && INTVAL (addr) < 0x8000                                     \
601           && INTVAL (addr) >= -0x8000)                                  \
602         fprintf (FILE, "%d.w", INTVAL (addr));                          \
603       else                                                              \
604         output_addr_const (FILE, addr);                                 \
605     }}
606
607 #define ASM_OUTPUT_ASCII(f, p, size)    \
608 do { register int i;                    \
609   int inside;                           \
610   inside = FALSE;                       \
611   for (i = 0; i < (size); i++) {        \
612     if (i % 8 == 0) {                   \
613       if (i != 0) {                     \
614         if (inside)                     \
615           putc('"', (f));               \
616         putc('\n', (f));                \
617         inside = FALSE;                 \
618       }                                 \
619       fprintf((f), "\t%s ", ASCII_DATA_ASM_OP); \
620     }                                   \
621     if ((p)[i] < 32 || (p)[i] == '\\' || (p)[i] == '"' || (p)[i] == 127) {      \
622       if (inside) {                     \
623         putc('"', (f));                 \
624         inside = FALSE;                 \
625       }                                 \
626       if (i % 8 != 0)                   \
627         putc(',', (f));                 \
628       fprintf((f), "%d", (p)[i]);       \
629     } else {                            \
630       if (!inside) {                    \
631         if (i % 8 != 0)                 \
632           putc(',', (f));               \
633         putc('"', (f));                 \
634         inside = TRUE;                  \
635       }                                 \
636       putc((p)[i], (f));                \
637     }                                   \
638   }                                     \
639   if (inside)                           \
640     putc('"', (f));                     \
641   putc('\n', (f));                      \
642 } while (0)
643
644 /* Translate Motorola opcodes such as `jbeq'
645    into SGS opcodes such as `beq.w'.
646    Delete the `e' in `move...' and `fmove'.
647    Change `ftst' to `ftest'.  */
648
649 #define ASM_OUTPUT_OPCODE(FILE, PTR)                    \
650 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')               \
651     { ++(PTR);                                          \
652       while (*(PTR) != ' ')                             \
653         { putc (*(PTR), (FILE)); ++(PTR); }             \
654       fprintf ((FILE), ".w"); }                         \
655   else if ((PTR)[0] == 'f')                             \
656     {                                                   \
657       if (!strncmp ((PTR), "fmove", 5))                 \
658         { fprintf ((FILE), "fmov"); (PTR) += 5; }       \
659       else if (!strncmp ((PTR), "ftst", 4))             \
660         { fprintf ((FILE), "ftest"); (PTR) += 4; }      \
661     }                                                   \
662   else if ((PTR)[0] == 'm' && (PTR)[1] == 'o'           \
663            && (PTR)[2] == 'v' && (PTR)[3] == 'e')       \
664     { fprintf ((FILE), "mov"); (PTR) += 4; }            \
665 }
666
667 /* Prevent output of `gcc_compiled.:'.  */
668
669 #define ASM_IDENTIFY_GCC(FILE)
670
671 #else /* not HPUX_ASM */
672
673 #undef FUNCTION_PROFILER
674
675 /* HP-UX needs the call to mcount before the link instruction.
676    Copy the return address onto the stack before the call to fake it out.  */
677 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
678   fprintf (FILE, \
679            "\tmovel a6@(4),sp@-\n\tmovl #LP%d,a0\n\tjsr mcount\n\taddqw #4,sp\n", \
680            (LABEL_NO));
681
682 #endif /* not HPUX_ASM */
683 /* In m68k svr4, a symbol_ref rtx can be a valid PIC operand if it is an
684    operand of a function call. */
685 #undef LEGITIMATE_PIC_OPERAND_P
686 #define LEGITIMATE_PIC_OPERAND_P(X) \
687   (! symbolic_operand (X, VOIDmode) \
688    || ((GET_CODE(X) == SYMBOL_REF) && SYMBOL_REF_FLAG(X)))
689
690 /* hpux8 and later have C++ compatable include files, so do not
691    pretend they are `extern "C"'.  */
692 #define NO_IMPLICIT_EXTERN_C