]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Replace insn_foo with insn_data.foo.
authorRichard Henderson <rth@cygnus.com>
Sun, 12 Sep 1999 12:46:08 +0000 (05:46 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 12 Sep 1999 12:46:08 +0000 (05:46 -0700)
From-SVN: r29358

33 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/combine.c
gcc/config/c4x/c4x.c
gcc/config/i860/i860.c
gcc/cse.c
gcc/explow.c
gcc/expmed.c
gcc/expr.c
gcc/expr.h
gcc/final.c
gcc/function.c
gcc/genattr.c
gcc/genattrtab.c
gcc/gencodes.c
gcc/genconfig.c
gcc/genemit.c
gcc/genextract.c
gcc/genflags.c
gcc/genopinit.c
gcc/genoutput.c
gcc/genpeep.c
gcc/genrecog.c
gcc/loop.c
gcc/optabs.c
gcc/print-rtl.c
gcc/recog.c
gcc/recog.h
gcc/regmove.c
gcc/reload.c
gcc/reload1.c
gcc/stmt.c
gcc/toplev.c

index 28a5ebbd85adfe2f87e83c68de96833075d12e85..4ba402ee2cda8e724eb79283509eb8f670eec606 100644 (file)
@@ -1,3 +1,87 @@
+Sun Sep 12 05:00:24 1999  Richard Henderson  <rth@cygnus.com>
+
+       * recog.h (insn_template, insn_outfun, insn_n_operands, insn_n_dups,
+       insn_n_alternatives, insn_operand_constraint, insn_operand_address_p,
+       insn_operand_mode, insn_operand_strict_low, insn_operand_predicate,
+       insn_name): Delete and consolidate into new structures.
+       (insn_operand_predicate_fn): New.
+       (insn_output_fn): New.
+       (insn_gen_fn): New.
+       (struct insn_operand_data): New.
+       (struct insn_data): New.
+       (insn_data): New.
+       (OUT_FCN): Update for insn_data change.
+       * builtins.c (expand_builtin_strlen): Likewise.
+       (expand_builtin_memcmp): Likewise.
+       * combine.c (make_extraction, simplify_comparison): Likewise.
+       * cse.c (canon_reg, cse_insn): Likewise.
+       * explow.c (allocate_dynamic_stack_space, probe_stack_range): Likewise.
+       * expmed.c (store_bit_field, extract_bit_field): Likewise.
+       (emit_store_flag): Likewise.
+       * expr.c (convert_move, emit_block_move): Likewise.
+       (clear_storage, emit_push_insn, expand_increment): Likewise.
+       (do_store_flag): Likewise.
+       * expr.h (GEN_FCN): Likewise.
+       (insn_gen_function): Die.
+       * final.c (final_scan_insn): Update for insn_data change.
+       (output_asm_name): Likewise.
+       * function.c (fixup_var_refs_1): Likewise.
+       * loop.c (check_dbra_loop): Likewise.
+       * optabs.c (expand_binop, expand_twoval_binop): Likewise.
+       (expand_unop, expand_complex_abs, emit_unop_insn): Likewise.
+       (prepare_cmp_insn, prepare_operand, emit_indirect_jump): Likewise.
+       (emit_conditional_move, gen_add2_insn, gen_sub2_insn): Likewise.
+       * recog.c (validate_replace_rtx_1, extract_insn): Likewise.
+       * regmove.c (gen_add3_insn): Likewise.
+       * reload.c (push_secondary_reload, combine_reloads): Likewise.
+       (find_reloads, find_reloads_address_1): Likewise.
+       (debug_reload_to_stream): Likewise.
+       * reload1.c (emit_reload_insns, gen_reload): Likewise.
+       * stmt.c (expand_end_case): Likewise.
+       * toplev.c (compile_file): Likewise.
+
+       * c4x/c4x.c (c4x_process_after_reload): Likewise.
+       * i860/i860.c (output_delayed_branch, output_delay_insn): Likewise.
+
+       * print-rtl.c (insn_name_ptr): Remove declaration.
+       (get_insn_name): Declare.
+       (print_rtx): Use it.
+       * genoutput.c (insn_name_ptr): Remove.
+       (next_operand_number): New.
+       (struct operand_data): New.
+       (null_operand, odata, odata_end): New.
+       (struct data): Use struct operand_data.
+       (idata, idata_end): Renamed from insn_data and end_of_insn_data.
+       (get_insn_name): Renamed from name_for_index.
+       (output_prologue): Define NO_MD_PROTOTYPES.
+       (output_predicate_decls): Break out from output_epilogue.
+       Iterate over the operands list.
+       (output_operand_data): Break out from output_epilogue.  Emit
+       just the operands list.
+       (output_insn_data): Break out from output_epilogue.  Emit just
+       the insn data.
+       (output_epilogue): Remove.
+       (output_get_insn_name): New.
+       (constraints, op_n_alternatives, predicates, address_p): Die.
+       (modes, strict_low, seen): Die.
+       (scan_operands): Take new param `d' instead of writing to 
+       seven global variables.
+       (compare_operands): New.
+       (place_operands): New.
+       (validate_insn_alternatives): Update for struct data change.
+       (gen_insn): Don't zero or copy 7 global arrays.  Update for
+       scan_operands; call place_operands.
+       (gen_peephole, gen_expand, gen_split): Likewise.
+       (main): Update for new output routines.
+
+       * genattr.c (insn_name_ptr): Remove.
+       (get_insn_name): New function.
+       * genattrtab.c, gencodes.c, genconfig.c, genemit.c: Likewise.
+       * genextract.c, genflags.c, genopinit.c, genpeep.c: Likewise.
+       * genrecog.c: Likewise.
+
+       * alpha.md (adddi3): Make `pattern' array static.
+
 Sun Sep 12 22:05:21 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
 
        * config/c4x/c4x.h (c4x_rpts_cycles_string,
index a77b0f860a62f92aeb649d2f055a4f22dba7937d..2d211f9c1a51dbe3f386fbf137ac1fc62ac05039 100644 (file)
@@ -1334,13 +1334,13 @@ expand_builtin_strlen (exp, target, mode)
 
       /* Make sure the operands are acceptable to the predicates.  */
 
-      if (! (*insn_operand_predicate[(int)icode][0]) (result, insn_mode))
+      if (! (*insn_data[(int)icode].operand[0].predicate) (result, insn_mode))
        result = gen_reg_rtx (insn_mode);
       src_rtx = memory_address (BLKmode,
                                expand_expr (src, NULL_RTX, ptr_mode,
                                             EXPAND_NORMAL));
 
-      if (! (*insn_operand_predicate[(int)icode][1]) (src_rtx, Pmode))
+      if (! (*insn_data[(int)icode].operand[1].predicate) (src_rtx, Pmode))
        src_rtx = copy_to_mode_reg (Pmode, src_rtx);
 
       /* Check the string is readable and has an end.  */
@@ -1351,8 +1351,8 @@ expand_builtin_strlen (exp, target, mode)
                           TYPE_MODE (integer_type_node));
 
       char_rtx = const0_rtx;
-      char_mode = insn_operand_mode[(int)icode][2];
-      if (! (*insn_operand_predicate[(int)icode][2]) (char_rtx, char_mode))
+      char_mode = insn_data[(int)icode].operand[2].mode;
+      if (! (*insn_data[(int)icode].operand[2].predicate) (char_rtx, char_mode))
        char_rtx = copy_to_mode_reg (char_mode, char_rtx);
 
       emit_insn (GEN_FCN (icode) (result,
@@ -1572,7 +1572,7 @@ expand_builtin_memcmp (exp, arglist, target)
     int arg2_align
       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
     enum machine_mode insn_mode
-      = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
+      = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
 
     /* If we don't have POINTER_TYPE, call the function.  */
     if (arg1_align == 0 || arg2_align == 0)
index b0646c21b0b041748a05132b855f381c22419e23..56a373b3805baa7a58cf0fe12e8a155cedcdf68c 100644 (file)
@@ -5752,14 +5752,17 @@ make_extraction (mode, inner, pos, pos_rtx, len,
   if (in_dest)
     {
       wanted_inner_reg_mode
-       = (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode
-          ? word_mode
-          : insn_operand_mode[(int) CODE_FOR_insv][0]);
-      pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode
-                 ? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]);
-      extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode
-                        ? word_mode
-                        : insn_operand_mode[(int) CODE_FOR_insv][3]);
+       = insn_data[(int) CODE_FOR_insv].operand[0].mode;
+      if (wanted_inner_reg_mode == VOIDmode)
+       wanted_inner_reg_mode = word_mode;
+
+      pos_mode = insn_data[(int) CODE_FOR_insv].operand[2].mode;
+      if (pos_mode == VOIDmode)
+       pos_mode = word_mode;
+
+      extraction_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
+      if (extraction_mode == VOIDmode)
+       extraction_mode = word_mode;
     }
 #endif
 
@@ -5767,14 +5770,17 @@ make_extraction (mode, inner, pos, pos_rtx, len,
   if (! in_dest && unsignedp)
     {
       wanted_inner_reg_mode
-       = (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode
-          ? word_mode
-          : insn_operand_mode[(int) CODE_FOR_extzv][1]);
-      pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode
-                 ? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]);
-      extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode
-                        ? word_mode
-                        : insn_operand_mode[(int) CODE_FOR_extzv][0]);
+       = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
+      if (wanted_inner_reg_mode == VOIDmode)
+       wanted_inner_reg_mode = word_mode;
+
+      pos_mode = insn_data[(int) CODE_FOR_extzv].operand[3].mode;
+      if (pos_mode == VOIDmode)
+       pos_mode = word_mode;
+
+      extraction_mode = insn_data[(int) CODE_FOR_extzv].operand[0].mode;
+      if (extraction_mode == VOIDmode)
+       extraction_mode = word_mode;
     }
 #endif
 
@@ -5782,14 +5788,17 @@ make_extraction (mode, inner, pos, pos_rtx, len,
   if (! in_dest && ! unsignedp)
     {
       wanted_inner_reg_mode
-       = (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode
-          ? word_mode
-          : insn_operand_mode[(int) CODE_FOR_extv][1]);
-      pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode
-                 ? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]);
-      extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode
-                        ? word_mode
-                        : insn_operand_mode[(int) CODE_FOR_extv][0]);
+       = insn_data[(int) CODE_FOR_extv].operand[1].mode;
+      if (wanted_inner_reg_mode == VOIDmode)
+       wanted_inner_reg_mode = word_mode;
+
+      pos_mode = insn_data[(int) CODE_FOR_extv].operand[3].mode;
+      if (pos_mode == VOIDmode)
+       pos_mode = word_mode;
+
+      extraction_mode = insn_data[(int) CODE_FOR_extv].operand[0].mode;
+      if (extraction_mode == VOIDmode)
+       extraction_mode = word_mode;
     }
 #endif
 
