OSDN Git Service

* config/mmix/mmix.md ("truncdfsf2"): Correct operator is
[pf3gnuchains/gcc-fork.git] / gcc / config / mmix / mmix.md
1 ;; GCC machine description for MMIX
2 ;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
3 ;; Contributed by Hans-Peter Nilsson (hp@bitrange.com)
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC 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 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC 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 GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et al.
26
27 ;; Uses of UNSPEC in this file:
28 ;; UNSPEC_VOLATILE:
29 ;;
30 ;;      0       sync_icache (sync icache before trampoline jump)
31 ;;      1       nonlocal_goto_receiver
32 ;;
33
34 ;; The order of insns is as in Node: Standard Names, with smaller modes
35 ;; before bigger modes.
36
37 ;; FIXME:s
38 ;; - Use new formats; e.g. '{' not '"*{'.
39
40 (define_constants
41   [(MMIX_rJ_REGNUM 259)]
42 )
43
44 ;; FIXME: Can we remove the reg-to-reg for smaller modes?  Shouldn't they
45 ;; be synthesized ok?
46 (define_insn "movqi"
47   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r ,r,x ,r,r,m,??r")
48         (match_operand:QI 1 "general_operand"       "r,LS,K,rI,x,m,r,n"))]
49   ""
50   "@
51    SET %0,%1
52    %s1 %0,%v1
53    NEGU %0,0,%n1
54    PUT %0,%1
55    GET %0,%1
56    LDB%U0 %0,%1
57    STBU %1,%0
58    %r0%I1")
59
60 (define_insn "movhi"
61   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,x,r,r,m,??r")
62         (match_operand:HI 1 "general_operand"       "r,LS,K,r,x,m,r,n"))]
63   ""
64   "@
65    SET %0,%1
66    %s1 %0,%v1
67    NEGU %0,0,%n1
68    PUT %0,%1
69    GET %0,%1
70    LDW%U0 %0,%1
71    STWU %1,%0
72    %r0%I1")
73
74 ;; gcc.c-torture/compile/920428-2.c fails if there's no "n".
75 (define_insn "movsi"
76   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r ,r,x,r,r,m,??r")
77         (match_operand:SI 1 "general_operand"       "r,LS,K,r,x,m,r,n"))]
78   ""
79   "@
80    SET %0,%1
81    %s1 %0,%v1
82    NEGU %0,0,%n1
83    PUT %0,%1
84    GET %0,%1
85    LDT%U0 %0,%1
86    STTU %1,%0
87    %r0%I1")
88
89 ;; We assume all "s" are addresses.  Does that hold?
90 (define_insn "movdi"
91   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r ,r,x,r,m,r,m,r,r,??r")
92         (match_operand:DI 1 "general_operand"       "r,LS,K,r,x,I,m,r,R,s,n"))]
93   ""
94   "@
95    SET %0,%1
96    %s1 %0,%v1
97    NEGU %0,0,%n1
98    PUT %0,%1
99    GET %0,%1
100    STCO %1,%0
101    LDO %0,%1
102    STOU %1,%0
103    GETA %0,%1
104    LDA %0,%1
105    %r0%I1")
106
107 ;; Note that we move around the float as a collection of bits; no
108 ;; conversion to double.
109 (define_insn "movsf"
110  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,x,r,r,m,??r")
111        (match_operand:SF 1 "general_operand"       "r,G,r,x,m,r,F"))]
112   ""
113   "@
114    SET %0,%1
115    SETL %0,0
116    PUT %0,%1
117    GET %0,%1
118    LDT %0,%1
119    STTU %1,%0
120    %r0%I1")
121
122 (define_insn "movdf"
123   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,x,r,r,m,??r")
124         (match_operand:DF 1 "general_operand"       "r,G,r,x,m,r,F"))]
125   ""
126   "@
127    SET %0,%1
128    SETL %0,0
129    PUT %0,%1
130    GET %0,%1
131    LDO %0,%1
132    STOU %1,%0
133    %r0%I1")
134 \f
135 (define_insn "adddi3"
136   [(set (match_operand:DI 0 "register_operand"  "=r,r,r")
137         (plus:DI
138          (match_operand:DI 1 "register_operand" "%r,r,0")
139          (match_operand:DI 2 "mmix_reg_or_constant_operand" "rI,K,LS")))]
140   ""
141   "@
142    ADDU %0,%1,%2
143    SUBU %0,%1,%n2
144    %i2 %0,%v2")
145
146 (define_insn "adddf3"
147   [(set (match_operand:DF 0 "register_operand" "=r")
148         (plus:DF (match_operand:DF 1 "register_operand" "%r")
149                  (match_operand:DF 2 "register_operand" "r")))]
150   ""
151   "FADD %0,%1,%2")
152
153 ;; Insn canonicalization *should* have removed the need for an integer
154 ;; in operand 2.
155 (define_insn "subdi3"
156   [(set (match_operand:DI 0 "register_operand" "=r,r")
157         (minus:DI (match_operand:DI 1 "mmix_reg_or_8bit_operand" "r,I")
158                   (match_operand:DI 2 "register_operand" "r,r")))]
159   ""
160   "@
161    SUBU %0,%1,%2
162    NEGU %0,%1,%2")
163
164 (define_insn "subdf3"
165   [(set (match_operand:DF 0 "register_operand" "=r")
166         (minus:DF (match_operand:DF 1 "register_operand" "r")
167                   (match_operand:DF 2 "register_operand" "r")))]
168   ""
169   "FSUB %0,%1,%2")
170
171 ;; FIXME: Should we define_expand and match 2, 4, 8 (etc) with shift (or
172 ;; %{something}2ADDU %0,%1,0)?  Hopefully GCC should still handle it, so
173 ;; we don't have to taint the machine description.  If results are bad
174 ;; enough, we may have to do it anyway.
175 (define_insn "muldi3"
176   [(set (match_operand:DI 0 "register_operand" "=r,r")
177         (mult:DI (match_operand:DI 1 "register_operand" "%r,r")
178                  (match_operand:DI 2 "mmix_reg_or_8bit_operand" "O,rI")))
179    (clobber (match_scratch:DI 3 "=X,z"))]
180   ""
181   "@
182    %m2ADDU %0,%1,%1
183    MULU %0,%1,%2")
184
185 (define_insn "muldf3"
186   [(set (match_operand:DF 0 "register_operand" "=r")
187         (mult:DF (match_operand:DF 1 "register_operand" "r")
188                  (match_operand:DF 2 "register_operand" "r")))]
189   ""
190   "FMUL %0,%1,%2")
191
192 (define_insn "divdf3"
193   [(set (match_operand:DF 0 "register_operand" "=r")
194         (div:DF (match_operand:DF 1 "register_operand" "r")
195                 (match_operand:DF 2 "register_operand" "r")))]
196   ""
197   "FDIV %0,%1,%2")
198
199 ;; FIXME: Is "frem" doing the right operation for moddf3?
200 (define_insn "moddf3"
201   [(set (match_operand:DF 0 "register_operand" "=r")
202         (mod:DF (match_operand:DF 1 "register_operand" "r")
203                 (match_operand:DF 2 "register_operand" "r")))]
204   ""
205   "FREM %0,%1,%2")
206
207 ;; FIXME: Should we define_expand for smin, smax, umin, umax using a
208 ;; nifty conditional sequence?
209
210 ;; FIXME: The cuter andn combinations don't get here, presumably because
211 ;; they ended up in the constant pool.  Check: still?
212 (define_insn "anddi3"
213   [(set (match_operand:DI 0 "register_operand" "=r,r")
214         (and:DI
215          (match_operand:DI 1 "register_operand" "%r,0")
216          (match_operand:DI 2 "mmix_reg_or_constant_operand" "rI,NT")))]
217   ""
218   "@
219    AND %0,%1,%2
220    %A2 %0,%V2")
221
222 (define_insn "iordi3"
223   [(set (match_operand:DI 0 "register_operand" "=r,r")
224         (ior:DI (match_operand:DI 1 "register_operand" "%r,0")
225                 (match_operand:DI 2 "mmix_reg_or_constant_operand" "rH,LS")))]
226   ""
227   "@
228    OR %0,%1,%2
229    %o2 %0,%v2")
230
231 (define_insn "xordi3"
232   [(set (match_operand:DI 0 "register_operand" "=r")
233         (xor:DI (match_operand:DI 1 "register_operand" "%r")
234                 (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))]
235   ""
236   "XOR %0,%1,%2")
237 \f
238 ;; FIXME:  When TImode works for other reasons (like cross-compiling from
239 ;; a 32-bit host), add back umulditi3 and umuldi3_highpart here.
240
241 ;; FIXME: Check what's really reasonable for the mod part.
242
243 ;; One day we might persuade GCC to expand divisions with constants the
244 ;; way MMIX does; giving the remainder the sign of the divisor.  But even
245 ;; then, it might be good to have an option to divide the way "everybody
246 ;; else" does.  Perhaps then, this option can be on by default.  Until
247 ;; then, we do division and modulus in a library function.
248
249 (define_insn "divmoddi4"
250   [(set (match_operand:DI 0 "register_operand" "=r")
251         (div:DI (match_operand:DI 1 "register_operand" "r")
252                 (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))
253    (set (match_operand:DI 3 "register_operand" "=y")
254         (mod:DI (match_dup 1) (match_dup 2)))]
255   ;; Do the library stuff later.
256   "TARGET_KNUTH_DIVISION"
257   "DIV %0,%1,%2")
258
259 (define_insn "udivmoddi4"
260   [(set (match_operand:DI 0 "register_operand" "=r")
261         (udiv:DI (match_operand:DI 1 "register_operand" "r")
262                  (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))
263    (set (match_operand:DI 3 "register_operand" "=y")
264         (umod:DI (match_dup 1) (match_dup 2)))]
265   ""
266   "DIVU %0,%1,%2")
267
268 (define_expand "divdi3"
269   [(parallel
270     [(set (match_operand:DI 0 "register_operand" "=&r")
271           (div:DI (match_operand:DI 1 "register_operand" "r")
272                   (match_operand:DI 2 "register_operand" "r")))
273      (clobber (scratch:DI))
274      (clobber (scratch:DI))])]
275   "! TARGET_KNUTH_DIVISION"
276   "")
277
278 ;; The %2-is-%1-case is there just to make sure things don't fail.  Could
279 ;; presumably happen with optimizations off; no evidence.
280 (define_insn "*divdi3_nonknuth"
281   [(set (match_operand:DI 0 "register_operand" "=&r,r")
282         (div:DI (match_operand:DI 1 "register_operand" "r,r")
283                 (match_operand:DI 2 "register_operand" "1,r")))
284    (clobber (match_scratch:DI 3 "=1,1"))
285    (clobber (match_scratch:DI 4 "=2,2"))]
286   "! TARGET_KNUTH_DIVISION"
287   "@
288    SETL %0,1
289    XOR $255,%1,%2\;NEGU %0,0,%2\;CSN %2,%2,%0\;NEGU %0,0,%1\;CSN %1,%1,%0\;\
290 DIVU %0,%1,%2\;NEGU %1,0,%0\;CSN %0,$255,%1")
291
292 (define_expand "moddi3"
293   [(parallel
294     [(set (match_operand:DI 0 "register_operand" "=&r")
295           (mod:DI (match_operand:DI 1 "register_operand" "r")
296                   (match_operand:DI 2 "register_operand" "r")))
297      (clobber (scratch:DI))
298      (clobber (scratch:DI))])]
299   "! TARGET_KNUTH_DIVISION"
300   "")
301
302 ;; The %2-is-%1-case is there just to make sure things don't fail.  Could
303 ;; presumably happen with optimizations off; no evidence.
304 (define_insn "*moddi3_nonknuth"
305   [(set (match_operand:DI 0 "register_operand" "=&r,r")
306         (mod:DI (match_operand:DI 1 "register_operand" "r,r")
307                 (match_operand:DI 2 "register_operand" "1,r")))
308    (clobber (match_scratch:DI 3 "=1,1"))
309    (clobber (match_scratch:DI 4 "=2,2"))]
310   "! TARGET_KNUTH_DIVISION"
311   "@
312    SETL %0,0
313    NEGU %0,0,%2\;CSN %2,%2,%0\;NEGU $255,0,%1\;CSN %1,%1,$255\;\
314 DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
315 \f
316 (define_insn "ashldi3"
317   [(set (match_operand:DI 0 "register_operand" "=r")
318         (ashift:DI
319          (match_operand:DI 1 "register_operand" "r")
320          (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))]
321   ""
322   "SLU %0,%1,%2")
323
324 (define_insn "ashrdi3"
325   [(set (match_operand:DI 0 "register_operand" "=r")
326         (ashiftrt:DI
327          (match_operand:DI 1 "register_operand" "r")
328          (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))]
329   ""
330   "SR %0,%1,%2")
331
332 (define_insn "lshrdi3"
333   [(set (match_operand:DI 0 "register_operand" "=r")
334         (lshiftrt:DI
335          (match_operand:DI 1 "register_operand" "r")
336          (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))]
337   ""
338   "SRU %0,%1,%2")
339
340 (define_insn "negdi2"
341   [(set (match_operand:DI 0 "register_operand" "=r")
342         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
343   ""
344   "NEGU %0,0,%1")
345
346 ;; FIXME: GCC should be able to synthesize this by itself as "0.0 - x".
347 (define_expand "negdf2"
348   [(set (match_operand:DF 0 "register_operand" "=r")
349         (minus:DF (match_dup 2)
350                 (match_operand:DF 1 "register_operand" "r")))]
351   ""
352   "operands[2] = force_reg (DFmode, CONST0_RTX (DFmode));")
353
354 ;; FIXME: define_expand for absdi2?
355
356 (define_insn "absdf2"
357   [(set (match_operand:DF 0 "register_operand" "=r")
358         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
359   ""
360   "ANDNH %0,#8000")
361
362 (define_insn "sqrtdf2"
363   [(set (match_operand:DF 0 "register_operand" "=r")
364         (sqrt:DF (match_operand:DF 1 "register_operand" "r")))]
365   ""
366   "FSQRT %0,%1")
367
368 ;; FIXME: define_expand for ffssi2? (not ffsdi2 since int is SImode).
369
370 (define_insn "one_cmpldi2"
371   [(set (match_operand:DI 0 "register_operand" "=r")
372         (not:DI (match_operand:DI 1 "register_operand" "r")))]
373   ""
374   "NOR %0,%1,0")
375 \f
376 ;; Since we don't have cc0, we do what is recommended in the manual;
377 ;; store away the operands for use in the branch, scc or movcc insn.
378 (define_expand "cmpdi"
379   [(match_operand:DI 0 "register_operand" "")
380    (match_operand:DI 1 "mmix_reg_or_8bit_operand" "")]
381   ""
382   "
383 {
384   mmix_compare_op0 = operands[0];
385   mmix_compare_op1 = operands[1];
386   DONE;
387 }")
388
389 (define_expand "cmpdf"
390   [(match_operand:DF 0 "register_operand" "")
391    (match_operand:DF 1 "register_operand" "")]
392   ""
393   "
394 {
395   mmix_compare_op0 = operands[0];
396   mmix_compare_op1 = operands[1];
397   DONE;
398 }")
399
400 ;; When the user-patterns expand, the resulting insns will match the
401 ;; patterns below.
402
403 ;; We can fold the signed-compare where the register value is
404 ;; already equal to (compare:CCTYPE (reg) (const_int 0)).
405 ;;  We can't do that at all for floating-point, due to NaN, +0.0
406 ;; and -0.0, and we can only do it for the non/zero test of
407 ;; unsigned, so that has to be done another way.
408 ;;  FIXME: Perhaps a peep2 changing CCcode to a new code, that
409 ;; gets folded here.
410 (define_insn "*cmpcc_folded"
411   [(set (match_operand:CC 0 "register_operand" "=r")
412         (compare:CC
413          (match_operand:DI 1 "register_operand" "r")
414          (const_int 0)))]
415   ;; FIXME: Can we test equivalence any other way?
416   ;; FIXME: Can we fold any other way?
417   "REGNO (operands[1]) == REGNO (operands[0])"
418   "%% folded: cmp %0,%1,0")
419
420 (define_insn "*cmpcc"
421   [(set (match_operand:CC 0 "register_operand" "=r")
422         (compare:CC
423          (match_operand:DI 1 "register_operand" "r")
424          (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))]
425   ""
426   "CMP %0,%1,%2")
427
428 (define_insn "*cmpu"
429   [(set (match_operand:CC_UNS 0 "register_operand" "=r")
430         (compare:CC_UNS
431          (match_operand:DI 1 "register_operand" "r")
432          (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI")))]
433   ""
434   "CMPU %0,%1,%2")
435
436 (define_insn "*fcmp"
437   [(set (match_operand:CC_FP 0 "register_operand" "=r")
438         (compare:CC_FP
439          (match_operand:DF 1 "register_operand" "r")
440          (match_operand:DF 2 "register_operand" "r")))]
441   ""
442   "FCMP%e0 %0,%1,%2")
443
444 ;; FIXME: for -mieee, add fsub %0,%1,%1\;fsub %0,%2,%2 before to
445 ;; make signalling compliant.
446 (define_insn "*feql"
447   [(set (match_operand:CC_FPEQ 0 "register_operand" "=r")
448         (compare:CC_FPEQ
449          (match_operand:DF 1 "register_operand" "r")
450          (match_operand:DF 2 "register_operand" "r")))]
451   ""
452   "FEQL%e0 %0,%1,%2")
453
454 (define_insn "*fun"
455   [(set (match_operand:CC_FUN 0 "register_operand" "=r")
456         (compare:CC_FUN
457          (match_operand:DF 1 "register_operand" "r")
458          (match_operand:DF 2 "register_operand" "r")))]
459   ""
460   "FUN%e0 %0,%1,%2")
461 \f
462 ;; In order to get correct rounding, we have to use SFLOT and SFLOTU for
463 ;; conversion.  They do not convert to SFmode; they convert to DFmode,
464 ;; with rounding as of SFmode.  They are not usable as is, but we pretend
465 ;; we have a single instruction but emit two.
466
467 ;; Note that this will (somewhat unexpectedly) create an inexact
468 ;; exception if rounding is necessary - has to be masked off in crt0?
469 (define_expand "floatdisf2"
470   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "=rm")
471                    (float:SF
472                     (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI")))
473               ;; Let's use a DI scratch, since SF don't generally get into
474               ;; registers.  Dunno what's best; it's really a DF, but that
475               ;; doesn't logically follow from operands in the pattern.
476               (clobber (match_scratch:DI 2 "=&r"))])]
477   ""
478   "
479 {
480   if (GET_CODE (operands[0]) != MEM)
481     {
482       rtx stack_slot;
483
484       /* FIXME: This stack-slot remains even at -O3.  There must be a
485          better way.  */
486       stack_slot
487         = validize_mem (assign_stack_temp (SFmode,
488                                            GET_MODE_SIZE (SFmode), 0));
489       emit_insn (gen_floatdisf2 (stack_slot, operands[1]));
490       emit_move_insn (operands[0], stack_slot);
491       DONE;
492     }
493 }")
494
495 (define_insn "*floatdisf2_real"
496   [(set (match_operand:SF 0 "memory_operand" "=m")
497         (float:SF
498          (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI")))
499    (clobber (match_scratch:DI 2 "=&r"))]
500   ""
501   "SFLOT %2,%1\;STSF %2,%0")
502
503 (define_expand "floatunsdisf2"
504   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "=rm")
505                    (unsigned_float:SF
506                     (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI")))
507               ;; Let's use a DI scratch, since SF don't generally get into
508               ;; registers.  Dunno what's best; it's really a DF, but that
509               ;; doesn't logically follow from operands in the pattern.
510               (clobber (scratch:DI))])]
511   ""
512   "
513 {
514   if (GET_CODE (operands[0]) != MEM)
515     {
516       rtx stack_slot;
517
518       /* FIXME: This stack-slot remains even at -O3.  Must be a better
519          way.  */
520       stack_slot
521         = validize_mem (assign_stack_temp (SFmode,
522                                            GET_MODE_SIZE (SFmode), 0));
523       emit_insn (gen_floatunsdisf2 (stack_slot, operands[1]));
524       emit_move_insn (operands[0], stack_slot);
525       DONE;
526     }
527 }")
528
529 (define_insn "*floatunsdisf2_real"
530   [(set (match_operand:SF 0 "memory_operand" "=m")
531         (unsigned_float:SF
532          (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI")))
533    (clobber (match_scratch:DI 2 "=&r"))]
534   ""
535   "SFLOTU %2,%1\;STSF %2,%0")
536
537 ;; Note that this will (somewhat unexpectedly) create an inexact
538 ;; exception if rounding is necessary - has to be masked off in crt0?
539 (define_insn "floatdidf2"
540   [(set (match_operand:DF 0 "register_operand" "=r")
541         (float:DF
542          (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI")))]
543   ""
544   "FLOT %0,%1")
545
546 (define_insn "floatunsdidf2"
547   [(set (match_operand:DF 0 "register_operand" "=r")
548         (unsigned_float:DF
549          (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI")))]
550   ""
551   "FLOTU %0,%1")
552
553 (define_insn "ftruncdf2"
554   [(set (match_operand:DF 0 "register_operand" "=r")
555         (fix:DF (match_operand:DF 1 "register_operand" "r")))]
556   ""
557   ;; ROUND_OFF
558   "FINT %0,1,%1")
559
560 ;; Note that this will (somewhat unexpectedly) create an inexact
561 ;; exception if rounding is necessary - has to be masked off in crt0?
562 (define_insn "fix_truncdfdi2"
563   [(set (match_operand:DI 0 "register_operand" "=r")
564         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "r"))))]
565   ""
566   ;; ROUND_OFF
567   "FIX %0,1,%1")
568
569 (define_insn "fixuns_truncdfdi2"
570   [(set (match_operand:DI 0 "register_operand" "=r")
571         (unsigned_fix:DI
572          (fix:DF (match_operand:DF 1 "register_operand" "r"))))]
573   ""
574   ;; ROUND_OFF
575   "FIXU %0,1,%1")
576
577 ;; It doesn't seem like it's possible to have memory_operand as a
578 ;; predicate here (testcase: libgcc2 floathisf).  FIXME:  Shouldn't it be
579 ;; possible to do that?  Bug in GCC?  Anyway, this used to be a simple
580 ;; pattern with a memory_operand predicate, but was split up with a
581 ;; define_expand with the old pattern as "anonymous".
582 ;; FIXME: Perhaps with SECONDARY_MEMORY_NEEDED?
583 (define_expand "truncdfsf2"
584   [(set (match_operand:SF 0 "memory_operand" "")
585         (float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
586   ""
587   "
588 {
589   if (GET_CODE (operands[0]) != MEM)
590     {
591       /* FIXME: There should be a way to say: 'put this in operands[0]
592          but *after* the expanded insn'.  */
593       rtx stack_slot;
594
595       /* There is no sane destination but a register here, if it wasn't
596          already MEM.  (It's too hard to get fatal_insn to work here.)  */
597       if (! REG_P (operands[0]))
598         internal_error (\"MMIX Internal: Bad truncdfsf2 expansion\");
599
600       /* FIXME: This stack-slot remains even at -O3.  Must be a better
601          way.  */
602       stack_slot
603         = validize_mem (assign_stack_temp (SFmode,
604                                            GET_MODE_SIZE (SFmode), 0));
605       emit_insn (gen_truncdfsf2 (stack_slot, operands[1]));
606       emit_move_insn (operands[0], stack_slot);
607       DONE;
608     }
609 }")
610
611 (define_insn "*truncdfsf2_real"
612   [(set (match_operand:SF 0 "memory_operand" "=m")
613         (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
614   ""
615   "STSF %1,%0")
616
617 ;; Same comment as for truncdfsf2.
618 (define_expand "extendsfdf2"
619   [(set (match_operand:DF 0 "register_operand" "=r")
620         (float_extend:DF (match_operand:SF 1 "memory_operand" "m")))]
621   ""
622   "
623 {
624   if (GET_CODE (operands[1]) != MEM)
625     {
626       rtx stack_slot;
627
628       /* There is no sane destination but a register here, if it wasn't
629          already MEM.  (It's too hard to get fatal_insn to work here.)  */
630       if (! REG_P (operands[0]))
631         internal_error (\"MMIX Internal: Bad extendsfdf2 expansion\");
632
633       /* FIXME: This stack-slot remains even at -O3.  There must be a
634          better way.  */
635       stack_slot
636         = validize_mem (assign_stack_temp (SFmode,
637                                            GET_MODE_SIZE (SFmode), 0));
638       emit_move_insn (stack_slot, operands[1]);
639       emit_insn (gen_extendsfdf2 (operands[0], stack_slot));
640       DONE;
641     }
642 }")
643
644 (define_insn "*extendsfdf2_real"
645   [(set (match_operand:DF 0 "register_operand" "=r")
646         (float_extend:DF (match_operand:SF 1 "memory_operand" "m")))]
647   ""
648   "LDSF %0,%1")
649 \f
650 ;; Neither sign-extend nor zero-extend are necessary; gcc knows how to
651 ;; synthesize using shifts or and, except with a memory source and not
652 ;; completely optimal.  FIXME: Actually, other bugs surface when those
653 ;; patterns are defined; fix later.
654
655 ;; There are no sane values with the bit-patterns of (int) 0..255 except
656 ;; 0 to use in movdfcc.
657
658 (define_expand "movdfcc"
659   [(set (match_operand:DF 0 "register_operand" "")
660         (if_then_else:DF
661          (match_operand 1 "comparison_operator" "")
662          (match_operand:DF 2 "mmix_reg_or_0_operand" "")
663          (match_operand:DF 3 "mmix_reg_or_0_operand" "")))]
664   ""
665   "
666 {
667   enum rtx_code code = GET_CODE (operands[1]);
668   rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0,
669                                      mmix_compare_op1);
670   if (cc_reg == NULL_RTX)
671     FAIL;
672   operands[1] = gen_rtx (code, VOIDmode, cc_reg, const0_rtx);
673 }")
674
675 (define_expand "movdicc"
676   [(set (match_operand:DI 0 "register_operand" "")
677         (if_then_else:DI
678          (match_operand 1 "comparison_operator" "")
679          (match_operand:DI 2 "mmix_reg_or_8bit_operand" "")
680          (match_operand:DI 3 "mmix_reg_or_8bit_operand" "")))]
681   ""
682   "
683 {
684   enum rtx_code code = GET_CODE (operands[1]);
685   rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0,
686                                      mmix_compare_op1);
687   if (cc_reg == NULL_RTX)
688     FAIL;
689   operands[1] = gen_rtx (code, VOIDmode, cc_reg, const0_rtx);
690 }")
691
692 ;; FIXME: Is this the right way to do "folding" of CCmode -> DImode?
693 (define_insn "*movdicc_real_foldable"
694   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
695         (if_then_else:DI
696          (match_operator 2 "mmix_foldable_comparison_operator"
697                          [(match_operand 3 "register_operand" "r,r,r,r")
698                           (const_int 0)])
699          (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI,0 ,rI,GM")
700          (match_operand:DI 4 "mmix_reg_or_8bit_operand" "0 ,rI,GM,rI")))]
701   ""
702   "@
703    CS%d2 %0,%3,%1
704    CS%D2 %0,%3,%4
705    ZS%d2 %0,%3,%1
706    ZS%D2 %0,%3,%4")
707
708 (define_insn "*movdicc_real"
709   [(set
710     (match_operand:DI 0 "register_operand"         "=r ,r ,r ,r")
711     (if_then_else:DI
712      (match_operator
713       2 "mmix_comparison_operator"
714       [(match_operand 3 "mmix_reg_cc_operand"       "r ,r ,r ,r")
715       (const_int 0)])
716      (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI,0 ,rI,GM")
717      (match_operand:DI 4 "mmix_reg_or_8bit_operand" "0 ,rI,GM,rI")))]
718   ""
719   "@
720    CS%d2 %0,%3,%1
721    CS%D2 %0,%3,%4
722    ZS%d2 %0,%3,%1
723    ZS%D2 %0,%3,%4")
724
725 (define_insn "*movdfcc_real_foldable"
726   [(set
727     (match_operand:DF 0 "register_operand"      "=r  ,r  ,r  ,r")
728     (if_then_else:DF
729      (match_operator
730       2 "mmix_foldable_comparison_operator"
731       [(match_operand 3 "register_operand"       "r  ,r  ,r  ,r")
732       (const_int 0)])
733      (match_operand:DF 1 "mmix_reg_or_0_operand" "rGM,0  ,rGM,GM")
734      (match_operand:DF 4 "mmix_reg_or_0_operand" "0  ,rGM,GM ,rGM")))]
735   ""
736   "@
737    CS%d2 %0,%3,%1
738    CS%D2 %0,%3,%4
739    ZS%d2 %0,%3,%1
740    ZS%D2 %0,%3,%4")
741
742 (define_insn "*movdfcc_real"
743   [(set
744     (match_operand:DF 0 "register_operand"      "=r  ,r  ,r  ,r")
745     (if_then_else:DF
746      (match_operator
747       2 "mmix_comparison_operator"
748       [(match_operand 3 "mmix_reg_cc_operand"    "r  ,r  ,r  ,r")
749       (const_int 0)])
750      (match_operand:DF 1 "mmix_reg_or_0_operand" "rGM,0  ,rGM,GM")
751      (match_operand:DF 4 "mmix_reg_or_0_operand" "0  ,rGM,GM ,rGM")))]
752   ""
753   "@
754    CS%d2 %0,%3,%1
755    CS%D2 %0,%3,%4
756    ZS%d2 %0,%3,%1
757    ZS%D2 %0,%3,%4")
758
759 ;; FIXME: scc patterns will probably help, I just skip them
760 ;; right now.  Revisit.
761 \f
762 (define_expand "beq"
763   [(set (pc)
764         (if_then_else (eq (match_dup 1) (const_int 0))
765                       (label_ref (match_operand 0 "" ""))
766                       (pc)))]
767   ""
768   "
769 {
770   operands[1]
771     = mmix_gen_compare_reg (EQ, mmix_compare_op0, mmix_compare_op1);
772 }")
773
774 (define_expand "bne"
775   [(set (pc)
776         (if_then_else (ne (match_dup 1) (const_int 0))
777                       (label_ref (match_operand 0 "" ""))
778                       (pc)))]
779   ""
780   "
781 {
782   operands[1]
783     = mmix_gen_compare_reg (NE, mmix_compare_op0, mmix_compare_op1);
784 }")
785
786 (define_expand "bgt"
787   [(set (pc)
788         (if_then_else (gt (match_dup 1) (const_int 0))
789                       (label_ref (match_operand 0 "" ""))
790                       (pc)))]
791   ""
792   "
793 {
794   operands[1]
795     = mmix_gen_compare_reg (GT, mmix_compare_op0, mmix_compare_op1);
796 }")
797
798 (define_expand "ble"
799   [(set (pc)
800         (if_then_else (le (match_dup 1) (const_int 0))
801                       (label_ref (match_operand 0 "" ""))
802                       (pc)))]
803   ""
804   "
805 {
806   operands[1]
807     = mmix_gen_compare_reg (LE, mmix_compare_op0, mmix_compare_op1);
808
809   /* The head comment of optabs.c:can_compare_p says we're required to
810      implement this, so we have to clean up the mess here. */
811   if (operands[1] == NULL_RTX)
812     {
813       /* FIXME: Watch out for sharing/unsharing of rtx:es.  */
814       emit_jump_insn ((*bcc_gen_fctn[(int) LT]) (operands[0]));
815       emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0]));
816       DONE;
817     }
818 }")
819
820 (define_expand "bge"
821   [(set (pc)
822         (if_then_else (ge (match_dup 1) (const_int 0))
823                       (label_ref (match_operand 0 "" ""))
824                       (pc)))]
825   ""
826   "
827 {
828   operands[1]
829     = mmix_gen_compare_reg (GE, mmix_compare_op0, mmix_compare_op1);
830
831   /* The head comment of optabs.c:can_compare_p says we're required to
832      implement this, so we have to clean up the mess here. */
833   if (operands[1] == NULL_RTX)
834     {
835       /* FIXME: Watch out for sharing/unsharing of rtx:es.  */
836       emit_jump_insn ((*bcc_gen_fctn[(int) GT]) (operands[0]));
837       emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0]));
838       DONE;
839     }
840 }")
841
842 (define_expand "blt"
843   [(set (pc)
844         (if_then_else (lt (match_dup 1) (const_int 0))
845                       (label_ref (match_operand 0 "" ""))
846                       (pc)))]
847   ""
848   "
849 {
850   operands[1]
851     = mmix_gen_compare_reg (LT, mmix_compare_op0, mmix_compare_op1);
852 }")
853
854 (define_expand "bgtu"
855   [(set (pc)
856         (if_then_else (gtu (match_dup 1) (const_int 0))
857                       (label_ref (match_operand 0 "" ""))
858                       (pc)))]
859   ""
860   "
861 {
862   operands[1]
863     = mmix_gen_compare_reg (GTU, mmix_compare_op0, mmix_compare_op1);
864 }")
865
866 (define_expand "bleu"
867   [(set (pc)
868         (if_then_else (leu (match_dup 1) (const_int 0))
869                       (label_ref (match_operand 0 "" ""))
870                       (pc)))]
871   ""
872   "
873 {
874   operands[1]
875     = mmix_gen_compare_reg (LEU, mmix_compare_op0, mmix_compare_op1);
876 }")
877
878 (define_expand "bgeu"
879   [(set (pc)
880         (if_then_else (geu (match_dup 1) (const_int 0))
881                       (label_ref (match_operand 0 "" ""))
882                       (pc)))]
883   ""
884   "
885 {
886   operands[1]
887     = mmix_gen_compare_reg (GEU, mmix_compare_op0, mmix_compare_op1);
888 }")
889
890 (define_expand "bltu"
891   [(set (pc)
892         (if_then_else (ltu (match_dup 1) (const_int 0))
893                       (label_ref (match_operand 0 "" ""))
894                       (pc)))]
895   ""
896   "
897 {
898   operands[1]
899     = mmix_gen_compare_reg (LTU, mmix_compare_op0, mmix_compare_op1);
900 }")
901
902 (define_expand "bunordered"
903   [(set (pc)
904         (if_then_else (unordered (match_dup 1) (const_int 0))
905                       (label_ref (match_operand 0 "" ""))
906                       (pc)))]
907   ""
908   "
909 {
910   operands[1]
911     = mmix_gen_compare_reg (UNORDERED, mmix_compare_op0, mmix_compare_op1);
912
913   if (operands[1] == NULL_RTX)
914     FAIL;
915 }")
916
917 (define_expand "bordered"
918   [(set (pc)
919         (if_then_else (ordered (match_dup 1) (const_int 0))
920                       (label_ref (match_operand 0 "" ""))
921                       (pc)))]
922   ""
923   "
924 {
925   operands[1]
926     = mmix_gen_compare_reg (ORDERED, mmix_compare_op0, mmix_compare_op1);
927 }")
928
929 ;; FIXME: we can emit an unordered-or-*not*-equal compare in one insn, but
930 ;; there's no RTL code for it.  Maybe revisit in future.
931
932 ;; FIXME: Odd/Even matchers?
933 (define_insn "*bCC_foldable"
934   [(set (pc)
935         (if_then_else
936          (match_operator 1 "mmix_foldable_comparison_operator"
937                          [(match_operand 2 "register_operand" "r")
938                           (const_int 0)])
939          (label_ref (match_operand 0 "" ""))
940          (pc)))]
941   ""
942   "%+B%d1 %2,%0")
943
944 (define_insn "*bCC"
945   [(set (pc)
946         (if_then_else
947          (match_operator 1 "mmix_comparison_operator"
948                          [(match_operand 2 "mmix_reg_cc_operand" "r")
949                           (const_int 0)])
950          (label_ref (match_operand 0 "" ""))
951          (pc)))]
952   ""
953   "%+B%d1 %2,%0")
954
955 (define_insn "*bCC_inverted_foldable"
956   [(set (pc)
957         (if_then_else
958          (match_operator 1 "mmix_foldable_comparison_operator"
959                          [(match_operand 2 "register_operand" "r")
960                           (const_int 0)])
961                       (pc)
962                       (label_ref (match_operand 0 "" ""))))]
963 ;; REVERSIBLE_CC_MODE is checked by mmix_foldable_comparison_operator.
964   ""
965   "%+B%D1 %2,%0")
966
967 (define_insn "*bCC_inverted"
968   [(set (pc)
969         (if_then_else
970          (match_operator 1 "mmix_comparison_operator"
971                          [(match_operand 2 "mmix_reg_cc_operand" "r")
972                           (const_int 0)])
973          (pc)
974          (label_ref (match_operand 0 "" ""))))]
975   "REVERSIBLE_CC_MODE (GET_MODE (operands[2]))"
976   "%+B%D1 %2,%0")
977 \f
978 (define_expand "call"
979   [(parallel [(call (match_operand:QI 0 "memory_operand" "")
980                     (match_operand 1 "general_operand" ""))
981               (use (match_operand 2 "general_operand" ""))
982               (clobber (match_dup 4))])
983    (set (match_dup 4) (match_dup 3))]
984   ""
985   "
986 {
987   /* Since the epilogue 'uses' the return address, and it is clobbered
988      in the call, and we set it back after every call (all but one setting
989      will be optimized away), integrity is maintained.  */
990   operands[3]
991     = get_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
992
993   /* FIXME: There's a bug in gcc which causes NULL to be passed as
994      operand[2] when we get out of registers, which later confuses gcc.
995      Work around it by replacing it with const_int 0.  Possibly documentation
996      error too.  */
997   if (operands[2] == NULL_RTX)
998     operands[2] = const0_rtx;
999
1000   operands[4] = gen_rtx_REG (DImode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
1001 }")
1002
1003 (define_expand "call_value"
1004   [(parallel [(set (match_operand 0 "" "")
1005                    (call (match_operand:QI 1 "memory_operand" "")
1006                          (match_operand 2 "general_operand" "")))
1007               (use (match_operand 3 "general_operand" ""))
1008               (clobber (match_dup 5))])
1009    (set (match_dup 5) (match_dup 4))]
1010   ""
1011   "
1012 {
1013   /* Since the epilogue 'uses' the return address, and it is clobbered
1014      in the call, and we set it back after every call (all but one setting
1015      will be optimized away), integrity is maintained.  */
1016   operands[4]
1017     = get_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
1018
1019   /* FIXME: See 'call'.  */
1020   if (operands[3] == NULL_RTX)
1021     operands[3] = const0_rtx;
1022
1023   /* FIXME: Documentation bug: operands[3] (operands[2] for 'call') is the
1024      *next* argument register, not the number of arguments in registers.
1025      (There used to be code here where that mattered.)  */
1026
1027   operands[5] = gen_rtx_REG (DImode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
1028 }")
1029
1030 ;; Don't use 'p' here.  A 'p' must stand first in constraints, or reload
1031 ;; messes up, not registering the address for reload.  Several C++
1032 ;; test-cases, including g++.brendan/crash40.C.  FIXME: This is arguably a
1033 ;; bug in gcc.  Note line ~2612 in reload.c, that does things on the
1034 ;; condition <<else if (constraints[i][0] == 'p')>> and the comment on
1035 ;; ~3017 that says:
1036 ;; <<   case 'p':
1037 ;;           /* All necessary reloads for an address_operand
1038 ;;              were handled in find_reloads_address.  */>>
1039 ;; Sorry, I have not dug deeper.  If symbolic addresses are used
1040 ;; rarely compared to addresses in registers, disparaging the
1041 ;; first ("p") alternative by adding ? in the first operand
1042 ;; might do the trick.  We define 'U' as a synonym to 'p', but without the
1043 ;; caveats (and very small advantages) of 'p'.
1044 (define_insn "*call_real"
1045   [(call (mem:QI
1046           (match_operand:DI 0 "mmix_symbolic_or_address_operand" "s,rU"))
1047          (match_operand 1 "" ""))
1048    (use (match_operand 2 "" ""))
1049    (clobber (reg:DI MMIX_rJ_REGNUM))]
1050   ""
1051   "@
1052    PUSHJ $%p2,%0
1053    PUSHGO $%p2,%a0")
1054
1055 (define_insn "*call_value_real"
1056   [(set (match_operand 0 "register_operand" "=r,r")
1057         (call (mem:QI
1058                (match_operand:DI 1 "mmix_symbolic_or_address_operand" "s,rU"))
1059               (match_operand 2 "" "")))
1060   (use (match_operand 3 "" ""))
1061   (clobber (reg:DI MMIX_rJ_REGNUM))]
1062   ""
1063   "@
1064    PUSHJ $%p3,%1
1065    PUSHGO $%p3,%a1")
1066
1067 ;; I hope untyped_call and untyped_return are not needed for MMIX.
1068 ;; Users of Objective C will notice.
1069
1070 ;; FIXME:  Add "return" pattern where the epilogue is just "pop
1071 ;; 0,0" or similar.
1072
1073 (define_insn "nop"
1074   [(const_int 0)]
1075   ""
1076   "SWYM 0,0,0")
1077
1078 (define_insn "jump"
1079   [(set (pc) (label_ref (match_operand 0 "" "")))]
1080   ""
1081   "JMP %0")
1082
1083 (define_insn "indirect_jump"
1084   [(set (pc) (match_operand 0 "address_operand" "p"))]
1085   ""
1086   "GO $255,%a0")
1087
1088 ;; FIXME: This is just a jump, and should be expanded to one.
1089 (define_insn "tablejump"
1090   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
1091    (use (label_ref (match_operand 1 "" "")))]
1092   ""
1093   "GO $255,%a0")
1094
1095 ;; The only peculiar thing is that the register stack has to be unwound at
1096 ;; nonlocal_goto_receiver.  At each function that has a nonlocal label, we
1097 ;; save at function entry the location of the "alpha" register stack
1098 ;; pointer, rO, in a stack slot known to that function (right below where
1099 ;; the frame-pointer would be located).
1100 ;; In the nonlocal goto receiver, we unwind the register stack by a series
1101 ;; of "pop 0,0" until rO equals the saved value.  (If it goes lower, we
1102 ;; should call abort.)
1103 (define_expand "nonlocal_goto_receiver"
1104   [(parallel [(unspec_volatile [(match_dup 0)] 1)
1105               (clobber (scratch:DI))
1106               (clobber (reg:DI MMIX_rJ_REGNUM))])
1107    (set (reg:DI MMIX_rJ_REGNUM) (match_dup 1))]
1108   ""
1109   "
1110 {
1111   rtx tem
1112     = validize_mem (gen_rtx_MEM (Pmode,
1113                                  plus_constant (frame_pointer_rtx, -24)));
1114   operands[0] = XEXP (tem, 0);
1115   operands[1]
1116     = get_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
1117
1118   /* Mark this function as containing a landing-pad.  */
1119   cfun->machine->has_landing_pad = 1;
1120 }")
1121
1122 ;; FIXME: Do we need to keep this in memory?  Can GCC counter our
1123 ;; expectations and use saved registers to keep the slot address in,
1124 ;; "across" the exception or goto?  Anyway, we need to make sure the value
1125 ;; ends up in a non-local register, so best is to load it ourselves.
1126 (define_insn "*nonlocal_goto_receiver_expanded"
1127   [(unspec_volatile [(match_operand:DI 0 "address_operand" "p")] 1)
1128    (clobber (match_scratch:DI 1 "=&r"))
1129    (clobber (reg:DI MMIX_rJ_REGNUM))]
1130   ""
1131   "GETA $255,0f\;PUT rJ,$255\;LDOU $255,%a0\n\
1132 0:\;GET %1,rO\;CMPU %1,%1,$255\;BNP %1,1f\;POP 0,0\n1:")
1133 \f
1134 (define_insn "*Naddu"
1135   [(set (match_operand:DI 0 "register_operand" "=r")
1136         (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "r")
1137                           (match_operand:DI 2 "const_int_operand" "n"))
1138                  (match_operand:DI 3 "mmix_reg_or_8bit_operand" "rI")))]
1139   "GET_CODE (operands[2]) == CONST_INT
1140    && (INTVAL (operands[2]) == 2
1141        || INTVAL (operands[2]) == 4
1142        || INTVAL (operands[2]) == 8
1143        || INTVAL (operands[2]) == 16)"
1144   "%2ADDU %0,%1,%3")
1145
1146 (define_insn "*andn"
1147   [(set (match_operand:DI 0 "register_operand" "=r")
1148         (and:DI
1149          (not:DI (match_operand:DI 1 "mmix_reg_or_8bit_operand" "rI"))
1150          (match_operand:DI 2 "register_operand" "r")))]
1151   ""
1152   "ANDN %0,%2,%1")
1153
1154 (define_insn "*nand"
1155   [(set (match_operand:DI 0 "register_operand" "=r")
1156         (ior:DI
1157          (not:DI (match_operand:DI 1 "register_operand" "%r"))
1158          (not:DI (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI"))))]
1159   ""
1160   "NAND %0,%1,%2")
1161
1162 (define_insn "*nor"
1163   [(set (match_operand:DI 0 "register_operand" "=r")
1164         (and:DI
1165          (not:DI (match_operand:DI 1 "register_operand" "%r"))
1166          (not:DI (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI"))))]
1167   ""
1168   "NOR %0,%1,%2")
1169
1170 (define_insn "*nxor"
1171   [(set (match_operand:DI 0 "register_operand" "=r")
1172         (not:DI
1173          (xor:DI (match_operand:DI 1 "register_operand" "%r")
1174                  (match_operand:DI 2 "mmix_reg_or_8bit_operand" "rI"))))]
1175   ""
1176   "NXOR %0,%1,%2")
1177
1178 (define_insn "sync_icache"
1179   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")
1180                      (match_operand:DI 1 "const_int_operand" "I")] 0)]
1181   ""
1182   "SYNCID %1,%0")
1183
1184 ;; Local Variables:
1185 ;; mode: lisp
1186 ;; indent-tabs-mode: t
1187 ;; End: