OSDN Git Service

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