OSDN Git Service

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