@@ -9901,7 +9910,7 @@ simplify_comparison (code, pop0, pop1)
              if (BITS_BIG_ENDIAN)
                {
 #ifdef HAVE_extzv
-                 mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+                 mode = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
                  if (mode == VOIDmode)
                    mode = word_mode;
                  i = (GET_MODE_BITSIZE (mode) - 1 - i);
index 7712695c9107ceb7b36226d2091fcef0f69e2727..b3f5a54345eda6609e16c7b174f3f036b913ee08 100644 (file)
@@ -2196,7 +2196,7 @@ c4x_process_after_reload (first)
            {
              const char *template;
 
-             template = insn_template[insn_code_number];
+             template = insn_data[insn_code_number].template;
              if (template && template[0] == '#' && template[1] == '\0')
                {
                  rtx new = try_split (PATTERN(insn), insn, 0);
index cb7e7f7ba28388178b8d65fd8ba1ae93516d8e65..a6e9458a8b928046bddaf49c56bd1db4694c9e70 100644 (file)
@@ -1446,7 +1446,7 @@ output_delayed_branch (template, operands, insn)
       if (insn_code_number == -1)
        abort ();
 
-      for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+      for (i = 0; i < insn_data[insn_code_number].n_operands; i++)
        {
          if (GET_CODE (recog_data.operand[i]) == SUBREG)
            recog_data.operand[i] = alter_subreg (recog_data.operand[i]);
@@ -1456,9 +1456,9 @@ output_delayed_branch (template, operands, insn)
       if (! constrain_operands (1))
        fatal_insn_not_found (delay_insn);
 
-      template = insn_template[insn_code_number];
+      template = insn_data[insn_code_number].template;
       if (template == 0)
-       template = ((*insn_outfun[insn_code_number])
+       template = ((*insn_data[insn_code_number].outfun)
                    (recog_data.operand, delay_insn));
       output_asm_insn (template, recog_data.operand);
     }
@@ -1490,7 +1490,7 @@ output_delay_insn (delay_insn)
      yet.  If this insn's operands don't appear in the peephole's
      actual operands, then they won't be fixed up by final, so we
      make sure they get fixed up here.  -- This is a kludge.  */
-  for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+  for (i = 0; i < insn_data[insn_code_number].n_operands; i++)
     {
       if (GET_CODE (recog_data.operand[i]) == SUBREG)
        recog_data.operand[i] = alter_subreg (recog_data.operand[i]);
@@ -1513,9 +1513,9 @@ output_delay_insn (delay_insn)
   /* Now get the template for what this insn would
      have been, without the branch.  */
 
-  template = insn_template[insn_code_number];
+  template = insn_data[insn_code_number].template;
   if (template == 0)
-    template = ((*insn_outfun[insn_code_number])
+    template = ((*insn_data[insn_code_number].outfun)
                (recog_data.operand, delay_insn));
   output_asm_insn (template, recog_data.operand);
   return "";
index e07e3384cc80d0cf40bd484f4dbe4ff6dd60bc5e..75952b0e128b9cf51c6645a0716c4c3dd3df0180 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2783,7 +2783,7 @@ canon_reg (x, insn)
              && (((REGNO (new) < FIRST_PSEUDO_REGISTER)
                   != (REGNO (XEXP (x, i)) < FIRST_PSEUDO_REGISTER))
                  || (insn_code = recog_memoized (insn)) < 0
-                 || insn_n_dups[insn_code] > 0))
+                 || insn_data[insn_code].n_dups > 0))
            validate_change (insn, &XEXP (x, i), new, 1);
          else
            XEXP (x, i) = new;
@@ -6568,7 +6568,7 @@ cse_insn (insn, libcall_insn)
           && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
               != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
          || (insn_code = recog_memoized (insn)) < 0
-         || insn_n_dups[insn_code] > 0)
+         || insn_data[insn_code].n_dups > 0)
        validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
       else
        SET_SRC (sets[i].rtl) = new;
index 3af4c2c06a88fbb7f36ef33dcc8bc9d9eb30b771..573c5295ede332bc06c9d4b544ac917ea6ee3583 100644 (file)
@@ -1305,10 +1305,10 @@ allocate_dynamic_stack_space (size, target, known_align)
   if (HAVE_allocate_stack)
     {
       enum machine_mode mode = STACK_SIZE_MODE;
+      insn_operand_predicate_fn pred;
 
-      if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][0]
-         && ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][0])
-               (target, Pmode)))
+      pred = insn_data[(int) CODE_FOR_allocate_stack].operand[0].predicate;
+      if (pred && ! ((*pred) (target, Pmode)))
 #ifdef POINTERS_EXTEND_UNSIGNED
        target = convert_memory_address (Pmode, target);
 #else
@@ -1319,9 +1319,8 @@ allocate_dynamic_stack_space (size, target, known_align)
        mode = Pmode;
 
       size = convert_modes (mode, ptr_mode, size, 1);
-      if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][1]
-         && ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][1])
-               (size, mode)))
+      pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate;
+      if (pred && ! ((*pred) (size, mode)))
        size = copy_to_mode_reg (mode, size);
 
       emit_insn (gen_allocate_stack (target, size));
@@ -1416,15 +1415,15 @@ probe_stack_range (first, size)
 #ifdef HAVE_check_stack
   if (HAVE_check_stack)
     {
+      insn_operand_predicate_fn pred;
       rtx last_addr
        = force_operand (gen_rtx_STACK_GROW_OP (Pmode,
                                                stack_pointer_rtx,
                                                plus_constant (size, first)),
                         NULL_RTX);
 
-      if (insn_operand_predicate[(int) CODE_FOR_check_stack][0]
-         && ! ((*insn_operand_predicate[(int) CODE_FOR_check_stack][0])
-               (last_addr, Pmode)))
+      pred = insn_data[(int) CODE_FOR_check_stack].operand[0].predicate;
+      if (pred && ! ((*pred) (last_addr, Pmode)))
        last_addr = copy_to_mode_reg (Pmode, last_addr);
 
       emit_insn (gen_check_stack (last_addr));
index 2138ad189af5f3b0dc2a40212b96b37fbcdf925c..1ac3272e80a54e56f9e3fc0999c577e116aea6e9 100644 (file)
@@ -234,11 +234,12 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
   register rtx op0 = str_rtx;
 #ifdef HAVE_insv
   int insv_bitsize;
+  enum machine_mode op_mode;
 
-  if (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode)
-    insv_bitsize = GET_MODE_BITSIZE (word_mode);
-  else
-    insv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]);
+  op_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
+  if (op_mode == VOIDmode)
+    op_mode = word_mode;
+  insv_bitsize = GET_MODE_BITSIZE (op_mode);
 #endif
 
   if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
@@ -349,7 +350,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       else
        {
          int icode = movstrict_optab->handlers[(int) fieldmode].insn_code;
-         if (! (*insn_operand_predicate[icode][1]) (value, fieldmode))
+         if (! (*insn_data[icode].operand[1].predicate) (value, fieldmode))
            value = copy_to_mode_reg (fieldmode, value);
 
          if (GET_CODE (op0) == SUBREG)
@@ -478,7 +479,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       enum machine_mode maxmode;
       int save_volatile_ok = volatile_ok;
 
-      maxmode = insn_operand_mode[(int) CODE_FOR_insv][3];
+      maxmode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
       if (maxmode == VOIDmode)
        maxmode = word_mode;
 
@@ -489,7 +490,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       /* This used to check flag_force_mem, but that was a serious
         de-optimization now that flag_force_mem is enabled by -O2.  */
       if (GET_CODE (op0) == MEM
-         && ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
+         && ! ((*insn_data[(int) CODE_FOR_insv].operand[0].predicate)
                (op0, VOIDmode)))
        {
          rtx tempreg;
@@ -586,7 +587,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
 
       /* If this machine's insv insists on a register,
         get VALUE1 into a register.  */
-      if (! ((*insn_operand_predicate[(int) CODE_FOR_insv][3])
+      if (! ((*insn_data[(int) CODE_FOR_insv].operand[3].predicate)
             (value1, maxmode)))
        value1 = force_reg (maxmode, value1);
 
@@ -963,24 +964,25 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
   rtx spec_target_subreg = 0;
 #ifdef HAVE_extv
   int extv_bitsize;
+  enum machine_mode extv_mode;
 #endif
 #ifdef HAVE_extzv
   int extzv_bitsize;
+  enum machine_mode extzv_mode;
 #endif
 
 #ifdef HAVE_extv
-  if (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode)
-    extv_bitsize = GET_MODE_BITSIZE (word_mode);
-  else
-    extv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]);
+  extv_mode = insn_data[(int) CODE_FOR_extv].operand[0].mode;
+  if (extv_mode == VOIDmode)
+    extv_mode = word_mode;
+  extv_bitsize = GET_MODE_BITSIZE (extv_mode);
 #endif
 
 #ifdef HAVE_extzv
-  if (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode)
-    extzv_bitsize = GET_MODE_BITSIZE (word_mode);
-  else
-    extzv_bitsize
-      = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]);
+  extzv_mode = insn_data[(int) CODE_FOR_extzv].operand[0].mode;
+  if (extzv_mode == VOIDmode)
+    extzv_mode = word_mode;
+  extzv_bitsize = GET_MODE_BITSIZE (extzv_mode);
 #endif
 
   /* Discount the part of the structure before the desired byte.
@@ -1210,7 +1212,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
          rtx pat;
          enum machine_mode maxmode;
 
-         maxmode = insn_operand_mode[(int) CODE_FOR_extzv][0];
+         maxmode = insn_data[(int) CODE_FOR_extzv].operand[0].mode;
          if (maxmode == VOIDmode)
            maxmode = word_mode;
 
@@ -1220,7 +1222,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
              volatile_ok = 1;
 
              /* Is the memory operand acceptable?  */
-             if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][1])
+             if (! ((*insn_data[(int) CODE_FOR_extzv].operand[1].predicate)
                     (xop0, GET_MODE (xop0))))
                {
                  /* No, load into a reg and extract from there.  */
@@ -1304,7 +1306,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
 
          /* If this machine's extzv insists on a register target,
             make sure we have one.  */
-         if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
+         if (! ((*insn_data[(int) CODE_FOR_extzv].operand[0].predicate)
                 (xtarget, maxmode)))
            xtarget = gen_reg_rtx (maxmode);
 
@@ -1350,14 +1352,14 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
          rtx pat;
          enum machine_mode maxmode;
 
-         maxmode = insn_operand_mode[(int) CODE_FOR_extv][0];
+         maxmode = insn_data[(int) CODE_FOR_extv].operand[0].mode;
          if (maxmode == VOIDmode)
            maxmode = word_mode;
 
          if (GET_CODE (xop0) == MEM)
            {
              /* Is the memory operand acceptable?  */
-             if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][1])
+             if (! ((*insn_data[(int) CODE_FOR_extv].operand[1].predicate)
                     (xop0, GET_MODE (xop0))))
                {
                  /* No, load into a reg and extract from there.  */
@@ -1440,7 +1442,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
 
          /* If this machine's extv insists on a register target,
             make sure we have one.  */
-         if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
+         if (! ((*insn_data[(int) CODE_FOR_extv].operand[0].predicate)
                 (xtarget, maxmode)))
            xtarget = gen_reg_rtx (maxmode);
 
@@ -4210,6 +4212,8 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
 
   if (icode != CODE_FOR_nothing)
     {
+      insn_operand_predicate_fn pred;
+
       /* We think we may be able to do this with a scc insn.  Emit the
         comparison and then the scc insn.
 
@@ -4235,10 +4239,11 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
        abort ();
 
       /* Get a reference to the target in the proper mode for this insn.  */
-      compare_mode = insn_operand_mode[(int) icode][0];
+      compare_mode = insn_data[(int) icode].operand[0].mode;
       subtarget = target;
+      pred = insn_data[(int) icode].operand[0].predicate;
       if (preserve_subexpressions_p ()
-         || ! (*insn_operand_predicate[(int) icode][0]) (subtarget, compare_mode))
+         || ! (*pred) (subtarget, compare_mode))
        subtarget = gen_reg_rtx (compare_mode);
 
       pattern = GEN_FCN (icode) (subtarget);
index 2f014d345e1a4a9f6434b8afd64be7a8a8be5c15..c4d0f143fe823ace687e800b8888097df26295c2 100644 (file)
@@ -818,7 +818,7 @@ convert_move (to, from, unsignedp)
        {
 #ifdef HAVE_slt
          if (HAVE_slt
-             && insn_operand_mode[(int) CODE_FOR_slt][0] == word_mode
+             && insn_data[(int) CODE_FOR_slt].operand[0].mode == word_mode
              && STORE_FLAG_VALUE == -1)
            {
              emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,
@@ -1591,6 +1591,7 @@ emit_block_move (x, y, size, align)
           mode = GET_MODE_WIDER_MODE (mode))
        {
          enum insn_code code = movstr_optab[(int) mode];
+         insn_operand_predicate_fn pred;
 
          if (code != CODE_FOR_nothing
              /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
@@ -1601,21 +1602,20 @@ emit_block_move (x, y, size, align)
                   && ((unsigned HOST_WIDE_INT) INTVAL (size)
                       <= (GET_MODE_MASK (mode) >> 1)))
                  || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
-             && (insn_operand_predicate[(int) code][0] == 0
-                 || (*insn_operand_predicate[(int) code][0]) (x, BLKmode))
-             && (insn_operand_predicate[(int) code][1] == 0
-                 || (*insn_operand_predicate[(int) code][1]) (y, BLKmode))
-             && (insn_operand_predicate[(int) code][3] == 0
-                 || (*insn_operand_predicate[(int) code][3]) (opalign,
-                                                              VOIDmode)))
+             && ((pred = insn_data[(int) code].operand[0].predicate) == 0
+                 || (*pred) (x, BLKmode))
+             && ((pred = insn_data[(int) code].operand[1].predicate) == 0
+                 || (*pred) (y, BLKmode))
+             && ((pred = insn_data[(int) code].operand[3].predicate) == 0
+                 || (*pred) (opalign, VOIDmode)))
            {
              rtx op2;
              rtx last = get_last_insn ();
              rtx pat;
 
              op2 = convert_to_mode (mode, size, 1);
-             if (insn_operand_predicate[(int) code][2] != 0
-                 && ! (*insn_operand_predicate[(int) code][2]) (op2, mode))
+             pred = insn_data[(int) code].operand[2].predicate;
+             if (pred != 0 && ! (*pred) (op2, mode))
                op2 = copy_to_mode_reg (mode, op2);
 
              pat = GEN_FCN ((int) code) (x, y, op2, opalign);
@@ -2365,6 +2365,7 @@ clear_storage (object, size, align)
               mode = GET_MODE_WIDER_MODE (mode))
            {
              enum insn_code code = clrstr_optab[(int) mode];
+             insn_operand_predicate_fn pred;
 
              if (code != CODE_FOR_nothing
                  /* We don't need MODE to be narrower than
@@ -2375,21 +2376,18 @@ clear_storage (object, size, align)
                       && ((unsigned HOST_WIDE_INT) INTVAL (size)
                           <= (GET_MODE_MASK (mode) >> 1)))
                      || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
-                 && (insn_operand_predicate[(int) code][0] == 0
-                     || (*insn_operand_predicate[(int) code][0]) (object,
-                                                                  BLKmode))
-                 && (insn_operand_predicate[(int) code][2] == 0
-                     || (*insn_operand_predicate[(int) code][2]) (opalign,
-                                                                  VOIDmode)))
+                 && ((pred = insn_data[(int) code].operand[0].predicate) == 0
+                     || (*pred) (object, BLKmode))
+                 && ((pred = insn_data[(int) code].operand[2].predicate) == 0
+                     || (*pred) (opalign, VOIDmode)))
                {
                  rtx op1;
                  rtx last = get_last_insn ();
                  rtx pat;
 
                  op1 = convert_to_mode (mode, size, 1);
-                 if (insn_operand_predicate[(int) code][1] != 0
-                     && ! (*insn_operand_predicate[(int) code][1]) (op1,
-                                                                    mode))
+                 pred = insn_data[(int) code].operand[1].predicate;
+                 if (pred != 0 && ! (*pred) (op1, mode))
                    op1 = copy_to_mode_reg (mode, op1);
 
                  pat = GEN_FCN ((int) code) (object, op1, opalign);
@@ -2984,29 +2982,26 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                   mode = GET_MODE_WIDER_MODE (mode))
                {
                  enum insn_code code = movstr_optab[(int) mode];
+                 insn_operand_predicate_fn pred;
 
                  if (code != CODE_FOR_nothing
                      && ((GET_CODE (size) == CONST_INT
                           && ((unsigned HOST_WIDE_INT) INTVAL (size)
                               <= (GET_MODE_MASK (mode) >> 1)))
                          || GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
-                     && (insn_operand_predicate[(int) code][0] == 0
-                         || ((*insn_operand_predicate[(int) code][0])
-                             (target, BLKmode)))
-                     && (insn_operand_predicate[(int) code][1] == 0
-                         || ((*insn_operand_predicate[(int) code][1])
-                             (xinner, BLKmode)))
-                     && (insn_operand_predicate[(int) code][3] == 0
-                         || ((*insn_operand_predicate[(int) code][3])
-                             (opalign, VOIDmode))))
+                     && (!(pred = insn_data[(int) code].operand[0].predicate)
+                         || ((*pred) (target, BLKmode)))
+                     && (!(pred = insn_data[(int) code].operand[1].predicate)
+                         || ((*pred) (xinner, BLKmode)))
+                     && (!(pred = insn_data[(int) code].operand[3].predicate)
+                         || ((*pred) (opalign, VOIDmode))))
                    {
                      rtx op2 = convert_to_mode (mode, size, 1);
                      rtx last = get_last_insn ();
                      rtx pat;
 
-                     if (insn_operand_predicate[(int) code][2] != 0
-                         && ! ((*insn_operand_predicate[(int) code][2])
-                               (op2, mode)))
+                     pred = insn_data[(int) code].operand[2].predicate;
+                     if (pred != 0 && ! (*pred) (op2, mode))
                        op2 = copy_to_mode_reg (mode, op2);
 
                      pat = GEN_FCN ((int) code) (target, xinner,
@@ -8373,9 +8368,9 @@ expand_increment (exp, post, ignore)
       if (icode != (int) CODE_FOR_nothing
          /* Make sure that OP0 is valid for operands 0 and 1
             of the insn we want to queue.  */
-         && (*insn_operand_predicate[icode][0]) (op0, mode)
-         && (*insn_operand_predicate[icode][1]) (op0, mode)
-         && (*insn_operand_predicate[icode][2]) (op1, mode))
+         && (*insn_data[icode].operand[0].predicate) (op0, mode)
+         && (*insn_data[icode].operand[1].predicate) (op0, mode)
+         && (*insn_data[icode].operand[2].predicate) (op1, mode))
        single_insn = 1;
     }
 
