|
|
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/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: -Asystem(unix) -Asystem(bsd) -Acpu(ns32k) -Amachine(ns32k)"
51:
52: /* This is how to align the code that follows an unconditional branch.
53: Don't define it, since it confuses the assembler (we hear). */
54:
55: #undef ASM_OUTPUT_ALIGN_CODE
56:
57: /* Assembler pseudo-op for shared data segment. */
58: #define SHARED_SECTION_ASM_OP ".shdata"
59:
60: /* %$ means print the prefix for an immediate operand. */
61:
62: #ifdef UTEK_ASM
63: #undef PRINT_OPERAND
64: #define PRINT_OPERAND(FILE, X, CODE) \
65: { if (CODE == '$') putc('$', FILE); \
66: else if (CODE == '?'); \
67: else if (GET_CODE (X) == CONST_INT) \
68: fprintf(FILE, "$%d", INTVAL(X)); \
69: else if (GET_CODE (X) == REG) \
70: fprintf (FILE, "%s", reg_names[REGNO (X)]); \
71: else if (GET_CODE (X) == MEM) \
72: { \
73: rtx xfoo; \
74: xfoo = XEXP (X, 0); \
75: switch (GET_CODE (xfoo)) \
76: { \
77: case MEM: \
78: if (GET_CODE (XEXP (xfoo, 0)) == REG) \
79: if (REGNO (XEXP (xfoo, 0)) == STACK_POINTER_REGNUM) \
80: fprintf (FILE, "0(0(sp))"); \
81: else fprintf (FILE, "0(0(%s))", \
82: reg_names[REGNO (XEXP (xfoo, 0))]); \
83: else \
84: { \
85: if (GET_CODE (XEXP (xfoo, 0)) == SYMBOL_REF \
86: || GET_CODE (XEXP (xfoo, 0)) == CONST) \
87: { \
88: fprintf(FILE, "0("); \
89: output_address(xfoo); \
90: fprintf(FILE, "(sb))"); \
91: } \
92: else \
93: { \
94: fprintf (FILE, "0("); \
95: output_address (xfoo); \
96: putc (')', FILE); \
97: } \
98: } \
99: break; \
100: case REG: \
101: fprintf (FILE, "0(%s)", reg_names[REGNO (xfoo)]); \
102: break; \
103: case PRE_DEC: \
104: case POST_INC: \
105: fprintf (FILE, "tos"); \
106: break; \
107: case CONST_INT: \
108: fprintf (FILE, "$%d", INTVAL (xfoo)); \
109: break; \
110: default: \
111: output_address (xfoo); \
112: break; \
113: } \
114: } \
115: else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode) \
116: if (GET_MODE (X) == DFmode) \
117: { union { double d; int i[2]; } u; \
118: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
119: fprintf (FILE, "$0d%.20e", u.d); } \
120: else { union { double d; int i[2]; } u; \
121: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
122: fprintf (FILE, "$0f%.20e", u.d); } \
123: else output_addr_const (FILE, X); }
124:
125: #undef FUNCTION_PROLOGUE
126:
127: /* This differs from the one in ns32k.h in printing a bitmask
128: rather than a register list in the enter or save instruction. */
129:
130: #define FUNCTION_PROLOGUE(FILE, SIZE) \
131: { register int regno, g_regs_used = 0; \
132: int used_regs_buf[8], *bufp = used_regs_buf; \
133: int used_fregs_buf[8], *fbufp = used_fregs_buf; \
134: extern char call_used_regs[]; \
135: MAIN_FUNCTION_PROLOGUE; \
136: for (regno = 0; regno < 8; regno++) \
137: if (regs_ever_live[regno] \
138: && ! call_used_regs[regno]) \
139: { \
140: *bufp++ = regno; g_regs_used++; \
141: } \
142: *bufp = -1; \
143: for (; regno < 16; regno++) \
144: if (regs_ever_live[regno] && !call_used_regs[regno]) { \
145: *fbufp++ = regno; \
146: } \
147: *fbufp = -1; \
148: bufp = used_regs_buf; \
149: if (frame_pointer_needed) \
150: fprintf (FILE, "\tenter "); \
151: else if (g_regs_used) \
152: fprintf (FILE, "\tsave "); \
153: if (frame_pointer_needed || g_regs_used) \
154: { \
155: char mask = 0; \
156: while (*bufp >= 0) \
157: mask |= 1 << *bufp++; \
158: fprintf (FILE, "$0x%x", (int) mask & 0xff); \
159: } \
160: if (frame_pointer_needed) \
161: fprintf (FILE, ",%d\n", SIZE); \
162: else if (g_regs_used) \
163: fprintf (FILE, "\n"); \
164: fbufp = used_fregs_buf; \
165: while (*fbufp >= 0) \
166: { \
167: if ((*fbufp & 1) || (fbufp[0] != fbufp[1] - 1)) \
168: fprintf (FILE, "\tmovf f%d,tos\n", *fbufp++ - 8); \
169: else \
170: { \
171: fprintf (FILE, "\tmovl f%d,tos\n", fbufp[0] - 8); \
172: fbufp += 2; \
173: } \
174: } \
175: }
176:
177: #undef FUNCTION_EPILOGUE
178:
179: /* This differs from the one in ns32k.h in printing a bitmask
180: rather than a register list in the exit or restore instruction. */
181:
182: #define FUNCTION_EPILOGUE(FILE, SIZE) \
183: { register int regno, g_regs_used = 0, f_regs_used = 0; \
184: int used_regs_buf[8], *bufp = used_regs_buf; \
185: int used_fregs_buf[8], *fbufp = used_fregs_buf; \
186: extern char call_used_regs[]; \
187: *fbufp++ = -2; \
188: for (regno = 8; regno < 16; regno++) \
189: if (regs_ever_live[regno] && !call_used_regs[regno]) { \
190: *fbufp++ = regno; f_regs_used++; \
191: } \
192: fbufp--; \
193: for (regno = 0; regno < 8; regno++) \
194: if (regs_ever_live[regno] \
195: && ! call_used_regs[regno]) \
196: { \
197: *bufp++ = regno; g_regs_used++; \
198: } \
199: while (fbufp > used_fregs_buf) \
200: { \
201: if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1) \
202: { \
203: fprintf (FILE, "\tmovl tos,f%d\n", fbufp[-1] - 8); \
204: fbufp -= 2; \
205: } \
206: else fprintf (FILE, "\tmovf tos,f%d\n", *fbufp-- - 8); \
207: } \
208: if (frame_pointer_needed) \
209: fprintf (FILE, "\texit "); \
210: else if (g_regs_used) \
211: fprintf (FILE, "\trestore "); \
212: if (g_regs_used || frame_pointer_needed) \
213: { \
214: char mask = 0; \
215: \
216: while (bufp > used_regs_buf) \
217: { \
218: /* Utek assembler takes care of reversing this */ \
219: mask |= 1 << *--bufp; \
220: } \
221: fprintf (FILE, "$0x%x\n", (int) mask & 0xff); \
222: } \
223: if (current_function_pops_args) \
224: fprintf (FILE, "\tret %d\n", current_function_pops_args); \
225: else fprintf (FILE, "\tret 0\n"); }
226:
227: #endif /* UTEK_ASM */
228:
229: #undef PRINT_OPERAND_ADDRESS
230: #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.