* varasm.c (assemble_real): Use REAL_VALUE_TO_x and assemble_integer
[official-gcc.git] / gcc / config / m68k / dpx2.h
blob2bc06b4bc2b757f66e60bbbf724f10302df0f279
1 /* Definitions of target machine for GNU compiler.
2 Bull DPX/2 200 and 300 systems (m68k, SysVr3).
3 Copyright (C) 1987, 1993, 1994, 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
24 #ifndef USE_GAS
25 #define MOTOROLA /* Use Motorola syntax rather than "MIT" */
26 #define SGS_NO_LI /* Suppress jump table label usage */
27 #define VERSADOS /* This is the name of the assembler we have */
28 #endif
30 #include "m68k/m68k.h"
31 #undef SELECT_RTX_SECTION
32 #include "svr3.h"
34 #undef INT_OP_GROUP
35 #define INT_OP_GROUP INT_OP_DC
37 /* We use collect2 instead of ctors_section constructors. */
38 #undef INIT_SECTION_ASM_OP
39 #undef FINI_SECTION_ASM_OP
40 #undef DTORS_SECTION_ASM_OP
41 #undef DO_GLOBAL_CTORS_BODY
43 /* Remove handling for a separate constant data section. We put
44 constant data in text_section, which is the default. */
45 #undef SELECT_SECTION
46 #undef SELECT_RTX_SECTION
47 #undef EXTRA_SECTIONS
48 #undef EXTRA_SECTION_FUNCTIONS
49 #undef CONST_SECTION_ASM_OP
50 #undef READONLY_DATA_SECTION
52 #define DPX2
54 /* See m68k.h. 7 means 68020 with 68881.
55 * We really have 68030 and 68882,
56 * but this will get us going.
58 #ifndef TARGET_DEFAULT
59 #define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020)
60 #endif
62 #define OBJECT_FORMAT_COFF
64 #ifdef CPP_PREDEFINES
65 #undef CPP_PREDEFINES
66 #endif
68 * define all the things the compiler should
70 #ifdef ncl_mr
71 # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_mr=1 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem=unix -Asystem=svr3 -Acpu=m68k -Amachine=m68k"
72 #else
73 # ifdef ncl_el
74 # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_el -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem=unix -Asystem=svr3 -Acpu=m68k -Amachine=m68k"
75 # else
76 # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem=unix -Asystem=svr3 -Acpu=m68k -Amachine=m68k"
77 # endif
78 #endif
80 #undef CPP_SPEC
82 * you can't get a DPX/2 without a 68882 but allow it
83 * to be ignored...
85 # define __HAVE_68881__ 1
86 # define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__ }"
88 #undef DO_GLOBAL_CTORS_BODY /* don't use svr3.h version */
89 #undef DO_GLOBAL_DTORS_BODY
91 #ifndef USE_GAS
93 * handle the native MOTOROLA VERSAdos assembler.
96 /* See m68k.h. 3 means 68020 with 68881 and no bitfield
97 * bitfield instructions do not seem to work a clean way.
99 #undef TARGET_DEFAULT
100 #define TARGET_DEFAULT (MASK_68881|MASK_68020)
102 /* The native assembler doesn't support fmovecr. */
103 #define NO_ASM_FMOVECR
105 #undef TEXT_SECTION_ASM_OP
106 #define TEXT_SECTION_ASM_OP "\tsection 10"
107 #undef DATA_SECTION_ASM_OP
108 #define DATA_SECTION_ASM_OP "\tsection 15"
109 #define BSS_SECTION_ASM_OP "\tsection 14"
112 /* Don't try using XFmode. */
113 #undef LONG_DOUBLE_TYPE_SIZE
114 #define LONG_DOUBLE_TYPE_SIZE 64
116 /* Define if you don't want extended real, but do want to use the
117 software floating point emulator for REAL_ARITHMETIC and
118 decimal <-> binary conversion. */
119 #define REAL_ARITHMETIC
121 #undef ASM_OUTPUT_SOURCE_FILENAME
122 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NA) \
123 do { fprintf ((FILE), "\t.file\t'%s'\n", (NA)); } while (0)
126 * we don't seem to support any of:
127 * .globl
128 * .even
129 * .align
130 * .ascii
132 #undef ASM_OUTPUT_SKIP
133 #define ASM_OUTPUT_SKIP(FILE,SIZE) \
134 fprintf (FILE, "\tdcb.b %u,0\n", (SIZE))
136 #undef GLOBAL_ASM_OP
137 #define GLOBAL_ASM_OP "\txdef\t"
139 #undef ASM_OUTPUT_ALIGN
140 #define ASM_OUTPUT_ALIGN(FILE,LOG) \
141 if ((LOG) >= 1) \
142 fprintf (FILE, "\tds.w 0\n");
145 #define STRING_LIMIT (0)
146 #undef ASM_APP_ON
147 #define ASM_APP_ON ""
148 #undef ASM_APP_OFF
149 #define ASM_APP_OFF ""
151 * dc.b 'hello, world!'
152 * dc.b 10,0
153 * is how we have to output "hello, world!\n"
155 #undef ASM_OUTPUT_ASCII
156 #define ASM_OUTPUT_ASCII(asm_out_file, p, thissize) \
157 do { register int i, c, f=0, len=0; \
158 for (i = 0; i < thissize; i++) { \
159 c = p[i]; \
160 if (c == '\'' || c < ' ' || c > 127) { \
161 switch(f) { \
162 case 0: /* need to output dc.b etc */ \
163 fprintf(asm_out_file, "\tdc.b %d", c); \
164 f=1; \
165 break; \
166 case 1: \
167 fprintf(asm_out_file, ",%d", c); \
168 break; \
169 default: \
170 /* close a string */ \
171 fprintf(asm_out_file, "'\n\tdc.b %d", c); \
172 f=1; \
173 break; \
175 } else { \
176 switch(f) { \
177 case 0: \
178 fprintf(asm_out_file, "\tdc.b '%c", c); \
179 f=2; \
180 break; \
181 case 2: \
182 if (len >= 79) { \
183 fprintf(asm_out_file, "'\n\tdc.b '%c", c); \
184 len = 0; } \
185 else \
186 fprintf(asm_out_file, "%c", c); \
187 break; \
188 default: \
189 len = 0; \
190 fprintf(asm_out_file, "\n\tdc.b '%c", c); \
191 f=2; \
192 break; \
195 len++; \
197 if (f==2) \
198 putc('\'', asm_out_file); \
199 putc('\n', asm_out_file); } while (0)
201 /* This is how to output an insn to push a register on the stack.
202 It need not be very fast code. */
204 #undef ASM_OUTPUT_REG_PUSH
205 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
206 fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
208 /* This is how to output an insn to pop a register from the stack.
209 It need not be very fast code. */
211 #undef ASM_OUTPUT_REG_POP
212 #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
213 fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
216 #define PUT_SDB_FUNCTION_START(LINE) \
217 fprintf (asm_out_file, \
218 "\t.def\t.bf%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
219 SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
221 #define PUT_SDB_FUNCTION_END(LINE) \
222 fprintf (asm_out_file, \
223 "\t.def\t.ef%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
224 SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
226 #define PUT_SDB_BLOCK_START(LINE) \
227 fprintf (asm_out_file, \
228 "\t.def\t.bb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
229 SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
231 #define PUT_SDB_BLOCK_END(LINE) \
232 fprintf (asm_out_file, \
233 "\t.def\t.eb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
234 SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
236 #define PUT_SDB_EPILOGUE_END(NAME)
238 /* Output type in decimal not in octal as done in sdbout.c */
239 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%d%s", a, SDB_DELIM)
241 /* Translate Motorola opcodes such as `jbeq'
242 into VERSAdos opcodes such as `beq'.
243 Change `fbeq' to `fbseq', `fbne' to `fbsneq'.
246 #undef ASM_OUTPUT_OPCODE
247 #define ASM_OUTPUT_OPCODE(FILE, PTR) \
248 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \
249 { ++(PTR); \
250 while (*(PTR) != ' ') \
251 { putc (*(PTR), (FILE)); ++(PTR); } \
253 else if ((PTR)[0] == 'f') \
255 if (!strncmp ((PTR), "fbeq", 4)) \
256 { fprintf ((FILE), "fbseq"); (PTR) += 4; } \
257 else if (!strncmp ((PTR), "fbne", 4)) \
258 { fprintf ((FILE), "fbsneq"); (PTR) += 4; } \
260 else if ((PTR)[0] == 'b' && (PTR)[1] == 'f') \
262 char *s; \
263 if ((s = (char*)strchr ((PTR), '{'))) \
264 while (*s != '}') { \
265 if (*s == 'b') \
266 /* hack, I replace it with R ie nothing */ \
267 *s = '0'; \
268 s++; } \
272 /* This is how to output an element of a case-vector that is absolute.
273 (The 68000 does not use such vectors,
274 but we must define this macro anyway.) */
275 #undef ASM_OUTPUT_ADDR_VEC_ELT
276 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
277 asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
279 /* This is how to output an element of a case-vector that is relative. */
280 #undef ASM_OUTPUT_ADDR_DIFF_ELT
281 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
282 asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
284 /* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
285 keep switch tables in the text section. */
286 #define JUMP_TABLES_IN_TEXT_SECTION 1
288 /* Output a float value (represented as a C double) as an immediate operand.
289 This macro is a 68k-specific macro. */
290 #undef ASM_OUTPUT_FLOAT_OPERAND
291 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
292 do { \
293 if (CODE == 'f') \
295 char dstr[30]; \
296 REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr); \
297 asm_fprintf ((FILE), "%I%s", dstr); \
299 else \
301 long l; \
302 REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
303 if (sizeof (int) == sizeof (long)) \
304 asm_fprintf ((FILE), "%I$%x", (int) l); \
305 else \
306 asm_fprintf ((FILE), "%I$%lx", l); \
308 } while (0)
310 /* Output a double value (represented as a C double) as an immediate operand.
311 This macro is a 68k-specific macro. */
312 #undef ASM_OUTPUT_DOUBLE_OPERAND
313 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \
314 do { char dstr[30]; \
315 REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \
316 asm_fprintf (FILE, "%I%s", dstr); \
317 } while (0)
319 /* Note, long double immediate operands are not actually
320 generated by m68k.md. */
321 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
322 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \
323 do { char dstr[30]; \
324 REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \
325 asm_fprintf (FILE, "%I%s", dstr); \
326 } while (0)
328 #undef ASM_OUTPUT_COMMON
329 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
330 ( fputs ("\t.comm ", (FILE)), \
331 assemble_name ((FILE), (NAME)), \
332 fprintf ((FILE), ",%u\n", (ROUNDED)))
334 #undef ASM_OUTPUT_LOCAL
335 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
336 do { \
337 int align = exact_log2 (ROUNDED); \
338 /*fprintf ((FILE), "\tsection 14\n"); */ \
339 data_section (); \
340 ASM_OUTPUT_ALIGN ((FILE), align) \
341 ASM_OUTPUT_LABEL ((FILE), (NAME)); \
342 fprintf ((FILE), "\tdcb.b %u,0\n", (ROUNDED)); \
343 /* fprintf ((FILE), "\tsection 10\n"); */ \
344 } while (0)
346 #undef PRINT_OPERAND_ADDRESS
347 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
348 { register rtx reg1, reg2, breg, ireg; \
349 register rtx addr = ADDR; \
350 rtx offset; \
351 switch (GET_CODE (addr)) \
353 case REG: \
354 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \
355 break; \
356 case PRE_DEC: \
357 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \
358 break; \
359 case POST_INC: \
360 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \
361 break; \
362 case PLUS: \
363 reg1 = 0; reg2 = 0; \
364 ireg = 0; breg = 0; \
365 offset = 0; \
366 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \
368 offset = XEXP (addr, 0); \
369 addr = XEXP (addr, 1); \
371 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \
373 offset = XEXP (addr, 1); \
374 addr = XEXP (addr, 0); \
376 if (GET_CODE (addr) != PLUS) ; \
377 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \
379 reg1 = XEXP (addr, 0); \
380 addr = XEXP (addr, 1); \
382 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \
384 reg1 = XEXP (addr, 1); \
385 addr = XEXP (addr, 0); \
387 else if (GET_CODE (XEXP (addr, 0)) == MULT) \
389 reg1 = XEXP (addr, 0); \
390 addr = XEXP (addr, 1); \
392 else if (GET_CODE (XEXP (addr, 1)) == MULT) \
394 reg1 = XEXP (addr, 1); \
395 addr = XEXP (addr, 0); \
397 else if (GET_CODE (XEXP (addr, 0)) == REG) \
399 reg1 = XEXP (addr, 0); \
400 addr = XEXP (addr, 1); \
402 else if (GET_CODE (XEXP (addr, 1)) == REG) \
404 reg1 = XEXP (addr, 1); \
405 addr = XEXP (addr, 0); \
407 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \
408 || GET_CODE (addr) == SIGN_EXTEND) \
409 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \
410 /* for OLD_INDEXING \
411 else if (GET_CODE (addr) == PLUS) \
413 if (GET_CODE (XEXP (addr, 0)) == REG) \
415 reg2 = XEXP (addr, 0); \
416 addr = XEXP (addr, 1); \
418 else if (GET_CODE (XEXP (addr, 1)) == REG) \
420 reg2 = XEXP (addr, 1); \
421 addr = XEXP (addr, 0); \
424 */ \
425 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \
426 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \
427 || GET_CODE (reg1) == MULT)) \
428 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \
429 { breg = reg2; ireg = reg1; } \
430 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \
431 { breg = reg1; ireg = reg2; } \
432 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \
433 { int scale = 1; \
434 if (GET_CODE (ireg) == MULT) \
435 { scale = INTVAL (XEXP (ireg, 1)); \
436 ireg = XEXP (ireg, 0); } \
437 if (GET_CODE (ireg) == SIGN_EXTEND) \
438 fprintf (FILE, "(.L%d,pc,%s.w", \
439 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
440 reg_names[REGNO (XEXP (ireg, 0))]); \
441 else \
442 fprintf (FILE, "(.L%d,pc,%s.l", \
443 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
444 reg_names[REGNO (ireg)]); \
445 if (scale != 1) fprintf (FILE, "*%d", scale); \
446 putc (')', FILE); \
447 break; } \
448 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF \
449 && ! (flag_pic && breg == pic_offset_table_rtx)) \
451 fprintf (FILE, "(.L%d,pc,%s.l", \
452 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
453 reg_names[REGNO (breg)]); \
454 putc (')', FILE); \
455 break; } \
456 if (ireg != 0 || breg != 0) \
457 { int scale = 1; \
458 if (breg == 0) \
459 abort (); \
460 putc ('(', FILE); \
461 if (addr != 0) \
463 output_addr_const (FILE, addr); \
464 putc (',', FILE); \
466 fprintf (FILE, "%s", reg_names[REGNO (breg)]); \
467 if (ireg != 0) \
468 putc (',', FILE); \
469 if (ireg != 0 && GET_CODE (ireg) == MULT) \
470 { scale = INTVAL (XEXP (ireg, 1)); \
471 ireg = XEXP (ireg, 0); } \
472 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \
473 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \
474 else if (ireg != 0) \
475 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \
476 if (scale != 1) fprintf (FILE, "*%d", scale); \
477 putc (')', FILE); \
478 break; \
480 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \
481 { fprintf (FILE, "(.L%d,pc,%s.w)", \
482 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
483 reg_names[REGNO (reg1)]); \
484 break; } \
485 default: \
486 if (GET_CODE (addr) == CONST_INT \
487 && INTVAL (addr) < 0x8000 \
488 && INTVAL (addr) >= -0x8000) \
489 fprintf (FILE, "%d.w", INTVAL (addr)); \
490 else \
491 output_addr_const (FILE, addr); \
495 #endif /* ! use gas */