;; Copyright (C) 2013-2021 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 ;; . (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" [(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" [(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" [(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" "") (set_attr "can_delay" "no")])