@@ -8429,10 +8424,10 @@ expand_increment (exp, post, ignore)
       if (icode != (int) CODE_FOR_nothing
          /* Make sure that OP0 is valid for operands 0 and 1
             of the insn we want to queue.  */
-         && (*insn_operand_predicate[icode][0]) (op0, mode)
-         && (*insn_operand_predicate[icode][1]) (op0, mode))
+         && (*insn_data[icode].operand[0].predicate) (op0, mode)
+         && (*insn_data[icode].operand[1].predicate) (op0, mode))
        {
-         if (! (*insn_operand_predicate[icode][2]) (op1, mode))
+         if (! (*insn_data[icode].operand[2].predicate) (op1, mode))
            op1 = force_reg (mode, op1);
 
          return enqueue_insn (op0, GEN_FCN (icode) (op0, op0, op1));
@@ -8446,7 +8441,7 @@ expand_increment (exp, post, ignore)
 
          op0 = change_address (op0, VOIDmode, addr);
          temp = force_reg (GET_MODE (op0), op0);
-         if (! (*insn_operand_predicate[icode][2]) (op1, mode))
+         if (! (*insn_data[icode].operand[2].predicate) (op1, mode))
            op1 = force_reg (mode, op1);
 
          /* The increment queue is LIFO, thus we have to `queue'
@@ -9590,7 +9585,7 @@ do_store_flag (exp, target, mode, only_cheap)
     return 0;
   icode = setcc_gen_code[(int) code];
   if (icode == CODE_FOR_nothing
-      || (only_cheap && insn_operand_mode[(int) icode][0] != mode))
+      || (only_cheap && insn_data[(int) icode].operand[0].mode != mode))
     {
       /* We can only do this if it is one of the special cases that
         can be handled without an scc insn.  */
index 26c53cf8dbc826c6676ccd8db7227f3daf074689..53cb9a9bd67f244d803ed23816fa65f70b128b87 100644 (file)
@@ -286,13 +286,11 @@ typedef struct optab
    So produce the pointer-to-function directly.
    Luckily, these compilers seem to work properly when you
    call the pointer-to-function.  */
-#define GEN_FCN(CODE) (insn_gen_function[(int) (CODE)])
+#define GEN_FCN(CODE) (insn_data[(int) (CODE)].genfun)
 #else
-#define GEN_FCN(CODE) (*insn_gen_function[(int) (CODE)])
+#define GEN_FCN(CODE) (*insn_data[(int) (CODE)].genfun)
 #endif
 
-extern rtx (*const insn_gen_function[]) PROTO ((rtx, ...));
-
 /* Enumeration of valid indexes into optab_table.  */
 enum optab_index
 {
index 6ace9b24f940910063291b2afdd9a92a6a197bef..e81895bd3bcc9a244dbf918799da85b5557236dc 100644 (file)
@@ -2898,10 +2898,10 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        /* If the proper template needs to be chosen by some C code,
           run that code and get the real template.  */
 
-       template = insn_template[insn_code_number];
+       template = insn_data[insn_code_number].template;
        if (template == 0)
          {
-           template = ((*insn_outfun[insn_code_number])
+           template = ((*insn_data[insn_code_number].outfun)
                        (recog_data.operand, insn));
 
            /* If the C code returns 0, it means that it is a jump insn
@@ -3359,11 +3359,13 @@ output_asm_name ()
        {
          register int num = INSN_CODE (debug_insn);
          fprintf (asm_out_file, "\t%s %d\t%s", 
-                  ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);
-         if (insn_n_alternatives[num] > 1)
+                  ASM_COMMENT_START, INSN_UID (debug_insn),
+                  insn_data[num].name);
+         if (insn_data[num].n_alternatives > 1)
            fprintf (asm_out_file, "/%d", which_alternative + 1);
 #ifdef HAVE_ATTR_length
-         fprintf (asm_out_file, "\t[length = %d]", get_attr_length (debug_insn));
+         fprintf (asm_out_file, "\t[length = %d]",
+                  get_attr_length (debug_insn));
 #endif
          /* Clear this so only the first assembler insn
             of any rtl insn will get the special comment for -dp.  */
index 213cf63d45e5223cee7dff0d1655133565d051be..d12dd3336f5dbf3db7eaaaffda5cda2c485289f7 100644 (file)
@@ -1831,7 +1831,8 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
 #ifdef HAVE_extzv
              if (GET_CODE (x) == ZERO_EXTRACT)
                {
-                 wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+                 wanted_mode
+                   = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
                  if (wanted_mode == VOIDmode)
                    wanted_mode = word_mode;
                }
@@ -1839,7 +1840,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
 #ifdef HAVE_extv
              if (GET_CODE (x) == SIGN_EXTRACT)
                {
-                 wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
+                 wanted_mode = insn_data[(int) CODE_FOR_extv].operand[1].mode;
                  if (wanted_mode == VOIDmode)
                    wanted_mode = word_mode;
                }
@@ -2034,7 +2035,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
                enum machine_mode is_mode = GET_MODE (tem);
                HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));
 
-               wanted_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
+               wanted_mode = insn_data[(int) CODE_FOR_insv].operand[0].mode;
                if (wanted_mode == VOIDmode)
                  wanted_mode = word_mode;
 
index f9501eda39ebcec1fdcdf509b518db49271c9355..71b2dc0f0b083e988a4126863ecbed4d77d3c51e 100644 (file)
@@ -32,9 +32,6 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
 /* A range of values.  */
 
 struct range
@@ -411,3 +408,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index 4196c7d81246c18c4c5cc7711ccb8e2d43651093..e5a405d610b56037166feac3c620c14cc6940c9a 100644 (file)
@@ -118,9 +118,6 @@ struct obstack *temp_obstack = &obstack2;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
 /* enough space to reserve for printing out ints */
 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
 
@@ -6152,3 +6149,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index 23d06787d9c792cde768c2791fc5a33ec3992096..87f93ab6fb318ca65aec9b0b6b343014548dd20c 100644 (file)
@@ -33,9 +33,6 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
 static int insn_code_number;
 
 static void gen_insn PROTO((rtx));
@@ -142,3 +139,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index a40b6b3f05a0f8687b1f69267b3c73586af3e551..94e2653a3925fbe4bab5f2b27f86e40e80488eb4 100644 (file)
@@ -32,9 +32,6 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
 /* flags to determine output of machine description dependent #define's.  */
 static int max_recog_operands;  /* Largest operand number seen.  */
 static int max_dup_operands;    /* Largest number of match_dup in any insn.  */
@@ -372,3 +369,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index bad78b537f54fc2b46e1d7f6c4cec0b2c9bf60a1..6aec54a2d55ad7812649d83d94fbb7443552fa4a 100644 (file)
@@ -31,9 +31,6 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
 static int max_opno;
 static int max_dup_opno;
 static int max_scratch_opno;
@@ -867,3 +864,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index 35ffbd099bcc996fa739dc7566b106f1b6849180..eeaf52b197a3f79edf38f3d15993d5bc60df4e4c 100644 (file)
@@ -32,9 +32,6 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Names for patterns.  Need to allow linking with print-rtl.  */
-char **insn_name_ptr;
-
 /* This structure contains all the information needed to describe one
    set of extractions methods.  Each method may be used by more than 
    one pattern if the operands are in the same place.
@@ -527,3 +524,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index d8dbf8791ed9bc9f14d94f5d869f201f39ff6e6c..bd3a983fbfda48710cc47267f1a92e834adfdd61 100644 (file)
@@ -33,9 +33,6 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Names for patterns.  Need to allow linking with print-rtl.  */
-char **insn_name_ptr;
-
 /* Obstacks to remember normal, and call insns.  */
 static struct obstack call_obstack, normal_obstack;
 
@@ -278,3 +275,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index 249500549e9fba597a2d0a80dd7cb2f600ea9c3e..ac4a5883e606bd8cc5a6569ddc829f693669aaf6 100644 (file)
@@ -118,9 +118,6 @@ const char *optabs[] =
   "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)",
   "clrstr_optab[(int) %A] = CODE_FOR_%(clrstr%a%)" };
 
-/* Allow linking with print-rtl.c.  */
-char **insn_name_ptr;
-
 static void gen_insn PROTO((rtx));
 
 static void
@@ -363,3 +360,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index 87c8b98a70a0b1649dcb81bbf8cc57440e3917fd..9c44d7e6475cfe7061a07c7bac33a9d7488c8f80 100644 (file)
@@ -1,5 +1,6 @@
 /* Generate code from to output assembler insns as recognized from rtl.
-   Copyright (C) 1987, 88, 92, 94-95, 97-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 92, 94-95, 97-98, 1999
+   Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -22,62 +23,56 @@ Boston, MA 02111-1307, USA.  */
 /* This program reads the machine description for the compiler target machine
    and produces a file containing these things:
 
-   1. An array of strings `insn_template' which is indexed by insn code number
-   and contains the template for output of that insn,
+   1. An array of `struct insn_data', which is indexed by insn code number,
+   which contains:
 
-   2. An array of functions `insn_outfun' which, indexed by the insn code
-   number, gives the function that returns a template to use for output of
-   that insn.  This is used only in the cases where the template is not
-   constant.  These cases are specified by a * or @ at the beginning of the
-   template string in the machine description.  They are identified for the
-   sake of other parts of the compiler by a zero element in `insn_template'.
+     a. `name' is the name for that pattern.  Nameless patterns are
+     given a name.
+
+     b. `template' is the template for output of that insn,
+
+     c. `outfun' is the function that returns a template to use for output of
+     that insn.  This is used only in the cases where the template is not
+     constant.  These cases are specified by a * or @ at the beginning of the
+     template string in the machine description.  They are identified for the
+     sake of other parts of the compiler by a zero element in `template'.
   
-   3. An array of functions `insn_gen_function' which, indexed
-   by insn code number, gives the function to generate a body
-   for that pattern, given operands as arguments.
+     d. `genfun' is the function to generate a body for that pattern,
+     given operands as arguments.
+
+     e. `n_operands' is the number of distinct operands in the pattern
+     for that insn,
 
-   4. An array of strings `insn_name' which, indexed by insn code number,
-   gives the name for that pattern.  Nameless patterns are given a name.
+     f. `n_dups' is the number of match_dup's that appear in the insn's
+     pattern.  This says how many elements of `recog_data.dup_loc' are
+     significant after an insn has been recognized.
 
-   5. An array of ints `insn_n_operands' which is indexed by insn code number
-   and contains the number of distinct operands in the pattern for that insn,
+     g. `n_alternatives' is the number of alternatives in the constraints
+     of each pattern.
 
-   6. An array of ints `insn_n_dups' which is indexed by insn code number
-   and contains the number of match_dup's that appear in the insn's pattern.
-   This says how many elements of `recog_data.dup_loc' are significant
-   after an insn has been recognized.
+     h. `operand' is the base of an array of operand data for the insn.
 
-   7. An array of arrays of operand constraint strings,
-   `insn_operand_constraint',
-   indexed first by insn code number and second by operand number,
-   containing the constraint for that operand.
+   2. An array of `struct insn_operand data', used by `operand' above.
 
-   This array is generated only if register constraints appear in 
-   match_operand rtx's.
+     a. `predicate', an int-valued function, is the match_operand predicate
+     for this operand.
 
-   8. An array of arrays of chars which indicate which operands of
-   which insn patterns appear within ADDRESS rtx's.  This array is
-   called `insn_operand_address_p' and is generated only if there
-   are *no* register constraints in the match_operand rtx's.
+     b. `constraint' is the constraint for this operand.  This exists
+     only if register constraints appear in match_operand rtx's.
 
-   9. An array of arrays of machine modes, `insn_operand_mode',
-   indexed first by insn code number and second by operand number,
-   containing the machine mode that that operand is supposed to have.
-   Also `insn_operand_strict_low', which is nonzero for operands
-   contained in a STRICT_LOW_PART.
+     c. `address_p' indicates that the operand appears within ADDRESS
+     rtx's.  This exists only if there are *no* register constraints
+     in the match_operand rtx's.
 
-   10. An array of arrays of int-valued functions, `insn_operand_predicate',
-   indexed first by insn code number and second by operand number,
-   containing the match_operand predicate for this operand.
+     d. `mode' is the machine mode that that operand is supposed to have.
 
-   11. An array of ints, `insn_n_alternatives', that gives the number
-   of alternatives in the constraints of each pattern.
+     e. `strict_low', is nonzero for operands contained in a STRICT_LOW_PART.
 
-The code number of an insn is simply its position in the machine description;
-code numbers are assigned sequentially to entries in the description,
-starting with code number 0.
+  The code number of an insn is simply its position in the machine
+  description; code numbers are assigned sequentially to entries in
+  the description, starting with code number 0.
 
-Thus, the following entry in the machine description
+  Thus, the following entry in the machine description
 
     (define_insn "clrdf"
       [(set (match_operand:DF 0 "general_operand" "")
@@ -85,10 +80,9 @@ Thus, the following entry in the machine description
       ""
       "clrd %0")
 
-assuming it is the 25th entry present, would cause
-insn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1.
-It would not make an case in output_insn_hairy because the template
-given in the entry is a constant (it does not start with `*').  */
+  assuming it is the 25th entry present, would cause
+  insn_data[24].template to be "clrd %0", and
+  insn_data[24].n_operands to be 1.  */
 \f
 #include "hconfig.h"
 #include "system.h"
@@ -96,9 +90,9 @@ given in the entry is a constant (it does not start with `*').  */
 #include "obstack.h"
 #include "errors.h"
 
-/* No instruction can have more operands than this.
-   Sorry for this arbitrary limit, but what machine will
-   have an instruction with this many operands?  */
+/* No instruction can have more operands than this.  Sorry for this
+   arbitrary limit, but what machine will have an instruction with
+   this many operands?  */
 
 #define MAX_MAX_OPERANDS 40
 
@@ -110,9 +104,6 @@ struct obstack *rtl_obstack = &obstack;
 
 static int n_occurrences PROTO((int, char *));
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
 /* insns in the machine description are assigned sequential code numbers
    that are used by insn-recog.c (produced by genrecog) to communicate
    to insn-output.c (produced by this program).  */
@@ -124,49 +115,73 @@ static int next_code_number;
 
 static int next_index_number;
 
+/* This counts all operands used in the md file.  The first is null.  */
+
+static int next_operand_number = 1;
+
+/* Record in this chain all information about the operands we will output.  */
+
+struct operand_data
+{
+  struct operand_data *next;
+  int index;
+  char *predicate;
+  char *constraint;
+  enum machine_mode mode;
+  unsigned char n_alternatives;
+  char address_p;
+  char strict_low;
+  char seen;
+};
+
+/* Begin with a null operand at index 0.  */
+
+static struct operand_data null_operand =
+{
+  0, 0, "", "", VOIDmode, 0, 0, 0, 0
+};
+
+static struct operand_data *odata = &null_operand;
+static struct operand_data **odata_end = &null_operand.next;
+
 /* Record in this chain all information that we will output,
    associated with the code number of the insn.  */
 
 struct data
 {
-  int code_number;
-  int index_number;
+  struct data *next;
   char *name;
   char *template;              /* string such as "movl %1,%0" */
+  int code_number;
+  int index_number;
   int n_operands;              /* Number of operands this insn recognizes */
   int n_dups;                  /* Number times match_dup appears in pattern */
   int n_alternatives;          /* Number of alternatives in each constraint */
-  struct data *next;
-  char *constraints[MAX_MAX_OPERANDS];
-  /* Number of alternatives in constraints of operand N.  */
-  int op_n_alternatives[MAX_MAX_OPERANDS];
-  char *predicates[MAX_MAX_OPERANDS];
-  char address_p[MAX_MAX_OPERANDS];
-  enum machine_mode modes[MAX_MAX_OPERANDS];
-  char strict_low[MAX_MAX_OPERANDS];
   char outfun;                 /* Nonzero means this has an output function */
+  int operand_number;          /* Operand index in the big array.  */
+  struct operand_data operand[MAX_MAX_OPERANDS];
 };
 
-/* This variable points to the first link in the chain.  */
-
-struct data *insn_data;
+/* This variable points to the first link in the insn chain.  */
 
-/* Pointer to the last link in the chain, so new elements
-   can be added at the end.  */
+static struct data *idata, **idata_end = &idata;
 
-struct data *end_of_insn_data;
+/* Nonzero if any match_operand has a constraint string; implies that
+   REGISTER_CONSTRAINTS will be defined for this machine description.  */
 
-/* Nonzero if any match_operand has a constraint string;
-   implies that REGISTER_CONSTRAINTS will be defined
-   for this machine description.  */
-
-int have_constraints;
+static int have_constraints;
 
 \f
 static char * name_for_index PROTO((int));
 static void output_prologue PROTO((void));
-static void output_epilogue PROTO((void));
-static void scan_operands PROTO((rtx, int, int));
+static void output_predicate_decls PROTO((void));
+static void output_operand_data PROTO((void));
+static void output_insn_data PROTO((void));
+static void output_get_insn_name PROTO((void));
+static void scan_operands PROTO((struct data *, rtx, int, int));
+static int compare_operands PROTO((struct operand_data *,
+                                  struct operand_data *));
+static void place_operands PROTO((struct data *));
 static void process_template PROTO((struct data *, char *));
 static void validate_insn_alternatives PROTO((struct data *));
 static void gen_insn PROTO((rtx));
@@ -175,14 +190,14 @@ static void gen_expand PROTO((rtx));
 static void gen_split PROTO((rtx));
 static int n_occurrences PROTO((int, char *));
 \f
-static char *
-name_for_index (index)
+const char *
+get_insn_name (index)
      int index;
 {
   static char buf[100];
 
   struct data *i, *last_named = NULL;
-  for (i = insn_data; i ; i = i->next)
+  for (i = idata; i ; i = i->next)
     {
       if (i->index_number == index)
        return i->name;
@@ -204,6 +219,7 @@ output_prologue ()
   printf ("/* Generated automatically by the program `genoutput'\n\
 from the machine description file `md'.  */\n\n");
 
+  printf ("#define NO_MD_PROTOTYPES\n");
   printf ("#include \"config.h\"\n");
   printf ("#include \"system.h\"\n");
   printf ("#include \"flags.h\"\n");
@@ -222,224 +238,171 @@ from the machine description file `md'.  */\n\n");
   printf ("#include \"output.h\"\n");
 }
 
+
+/* We need to define all predicates used.  Keep a list of those we
+   have defined so far.  There normally aren't very many predicates
+   used, so a linked list should be fast enough.  */
+
 static void
-output_epilogue ()
+output_predicate_decls ()
 {
-  register struct data *d;
+  struct predicate { char *name; struct predicate *next; } *predicates = 0;
+  register struct operand_data *d;
+  struct predicate *p;
 
-  printf ("\nconst char * const insn_template[] =\n  {\n");
-  for (d = insn_data; d; d = d->next)
-    {
-      if (d->template)
-       printf ("    \"%s\",\n", d->template);
-      else
-       printf ("    0,\n");
-    }
-  printf ("  };\n");
+  for (d = odata; d; d = d->next)
+    if (d->predicate && d->predicate[0])
+      {
+       for (p = predicates; p; p = p->next)
+         if (strcmp (p->name, d->predicate) == 0)
+           break;
 
-  printf ("\nconst char *(*const insn_outfun[]) PROTO((rtx *, rtx)) =\n  {\n");
-  for (d = insn_data; d; d = d->next)
-    {
-      if (d->outfun)
-       printf ("    output_%d,\n", d->code_number);
-      else
-       printf ("    0,\n");
-    }
-  printf ("  };\n");
+       if (p == 0)
+         {
+           printf ("extern int %s PROTO ((rtx, enum machine_mode));\n",
+                   d->predicate);
+           p = (struct predicate *) alloca (sizeof (struct predicate));
+           p->name = d->predicate;
+           p->next = predicates;
+           predicates = p;
+         }
+      }
+
+  printf ("\n\n");
+}
 
-  printf ("\nrtx (*const insn_gen_function[]) () =\n  {\n");
-  for (d = insn_data; d; d = d->next)
+static void
+output_operand_data ()
+{
+  register struct operand_data *d;
+
+  printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
+
+  for (d = odata; d; d = d->next)
     {
-      if (d->name && d->name[0] != '*')
-       printf ("    gen_%s,\n", d->name);
-      else
-       printf ("    0,\n");
-    }
-  printf ("  };\n");
-
-  printf ("\nconst char *insn_name[] =\n  {\n");
-  {
-    int offset = 0;
-    int next;
-    char * last_name = 0;
-    char * next_name = 0;
-    register struct data *n;
-
-    for (n = insn_data, next = 1; n; n = n->next, next++)
-      if (n->name)
+      printf ("  {\n");
+
+      printf ("    %s,\n",
+             d->predicate && d->predicate[0] ? d->predicate : "0");
+
+      if (have_constraints)
        {
-         next_name = n->name;
-         break;
+         printf ("    \"%s\",\n",
+                 d->constraint ? d->constraint : "");
        }
 
-    for (d = insn_data; d; d = d->next)
+      printf ("    %smode,\n", GET_MODE_NAME (d->mode));
+
+      if (! have_constraints)
+       printf ("    %d,\n", d->address_p);
+
+      printf ("    %d\n", d->strict_low);
+
+      printf("  },\n");
+    }
+  printf("};\n\n\n");
+}
+
+static void
+output_insn_data ()
+{
+  register struct data *d;
+  int name_offset = 0;
+  int next_name_offset;
+  const char * last_name = 0;
+  const char * next_name = 0;
+  register struct data *n;
+
+  for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
+    if (n->name)
       {
-       if (d->name)
-         {
-           printf ("    \"%s\",\n", d->name);
-           offset = 0;
-           last_name = d->name;
-           next_name = 0;
-           for (n = d->next, next = 1; n; n = n->next, next++)
-             if (n->name)
-               {
-                 next_name = n->name;
-                 break;
-               }
-         }
-       else
-         {
-           offset++;
-           if (next_name && (last_name == 0 || offset > next / 2))
-             printf ("    \"%s-%d\",\n", next_name, next - offset);
-           else
-             printf ("    \"%s+%d\",\n", last_name, offset);
-         }
+       next_name = n->name;
+       break;
       }
-  }
-  printf ("  };\n");
-  printf ("const char **insn_name_ptr = insn_name;\n");
-
-  printf ("\nconst int insn_n_operands[] =\n  {\n");
-  for (d = insn_data; d; d = d->next)
-    printf ("    %d,\n", d->n_operands);
-  printf ("  };\n");
 
-  printf ("\nconst int insn_n_dups[] =\n  {\n");
-  for (d = insn_data; d; d = d->next)
-    printf ("    %d,\n", d->n_dups);
-  printf ("  };\n");
+  printf ("\nconst struct insn_data insn_data[] = \n{\n");
 
-  if (have_constraints)
+  for (d = idata; d; d = d->next)
     {
-      printf ("\nconst char *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n  {\n");
-      for (d = insn_data; d; d = d->next)
+      printf ("  {\n");
+
+      if (d->name)
        {
-         register int i;
-         printf ("    {");
-         for (i = 0; i < d->n_operands; i++)
+         printf ("    \"%s\",\n", d->name);
+         name_offset = 0;
+         last_name = d->name;
+         next_name = 0;
+         for (n = d->next, next_name_offset = 1; n;
+              n = n->next, next_name_offset++)
            {
-             if (d->constraints[i] == 0)
-               printf (" \"\",");
-             else
-               printf (" \"%s\",", d->constraints[i]);
+             if (n->name)
+               {
+                 next_name = n->name;
+                 break;
+               }
            }
-         if (d->n_operands == 0)
-           printf (" 0");
-         printf (" },\n");
        }
-      printf ("  };\n");
-    }
-  else
-    {
-      printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n  {\n");
-      for (d = insn_data; d; d = d->next)
+      else
        {
-         register int i;
-         printf ("    {");
-         for (i = 0; i < d->n_operands; i++)
-           printf (" %d,", d->address_p[i]);
-         if (d->n_operands == 0)
-           printf (" 0");
-         printf (" },\n");
+         name_offset++;
+         if (next_name && (last_name == 0
+                           || name_offset > next_name_offset / 2))
+           printf ("    \"%s-%d\",\n", next_name,
+                   next_name_offset - name_offset);
+         else
+           printf ("    \"%s+%d\",\n", last_name, name_offset);
        }
-      printf ("  };\n");
-    }
 
-  printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n  {\n");
-  for (d = insn_data; d; d = d->next)
-    {
-      register int i;
-      printf ("    {");
-      for (i = 0; i < d->n_operands; i++)
-       printf (" %smode,", GET_MODE_NAME (d->modes[i]));
-      if (d->n_operands == 0)
-       printf (" VOIDmode");
-      printf (" },\n");
-    }
-  printf ("  };\n");
+      if (d->template)
+       printf ("    \"%s\",\n", d->template);
+      else
+       printf ("    0,\n");
 
-  printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n  {\n");
-  for (d = insn_data; d; d = d->next)
-    {
-      register int i;
-      printf ("    {");
-      for (i = 0; i < d->n_operands; i++)
-       printf (" %d,", d->strict_low[i]);
-      if (d->n_operands == 0)
-       printf (" 0");
-      printf (" },\n");
+      if (d->outfun)
+       printf ("    output_%d,\n", d->code_number);
+      else
+       printf ("    0,\n");
+
+      if (d->name && d->name[0] != '*')
+       printf ("    gen_%s,\n", d->name);
+      else
+       printf ("    0,\n");
+
+      printf ("    &operand_data[%d],\n", d->operand_number);
+      printf ("    %d,\n", d->n_operands);
+      printf ("    %d,\n", d->n_dups);
+      printf ("    %d\n", d->n_alternatives);
+
+      printf("  },\n");
     }
-  printf ("  };\n");
-
-  {
-    /* We need to define all predicates used.  Keep a list of those we
-       have defined so far.  There normally aren't very many predicates used,
-       so a linked list should be fast enough.  */
-    struct predicate { char *name; struct predicate *next; } *predicates = 0;
-    struct predicate *p;
-    int i;
-
-    printf ("\n");
-    for (d = insn_data; d; d = d->next)
-      for (i = 0; i < d->n_operands; i++)
-       if (d->predicates[i] && d->predicates[i][0])
-         {
-           for (p = predicates; p; p = p->next)
-             if (! strcmp (p->name, d->predicates[i]))
-               break;
-
-           if (p == 0)
-             {
-               printf ("extern int %s PROTO ((rtx, enum machine_mode));\n",
-                       d->predicates[i]);
-               p = (struct predicate *) alloca (sizeof (struct predicate));
-               p->name = d->predicates[i];
-               p->next = predicates;
-               predicates = p;
-             }
-         }
-    
-    printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS]) PROTO ((rtx, enum machine_mode)) =\n  {\n");
-    for (d = insn_data; d; d = d->next)
-      {
-       printf ("    {");
-       for (i = 0; i < d->n_operands; i++)
-         printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
-                          ? d->predicates[i] : "0"));
-       if (d->n_operands == 0)
-         printf (" 0");
-       printf (" },\n");
-      }
-    printf ("  };\n");
-  }
+  printf ("};\n\n\n");
+}
 
-  printf ("\nconst int insn_n_alternatives[] =\n  {\n");
-  for (d = insn_data; d; d = d->next)
-    printf ("    %d,\n", d->n_alternatives);
-  printf("  };\n");
+static void
+output_get_insn_name ()
+{
+  printf ("const char *\n");
+  printf ("get_insn_name (code)\n");
+  printf ("     int code;\n");
+  printf ("{\n");
+  printf ("  return insn_data[code].name;\n");
+  printf ("}\n");
 }
+
 \f
-/* scan_operands (X) stores in max_opno the largest operand
-   number present in X, if that is larger than the previous
-   value of max_opno.  It stores all the constraints in `constraints'
-   and all the machine modes in `modes'.
+/* Stores in max_opno the largest operand number present in `part', if
+   that is larger than the previous value of max_opno, and the rest of
+   the operand data into `d->operand[i]'.
 
    THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
    THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART.  */
 
 static int max_opno;
 static int num_dups;
-static char *constraints[MAX_MAX_OPERANDS];
-static int op_n_alternatives[MAX_MAX_OPERANDS];
-static const char *predicates[MAX_MAX_OPERANDS];
-static char address_p[MAX_MAX_OPERANDS];
-static enum machine_mode modes[MAX_MAX_OPERANDS];
-static char strict_low[MAX_MAX_OPERANDS];
-static char seen[MAX_MAX_OPERANDS];
 
 static void
-scan_operands (part, this_address_p, this_strict_low)
+scan_operands (d, part, this_address_p, this_strict_low)
+     struct data *d;
      rtx part;
      int this_address_p;
      int this_strict_low;
@@ -460,23 +423,24 @@ scan_operands (part, this_address_p, this_strict_low)
       if (max_opno >= MAX_MAX_OPERANDS)
        {
          error ("Too many operands (%d) in definition %s.\n",
-                max_opno + 1, name_for_index (next_index_number));
+                max_opno + 1, get_insn_name (next_index_number));
          return;
        }
-      if (seen[opno])
+      if (d->operand[opno].seen)
        error ("Definition %s specified operand number %d more than once.\n",
-              name_for_index (next_index_number), opno);
-      seen[opno] = 1;
-      modes[opno] = GET_MODE (part);
-      strict_low[opno] = this_strict_low;
-      predicates[opno] = XSTR (part, 1);
-      constraints[opno] = XSTR (part, 2);
+              get_insn_name (next_index_number), opno);
+      d->operand[opno].seen = 1;
+      d->operand[opno].mode = GET_MODE (part);
+      d->operand[opno].strict_low = this_strict_low;
+      d->operand[opno].predicate = XSTR (part, 1);
+      d->operand[opno].constraint = XSTR (part, 2);
       if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
        {
-         op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
+         d->operand[opno].n_alternatives
+           = n_occurrences (',', XSTR (part, 2)) + 1;
          have_constraints = 1;
        }
-      address_p[opno] = this_address_p;
+      d->operand[opno].address_p = this_address_p;
       return;
 
     case MATCH_SCRATCH:
@@ -486,23 +450,24 @@ scan_operands (part, this_address_p, this_strict_low)
       if (max_opno >= MAX_MAX_OPERANDS)
        {
          error ("Too many operands (%d) in definition %s.\n",
-                max_opno + 1, name_for_index (next_index_number));
+                max_opno + 1, get_insn_name (next_index_number));
          return;
        }
-      if (seen[opno])
+      if (d->operand[opno].seen)
        error ("Definition %s specified operand number %d more than once.\n",
-              name_for_index (next_index_number), opno);
-      seen[opno] = 1;
-      modes[opno] = GET_MODE (part);
-      strict_low[opno] = 0;
-      predicates[opno] = "scratch_operand";
-      constraints[opno] = XSTR (part, 1);
+              get_insn_name (next_index_number), opno);
+      d->operand[opno].seen = 1;
+      d->operand[opno].mode = GET_MODE (part);
+      d->operand[opno].strict_low = 0;
+      d->operand[opno].predicate = "scratch_operand";
+      d->operand[opno].constraint = XSTR (part, 1);
       if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
        {
-         op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
+         d->operand[opno].n_alternatives
+           = n_occurrences (',', XSTR (part, 1)) + 1;
          have_constraints = 1;
        }
-      address_p[opno] = 0;
+      d->operand[opno].address_p = 0;
       return;
 
     case MATCH_OPERATOR:
@@ -513,20 +478,20 @@ scan_operands (part, this_address_p, this_strict_low)
       if (max_opno >= MAX_MAX_OPERANDS)
        {
          error ("Too many operands (%d) in definition %s.\n",
-                max_opno + 1, name_for_index (next_index_number));
+                max_opno + 1, get_insn_name (next_index_number));
          return;
        }
-      if (seen[opno])
+      if (d->operand[opno].seen)
        error ("Definition %s specified operand number %d more than once.\n",
-              name_for_index (next_index_number), opno);
-      seen[opno] = 1;
-      modes[opno] = GET_MODE (part);
-      strict_low[opno] = 0;
-      predicates[opno] = XSTR (part, 1);
-      constraints[opno] = 0;
-      address_p[opno] = 0;
+              get_insn_name (next_index_number), opno);
+      d->operand[opno].seen = 1;
+      d->operand[opno].mode = GET_MODE (part);
+      d->operand[opno].strict_low = 0;
+      d->operand[opno].predicate = XSTR (part, 1);
+      d->operand[opno].constraint = 0;
+      d->operand[opno].address_p = 0;
       for (i = 0; i < XVECLEN (part, 2); i++)
-       scan_operands (XVECEXP (part, 2, i), 0, 0);
+       scan_operands (d, XVECEXP (part, 2, i), 0, 0);
       return;
 
     case MATCH_DUP:
@@ -536,11 +501,11 @@ scan_operands (part, this_address_p, this_strict_low)
       return;
 
     case ADDRESS:
-      scan_operands (XEXP (part, 0), 1, 0);
+      scan_operands (d, XEXP (part, 0), 1, 0);
       return;
 
     case STRICT_LOW_PART:
-      scan_operands (XEXP (part, 0), 0, 1);
+      scan_operands (d, XEXP (part, 0), 0, 1);
       return;
       
     default:
@@ -554,15 +519,111 @@ scan_operands (part, this_address_p, this_strict_low)
       {
       case 'e':
       case 'u':
-       scan_operands (XEXP (part, i), 0, 0);
+       scan_operands (d, XEXP (part, i), 0, 0);
        break;
       case 'E':
        if (XVEC (part, i) != NULL)
          for (j = 0; j < XVECLEN (part, i); j++)
-           scan_operands (XVECEXP (part, i, j), 0, 0);
+           scan_operands (d, XVECEXP (part, i, j), 0, 0);
        break;
       }
 }
+
+/* Compare two operands for content equality.  */
+
+static int
+compare_operands (d0, d1)
+     struct operand_data *d0, *d1;
+{
+  char *p0, *p1;
+
+  p0 = d0->predicate;
+  if (!p0)
+    p0 = "";
+  p1 = d1->predicate;
+  if (!p1)
+    p1 = "";
+  if (strcmp (p0, p1) != 0)
+    return 0;
+
+  if (have_constraints)
+    {
+      p0 = d0->constraint;
+      if (!p0)
+       p0 = "";
+      p1 = d1->constraint;
+      if (!p1)
+       p1 = "";
+      if (strcmp (p0, p1) != 0)
+       return 0;
+    }
+
+  if (d0->mode != d1->mode)
+    return 0;
+
+  if (!have_constraints)
+    if (d0->address_p != d1->address_p)
+      return 0;
+
+  if (d0->strict_low != d1->strict_low)
+    return 0;
+
+  return 1;
+}
+
+/* Scan the list of operands we've already committed to output and either
+   find a subsequence that is the same, or allocate a new one at the end.  */
+
+static void
+place_operands (d)
+     struct data *d;
+{
+  struct operand_data *od, *od2;
+  int i;
+
+  if (d->n_operands == 0)
+    {
+      d->operand_number = 0;
+      return;
+    }
+
+  /* Brute force substring search.  */
+  for (od = odata, i = 0; od; od = od->next, i = 0)
+    if (compare_operands (od, &d->operand[0]))
+      {
+       od2 = od->next;
+       i = 1;
+       while (1)
+         {
+           if (i == d->n_operands)
+             goto full_match;
+           if (od2 == NULL)
+             goto partial_match;
+           if (! compare_operands (od2, &d->operand[i]))
+             break;
+           ++i, od2 = od2->next;
+         }
+      }
+
+  /* Either partial match at the end of the list, or no match.  In either
+     case, we tack on what operands are remaining to the end of the list.  */
+ partial_match:
+  d->operand_number = next_operand_number - i;
+  for (; i < d->n_operands; ++i)
+    {
+      od2 = &d->operand[i];
+      *odata_end = od2;
+      odata_end = &od2->next;
+      od2->index = next_operand_number++;
+    }
+  *odata_end = NULL;
+  return;
+
+ full_match:
+  d->operand_number = od->index;
+  return;
+}
+
 \f
 /* Process an assembler template from a define_insn or a define_peephole.
    It is either the assembler code template, a list of assembler code
@@ -634,9 +695,9 @@ process_template (d, template)
     }
   else
     {
-       /* The following is done in a funny way to get around problems in
-         VAX-11 "C" on VMS.  It is the equivalent of:
-               printf ("%s\n", &template[1])); */
+      /* The following is done in a funny way to get around problems in
+        VAX-11 "C" on VMS.  It is the equivalent of:
+        printf ("%s\n", &template[1])); */
       cp = &template[1];
       while (*cp)
        {
@@ -656,25 +717,26 @@ validate_insn_alternatives (d)
      struct data *d;
 {
   register int n = 0, start;
-  /* Make sure all the operands have the same number of
-     alternatives in their constraints.
-     Let N be that number.  */
+
+  /* Make sure all the operands have the same number of alternatives
+     in their constraints.  Let N be that number.  */
   for (start = 0; start < d->n_operands; start++)
-    if (d->op_n_alternatives[start] > 0)
+    if (d->operand[start].n_alternatives > 0)
       {
        if (n == 0)
-         n = d->op_n_alternatives[start];
-       else if (n != d->op_n_alternatives[start])
+         n = d->operand[start].n_alternatives;
+       else if (n != d->operand[start].n_alternatives)
          error ("wrong number of alternatives in operand %d of insn %s",
-                start, name_for_index (d->index_number));
+                start, get_insn_name (d->index_number));
       }
+
   /* Record the insn's overall number of alternatives.  */
   d->n_alternatives = n;
 }
 \f
-/* Look at a define_insn just read.  Assign its code number.
-   Record on insn_data the template and the number of arguments.
-   If the insn has a hairy output action, output a function for now.  */
+/* Look at a define_insn just read.  Assign its code number.  Record
+   on idata the template and the number of arguments.  If the insn has
+   a hairy output action, output a function for now.  */
 
 static void
 gen_insn (insn)
@@ -693,43 +755,26 @@ gen_insn (insn)
   /* Build up the list in the same order as the insns are seen
      in the machine description.  */
   d->next = 0;
-  if (end_of_insn_data)
-    end_of_insn_data->next = d;
-  else
-    insn_data = d;
-
-  end_of_insn_data = d;
+  *idata_end = d;
+  idata_end = &d->next;
 
   max_opno = -1;
   num_dups = 0;
-
-  memset (constraints, 0, sizeof constraints);
-  memset (op_n_alternatives, 0, sizeof op_n_alternatives);
-  memset (predicates, 0, sizeof predicates);
-  memset (address_p, 0, sizeof address_p);
-  memset (modes, 0, sizeof modes);
-  memset (strict_low, 0, sizeof strict_low);
-  memset (seen, 0, sizeof seen);
+  memset (d->operand, 0, sizeof (d->operand));
 
   for (i = 0; i < XVECLEN (insn, 1); i++)
-    scan_operands (XVECEXP (insn, 1, i), 0, 0);
+    scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
 
   d->n_operands = max_opno + 1;
   d->n_dups = num_dups;
 
-  memcpy (d->constraints, constraints, sizeof constraints);
-  memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
-  memcpy (d->predicates, predicates, sizeof predicates);
-  memcpy (d->address_p, address_p, sizeof address_p);
-  memcpy (d->modes, modes, sizeof modes);
-  memcpy (d->strict_low, strict_low, sizeof strict_low);
-
   validate_insn_alternatives (d);
+  place_operands (d);
   process_template (d, XSTR (insn, 3));
 }
 \f
 /* Look at a define_peephole just read.  Assign its code number.
-   Record on insn_data the template and the number of arguments.
+   Record on idata the template and the number of arguments.
    If the insn has a hairy output action, output it now.  */
 
 static void
@@ -746,39 +791,24 @@ gen_peephole (peep)
   /* Build up the list in the same order as the insns are seen
      in the machine description.  */
   d->next = 0;
-  if (end_of_insn_data)
-    end_of_insn_data->next = d;
-  else
-    insn_data = d;
-
-  end_of_insn_data = d;
+  *idata_end = d;
+  idata_end = &d->next;
 
   max_opno = -1;
-  memset (constraints, 0, sizeof constraints);
-  memset (op_n_alternatives, 0, sizeof op_n_alternatives);
-  memset (predicates, 0, sizeof predicates);
-  memset (address_p, 0, sizeof address_p);
-  memset (modes, 0, sizeof modes);
-  memset (strict_low, 0, sizeof strict_low);
-  memset (seen, 0, sizeof seen);
-
-  /* Get the number of operands by scanning all the
-     patterns of the peephole optimizer.
-     But ignore all the rest of the information thus obtained.  */
+  num_dups = 0;
+  memset (d->operand, 0, sizeof (d->operand));
+
+  /* Get the number of operands by scanning all the patterns of the
+     peephole optimizer.  But ignore all the rest of the information
+     thus obtained.  */
   for (i = 0; i < XVECLEN (peep, 0); i++)
-    scan_operands (XVECEXP (peep, 0, i), 0, 0);
+    scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
 
   d->n_operands = max_opno + 1;
   d->n_dups = 0;
 
-  memcpy (d->constraints, constraints, sizeof constraints);
-  memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
-  memset (d->predicates, 0, sizeof predicates);
-  memset (d->address_p, 0, sizeof address_p);
-  memset (d->modes, 0, sizeof modes);
-  memset (d->strict_low, 0, sizeof strict_low);
-
   validate_insn_alternatives (d);
+  place_operands (d);
   process_template (d, XSTR (peep, 2));
 }
 \f
@@ -802,50 +832,32 @@ gen_expand (insn)
   /* Build up the list in the same order as the insns are seen
      in the machine description.  */
   d->next = 0;
-  if (end_of_insn_data)
-    end_of_insn_data->next = d;
-  else
-    insn_data = d;
-
-  end_of_insn_data = d;
+  *idata_end = d;
+  idata_end = &d->next;
 
   max_opno = -1;
   num_dups = 0;
+  memset (d->operand, 0, sizeof (d->operand));
 
   /* Scan the operands to get the specified predicates and modes,
      since expand_binop needs to know them.  */
 
-  memset (constraints, 0, sizeof constraints);
-  memset (op_n_alternatives, 0, sizeof op_n_alternatives);
-  memset (predicates, 0, sizeof predicates);
-  memset (address_p, 0, sizeof address_p);
-  memset (modes, 0, sizeof modes);
-  memset (strict_low, 0, sizeof strict_low);
-  memset (seen, 0, sizeof seen);
-
   if (XVEC (insn, 1))
     for (i = 0; i < XVECLEN (insn, 1); i++)
-      scan_operands (XVECEXP (insn, 1, i), 0, 0);
+      scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
 
   d->n_operands = max_opno + 1;
   d->n_dups = num_dups;
-
-  memcpy (d->constraints, constraints, sizeof constraints);
-  memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
-  memcpy (d->predicates, predicates, sizeof predicates);
-  memcpy (d->address_p, address_p, sizeof address_p);
-  memcpy (d->modes, modes, sizeof modes);
-  memcpy (d->strict_low, strict_low, sizeof strict_low);
-
   d->template = 0;
   d->outfun = 0;
+
   validate_insn_alternatives (d);
+  place_operands (d);
 }
 \f
 /* Process a define_split just read.  Assign its code number,
    only for reasons of consistency and to simplify genrecog.  */
 
-
 static void
 gen_split (split)
      rtx split;
@@ -860,43 +872,26 @@ gen_split (split)
   /* Build up the list in the same order as the insns are seen
      in the machine description.  */
   d->next = 0;
-  if (end_of_insn_data)
-    end_of_insn_data->next = d;
-  else
-    insn_data = d;
-
-  end_of_insn_data = d;
+  *idata_end = d;
+  idata_end = &d->next;
 
   max_opno = -1;
   num_dups = 0;
+  memset (d->operand, 0, sizeof (d->operand));
 
-  memset (constraints, 0, sizeof constraints);
-  memset (op_n_alternatives, 0, sizeof op_n_alternatives);
-  memset (predicates, 0, sizeof predicates);
-  memset (address_p, 0, sizeof address_p);
-  memset (modes, 0, sizeof modes);
-  memset (strict_low, 0, sizeof strict_low);
-  memset (seen, 0, sizeof seen);
-
-  /* Get the number of operands by scanning all the
-     patterns of the split patterns.
-     But ignore all the rest of the information thus obtained.  */
+  /* Get the number of operands by scanning all the patterns of the
+     split patterns.  But ignore all the rest of the information thus
+     obtained.  */
   for (i = 0; i < XVECLEN (split, 0); i++)
-    scan_operands (XVECEXP (split, 0, i), 0, 0);
+    scan_operands (d, XVECEXP (split, 0, i), 0, 0);
 
   d->n_operands = max_opno + 1;
-
-  memset (d->constraints, 0, sizeof constraints);
-  memset (d->op_n_alternatives, 0, sizeof op_n_alternatives);
-  memset (d->predicates, 0, sizeof predicates);
-  memset (d->address_p, 0, sizeof address_p);
-  memset (d->modes, 0, sizeof modes);
-  memset (d->strict_low, 0, sizeof strict_low);
-
   d->n_dups = 0;
   d->n_alternatives = 0;
   d->template = 0;
   d->outfun = 0;
+
+  place_operands (d);
 }
 \f
 PTR
@@ -974,7 +969,11 @@ main (argc, argv)
       next_index_number++;
     }
 
-  output_epilogue ();
+  printf("\n\n");
+  output_predicate_decls ();
+  output_operand_data ();
+  output_insn_data ();
+  output_get_insn_name ();
 
   fflush (stdout);
   exit (ferror (stdout) != 0 || have_error
index b20c0365a3ff80b3384effdd4cf60d4e5f4c7529..b9dae533f0a2f81e3ce5aa84c34c2cedca032696 100644 (file)
@@ -31,9 +31,6 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
-char **insn_name_ptr = 0;
-
 /* While tree-walking an instruction pattern, we keep a chain
    of these `struct link's to record how to get down to the
    current position.  In each one, POS is the operand number,
@@ -493,3 +490,11 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  return NULL;
+}
index 2c2978b4b050c25a28178dc323d47160f8d38c63..0ee656fa8bb274382cb3d02b92603e7e141de5fc 100644 (file)
@@ -62,8 +62,8 @@ struct obstack *rtl_obstack = &obstack;
 #define obstack_chunk_free free
 
 /* Holds an array of names indexed by insn_code_number.  */
-char **insn_name_ptr = 0;
-int insn_name_ptr_size = 0;
+static char **insn_name_ptr = 0;
+static int insn_name_ptr_size = 0;
 
 /* Data structure for a listhead of decision trees.  The alternatives
    to a node are kept in a doublely-linked list so we can easily add nodes
@@ -1991,3 +1991,14 @@ from the machine description file `md'.  */\n\n");
   /* NOTREACHED */
   return 0;
 }
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code;
+{
+  if (code < insn_name_ptr_size)
+    return insn_name_ptr[code];
+  else
+    return NULL;
+}
index 4025f7c67d555b05232af863c38d6b0dbad0a64e..ea1a3d57b01d0084a792f39bd25314cda9a3250a 100644 (file)
@@ -8132,10 +8132,12 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
                  enum machine_mode mode = GET_MODE (reg);
                  enum insn_code icode
                    = add_optab->handlers[(int) mode].insn_code;
