aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips/micromips.md
blob: 4b7a4a7013f7d6740e338e0fb7dba7a002ebcedd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
;; Copyright (C) 2013 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 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")])