home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gcc-2.7.2.1-base.tgz / gcc-2.7.2.1-base.tar / fsf / gcc / config / ns32k / merlin.h < prev    next >
C/C++ Source or Header  |  1995-06-15  |  8KB  |  232 lines

  1. /* Definitions of target machine for GNU compiler.  MERLIN NS32000 version.
  2.    Copyright (C) 1990, 1994 Free Software Foundation, Inc.
  3.    By Mark Mason (mason@reed.bitnet, pyramid!unify!mason@uunet.uu.net).
  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, 59 Temple Place - Suite 330,
  20. Boston, MA 02111-1307, USA.  */
  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 \
  50.     "-Dns32000 -Dns32k -Dns16000 -Dmerlin -Dunix -DUtek -Dbsd \
  51.     -Asystem(unix) -Asystem(bsd) -Acpu(ns32k) -Amachine(ns32k)"
  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.     }                                    \
  116.   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode)    \
  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)
  232.