diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-18 17:34:06 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-18 17:34:06 +0000 |
commit | 43850f7a4acda2d8fe0118a296b3c888cf968202 (patch) | |
tree | 2d71577e02e248f2a39d8d852e69ab9ea07433d6 /gcc/optabs.c | |
parent | 2642796685af2c90aa6c18a3bba03f5c571f87bd (diff) | |
download | gcc-43850f7a4acda2d8fe0118a296b3c888cf968202.tar.gz |
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<mode>, extv<mode>): ...these new patterns. Rename
existing extv<mode> pattern to...
(*extv<mode>): ...this.
(extzv): Split into...
(extzvmisalign<mode>, extzv<mode>): ...these new patterns. Rename
existing extzv<mode> pattern to...
(*extzv<mode>): ...this.
(insv): Split into...
(insvmisalign<mode>, insv<mode>): ...these new patterns. Rename
existing insv<mode> pattern to...
(*insv<mode>): ...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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193606 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 66c0337b0fd..353727f3324 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 (); |