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, 2003
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
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)
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.
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. */
22 /* gcc.c should find libgcc.a itself rather than expecting linker to. */
23 #define LINK_LIBGCC_SPECIAL
24 /* The arguments of -L must be a separate argv element. */
25 #define SPACE_AFTER_L_OPTION
26 /* HP/UX doesn't have libg.a. */
27 #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
29 /* Be compatible with system stddef.h. */
30 #define SIZE_TYPE "unsigned int"
33 #define INT_OP_GROUP INT_OP_NO_DOT
35 /* See m68k.h. 7 means 68020 with 68881. */
37 #ifndef TARGET_DEFAULT
38 #define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020)
41 /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified.
42 This will control the use of inline 68881 insns in certain macros. */
46 #define ASM_SPEC "%{m68000:+X}%{mc68000:+X}"
48 #define NO_DOT_IN_LABEL
50 #if TARGET_DEFAULT & MASK_68881 /* -m68881 is the default */
52 /* These definitions differ from those used for GAS by defining __HPUX_ASM__.
53 This is needed because some programs, particularly GDB, need to
54 know which assembler is being used so that the correct `asm'
55 instructions can be used. */
58 "%{!msoft-float:-D__HAVE_68881__ }\
59 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE} -D__HPUX_ASM__"
61 #else /* default is -msoft-float */
64 "%{m68881:-D__HAVE_68881__ }\
65 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE} -D__HPUX_ASM__"
67 #endif /* default is -msoft-float */
69 #else /* not HPUX_ASM */
71 #if TARGET_DEFAULT & MASK_68881 /* -m68881 is the default */
74 "%{!msoft-float:-D__HAVE_68881__ }\
75 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE}"
77 #else /* default is -msoft-float */
80 "%{m68881:-D__HAVE_68881__ }\
81 %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}} -D_HPUX_SOURCE}"
83 #endif /* default is -msoft-float */
85 /* -m68000 requires special flags to the assembler. */
87 "%{m68000:-mc68000}%{mc68000:-mc68000}%{!mc68000:%{!m68000:-mc68020}}"
89 /* Tell GCC to put a space after -L when generating such options. */
90 #define SPACE_AFTER_L_OPTION
92 #endif /* Not HPUX_ASM */
94 /* Translate -static for HPUX linker. */
95 #define LINK_SPEC "%{static:-a archive}"
98 /* Target OS builtins. These are the ones defined by HPUX cc. */
99 #define TARGET_OS_CPP_BUILTINS() \
102 builtin_define_std ("hp9000s200"); \
103 builtin_define_std ("hp9000s300"); \
104 builtin_define_std ("hpux"); \
105 builtin_define_std ("unix"); \
106 builtin_define_std ("PWB"); \
107 builtin_define ("__motorola__"); \
108 builtin_assert ("system=unix"); \
109 builtin_assert ("system=hpux"); \
113 /* Every structure or union's size must be a multiple of 2 bytes. */
115 #define STRUCTURE_SIZE_BOUNDARY 16
117 /* hpux doesn't use static area for struct returns. */
118 #undef PCC_STATIC_STRUCT_RETURN
120 /* Generate calls to memcpy, memcmp and memset. */
121 #define TARGET_MEM_FUNCTIONS
123 #if 0 /* No longer correct in HPUX version 6.5. */
124 /* Function calls don't save any fp registers on hpux. */
125 #undef CALL_USED_REGISTERS
126 #define CALL_USED_REGISTERS \
127 {1, 1, 0, 0, 0, 0, 0, 0, \
128 1, 1, 0, 0, 0, 0, 0, 1, \
129 1, 1, 1, 1, 1, 1, 1, 1}
134 /* Override parts of m68k.h to fit the HPUX assembler. */
136 #undef TARGET_VERSION
137 #undef REGISTER_NAMES
138 #undef ASM_OUTPUT_REG_PUSH
139 #undef ASM_OUTPUT_REG_POP
142 #undef TEXT_SECTION_ASM_OP
143 #undef DATA_SECTION_ASM_OP
144 #undef READONLY_DATA_SECTION_ASM_OP
145 #undef ASM_OUTPUT_ADDR_VEC_ELT
146 #undef ASM_OUTPUT_ADDR_DIFF_ELT
147 #undef ASM_OUTPUT_ALIGN
148 #undef ASM_OUTPUT_SKIP
149 #undef ASM_OUTPUT_COMMON
150 #undef ASM_OUTPUT_LOCAL
151 #undef FUNCTION_PROFILER
153 #undef IMMEDIATE_PREFIX
154 #undef REGISTER_PREFIX
156 #define TARGET_VERSION fprintf (stderr, " (68k, SGS/hpux syntax)");
158 #define REGISTER_NAMES \
159 {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", \
160 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp", \
161 "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7"}
163 #define IMMEDIATE_PREFIX "&"
164 #define REGISTER_PREFIX "%"
166 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
167 fprintf (FILE, "\tmov.l &LP%d,%%a0\n\tjsr mcount\n", (LABEL_NO));
169 /* This is how to output an insn to push a register on the stack.
170 It need not be very fast code. */
172 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
173 fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])
175 /* This is how to output an insn to pop a register from the stack.
176 It need not be very fast code. */
178 #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
179 fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])
181 /* For HPUX versions before 6.5, define this macro as empty. */
182 #define TARGET_ASM_FILE_START m68k_hp320_file_start
184 #define ASM_APP_ON ""
186 #define ASM_APP_OFF ""
188 #ifdef AS_BUG_TRAILING_LABEL
189 #define TEXT_SECTION_ASM_OP "\tlalign\t1\ntext"
190 #define DATA_SECTION_ASM_OP "\tlalign\t1\ndata"
192 #define TEXT_SECTION_ASM_OP "text"
193 #define DATA_SECTION_ASM_OP "data"
195 #define ASCII_DATA_ASM_OP "\tbyte\t"
197 /* This is the command to make the user-level label named NAME
198 defined for reference from other files. */
200 #define GLOBAL_ASM_OP "\tglobal\t"
202 /* This says how to output an assembler line
203 to define a global common symbol. */
205 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
206 ( fputs ("\tcomm ", (FILE)), \
207 assemble_name ((FILE), (NAME)), \
208 fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
210 /* This says how to output an assembler line
211 to define a local common symbol. */
213 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
214 ( fputs ("\tlcomm ", (FILE)), \
215 assemble_name ((FILE), (NAME)), \
216 fprintf ((FILE), ",%u,2\n", (int)(ROUNDED)))
218 #define ASM_PN_FORMAT "%s___%lu"
220 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
221 fprintf (FILE, "\tlong L%d\n", VALUE)
223 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
224 fprintf (FILE, "\tshort L%d-L%d\n", VALUE, REL)
226 #define ASM_OUTPUT_ALIGN(FILE,LOG) \
229 fprintf (FILE, "\tlalign 2\n"); \
230 else if ((LOG) != 0) \
234 #define ASM_OUTPUT_SKIP(FILE,SIZE) \
235 fprintf (FILE, "\tspace %u\n", (int)(SIZE))
237 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME)
238 #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO, COUNTER)
240 /* Output a float value (represented as a C double) as an immediate operand.
241 This macro is a 68k-specific macro. */
243 #undef ASM_OUTPUT_FLOAT_OPERAND
244 #ifdef AS_BUG_FLOATING_CONSTANT
245 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
247 REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
248 fprintf ((FILE), "&0x%lx", l); \
251 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
256 real_to_decimal (dstr, &(VALUE), sizeof (dstr), 9, 0); \
257 fprintf ((FILE), "&0f%s", dstr); \
262 REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
263 fprintf ((FILE), "&0x%lx", l); \
266 #endif /* AS_BUG_FLOATING_CONSTANT */
268 /* Output a double value (represented as a C double) as an immediate operand.
269 This macro is a 68k-specific macro. */
270 #undef ASM_OUTPUT_DOUBLE_OPERAND
271 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \
272 do { char dstr[30]; \
273 real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1); \
274 fprintf (FILE, "&0f%s", dstr); \
277 /* Note, long double immediate operands are not actually
278 generated by m68k.md. */
279 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
280 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \
281 do { char dstr[30]; \
282 real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1); \
283 fprintf (FILE, "&0f%s", dstr); \
288 #define PRINT_OPERAND(FILE, X, CODE) \
289 { if (CODE == '.') fprintf (FILE, "."); \
290 else if (CODE == '#') fprintf (FILE, "&"); \
291 else if (CODE == '-') fprintf (FILE, "-(%%sp)"); \
292 else if (CODE == '+') fprintf (FILE, "(%%sp)+"); \
293 else if (CODE == '@') fprintf (FILE, "(%%sp)"); \
294 else if (CODE == '!') fprintf (FILE, "%%fpcr"); \
295 else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \
296 else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \
297 else if (CODE == '/') \
298 fprintf (FILE, "%%"); \
299 else if (GET_CODE (X) == REG) \
300 fprintf (FILE, "%s", reg_names[REGNO (X)]); \
301 else if (GET_CODE (X) == MEM) \
302 output_address (XEXP (X, 0)); \
303 else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \
304 { REAL_VALUE_TYPE r; long l; \
305 REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
306 PRINT_OPERAND_FLOAT (CODE, FILE, r, l); } \
307 else if (GET_CODE (X) == CONST_DOUBLE \
308 && (GET_MODE (X) == DFmode || GET_MODE (X) == XFmode)) \
310 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X), \
311 sizeof (dstr), 0, 1); \
312 fprintf (FILE, "&0f%s", dstr); } \
313 else { putc ('&', FILE); output_addr_const (FILE, X); }}
316 #undef PRINT_OPERAND_ADDRESS
317 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
318 { register rtx reg1, reg2, breg, ireg; \
319 register rtx addr = ADDR; \
321 switch (GET_CODE (addr)) \
324 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \
327 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \
330 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \
333 reg1 = 0; reg2 = 0; \
334 ireg = 0; breg = 0; \
336 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \
338 offset = XEXP (addr, 0); \
339 addr = XEXP (addr, 1); \
341 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \
343 offset = XEXP (addr, 1); \
344 addr = XEXP (addr, 0); \
346 if (GET_CODE (addr) != PLUS) ; \
347 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \
349 reg1 = XEXP (addr, 0); \
350 addr = XEXP (addr, 1); \
352 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \
354 reg1 = XEXP (addr, 1); \
355 addr = XEXP (addr, 0); \
357 else if (GET_CODE (XEXP (addr, 0)) == MULT) \
359 reg1 = XEXP (addr, 0); \
360 addr = XEXP (addr, 1); \
362 else if (GET_CODE (XEXP (addr, 1)) == MULT) \
364 reg1 = XEXP (addr, 1); \
365 addr = XEXP (addr, 0); \
367 else if (GET_CODE (XEXP (addr, 0)) == REG) \
369 reg1 = XEXP (addr, 0); \
370 addr = XEXP (addr, 1); \
372 else if (GET_CODE (XEXP (addr, 1)) == REG) \
374 reg1 = XEXP (addr, 1); \
375 addr = XEXP (addr, 0); \
377 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \
378 || GET_CODE (addr) == SIGN_EXTEND) \
379 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \
380 /* for OLD_INDEXING \
381 else if (GET_CODE (addr) == PLUS) \
383 if (GET_CODE (XEXP (addr, 0)) == REG) \
385 reg2 = XEXP (addr, 0); \
386 addr = XEXP (addr, 1); \
388 else if (GET_CODE (XEXP (addr, 1)) == REG) \
390 reg2 = XEXP (addr, 1); \
391 addr = XEXP (addr, 0); \
395 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \
396 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \
397 || GET_CODE (reg1) == MULT)) \
398 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \
399 { breg = reg2; ireg = reg1; } \
400 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \
401 { breg = reg1; ireg = reg2; } \
402 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \
404 if (GET_CODE (ireg) == MULT) \
405 { scale = INTVAL (XEXP (ireg, 1)); \
406 ireg = XEXP (ireg, 0); } \
407 if (GET_CODE (ireg) == SIGN_EXTEND) \
408 fprintf (FILE, "L%d-LI%d(%%pc,%s.w", \
409 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
410 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
411 reg_names[REGNO (XEXP (ireg, 0))]); \
413 fprintf (FILE, "L%d-LI%d(%%pc,%s.l", \
414 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
415 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
416 reg_names[REGNO (ireg)]); \
417 if (scale != 1) fprintf (FILE, "*%d", scale); \
420 if (ireg != 0 || breg != 0) \
425 output_addr_const (FILE, addr); \
426 fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \
429 if (ireg != 0 && GET_CODE (ireg) == MULT) \
430 { scale = INTVAL (XEXP (ireg, 1)); \
431 ireg = XEXP (ireg, 0); } \
432 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \
433 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \
434 else if (ireg != 0) \
435 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \
436 if (scale != 1) fprintf (FILE, "*%d", scale); \
440 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \
441 { fprintf (FILE, "L%d-LI%d(%%pc,%s.w)", \
442 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
443 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
444 reg_names[REGNO (reg1)]); \
447 if (GET_CODE (addr) == CONST_INT \
448 && INTVAL (addr) < 0x8000 \
449 && INTVAL (addr) >= -0x8000) \
450 fprintf (FILE, "%d.w", (int) INTVAL (addr)); \
452 output_addr_const (FILE, addr); \
455 #define ASM_OUTPUT_ASCII(f, p, SIZE) \
456 do { size_t i, limit = (SIZE); \
459 for (i = 0; i < limit; i++) { \
467 fprintf((f), "%s", ASCII_DATA_ASM_OP); \
469 if ((p)[i] < 32 || (p)[i] == '\\' || (p)[i] == '"' || (p)[i] == 127) { \
476 fprintf((f), "%d", (p)[i]); \
492 /* Translate Motorola opcodes such as `jbeq'
493 into SGS opcodes such as `beq.w'.
494 Delete the `e' in `move...' and `fmove'.
495 Change `ftst' to `ftest'. */
497 #define ASM_OUTPUT_OPCODE(FILE, PTR) \
498 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \
500 while (*(PTR) != ' ') \
501 { putc (*(PTR), (FILE)); ++(PTR); } \
502 fprintf ((FILE), ".w"); } \
503 else if ((PTR)[0] == 'f') \
505 if (!strncmp ((PTR), "fmove", 5)) \
506 { fprintf ((FILE), "fmov"); (PTR) += 5; } \
507 else if (!strncmp ((PTR), "ftst", 4)) \
508 { fprintf ((FILE), "ftest"); (PTR) += 4; } \
510 else if ((PTR)[0] == 'm' && (PTR)[1] == 'o' \
511 && (PTR)[2] == 'v' && (PTR)[3] == 'e') \
512 { fprintf ((FILE), "mov"); (PTR) += 4; } \
515 #else /* not HPUX_ASM */
517 #undef FUNCTION_PROFILER
519 /* HP-UX needs the call to mcount before the link instruction.
520 Copy the return address onto the stack before the call to fake it out. */
521 #define FUNCTION_PROFILER(FILE, LABEL_NO) \
523 "\tmovel a6@(4),sp@-\n\tmovl #LP%d,a0\n\tjsr mcount\n\taddqw #4,sp\n", \
526 #endif /* not HPUX_ASM */
528 /* hpux8 and later have C++ compatible include files, so do not
529 pretend they are `extern "C"'. */
530 #define NO_IMPLICIT_EXTERN_C