OSDN Git Service

* desc-cpu.scm (cgen-desc.h): Don't print virtual enums.
[pf3gnuchains/pf3gnuchains4x.git] / cgen / rtx-funcs.scm
1 ; Standard RTL functions.
2 ; Copyright (C) 2000, 2009, 2010 Red Hat, Inc.
3 ; This file is part of CGEN.
4 ; See file COPYING.CGEN for details.
5
6 ; THIS FILE CONTAINS ONE BIG FUNCTION: def-rtx-funcs.
7 ;
8 ; It is ok for this file to use procs "internal" to rtl.scm.
9 ;
10 ; Each rtx functions has two leading operands: &options, &mode;
11 ; though `&mode' may be spelled differently.
12 ; The "&" prefix is to indicate that the parsing of these operands is handled
13 ; differently.  They are optional and are written with leading colons
14 ; (e.g. :SI).  The leading ":" is to help the parser - all leading optional
15 ; operands begin with ":".  The order of the arguments is &options then &mode
16 ; though there is no imposed order in written RTL.
17
18 (define (def-rtx-funcs)
19
20 ; Do not change the indentation here.
21 (let
22 (
23  ; These are defined in rtl.scm.
24  (drn define-rtx-node)
25  (drsn define-rtx-syntax-node)
26  (dron define-rtx-operand-node)
27  (drmn define-rtx-macro-node)
28 )
29
30 ; The reason for the odd indenting above is so that emacs begins indenting the
31 ; following code at column 1.
32 \f
33 ; Error reporting.
34 ; MODE is present for use in situations like non-VOID mode cond's.
35 ; The code will expect the mode to be compatible even though `error'
36 ; "doesn't return".  A small concession for simpler code.
37
38 (drn (error &options &mode message)
39      #f
40      (OPTIONS VOIDORNUMMODE STRING) (NA NA NA)
41      MISC
42      (estate-error *estate* "error in rtl" message)
43 )
44
45 ; Enums
46 ; Default mode is INT.
47
48 (drn (enum &options &mode enum-name)
49      #f
50      (OPTIONS ANYINTMODE SYMBOL) (NA NA NA) ;; ??? s/SYMBOL/ENUM-NAME/ ?
51      ARG
52      ;; When computing a value, return the enum's value.
53      ;; Canonicalization should have already caught bad values.
54      (car (enum-lookup-val enum-name))
55 )
56
57 ; Instruction fields
58 ; These are used in the encode/decode specs of other ifields as well as in
59 ; instruction semantics.
60 ; Ifields are normally specified by name, but they are subsequently wrapped
61 ; in this.
62
63 (dron (ifield &options &mode ifld-name)
64       #f
65       (OPTIONS ANYNUMMODE SYMBOL) (NA NA NA) ;; ??? s/SYMBOL/IFIELD-NAME/ ?
66       ARG
67       (let ((f (current-ifld-lookup ifld-name)))
68         (make <operand> (obj-location f)
69               ifld-name (string-append ifld-name " used as operand")
70               (atlist-cons (bool-attr-make 'SEM-ONLY #t)
71                            (obj-atlist f))
72               (obj:name (ifld-hw-type f))
73               (obj:name (ifld-mode f))
74               (make <hw-index> 'anonymous 'ifield (ifld-mode f) f)
75               nil #f #f))
76 )
77
78 ; Specify an operand.
79 ; Operands are normally specified by name, but they are subsequently wrapped
80 ; in this.
81
82 (dron (operand &options &mode op-name)
83       #f
84       (OPTIONS ANYNUMMODE SYMBOL) (NA NA NA) ;; ??? s/SYMBOL/OPERAND-NAME/ ?
85       ARG
86       (current-op-lookup op-name)
87 )
88
89 ; Operand naming/numbering.
90 ; Operands are given names so that the operands as used in the semantics can
91 ; be matched with arguments of function units.  With good name choices of
92 ; operands and function unit arguments, this is rarely necessary, but
93 ; sometimes it is.
94 ;
95 ; ??? This obfuscates the semantic code a fair bit.  Another way to do this
96 ; would be to add new elements to <insn> to specify operands outside of
97 ; the semantic code.  E.g.
98 ; (define-insn ...
99 ;   (inputs (in-gr1 src1) (in-gr2 src2))
100 ;   (outputs (out-pc pc) (out-gr dr) (reg-14 (reg WI h-gr 14)))
101 ;   ...)
102 ; The intent here is to continue to allow the semantic code to use names
103 ; of operands, and not overly complicate the input/output description.
104 ;
105 ; In instructions, operand numbers are recorded as well, to implement
106 ; profiling and result writeback of parallel insns.
107
108 ; Rename operand VALUE to NEW-NAME.
109 ; VALUE is an expression whose result is an object of type <operand>.
110 ; It can be the name of an existing operand.
111 ; ??? Might also support numbering by allowing NEW-NAME to be a number.
112
113 (drsn (name &options &mode new-name value)
114       #f
115       (OPTIONS ANYNUMMODE SYMBOL RTX) (NA NA NA ANY)
116       ARG
117       ;; FIXME: s/DFLT/&mode/ ?
118       (let ((result (object-copy (rtx-get 'DFLT value))))
119         (op:set-sem-name! result new-name)
120         result)
121 )
122
123 ; Operands are generally compiled to an internal form first.
124 ; There is a fair bit of state associated with them, and it's easier to
125 ; work with an object than source [which might get fairly complicated if
126 ; it expresses all the state].
127 ; Compiled operands are wrapped in this so that they still look like rtx.
128
129 (dron (xop &options &mode object)
130       #f
131       (OPTIONS ANYNUMMODE OBJECT) (NA NA NA) ;; ??? s/OBJECT/OPERAND/ ?
132       ARG
133       object
134 )
135
136 ;(dron (opspec: &options &mode op-name op-num hw-ref attrs)
137 ;      (OPTIONS ANYNUMMODE SYMBOL NUMBER RTX ATTRS) (NA NA NA NA ANY NA)
138 ;      ARG
139 ;      (let ((opval (rtx-eval-with-estate hw-ref (mode:lookup &mode) *estate*)))
140 ;       (assert (operand? opval))
141 ;       ; Set the specified mode, ensuring it's ok.
142 ;       ; This also makes a copy as we don't want to modify predefined
143 ;       ; operands.
144 ;       (let ((operand (op:new-mode opval mode)))
145 ;         (op:set-sem-name! operand op-name)
146 ;         (op:set-num! operand op-num)
147 ;         (op:set-cond?! operand (attr-value attrs 'COND-REF #f))
148 ;         operand))
149 ;)
150
151 ; Specify a reference to a local variable.
152 ; Local variables are normally specified by name, but they are subsequently
153 ; wrapped in this.
154
155 (dron (local &options &mode local-name)
156       #f
157       (OPTIONS ANYNUMMODE SYMBOL) (NA NA NA) ;; ??? s/SYMBOL/LOCAL-NAME/ ?
158       ARG
159       (rtx-temp-lookup (tstate-env *tstate*) local-name)
160 )
161
162 ; FIXME: This doesn't work.  See s-operand.
163 ;(define (s-dup estate op-name)
164 ;  (if (not (insn? (estate-owner estate)))
165 ;      (error "dup: not processing an insn"))
166 ;  (vector-ref (insn:operands (current-current-context))
167 ;              (op:lookup-num (insn:operands (estate-owner estate)) op-name))
168 ;)
169 ;
170 ; ??? Since operands are given names and not numbers this isn't currently used.
171 ;
172 ;(drsn (dup &options &mode op-name)
173 ;     #f
174 ;     (OPTIONS ANYNUMMODE SYMBOL) (NA NA NA)
175 ;     ;(s-dup *estate* op-name)
176 ;     (begin
177 ;       (if (not (insn? (estate-owner *estate*)))
178 ;          (error "dup: not processing an insn"))
179 ;       (vector-ref (insn:operands (estate-owner *estate*))
180 ;                  (op:lookup-num (insn:operands (estate-owner *estate*)) op-name)))
181 ;     #f
182 ;)
183
184 ; Returns non-zero if operand NAME was referenced (read if input operand
185 ; and written if output operand).
186 ; ??? What about input/output operands.
187
188 (drsn (ref &options &mode name)
189       BI
190       (OPTIONS BIMODE SYMBOL) (NA NA NA) ;; ??? s/SYMBOL/OPERAND-NAME/ ?
191       ARG
192       #f
193 )
194
195 ; Return the index of an operand.
196 ; For registers this is the register number.
197 ; ??? Mode handling incomplete, this doesn't handle mem, which it could.
198 ; Until then we fix the mode of the result to INT.
199
200 (dron (index-of &options &mode op-rtx)
201       INT
202       (OPTIONS INTMODE RTX) (NA NA ANY)
203       ARG
204       ;; FIXME: s/DFLT/&mode/ ?
205       (let* ((operand (rtx-eval-with-estate op-rtx DFLT *estate*))
206              (f (hw-index:value (op:index operand)))
207              (f-name (obj:name f)))
208         (make <operand> (if (source-ident? f) (obj-location f) #f)
209               f-name f-name
210               (atlist-cons (bool-attr-make 'SEM-ONLY #t)
211                            (obj-atlist f))
212               (obj:name (ifld-hw-type f))
213               (obj:name (ifld-mode f))
214               (make <hw-index> 'anonymous
215                     'ifield
216                     (ifld-mode f)
217                     ; (send (op:type op) 'get-index-mode)
218                     f)
219               nil #f #f))
220 )
221
222 ; Same as index-of, but improves readability for registers.
223
224 (drmn (regno reg)
225       (list 'index-of reg)
226 )
227 \f
228 ; Hardware elements.
229
230 ; Describe a random hardware object.
231 ; If INDX is missing, assume the element is a scalar.  We pass 0 so s-hw
232 ; doesn't have to unpack the list that would be passed if it were defined as
233 ; (hw mode hw-name . indx).  This is an internal implementation detail
234 ; and thus harmless to the description language.
235 ; These are implemented as syntax nodes as we must pass INDX to `s-hw'
236 ; unevaluated.
237 ; ??? Not currently supported.  Not sure whether it should be.
238 ;(drsn (hw &options &mode hw-elm . indx-sel)
239 ;      (OPTIONS ANYNUMMODE SYMBOL . RTX) (NA NA NA . INT)
240 ;      ARG
241 ;      (let ((indx (if (pair? indx-sel) (car indx-sel) 0))
242 ;            (selector (if (and (pair? indx-sel) (pair? (cdr indx-sel)))
243 ;                          (cadr indx-sel)
244 ;                          hw-selector-default))))
245 ;      (s-hw *estate* mode hw-elm indx selector)
246 ;)
247
248 ; Register accesses.
249 ; INDX-SEL is an optional index and possible selector.
250 (dron (reg &options &mode hw-elm . indx-sel)
251       #f
252       (OPTIONS ANYNUMMODE SYMBOL . RTX) (NA NA NA . INT) ;; ??? s/SYMBOL/HW-NAME/ ?
253       ARG
254       (let ((indx (if (pair? indx-sel) (car indx-sel) 0))
255             (selector (if (and (pair? indx-sel) (pair? (cdr indx-sel)))
256                           (cadr indx-sel)
257                           hw-selector-default)))
258         (s-hw *estate* mode hw-elm indx selector))          
259 )
260
261 ; A raw-reg bypasses the getter/setter stuff.  It's usually used in
262 ; getter/setter definitions.
263
264 (dron (raw-reg &options &mode hw-elm . indx-sel)
265       #f
266       (OPTIONS ANYNUMMODE SYMBOL . RTX) (NA NA NA . INT) ;; ??? s/SYMBOL/HW-NAME/ ?
267       ARG
268       (let ((indx (if (pair? indx-sel) (car indx-sel) 0))
269             (selector (if (and (pair? indx-sel) (pair? (cdr indx-sel)))
270                           (cadr indx-sel)
271                           hw-selector-default)))
272         (let ((result (s-hw *estate* mode hw-elm indx selector)))
273           (obj-cons-attr! result (bool-attr-make 'RAW #t))
274           result))
275 )
276
277 ; Memory accesses.
278 (dron (mem &options &mode addr . sel)
279       #f
280       (OPTIONS EXPLNUMMODE RTX . RTX) (NA NA AI . INT)
281       ARG
282       (s-hw *estate* mode 'h-memory addr
283             (if (pair? sel) (car sel) hw-selector-default))
284 )
285 \f
286 ; Instruction execution support.
287 ; There are no jumps, per se.  A jump is a set of `pc'.
288
289 ; The program counter.
290 ; ??? Hmmm... needed?  The pc is usually specified as `pc' which is shorthand
291 ; for (operand pc).
292 ;(dron (pc) () () ARG s-pc)
293
294 ; Fetch bytes from the instruction stream of size MODE.
295 ; FIXME: Later need to augment this by passing an indicator to the mem-fetch
296 ; routines that we're doing an ifetch.
297 ; ??? wip!
298
299 (drmn (ifetch mode pc)
300       (list 'mem mode pc) ; hw-selector-ispace
301 )
302
303 ; NUM is the instruction number.  Generally it is zero but if more than one
304 ; insn is decoded at a time, it is non-zero.  This is used, for example, to
305 ; index into the scache [as an offset from the first insn].
306 ; ??? wip!
307
308 (drmn (decode mode pc insn num)
309       (list 'c-call mode 'EXTRACT pc insn num)
310 )
311
312 ; NUM is the same number passed to `decode'.
313 ; ??? wip!
314
315 (drmn (execute mode num)
316       (list 'c-call mode 'EXECUTE num)
317 )
318 \f
319 ; Control Transfer Instructions
320
321 ; Sets of pc are handled like other sets so there are no branch rtx's.
322
323 ; Indicate there are N delay slots in the processing of RTX.
324 ; N is a `const' node.
325 ; The mode of the result is the mode of RTX.
326 ; ??? wip!
327
328 (drn (delay &options &mode n rtx)
329      #f
330      (OPTIONS VOIDORNUMMODE RTX RTX) (NA NA INT MATCHEXPR)
331      MISC
332      #f ; (s-sequence *estate* VOID '() rtx) ; wip!
333 )
334
335 ; Annul the following insn if YES? is non-zero.
336 ; PC is the address of the annuling insn.
337 ; The target is required to define SEM_ANNUL_INSN.
338 ; ??? wip!
339
340 (drmn (annul yes?)
341       ; The pc reference here is hidden in c-code to not generate a spurious
342       ; pc input operand.
343       (list 'c-call 'VOID "SEM_ANNUL_INSN" (list 'c-code 'IAI "pc") yes?)
344 )
345
346 ; Skip the following insn if YES? is non-zero.
347 ; The target is required to define SEM_SKIP_INSN.
348 ; ??? This is similar to annul.  Deletion of one of them defered.
349 ; ??? wip!
350
351 (drn (skip &options &mode yes?)
352      VOID
353      (OPTIONS VOIDMODE RTX) (NA NA INT)
354      MISC
355      #f
356 )
357 \f
358 ; Attribute support.
359
360 ; Return a boolean indicating if attribute named ATTR is VALUE in OWNER.
361 ; If VALUE is a list, return "true" if ATTR is any of the listed values.
362 ; ??? Don't yet support !VALUE.
363 ; OWNER is the result of either (current-insn) or (current-mach)
364 ; [note that canonicalization will turn them into
365 ; (current-{insn,mach} () DFLT)].
366 ; The result is always of mode BI.
367 ; FIXME: wip
368 ;
369 ; This is a syntax node so the args are not pre-evaluated.
370 ; We just want the symbols.
371 ; FIXME: Hmmm... it currently isn't a syntax node.
372
373 (drn (eq-attr &options &mode owner attr value)
374      BI
375       (OPTIONS BIMODE RTX SYMBOL SYMORNUM) (NA NA ANY NA NA)
376       MISC
377       (let ((atval (if owner
378                        (obj-attr-value owner attr)
379                        (attr-lookup-default attr #f))))
380         (if (list? value)
381             (->bool (memq atval value))
382             (eq? atval value)))
383 )
384
385 ; Get the value of attribute ATTR-NAME, expressable as an integer.
386 ; OBJ is the result of either (current-insn) or (current-mach).
387 ; Note that canonicalization will turn them into
388 ; (current-{insn,mach} () {INSN,MACH}MODE).
389 ; FIXME:wip
390 ; This uses INTMODE because we can't otherwise determine the
391 ; mode of the result (if elided).
392
393 (drn (int-attr &options &mode obj attr-name)
394      #f
395      (OPTIONS INTMODE RTX SYMBOL) (NA NA ANY NA)
396      MISC
397      #f
398 )
399
400 ;; Deprecated alias for int-attr.
401
402 (drmn (attr arg1 . rest)
403       (cons 'int-attr (cons arg1 rest))
404 )
405
406 ; Same as `quote', for use in attributes cus "quote" sounds too jargonish.
407 ; [Ok, not a strong argument for using "symbol", but so what?]
408
409 (drsn (symbol &options &mode name)
410       SYM
411       (OPTIONS SYMMODE SYMBOL) (NA NA NA)
412       ARG
413       name
414 )
415
416 ; Return the current instruction.
417
418 (drn (current-insn &options &mode)
419      INSN
420      (OPTIONS INSNMODE) (NA NA)
421      MISC
422      (let ((obj (estate-owner *estate*)))
423        (if (not (insn? obj))
424            (error "current context not an insn"))
425        obj)
426 )
427
428 ; Return the currently selected machine.
429 ; This can either be a compile-time or run-time value.
430
431 (drn (current-mach &options &mode)
432      MACH
433      (OPTIONS MACHMODE) (NA NA)
434      MISC
435      -rtx-current-mach
436 )
437 \f
438 ; Constants.
439
440 ; FIXME: Need to consider 64 bit hosts.
441 (drn (const &options &mode c)
442      #f
443      (OPTIONS ANYNUMMODE NUMBER) (NA NA NA)
444      ARG
445      ; When computing a value, just return the constant unchanged.
446      c
447 )
448 \f
449 ; Large mode support.
450
451 ; Combine smaller modes into a larger one.
452 ; Arguments are specified most significant to least significant.
453 ; ??? Not all of the combinations are supported in the simulator.
454 ; They'll get added as necessary.
455 (drn (join &options &out-mode in-mode arg1 . arg-rest)
456      #f
457      (OPTIONS ANYNUMMODE ANYNUMMODE RTX . RTX) (NA NA NA ANY . ANY)
458      MISC
459      ; FIXME: Ensure correct number of args for in/out modes.
460      ; FIXME: Ensure compatible modes.
461      #f
462 )
463
464 ; GCC's subreg.
465 ; Called subword 'cus it's not exactly subreg.
466 ; Word numbering is word-order dependent.
467 ; Word number 0 is the most significant word if big-endian-words.
468 ; Word number 0 is the least significant word if little-endian-words.
469 ; ??? GCC plans to switch to SUBREG_BYTE.  Keep an eye out for the switch
470 ; (which is extensive so probably won't happen anytime soon).
471 ; MODE is the mode of the result, not operand0.
472 ;
473 ; The mode spec of operand0 use to be MATCHEXPR, but subword is not a normal rtx.
474 ; The mode of operand0 is not necessarily the same as the mode of the result,
475 ; and code which analyzes it would otherwise use the result mode (specified by
476 ; `&mode') for the mode of operand0.
477
478 (drn (subword &options &mode value word-num)
479      #f
480      (OPTIONS ANYNUMMODE RTX RTX) (NA NA ANY INT)
481      ARG
482      #f
483 )
484
485 ; ??? The split and concat stuff is just an experiment and should not be used.
486 ; What's there now is just "thoughts put down on paper."
487
488 (drmn (split split-mode in-mode di)
489       ; FIXME: Ensure compatible modes
490       ;(list 'c-raw-call 'BLK (string-append "SPLIT" in-mode split-mode) di)
491       '(const 0)
492 )
493
494 (drmn (concat modes arg1 . arg-rest)
495       ; FIXME: Here might be the place to ensure
496       ; (= (length modes) (length (cons arg1 arg-rest))).
497       ;(cons 'c-raw-call (cons modes (cons "CONCAT" (cons arg1 arg-rest))))
498       '(const 0)
499 )
500 \f
501 ; Support for explicit C code.
502 ; ??? GCC RTL calls this "unspec" which is arguably a more application
503 ; independent name.
504
505 (drn (c-code &options &mode text)
506      #f
507      (OPTIONS ANYCEXPRMODE STRING) (NA NA NA)
508      UNSPEC
509      #f
510 )
511
512 ; Invoke C functions passing them arguments from the semantic code.
513 ; The arguments are passed as is, no conversion is done here.
514 ; Usage is:
515 ;           (c-call mode name arg1 arg2 ...)
516 ; which is converted into a C function call:
517 ;           name (current_cpu, arg1, arg2, ...)
518 ; MODE is the mode of the result.
519 ; If it is VOID this call is a statement and ';' is appended.
520 ; Otherwise it is part of an expression.
521
522 (drn (c-call &options &mode name . args)
523      #f
524      (OPTIONS ANYCEXPRMODE STRING . RTX) (NA NA NA . ANY)
525      UNSPEC
526      #f
527 )
528
529 ; Same as c-call but without implicit first arg of `current_cpu'.
530
531 (drn (c-raw-call &options &mode name . args)
532      #f
533      (OPTIONS ANYCEXPRMODE STRING . RTX) (NA NA NA . ANY)
534      UNSPEC
535      #f
536 )
537 \f
538 ; Set/get/miscellaneous
539
540 (drn (nop &options &mode)
541      VOID
542      (OPTIONS VOIDMODE) (NA NA)
543      MISC
544      #f
545 )
546
547 ; Clobber - mark an object as modified without explaining why or how.
548
549 (drn (clobber &options &mode object)
550      VOID
551      (OPTIONS VOIDORNUMMODE RTX) (NA NA MATCHEXPR)
552      MISC
553      #f
554 )
555
556 ; The `set' rtx.
557 ; MODE is the mode of DST.  If DFLT, use DST's default mode.
558 ; The mode of the result is always VOID.
559 ;
560 ; ??? It might be more consistent to rename set -> set-trace, but that's
561 ; too wordy.  The `set' rtx is the normal one and we want the normal one to
562 ; be the verbose one (prints result tracing messages).  `set-quiet' is the
563 ; atypical one, it doesn't print tracing messages.  It may also turn out that
564 ; a different mechanism (rather than the name "set-quiet") is used some day.
565 ; One way would be to record the "quietness" state with the traversal state and
566 ; use something like (with-quiet (set foo bar)) akin to with-output-to-string
567 ; in Guile.
568 ;
569 ; i.e. set -> gen-set-trace
570 ;      set-quiet -> gen-set-quiet
571 ;
572 ; ??? One might want a `!' suffix as in `set!', but methinks that's following
573 ; Scheme too closely.
574
575 (drn (set &options &mode dst src)
576      VOID
577      (OPTIONS ANYNUMMODE SETRTX RTX) (NA NA MATCHEXPR MATCH2)
578      SET
579      #f
580 )
581
582 (drn (set-quiet &options &mode dst src)
583      VOID
584      (OPTIONS ANYNUMMODE SETRTX RTX) (NA NA MATCHEXPR MATCH2)
585      SET
586      #f
587 )
588 \f
589 ; Standard arithmetic operations.
590
591 ; It's nice emitting macro calls to the actual C operation in that the RTX
592 ; expression is preserved, albeit in C.  On the one hand it's one extra thing
593 ; the programmer has to know when looking at the code.  But on the other it's
594 ; trivial stuff, and having a layer between RTX and C allows the
595 ; macros/functions to be modified to handle unexpected situations.
596
597 ; We do emit C directly for cases other than cpu semantics
598 ; (e.g. the assembler).
599 ;
600 ; The language is defined such that we assume ANSI C semantics while avoiding
601 ; implementation defined areas, with as few exceptions as possible.
602 ;
603 ; Current exceptions:
604 ; - signed shift right assumes the sign bit is replicated.
605 ;
606 ; Additional notes [perhaps repeating what's in ANSI C for emphasis]:
607 ; - callers of division and modulus fns must test for 0 beforehand
608 ;   if necessary
609 ; - division and modulus fns have unspecified behavior for negative args
610 ;   [yes I know the C standard says implementation defined, here its
611 ;   unspecified]
612 ; - later add versions of div/mod that have an explicit behaviour for -ve args
613 ; - signedness is part of the rtx operation name, and is not determined
614 ;   from the arguments [elsewhere is a description of the tradeoffs]
615 ; - ???
616
617 (drn (neg &options &mode s1)
618      #f
619      (OPTIONS ANYNUMMODE RTX) (NA NA MATCHEXPR)
620      UNARY
621      #f
622 )
623
624 (drn (abs &options &mode s1)
625      #f
626      (OPTIONS ANYNUMMODE RTX) (NA NA MATCHEXPR)
627      UNARY
628      #f
629 )
630
631 ; For integer values this is a bitwise operation (each bit inverted).
632 ; For floating point values this produces 1/x.
633 ; ??? Might want different names.
634 (drn (inv &options &mode s1)
635      #f
636      (OPTIONS ANYINTMODE RTX) (NA NA MATCHEXPR)
637      UNARY
638      #f
639 )
640
641 ; This is a boolean operation.
642 ; MODE is the mode of S1.  The result always has mode BI.
643 ; ??? Perhaps `mode' shouldn't be here.
644 (drn (not &options &mode s1)
645      BI
646      (OPTIONS ANYINTMODE RTX) (NA NA MATCHEXPR)
647      UNARY
648      #f
649 )
650
651 (drn (add &options &mode s1 s2)
652      #f
653      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
654      BINARY
655      #f
656 )
657 (drn (sub &options &mode s1 s2)
658      #f
659      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
660      BINARY
661      #f
662 )
663
664 ; "OF" for "overflow flag", "CF" for "carry flag",
665 ; "s3" here must have type BI.
666 ; For the *flag rtx's, MODE is the mode of S1,S2; the result always has
667 ; mode BI.
668 (drn (addc &options &mode s1 s2 s3)
669      #f
670      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
671      TRINARY
672      #f
673 )
674 (drn (addc-cflag &options &mode s1 s2 s3)
675      BI
676      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
677      TRINARY
678      #f
679 )
680 (drn (addc-oflag &options &mode s1 s2 s3)
681      BI
682      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
683      TRINARY
684      #f
685 )
686 (drn (subc &options &mode s1 s2 s3)
687      #f
688      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
689      TRINARY
690      #f
691 )
692 (drn (subc-cflag &options &mode s1 s2 s3)
693      BI
694      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
695      TRINARY
696      #f
697 )
698 (drn (subc-oflag &options &mode s1 s2 s3)
699      BI
700      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
701      TRINARY
702      #f
703 )
704
705 ;; ??? These are deprecated.  Delete in time.
706 (drn (add-cflag &options &mode s1 s2 s3)
707      BI
708      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
709      TRINARY
710      #f
711 )
712 (drn (add-oflag &options &mode s1 s2 s3)
713      BI
714      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
715      TRINARY
716      #f
717 )
718 (drn (sub-cflag &options &mode s1 s2 s3)
719      BI
720      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
721      TRINARY
722      #f
723 )
724 (drn (sub-oflag &options &mode s1 s2 s3)
725      BI
726      (OPTIONS ANYINTMODE RTX RTX RTX) (NA NA MATCHEXPR MATCH2 BI)
727      TRINARY
728      #f
729 )
730
731 ; Usurp these names so that we have consistent rtl should a program generator
732 ; ever want to infer more about what the semantics are doing.
733 ; For now these are just macros that expand to real rtl to perform the
734 ; operation.
735
736 ; Return bit indicating if VALUE is zero/non-zero.
737 (drmn (zflag arg1 . rest) ; mode value)
738       (if (null? rest) ; mode missing?
739           (list 'eq 'DFLT arg1 0)
740           (list 'eq arg1 (car rest) 0))
741 )
742
743 ; Return bit indicating if VALUE is negative/non-negative.
744 (drmn (nflag arg1 . rest) ; mode value)
745       (if (null? rest) ; mode missing?
746           (list 'lt 'DFLT arg1 0)
747           (list 'lt arg1 (car rest) 0))
748 )
749
750 ; Multiply/divide.
751
752 (drn (mul &options &mode s1 s2)
753      #f
754      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
755      BINARY
756      #f
757 )
758 ; ??? In non-sim case, ensure s1,s2 is in right C type for right result.
759 ; ??? Need two variants, one that avoids implementation defined situations
760 ; [both host and target], and one that specifies implementation defined
761 ; situations [target].
762 (drn (div &options &mode s1 s2)
763      #f
764      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
765      BINARY
766      #f
767 )
768 (drn (udiv &options &mode s1 s2)
769      #f
770      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
771      BINARY
772      #f
773 )
774 (drn (mod &options &mode s1 s2)
775      #f
776      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
777      BINARY
778      #f
779 )
780 (drn (umod &options &mode s1 s2)
781      #f
782      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
783      BINARY
784      #f
785 )
786
787 ; wip: mixed mode mul/div
788
789 ; various floating point routines
790
791 (drn (sqrt &options &mode s1)
792      #f
793      (OPTIONS ANYFLOATMODE RTX) (NA NA MATCHEXPR)
794      UNARY
795      #f
796 )
797
798 (drn (cos &options &mode s1)
799      #f
800      (OPTIONS ANYFLOATMODE RTX) (NA NA MATCHEXPR)
801      UNARY
802      #f
803 )
804
805 (drn (sin &options &mode s1)
806      #f
807      (OPTIONS ANYFLOATMODE RTX) (NA NA MATCHEXPR)
808      UNARY
809      #f
810 )
811
812 (drn (nan &options &mode s1)
813      BI
814      (OPTIONS ANYFLOATMODE RTX) (NA NA MATCHEXPR)
815      UNARY
816      #f
817 )
818 (drn (qnan &options &mode s1)
819      BI
820      (OPTIONS ANYFLOATMODE RTX) (NA NA MATCHEXPR)
821      UNARY
822      #f
823 )
824 (drn (snan &options &mode s1)
825      BI
826      (OPTIONS ANYFLOATMODE RTX) (NA NA MATCHEXPR)
827      UNARY
828      #f
829 )
830
831 ; min/max
832
833 (drn (min &options &mode s1 s2)
834      #f
835      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
836      BINARY
837      #f
838 )
839
840 (drn (max &options &mode s1 s2)
841      #f
842      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
843      BINARY
844      #f
845 )
846
847 (drn (umin &options &mode s1 s2)
848      #f
849      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
850      BINARY
851      #f
852 )
853
854 (drn (umax &options &mode s1 s2)
855      #f
856      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
857      BINARY
858      #f
859 )
860
861 ; These are bitwise operations.
862 (drn (and &options &mode s1 s2)
863      #f
864      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
865      BINARY
866      #f
867 )
868 (drn (or &options &mode s1 s2)
869      #f
870      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
871      BINARY
872      #f
873 )
874 (drn (xor &options &mode s1 s2)
875      #f
876      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
877      BINARY
878      #f
879 )
880
881 ; Shift operations.
882
883 (drn (sll &options &mode s1 s2)
884      #f
885      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR INT)
886      BINARY
887      #f
888 )
889 (drn (srl &options &mode s1 s2)
890      #f
891      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR INT)
892      BINARY
893      #f
894 )
895 ; ??? In non-sim case, ensure s1 is in right C type for right result.
896 (drn (sra &options &mode s1 s2)
897      #f
898      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR INT)
899      BINARY
900      #f
901 )
902 ; Rotates don't really have a sign, so doesn't matter what we say.
903 (drn (ror &options &mode s1 s2)
904      #f
905      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR INT)
906      BINARY
907      #f
908 )
909 (drn (rol &options &mode s1 s2)
910      #f
911      (OPTIONS ANYINTMODE RTX RTX) (NA NA MATCHEXPR INT)
912      BINARY
913      #f
914 )
915 ; ??? Will also need rotate-with-carry [duh...].
916
917 ; These are boolean operations (e.g. C &&, ||).
918 ; The result always has mode BI.
919 ; ??? 'twould be more Schemey to take a variable number of args.
920 ; ??? 'twould also simplify several .cpu description entries.
921 ; On the other hand, handling an arbitrary number of args isn't supported by
922 ; ISA's, which the main goal of what we're trying to represent.
923 (drn (andif &options &mode s1 s2)
924      BI
925      (OPTIONS BIMODE RTX RTX) (NA NA ANYINT ANYINT)
926      BINARY ; IF?
927      #f
928 )
929 (drn (orif &options &mode s1 s2)
930      BI
931      (OPTIONS BIMODE RTX RTX) (NA NA ANYINT ANYINT)
932      BINARY ; IF?
933      #f
934 )
935 \f
936 ; `bitfield' is an experimental operation.
937 ; It's not really needed but it might help simplify some things.
938 ;
939 ;(drn (bitfield mode src start length)
940 ;     ...
941 ;     ...
942 ;)
943 \f
944 ;; Integer conversions.
945
946 (drn (ext &options &mode s1)
947      #f
948      (OPTIONS ANYINTMODE RTX) (NA NA ANY)
949      UNARY
950      #f
951 )
952 (drn (zext &options &mode s1)
953      #f
954      (OPTIONS ANYINTMODE RTX) (NA NA ANY)
955      UNARY
956      #f
957 )
958 (drn (trunc &options &mode s1)
959      #f
960      (OPTIONS ANYINTMODE RTX) (NA NA ANY)
961      UNARY
962      #f
963 )
964
965 ;; Conversions involving floating point values.
966
967 (drn (fext &options &mode how s1)
968      #f
969      (OPTIONS ANYFLOATMODE RTX RTX) (NA NA INT ANY)
970      UNARY
971      #f
972 )
973 (drn (ftrunc &options &mode how s1)
974      #f
975      (OPTIONS ANYFLOATMODE RTX RTX) (NA NA INT ANY)
976      UNARY
977      #f
978 )
979 (drn (float &options &mode how s1)
980      #f
981      (OPTIONS ANYFLOATMODE RTX RTX) (NA NA INT ANY)
982      UNARY
983      #f
984 )
985 (drn (ufloat &options &mode how s1)
986      #f
987      (OPTIONS ANYFLOATMODE RTX RTX) (NA NA INT ANY)
988      UNARY
989      #f
990 )
991 (drn (fix &options &mode how s1)
992      #f
993      (OPTIONS ANYINTMODE RTX RTX) (NA NA INT ANY)
994      UNARY
995      #f
996 )
997 (drn (ufix &options &mode how s1)
998      #f
999      (OPTIONS ANYINTMODE RTX RTX) (NA NA INT ANY)
1000      UNARY
1001      #f
1002 )
1003 \f
1004 ; Comparisons.
1005 ; MODE is the mode of S1,S2.  The result always has mode BI.
1006
1007 (drn (eq &options &mode s1 s2)
1008      BI
1009      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1010      COMPARE
1011      #f
1012 )
1013 (drn (ne &options &mode s1 s2)
1014      BI
1015      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1016      COMPARE
1017      #f
1018 )
1019 ; ??? In non-sim case, ensure s1,s2 is in right C type for right result.
1020 (drn (lt &options &mode s1 s2)
1021      BI
1022      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1023      COMPARE
1024      #f
1025 )
1026 (drn (le &options &mode s1 s2)
1027      BI
1028      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1029      COMPARE
1030      #f
1031 )
1032 (drn (gt &options &mode s1 s2)
1033      BI
1034      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1035      COMPARE
1036      #f
1037 )
1038 (drn (ge &options &mode s1 s2)
1039      BI
1040      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1041      COMPARE
1042      #f
1043 )
1044 ; ??? In non-sim case, ensure s1,s2 is in right C type for right result.
1045 (drn (ltu &options &mode s1 s2)
1046      BI
1047      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1048      COMPARE
1049      #f
1050 )
1051 (drn (leu &options &mode s1 s2)
1052      BI
1053      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1054      COMPARE
1055      #f
1056 )
1057 (drn (gtu &options &mode s1 s2)
1058      BI
1059      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1060      COMPARE
1061      #f
1062 )
1063 (drn (geu &options &mode s1 s2)
1064      BI
1065      (OPTIONS ANYNUMMODE RTX RTX) (NA NA MATCHEXPR MATCH2)
1066      COMPARE
1067      #f
1068 )
1069 \f
1070 ; Set membership.
1071 ; Useful in ifield assertions.
1072
1073 ; Return a boolean (BI mode) indicating if VALUE is in SET.
1074 ; VALUE is any constant rtx.  SET is a `number-list' rtx.
1075
1076 (drn (member &options &mode value set)
1077      #f
1078      (OPTIONS BIMODE RTX RTX) (NA NA INT INT)
1079      MISC
1080      (begin
1081        (if (not (rtx-constant? value))
1082            (estate-error *estate* "`member rtx'"
1083                          "value is not a constant" value))
1084        (if (not (rtx-kind? 'number-list set))
1085            (estate-error *estate* "`member' rtx"
1086                          "set is not a `number-list' rtx" set))
1087        (if (memq (rtx-constant-value value) (rtx-number-list-values set))
1088            (rtx-true)
1089            (rtx-false)))
1090 )
1091
1092 ;; FIXME: "number" in "number-list" implies floats are ok.
1093 ;; Rename to integer-list, int-list, or some such.
1094
1095 (drn (number-list &options &mode value-list)
1096      #f
1097      (OPTIONS INTMODE NUMBER . NUMBER) (NA NA NA . NA)
1098      MISC
1099      #f
1100 )
1101 \f
1102 ; Conditional execution.
1103
1104 ; FIXME: make syntax node?
1105 (drn (if &options &mode cond then . else)
1106      #f
1107      ;; ??? It would be cleaner if TESTRTX had to have BI mode.
1108      (OPTIONS ANYEXPRMODE TESTRTX RTX . RTX) (NA NA ANYINT MATCHEXPR . MATCH3)
1109      IF
1110      (apply e-if (append! (list *estate* mode cond then) else))
1111 )
1112
1113 ; ??? The syntax here isn't quite that of Scheme.  A condition must be
1114 ; followed by a result expression.
1115 ; ??? The syntax here isn't quite right, there must be at least one cond rtx.
1116 ; ??? Intermediate expressions (the ones before the last one) needn't have
1117 ; the same mode as the result.
1118 (drsn (cond &options &mode . cond-code-list)
1119      #f
1120       (OPTIONS ANYEXPRMODE . CONDRTX) (NA NA . MATCHEXPR)
1121       COND
1122       #f
1123 )
1124
1125 ; ??? The syntax here isn't quite right, there must be at least one case.
1126 ; ??? Intermediate expressions (the ones before the last one) needn't have
1127 ; the same mode as the result.
1128 (drn (case &options &mode test . case-list)
1129      #f
1130      (OPTIONS ANYEXPRMODE RTX . CASERTX) (NA NA ANY . MATCHEXPR)
1131      COND
1132      #f
1133 )
1134 \f
1135 ; parallel, sequence, do-count, closure
1136
1137 ; This has to be a syntax node as we don't want EXPRS to be pre-evaluated.
1138 ; All semantic ops must have a mode, though here it must be VOID.
1139 ; IGNORE is for consistency with sequence.  ??? Delete some day.
1140 ; ??? There's no real need for mode either, but convention requires it.
1141
1142 (drsn (parallel &options &mode ignore expr . exprs)
1143      #f
1144       (OPTIONS VOIDMODE LOCALS RTX . RTX) (NA NA NA VOID . VOID)
1145       SEQUENCE
1146       #f
1147 )
1148
1149 ; This has to be a syntax node to handle locals properly: they're not defined
1150 ; yet and thus pre-evaluating the expressions doesn't work.
1151
1152 (drsn (sequence &options &mode locals expr . exprs)
1153      #f
1154       (OPTIONS VOIDORNUMMODE LOCALS RTX . RTX) (NA NA NA MATCHSEQ . MATCHSEQ)
1155       SEQUENCE
1156       #f
1157 )
1158
1159 ; This has to be a syntax node to handle iter-var properly: it's not defined
1160 ; yet and thus pre-evaluating the expressions doesn't work.
1161
1162 (drsn (do-count &options &mode iter-var nr-times expr . exprs)
1163      #f
1164       (OPTIONS VOIDMODE ITERATION RTX RTX . RTX) (NA NA NA INT VOID . VOID)
1165       SEQUENCE
1166       #f
1167 )
1168
1169 ; Internal rtx to create a closure.
1170 ; Internal, so it does not appear in rtl.texi (at least not yet).
1171 ; ??? Maybe closures shouldn't be separate from sequences,
1172 ; but I'm less convinced these days.
1173
1174 (drsn (closure &options &mode isa-name-list env-stack expr)
1175      #f
1176       (OPTIONS VOIDORNUMMODE SYMBOLLIST ENVSTACK RTX) (NA NA NA NA MATCHEXPR)
1177       MISC
1178       #f
1179 )
1180 \f
1181 )) ; End of def-rtx-funcs