|
|
1.1 root 1: /* Definitions of target machine for GNU compiler. MERLIN NS32000 version.
2: Copyright (C) 1990 Free Software Foundation, Inc.
3: By Mark Mason ([email protected], [email protected]).
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
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: /* Two flags to control how addresses are printed in assembler insns. */
22:
23: #define SEQUENT_ADDRESS_BUG 1
24: #define SEQUENT_BASE_REGS
25:
26: #include "ns32k.h"
27:
28: /* This is BSD, so it wants DBX format. */
29: #define DBX_DEBUGGING_INFO
30:
31: /* Sequent has some changes in the format of DBX symbols. */
32: #define DBX_NO_XREFS 1
33:
34: /* Don't split DBX symbols into continuations. */
35: #define DBX_CONTIN_LENGTH 0
36:
37: #define TARGET_DEFAULT 1
38:
39: /* Print subsidiary information on the compiler version in use. */
40: #undef TARGET_VERSION
41: #define TARGET_VERSION fprintf (stderr, " (32000, UTek syntax)");
42:
43: /* These control the C++ compiler somehow. */
44: #define FASCIST_ASSEMBLER
45: #define USE_COLLECT
46:
47: #undef CPP_PREDEFINES
48: #define CPP_PREDEFINES \
49: "-Dns32000 -Dns32k -Dns16000 -Dmerlin -Dunix -DUtek -Dbsd"
50:
51: /* This is how to align the code that follows an unconditional branch.
52: Don't define it, since it confuses the assembler (we hear). */
53:
54: #undef ASM_OUTPUT_ALIGN_CODE
55:
56: /* Assember pseudo-op for shared data segment. */
57: #define SHARED_SECTION_ASM_OP ".shdata"
58:
59: /* %$ means print the prefix for an immediate operand. */
60:
61: #ifdef UTEK_ASM
62: #undef PRINT_OPERAND
63: #define PRINT_OPERAND(FILE, X, CODE) \
64: { if (CODE == '$') putc('$', FILE); \
65: else if (CODE == '?'); \
66: else if (GET_CODE (X) == CONST_INT) \
67: fprintf(FILE, "$%d", INTVAL(X)); \
68: else if (GET_CODE (X) == REG) \
69: fprintf (FILE, "%s", reg_names[REGNO (X)]); \
70: else if (GET_CODE (X) == MEM) \
71: { \
72: rtx xfoo; \
73: xfoo = XEXP (X, 0); \
74: switch (GET_CODE (xfoo)) \
75: { \
76: case MEM: \
77: if (GET_CODE (XEXP (xfoo, 0)) == REG) \
78: if (REGNO (XEXP (xfoo, 0)) == STACK_POINTER_REGNUM) \
79: fprintf (FILE, "0(0(sp))"); \
80: else fprintf (FILE, "0(0(%s))", \
81: reg_names[REGNO (XEXP (xfoo, 0))]); \
82: else \
83: { \
84: if (GET_CODE (XEXP (xfoo, 0)) == SYMBOL_REF \
85: || GET_CODE (XEXP (xfoo, 0)) == CONST) \
86: { \
87: fprintf(FILE, "0("); \
88: output_address(xfoo); \
89: fprintf(FILE, "(sb))"); \
90: } \
91: else \
92: { \
93: fprintf (FILE, "0("); \
94: output_address (xfoo); \
95: putc (')', FILE); \
96: } \
97: } \
98: break; \
99: case REG: \
100: fprintf (FILE, "0(%s)", reg_names[REGNO (xfoo)]); \
101: break; \
102: case PRE_DEC: \
103: case POST_INC: \
104: fprintf (FILE, "tos"); \
105: break; \
106: case CONST_INT: \
107: fprintf (FILE, "$%d", INTVAL (xfoo)); \
108: break; \
109: default: \
110: output_address (xfoo); \
111: break; \
112: } \
113: } \
114: else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode) \
115: if (GET_MODE (X) == DFmode) \
116: { union { double d; int i[2]; } u; \
117: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
118: fprintf (FILE, "$0d%.20e", u.d); } \
119: else { union { double d; int i[2]; } u; \
120: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
121: fprintf (FILE, "$0f%.20e", u.d); } \
122: else output_addr_const (FILE, X); }
123:
124: #undef FUNCTION_PROLOGUE
125:
126: /* This differs from the one in ns32k.h in printing a bitmask
127: rather than a register list in the enter or save instruction. */
128:
129: #define FUNCTION_PROLOGUE(FILE, SIZE) \
130: { register int regno, g_regs_used = 0; \
131: int used_regs_buf[8], *bufp = used_regs_buf; \
132: int used_fregs_buf[8], *fbufp = used_fregs_buf; \
133: extern char call_used_regs[]; \
134: MAIN_FUNCTION_PROLOGUE; \
135: for (regno = 0; regno < 8; regno++) \
136: if (regs_ever_live[regno] \
137: && ! call_used_regs[regno]) \
138: { \
139: *bufp++ = regno; g_regs_used++; \
140: } \
141: *bufp = -1; \
142: for (; regno < 16; regno++) \
143: if (regs_ever_live[regno] && !call_used_regs[regno]) { \
144: *fbufp++ = regno; \
145: } \
146: *fbufp = -1; \
147: bufp = used_regs_buf; \
148: if (frame_pointer_needed) \
149: fprintf (FILE, "\tenter "); \
150: else if (g_regs_used) \
151: fprintf (FILE, "\tsave "); \
152: if (frame_pointer_needed || g_regs_used) \
153: { \
154: char mask = 0; \
155: while (*bufp >= 0) \
156: mask |= 1 << *bufp++; \
157: fprintf (FILE, "$0x%x", (int) mask & 0xff); \
158: } \
159: if (frame_pointer_needed) \
160: fprintf (FILE, ",%d\n", SIZE); \
161: else if (g_regs_used) \
162: fprintf (FILE, "\n"); \
163: fbufp = used_fregs_buf; \
164: while (*fbufp >= 0) \
165: { \
166: if ((*fbufp & 1) || (fbufp[0] != fbufp[1] - 1)) \
167: fprintf (FILE, "\tmovf f%d,tos\n", *fbufp++ - 8); \
168: else \
169: { \
170: fprintf (FILE, "\tmovl f%d,tos\n", fbufp[0] - 8); \
171: fbufp += 2; \
172: } \
173: } \
174: }
175:
176: #undef FUNCTION_EPILOGUE
177:
178: /* This differs from the one in ns32k.h in printing a bitmask
179: rather than a register list in the exit or restore instruction. */
180:
181: #define FUNCTION_EPILOGUE(FILE, SIZE) \
182: { register int regno, g_regs_used = 0, f_regs_used = 0; \
183: int used_regs_buf[8], *bufp = used_regs_buf; \
184: int used_fregs_buf[8], *fbufp = used_fregs_buf; \
185: extern char call_used_regs[]; \
186: *fbufp++ = -2; \
187: for (regno = 8; regno < 16; regno++) \
188: if (regs_ever_live[regno] && !call_used_regs[regno]) { \
189: *fbufp++ = regno; f_regs_used++; \
190: } \
191: fbufp--; \
192: for (regno = 0; regno < 8; regno++) \
193: if (regs_ever_live[regno] \
194: && ! call_used_regs[regno]) \
195: { \
196: *bufp++ = regno; g_regs_used++; \
197: } \
198: while (fbufp > used_fregs_buf) \
199: { \
200: if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1) \
201: { \
202: fprintf (FILE, "\tmovl tos,f%d\n", fbufp[-1] - 8); \
203: fbufp -= 2; \
204: } \
205: else fprintf (FILE, "\tmovf tos,f%d\n", *fbufp-- - 8); \
206: } \
207: if (frame_pointer_needed) \
208: fprintf (FILE, "\texit "); \
209: else if (g_regs_used) \
210: fprintf (FILE, "\trestore "); \
211: if (g_regs_used || frame_pointer_needed) \
212: { \
213: char mask = 0; \
214: \
215: while (bufp > used_regs_buf) \
216: { \
217: /* Utek assembler takes care of reversing this */ \
218: mask |= 1 << *--bufp; \
219: } \
220: fprintf (FILE, "$0x%x\n", (int) mask & 0xff); \
221: } \
222: if (current_function_pops_args) \
223: fprintf (FILE, "\tret %d\n", current_function_pops_args); \
224: else fprintf (FILE, "\tret 0\n"); }
225:
226: #endif /* UTEK_ASM */
227:
228: #undef PRINT_OPERAND_ADDRESS
229: #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address(FILE, ADDR)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.