OSDN Git Service

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