From d2eeb2d179a4353af0a8ff989222301c4f7dc11b Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 18 Nov 2012 17:34:06 +0000 Subject: gcc/ * doc/md.texi (extv@var{m}, extvmisalign@var{m}, extzv@var{m}) (extzvmisalign@var{m}, insv@var{m}, insvmisalign@var{m}): Document. (insv, extv, extzv): Deprecate. * optabs.def (insv_optab, extv_optab, extzv_optab) (insvmisalign_optab, extvmisalign_optab, extzvmisalign_optab): New optabs. * optabs.c (get_optab_extraction_insn): New function. (get_extraction_insn): Use it. * config/mips/mips.md (extv): Split into... (extvmisalign, extv): ...these new patterns. Rename existing extv pattern to... (*extv): ...this. (extzv): Split into... (extzvmisalign, extzv): ...these new patterns. Rename existing extzv pattern to... (*extzv): ...this. (insv): Split into... (insvmisalign, insv): ...these new patterns. Rename existing insv pattern to... (*insv): ...this. Use const_int_operand rather than immediate_operand. * config/mips/mips.c (mips_block_move_straight): Use set_mem_size to set the size of BLKmode accesses. (mips_get_unaligned_mem): Require OP0 to be a BLKmode memory, turning it from an "rtx *" to an rtx. (mips_expand_ext_as_unaligned_load): Simplify for new optab interface. Update call to mips_get_unaligned_mem. (mips_expand_ins_as_unaligned_store): Update call to mips_get_unaligned_mem. From-SVN: r193606 --- gcc/optabs.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'gcc/optabs.c') diff --git a/gcc/optabs.c b/gcc/optabs.c index 66c0337..353727f 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -8294,6 +8294,35 @@ get_traditional_extraction_insn (extraction_insn *insn, return true; } +/* Return true if an optab exists to perform an insertion or extraction + of type TYPE in mode MODE. Describe the instruction in *INSN if so. + + REG_OPTAB is the optab to use for register structures and + MISALIGN_OPTAB is the optab to use for misaligned memory structures. + POS_OP is the operand number of the bit position. */ + +static bool +get_optab_extraction_insn (struct extraction_insn *insn, + enum extraction_type type, + enum machine_mode mode, direct_optab reg_optab, + direct_optab misalign_optab, int pos_op) +{ + direct_optab optab = (type == ET_unaligned_mem ? misalign_optab : reg_optab); + enum insn_code icode = direct_optab_handler (optab, mode); + if (icode == CODE_FOR_nothing) + return false; + + const struct insn_data_d *data = &insn_data[icode]; + + insn->icode = icode; + insn->field_mode = mode; + insn->struct_mode = (type == ET_unaligned_mem ? BLKmode : mode); + insn->pos_mode = data->operand[pos_op].mode; + if (insn->pos_mode == VOIDmode) + insn->pos_mode = word_mode; + return true; +} + /* Return true if an instruction exists to perform an insertion or extraction (PATTERN says which) of type TYPE in mode MODE. Describe the instruction in *INSN if so. */ @@ -8311,21 +8340,24 @@ get_extraction_insn (extraction_insn *insn, && get_traditional_extraction_insn (insn, type, mode, CODE_FOR_insv, 0, 3)) return true; - return false; + return get_optab_extraction_insn (insn, type, mode, insv_optab, + insvmisalign_optab, 2); case EP_extv: if (HAVE_extv && get_traditional_extraction_insn (insn, type, mode, CODE_FOR_extv, 1, 0)) return true; - return false; + return get_optab_extraction_insn (insn, type, mode, extv_optab, + extvmisalign_optab, 3); case EP_extzv: if (HAVE_extzv && get_traditional_extraction_insn (insn, type, mode, CODE_FOR_extzv, 1, 0)) return true; - return false; + return get_optab_extraction_insn (insn, type, mode, extzv_optab, + extzvmisalign_optab, 3); default: gcc_unreachable (); -- cgit v1.1