home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gcc-2.4.5 / config / ns32k / ns32k.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-06  |  16.2 KB  |  713 lines

  1. /* Subroutines for assembler code output on the NS32000.
  2.    Copyright (C) 1988 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. /* Some output-actions in ns32k.md need these.  */
  21. #include <stdio.h>
  22. #include "config.h"
  23. #include "rtl.h"
  24. #include "regs.h"
  25. #include "hard-reg-set.h"
  26. #include "real.h"
  27. #include "insn-config.h"
  28. #include "conditions.h"
  29. #include "insn-flags.h"
  30. #include "output.h"
  31. #include "insn-attr.h"
  32.  
  33. #ifdef OSF_OS
  34. int ns32k_num_files = 0;
  35. #endif
  36.  
  37. void
  38. trace (s, s1, s2)
  39.      char *s, *s1, *s2;
  40. {
  41.   fprintf (stderr, s, s1, s2);
  42. }
  43.  
  44. /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ 
  45.  
  46. int
  47. hard_regno_mode_ok (regno, mode)
  48.      int regno;
  49.      enum machine_mode mode;
  50. {
  51.   switch (mode)
  52.     {
  53.     case QImode:
  54.     case HImode:
  55.     case PSImode:
  56.     case SImode:
  57.     case PDImode:
  58.     case VOIDmode:
  59.     case BLKmode:
  60.       if (regno < 8 || regno == 16 || regno == 17)
  61.     return 1;
  62.       else
  63.     return 0;
  64.  
  65.     case DImode:
  66.       if (regno < 8 && (regno & 1) == 0)
  67.     return 1;
  68.       else
  69.     return 0;
  70.  
  71.     case SFmode:
  72.     case SCmode:
  73.       if (TARGET_32081)
  74.     {
  75.       if (regno < 16)
  76.         return 1;
  77.       else
  78.         return 0;
  79.     }
  80.       else
  81.     {
  82.       if (regno < 8)
  83.         return 1;
  84.       else 
  85.         return 0;
  86.     }
  87.  
  88.     case DFmode:
  89.     case DCmode:
  90.       if ((regno & 1) == 0)
  91.     {    
  92.       if (TARGET_32081)
  93.         {
  94.           if (regno < 16)
  95.         return 1;
  96.           else
  97.         return 0;
  98.         }
  99.       else
  100.         {
  101.           if (regno < 8)
  102.         return 1;
  103.           else
  104.         return 0;
  105.         }
  106.     }
  107.       else
  108.     return 0;
  109.     }
  110.  
  111.   /* Used to abort here, but simply saying "no" handles TImode
  112.      much better.  */
  113.   return 0;
  114. }
  115.  
  116. /* ADDRESS_COST calls this.  This function is not optimal
  117.    for the 32032 & 32332, but it probably is better than
  118.    the default. */
  119.  
  120. int
  121. calc_address_cost (operand)
  122.      rtx operand;
  123. {
  124.   int i;
  125.   int cost = 0;
  126.   
  127.   if (GET_CODE (operand) == MEM)
  128.     cost += 3;
  129.   if (GET_CODE (operand) == MULT)
  130.     cost += 2;
  131. #if 0
  132.   if (GET_CODE (operand) == REG)
  133.     cost += 1;            /* not really, but the documentation
  134.                    says different amount of registers
  135.                    shouldn't return the same costs */
  136. #endif
  137.   switch (GET_CODE (operand))
  138.     {
  139.     case REG:
  140.     case CONST:
  141.     case CONST_INT:
  142.     case CONST_DOUBLE:
  143.     case SYMBOL_REF:
  144.     case LABEL_REF:
  145.     case POST_DEC:
  146.     case PRE_DEC:
  147.       break;
  148.     case MULT:
  149.     case MEM:
  150.     case PLUS:
  151.       for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++)
  152.     {
  153.       cost += calc_address_cost (XEXP (operand, i));
  154.     }
  155.     default:
  156.       break;
  157.     }
  158.   return cost;
  159. }
  160.  
  161. /* Return the register class of a scratch register needed to copy IN into
  162.    or out of a register in CLASS in MODE.  If it can be done directly,
  163.    NO_REGS is returned.  */
  164.  
  165. enum reg_class
  166. secondary_reload_class (class, mode, in)
  167.      enum reg_class class;
  168.      enum machine_mode mode;
  169.      rtx in;
  170. {
  171.   int regno = true_regnum (in);
  172.  
  173.   if (regno >= FIRST_PSEUDO_REGISTER)
  174.     regno = -1;
  175.  
  176.   /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
  177.      into anything.  */
  178.   if (class == GENERAL_REGS || (regno >= 0 && regno < 8))
  179.     return NO_REGS;
  180.  
  181.   /* Constants, memory, and FP registers can go into FP registers.  */
  182.   if ((regno == -1 || (regno >= 8 && regno < 16)) && (class == FLOAT_REGS))
  183.     return NO_REGS;
  184.  
  185. #if 0 /* This isn't strictly true (can't move fp to sp or vice versa),
  186.      so it's cleaner to use PREFERRED_RELOAD_CLASS
  187.      to make the right things happen.  */
  188.   if (regno >= 16 && class == GEN_AND_MEM_REGS)
  189.     return NO_REGS;
  190. #endif
  191.  
  192.   /* Otherwise, we need GENERAL_REGS. */
  193.   return GENERAL_REGS;
  194. }
  195. /* Generate the rtx that comes from an address expression in the md file */
  196. /* The expression to be build is BASE[INDEX:SCALE].  To recognize this,
  197.    scale must be converted from an exponent (from ASHIFT) to a
  198.    multiplier (for MULT). */
  199. rtx
  200. gen_indexed_expr (base, index, scale)
  201.      rtx base, index, scale;
  202. {
  203.   rtx addr;
  204.  
  205.   /* This generates an illegal addressing mode, if BASE is
  206.      fp or sp.  This is handled by PRINT_OPERAND_ADDRESS.  */
  207.   if (GET_CODE (base) != REG && GET_CODE (base) != CONST_INT)
  208.     base = gen_rtx (MEM, SImode, base);
  209.   addr = gen_rtx (MULT, SImode, index,
  210.           gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (scale)));
  211.   addr = gen_rtx (PLUS, SImode, base, addr);
  212.   return addr;
  213. }
  214.  
  215. /* Return 1 if OP is a valid operand of mode MODE.  This
  216.    predicate rejects operands which do not have a mode
  217.    (such as CONST_INT which are VOIDmode).  */
  218. int
  219. reg_or_mem_operand (op, mode)
  220.      register rtx op;
  221.      enum machine_mode mode;
  222. {
  223.   return (GET_MODE (op) == mode
  224.       && (GET_CODE (op) == REG
  225.           || GET_CODE (op) == SUBREG
  226.           || GET_CODE (op) == MEM));
  227. }
  228.  
  229. /* Return the best assembler insn template
  230.    for moving operands[1] into operands[0] as a fullword.  */
  231.  
  232. static char *
  233. singlemove_string (operands)
  234.      rtx *operands;
  235. {
  236.   if (GET_CODE (operands[1]) == CONST_INT
  237.       && INTVAL (operands[1]) <= 7
  238.       && INTVAL (operands[1]) >= -8)
  239.     return "movqd %1,%0";
  240.   return "movd %1,%0";
  241. }
  242.  
  243. char *
  244. output_move_double (operands)
  245.      rtx *operands;
  246. {
  247.   enum anon1 { REGOP, OFFSOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
  248.   rtx latehalf[2];
  249.  
  250.   /* First classify both operands.  */
  251.  
  252.   if (REG_P (operands[0]))
  253.     optype0 = REGOP;
  254.   else if (offsettable_memref_p (operands[0]))
  255.     optype0 = OFFSOP;
  256.   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
  257.     optype0 = POPOP;
  258.   else
  259.     optype0 = RNDOP;
  260.  
  261.   if (REG_P (operands[1]))
  262.     optype1 = REGOP;
  263.   else if (CONSTANT_ADDRESS_P (operands[1])
  264.        || GET_CODE (operands[1]) == CONST_DOUBLE)
  265.     optype1 = CNSTOP;
  266.   else if (offsettable_memref_p (operands[1]))
  267.     optype1 = OFFSOP;
  268.   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
  269.     optype1 = POPOP;
  270.   else
  271.     optype1 = RNDOP;
  272.  
  273.   /* Check for the cases that the operand constraints are not
  274.      supposed to allow to happen.  Abort if we get one,
  275.      because generating code for these cases is painful.  */
  276.  
  277.   if (optype0 == RNDOP || optype1 == RNDOP)
  278.     abort ();
  279.  
  280.   /* Ok, we can do one word at a time.
  281.      Normally we do the low-numbered word first,
  282.      but if either operand is autodecrementing then we
  283.      do the high-numbered word first.
  284.  
  285.      In either case, set up in LATEHALF the operands to use
  286.      for the high-numbered word and in some cases alter the
  287.      operands in OPERANDS to be suitable for the low-numbered word.  */
  288.  
  289.   if (optype0 == REGOP)
  290.     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  291.   else if (optype0 == OFFSOP)
  292.     latehalf[0] = adj_offsettable_operand (operands[0], 4);
  293.   else
  294.     latehalf[0] = operands[0];
  295.  
  296.   if (optype1 == REGOP)
  297.     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
  298.   else if (optype1 == OFFSOP)
  299.     latehalf[1] = adj_offsettable_operand (operands[1], 4);
  300.   else if (optype1 == CNSTOP)
  301.     {
  302.       if (CONSTANT_ADDRESS_P (operands[1]))
  303.     latehalf[1] = const0_rtx;
  304.       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
  305.     split_double (operands[1], &operands[1], &latehalf[1]);
  306.     }
  307.   else
  308.     latehalf[1] = operands[1];
  309.  
  310.   /* If one or both operands autodecrementing,
  311.      do the two words, high-numbered first.  */
  312.  
  313.   if (optype0 == POPOP || optype1 == POPOP)
  314.     {
  315.       output_asm_insn (singlemove_string (latehalf), latehalf);
  316.       return singlemove_string (operands);
  317.     }
  318.  
  319.   /* Not autodecrementing.  Do the two words, low-numbered first.  */
  320.  
  321.   output_asm_insn (singlemove_string (operands), operands);
  322.  
  323.   operands[0] = latehalf[0];
  324.   operands[1] = latehalf[1];
  325.   return singlemove_string (operands);
  326. }
  327.  
  328. int
  329. check_reg (oper, reg)
  330.      rtx oper;
  331.      int reg;
  332. {
  333.   register int i;
  334.  
  335.   if (oper == 0)
  336.     return 0;
  337.   switch (GET_CODE(oper))
  338.     {
  339.     case REG:
  340.       return (REGNO(oper) == reg) ? 1 : 0;
  341.     case MEM:
  342.       return check_reg(XEXP(oper, 0), reg);
  343.     case PLUS:
  344.     case MULT:
  345.       return check_reg(XEXP(oper, 0), reg) || check_reg(XEXP(oper, 1), reg);
  346.     }
  347.   return 0;
  348. }
  349.  
  350. /* PRINT_OPERAND is defined to call this function,
  351.    which is easier to debug than putting all the code in
  352.    a macro definition in ns32k.h.  */
  353.  
  354. void
  355. print_operand (file, x, code)
  356.      FILE *file;
  357.      rtx x;
  358.      char code;
  359. {
  360.   if (code == '$')
  361.     PUT_IMMEDIATE_PREFIX (file);
  362.   else if (code == '?')
  363.     PUT_EXTERNAL_PREFIX (file);
  364.   else if (GET_CODE (x) == REG)
  365.     fprintf (file, "%s", reg_names[REGNO (x)]);
  366.   else if (GET_CODE (x) == MEM)
  367.     {
  368.       rtx tmp = XEXP (x, 0);
  369. #if ! (defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC))
  370.       if (GET_CODE (tmp) != CONST_INT)
  371.     {
  372.       char *out = XSTR (tmp, 0);
  373.       if (out[0] == '*')
  374.         {
  375.           PUT_ABSOLUTE_PREFIX (file);
  376.           fprintf (file, "%s", &out[1]);
  377.         }
  378.       else
  379.         ASM_OUTPUT_LABELREF (file, out);
  380.     }
  381.       else
  382. #endif
  383.     output_address (XEXP (x, 0));
  384.     }
  385.   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode)
  386.     {
  387.       if (GET_MODE (x) == DFmode)
  388.     { 
  389.       union { double d; int i[2]; } u;
  390.       u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
  391.       PUT_IMMEDIATE_PREFIX(file);
  392. #ifdef SEQUENT_ASM
  393.       /* Sequent likes it's floating point constants as integers */
  394.       fprintf (file, "0Dx%08x%08x", u.i[1], u.i[0]);
  395. #else
  396. #ifdef ENCORE_ASM
  397.       fprintf (file, "0f%.20e", u.d); 
  398. #else
  399.       fprintf (file, "0d%.20e", u.d); 
  400. #endif
  401. #endif
  402.     }
  403.       else
  404.     { 
  405.       union { double d; int i[2]; } u;
  406.       u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
  407.       PUT_IMMEDIATE_PREFIX (file);
  408. #ifdef SEQUENT_ASM
  409.       /* We have no way of winning if we can't get the bits
  410.          for a sequent floating point number.  */
  411. #if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
  412.       abort ();
  413. #endif
  414.       {
  415.         union { float f; long l; } uu;
  416.         uu.f = u.d;
  417.         fprintf (file, "0Fx%08x", uu.l);
  418.       }
  419. #else
  420.       fprintf (file, "0f%.20e", u.d); 
  421. #endif
  422.     }
  423.     }
  424.   else
  425.     {
  426. #ifdef NO_IMMEDIATE_PREFIX_IF_SYMBOLIC
  427.       if (GET_CODE (x) == CONST_INT)
  428. #endif
  429.     PUT_IMMEDIATE_PREFIX (file);
  430.       output_addr_const (file, x);
  431.     }
  432. }
  433.  
  434. /* PRINT_OPERAND_ADDRESS is defined to call this function,
  435.    which is easier to debug than putting all the code in
  436.    a macro definition in ns32k.h .  */
  437.  
  438. /* Completely rewritten to get this to work with Gas for PC532 Mach.
  439.    This function didn't work and I just wasn't able (nor very willing) to
  440.    figure out how it worked.
  441.    90-11-25 Tatu Yl|nen <ylo@cs.hut.fi> */
  442.  
  443. print_operand_address (file, addr)
  444.      register FILE *file;
  445.      register rtx addr;
  446. {
  447.   static char scales[] = { 'b', 'w', 'd', 0, 'q', };
  448.   rtx offset, base, indexexp, tmp;
  449.   int scale;
  450.  
  451.   if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC)
  452.     {
  453.       fprintf (file, "tos");
  454.       return;
  455.     }
  456.  
  457.   offset = NULL;
  458.   base = NULL;
  459.   indexexp = NULL;
  460.   while (addr != NULL)
  461.     {
  462.       if (GET_CODE (addr) == PLUS)
  463.     {
  464.       if (GET_CODE (XEXP (addr, 0)) == PLUS)
  465.         {
  466.           tmp = XEXP (addr, 1);
  467.           addr = XEXP (addr, 0);
  468.         }
  469.       else
  470.         {
  471.           tmp = XEXP (addr,0);
  472.           addr = XEXP (addr,1);
  473.         }
  474.     }
  475.       else
  476.     {
  477.       tmp = addr;
  478.       addr = NULL;
  479.     }
  480.       switch (GET_CODE (tmp))
  481.     {
  482.     case PLUS:
  483.       abort ();
  484.     case MEM:
  485.       if (base)
  486.         {
  487.           indexexp = base;
  488.           base = tmp;
  489.         }
  490.       else
  491.         base = tmp;
  492.       break;
  493.     case REG:
  494.       if (REGNO (tmp) < 8)
  495.         if (base)
  496.           {
  497.         indexexp = tmp;
  498.           }
  499.         else
  500.           base = tmp;
  501.       else
  502.         if (base)
  503.           {
  504.         indexexp = base;
  505.         base = tmp;
  506.           }
  507.         else
  508.           base = tmp;
  509.       break;
  510.     case MULT:
  511.       indexexp = tmp;
  512.       break;
  513.     case CONST:
  514.     case CONST_INT:
  515.     case SYMBOL_REF:
  516.     case LABEL_REF:
  517.       if (offset)
  518.         offset = gen_rtx (PLUS, SImode, tmp, offset);
  519.       else
  520.         offset = tmp;
  521.       break;
  522.     default:
  523.       abort ();
  524.     }
  525.     }
  526.   if (! offset)
  527.     offset = const0_rtx;
  528.  
  529. #ifdef INDEX_RATHER_THAN_BASE
  530.   /* This is a re-implementation of the SEQUENT_ADDRESS_BUG fix.  */
  531.   if (base && !indexexp && GET_CODE (base) == REG
  532.       && REG_OK_FOR_INDEX_P (base))
  533.     {
  534.       indexexp = base;
  535.       base = 0;
  536.     }
  537. #endif
  538.  
  539.   /* now, offset, base and indexexp are set */
  540.   if (! base)
  541.     {
  542. #if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC)
  543.       if (GET_CODE (offset) == CONST_INT)
  544. /*      if (! (GET_CODE (offset) == LABEL_REF
  545.          || GET_CODE (offset) == SYMBOL_REF)) */
  546. #endif
  547.     PUT_ABSOLUTE_PREFIX (file);
  548.     }
  549.  
  550.   output_addr_const (file, offset);
  551.   if (base) /* base can be (REG ...) or (MEM ...) */
  552.     switch (GET_CODE (base))
  553.       {
  554.     /* now we must output base.  Possible alternatives are:
  555.        (rN)       (REG ...)
  556.        (sp)          (REG ...)
  557.        (fp)       (REG ...)
  558.        (pc)       (REG ...)  used for SYMBOL_REF and LABEL_REF, output
  559.        (disp(fp)) (MEM ...)       just before possible [rX:y]
  560.        (disp(sp)) (MEM ...)
  561.        (disp(sb)) (MEM ...)
  562.        */
  563.       case REG:
  564.     fprintf (file, "(%s)", reg_names[REGNO (base)]);
  565.     break;
  566.       case MEM:
  567.     addr = XEXP(base,0);
  568.     base = NULL;
  569.     offset = NULL;
  570.     while (addr != NULL)
  571.       {
  572.         if (GET_CODE (addr) == PLUS)
  573.           {
  574.         if (GET_CODE (XEXP (addr, 0)) == PLUS)
  575.           {
  576.             tmp = XEXP (addr, 1);
  577.             addr = XEXP (addr, 0);
  578.           }
  579.         else
  580.           {
  581.             tmp = XEXP (addr, 0);
  582.             addr = XEXP (addr, 1);
  583.           }
  584.           }
  585.         else
  586.           {
  587.         tmp = addr;
  588.         addr = NULL;
  589.           }
  590.         switch (GET_CODE (tmp))
  591.           {
  592.           case REG:
  593.         base = tmp;
  594.         break;
  595.           case CONST:
  596.           case CONST_INT:
  597.           case SYMBOL_REF:
  598.           case LABEL_REF:
  599.         if (offset)
  600.           offset = gen_rtx (PLUS, SImode, tmp, offset);
  601.         else
  602.           offset = tmp;
  603.         break;
  604.           default:
  605.         abort ();
  606.           }
  607.       }
  608.     if (! offset)
  609.       offset = const0_rtx;
  610.     fprintf (file, "(");
  611.     output_addr_const (file, offset);
  612.     if (base)
  613.       fprintf (file, "(%s)", reg_names[REGNO (base)]);
  614. #ifdef BASE_REG_NEEDED
  615.     else if (TARGET_SB)
  616.       fprintf (file, "(sb)");
  617.     else
  618.       abort ();
  619. #endif
  620.     fprintf (file, ")");
  621.     break;
  622.  
  623.       default:
  624.     abort ();
  625.       }
  626. #ifdef PC_RELATIVE
  627.   else                /* no base */
  628.     if (GET_CODE (offset) == LABEL_REF || GET_CODE (offset) == SYMBOL_REF)
  629.       fprintf (file, "(pc)");
  630. #endif
  631. #ifdef BASE_REG_NEEDED        /* this is defined if the assembler always
  632.                       needs a base register */
  633.     else if (TARGET_SB)
  634.       fprintf (file, "(sb)");
  635.     else
  636.       abort ();
  637. #endif
  638.   /* now print index if we have one */
  639.   if (indexexp)
  640.     {
  641.       if (GET_CODE (indexexp) == MULT)
  642.     {
  643.       scale = INTVAL (XEXP (indexexp, 1)) >> 1;
  644.       indexexp = XEXP (indexexp, 0);
  645.     }
  646.       else
  647.     scale = 0;
  648.       if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= 8)
  649.     abort ();
  650.  
  651. #ifdef UTEK_ASM
  652.       fprintf (file, "[%c`%s]",
  653.            scales[scale],
  654.            reg_names[REGNO (indexexp)]);
  655. #else
  656.       fprintf (file, "[%s:%c]",
  657.            reg_names[REGNO (indexexp)],
  658.            scales[scale]);
  659. #endif
  660.     }
  661. }
  662.  
  663. /* National 32032 shifting is so bad that we can get
  664.    better performance in many common cases by using other
  665.    techniques.  */
  666. char *
  667. output_shift_insn (operands)
  668.      rtx *operands;
  669. {
  670.   if (GET_CODE (operands[2]) == CONST_INT
  671.       && INTVAL (operands[2]) > 0
  672.       && INTVAL (operands[2]) <= 3)
  673.     if (GET_CODE (operands[0]) == REG)
  674.       {
  675.     if (GET_CODE (operands[1]) == REG)
  676.       {
  677.         if (REGNO (operands[0]) == REGNO (operands[1]))
  678.           {
  679.         if (operands[2] == const1_rtx)
  680.           return "addd %0,%0";
  681.         else if (INTVAL (operands[2]) == 2)
  682.           return "addd %0,%0\n\taddd %0,%0";
  683.           }
  684.         if (operands[2] == const1_rtx)
  685.           return "movd %1,%0\n\taddd %0,%0";
  686.         
  687.         operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
  688.         return "addr %a1,%0";
  689.       }
  690.     if (operands[2] == const1_rtx)
  691.       return "movd %1,%0\n\taddd %0,%0";
  692.       }
  693.     else if (GET_CODE (operands[1]) == REG)
  694.       {
  695.     operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
  696.     return "addr %a1,%0";
  697.       }
  698.     else if (INTVAL (operands[2]) == 1
  699.          && GET_CODE (operands[1]) == MEM
  700.          && rtx_equal_p (operands [0], operands[1]))
  701.       {
  702.     rtx temp = XEXP (operands[1], 0);
  703.     
  704.     if (GET_CODE (temp) == REG
  705.         || (GET_CODE (temp) == PLUS
  706.         && GET_CODE (XEXP (temp, 0)) == REG
  707.         && GET_CODE (XEXP (temp, 1)) == CONST_INT))
  708.       return "addd %0,%0";
  709.       }
  710.     else return "ashd %2,%0";
  711.   return "ashd %2,%0";
  712. }
  713.