comparison gcc/config/h8300/shiftrotate.md @ 19:2b5abeee2509 default tip

update gcc11
author anatofuz
date Mon, 25 May 2020 07:50:57 +0900
parents
children
comparison
equal deleted inserted replaced
18:1830386684a0 19:2b5abeee2509
1 ;; ----------------------------------------------------------------------
2 ;; SHIFTS
3 ;; ----------------------------------------------------------------------
4 ;;
5 ;; We make some attempt to provide real efficient shifting. One example is
6 ;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
7 ;; reg and moving 0 into the former reg.
8 ;;
9 ;; We also try to achieve this in a uniform way. IE: We don't try to achieve
10 ;; this in both rtl and at insn emit time. Ideally, we'd use rtl as that would
11 ;; give the optimizer more cracks at the code. However, we wish to do things
12 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
13 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
14 ;; 16-bit rotates. Also, if we emit complicated rtl, combine may not be able
15 ;; to detect cases it can optimize.
16 ;;
17 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
18 ;; easier "do it at insn emit time" route.
19
20
21 (define_expand "ashl<mode>3"
22 [(set (match_operand:QHSI 0 "register_operand" "")
23 (ashift:QHSI (match_operand:QHSI 1 "register_operand" "")
24 (match_operand:QI 2 "nonmemory_operand" "")))]
25 ""
26 {
27 if (expand_a_shift (<MODE>mode, ASHIFT, operands))
28 DONE;
29 })
30
31 (define_expand "ashr<mode>3"
32 [(set (match_operand:QHSI 0 "register_operand" "")
33 (ashiftrt:QHSI (match_operand:QHSI 1 "register_operand" "")
34 (match_operand:QI 2 "nonmemory_operand" "")))]
35 ""
36 {
37 if (expand_a_shift (<MODE>mode, ASHIFTRT, operands))
38 DONE;
39 })
40
41 (define_expand "lshr<mode>3"
42 [(set (match_operand:QHSI 0 "register_operand" "")
43 (lshiftrt:QHSI (match_operand:QHSI 1 "register_operand" "")
44 (match_operand:QI 2 "nonmemory_operand" "")))]
45 ""
46 {
47 if (expand_a_shift (<MODE>mode, LSHIFTRT, operands))
48 DONE;
49 })
50
51 ;; QI/HI/SI BIT SHIFTS
52
53 (define_insn ""
54 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
55 (match_operator:QHSI 3 "h8sx_unary_shift_operator"
56 [(match_operand:QHSI 1 "h8300_dst_operand" "0")
57 (match_operand:QI 2 "const_int_operand" "")]))]
58 "h8300_operands_match_p (operands)"
59 {
60 if (<MODE>mode == E_QImode)
61 return output_h8sx_shift (operands, 'b', 'X');
62 if (<MODE>mode == E_HImode)
63 return output_h8sx_shift (operands, 'w', 'T');
64 if (<MODE>mode == E_SImode)
65 return output_h8sx_shift (operands, 'l', 'S');
66 gcc_unreachable ();
67 }
68 [(set_attr "length_table" "unary")
69 (set_attr "cc" "set_znv")])
70
71 (define_insn ""
72 [(set (match_operand:QHSI 0 "register_operand" "=r")
73 (match_operator:QHSI 3 "h8sx_binary_shift_operator"
74 [(match_operand:QHSI 1 "register_operand" "0")
75 (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
76 ""
77 {
78 if (<MODE>mode == QImode)
79 return output_h8sx_shift (operands, 'b', 'X');
80 if (<MODE>mode == HImode)
81 return output_h8sx_shift (operands, 'w', 'T');
82 if (<MODE>mode == SImode)
83 return output_h8sx_shift (operands, 'l', 'S');
84 gcc_unreachable ();
85 }
86 [(set_attr "length" "4")
87 (set_attr "cc" "set_znv")])
88
89 (define_insn "*shiftqi"
90 [(set (match_operand:QI 0 "register_operand" "=r,r")
91 (match_operator:QI 3 "nshift_operator"
92 [(match_operand:QI 1 "register_operand" "0,0")
93 (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
94 (clobber (match_scratch:QI 4 "=X,&r"))]
95 ""
96 {
97 return output_a_shift (operands);
98 }
99 [(set (attr "length")
100 (symbol_ref "compute_a_shift_length (insn, operands)"))
101 (set (attr "cc")
102 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
103
104 (define_insn "*shifthi"
105 [(set (match_operand:HI 0 "register_operand" "=r,r")
106 (match_operator:HI 3 "nshift_operator"
107 [(match_operand:HI 1 "register_operand" "0,0")
108 (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
109 (clobber (match_scratch:QI 4 "=X,&r"))]
110 ""
111 {
112 return output_a_shift (operands);
113 }
114 [(set (attr "length")
115 (symbol_ref "compute_a_shift_length (insn, operands)"))
116 (set (attr "cc")
117 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
118
119 (define_insn "*shiftsi"
120 [(set (match_operand:SI 0 "register_operand" "=r,r")
121 (match_operator:SI 3 "nshift_operator"
122 [(match_operand:SI 1 "register_operand" "0,0")
123 (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
124 (clobber (match_scratch:QI 4 "=X,&r"))]
125 ""
126 {
127 return output_a_shift (operands);
128 }
129 [(set (attr "length")
130 (symbol_ref "compute_a_shift_length (insn, operands)"))
131 (set (attr "cc")
132 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
133
134
135 ;; Split a variable shift into a loop. If the register containing
136 ;; the shift count dies, then we just use that register.
137
138 (define_split
139 [(set (match_operand 0 "register_operand" "")
140 (match_operator 2 "nshift_operator"
141 [(match_dup 0)
142 (match_operand:QI 1 "register_operand" "")]))
143 (clobber (match_operand:QI 3 "register_operand" ""))]
144 "epilogue_completed
145 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
146 [(set (cc0) (compare (match_dup 1) (const_int 0)))
147 (set (pc)
148 (if_then_else (le (cc0) (const_int 0))
149 (label_ref (match_dup 5))
150 (pc)))
151 (match_dup 4)
152 (parallel
153 [(set (match_dup 0)
154 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
155 (clobber (scratch:QI))])
156 (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
157 (set (cc0) (compare (match_dup 1) (const_int 0)))
158 (set (pc)
159 (if_then_else (ne (cc0) (const_int 0))
160 (label_ref (match_dup 4))
161 (pc)))
162 (match_dup 5)]
163 {
164 operands[4] = gen_label_rtx ();
165 operands[5] = gen_label_rtx ();
166 })
167
168 (define_split
169 [(set (match_operand 0 "register_operand" "")
170 (match_operator 2 "nshift_operator"
171 [(match_dup 0)
172 (match_operand:QI 1 "register_operand" "")]))
173 (clobber (match_operand:QI 3 "register_operand" ""))]
174 "epilogue_completed
175 && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
176 [(set (match_dup 3)
177 (match_dup 1))
178 (set (cc0) (compare (match_dup 3) (const_int 0)))
179 (set (pc)
180 (if_then_else (le (cc0) (const_int 0))
181 (label_ref (match_dup 5))
182 (pc)))
183 (match_dup 4)
184 (parallel
185 [(set (match_dup 0)
186 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
187 (clobber (scratch:QI))])
188 (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
189 (set (cc0) (compare (match_dup 3) (const_int 0)))
190 (set (pc)
191 (if_then_else (ne (cc0) (const_int 0))
192 (label_ref (match_dup 4))
193 (pc)))
194 (match_dup 5)]
195 {
196 operands[4] = gen_label_rtx ();
197 operands[5] = gen_label_rtx ();
198 })
199
200 ;; ----------------------------------------------------------------------
201 ;; ROTATIONS
202 ;; ----------------------------------------------------------------------
203
204 (define_expand "rotl<mode>3"
205 [(set (match_operand:QHSI 0 "register_operand" "")
206 (rotate:QHSI (match_operand:QHSI 1 "register_operand" "")
207 (match_operand:QI 2 "nonmemory_operand" "")))]
208 ""
209 {
210 if (expand_a_rotate (operands))
211 DONE;
212 })
213
214 (define_insn "rotl<mode>3_1"
215 [(set (match_operand:QHSI 0 "register_operand" "=r")
216 (rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
217 (match_operand:QI 2 "immediate_operand" "")))]
218 ""
219 {
220 return output_a_rotate (ROTATE, operands);
221 }
222 [(set (attr "length")
223 (symbol_ref "compute_a_rotate_length (operands)"))])