home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / gcc-2.5.8-src.lha / src / amiga / gcc-2.5.8 / config / h8300 / h8300.c next >
Encoding:
C/C++ Source or Header  |  1993-08-15  |  19.7 KB  |  949 lines

  1. /* Subroutines for insn-output.c for Hitachi H8/300.
  2.    Copyright (C) 1992,1993 Free Software Foundation, Inc.
  3.  
  4.    Contributed by Steve Chamberlain (sac@cygnus.com) and
  5.    Jim Wilson (wilson@cygnus.com).
  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. You should have received a copy of the GNU General Public License
  20. along with GNU CC; see the file COPYING.  If not, write to
  21. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  22.  
  23. #include <stdio.h>
  24. #include "config.h"
  25. #include "rtl.h"
  26. #include "regs.h"
  27. #include "hard-reg-set.h"
  28. #include "real.h"
  29. #include "insn-config.h"
  30. #include "conditions.h"
  31. #include "insn-flags.h"
  32. #include "output.h"
  33. #include "insn-attr.h"
  34. #include "flags.h"
  35. #include "recog.h"
  36. #include "expr.h"
  37. #include "tree.h"
  38.  
  39. /* Forward declarations.  */
  40. void print_operand_address ();
  41. char *index ();
  42.  
  43. /* True if a #pragma interrupt has been seen for the current function.  */
  44. int pragma_interrupt;
  45.  
  46. /* True if a #pragma saveall has been seen for the current function.  */
  47. int pragma_saveall;
  48.  
  49. char *names_big[] 
  50.  = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
  51.  
  52. char *
  53. byte_reg (x, b)
  54.      rtx x;
  55.      int b;
  56. {
  57.   static char *names_small[] 
  58.     =  {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
  59.     "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7lBAD", "r7hBAD"};
  60.  
  61.   return names_small[REGNO (x) * 2 + b];
  62. }
  63.  
  64. /* REGNO must be saved/restored across calls if this macro is true.  */
  65. static int 
  66. word_reg_used (regno)
  67. int regno;
  68. {
  69.   if (regno < 7  
  70.       && (pragma_interrupt || pragma_saveall 
  71.       || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno])
  72.       || (regs_ever_live[regno] & ! call_used_regs[regno])))
  73.     return 1;
  74.   return 0;
  75. }
  76.  
  77. /* Output assembly language to FILE for the operation OP with operand size
  78.    SIZE.  */
  79. static void
  80. dosize (file, op, size, fped)
  81.      FILE *file;
  82.      char *op;
  83.      unsigned int size;
  84.      int fped;
  85. {
  86.   switch (size)
  87.     {
  88.     case 4:
  89.     case 3:
  90.       fprintf (file, "\t%ss\t#%d,sp\n", op, 2);
  91.       size -= 2;
  92.       /* Fall through...  */
  93.     case 2:
  94.     case 1:
  95.       fprintf (file, "\t%ss\t#%d,sp\n", op, size);
  96.       size = 0;
  97.       break;
  98.     case 0:
  99.       break;
  100.     default:
  101.       fprintf (file, "\tmov.w\t#%d,r5\n\t%s.w\tr5,sp\n", size, op);
  102.       size = 0;
  103.       break;
  104.     }
  105. }
  106.  
  107. /* Output assembly language code for the function prologue.  */
  108. static int push_order[FIRST_PSEUDO_REGISTER] 
  109.   = {6, 5, 4, 3, 2, 1, 0, -1, -1};
  110. static int pop_order[FIRST_PSEUDO_REGISTER] 
  111.   = {0, 1, 2, 3, 4, 5, 6, -1, -1};
  112.  
  113. /* This is what the stack looks like after the prolog of 
  114.    a function with a frame has been set up:
  115.  
  116.     <pushed args>
  117.     return pc
  118.    fp->    old fp
  119.        <locals>
  120.     <saved register-0> 
  121.     <saved register-1> 
  122.    sp->    <saved register-n>
  123.  
  124.  
  125.    This is what the stack looks like after the prolog of
  126.    a function which doesn't have a frame:
  127.  
  128.        <pushed args>
  129.        return pc
  130.     <locals>
  131.     <saved register-0>
  132.    sp-> <saved register-n>
  133. */
  134.  
  135. void
  136. function_prologue (file, size)
  137.      FILE *file;
  138.      int size;
  139. {
  140.   register int mask = 0;
  141.   int fsize = (size + 1) & -2;
  142.   int idx;
  143.  
  144.   if (frame_pointer_needed)
  145.     {
  146.       /* Push the fp.  */
  147.       fprintf (file, "\tpush\t%s\n", names_big[FRAME_POINTER_REGNUM]);
  148.       fprintf (file, "\tmov.w\tr7,r6\n");
  149.  
  150.       /* Leave room for the locals.  */
  151.       dosize (file, "sub", fsize, 1);
  152.  
  153.       /* Push the rest of the registers.  */
  154.       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) 
  155.     {
  156.       int regno = push_order[idx];
  157.  
  158.       if (regno >= 0 && word_reg_used (regno)
  159.           && regno != FRAME_POINTER_REGNUM)
  160.         fprintf (file, "\tpush\t%s\n", names_big[regno]);
  161.     }
  162.     }
  163.   else
  164.     {
  165.       dosize (file, "sub", fsize, 0);
  166.       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
  167.     {
  168.       int regno = push_order[idx];
  169.  
  170.       if (regno >= 0 && word_reg_used (regno))
  171.         fprintf (file, "\tpush\t%s\n", names_big[regno]);
  172.     }
  173.     }
  174. }
  175.  
  176. /* Output assembly language code for the function epilogue.  */
  177.  
  178. void
  179. function_epilogue (file, size)
  180.      FILE *file;
  181.      int size;
  182. {
  183.   register int regno;
  184.   register int mask = 0;
  185.   int fsize = (size + 1) & -2;
  186.   int nregs;
  187.   int offset;
  188.   int idx;
  189.   rtx insn = get_last_insn ();
  190.  
  191.   /* If the last insn was a BARRIER, we don't have to write any code.  */
  192.   if (GET_CODE (insn) == NOTE)
  193.     insn = prev_nonnote_insn (insn);
  194.   if (insn && GET_CODE (insn) == BARRIER)
  195.     return;
  196.  
  197.   nregs = 0;
  198.  
  199.   if (frame_pointer_needed)
  200.     {
  201.       /* Pop saved registers.  */
  202.       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
  203.     {
  204.       regno = pop_order[idx];
  205.       if (regno >= 0 && regno != FRAME_POINTER_REGNUM
  206.           && word_reg_used (regno))
  207.         fprintf (file, "\tpop\t%s\n", names_big[regno]);
  208.     }
  209.       /* Deallocate locals.  */
  210.       dosize (file, "add", fsize, 1);
  211.       /* Pop frame pointer.  */
  212.       fprintf (file, "\tpop\t%s\n", names_big[FRAME_POINTER_REGNUM]);
  213.     }
  214.   else
  215.     {
  216.       /* Deallocate locals and pop saved registers.  */
  217.       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
  218.     {
  219.       regno = pop_order[idx];
  220.       if (regno >= 0 && word_reg_used (regno))
  221.         fprintf (file, "\tpop\t%s\n", names_big[regno]);
  222.     }
  223.       dosize (file, "add", fsize, 0);
  224.     }
  225.   if (pragma_interrupt)
  226.     fprintf (file, "\trte\n");
  227.   else
  228.     fprintf (file, "\trts\n");
  229.  
  230.   pragma_interrupt = 0;
  231.   pragma_saveall = 0;
  232. }
  233.  
  234. /* Return true if VALUE is a valid constant for constraint 'P'.  */
  235.  
  236. int
  237. potl8 (value)
  238. {
  239.   switch (value)
  240.     {
  241.     case 1:
  242.     case 2:
  243.     case 4:
  244.     case 8:
  245.     case 16:
  246.     case 32:
  247.     case 64:
  248.     case 128:
  249.       return 1;
  250.     }
  251.   return 0;
  252. }
  253.  
  254. /* Return true if VALUE is a valid constant for constraint 'O'.  */
  255. int
  256. potg8 (value)
  257.      int value;
  258. {
  259.   switch (value)
  260.     {
  261.     case 256:
  262.     case 512:
  263.     case 1024:
  264.     case 2048:
  265.     case 4096:
  266.     case 8192:
  267.     case 16384:
  268.     case 32768:
  269.       return 1;
  270.     }
  271.   return 0;
  272. }
  273.  
  274. /* Return true is OP is a valid source operand for an integer move
  275.    instruction.  */
  276. int
  277. general_operand_src (op, mode)
  278.      rtx op;
  279.      enum machine_mode mode;
  280. {
  281.   /* We can't have a pre-dec as a source.  */
  282.   if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
  283.     return 0;
  284.   return general_operand (op, mode);
  285. }
  286.  
  287. /* Return true if OP is a valid destination operand for an integer move
  288.    instruction.  */
  289. int
  290. general_operand_dst (op, mode)
  291.      rtx op;
  292.      enum machine_mode mode;
  293. {
  294.   /* We can't have a post-inc as a dest.  */
  295.   if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
  296.     return 0;
  297.   return general_operand (op, mode);
  298. }
  299.  
  300. /* Handle machine specific pragmas for compatibility with existing
  301.    compilers for the H8/300
  302.  
  303.    pragma saveall generates prolog/epilog code which saves and
  304.    restores all the registers on function entry.
  305.    
  306.    pragma interrupt saves and restores all registers, and exits with
  307.    an rte instruction rather than an rts.  A pointer to a function
  308.    with this attribute may be safely used in an interrupt vector.  */
  309. int
  310. handle_pragma (file)
  311.      FILE *file;
  312. {
  313.   int c;
  314.   char pbuf[20];
  315.   int psize;
  316.  
  317.   c = getc (file);
  318.   while (c == ' ' || c == '\t')
  319.     c = getc (file);
  320.  
  321.   if (c == '\n' || c == EOF)
  322.     return c;
  323.  
  324.   for (psize = 0; psize < sizeof (pbuf) - 1 && isalpha (c); psize++)
  325.     {
  326.       pbuf[psize] = c;
  327.       c = getc (file);
  328.     }
  329.  
  330.   pbuf[psize] = 0;
  331.  
  332.   if (strcmp (pbuf, "interrupt") == 0)
  333.     pragma_interrupt = 1;
  334.  
  335.   if (strcmp (pbuf, "saveall") == 0)
  336.     pragma_saveall = 1;
  337.  
  338.   return c;
  339. }
  340.  
  341. /* If the next arg with MODE and TYPE is to be passed in a register, return
  342.    the rtx to represent where it is passed.  CUM represents the state after
  343.    the last argument.  NAMED is not used.  */
  344.  
  345. rtx
  346. function_arg (cum, mode, type, named)
  347.      CUMULATIVE_ARGS *cum;
  348.      enum machine_mode mode;
  349.      tree type;
  350.      int named;
  351. {
  352.   rtx result = 0;
  353.   int libcall = 0;
  354.  
  355.   /* Right now reload has a problem with reg passing with small reg
  356.      classes.  */
  357.  
  358.   if (cum->libcall || (named && TARGET_QUICKCALL))
  359.     libcall = 1;
  360.  
  361.   if (TARGET_NOQUICK)
  362.     libcall = 0;
  363.  
  364.   if (mode != VOIDmode && libcall && mode != DFmode && mode != SFmode)
  365.     {
  366.       switch (cum->nbytes)
  367.     {
  368.     case 0:
  369.       result = gen_rtx (REG, mode, 0);
  370.       break;
  371.     case 2:
  372.       result = gen_rtx (REG, mode, 1);
  373.       break;
  374.     case 4:
  375.       result = gen_rtx (REG, mode, 4);
  376.       break;
  377.     case 6:
  378.       result = gen_rtx (REG, mode, 5);
  379.       break;
  380.     default:
  381.       return 0;
  382.     }
  383.     }
  384.   return result;
  385. }
  386.  
  387. /* Documentation for the machine specific operand escapes:
  388.  
  389.    'C' print (operand - 2).
  390.    'E' low byte of reg or -ve lsb of constant
  391.    'F' high byte of reg of -ve  msb of constant
  392.  
  393.    'G' negate constant
  394.    'L' fake label, changed after used twice.
  395.    'M' turn a 'M' constant into its negative mod 2.
  396.    'T' print operand as a word
  397.    'V' print log2 of constant - used for bset instructions
  398.    'X' 8 bit register or other operand
  399.  
  400.    'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
  401.    'Z' print int & 7
  402.  
  403.    'e' first word of 32 bit value
  404.    'f' second word of 32 bit value
  405.  
  406.    'j' print operand as condition code.
  407.    'k' print operand as reverse condition code.
  408.  
  409.    's' low byte of 16 bit value
  410.    't' high byte of 16 bit value
  411.  
  412.    'w' 1st byte of 32 bit value           zzzzzzzz yyyyyyyy xxxxxxxx wwwwwwww
  413.    'x' 2nd byte of 32 bit value
  414.    'y' 3rd byte of 32 bit value
  415.    'z' 4th byte of 32 bit value
  416.  
  417.  */
  418.  
  419. /* Return assembly language string which identifies a comparison type.  */
  420.  
  421. char *
  422. cond_string (code)
  423.      enum rtx_code code;
  424. {
  425.   switch (code)
  426.     {
  427.     case NE:
  428.       return "ne";
  429.     case EQ:
  430.       return "eq";
  431.     case GE:
  432.       return "ge";
  433.     case GT:
  434.       return "gt";
  435.     case LE:
  436.       return "le";
  437.     case LT:
  438.       return "lt";
  439.     case GEU:
  440.       return "hs";
  441.     case GTU:
  442.       return "hi";
  443.     case LEU:
  444.       return "ls";
  445.     case LTU:
  446.       return "lo";
  447.     default:
  448.       abort ();
  449.     }
  450. }
  451.  
  452. /* Print operand X using operand code CODE to assembly language output file
  453.    FILE.  */
  454.  
  455. void
  456. print_operand (file, x, code)
  457.      FILE *file;
  458.      rtx x;
  459.      int code;
  460. {
  461.   /* This is used to general unique labels for the 'L' code.  */
  462.   static int lab = 1000;
  463.  
  464.   /* This is used for communication between the 'P' and 'U' codes.  */
  465.   static char *last_p;
  466.  
  467.   /* This is used for communication between the 'Z' and 'Y' codes.  */
  468.   static int bitint;
  469.  
  470.   switch (code)
  471.     {
  472.     case 'L':
  473.       /* 'L' must always be used twice in a single pattern.  It generates
  474.      the same lable twice, and then will generate a unique label the
  475.      next time it is used.  */
  476.       asm_fprintf (file, "tl%d", (lab++) / 2);
  477.       break;
  478.  
  479.     case 'X':
  480.       if (GET_CODE (x) == REG)
  481.     fprintf (file, "%s", byte_reg (x, 0));
  482.       else
  483.     goto def;
  484.       break;
  485.  
  486.     case 'G':
  487.       if (GET_CODE (x) != CONST_INT)
  488.     abort ();
  489.       fprintf (file, "#%d", 0xff & (-INTVAL (x)));
  490.       break;
  491.  
  492.     case 'T':
  493.       if (GET_CODE (x) == REG)
  494.     fprintf (file, "%s", names_big[REGNO (x)]);
  495.       else
  496.     goto def;
  497.       break;
  498.  
  499.     case 'w':
  500.       if (GET_CODE (x) == CONST_INT)
  501.     fprintf (file, "#%d", INTVAL (x) & 0xff);
  502.       else
  503.     fprintf (file, "%s", byte_reg (x, 2));
  504.       break;
  505.  
  506.     case 'x':
  507.       if (GET_CODE (x) == CONST_INT)
  508.     fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
  509.       else
  510.     fprintf (file, "%s", byte_reg (x, 3));
  511.       break;
  512.  
  513.     case 'y':
  514.       if (GET_CODE (x) == CONST_INT)
  515.     fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
  516.       else
  517.     fprintf (file, "%s", byte_reg (x, 0));
  518.       break;
  519.  
  520.     case 'z':
  521.       if (GET_CODE (x) == CONST_INT)
  522.     fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
  523.       else
  524.     fprintf (file, "%s", byte_reg (x, 1));
  525.       break;
  526.  
  527.       /* FOR 16 bits.  */
  528.     case 't':
  529.       if (GET_CODE (x) == CONST_INT)
  530.     fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
  531.       else
  532.     fprintf (file, "%s", byte_reg (x, 1));
  533.       break;
  534.  
  535.     case 's':
  536.       if (GET_CODE (x) == CONST_INT)
  537.     fprintf (file, "#%d", (INTVAL (x)) & 0xff);
  538.       else
  539.     fprintf (file, "%s", byte_reg (x, 0));
  540.       break;
  541.  
  542.     case 'u':
  543.       if (GET_CODE (x) != CONST_INT)
  544.     abort ();
  545.       fprintf (file, "%d", INTVAL (x));
  546.       break;
  547.  
  548.     case 'Z':
  549.       bitint = INTVAL (x);
  550.       fprintf (file, "#%d", bitint & 7);
  551.       break;
  552.  
  553.     case 'Y':
  554.       fprintf (file, "%c", bitint > 7 ? 'h' : 'l');
  555.       break;
  556.  
  557.     case 'O':
  558.       bitint = exact_log2 ((~INTVAL (x)) & 0xff);
  559.       if (bitint == -1)
  560.     abort ();
  561.       fprintf (file, "#%d", bitint & 7);
  562.       break;
  563.  
  564.     case 'V':
  565.       bitint = exact_log2 (INTVAL (x));
  566.       if (bitint == -1)
  567.     abort ();
  568.       fprintf (file, "#%d", bitint & 7);
  569.       break;
  570.  
  571.     case 'P':
  572.       if (REGNO (XEXP (XEXP (x, 0), 0)) == STACK_POINTER_REGNUM)
  573.     {
  574.       last_p = "";
  575.       fprintf (file, ".w");
  576.     }
  577.       else
  578.     {
  579.       last_p = "l";
  580.       fprintf (file, ".b");
  581.     }
  582.       break;
  583.  
  584.     case 'U':
  585.       fprintf (file, "%s%s", names_big[REGNO (x)], last_p);
  586.       break;
  587.  
  588.     case 'M':
  589.       /* For -4 and -2, the other 2 is handled separately.  */
  590.       switch (INTVAL (x))
  591.     {
  592.     case -2:
  593.     case -4:
  594.       fprintf (file, "#2");
  595.       break;
  596.     case -1:
  597.     case -3:
  598.       fprintf (file, "#1");
  599.       break;
  600.  
  601.     default:
  602.       abort ();
  603.     }
  604.       break;
  605.  
  606.     case 'e':
  607.       switch (GET_CODE (x))
  608.     {
  609.     case REG:
  610.       fprintf (file, "%s", names_big[REGNO (x)]);
  611.       break;
  612.     case MEM:
  613.       x = adj_offsettable_operand (x, 0);
  614.       print_operand (file, x, 0);
  615.       break;
  616.     case CONST_INT:
  617.       fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
  618.       break;
  619.     default:
  620.       abort ();
  621.       break;
  622.     }
  623.       break;
  624.  
  625.     case 'f':
  626.       switch (GET_CODE (x))
  627.     {
  628.     case REG:
  629.       fprintf (file, "%s", names_big[REGNO (x) + 1]);
  630.       break;
  631.  
  632.     case MEM:
  633.       x = adj_offsettable_operand (x, 2);
  634.       print_operand (file, x, 0);
  635.       break;
  636.  
  637.     case CONST_INT:
  638.       fprintf (file, "#%d", INTVAL (x) & 0xffff);
  639.       break;
  640.  
  641.     default:
  642.       abort ();
  643.     }
  644.       break;
  645.  
  646.     case 'C':
  647.       fprintf (file, "#%d", INTVAL (x) - 2);
  648.       break;
  649.  
  650.     case 'E':
  651.       switch (GET_CODE (x))
  652.     {
  653.     case REG:
  654.       fprintf (file, "%sl", names_big[REGNO (x)]);
  655.       break;
  656.  
  657.     case CONST_INT:
  658.       fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
  659.       break;
  660.  
  661.     default:
  662.       abort ();
  663.     }
  664.       break;
  665.  
  666.     case 'F':
  667.       switch (GET_CODE (x))
  668.     {
  669.     case REG:
  670.       fprintf (file, "%sh", names_big[REGNO (x)]);
  671.       break;
  672.  
  673.     case CONST_INT:
  674.       fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
  675.       break;
  676.  
  677.     default:
  678.       abort ();
  679.     }
  680.       break;
  681.  
  682.     case 'j':
  683.       asm_fprintf (file, cond_string (GET_CODE (x)));
  684.       break;
  685.  
  686.     case 'k':
  687.       asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
  688.       break;
  689.     def: ;
  690.     default:
  691.       switch (GET_CODE (x))
  692.     {
  693.     case REG:
  694.       fprintf (file, "%s", names_big[REGNO (x)]);
  695.       break;
  696.  
  697.     case MEM:
  698.       fprintf (file, "@");
  699.       output_address (XEXP (x, 0));
  700.       break;
  701.  
  702.     case CONST_INT:
  703.     case SYMBOL_REF:
  704.     case CONST:
  705.     case LABEL_REF:
  706.       fprintf (file, "#");
  707.       print_operand_address (file, x);
  708.       break;
  709.     }
  710.     }
  711. }
  712.  
  713. /* Output assembly language output for the address ADDR to FILE.  */
  714.  
  715. void
  716. print_operand_address (file, addr)
  717.      FILE *file;
  718.      rtx addr;
  719. {
  720.   switch (GET_CODE (addr))
  721.     {
  722.     case REG:
  723.       fprintf (file, "%s", names_big[REGNO (addr)]);
  724.       break;
  725.  
  726.     case PRE_DEC:
  727.       fprintf (file, "-%s", names_big[REGNO (XEXP (addr, 0))]);
  728.       break;
  729.  
  730.     case POST_INC:
  731.       fprintf (file, "%s+", names_big[REGNO (XEXP (addr, 0))]);
  732.       break;
  733.  
  734.     case PLUS:
  735.       fprintf (file, "(");
  736.       if (GET_CODE (XEXP (addr, 0)) == REG)
  737.     {
  738.       /* reg,foo */
  739.       print_operand_address (file, XEXP (addr, 1));
  740.       fprintf (file, ",");
  741.       print_operand_address (file, XEXP (addr, 0));
  742.     }
  743.       else
  744.     {
  745.       /* foo+k */
  746.       print_operand_address (file, XEXP (addr, 0));
  747.       fprintf (file, "+");
  748.       print_operand_address (file, XEXP (addr, 1));
  749.     }
  750.       fprintf (file, ")");
  751.       break;
  752.  
  753.     case CONST_INT:
  754.       if (INTVAL (addr) < 0)
  755.     {
  756.       int v = -INTVAL (addr);
  757.  
  758.       fprintf (file, "-%d", v);
  759.     }
  760.       else
  761.     fprintf (file, "%d", INTVAL (addr));
  762.       break;
  763.  
  764.     default:
  765.       output_addr_const (file, addr);
  766.       break;
  767.     }
  768. }
  769.  
  770. /* Output to FILE a reference to the user-level label NAME.
  771.    Strip off the section name if any.  It is separated from the label name
  772.    by a space.  */
  773.  
  774. void
  775. asm_output_labelref (file, name)
  776.      FILE *file;
  777.      char *name;
  778. {
  779.   char *p;
  780.  
  781.   fputc ('_', file);
  782.  
  783.   for (p = name; *p; p++)
  784.     {
  785.       if (*p == ' ')
  786.     {
  787.       /* If we found a space in the name, then we've skipped over the
  788.          section encoding.  */
  789.       fputs (p + 1, file);
  790.       return;
  791.     }
  792.     }
  793.  
  794.   /* No space, so no section.  */
  795.   fputs (name, file);
  796. }
  797.  
  798. /* Output all insn addresses and their sizes into the assembly language
  799.    output file.  This is helpful for debugging whether the length attributes
  800.    in the md file are correct.  This is not meant to be a user selectable
  801.    option.  */
  802.  
  803. void
  804. final_prescan_insn (insn, operand, num_operands)
  805.      rtx insn, *operand;
  806.      int num_operands;
  807. {
  808.   /* This holds the last insn address.  */
  809.   static int last_insn_address = 0;
  810.  
  811.   int uid = INSN_UID (insn);
  812.  
  813.   if (TARGET_ADDRESSES)
  814.     {
  815.       fprintf (asm_out_file, "; %d %d\n", insn_addresses[uid],
  816.            insn_addresses[uid] - last_insn_address);
  817.       last_insn_address = insn_addresses[uid];
  818.     }
  819. }
  820.  
  821. static void
  822. shift_n_bits (lval, operand, f, notzero)
  823.      rtx lval;
  824.      rtx operand;
  825.      rtx (*f) ();
  826.      int notzero;
  827. {
  828.   rtx label = gen_label_rtx ();
  829.   rtx bot = gen_label_rtx ();
  830.  
  831.   if (! notzero)
  832.     {
  833.       /* Have to put a zero test at the top.  */
  834.       emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, lval));
  835.       emit_jump_insn (gen_beq (bot));
  836.     }
  837.   emit_label (label);
  838.   f (operand);
  839.   emit_insn (gen_rtx (SET, QImode, lval,
  840.               gen_rtx (MINUS, QImode, lval, const1_rtx)));
  841.   emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, lval));
  842.   emit_jump_insn (gen_bne (label));
  843.  
  844.   emit_label (bot);
  845.   /* We can't end an expand with a label.  */
  846.   emit_move_insn (operand, operand);
  847. }
  848.  
  849. int
  850. can_shift (code, operands, f, limit, fby_eight)
  851.      int code;
  852.      rtx operands[];
  853.      rtx (*f) ();
  854.      int limit;
  855.      rtx (*fby_eight) ();
  856. {
  857.   extern int rtx_equal_function_value_matters;
  858.  
  859.   emit_move_insn (operands[0], operands[1]);
  860.  
  861.   if (GET_CODE (operands[2]) != CONST_INT)
  862.     {
  863.       rtx lval;
  864.  
  865.       /* Can't define expand a loop after rtl generation.  */
  866.       if (! rtx_equal_function_value_matters)
  867.     return 0;
  868.  
  869.       lval = gen_reg_rtx (QImode);
  870.  
  871.       convert_move (lval, operands[2], 1);
  872.       shift_n_bits (lval, operands[0], f, 0);
  873.     }
  874.   else
  875.     {
  876.       int i;
  877.  
  878.       i = INTVAL (operands[2]);
  879.       if (i >= 8 && fby_eight)
  880.     {
  881.       fby_eight (operands[0]);
  882.       i -= 8;
  883.     }
  884.       if (i > limit)
  885.     {
  886.       rtx lval;
  887.  
  888.       /* Can't define expand a loop after rtl generation.  */
  889.       if (! rtx_equal_function_value_matters)
  890.         return 0;
  891.       lval = gen_reg_rtx (QImode);
  892.       emit_move_insn (lval, gen_rtx (CONST_INT, VOIDmode, i));
  893.       shift_n_bits (lval, operands[0], f, 1);
  894.     }
  895.       else
  896.     {
  897.       while (i--)
  898.         f (operands[0]);
  899.     }
  900.     }
  901.   return 1;
  902. }
  903.  
  904. int
  905. domovsi (operands)
  906.      rtx operands[];
  907. {
  908.   rtx src = operands[1];
  909.   rtx dst = operands[0];
  910.  
  911.   if (push_operand (dst, GET_MODE (dst)))
  912.     {
  913.       /* Source must be a reg.  */
  914.       if (! REG_P (src))
  915.     {
  916.       rtx tmp = gen_reg_rtx (GET_MODE (dst));
  917.  
  918.       emit_move_insn (tmp, src);
  919.       operands[1] = tmp;
  920.     }
  921.     }
  922.   return 0;
  923. }
  924.  
  925. int
  926. io (FROM, TO)
  927. {
  928.   int OFFSET = 0;
  929.  
  930.   if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM)
  931.     (OFFSET) = 2 + frame_pointer_needed * 2;
  932.   else
  933.     {
  934.       int regno;
  935.       int offset = 0;
  936.  
  937.       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  938.     if ((regs_ever_live[regno]
  939.          && (! call_used_regs[regno] || regno == FRAME_POINTER_REGNUM)))
  940.       offset += 2;
  941.  
  942.       (OFFSET) = offset + get_frame_size ();
  943.  
  944.       if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)
  945.     (OFFSET) += 2;        /* Skip saved PC.  */
  946.     }
  947.   return OFFSET;
  948. }
  949.