summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-18 17:34:06 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-18 17:34:06 +0000
commit43850f7a4acda2d8fe0118a296b3c888cf968202 (patch)
tree2d71577e02e248f2a39d8d852e69ab9ea07433d6 /gcc/optabs.c
parent2642796685af2c90aa6c18a3bba03f5c571f87bd (diff)
downloadgcc-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.c38
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 ();