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)
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. */
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 */
30 #include "m68k/m68k.h"
31 #undef SELECT_RTX_SECTION
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. */
46 #undef SELECT_RTX_SECTION
48 #undef EXTRA_SECTION_FUNCTIONS
49 #undef CONST_SECTION_ASM_OP
50 #undef READONLY_DATA_SECTION
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)
62 #define OBJECT_FORMAT_COFF
68 * define all the things the compiler should
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"
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"
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"
82 * you can't get a DPX/2 without a 68882 but allow it
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
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.
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 #undef ASM_OUTPUT_SOURCE_FILENAME
117 #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NA) \
118 do { fprintf ((FILE), "\t.file\t'%s'\n", (NA)); } while (0)
121 * we don't seem to support any of:
127 #undef ASM_OUTPUT_SKIP
128 #define ASM_OUTPUT_SKIP(FILE,SIZE) \
129 fprintf (FILE, "\tdcb.b %u,0\n", (SIZE))
132 #define GLOBAL_ASM_OP "\txdef\t"
134 #undef ASM_OUTPUT_ALIGN
135 #define ASM_OUTPUT_ALIGN(FILE,LOG) \
137 fprintf (FILE, "\tds.w 0\n");
140 #define STRING_LIMIT (0)
142 #define ASM_APP_ON ""
144 #define ASM_APP_OFF ""
146 * dc.b 'hello, world!'
148 * is how we have to output "hello, world!\n"
150 #undef ASM_OUTPUT_ASCII
151 #define ASM_OUTPUT_ASCII(asm_out_file, p, thissize) \
152 do { register int i, c, f=0, len=0; \
153 for (i = 0; i < thissize; i++) { \
155 if (c == '\'' || c < ' ' || c > 127) { \
157 case 0: /* need to output dc.b etc */ \
158 fprintf(asm_out_file, "\tdc.b %d", c); \
162 fprintf(asm_out_file, ",%d", c); \
165 /* close a string */ \
166 fprintf(asm_out_file, "'\n\tdc.b %d", c); \
173 fprintf(asm_out_file, "\tdc.b '%c", c); \
178 fprintf(asm_out_file, "'\n\tdc.b '%c", c); \
181 fprintf(asm_out_file, "%c", c); \
185 fprintf(asm_out_file, "\n\tdc.b '%c", c); \
193 putc('\'', asm_out_file); \
194 putc('\n', asm_out_file); } while (0)
196 /* This is how to output an insn to push a register on the stack.
197 It need not be very fast code. */
199 #undef ASM_OUTPUT_REG_PUSH
200 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
201 fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
203 /* This is how to output an insn to pop a register from the stack.
204 It need not be very fast code. */
206 #undef ASM_OUTPUT_REG_POP
207 #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
208 fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
211 #define PUT_SDB_FUNCTION_START(LINE) \
212 fprintf (asm_out_file, \
213 "\t.def\t.bf%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
214 SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
216 #define PUT_SDB_FUNCTION_END(LINE) \
217 fprintf (asm_out_file, \
218 "\t.def\t.ef%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_BLOCK_START(LINE) \
222 fprintf (asm_out_file, \
223 "\t.def\t.bb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
224 SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
226 #define PUT_SDB_BLOCK_END(LINE) \
227 fprintf (asm_out_file, \
228 "\t.def\t.eb%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_EPILOGUE_END(NAME)
233 /* Output type in decimal not in octal as done in sdbout.c */
234 #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%d%s", a, SDB_DELIM)
236 /* Translate Motorola opcodes such as `jbeq'
237 into VERSAdos opcodes such as `beq'.
238 Change `fbeq' to `fbseq', `fbne' to `fbsneq'.
241 #undef ASM_OUTPUT_OPCODE
242 #define ASM_OUTPUT_OPCODE(FILE, PTR) \
243 { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \
245 while (*(PTR) != ' ') \
246 { putc (*(PTR), (FILE)); ++(PTR); } \
248 else if ((PTR)[0] == 'f') \
250 if (!strncmp ((PTR), "fbeq", 4)) \
251 { fprintf ((FILE), "fbseq"); (PTR) += 4; } \
252 else if (!strncmp ((PTR), "fbne", 4)) \
253 { fprintf ((FILE), "fbsneq"); (PTR) += 4; } \
255 else if ((PTR)[0] == 'b' && (PTR)[1] == 'f') \
258 if ((s = (char*)strchr ((PTR), '{'))) \
259 while (*s != '}') { \
261 /* hack, I replace it with R ie nothing */ \
267 /* This is how to output an element of a case-vector that is absolute.
268 (The 68000 does not use such vectors,
269 but we must define this macro anyway.) */
270 #undef ASM_OUTPUT_ADDR_VEC_ELT
271 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
272 asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
274 /* This is how to output an element of a case-vector that is relative. */
275 #undef ASM_OUTPUT_ADDR_DIFF_ELT
276 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
277 asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
279 /* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
280 keep switch tables in the text section. */
281 #define JUMP_TABLES_IN_TEXT_SECTION 1
283 /* Output a float value (represented as a C double) as an immediate operand.
284 This macro is a 68k-specific macro. */
285 #undef ASM_OUTPUT_FLOAT_OPERAND
286 #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
291 REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr); \
292 asm_fprintf ((FILE), "%I%s", dstr); \
297 REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
298 if (sizeof (int) == sizeof (long)) \
299 asm_fprintf ((FILE), "%I$%x", (int) l); \
301 asm_fprintf ((FILE), "%I$%lx", l); \
305 /* Output a double value (represented as a C double) as an immediate operand.
306 This macro is a 68k-specific macro. */
307 #undef ASM_OUTPUT_DOUBLE_OPERAND
308 #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \
309 do { char dstr[30]; \
310 REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \
311 asm_fprintf (FILE, "%I%s", dstr); \
314 /* Note, long double immediate operands are not actually
315 generated by m68k.md. */
316 #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND
317 #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \
318 do { char dstr[30]; \
319 REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \
320 asm_fprintf (FILE, "%I%s", dstr); \
323 #undef ASM_OUTPUT_COMMON
324 #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
325 ( fputs ("\t.comm ", (FILE)), \
326 assemble_name ((FILE), (NAME)), \
327 fprintf ((FILE), ",%u\n", (ROUNDED)))
329 #undef ASM_OUTPUT_LOCAL
330 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
332 int align = exact_log2 (ROUNDED); \
333 /*fprintf ((FILE), "\tsection 14\n"); */ \
335 ASM_OUTPUT_ALIGN ((FILE), align) \
336 ASM_OUTPUT_LABEL ((FILE), (NAME)); \
337 fprintf ((FILE), "\tdcb.b %u,0\n", (ROUNDED)); \
338 /* fprintf ((FILE), "\tsection 10\n"); */ \
341 #undef PRINT_OPERAND_ADDRESS
342 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
343 { register rtx reg1, reg2, breg, ireg; \
344 register rtx addr = ADDR; \
346 switch (GET_CODE (addr)) \
349 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \
352 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \
355 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \
358 reg1 = 0; reg2 = 0; \
359 ireg = 0; breg = 0; \
361 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \
363 offset = XEXP (addr, 0); \
364 addr = XEXP (addr, 1); \
366 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \
368 offset = XEXP (addr, 1); \
369 addr = XEXP (addr, 0); \
371 if (GET_CODE (addr) != PLUS) ; \
372 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \
374 reg1 = XEXP (addr, 0); \
375 addr = XEXP (addr, 1); \
377 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \
379 reg1 = XEXP (addr, 1); \
380 addr = XEXP (addr, 0); \
382 else if (GET_CODE (XEXP (addr, 0)) == MULT) \
384 reg1 = XEXP (addr, 0); \
385 addr = XEXP (addr, 1); \
387 else if (GET_CODE (XEXP (addr, 1)) == MULT) \
389 reg1 = XEXP (addr, 1); \
390 addr = XEXP (addr, 0); \
392 else if (GET_CODE (XEXP (addr, 0)) == REG) \
394 reg1 = XEXP (addr, 0); \
395 addr = XEXP (addr, 1); \
397 else if (GET_CODE (XEXP (addr, 1)) == REG) \
399 reg1 = XEXP (addr, 1); \
400 addr = XEXP (addr, 0); \
402 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \
403 || GET_CODE (addr) == SIGN_EXTEND) \
404 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \
405 /* for OLD_INDEXING \
406 else if (GET_CODE (addr) == PLUS) \
408 if (GET_CODE (XEXP (addr, 0)) == REG) \
410 reg2 = XEXP (addr, 0); \
411 addr = XEXP (addr, 1); \
413 else if (GET_CODE (XEXP (addr, 1)) == REG) \
415 reg2 = XEXP (addr, 1); \
416 addr = XEXP (addr, 0); \
420 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \
421 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \
422 || GET_CODE (reg1) == MULT)) \
423 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \
424 { breg = reg2; ireg = reg1; } \
425 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \
426 { breg = reg1; ireg = reg2; } \
427 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \
429 if (GET_CODE (ireg) == MULT) \
430 { scale = INTVAL (XEXP (ireg, 1)); \
431 ireg = XEXP (ireg, 0); } \
432 if (GET_CODE (ireg) == SIGN_EXTEND) \
433 fprintf (FILE, "(.L%d,pc,%s.w", \
434 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
435 reg_names[REGNO (XEXP (ireg, 0))]); \
437 fprintf (FILE, "(.L%d,pc,%s.l", \
438 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
439 reg_names[REGNO (ireg)]); \
440 if (scale != 1) fprintf (FILE, "*%d", scale); \
443 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF \
444 && ! (flag_pic && breg == pic_offset_table_rtx)) \
446 fprintf (FILE, "(.L%d,pc,%s.l", \
447 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
448 reg_names[REGNO (breg)]); \
451 if (ireg != 0 || breg != 0) \
458 output_addr_const (FILE, addr); \
461 fprintf (FILE, "%s", reg_names[REGNO (breg)]); \
464 if (ireg != 0 && GET_CODE (ireg) == MULT) \
465 { scale = INTVAL (XEXP (ireg, 1)); \
466 ireg = XEXP (ireg, 0); } \
467 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \
468 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \
469 else if (ireg != 0) \
470 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \
471 if (scale != 1) fprintf (FILE, "*%d", scale); \
475 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \
476 { fprintf (FILE, "(.L%d,pc,%s.w)", \
477 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
478 reg_names[REGNO (reg1)]); \
481 if (GET_CODE (addr) == CONST_INT \
482 && INTVAL (addr) < 0x8000 \
483 && INTVAL (addr) >= -0x8000) \
484 fprintf (FILE, "%d.w", INTVAL (addr)); \
486 output_addr_const (FILE, addr); \
490 #endif /* ! use gas */