diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2010-07-04 22:14:56 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2010-07-04 22:14:56 +0000 |
commit | f9621cc4774d44166dc6e25228a1d86f14aaaca6 (patch) | |
tree | a30ef11d74c7da9ce0ee003131a81a63259e96d2 /gcc/optabs.c | |
parent | 596455ce057d68deec9e7a3e308a10364c2d4498 (diff) | |
download | gcc-f9621cc4774d44166dc6e25228a1d86f14aaaca6.zip gcc-f9621cc4774d44166dc6e25228a1d86f14aaaca6.tar.gz gcc-f9621cc4774d44166dc6e25228a1d86f14aaaca6.tar.bz2 |
gcc/
* optabs.h (reload_in_optab, reload_out_optab, code_to_optab)
(vcond_gen_code, vcondu_gen_code, movmem_optab, setmem_optab)
(cmpstr_optab, cmpstrn_optab, cmpmem_optab, sync_add_optab)
(sync_sub_optab, sync_ior_optab, sync_and_optab, sync_xor_optab)
(sync_nand_optab, sync_old_add_optab, sync_old_sub_optab)
(sync_old_ior_optab, sync_old_and_optab, sync_old_xor_optab)
(sync_old_nand_optab, sync_new_add_optab, sync_new_sub_optab)
(sync_new_ior_optab, sync_new_and_optab, sync_new_xor_optab)
(sync_new_nand_optab): Redefine as macros.
(sync_compare_and_swap, sync_lock_test_and_set, sync_lock_release):
Delete.
(direct_optab_index): New enum.
(direct_optab_d): New structure.
(direct_optab): New typedef.
(direct_optab_table): Declare.
(direct_optab_handler, set_direct_optab_handler): New functions.
(sync_compare_and_swap_optab, sync_lock_test_and_set_optab)
(sync_lock_release_optab): New macros.
* optabs.c (direct_optab_table): New variable.
(movcc_gen_code, vcond_gen_code, vcondu_gen_code): Delete.
(prepare_cmp_insn): Use direct_optab_handler for cmpmem_optab,
cmpstr_optab and cmpstrn_optab.
(emit_conditional_move): Likewise for movcc_optab.
(can_conditionally_move_p): Likewise for movcc_gen_code.
(init_insn_codes): Clear direct_optab_table.
(init_optabs): Don't initialize the new "direct optabs" here.
(get_vcond_icode): Use direct_optab_handler for vcondu_gen_code and
vcond_gen_code.
(expand_val_compare_and_swap): Likewise sync_compare_and_swap_optab.
(expand_bool_compare_and_swap): Likewise sync_compare_and_swap_optab.
(expand_compare_and_swap_loop): Likewise sync_compare_and_swap_optab.
(expand_sync_operation): Likewise other sync_*_optabs.
(expand_sync_fetch_operation): Likewise. Rename sync_compare_and_swap
to sync_compare_and_swap_optab.
(expand_sync_lock_test_and_set): Use direct_optab_handler for
sync_lock_test_and_set and sync_compare_and_swap, adding "_optab"
to the names of both.
* builtins.c (expand_builtin_strcmp): Use direct_optab_handler for
cmpstr_optab and cmpstrn_optab.
(expand_builtin_lock_release): Likewise sync_lock_release.
* expr.c (movmem_optab, setmem_optab, cmpstr_optab, cmpstrn_optab)
(cmpmem_optab, sync_add_optab, sync_sub_optab, sync_ior_optab)
(sync_and_optab, sync_xor_optab, sync_nand_optab, sync_old_add_optab)
(sync_old_sub_optab, sync_old_ior_optab, sync_old_and_optab)
(sync_old_xor_optab, sync_old_nand_optab, sync_new_add_optab)
(sync_new_sub_optab, sync_new_ior_optab, sync_new_and_optab)
(sync_new_xor_optab, sync_new_nand_optab, sync_compare_and_swap)
(sync_lock_test_and_set, sync_lock_release): Delete.
(emit_block_move_via_movmem): Use direct_optab_handler for movmem_optab.
(emit_block_move_via_setmem): Use direct_optab_handler for setmem_optab.
* genopinit.c (optabs): Use set_direct_optab_handler for the new
macro optabs.
* omp-low.c (expand_omp_atomic_fetch_op): Update the type of
the "optab" local variable. Use direct_optab_handler for optab and
sync_compare_and_swap_optab.
* reload1.c (reload_in_optab, reload_out_optab): Delete.
* targhooks.c (default_secondary_reload): Use direct_optab_handler for
reload_in_optab and reload_out_optab.
* config/alpha/alpha.c (alpha_secondary_reload): Likewise.
* config/frv/frv.c (frv_alloc_temp_reg): Likewise.
* config/pa/pa.c (pa_secondary_reload): Likewise.
* java/builtins.c (compareAndSwapInt_builtin): Use direct_optab_handler
for sync_compare_and_swap, renaming it to sync_compare_and_swap_optab.
(compareAndSwapLong_builtin, compareAndSwapObject_builtin): Likewise.
(VMSupportsCS8_builtin): Likewise.
From-SVN: r161810
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 142 |
1 files changed, 45 insertions, 97 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 29dd6d0..1b1a869 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -60,24 +60,13 @@ rtx libfunc_table[LTI_MAX]; /* Tables of patterns for converting one mode to another. */ struct convert_optab_d convert_optab_table[COI_MAX]; +/* Tables of patterns for direct optabs (i.e. those which cannot be + implemented using a libcall). */ +struct direct_optab_d direct_optab_table[(int) DOI_MAX]; + /* Contains the optab used for each rtx code. */ optab code_to_optab[NUM_RTX_CODE + 1]; -#ifdef HAVE_conditional_move -/* Indexed by the machine mode, gives the insn code to make a conditional - move insn. This is not indexed by the rtx-code like bcc_gen_fctn and - setcc_gen_code to cut down on the number of named patterns. Consider a day - when a lot more rtx codes are conditional (eg: for the ARM). */ - -enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; -#endif - -/* Indexed by the machine mode, gives the insn code for vector conditional - operation. */ - -enum insn_code vcond_gen_code[NUM_MACHINE_MODES]; -enum insn_code vcondu_gen_code[NUM_MACHINE_MODES]; - static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *, enum machine_mode *); static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int); @@ -4071,11 +4060,11 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size, cmp_mode != VOIDmode; cmp_mode = GET_MODE_WIDER_MODE (cmp_mode)) { - cmp_code = cmpmem_optab[cmp_mode]; + cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode); if (cmp_code == CODE_FOR_nothing) - cmp_code = cmpstr_optab[cmp_mode]; + cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode); if (cmp_code == CODE_FOR_nothing) - cmp_code = cmpstrn_optab[cmp_mode]; + cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode); if (cmp_code == CODE_FOR_nothing) continue; @@ -4520,7 +4509,7 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, if (mode == VOIDmode) mode = GET_MODE (op2); - icode = movcc_gen_code[mode]; + icode = direct_optab_handler (movcc_optab, mode); if (icode == CODE_FOR_nothing) return 0; @@ -4593,7 +4582,7 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, int can_conditionally_move_p (enum machine_mode mode) { - if (movcc_gen_code[mode] != CODE_FOR_nothing) + if (direct_optab_handler (movcc_optab, mode) != CODE_FOR_nothing) return 1; return 0; @@ -5439,6 +5428,7 @@ init_insn_codes (void) { memset (optab_table, 0, sizeof (optab_table)); memset (convert_optab_table, 0, sizeof (convert_optab_table)); + memset (direct_optab_table, 0, sizeof (direct_optab_table)); } /* Initialize OP's code to CODE, and write it into the code_to_optab table. */ @@ -6146,25 +6136,12 @@ set_conv_libfunc (convert_optab optable, enum machine_mode tmode, void init_optabs (void) { - unsigned int i; static bool reinit; libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL); - /* Start by initializing all tables to contain CODE_FOR_nothing. */ - -#ifdef HAVE_conditional_move - for (i = 0; i < NUM_MACHINE_MODES; i++) - movcc_gen_code[i] = CODE_FOR_nothing; -#endif - - for (i = 0; i < NUM_MACHINE_MODES; i++) - { - vcond_gen_code[i] = CODE_FOR_nothing; - vcondu_gen_code[i] = CODE_FOR_nothing; - } /* We statically initialize the insn_codes with the equivalent of - CODE_FOR_nothing. */ + CODE_FOR_nothing. Repeat the process if reinitialising. */ if (reinit) init_insn_codes (); @@ -6357,39 +6334,6 @@ init_optabs (void) init_convert_optab (satfract_optab, SAT_FRACT); init_convert_optab (satfractuns_optab, UNSIGNED_SAT_FRACT); - for (i = 0; i < NUM_MACHINE_MODES; i++) - { - movmem_optab[i] = CODE_FOR_nothing; - cmpstr_optab[i] = CODE_FOR_nothing; - cmpstrn_optab[i] = CODE_FOR_nothing; - cmpmem_optab[i] = CODE_FOR_nothing; - setmem_optab[i] = CODE_FOR_nothing; - - sync_add_optab[i] = CODE_FOR_nothing; - sync_sub_optab[i] = CODE_FOR_nothing; - sync_ior_optab[i] = CODE_FOR_nothing; - sync_and_optab[i] = CODE_FOR_nothing; - sync_xor_optab[i] = CODE_FOR_nothing; - sync_nand_optab[i] = CODE_FOR_nothing; - sync_old_add_optab[i] = CODE_FOR_nothing; - sync_old_sub_optab[i] = CODE_FOR_nothing; - sync_old_ior_optab[i] = CODE_FOR_nothing; - sync_old_and_optab[i] = CODE_FOR_nothing; - sync_old_xor_optab[i] = CODE_FOR_nothing; - sync_old_nand_optab[i] = CODE_FOR_nothing; - sync_new_add_optab[i] = CODE_FOR_nothing; - sync_new_sub_optab[i] = CODE_FOR_nothing; - sync_new_ior_optab[i] = CODE_FOR_nothing; - sync_new_and_optab[i] = CODE_FOR_nothing; - sync_new_xor_optab[i] = CODE_FOR_nothing; - sync_new_nand_optab[i] = CODE_FOR_nothing; - sync_compare_and_swap[i] = CODE_FOR_nothing; - sync_lock_test_and_set[i] = CODE_FOR_nothing; - sync_lock_release[i] = CODE_FOR_nothing; - - reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing; - } - /* Fill in the optabs with the insns we support. */ init_all_optabs (); @@ -6845,9 +6789,9 @@ get_vcond_icode (tree type, enum machine_mode mode) enum insn_code icode = CODE_FOR_nothing; if (TYPE_UNSIGNED (type)) - icode = vcondu_gen_code[mode]; + icode = direct_optab_handler (vcondu_optab, mode); else - icode = vcond_gen_code[mode]; + icode = direct_optab_handler (vcond_optab, mode); return icode; } @@ -6945,7 +6889,8 @@ rtx expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target) { enum machine_mode mode = GET_MODE (mem); - enum insn_code icode = sync_compare_and_swap[mode]; + enum insn_code icode + = direct_optab_handler (sync_compare_and_swap_optab, mode); if (icode == CODE_FOR_nothing) return NULL_RTX; @@ -6982,7 +6927,7 @@ expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target) /* If the target supports a compare-and-swap pattern that simultaneously sets some flag for success, then use it. Otherwise use the regular compare-and-swap and follow that immediately with a compare insn. */ - icode = sync_compare_and_swap[mode]; + icode = direct_optab_handler (sync_compare_and_swap_optab, mode); if (icode == CODE_FOR_nothing) return NULL_RTX; @@ -7060,7 +7005,7 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq) /* If the target supports a compare-and-swap pattern that simultaneously sets some flag for success, then use it. Otherwise use the regular compare-and-swap and follow that immediately with a compare insn. */ - icode = sync_compare_and_swap[mode]; + icode = direct_optab_handler (sync_compare_and_swap_optab, mode); if (icode == CODE_FOR_nothing) return false; @@ -7104,26 +7049,26 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code) switch (code) { case PLUS: - icode = sync_add_optab[mode]; + icode = direct_optab_handler (sync_add_optab, mode); break; case IOR: - icode = sync_ior_optab[mode]; + icode = direct_optab_handler (sync_ior_optab, mode); break; case XOR: - icode = sync_xor_optab[mode]; + icode = direct_optab_handler (sync_xor_optab, mode); break; case AND: - icode = sync_and_optab[mode]; + icode = direct_optab_handler (sync_and_optab, mode); break; case NOT: - icode = sync_nand_optab[mode]; + icode = direct_optab_handler (sync_nand_optab, mode); break; case MINUS: - icode = sync_sub_optab[mode]; + icode = direct_optab_handler (sync_sub_optab, mode); if (icode == CODE_FOR_nothing || CONST_INT_P (val)) { - icode = sync_add_optab[mode]; + icode = direct_optab_handler (sync_add_optab, mode); if (icode != CODE_FOR_nothing) { val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1); @@ -7154,7 +7099,8 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code) /* Failing that, generate a compare-and-swap loop in which we perform the operation with normal arithmetic instructions. */ - if (sync_compare_and_swap[mode] != CODE_FOR_nothing) + if (direct_optab_handler (sync_compare_and_swap_optab, mode) + != CODE_FOR_nothing) { rtx t0 = gen_reg_rtx (mode), t1; @@ -7199,34 +7145,34 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code, switch (code) { case PLUS: - old_code = sync_old_add_optab[mode]; - new_code = sync_new_add_optab[mode]; + old_code = direct_optab_handler (sync_old_add_optab, mode); + new_code = direct_optab_handler (sync_new_add_optab, mode); break; case IOR: - old_code = sync_old_ior_optab[mode]; - new_code = sync_new_ior_optab[mode]; + old_code = direct_optab_handler (sync_old_ior_optab, mode); + new_code = direct_optab_handler (sync_new_ior_optab, mode); break; case XOR: - old_code = sync_old_xor_optab[mode]; - new_code = sync_new_xor_optab[mode]; + old_code = direct_optab_handler (sync_old_xor_optab, mode); + new_code = direct_optab_handler (sync_new_xor_optab, mode); break; case AND: - old_code = sync_old_and_optab[mode]; - new_code = sync_new_and_optab[mode]; + old_code = direct_optab_handler (sync_old_and_optab, mode); + new_code = direct_optab_handler (sync_new_and_optab, mode); break; case NOT: - old_code = sync_old_nand_optab[mode]; - new_code = sync_new_nand_optab[mode]; + old_code = direct_optab_handler (sync_old_nand_optab, mode); + new_code = direct_optab_handler (sync_new_nand_optab, mode); break; case MINUS: - old_code = sync_old_sub_optab[mode]; - new_code = sync_new_sub_optab[mode]; + old_code = direct_optab_handler (sync_old_sub_optab, mode); + new_code = direct_optab_handler (sync_new_sub_optab, mode); if ((old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing) || CONST_INT_P (val)) { - old_code = sync_old_add_optab[mode]; - new_code = sync_new_add_optab[mode]; + old_code = direct_optab_handler (sync_old_add_optab, mode); + new_code = direct_optab_handler (sync_new_add_optab, mode); if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing) { val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1); @@ -7316,7 +7262,8 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code, /* Failing that, generate a compare-and-swap loop in which we perform the operation with normal arithmetic instructions. */ - if (sync_compare_and_swap[mode] != CODE_FOR_nothing) + if (direct_optab_handler (sync_compare_and_swap_optab, mode) + != CODE_FOR_nothing) { rtx t0 = gen_reg_rtx (mode), t1; @@ -7365,7 +7312,7 @@ expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target) rtx insn; /* If the target supports the test-and-set directly, great. */ - icode = sync_lock_test_and_set[mode]; + icode = direct_optab_handler (sync_lock_test_and_set_optab, mode); if (icode != CODE_FOR_nothing) { if (!target || !insn_data[icode].operand[0].predicate (target, mode)) @@ -7385,7 +7332,8 @@ expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target) } /* Otherwise, use a compare-and-swap loop for the exchange. */ - if (sync_compare_and_swap[mode] != CODE_FOR_nothing) + if (direct_optab_handler (sync_compare_and_swap_optab, mode) + != CODE_FOR_nothing) { if (!target || !register_operand (target, mode)) target = gen_reg_rtx (mode); |