ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
[gcc.git] / gcc / expmed.c
index 861626ed9220c92d1ad5cebd23d9bce2be07b7a4..0304e46ebb350c8a9a7ab19a525ac996bb12e15e 100644 (file)
@@ -31,9 +31,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "insn-config.h"
 #include "expr.h"
+#include "insn-codes.h"
 #include "optabs.h"
 #include "recog.h"
 #include "langhooks.h"
+#include "predict.h"
+#include "basic-block.h"
 #include "df.h"
 #include "target.h"
 #include "expmed.h"
@@ -56,18 +59,18 @@ static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT,
                                   unsigned HOST_WIDE_INT,
                                   unsigned HOST_WIDE_INT,
                                   rtx);
-static rtx extract_fixed_bit_field (enum machine_mode, rtx,
+static rtx extract_fixed_bit_field (machine_mode, rtx,
                                    unsigned HOST_WIDE_INT,
                                    unsigned HOST_WIDE_INT, rtx, int);
-static rtx extract_fixed_bit_field_1 (enum machine_mode, rtx,
+static rtx extract_fixed_bit_field_1 (machine_mode, rtx,
                                      unsigned HOST_WIDE_INT,
                                      unsigned HOST_WIDE_INT, rtx, int);
-static rtx lshift_value (enum machine_mode, unsigned HOST_WIDE_INT, int);
+static rtx lshift_value (machine_mode, unsigned HOST_WIDE_INT, int);
 static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT,
                                    unsigned HOST_WIDE_INT, int);
-static void do_cmp_and_jump (rtx, rtx, enum rtx_code, enum machine_mode, rtx);
-static rtx expand_smod_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
-static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
+static void do_cmp_and_jump (rtx, rtx, enum rtx_code, machine_mode, rtx_code_label *);
+static rtx expand_smod_pow2 (machine_mode, rtx, HOST_WIDE_INT);
+static rtx expand_sdiv_pow2 (machine_mode, rtx, HOST_WIDE_INT);
 
 /* Return a constant integer mask value of mode MODE with BITSIZE ones
    followed by BITPOS zeros, or the complement of that if COMPLEMENT.
@@ -75,7 +78,7 @@ static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
    mask is zero-extended if BITSIZE+BITPOS is too small for MODE.  */
 
 static inline rtx
-mask_rtx (enum machine_mode mode, int bitpos, int bitsize, bool complement)
+mask_rtx (machine_mode mode, int bitpos, int bitsize, bool complement)
 {
   return immed_wide_int_const
     (wi::shifted_mask (bitpos, bitsize, complement,
@@ -88,86 +91,92 @@ mask_rtx (enum machine_mode mode, int bitpos, int bitsize, bool complement)
 
 struct init_expmed_rtl
 {
-  struct rtx_def reg;
-  struct rtx_def plus;
-  struct rtx_def neg;
-  struct rtx_def mult;
-  struct rtx_def sdiv;
-  struct rtx_def udiv;
-  struct rtx_def sdiv_32;
-  struct rtx_def smod_32;
-  struct rtx_def wide_mult;
-  struct rtx_def wide_lshr;
-  struct rtx_def wide_trunc;
-  struct rtx_def shift;
-  struct rtx_def shift_mult;
-  struct rtx_def shift_add;
-  struct rtx_def shift_sub0;
-  struct rtx_def shift_sub1;
-  struct rtx_def zext;
-  struct rtx_def trunc;
+  rtx reg;
+  rtx plus;
+  rtx neg;
+  rtx mult;
+  rtx sdiv;
+  rtx udiv;
+  rtx sdiv_32;
+  rtx smod_32;
+  rtx wide_mult;
+  rtx wide_lshr;
+  rtx wide_trunc;
+  rtx shift;
+  rtx shift_mult;
+  rtx shift_add;
+  rtx shift_sub0;
+  rtx shift_sub1;
+  rtx zext;
+  rtx trunc;
 
   rtx pow2[MAX_BITS_PER_WORD];
   rtx cint[MAX_BITS_PER_WORD];
 };
 
 static void
-init_expmed_one_conv (struct init_expmed_rtl *all, enum machine_mode to_mode,
-                     enum machine_mode from_mode, bool speed)
+init_expmed_one_conv (struct init_expmed_rtl *all, machine_mode to_mode,
+                     machine_mode from_mode, bool speed)
 {
   int to_size, from_size;
   rtx which;
 
-  /* We're given no information about the true size of a partial integer,
-     only the size of the "full" integer it requires for storage.  For
-     comparison purposes here, reduce the bit size by one in that case.  */
-  to_size = (GET_MODE_BITSIZE (to_mode)
-            - (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT));
-  from_size = (GET_MODE_BITSIZE (from_mode)
-              - (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT));
+  to_size = GET_MODE_PRECISION (to_mode);
+  from_size = GET_MODE_PRECISION (from_mode);
+
+  /* Most partial integers have a precision less than the "full"
+     integer it requires for storage.  In case one doesn't, for
+     comparison purposes here, reduce the bit size by one in that
+     case.  */
+  if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT
+      && exact_log2 (to_size) != -1)
+    to_size --;
+  if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT
+      && exact_log2 (from_size) != -1)
+    from_size --;
   
   /* Assume cost of zero-extend and sign-extend is the same.  */
-  which = (to_size < from_size ? &all->trunc : &all->zext);
+  which = (to_size < from_size ? all->trunc : all->zext);
 
-  PUT_MODE (&all->reg, from_mode);
+  PUT_MODE (all->reg, from_mode);
   set_convert_cost (to_mode, from_mode, speed, set_src_cost (which, speed));
 }
 
 static void
 init_expmed_one_mode (struct init_expmed_rtl *all,
-                     enum machine_mode mode, int speed)
+                     machine_mode mode, int speed)
 {
   int m, n, mode_bitsize;
-  enum machine_mode mode_from;
+  machine_mode mode_from;
 
   mode_bitsize = GET_MODE_UNIT_BITSIZE (mode);
 
-  PUT_MODE (&all->reg, mode);
-  PUT_MODE (&all->plus, mode);
-  PUT_MODE (&all->neg, mode);
-  PUT_MODE (&all->mult, mode);
-  PUT_MODE (&all->sdiv, mode);
-  PUT_MODE (&all->udiv, mode);
-  PUT_MODE (&all->sdiv_32, mode);
-  PUT_MODE (&all->smod_32, mode);
-  PUT_MODE (&all->wide_trunc, mode);
-  PUT_MODE (&all->shift, mode);
-  PUT_MODE (&all->shift_mult, mode);
-  PUT_MODE (&all->shift_add, mode);
-  PUT_MODE (&all->shift_sub0, mode);
-  PUT_MODE (&all->shift_sub1, mode);
-  PUT_MODE (&all->zext, mode);
-  PUT_MODE (&all->trunc, mode);
-
-  set_add_cost (speed, mode, set_src_cost (&all->plus, speed));
-  set_neg_cost (speed, mode, set_src_cost (&all->neg, speed));
-  set_mul_cost (speed, mode, set_src_cost (&all->mult, speed));
-  set_sdiv_cost (speed, mode, set_src_cost (&all->sdiv, speed));
-  set_udiv_cost (speed, mode, set_src_cost (&all->udiv, speed));
-
-  set_sdiv_pow2_cheap (speed, mode, (set_src_cost (&all->sdiv_32, speed)
+  PUT_MODE (all->reg, mode);
+  PUT_MODE (all->plus, mode);
+  PUT_MODE (all->neg, mode);
+  PUT_MODE (all->mult, mode);
+  PUT_MODE (all->sdiv, mode);
+  PUT_MODE (all->udiv, mode);
+  PUT_MODE (all->sdiv_32, mode);
+  PUT_MODE (all->smod_32, mode);
+  PUT_MODE (all->wide_trunc, mode);
+  PUT_MODE (all->shift, mode);
+  PUT_MODE (all->shift_mult, mode);
+  PUT_MODE (all->shift_add, mode);
+  PUT_MODE (all->shift_sub0, mode);
+  PUT_MODE (all->shift_sub1, mode);
+  PUT_MODE (all->zext, mode);
+  PUT_MODE (all->trunc, mode);
+
+  set_add_cost (speed, mode, set_src_cost (all->plus, speed));
+  set_neg_cost (speed, mode, set_src_cost (all->neg, speed));
+  set_mul_cost (speed, mode, set_src_cost (all->mult, speed));
+  set_sdiv_cost (speed, mode, set_src_cost (all->sdiv, speed));
+  set_udiv_cost (speed, mode, set_src_cost (all->udiv, speed));
+
+  set_sdiv_pow2_cheap (speed, mode, (set_src_cost (all->sdiv_32, speed)
                                     <= 2 * add_cost (speed, mode)));
-  set_smod_pow2_cheap (speed, mode, (set_src_cost (&all->smod_32, speed)
+  set_smod_pow2_cheap (speed, mode, (set_src_cost (all->smod_32, speed)
                                     <= 4 * add_cost (speed, mode)));
 
   set_shift_cost (speed, mode, 0, 0);
@@ -181,35 +190,35 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
   n = MIN (MAX_BITS_PER_WORD, mode_bitsize);
   for (m = 1; m < n; m++)
     {
-      XEXP (&all->shift, 1) = all->cint[m];
-      XEXP (&all->shift_mult, 1) = all->pow2[m];
+      XEXP (all->shift, 1) = all->cint[m];
+      XEXP (all->shift_mult, 1) = all->pow2[m];
 
-      set_shift_cost (speed, mode, m, set_src_cost (&all->shift, speed));
-      set_shiftadd_cost (speed, mode, m, set_src_cost (&all->shift_add, speed));
-      set_shiftsub0_cost (speed, mode, m, set_src_cost (&all->shift_sub0, speed));
-      set_shiftsub1_cost (speed, mode, m, set_src_cost (&all->shift_sub1, speed));
+      set_shift_cost (speed, mode, m, set_src_cost (all->shift, speed));
+      set_shiftadd_cost (speed, mode, m, set_src_cost (all->shift_add, speed));
+      set_shiftsub0_cost (speed, mode, m, set_src_cost (all->shift_sub0, speed));
+      set_shiftsub1_cost (speed, mode, m, set_src_cost (all->shift_sub1, speed));
     }
 
   if (SCALAR_INT_MODE_P (mode))
     {
       for (mode_from = MIN_MODE_INT; mode_from <= MAX_MODE_INT;
-          mode_from = (enum machine_mode)(mode_from + 1))
+          mode_from = (machine_mode)(mode_from + 1))
        init_expmed_one_conv (all, mode, mode_from, speed);
     }
   if (GET_MODE_CLASS (mode) == MODE_INT)
     {
-      enum machine_mode  wider_mode = GET_MODE_WIDER_MODE (mode);
+      machine_mode  wider_mode = GET_MODE_WIDER_MODE (mode);
       if (wider_mode != VOIDmode)
        {
-         PUT_MODE (&all->zext, wider_mode);
-         PUT_MODE (&all->wide_mult, wider_mode);
-         PUT_MODE (&all->wide_lshr, wider_mode);
-         XEXP (&all->wide_lshr, 1) = GEN_INT (mode_bitsize);
+         PUT_MODE (all->zext, wider_mode);
+         PUT_MODE (all->wide_mult, wider_mode);
+         PUT_MODE (all->wide_lshr, wider_mode);
+         XEXP (all->wide_lshr, 1) = GEN_INT (mode_bitsize);
 
          set_mul_widen_cost (speed, wider_mode,
-                             set_src_cost (&all->wide_mult, speed));
+                             set_src_cost (all->wide_mult, speed));
          set_mul_highpart_cost (speed, mode,
-                                set_src_cost (&all->wide_trunc, speed));
+                                set_src_cost (all->wide_trunc, speed));
        }
     }
 }
@@ -218,7 +227,7 @@ void
 init_expmed (void)
 {
   struct init_expmed_rtl all;
-  enum machine_mode mode;
+  machine_mode mode = QImode;
   int m, speed;
 
   memset (&all, 0, sizeof all);
@@ -228,70 +237,25 @@ init_expmed (void)
       all.cint[m] = GEN_INT (m);
     }
 
-  PUT_CODE (&all.reg, REG);
   /* Avoid using hard regs in ways which may be unsupported.  */
-  SET_REGNO (&all.reg, LAST_VIRTUAL_REGISTER + 1);
-
-  PUT_CODE (&all.plus, PLUS);
-  XEXP (&all.plus, 0) = &all.reg;
-  XEXP (&all.plus, 1) = &all.reg;
-
-  PUT_CODE (&all.neg, NEG);
-  XEXP (&all.neg, 0) = &all.reg;
-
-  PUT_CODE (&all.mult, MULT);
-  XEXP (&all.mult, 0) = &all.reg;
-  XEXP (&all.mult, 1) = &all.reg;
-
-  PUT_CODE (&all.sdiv, DIV);
-  XEXP (&all.sdiv, 0) = &all.reg;
-  XEXP (&all.sdiv, 1) = &all.reg;
-
-  PUT_CODE (&all.udiv, UDIV);
-  XEXP (&all.udiv, 0) = &all.reg;
-  XEXP (&all.udiv, 1) = &all.reg;
-
-  PUT_CODE (&all.sdiv_32, DIV);
-  XEXP (&all.sdiv_32, 0) = &all.reg;
-  XEXP (&all.sdiv_32, 1) = 32 < MAX_BITS_PER_WORD ? all.cint[32] : GEN_INT (32);
-
-  PUT_CODE (&all.smod_32, MOD);
-  XEXP (&all.smod_32, 0) = &all.reg;
-  XEXP (&all.smod_32, 1) = XEXP (&all.sdiv_32, 1);
-
-  PUT_CODE (&all.zext, ZERO_EXTEND);
-  XEXP (&all.zext, 0) = &all.reg;
-
-  PUT_CODE (&all.wide_mult, MULT);
-  XEXP (&all.wide_mult, 0) = &all.zext;
-  XEXP (&all.wide_mult, 1) = &all.zext;
-
-  PUT_CODE (&all.wide_lshr, LSHIFTRT);
-  XEXP (&all.wide_lshr, 0) = &all.wide_mult;
-
-  PUT_CODE (&all.wide_trunc, TRUNCATE);
-  XEXP (&all.wide_trunc, 0) = &all.wide_lshr;
-
-  PUT_CODE (&all.shift, ASHIFT);
-  XEXP (&all.shift, 0) = &all.reg;
-
-  PUT_CODE (&all.shift_mult, MULT);
-  XEXP (&all.shift_mult, 0) = &all.reg;
-
-  PUT_CODE (&all.shift_add, PLUS);
-  XEXP (&all.shift_add, 0) = &all.shift_mult;
-  XEXP (&all.shift_add, 1) = &all.reg;
-
-  PUT_CODE (&all.shift_sub0, MINUS);
-  XEXP (&all.shift_sub0, 0) = &all.shift_mult;
-  XEXP (&all.shift_sub0, 1) = &all.reg;
-
-  PUT_CODE (&all.shift_sub1, MINUS);
-  XEXP (&all.shift_sub1, 0) = &all.reg;
-  XEXP (&all.shift_sub1, 1) = &all.shift_mult;
-
-  PUT_CODE (&all.trunc, TRUNCATE);
-  XEXP (&all.trunc, 0) = &all.reg;
+  all.reg = gen_rtx_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1);
+  all.plus = gen_rtx_PLUS (mode, all.reg, all.reg);
+  all.neg = gen_rtx_NEG (mode, all.reg);
+  all.mult = gen_rtx_MULT (mode, all.reg, all.reg);
+  all.sdiv = gen_rtx_DIV (mode, all.reg, all.reg);
+  all.udiv = gen_rtx_UDIV (mode, all.reg, all.reg);
+  all.sdiv_32 = gen_rtx_DIV (mode, all.reg, all.pow2[5]);
+  all.smod_32 = gen_rtx_MOD (mode, all.reg, all.pow2[5]);
+  all.zext = gen_rtx_ZERO_EXTEND (mode, all.reg);
+  all.wide_mult = gen_rtx_MULT (mode, all.zext, all.zext);
+  all.wide_lshr = gen_rtx_LSHIFTRT (mode, all.wide_mult, all.reg);
+  all.wide_trunc = gen_rtx_TRUNCATE (mode, all.wide_lshr);
+  all.shift = gen_rtx_ASHIFT (mode, all.reg, all.reg);
+  all.shift_mult = gen_rtx_MULT (mode, all.reg, all.reg);
+  all.shift_add = gen_rtx_PLUS (mode, all.shift_mult, all.reg);
+  all.shift_sub0 = gen_rtx_MINUS (mode, all.shift_mult, all.reg);
+  all.shift_sub1 = gen_rtx_MINUS (mode, all.reg, all.shift_mult);
+  all.trunc = gen_rtx_TRUNCATE (mode, all.reg);
 
   for (speed = 0; speed < 2; speed++)
     {
@@ -299,17 +263,17 @@ init_expmed (void)
       set_zero_cost (speed, set_src_cost (const0_rtx, speed));
 
       for (mode = MIN_MODE_INT; mode <= MAX_MODE_INT;
-          mode = (enum machine_mode)(mode + 1))
+          mode = (machine_mode)(mode + 1))
        init_expmed_one_mode (&all, mode, speed);
 
       if (MIN_MODE_PARTIAL_INT != VOIDmode)
        for (mode = MIN_MODE_PARTIAL_INT; mode <= MAX_MODE_PARTIAL_INT;
-            mode = (enum machine_mode)(mode + 1))
+            mode = (machine_mode)(mode + 1))
          init_expmed_one_mode (&all, mode, speed);
 
       if (MIN_MODE_VECTOR_INT != VOIDmode)
        for (mode = MIN_MODE_VECTOR_INT; mode <= MAX_MODE_VECTOR_INT;
-            mode = (enum machine_mode)(mode + 1))
+            mode = (machine_mode)(mode + 1))
          init_expmed_one_mode (&all, mode, speed);
     }
 
