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