diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-23 09:30:58 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-23 09:30:58 +0000 |
commit | 8786db1e7327a0488bb81202ca021ddc418fa51c (patch) | |
tree | 149ffb595908dd2c0744e01184f253f737706ef4 /gcc/builtins.c | |
parent | 10d06e9c55dbaec4b53e411ee2213ca16c8786bd (diff) | |
download | gcc-8786db1e7327a0488bb81202ca021ddc418fa51c.tar.gz |
gcc/
* optabs.h (emit_unop_insn, maybe_emit_unop_insn): Change insn code
parameter from "int" to "enum insn_code".
(expand_operand_type): New enum.
(expand_operand): New structure.
(create_expand_operand): New function.
(create_fixed_operand, create_output_operand): Likewise
(create_input_operand, create_convert_operand_to): Likewise.
(create_convert_operand_from, create_address_operand): Likewise.
(create_integer_operand): Likewise.
(create_convert_operand_from_type, maybe_legitimize_operands): Declare.
(maybe_gen_insn, maybe_expand_insn, maybe_expand_jump_insn): Likewise.
(expand_insn, expand_jump_insn): Likewise.
* builtins.c (expand_builtin_prefetch): Use the new interfaces.
(expand_builtin_interclass_mathfn, expand_builtin_strlen): Likewise.
(expand_movstr, expand_builtin___clear_cache): Likewise.
(expand_builtin_lock_release): Likewise.
* explow.c (allocate_dynamic_stack_space): Likewise.
(probe_stack_range): Likewise. Allow check_stack to FAIL,
and use the default handling in that case.
* expmed.c (check_predicate_volatile_ok): Delete.
(store_bit_field_1, extract_bit_field_1): Use the new interfaces.
(emit_cstore): Likewise.
* expr.c (emit_block_move_via_movmem): Likewise.
(set_storage_via_setmem, expand_assignment): Likewise.
(emit_storent_insn, try_casesi): Likewise.
(emit_single_push_insn): Likewise. Allow the expansion to fail.
* optabs.c (expand_widen_pattern_expr, expand_ternary_op): Likewise.
(expand_vec_shift_expr, expand_binop_directly): Likewise.
(expand_twoval_unop, expand_twoval_binop): Likewise.
(expand_unop_direct, emit_indirect_jump): Likewise.
(emit_conditional_move, vector_compare_rtx): Likewise.
(expand_vec_cond_expr, expand_val_compare_and_swap_1): Likewise.
(expand_sync_operation, expand_sync_fetch_operation): Likewise.
(expand_sync_lock_test_and_set): Likewise.
(maybe_emit_unop_insn): Likewise. Change icode to an insn_code.
(emit_unop_insn): Likewise.
(expand_copysign_absneg): Change icode to an insn_code.
(create_convert_operand_from_type): New function.
(maybe_legitimize_operand, maybe_legitimize_operands): Likewise.
(maybe_gen_insn, maybe_expand_insn, maybe_expand_jump_insn): Likewise.
(expand_insn, expand_jump_insn): Likewise.
* config/i386/i386.md (setmem<mode>): Use nonmemory_operand rather
than const_int_operand for operand 2.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171341 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 150 |
1 files changed, 52 insertions, 98 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index ad21b2d6163..f2b5130b837 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1143,15 +1143,13 @@ expand_builtin_prefetch (tree exp) #ifdef HAVE_prefetch if (HAVE_prefetch) { - if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate) - (op0, - insn_data[(int) CODE_FOR_prefetch].operand[0].mode)) - || (GET_MODE (op0) != Pmode)) - { - op0 = convert_memory_address (Pmode, op0); - op0 = force_reg (Pmode, op0); - } - emit_insn (gen_prefetch (op0, op1, op2)); + struct expand_operand ops[3]; + + create_address_operand (&ops[0], op0); + create_integer_operand (&ops[1], INTVAL (op1)); + create_integer_operand (&ops[2], INTVAL (op2)); + if (maybe_expand_insn (CODE_FOR_prefetch, 3, ops)) + return; } #endif @@ -2431,16 +2429,9 @@ expand_builtin_interclass_mathfn (tree exp, rtx target) if (icode != CODE_FOR_nothing) { + struct expand_operand ops[1]; rtx last = get_last_insn (); tree orig_arg = arg; - /* Make a suitable register to place result in. */ - if (!target - || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)) - || !insn_data[icode].operand[0].predicate (target, GET_MODE (target))) - target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); - - gcc_assert (insn_data[icode].operand[0].predicate - (target, GET_MODE (target))); /* Wrap the computation of the argument in a SAVE_EXPR, as we may need to expand the argument again. This way, we will not perform @@ -2452,10 +2443,11 @@ expand_builtin_interclass_mathfn (tree exp, rtx target) if (mode != GET_MODE (op0)) op0 = convert_to_mode (mode, op0, 0); - /* Compute into TARGET. - Set TARGET to wherever the result comes back. */ - if (maybe_emit_unop_insn (icode, target, op0, UNKNOWN)) - return target; + create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp))); + if (maybe_legitimize_operands (icode, 0, 1, ops) + && maybe_emit_unop_insn (icode, ops[0].value, op0, UNKNOWN)) + return ops[0].value; + delete_insns_since (last); CALL_EXPR_ARG (exp, 0) = orig_arg; } @@ -3362,11 +3354,12 @@ expand_builtin_strlen (tree exp, rtx target, return NULL_RTX; else { + struct expand_operand ops[4]; rtx pat; tree len; tree src = CALL_EXPR_ARG (exp, 0); - rtx result, src_reg, char_rtx, before_strlen; - enum machine_mode insn_mode = target_mode, char_mode; + rtx src_reg, before_strlen; + enum machine_mode insn_mode = target_mode; enum insn_code icode = CODE_FOR_nothing; unsigned int align; @@ -3405,14 +3398,6 @@ expand_builtin_strlen (tree exp, rtx target, if (insn_mode == VOIDmode) return NULL_RTX; - /* Make a place to write the result of the instruction. */ - result = target; - if (! (result != 0 - && REG_P (result) - && GET_MODE (result) == insn_mode - && REGNO (result) >= FIRST_PSEUDO_REGISTER)) - result = gen_reg_rtx (insn_mode); - /* Make a place to hold the source address. We will not expand the actual source until we are sure that the expansion will not fail -- there are trees that cannot be expanded twice. */ @@ -3422,17 +3407,12 @@ expand_builtin_strlen (tree exp, rtx target, source operand later. */ before_strlen = get_last_insn (); - char_rtx = const0_rtx; - 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); - - pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg), - char_rtx, GEN_INT (align)); - if (! pat) + create_output_operand (&ops[0], target, insn_mode); + create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg)); + create_integer_operand (&ops[2], 0); + create_integer_operand (&ops[3], align); + if (!maybe_expand_insn (icode, 4, ops)) return NULL_RTX; - emit_insn (pat); /* Now that we are assured of success, expand the source. */ start_sequence (); @@ -3448,12 +3428,12 @@ expand_builtin_strlen (tree exp, rtx target, emit_insn_before (pat, get_insns ()); /* Return the value in the proper mode for this function. */ - if (GET_MODE (result) == target_mode) - target = result; + if (GET_MODE (ops[0].value) == target_mode) + target = ops[0].value; else if (target != 0) - convert_move (target, result, 0); + convert_move (target, ops[0].value, 0); else - target = convert_to_mode (target_mode, result, 0); + target = convert_to_mode (target_mode, ops[0].value, 0); return target; } @@ -3674,56 +3654,39 @@ expand_builtin_mempcpy_args (tree dest, tree src, tree len, static rtx expand_movstr (tree dest, tree src, rtx target, int endp) { + struct expand_operand ops[3]; rtx end; rtx dest_mem; rtx src_mem; - rtx insn; - const struct insn_data_d * data; if (!HAVE_movstr) return NULL_RTX; dest_mem = get_memory_rtx (dest, NULL); src_mem = get_memory_rtx (src, NULL); - data = insn_data + CODE_FOR_movstr; if (!endp) { target = force_reg (Pmode, XEXP (dest_mem, 0)); dest_mem = replace_equiv_address (dest_mem, target); - end = gen_reg_rtx (Pmode); - } - else - { - if (target == 0 - || target == const0_rtx - || ! (*data->operand[0].predicate) (target, Pmode)) - { - end = gen_reg_rtx (Pmode); - if (target != const0_rtx) - target = end; - } - else - end = target; } - if (data->operand[0].mode != VOIDmode) - end = gen_lowpart (data->operand[0].mode, end); - - insn = data->genfun (end, dest_mem, src_mem); - - gcc_assert (insn); + create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode); + create_fixed_operand (&ops[1], dest_mem); + create_fixed_operand (&ops[2], src_mem); + expand_insn (CODE_FOR_movstr, 3, ops); - emit_insn (insn); - - /* movstr is supposed to set end to the address of the NUL - terminator. If the caller requested a mempcpy-like return value, - adjust it. */ - if (endp == 1 && target != const0_rtx) + if (endp && target != const0_rtx) { - rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1); - emit_move_insn (target, force_operand (tem, NULL_RTX)); + target = ops[0].value; + /* movstr is supposed to set end to the address of the NUL + terminator. If the caller requested a mempcpy-like return value, + adjust it. */ + if (endp == 1) + { + rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1); + emit_move_insn (target, force_operand (tem, NULL_RTX)); + } } - return target; } @@ -5223,7 +5186,6 @@ expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED) /* We have a "clear_cache" insn, and it will handle everything. */ tree begin, end; rtx begin_rtx, end_rtx; - enum insn_code icode; /* We must not expand to a library call. If we did, any fallback library function in libgcc that might contain a call to @@ -5236,21 +5198,18 @@ expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED) if (HAVE_clear_cache) { - icode = CODE_FOR_clear_cache; + struct expand_operand ops[2]; begin = CALL_EXPR_ARG (exp, 0); begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL); - begin_rtx = convert_memory_address (Pmode, begin_rtx); - if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode)) - begin_rtx = copy_to_mode_reg (Pmode, begin_rtx); end = CALL_EXPR_ARG (exp, 1); end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL); - end_rtx = convert_memory_address (Pmode, end_rtx); - if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode)) - end_rtx = copy_to_mode_reg (Pmode, end_rtx); - emit_insn (gen_clear_cache (begin_rtx, end_rtx)); + create_address_operand (&ops[0], begin_rtx); + create_address_operand (&ops[1], end_rtx); + if (maybe_expand_insn (CODE_FOR_clear_cache, 2, ops)) + return const0_rtx; } return const0_rtx; #endif /* HAVE_clear_cache */ @@ -5748,9 +5707,9 @@ expand_builtin_synchronize (void) static void expand_builtin_lock_release (enum machine_mode mode, tree exp) { + struct expand_operand ops[2]; enum insn_code icode; - rtx mem, insn; - rtx val = const0_rtx; + rtx mem; /* Expand the operands. */ mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); @@ -5759,21 +5718,16 @@ expand_builtin_lock_release (enum machine_mode mode, tree exp) icode = direct_optab_handler (sync_lock_release_optab, mode); if (icode != CODE_FOR_nothing) { - if (!insn_data[icode].operand[1].predicate (val, mode)) - val = force_reg (mode, val); - - insn = GEN_FCN (icode) (mem, val); - if (insn) - { - emit_insn (insn); - return; - } + create_fixed_operand (&ops[0], mem); + create_input_operand (&ops[1], const0_rtx, mode); + if (maybe_expand_insn (icode, 2, ops)) + return; } /* Otherwise we can implement this operation by emitting a barrier followed by a store of zero. */ expand_builtin_synchronize (); - emit_move_insn (mem, val); + emit_move_insn (mem, const0_rtx); } /* Expand an expression EXP that calls a built-in function, |