-                 if (! (*insn_operand_predicate[icode][0]) (reg, mode)
-                     || ! ((*insn_operand_predicate[icode][1])
+
+                 if (! (*insn_data[icode].operand[0].predicate) (reg, mode)
+                     || ! ((*insn_data[icode].operand[1].predicate)
                            (comparison_value, mode))
-                     || ! (*insn_operand_predicate[icode][2]) (offset, mode))
+                     || ! ((*insn_data[icode].operand[2].predicate)
+                           (offset, mode)))
                    return 0;
                  start_value
                    = gen_rtx_PLUS (mode, comparison_value, offset);
@@ -8151,10 +8153,10 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
                  enum machine_mode mode = GET_MODE (reg);
                  enum insn_code icode
                    = sub_optab->handlers[(int) mode].insn_code;
-                 if (! (*insn_operand_predicate[icode][0]) (reg, mode)
-                     || ! ((*insn_operand_predicate[icode][1])
+                 if (! (*insn_data[icode].operand[0].predicate) (reg, mode)
+                     || ! ((*insn_data[icode].operand[1].predicate)
                            (comparison_value, mode))
-                     || ! ((*insn_operand_predicate[icode][2])
+                     || ! ((*insn_data[icode].operand[2].predicate)
                            (initial_value, mode)))
                    return 0;
                  start_value
index 91e757b1da43ef049802d88337358698a24ead7a..558be7d12b5fce14f3aaa52b4d26906d47dad689 100644 (file)
@@ -677,8 +677,8 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
       && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
     {
       int icode = (int) binoptab->handlers[(int) mode].insn_code;
-      enum machine_mode mode0 = insn_operand_mode[icode][1];
-      enum machine_mode mode1 = insn_operand_mode[icode][2];
+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
       rtx pat;
       rtx xop0 = op0, xop1 = op1;
 
@@ -717,15 +717,15 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
       /* Now, if insn's predicates don't allow our operands, put them into
         pseudo regs.  */
 
-      if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
          && mode0 != VOIDmode)
        xop0 = copy_to_mode_reg (mode0, xop0);
 
-      if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
+      if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
          && mode1 != VOIDmode)
        xop1 = copy_to_mode_reg (mode1, xop1);
 
-      if (! (*insn_operand_predicate[icode][0]) (temp, mode))
+      if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
        temp = gen_reg_rtx (mode);
 
       pat = GEN_FCN (icode) (temp, xop0, xop1);
@@ -1899,8 +1899,8 @@ expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
   if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
     {
       int icode = (int) binoptab->handlers[(int) mode].insn_code;
-      enum machine_mode mode0 = insn_operand_mode[icode][1];
-      enum machine_mode mode1 = insn_operand_mode[icode][2];
+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
       rtx pat;
       rtx xop0 = op0, xop1 = op1;
 
@@ -1913,16 +1913,16 @@ expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
        xop1 = convert_to_mode (mode1, xop1, unsignedp);
 
       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
-      if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
        xop0 = copy_to_mode_reg (mode0, xop0);
 
-      if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
+      if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
        xop1 = copy_to_mode_reg (mode1, xop1);
 
       /* We could handle this, but we should always be called with a pseudo
         for our targets and all insns should take them as outputs.  */
-      if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
-         || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
+      if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
+         || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
        abort ();
        
       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
@@ -2009,7 +2009,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
     {
       int icode = (int) unoptab->handlers[(int) mode].insn_code;
-      enum machine_mode mode0 = insn_operand_mode[icode][1];
+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
       rtx xop0 = op0;
 
       if (target)
@@ -2023,10 +2023,10 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
 
       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
 
-      if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
        xop0 = copy_to_mode_reg (mode0, xop0);
 
-      if (! (*insn_operand_predicate[icode][0]) (temp, mode))
+      if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
        temp = gen_reg_rtx (mode);
 
       pat = GEN_FCN (icode) (temp, xop0);
@@ -2370,7 +2370,7 @@ expand_complex_abs (mode, op0, target, unsignedp)
   if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
     {
       int icode = (int) abs_optab->handlers[(int) mode].insn_code;
-      enum machine_mode mode0 = insn_operand_mode[icode][1];
+      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
       rtx xop0 = op0;
 
       if (target)
@@ -2384,10 +2384,10 @@ expand_complex_abs (mode, op0, target, unsignedp)
 
       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
 
-      if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
+      if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
        xop0 = copy_to_mode_reg (mode0, xop0);
 
-      if (! (*insn_operand_predicate[icode][0]) (temp, submode))
+      if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
        temp = gen_reg_rtx (submode);
 
       pat = GEN_FCN (icode) (temp, xop0);
@@ -2534,7 +2534,7 @@ emit_unop_insn (icode, target, op0, code)
      enum rtx_code code;
 {
   register rtx temp;
-  enum machine_mode mode0 = insn_operand_mode[icode][1];
+  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
   rtx pat;
 
   temp = target = protect_from_queue (target, 1);
@@ -2549,10 +2549,10 @@ emit_unop_insn (icode, target, op0, code)
 
   /* Now, if insn does not accept our operands, put them into pseudos.  */
 
-  if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
+  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
     op0 = copy_to_mode_reg (mode0, op0);
 
-  if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
+  if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
       || (flag_force_mem && GET_CODE (temp) == MEM))
     temp = gen_reg_rtx (GET_MODE (temp));
 
@@ -2924,7 +2924,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align)
          && GET_CODE (size) == CONST_INT
          && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
        {
-         result_mode = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
+         result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
          result = gen_reg_rtx (result_mode);
          emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
        }
@@ -2935,7 +2935,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align)
          && GET_CODE (size) == CONST_INT
          && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
        {
-         result_mode = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
+         result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
          result = gen_reg_rtx (result_mode);
          emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
        }
@@ -2944,7 +2944,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align)
 #ifdef HAVE_cmpstrsi
       if (HAVE_cmpstrsi)
        {
-         result_mode = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
+         result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
          result = gen_reg_rtx (result_mode);
          size = protect_from_queue (size, 0);
          emit_insn (gen_cmpstrsi (result, x, y,
@@ -3044,9 +3044,9 @@ prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
   if (mode != wider_mode)
     x = convert_modes (wider_mode, mode, x, unsignedp);
 
-  if (! (*insn_operand_predicate[icode][opnum])
-      (x, insn_operand_mode[icode][opnum]))
-    x = copy_to_mode_reg (insn_operand_mode[icode][opnum], x);
+  if (! (*insn_data[icode].operand[opnum].predicate)
+      (x, insn_data[icode].operand[opnum].mode))
+    x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
   return x;
 }
 
@@ -3413,7 +3413,7 @@ void
 emit_indirect_jump (loc)
      rtx loc;
 {
-  if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
+  if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
         (loc, Pmode)))
     loc = copy_to_mode_reg (Pmode, loc);
 
@@ -3513,17 +3513,17 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
 
   /* If the insn doesn't accept these operands, put them in pseudos.  */
 
-  if (! (*insn_operand_predicate[icode][0])
-      (subtarget, insn_operand_mode[icode][0]))
-    subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
+  if (! (*insn_data[icode].operand[0].predicate)
+      (subtarget, insn_data[icode].operand[0].mode))
+    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
 
-  if (! (*insn_operand_predicate[icode][2])
-      (op2, insn_operand_mode[icode][2]))
-    op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
+  if (! (*insn_data[icode].operand[2].predicate)
+      (op2, insn_data[icode].operand[2].mode))
+    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
 
-  if (! (*insn_operand_predicate[icode][3])
-      (op3, insn_operand_mode[icode][3]))
-    op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
+  if (! (*insn_data[icode].operand[3].predicate)
+      (op3, insn_data[icode].operand[3].mode))
+    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
 
   /* Everything should now be in the suitable form, so emit the compare insn
      and then the conditional move.  */
@@ -3585,9 +3585,12 @@ gen_add2_insn (x, y)
 {
   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
 
-  if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
-      || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
-      || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
+  if (! ((*insn_data[icode].operand[0].predicate)
+        (x, insn_data[icode].operand[0].mode))
+      || ! ((*insn_data[icode].operand[1].predicate)
+           (x, insn_data[icode].operand[1].mode))
+      || ! ((*insn_data[icode].operand[2].predicate)
+           (y, insn_data[icode].operand[2].mode)))
     abort ();
 
   return (GEN_FCN (icode) (x, x, y));
@@ -3608,9 +3611,12 @@ gen_sub2_insn (x, y)
 {
   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
 
-  if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
-      || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
-      || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
+  if (! ((*insn_data[icode].operand[0].predicate)
+        (x, insn_data[icode].operand[0].mode))
+      || ! ((*insn_data[icode].operand[1].predicate)
+           (x, insn_data[icode].operand[1].mode))
+      || ! ((*insn_data[icode].operand[2].predicate)
+           (y, insn_data[icode].operand[2].mode)))
     abort ();
 
   return (GEN_FCN (icode) (x, x, y));
index 03c4c41bcb21787f2c7006cd7d26caf3dc13444d..59193f4c7ebdc3972bc75fb31285358fc04c2927 100644 (file)
@@ -52,9 +52,9 @@ static int sawclose = 0;
 
 static int indent;
 
-/* Names for patterns.  Non-zero only when linked with insn-output.c.  */
+/* Names for patterns.  */
 
-extern char **insn_name_ptr;
+extern const char *get_insn_name PROTO ((int));
 
 static void print_rtx          PROTO ((rtx));
 
@@ -246,6 +246,7 @@ print_rtx (in_rtx)
       case 'i':
        {
          register int value = XINT (in_rtx, i);
+         const char *name;
 
          if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER)
            {
@@ -273,12 +274,13 @@ print_rtx (in_rtx)
            fputc ('#', outfile);
          else
            fprintf (outfile, " %d", value);
+
+         if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
+             && XINT (in_rtx, i) >= 0
+             && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
+           fprintf (outfile, " {%s}", name);
+         sawclose = 0;
        }
-       if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
-           && insn_name_ptr
-           && XINT (in_rtx, i) >= 0)
-         fprintf (outfile, " {%s}", insn_name_ptr[XINT (in_rtx, i)]);
-       sawclose = 0;
        break;
 
       /* Print NOTE_INSN names rather than integer codes.  */
index 2ec59111f64c9ccb3bf7527b445f6faabf71f04b..1d4014ba1ec0273fbcdecb2681d6791bb204cf18 100644 (file)
@@ -543,7 +543,7 @@ validate_replace_rtx_1 (loc, from, to, object)
 #ifdef HAVE_extzv
          if (code == ZERO_EXTRACT)
            {
-             wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+             wanted_mode = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
              if (wanted_mode == VOIDmode)
                wanted_mode = word_mode;
            }
@@ -551,7 +551,7 @@ validate_replace_rtx_1 (loc, from, to, object)
 #ifdef HAVE_extv
          if (code == SIGN_EXTRACT)
            {
-             wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
+             wanted_mode = insn_data[(int) CODE_FOR_extv].operand[1].mode;
              if (wanted_mode == VOIDmode)
                wanted_mode = word_mode;
            }
@@ -2027,20 +2027,21 @@ extract_insn (insn)
       if (icode < 0)
        fatal_insn_not_found (insn);
 
-      recog_data.n_operands = noperands = insn_n_operands[icode];
-      recog_data.n_alternatives = insn_n_alternatives[icode];
-      recog_data.n_dups = insn_n_dups[icode];
+      recog_data.n_operands = noperands = insn_data[icode].n_operands;
+      recog_data.n_alternatives = insn_data[icode].n_alternatives;
+      recog_data.n_dups = insn_data[icode].n_dups;
 
       insn_extract (insn);
 
       for (i = 0; i < noperands; i++)
        {
 #ifdef REGISTER_CONSTRAINTS
-         recog_data.constraints[i] = insn_operand_constraint[icode][i];
+         recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
 #else
-         recog_data.operand_address_p[i] = insn_operand_address_p[icode][i];
+         recog_data.operand_address_p[i]
+           = insn_data[icode].operand[i].address_p;
 #endif
-         recog_data.operand_mode[i] = insn_operand_mode[icode][i];
+         recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
        }
     }
   for (i = 0; i < noperands; i++)
index 55ddb29c26aeb3f54be43a6799d8fcbef6ff28b8..0d4cc977cf57e0ab6dc681f01ab327caece9650f 100644 (file)
@@ -181,40 +181,47 @@ extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALT
 
 /* Access the output function for CODE.  */
 
-#define OUT_FCN(CODE) (*insn_outfun[(int) (CODE)])
+#define OUT_FCN(CODE) (*insn_data[(int) (CODE)].outfun)
 
-/* Tables defined in insn-output.c that give information about
+/* A table defined in insn-output.c that give information about
    each insn-code value.  */
 
-/* These are vectors indexed by insn-code.  Details in genoutput.c.  */
-
-extern const char *const insn_template[];
-
-extern const char *(*const insn_outfun[]) PROTO ((rtx *, rtx));
-
-extern const int insn_n_operands[];
-
-extern const int insn_n_dups[];
-
-/* Indexed by insn code number, gives # of constraint alternatives.  */
-
-extern const int insn_n_alternatives[];
+typedef int (*insn_operand_predicate_fn) PROTO ((rtx, enum machine_mode));
+typedef const char * (*insn_output_fn) PROTO ((rtx *, rtx));
+#ifndef NO_MD_PROTOTYPES
+typedef rtx (*insn_gen_fn) PROTO ((rtx, ...));
+#else
+typedef rtx (*insn_gen_fn) ();
+#endif
 
-/* These are two-dimensional arrays indexed first by the insn-code
-   and second by the operand number.  Details in genoutput.c.  */
+struct insn_operand_data
+{
+  insn_operand_predicate_fn predicate;
 
-#ifdef REGISTER_CONSTRAINTS  /* Avoid undef sym in certain broken linkers.  */
-extern const char *const insn_operand_constraint[][MAX_RECOG_OPERANDS];
+#ifdef REGISTER_CONSTRAINTS
+  const char *constraint;
 #endif
 
-#ifndef REGISTER_CONSTRAINTS  /* Avoid undef sym in certain broken linkers.  */
-extern const char insn_operand_address_p[][MAX_RECOG_OPERANDS];
+  enum machine_mode mode;
+
+#ifndef REGISTER_CONSTRAINTS
+  char address_p;
 #endif
 
-extern const enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS];
+  char strict_low;
+};
 
-extern const char insn_operand_strict_low[][MAX_RECOG_OPERANDS];
+struct insn_data
+{
+  const char *name;
+  const char *template;
+  insn_output_fn outfun;
+  insn_gen_fn genfun;
+  const struct insn_operand_data *operand;
 
-extern int (*const insn_operand_predicate[][MAX_RECOG_OPERANDS]) PROTO ((rtx, enum machine_mode));
+  unsigned char n_operands;
+  unsigned char n_dups;
+  unsigned char n_alternatives;
+};
 
-extern const char * insn_name[];
+extern const struct insn_data insn_data[];
index fea96c9dabe2f1597f3d252abf7df6afbf141c0a..9a7a191ea7f53d5a0108e20da58ae000e631606c 100644 (file)
@@ -89,9 +89,12 @@ gen_add3_insn (r0, r1, c)
   int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
 
     if (icode == CODE_FOR_nothing
-      || ! (*insn_operand_predicate[icode][0]) (r0, insn_operand_mode[icode][0])
-      || ! (*insn_operand_predicate[icode][1]) (r1, insn_operand_mode[icode][1])
-      || ! (*insn_operand_predicate[icode][2]) (c, insn_operand_mode[icode][2]))
+      || ! ((*insn_data[icode].operand[0].predicate)
+           (r0, insn_data[icode].operand[0].mode))
+      || ! ((*insn_data[icode].operand[1].predicate)
+           (r1, insn_data[icode].operand[1].mode))
+      || ! ((*insn_data[icode].operand[2].predicate)
+           (c, insn_data[icode].operand[2].mode)))
     return NULL_RTX;
 
   return (GEN_FCN (icode) (r0, r1, c));
index d8afc6e70fc5c11d5a33627037456c68bb4284f0..ac186331df95620458d3572a9987a25c92480376 100644 (file)
@@ -427,8 +427,8 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
           : reload_out_optab[(int) reload_mode]);
 
   if (icode != CODE_FOR_nothing
-      && insn_operand_predicate[(int) icode][in_p]
-      && (! (insn_operand_predicate[(int) icode][in_p]) (x, reload_mode)))
+      && insn_data[(int) icode].operand[in_p].predicate
+      && (! (insn_data[(int) icode].operand[in_p].predicate) (x, reload_mode)))
     icode = CODE_FOR_nothing;
 
   /* If we will be using an insn, see if it can directly handle the reload
@@ -444,25 +444,27 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
         in operand 1.  Outputs should have an initial "=", which we must
         skip.  */
 
