]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/m68k/3b1.h
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / config / m68k / 3b1.h
CommitLineData
941d35a7
RS
1/* Definitions of target machine for GNU compiler.
2 AT&T UNIX PC version (pc7300, 3b1)
016c8440 3 Copyright (C) 1987, 1993, 1996, 1999, 2000 Free Software Foundation, Inc.
66dae892 4 Contributed by Alex Crain (alex@umbc3.umd.edu).
941d35a7
RS
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
5129e171 20the Free Software Foundation, 59 Temple Place - Suite 330,
17337c4a 21Boston, MA 02111-1307, USA. */
941d35a7 22
941d35a7
RS
23#define SGS_SWITCH_TABLES /* Different switch table handling */
24
57e51b0e 25#include "m68k/hp320.h"
941d35a7
RS
26
27/* See m68k.h. 0 means 680[01]0 with no 68881. */
28
29#undef TARGET_DEFAULT
30#define TARGET_DEFAULT 0
31
92e6e51e
RS
32/* Don't try using XFmode. */
33#undef LONG_DOUBLE_TYPE_SIZE
34#define LONG_DOUBLE_TYPE_SIZE 64
35
941d35a7
RS
36/* -m68020 requires special flags to the assembler. */
37
38#undef ASM_SPEC
39#define ASM_SPEC "%{m68020:-68020}%{!m68020:-68010} %{m68881:-68881}"
40
41/* we use /lib/libp/lib* when profiling */
42
43#undef LIB_SPEC
44#define LIB_SPEC "%{!shlib:%{p:-L/lib/libp} %{pg:-L/lib/libp} -lc}"
45
46/* shared libraries need to use crt0s.o */
47
48#undef STARTFILE_SPEC
49#define STARTFILE_SPEC \
50 "%{!shlib:%{pg:mcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}\
51 %{shlib:crt0s.o%s shlib.ifile%s} "
52
941d35a7
RS
53/* Make output for SDB. */
54
23532de9 55#define SDB_DEBUGGING_INFO 1
941d35a7
RS
56
57/* The .file command should always begin the output. */
58
59#undef ASM_FILE_START
60#define ASM_FILE_START(FILE) \
61output_file_directive ((FILE), main_input_filename)
62
941d35a7
RS
63/* Define __HAVE_68881__ in preprocessor if -m68881 is specified.
64 This will control the use of inline 68881 insns in certain macros. */
65
66#undef CPP_SPEC
67#define CPP_SPEC "%{m68881:-D__HAVE_68881__}"
68
69/* Names to predefine in the preprocessor for this target machine. */
70/* ihnp4!lmayk!lgm@eddie.mit.edu says mc68000 and m68k should not be here. */
71
72#undef CPP_PREDEFINES
2b57e919 73#define CPP_PREDEFINES "-Dmc68k -Dunix -Dunixpc -D__motorola__ -Asystem=unix -Asystem=svr3 -Acpu=m68k -Amachine=m68k"
941d35a7
RS
74
75#undef REGISTER_NAMES
76#define REGISTER_NAMES \
77{"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", \
78 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp", \
79 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7"}
80
81/* Specify how to pad function arguments.
82 Value should be `upward', `downward' or `none'.
83 Same as the default, except no padding for large or variable-size args. */
84
85#define FUNCTION_ARG_PADDING(MODE, TYPE) \
86 (((MODE) == BLKmode \
87 ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
88 && int_size_in_bytes (TYPE) < PARM_BOUNDARY / BITS_PER_UNIT) \
89 : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \
90 ? downward : none)
91
0310ba22
RS
92/* The 3b1 does not have `atexit'. */
93
c063dc98 94#define NEED_ATEXIT
0310ba22 95
941d35a7
RS
96/* Override parts of m68k.h to fit the SGS-3b1 assembler. */
97
98#undef TARGET_VERSION
941d35a7
RS
99#undef ASM_OUTPUT_ALIGN
100#undef ASM_OUTPUT_SOURCE_FILENAME
101#undef ASM_OUTPUT_SOURCE_LINE
102#undef PRINT_OPERAND_ADDRESS
103#undef ASM_GENERATE_INTERNAL_LABEL
104#undef FUNCTION_PROFILER
105#undef ASM_OUTPUT_ADDR_VEC_ELT
106#undef ASM_OUTPUT_ADDR_DIFF_ELT
941d35a7
RS
107#undef ASM_OUTPUT_OPCODE
108#undef ASM_OUTPUT_LOCAL
66dae892 109#undef USER_LABEL_PREFIX
941d35a7
RS
110#undef ASM_OUTPUT_ASCII
111
112#define TARGET_VERSION fprintf (stderr, " (68k, SGS/AT&T unixpc syntax)");
113
4977bab6 114#define ASM_PN_FORMAT "%s_%%%lu"
941d35a7 115
941d35a7 116#define ASM_OUTPUT_ALIGN(FILE,LOG) \
046b71ed 117do { \
941d35a7
RS
118 if ((LOG) == 1) \
119 fprintf (FILE, "\teven\n"); \
120 else if ((LOG) != 0) \
046b71ed
KG
121 abort (); \
122} while (0)
941d35a7
RS
123
124/* This is how to output an assembler line
125 that says to advance the location counter by SIZE bytes. */
126
127#undef ASM_OUTPUT_SKIP
128#define ASM_OUTPUT_SKIP(FILE,SIZE) \
129 fprintf (FILE, "\tspace %d\n", (SIZE))
130
131/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */
132
133#define ASM_NO_SKIP_IN_TEXT 1
134
7a1929e1 135/* The beginnings of sdb support... */
941d35a7
RS
136
137#define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \
f40176b1
PE
138 do { fprintf (FILE, "\tfile\t"); \
139 output_quoted_string (FILE, FILENAME); \
140 fprintf (FILE, "\n"); \
141 } while (0)
941d35a7
RS
142
143#define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \
144 fprintf (FILE, "\tln\t%d\n", \
145 (sdb_begin_function_line \
da905677 146 ? (LINENO) - sdb_begin_function_line : 1))
941d35a7 147
7a1929e1 148/* Yet another null terminated string format. */
941d35a7
RS
149
150#define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \
9d955c3a 151 do { register size_t sp = 0, lp = 0, limit = (LEN); \
941d35a7
RS
152 fprintf ((FILE), "\tbyte\t"); \
153 loop: \
154 if ((PTR)[sp] > ' ' && ! ((PTR)[sp] & 0x80) && (PTR)[sp] != '\\') \
155 { lp += 3; \
156 fprintf ((FILE), "'%c", (PTR)[sp]); } \
157 else \
158 { lp += 5; \
159 fprintf ((FILE), "0x%x", (PTR)[sp]); } \
9d955c3a 160 if (++sp < limit) \
941d35a7
RS
161 { if (lp > 60) \
162 { lp = 0; \
016c8440 163 fprintf ((FILE), "\n%s", ASCII_DATA_ASM_OP); } \
941d35a7
RS
164 else \
165 putc (',', (FILE)); \
166 goto loop; } \
9e269f72 167 putc ('\n', (FILE)); } while (0)
941d35a7
RS
168
169/* Note that in the case of the movhi which fetches an element of
170 an ADDR_DIFF_VEC the offset output is too large by 2.
171 This is because the 3b1 assembler refuses to subtract 2.
172 ASM_OUTPUT_CASE_LABEL, below, compensates for this. */
173
174#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
175{ register rtx reg1, reg2, breg, ireg; \
176 register rtx addr = ADDR; \
177 rtx offset; \
178 switch (GET_CODE (addr)) \
179 { \
180 case REG: \
181 fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \
182 break; \
183 case PRE_DEC: \
184 fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \
185 break; \
186 case POST_INC: \
187 fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \
188 break; \
189 case PLUS: \
190 reg1 = 0; reg2 = 0; \
191 ireg = 0; breg = 0; \
192 offset = 0; \
193 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \
194 { \
195 offset = XEXP (addr, 0); \
196 addr = XEXP (addr, 1); \
197 } \
198 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \
199 { \
200 offset = XEXP (addr, 1); \
201 addr = XEXP (addr, 0); \
202 } \
203 if (GET_CODE (addr) != PLUS) ; \
204 else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \
205 { \
206 reg1 = XEXP (addr, 0); \
207 addr = XEXP (addr, 1); \
208 } \
209 else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \
210 { \
211 reg1 = XEXP (addr, 1); \
212 addr = XEXP (addr, 0); \
213 } \
214 else if (GET_CODE (XEXP (addr, 0)) == MULT) \
215 { \
216 reg1 = XEXP (addr, 0); \
217 addr = XEXP (addr, 1); \
218 } \
219 else if (GET_CODE (XEXP (addr, 1)) == MULT) \
220 { \
221 reg1 = XEXP (addr, 1); \
222 addr = XEXP (addr, 0); \
223 } \
224 else if (GET_CODE (XEXP (addr, 0)) == REG) \
225 { \
226 reg1 = XEXP (addr, 0); \
227 addr = XEXP (addr, 1); \
228 } \
229 else if (GET_CODE (XEXP (addr, 1)) == REG) \
230 { \
231 reg1 = XEXP (addr, 1); \
232 addr = XEXP (addr, 0); \
233 } \
234 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT \
235 || GET_CODE (addr) == SIGN_EXTEND) \
236 { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \
237/* for OLD_INDEXING \
238 else if (GET_CODE (addr) == PLUS) \
239 { \
240 if (GET_CODE (XEXP (addr, 0)) == REG) \
241 { \
242 reg2 = XEXP (addr, 0); \
243 addr = XEXP (addr, 1); \
244 } \
245 else if (GET_CODE (XEXP (addr, 1)) == REG) \
246 { \
247 reg2 = XEXP (addr, 1); \
248 addr = XEXP (addr, 0); \
249 } \
250 } \
251 */ \
252 if (offset != 0) { if (addr != 0) abort (); addr = offset; } \
253 if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \
254 || GET_CODE (reg1) == MULT)) \
255 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \
256 { breg = reg2; ireg = reg1; } \
257 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \
258 { breg = reg1; ireg = reg2; } \
259 if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \
260 { int scale = 1; \
261 if (GET_CODE (ireg) == MULT) \
262 { scale = INTVAL (XEXP (ireg, 1)); \
263 ireg = XEXP (ireg, 0); } \
264 if (GET_CODE (ireg) == SIGN_EXTEND) \
265 fprintf (FILE, "LD%%%d(%%pc,%s.w", \
266 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
267 reg_names[REGNO (XEXP (ireg, 0))]); \
268 else \
269 fprintf (FILE, "LD%%%d(%%pc,%s.l", \
270 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
271 reg_names[REGNO (ireg)]); \
272 if (scale != 1) fprintf (FILE, "*%d", scale); \
273 fprintf (FILE, ")"); \
274 break; } \
275 if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF) \
276 { fprintf (FILE, "LD%%%d(%%pc,%s.l", \
277 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
278 reg_names[REGNO (breg)]); \
279 putc (')', FILE); \
280 break; } \
281 if (ireg != 0 || breg != 0) \
282 { int scale = 1; \
283 if (breg == 0) \
284 abort (); \
285 if (addr != 0) \
286 output_addr_const (FILE, addr); \
287 fprintf (FILE, "(%s", reg_names[REGNO (breg)]); \
288 if (ireg != 0) \
289 putc (',', FILE); \
290 if (ireg != 0 && GET_CODE (ireg) == MULT) \
291 { scale = INTVAL (XEXP (ireg, 1)); \
292 ireg = XEXP (ireg, 0); } \
293 if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \
294 fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \
295 else if (ireg != 0) \
296 fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \
297 if (scale != 1) fprintf (FILE, "*%d", scale); \
298 putc (')', FILE); \
299 break; \
300 } \
301 else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \
302 { fprintf (FILE, "LD%%%d(%%pc,%s.w)", \
303 CODE_LABEL_NUMBER (XEXP (addr, 0)), \
304 reg_names[REGNO (reg1)]); \
305 break; } \
306 default: \
307 if (GET_CODE (addr) == CONST_INT \
308 && INTVAL (addr) < 0x8000 \
309 && INTVAL (addr) >= -0x8000) \
310 fprintf (FILE, "%d", INTVAL (addr)); \
311 else \
312 output_addr_const (FILE, addr); \
313 }}
314
315#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
e59f7d3d 316 sprintf ((LABEL), "%s%%%ld", (PREFIX), (long)(NUM))
941d35a7 317
941d35a7
RS
318/* Must put address in %a0 , not %d0 . -- LGM, 7/15/88 */
319#define FUNCTION_PROFILER(FILE, LABEL_NO) \
320 fprintf (FILE, "\tmov.l &LP%%%d,%%a0\n\tjsr mcount\n", (LABEL_NO))
321
322#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
323 fprintf (FILE, "\tlong L%%%d\n", (VALUE))
324
33f7f353 325#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
941d35a7
RS
326 fprintf (FILE, "\tshort L%%%d-L%%%d\n", (VALUE), (REL))
327
328/* ihnp4!lmayk!lgm says that `short 0' triggers assembler bug;
329 `short L%nn-L%nn' supposedly works. */
330#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
331 if (! RTX_INTEGRATED_P (TABLE)) \
332 fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n", \
333 XVECLEN (PATTERN (TABLE), 1), (PREFIX), (NUM)); \
334 else \
335 fprintf (FILE, "\tswbeg &%d\n%s%%%d:\n\tshort %s%%%d-%s%%%d\n", \
336 XVECLEN (PATTERN (TABLE), 1) + 1, (PREFIX), (NUM), \
337 (PREFIX), (NUM), (PREFIX), (NUM))
338
fc3ffe83
RK
339/* At end of a switch table, define LDnnn iff the symbol LInnn was defined.
340 Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"
341 fails to assemble. Luckily "LDnnn(pc,d0.l*2)" produces the results
342 we want. This difference can be accommodated by making the assembler
343 define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other
344 string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END
7a1929e1 345 macro. */
fc3ffe83
RK
346
347#define ASM_OUTPUT_CASE_END(FILE,NUM,TABLE) \
348{ if (switch_table_difference_label_flag) \
96b327f4 349 fprintf (FILE, "\tset LD%%%d,L%%%d-LI%%%d\n", (NUM), (NUM), (NUM)); \
fc3ffe83
RK
350 switch_table_difference_label_flag = 0; }
351
352int switch_table_difference_label_flag;
941d35a7
RS
353
354#define ASM_OUTPUT_OPCODE(FILE, PTR) \
355{ if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \
356 { ++(PTR); \
357 while (*(PTR) != ' ') \
358 { putc (*(PTR), (FILE)); ++(PTR); } \
359 fprintf ((FILE), ".w"); } \
d69eb909
RS
360 else if ((PTR)[0] == 's') \
361 { \
362 if (!strncmp ((PTR), "swap", 4)) \
363 { fprintf ((FILE), "swap.w"); (PTR) += 4; } \
364 } \
941d35a7
RS
365 else if ((PTR)[0] == 'f') \
366 { \
367 if (!strncmp ((PTR), "fmove", 5)) \
368 { fprintf ((FILE), "fmov"); (PTR) += 5; } \
369 else if (!strncmp ((PTR), "fbne", 4)) \
370 { fprintf ((FILE), "fbneq"); (PTR) += 4; } \
371 } \
372/* MOVE, MOVEA, MOVEQ, MOVEC ==> MOV */ \
373 else if ((PTR)[0] == 'm' && (PTR)[1] == 'o' \
374 && (PTR)[2] == 'v' && (PTR)[3] == 'e') \
375 { fprintf ((FILE), "mov"); (PTR) += 4; \
d69eb909
RS
376 if ((PTR)[0] == 'q' || (PTR)[0] == 'a' \
377 || (PTR)[0] == 'c') (PTR)++; } \
941d35a7
RS
378/* SUB, SUBQ, SUBA, SUBI ==> SUB */ \
379 else if ((PTR)[0] == 's' && (PTR)[1] == 'u' \
380 && (PTR)[2] == 'b') \
381 { fprintf ((FILE), "sub"); (PTR) += 3; \
d69eb909
RS
382 if ((PTR)[0] == 'q' || (PTR)[0] == 'i' \
383 || (PTR)[0] == 'a') (PTR)++; } \
941d35a7
RS
384/* CMP, CMPA, CMPI, CMPM ==> CMP */ \
385 else if ((PTR)[0] == 'c' && (PTR)[1] == 'm' \
386 && (PTR)[2] == 'p') \
387 { fprintf ((FILE), "cmp"); (PTR) += 3; \
d69eb909
RS
388 if ((PTR)[0] == 'a' || (PTR)[0] == 'i' \
389 || (PTR)[0] == 'm') (PTR)++; } \
941d35a7
RS
390}
391
392#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
393( fputs ("\tlcomm ", (FILE)), \
394 assemble_name ((FILE), (NAME)), \
395 fprintf ((FILE), ",%u\n", (ROUNDED)))
396
66dae892 397#define USER_LABEL_PREFIX ""
941d35a7
RS
398\f
399/* Override usual definitions of SDB output macros.
400 These definitions differ only in the absence of the period
401 at the beginning of the name of the directive
402 and in the use of `~' as the symbol for the current location. */
403
404#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\tscl\t%d;", (a))
405#define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\tval\t%d;", (a))
406#define PUT_SDB_VAL(a) \
407( fputs ("\tval\t", asm_out_file), \
408 output_addr_const (asm_out_file, (a)), \
409 fputc (';', asm_out_file))
410
411#define PUT_SDB_DEF(a) \
412do { fprintf (asm_out_file, "\tdef\t"); \
413 ASM_OUTPUT_LABELREF (asm_out_file, a); \
414 fprintf (asm_out_file, ";"); } while (0)
415
416#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\tdef\t~%s;",a)
417#define PUT_SDB_ENDEF fputs("\tendef\n", asm_out_file)
418#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\ttype\t0%o;", a)
419#define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\tsize\t%d;", a)
420#define PUT_SDB_START_DIM fprintf(asm_out_file, "\tdim\t")
421
422#define PUT_SDB_TAG(a) \
423do { fprintf (asm_out_file, "\ttag\t"); \
424 ASM_OUTPUT_LABELREF (asm_out_file, a); \
425 fprintf (asm_out_file, ";"); } while (0)
426
427#define PUT_SDB_BLOCK_START(LINE) \
428 fprintf (asm_out_file, \
429 "\tdef\t~bb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
430 (LINE))
431
432#define PUT_SDB_BLOCK_END(LINE) \
433 fprintf (asm_out_file, \
434 "\tdef\t~eb;\tval\t~;\tscl\t100;\tline\t%d;\tendef\n", \
435 (LINE))
436
437#define PUT_SDB_FUNCTION_START(LINE) \
438 fprintf (asm_out_file, \
439 "\tdef\t~bf;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
440 (LINE))
441
442#define PUT_SDB_FUNCTION_END(LINE) \
443 fprintf (asm_out_file, \
444 "\tdef\t~ef;\tval\t~;\tscl\t101;\tline\t%d;\tendef\n", \
445 (LINE))
446
447#define PUT_SDB_EPILOGUE_END(NAME) \
448 fprintf (asm_out_file, \
449 "\tdef\t%s;\tval\t~;\tscl\t-1;\tendef\n", \
450 (NAME))
451
452#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
453 sprintf ((BUFFER), "~%dfake", (NUMBER));
454
455/* Define subroutines to call to handle multiply, divide, and remainder.
456 Use the subroutines that the 3b1's library provides.
457 The `*' prevents an underscore from being prepended by the compiler. */
458
459#define DIVSI3_LIBCALL "*ldiv"
460#define UDIVSI3_LIBCALL "*uldiv"
461#define MODSI3_LIBCALL "*lrem"
462#define UMODSI3_LIBCALL "*ulrem"
463#define MULSI3_LIBCALL "*lmul"
464#define UMULSI3_LIBCALL "*ulmul"
c270f796
RS
465
466/* Definitions for collect2. */
467
468#define OBJECT_FORMAT_COFF
c270f796
RS
469#define MY_ISCOFF(magic) \
470 ((magic) == MC68KWRMAGIC || (magic) == MC68KROMAGIC || (magic) == MC68KPGMAGIC)