Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/h8300/jumpcall.md @ 152:2b5abeee2509
update gcc11
author | anatofuz |
---|---|
date | Mon, 25 May 2020 07:50:57 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
145:1830386684a0 | 152:2b5abeee2509 |
---|---|
1 ;; ---------------------------------------------------------------------- | |
2 ;; JUMP INSTRUCTIONS | |
3 ;; ---------------------------------------------------------------------- | |
4 | |
5 ;; Conditional jump instructions | |
6 | |
7 (define_expand "cbranchqi4" | |
8 [(use (match_operator 0 "ordered_comparison_operator" | |
9 [(match_operand:QI 1 "h8300_dst_operand" "") | |
10 (match_operand:QI 2 "h8300_src_operand" "")])) | |
11 (use (match_operand 3 ""))] | |
12 "" | |
13 { | |
14 h8300_expand_branch (operands); | |
15 DONE; | |
16 }) | |
17 | |
18 (define_expand "cbranchhi4" | |
19 [(use (match_operator 0 "ordered_comparison_operator" | |
20 [(match_operand:HI 1 "h8300_dst_operand" "") | |
21 (match_operand:HI 2 "h8300_src_operand" "")])) | |
22 (use (match_operand 3 ""))] | |
23 "" | |
24 { | |
25 h8300_expand_branch (operands); | |
26 DONE; | |
27 }) | |
28 | |
29 (define_expand "cbranchsi4" | |
30 [(use (match_operator 0 "ordered_comparison_operator" | |
31 [(match_operand:SI 1 "h8300_dst_operand" "") | |
32 (match_operand:SI 2 "h8300_src_operand" "")])) | |
33 (use (match_operand 3 ""))] | |
34 "" | |
35 { | |
36 h8300_expand_branch (operands); | |
37 DONE; | |
38 }) | |
39 | |
40 (define_insn "branch" | |
41 [(set (pc) | |
42 (if_then_else (match_operator 2 "comparison_operator" | |
43 [(cc0) (const_int 0)]) | |
44 (match_operand 0 "pc_or_label_operand" "") | |
45 (match_operand 1 "pc_or_label_operand" "")))] | |
46 "operands[0] == pc_rtx || operands[1] == pc_rtx" | |
47 { | |
48 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 | |
49 && (GET_CODE (operands[2]) == GT | |
50 || GET_CODE (operands[2]) == GE | |
51 || GET_CODE (operands[2]) == LE | |
52 || GET_CODE (operands[2]) == LT)) | |
53 { | |
54 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; | |
55 return 0; | |
56 } | |
57 | |
58 if (operands[0] != pc_rtx) | |
59 { | |
60 if (get_attr_length (insn) == 2) | |
61 return "b%j2 %l0"; | |
62 else if (get_attr_length (insn) == 4) | |
63 return "b%j2 %l0:16"; | |
64 else | |
65 return "b%k2 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:"; | |
66 } | |
67 else | |
68 { | |
69 if (get_attr_length (insn) == 2) | |
70 return "b%k2 %l1"; | |
71 else if (get_attr_length (insn) == 4) | |
72 return "b%k2 %l1:16"; | |
73 else | |
74 return "b%j2 .Lh8BR%=\;jmp @%l1\\n.Lh8BR%=:"; | |
75 } | |
76 } | |
77 [(set_attr "type" "branch") | |
78 (set_attr "cc" "none")]) | |
79 | |
80 (define_insn "*brabc" | |
81 [(set (pc) | |
82 (if_then_else (eq (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU") | |
83 (const_int 1) | |
84 (match_operand:QI 2 "immediate_operand" "n")) | |
85 (const_int 0)) | |
86 (label_ref (match_operand 0 "" "")) | |
87 (pc)))] | |
88 "TARGET_H8300SX" | |
89 { | |
90 switch (get_attr_length (insn) | |
91 - h8300_insn_length_from_table (insn, operands)) | |
92 { | |
93 case 2: | |
94 return "bra/bc %2,%R1,%l0"; | |
95 case 4: | |
96 return "bra/bc %2,%R1,%l0:16"; | |
97 default: | |
98 return "bra/bs %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:"; | |
99 } | |
100 } | |
101 [(set_attr "type" "bitbranch") | |
102 (set_attr "length_table" "bitbranch") | |
103 (set_attr "cc" "none")]) | |
104 | |
105 (define_insn "*brabs" | |
106 [(set (pc) | |
107 (if_then_else (ne (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU") | |
108 (const_int 1) | |
109 (match_operand:QI 2 "immediate_operand" "n")) | |
110 (const_int 0)) | |
111 (label_ref (match_operand 0 "" "")) | |
112 (pc)))] | |
113 "TARGET_H8300SX" | |
114 { | |
115 switch (get_attr_length (insn) | |
116 - h8300_insn_length_from_table (insn, operands)) | |
117 { | |
118 case 2: | |
119 return "bra/bs %2,%R1,%l0"; | |
120 case 4: | |
121 return "bra/bs %2,%R1,%l0:16"; | |
122 default: | |
123 return "bra/bc %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:"; | |
124 } | |
125 } | |
126 [(set_attr "type" "bitbranch") | |
127 (set_attr "length_table" "bitbranch") | |
128 (set_attr "cc" "none")]) | |
129 | |
130 ;; Unconditional and other jump instructions. | |
131 | |
132 (define_insn "jump" | |
133 [(set (pc) | |
134 (label_ref (match_operand 0 "" "")))] | |
135 "" | |
136 { | |
137 if (final_sequence != 0) | |
138 { | |
139 if (get_attr_length (insn) == 2) | |
140 return "bra/s %l0"; | |
141 else | |
142 { | |
143 /* The branch isn't short enough to use bra/s. Output the | |
144 branch and delay slot in their normal order. | |
145 | |
146 If this is a backward branch, it will now be branching two | |
147 bytes further than previously thought. The length-based | |
148 test for bra vs. jump is very conservative though, so the | |
149 branch will still be within range. */ | |
150 rtx_sequence *seq; | |
151 int seen; | |
152 | |
153 seq = final_sequence; | |
154 final_sequence = 0; | |
155 final_scan_insn (seq->insn (1), asm_out_file, optimize, 1, & seen); | |
156 final_scan_insn (seq->insn (0), asm_out_file, optimize, 1, & seen); | |
157 seq->insn (1)->set_deleted (); | |
158 return ""; | |
159 } | |
160 } | |
161 else if (get_attr_length (insn) == 2) | |
162 return "bra %l0"; | |
163 else if (get_attr_length (insn) == 4) | |
164 return "bra %l0:16"; | |
165 else | |
166 return "jmp @%l0"; | |
167 } | |
168 [(set_attr "type" "branch") | |
169 (set (attr "delay_slot") | |
170 (if_then_else (match_test "TARGET_H8300SX") | |
171 (const_string "jump") | |
172 (const_string "none"))) | |
173 (set_attr "cc" "none")]) | |
174 | |
175 ;; This is a define expand, because pointers may be either 16 or 32 bits. | |
176 | |
177 (define_expand "tablejump" | |
178 [(parallel [(set (pc) (match_operand 0 "register_operand" "")) | |
179 (use (label_ref (match_operand 1 "" "")))])] | |
180 "" | |
181 "") | |
182 | |
183 (define_insn "tablejump<mode>" | |
184 [(set (pc) (match_operand:P 0 "register_operand" "r")) | |
185 (use (label_ref (match_operand 1 "" "")))] | |
186 "" | |
187 { | |
188 if (<MODE>mode == E_HImode) | |
189 return "jmp @%0"; | |
190 if (<MODE>mode == E_SImode) | |
191 return "jmp @%S0"; | |
192 abort (); | |
193 } | |
194 [(set_attr "cc" "none") | |
195 (set_attr "length" "2")]) | |
196 | |
197 ;; This is a define expand, because pointers may be either 16 or 32 bits. | |
198 | |
199 (define_expand "indirect_jump" | |
200 [(set (pc) (match_operand 0 "jump_address_operand" ""))] | |
201 "" | |
202 "") | |
203 | |
204 (define_insn "*indirect_jump_<mode>" | |
205 [(set (pc) (match_operand:P 0 "jump_address_operand" "Vr"))] | |
206 "" | |
207 { | |
208 if (<MODE>mode == E_HImode) | |
209 return "jmp @%0"; | |
210 if (<MODE>mode == E_SImode) | |
211 return "jmp @%S0"; | |
212 abort (); | |
213 } | |
214 [(set_attr "cc" "none") | |
215 (set_attr "length" "2")]) | |
216 | |
217 ;; Call subroutine with no return value. | |
218 | |
219 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S. | |
220 | |
221 (define_expand "call" | |
222 [(call (match_operand:QI 0 "call_expander_operand" "") | |
223 (match_operand 1 "general_operand" ""))] | |
224 "" | |
225 { | |
226 if (!register_operand (XEXP (operands[0], 0), Pmode) | |
227 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) | |
228 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0)); | |
229 }) | |
230 | |
231 (define_insn "call_insn_<mode>" | |
232 [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr")) | |
233 (match_operand:P 1 "general_operand" "g"))] | |
234 "" | |
235 { | |
236 rtx xoperands[1]; | |
237 xoperands[0] = gen_rtx_MEM (QImode, operands[0]); | |
238 gcc_assert (GET_MODE (operands[0]) == Pmode); | |
239 if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF | |
240 && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION)) | |
241 output_asm_insn ("jsr\\t@%0:8", xoperands); | |
242 else | |
243 output_asm_insn ("jsr\\t%0", xoperands); | |
244 return ""; | |
245 } | |
246 [(set_attr "type" "call") | |
247 (set (attr "length") | |
248 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "") | |
249 (const_int 2) | |
250 (const_int 4)))]) | |
251 | |
252 ;; Call subroutine, returning value in operand 0 | |
253 ;; (which must be a hard register). | |
254 | |
255 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S. | |
256 | |
257 (define_expand "call_value" | |
258 [(set (match_operand 0 "" "") | |
259 (call (match_operand:QI 1 "call_expander_operand" "") | |
260 (match_operand 2 "general_operand" "")))] | |
261 "" | |
262 { | |
263 if (!register_operand (XEXP (operands[1], 0), Pmode) | |
264 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) | |
265 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0)); | |
266 }) | |
267 | |
268 (define_insn "call_value_insn_<mode>" | |
269 [(set (match_operand 0 "" "=r") | |
270 (call (mem:QI (match_operand 1 "call_insn_operand" "Cr")) | |
271 (match_operand:P 2 "general_operand" "g")))] | |
272 "" | |
273 { | |
274 rtx xoperands[2]; | |
275 gcc_assert (GET_MODE (operands[1]) == Pmode); | |
276 xoperands[0] = operands[0]; | |
277 xoperands[1] = gen_rtx_MEM (QImode, operands[1]); | |
278 if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF | |
279 && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION)) | |
280 output_asm_insn ("jsr\\t@%1:8", xoperands); | |
281 else | |
282 output_asm_insn ("jsr\\t%1", xoperands); | |
283 return ""; | |
284 } | |
285 [(set_attr "type" "call") | |
286 (set (attr "length") | |
287 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "") | |
288 (const_int 2) | |
289 (const_int 4)))]) | |
290 |