diff options
Diffstat (limited to 'gcc-4.9/gcc/config/mips/micromips.md')
-rw-r--r-- | gcc-4.9/gcc/config/mips/micromips.md | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/mips/micromips.md b/gcc-4.9/gcc/config/mips/micromips.md new file mode 100644 index 000000000..3504044f9 --- /dev/null +++ b/gcc-4.9/gcc/config/mips/micromips.md @@ -0,0 +1,138 @@ +;; Copyright (C) 2013-2014 Free Software Foundation, Inc. +;; +;; micromips.md Machine Description for the microMIPS instruction set +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +(define_insn "*store_word_multiple" + [(match_parallel 0 "" + [(set (match_operand:SI 1 "memory_operand") + (match_operand:SI 2 "register_operand"))])] + "TARGET_MICROMIPS + && umips_save_restore_pattern_p (true, operands[0])" + { return umips_output_save_restore (true, operands[0]); } + [(set_attr "type" "multimem") + (set_attr "mode" "SI") + (set_attr "can_delay" "no")]) + +(define_insn "*load_word_multiple" + [(match_parallel 0 "" + [(set (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "memory_operand"))])] + "TARGET_MICROMIPS + && umips_save_restore_pattern_p (false, operands[0])" + { return umips_output_save_restore (false, operands[0]); } + [(set_attr "type" "multimem") + (set_attr "mode" "SI") + (set_attr "can_delay" "no")]) + +;; For LWP. +(define_peephole2 + [(set (match_operand:SI 0 "d_operand" "") + (match_operand:SI 1 "non_volatile_mem_operand" "")) + (set (match_operand:SI 2 "d_operand" "") + (match_operand:SI 3 "non_volatile_mem_operand" ""))] + "TARGET_MICROMIPS + && umips_load_store_pair_p (true, operands)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])]) + +;; The behavior of the LWP insn is undefined if placed in a delay slot. +(define_insn "*lwp" + [(parallel [(set (match_operand:SI 0 "d_operand") + (match_operand:SI 1 "non_volatile_mem_operand")) + (set (match_operand:SI 2 "d_operand") + (match_operand:SI 3 "non_volatile_mem_operand"))])] + + "TARGET_MICROMIPS + && umips_load_store_pair_p (true, operands)" +{ + umips_output_load_store_pair (true, operands); + return ""; +} + [(set_attr "type" "load") + (set_attr "mode" "SI") + (set_attr "can_delay" "no")]) + +;; For SWP. +(define_peephole2 + [(set (match_operand:SI 0 "non_volatile_mem_operand" "") + (match_operand:SI 1 "d_operand" "")) + (set (match_operand:SI 2 "non_volatile_mem_operand" "") + (match_operand:SI 3 "d_operand" ""))] + "TARGET_MICROMIPS + && umips_load_store_pair_p (false, operands)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])]) + +;; The behavior of the SWP insn is undefined if placed in a delay slot. +(define_insn "*swp" + [(parallel [(set (match_operand:SI 0 "non_volatile_mem_operand") + (match_operand:SI 1 "d_operand")) + (set (match_operand:SI 2 "non_volatile_mem_operand") + (match_operand:SI 3 "d_operand"))])] + + "TARGET_MICROMIPS + && umips_load_store_pair_p (false, operands)" +{ + umips_output_load_store_pair (false, operands); + return ""; +} + [(set_attr "type" "store") + (set_attr "mode" "SI") + (set_attr "can_delay" "no")]) + +;; For JRADDIUSP. +(define_insn "jraddiusp" + [(parallel [(return) + (use (reg:SI 31)) + (set (reg:SI 29) + (plus:SI (reg:SI 29) + (match_operand 0 "uw5_operand")))])] + "TARGET_MICROMIPS" + "jraddiusp\t%0" + [(set_attr "type" "trap") + (set_attr "can_delay" "no") + (set_attr "mode" "SI")]) + +;; For MOVEP. +(define_peephole2 + [(set (match_operand:MOVEP1 0 "register_operand" "") + (match_operand:MOVEP1 1 "movep_src_operand" "")) + (set (match_operand:MOVEP2 2 "register_operand" "") + (match_operand:MOVEP2 3 "movep_src_operand" ""))] + "TARGET_MICROMIPS + && umips_movep_target_p (operands[0], operands[2])" + [(parallel [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))])]) + +;; The behavior of the MOVEP insn is undefined if placed in a delay slot. +(define_insn "*movep<MOVEP1:mode><MOVEP2:mode>" + [(parallel [(set (match_operand:MOVEP1 0 "register_operand") + (match_operand:MOVEP1 1 "movep_src_operand")) + (set (match_operand:MOVEP2 2 "register_operand") + (match_operand:MOVEP2 3 "movep_src_operand"))])] + "TARGET_MICROMIPS + && umips_movep_target_p (operands[0], operands[2])" +{ + if (REGNO (operands[0]) < REGNO (operands[2])) + return "movep\t%0,%2,%z1,%z3"; + else + return "movep\t%2,%0,%z3,%z1"; +} + [(set_attr "type" "move") + (set_attr "mode" "<MODE>") + (set_attr "can_delay" "no")]) |