OSDN Git Service

* better support multiple-isa devices.
[pf3gnuchains/pf3gnuchains4x.git] / cgen / sid-decode.scm
1 ; Decoder generation.
2 ; Copyright (C) 2000, 2002 Red Hat, Inc.
3 ; This file is part of CGEN.
4
5 ; Return decode entries for each insn.
6 ; ??? At one point we generated one variable per instruction rather than one
7 ; big array.  It doesn't matter too much (yet).  Generating one big array is
8 ; simpler.
9
10 (define (-gen-decode-insn-globals insn-list)
11   ; Print the higher detailed stuff at higher verbosity.
12   (logit 2 "Processing decode insn globals ...\n")
13
14   (let* ((all-attrs (current-insn-attr-list))
15          (last-insn (string-upcase (gen-c-symbol (caar (list-take -1
16                       (gen-obj-list-enums (non-multi-insns (current-insn-list)))))))))
17
18     (string-write
19      "
20 // The instruction descriptor array. 
21 \n"
22
23      (if (with-pbb?)
24          "\
25 // Have label pointers been initialized?
26 // XXX: Note that this is also needed by when semantics are implemented as
27 // functions to handle machine variants.
28 bool @prefix@_idesc::idesc_table_initialized_p = false;\n\n"
29          "")
30
31      "\
32 @prefix@_idesc @prefix@_idesc::idesc_table[@PREFIX@_INSN_" last-insn " + 1] =
33 {\n"
34
35      (string-map
36       (lambda (insn)
37         (let ((name (gen-sym insn))
38               (sfmt (insn-sfmt insn))
39               (pbb? (obj-has-attr? insn 'PBB))
40               (virtual? (obj-has-attr? insn 'VIRTUAL)))
41           (string-append
42            "  { "
43            (if (with-pbb?)
44                "0, "
45                "")
46            (if (with-scache?)
47                (if pbb?
48                    "0, "
49                    (string-append (-gen-sem-fn-name insn) ", "))
50                "")
51            (if (with-parallel?)
52                (string-append (-gen-write-fn-name sfmt) ", ")
53                "")
54            "\"" (string-upcase name) "\", "
55            (gen-cpu-insn-enum (current-cpu) insn)
56            ", "
57            (gen-obj-attr-sid-defn 'insn insn all-attrs)
58            " },\n")))
59       insn-list)
60
61      "\n};\n\n"
62      ))
63 )
64
65 ; Return a function that lookups up virtual insns.
66
67 (define (-gen-virtual-insn-finder)
68   (string-list
69    "\
70 // Given a canonical virtual insn id, return the target specific one.
71
72 @prefix@_insn_type
73 @prefix@_idesc::lookup_virtual (virtual_insn_type vit)
74 {
75   switch (vit)
76     {
77       case VIRTUAL_INSN_INVALID: return @PREFIX@_INSN_X_INVALID;
78 "
79
80    (if (with-pbb?)
81        "\
82       case VIRTUAL_INSN_BEGIN: return @PREFIX@_INSN_X_BEGIN;
83       case VIRTUAL_INSN_CHAIN: return @PREFIX@_INSN_X_CHAIN;
84       case VIRTUAL_INSN_CTI_CHAIN: return @PREFIX@_INSN_X_CTI_CHAIN;
85       case VIRTUAL_INSN_BEFORE: return @PREFIX@_INSN_X_BEFORE;
86       case VIRTUAL_INSN_AFTER: return @PREFIX@_INSN_X_AFTER;
87 "
88        "")
89    (if (and (with-pbb?)
90             (state-conditional-exec?))
91        "\
92       case VIRTUAL_INSN_COND: return @PREFIX@_INSN_X_COND;
93 "
94        ; Unused, but may still be requested.  Just return X_INVALID.
95        "\
96       case VIRTUAL_INSN_COND: return @PREFIX@_INSN_X_INVALID;
97 ")
98    "\
99     }
100   abort ();
101 }\n\n"
102    )
103 )
104 \f
105 ; Return enum name of format FMT.
106
107 (define (-gen-fmt-enum fmt)
108   (string-upcase (gen-sym fmt))
109 )
110
111 ; Return names of semantic fns for INSN.
112 ; ??? Make global, call from gen-semantic-fn, blah blah blah.
113
114 (define (-gen-sem-fn-name insn)
115   (string-append "@prefix@_sem_" (gen-sym insn))
116 )
117
118 ; Return decls of each semantic fn.
119
120 (define (-gen-sem-fn-decls)
121   (string-write
122    "// Decls of each semantic fn.\n\n"
123    "using @cpu@::@prefix@_sem_fn;\n"
124    (string-list-map (lambda (insn)
125                       (string-list "extern @prefix@_sem_fn "
126                                    (-gen-sem-fn-name insn)
127                                    ";\n"))
128                     (scache-engine-insns))
129    "\n"
130    )
131 )
132
133
134 ;; and the same for writeback functions
135
136 (define (-gen-write-fn-name sfmt)
137   (string-append "@prefix@_write_" (gen-sym sfmt))
138 )
139
140
141 (define (-gen-write-fn-decls)
142   (string-write
143    "// Decls of each writeback fn.\n\n"
144    "using @cpu@::@prefix@_write_fn;\n"
145    (string-list-map (lambda (sfmt)
146                       (string-list "extern @prefix@_write_fn "
147                                    (-gen-write-fn-name sfmt)
148                                    ";\n"))
149                     (current-sfmt-list))
150    "\n"
151    )
152 )
153
154 \f
155 ; idesc, argbuf, and scache types
156
157 ; Generate decls for the insn descriptor table type IDESC.
158
159 (define (-gen-idesc-decls)
160   (string-append 
161    "
162 // Forward decls.
163 struct @cpu@_cpu;
164 struct @prefix@_scache;
165 "
166    (if (with-parallel?)
167        "struct @prefix@_parexec;\n" "")
168    (if (with-parallel?)
169        "typedef void (@prefix@_sem_fn) (@cpu@_cpu* cpu, @prefix@_scache* sem, @prefix@_parexec* par_exec);"
170        "typedef sem_status (@prefix@_sem_fn) (@cpu@_cpu* cpu, @prefix@_scache* sem);")
171    "\n"
172    (if (with-parallel?)
173        "typedef sem_status (@prefix@_write_fn) (@cpu@_cpu* cpu, @prefix@_scache* sem, @prefix@_parexec* par_exec);"
174        "")
175    "\n"   
176 "
177 // Instruction descriptor.
178
179 struct @prefix@_idesc {
180 \n"
181
182    (if (with-pbb?)
183        "\
184   // computed-goto label pointer (pbb engine)
185   // FIXME: frag case to be redone (should instead point to usage table).
186   cgoto_label cgoto;\n\n"
187        "")
188
189    (if (with-scache?)
190        "\
191   // scache engine executor for this insn
192   @prefix@_sem_fn* execute;\n\n"
193        "")
194
195    (if (with-parallel?)
196        "\
197   // scache write executor for this insn
198   @prefix@_write_fn* writeback;\n\n"
199        "")
200
201    "\
202   const char* insn_name;
203   enum @prefix@_insn_type sem_index;
204   @arch@_insn_attr attrs;
205
206   // idesc table: indexed by sem_index
207   static @prefix@_idesc idesc_table[];
208 "
209
210    (if (with-pbb?)
211       "\
212
213   // semantic label pointers filled_in?
214   static bool idesc_table_initialized_p;\n"
215       "")
216
217    "\
218
219   static @prefix@_insn_type lookup_virtual (virtual_insn_type vit);
220 };
221
222 ")
223 )
224
225 ; Utility of -gen-argbuf-fields-union to generate the definition for
226 ; <sformat-abuf> SBUF.
227
228 (define (-gen-argbuf-elm sbuf)
229   (logit 2 "Processing sbuf format " (obj:name sbuf) " ...\n")
230   (string-list
231    "  struct { /* " (obj:comment sbuf) " */\n"
232    (let ((elms (sbuf-elms sbuf)))
233      (if (null? elms)
234          "    int empty;\n"
235          (string-list-map (lambda (elm)
236                             (string-append "    "
237                                            (cadr elm)
238                                            " "
239                                            (car elm)
240                                            ";\n"))
241                           (sbuf-elms sbuf))))
242    "  } " (gen-sym sbuf) ";\n")
243 )
244
245 ; Utility of -gen-scache-decls to generate the union of extracted ifields.
246
247 (define (-gen-argbuf-fields-union)
248   (string-list
249    "\
250 // Instruction argument buffer.
251
252 union @prefix@_sem_fields {\n"
253    (string-list-map -gen-argbuf-elm (current-sbuf-list))
254    "\
255   // This one is for chain/cti-chain virtual insns.
256   struct {
257     // Number of insns in pbb.
258     unsigned insn_count;
259     // This is used by chain insns and by untaken conditional branches.
260     @prefix@_scache* next;
261     @prefix@_scache* branch_target;
262   } chain;
263   // This one is for `before' virtual insns.
264   struct {
265     // The cache entry of the real insn.
266     @prefix@_scache* insn;
267   } before;
268 };\n\n"
269    )
270 )
271
272 (define (-gen-scache-decls)
273   (string-list
274    (-gen-argbuf-fields-union)
275    "\
276 // Simulator instruction cache.
277
278 struct @prefix@_scache {
279   // executor
280   union {
281     cgoto_label cgoto;
282     @prefix@_sem_fn* fn;
283   } execute;
284 \n"
285    
286    (if (state-conditional-exec?)
287        "\
288   // condition
289   UINT cond;
290 \n"
291        "")
292
293    "\
294   // PC of this instruction.
295   PCADDR addr;
296
297   // instruction class
298   @prefix@_idesc* idesc;
299
300   // argument buffer
301   @prefix@_sem_fields fields;
302
303 " (if (or (with-profile?) (with-parallel-write?))
304       (string-append "
305   // writeback flags
306   // Only used if profiling or parallel execution support enabled during
307   // file generation.
308   unsigned long long written;
309 ")
310       "") "
311
312   // decode given instruction
313   void decode (@cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn);
314 };
315
316 ")
317 )
318 \f
319 ; Instruction field extraction support.
320 ; Two implementations are provided, one for !with-scache and one for
321 ; with-scache.
322 ;
323 ; Extracting ifields is a three phase process.  First the ifields are
324 ; extracted and stored in local variables.  Then any ifields requiring
325 ; additional processing for operands are handled.  Then in the with-scache
326 ; case the results are stored in a struct for later retrieval by the semantic
327 ; code.
328 ;
329 ; The !with-scache case does this processing in the semantic function,
330 ; except it doesn't need the last step (it doesn't need to store the results
331 ; in a struct for later use).
332 ;
333 ; The with-scache case extracts the ifields in the decode function.
334 ; Furthermore, we use <sformat-argbuf> to reduce the quantity of structures
335 ; created (this helps semantic-fragment pbb engines).
336
337 ; Return C code to record <ifield> F for the semantic handler
338 ; in a local variable rather than an ARGBUF struct.
339
340 (define (-gen-record-argbuf-ifld f sfmt)
341   (string-append "  " (gen-ifld-argbuf-ref f)
342                  " = " (gen-extracted-ifld-value f) ";\n")
343 )
344
345 ; Return three of arguments to TRACE:
346 ; string argument to fprintf, character indicating type of third arg, value.
347 ; The type is one of: x.
348
349 (define (-gen-trace-argbuf-ifld f sfmt)
350   (string-append
351    ; FIXME: Add method to return fprintf format string.
352    ", \"" (gen-sym f) " 0x%x\""
353    ", 'x'"
354    ", " (gen-extracted-ifld-value f))
355 )
356 \f
357 ; Instruction field extraction support cont'd.
358 ; Hardware support.
359
360 ; gen-extract method.
361 ; For the default case we use the ifield as is, which is output elsewhere.
362
363 (method-make!
364  <hardware-base> 'gen-extract
365  (lambda (self op sfmt local?)
366    "")
367 )
368
369 ; gen-trace-extract method.
370 ; Return appropriate arguments for TRACE_EXTRACT.
371
372 (method-make!
373  <hardware-base> 'gen-trace-extract
374  (lambda (self op sfmt)
375    "")
376 )
377
378 ; Extract the necessary fields into ARGBUF.
379
380 (method-make!
381  <hw-register> 'gen-extract
382  (lambda (self op sfmt local?)
383    (if (hw-cache-addr? self)
384        (string-append "  "
385                       (if local?
386                           (gen-hw-index-argbuf-name (op:index op))
387                           (gen-hw-index-argbuf-ref (op:index op)))
388                       " = & "
389                       (gen-cpu-ref (hw-isas self) (gen-sym (op:type op)))
390                       (gen-array-ref (gen-extracted-ifld-value (op-ifield op)))
391                       ";\n")
392        ""))
393 )
394
395 ; Return appropriate arguments for TRACE_EXTRACT.
396
397 (method-make!
398  <hw-register> 'gen-trace-extract
399  (lambda (self op sfmt)
400    (if (hw-cache-addr? self)
401        (string-append
402         ; FIXME: Add method to return fprintf format string.
403         ", \"" (gen-sym op) " 0x%x\""
404         ", 'x'"
405         ", " (gen-extracted-ifld-value (op-ifield op)))
406        ""))
407 )
408
409 ; Extract the necessary fields into ARGBUF.
410
411 (method-make!
412  <hw-address> 'gen-extract
413  (lambda (self op sfmt local?)
414    (string-append "  "
415                   (if local?
416                       (gen-hw-index-argbuf-name (op:index op))
417                       (gen-hw-index-argbuf-ref (op:index op)))
418                   " = "
419                   (gen-extracted-ifld-value (op-ifield op))
420                   ";\n"))
421 )
422
423 ; Return appropriate arguments for TRACE_EXTRACT.
424
425 (method-make!
426  <hw-address> 'gen-trace-extract
427  (lambda (self op sfmt)
428    (string-append
429     ; FIXME: Add method to return fprintf format string.
430     ", \"" (gen-sym op) " 0x%x\""
431     ", 'x'"
432     ", " (gen-extracted-ifld-value (op-ifield op))))
433 )
434 \f
435 ; Instruction field extraction support cont'd.
436 ; Operand support.
437
438 ; Return C code to record the field for the semantic handler.
439 ; In the case of a register, this is usually the address of the register's
440 ; value (if CACHE-ADDR).
441 ; LOCAL? indicates whether to record the value in a local variable or in
442 ; the ARGBUF struct.
443 ; ??? Later allow target to provide an `extract' expression.
444
445 (define (-gen-op-extract op sfmt local?)
446   (send (op:type op) 'gen-extract op sfmt local?)
447 )
448
449 ; Return three of arguments to TRACE_EXTRACT:
450 ; string argument to fprintf, character indicating type of third arg, value.
451 ; The type is one of: x.
452
453 (define (-gen-op-trace-extract op sfmt)
454   (send (op:type op) 'gen-trace-extract op sfmt)
455 )
456
457 ; Return C code to define local vars to hold processed ifield data for
458 ; <sformat> SFMT.
459 ; This is used when !with-scache.
460 ; Definitions of the extracted ifields is handled elsewhere.
461
462 (define (gen-sfmt-op-argbuf-defns sfmt)
463   (let ((operands (sfmt-extracted-operands sfmt)))
464     (logit 3 "sfmt = " (obj:name sfmt) " operands=" (string-map obj:name operands))
465     (string-list-map (lambda (op)
466                        (let ((var-spec (sfmt-op-sbuf-elm op sfmt)))
467                          (if var-spec
468                              (string-append "  "
469                                             (cadr var-spec)
470                                             " "
471                                             (car var-spec)
472                                             ";\n")
473                              "")))
474                      operands))
475 )
476
477 ; Return C code to assign values to the local vars that hold processed ifield
478 ; data for <sformat> SFMT.
479 ; This is used when !with-scache.
480 ; Assignment of the extracted ifields is handled elsewhere.
481
482 (define (gen-sfmt-op-argbuf-assigns sfmt)
483   (let ((operands (sfmt-extracted-operands sfmt)))
484     (string-list-map (lambda (op)
485                        (-gen-op-extract op sfmt #t))
486                      operands))
487 )
488 \f
489 ; Instruction field extraction support cont'd.
490 ; Emit extraction section of decode function.
491
492 ; Return C code to record insn field data for <sformat> SFMT.
493 ; This is used when with-scache.
494
495 (define (-gen-record-args sfmt)
496   (let ((operands (sfmt-extracted-operands sfmt))
497         (iflds (sfmt-needed-iflds sfmt)))
498     (string-list
499      "  /* Record the fields for the semantic handler.  */\n"
500      (string-list-map (lambda (f) (-gen-record-argbuf-ifld f sfmt))
501                       iflds)
502      (string-list-map (lambda (op) (-gen-op-extract op sfmt #f))
503                       operands)
504      "  if (UNLIKELY(current_cpu->trace_extract_p))\n"
505      "    {\n"
506      "      current_cpu->trace_stream \n"
507      "        << \"0x\" << hex << pc << dec << \" (" (gen-sym sfmt) ")\\t\"\n"
508      ; NB: The following is not necessary any more, as the ifield list 
509      ;     is a subset of the operand list.
510      ; (string-list-map (lambda (f) 
511      ;                  (string-list
512      ;                   "        << \" " (gen-sym f) ":0x\" << hex << " (gen-sym f) " << dec\n"))
513      ;                iflds)
514      (string-list-map (lambda (ifld) 
515                         (string-list
516                          "        << \" " (gen-extracted-ifld-value ifld) ":0x\" << hex << "
517                                         ; Add (SI) or (USI) cast for byte-wide data, to prevent C++ iostreams
518                                         ; from printing byte as plain raw char.
519                          (cond ((not ifld) "")
520                                ((mode:eq? 'QI (ifld-decode-mode ifld)) "(SI) ")
521                                ((mode:eq? 'UQI (ifld-decode-mode ifld)) "(USI) ")
522                                (else ""))
523                          (gen-extracted-ifld-value ifld)
524                          " << dec\n"))
525                       iflds)
526      "        << endl;\n"
527      "    }\n"
528      ))
529 )
530
531 ; Return C code to record insn field data for profiling.
532 ; Also recorded are operands not mentioned in the fields but mentioned
533 ; in the semantic code.
534 ;
535 ; FIXME: Register usage may need to be tracked as an array of longs.
536 ; If there are more than 32 regs, we can't know which until build time.
537 ; ??? For now we only handle reg sets of 32 or less.
538 ;
539 ; ??? The other way to obtain register numbers is to defer computing them
540 ; until they're actually needed.  It will speed up execution when not doing
541 ; profiling, though the speed up is only for the extraction phase.
542 ; On the other hand the current way has one memory reference per register
543 ; number in the profiling routines.  For RISC this can be a lose, though for
544 ; more complicated instruction sets it could be a win as all the computation
545 ; is kept to the extraction phase.  If someone wants to put forth some real
546 ; data, this might then be changed (or at least noted).
547
548 (define (-gen-record-profile-args sfmt)
549   (let ((in-ops (find op-profilable? (sfmt-in-ops sfmt)))
550         (out-ops (find op-profilable? (sfmt-out-ops sfmt)))
551         )
552     (if (and (null? in-ops) (null? out-ops))
553         ""
554         (string-list
555          "#if WITH_PROFILE_MODEL_P\n"
556          "  /* Record the fields for profiling.  */\n"
557          "  if (PROFILE_MODEL_P (current_cpu))\n"
558          "    {\n"
559          (string-list-map (lambda (op) (op:record-profile op sfmt #f))
560                           in-ops)
561          (string-list-map (lambda (op) (op:record-profile op sfmt #t))
562                           out-ops)
563          "    }\n"
564          "#endif\n"
565          )))
566 )
567
568 ; Return C code that extracts the fields of <sformat> SFMT.
569 ;
570 ; Extraction is based on formats to reduce the amount of code generated.
571 ; However, we also need to emit code which records the hardware elements used
572 ; by the semantic code.  This is currently done by recording this information
573 ; with the format.
574
575 (define (-gen-extract-fn sfmt)
576   (logit 2 "Processing extractor for \"" (sfmt-key sfmt) "\" ...\n")
577   (string-list
578    "void
579 @prefix@_extract_" (gen-sym sfmt) " (@prefix@_scache* abuf, @cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn)"
580    "{\n"
581    "    @prefix@_insn_word insn = "
582    (if (adata-integral-insn? CURRENT-ARCH)
583        "entire_insn;\n"
584        "base_insn;\n")
585    (gen-define-field-macro sfmt)
586    (gen-define-ifields (sfmt-iflds sfmt) (sfmt-length sfmt) "    " #f)
587    "\n"
588    (gen-extract-ifields (sfmt-iflds sfmt) (sfmt-length sfmt) "    " #f)
589    "\n"
590    (-gen-record-args sfmt)
591    "\n"
592    ;(-gen-record-profile-args sfmt) ??? not supported yet
593    (gen-undef-field-macro sfmt)
594    "}\n\n"
595    )
596 )
597
598 ; For each format, return its extraction function.
599
600 (define (-define-all-extractor-fns)
601   (logit 2 "Processing extractor fn bodies ...\n")
602   (string-list-map -gen-extract-fn (current-sfmt-list))
603 )
604
605 (define (-declare-all-extractor-fns)
606   (logit 2 "Processing extractor fn declarations ...\n")
607   (string-map (lambda (sfmt)
608                 (string-append "
609 static void
610 @prefix@_extract_" (gen-sym sfmt) " (@prefix@_scache* abuf, @cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn);"))
611               (current-sfmt-list))
612 )
613
614 \f
615 ; Generate top level decoder.
616 ; INITIAL-BITNUMS is a target supplied list of bit numbers to use to
617 ; build the first decode table.  If nil, we compute 8 bits of it (FIXME)
618 ; ourselves.
619 ; LSB0? is non-#f if bit number 0 is the least significant bit.
620 ; FIXME: Need to be perfect for every subtable, or allow target more control.
621 ; Leave for later (and don't give target more control until oodles of effort
622 ; have been spent trying to be perfect! ... or close enough).
623
624 (define (-gen-decode-fn insn-list initial-bitnums lsb0?)
625   (assert (with-scache?))
626
627   ; Compute the initial DECODE-BITSIZE as the minimum of all insn lengths.
628   ; The caller of @prefix@_decode must fetch and pass exactly this number of bits
629   ; of the instruction.
630   ; ??? Make this a parameter later but only if necessary.
631
632   (let ((decode-bitsize (state-base-insn-bitsize)))
633
634     ; Compute INITIAL-BITNUMS if not supplied.
635     ; 0 is passed for the start bit (it is independent of lsb0?)
636     (if (null? initial-bitnums)
637         (set! initial-bitnums
638               (if (= 0 (length insn-list)) (list 0) ; dummy value
639                   (decode-get-best-bits insn-list nil
640                                         0 ; startbit
641                                         8 ; max
642                                         decode-bitsize
643                                         lsb0?))))
644         
645     ; All set.  gen-decoder does the hard part, we just print out the result. 
646     (let ((decode-code (gen-decoder insn-list initial-bitnums
647                                     decode-bitsize
648                                     "    " lsb0?
649                                     (current-insn-lookup 'x-invalid)
650                                     #t)))
651
652       (string-write
653        "
654 // Declare extractor functions
655 "
656        -declare-all-extractor-fns
657
658        "
659
660 // Fetch & decode instruction
661 void
662 @prefix@_scache::decode (@cpu@_cpu* current_cpu, PCADDR pc, @prefix@_insn_word base_insn, @prefix@_insn_word entire_insn)
663 {
664   /* Result of decoder.  */
665   @PREFIX@_INSN_TYPE itype;
666
667   {
668     @prefix@_insn_word insn = base_insn;
669 \n"
670        decode-code
671        "
672   }
673
674   /* The instruction has been decoded and fields extracted.  */
675   done:
676 "
677        (if (state-conditional-exec?)
678            (let ((cond-ifld (current-ifld-lookup (car (isa-condition (current-isa))))))
679              (string-append
680               "  {\n"
681               (gen-ifld-extract-decl cond-ifld "    " #f)
682               (gen-ifld-extract cond-ifld "    "
683                                 (state-base-insn-bitsize)
684                                 (state-base-insn-bitsize)
685                                 "base_insn" nil #f)
686               "    this->cond = " (gen-sym cond-ifld) ";\n"
687               "  }\n"))
688            "")
689
690        "
691   this->addr = pc;
692   // FIXME: To be redone (to handle ISA variants).
693   this->idesc = & @prefix@_idesc::idesc_table[itype];
694   // ??? record semantic handler?
695   assert(this->idesc->sem_index == itype);
696 }
697
698 "
699
700        -define-all-extractor-fns
701        )))
702 )
703 \f
704 ; Entry point.  Generate decode.h.
705
706 (define (cgen-decode.h)
707   (logit 1 "Generating " (gen-cpu-name) " decode.h ...\n")
708
709   (sim-analyze-insns!)
710
711   ; Turn parallel execution support on if cpu needs it.
712   (set-with-parallel?! (state-parallel-exec?))
713
714   (string-write
715    (gen-copyright "Decode header for @prefix@."
716                   copyright-red-hat package-red-hat-simulators)
717    "\
718 #ifndef @PREFIX@_DECODE_H
719 #define @PREFIX@_DECODE_H
720
721 namespace @cpu@ {
722
723 using namespace cgen;
724 using namespace @arch@;
725
726 typedef UINT @prefix@_insn_word;
727
728 "
729    (lambda () (gen-cpu-insn-enum-decl (current-cpu)
730                                       (non-multi-insns (non-alias-insns (current-insn-list)))))
731    -gen-idesc-decls
732    -gen-scache-decls
733
734    "\
735 } // end @cpu@ namespace
736 \n"
737
738    ; ??? The semantic functions could go in the cpu's namespace.
739    ; There's no pressing need for it though.
740    (if (with-scache?)
741        -gen-sem-fn-decls
742        "")
743
744    (if (with-parallel?)
745        -gen-write-fn-decls
746        "")
747
748    "\
749 #endif /* @PREFIX@_DECODE_H */\n"
750    )
751 )
752 \f
753 ; Entry point.  Generate decode.cxx.
754
755 (define (cgen-decode.cxx)
756   (logit 1 "Generating " (gen-cpu-name) " decode.cxx ...\n")
757
758   (sim-analyze-insns!)
759
760   ; Turn parallel execution support on if cpu needs it.
761   (set-with-parallel?! (state-parallel-exec?))
762
763   ; Tell the rtx->c translator we are the simulator.
764   (rtl-c-config! #:rtl-cover-fns? #t)
765
766   (string-write
767    (gen-copyright "Simulator instruction decoder for @prefix@."
768                   copyright-red-hat package-red-hat-simulators)
769    "\
770
771 #include \"@cpu@.h\"
772
773 using namespace @cpu@; // FIXME: namespace organization still wip
774 \n"
775
776    (lambda () (-gen-decode-insn-globals (non-multi-insns (non-alias-insns (current-insn-list)))))
777    -gen-virtual-insn-finder
778    (lambda () (-gen-decode-fn (non-multi-insns (real-insns (current-insn-list)))
779                               (state-decode-assist)
780                               (current-arch-insn-lsb0?)))
781    )
782 )