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