home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gcc-2.4.5 / config / sh / sh.c next >
Encoding:
C/C++ Source or Header  |  1993-05-10  |  27.7 KB  |  1,270 lines

  1. /* Output routines for GCC for Hitachi Super-H
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. /* Contributed by Steve Chamberlain (sac@cygnus.com) */
  22.  
  23. #include <stdio.h>
  24. #include "assert.h"
  25. #include "config.h"
  26. #include "rtl.h"
  27. #include "regs.h"
  28. #include "hard-reg-set.h"
  29. #include "real.h"
  30. #include "insn-config.h"
  31. #include "conditions.h"
  32. #include "insn-flags.h"
  33. #include "tree.h"
  34. #include "output.h"
  35. #include "insn-attr.h"
  36. #include "flags.h"
  37. #include "obstack.h"
  38. #include "expr.h"
  39.  
  40.  
  41. static int add_constant ();
  42. static int dump_constants ();
  43.  
  44. int current_function_anonymous_args;
  45. extern int current_function_pretend_args_size;
  46.  
  47. /* Global variables for machine-dependent things. */
  48.  
  49. /* Saved operands from the last compare to use when we generate an scc
  50.   or bcc insn. */
  51.  
  52. rtx sh_compare_op0;
  53. rtx sh_compare_op1;
  54.  
  55. /* Provides the class number of the smallest class containing
  56.    reg number */
  57.  
  58. int regno_reg_class[FIRST_PSEUDO_REGISTER] =
  59. {
  60.   R0_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
  61.   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
  62.   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
  63.   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
  64.   GENERAL_REGS, PR_REGS, T_REGS, NO_REGS, MAC_REGS,
  65.   MAC_REGS,
  66. };
  67.  
  68. /* Provide reg_class from a letter such as appears in the machine
  69.    description. */
  70.  
  71. enum reg_class reg_class_from_letter[] =
  72. {
  73.   /* a */ NO_REGS, /* b */ NO_REGS, /* c */ NO_REGS, /* d */ NO_REGS,
  74.   /* e */ NO_REGS, /* f */ NO_REGS, /* g */ NO_REGS, /* h */ NO_REGS,
  75.   /* i */ NO_REGS, /* j */ NO_REGS, /* k */ NO_REGS, /* l */ PR_REGS,
  76.   /* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS,
  77.   /* q */ NO_REGS, /* r */ NO_REGS, /* s */ NO_REGS, /* t */ T_REGS,
  78.   /* u */ NO_REGS, /* v */ NO_REGS, /* w */ NO_REGS, /* x */ MAC_REGS,
  79.   /* y */ NO_REGS, /* z */ R0_REGS
  80. };
  81.  
  82.  
  83. /* Local label counter, used for constants in the pool and inside
  84.    pattern branches.  */
  85.  
  86. static int lf = 100;
  87.  
  88. /* Used to work out sizes of instructions */
  89. static int first_pc;
  90. static int pc;
  91. #define MAYBE_DUMP_LEVEL 900
  92. #define MUST_DUMP_LEVEL 1000
  93. static int dumpnext;
  94.  
  95. /* Functions for generating procedure prologue and epilogue code */
  96.  
  97. /* Adjust the stack and return the number of bytes taken to do it */
  98.  
  99. static int
  100. output_stack_adjust (file, direction, size)
  101.      FILE *file;
  102.      int direction;
  103.      int size;
  104. {
  105.   int code_size;
  106.  
  107.   if (size > 127)
  108.     {
  109.       fprintf (file, "\tmov.l    LK%d,r13\n",
  110.            add_constant (GEN_INT (size * direction), SImode));
  111.  
  112.       fprintf (file, "\tadd    r13,r15\n");
  113.       code_size += 4;
  114.     }
  115.   else if (size)
  116.     {
  117.       fprintf (file, "\tadd    #%d,r15\n", direction * size);
  118.       code_size += 2;
  119.     }
  120.   return code_size;
  121. }
  122.  
  123. /* Generate code to push the regs specified in the mask, and return
  124.    the number of bytes the insns take. */
  125.  
  126. static int
  127. push_regs (f, mask)
  128.      FILE *f;
  129.      int mask;
  130. {
  131.   int i;
  132.   int size = 0;
  133.  
  134.   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  135.     {
  136.       if (mask & (1 << i))
  137.     {
  138.       fprintf (f, "\tmov.l    r%d,@-r15\n", i);
  139.       size += 2;
  140.     }
  141.     }
  142.   return size;
  143. }
  144.  
  145.  
  146. /* Working out the right code to use for an epilogue can get quite
  147.    hairy, since there are only certain insns which can go in the delay
  148.    slot, and there may or may not be a delay insn provided already.
  149.  
  150.    We generate a canonical list of the instructions to use to perform
  151.    the exit, massage that and output from that list */
  152.  
  153.  
  154. /* The structure of a canonical element. */
  155.  
  156. typedef struct
  157. {
  158.   enum epi_type
  159.     {
  160.       STACK_ADJUST,        /* add i to stack pointer     */
  161.       POP,            /* pop into register i         */
  162.       RTS,            /* rts instruction         */
  163.       DELAY,            /* delay slot instruction     */
  164.       NOP,            /* a nop             */
  165.       DELETED,
  166.     } type;
  167.   int i;
  168. }
  169.  
  170. epilogue_insn;
  171.  
  172. static epilogue_insn epilogue_vec[20];
  173. static int epilogue_vec_len;
  174.  
  175. static void
  176. set_epilogue_insn (type, l)
  177.      enum epi_type type;
  178.      int l;
  179. {
  180.   epilogue_vec[epilogue_vec_len].type = type;
  181.   epilogue_vec[epilogue_vec_len].i = l;
  182.   epilogue_vec_len++;
  183. }
  184.  
  185. /* Delete an insn from the epilogue list. */
  186.  
  187. static void
  188. delete_epilogue_insn (n)
  189.      int n;
  190. {
  191.   int j;
  192.  
  193.   for (j = n; j < epilogue_vec_len; j++)
  194.     epilogue_vec[j] = epilogue_vec[j + 1];
  195.  
  196.   epilogue_vec_len--;
  197. }
  198.  
  199. /* Run through the epilogue list and optimize it. */
  200.  
  201. static void
  202. optimize_epilogue_vec ()
  203. {
  204.   int i;
  205.  
  206.   /* Turn two adds in a row into one add and kill empty adds */
  207.   for (i = 0; i < epilogue_vec_len - 1; i++)
  208.     {
  209.       if (epilogue_vec[i].type == STACK_ADJUST
  210.       && epilogue_vec[i + 1].type == STACK_ADJUST)
  211.     {
  212.       epilogue_vec[i].i += epilogue_vec[i + 1].i;
  213.       delete_epilogue_insn (i + 1);
  214.     }
  215.       if (epilogue_vec[i].type == STACK_ADJUST
  216.       && epilogue_vec[i].i == 0)
  217.     delete_epilogue_insn (i);
  218.     }
  219.  
  220.   /* If the instruction after the RTS is a nop, see if it can be
  221.      changed */
  222.  
  223.   for (i = 1; i < epilogue_vec_len - 1; i++)
  224.     {
  225.       if (epilogue_vec[i].type == RTS
  226.       && epilogue_vec[i + 1].type == NOP)
  227.     {
  228.       epilogue_vec[i + 1] = epilogue_vec[i - 1];
  229.       delete_epilogue_insn (i - 1);
  230.     }
  231.     }
  232.  
  233.   /* Delete all the instructions after the rts's delay slot */
  234.   for (i = 0; i < epilogue_vec_len; i++)
  235.     {
  236.       if (epilogue_vec[i].type == RTS)
  237.     {
  238.       int j;
  239.  
  240.       for (j = i + 2; j < epilogue_vec_len; j++)
  241.         epilogue_vec[j].type = DELETED;
  242.       return;
  243.     }
  244.     }
  245. }
  246.  
  247. /* Dump out the insns in epilogue vector. */
  248.  
  249. static void
  250. output_epilogue_vec ()
  251. {
  252.   int i;
  253.  
  254.   for (i = 0; i < epilogue_vec_len; i++)
  255.     {
  256.       switch (epilogue_vec[i].type)
  257.     {
  258.     case STACK_ADJUST:
  259.       fprintf (asm_out_file, "\tadd    #%d,r15\n", epilogue_vec[i].i);
  260.       break;
  261.  
  262.     case NOP:
  263.       fprintf (asm_out_file, "\tor    r0,r0\n");
  264.       break;
  265.  
  266.     case DELAY:
  267.       final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
  268.                asm_out_file, 1, 0, 1);
  269.       break;
  270.  
  271.     case DELETED:
  272.       fprintf (asm_out_file, "\t!delete_epilogue_insnd\n");
  273.       break;
  274.  
  275.     case RTS:
  276.       fprintf (asm_out_file, "\trts\n");
  277.       break;
  278.  
  279.     case POP:
  280.       fprintf (asm_out_file, "\tmov.l    @r15+,r%d\n",
  281.            epilogue_vec[i].i);
  282.       break;
  283.     }
  284.     }
  285.   epilogue_vec_len = 0;
  286. }
  287.  
  288. /* Number of bytes pushed for anonymous args */
  289.  
  290. static int extra_push;
  291.  
  292. /* Work out the registers which need to be saved, both as a mask and a
  293.    count */
  294.  
  295. int
  296. calc_live_regs (count)
  297.      int *count;
  298. {
  299.   int reg;
  300.   int live_regs_mask = 0;
  301.   *count = 0;
  302.  
  303.   for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
  304.     {
  305.       if (regs_ever_live[reg] && !call_used_regs[reg])
  306.     {
  307.       (*count)++;
  308.       live_regs_mask |= (1 << reg);
  309.     }
  310.     }
  311.   return live_regs_mask;
  312. }
  313.  
  314. /* Generate a procedure prologue.  */
  315.  
  316. void
  317. output_prologue (f, frame_size)
  318.      FILE *f;
  319.      int frame_size;
  320. {
  321.   int live_regs_mask;
  322.   int d;
  323.  
  324.   pc = 0;
  325.  
  326.   /* This only happens when an arg has been split, part in
  327.      registers, part in memory.  Allocate the stack space so there is
  328.      somewhere to put the value */
  329.  
  330.   output_stack_adjust (f, -1, current_function_pretend_args_size);
  331.  
  332.   live_regs_mask = calc_live_regs (&d);
  333.  
  334.   extra_push = 0;
  335.  
  336.   if (current_function_anonymous_args)
  337.     {
  338.       /* Push arg regs as if they'd been provided by caller in stack */
  339.       int i;
  340.       for (i = 0; i < NPARM_REGS; i++)
  341.     {
  342.       int rn = NPARM_REGS + FIRST_PARM_REG - i - 1;
  343.       if (i > NPARM_REGS - current_function_args_info)
  344.         break;
  345.       fprintf (f, "\tmov.l    r%d,@-r15\n", rn);
  346.       extra_push += 4;
  347.       pc += 2;
  348.     }
  349.     }
  350.  
  351.   if (frame_pointer_needed)
  352.     {
  353.       /* Don't need to push the fp with the rest of the registers. */
  354.       live_regs_mask &= ~(1 << FRAME_POINTER_REGNUM);
  355.       pc += push_regs (f, live_regs_mask);
  356.       if (regs_ever_live[PR_REG])
  357.     {
  358.  
  359.       fprintf (f, "\tsts.l    pr,@-r15\n");
  360.       pc += 2;
  361.     }
  362.  
  363.       fprintf (f, "\tmov.l    r14,@-r15\n");
  364.       fprintf (f, "\tmov    r15,r14\n");
  365.       pc += 4;
  366.       pc += output_stack_adjust (f, -1, frame_size);
  367.     }
  368.   else
  369.     {
  370.       pc += push_regs (f, live_regs_mask);
  371.  
  372.       if (regs_ever_live[PR_REG])
  373.     {
  374.  
  375.       fprintf (f, "\tsts.l    pr,@-r15\n");
  376.       pc += 2;
  377.     }
  378.       pc += output_stack_adjust (f, -1, frame_size);
  379.     }
  380. }
  381.  
  382.  
  383. /* Generate a procedure epilogue. */
  384.  
  385. void
  386. output_epilogue (f, frame_size)
  387.      FILE *f;
  388.      int frame_size;
  389. {
  390.   int live_regs_mask = 0;
  391.   int d;
  392.   int i;
  393.   rtx delay_insn;
  394.   
  395.   live_regs_mask = calc_live_regs (&d);
  396.  
  397.  
  398.   /* See if the delay insn is really ok for the slot. */
  399.   if (current_function_epilogue_delay_list) {
  400.     delay_insn = PATTERN (XEXP (current_function_epilogue_delay_list, 0));
  401.  
  402.   if (GET_CODE (delay_insn) == SET
  403.       && SET_DEST (delay_insn) == stack_pointer_rtx)
  404.     {
  405.       /* Can not use this instruction in the delay slot because
  406.      it changes the stack pointer, so emit it now.  */
  407.       final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
  408.                asm_out_file, 1, 0, 1);
  409.       current_function_epilogue_delay_list = 0;
  410.     }
  411.   }
  412.   
  413.  
  414.   /* Reclaim the room for the automatics. */
  415.  
  416.   output_stack_adjust (f, 1, frame_size);
  417.  
  418.   /* Make the frame pointer. */
  419.  
  420.   if (frame_pointer_needed)
  421.     {
  422.       fprintf (f, "\tmov    r14,r15\n");
  423.       fprintf (f, "\tmov.l    @r15+,r14\n");
  424.       live_regs_mask &= ~(1 << FRAME_POINTER_REGNUM);
  425.     }
  426.  
  427.   /* Get the PR register if it was clobbered in the function. */
  428.  
  429.   if (regs_ever_live[PR_REG])
  430.     fprintf (f, "\tlds.l    @r15+,pr\n");
  431.  
  432.   /* Pop all the registers */
  433.   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  434.     {
  435.       int j = (FIRST_PSEUDO_REGISTER - 1) - i;
  436.       if (live_regs_mask & (1 << j))
  437.     {
  438.       set_epilogue_insn (POP, j);
  439.     }
  440.     }
  441.  
  442.   /* Need to adjust the stack by some amount of bytes since we've pushed
  443.      some of the args which normally come in registers */
  444.  
  445.   set_epilogue_insn (STACK_ADJUST, extra_push);
  446.  
  447.   /* Need to adjust the stack by some amount of bytes if there
  448.      an arg has been split part register and part stack */
  449.  
  450.   set_epilogue_insn (STACK_ADJUST, current_function_pretend_args_size);
  451.  
  452.   set_epilogue_insn (RTS, 0);
  453.  
  454.   /* Got here without dumping a register pop into the delay slot */
  455.   if (current_function_epilogue_delay_list)
  456.     {
  457.       set_epilogue_insn (DELAY, 0);
  458.     }
  459.   set_epilogue_insn (NOP, 0);
  460.  
  461.   optimize_epilogue_vec ();
  462.  
  463.   output_epilogue_vec ();
  464.  
  465.   dump_constants (0);
  466.   current_function_anonymous_args = 0;
  467. }
  468.  
  469. /* Print the operand address in x to the stream */
  470.  
  471. void
  472. print_operand_address (stream, x)
  473.      FILE *stream;
  474.      rtx x;
  475. {
  476.   switch (GET_CODE (x))
  477.     {
  478.     case REG:
  479.       fprintf (stream, "@%s", reg_names[REGNO (x)]);
  480.       break;
  481.  
  482.     case PLUS:
  483.       {
  484.     rtx base = XEXP (x, 0);
  485.     rtx index = XEXP (x, 1);
  486.  
  487.     if (GET_CODE (base) != REG)
  488.       {
  489.         /* Ensure that BASE is a register (one of them must be). */
  490.         rtx temp = base;
  491.         base = index;
  492.         index = temp;
  493.       }
  494.  
  495.     switch (GET_CODE (index))
  496.       {
  497.       case CONST_INT:
  498.         fprintf (stream, "@(%d,%s)",
  499.              INTVAL (index),
  500.              reg_names[REGNO (base)]);
  501.         break;
  502.  
  503.       case REG:
  504.         fprintf (stream, "@(%s,%s)",
  505.              reg_names[REGNO (base)],
  506.              reg_names[REGNO (index)]);
  507.         break;
  508.  
  509.       default:
  510.         abort ();
  511.       }
  512.       }
  513.  
  514.       break;
  515.     case PRE_DEC:
  516.       fprintf (stream, "@-%s", reg_names[REGNO (XEXP (x, 0))]);
  517.       break;
  518.  
  519.     case POST_INC:
  520.       fprintf (stream, "@%s+", reg_names[REGNO (XEXP (x, 0))]);
  521.       break;
  522.  
  523.     default:
  524.       output_addr_const (stream, x);
  525.       break;
  526.     }
  527. }
  528.  
  529. /* Print operand x (an rtx) in assembler syntax to file stream
  530.    according to modifier code.
  531.  
  532.  '*'  print a local label
  533.  '^'  increment the local label number
  534.  '!'  dump the constant table
  535.  '#'  output a nop if there is nothing to put in the delay slot
  536.  'R'  print the next register or memory location along, ie the lsw in
  537.       a double word value
  538.  'I'  put something into the constant pool and print its label */
  539.  
  540. void
  541. print_operand (stream, x, code)
  542.      FILE *stream;
  543.      rtx x;
  544.      int code;
  545. {
  546.   switch (code)
  547.     {
  548.     case '*':
  549.       fprintf (stream, "LF%d", lf);
  550.       break;
  551.     case '!':
  552.       dump_constants (0);
  553.       break;
  554.     case '^':
  555.       lf++;
  556.       break;
  557.  
  558.     case '#':
  559.       /* Output a nop if there's nothing in the delay slot */
  560.       if (dbr_sequence_length () == 0)
  561.     {
  562.       fprintf (stream, "\n\tor    r0,r0\t!wasted slot");
  563.     }
  564.       break;
  565.  
  566.     case 'I':
  567.       fprintf (asm_out_file, "LK%d", add_constant (x, SImode));
  568.       break;
  569.  
  570.     case 'R':
  571.       /* Next location along in memory or register*/
  572.       switch (GET_CODE (x))
  573.     {
  574.     case REG:
  575.       fputs (reg_names[REGNO (x) + 1], (stream));
  576.       break;
  577.     case MEM:
  578.       print_operand_address (stream,
  579.                    XEXP (adj_offsettable_operand (x, 4), 0), 0);
  580.       break;
  581.     }
  582.       break;
  583.  
  584.     default:
  585.       switch (GET_CODE (x))
  586.     {
  587.     case REG:
  588.       fputs (reg_names[REGNO (x)], (stream));
  589.       break;
  590.     case MEM:
  591.       output_address (XEXP (x, 0));
  592.       break;
  593.     default:
  594.       fputc ('#', stream);
  595.       output_addr_const (stream, x);
  596.       break;
  597.  
  598.     }
  599.       break;
  600.     }
  601. }
  602.  
  603.  
  604.  
  605. /* Define the offset between two registers, one to be eliminated, and 
  606.    the other its replacement, at the start of a routine.  */
  607.  
  608. int
  609. initial_elimination_offset (from, to)
  610. {
  611.   int regs_saved;
  612.   int d = calc_live_regs (®s_saved);
  613.   int total_saved_regs_space = (regs_saved + regs_ever_live[PR_REG]) * 4;
  614.   int total_auto_space = get_frame_size ();
  615.  
  616.  
  617.   if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
  618.     {
  619.       return total_saved_regs_space;
  620.     }
  621.  
  622.   if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
  623.     {
  624.       return total_saved_regs_space + total_auto_space;
  625.     }
  626.  
  627.   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
  628.     {
  629.       return total_auto_space;
  630.     }
  631. }
  632.  
  633. delay_slots_for_epilogue ()
  634. {
  635.   /* We need to find something to fill the epilogue if there won't be
  636.      any instructions to make the stack or pop registers which can be
  637.      moved into the slot */
  638.  
  639.   int d;
  640.   calc_live_regs (&d);
  641.   return !(get_frame_size () + d);
  642. }
  643.  
  644.  
  645. /* Prepare operands for a move define_expand; specifically, one of the
  646.    operands must be in a register */
  647.  
  648. void
  649. prepare_move_operands (operands, mode)
  650.      rtx operands[];
  651.      enum machine_mode mode;
  652. {
  653.   /* One of the operands has to be a register */
  654.   if ((!register_operand (operands[0], mode)
  655.        && !register_operand (operands[1], mode))
  656.       || GET_CODE(operands[1]) == PLUS)
  657.     {
  658.       /* copy the source to a register */
  659.       operands[1] = copy_to_mode_reg (mode, operands[1]);
  660.     }
  661. }
  662.  
  663.  
  664. /* Prepare the operands for an scc instruction; make sure that the
  665.    compare has been done.  */
  666. rtx
  667. prepare_scc_operands (code)
  668. {
  669.   if (GET_CODE(sh_compare_op0) != REG 
  670.       || REGNO(sh_compare_op0) != T_REG)
  671.     {
  672.       /* First need a compare insn */
  673.       emit_insn (gen_rtx (SET, SImode, 
  674.               gen_rtx (REG, SImode, T_REG),
  675.               gen_rtx (code, SImode, sh_compare_op0,
  676.                    sh_compare_op1)));
  677.     }
  678.   return gen_rtx(REG, SImode, T_REG);
  679. }
  680.  
  681. /* Functions to output assembly */
  682.  
  683. /* Return a sequence of instructions to perform DI move, taking into
  684.    account overlapping source and dest registers */
  685.  
  686. char *
  687. output_movedouble (operands, mode)
  688.      rtx operands[];
  689.      enum machine_mode mode;
  690. {
  691.   if (register_operand (operands[0], mode)
  692.       && register_operand (operands[1], mode))
  693.     {
  694.       if (REGNO (operands[1]) == MACH_REG)
  695.     return "sts    mach,%0\n\tsts    macl,%R0";
  696.       if (REGNO (operands[1]) > REGNO (operands[0])) 
  697.     {
  698.       return "mov    %1,%0\n\tmov    %R1,%R0";
  699.     }
  700.       else 
  701.     {
  702.       return "mov    %R1,%R0\n\tmov    %1,%0";
  703.     }
  704.     }
  705.  
  706.   if (GET_CODE (operands[1]) == CONST_INT)
  707.     {
  708.       if (INTVAL (operands[1]) < 0)
  709.     return "mov    #-1,%0\n\tmov    %1,%R0";
  710.       else
  711.     return "mov    #0,%0\n\tmov    %1,%R0";
  712.     }
  713.  
  714.   if (GET_CODE (operands[1]) == MEM)
  715.     {
  716.       int idxreg = -1;
  717.       rtx inside = XEXP (operands[1], 0);
  718.  
  719.       if (GET_CODE (inside) == REG)
  720.     idxreg = REGNO (inside);
  721.       else if (GET_CODE (inside) == PLUS)
  722.     {
  723.       rtx lhs = XEXP (inside, 0);
  724.       rtx rhs = XEXP (inside, 1);
  725.       if (GET_CODE (lhs) == REG)
  726.         idxreg = REGNO (lhs);
  727.       else if (GET_CODE (rhs) == REG)
  728.         idxreg = REGNO (rhs);
  729.       else
  730.         abort ();
  731.     }
  732.       else
  733.     abort ();
  734.  
  735.       if (REGNO (operands[0]) != idxreg)
  736.     {
  737.       /* The dest register is mentioned in the addressing mode,
  738.          so print them the other way around */
  739.       return "mov.l    %1,%0\n\tmov.l    %R1,%R0 ! one way";
  740.     }
  741.       return "mov.l    %R1,%R0\n\tmov.l    %1,%0 ! other way";
  742.     }
  743.  
  744.   return "mov.l    %R1,%R0\n\tmov.l    %1,%0";
  745. }
  746.  
  747. /* Emit assembly to shift reg by k bits */
  748.  
  749. char *
  750. output_shift (string, reg, k)
  751.      char *string;
  752.      rtx reg;
  753.      rtx k;
  754. {
  755.   int s = INTVAL (k);
  756.   while (s)
  757.     {
  758.       char *out;
  759.       int d;
  760.  
  761.       if (s >= 16)
  762.     {
  763.       d = 16;
  764.       out = "16";
  765.     }
  766.       else if (s >= 8)
  767.     {
  768.       d = 8;
  769.       out = "8";
  770.     }
  771.       else if (s >= 2)
  772.     {
  773.       d = 2;
  774.       out = "2";
  775.     }
  776.       else
  777.     {
  778.       d = 1;
  779.       out = "";
  780.     }
  781.       fprintf (asm_out_file, "\t%s%s\tr%d\n", string, out, REGNO (reg));
  782.       s -= d;
  783.     }
  784.   return "";
  785. }
  786.  
  787. /* Return the text of the branch instruction which matches its length
  788.    attribute.  */
  789.  
  790. char *
  791. output_branch (logic, insn)
  792.      int logic;
  793.      rtx *insn;
  794. {
  795.   extern rtx recog_operand[];
  796.   int label = lf++;
  797.   
  798.   switch (get_attr_length (insn))
  799.     {
  800.     case 2:
  801.       /* Simple branch in range -200..+200 bytes */
  802.       return logic ? "bt    %l0" : "bf    %l0";
  803.  
  804.     case 6:
  805.       /* Branch in range -4000..+4000 bytes */
  806.       fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label);
  807.       output_asm_insn ("bra    %l0    ! 12 bit cond ", recog_operand);
  808.       fprintf (asm_out_file, "\tor    r0,r0\n");
  809.       label = dump_constants (label);
  810.       fprintf (asm_out_file, "LF%d:\n", label);
  811.       return "";
  812.  
  813.     case 8:
  814.       /* Branches a long way away */
  815.     
  816.       fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label);
  817.       output_asm_insn ("mov.l    %I0,r13", recog_operand);
  818.       fprintf (asm_out_file, "\tjmp    @r13    ! 32 cond \n");
  819.       fprintf (asm_out_file, "\tor    r0,r0\n");
  820.       fprintf (asm_out_file, "LF%d:\n", label);
  821.       return "";
  822.     }
  823.   return "bad";
  824.  
  825. }
  826.  
  827. /* Predicates used by the templates */
  828.  
  829. /* Nonzero if OP is a normal arithmetic register. */
  830.  
  831. int
  832. arith_reg_operand(op, mode)
  833.      rtx op;
  834.      enum machine_mode mode;
  835. {
  836.   if (register_operand (op, mode))
  837.     {
  838.       if (GET_CODE (op) == REG)
  839.     return REGNO (op) != T_REG;
  840.       return 1;
  841.     }
  842.   return 0;
  843. }
  844.  
  845.   
  846. /* Nonzero if OP is a valid source operand for an arithmetic insn.  */
  847.  
  848. int
  849. arith_operand (op, mode)
  850.      rtx op;
  851.      enum machine_mode mode;
  852. {
  853.   if (register_operand (op, mode))
  854.     return 1;
  855.  
  856.   if (GET_CODE (op) == CONST_INT)
  857.     {
  858.       if (CONST_OK_FOR_I (INTVAL (op)))
  859.     return 1;
  860.     }
  861.   return 0;
  862. }
  863.  
  864.  
  865. /* Nonzero if OP is a valid source operand for a logical operation */
  866.  
  867. int
  868. logical_operand (op, mode)
  869.      rtx op;
  870.      enum machine_mode mode;
  871. {
  872.   if (register_operand (op, mode))
  873.     return 1;
  874.  
  875.   if (GET_CODE (op) == CONST_INT)
  876.     {
  877.       if (CONST_OK_FOR_L (INTVAL (op)))
  878.     return 1;
  879.     }
  880.   return 0;
  881. }
  882.  
  883. /* Nonzero if p is a valid shift operand for lshr and ashl */
  884.  
  885. int
  886. ok_shift_value (p)
  887.      rtx p;
  888. {
  889.   if (GET_CODE (p) == CONST_INT)
  890.     {
  891.       switch (INTVAL (p))
  892.     {
  893.     case 1:
  894.     case 2:
  895.     case 8:
  896.     case 16:
  897.       return 1;
  898.     default:
  899.       if (TARGET_FASTCODE)
  900.         return INTVAL(p) >= 0;
  901.     }
  902.     }
  903.   return 0;
  904. }
  905.  
  906. /* Nonzero if the arg is an immediate which has to be loaded from
  907.    memory */
  908.  
  909. int
  910. hard_immediate_operand (op, mode)
  911.      rtx op;
  912.      enum machine_mode mode;
  913. {
  914.   if (immediate_operand (op, mode))
  915.     {
  916.       if (GET_CODE (op) == CONST_INT
  917.       && INTVAL (op) >= -128 && INTVAL (op) < 127)
  918.     return 0;
  919.       return 1;
  920.     }
  921.   return 0;
  922. }
  923.  
  924. /* The SH cannot load a large constant into a register, constants have to
  925.    come from a pc relative load.  The reference of a pc relative load
  926.    instruction must be less than 1k infront of the instruction.  This
  927.    means that we often have to dump a constant inside a function, and
  928.    generate code to branch around it.
  929.  
  930.    It is important to minimize this, since the branches will slow things
  931.    down and make things bigger.
  932.  
  933.   Worst case code looks like:
  934.  
  935.       mov.l L1,rn
  936.       bra   L2
  937.       nop
  938.       align
  939. L1:   .long value
  940. L2:
  941.       ..
  942.  
  943.       mov.l L3,rn
  944.       bra   L4
  945.       nop
  946.       align
  947. L3:   .long value
  948. L4:
  949.       ..
  950.  
  951.    During shorten_branches we notice the instructions which can have a
  952.    constant table in them, if we see two that are close enough
  953.    together, we move the constants from the first table to the second
  954.    table and continue.  This process can happen again and again, and
  955.    in the best case, moves the constant table outside of the function.
  956.  
  957.    In the above example, we can tell that L3 is within 1k of L1, so
  958.    the first move can be shrunk from the 3 insn+constant sequence into
  959.    just 1 insn, and the constant moved to L3 to make:
  960.  
  961.    mov.l    L1,rn
  962.    ..
  963.    mov.l    L3,rn
  964.    bra        L4
  965.    nop
  966.    align
  967. L3:.long value
  968. L4:.long value
  969.  
  970.    Then the second move becomes the target for the shortening process.
  971.  
  972.    We keep a simple list of all the constants accumulated in the
  973.    current pool so there are no duplicates in a single table, but
  974.    they are not factored into the size estimates.
  975.  
  976. */
  977.  
  978. typedef struct
  979. {
  980.   rtx value;
  981.   int number;
  982.   enum machine_mode mode;
  983. } pool_node;
  984.  
  985. /* The maximum number of constants that can fit into one pool, since
  986.    the pc relative range is 0...1020 bytes and constants are at least 4
  987.    bytes long */
  988.  
  989. #define MAX_POOL_SIZE (1020/4)
  990. static pool_node pool_vector[MAX_POOL_SIZE];
  991. static int pool_size;
  992.  
  993.  
  994. /* Add a constant to the pool and return its label number.  */
  995.  
  996. static int
  997. add_constant (x, mode)
  998.      rtx x;
  999.      enum machine_mode mode;
  1000. {
  1001.   int i;
  1002.  
  1003.   /* Start the countdown on the first constant */
  1004.  
  1005.   if (!pool_size)
  1006.     {
  1007.       first_pc = pc;
  1008.     }
  1009.  
  1010.   /* First see if we've already got it */
  1011.  
  1012.   for (i = 0; i < pool_size; i++)
  1013.     {
  1014.  
  1015.       if (x->code == pool_vector[i].value->code
  1016.       && mode == pool_vector[i].mode)
  1017.     {
  1018.       if (x->code == CODE_LABEL)
  1019.         {
  1020.           if (XINT (x, 3) != XINT (pool_vector[i].value, 3))
  1021.         continue;
  1022.         }
  1023.     }
  1024.  
  1025.       if (rtx_equal_p (x, pool_vector[i].value))
  1026.     return pool_vector[i].number;
  1027.     }
  1028.   
  1029.  
  1030.   pool_vector[pool_size].value = x;
  1031.   pool_vector[pool_size].mode = mode;
  1032.   pool_vector[pool_size].number = lf;
  1033.   pool_size++;
  1034.  
  1035.   return lf++;
  1036. }
  1037.  
  1038. /* Nonzero if the insn could take a constant table.  */
  1039.  
  1040. static int
  1041. has_constant_table (insn)
  1042.      rtx insn;
  1043. {
  1044.   rtx body;
  1045.  
  1046.   if (GET_CODE (insn) == NOTE
  1047.       || GET_CODE (insn) == BARRIER
  1048.       || GET_CODE (insn) == CODE_LABEL)
  1049.     return 0;
  1050.  
  1051.   body = PATTERN (insn);
  1052.   if (GET_CODE (body) == SEQUENCE)
  1053.     return 0;
  1054.   if (GET_CODE (body) == ADDR_VEC)
  1055.     return 0;
  1056.   if (GET_CODE (body) == USE)
  1057.     return 0;
  1058.   if (GET_CODE (body) == CLOBBER)
  1059.     return 0;
  1060.   if (get_attr_constneed (insn) == CONSTNEED_YES)
  1061.     return 1;
  1062.  
  1063.   if (GET_CODE (body) == UNSPEC_VOLATILE)
  1064.     {
  1065.       return INTVAL (XVECEXP (body, 0, 0)) == 1;
  1066.     }
  1067.   return 0;
  1068. }
  1069.  
  1070. /*  Adjust the length of an instruction.
  1071.  
  1072.     We'll look at the previous instruction which holds a constant
  1073.     table and see if we can move the table to here instead. */
  1074.  
  1075. int target_insn_uid;
  1076. int target_insn_smallest_size;
  1077.  
  1078. int target_pc;
  1079. int target_insn_range;
  1080. int current_pc;
  1081. int table_size;
  1082.  
  1083. void
  1084. adjust_insn_length (insn, insn_lengths)
  1085.      rtx insn;
  1086.      short *insn_lengths;
  1087. {
  1088.   int uid = INSN_UID (insn);
  1089.  
  1090.   current_pc += insn_lengths[uid];
  1091.  
  1092.   if (has_constant_table (insn)) 
  1093.     {
  1094.       if (current_pc >= target_insn_range)
  1095.     {
  1096.       /* This instruction is further away from the referencing
  1097.          instruction than it can reach, so we'll stop accumulating
  1098.          from that one and start fresh. */
  1099.       target_pc = current_pc;
  1100.       target_insn_range = current_pc + MAYBE_DUMP_LEVEL;
  1101.     }
  1102.       else
  1103.     {
  1104.       /* This instruction is within the reach of the target,
  1105.          remove the constant table from the target by adjusting
  1106.          downwards, and increase the size of this one to
  1107.          compensate.  */
  1108.  
  1109.  
  1110.       /* Add the stuff from this insn to what will go in the
  1111.          growing table. */
  1112.  
  1113.       table_size += get_attr_constantsize (insn);
  1114.  
  1115.       /* The target shinks to its smallest natural size */
  1116.       insn_lengths[target_insn_uid] = target_insn_smallest_size;
  1117.  
  1118.       /* The current insn grows to be its larger size plust the
  1119.          table size. */
  1120.  
  1121.       insn_lengths[uid] = get_attr_largestsize (insn) + table_size;
  1122.  
  1123.     }
  1124.       /* Current insn becomes the target.  */
  1125.       target_insn_uid = uid;
  1126.       target_insn_smallest_size = get_attr_smallestsize (insn);
  1127.  
  1128.     }
  1129.  
  1130. }
  1131.  
  1132.  
  1133. /* Dump out the pending constant pool. 
  1134.    If label provided then insert an branch in the middle of the table 
  1135.   */
  1136.  
  1137. static int
  1138. dump_constants (label)
  1139. {
  1140.   int i;
  1141.   int rlabel = label;
  1142.   int size = 0;
  1143.   
  1144.   for (i = 0; i < pool_size; i++)
  1145.     {
  1146.       pool_node *p = pool_vector + i;
  1147.       fprintf (asm_out_file, "\n\t! constants - waited %d\n", pc - first_pc);
  1148.       fprintf (asm_out_file, "\t.align\t2\n");
  1149.       fprintf (asm_out_file, "LK%d:", p->number);
  1150.       size += GET_MODE_SIZE (p->mode);
  1151.       
  1152.       switch (GET_MODE_CLASS (p->mode))
  1153.     {
  1154.     case MODE_INT:
  1155.     case MODE_PARTIAL_INT:
  1156.       assemble_integer (p->value, GET_MODE_SIZE (p->mode), 1);
  1157.       break;
  1158.     case MODE_FLOAT:
  1159.       {
  1160.         union real_extract u;
  1161.         bcopy (&CONST_DOUBLE_LOW (p->value), &u, sizeof u);
  1162.         assemble_real (u.d, p->mode);
  1163.       }
  1164.     }
  1165.       
  1166.       /* After 200 bytes of table, stick in another branch */
  1167.       if (label && size > 200) 
  1168.     {
  1169.       rlabel = lf ++;
  1170.       fprintf (asm_out_file,"LF%d:\tbra    LF%d\n", label, rlabel);
  1171.       fprintf (asm_out_file,"\tor    r0,r0\n");
  1172.       label = 0;
  1173.     }
  1174.       
  1175.       fprintf (asm_out_file, "\n");
  1176.     }
  1177.   pool_size = 0;
  1178.   current_pc = 0;
  1179.   target_insn_range = 0;
  1180.   return rlabel;
  1181.   
  1182. }
  1183.  
  1184.  
  1185. /* Emit the text to load a value from a constant table.  */
  1186.  
  1187. char *
  1188. output_movepcrel (insn, operands, mode)
  1189.      rtx insn;
  1190.      rtx operands[];
  1191.      enum machine_mode mode;
  1192. {
  1193.   int len = GET_MODE_SIZE (mode);
  1194.   int rn = REGNO (operands[0]);
  1195.  
  1196.   fprintf (asm_out_file, "\tmov.l    LK%d,r%d\n",
  1197.        add_constant (operands[1], mode), rn);
  1198.  
  1199.   if (GET_MODE_SIZE(mode) > 4) 
  1200.     {
  1201.       fprintf (asm_out_file,
  1202.            "\tmov.l    LK%d+4,r%d\n",
  1203.            add_constant (operands[1], mode),
  1204.            rn + 1);
  1205.  
  1206.     } 
  1207.   /* If this instruction is as small as it can be, there can be no 
  1208.      constant table attached to it.  */
  1209.   if (get_attr_length (insn) !=  get_attr_smallestsize (insn))
  1210.     {
  1211.       /* This needs a constant table */
  1212.       fprintf (asm_out_file, "\t!constant table start\n");
  1213.       fprintf (asm_out_file, "\tbra    LF%d\n", lf);
  1214.       fprintf (asm_out_file, "\tor    r0,r0 ! wasted slot\n");
  1215.       dump_constants (0);
  1216.       fprintf (asm_out_file, "LF%d:\n", lf++);
  1217.       fprintf (asm_out_file, "\t!constant table end\n");
  1218.     }
  1219.   return "";
  1220. }
  1221.  
  1222.  
  1223. /* Dump out interesting debug info */
  1224.  
  1225. void
  1226. final_prescan_insn (insn, opvec, noperands)
  1227.      rtx insn;
  1228.      rtx *opvec;
  1229.      int noperands;
  1230. {
  1231.   register rtx body = PATTERN (insn);
  1232.  
  1233.   if (target_flags & ISIZE_BIT)
  1234.     {
  1235.       extern int *insn_addresses;
  1236.  
  1237.       fprintf (asm_out_file, "\n!%04x*\n",
  1238.            insn_addresses[INSN_UID (insn)] + 0x10);
  1239.  
  1240.       fprintf (asm_out_file, "\n!%04x %d %04x len=%d\n",
  1241.            pc, pool_size, first_pc, get_attr_length (insn));
  1242.  
  1243.       if (TARGET_DUMP_RTL)
  1244.     print_rtl (asm_out_file, body);
  1245.  
  1246.  
  1247.     }
  1248.   
  1249.   pc += get_attr_length (insn);
  1250.  
  1251.   if (pool_size && pc - first_pc > MUST_DUMP_LEVEL)
  1252.     {
  1253.       /* For some reason we have not dumped out a constant table, and 
  1254.       we have emitted a lot of code.  This can happen if the think
  1255.       which wants the table is a long conditional branch (which has no
  1256.       room for a constant table), and there has not been a move
  1257.       constant anywhere. */
  1258.       int label = lf++;
  1259.       fprintf (asm_out_file, "\t!forced constant table\n");      
  1260.       fprintf (asm_out_file, "\tbra    LF%d\n", label);
  1261.       fprintf (asm_out_file, "\tor    r0,r0 ! wasted slot\n");
  1262.       label = dump_constants (label);
  1263.       fprintf (asm_out_file, "LF%d:\n", label);
  1264.       fprintf (asm_out_file, "\t!constant table end\n");
  1265.     }
  1266.   
  1267. }
  1268.  
  1269.  
  1270.