|
|
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.