|
|
1.1 root 1: /* Definitions of target machine for GNU compiler. Genix ns32000 version.
2: Copyright (C) 1987, 1988 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 1, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20: #include "tm-encore.h"
21:
22: /* We don't want the one Encore needs. */
23: #undef ASM_SPEC
24:
25: /* The following defines override ones in tm-ns32k.h and prevent any attempts
26: to explicitly or implicitly make references to the SB register in the GCC
27: generated code. It is necessary to avoid such references under Genix V.3.1
28: because this OS doesn't even save/restore the SB on context switches! */
29:
30: #define IS_OK_REG_FOR_BASE_P(X) \
31: ( (GET_CODE (X) == REG) && REG_OK_FOR_BASE_P (X) )
32:
33: #undef INDIRECTABLE_1_ADDRESS_P
34: #define INDIRECTABLE_1_ADDRESS_P(X) \
35: (CONSTANT_ADDRESS_NO_LABEL_P (X) \
36: || IS_OK_REG_FOR_BASE_P (X) \
37: || (GET_CODE (X) == PLUS \
38: && IS_OK_REG_FOR_BASE_P (XEXP (X, 0)) \
39: && CONSTANT_ADDRESS_P (XEXP (X, 1)) ) )
40:
41: /* Note that for double indirects, only FP, SP, and SB are allowed
42: as the inner-most base register. But we are avoiding use of SB. */
43:
44: #undef MEM_REG
45: #define MEM_REG(X) \
46: ( (GET_CODE (X) == REG) \
47: && ( (REGNO (X) == FRAME_POINTER_REGNUM) \
48: || (REGNO (X) == STACK_POINTER_REGNUM) ) )
49:
50: #undef INDIRECTABLE_2_ADDRESS_P
51: #define INDIRECTABLE_2_ADDRESS_P(X) \
52: (GET_CODE (X) == MEM \
53: && (((xfoo0 = XEXP (X, 0), MEM_REG (xfoo0)) \
54: || (GET_CODE (xfoo0) == PLUS \
55: && MEM_REG (XEXP (xfoo0, 0)) \
56: && CONSTANT_ADDRESS_NO_LABEL_P (XEXP (xfoo0, 1)))) \
57: || CONSTANT_ADDRESS_NO_LABEL_P (xfoo0)))
58:
59: /* Go to ADDR if X is a valid address not using indexing.
60: (This much is the easy part.) */
61: #undef GO_IF_NONINDEXED_ADDRESS
62: #define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \
63: { register rtx xfoob = (X); \
64: if (GET_CODE (xfoob) == REG) goto ADDR; \
65: if (INDIRECTABLE_1_ADDRESS_P(X)) goto ADDR; \
66: if (CONSTANT_P(X)) goto ADDR; \
67: if (INDIRECTABLE_2_ADDRESS_P (X)) goto ADDR; \
68: if (GET_CODE (X) == PLUS) \
69: if (CONSTANT_ADDRESS_NO_LABEL_P (XEXP (X, 1))) \
70: if (INDIRECTABLE_2_ADDRESS_P (XEXP (X, 0))) \
71: goto ADDR; \
72: }
73:
74: /* A bug in the GNX 3.X assembler causes references to external symbols to
75: be mishandled if the symbol is also used as the name of a function-local
76: variable or as the name of a struct or union field. The problem only
77: appears when you are also using the -g option so that SDB debugging
78: directives are also being produced by GCC. In such cases, the assembler
79: gets the external entity confused with the local entity and addressing
80: havoc ensues. The solution is to get GCC to produce .global directives
81: for all external entities which are actually referenced within the current
82: source file. The following macro does this. */
83:
84: #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
85: ASM_GLOBALIZE_LABEL(FILE,NAME);
86:
87: /* A bug in the GNX 3.X linker prevents symbol-table entries with a storage-
88: class field of C_EFCN (-1) from being accepted. */
89:
90: #ifdef PUT_SDB_EPILOGUE_END
91: #undef PUT_SDB_EPILOGUE_END
92: #endif
93: #define PUT_SDB_EPILOGUE_END(NAME)
94:
95: #undef TARGET_VERSION
96: #define TARGET_VERSION fprintf (stderr, " (32000, National syntax)");
97:
98: /* Same as the tm-encore definition except
99: * Different syntax for double constants.
100: * Don't output `?' before external regs.
101: * Output `(sb)' in certain indirect refs. */
102:
103: #undef PRINT_OPERAND
104: #define PRINT_OPERAND(FILE, X, CODE) \
105: { if (CODE == '$') putc ('$', FILE); \
106: else if (CODE == '?'); \
107: else if (GET_CODE (X) == REG) \
108: fprintf (FILE, "%s", reg_names[REGNO (X)]); \
109: else if (GET_CODE (X) == MEM) \
110: { \
111: rtx xfoo; \
112: xfoo = XEXP (X, 0); \
113: switch (GET_CODE (xfoo)) \
114: { \
115: case MEM: \
116: if (GET_CODE (XEXP (xfoo, 0)) == REG) \
117: if (REGNO (XEXP (xfoo, 0)) == STACK_POINTER_REGNUM) \
118: fprintf (FILE, "0(0(sp))"); \
119: else fprintf (FILE, "0(0(%s))", \
120: reg_names[REGNO (XEXP (xfoo, 0))]); \
121: else \
122: { \
123: extern int paren_base_reg_printed; \
124: fprintf (FILE, "0("); \
125: paren_base_reg_printed = 0; \
126: output_address (xfoo); \
127: if (!paren_base_reg_printed) \
128: fprintf (FILE, "(sb)"); \
129: putc (')', FILE); \
130: } \
131: break; \
132: case REG: \
133: fprintf (FILE, "0(%s)", reg_names[REGNO (xfoo)]); \
134: break; \
135: case PRE_DEC: \
136: case POST_INC: \
137: fprintf (FILE, "tos"); \
138: break; \
139: case CONST_INT: \
140: fprintf (FILE, "@%d", INTVAL (xfoo)); \
141: break; \
142: default: \
143: output_address (xfoo); \
144: break; \
145: } \
146: } \
147: else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode) \
148: if (GET_MODE (X) == DFmode) \
149: { union { double d; int i[2]; } u; \
150: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
151: fprintf (FILE, "$0l%.20e", u.d); } \
152: else { union { double d; int i[2]; } u; \
153: u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
154: fprintf (FILE, "$0f%.20e", u.d); } \
155: else if (GET_CODE (X) == CONST) \
156: output_addr_const (FILE, X); \
157: else { putc ('$', FILE); output_addr_const (FILE, X); }}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.