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