xref: /openbsd-src/gnu/usr.bin/gcc/gcc/config/m68k/hp320.h (revision 34c265351bd856b02f65e501b7eace15724bc0d4)
1 /* Definitions of target machine for GNU compiler.  HP-UX 68000/68020 version.
2    Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002
3    Free Software Foundation, Inc.
4 
5 This file is part of GNU CC.
6 
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11 
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21 
22 /* Define USE_GAS if GCC is supposed to work with the GNU assembler,
23    GNU linker and GNU debugger using DBX debugging information.
24    (In other words, much of HPUX has been cast aside.)
25    Undefine USE_GAS if you want GCC to feed the HP assembler.  */
26 
27 /* #define USE_GAS */  /* Use hp320g.h if you want this.  */
28 
29 /* Control assembler-syntax conditionals in m68k.md.  */
30 
31 #ifndef USE_GAS
32 #define MOTOROLA		/* Use Motorola syntax rather than "MIT" */
33 #define SGS			/* Uses SGS assembler */
34 #define SGS_CMP_ORDER		/* Takes cmp operands in reverse order */
35 #define HPUX_ASM
36 
37 #if !defined (CROSS_COMPILE) && !defined (NO_BUGS)
38 /* The assembler on HP 9k3xx machines running HPUX 8.0 doesn't translate
39    floating point constants behind some operands.  The workaround is to
40    use hex constants.  Reported by Thomas Nau (nau@medizin.uni-ulm.de).  */
41 #define AS_BUG_FLOATING_CONSTANT
42 /* The assembler on HP 9k3xx machines running HPUX 8.0 doesn't accept
43    labels followed by a text, data, or other section directive.  Reported
44    by Thomas Nau (nau@medizin.uni-ulm.de).  */
45 #define AS_BUG_TRAILING_LABEL
46 #endif
47 
48 #endif /* not USE_GAS */
49 
50 /* gcc.c should find libgcc.a itself rather than expecting linker to.  */
51 #define LINK_LIBGCC_SPECIAL
52 /* The arguments of -L must be a separate argv element.  */
53 #define SPACE_AFTER_L_OPTION
54 /* HP/UX doesn't have libg.a.  */
55 #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
56 
57 /* Be compatible with system stddef.h.  */
58 #define SIZE_TYPE "unsigned int"
59 
60 #include "m68k/m68k.h"
61 
62 #undef INT_OP_GROUP
63 #define INT_OP_GROUP INT_OP_NO_DOT
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_ASM_OP
168 #undef ASM_OUTPUT_ADDR_VEC_ELT
169 #undef ASM_OUTPUT_ADDR_DIFF_ELT
170 #undef ASM_OUTPUT_ALIGN
171 #undef ASM_OUTPUT_SKIP
172 #undef ASM_OUTPUT_COMMON
173 #undef ASM_OUTPUT_LOCAL
174 #undef ASM_FORMAT_PRIVATE_NAME
175 #undef FUNCTION_PROFILER
176 #undef ASM_OUTPUT_INTERNAL_LABEL
177 #undef GLOBAL_ASM_OP
178 #undef IMMEDIATE_PREFIX
179 #undef REGISTER_PREFIX
180 
181 #define TARGET_VERSION fprintf (stderr, " (68k, SGS/hpux syntax)");
182 
183 #define REGISTER_NAMES \
184 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",	\
185  "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",	\
186  "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7"}
187 
188 #define IMMEDIATE_PREFIX        "&"
189 #define REGISTER_PREFIX         "%"
190 
191 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
192    fprintf (FILE, "\tmov.l &LP%d,%%a0\n\tjsr mcount\n", (LABEL_NO));
193 
194 /* This is how to output an insn to push a register on the stack.
195    It need not be very fast code.  */
196 
197 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
198   fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
199 
200 /* This is how to output an insn to pop a register from the stack.
201    It need not be very fast code.  */
202 
203 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
204   fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
205 
206 /* For HPUX versions before 6.5, define this macro as empty.  */
207 #define ASM_FILE_START(FILE)						\
208   if (TARGET_68020)							\
209     {									\
210       if (TARGET_68881)							\
211 	 fprintf (FILE, "\tversion 3\n"); /* 68020 fp regs saved */	\
212       else								\
213 	 fprintf (FILE, "\tversion 2\n"); /* 68020 no fp regs saved */	\
214     }									\
215   else									\
216     fprintf (FILE, "\tversion 1\n");	/* 68010 */
217 
218 #define ASM_APP_ON ""
219 
220 #define ASM_APP_OFF ""
221 
222 #ifdef AS_BUG_TRAILING_LABEL
223 #define TEXT_SECTION_ASM_OP "\tlalign\t1\ntext"
224 #define DATA_SECTION_ASM_OP "\tlalign\t1\ndata"
225 #else
226 #define TEXT_SECTION_ASM_OP "text"
227 #define DATA_SECTION_ASM_OP "data"
228 #endif
229 #define	ASCII_DATA_ASM_OP "\tbyte\t"
230 
231 /* This is the command to make the user-level label named NAME
232    defined for reference from other files.  */
233 
234 #define GLOBAL_ASM_OP "\tglobal\t"
235 
236 /* This says how to output an assembler line
237    to define a global common symbol.  */
238 
239 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
240 ( fputs ("\tcomm ", (FILE)),			\
241   assemble_name ((FILE), (NAME)),		\
242   fprintf ((FILE), ",%u\n", (ROUNDED)))
243 
244 /* This says how to output an assembler line
245    to define a local common symbol.  */
246 
247 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
248 ( fputs ("\tlcomm ", (FILE)),			\
249   assemble_name ((FILE), (NAME)),		\
250   fprintf ((FILE), ",%u,2\n", (ROUNDED)))
251 
252 /* Store in OUTPUT a string (made with alloca) containing
253    an assembler-name for a local static variable named NAME.
254    LABELNO is an integer which is different for each call.  */
255 
256 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)	\
257 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12),	\
258   sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
259 
260 #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
261 do{  if (PREFIX[0] == 'L' && PREFIX[1] == 'I')		\
262     fprintf(FILE, "\tset %s%d,.+2\n", PREFIX, NUM);	\
263   else							\
264     fprintf (FILE, "%s%d:\n", PREFIX, NUM);		\
265 } while(0)
266 
267 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
268   fprintf (FILE, "\tlong L%d\n", VALUE)
269 
270 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)  \
271   fprintf (FILE, "\tshort L%d-L%d\n", VALUE, REL)
272 
273 #define ASM_OUTPUT_ALIGN(FILE,LOG)	\
274 do {					\
275   if ((LOG) == 1)			\
276     fprintf (FILE, "\tlalign 2\n");	\
277   else if ((LOG) != 0)			\
278     abort ();				\
279 } while (0)
280 
281 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
282   fprintf (FILE, "\tspace %u\n", (SIZE))
283 
284 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME)
285 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO)
286 
287 /* Output a float value (represented as a C double) as an immediate operand.
288    This macro is a 68k-specific macro.  */
289 
290 #undef ASM_OUTPUT_FLOAT_OPERAND
291 #ifdef AS_BUG_FLOATING_CONSTANT
292 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)		\
293  do { long l;							\
294       REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);			\
295       fprintf ((FILE), "&0x%lx", l);				\
296      } while (0)
297 #else
298 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)		\
299  do {								\
300       if (CODE == 'f')						\
301         {							\
302           char dstr[30];					\
303       	  real_to_decimal (dstr, &(VALUE), sizeof (dstr), 9, 0); \
304           fprintf ((FILE), "&0f%s", dstr);			\
305         }							\
306       else							\
307         {							\
308           long l;						\
309           REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);		\
310           fprintf ((FILE), "&0x%lx", l);			\
311         }							\
312      } while (0)
313 #endif /* AS_BUG_FLOATING_CONSTANT */
314 
315 /* Output a double value (represented as a C double) as an immediate operand.
316    This macro is a 68k-specific macro.  */
317 #undef ASM_OUTPUT_DOUBLE_OPERAND
318 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)				\
319  do { char dstr[30];							\
320       real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1);		\
321       fprintf (FILE, "&0f%s", dstr);					\
322     } while (0)
323 
324 /* Note, long double immediate operands are not actually
325    generated by m68k.md.  */
326 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
327 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE)			\
328  do { char dstr[30];							\
329       real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1);		\
330       fprintf (FILE, "&0f%s", dstr);					\
331     } while (0)
332 
333 #if 0
334 #undef PRINT_OPERAND
335 #define PRINT_OPERAND(FILE, X, CODE)  \
336 { if (CODE == '.') fprintf (FILE, ".");					\
337   else if (CODE == '#') fprintf (FILE, "&");				\
338   else if (CODE == '-') fprintf (FILE, "-(%%sp)");			\
339   else if (CODE == '+') fprintf (FILE, "(%%sp)+");			\
340   else if (CODE == '@') fprintf (FILE, "(%%sp)");			\
341   else if (CODE == '!') fprintf (FILE, "%%fpcr");			\
342   else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
343   else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
344   else if (CODE == '/')							\
345     fprintf (FILE, "%%");						\
346   else if (GET_CODE (X) == REG)						\
347     fprintf (FILE, "%s", reg_names[REGNO (X)]);				\
348   else if (GET_CODE (X) == MEM)						\
349     output_address (XEXP (X, 0));					\
350   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)	\
351     { REAL_VALUE_TYPE r;  long l;					\
352       REAL_VALUE_FROM_CONST_DOUBLE (r, X);				\
353       PRINT_OPERAND_FLOAT (CODE, FILE, r, l); }				\
354   else if (GET_CODE (X) == CONST_DOUBLE					\
355 	   && (GET_MODE (X) == DFmode || GET_MODE (X) == XFmode))	\
356     { char dstr[30];							\
357       real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X),		\
358 		       sizeof (dstr), 0, 1);				\
359       fprintf (FILE, "&0f%s", dstr); }					\
360   else { putc ('&', FILE); output_addr_const (FILE, X); }}
361 #endif
362 
363 #undef PRINT_OPERAND_ADDRESS
364 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
365 { register rtx reg1, reg2, breg, ireg;					\
366   register rtx addr = ADDR;						\
367   rtx offset;								\
368   switch (GET_CODE (addr))						\
369     {									\
370     case REG:								\
371       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);			\
372       break;								\
373     case PRE_DEC:							\
374       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);	\
375       break;								\
376     case POST_INC:							\
377       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);	\
378       break;								\
379     case PLUS:								\
380       reg1 = 0;	reg2 = 0;						\
381       ireg = 0;	breg = 0;						\
382       offset = 0;							\
383       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))				\
384 	{								\
385 	  offset = XEXP (addr, 0);					\
386 	  addr = XEXP (addr, 1);					\
387 	}								\
388       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))			\
389 	{								\
390 	  offset = XEXP (addr, 1);					\
391 	  addr = XEXP (addr, 0);					\
392 	}								\
393       if (GET_CODE (addr) != PLUS) ;					\
394       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)		\
395 	{								\
396 	  reg1 = XEXP (addr, 0);					\
397 	  addr = XEXP (addr, 1);					\
398 	}								\
399       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)		\
400 	{								\
401 	  reg1 = XEXP (addr, 1);					\
402 	  addr = XEXP (addr, 0);					\
403 	}								\
404       else if (GET_CODE (XEXP (addr, 0)) == MULT)			\
405 	{								\
406 	  reg1 = XEXP (addr, 0);					\
407 	  addr = XEXP (addr, 1);					\
408 	}								\
409       else if (GET_CODE (XEXP (addr, 1)) == MULT)			\
410 	{								\
411 	  reg1 = XEXP (addr, 1);					\
412 	  addr = XEXP (addr, 0);					\
413 	}								\
414       else if (GET_CODE (XEXP (addr, 0)) == REG)			\
415 	{								\
416 	  reg1 = XEXP (addr, 0);					\
417 	  addr = XEXP (addr, 1);					\
418 	}								\
419       else if (GET_CODE (XEXP (addr, 1)) == REG)			\
420 	{								\
421 	  reg1 = XEXP (addr, 1);					\
422 	  addr = XEXP (addr, 0);					\
423 	}								\
424       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT		\
425 	  || GET_CODE (addr) == SIGN_EXTEND)				\
426 	{ if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }	\
427 /*  for OLD_INDEXING							\
428       else if (GET_CODE (addr) == PLUS)					\
429 	{								\
430 	  if (GET_CODE (XEXP (addr, 0)) == REG)				\
431 	    {								\
432 	      reg2 = XEXP (addr, 0);					\
433 	      addr = XEXP (addr, 1);					\
434 	    }								\
435 	  else if (GET_CODE (XEXP (addr, 1)) == REG)			\
436 	    {								\
437 	      reg2 = XEXP (addr, 1);					\
438 	      addr = XEXP (addr, 0);					\
439 	    }								\
440 	}								\
441   */									\
442       if (offset != 0) { if (addr != 0) abort (); addr = offset; }	\
443       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND			\
444 		    || GET_CODE (reg1) == MULT))			\
445 	  || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))		\
446 	{ breg = reg2; ireg = reg1; }					\
447       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))		\
448 	{ breg = reg1; ireg = reg2; }					\
449       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)	\
450         { int scale = 1;						\
451 	  if (GET_CODE (ireg) == MULT)					\
452 	    { scale = INTVAL (XEXP (ireg, 1));				\
453 	      ireg = XEXP (ireg, 0); }					\
454 	  if (GET_CODE (ireg) == SIGN_EXTEND)				\
455 	    fprintf (FILE, "L%d-LI%d(%%pc,%s.w",			\
456 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
457 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
458 		     reg_names[REGNO (XEXP (ireg, 0))]); 		\
459 	  else								\
460 	    fprintf (FILE, "L%d-LI%d(%%pc,%s.l",			\
461 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
462 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
463 		     reg_names[REGNO (ireg)]);				\
464 	  if (scale != 1) fprintf (FILE, "*%d", scale);			\
465 	  putc (')', FILE);						\
466 	  break; }							\
467       if (ireg != 0 || breg != 0)					\
468 	{ int scale = 1;						\
469 	  if (breg == 0)						\
470 	    abort ();							\
471 	  if (addr != 0)						\
472 	    output_addr_const (FILE, addr);				\
473 	  fprintf (FILE, "(%s", reg_names[REGNO (breg)]);		\
474 	  if (ireg != 0)						\
475 	    putc (',', FILE);						\
476 	  if (ireg != 0 && GET_CODE (ireg) == MULT)			\
477 	    { scale = INTVAL (XEXP (ireg, 1));				\
478 	      ireg = XEXP (ireg, 0); }					\
479 	  if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)		\
480 	    fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);	\
481 	  else if (ireg != 0)						\
482 	    fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);		\
483 	  if (scale != 1) fprintf (FILE, "*%d", scale);			\
484 	  putc (')', FILE);						\
485 	  break;							\
486 	}								\
487       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)		\
488 	{ fprintf (FILE, "L%d-LI%d(%%pc,%s.w)",				\
489 		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
490 		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
491 		   reg_names[REGNO (reg1)]);				\
492 	  break; }							\
493     default:								\
494       if (GET_CODE (addr) == CONST_INT					\
495 	  && INTVAL (addr) < 0x8000					\
496 	  && INTVAL (addr) >= -0x8000)					\
497 	fprintf (FILE, "%d.w", INTVAL (addr));				\
498       else								\
499         output_addr_const (FILE, addr);					\
500     }}
501 
502 #define	ASM_OUTPUT_ASCII(f, p, SIZE)	\
503 do { size_t i, limit = (SIZE);		\
504   int inside;				\
505   inside = FALSE;			\
506   for (i = 0; i < limit; i++) {	\
507     if (i % 8 == 0) {			\
508       if (i != 0) {			\
509 	if (inside)			\
510 	  putc('"', (f));		\
511 	putc('\n', (f));		\
512 	inside = FALSE;			\
513       }					\
514       fprintf((f), "%s", ASCII_DATA_ASM_OP);	\
515     }					\
516     if ((p)[i] < 32 || (p)[i] == '\\' || (p)[i] == '"' || (p)[i] == 127) {	\
517       if (inside) {			\
518 	putc('"', (f));			\
519 	inside = FALSE;			\
520       }					\
521       if (i % 8 != 0)			\
522 	putc(',', (f));			\
523       fprintf((f), "%d", (p)[i]);	\
524     } else {				\
525       if (!inside) {			\
526 	if (i % 8 != 0)			\
527 	  putc(',', (f));		\
528 	putc('"', (f));			\
529 	inside = TRUE;			\
530       }					\
531       putc((p)[i], (f));		\
532     }					\
533   }					\
534   if (inside)				\
535     putc('"', (f));			\
536   putc('\n', (f));			\
537 } while (0)
538 
539 /* Translate Motorola opcodes such as `jbeq'
540    into SGS opcodes such as `beq.w'.
541    Delete the `e' in `move...' and `fmove'.
542    Change `ftst' to `ftest'.  */
543 
544 #define ASM_OUTPUT_OPCODE(FILE, PTR)			\
545 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b')		\
546     { ++(PTR);						\
547       while (*(PTR) != ' ')				\
548 	{ putc (*(PTR), (FILE)); ++(PTR); }		\
549       fprintf ((FILE), ".w"); }				\
550   else if ((PTR)[0] == 'f')				\
551     {							\
552       if (!strncmp ((PTR), "fmove", 5))			\
553 	{ fprintf ((FILE), "fmov"); (PTR) += 5; }	\
554       else if (!strncmp ((PTR), "ftst", 4))		\
555 	{ fprintf ((FILE), "ftest"); (PTR) += 4; }	\
556     }							\
557   else if ((PTR)[0] == 'm' && (PTR)[1] == 'o'		\
558 	   && (PTR)[2] == 'v' && (PTR)[3] == 'e')	\
559     { fprintf ((FILE), "mov"); (PTR) += 4; }		\
560 }
561 
562 #else /* not HPUX_ASM */
563 
564 #undef FUNCTION_PROFILER
565 
566 /* HP-UX needs the call to mcount before the link instruction.
567    Copy the return address onto the stack before the call to fake it out.  */
568 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
569   fprintf (FILE, \
570 	   "\tmovel a6@(4),sp@-\n\tmovl #LP%d,a0\n\tjsr mcount\n\taddqw #4,sp\n", \
571 	   (LABEL_NO));
572 
573 #endif /* not HPUX_ASM */
574 
575 /* hpux8 and later have C++ compatible include files, so do not
576    pretend they are `extern "C"'.  */
577 #define NO_IMPLICIT_EXTERN_C
578