diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-12 12:46:08 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-12 12:46:08 +0000 |
commit | 6357eaae5779649838519220018bd3f912036f24 (patch) | |
tree | c2582159a30e1f83f4d7b7bcd2806fb8331123b2 /gcc | |
parent | c23a82fe96b6e0344496b8c5d928989cb76f0bc5 (diff) | |
download | gcc-6357eaae5779649838519220018bd3f912036f24.tar.gz |
Replace insn_foo with insn_data.foo.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29358 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 84 | ||||
-rw-r--r-- | gcc/builtins.c | 10 | ||||
-rw-r--r-- | gcc/combine.c | 59 | ||||
-rw-r--r-- | gcc/config/c4x/c4x.c | 2 | ||||
-rw-r--r-- | gcc/config/i860/i860.c | 12 | ||||
-rw-r--r-- | gcc/cse.c | 4 | ||||
-rw-r--r-- | gcc/explow.c | 17 | ||||
-rw-r--r-- | gcc/expmed.c | 55 | ||||
-rw-r--r-- | gcc/expr.c | 73 | ||||
-rw-r--r-- | gcc/expr.h | 6 | ||||
-rw-r--r-- | gcc/final.c | 12 | ||||
-rw-r--r-- | gcc/function.c | 7 | ||||
-rw-r--r-- | gcc/genattr.c | 11 | ||||
-rw-r--r-- | gcc/genattrtab.c | 11 | ||||
-rw-r--r-- | gcc/gencodes.c | 11 | ||||
-rw-r--r-- | gcc/genconfig.c | 11 | ||||
-rw-r--r-- | gcc/genemit.c | 11 | ||||
-rw-r--r-- | gcc/genextract.c | 11 | ||||
-rw-r--r-- | gcc/genflags.c | 11 | ||||
-rw-r--r-- | gcc/genopinit.c | 11 | ||||
-rw-r--r-- | gcc/genoutput.c | 819 | ||||
-rw-r--r-- | gcc/genpeep.c | 11 | ||||
-rw-r--r-- | gcc/genrecog.c | 15 | ||||
-rw-r--r-- | gcc/loop.c | 14 | ||||
-rw-r--r-- | gcc/optabs.c | 90 | ||||
-rw-r--r-- | gcc/print-rtl.c | 16 | ||||
-rw-r--r-- | gcc/recog.c | 17 | ||||
-rw-r--r-- | gcc/recog.h | 57 | ||||
-rw-r--r-- | gcc/regmove.c | 9 | ||||
-rw-r--r-- | gcc/reload.c | 46 | ||||
-rw-r--r-- | gcc/reload1.c | 15 | ||||
-rw-r--r-- | gcc/stmt.c | 12 | ||||
-rw-r--r-- | gcc/toplev.c | 4 |
33 files changed, 864 insertions, 690 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 28a5ebbd85a..4ba402ee2cd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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, diff --git a/gcc/builtins.c b/gcc/builtins.c index a77b0f860a6..2d211f9c1a5 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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) diff --git a/gcc/combine.c b/gcc/combine.c index b0646c21b0b..56a373b3805 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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); diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c index 7712695c910..b3f5a54345e 100644 --- a/gcc/config/c4x/c4x.c +++ b/gcc/config/c4x/c4x.c @@ -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); diff --git a/gcc/config/i860/i860.c b/gcc/config/i860/i860.c index cb7e7f7ba28..a6e9458a8b9 100644 --- a/gcc/config/i860/i860.c +++ b/gcc/config/i860/i860.c @@ -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 ""; diff --git a/gcc/cse.c b/gcc/cse.c index e07e3384cc8..75952b0e128 100644 --- 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; diff --git a/gcc/explow.c b/gcc/explow.c index 3af4c2c06a8..573c5295ede 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -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)); diff --git a/gcc/expmed.c b/gcc/expmed.c index 2138ad189af..1ac3272e80a 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -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); diff --git a/gcc/expr.c b/gcc/expr.c index 2f014d345e1..c4d0f143fe8 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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. */ diff --git a/gcc/expr.h b/gcc/expr.h index 26c53cf8dbc..53cb9a9bd67 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -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 { diff --git a/gcc/final.c b/gcc/final.c index 6ace9b24f94..e81895bd3bc 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -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. */ diff --git a/gcc/function.c b/gcc/function.c index 213cf63d45e..d12dd3336f5 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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; diff --git a/gcc/genattr.c b/gcc/genattr.c index f9501eda39e..71b2dc0f0b0 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -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; +} diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 4196c7d8124..e5a405d610b 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -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; +} diff --git a/gcc/gencodes.c b/gcc/gencodes.c index 23d06787d9c..87f93ab6fb3 100644 --- a/gcc/gencodes.c +++ b/gcc/gencodes.c @@ -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; +} diff --git a/gcc/genconfig.c b/gcc/genconfig.c index a40b6b3f05a..94e2653a392 100644 --- a/gcc/genconfig.c +++ b/gcc/genconfig.c @@ -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; +} diff --git a/gcc/genemit.c b/gcc/genemit.c index bad78b537f5..6aec54a2d55 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -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; +} diff --git a/gcc/genextract.c b/gcc/genextract.c index 35ffbd099bc..eeaf52b197a 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -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; +} diff --git a/gcc/genflags.c b/gcc/genflags.c index d8dbf8791ed..bd3a983fbfd 100644 --- a/gcc/genflags.c +++ b/gcc/genflags.c @@ -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; +} diff --git a/gcc/genopinit.c b/gcc/genopinit.c index 249500549e9..ac4a5883e60 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -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; +} diff --git a/gcc/genoutput.c b/gcc/genoutput.c index 87c8b98a70a..9c44d7e6475 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -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. */ #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; 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 *)); -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"); } + -/* 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; +} + /* 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; } -/* 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)); } /* 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)); } @@ -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); } /* 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); } 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 diff --git a/gcc/genpeep.c b/gcc/genpeep.c index b20c0365a3f..b9dae533f0a 100644 --- a/gcc/genpeep.c +++ b/gcc/genpeep.c @@ -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; +} diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 2c2978b4b05..0ee656fa8bb 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -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; +} diff --git a/gcc/loop.c b/gcc/loop.c index 4025f7c67d5..ea1a3d57b01 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -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 diff --git a/gcc/optabs.c b/gcc/optabs.c index 91e757b1da4..558be7d12b5 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -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)); diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 03c4c41bcb2..59193f4c7eb 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -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. */ diff --git a/gcc/recog.c b/gcc/recog.c index 2ec59111f64..1d4014ba1ec 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -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++) diff --git a/gcc/recog.h b/gcc/recog.h index 55ddb29c26a..0d4cc977cf5 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -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[]; diff --git a/gcc/regmove.c b/gcc/regmove.c index fea96c9dabe..9a7a191ea7f 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -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)); diff --git a/gcc/reload.c b/gcc/reload.c index d8afc6e70fc..ac186331df9 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -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"); } diff --git a/gcc/reload1.c b/gcc/reload1.c index c8a914af91b..fdbc9459375 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -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); diff --git a/gcc/stmt.c b/gcc/stmt.c index ad45fddcc33..107735f359d 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -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); diff --git a/gcc/toplev.c b/gcc/toplev.c index ff4c878ea45..b1b3b8fa318 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -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); } |