summaryrefslogtreecommitdiff
path: root/gcc/config/ns32k/genix.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/ns32k/genix.h')
-rwxr-xr-xgcc/config/ns32k/genix.h167
1 files changed, 167 insertions, 0 deletions
diff --git a/gcc/config/ns32k/genix.h b/gcc/config/ns32k/genix.h
new file mode 100755
index 0000000..ac84cfc
--- /dev/null
+++ b/gcc/config/ns32k/genix.h
@@ -0,0 +1,167 @@
+/* Definitions of target machine for GNU compiler. Genix ns32000 version.
+ Copyright (C) 1987, 1988, 1994 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "ns32k/encore.h"
+
+/* We don't want the one Encore needs. */
+#undef ASM_SPEC
+
+/* The following defines override ones in ns32k.h and prevent any attempts
+ to explicitly or implicitly make references to the SB register in the GCC
+ generated code. It is necessary to avoid such references under Genix V.3.1
+ because this OS doesn't even save/restore the SB on context switches! */
+
+#define IS_OK_REG_FOR_BASE_P(X) \
+ ( (GET_CODE (X) == REG) && REG_OK_FOR_BASE_P (X) )
+
+#undef INDIRECTABLE_1_ADDRESS_P
+#define INDIRECTABLE_1_ADDRESS_P(X) \
+ (CONSTANT_ADDRESS_NO_LABEL_P (X) \
+ || IS_OK_REG_FOR_BASE_P (X) \
+ || (GET_CODE (X) == PLUS \
+ && IS_OK_REG_FOR_BASE_P (XEXP (X, 0)) \
+ && CONSTANT_ADDRESS_P (XEXP (X, 1)) ) )
+
+/* Note that for double indirects, only FP, SP, and SB are allowed
+ as the inner-most base register. But we are avoiding use of SB. */
+
+#undef MEM_REG
+#define MEM_REG(X) \
+ ( (GET_CODE (X) == REG) \
+ && ( (REGNO (X) == FRAME_POINTER_REGNUM) \
+ || (REGNO (X) == STACK_POINTER_REGNUM) ) )
+
+#undef INDIRECTABLE_2_ADDRESS_P
+#define INDIRECTABLE_2_ADDRESS_P(X) \
+ (GET_CODE (X) == MEM \
+ && (((xfoo0 = XEXP (X, 0), MEM_REG (xfoo0)) \
+ || (GET_CODE (xfoo0) == PLUS \
+ && MEM_REG (XEXP (xfoo0, 0)) \
+ && CONSTANT_ADDRESS_NO_LABEL_P (XEXP (xfoo0, 1)))) \
+ || CONSTANT_ADDRESS_NO_LABEL_P (xfoo0)))
+
+/* Go to ADDR if X is a valid address not using indexing.
+ (This much is the easy part.) */
+#undef GO_IF_NONINDEXED_ADDRESS
+#define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \
+{ register rtx xfoob = (X); \
+ if (GET_CODE (xfoob) == REG) goto ADDR; \
+ if (INDIRECTABLE_1_ADDRESS_P(X)) goto ADDR; \
+ if (CONSTANT_P(X)) goto ADDR; \
+ if (INDIRECTABLE_2_ADDRESS_P (X)) goto ADDR; \
+ if (GET_CODE (X) == PLUS) \
+ if (CONSTANT_ADDRESS_NO_LABEL_P (XEXP (X, 1))) \
+ if (INDIRECTABLE_2_ADDRESS_P (XEXP (X, 0))) \
+ goto ADDR; \
+}
+
+/* A bug in the GNX 3.X assembler causes references to external symbols to
+ be mishandled if the symbol is also used as the name of a function-local
+ variable or as the name of a struct or union field. The problem only
+ appears when you are also using the -g option so that SDB debugging
+ directives are also being produced by GCC. In such cases, the assembler
+ gets the external entity confused with the local entity and addressing
+ havoc ensues. The solution is to get GCC to produce .global directives
+ for all external entities which are actually referenced within the current
+ source file. The following macro does this. */
+
+#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
+ ASM_GLOBALIZE_LABEL(FILE,NAME);
+
+/* Genix wants 0l instead of 0f. */
+
+#undef ASM_OUTPUT_DOUBLE
+#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
+ fprintf (FILE, "\t.long 0l%.20e\n", (VALUE))
+
+/* A bug in the GNX 3.X linker prevents symbol-table entries with a storage-
+ class field of C_EFCN (-1) from being accepted. */
+
+#ifdef PUT_SDB_EPILOGUE_END
+#undef PUT_SDB_EPILOGUE_END
+#endif
+#define PUT_SDB_EPILOGUE_END(NAME)
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (32000, National syntax)");
+
+/* Same as the encore definition except
+ * Different syntax for double constants.
+ * Don't output `?' before external regs.
+ * Output `(sb)' in certain indirect refs. */
+
+#error this has not been updated since version 1.
+#error it is certainly wrong.
+
+#undef PRINT_OPERAND
+#define PRINT_OPERAND(FILE, X, CODE) \
+{ if (CODE == '$') putc ('$', FILE); \
+ else if (CODE == '?'); \
+ else if (GET_CODE (X) == REG) \
+ fprintf (FILE, "%s", reg_names[REGNO (X)]); \
+ else if (GET_CODE (X) == MEM) \
+ { \
+ rtx xfoo; \
+ xfoo = XEXP (X, 0); \
+ switch (GET_CODE (xfoo)) \
+ { \
+ case MEM: \
+ if (GET_CODE (XEXP (xfoo, 0)) == REG) \
+ if (REGNO (XEXP (xfoo, 0)) == STACK_POINTER_REGNUM) \
+ fprintf (FILE, "0(0(sp))"); \
+ else fprintf (FILE, "0(0(%s))", \
+ reg_names[REGNO (XEXP (xfoo, 0))]); \
+ else \
+ { \
+ extern int paren_base_reg_printed; \
+ fprintf (FILE, "0("); \
+ paren_base_reg_printed = 0; \
+ output_address (xfoo); \
+ if (!paren_base_reg_printed) \
+ fprintf (FILE, "(sb)"); \
+ putc (')', FILE); \
+ } \
+ break; \
+ case REG: \
+ fprintf (FILE, "0(%s)", reg_names[REGNO (xfoo)]); \
+ break; \
+ case PRE_DEC: \
+ case POST_INC: \
+ fprintf (FILE, "tos"); \
+ break; \
+ case CONST_INT: \
+ fprintf (FILE, "@%d", INTVAL (xfoo)); \
+ break; \
+ default: \
+ output_address (xfoo); \
+ break; \
+ } \
+ } \
+ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode) \
+ if (GET_MODE (X) == DFmode) \
+ { union { double d; int i[2]; } u; \
+ u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
+ fprintf (FILE, "$0l%.20e", u.d); } \
+ else { union { double d; int i[2]; } u; \
+ u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
+ fprintf (FILE, "$0f%.20e", u.d); } \
+ else if (GET_CODE (X) == CONST) \
+ output_addr_const (FILE, X); \
+ else { putc ('$', FILE); output_addr_const (FILE, X); }}