]>
Commit | Line | Data |
---|---|---|
f0b7c5aa | 1 | /* Definitions of target machine for GNU compiler. HP-UX 68000/68020 version. |
d48bc59a | 2 | Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002 |
2398fb2a | 3 | Free Software Foundation, Inc. |
f0b7c5aa RS |
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 | |
0e29e3c9 RK |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | |
f0b7c5aa RS |
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 | |
fd9c4f83 | 36 | |
a603c4aa TW |
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 | ||
42cd476b RS |
48 | #endif /* not USE_GAS */ |
49 | ||
fd9c4f83 RS |
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}" | |
f0b7c5aa RS |
56 | |
57 | /* Be compatible with system stddef.h. */ | |
58 | #define SIZE_TYPE "unsigned int" | |
59 | ||
57e51b0e | 60 | #include "m68k/m68k.h" |
f0b7c5aa | 61 | |
301d03af RS |
62 | #undef INT_OP_GROUP |
63 | #define INT_OP_GROUP INT_OP_NO_DOT | |
64 | ||
f0b7c5aa RS |
65 | /* See m68k.h. 7 means 68020 with 68881. */ |
66 | ||
67 | #ifndef TARGET_DEFAULT | |
9811059c | 68 | #define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020) |
f0b7c5aa RS |
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 | ||
06601015 RK |
78 | #define NO_DOT_IN_LABEL |
79 | ||
9811059c | 80 | #if TARGET_DEFAULT & MASK_68881 /* -m68881 is the default */ |
f0b7c5aa RS |
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' | |
7a1929e1 | 85 | instructions can be used. */ |
f0b7c5aa RS |
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 | ||
9811059c | 101 | #if TARGET_DEFAULT & MASK_68881 /* -m68881 is the default */ |
f0b7c5aa RS |
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 | ||
a03618e9 RS |
120 | /* Tell GCC to put a space after -L when generating such options. */ |
121 | #define SPACE_AFTER_L_OPTION | |
f0b7c5aa RS |
122 | |
123 | #endif /* Not HPUX_ASM */ | |
124 | ||
49501ea4 RK |
125 | /* Translate -static for HPUX linker. */ |
126 | #define LINK_SPEC "%{static:-a archive}" | |
127 | ||
f0b7c5aa | 128 | |
a7fbe404 NB |
129 | /* Target OS builtins. These are the ones defined by HPUX cc. */ |
130 | #define TARGET_OS_CPP_BUILTINS() \ | |
131 | do \ | |
132 | { \ | |
133 | builtin_define_std ("hp9000s200"); \ | |
134 | builtin_define_std ("hp9000s300"); \ | |
135 | builtin_define_std ("hpux"); \ | |
136 | builtin_define_std ("unix"); \ | |
137 | builtin_define_std ("PWB"); \ | |
138 | builtin_define ("__motorola__"); \ | |
139 | builtin_assert ("system=unix"); \ | |
140 | builtin_assert ("system=hpux"); \ | |
141 | } \ | |
142 | while (0) | |
f0b7c5aa RS |
143 | |
144 | /* Every structure or union's size must be a multiple of 2 bytes. */ | |
145 | ||
146 | #define STRUCTURE_SIZE_BOUNDARY 16 | |
147 | ||
7a1929e1 | 148 | /* hpux doesn't use static area for struct returns. */ |
f0b7c5aa RS |
149 | #undef PCC_STATIC_STRUCT_RETURN |
150 | ||
151 | /* Generate calls to memcpy, memcmp and memset. */ | |
152 | #define TARGET_MEM_FUNCTIONS | |
153 | ||
154 | #if 0 /* No longer correct in HPUX version 6.5. */ | |
155 | /* Function calls don't save any fp registers on hpux. */ | |
156 | #undef CALL_USED_REGISTERS | |
157 | #define CALL_USED_REGISTERS \ | |
158 | {1, 1, 0, 0, 0, 0, 0, 0, \ | |
159 | 1, 1, 0, 0, 0, 0, 0, 1, \ | |
160 | 1, 1, 1, 1, 1, 1, 1, 1} | |
161 | #endif /* 0 */ | |
162 | ||
163 | #ifdef HPUX_ASM | |
164 | ||
165 | /* Override parts of m68k.h to fit the HPUX assembler. */ | |
166 | ||
167 | #undef TARGET_VERSION | |
168 | #undef REGISTER_NAMES | |
f0b7c5aa RS |
169 | #undef ASM_OUTPUT_REG_PUSH |
170 | #undef ASM_OUTPUT_REG_POP | |
171 | #undef ASM_FILE_START | |
172 | #undef ASM_APP_ON | |
173 | #undef ASM_APP_OFF | |
174 | #undef TEXT_SECTION_ASM_OP | |
175 | #undef DATA_SECTION_ASM_OP | |
d48bc59a | 176 | #undef READONLY_DATA_SECTION_ASM_OP |
f0b7c5aa RS |
177 | #undef ASM_OUTPUT_ADDR_VEC_ELT |
178 | #undef ASM_OUTPUT_ADDR_DIFF_ELT | |
179 | #undef ASM_OUTPUT_ALIGN | |
180 | #undef ASM_OUTPUT_SKIP | |
181 | #undef ASM_OUTPUT_COMMON | |
182 | #undef ASM_OUTPUT_LOCAL | |
f0b7c5aa | 183 | #undef FUNCTION_PROFILER |
ef58021b | 184 | #undef GLOBAL_ASM_OP |
4b341aaa RK |
185 | #undef IMMEDIATE_PREFIX |
186 | #undef REGISTER_PREFIX | |
f0b7c5aa RS |
187 | |
188 | #define TARGET_VERSION fprintf (stderr, " (68k, SGS/hpux syntax)"); | |
189 | ||
190 | #define REGISTER_NAMES \ | |
191 | {"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", \ | |
192 | "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp", \ | |
193 | "%fp0", "%fp1", "%fp2", "%fp3", "%fp4", "%fp5", "%fp6", "%fp7"} | |
194 | ||
4b341aaa RK |
195 | #define IMMEDIATE_PREFIX "&" |
196 | #define REGISTER_PREFIX "%" | |
f0b7c5aa RS |
197 | |
198 | #define FUNCTION_PROFILER(FILE, LABEL_NO) \ | |
199 | fprintf (FILE, "\tmov.l &LP%d,%%a0\n\tjsr mcount\n", (LABEL_NO)); | |
200 | ||
f0b7c5aa RS |
201 | /* This is how to output an insn to push a register on the stack. |
202 | It need not be very fast code. */ | |
203 | ||
204 | #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ | |
205 | fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO]) | |
206 | ||
207 | /* This is how to output an insn to pop a register from the stack. | |
208 | It need not be very fast code. */ | |
209 | ||
210 | #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ | |
211 | fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO]) | |
212 | ||
213 | /* For HPUX versions before 6.5, define this macro as empty. */ | |
214 | #define ASM_FILE_START(FILE) \ | |
215 | if (TARGET_68020) \ | |
216 | { \ | |
217 | if (TARGET_68881) \ | |
218 | fprintf (FILE, "\tversion 3\n"); /* 68020 fp regs saved */ \ | |
219 | else \ | |
220 | fprintf (FILE, "\tversion 2\n"); /* 68020 no fp regs saved */ \ | |
221 | } \ | |
222 | else \ | |
223 | fprintf (FILE, "\tversion 1\n"); /* 68010 */ | |
224 | ||
225 | #define ASM_APP_ON "" | |
226 | ||
227 | #define ASM_APP_OFF "" | |
228 | ||
a603c4aa TW |
229 | #ifdef AS_BUG_TRAILING_LABEL |
230 | #define TEXT_SECTION_ASM_OP "\tlalign\t1\ntext" | |
231 | #define DATA_SECTION_ASM_OP "\tlalign\t1\ndata" | |
232 | #else | |
f0b7c5aa | 233 | #define TEXT_SECTION_ASM_OP "text" |
f0b7c5aa | 234 | #define DATA_SECTION_ASM_OP "data" |
a603c4aa | 235 | #endif |
6e7b07a7 | 236 | #define ASCII_DATA_ASM_OP "\tbyte\t" |
ef58021b RS |
237 | |
238 | /* This is the command to make the user-level label named NAME | |
239 | defined for reference from other files. */ | |
240 | ||
6e7b07a7 | 241 | #define GLOBAL_ASM_OP "\tglobal\t" |
f0b7c5aa RS |
242 | |
243 | /* This says how to output an assembler line | |
244 | to define a global common symbol. */ | |
245 | ||
246 | #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ | |
247 | ( fputs ("\tcomm ", (FILE)), \ | |
248 | assemble_name ((FILE), (NAME)), \ | |
58e15542 | 249 | fprintf ((FILE), ",%u\n", (int)(ROUNDED))) |
f0b7c5aa RS |
250 | |
251 | /* This says how to output an assembler line | |
252 | to define a local common symbol. */ | |
253 | ||
254 | #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ | |
255 | ( fputs ("\tlcomm ", (FILE)), \ | |
256 | assemble_name ((FILE), (NAME)), \ | |
58e15542 | 257 | fprintf ((FILE), ",%u,2\n", (int)(ROUNDED))) |
f0b7c5aa | 258 | |
4977bab6 | 259 | #define ASM_PN_FORMAT "%s___%lu" |
f0b7c5aa | 260 | |
f0b7c5aa RS |
261 | #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ |
262 | fprintf (FILE, "\tlong L%d\n", VALUE) | |
263 | ||
33f7f353 | 264 | #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ |
f0b7c5aa RS |
265 | fprintf (FILE, "\tshort L%d-L%d\n", VALUE, REL) |
266 | ||
267 | #define ASM_OUTPUT_ALIGN(FILE,LOG) \ | |
046b71ed | 268 | do { \ |
f0b7c5aa RS |
269 | if ((LOG) == 1) \ |
270 | fprintf (FILE, "\tlalign 2\n"); \ | |
271 | else if ((LOG) != 0) \ | |
046b71ed KG |
272 | abort (); \ |
273 | } while (0) | |
f0b7c5aa RS |
274 | |
275 | #define ASM_OUTPUT_SKIP(FILE,SIZE) \ | |
58e15542 | 276 | fprintf (FILE, "\tspace %u\n", (int)(SIZE)) |
f0b7c5aa RS |
277 | |
278 | #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) | |
a8d0467e | 279 | #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO, COUNTER) |
f0b7c5aa | 280 | |
6339db3f RK |
281 | /* Output a float value (represented as a C double) as an immediate operand. |
282 | This macro is a 68k-specific macro. */ | |
283 | ||
284 | #undef ASM_OUTPUT_FLOAT_OPERAND | |
a603c4aa | 285 | #ifdef AS_BUG_FLOATING_CONSTANT |
6339db3f RK |
286 | #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \ |
287 | do { long l; \ | |
288 | REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ | |
289 | fprintf ((FILE), "&0x%lx", l); \ | |
290 | } while (0) | |
a603c4aa | 291 | #else |
6339db3f RK |
292 | #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \ |
293 | do { \ | |
294 | if (CODE == 'f') \ | |
295 | { \ | |
296 | char dstr[30]; \ | |
da6eec72 | 297 | real_to_decimal (dstr, &(VALUE), sizeof (dstr), 9, 0); \ |
6339db3f RK |
298 | fprintf ((FILE), "&0f%s", dstr); \ |
299 | } \ | |
300 | else \ | |
301 | { \ | |
302 | long l; \ | |
303 | REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ | |
304 | fprintf ((FILE), "&0x%lx", l); \ | |
305 | } \ | |
306 | } while (0) | |
a603c4aa TW |
307 | #endif /* AS_BUG_FLOATING_CONSTANT */ |
308 | ||
6339db3f RK |
309 | /* Output a double value (represented as a C double) as an immediate operand. |
310 | This macro is a 68k-specific macro. */ | |
311 | #undef ASM_OUTPUT_DOUBLE_OPERAND | |
312 | #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \ | |
313 | do { char dstr[30]; \ | |
da6eec72 | 314 | real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1); \ |
6339db3f RK |
315 | fprintf (FILE, "&0f%s", dstr); \ |
316 | } while (0) | |
317 | ||
318 | /* Note, long double immediate operands are not actually | |
319 | generated by m68k.md. */ | |
320 | #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND | |
321 | #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \ | |
322 | do { char dstr[30]; \ | |
da6eec72 | 323 | real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1); \ |
6339db3f RK |
324 | fprintf (FILE, "&0f%s", dstr); \ |
325 | } while (0) | |
326 | ||
327 | #if 0 | |
328 | #undef PRINT_OPERAND | |
f0b7c5aa RS |
329 | #define PRINT_OPERAND(FILE, X, CODE) \ |
330 | { if (CODE == '.') fprintf (FILE, "."); \ | |
331 | else if (CODE == '#') fprintf (FILE, "&"); \ | |
332 | else if (CODE == '-') fprintf (FILE, "-(%%sp)"); \ | |
333 | else if (CODE == '+') fprintf (FILE, "(%%sp)+"); \ | |
334 | else if (CODE == '@') fprintf (FILE, "(%%sp)"); \ | |
7c129456 | 335 | else if (CODE == '!') fprintf (FILE, "%%fpcr"); \ |
0aaa6af8 RS |
336 | else if (CODE == '$') { if (TARGET_68040_ONLY) fprintf (FILE, "s"); } \ |
337 | else if (CODE == '&') { if (TARGET_68040_ONLY) fprintf (FILE, "d"); } \ | |
00c5c72e RS |
338 | else if (CODE == '/') \ |
339 | fprintf (FILE, "%%"); \ | |
f0b7c5aa RS |
340 | else if (GET_CODE (X) == REG) \ |
341 | fprintf (FILE, "%s", reg_names[REGNO (X)]); \ | |
342 | else if (GET_CODE (X) == MEM) \ | |
343 | output_address (XEXP (X, 0)); \ | |
344 | else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ | |
475dd3b4 RS |
345 | { REAL_VALUE_TYPE r; long l; \ |
346 | REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ | |
347 | PRINT_OPERAND_FLOAT (CODE, FILE, r, l); } \ | |
da6eec72 RH |
348 | else if (GET_CODE (X) == CONST_DOUBLE \ |
349 | && (GET_MODE (X) == DFmode || GET_MODE (X) == XFmode)) \ | |
350 | { char dstr[30]; \ | |
351 | real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X), \ | |
352 | sizeof (dstr), 0, 1); \ | |
475dd3b4 | 353 | fprintf (FILE, "&0f%s", dstr); } \ |
f0b7c5aa | 354 | else { putc ('&', FILE); output_addr_const (FILE, X); }} |
6339db3f | 355 | #endif |
f0b7c5aa | 356 | |
6339db3f | 357 | #undef PRINT_OPERAND_ADDRESS |
f0b7c5aa RS |
358 | #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ |
359 | { register rtx reg1, reg2, breg, ireg; \ | |
360 | register rtx addr = ADDR; \ | |
361 | rtx offset; \ | |
362 | switch (GET_CODE (addr)) \ | |
363 | { \ | |
364 | case REG: \ | |
365 | fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \ | |
366 | break; \ | |
367 | case PRE_DEC: \ | |
368 | fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \ | |
369 | break; \ | |
370 | case POST_INC: \ | |
371 | fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \ | |
372 | break; \ | |
373 | case PLUS: \ | |
374 | reg1 = 0; reg2 = 0; \ | |
375 | ireg = 0; breg = 0; \ | |
376 | offset = 0; \ | |
377 | if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \ | |
378 | { \ | |
379 | offset = XEXP (addr, 0); \ | |
380 | addr = XEXP (addr, 1); \ | |
381 | } \ | |
382 | else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \ | |
383 | { \ | |
384 | offset = XEXP (addr, 1); \ | |
385 | addr = XEXP (addr, 0); \ | |
386 | } \ | |
387 | if (GET_CODE (addr) != PLUS) ; \ | |
388 | else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \ | |
389 | { \ | |
390 | reg1 = XEXP (addr, 0); \ | |
391 | addr = XEXP (addr, 1); \ | |
392 | } \ | |
393 | else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \ | |
394 | { \ | |
395 | reg1 = XEXP (addr, 1); \ | |
396 | addr = XEXP (addr, 0); \ | |
397 | } \ | |
398 | else if (GET_CODE (XEXP (addr, 0)) == MULT) \ | |
399 | { \ | |
400 | reg1 = XEXP (addr, 0); \ | |
401 | addr = XEXP (addr, 1); \ | |
402 | } \ | |
403 | else if (GET_CODE (XEXP (addr, 1)) == MULT) \ | |
404 | { \ | |
405 | reg1 = XEXP (addr, 1); \ | |
406 | addr = XEXP (addr, 0); \ | |
407 | } \ | |
408 | else if (GET_CODE (XEXP (addr, 0)) == REG) \ | |
409 | { \ | |
410 | reg1 = XEXP (addr, 0); \ | |
411 | addr = XEXP (addr, 1); \ | |
412 | } \ | |
413 | else if (GET_CODE (XEXP (addr, 1)) == REG) \ | |
414 | { \ | |
415 | reg1 = XEXP (addr, 1); \ | |
416 | addr = XEXP (addr, 0); \ | |
417 | } \ | |
418 | if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \ | |
419 | || GET_CODE (addr) == SIGN_EXTEND) \ | |
420 | { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \ | |
421 | /* for OLD_INDEXING \ | |
422 | else if (GET_CODE (addr) == PLUS) \ | |
423 | { \ | |
424 | if (GET_CODE (XEXP (addr, 0)) == REG) \ | |
425 | { \ | |
426 | reg2 = XEXP (addr, 0); \ | |
427 | addr = XEXP (addr, 1); \ | |
428 | } \ | |
429 | else if (GET_CODE (XEXP (addr, 1)) == REG) \ | |
430 | { \ | |
431 | reg2 = XEXP (addr, 1); \ | |
432 | addr = XEXP (addr, 0); \ | |
433 | } \ | |
434 | } \ | |
435 | */ \ | |
436 | if (offset != 0) { if (addr != 0) abort (); addr = offset; } \ | |
437 | if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \ | |
438 | || GET_CODE (reg1) == MULT)) \ | |
439 | || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \ | |
440 | { breg = reg2; ireg = reg1; } \ | |
441 | else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \ | |
442 | { breg = reg1; ireg = reg2; } \ | |
443 | if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \ | |
444 | { int scale = 1; \ | |
445 | if (GET_CODE (ireg) == MULT) \ | |
446 | { scale = INTVAL (XEXP (ireg, 1)); \ | |
447 | ireg = XEXP (ireg, 0); } \ | |
448 | if (GET_CODE (ireg) == SIGN_EXTEND) \ | |
449 | fprintf (FILE, "L%d-LI%d(%%pc,%s.w", \ | |
450 | CODE_LABEL_NUMBER (XEXP (addr, 0)), \ | |
451 | CODE_LABEL_NUMBER (XEXP (addr, 0)), \ | |
452 | reg_names[REGNO (XEXP (ireg, 0))]); \ | |
453 | else \ | |
454 | fprintf (FILE, "L%d-LI%d(%%pc,%s.l", \ | |
455 | CODE_LABEL_NUMBER (XEXP (addr, 0)), \ | |
456 | CODE_LABEL_NUMBER (XEXP (addr, 0)), \ | |
457 | reg_names[REGNO (ireg)]); \ | |
458 | if (scale != 1) fprintf (FILE, "*%d", scale); \ | |
459 | putc (')', FILE); \ | |
460 | break; } \ | |
461 | if (ireg != 0 || breg != 0) \ | |
462 | { int scale = 1; \ | |
463 | if (breg == 0) \ | |
464 | abort (); \ | |
465 | if (addr != 0) \ | |
466 | output_addr_const (FILE, addr); \ | |
467 | fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \ | |
468 | if (ireg != 0) \ | |
469 | putc (',', FILE); \ | |
470 | if (ireg != 0 && GET_CODE (ireg) == MULT) \ | |
471 | { scale = INTVAL (XEXP (ireg, 1)); \ | |
472 | ireg = XEXP (ireg, 0); } \ | |
473 | if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \ | |
474 | fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \ | |
475 | else if (ireg != 0) \ | |
476 | fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \ | |
477 | if (scale != 1) fprintf (FILE, "*%d", scale); \ | |
478 | putc (')', FILE); \ | |
479 | break; \ | |
480 | } \ | |
481 | else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \ | |
482 | { fprintf (FILE, "L%d-LI%d(%%pc,%s.w)", \ | |
483 | CODE_LABEL_NUMBER (XEXP (addr, 0)), \ | |
484 | CODE_LABEL_NUMBER (XEXP (addr, 0)), \ | |
485 | reg_names[REGNO (reg1)]); \ | |
486 | break; } \ | |
487 | default: \ | |
488 | if (GET_CODE (addr) == CONST_INT \ | |
489 | && INTVAL (addr) < 0x8000 \ | |
490 | && INTVAL (addr) >= -0x8000) \ | |
74eda121 | 491 | fprintf (FILE, "%d.w", (int) INTVAL (addr)); \ |
f0b7c5aa RS |
492 | else \ |
493 | output_addr_const (FILE, addr); \ | |
494 | }} | |
495 | ||
9d955c3a KG |
496 | #define ASM_OUTPUT_ASCII(f, p, SIZE) \ |
497 | do { size_t i, limit = (SIZE); \ | |
f0b7c5aa RS |
498 | int inside; \ |
499 | inside = FALSE; \ | |
9d955c3a | 500 | for (i = 0; i < limit; i++) { \ |
f0b7c5aa RS |
501 | if (i % 8 == 0) { \ |
502 | if (i != 0) { \ | |
503 | if (inside) \ | |
504 | putc('"', (f)); \ | |
505 | putc('\n', (f)); \ | |
506 | inside = FALSE; \ | |
507 | } \ | |
016c8440 | 508 | fprintf((f), "%s", ASCII_DATA_ASM_OP); \ |
f0b7c5aa RS |
509 | } \ |
510 | if ((p)[i] < 32 || (p)[i] == '\\' || (p)[i] == '"' || (p)[i] == 127) { \ | |
511 | if (inside) { \ | |
512 | putc('"', (f)); \ | |
513 | inside = FALSE; \ | |
514 | } \ | |
515 | if (i % 8 != 0) \ | |
516 | putc(',', (f)); \ | |
517 | fprintf((f), "%d", (p)[i]); \ | |
518 | } else { \ | |
519 | if (!inside) { \ | |
520 | if (i % 8 != 0) \ | |
521 | putc(',', (f)); \ | |
522 | putc('"', (f)); \ | |
523 | inside = TRUE; \ | |
524 | } \ | |
525 | putc((p)[i], (f)); \ | |
526 | } \ | |
527 | } \ | |
528 | if (inside) \ | |
529 | putc('"', (f)); \ | |
530 | putc('\n', (f)); \ | |
9e269f72 | 531 | } while (0) |
f0b7c5aa RS |
532 | |
533 | /* Translate Motorola opcodes such as `jbeq' | |
534 | into SGS opcodes such as `beq.w'. | |
535 | Delete the `e' in `move...' and `fmove'. | |
536 | Change `ftst' to `ftest'. */ | |
537 | ||
538 | #define ASM_OUTPUT_OPCODE(FILE, PTR) \ | |
539 | { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \ | |
540 | { ++(PTR); \ | |
541 | while (*(PTR) != ' ') \ | |
542 | { putc (*(PTR), (FILE)); ++(PTR); } \ | |
543 | fprintf ((FILE), ".w"); } \ | |
544 | else if ((PTR)[0] == 'f') \ | |
545 | { \ | |
546 | if (!strncmp ((PTR), "fmove", 5)) \ | |
547 | { fprintf ((FILE), "fmov"); (PTR) += 5; } \ | |
548 | else if (!strncmp ((PTR), "ftst", 4)) \ | |
549 | { fprintf ((FILE), "ftest"); (PTR) += 4; } \ | |
550 | } \ | |
551 | else if ((PTR)[0] == 'm' && (PTR)[1] == 'o' \ | |
552 | && (PTR)[2] == 'v' && (PTR)[3] == 'e') \ | |
553 | { fprintf ((FILE), "mov"); (PTR) += 4; } \ | |
554 | } | |
555 | ||
f0b7c5aa RS |
556 | #else /* not HPUX_ASM */ |
557 | ||
558 | #undef FUNCTION_PROFILER | |
275bb158 RS |
559 | |
560 | /* HP-UX needs the call to mcount before the link instruction. | |
561 | Copy the return address onto the stack before the call to fake it out. */ | |
562 | #define FUNCTION_PROFILER(FILE, LABEL_NO) \ | |
f7fcfd3f JW |
563 | fprintf (FILE, \ |
564 | "\tmovel a6@(4),sp@-\n\tmovl #LP%d,a0\n\tjsr mcount\n\taddqw #4,sp\n", \ | |
565 | (LABEL_NO)); | |
f0b7c5aa RS |
566 | |
567 | #endif /* not HPUX_ASM */ | |
56cbbbd7 | 568 | |
72ba6556 | 569 | /* In m68k svr4, a symbol_ref rtx can be a valid PIC operand if it is an |
7a1929e1 | 570 | operand of a function call. */ |
72ba6556 RK |
571 | #undef LEGITIMATE_PIC_OPERAND_P |
572 | #define LEGITIMATE_PIC_OPERAND_P(X) \ | |
56cbbbd7 | 573 | ((! symbolic_operand (X, VOIDmode) \ |
03f54026 RK |
574 | && ! (GET_CODE (X) == CONST_DOUBLE && mem_for_const_double (X) != 0 \ |
575 | && GET_CODE (mem_for_const_double (X)) == MEM \ | |
576 | && symbolic_operand (XEXP (mem_for_const_double (X), 0), \ | |
577 | VOIDmode))) \ | |
578 | || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \ | |
2c8ec431 | 579 | || PCREL_GENERAL_OPERAND_OK) |
607ca0aa | 580 | |
ddd5a7c1 | 581 | /* hpux8 and later have C++ compatible include files, so do not |
607ca0aa JM |
582 | pretend they are `extern "C"'. */ |
583 | #define NO_IMPLICIT_EXTERN_C |