-      char insn_letter = insn_operand_constraint[(int) icode][!in_p][in_p];
+      char insn_letter
+       = insn_data[(int) icode].operand[!in_p].constraint[in_p];
       enum reg_class insn_class
        = (insn_letter == 'r' ? GENERAL_REGS
           : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
 
       if (insn_class == NO_REGS
-         || (in_p && insn_operand_constraint[(int) icode][!in_p][0] != '=')
+         || (in_p
+             && insn_data[(int) icode].operand[!in_p].constraint[0] != '=')
          /* The scratch register's constraint must start with "=&".  */
-         || insn_operand_constraint[(int) icode][2][0] != '='
-         || insn_operand_constraint[(int) icode][2][1] != '&')
+         || insn_data[(int) icode].operand[2].constraint[0] != '='
+         || insn_data[(int) icode].operand[2].constraint[1] != '&')
        abort ();
 
       if (reg_class_subset_p (reload_class, insn_class))
-       mode = insn_operand_mode[(int) icode][2];
+       mode = insn_data[(int) icode].operand[2].mode;
       else
        {
-         char t_letter = insn_operand_constraint[(int) icode][2][2];
+         char t_letter = insn_data[(int) icode].operand[2].constraint[2];
          class = insn_class;
-         t_mode = insn_operand_mode[(int) icode][2];
+         t_mode = insn_data[(int) icode].operand[2].mode;
          t_class = (t_letter == 'r' ? GENERAL_REGS
                     : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
          t_icode = icode;
@@ -1785,9 +1787,9 @@ combine_reloads ()
   if (INSN_CODE (this_insn) == -1)
     return;
 
-  for (i = 1; i < insn_n_operands[INSN_CODE (this_insn)]; i++)
-    if (insn_operand_constraint[INSN_CODE (this_insn)][i][0] == '='
-       || insn_operand_constraint[INSN_CODE (this_insn)][i][0] == '+')
+  for (i = 1; i < insn_data[INSN_CODE (this_insn)].n_operands; i++)
+    if (insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '='
+       || insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '+')
       return;
 
   /* See if some hard register that dies in this insn and is not used in
@@ -3700,7 +3702,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                             (modified[i] == RELOAD_READ
                              ? VOIDmode : operand_mode[i]),
                             (insn_code_number < 0 ? 0
-                             : insn_operand_strict_low[insn_code_number][i]),
+                             : insn_data[insn_code_number].operand[i].strict_low),
                             0, i, operand_type[i]);
          }
        /* In a matching pair of operands, one must be input only
@@ -3790,7 +3792,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                           (modified[i] == RELOAD_READ
                            ? VOIDmode : operand_mode[i]),
                           (insn_code_number < 0 ? 0
-                           : insn_operand_strict_low[insn_code_number][i]),
+                           : insn_data[insn_code_number].operand[i].strict_low),
                           1, i, operand_type[i]);
        /* If a memory reference remains (either as a MEM or a pseudo that
           did not get a hard register), yet we can't make an optional
@@ -3886,13 +3888,13 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
      it doesn't expect.  */
 
   if (insn_code_number >= 0 && replace)
-    for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
+    for (i = insn_data[insn_code_number].n_dups - 1; i >= 0; i--)
       {
        int opno = recog_data.dup_num[i];
        *recog_data.dup_loc[i] = *recog_data.operand_loc[opno];
        if (operand_reloadnum[opno] >= 0)
          push_replacement (recog_data.dup_loc[i], operand_reloadnum[opno],
-                           insn_operand_mode[insn_code_number][opno]);
+                           insn_data[insn_code_number].operand[opno].mode);
       }
 
 #if 0
@@ -4274,7 +4276,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
       int is_set_dest = GET_CODE (body) == SET && (i == 0);
 
       if (insn_code_number >= 0)
-       if (insn_operand_address_p[insn_code_number][i])
+       if (insn_data[insn_code_number].operand[i].address_p)
          find_reloads_address (VOIDmode, NULL_PTR,
                                recog_data.operand[i],
                                recog_data.operand_loc[i],
@@ -5333,8 +5335,10 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                  && ! sets_cc0_p (PATTERN (insn))
 #endif
                  && ! (icode != CODE_FOR_nothing
-                       && (*insn_operand_predicate[icode][0]) (equiv, Pmode)
-                       && (*insn_operand_predicate[icode][1]) (equiv, Pmode)))
+                       && ((*insn_data[icode].operand[0].predicate)
+                           (equiv, Pmode))
+                       && ((*insn_data[icode].operand[1].predicate)
+                           (equiv, Pmode))))
                {
                  loc = &XEXP (x, 0);
                  x = XEXP (x, 0);
@@ -6730,13 +6734,13 @@ debug_reload_to_stream (f)
       if (reload_secondary_in_icode[r] != CODE_FOR_nothing)
        {
          fprintf (stderr, "%ssecondary_in_icode = %s", prefix,
-                  insn_name[reload_secondary_in_icode[r]]);
+                  insn_data[reload_secondary_in_icode[r]].name);
          prefix = ", ";
        }
 
       if (reload_secondary_out_icode[r] != CODE_FOR_nothing)
        fprintf (stderr, "%ssecondary_out_icode = %s", prefix,
-                insn_name[reload_secondary_out_icode[r]]);
+                insn_data[reload_secondary_out_icode[r]].name);
 
       fprintf (f, "\n");
     }
