1 ;;- Machine description for the Motorola 88000 for GNU C compiler
2 ;; Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@mcc.com)
4 ;; Additional changes by Michael Meissner (meissner@osf.org)
5 ;; Currently supported by Tom Wood (wood@dg-rtp.dg.com)
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; SCCS rev field. This is a NOP, just to get the SCCS id into the
28 (define_expand "m88k_sccs_id"
29 [(match_operand:SI 0 "" "")]
31 "{ static char sccs_id[] = \"@(#)m88k.md 2.0.3.4 20 Mar 1992 15:09:03\";
34 ;; Attribute specifications
37 (define_attr "cpu" "m88000,m88100,m88110"
38 (const (symbol_ref "m88k_cpu")))
40 ; Type of each instruction. Default is arithmetic.
41 ; I'd like to write the list as this, but genattrtab won't accept it.
43 ; "branch,jump,call, ; flow-control instructions
44 ; load,store,loada, ; data unit instructions
45 ; spadd,dpadd,spdiv,dpdiv,idiv, ; FPU add instructions
46 ; spmul,dpmul,imul, ; FPU multiply instructions
47 ; arith, ; integer unit instructions
48 ; marith,mstore,mfp,weird" ; multi-word instructions
50 ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.
52 "branch,jump,call,load,store,loada,spadd,dpadd,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,marith,mstore,mfp,weird"
53 (const_string "arith"))
55 ; Convenience attributes.
56 (define_attr "fpu" "yes,no"
58 (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spdiv,dpdiv,idiv,mfp")
59 (const_string "yes") (const_string "no")))
61 ; Length in # of instructions of each insn. The values are not exact, but
63 (define_attr "length" ""
64 (cond [(eq_attr "type" "marith,mstore,mfp")
68 ; Describe a user's asm statement.
69 (define_asm_attributes
70 [(set_attr "type" "weird")])
72 ; Define the delay slot requirements for branches and calls.
73 ; The m88100 annuls instructions if a conditional branch is taken.
74 ; For insns of TYPE_BRANCH that are multi-word instructions, the
75 ; delay slot applies to the first instruction.
77 ; @@ For the moment, reorg.c requires that the delay slot of a branch not
78 ; be a call or branch.
80 (define_delay (eq_attr "type" "branch,jump")
83 (eq_attr "type" "!branch,jump,call,marith,mstore,mfp,weird") ; required.
84 (eq_attr "type" "!load")) ; issue as-soon-as-possible.
85 (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
86 (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
88 ; output_call supports an unconditional branch in the delay slot of
89 ; a call. (@@ Support for this case is expected in reorg.c soon.)
91 (define_delay (eq_attr "type" "call")
92 [(eq_attr "type" "!branch,call,marith,mstore,mfp,weird") ; required.
95 ; An abstract block diagram of the function units for the m88100.
102 ; ,----------'| | `----------------------.
104 ; load | store | | arith | | |
105 ; | | | +-v-v-+ | dp source
107 ; store | | | div +-v-v-+
108 ; ,------. | | | ,-----. ,-----------' `-----------.
110 ; | +--v---v--+ ,---' | | +-v-v---+ +---v---+
111 ; | | stage 2 | | | `---| add 2 | | mul 2 |
112 ; | +---------+ | +--v--+ +-------+ imul +-------+
113 ; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 |
114 ; | +---------+ | +--v--+ +-------+ | +-------+
115 ; | | stage 0 | | | | add 4 | | | mul 4 |
116 ; | +--v---v--+ | | +---v---+ | +-------+
117 ; | | | | | | | | mul 5 |
118 ; | * | | | | | +---v---+
119 ; | | | | | +----v----+ |
120 ; | load | | | fp add `------>| fp last |<------' fp mul
121 ; | | | | +---v-v--^+
123 ; | | | | | `--' dp dest
124 ; | | +--v-----v--+ |
125 ; | `--->| writeback |<--------------------'
128 ; `------------------' *
130 ; The decode unit need not be specified.
131 ; Consideration of writeback contention is critical to superb scheduling.
133 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
134 ; TEST READY-DELAY BUSY-DELAY [CONFLICT-LIST])
136 ;(define_function_unit "decode" 1 1 (const_int 1) 0 1)
138 ; Describing the alu is currently not useful.
139 ;(define_function_unit "alu" 1 0 (eq_attr "type"
140 ; "!store,mstore,marith,mfp,weird") 1 0)
141 ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
143 (define_function_unit "memory" 1 3 (eq_attr "type" "load") 3 2)
145 ; The fp1 and fplast descriptions currently have no effect.
146 ;(define_function_unit "fp1" 1 1 (eq_attr "fpu" "yes") 1 2)
148 ; The times are adjusted to include fp1 and fplast, but then are further
149 ; adjusted based on the actual generated code. The notation to the right
150 ; is the total latency. A range denotes a group of instructions and/or
151 ; conditions (the extra clock of fplast time with some sequences).
152 (define_function_unit "fpmul" 1 4 (eq_attr "type" "spmul") 4 2) ; 6-8
153 (define_function_unit "fpmul" 1 4 (eq_attr "type" "dpmul,mfp") 7 2) ; 9-10
154 (define_function_unit "fpmul" 1 4 (eq_attr "type" "imul") 3 2) ; 4
156 (define_function_unit "fpadd" 1 3 (eq_attr "type" "spadd") 3 2) ; 5-6
157 (define_function_unit "fpadd" 1 3 (eq_attr "type" "dpadd") 4 2) ; 6-7
158 (define_function_unit "fpadd" 1 3 (eq_attr "type" "spdiv") 30 2) ; 30-31
159 (define_function_unit "fpadd" 1 3 (eq_attr "type" "dpdiv") 60 2) ; 60-61
160 (define_function_unit "fpadd" 1 3 (eq_attr "type" "idiv") 38 2) ; 38
162 ;(define_function_unit "fplast" 1 1 (eq_attr "fpu" "yes") 1 2)
164 ; Describing writeback contention is currently not useful.
165 ;(define_function_unit "writeback" 1 1
166 ; (eq_attr "type" "!store,mstore,branch,jump,call") 0 1)
168 ; Describing stores is currently not useful. The suggestion here is that the
169 ; function unit ordering has already been established (writeback is last) and
170 ; that store insns use the units in an unusual order.
171 ;(define_function_unit "writeback" 1 1 (eq_attr "type" "store,mstore") 0 1)
172 ;(define_function_unit "memory" 1 3 (eq_attr "type" "store,mstore") 1 2)
174 ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
175 ;; (tege@sics.se). They've changed since then, so don't complain to him
176 ;; if they don't work right.
178 ;; Regarding shifts, gen_lshlsi3 generates ASHIFT. LSHIFT opcodes are
179 ;; not produced and should not normally occur. Also, the gen functions
180 ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
181 ;; special needs to be done here.
183 ;; (a << int1) >> int2 optimizations into a single extract.
184 ;; These patterns need to occur before the normal shift patterns
187 [(set (match_operand:SI 0 "register_operand" "=r")
188 (ashiftrt:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
189 (match_operand:SI 2 "int5_operand" ""))
190 (match_operand:SI 3 "int5_operand" "")))]
191 "INTVAL (operands [2]) <= INTVAL (operands [3])"
194 operands[4] = gen_rtx (CONST_INT, SImode,
195 INTVAL (operands[3]) - INTVAL (operands[2]));
196 return \"ext %0,%1,%w3<%4>\"; /* <(%3-%2)> */
200 [(set (match_operand:SI 0 "register_operand" "=r")
201 (lshiftrt:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
202 (match_operand:SI 2 "int5_operand" ""))
203 (match_operand:SI 3 "int5_operand" "")))]
204 "INTVAL (operands [2]) <= INTVAL (operands [3])"
207 operands[4] = gen_rtx (CONST_INT, SImode,
208 INTVAL (operands[3]) - INTVAL (operands[2]));
209 return \"extu %0,%1,%w3<%4>\"; /* <(%3-%2)> */
212 ;; Optimize possible cases of the set instruction.
215 [(set (match_operand:SI 0 "register_operand" "=r")
216 (ashift:SI (const_int -1)
217 (match_operand:SI 1 "register_operand" "r")))]
222 [(set (match_operand:SI 0 "register_operand" "=r")
223 (ior:SI (ashift:SI (const_int -1)
224 (match_operand:SI 1 "register_operand" "r"))
225 (match_operand:SI 2 "register_operand" "r")))]
230 [(set (match_operand:SI 0 "register_operand" "=r")
231 (ior:SI (match_operand:SI 1 "register_operand" "r")
232 (ashift:SI (const_int -1)
233 (match_operand:SI 2 "register_operand" "r"))))]
237 ;; Optimize possible cases of the mak instruction.
240 [(set (match_operand:SI 0 "register_operand" "=r")
241 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
242 (match_operand:SI 2 "int5_operand" ""))
243 (match_operand:SI 3 "immediate_operand" "n")))]
244 "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
247 operands[4] = gen_rtx (CONST_INT, SImode,
248 exact_log2 (1 + (INTVAL (operands[3])
249 >> INTVAL(operands[2]))));
250 return \"mak %0,%1,%4<%2>\";
253 ;; Optimize possible cases of output_and.
256 [(set (match_operand:SI 0 "register_operand" "=r")
257 (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
258 (match_operand:SI 2 "int5_operand" "")
259 (match_operand:SI 3 "int5_operand" ""))
260 (match_operand:SI 4 "int5_operand" "")))]
261 "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
265 = gen_rtx (CONST_INT, SImode,
266 ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
267 return output_and (operands);
269 [(set_attr "type" "marith")]) ; length is 1 or 2.
271 ;; Recognize bcnd instructions for integer values. This is distinguished
272 ;; from a conditional branch instruction (below) with SImode instead of
278 (match_operator 0 "relop_no_unsigned"
279 [(match_operand:SI 1 "register_operand" "r")
281 (match_operand 2 "pc_or_label_ref" "")
282 (match_operand 3 "pc_or_label_ref" "")))]
284 "bcnd%. %R3%B0,%1,%P2%P3"
285 [(set_attr "type" "branch")])
287 ;; Recognize tests for sign and zero.
292 (match_operator 0 "equality_op"
293 [(match_operand:SI 1 "register_operand" "r")
294 (const_int -2147483648)])
295 (match_operand 2 "pc_or_label_ref" "")
296 (match_operand 3 "pc_or_label_ref" "")))]
298 "bcnd%. %R3%E0,%1,%P2%P3"
299 [(set_attr "type" "branch")])
304 (match_operator 0 "equality_op"
306 (match_operand:SI 1 "register_operand" "r")
310 (match_operand 2 "pc_or_label_ref" "")
311 (match_operand 3 "pc_or_label_ref" "")))]
313 "bcnd%. %R3%D0,%1,%P2%P3"
314 [(set_attr "type" "branch")])
316 ;; Recognize bcnd instructions for double integer values
321 (match_operator 0 "relop_no_unsigned"
323 (match_operand:SI 1 "register_operand" "r"))
325 (match_operand 2 "pc_or_label_ref" "")
326 (match_operand 3 "pc_or_label_ref" "")))]
328 "bcnd%. %R3%B0,%1,%P2%P3"
329 [(set_attr "type" "branch")])
334 (match_operator 0 "equality_op"
336 (match_operand:SI 1 "register_operand" "r"))
338 (match_operand 2 "pc_or_label_ref" "")
339 (match_operand 3 "pc_or_label_ref" "")))]
341 "bcnd%. %R3%B0,%1,%P2%P3"
342 [(set_attr "type" "branch")])
344 ; @@ I doubt this is interesting until cmpdi is provided. Anyway, it needs
350 ; (match_operator 0 "relop_no_unsigned"
351 ; [(match_operand:DI 1 "register_operand" "r")
353 ; (match_operand 2 "pc_or_label_ref" "")
354 ; (match_operand 3 "pc_or_label_ref" "")))]
358 ; switch (GET_CODE (operands[0]))
362 ; /* I'm not sure if it's safe to use .n here. */
363 ; return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
366 ; return \"bcnd%. %R3%B0,%1,%P2%P3\";
369 ; rtx op2 = operands[2];
370 ; operands[2] = operands[3];
374 ; if (GET_CODE (operands[3]) == LABEL_REF)
377 ; operands[2] = gen_label_rtx ();
378 ; label_num = XINT (operands[2], 3);
380 ; (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
381 ; output_label (label_num);
385 ; return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
389 ;; Recognize bcnd instructions for single precision float values
390 ;; Exclude relational operations as they must signal NaNs.
392 ;; @@ These bcnd insns for float and double values don't seem to be recognized.
397 (match_operator 0 "equality_op"
399 (match_operand:SF 1 "register_operand" "r"))
401 (match_operand 2 "pc_or_label_ref" "")
402 (match_operand 3 "pc_or_label_ref" "")))]
404 "bcnd%. %R3%D0,%1,%P2%P3"
405 [(set_attr "type" "branch")])
410 (match_operator 0 "equality_op"
411 [(match_operand:SF 1 "register_operand" "r")
413 (match_operand 2 "pc_or_label_ref" "")
414 (match_operand 3 "pc_or_label_ref" "")))]
416 "bcnd%. %R3%D0,%1,%P2%P3"
417 [(set_attr "type" "branch")])
419 ;; Recognize bcnd instructions for double precision float values
420 ;; Exclude relational operations as they must signal NaNs.
425 (match_operator 0 "equality_op"
426 [(match_operand:DF 1 "register_operand" "r")
428 (match_operand 2 "pc_or_label_ref" "")
429 (match_operand 3 "pc_or_label_ref" "")))]
435 if (GET_CODE (operands[0]) == NE)
437 rtx op2 = operands[2];
438 operands[2] = operands[3];
441 if (GET_CODE (operands[3]) == LABEL_REF)
442 return \"bcnd%. 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
444 operands[3] = gen_label_rtx ();
445 label_num = XINT (operands[3], 3);
446 output_asm_insn (\"bcnd%. 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
447 output_label (label_num);
450 [(set_attr "type" "branch")])
452 ;; Recognize bb0 and bb1 instructions. These use two unusual template
453 ;; patterns, %Lx and %Px. %Lx outputs a 1 if operand `x' is a LABEL_REF
454 ;; otherwise it outputs a 0. It then may print ".n" if the delay slot
455 ;; is used. %Px does noting if `x' is PC and outputs the operand if `x'
461 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
463 (match_operand:SI 1 "int5_operand" ""))
465 (match_operand 2 "pc_or_label_ref" "")
466 (match_operand 3 "pc_or_label_ref" "")))]
468 "bb%L2 (31-%1),%0,%P2%P3"
469 [(set_attr "type" "branch")])
474 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
476 (match_operand:SI 1 "int5_operand" ""))
478 (match_operand 2 "pc_or_label_ref" "")
479 (match_operand 3 "pc_or_label_ref" "")))]
481 "bb%L3 (31-%1),%0,%P2%P3"
482 [(set_attr "type" "branch")])
487 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
489 (match_operand:SI 1 "int5_operand" ""))
491 (match_operand 2 "pc_or_label_ref" "")
492 (match_operand 3 "pc_or_label_ref" "")))]
494 "bb%L2 (31-%1),%0,%P2%P3"
495 [(set_attr "type" "branch")])
500 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
502 (match_operand:SI 1 "int5_operand" ""))
504 (match_operand 2 "pc_or_label_ref" "")
505 (match_operand 3 "pc_or_label_ref" "")))]
507 "bb%L3 (31-%1),%0,%P2%P3"
508 [(set_attr "type" "branch")])
513 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
514 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
516 (match_operand 2 "pc_or_label_ref" "")
517 (match_operand 3 "pc_or_label_ref" "")))]
518 "(GET_CODE (operands[0]) == CONST_INT)
519 != (GET_CODE (operands[1]) == CONST_INT)"
520 "bb%L3 %p1,%0,%P2%P3"
521 [(set_attr "type" "branch")])
526 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
527 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
529 (match_operand 2 "pc_or_label_ref" "")
530 (match_operand 3 "pc_or_label_ref" "")))]
531 "(GET_CODE (operands[0]) == CONST_INT)
532 != (GET_CODE (operands[1]) == CONST_INT)"
533 "bb%L2 %p1,%0,%P2%P3"
534 [(set_attr "type" "branch")])
536 ;; The comparison operations store the comparison into a register and
537 ;; record that register. The following Bxx or Sxx insn uses that
538 ;; register as an input. To facilitate use of bcnd instead of cmp/bb1,
539 ;; cmpsi records it's operands and produces no code when any operand
540 ;; is constant. In this case, the Bxx insns use gen_bcnd and the
541 ;; Sxx insns use gen_test to ensure a cmp has been emitted.
543 ;; This could also be done for SFmode and DFmode having only beq and bne
544 ;; use gen_bcnd. The others must signal NaNs. It seems though that zero
545 ;; has already been copied into a register.
547 ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
548 ;; is a constant. (This idea is due to Torbjorn Granlund.) Others can
549 ;; use bcnd only if an operand is zero.
551 ;; It is necessary to distinguish a register holding condition codes.
552 ;; This is done by context.
554 (define_expand "test"
556 (compare:CC (match_operand 0 "" "")
557 (match_operand 1 "" "")))]
561 if (m88k_compare_reg)
564 if (GET_CODE (operands[0]) == CONST_INT
565 && ! SMALL_INT (operands[0]))
566 operands[0] = force_reg (SImode, operands[0]);
568 if (GET_CODE (operands[1]) == CONST_INT
569 && ! SMALL_INT (operands[1]))
570 operands[1] = force_reg (SImode, operands[1]);
572 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
575 ; @@ The docs say don't do this. It's probably a nop since the insn looks
576 ; identical to cmpsi against zero. Is there an advantage to providing
577 ; this, perhaps with a different form?
579 ;(define_expand "tstsi"
580 ; [(set (match_dup 1)
581 ; (compare:CC (match_operand:SI 0 "register_operand" "")
586 ; m88k_compare_reg = 0;
587 ; m88k_compare_op0 = operands[0];
588 ; m88k_compare_op1 = const0_rtx;
592 (define_expand "cmpsi"
594 (compare:CC (match_operand:SI 0 "register_operand" "")
595 (match_operand:SI 1 "arith32_operand" "")))]
599 if (GET_CODE (operands[0]) == CONST_INT
600 || GET_CODE (operands[1]) == CONST_INT)
602 m88k_compare_reg = 0;
603 m88k_compare_op0 = operands[0];
604 m88k_compare_op1 = operands[1];
607 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
610 (define_expand "cmpsf"
612 (compare:CC (match_operand:SF 0 "register_operand" "")
613 (match_operand:SF 1 "register_operand" "")))]
615 "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
617 (define_expand "cmpdf"
619 (compare:CC (match_operand:DF 0 "general_operand" "")
620 (match_operand:DF 1 "general_operand" "")))]
624 operands[0] = legitimize_operand (operands[0], DFmode);
625 operands[1] = legitimize_operand (operands[1], DFmode);
626 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
629 ; @@ Get back to this later on.
631 ;(define_insn "cmpdi"
633 ; (compare:CC (match_operand:DI 0 "register_operand" "r")
634 ; (match_operand:DI 1 "register_operand" "r")))]
638 ; if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
639 ; abort (); /* output_move_double MDEP_LS_CHANGE bits were set. */
641 ; cc_status.mdep &= ~ MDEP_LS_MASK;
643 ; operands[2] = gen_label_rtx ();
644 ; /* Remember, %! is the condition code register and %@ is the
645 ; literal synthesis register. */
647 ; output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
650 ; output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
651 ; output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
652 ; output_label (XINT (operands[2], 3));
656 ;; The actual compare instructions.
659 [(set (match_operand:CC 0 "register_operand" "=r")
660 (compare:CC (match_operand:SI 1 "register_operand" "rO")
661 (match_operand:SI 2 "arith_operand" "rI")))]
666 [(set (match_operand:CC 0 "register_operand" "=r,r")
667 (compare:CC (match_operand:SF 1 "register_operand" "r,r")
668 (match_operand:SF 2 "real_or_0_operand" "r,G")))]
673 [(set_attr "type" "spadd")])
676 [(set (match_operand:CC 0 "register_operand" "=r")
677 (compare:CC (match_operand:DF 1 "register_operand" "r")
679 (match_operand:SF 2 "register_operand" "r"))))]
682 [(set_attr "type" "dpadd")])
685 [(set (match_operand:CC 0 "register_operand" "=r")
686 (compare:CC (float_extend:DF
687 (match_operand:SF 1 "register_operand" "r"))
688 (match_operand:DF 2 "register_operand" "r")))]
691 [(set_attr "type" "dpadd")])
694 [(set (match_operand:CC 0 "register_operand" "=r,r")
695 (compare:CC (match_operand:DF 1 "register_operand" "r,r")
696 (match_operand:DF 2 "real_or_0_operand" "r,G")))]
701 [(set_attr "type" "dpadd")])
703 ;; Store condition code insns. The compare insns set a register
704 ;; rather than cc0 and record that register for use here. See above
705 ;; for the special treatment of cmpsi with a constant operand.
708 [(set (match_operand:SI 0 "register_operand" "")
711 "operands[1] = emit_test (EQ, SImode);")
714 [(set (match_operand:SI 0 "register_operand" "")
717 "operands[1] = emit_test (NE, SImode);")
720 [(set (match_operand:SI 0 "register_operand" "")
723 "operands[1] = emit_test (GT, SImode);")
725 (define_expand "sgtu"
726 [(set (match_operand:SI 0 "register_operand" "")
729 "operands[1] = emit_test (GTU, SImode);")
732 [(set (match_operand:SI 0 "register_operand" "")
735 "operands[1] = emit_test (LT, SImode);")
737 (define_expand "sltu"
738 [(set (match_operand:SI 0 "register_operand" "")
741 "operands[1] = emit_test (LTU, SImode);")
744 [(set (match_operand:SI 0 "register_operand" "")
747 "operands[1] = emit_test (GE, SImode);")
749 (define_expand "sgeu"
750 [(set (match_operand:SI 0 "register_operand" "")
753 "operands[1] = emit_test (GEU, SImode);")
756 [(set (match_operand:SI 0 "register_operand" "")
759 "operands[1] = emit_test (LE, SImode);")
761 (define_expand "sleu"
762 [(set (match_operand:SI 0 "register_operand" "")
765 "operands[1] = emit_test (LEU, SImode);")
767 ;; The actual set condition code instruction.
770 [(set (match_operand:SI 0 "register_operand" "=r")
771 (match_operator:SI 1 "relop"
772 [(match_operand:CC 2 "register_operand" "r")
778 [(set (match_operand:SI 0 "register_operand" "=r")
780 (match_operator:SI 1 "relop"
781 [(match_operand:CC 2 "register_operand" "r")
786 ;; Conditional branch insns. The compare insns set a register
787 ;; rather than cc0 and record that register for use here. See above
788 ;; for the special case of cmpsi with a constant operand.
790 (define_expand "bcnd"
792 (if_then_else (match_operand 0 "" "")
793 (label_ref (match_operand 1 "" ""))
796 "if (m88k_compare_reg) abort ();")
800 (if_then_else (match_operand 0 "" "")
801 (label_ref (match_operand 1 "" ""))
804 "if (m88k_compare_reg == 0) abort ();")
808 (if_then_else (eq (match_dup 1) (const_int 0))
809 (label_ref (match_operand 0 "" ""))
812 "if (m88k_compare_reg == 0)
814 emit_bcnd (EQ, operands[0]);
817 operands[1] = m88k_compare_reg;")
821 (if_then_else (ne (match_dup 1) (const_int 0))
822 (label_ref (match_operand 0 "" ""))
825 "if (m88k_compare_reg == 0)
827 emit_bcnd (NE, operands[0]);
830 operands[1] = m88k_compare_reg;")
834 (if_then_else (gt (match_dup 1) (const_int 0))
835 (label_ref (match_operand 0 "" ""))
838 "if (m88k_compare_reg == 0)
840 emit_bcnd (GT, operands[0]);
843 operands[1] = m88k_compare_reg;")
845 (define_expand "bgtu"
847 (if_then_else (gtu (match_dup 1) (const_int 0))
848 (label_ref (match_operand 0 "" ""))
851 "if (m88k_compare_reg == 0)
853 emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
856 operands[1] = m88k_compare_reg;")
860 (if_then_else (lt (match_dup 1) (const_int 0))
861 (label_ref (match_operand 0 "" ""))
864 "if (m88k_compare_reg == 0)
866 emit_bcnd (LT, operands[0]);
869 operands[1] = m88k_compare_reg;")
871 (define_expand "bltu"
873 (if_then_else (ltu (match_dup 1) (const_int 0))
874 (label_ref (match_operand 0 "" ""))
877 "if (m88k_compare_reg == 0)
879 emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
882 operands[1] = m88k_compare_reg;")
886 (if_then_else (ge (match_dup 1) (const_int 0))
887 (label_ref (match_operand 0 "" ""))
890 "if (m88k_compare_reg == 0)
892 emit_bcnd (GE, operands[0]);
895 operands[1] = m88k_compare_reg;")
897 (define_expand "bgeu"
899 (if_then_else (geu (match_dup 1) (const_int 0))
900 (label_ref (match_operand 0 "" ""))
903 "if (m88k_compare_reg == 0)
905 emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
908 operands[1] = m88k_compare_reg;")
912 (if_then_else (le (match_dup 1) (const_int 0))
913 (label_ref (match_operand 0 "" ""))
916 "if (m88k_compare_reg == 0)
918 emit_bcnd (LE, operands[0]);
921 operands[1] = m88k_compare_reg;")
923 (define_expand "bleu"
925 (if_then_else (leu (match_dup 1) (const_int 0))
926 (label_ref (match_operand 0 "" ""))
929 "if (m88k_compare_reg == 0)
931 emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
934 operands[1] = m88k_compare_reg;")
936 ;; The actual conditional branch instruction (both directions). This
937 ;; uses two unusual template patterns, %Rx and %Px. %Rx is a prefix code
938 ;; for the immediately following condition and reverses the condition iff
939 ;; operand `x' is a LABEL_REF. %Px does nothing if `x' is PC and outputs
940 ;; the operand if `x' is a LABEL_REF.
943 [(set (pc) (if_then_else
944 (match_operator 0 "relop"
945 [(match_operand:CC 1 "register_operand" "r")
947 (match_operand 2 "pc_or_label_ref" "")
948 (match_operand 3 "pc_or_label_ref" "")))]
950 "bb1%. %R3%C0,%1,%P2%P3"
951 [(set_attr "type" "branch")])
953 ;; SImode move instructions
955 (define_expand "movsi"
956 [(set (match_operand:SI 0 "general_operand" "")
957 (match_operand:SI 1 "general_operand" ""))]
961 if (emit_move_sequence (operands, SImode))
966 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r")
967 (match_operand:SI 1 "move_operand" "rI,m,rO,J,M"))]
968 "(register_operand (operands[0], SImode)
969 || register_operand (operands[1], SImode)
970 || operands[1] == const0_rtx)"
977 [(set_attr "type" "arith,load,store,arith,arith")])
980 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
981 (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
988 or.u %0,%#r0,%X1\;or %0,%0,%x1"
989 [(set_attr "type" "arith,arith,arith,arith,marith")])
991 ;; @@ Why the constraint "in"? Doesn't `i' include `n'?
993 [(set (match_operand:SI 0 "register_operand" "=r")
994 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
995 (match_operand:SI 2 "immediate_operand" "in")))]
997 "or %0,%1,%#lo16(%g2)")
1000 [(set (match_operand:SI 0 "register_operand" "=r")
1001 (high:SI (match_operand 1 "" "")))]
1003 "or.u %0,%#r0,%#hi16(%g1)")
1005 ;; HImode move instructions
1007 (define_expand "movhi"
1008 [(set (match_operand:HI 0 "general_operand" "")
1009 (match_operand:HI 1 "general_operand" ""))]
1013 if (emit_move_sequence (operands, HImode))
1018 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1019 (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1020 "(register_operand (operands[0], HImode)
1021 || register_operand (operands[1], HImode)
1022 || operands[1] == const0_rtx)"
1028 [(set_attr "type" "arith,load,store,arith")])
1031 [(set (match_operand:HI 0 "register_operand" "=r")
1032 (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1033 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1035 "or %0,%1,%#lo16(%2)")
1037 ;; QImode move instructions
1039 (define_expand "movqi"
1040 [(set (match_operand:QI 0 "general_operand" "")
1041 (match_operand:QI 1 "general_operand" ""))]
1045 if (emit_move_sequence (operands, QImode))
1050 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1051 (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1052 "(register_operand (operands[0], QImode)
1053 || register_operand (operands[1], QImode)
1054 || operands[1] == const0_rtx)"
1060 [(set_attr "type" "arith,load,store,arith")])
1063 [(set (match_operand:QI 0 "register_operand" "=r")
1064 (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1065 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1067 "or %0,%1,%#lo16(%2)")
1069 ;; DImode move instructions
1071 (define_expand "movdi"
1072 [(set (match_operand:DI 0 "general_operand" "")
1073 (match_operand:DI 1 "general_operand" ""))]
1077 if (emit_move_sequence (operands, DImode))
1082 [(set (match_operand:DI 0 "register_operand" "=r")
1085 "or %0,%#r0,0\;or %d0,%#r0,0"
1086 [(set_attr "type" "marith")])
1089 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
1090 (match_operand:DI 1 "nonimmediate_operand" "r,m,r"))]
1093 or %0,%#r0,%1\;or %d0,%#r0,%d1
1096 [(set_attr "type" "marith,load,store")])
1099 [(set (match_operand:DI 0 "register_operand" "=r")
1100 (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1101 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1103 "or %0,%1,%#lo16(%2)")
1106 [(set (match_operand:DI 0 "register_operand" "=r")
1107 (match_operand:DI 1 "immediate_operand" "n"))]
1109 "* return output_load_const_dimode (operands);"
1110 [(set_attr "type" "marith")
1111 (set_attr "length" "4")]) ; length is 2, 3 or 4.
1113 ;; DFmode move instructions
1115 (define_expand "movdf"
1116 [(set (match_operand:DF 0 "general_operand" "")
1117 (match_operand:DF 1 "general_operand" ""))]
1121 if (emit_move_sequence (operands, DFmode))
1125 ;; @@ This pattern is incomplete and doesn't appear necessary.
1127 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1128 ;; to be reloaded by putting the constant into memory.
1129 ;; It must come before the more general movdf pattern.
1132 ; [(set (match_operand:DF 0 "general_operand" "=r,o")
1133 ; (match_operand:DF 1 "" "G,G"))]
1134 ; "GET_CODE (operands[1]) == CONST_DOUBLE"
1137 ; switch (which_alternative)
1140 ; return \"or %0,%#r0,0\;or %d0,%#r0,0\";
1142 ; operands[1] = adj_offsettable_operand (operands[0], 4);
1143 ; return \"st %#r0,%0\;st %#r0,%1\";
1148 [(set (match_operand:DF 0 "register_operand" "=r")
1151 "or %0,%#r0,0\;or %d0,%#r0,0"
1152 [(set_attr "type" "marith")])
1155 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
1156 (match_operand:DF 1 "nonimmediate_operand" "r,m,r"))]
1159 or %0,%#r0,%1\;or %d0,%#r0,%d1
1162 [(set_attr "type" "marith,load,store")])
1165 [(set (match_operand:DF 0 "register_operand" "=r")
1166 (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1167 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1169 "or %0,%1,%#lo16(%2)")
1172 [(set (match_operand:DF 0 "register_operand" "=r")
1173 (match_operand:DF 1 "immediate_operand" "F"))]
1175 "* return output_load_const_double (operands);"
1176 [(set_attr "type" "marith")
1177 (set_attr "length" "4")]) ; length is 2, 3, or 4.
1179 ;; SFmode move instructions
1181 (define_expand "movsf"
1182 [(set (match_operand:SF 0 "general_operand" "")
1183 (match_operand:SF 1 "general_operand" ""))]
1187 if (emit_move_sequence (operands, SFmode))
1191 ;; @@ What happens to fconst0_rtx?
1193 [(set (match_operand:SF 0 "register_operand" "=r")
1199 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
1200 (match_operand:SF 1 "nonimmediate_operand" "r,m,r"))]
1206 [(set_attr "type" "arith,load,store")])
1209 [(set (match_operand:SF 0 "register_operand" "=r")
1210 (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1211 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1213 "or %0,%1,%#lo16(%2)")
1216 [(set (match_operand:SF 0 "register_operand" "=r")
1217 (match_operand:SF 1 "immediate_operand" "F"))]
1218 "operands[1] != const0_rtx"
1219 "* return output_load_const_float (operands);"
1220 [(set_attr "type" "marith")]) ; length is 1 or 2.
1222 ;; String/block move insn. See m88k.c for details.
1224 (define_expand "movstrsi"
1225 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1226 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1227 (use (match_operand:SI 2 "arith32_operand" ""))
1228 (use (match_operand:SI 3 "immediate_operand" ""))])]
1232 rtx dest_mem = operands[0];
1233 rtx src_mem = operands[1];
1234 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1235 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1236 expand_block_move (dest_mem, src_mem, operands);
1240 ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
1241 ;; operand 0 is the function name
1242 ;; operand 1 is the destination pointer
1243 ;; operand 2 is the source pointer
1244 ;; operand 3 is the offset for the source and destination pointers
1245 ;; operand 4 is the first value to be loaded
1246 ;; operand 5 is the register to hold the value (r4 or r5)
1248 (define_expand "call_block_move"
1249 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "r")
1250 (match_operand:SI 3 "immediate_operand" "i")))
1251 (set (match_operand 5 "register_operand" "r")
1252 (match_operand 4 "memory_operand" "m"))
1253 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "r")
1258 (parallel [(call (mem:SI (match_operand 0 "" ""))
1264 ;; Call a looping block move library function (e.g. __movstrSI64n68).
1265 ;; operands 0-5 as in the non-looping interface
1266 ;; operand 6 is the loop count
1268 (define_expand "call_block_move_loop"
1269 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "r")
1270 (match_operand:SI 3 "immediate_operand" "i")))
1271 (set (match_operand:SI 5 "register_operand" "r")
1272 (match_operand:SI 4 "memory_operand" "m"))
1273 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "r")
1275 (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" "i"))
1280 (parallel [(call (mem:SI (match_operand 0 "" ""))
1286 ;;- zero extension instructions
1288 (define_expand "zero_extendhisi2"
1289 [(set (match_operand:SI 0 "register_operand" "")
1290 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1294 if (GET_CODE (operands[1]) == MEM
1295 && symbolic_address_p (XEXP (operands[1], 0)))
1297 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1301 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1302 (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
1303 "GET_CODE (operands[1]) != CONST_INT"
1308 [(set_attr "type" "arith,arith,load")])
1310 (define_expand "zero_extendqihi2"
1311 [(set (match_operand:HI 0 "register_operand" "")
1312 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1316 if (GET_CODE (operands[1]) == MEM
1317 && symbolic_address_p (XEXP (operands[1], 0)))
1319 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1323 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1324 (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
1325 "GET_CODE (operands[1]) != CONST_INT"
1330 [(set_attr "type" "arith,arith,load")])
1332 (define_expand "zero_extendqisi2"
1333 [(set (match_operand:SI 0 "register_operand" "")
1334 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1338 if (GET_CODE (operands[1]) == MEM
1339 && symbolic_address_p (XEXP (operands[1], 0)))
1342 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1343 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1344 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
1350 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1351 (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
1352 "GET_CODE (operands[1]) != CONST_INT"
1357 [(set_attr "type" "arith,arith,load")])
1359 ;;- sign extension instructions
1361 (define_expand "extendsidi2"
1362 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
1363 (match_operand:SI 1 "general_operand" "g"))
1364 (set (subreg:SI (match_dup 0) 0)
1365 (ashiftrt:SI (subreg:SI (match_dup 0) 1)
1370 (define_expand "extendhisi2"
1371 [(set (match_operand:SI 0 "register_operand" "")
1372 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1376 if (GET_CODE (operands[1]) == MEM
1377 && symbolic_address_p (XEXP (operands[1], 0)))
1379 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1383 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1384 (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
1385 "GET_CODE (operands[1]) != CONST_INT"
1391 [(set_attr "type" "arith,arith,arith,load")])
1393 (define_expand "extendqihi2"
1394 [(set (match_operand:HI 0 "register_operand" "")
1395 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1399 if (GET_CODE (operands[1]) == MEM
1400 && symbolic_address_p (XEXP (operands[1], 0)))
1402 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1406 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1407 (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
1408 "GET_CODE (operands[1]) != CONST_INT"
1414 [(set_attr "type" "arith,arith,arith,load")])
1416 (define_expand "extendqisi2"
1417 [(set (match_operand:SI 0 "register_operand" "")
1418 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1422 if (GET_CODE (operands[1]) == MEM
1423 && symbolic_address_p (XEXP (operands[1], 0)))
1425 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1429 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1430 (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
1431 "GET_CODE (operands[1]) != CONST_INT"
1437 [(set_attr "type" "arith,arith,arith,load")])
1439 ;; Conversions between float and double.
1441 ;; The fadd instruction does not conform to IEEE 754 when used to
1442 ;; convert between float and double. In particular, the sign of -0 is
1443 ;; not preserved. Interestingly, fsub does conform.
1445 (define_insn "extendsfdf2"
1446 [(set (match_operand:DF 0 "register_operand" "=r")
1447 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
1449 "fsub.dss %0,%1,%#r0"
1450 [(set_attr "type" "spadd")])
1452 (define_insn "truncdfsf2"
1453 [(set (match_operand:SF 0 "register_operand" "=r")
1454 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
1456 "fsub.sds %0,%1,%#r0"
1457 [(set_attr "type" "dpadd")])
1459 ;; Conversions between floating point and integer
1461 (define_insn "floatsidf2"
1462 [(set (match_operand:DF 0 "register_operand" "=r")
1463 (float:DF (match_operand:SI 1 "register_operand" "r")))]
1466 [(set_attr "type" "spadd")])
1468 (define_insn "floatsisf2"
1469 [(set (match_operand:SF 0 "register_operand" "=r")
1470 (float:SF (match_operand:SI 1 "register_operand" "r")))]
1473 [(set_attr "type" "spadd")])
1475 (define_insn "fix_truncdfsi2"
1476 [(set (match_operand:SI 0 "register_operand" "=r")
1477 (fix:SI (match_operand:DF 1 "register_operand" "r")))]
1480 [(set_attr "type" "dpadd")])
1482 (define_insn "fix_truncsfsi2"
1483 [(set (match_operand:SI 0 "register_operand" "=r")
1484 (fix:SI (match_operand:SF 1 "register_operand" "r")))]
1487 [(set_attr "type" "spadd")])
1490 ;;- arithmetic instructions
1491 ;;- add instructions
1493 (define_insn "addsi3"
1494 [(set (match_operand:SI 0 "register_operand" "=r,r")
1495 (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
1496 (match_operand:SI 2 "add_operand" "rI,J")))]
1502 ;; In unusual contexts, an add of a large value is generated (case statements
1503 ;; for example). In these contexts, it is sufficient to accept only those
1504 ;; cases where the two registers are different.
1507 [(set (match_operand:SI 0 "register_operand" "=r,&r")
1508 (plus:SI (match_operand:SI 1 "arith32_operand" "%r,r")
1509 (match_operand:SI 2 "arith32_operand" "r,!n")))]
1515 if (which_alternative == 0)
1516 return \"addu %0,%1,%2\";
1518 xoperands[0] = operands[0];
1519 xoperands[1] = operands[2];
1520 output_asm_insn (output_load_const_int (SImode, xoperands),
1523 return \"addu %0,%1,%0\";
1525 [(set_attr "type" "arith,marith")
1526 (set_attr "length" "1,3")]) ; may be 2 or 3.
1528 ;; patterns for mixed mode floating point.
1529 ;; Do not define patterns that utilize mixed mode arithmetic that result
1530 ;; in narrowing the precision, because it loses accuracy, since the standard
1531 ;; requires double rounding, whereas the 88000 instruction only rounds once.
1533 (define_expand "adddf3"
1534 [(set (match_operand:DF 0 "register_operand" "=r")
1535 (plus:DF (match_operand:DF 1 "general_operand" "%r")
1536 (match_operand:DF 2 "general_operand" "r")))]
1540 operands[1] = legitimize_operand (operands[1], DFmode);
1541 operands[2] = legitimize_operand (operands[2], DFmode);
1545 [(set (match_operand:DF 0 "register_operand" "=r")
1546 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
1547 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
1550 [(set_attr "type" "spadd")])
1553 [(set (match_operand:DF 0 "register_operand" "=r")
1554 (plus:DF (match_operand:DF 1 "register_operand" "r")
1555 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
1558 [(set_attr "type" "dpadd")])
1561 [(set (match_operand:DF 0 "register_operand" "=r")
1562 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
1563 (match_operand:DF 2 "register_operand" "r")))]
1566 [(set_attr "type" "dpadd")])
1569 [(set (match_operand:DF 0 "register_operand" "=r")
1570 (plus:DF (match_operand:DF 1 "register_operand" "%r")
1571 (match_operand:DF 2 "register_operand" "r")))]
1574 [(set_attr "type" "dpadd")])
1576 (define_insn "addsf3"
1577 [(set (match_operand:SF 0 "register_operand" "=r")
1578 (plus:SF (match_operand:SF 1 "register_operand" "%r")
1579 (match_operand:SF 2 "register_operand" "r")))]
1582 [(set_attr "type" "spadd")])
1585 [(set (match_operand:DI 0 "register_operand" "=r")
1586 (plus:DI (match_operand:DI 1 "register_operand" "r")
1588 (match_operand:SI 2 "register_operand" "r"))))]
1590 "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
1591 [(set_attr "type" "marith")])
1594 [(set (match_operand:DI 0 "register_operand" "=r")
1595 (plus:DI (zero_extend:DI
1596 (match_operand:SI 1 "register_operand" "r"))
1597 (match_operand:DI 2 "register_operand" "r")))]
1599 "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
1600 [(set_attr "type" "marith")])
1602 (define_insn "adddi3"
1603 [(set (match_operand:DI 0 "register_operand" "=r")
1604 (plus:DI (match_operand:DI 1 "register_operand" "%r")
1605 (match_operand:DI 2 "register_operand" "r")))]
1607 "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
1608 [(set_attr "type" "marith")])
1610 ;;- subtract instructions
1612 (define_insn "subsi3"
1613 [(set (match_operand:SI 0 "register_operand" "=r")
1614 (minus:SI (match_operand:SI 1 "register_operand" "r")
1615 (match_operand:SI 2 "arith32_operand" "rI")))]
1619 ;; patterns for mixed mode floating point
1620 ;; Do not define patterns that utilize mixed mode arithmetic that result
1621 ;; in narrowing the precision, because it loses accuracy, since the standard
1622 ;; requires double rounding, whereas the 88000 instruction only rounds once.
1624 (define_expand "subdf3"
1625 [(set (match_operand:DF 0 "register_operand" "=r")
1626 (minus:DF (match_operand:DF 1 "general_operand" "r")
1627 (match_operand:DF 2 "general_operand" "r")))]
1631 operands[1] = legitimize_operand (operands[1], DFmode);
1632 operands[2] = legitimize_operand (operands[2], DFmode);
1636 [(set (match_operand:DF 0 "register_operand" "=r")
1637 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
1638 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
1641 [(set_attr "type" "spadd")])
1644 [(set (match_operand:DF 0 "register_operand" "=r")
1645 (minus:DF (match_operand:DF 1 "register_operand" "r")
1646 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
1649 [(set_attr "type" "dpadd")])
1652 [(set (match_operand:DF 0 "register_operand" "=r")
1653 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
1654 (match_operand:DF 2 "register_operand" "r")))]
1657 [(set_attr "type" "dpadd")])
1660 [(set (match_operand:DF 0 "register_operand" "=r")
1661 (minus:DF (match_operand:DF 1 "register_operand" "r")
1662 (match_operand:DF 2 "register_operand" "r")))]
1665 [(set_attr "type" "dpadd")])
1667 (define_insn "subsf3"
1668 [(set (match_operand:SF 0 "register_operand" "=r")
1669 (minus:SF (match_operand:SF 1 "register_operand" "r")
1670 (match_operand:SF 2 "register_operand" "r")))]
1673 [(set_attr "type" "spadd")])
1676 [(set (match_operand:DI 0 "register_operand" "=r")
1677 (minus:DI (match_operand:DI 1 "register_operand" "r")
1679 (match_operand:SI 2 "register_operand" "r"))))]
1681 "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
1682 [(set_attr "type" "marith")])
1685 [(set (match_operand:DI 0 "register_operand" "=r")
1686 (minus:DI (zero_extend:DI
1687 (match_operand:SI 1 "register_operand" "r"))
1688 (match_operand:DI 2 "register_operand" "r")))]
1690 "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
1691 [(set_attr "type" "marith")])
1693 (define_insn "subdi3"
1694 [(set (match_operand:DI 0 "register_operand" "=r")
1695 (minus:DI (match_operand:DI 1 "register_operand" "r")
1696 (match_operand:DI 2 "register_operand" "r")))]
1698 "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
1699 [(set_attr "type" "marith")])
1701 ;;- multiply instructions
1703 ;; There is an unfounded silicon eratta for E.1 requiring that an
1704 ;; immediate constant value in div/divu/mul instructions be less than
1705 ;; 0x800. This is no longer provided for.
1707 (define_insn "mulsi3"
1708 [(set (match_operand:SI 0 "register_operand" "=r")
1709 (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
1710 (match_operand:SI 2 "arith32_operand" "rI")))]
1713 [(set_attr "type" "imul")])
1715 ;; patterns for mixed mode floating point
1716 ;; Do not define patterns that utilize mixed mode arithmetic that result
1717 ;; in narrowing the precision, because it loses accuracy, since the standard
1718 ;; requires double rounding, whereas the 88000 instruction only rounds once.
1720 (define_expand "muldf3"
1721 [(set (match_operand:DF 0 "register_operand" "=r")
1722 (mult:DF (match_operand:DF 1 "general_operand" "%r")
1723 (match_operand:DF 2 "general_operand" "r")))]
1727 operands[1] = legitimize_operand (operands[1], DFmode);
1728 operands[2] = legitimize_operand (operands[2], DFmode);
1732 [(set (match_operand:DF 0 "register_operand" "=r")
1733 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
1734 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
1737 [(set_attr "type" "spmul")])
1740 [(set (match_operand:DF 0 "register_operand" "=r")
1741 (mult:DF (match_operand:DF 1 "register_operand" "r")
1742 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
1745 [(set_attr "type" "spmul")])
1748 [(set (match_operand:DF 0 "register_operand" "=r")
1749 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
1750 (match_operand:DF 2 "register_operand" "r")))]
1753 [(set_attr "type" "spmul")])
1756 [(set (match_operand:DF 0 "register_operand" "=r")
1757 (mult:DF (match_operand:DF 1 "register_operand" "%r")
1758 (match_operand:DF 2 "register_operand" "r")))]
1761 [(set_attr "type" "dpmul")])
1763 (define_insn "mulsf3"
1764 [(set (match_operand:SF 0 "register_operand" "=r")
1765 (mult:SF (match_operand:SF 1 "register_operand" "%r")
1766 (match_operand:SF 2 "register_operand" "r")))]
1769 [(set_attr "type" "spmul")])
1771 ;;- divide instructions
1773 ;; The 88k div and divu instructions don't reliably trap on
1774 ;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The
1775 ;; general scheme for doing divide is to do a 4-way split based on the
1776 ;; sign of the two operand and do the appropriate negates.
1778 ;; The conditional trap instruction is not used as this serializes the
1779 ;; processor. Instead a conditional branch and an unconditional trap
1780 ;; are used, but after the divu. Since the divu takes up to 38 cycles,
1781 ;; the conditional branch is essentially free.
1783 ;; Two target options control how divide is done. One options selects
1784 ;; whether to do the branch and negate scheme instead of using the div
1785 ;; instruction; the other option selects whether to explicitly check
1786 ;; for divide-by-zero or take your chances. If the div instruction is
1787 ;; used, the O/S must complete the operation if the operands are
1788 ;; negative. The O/S will signal an overflow condition if the most
1789 ;; negative number (-214783648) is divided by negative 1.
1791 ;; There is an unfounded silicon eratta for E.1 requiring that an
1792 ;; immediate constant value in div/divu/mul instructions be less than
1793 ;; 0x800. This is no longer provided for.
1795 ;; Division by 0 trap
1796 (define_insn "trap_divide_by_zero"
1797 [(trap_if (const_int 1) 503)]
1800 [(set_attr "type" "weird")])
1802 ;; Conditional division by 0 trap.
1803 (define_expand "tcnd_divide_by_zero"
1805 (if_then_else (eq (match_operand:SI 0 "register_operand" "")
1808 (match_operand 1 "" "")))
1809 (trap_if (const_int 1) 503)]
1813 emit_insn (gen_cmpsi (operands[0], const0_rtx));
1814 emit_jump_insn (gen_bne (operands[1]));
1815 emit_insn (gen_trap_divide_by_zero ());
1820 (define_expand "divsi3"
1821 [(set (match_operand:SI 0 "register_operand" "")
1822 (div:SI (match_operand:SI 1 "arith32_operand" "")
1823 (match_operand:SI 2 "arith32_operand" "")))]
1827 rtx op0 = operands[0];
1828 rtx op1 = operands[1];
1829 rtx op2 = operands[2];
1832 /* @@ This needs to be reworked. Torbjorn Granlund has suggested making
1833 it a runtime (perhaps quite special). */
1835 if (GET_CODE (op1) == CONST_INT)
1836 op1 = force_reg (SImode, op1);
1838 else if (GET_CODE (op2) == CONST_INT
1839 && ! SMALL_INT (operands[2]))
1840 op2 = force_reg (SImode, op2);
1842 if (op2 == const0_rtx)
1844 emit_insn (gen_trap_divide_by_zero ());
1846 emit_insn (gen_dummy (op0));
1852 emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2));
1853 if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
1855 rtx label = gen_label_rtx ();
1856 emit_insn (gen_tcnd_divide_by_zero (op2, label));
1858 emit_insn (gen_dummy (op0));
1863 join_label = gen_label_rtx ();
1864 if (GET_CODE (op1) == CONST_INT)
1867 rtx neg_op2 = gen_reg_rtx (SImode);
1868 rtx label1 = gen_label_rtx ();
1870 if (INTVAL (op1) < 0)
1873 op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1));
1875 op1 = force_reg (SImode, op1);
1877 emit_insn (gen_negsi2 (neg_op2, op2));
1878 emit_insn (gen_cmpsi (op2, const0_rtx));
1879 emit_jump_insn (gen_bgt (label1));
1880 /* constant / 0-or-negative */
1881 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
1883 emit_insn (gen_negsi2 (op0, op0));
1885 if (TARGET_CHECK_ZERO_DIV)
1886 emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
1889 emit_jump_insn (gen_jump (join_label));
1893 emit_label (label1); /* constant / positive */
1894 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
1896 emit_insn (gen_negsi2 (op0, op0));
1899 else if (GET_CODE (op2) == CONST_INT)
1902 rtx neg_op1 = gen_reg_rtx (SImode);
1903 rtx label1 = gen_label_rtx ();
1905 if (INTVAL (op2) < 0)
1908 op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2));
1910 else if (! SMALL_INT (operands[2]))
1911 op2 = force_reg (SImode, op2);
1913 emit_insn (gen_negsi2 (neg_op1, op1));
1914 emit_insn (gen_cmpsi (op1, const0_rtx));
1915 emit_jump_insn (gen_bge (label1));
1916 /* 0-or-negative / constant */
1917 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
1919 emit_insn (gen_negsi2 (op0, op0));
1921 emit_jump_insn (gen_jump (join_label));
1924 emit_label (label1); /* positive / constant */
1925 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
1927 emit_insn (gen_negsi2 (op0, op0));
1932 rtx neg_op1 = gen_reg_rtx (SImode);
1933 rtx neg_op2 = gen_reg_rtx (SImode);
1934 rtx label1 = gen_label_rtx ();
1935 rtx label2 = gen_label_rtx ();
1936 rtx label3 = gen_label_rtx ();
1939 emit_insn (gen_negsi2 (neg_op2, op2));
1940 emit_insn (gen_cmpsi (op2, const0_rtx));
1941 emit_jump_insn (gen_bgt (label1));
1943 emit_insn (gen_negsi2 (neg_op1, op1));
1944 emit_insn (gen_cmpsi (op1, const0_rtx));
1945 emit_jump_insn (gen_bge (label2));
1946 /* negative / negative-or-0 */
1947 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2));
1949 if (TARGET_CHECK_ZERO_DIV)
1951 label4 = gen_label_rtx ();
1952 emit_insn (gen_cmpsi (op2, const0_rtx));
1953 emit_jump_insn (gen_bne (join_label));
1954 emit_label (label4);
1955 emit_insn (gen_trap_divide_by_zero ());
1960 emit_jump_insn (gen_jump (join_label));
1964 emit_label (label2); /* pos.-or-0 / neg.-or-0 */
1965 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
1967 if (TARGET_CHECK_ZERO_DIV)
1969 emit_insn (gen_cmpsi (op2, const0_rtx));
1970 emit_jump_insn (gen_beq (label4));
1973 emit_insn (gen_negsi2 (op0, op0));
1974 emit_jump_insn (gen_jump (join_label));
1977 emit_label (label1);
1978 emit_insn (gen_negsi2 (neg_op1, op1));
1979 emit_insn (gen_cmpsi (op1, const0_rtx));
1980 emit_jump_insn (gen_bge (label3));
1981 /* negative / positive */
1982 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
1983 emit_insn (gen_negsi2 (op0, op0));
1984 emit_jump_insn (gen_jump (join_label));
1987 emit_label (label3); /* positive-or-0 / positive */
1988 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
1991 emit_label (join_label);
1993 emit_insn (gen_dummy (op0));
1998 [(set (match_operand:SI 0 "register_operand" "=r")
1999 (div:SI (match_operand:SI 1 "register_operand" "r")
2000 (match_operand:SI 2 "arith_operand" "rI")))]
2003 [(set_attr "type" "idiv")])
2005 (define_expand "udivsi3"
2006 [(set (match_operand:SI 0 "register_operand" "")
2007 (udiv:SI (match_operand:SI 1 "register_operand" "")
2008 (match_operand:SI 2 "arith32_operand" "")))]
2012 rtx op2 = operands[2];
2014 if (op2 == const0_rtx)
2016 emit_insn (gen_trap_divide_by_zero ());
2018 emit_insn (gen_dummy (operands[0]));
2021 else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
2023 rtx label = gen_label_rtx ();
2024 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2025 gen_rtx (UDIV, SImode, operands[1], op2)));
2026 emit_insn (gen_tcnd_divide_by_zero (op2, label));
2028 emit_insn (gen_dummy (operands[0]));
2034 [(set (match_operand:SI 0 "register_operand" "=r")
2035 (udiv:SI (match_operand:SI 1 "register_operand" "r")
2036 (match_operand:SI 2 "arith32_operand" "rI")))]
2037 "operands[2] != const0_rtx"
2039 [(set_attr "type" "idiv")])
2042 [(set (match_operand:SI 0 "register_operand" "=r")
2043 (udiv:SI (match_operand:SI 1 "register_operand" "r")
2047 [(set_attr "type" "weird")])
2049 ;; patterns for mixed mode floating point.
2050 ;; Do not define patterns that utilize mixed mode arithmetic that result
2051 ;; in narrowing the precision, because it loses accuracy, since the standard
2052 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2054 (define_expand "divdf3"
2055 [(set (match_operand:DF 0 "register_operand" "=r")
2056 (div:DF (match_operand:DF 1 "general_operand" "r")
2057 (match_operand:DF 2 "general_operand" "r")))]
2061 operands[1] = legitimize_operand (operands[1], DFmode);
2062 if (real_power_of_2_operand (operands[2]))
2064 union real_extract u;
2065 bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u);
2066 emit_insn (gen_muldf3 (operands[0], operands[1],
2067 CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode)));
2070 else if (! register_operand (operands[2], DFmode))
2071 operands[2] = force_reg (DFmode, operands[2]);
2075 [(set (match_operand:DF 0 "register_operand" "=r")
2076 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
2077 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
2080 [(set_attr "type" "dpdiv")])
2083 [(set (match_operand:DF 0 "register_operand" "=r")
2084 (div:DF (match_operand:DF 1 "register_operand" "r")
2085 (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
2088 [(set_attr "type" "dpdiv")])
2091 [(set (match_operand:DF 0 "register_operand" "=r")
2092 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r"))
2093 (match_operand:DF 2 "register_operand" "r")))]
2096 [(set_attr "type" "dpdiv")])
2098 (define_insn "divsf3"
2099 [(set (match_operand:SF 0 "register_operand" "=r")
2100 (div:SF (match_operand:SF 1 "register_operand" "r")
2101 (match_operand:SF 2 "register_operand" "r")))]
2104 [(set_attr "type" "spdiv")])
2107 [(set (match_operand:DF 0 "register_operand" "=r")
2108 (div:DF (match_operand:DF 1 "register_operand" "r")
2109 (match_operand:DF 2 "register_operand" "r")))]
2112 [(set_attr "type" "dpdiv")])
2114 ;; - remainder instructions, don't define, since the hardware doesn't have any
2115 ;; direct support, and GNU can synthesis them out of div/mul just fine.
2117 ;;- load effective address, must come after add, so that we favor using
2118 ;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require
2119 ;; the data unit), and also future 88k chips might not support unscaled
2120 ;; lda instructions.
2123 [(set (match_operand:SI 0 "register_operand" "=r")
2124 (match_operand:SI 1 "address_operand" "p"))]
2125 "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
2129 [(set (match_operand:SI 0 "register_operand" "=r")
2130 (match_operand:HI 1 "address_operand" "p"))]
2133 [(set_attr "type" "loada")])
2136 [(set (match_operand:SI 0 "register_operand" "=r")
2137 (match_operand:SI 1 "address_operand" "p"))]
2140 [(set_attr "type" "loada")])
2143 [(set (match_operand:SI 0 "register_operand" "=r")
2144 (match_operand:DI 1 "address_operand" "p"))]
2147 [(set_attr "type" "loada")])
2150 [(set (match_operand:SI 0 "register_operand" "=r")
2151 (match_operand:SF 1 "address_operand" "p"))]
2154 [(set_attr "type" "loada")])
2157 [(set (match_operand:SI 0 "register_operand" "=r")
2158 (match_operand:DF 1 "address_operand" "p"))]
2161 [(set_attr "type" "loada")])
2163 ;;- and instructions (with complement also)
2165 [(set (match_operand:SI 0 "register_operand" "=r")
2166 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2167 (match_operand:SI 2 "register_operand" "r")))]
2171 ;; If the operation is being performed on a 32-bit constant such that
2172 ;; it cannot be done in one insn, do it in two. We may lose a bit on
2173 ;; CSE in pathological cases, but it seems better doing it this way.
2175 (define_expand "andsi3"
2176 [(set (match_operand:SI 0 "register_operand" "")
2177 (and:SI (match_operand:SI 1 "arith32_operand" "")
2178 (match_operand:SI 2 "arith32_operand" "")))]
2182 if (GET_CODE (operands[2]) == CONST_INT)
2184 int value = INTVAL (operands[2]);
2186 if (! (SMALL_INTVAL (value)
2187 || (value & 0xffff0000) == 0xffff0000
2188 || (value & 0xffff) == 0xffff
2189 || (value & 0xffff) == 0
2190 || integer_ok_for_set (~value)))
2192 emit_insn (gen_andsi3 (operands[0], operands[1],
2193 gen_rtx (CONST_INT, VOIDmode,
2195 operands[1] = operands[0];
2196 operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000);
2202 [(set (match_operand:SI 0 "register_operand" "=r,r")
2203 (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
2204 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
2206 "* return output_and (operands);"
2207 [(set_attr "type" "arith,marith")])
2210 [(set (match_operand:DI 0 "register_operand" "=r")
2211 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2212 (match_operand:DI 2 "register_operand" "r")))]
2214 "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
2215 [(set_attr "type" "marith")])
2217 (define_insn "anddi3"
2218 [(set (match_operand:DI 0 "register_operand" "=r")
2219 (and:DI (match_operand:DI 1 "arith64_operand" "%r")
2220 (match_operand:DI 2 "arith64_operand" "rn")))]
2226 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
2227 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
2228 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
2230 output_asm_insn (output_and (xoperands), xoperands);
2232 operands[0] = operand_subword (operands[0], 0, 0, DImode);
2233 operands[1] = operand_subword (operands[1], 0, 0, DImode);
2234 operands[2] = operand_subword (operands[2], 0, 0, DImode);
2236 return output_and (operands);
2238 [(set_attr "type" "marith")
2239 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2241 ;;- Bit set (inclusive or) instructions (with complement also)
2243 [(set (match_operand:SI 0 "register_operand" "=r")
2244 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2245 (match_operand:SI 2 "register_operand" "r")))]
2249 (define_expand "iorsi3"
2250 [(set (match_operand:SI 0 "register_operand" "")
2251 (ior:SI (match_operand:SI 1 "arith32_operand" "")
2252 (match_operand:SI 2 "arith32_operand" "")))]
2256 if (GET_CODE (operands[2]) == CONST_INT)
2258 int value = INTVAL (operands[2]);
2260 if (! (SMALL_INTVAL (value)
2261 || (value & 0xffff) == 0
2262 || integer_ok_for_set (value)))
2264 emit_insn (gen_iorsi3 (operands[0], operands[1],
2265 gen_rtx (CONST_INT, VOIDmode,
2266 value & 0xffff0000)));
2267 operands[1] = operands[0];
2268 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
2274 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2275 (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
2276 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
2282 or.u %0,%1,%X2\;or %0,%0,%x2"
2283 [(set_attr "type" "arith,arith,arith,marith")])
2286 [(set (match_operand:DI 0 "register_operand" "=r")
2287 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2288 (match_operand:DI 2 "register_operand" "r")))]
2290 "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
2291 [(set_attr "type" "marith")])
2293 (define_insn "iordi3"
2294 [(set (match_operand:DI 0 "register_operand" "=r")
2295 (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
2296 (match_operand:DI 2 "arith64_operand" "rn")))]
2302 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
2303 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
2304 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
2306 output_asm_insn (output_ior (xoperands), xoperands);
2308 operands[0] = operand_subword (operands[0], 0, 0, DImode);
2309 operands[1] = operand_subword (operands[1], 0, 0, DImode);
2310 operands[2] = operand_subword (operands[2], 0, 0, DImode);
2312 return output_ior (operands);
2314 [(set_attr "type" "marith")
2315 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2317 ;;- xor instructions (with complement also)
2319 [(set (match_operand:SI 0 "register_operand" "=r")
2320 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
2321 (match_operand:SI 2 "register_operand" "r"))))]
2325 (define_expand "xorsi3"
2326 [(set (match_operand:SI 0 "register_operand" "")
2327 (xor:SI (match_operand:SI 1 "arith32_operand" "")
2328 (match_operand:SI 2 "arith32_operand" "")))]
2332 if (GET_CODE (operands[2]) == CONST_INT)
2334 int value = INTVAL (operands[2]);
2336 if (! (SMALL_INTVAL (value)
2337 || (value & 0xffff) == 0))
2339 emit_insn (gen_xorsi3 (operands[0], operands[1],
2340 gen_rtx (CONST_INT, VOIDmode,
2341 value & 0xffff0000)));
2342 operands[1] = operands[0];
2343 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
2349 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2350 (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
2351 (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
2356 xor.u %0,%1,%X2\;xor %0,%0,%x2"
2357 [(set_attr "type" "arith,arith,marith")])
2360 [(set (match_operand:DI 0 "register_operand" "=r")
2361 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2362 (match_operand:DI 2 "register_operand" "r"))))]
2364 "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
2365 [(set_attr "type" "marith")])
2367 (define_insn "xordi3"
2368 [(set (match_operand:DI 0 "register_operand" "=r")
2369 (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
2370 (match_operand:DI 2 "arith64_operand" "rn")))]
2376 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
2377 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
2378 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
2380 output_asm_insn (output_xor (xoperands), xoperands);
2382 operands[0] = operand_subword (operands[0], 0, 0, DImode);
2383 operands[1] = operand_subword (operands[1], 0, 0, DImode);
2384 operands[2] = operand_subword (operands[2], 0, 0, DImode);
2386 return output_xor (operands);
2388 [(set_attr "type" "marith")
2389 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2391 ;;- ones complement instructions
2392 (define_insn "one_cmplsi2"
2393 [(set (match_operand:SI 0 "register_operand" "=r")
2394 (not:SI (match_operand:SI 1 "register_operand" "r")))]
2398 (define_insn "one_cmpldi2"
2399 [(set (match_operand:DI 0 "register_operand" "=r")
2400 (not:DI (match_operand:DI 1 "register_operand" "r")))]
2402 "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
2403 [(set_attr "type" "marith")])
2405 ;; Optimized special cases of shifting.
2406 ;; Must precede the general case.
2408 ;; @@ What about HImode shifted by 8?
2411 [(set (match_operand:SI 0 "register_operand" "=r")
2412 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2414 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
2416 [(set_attr "type" "load")])
2419 [(set (match_operand:SI 0 "register_operand" "=r")
2420 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2422 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
2424 [(set_attr "type" "load")])
2427 [(set (match_operand:SI 0 "register_operand" "=r")
2428 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2430 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
2432 [(set_attr "type" "load")])
2435 [(set (match_operand:SI 0 "register_operand" "=r")
2436 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2438 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
2440 [(set_attr "type" "load")])
2442 ;;- arithmetic shift instructions.
2444 ;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should
2445 ;; be arith32_operand?
2447 ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
2449 [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
2450 (match_operand:SI 1 "arith_operand" "rI"))
2454 [(set_attr "type" "weird")])
2456 ;; Just in case the optimizer decides to fold away the test.
2458 [(trap_if (const_int 1) 7)]
2461 [(set_attr "type" "weird")])
2463 (define_expand "ashlsi3"
2464 [(set (match_operand:SI 0 "register_operand" "")
2465 (ashift:SI (match_operand:SI 1 "register_operand" "")
2466 (match_operand:SI 2 "arith32_operand" "")))]
2470 if (GET_CODE (operands[2]) == CONST_INT)
2472 if ((unsigned) INTVAL (operands[2]) > 31)
2474 if (TARGET_TRAP_LARGE_SHIFT)
2475 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
2476 gen_rtx (CONST_INT, VOIDmode, 31)));
2478 emit_move_insn (operands[0], const0_rtx);
2483 else if (TARGET_TRAP_LARGE_SHIFT)
2484 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
2486 else if (TARGET_HANDLE_LARGE_SHIFT)
2488 rtx reg = gen_reg_rtx (SImode);
2489 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
2490 emit_insn (gen_sleu (reg));
2491 emit_insn (gen_andsi3 (reg, operands[1], reg));
2497 [(set (match_operand:SI 0 "register_operand" "=r,r")
2498 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
2499 (match_operand:SI 2 "arith5_operand" "r,n")))]
2505 (define_expand "ashrsi3"
2506 [(set (match_operand:SI 0 "register_operand" "")
2507 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2508 (match_operand:SI 2 "arith32_operand" "")))]
2512 if (GET_CODE (operands[2]) == CONST_INT)
2514 if ((unsigned) INTVAL (operands[2]) > 31)
2516 if (TARGET_TRAP_LARGE_SHIFT)
2518 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
2519 gen_rtx (CONST_INT, VOIDmode, 31)));
2523 operands[2] = gen_rtx (CONST_INT, VOIDmode, 31);
2527 else if (TARGET_TRAP_LARGE_SHIFT)
2528 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
2530 else if (TARGET_HANDLE_LARGE_SHIFT)
2532 rtx reg = gen_reg_rtx (SImode);
2533 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
2534 emit_insn (gen_sgtu (reg));
2535 emit_insn (gen_iorsi3 (reg, operands[2], reg));
2541 [(set (match_operand:SI 0 "register_operand" "=r,r")
2542 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
2543 (match_operand:SI 2 "arith5_operand" "r,n")))]
2549 ;;- logical shift instructions. Logical shift left becomes arithmetic
2550 ;; shift left. LSHIFT is not normally produced, but is supported.
2552 (define_expand "lshlsi3"
2553 [(set (match_operand:SI 0 "register_operand" "")
2554 (lshift:SI (match_operand:SI 1 "register_operand" "")
2555 (match_operand:SI 2 "arith32_operand" "")))]
2559 emit_insn (gen_ashlsi3 (operands[0], operands[1], operands[2]));
2564 [(set (match_operand:SI 0 "register_operand" "=r,r")
2565 (lshift:SI (match_operand:SI 1 "register_operand" "r,r")
2566 (match_operand:SI 2 "arith5_operand" "r,n")))]
2572 (define_expand "lshrsi3"
2573 [(set (match_operand:SI 0 "register_operand" "")
2574 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2575 (match_operand:SI 2 "arith32_operand" "")))]
2579 if (GET_CODE (operands[2]) == CONST_INT)
2581 if ((unsigned) INTVAL (operands[2]) > 31)
2583 if (TARGET_TRAP_LARGE_SHIFT)
2584 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
2585 gen_rtx (CONST_INT, VOIDmode, 31)));
2587 emit_move_insn (operands[0], const0_rtx);
2592 else if (TARGET_TRAP_LARGE_SHIFT)
2593 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
2595 else if (TARGET_HANDLE_LARGE_SHIFT)
2597 rtx reg = gen_reg_rtx (SImode);
2598 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
2599 emit_insn (gen_sleu (reg));
2600 emit_insn (gen_andsi3 (reg, operands[1], reg));
2606 [(set (match_operand:SI 0 "register_operand" "=r,r")
2607 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
2608 (match_operand:SI 2 "arith5_operand" "r,n")))]
2614 ;;- rotate instructions
2616 (define_expand "rotlsi3"
2617 [(set (match_operand:SI 0 "register_operand" "")
2618 (rotatert:SI (match_operand:SI 1 "register_operand" "")
2619 (match_operand:SI 2 "arith32_operand" "")))]
2623 if (GET_CODE (operands[2]) == CONST_INT
2624 && (unsigned) INTVAL (operands[2]) >= 32)
2625 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2626 (32 - INTVAL (operands[2])) % 32);
2629 rtx op = gen_reg_rtx (SImode);
2630 emit_insn (gen_negsi2 (op, operands[2]));
2635 (define_insn "rotrsi3"
2636 [(set (match_operand:SI 0 "register_operand" "=r")
2637 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
2638 (match_operand:SI 2 "arith_operand" "rI")))]
2642 ;; Bit field instructions.
2645 [(set (match_operand:SI 0 "register_operand" "=r")
2646 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
2653 [(set (match_operand:SI 0 "register_operand" "=r")
2654 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
2655 (match_operand:SI 2 "int5_operand" "")
2656 (match_operand:SI 3 "int5_operand" "")))]
2660 operands[4] = gen_rtx (CONST_INT, SImode,
2661 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
2662 return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
2666 [(set (match_operand:SI 0 "register_operand" "=r")
2667 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2673 (define_insn "extzv"
2674 [(set (match_operand:SI 0 "register_operand" "=r")
2675 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2676 (match_operand:SI 2 "int5_operand" "")
2677 (match_operand:SI 3 "int5_operand" "")))]
2681 operands[4] = gen_rtx (CONST_INT, SImode,
2682 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
2683 return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
2687 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2688 (match_operand:SI 1 "int5_operand" "")
2689 (match_operand:SI 2 "int5_operand" ""))
2694 operands[3] = gen_rtx (CONST_INT, SImode,
2695 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
2696 return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
2700 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2701 (match_operand:SI 1 "int5_operand" "")
2702 (match_operand:SI 2 "int5_operand" ""))
2707 operands[3] = gen_rtx (CONST_INT, SImode,
2708 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
2709 return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
2713 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2714 (match_operand:SI 1 "int5_operand" "")
2715 (match_operand:SI 2 "int5_operand" ""))
2716 (match_operand:SI 3 "int32_operand" "n"))]
2720 int value = INTVAL (operands[3]);
2722 if (INTVAL (operands[1]) < 32)
2723 value &= (1 << INTVAL (operands[1])) - 1;
2725 operands[2] = gen_rtx (CONST_INT, VOIDmode,
2726 32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
2728 value <<= INTVAL (operands[2]);
2729 operands[3] = gen_rtx (CONST_INT, VOIDmode, value);
2731 if (SMALL_INTVAL (value))
2732 return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
2733 else if ((value & 0x0000ffff) == 0)
2734 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
2736 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
2738 [(set_attr "type" "marith")
2739 (set_attr "length" "3")]) ; may be 2 or 3.
2742 (define_insn "negsi2"
2743 [(set (match_operand:SI 0 "register_operand" "=r")
2744 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2749 [(set (match_operand:SF 0 "register_operand" "=r")
2750 (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r"))))]
2752 "fsub.ssd %0,%#r0,%1"
2753 [(set_attr "type" "dpadd")])
2756 [(set (match_operand:DF 0 "register_operand" "+r")
2757 (neg:DF (match_dup 0)))]
2759 "xor.u %0,%0,0x8000")
2761 (define_insn "negdf2"
2762 [(set (match_operand:DF 0 "register_operand" "=&r")
2763 (neg:DF (match_operand:DF 1 "register_operand" "r")))]
2765 "xor.u %0,%1,0x8000\;or %d0,%#r0,%d1"
2766 [(set_attr "type" "marith")])
2768 (define_insn "negsf2"
2769 [(set (match_operand:SF 0 "register_operand" "=r")
2770 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2772 "xor.u %0,%1,0x8000")
2774 ;; absolute value insns for floating-point (integer abs can be done using the
2775 ;; machine-independent sequence).
2778 [(set (match_operand:DF 0 "register_operand" "+r")
2779 (abs:DF (match_dup 0)))]
2781 "and.u %0,%0,0x7fff")
2783 (define_insn "absdf2"
2784 [(set (match_operand:DF 0 "register_operand" "=&r")
2785 (abs:DF (match_operand:DF 1 "register_operand" "r")))]
2787 "and.u %0,%1,0x7fff\;or %d0,%#r0,%d1"
2788 [(set_attr "type" "marith")])
2790 (define_insn "abssf2"
2791 [(set (match_operand:SF 0 "register_operand" "=r")
2792 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2794 "and.u %0,%1,0x7fff")
2796 ;; Subroutines of "casesi".
2798 ;; Operand 0 is index
2799 ;; operand 1 is the minimum bound
2800 ;; operand 2 is the maximum bound - minimum bound + 1
2801 ;; operand 3 is CODE_LABEL for the table;
2802 ;; operand 4 is the CODE_LABEL to go to if index out of range.
2804 (define_expand "casesi"
2805 ;; We don't use these for generating the RTL, but we must describe
2806 ;; the operands here.
2807 [(match_operand:SI 0 "general_operand" "")
2808 (match_operand:SI 1 "immediate_operand" "")
2809 (match_operand:SI 2 "immediate_operand" "")
2810 (match_operand 3 "" "")
2811 (match_operand 4 "" "")]
2815 register rtx index_diff = gen_reg_rtx (SImode);
2816 register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
2818 /* Compute the index difference and handle the default case. */
2819 emit_insn (gen_addsi3 (index_diff,
2820 force_reg (SImode, operands[0]),
2821 ADD_INT (low) ? low : force_reg (SImode, low)));
2822 emit_insn (gen_cmpsi (index_diff, operands[2]));
2823 emit_jump_insn (gen_bgtu (operands[4]));
2825 /* Call the jump that will branch to the appropriate case. */
2826 emit_jump_insn (gen_casesi_enter (gen_rtx (LABEL_REF, VOIDmode, operands[3]),
2829 /* Claim that flow drops into the table so it will be adjacent. */
2833 ;; The bsr.n instruction is directed to the END of the table. See
2834 ;; ASM_OUTPUT_CASE_END.
2836 (define_insn "casesi_enter"
2837 [(set (pc) (match_operand 0 "" ""))
2838 (use (match_operand:SI 1 "register_operand" "r"))
2839 ;; The USE here is so that at least one jump-insn will refer to the label,
2840 ;; to keep it alive in jump_optimize.
2841 (use (label_ref (match_operand 2 "" "")))
2842 (clobber (reg:SI 1))]
2846 if (flag_delayed_branch)
2847 return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
2848 m88k_case_index = REGNO (operands[1]);
2851 [(set_attr "type" "weird")
2852 (set_attr "length" "3")]) ; Including the "jmp r1".
2854 ;;- jump to subroutine
2855 (define_expand "call"
2856 [(parallel [(call (match_operand:SI 0 "" "")
2857 (match_operand 1 "" ""))
2862 if (GET_CODE (operands[0]) == MEM
2863 && ! call_address_operand (XEXP (operands[0], 0), SImode))
2864 operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
2865 force_reg (Pmode, XEXP (operands[0], 0)));
2869 [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
2870 (match_operand 1 "" ""))
2873 "* return output_call (operands, operands[0]);"
2874 [(set_attr "type" "call")])
2876 (define_expand "call_value"
2877 [(parallel [(set (match_operand 0 "register_operand" "")
2878 (call (match_operand:SI 1 "" "")
2879 (match_operand 2 "" "")))
2884 if (GET_CODE (operands[1]) == MEM
2885 && ! call_address_operand (XEXP (operands[1], 0), SImode))
2886 operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
2887 force_reg (Pmode, XEXP (operands[1], 0)));
2891 [(parallel [(set (match_operand 0 "register_operand" "=r")
2893 (match_operand:SI 1 "call_address_operand" "rQ"))
2894 (match_operand 2 "" "")))
2897 "* return output_call (operands, operands[1]);"
2898 [(set_attr "type" "call")])
2900 ;; Nop instruction and others
2907 (define_insn "return"
2911 [(set_attr "type" "branch")])
2913 (define_insn "indirect_jump"
2914 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2917 [(set_attr "type" "branch")])
2921 (label_ref (match_operand 0 "" "")))]
2924 [(set_attr "type" "jump")])
2926 ;; This insn is used for some loop tests, typically loops reversed when
2927 ;; strength reduction is used. It is actually created when the instruction
2928 ;; combination phase combines the special loop test. Since this insn
2929 ;; is both a jump insn and has an output, it must deal with it's own
2930 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
2931 ;; to not choose the register alternatives in the event a reload is needed.
2933 (define_insn "decrement_and_branch_until_zero"
2936 (match_operator 0 "relop_no_unsigned"
2937 [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
2939 (label_ref (match_operand 2 "" ""))
2942 (plus:SI (match_dup 1)
2943 (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
2944 (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
2945 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
2946 "find_reg_note (insn, REG_NONNEG, 0)"
2948 bcnd.n %B0,%1,%2\;addu %1,%1,%3
2949 bcnd.n %B0,%1,%2\;subu %1,%1,%n3
2950 ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
2951 ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
2952 [(set_attr "type" "weird")
2953 (set_attr "length" "2,2,4,4")])
2955 ;; Special insn to serve as the last insn of a define_expand. This insn
2956 ;; will generate no code.
2958 (define_expand "dummy"
2959 [(set (match_operand 0 "" "") (match_dup 0))]
2963 ;;- Local variables:
2965 ;;- comment-start: ";;- "
2966 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
2967 ;;- eval: (modify-syntax-entry ?[ "(]")
2968 ;;- eval: (modify-syntax-entry ?] ")[")
2969 ;;- eval: (modify-syntax-entry ?{ "(}")
2970 ;;- eval: (modify-syntax-entry ?} "){")