@@ -321,6 +285,25 @@ init_expmed (void)
   else
     set_alg_hash_used_p (true);
   default_rtl_profile ();
+
+  ggc_free (all.trunc);
+  ggc_free (all.shift_sub1);
+  ggc_free (all.shift_sub0);
+  ggc_free (all.shift_add);
+  ggc_free (all.shift_mult);
+  ggc_free (all.shift);
+  ggc_free (all.wide_trunc);
+  ggc_free (all.wide_lshr);
+  ggc_free (all.wide_mult);
+  ggc_free (all.zext);
+  ggc_free (all.smod_32);
+  ggc_free (all.sdiv_32);
+  ggc_free (all.udiv);
+  ggc_free (all.sdiv);
+  ggc_free (all.mult);
+  ggc_free (all.neg);
+  ggc_free (all.plus);
+  ggc_free (all.reg);
 }
 
 /* Return an rtx representing minus the value of X.
@@ -328,7 +311,7 @@ init_expmed (void)
    useful if X is a CONST_INT.  */
 
 rtx
-negate_rtx (enum machine_mode mode, rtx x)
+negate_rtx (machine_mode mode, rtx x)
 {
   rtx result = simplify_unary_operation (NEG, mode, x, mode);
 
@@ -344,7 +327,7 @@ negate_rtx (enum machine_mode mode, rtx x)
    Set *NEW_BITNUM to the bit position of the field within the new memory.  */
 
 static rtx
-narrow_bit_field_mem (rtx mem, enum machine_mode mode,
+narrow_bit_field_mem (rtx mem, machine_mode mode,
                      unsigned HOST_WIDE_INT bitsize,
                      unsigned HOST_WIDE_INT bitnum,
                      unsigned HOST_WIDE_INT *new_bitnum)
@@ -382,13 +365,13 @@ adjust_bit_field_mem_for_reg (enum extraction_pattern pattern,
                              HOST_WIDE_INT bitnum,
                              unsigned HOST_WIDE_INT bitregion_start,
                              unsigned HOST_WIDE_INT bitregion_end,
-                             enum machine_mode fieldmode,
+                             machine_mode fieldmode,
                              unsigned HOST_WIDE_INT *new_bitnum)
 {
   bit_field_mode_iterator iter (bitsize, bitnum, bitregion_start,
                                bitregion_end, MEM_ALIGN (op0),
                                MEM_VOLATILE_P (op0));
-  enum machine_mode best_mode;
+  machine_mode best_mode;
   if (iter.next_mode (&best_mode))
     {
       /* We can use a memory in BEST_MODE.  See whether this is true for
@@ -399,14 +382,14 @@ adjust_bit_field_mem_for_reg (enum extraction_pattern pattern,
        {
          /* Limit the search to the mode required by the corresponding
             register insertion or extraction instruction, if any.  */
-         enum machine_mode limit_mode = word_mode;
+         machine_mode limit_mode = word_mode;
          extraction_insn insn;
          if (get_best_reg_extraction_insn (&insn, pattern,
                                            GET_MODE_BITSIZE (best_mode),
                                            fieldmode))
            limit_mode = insn.field_mode;
 
-         enum machine_mode wider_mode;
+         machine_mode wider_mode;
          while (iter.next_mode (&wider_mode)
                 && GET_MODE_SIZE (wider_mode) <= GET_MODE_SIZE (limit_mode))
            best_mode = wider_mode;
@@ -424,7 +407,7 @@ adjust_bit_field_mem_for_reg (enum extraction_pattern pattern,
 static bool
 lowpart_bit_field_p (unsigned HOST_WIDE_INT bitnum,
                     unsigned HOST_WIDE_INT bitsize,
-                    enum machine_mode struct_mode)
+                    machine_mode struct_mode)
 {
   if (BYTES_BIG_ENDIAN)
     return (bitnum % BITS_PER_UNIT == 0
@@ -443,7 +426,7 @@ lowpart_bit_field_p (unsigned HOST_WIDE_INT bitnum,
 static bool
 strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
                            unsigned HOST_WIDE_INT bitnum,
-                           enum machine_mode fieldmode,
+                           machine_mode fieldmode,
                            unsigned HOST_WIDE_INT bitregion_start,
                            unsigned HOST_WIDE_INT bitregion_end)
 {
@@ -475,7 +458,7 @@ strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
   /* Check for cases where the C++ memory model applies.  */
   if (bitregion_end != 0
       && (bitnum - bitnum % modesize < bitregion_start
-         || bitnum - bitnum % modesize + modesize > bitregion_end))
+         || bitnum - bitnum % modesize + modesize - 1 > bitregion_end))
     return false;
 
   return true;
@@ -486,7 +469,7 @@ strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
 
 static bool
 simple_mem_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
-                      unsigned HOST_WIDE_INT bitnum, enum machine_mode mode)
+                      unsigned HOST_WIDE_INT bitnum, machine_mode mode)
 {
   return (MEM_P (op0)
          && bitnum % BITS_PER_UNIT == 0
@@ -508,10 +491,10 @@ store_bit_field_using_insv (const extraction_insn *insv, rtx op0,
   struct expand_operand ops[4];
   rtx value1;
   rtx xop0 = op0;
-  rtx last = get_last_insn ();
+  rtx_insn *last = get_last_insn ();
   bool copy_back = false;
 
-  enum machine_mode op_mode = insv->field_mode;
+  machine_mode op_mode = insv->field_mode;
   unsigned int unit = GET_MODE_BITSIZE (op_mode);
   if (bitsize == 0 || bitsize > unit)
     return false;
@@ -621,7 +604,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                   unsigned HOST_WIDE_INT bitnum,
                   unsigned HOST_WIDE_INT bitregion_start,
                   unsigned HOST_WIDE_INT bitregion_end,
-                  enum machine_mode fieldmode,
+                  machine_mode fieldmode,
                   rtx value, bool fallback_p)
 {
   rtx op0 = str_rtx;
@@ -671,8 +654,8 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       && !(bitnum % GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0)))))
     {
       struct expand_operand ops[3];
-      enum machine_mode outermode = GET_MODE (op0);
-      enum machine_mode innermode = GET_MODE_INNER (outermode);
+      machine_mode outermode = GET_MODE (op0);
+      machine_mode innermode = GET_MODE_INNER (outermode);
       enum insn_code icode = optab_handler (vec_set_optab, outermode);
       int pos = bitnum / GET_MODE_BITSIZE (innermode);
 
@@ -731,7 +714,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
      since that case is valid for any mode.  The following cases are only
      valid for integral modes.  */
   {
-    enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
+    machine_mode imode = int_mode_for_mode (GET_MODE (op0));
     if (imode != GET_MODE (op0))
       {
        if (MEM_P (op0))
@@ -794,7 +777,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       unsigned int backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
       unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
       unsigned int i;
-      rtx last;
+      rtx_insn *last;
 
       /* This is the mode we must force value to, so that there will be enough
         subwords to extract.  Note that fieldmode will often (always?) be
@@ -900,7 +883,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
          && store_bit_field_using_insv (&insv, op0, bitsize, bitnum, value))
        return true;
 
-      rtx last = get_last_insn ();
+      rtx_insn *last = get_last_insn ();
 
       /* Try loading part of OP0 into a register, inserting the bitfield
         into that, and then copying the result back to OP0.  */
@@ -946,7 +929,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                 unsigned HOST_WIDE_INT bitnum,
                 unsigned HOST_WIDE_INT bitregion_start,
                 unsigned HOST_WIDE_INT bitregion_end,
-                enum machine_mode fieldmode,
+                machine_mode fieldmode,
                 rtx value)
 {
   /* Handle -fstrict-volatile-bitfields in the cases where it applies.  */
@@ -980,7 +963,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
      bit region.  */
   if (MEM_P (str_rtx) && bitregion_start > 0)
     {
-      enum machine_mode bestmode;
+      machine_mode bestmode;
       HOST_WIDE_INT offset, size;
 
       gcc_assert ((bitregion_start % BITS_PER_UNIT) == 0);
@@ -1022,7 +1005,7 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
 
   if (MEM_P (op0))
     {
-      enum machine_mode mode = GET_MODE (op0);
+      machine_mode mode = GET_MODE (op0);
       if (GET_MODE_BITSIZE (mode) == 0
          || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode))
        mode = word_mode;
@@ -1052,7 +1035,7 @@ store_fixed_bit_field_1 (rtx op0, unsigned HOST_WIDE_INT bitsize,
                         unsigned HOST_WIDE_INT bitnum,
                         rtx value)
 {
-  enum machine_mode mode;
+  machine_mode mode;
   rtx temp;
   int all_zero = 0;
   int all_one = 0;
@@ -1077,16 +1060,17 @@ store_fixed_bit_field_1 (rtx op0, unsigned HOST_WIDE_INT bitsize,
 
   if (CONST_INT_P (value))
     {
-      HOST_WIDE_INT v = INTVAL (value);
+      unsigned HOST_WIDE_INT v = UINTVAL (value);
 
       if (bitsize < HOST_BITS_PER_WIDE_INT)
-       v &= ((HOST_WIDE_INT) 1 << bitsize) - 1;
+       v &= ((unsigned HOST_WIDE_INT) 1 << bitsize) - 1;
 
       if (v == 0)
        all_zero = 1;
       else if ((bitsize < HOST_BITS_PER_WIDE_INT
-               && v == ((HOST_WIDE_INT) 1 << bitsize) - 1)
-              || (bitsize == HOST_BITS_PER_WIDE_INT && v == -1))
+               && v == ((unsigned HOST_WIDE_INT) 1 << bitsize) - 1)
+              || (bitsize == HOST_BITS_PER_WIDE_INT
+                  && v == (unsigned HOST_WIDE_INT) -1))
        all_one = 1;
 
       value = lshift_value (mode, v, bitnum);
@@ -1257,7 +1241,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
        {
          int word_offset = (SUBREG_BYTE (op0) / UNITS_PER_WORD)
                            + (offset * unit / BITS_PER_WORD);
-         enum machine_mode sub_mode = GET_MODE (SUBREG_REG (op0));
+         machine_mode sub_mode = GET_MODE (SUBREG_REG (op0));
          if (sub_mode != BLKmode && GET_MODE_SIZE (sub_mode) < UNITS_PER_WORD)
            word = word_offset ? const0_rtx : op0;
          else
@@ -1267,7 +1251,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
        }
       else if (REG_P (op0))
        {
-         enum machine_mode op0_mode = GET_MODE (op0);
+         machine_mode op0_mode = GET_MODE (op0);
          if (op0_mode != BLKmode && GET_MODE_SIZE (op0_mode) < UNITS_PER_WORD)
            word = offset ? const0_rtx : op0;
          else
@@ -1292,8 +1276,8 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
    to extract_bit_field.  */
 
 static rtx
-convert_extracted_bit_field (rtx x, enum machine_mode mode,
-                            enum machine_mode tmode, bool unsignedp)
+convert_extracted_bit_field (rtx x, machine_mode mode,
+                            machine_mode tmode, bool unsignedp)
 {
   if (GET_MODE (x) == tmode || GET_MODE (x) == mode)
     return x;
@@ -1303,7 +1287,7 @@ convert_extracted_bit_field (rtx x, enum machine_mode mode,
      value via a SUBREG.  */
   if (!SCALAR_INT_MODE_P (tmode))
     {
-      enum machine_mode smode;
+      machine_mode smode;
 
       smode = mode_for_size (GET_MODE_BITSIZE (tmode), MODE_INT, 0);
       x = convert_to_mode (smode, x, unsignedp);
@@ -1324,12 +1308,12 @@ extract_bit_field_using_extv (const extraction_insn *extv, rtx op0,
                              unsigned HOST_WIDE_INT bitsize,
                              unsigned HOST_WIDE_INT bitnum,
                              int unsignedp, rtx target,
-                             enum machine_mode mode, enum machine_mode tmode)
+                             machine_mode mode, machine_mode tmode)
 {
   struct expand_operand ops[4];
   rtx spec_target = target;
   rtx spec_target_subreg = 0;
-  enum machine_mode ext_mode = extv->field_mode;
+  machine_mode ext_mode = extv->field_mode;
   unsigned unit = GET_MODE_BITSIZE (ext_mode);
 
   if (bitsize == 0 || unit < bitsize)
@@ -1406,12 +1390,12 @@ extract_bit_field_using_extv (const extraction_insn *extv, rtx op0,
 static rtx
 extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                     unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
-                    enum machine_mode mode, enum machine_mode tmode,
+                    machine_mode mode, machine_mode tmode,
                     bool fallback_p)
 {
   rtx op0 = str_rtx;
-  enum machine_mode int_mode;
-  enum machine_mode mode1;
+  machine_mode int_mode;
+  machine_mode mode1;
 
   if (tmode == VOIDmode)
     tmode = mode;
@@ -1442,7 +1426,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       && !MEM_P (op0)
       && GET_MODE_INNER (GET_MODE (op0)) != tmode)
     {
-      enum machine_mode new_mode;
+      machine_mode new_mode;
 
       if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
        new_mode = MIN_MODE_VECTOR_FLOAT;
@@ -1474,8 +1458,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
          == bitnum / GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0)))))
     {
       struct expand_operand ops[3];
-      enum machine_mode outermode = GET_MODE (op0);
-      enum machine_mode innermode = GET_MODE_INNER (outermode);
+      machine_mode outermode = GET_MODE (op0);
+      machine_mode innermode = GET_MODE_INNER (outermode);
       enum insn_code icode = optab_handler (vec_extract_optab, outermode);
       unsigned HOST_WIDE_INT pos = bitnum / GET_MODE_BITSIZE (innermode);
 
@@ -1494,7 +1478,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
   /* Make sure we are playing with integral modes.  Pun with subregs
      if we aren't.  */
   {
-    enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
+    machine_mode imode = int_mode_for_mode (GET_MODE (op0));
     if (imode != GET_MODE (op0))
       {
        if (MEM_P (op0))
@@ -1538,7 +1522,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
   mode1 = mode;
   if (SCALAR_INT_MODE_P (tmode))
     {
-      enum machine_mode try_mode = mode_for_size (bitsize,
+      machine_mode try_mode = mode_for_size (bitsize,
                                                  GET_MODE_CLASS (tmode), 0);
       if (try_mode != BLKmode)
        mode1 = try_mode;
@@ -1579,7 +1563,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       unsigned int backwards = WORDS_BIG_ENDIAN;
       unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
       unsigned int i;
-      rtx last;
+      rtx_insn *last;
 
       if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
        target = gen_reg_rtx (mode);
@@ -1697,7 +1681,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
            return result;
        }
 
-      rtx last = get_last_insn ();
+      rtx_insn *last = get_last_insn ();
 
       /* Try loading part of OP0 into a register and extracting the
         bitfield from that.  */
@@ -1751,9 +1735,9 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 rtx
 extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
                   unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
-                  enum machine_mode mode, enum machine_mode tmode)
+                  machine_mode mode, machine_mode tmode)
 {
-  enum machine_mode mode1;
+  machine_mode mode1;
 
   /* Handle -fstrict-volatile-bitfields in the cases where it applies.  */
   if (GET_MODE_BITSIZE (GET_MODE (str_rtx)) > 0)
@@ -1796,14 +1780,14 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
    If TARGET is not used, create a pseudo-reg of mode TMODE for the value.  */
 
 static rtx
-extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
+extract_fixed_bit_field (machine_mode tmode, rtx op0,
                         unsigned HOST_WIDE_INT bitsize,
                         unsigned HOST_WIDE_INT bitnum, rtx target,
                         int unsignedp)
 {
   if (MEM_P (op0))
     {
-      enum machine_mode mode
+      machine_mode mode
        = get_best_mode (bitsize, bitnum, 0, 0, MEM_ALIGN (op0), word_mode,
                         MEM_VOLATILE_P (op0));
 
@@ -1823,12 +1807,12 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
    the bit field always using the MODE of OP0.  */
 
 static rtx
-extract_fixed_bit_field_1 (enum machine_mode tmode, rtx op0,
+extract_fixed_bit_field_1 (machine_mode tmode, rtx op0,
                           unsigned HOST_WIDE_INT bitsize,
                           unsigned HOST_WIDE_INT bitnum, rtx target,
                           int unsignedp)
 {
-  enum machine_mode mode = GET_MODE (op0);
+  machine_mode mode = GET_MODE (op0);
   gcc_assert (SCALAR_INT_MODE_P (mode));
 
   /* Note that bitsize + bitnum can be greater than GET_MODE_BITSIZE (mode)
@@ -1902,7 +1886,7 @@ extract_fixed_bit_field_1 (enum machine_mode tmode, rtx op0,
    VALUE << BITPOS.  */
 
 static rtx
-lshift_value (enum machine_mode mode, unsigned HOST_WIDE_INT value,
+lshift_value (machine_mode mode, unsigned HOST_WIDE_INT value,
              int bitpos)
 {
   return immed_wide_int_const (wi::lshift (value, bitpos), mode);
@@ -2032,9 +2016,9 @@ extract_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
    operations.  */
 
 rtx
-extract_low_bits (enum machine_mode mode, enum machine_mode src_mode, rtx src)
+extract_low_bits (machine_mode mode, machine_mode src_mode, rtx src)
 {
-  enum machine_mode int_mode, src_int_mode;
+  machine_mode int_mode, src_int_mode;
 
   if (mode == src_mode)
     return src;
@@ -2116,7 +2100,7 @@ expand_dec (rtx target, rtx dec)
    Return the rtx for where the value is.  */
 
 static rtx
-expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
+expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted,
                rtx amount, rtx target, int unsignedp)
 {
   rtx op1, temp = 0;
@@ -2127,8 +2111,8 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
   optab rshift_uns_optab = lshr_optab;
   optab lrotate_optab = rotl_optab;
   optab rrotate_optab = rotr_optab;
-  enum machine_mode op1_mode;
-  enum machine_mode scalar_mode = mode;
+  machine_mode op1_mode;
+  machine_mode scalar_mode = mode;
   int attempt;
   bool speed = optimize_insn_for_speed_p ();
 
@@ -2180,6 +2164,18 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
       code = left ? LROTATE_EXPR : RROTATE_EXPR;
     }
 
+  /* Rotation of 16bit values by 8 bits is effectively equivalent to a bswaphi.
+     Note that this is not the case for bigger values.  For instance a rotation
+     of 0x01020304 by 16 bits gives 0x03040102 which is different from
+     0x04030201 (bswapsi).  */
+  if (rotate
+      && CONST_INT_P (op1)
+      && INTVAL (op1) == BITS_PER_UNIT
+      && GET_MODE_SIZE (scalar_mode) == 2
+      && optab_handler (bswap_optab, HImode) != CODE_FOR_nothing)
+    return expand_unop (HImode, bswap_optab, shifted, NULL_RTX,
+                                 unsignedp);
+
   if (op1 == const0_rtx)
     return shifted;
 
@@ -2314,7 +2310,7 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
    Return the rtx for where the value is.  */
 
 rtx
-expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
+expand_shift (enum tree_code code, machine_mode mode, rtx shifted,
              int amount, rtx target, int unsignedp)
 {
   return expand_shift_1 (code, mode,
@@ -2329,7 +2325,7 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
    Return the rtx for where the value is.  */
 
 rtx
-expand_variable_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
+expand_variable_shift (enum tree_code code, machine_mode mode, rtx shifted,
                       tree amount, rtx target, int unsignedp)
 {
   return expand_shift_1 (code, mode,
@@ -2344,15 +2340,15 @@ expand_variable_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
 enum mult_variant {basic_variant, negate_variant, add_variant};
 
 static void synth_mult (struct algorithm *, unsigned HOST_WIDE_INT,
-                       const struct mult_cost *, enum machine_mode mode);
-static bool choose_mult_variant (enum machine_mode, HOST_WIDE_INT,
+                       const struct mult_cost *, machine_mode mode);
+static bool choose_mult_variant (machine_mode, HOST_WIDE_INT,
                                 struct algorithm *, enum mult_variant *, int);
-static rtx expand_mult_const (enum machine_mode, rtx, HOST_WIDE_INT, rtx,
+static rtx expand_mult_const (machine_mode, rtx, HOST_WIDE_INT, rtx,
                              const struct algorithm *, enum mult_variant);
 static unsigned HOST_WIDE_INT invert_mod2n (unsigned HOST_WIDE_INT, int);
-static rtx extract_high_half (enum machine_mode, rtx);
-static rtx expmed_mult_highpart (enum machine_mode, rtx, rtx, rtx, int, int);
-static rtx expmed_mult_highpart_optab (enum machine_mode, rtx, rtx, rtx,
+static rtx extract_high_half (machine_mode, rtx);
+static rtx expmed_mult_highpart (machine_mode, rtx, rtx, rtx, int, int);
+static rtx expmed_mult_highpart_optab (machine_mode, rtx, rtx, rtx,
                                       int, int);
 /* Compute and return the best algorithm for multiplying by T.
    The algorithm must cost less than cost_limit
@@ -2362,7 +2358,7 @@ static rtx expmed_mult_highpart_optab (enum machine_mode, rtx, rtx, rtx,
 
 static void
 synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
-           const struct mult_cost *cost_limit, enum machine_mode mode)
+           const struct mult_cost *cost_limit, machine_mode mode)
 {
   int m;
   struct algorithm *alg_in, *best_alg;
@@ -2375,7 +2371,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
   bool cache_hit = false;
   enum alg_code cache_alg = alg_zero;
   bool speed = optimize_insn_for_speed_p ();
-  enum machine_mode imode;
+  machine_mode imode;
   struct alg_hash_entry *entry_ptr;
 
   /* Indicate that no algorithm is yet found.  If no algorithm
@@ -2851,7 +2847,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
    describing the algorithm in *ALG and final fixup in *VARIANT.  */
 
 static bool
-choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
+choose_mult_variant (machine_mode mode, HOST_WIDE_INT val,
                     struct algorithm *alg, enum mult_variant *variant,
                     int mult_cost)
 {
@@ -2927,14 +2923,15 @@ choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
    the final fixup specified by VARIANT.  */
 
 static rtx
-expand_mult_const (enum machine_mode mode, rtx op0, HOST_WIDE_INT val,
+expand_mult_const (machine_mode mode, rtx op0, HOST_WIDE_INT val,
                   rtx target, const struct algorithm *alg,
                   enum mult_variant variant)
 {
   HOST_WIDE_INT val_so_far;
-  rtx insn, accum, tem;
+  rtx_insn *insn;
+  rtx accum, tem;
   int opno;
-  enum machine_mode nmode;
+  machine_mode nmode;
 
   /* Avoid referencing memory over and over and invalid sharing
      on SUBREGs.  */
@@ -3079,7 +3076,7 @@ expand_mult_const (enum machine_mode mode, rtx op0, HOST_WIDE_INT val,
    you should swap the two operands if OP0 would be constant.  */
 
 rtx
-expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
+expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
             int unsignedp)
 {
   enum mult_variant variant;
@@ -3248,7 +3245,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
    COEFFicient in the given MODE and SPEED.  */
 
 int
-mult_by_coeff_cost (HOST_WIDE_INT coeff, enum machine_mode mode, bool speed)
+mult_by_coeff_cost (HOST_WIDE_INT coeff, machine_mode mode, bool speed)
 {
   int max_cost;
   struct algorithm algorithm;
@@ -3273,7 +3270,7 @@ mult_by_coeff_cost (HOST_WIDE_INT coeff, enum machine_mode mode, bool speed)
    and adds.  */
 
 rtx
-expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
+expand_widening_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
                      int unsignedp, optab this_optab)
 {
   bool speed = optimize_insn_for_speed_p ();
@@ -3426,7 +3423,7 @@ invert_mod2n (unsigned HOST_WIDE_INT x, int n)
    MODE is the mode of operation.  */
 
 rtx
-expand_mult_highpart_adjust (enum machine_mode mode, rtx adj_operand, rtx op0,
+expand_mult_highpart_adjust (machine_mode mode, rtx adj_operand, rtx op0,
                             rtx op1, rtx target, int unsignedp)
 {
   rtx tem;
@@ -3451,9 +3448,9 @@ expand_mult_highpart_adjust (enum machine_mode mode, rtx adj_operand, rtx op0,
 /* Subroutine of expmed_mult_highpart.  Return the MODE high part of OP.  */
 
 static rtx
-extract_high_half (enum machine_mode mode, rtx op)
+extract_high_half (machine_mode mode, rtx op)
 {
-  enum machine_mode wider_mode;
+  machine_mode wider_mode;
 
   if (mode == word_mode)
     return gen_highpart (mode, op);
@@ -3470,11 +3467,11 @@ extract_high_half (enum machine_mode mode, rtx op)
    optab.  OP1 is an rtx for the constant operand.  */
 
 static rtx
-expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
+expmed_mult_highpart_optab (machine_mode mode, rtx op0, rtx op1,
                            rtx target, int unsignedp, int max_cost)
 {
   rtx narrow_op1 = gen_int_mode (INTVAL (op1), mode);
-  enum machine_mode wider_mode;
+  machine_mode wider_mode;
   optab moptab;
   rtx tem;
   int size;
@@ -3529,7 +3526,8 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
       && (mul_cost (speed, wider_mode) + shift_cost (speed, mode, size-1)
          < max_cost))
     {
-      rtx insns, wop0, wop1;
+      rtx_insn *insns;
+      rtx wop0, wop1;
 
       /* We need to widen the operands, for example to ensure the
         constant multiplier is correctly sign or zero extended.
@@ -3584,10 +3582,10 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
    MAX_COST is the total allowed cost for the expanded RTL.  */
 
 static rtx
-expmed_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
+expmed_mult_highpart (machine_mode mode, rtx op0, rtx op1,
                      rtx target, int unsignedp, int max_cost)
 {
-  enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
+  machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
   unsigned HOST_WIDE_INT cnst1;
   int extra_cost;
   bool sign_adjust = false;
@@ -3648,9 +3646,10 @@ expmed_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
 /* Expand signed modulus of OP0 by a power of two D in mode MODE.  */
 
 static rtx
-expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
+expand_smod_pow2 (machine_mode mode, rtx op0, HOST_WIDE_INT d)
 {
-  rtx result, temp, shift, label;
+  rtx result, temp, shift;
+  rtx_code_label *label;
   int logd;
   int prec = GET_MODE_PRECISION (mode);
 
@@ -3744,9 +3743,10 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
    This routine is only called for positive values of D.  */
 
 static rtx
-expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
+expand_sdiv_pow2 (machine_mode mode, rtx op0, HOST_WIDE_INT d)
 {
-  rtx temp, label;
+  rtx temp;
+  rtx_code_label *label;
   int logd;
 
   logd = floor_log2 (d);
@@ -3779,7 +3779,7 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
                                     mode, temp, temp2, mode, 0);
       if (temp2)
        {
-         rtx seq = get_insns ();
+         rtx_insn *seq = get_insns ();
          end_sequence ();
          emit_insn (seq);
          return expand_shift (RSHIFT_EXPR, mode, temp2, logd, NULL_RTX, 0);
@@ -3795,8 +3795,9 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
 
       temp = gen_reg_rtx (mode);
       temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, -1);
-      if (shift_cost (optimize_insn_for_speed_p (), mode, ushift)
-         > COSTS_N_INSNS (1))
+      if (GET_MODE_BITSIZE (mode) >= BITS_PER_WORD
+         || shift_cost (optimize_insn_for_speed_p (), mode, ushift)
+            > COSTS_N_INSNS (1))
        temp = expand_binop (mode, and_optab, temp, gen_int_mode (d - 1, mode),
                             NULL_RTX, 0, OPTAB_LIB_WIDEN);
       else
@@ -3854,15 +3855,15 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
    */
 
 rtx
-expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
               rtx op0, rtx op1, rtx target, int unsignedp)
 {
-  enum machine_mode compute_mode;
+  machine_mode compute_mode;
   rtx tquotient;
   rtx quotient = 0, remainder = 0;
-  rtx last;
+  rtx_insn *last;
   int size;
-  rtx insn;
+  rtx_insn *insn;
   optab optab1, optab2;
   int op1_is_constant, op1_is_pow2 = 0;
   int max_cost, extra_cost;
@@ -4480,7 +4481,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
            /* This could be computed with a branch-less sequence.
               Save that for later.  */
            rtx tem;
-           rtx label = gen_label_rtx ();
+           rtx_code_label *label = gen_label_rtx ();
            do_cmp_and_jump (remainder, const0_rtx, EQ, compute_mode, label);
            tem = expand_binop (compute_mode, xor_optab, op0, op1,
                                NULL_RTX, 0, OPTAB_WIDEN);
@@ -4494,7 +4495,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
        /* No luck with division elimination or divmod.  Have to do it
           by conditionally adjusting op0 *and* the result.  */
        {
-         rtx label1, label2, label3, label4, label5;
+         rtx_code_label *label1, *label2, *label3, *label4, *label5;
          rtx adjusted_op0;
          rtx tem;
 
@@ -4555,7 +4556,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
                                      compute_mode, 1, 1);
                if (t3 == 0)
                  {
-                   rtx lab;
+                   rtx_code_label *lab;
                    lab = gen_label_rtx ();
                    do_cmp_and_jump (t2, const0_rtx, EQ, compute_mode, lab);
                    expand_inc (t1, const1_rtx);
@@ -4595,7 +4596,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
              {
                /* This could be computed with a branch-less sequence.
                   Save that for later.  */
-               rtx label = gen_label_rtx ();
+               rtx_code_label *label = gen_label_rtx ();
                do_cmp_and_jump (remainder, const0_rtx, EQ,
                                 compute_mode, label);
                expand_inc (quotient, const1_rtx);
@@ -4607,7 +4608,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
            /* No luck with division elimination or divmod.  Have to do it
               by conditionally adjusting op0 *and* the result.  */
            {
-             rtx label1, label2;
+             rtx_code_label *label1, *label2;
              rtx adjusted_op0, tem;
 
              quotient = gen_reg_rtx (compute_mode);
@@ -4652,7 +4653,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
                                      compute_mode, 1, 1);
                if (t3 == 0)
                  {
-                   rtx lab;
+                   rtx_code_label *lab;
                    lab = gen_label_rtx ();
                    do_cmp_and_jump (t2, const0_rtx, EQ, compute_mode, lab);
                    expand_inc (t1, const1_rtx);
@@ -4692,7 +4693,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
                /* This could be computed with a branch-less sequence.
                   Save that for later.  */
                rtx tem;
-               rtx label = gen_label_rtx ();
+               rtx_code_label *label = gen_label_rtx ();
                do_cmp_and_jump (remainder, const0_rtx, EQ,
                                 compute_mode, label);
                tem = expand_binop (compute_mode, xor_optab, op0, op1,
@@ -4707,7 +4708,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
            /* No luck with division elimination or divmod.  Have to do it
               by conditionally adjusting op0 *and* the result.  */
            {
-             rtx label1, label2, label3, label4, label5;
+             rtx_code_label *label1, *label2, *label3, *label4, *label5;
              rtx adjusted_op0;
              rtx tem;
 
@@ -4782,7 +4783,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
        if (unsignedp)
          {
            rtx tem;
-           rtx label;
+           rtx_code_label *label;
            label = gen_label_rtx ();
            quotient = gen_reg_rtx (compute_mode);
            remainder = gen_reg_rtx (compute_mode);
@@ -4805,7 +4806,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
        else
          {
            rtx abs_rem, abs_op1, tem, mask;
-           rtx label;
+           rtx_code_label *label;
            label = gen_label_rtx ();
            quotient = gen_reg_rtx (compute_mode);
            remainder = gen_reg_rtx (compute_mode);
@@ -5091,7 +5092,7 @@ make_tree (tree type, rtx x)
    If TARGET is 0, a pseudo-register or constant is returned.  */
 
 rtx
-expand_and (enum machine_mode mode, rtx op0, rtx op1, rtx target)
+expand_and (machine_mode mode, rtx op0, rtx op1, rtx target)
 {
   rtx tem = 0;
 
@@ -5108,15 +5109,16 @@ expand_and (enum machine_mode mode, rtx op0, rtx op1, rtx target)
 }
 
 /* Helper function for emit_store_flag.  */
-static rtx
+rtx
 emit_cstore (rtx target, enum insn_code icode, enum rtx_code code,
-            enum machine_mode mode, enum machine_mode compare_mode,
+            machine_mode mode, machine_mode compare_mode,
             int unsignedp, rtx x, rtx y, int normalizep,
-            enum machine_mode target_mode)
+            machine_mode target_mode)
 {
   struct expand_operand ops[4];
-  rtx op0, last, comparison, subtarget;
-  enum machine_mode result_mode = targetm.cstore_mode (icode);
+  rtx op0, comparison, subtarget;
+  rtx_insn *last;
+  machine_mode result_mode = targetm.cstore_mode (icode);
 
   last = get_last_insn ();
   x = prepare_operand (icode, x, 2, mode, compare_mode, unsignedp);
@@ -5211,12 +5213,12 @@ emit_cstore (rtx target, enum insn_code icode, enum rtx_code code,
 
 static rtx
 emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
-                  enum machine_mode mode, int unsignedp, int normalizep,
-                  enum machine_mode target_mode)
+                  machine_mode mode, int unsignedp, int normalizep,
+                  machine_mode target_mode)
 {
   rtx subtarget;
   enum insn_code icode;
-  enum machine_mode compare_mode;
+  machine_mode compare_mode;
   enum mode_class mclass;
   enum rtx_code scode;
   rtx tem;
@@ -5373,7 +5375,7 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
   for (compare_mode = mode; compare_mode != VOIDmode;
        compare_mode = GET_MODE_WIDER_MODE (compare_mode))
     {
-     enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
+     machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
      icode = optab_handler (cstore_optab, optab_mode);
      if (icode != CODE_FOR_nothing)
        {
@@ -5414,12 +5416,13 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
 
 rtx
 emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
-                enum machine_mode mode, int unsignedp, int normalizep)
+                machine_mode mode, int unsignedp, int normalizep)
 {
-  enum machine_mode target_mode = target ? GET_MODE (target) : VOIDmode;
+  machine_mode target_mode = target ? GET_MODE (target) : VOIDmode;
   enum rtx_code rcode;
   rtx subtarget;
-  rtx tem, last, trueval;
+  rtx tem, trueval;
+  rtx_insn *last;
 
   /* If we compare constants, we shouldn't use a store-flag operation,
      but a constant load.  We can get there via the vanilla route that
@@ -5745,9 +5748,10 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
 
 rtx
 emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1,
-                      enum machine_mode mode, int unsignedp, int normalizep)
+                      machine_mode mode, int unsignedp, int normalizep)
 {
-  rtx tem, label;
+  rtx tem;
+  rtx_code_label *label;
   rtx trueval, falseval;
 
   /* First see if emit_store_flag can do the job.  */
@@ -5820,8 +5824,8 @@ emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1,
    now a thin wrapper around do_compare_rtx_and_jump.  */
 
 static void
-do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, enum machine_mode mode,
-                rtx label)
+do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, machine_mode mode,
+                rtx_code_label *label)
 {
   int unsignedp = (op == LTU || op == LEU || op == GTU || op == GEU);
   do_compare_rtx_and_jump (arg1, arg2, op, unsignedp, mode,