home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / config / gmicro.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  21KB  |  984 lines

  1. /* Subroutines for insn-output.c for the Gmicro.
  2.    Ported by Masanobu Yuhara, Fujitsu Laboratories LTD.
  3.    (yuhara@flab.fujitsu.co.jp)
  4.  
  5.    Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  6.  
  7. This file is part of GNU CC.
  8.  
  9. GNU CC is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 2, or (at your option)
  12. any later version.
  13.  
  14. GNU CC is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. GNU General Public License for more details.
  18.  
  19. Among other things, the copyright
  20. notice and this notice must be preserved on all copies.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with GNU CC; see the file COPYING.  If not, write to
  24. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  25.  
  26.  
  27. #include <stdio.h>
  28. #include "config.h"
  29. #include "rtl.h"
  30. #include "regs.h"
  31. #include "hard-reg-set.h"
  32. #include "real.h"
  33. #include "insn-config.h"
  34. #include "conditions.h"
  35. #include "insn-flags.h"
  36. #include "output.h"
  37. #include "insn-attr.h"
  38.  
  39. extern char *rtx_name[];
  40.  
  41. mypr (s, a1, a2, a3, a4, a5)
  42.      char *s;
  43.      int a1, a2, a3, a4, a5;
  44. {
  45.   fprintf (stderr, s, a1, a2, a3, a4, a5);
  46. }
  47.  
  48. myprcode (i)
  49.      int i;
  50. {
  51.   if (i < 0 || i > 90)
  52.     fprintf (stderr, "code = %d\n", i);
  53.   else
  54.     fprintf (stderr, "code = %s\n", rtx_name[i]);
  55. }
  56.  
  57. myabort (i)
  58.      int i;
  59. {
  60.   fprintf (stderr, "myabort");
  61.   myprcode (i);
  62. }
  63.  
  64.  
  65. /* This is how to output an ascii string.  */
  66. /* See ASM_OUTPUT_ASCII in gmicro.h.  */
  67. output_ascii (file, p, size)
  68.      FILE *file;
  69.      char *p;
  70.      int size;
  71. {
  72.   int i;
  73.   int in_quote = 0;
  74.   register int c;
  75.  
  76.   fprintf (file, "\t.sdata ");
  77.  
  78.   for (i = 0; i < size; i++) 
  79.     {
  80.       c = p[i];
  81.       if (c >= ' ' && c < 0x7f) 
  82.     {
  83.       if (!in_quote) 
  84.         {
  85.           putc ('"', file);
  86.           in_quote = 1;
  87.         }
  88.       putc (c, file);
  89.     }
  90.       else 
  91.     {
  92.       if (in_quote) 
  93.         {
  94.           putc ('"', file);
  95.           in_quote = 0;
  96.         }
  97.       fprintf (file, "<%d>", c);
  98.     }
  99.     }
  100.   if (in_quote)
  101.     putc ('"', file);
  102.   putc ('\n', file);
  103. }
  104.  
  105.  
  106. /* call this when GET_CODE (index) is MULT. */
  107. print_scaled_index (file, index)
  108.      FILE *file;
  109.      register rtx index;
  110. {
  111.   register rtx ireg;
  112.   int scale;
  113.  
  114.   if (GET_CODE (XEXP (index, 0)) == REG) 
  115.     {
  116.       ireg = XEXP (index, 0);
  117.       scale = INTVAL (XEXP (index, 1));
  118.     }
  119.   else 
  120.     {
  121.       ireg = XEXP (index, 1);
  122.       scale = INTVAL (XEXP (index, 0));
  123.     }
  124.   if (scale == 1)
  125.     fprintf (file, "%s", reg_names[REGNO (ireg)]);
  126.   else
  127.     fprintf (file, "%s*%d", reg_names[REGNO (ireg)], scale);
  128. }
  129.     
  130.  
  131. print_operand_address (file, addr)
  132.      FILE *file;
  133.      register rtx addr;
  134. {
  135.   register rtx xtmp0, xtmp1, breg, ixreg;
  136.   int scale;
  137.   int needcomma = 0;
  138.   rtx offset;
  139.  
  140.   fprintf (file, "@");
  141.  retry:
  142.   switch (GET_CODE (addr)) 
  143.     {
  144.     case MEM:
  145.       fprintf (file, "@");
  146.       addr = XEXP (addr, 0);
  147.       goto retry;
  148.  
  149.     case REG:
  150.       fprintf (file, "%s", reg_names[REGNO (addr)]);
  151.       break;
  152.  
  153.     case MULT:
  154.       print_scaled_index (file, addr);
  155.       break;
  156.  
  157.     case PRE_DEC:
  158.       fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]);
  159.       break;
  160.  
  161.     case POST_INC:
  162.       fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]);
  163.       break;
  164.  
  165.     case PLUS:
  166.       xtmp0 = XEXP (addr, 0);
  167.       xtmp1 = XEXP (addr, 1);
  168.       ixreg = 0;    breg = 0;
  169.       offset = 0;
  170.       if (CONSTANT_ADDRESS_P (xtmp0)) 
  171.     {
  172.       offset = xtmp0;
  173.       breg = xtmp1;
  174.     }
  175.       else if (CONSTANT_ADDRESS_P (xtmp1)) 
  176.     {
  177.       offset = xtmp1;
  178.       breg = xtmp0;
  179.     }
  180.       else 
  181.     {
  182.       goto NOT_DISP;
  183.     }
  184.  
  185.       if (REG_CODE_BASE_P (breg))
  186.     goto PRINT_MEM;
  187.  
  188.       if (GET_CODE (breg) == MULT) 
  189.     {
  190.       if (REG_CODE_INDEX_P (XEXP (breg, 0))) 
  191.         {
  192.           ixreg = XEXP (breg, 0);
  193.           scale = INTVAL (XEXP (breg, 1));
  194.           breg = 0;
  195.         }
  196.       else 
  197.         {
  198.           ixreg = XEXP (breg, 1);
  199.           scale = INTVAL (XEXP (breg, 0));
  200.           breg = 0;
  201.         }
  202.       goto PRINT_MEM;
  203.     }
  204.  
  205.       /* GET_CODE (breg) must be PLUS here. */
  206.       xtmp0 = XEXP (breg, 0);
  207.       xtmp1 = XEXP (breg, 1);
  208.       if (REG_CODE_BASE_P (xtmp0)) 
  209.     {
  210.       breg = xtmp0;
  211.       xtmp0 = xtmp1;
  212.     }
  213.       else 
  214.     {
  215.       breg = xtmp1;
  216.       /* xtmp0 = xtmp0; */
  217.     }
  218.  
  219.       if (GET_CODE (xtmp0) == MULT) 
  220.     {
  221.       if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 
  222.         {
  223.           ixreg = XEXP (xtmp0, 0);
  224.           scale = INTVAL (XEXP (xtmp0, 1));
  225.         }
  226.       else 
  227.         {
  228.           ixreg = XEXP (xtmp0, 1);
  229.           scale = INTVAL (XEXP (xtmp0, 0));
  230.         }
  231.     }
  232.       else 
  233.     {
  234.       ixreg = xtmp0;
  235.       scale = 1;
  236.     }
  237.       goto PRINT_MEM;
  238.  
  239.     NOT_DISP:
  240.       if (REG_CODE_BASE_P (xtmp0)) 
  241.     {
  242.       breg = xtmp0;
  243.       xtmp0 = xtmp1;
  244.     }
  245.       else if (REG_CODE_BASE_P (xtmp1)) 
  246.     {
  247.       breg = xtmp1;
  248.       /* xtmp0 = xtmp0; */
  249.     }
  250.       else
  251.     goto NOT_BASE;
  252.     
  253.       if (REG_CODE_INDEX_P (xtmp0)) 
  254.     {
  255.       ixreg = xtmp0;
  256.       scale = 1;
  257.       goto PRINT_MEM;
  258.     }
  259.       else if (CONSTANT_ADDRESS_P (xtmp0)) 
  260.     {
  261.       offset = xtmp0;
  262.       goto PRINT_MEM;
  263.     }
  264.       else if (GET_CODE (xtmp0) == MULT) 
  265.     {
  266.       if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 
  267.         {
  268.           ixreg = XEXP (xtmp0, 0);
  269.           scale = INTVAL (XEXP (xtmp0, 1));
  270.         }
  271.       else 
  272.         {
  273.           ixreg = XEXP (xtmp0, 1);
  274.           scale = INTVAL (XEXP (xtmp0, 0));
  275.         }
  276.       goto PRINT_MEM;
  277.     }
  278.  
  279.       /* GET_CODE (xtmp0) must be PLUS. */
  280.       xtmp1 = XEXP (xtmp0, 1);
  281.       xtmp0 = XEXP (xtmp0, 0);
  282.  
  283.       if (CONSTANT_ADDRESS_P (xtmp0)) 
  284.     {
  285.       offset = xtmp0;
  286.       xtmp0 = xtmp1;
  287.     }
  288.       else 
  289.     {
  290.       offset = xtmp1;
  291.       /* xtmp0 = xtmp0; */
  292.     }
  293.  
  294.       if (REG_CODE_INDEX_P (xtmp0)) 
  295.     {
  296.       ixreg = xtmp0;
  297.     }
  298.       else 
  299.     {            /* GET_CODE (xtmp0) must be MULT. */
  300.       if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 
  301.         {
  302.           ixreg = XEXP (xtmp0, 0);
  303.           scale = INTVAL (XEXP (xtmp0, 1));
  304.         }
  305.       else 
  306.         {
  307.           ixreg = XEXP (xtmp0, 1);
  308.           scale = INTVAL (XEXP (xtmp0, 0));
  309.         }
  310.     }
  311.       goto PRINT_MEM;
  312.  
  313.     NOT_BASE:
  314.       if (GET_CODE (xtmp0) == PLUS) 
  315.     {
  316.       ixreg = xtmp1;
  317.       /* xtmp0 = xtmp0; */
  318.     }
  319.       else 
  320.     {
  321.       ixreg = xtmp0;
  322.       xtmp0 = xtmp1;
  323.     }
  324.  
  325.       if (REG_CODE_INDEX_P (ixreg)) 
  326.     {
  327.       scale = 1;
  328.     }
  329.       else if (REG_CODE_INDEX_P (XEXP (ixreg, 0))) 
  330.     {
  331.       scale = INTVAL (XEXP (ixreg, 1));
  332.       ixreg = XEXP (ixreg, 0);
  333.     }
  334.       else 
  335.     {            /* was else if with no condition. OK ??? */
  336.       scale = INTVAL (XEXP (ixreg, 0));
  337.       ixreg = XEXP (ixreg, 1);
  338.     }
  339.  
  340.       if (REG_CODE_BASE_P (XEXP (xtmp0, 0))) 
  341.     {
  342.       breg = XEXP (xtmp0, 0);
  343.       offset = XEXP (xtmp0, 1);
  344.     }
  345.       else 
  346.     {
  347.       breg = XEXP (xtmp0, 1);
  348.       offset = XEXP (xtmp0, 0);
  349.     }
  350.  
  351.     PRINT_MEM:
  352.       if (breg == 0 && ixreg == 0) 
  353.     {
  354.       output_address (offset);
  355.       break;
  356.     }
  357.       else if (ixreg == 0 && offset == 0) 
  358.     {
  359.       fprintf (file, "%s", reg_names[REGNO (breg)]);
  360.       break;
  361.     }
  362.       else 
  363.     {
  364.       fprintf (file, "(");
  365.       if (offset != 0) 
  366.         {
  367.           output_addr_const (file, offset);
  368.           needcomma = 1;
  369.         }
  370.       if (breg != 0) 
  371.         {
  372.           if (needcomma)
  373.         fprintf (file, ",");
  374.           fprintf (file, "%s", reg_names[REGNO (breg)]);
  375.           needcomma = 1;
  376.         }
  377.       if (ixreg != 0) 
  378.         {
  379.           if (needcomma)
  380.         fprintf (file, ",");
  381.           fprintf (file, "%s", reg_names[REGNO (ixreg)]);
  382.           if (scale != 1)
  383.         fprintf (file,"*%d", scale);
  384.         }
  385.       fprintf (file, ")");
  386.  
  387.       break;
  388.     }
  389.  
  390.     default:
  391.       output_addr_const (file, addr);
  392.     }
  393. }
  394.  
  395.  
  396.  
  397. /* Return a REG that occurs in ADDR with coefficient 1.
  398.    ADDR can be effectively incremented by incrementing REG.  */
  399.  
  400. static rtx
  401. find_addr_reg (addr)
  402.      rtx addr;
  403. {
  404.   while (GET_CODE (addr) == PLUS)
  405.     {
  406.       if (GET_CODE (XEXP (addr, 0)) == REG)
  407.     addr = XEXP (addr, 0);
  408.       else if (GET_CODE (XEXP (addr, 1)) == REG)
  409.     addr = XEXP (addr, 1);
  410.       else if (GET_CODE (XEXP (addr, 0)) == PLUS)
  411.     addr = XEXP (addr, 0);
  412.       else if (GET_CODE (XEXP (addr, 1)) == PLUS)
  413.     addr = XEXP (addr, 1);
  414.     }
  415.   if (GET_CODE (addr) == REG)
  416.     return addr;
  417.   return 0;
  418. }
  419.  
  420.  
  421.     /* Return the best assembler insn template
  422.     for moving operands[1] into operands[0] as a fullword.  */
  423.  
  424. static char *
  425. singlemove_string (operands)
  426.      rtx *operands;
  427. {
  428.   if (FPU_REG_P (operands[0]) || FPU_REG_P