]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/msp430/msp430.md
genrecog.c (validate_pattern): Treat all messages except missing modes as errors.
[thirdparty/gcc.git] / gcc / config / msp430 / msp430.md
1 ;; Machine Description for TI MSP43* processors
2 ;; Copyright (C) 2013 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20 \f
21
22 (define_constants
23 [
24 (PC_REGNO 0)
25 (SP_REGNO 1)
26 (CARRY 2)
27 ])
28
29 (define_c_enum "unspec"
30 [
31 UNS_PROLOGUE_START_MARKER
32 UNS_PROLOGUE_END_MARKER
33 UNS_EPILOGUE_START_MARKER
34 UNS_EPILOGUE_HELPER
35
36 UNS_PUSHM
37 UNS_POPM
38
39 UNS_GROW_AND_SWAP
40 UNS_SWAP_AND_SHRINK
41
42 UNS_DINT
43 UNS_EINT
44 UNS_PUSH_INTR
45 UNS_POP_INTR
46 UNS_BIC_SR
47 UNS_BIS_SR
48 ])
49
50 (include "predicates.md")
51 (include "constraints.md")
52
53 (define_mode_iterator QHI [QI HI PSI])
54
55 ;; There are two basic "family" tests we do here:
56 ;;
57 ;; msp430x - true if 430X instructions are available.
58 ;; TARGET_LARGE - true if pointers are 20-bits
59 ;;
60 ;; Note that there are three supported cases, since the base 430
61 ;; doesn't have 20-bit pointers:
62 ;;
63 ;; 1. MSP430 cpu, small model
64 ;; 2. MSP430X cpu, small model.
65 ;; 3. MSP430X cpu, large model.
66
67 ;;------------------------------------------------------------
68 ;; Moves
69
70 ;; Push/Pop must be before the generic move patterns
71
72 (define_insn "push"
73 [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO)))
74 (match_operand:HI 0 "register_operand" "r"))]
75 ""
76 "PUSH\t%0"
77 )
78
79 (define_insn "pusha"
80 [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
81 (match_operand:PSI 0 "register_operand" "r"))]
82 "TARGET_LARGE"
83 "PUSHX.A\t%0"
84 )
85
86 (define_insn "pushm"
87 [(unspec_volatile [(match_operand 0 "register_operand" "r")
88 (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
89 ""
90 "PUSHM%B0\t%1, %0"
91 )
92
93 (define_insn "pop"
94 [(set (match_operand:HI 0 "register_operand" "=r")
95 (mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
96 ""
97 "POP\t%0"
98 )
99
100 (define_insn "popa"
101 [(set (match_operand:PSI 0 "register_operand" "=r")
102 (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
103 "TARGET_LARGE"
104 "POPX.A\t%0"
105 )
106
107 ;; This is nasty. Operand0 is bogus. It is only there so that we can get a
108 ;; mode for the %B0 to work. We should use operand1 for this, but that does
109 ;; not have a mode.
110 ;;
111 ;; Operand1 is actually a register, but we cannot accept (REG...) because the
112 ;; cprop_hardreg pass can and will renumber registers even inside
113 ;; unspec_volatiles. So we take an integer register number parameter and
114 ;; fudge it to be a register name when we generate the assembler. We use %I
115 ;; because that is the only operator that will omit the # prefix to an
116 ;; integer value. Unfortunately it also inverts the integer value, so we
117 ;; have pre-invert it when generating this insn. (We could of course add a
118 ;; new operator, eg %D, just for this pattern...)
119 ;;
120 ;; The pushm pattern does not have this problem because of all of the
121 ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
122 (define_insn "popm"
123 [(unspec_volatile [(match_operand 0 "register_operand" "r")
124 (match_operand 1 "immediate_operand" "i")
125 (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
126 ""
127 "POPM%B0\t%2, r%I1"
128 )
129
130 ;; The next two patterns are here to support a "feature" of how GCC implements
131 ;; varargs. When a function uses varargs and the *second* to last named
132 ;; argument is split between argument registers and the stack, gcc expects the
133 ;; callee to allocate space on the stack that can contain the register-based
134 ;; part of the argument. This space *has* to be just before the remaining
135 ;; arguments (ie the ones that are fully on the stack).
136 ;;
137 ;; The problem is that the MSP430 CALL instruction pushes the return address
138 ;; onto the stack in the exact place where the callee wants to allocate
139 ;; this extra space. So we need a sequence of instructions that can allocate
140 ;; the extra space and then move the return address down the stack, so that
141 ;; the extra space is now adjacent to the remaining arguments.
142 ;;
143 ;; This could be constructed through regular insns, but they might be split up
144 ;; by a misguided optimization, so an unspec volatile is used instead.
145
146 (define_insn "grow_and_swap"
147 [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)]
148 ""
149 { if (TARGET_LARGE)
150 return "SUBA\t#2, r1 \n MOVX.A\t2(r1), 0(r1)";
151 return "SUB\t#2, r1 \n MOV.W\t2(r1), 0(r1)";
152 }
153 )
154
155 (define_insn "swap_and_shrink"
156 [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)]
157 ""
158 { return TARGET_LARGE
159 ? "MOVX.A\t0(r1), 2(r1) \n ADDA\t#2, SP"
160 : "MOV.W\t0(r1), 2(r1) \n ADD\t#2, SP";
161 })
162
163 ; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
164 ; zero_extend anyway. Catch it here.
165 (define_insn "movqihi"
166 [(set (match_operand:HI 0 "register_operand" "=r,r")
167 (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))]
168 ""
169 "@
170 MOV.B\t%1, %0
171 MOV%X1.B\t%1, %0"
172 )
173
174 (define_insn "movqi"
175 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm")
176 (match_operand:QI 1 "general_operand" "riYs,rmi"))]
177 ""
178 "@
179 MOV.B\t%1, %0
180 MOV%X0.B\t%1, %0"
181 )
182
183 (define_insn "movhi"
184 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm")
185 (match_operand:HI 1 "general_operand" "riYs,rmi"))]
186 ""
187 "@
188 MOV.W\t%1, %0
189 MOV%X0.W\t%1, %0"
190 )
191
192 (define_expand "movsi"
193 [(set (match_operand:SI 0 "nonimmediate_operand")
194 (match_operand:SI 1 "general_operand"))]
195 ""
196 ""
197 )
198
199 (define_insn_and_split "movsi_x"
200 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
201 (match_operand:SI 1 "general_operand" "rmi"))]
202 ""
203 "#"
204 "reload_completed"
205 [(set (match_operand:HI 2 "nonimmediate_operand")
206 (match_operand:HI 4 "general_operand"))
207 (set (match_operand:HI 3 "nonimmediate_operand")
208 (match_operand:HI 5 "general_operand"))]
209 "msp430_split_movsi (operands);"
210 )
211
212 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
213 (define_insn "movpsi"
214 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,Ya,rm")
215 (match_operand:PSI 1 "general_operand" "riYa,r,rmi"))]
216 ""
217 "@
218 MOV%A0\t%1, %0
219 MOV%A0\t%1, %0
220 MOV%X0.%A0\t%1, %0")
221
222 ; This pattern is identical to the truncsipsi2 pattern except
223 ; that it uses a SUBREG instead of a TRUNC. It is needed in
224 ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI)))
225 ; into (SET:PSI (PSI)).
226 ;
227 ; Note: using POPM.A #1 is two bytes smaller than using POPX.A....
228
229 (define_insn "movsipsi2"
230 [(set (match_operand:PSI 0 "register_operand" "=r")
231 (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
232 "TARGET_LARGE"
233 "PUSH.W\t%H1 { PUSH.W %L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
234 )
235
236 ;;------------------------------------------------------------
237 ;; Math
238
239 (define_insn "addpsi3"
240 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,rm")
241 (plus:PSI (match_operand:PSI 1 "nonimmediate_operand" "%0,0")
242 (match_operand:PSI 2 "general_operand" "rLs,rmi")))]
243 ""
244 "@
245 ADDA\t%2, %0
246 ADDX.A\t%2, %0"
247 )
248
249 (define_insn "addqi3"
250 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm")
251 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
252 (match_operand:QI 2 "general_operand" "riYs,rmi")))]
253 ""
254 "@
255 ADD.B\t%2, %0
256 ADD%X0.B\t%2, %0"
257 )
258
259 (define_insn "addhi3"
260 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm")
261 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
262 (match_operand:HI 2 "general_operand" "riYs,rmi")))]
263 ""
264 "@
265 ADD.W\t%2, %0
266 ADD%X0.W\t%2, %0"
267 )
268
269 ; This pattern is needed in order to avoid reload problems.
270 ; It takes an SI pair of registers, adds a value to them, and
271 ; then converts them into a single PSI register.
272
273 (define_insn "addsipsi3"
274 [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0)
275 (plus:SI (match_operand:SI 1 "register_operand" "0")
276 (match_operand 2 "general_operand" "rmi")))]
277 ""
278 "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W %H0 { PUSH.W %L0 { POPM.A #1, %0"
279 )
280
281 (define_insn "addsi3"
282 [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm")
283 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
284 (match_operand:SI 2 "general_operand" "r,mi")))]
285 ""
286 "@
287 ADD\t%L2, %L0 { ADDC\t%H2, %H0
288 ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0"
289 )
290
291 ; Version of addhi that exposes the carry operations, for SImode adds.
292 ;
293 ; NOTE - we are playing a dangerous game with GCC here. We have these two
294 ; add patterns and the splitter that follows because our tests have shown
295 ; that this results in a significant reduction in code size - because GCC is
296 ; able to discard any unused part of the addition. We have to annotate the
297 ; patterns with the set and use of the carry flag because otherwise GCC will
298 ; discard parts of the addition when they are actually needed. But we have
299 ; not annotated all the other patterns that set the CARRY flag as doing so
300 ; results in an overall increase in code size[1]. Instead we just *hope*
301 ; that GCC will not move a carry-setting instruction in between the first
302 ; and second adds.
303 ;
304 ; So far our experiments have shown that GCC is likely to move MOV and CMP
305 ; instructions in between the two adds, but not other instructions. MOV is
306 ; safe, CMP is not. So we have annotated the CMP patterns and left the
307 ; subtract, shift and other add patterns alone. At the moment this is
308 ; working, but with future changes to the generic parts of GCC that might
309 ; change.
310 ;
311 ; [1] It is not clear exactly why the code size increases. The cause appears
312 ; to be that reload is more prevelent to spilling a variable onto the stack
313 ; but why it does this is unknown. Possibly the additional CLOBBERs necessary
314 ; to correctly annotate the other patterns makes reload think that there is
315 ; increased register pressure. Or possibly reload does not handle ADD patterns
316 ; that are not single_set() very well.
317
318 (define_insn "addhi3_cy"
319 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
320 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
321 (match_operand:HI 2 "general_operand" "r,rm")))
322 (set (reg:BI CARRY)
323 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
324 (zero_extend:SI (match_dup 2)))
325 (const_int 16))))
326 ]
327 ""
328 "@
329 ADD\t%2, %1 ; cy
330 ADD%X0\t%2, %1 ; cy"
331 )
332
333 (define_insn "addhi3_cy_i"
334 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
335 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
336 (match_operand:HI 2 "general_operand" "i,i")))
337 (set (reg:BI CARRY)
338 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
339 (match_operand 3 "immediate_operand" "i,i"))
340 (const_int 16))))
341 ]
342 ""
343 "@
344 ADD\t%2, %1 ; cy
345 ADD%X0\t%2, %1 ; cy"
346 )
347
348 ; Version of addhi that adds the carry, for SImode adds.
349 (define_insn "addchi4_cy"
350 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
351 (plus:HI (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
352 (match_operand:HI 2 "general_operand" "ri,rmi"))
353 (zero_extend:HI (reg:BI CARRY))))
354 ]
355 ""
356 "@
357 ADDC\t%2, %1
358 ADDC%X0\t%2, %1"
359 )
360
361 ; Split an SImode add into two HImode adds, keeping track of the carry
362 ; so that gcc knows when it can and can't optimize away the two
363 ; halves.
364 (define_split
365 [(set (match_operand:SI 0 "msp430_nonsubreg_operand")
366 (plus:SI (match_operand:SI 1 "nonimmediate_operand")
367 (match_operand:SI 2 "general_operand")))
368 ]
369 ""
370 [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm")
371 (plus:HI (match_dup 4)
372 (match_dup 5)))
373 (set (reg:BI CARRY)
374 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4))
375 (match_dup 9))
376 (const_int 16))))
377 ])
378 (set (match_operand:HI 6 "nonimmediate_operand" "=&rm")
379 (plus:HI (plus:HI (match_dup 7)
380 (match_dup 8))
381 (zero_extend:HI (reg:BI CARRY))))
382 ]
383 "
384 operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
385 operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
386 operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
387 operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
388 operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
389 operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
390 if (GET_CODE (operands[5]) == CONST_INT)
391 {
392 operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
393 }
394 else
395 {
396 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
397 }
398 "
399 )
400
401
402 ;; Alternatives 2 and 3 are to handle cases generated by reload.
403 (define_insn "subpsi3"
404 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r, rm, &?r, ?&r")
405 (minus:PSI (match_operand:PSI 1 "general_operand" "0, 0, !r, !i")
406 (match_operand:PSI 2 "general_operand" "rLs, rmi, rmi, r")))]
407 ""
408 "@
409 SUBA\t%2, %0
410 SUBX.A\t%2, %0
411 MOVX.A\t%1, %0 { SUBX.A\t%2, %0
412 MOVX.A\t%1, %0 { SUBA\t%2, %0"
413 )
414
415 ;; Alternatives 2 and 3 are to handle cases generated by reload.
416 (define_insn "subqi3"
417 [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
418 (minus:QI (match_operand:QI 1 "general_operand" "0, 0, !r, !i")
419 (match_operand:QI 2 "general_operand" " riYs, rmi, rmi, r")))]
420 ""
421 "@
422 SUB.B\t%2, %0
423 SUB%X0.B\t%2, %0
424 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0
425 MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
426 )
427
428 ;; Alternatives 2 and 3 are to handle cases generated by reload.
429 (define_insn "subhi3"
430 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r")
431 (minus:HI (match_operand:HI 1 "general_operand" "0, 0, !r, !i")
432 (match_operand:HI 2 "general_operand" " riYs, rmi, rmi, r")))]
433 ""
434 "@
435 SUB.W\t%2, %0
436 SUB%X0.W\t%2, %0
437 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0
438 MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
439 )
440
441 (define_insn "subsi3"
442 [(set (match_operand:SI 0 "nonimmediate_operand" "=&rm")
443 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
444 (match_operand:SI 2 "general_operand" "rmi")))]
445 ""
446 "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0"
447 )
448
449 (define_insn "*bic<mode>_cg"
450 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m")
451 (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0")
452 (match_operand 2 "msp430_inv_constgen_operator" "n,n")))]
453 ""
454 "@
455 BIC%x0%B0\t#%I2, %0
456 BIC%X0%B0\t#%I2, %0"
457 )
458
459 (define_insn "bic<mode>3"
460 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
461 (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand" "rYs,rmn"))
462 (match_operand:QHI 2 "msp_nonimmediate_operand" "0,0")))]
463 ""
464 "@
465 BIC%x0%B0\t%1, %0
466 BIC%X0%B0\t%1, %0"
467 )
468
469 (define_insn "and<mode>3"
470 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
471 (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
472 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
473 ""
474 "@
475 AND%x0%B0\t%2, %0
476 AND%X0%B0\t%2, %0"
477 )
478
479 (define_insn "ior<mode>3"
480 [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
481 (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
482 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
483 ""
484 "@
485 BIS%x0%B0\t%2, %0
486 BIS%X0%B0\t%2, %0"
487 )
488
489 (define_insn "xor<mode>3"
490 [(set (match_operand:QHI 0 "nonimmediate_operand" "=rYs,rm")
491 (xor:QHI (match_operand:QHI 1 "nonimmediate_operand" "%0,0")
492 (match_operand:QHI 2 "general_operand" "riYs,rmi")))]
493 ""
494 "@
495 XOR%x0%B0\t%2, %0
496 XOR%X0%B0\t%2, %0"
497 )
498
499 ;; Macro : XOR #~0, %0
500 (define_insn "one_cmpl<mode>2"
501 [(set (match_operand:QHI 0 "nonimmediate_operand" "=rYs,m")
502 (not:QHI (match_operand:QHI 1 "nonimmediate_operand" "0,0")))]
503 ""
504 "@
505 INV%x0%B0\t%0
506 INV%X0%B0\t%0"
507 )
508
509 (define_insn "extendqihi2"
510 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,m")
511 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
512 ""
513 "@
514 SXT%X0\t%0
515 SXT%X0\t%0"
516 )
517
518 (define_insn "zero_extendqihi2"
519 [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,m")
520 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
521 ""
522 "@
523 AND\t#0xff, %0
524 AND%X0\t#0xff, %0"
525 )
526
527 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
528 (define_peephole2
529 [(set (match_operand:HI 0 "register_operand")
530 (zero_extend:HI (match_operand:QI 1 "general_operand")))
531 (set (match_operand:HI 2 "register_operand")
532 (zero_extend:HI (match_operand:QI 3 "register_operand")))]
533 "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])"
534 [(set (match_dup 0)
535 (zero_extend:HI (match_dup 1)))]
536 )
537
538 (define_insn "zero_extendhipsi2"
539 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,m")
540 (zero_extend:PSI (match_operand:HI 1 "nonimmediate_operand" "rm,r")))]
541 ""
542 "MOVX\t%1, %0"
543 )
544
545 (define_insn "truncpsihi2"
546 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
547 (truncate:HI (match_operand:PSI 1 "register_operand" "r")))]
548 ""
549 "MOVX\t%1, %0"
550 )
551
552 (define_insn "extendhisi2"
553 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
554 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
555 ""
556 { return msp430x_extendhisi (operands); }
557 )
558
559 (define_insn "extendhipsi2"
560 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r")
561 (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))]
562 "TARGET_LARGE"
563 "RLAM #4, %0 { RRAM #4, %0"
564 )
565
566 ;; Look for cases where integer/pointer conversions are suboptimal due
567 ;; to missing patterns, despite us not having opcodes for these
568 ;; patterns. Doing these manually allows for alternate optimization
569 ;; paths.
570 (define_insn "zero_extendhisi2"
571 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
572 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))]
573 "TARGET_LARGE"
574 "MOV.W\t#0,%H0"
575 )
576
577 (define_insn "zero_extendhisipsi2"
578 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r")
579 (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))]
580 "TARGET_LARGE"
581 "@
582 AND.W\t#-1,%0
583 MOV.W\t%1,%0"
584 )
585
586 (define_insn "extend_and_shift1_hipsi2"
587 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
588 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
589 (const_int 1)))]
590 "TARGET_LARGE"
591 "RLAM #4, %0 { RRAM #3, %0"
592 )
593
594 (define_insn "extend_and_shift2_hipsi2"
595 [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0)
596 (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0"))
597 (const_int 2)))]
598 "TARGET_LARGE"
599 "RLAM #4, %0 { RRAM #2, %0"
600 )
601
602 ; Nasty - we are sign-extending a 20-bit PSI value in one register into
603 ; two adjacent 16-bit registers to make an SI value. There is no MSP430X
604 ; instruction that will do this, so we push the 20-bit value onto the stack
605 ; and then pop it off as two 16-bit values.
606 ;
607 ; FIXME: The MSP430X documentation does not specify if zero-extension or
608 ; sign-extension happens when the 20-bit value is pushed onto the stack.
609 ; It is probably zero-extension, but if not this pattern will not work
610 ; when the PSI value is negative..
611 ;
612 ; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A....
613
614 (define_insn "zero_extendpsisi2"
615 [(set (match_operand:SI 0 "register_operand" "=r")
616 (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
617 ""
618 "*
619 if (REGNO (operands[1]) == SP_REGNO)
620 /* If the source register is the stack pointer, the value
621 stored in the stack slot will be the value *after* the
622 stack pointer has been decremented. So allow for that
623 here. */
624 return \"PUSHM.A\t#1, %1 { ADDX.W #4, @r1 { POPX.W %L0 { POPX.W %H0 ; get stack pointer into %L0:%H0\";
625 else
626 return \"PUSHM.A\t#1, %1 { POPX.W %L0 { POPX.W %H0 ; move pointer in %1 into reg-pair %L0:%H0\";
627 "
628 )
629
630 ;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
631 ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends
632 ;; it, we use a different method here.
633
634 (define_insn "extendpsisi2"
635 [(set (match_operand:SI 0 "register_operand" "=r")
636 (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
637 "TARGET_LARGE"
638 "*
639 /* The intention here is that we copy the bottom 16-bits of
640 %1 into %L0 (zeroing the top four bits). Then we copy the
641 entire 20-bits of %1 into %H0 and then arithmetically shift
642 it right by 16 bits, to get the top four bits of the pointer
643 sign-extended in %H0. */
644 if (REGNO (operands[0]) == REGNO (operands[1]))
645 return \"MOVX.A\t%1, %H0 { MOV.W %1, %L0 { RPT #16 { RRAX.A %H0 ; sign extend pointer in %1 into %L0:%H0\";
646 else
647 return \"MOV.W \t%1, %L0 { MOVX.A %1, %H0 { RPT #16 { RRAX.A %H0 ; sign extend pointer in %1 into %L0:%H0\";
648 "
649 )
650
651 ; See the movsipsi2 pattern above for another way that GCC performs this
652 ; conversion.
653 (define_insn "truncsipsi2"
654 [(set (match_operand:PSI 0 "register_operand" "=r")
655 (truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
656 ""
657 "PUSH.W %H1 { PUSH.W %1 { POPM.A #1, %0"
658 )
659
660 ;;------------------------------------------------------------
661 ;; Shift Functions
662
663 ;; Note: We do not use the RPT ... SHIFT instruction sequence
664 ;; when the repeat count is in a register, because even though RPT
665 ;; accepts counts in registers, it does not work if the count is
666 ;; zero, and the actual count in the register has to be one less
667 ;; than the required number of iterations. We could encode a
668 ;; seqeunce like this:
669 ;;
670 ;; bit #0xf, Rn
671 ;; bz 1f
672 ;; dec Rn
673 ;; rpt Rn
674 ;; <shift> Rm
675 ;; inc Rn
676 ;; 1:
677 ;;
678 ;; But is longer than calling a helper function, and we are mostly
679 ;; concerned with code size. FIXME: Maybe enable a sequence like
680 ;; this at -O3 and above ?
681 ;;
682 ;; Note - we ignore shift counts of less than one or more than 15.
683 ;; This is permitted by the ISO C99 standard as such shifts result
684 ;; in "undefined" behaviour. [6.5.7 (3)]
685
686 ;; signed A << C
687
688 (define_expand "ashlhi3"
689 [(set (match_operand:HI 0 "nonimmediate_operand")
690 (ashift:HI (match_operand:HI 1 "general_operand")
691 (match_operand:HI 2 "general_operand")))]
692 ""
693 {
694 if (msp430x
695 && REG_P (operands[0])
696 && REG_P (operands[1])
697 && CONST_INT_P (operands[2]))
698 emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
699 else
700 msp430_expand_helper (operands, \"__mspabi_slli\", true);
701 DONE;
702 }
703 )
704
705 (define_insn "slli_1"
706 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
707 (ashift:HI (match_operand:HI 1 "general_operand" "0")
708 (const_int 1)))]
709 ""
710 "RLA.W\t%0" ;; Note - this is a macro for ADD
711 )
712
713 (define_insn "430x_shift_left"
714 [(set (match_operand:HI 0 "register_operand" "=r")
715 (ashift:HI (match_operand:HI 1 "register_operand" "0")
716 (match_operand 2 "immediate_operand" "n")))]
717 "msp430x"
718 "*
719 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
720 return \"rpt\t%2 { rlax.w\t%0\";
721 return \"# nop left shift\";
722 "
723 )
724
725 (define_insn "slll_1"
726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
727 (ashift:SI (match_operand:SI 1 "general_operand" "0")
728 (const_int 1)))]
729 ""
730 "RLA.W\t%L0 { RLC.W\t%H0"
731 )
732
733 (define_insn "slll_2"
734 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
735 (ashift:SI (match_operand:SI 1 "general_operand" "0")
736 (const_int 2)))]
737 ""
738 "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0"
739 )
740
741 (define_expand "ashlsi3"
742 [(set (match_operand:SI 0 "nonimmediate_operand")
743 (ashift:SI (match_operand:SI 1 "general_operand")
744 (match_operand:SI 2 "general_operand")))]
745 ""
746 "msp430_expand_helper (operands, \"__mspabi_slll\", true);
747 DONE;"
748 )
749
750 ;;----------
751
752 ;; signed A >> C
753
754 (define_expand "ashrhi3"
755 [(set (match_operand:HI 0 "nonimmediate_operand")
756 (ashiftrt:HI (match_operand:HI 1 "general_operand")
757 (match_operand:HI 2 "general_operand")))]
758 ""
759 {
760 if (msp430x
761 && REG_P (operands[0])
762 && REG_P (operands[1])
763 && CONST_INT_P (operands[2]))
764 emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
765 else
766 msp430_expand_helper (operands, \"__mspabi_srai\", true);
767 DONE;
768 }
769 )
770
771 (define_insn "srai_1"
772 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
773 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
774 (const_int 1)))]
775 ""
776 "RRA.W\t%0"
777 )
778
779 (define_insn "430x_arithmetic_shift_right"
780 [(set (match_operand:HI 0 "register_operand" "=r")
781 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
782 (match_operand 2 "immediate_operand" "n")))]
783 "msp430x"
784 "*
785 if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16)
786 return \"rpt\t%2 { rrax.w\t%0\";
787 return \"# nop arith right shift\";
788 "
789 )
790
791 (define_insn "srap_1"
792 [(set (match_operand:PSI 0 "register_operand" "=r")
793 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
794 (const_int 1)))]
795 "msp430x"
796 "RRAM.A #1,%0"
797 )
798
799 (define_insn "srap_2"
800 [(set (match_operand:PSI 0 "register_operand" "=r")
801 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
802 (const_int 2)))]
803 "msp430x"
804 "RRAM.A #2,%0"
805 )
806
807 (define_insn "sral_1"
808 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
809 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
810 (const_int 1)))]
811 ""
812 "RRA.W\t%H0 { RRC.W\t%L0"
813 )
814
815 (define_insn "sral_2"
816 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
817 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
818 (const_int 2)))]
819 ""
820 "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0"
821 )
822
823 (define_expand "ashrsi3"
824 [(set (match_operand:SI 0 "nonimmediate_operand")
825 (ashiftrt:SI (match_operand:SI 1 "general_operand")
826 (match_operand:SI 2 "general_operand")))]
827 ""
828 "msp430_expand_helper (operands, \"__mspabi_sral\", true);
829 DONE;"
830 )
831
832 ;;----------
833
834 ;; unsigned A >> C
835
836 (define_expand "lshrhi3"
837 [(set (match_operand:HI 0 "nonimmediate_operand")
838 (lshiftrt:HI (match_operand:HI 1 "general_operand")
839 (match_operand:HI 2 "general_operand")))]
840 ""
841 {
842 if (msp430x
843 && REG_P (operands[0])
844 && REG_P (operands[1])
845 && CONST_INT_P (operands[2]))
846 emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
847 else
848 msp430_expand_helper (operands, \"__mspabi_srli\", true);
849 DONE;
850 }
851 )
852
853 (define_insn "srli_1"
854 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
855 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
856 (const_int 1)))]
857 ""
858 "CLRC { RRC.W\t%0"
859 )
860
861 (define_insn "430x_logical_shift_right"
862 [(set (match_operand:HI 0 "register_operand" "=r")
863 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
864 (match_operand 2 "immediate_operand" "n")))]
865 "msp430x"
866 {
867 return msp430x_logical_shift_right (operands[2]);
868 }
869 )
870
871 (define_insn "srlp_1"
872 [(set (match_operand:PSI 0 "register_operand" "=r")
873 (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0")
874 (const_int 1)))]
875 ""
876 "RRUM.A #1,%0"
877 )
878
879 (define_insn "srll_1"
880 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
881 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
882 (const_int 1)))]
883 ""
884 "CLRC { RRC.W\t%H0 { RRC.W\t%L0"
885 )
886
887 (define_insn "srll_2x"
888 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
889 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
890 (const_int 2)))]
891 "msp430x"
892 "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0"
893 )
894
895 (define_expand "lshrsi3"
896 [(set (match_operand:SI 0 "nonimmediate_operand")
897 (lshiftrt:SI (match_operand:SI 1 "general_operand")
898 (match_operand:SI 2 "general_operand")))]
899 ""
900 "msp430_expand_helper (operands, \"__mspabi_srll\", true);
901 DONE;"
902 )
903
904 ;;------------------------------------------------------------
905 ;; Function Entry/Exit
906
907 (define_expand "prologue"
908 [(const_int 0)]
909 ""
910 "msp430_expand_prologue (); DONE;"
911 )
912
913 (define_expand "epilogue"
914 [(const_int 0)]
915 ""
916 "msp430_expand_epilogue (0); DONE;"
917 )
918
919
920 (define_insn "epilogue_helper"
921 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
922 ""
923 "BR%A0\t#__mspabi_func_epilog_%D0"
924 )
925
926
927 (define_insn "prologue_start_marker"
928 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
929 ""
930 "; start of prologue"
931 )
932
933 (define_insn "prologue_end_marker"
934 [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
935 ""
936 "; end of prologue"
937 )
938
939 (define_insn "epilogue_start_marker"
940 [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
941 ""
942 "; start of epilogue"
943 )
944
945 ;;------------------------------------------------------------
946 ;; Jumps
947
948 (define_expand "call"
949 [(call:HI (match_operand 0 "")
950 (match_operand 1 ""))]
951 ""
952 ""
953 )
954
955 (define_insn "call_internal"
956 [(call (mem:HI (match_operand 0 "general_operand" "rmi"))
957 (match_operand 1 ""))]
958 ""
959 "CALL%A0\t%0"
960 )
961
962 (define_expand "call_value"
963 [(set (match_operand 0 "register_operand")
964 (call:HI (match_operand 1 "general_operand")
965 (match_operand 2 "")))]
966 ""
967 ""
968 )
969
970 (define_insn "call_value_internal"
971 [(set (match_operand 0 "register_operand" "=r")
972 (call (mem:HI (match_operand 1 "general_operand" "rmi"))
973 (match_operand 2 "")))]
974 ""
975 "CALL%A0\t%1"
976 )
977
978 (define_insn "msp_return"
979 [(return)]
980 ""
981 { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
982 )
983
984 ;; This pattern is NOT, as expected, a return pattern. It's called
985 ;; before reload and must only store its operands, and emit a
986 ;; placeholder where the epilog needs to be. AFTER reload, the
987 ;; placeholder should get expanded into a regular-type epilogue that
988 ;; also does the EH return.
989 (define_expand "eh_return"
990 [(match_operand:HI 0 "")]
991 ""
992 "msp430_expand_eh_return (operands[0]);
993 emit_jump_insn (gen_msp430_eh_epilogue ());
994 emit_barrier ();
995 DONE;"
996 )
997
998 ;; This is the actual EH epilogue. We emit it in the pattern above,
999 ;; before reload, and convert it to a real epilogue after reload.
1000 (define_insn_and_split "msp430_eh_epilogue"
1001 [(eh_return)]
1002 ""
1003 "#"
1004 "reload_completed"
1005 [(const_int 0)]
1006 "msp430_expand_epilogue (1); DONE;"
1007 )
1008
1009 (define_insn "jump"
1010 [(set (pc)
1011 (label_ref (match_operand 0 "" "")))]
1012 ""
1013 "BR%A0\t#%l0"
1014 )
1015
1016 ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
1017 ;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
1018 (define_insn "indirect_jump"
1019 [(set (pc)
1020 (match_operand 0 "nonimmediate_operand" "rYl"))]
1021 ""
1022 "BR%A0\t%0"
1023 )
1024
1025 ;;------------------------------------------------------------
1026 ;; Various Conditionals
1027
1028 (define_expand "cbranch<mode>4"
1029 [(parallel [(set (pc) (if_then_else
1030 (match_operator 0 ""
1031 [(match_operand:QHI 1 "nonimmediate_operand")
1032 (match_operand:QHI 2 "general_operand")])
1033 (label_ref (match_operand 3 "" ""))
1034 (pc)))
1035 (clobber (reg:BI CARRY))]
1036 )]
1037 ""
1038 "msp430_fixup_compare_operands (<MODE>mode, operands);"
1039 )
1040
1041 (define_insn "cbranchpsi4_real"
1042 [(set (pc) (if_then_else
1043 (match_operator 0 "msp430_cmp_operator"
1044 [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm")
1045 (match_operand:PSI 2 "general_operand" "rLs,rYsi,rmi")])
1046 (label_ref (match_operand 3 "" ""))
1047 (pc)))
1048 (clobber (reg:BI CARRY))
1049 ]
1050 ""
1051 "@
1052 CMP%A0\t%2, %1 { J%0\t%l3
1053 CMPX.A\t%2, %1 { J%0\t%l3
1054 CMPX.A\t%2, %1 { J%0\t%l3"
1055 )
1056
1057 (define_insn "cbranchqi4_real"
1058 [(set (pc) (if_then_else
1059 (match_operator 0 "msp430_cmp_operator"
1060 [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm")
1061 (match_operand:QI 2 "general_operand" "rYsi,rmi")])
1062 (label_ref (match_operand 3 "" ""))
1063 (pc)))
1064 (clobber (reg:BI CARRY))
1065 ]
1066 ""
1067 "@
1068 CMP.B\t%2, %1 { J%0\t%l3
1069 CMP%X0.B\t%2, %1 { J%0\t%l3"
1070 )
1071
1072 (define_insn "cbranchhi4_real"
1073 [(set (pc) (if_then_else
1074 (match_operator 0 "msp430_cmp_operator"
1075 [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm")
1076 (match_operand:HI 2 "general_operand" "rYsi,rmi")])
1077 (label_ref (match_operand 3 "" ""))
1078 (pc)))
1079 (clobber (reg:BI CARRY))
1080 ]
1081 ""
1082 "@
1083 CMP.W\t%2, %1 { J%0\t%l3
1084 CMP%X0.W\t%2, %1 { J%0\t%l3"
1085 )
1086
1087 (define_insn "cbranchpsi4_reversed"
1088 [(set (pc) (if_then_else
1089 (match_operator 0 "msp430_reversible_cmp_operator"
1090 [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi")
1091 (match_operand:PSI 2 "general_operand" "r,rYs,rm")])
1092 (label_ref (match_operand 3 "" ""))
1093 (pc)))
1094 (clobber (reg:BI CARRY))
1095 ]
1096 ""
1097 "@
1098 CMP%A0\t%1, %2 { J%R0\t%l3
1099 CMPX.A\t%1, %2 { J%R0\t%l3
1100 CMPX.A\t%1, %2 { J%R0\t%l3"
1101 )
1102
1103 (define_insn "cbranchqi4_reversed"
1104 [(set (pc) (if_then_else
1105 (match_operator 0 "msp430_reversible_cmp_operator"
1106 [(match_operand:QI 1 "general_operand" "rYsi,rmi")
1107 (match_operand:QI 2 "general_operand" "rYs,rm")])
1108 (label_ref (match_operand 3 "" ""))
1109 (pc)))
1110 (clobber (reg:BI CARRY))
1111 ]
1112 ""
1113 "@
1114 CMP.B\t%1, %2 { J%R0\t%l3
1115 CMP%X0.B\t%1, %2 { J%R0\t%l3"
1116 )
1117
1118 (define_insn "cbranchhi4_reversed"
1119 [(set (pc) (if_then_else
1120 (match_operator 0 "msp430_reversible_cmp_operator"
1121 [(match_operand:HI 1 "general_operand" "rYsi,rmi")
1122 (match_operand:HI 2 "general_operand" "rYs,rm")])
1123 (label_ref (match_operand 3 "" ""))
1124 (pc)))
1125 (clobber (reg:BI CARRY))
1126 ]
1127 ""
1128 "@
1129 CMP.W\t%1, %2 { J%R0\t%l3
1130 CMP%X0.W\t%1, %2 { J%R0\t%l3"
1131 )
1132
1133 (define_insn "*bitbranch<mode>4"
1134 [(set (pc) (if_then_else
1135 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1136 (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi"))
1137 (const_int 0))
1138 (label_ref (match_operand 2 "" ""))
1139 (pc)))
1140 (clobber (reg:BI CARRY))
1141 ]
1142 ""
1143 "@
1144 BIT%x0%B0\t%1, %0 { JNE\t%l2
1145 BIT%X0%B0\t%1, %0 { JNE\t%l2"
1146 )
1147
1148 (define_insn "*bitbranch<mode>4"
1149 [(set (pc) (if_then_else
1150 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1151 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1152 (const_int 0))
1153 (label_ref (match_operand 2 "" ""))
1154 (pc)))
1155 (clobber (reg:BI CARRY))
1156 ]
1157 ""
1158 "BIT%x0%X0%B0\t%1, %0 { JEQ\t%l2"
1159 )
1160
1161 (define_insn "*bitbranch<mode>4"
1162 [(set (pc) (if_then_else
1163 (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1164 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1165 (const_int 0))
1166 (pc)
1167 (label_ref (match_operand 2 "" ""))))
1168 (clobber (reg:BI CARRY))
1169 ]
1170 ""
1171 "BIT%X0%B0\t%1, %0 { JNE\t%l2"
1172 )
1173
1174 (define_insn "*bitbranch<mode>4"
1175 [(set (pc) (if_then_else
1176 (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1177 (match_operand:QHI 1 "msp_general_operand" "rmi"))
1178 (const_int 0))
1179 (pc)
1180 (label_ref (match_operand 2 "" ""))))
1181 (clobber (reg:BI CARRY))
1182 ]
1183 ""
1184 "BIT%X0%B0\t%1, %0 { JEQ\t%l2"
1185 )
1186
1187 ;;------------------------------------------------------------
1188 ;; zero-extract versions of the above
1189
1190 (define_insn "*bitbranch<mode>4_z"
1191 [(set (pc) (if_then_else
1192 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm")
1193 (const_int 1)
1194 (match_operand 1 "msp430_bitpos" "i,i"))
1195 (const_int 0))
1196 (label_ref (match_operand 2 "" ""))
1197 (pc)))
1198 (clobber (reg:BI CARRY))
1199 ]
1200 ""
1201 "@
1202 BIT%x0%B0\t%p1, %0 { JNE\t%l2
1203 BIT%X0%B0\t%p1, %0 { JNE\t%l2"
1204 )
1205
1206 (define_insn "*bitbranch<mode>4_z"
1207 [(set (pc) (if_then_else
1208 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1209 (const_int 1)
1210 (match_operand 1 "msp430_bitpos" "i"))
1211 (const_int 0))
1212 (label_ref (match_operand 2 "" ""))
1213 (pc)))
1214 (clobber (reg:BI CARRY))
1215 ]
1216 ""
1217 "BIT%x0%X0%B0\t%p1, %0 { JEQ\t%l2"
1218 )
1219
1220 (define_insn "*bitbranch<mode>4_z"
1221 [(set (pc) (if_then_else
1222 (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1223 (const_int 1)
1224 (match_operand 1 "msp430_bitpos" "i"))
1225 (const_int 0))
1226 (pc)
1227 (label_ref (match_operand 2 "" ""))))
1228 (clobber (reg:BI CARRY))
1229 ]
1230 ""
1231 "BIT%X0%B0\t%p1, %0 { JNE\t%l2"
1232 )
1233
1234 (define_insn "*bitbranch<mode>4_z"
1235 [(set (pc) (if_then_else
1236 (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm")
1237 (const_int 1)
1238 (match_operand 1 "msp430_bitpos" "i"))
1239 (const_int 0))
1240 (pc)
1241 (label_ref (match_operand 2 "" ""))))
1242 (clobber (reg:BI CARRY))
1243 ]
1244 ""
1245 "BIT%X0%B0\t%p1, %0 { JEQ\t%l2"
1246 )
1247
1248 ;;------------------------------------------------------------
1249 ;; Misc
1250
1251 (define_insn "nop"
1252 [(const_int 0)]
1253 "1"
1254 "NOP"
1255 )
1256
1257 (define_insn "disable_interrupts"
1258 [(unspec_volatile [(const_int 0)] UNS_DINT)]
1259 ""
1260 "DINT"
1261 )
1262
1263 (define_insn "enable_interrupts"
1264 [(unspec_volatile [(const_int 0)] UNS_EINT)]
1265 ""
1266 "EINT"
1267 )
1268
1269 (define_insn "push_intr_state"
1270 [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
1271 ""
1272 "PUSH\tSR"
1273 )
1274
1275 (define_insn "pop_intr_state"
1276 [(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
1277 ""
1278 "POP\tSR"
1279 )
1280
1281 ;; Clear bits in the copy of the status register that is currently
1282 ;; saved on the stack at the top of the interrupt handler.
1283 (define_insn "bic_SR"
1284 [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
1285 ""
1286 "BIC.W\t%0, %O0(SP)"
1287 )
1288
1289 ;; Set bits in the copy of the status register that is currently
1290 ;; saved on the stack at the top of the interrupt handler.
1291 (define_insn "bis_SR"
1292 [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
1293 ""
1294 "BIS.W\t%0, %O0(SP)"
1295 )
1296
1297 ;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
1298 ;; very late on in the compilation and not splitting it into separate
1299 ;; instructions, so we provide a pattern to support it here.
1300 (define_insn "andneghi3"
1301 [(set (match_operand:HI 0 "register_operand" "=r")
1302 (and:HI (neg:HI (match_operand:HI 1 "register_operand" "r"))
1303 (match_operand 2 "immediate_operand" "n")))]
1304 ""
1305 "*
1306 if (REGNO (operands[0]) != REGNO (operands[1]))
1307 return \"MOV.W\t%1, %0 { SUB.W #0, %0 { AND.W %2, %0\";
1308 else
1309 return \"SUB.W\t#0, %0 { AND.W %2, %0\";
1310 "
1311 )