index c8a914af91b865cdffb5fca57021ffcf8ce3c48f..fdbc9459375e56a0c33c4b7b1e5af6c8b0c9d283 100644 (file)
@@ -6816,7 +6816,7 @@ emit_reload_insns (chain)
                  /* Make sure we can access insn_operand_constraint.  */
                  && asm_noperands (PATTERN (temp)) < 0
                  /* This is unsafe if prev insn rejects our reload reg.  */
-                 && constraint_accepts_reg_p (insn_operand_constraint[recog_memoized (temp)][0],
+                 && constraint_accepts_reg_p (insn_data[recog_memoized (temp)].operand[0].constraint,
                                               reloadreg)
                  /* This is unsafe if operand occurs more than once in current
                     insn.  Perhaps some occurrences aren't reloaded.  */
@@ -6945,18 +6945,18 @@ emit_reload_insns (chain)
                            {
                              new_icode = reload_in_optab[(int) mode];
                              if (new_icode != CODE_FOR_nothing
-                                 && ((insn_operand_predicate[(int) new_icode][0]
-                                      && ! ((*insn_operand_predicate[(int) new_icode][0])
+                                 && ((insn_data[(int) new_icode].operand[0].predicate
+                                      && ! ((*insn_data[(int) new_icode].operand[0].predicate)
                                             (reloadreg, mode)))
-                                     || (insn_operand_predicate[(int) new_icode][1]
-                                         && ! ((*insn_operand_predicate[(int) new_icode][1])
+                                     || (insn_data[(int) new_icode].operand[1].predicate
+                                         && ! ((*insn_data[(int) new_icode].operand[1].predicate)
                                                (real_oldequiv, mode)))))
                                new_icode = CODE_FOR_nothing;
 
                              if (new_icode == CODE_FOR_nothing)
                                new_mode = mode;
                              else
-                               new_mode = insn_operand_mode[(int) new_icode][2];
+                               new_mode = insn_data[(int) new_icode].operand[2].mode;
 
                              if (GET_MODE (second_reload_reg) != new_mode)
                                {
@@ -7840,7 +7840,8 @@ gen_reload (out, in, opnum, type)
          || (GET_CODE (op1) == REG
              && REGNO (op1) >= FIRST_PSEUDO_REGISTER)
          || (code != CODE_FOR_nothing
-             && ! (*insn_operand_predicate[code][2]) (op1, insn_operand_mode[code][2])))
+             && ! ((*insn_data[code].operand[2].predicate)
+                   (op1, insn_data[code].operand[2].mode))))
        tem = op0, op0 = op1, op1 = tem;
 
       gen_reload (out, op0, opnum, type);
index ad45fddcc334c17240200f780c216ec00c2fbd97..107735f359d2648a34450fe87fca0b79fc5370dc 100644 (file)
@@ -5442,22 +5442,22 @@ expand_end_case (orig_index)
              index = protect_from_queue (index, 0);
              do_pending_stack_adjust ();
 
-             op_mode = insn_operand_mode[(int)CODE_FOR_casesi][0];
-             if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][0])
+             op_mode = insn_data[(int)CODE_FOR_casesi].operand[0].mode;
+             if (! (*insn_data[(int)CODE_FOR_casesi].operand[0].predicate)
                  (index, op_mode))
                index = copy_to_mode_reg (op_mode, index);
 
              op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0);
 
-             op_mode = insn_operand_mode[(int)CODE_FOR_casesi][1];
-             if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][1])
+             op_mode = insn_data[(int)CODE_FOR_casesi].operand[1].mode;
+             if (! (*insn_data[(int)CODE_FOR_casesi].operand[1].predicate)
                  (op1, op_mode))
                op1 = copy_to_mode_reg (op_mode, op1);
 
              op2 = expand_expr (range, NULL_RTX, VOIDmode, 0);
 
-             op_mode = insn_operand_mode[(int)CODE_FOR_casesi][2];
-             if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][2])
+             op_mode = insn_data[(int)CODE_FOR_casesi].operand[2].mode;
+             if (! (*insn_data[(int)CODE_FOR_casesi].operand[2].predicate)
                  (op2, op_mode))
                op2 = copy_to_mode_reg (op_mode, op2);
 
index ff4c878ea4509341094d7c0f0505bb38896c3733..b1b3b8fa318cfa87d81b9ffb7d621e9c7569d394 100644 (file)
@@ -3171,8 +3171,8 @@ compile_file (name)
     {
       /* It's best if we can write a nop here since some
         assemblers don't tolerate zeros in the text section.  */
-      if (insn_template[CODE_FOR_nop] != 0)
-       output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
+      if (insn_data[CODE_FOR_nop].template != 0)
+       output_asm_insn (insn_data[CODE_FOR_nop].template, NULL_PTR);
       else
        assemble_zeros (UNITS_PER_WORD);
     }