OSDN Git Service

gdb/testsuite/
[pf3gnuchains/pf3gnuchains3x.git] / cgen / opc-itab.scm
1 ; Opcode table support.
2 ; Copyright (C) 2000, 2005, 2009 Red Hat, Inc.
3 ; This file is part of CGEN.
4
5 ; Append code here to be run before insn parsing/etc.
6 ; These are for internal use and aren't intended to appear in .cpu files.
7 ; ??? Nothing currently uses them but that might change.
8
9 (define parse-init-code "")
10 (define insert-init-code "")
11 (define extract-init-code "")
12 (define print-init-code "")
13
14 ; Define CGEN_INIT_{PARSE,INSERT,EXTRACT,PRINT} macros.
15 ; ??? These were early escape hatches.  Not currently used.
16
17 (define (/gen-init-macros)
18   (logit 2 "Generating init macros ...\n")
19   (string-append
20    "#define CGEN_INIT_PARSE(od) \\
21 {\\\n"
22    parse-init-code
23    "}\n"
24    "#define CGEN_INIT_INSERT(od) \\
25 {\\\n"
26    insert-init-code
27    "}\n"
28    "#define CGEN_INIT_EXTRACT(od) \\
29 {\\\n"
30    extract-init-code
31    "}\n"
32    "#define CGEN_INIT_PRINT(od) \\
33 {\\\n"
34    print-init-code
35    "}\n"
36   )
37 )
38 \f
39 ; Instruction field support.
40
41 ; Return C code to declare various ifield types,decls.
42
43 (define (/gen-ifield-decls)
44   (logit 2 "Generating instruction field decls ...\n")
45   (string-append
46    "/* This struct records data prior to insertion or after extraction.  */\n"
47    "struct cgen_fields\n{\n"
48    ; A special member `length' is used to record the length.
49    "  int length;\n"
50    (string-map gen-ifield-value-decl (non-derived-ifields (current-ifld-list)))
51    "};\n\n"
52    )
53 )
54 \f
55 ; Instruction syntax support.
56
57 ; Extract the operand fields in SYNTAX-STRING.
58 ; The result is a list of operand names.
59 ; ??? Not currently used, but keep awhile.
60
61 (define (extract-syntax-operands syntax)
62   (let loop ((syn syntax) (result nil))
63
64     (cond ((= (string-length syn) 0)
65            (reverse! result))
66
67           ((char=? #\\ (string-ref syn 0))
68            (if (= (string-length syn) 1)
69                (error "missing char after '\\'" syntax))
70            (loop (string-drop 2 syn) result))
71
72           ((char=? #\$ (string-ref syn 0))
73            ; Extract the symbol from the string, which will be the name of
74            ; an operand.  Append it to the result.
75            (if (= (string-length syn) 1)
76                (error "missing operand name" syntax))
77            (if (char=? (string-ref syn 1) #\{)
78                (let ((n (chars-until-delimiter syn #\})))
79                  ; Note that 'n' includes the leading ${.
80                  (case n
81                    ((0) (error "empty operand name" syntax))
82                    ((#f) (error "missing '}'" syntax))
83                    (else (loop (string-drop (+ n 1) syn)
84                                (cons (string->symbol (substring syn 2 n))
85                                      result)))))
86                (let ((n (id-len (string-drop1 syn))))
87                  (if (= n 0)
88                      (error "empty or invalid operand name" syntax))
89                  (loop (string-drop (1+ n) syn)
90                        (cons (string->symbol (substring syn 1 (1+ n)))
91                              result)))))
92
93           (else (loop (string-drop1 syn) result))))
94 )
95
96 ; Strip the mnemonic part from SYNTAX.
97 ; (ie: everything up to but not including the first space or '$')
98 ; If STRIP-MNEM-OPERANDS?, strip them too.
99
100 (define (strip-mnemonic strip-mnem-operands? syntax)
101   (let ((space (string-index syntax #\space)))
102     (if strip-mnem-operands?
103         (if space
104             (string-drop space syntax)
105             "")
106         (let loop ((syn syntax))
107           (if (= (string-length syn) 0)
108               ""
109               (case (string-ref syn 0)
110                 ((#\space) syn)
111                 ((#\\) (loop (string-drop 2 syn)))
112                 ((#\$) syn)
113                 (else (loop (string-drop1 syn))))))))
114 )
115
116 ; Compute the sequence of syntax bytes for SYNTAX.
117 ; STRIP-MNEMONIC? is #t if the mnemonic part is to be stripped off.
118 ; STRIP-MNEM-OPERANDS? is #t if any mnemonic operands are to be stripped off.
119 ; SYNTAX is a string of text and operands.
120 ; OP-MACRO is the macro to call that computes an operand's value.
121 ; The resulting syntax is expressed as a sequence of bytes.
122 ; Values < 128 are characters that must be matched.
123 ; Values >= 128 are 128 + the index into the operand table.
124
125 (define (compute-syntax strip-mnemonic? strip-mnem-operands? syntax op-macro
126                         isa-name-list)
127   (let ((context (make-prefix-context "syntax computation"))
128         (syntax (if strip-mnemonic?
129                     (strip-mnemonic strip-mnem-operands? syntax)
130                     syntax)))
131
132     (let loop ((syn syntax) (result ""))
133
134       (cond ((= (string-length syn) 0)
135              (string-append result "0"))
136
137             ((char=? #\\ (string-ref syn 0))
138              (if (= (string-length syn) 1)
139                  (parse-error context "missing char after '\\'" syntax))
140              (let ((escaped-char (string-ref syn 1))
141                    (remainder (string-drop 2 syn)))
142                (if (char=? #\\ escaped-char)
143                    (loop remainder (string-append result "'\\\\', "))
144                    (loop remainder (string-append result "'" (string escaped-char) "', ")))))
145
146             ((char=? #\$ (string-ref syn 0))
147              ; Extract the symbol from the string, which will be the name of
148              ; an operand.  Append it to the result.
149              (if (= (string-length syn) 1)
150                  (parse-error context "missing operand name" syntax))
151              ; Is it $foo or ${foo}?
152              (if (char=? (string-ref syn 1) #\{)
153                  (let ((n (chars-until-delimiter syn #\})))
154                    ; Note that 'n' includes the leading ${.
155                    ; FIXME: \} not implemented yet.
156                    (case n
157                      ((0) (parse-error context "empty operand name" syntax))
158                      ((#f) (parse-error context "missing '}'" syntax))
159                      (else (loop (string-drop (+ n 1) syn)
160                                  (string-append result op-macro " ("
161                                                 (string-upcase
162                                                  (gen-c-symbol
163                                                   (substring syn 2 n)))
164                                                 "), ")))))
165                  (let ((n (id-len (string-drop1 syn))))
166                    (if (= n 0)
167                        (parse-error context "empty or invalid operand name" syntax))
168                    (let ((operand (string->symbol (substring syn 1 (1+ n)))))
169                      (if (not (current-op-lookup operand isa-name-list))
170                          (parse-error context "undefined operand " operand syntax)))
171                    (loop (string-drop (1+ n) syn)
172                          (string-append result op-macro " ("
173                                         (string-upcase
174                                          (gen-c-symbol
175                                           (substring syn 1 (1+ n))))
176                                         "), ")))))
177
178             ; Append the character to the result.
179             (else (loop (string-drop1 syn)
180                         (string-append result
181                                        "'" (string-take1 syn) "', "))))))
182 )
183
184 ; Return C code to define the syntax string for SYNTAX
185 ; MNEM is the C value to use to represent the instruction's mnemonic.
186 ; OP is the C macro to use to compute an operand's syntax value.
187 ; ISA-NAME-LIST is the list of ISA names in which the owning insn lives.
188
189 (define (gen-syntax-entry mnem op syntax isa-name-list)
190   (string-append
191    "{ { "
192    mnem ", "
193    ; `mnem' is used to represent the mnemonic, so we always want to strip it
194    ; from the syntax string, regardless of the setting of `strip-mnemonic?'.
195    (compute-syntax #t #f syntax op isa-name-list)
196    " } }")
197 )
198 \f
199 ; Instruction format table support.
200
201 ; Return the table for IFMT, an <iformat> object.
202
203 (define (/gen-ifmt-table-1 ifmt)
204   (gen-obj-sanitize
205    (ifmt-eg-insn ifmt) ; sanitize based on the example insn
206    (string-list
207     "static const CGEN_IFMT " (gen-sym ifmt) " ATTRIBUTE_UNUSED = {\n"
208     "  "
209     (number->string (ifmt-mask-length ifmt)) ", "
210     (number->string (ifmt-length ifmt)) ", "
211     "0x" (number->string (ifmt-mask ifmt) 16) ", "
212     "{ "
213     (string-list-map (lambda (ifld)
214                        (string-list "{ F (" (ifld-enum ifld #f) ") }, "))
215                      (ifmt-ifields ifmt))
216     "{ 0 } }\n};\n\n"))
217 )
218
219 ; Generate the insn format table.
220
221 (define (/gen-ifmt-table)
222   (string-write
223    "/* Instruction formats.  */\n\n"
224    (gen-define-with-symcat "F(f) & @arch@_cgen_ifld_table[@ARCH@_" "f]")
225    (string-list-map /gen-ifmt-table-1 (current-ifmt-list))
226    "#undef F\n\n"
227    )
228 )
229 \f
230 ; Parse/insert/extract/print handlers.
231 ; Each handler type is recorded in the assembler/disassembler as an array of
232 ; pointers to functions.  The value recorded in the operand table is the index
233 ; into this array. The first element in the array is reserved as index 0 is
234 ; special (the "default").
235 ;
236 ; The handlers are recorded here as associative lists in case we ever want
237 ; to record more than just the name.
238 ;
239 ; Adding a new handler involves
240 ; - specifying its name in the .cpu file
241 ; - getting its name appended to these tables
242 ; - writing the C code
243 ;
244 ; ??? It might be useful to define the handler in Scheme.  Later.
245
246 (define opc-parse-handlers '((insn-normal)))
247 (define opc-insert-handlers '((insn-normal)))
248 (define opc-extract-handlers '((insn-normal)))
249 (define opc-print-handlers '((insn-normal)))
250
251 ; FIXME: There currently isn't a spot for specifying special handlers for
252 ; each instruction.  For now assume we always use the same ones.
253
254 (define (insn-handlers insn)
255   (string-append
256    (number->string (assq-lookup-index 'insn-normal opc-parse-handlers 0))
257    ", "
258    (number->string (assq-lookup-index 'insn-normal opc-insert-handlers 0))
259    ", "
260    (number->string (assq-lookup-index 'insn-normal opc-extract-handlers 0))
261    ", "
262    (number->string (assq-lookup-index 'insn-normal opc-print-handlers 0))
263    )
264 )
265
266 ; Return C code to define the cgen_opcode_handler struct for INSN.
267 ; This is intended to be the ultimate escape hatch for the parse/insert/
268 ; extract/print handlers.  Each entry is an index into a table of handlers.
269 ; The escape hatch isn't used yet.
270
271 (define (gen-insn-handlers insn)
272   (string-append
273    "{ "
274    (insn-handlers insn)
275    " }"
276    )
277 )
278
279 ; Handler table support.
280 ; There are tables for each of parse/insert/extract/print.
281
282 ; Return C code to define the handler table for NAME with values VALUES.
283
284 (define (gen-handler-table name values)
285   (string-append
286    "cgen_" name "_fn * const @arch@_cgen_" name "_handlers[] = \n{\n"
287    (string-map (lambda (elm)
288                  (string-append "  " name "_"
289                                 (gen-c-symbol (car elm))
290                                 ",\n"))
291                values)
292    "};\n\n"
293    )
294 )
295 \f
296 ; Instruction table support.
297
298 ; Return a declaration of an enum for all insns.
299
300 (define (/gen-insn-enum)
301   (logit 2 "Generating instruction enum ...\n")
302   (let ((insns (gen-obj-list-enums (non-multi-insns (current-insn-list)))))
303     (string-list
304      (gen-enum-decl 'cgen_insn_type "@arch@ instruction types"
305                     "@ARCH@_INSN_"
306                     (cons '(invalid) insns))
307      "/* Index of `invalid' insn place holder.  */\n"
308      "#define CGEN_INSN_INVALID @ARCH@_INSN_INVALID\n\n"
309      "/* Total number of insns in table.  */\n"
310      "#define MAX_INSNS ((int) @ARCH@_INSN_"
311      (string-upcase (gen-c-symbol (caar (list-take -1 insns)))) " + 1)\n\n"
312    )
313   )
314 )
315
316 ; Return a reference to the format table entry of INSN.
317
318 (define (gen-ifmt-entry insn)
319   (string-append "& " (gen-sym (insn-ifmt insn)))
320 )
321
322 ; Return the definition of an instruction value entry.
323
324 (define (gen-ivalue-entry insn)
325   (string-list "{ "
326                "0x" (number->string (insn-value insn) 16)
327                (if #f ; (ifmt-opcodes-beyond-base? (insn-ifmt insn))
328                    (string-list ", { "
329                                 ; ??? wip: opcode values beyond the base insn
330                                 "0 }")
331                    "")
332                " }")
333 )
334
335 ; Generate an insn opcode entry for INSN.
336 ; ALL-ATTRS is a list of all instruction attributes.
337 ; NUM-NON-BOOLS is the number of non-boolean insn attributes.
338
339 (define (/gen-insn-opcode-entry insn all-attrs num-non-bools)
340   (gen-obj-sanitize
341    insn
342    (string-list
343     "/* " (insn-syntax insn) " */\n"
344     "  {\n"
345     "    " (gen-insn-handlers insn) ",\n"
346     "    "
347     (gen-syntax-entry "MNEM" "OP" (insn-syntax insn) (obj-isa-list insn))
348     ",\n"
349     ; ??? 'twould save space to put a pointer here and record format separately
350     "    " (gen-ifmt-entry insn) ", "
351     ;"0x" (number->string (insn-value insn) 16) ",\n"
352     (gen-ivalue-entry insn) "\n"
353     "  },\n"))
354 )
355
356 ; Generate insn table.
357
358 (define (/gen-insn-opcode-table)
359   (logit 2 "Generating instruction opcode table ...\n")
360   (let* ((all-attrs (current-insn-attr-list))
361          (num-non-bools (attr-count-non-bools all-attrs)))
362     (string-write
363      (gen-define-with-symcat "A(a) (1 << CGEN_INSN_" "a)")
364      (gen-define-with-symcat "OPERAND(op) @ARCH@_OPERAND_" "op")
365      "\
366 #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
367 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
368
369 /* The instruction table.  */
370
371 static const CGEN_OPCODE @arch@_cgen_insn_opcode_table[MAX_INSNS] =
372 {
373   /* Special null first entry.
374      A `num' value of zero is thus invalid.
375      Also, the special `invalid' insn resides here.  */
376   { { 0, 0, 0, 0 }, {{0}}, 0, {0}},\n"
377
378      (lambda ()
379        (string-write-map (lambda (insn)
380                            (logit 3 "Generating insn opcode entry for " (obj:name insn) " ...\n")
381                            (/gen-insn-opcode-entry insn all-attrs
382                                                    num-non-bools))
383                          (non-multi-insns (current-insn-list))))
384
385      "\
386 };
387
388 #undef A
389 #undef OPERAND
390 #undef MNEM
391 #undef OP
392
393 "
394      )
395     )
396 )
397 \f
398 ; Return assembly/disassembly hashing support.
399
400 (define (/gen-hash-fns)
401   (string-list
402    "\
403 #ifndef CGEN_ASM_HASH_P
404 #define CGEN_ASM_HASH_P(insn) 1
405 #endif
406
407 #ifndef CGEN_DIS_HASH_P
408 #define CGEN_DIS_HASH_P(insn) 1
409 #endif
410
411 /* Return non-zero if INSN is to be added to the hash table.
412    Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file.  */
413
414 static int
415 asm_hash_insn_p (insn)
416      const CGEN_INSN *insn ATTRIBUTE_UNUSED;
417 {
418   return CGEN_ASM_HASH_P (insn);
419 }
420
421 static int
422 dis_hash_insn_p (insn)
423      const CGEN_INSN *insn;
424 {
425   /* If building the hash table and the NO-DIS attribute is present,
426      ignore.  */
427   if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS))
428     return 0;
429   return CGEN_DIS_HASH_P (insn);
430 }
431
432 #ifndef CGEN_ASM_HASH
433 #define CGEN_ASM_HASH_SIZE 127
434 #ifdef CGEN_MNEMONIC_OPERANDS
435 #define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE)
436 #else
437 #define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/
438 #endif
439 #endif
440
441 /* It doesn't make much sense to provide a default here,
442    but while this is under development we do.
443    BUFFER is a pointer to the bytes of the insn, target order.
444    VALUE is the first base_insn_bitsize bits as an int in host order.  */
445
446 #ifndef CGEN_DIS_HASH
447 #define CGEN_DIS_HASH_SIZE 256
448 #define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf))
449 #endif
450
451 /* The result is the hash value of the insn.
452    Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file.  */
453
454 static unsigned int
455 asm_hash_insn (mnem)
456      const char * mnem;
457 {
458   return CGEN_ASM_HASH (mnem);
459 }
460
461 /* BUF is a pointer to the bytes of the insn, target order.
462    VALUE is the first base_insn_bitsize bits as an int in host order.  */
463
464 static unsigned int
465 dis_hash_insn (buf, value)
466      const char * buf ATTRIBUTE_UNUSED;
467      CGEN_INSN_INT value ATTRIBUTE_UNUSED;
468 {
469   return CGEN_DIS_HASH (buf, value);
470 }
471 \n"
472    )
473 )
474
475 ; Hash support decls.
476
477 (define (/gen-hash-decls)
478   (string-list
479    "\
480 /* The hash functions are recorded here to help keep assembler code out of
481    the disassembler and vice versa.  */
482
483 static int asm_hash_insn_p        (const CGEN_INSN *);
484 static unsigned int asm_hash_insn (const char *);
485 static int dis_hash_insn_p        (const CGEN_INSN *);
486 static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT);
487 \n"
488    )
489 )
490 \f
491 ; Macro insn support.
492
493 ; Return a macro-insn expansion entry.
494
495 (define (/gen-miexpn-entry entry)
496    ; FIXME: wip
497   "0, "
498 )
499
500 ; Return a macro-insn table entry.
501 ; ??? wip, not currently used.
502
503 (define (/gen-minsn-table-entry minsn all-attrs num-non-bools)
504   (gen-obj-sanitize
505    minsn
506    (string-list
507     "  /* " (minsn-syntax minsn) " */\n"
508     "  {\n"
509     "    "
510     "-1, " ; macro-insns are not currently enumerated, no current need to
511     "\"" (obj:str-name minsn) "\", "
512     "\"" (minsn-mnemonic minsn) "\",\n"
513     "    "
514     (gen-syntax-entry "MNEM" "OP" (minsn-syntax minsn) (obj-isa-list minsn))
515     ",\n"
516     "    (PTR) & macro_" (gen-sym minsn) "_expansions[0],\n"
517     "    "
518     (gen-obj-attr-defn 'minsn minsn all-attrs num-non-bools gen-insn-attr-mask)
519     "\n"
520     "  },\n"))
521 )
522
523 ; Return a macro-insn opcode table entry.
524 ; ??? wip, not currently used.
525
526 (define (/gen-minsn-opcode-entry minsn all-attrs num-non-bools)
527   (gen-obj-sanitize
528    minsn
529    (string-list
530     "  /* " (minsn-syntax minsn) " */\n"
531     "  {\n"
532     "    "
533     "-1, " ; macro-insns are not currently enumerated, no current need to
534     "\"" (obj:str-name minsn) "\", "
535     "\"" (minsn-mnemonic minsn) "\",\n"
536     "    "
537     (gen-syntax-entry "MNEM" "OP" (minsn-syntax minsn) (obj-isa-list minsn))
538     ",\n"
539     "    (PTR) & macro_" (gen-sym minsn) "_expansions[0],\n"
540     "    "
541     (gen-obj-attr-defn 'minsn minsn all-attrs num-non-bools gen-insn-attr-mask)
542     "\n"
543     "  },\n"))
544 )
545
546 ; Macro insn expansion has one basic form, but we optimize the common case
547 ; of unconditionally expanding the input text to one instruction.
548 ; The general form is a Scheme expression that is interpreted at runtime to
549 ; decide how to perform the expansion.  Yes, that means having a (perhaps
550 ; minimal) Scheme interpreter in the assembler.
551 ; Another thing to do is have a builder for each real insn so instead of
552 ; expanding to text, the macro-expansion could invoke the builder for each
553 ; expanded-to insn.
554
555 (define (/gen-macro-insn-table)
556   (logit 2 "Generating macro-instruction table ...\n")
557   (let* ((minsn-list (map (lambda (minsn)
558                             (if (has-attr? minsn 'ALIAS)
559                                 (minsn-make-alias (make-prefix-context "gen-macro-insn-table")
560                                                   minsn)
561                                 minsn))
562                           (current-minsn-list)))
563          (all-attrs (current-insn-attr-list))
564          (num-non-bools (attr-count-non-bools all-attrs)))
565     (string-write
566      "/* Formats for ALIAS macro-insns.  */\n\n"
567      (gen-define-with-symcat "F(f) & @arch@_cgen_ifld_table[@ARCH@_" "f]")
568      (lambda ()
569        (string-write-map /gen-ifmt-table-1
570                          (map insn-ifmt (find (lambda (minsn)
571                                                 (has-attr? minsn 'ALIAS))
572                                               minsn-list))))
573      "#undef F\n\n"
574      "/* Each non-simple macro entry points to an array of expansion possibilities.  */\n\n"
575      (lambda () 
576        (string-write-map (lambda (minsn)
577                            (if (has-attr? minsn 'ALIAS)
578                                ""
579                                (string-append
580                                 "static const CGEN_MINSN_EXPANSION macro_" (gen-sym minsn) "_expansions[] =\n"
581                                 "{\n"
582                                 (string-map /gen-miexpn-entry
583                                             (minsn-expansions minsn))
584                                 "  { 0, 0 }\n};\n\n")))
585                          minsn-list))
586      (gen-define-with-symcat "A(a) (1 << CGEN_INSN_" "a)")
587      (gen-define-with-symcat "OPERAND(op) @ARCH@_OPERAND_" "op")
588      "\
589 #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
590 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
591
592 /* The macro instruction table.  */
593
594 static const CGEN_IBASE @arch@_cgen_macro_insn_table[] =
595 {
596 "
597      (lambda ()
598        (string-write-map (lambda (minsn)
599                            (logit 3 "Generating macro-insn table entry for " (obj:name minsn) " ...\n")
600                            ; Simple macro-insns are emitted as aliases of real insns.
601                            (if (has-attr? minsn 'ALIAS)
602                                (gen-insn-table-entry minsn all-attrs num-non-bools)
603                                (/gen-minsn-table-entry minsn all-attrs num-non-bools)))
604                          minsn-list))
605      "\
606 };
607
608 /* The macro instruction opcode table.  */
609
610 static const CGEN_OPCODE @arch@_cgen_macro_insn_opcode_table[] =
611 {\n"
612      (lambda ()
613        (string-write-map (lambda (minsn)
614                            (logit 3 "Generating macro-insn table entry for " (obj:name minsn) " ...\n")
615                            ; Simple macro-insns are emitted as aliases of real insns.
616                            (if (has-attr? minsn 'ALIAS)
617                                (/gen-insn-opcode-entry minsn all-attrs num-non-bools)
618                                (/gen-minsn-opcode-entry minsn all-attrs num-non-bools)))
619                          minsn-list))
620      "\
621 };
622
623 #undef A
624 #undef OPERAND
625 #undef MNEM
626 #undef OP
627 \n"
628     ))
629 )
630 \f
631 ; Emit a function to call to initialize the opcode table.
632
633 (define (/gen-opcode-init-fn)
634   (string-write
635    "\
636 /* Set the recorded length of the insn in the CGEN_FIELDS struct.  */
637
638 static void
639 set_fields_bitsize (CGEN_FIELDS *fields, int size)
640 {
641   CGEN_FIELDS_BITSIZE (fields) = size;
642 }
643
644 /* Function to call before using the operand instance table.
645    This plugs the opcode entries and macro instructions into the cpu table.  */
646
647 void
648 @arch@_cgen_init_opcode_table (CGEN_CPU_DESC cd)
649 {
650   int i;
651   int num_macros = (sizeof (@arch@_cgen_macro_insn_table) /
652                     sizeof (@arch@_cgen_macro_insn_table[0]));
653   const CGEN_IBASE *ib = & @arch@_cgen_macro_insn_table[0];
654   const CGEN_OPCODE *oc = & @arch@_cgen_macro_insn_opcode_table[0];
655   CGEN_INSN *insns = xmalloc (num_macros * sizeof (CGEN_INSN));
656
657   /* This test has been added to avoid a warning generated
658      if memset is called with a third argument of value zero.  */
659   if (num_macros >= 1)
660     memset (insns, 0, num_macros * sizeof (CGEN_INSN));
661   for (i = 0; i < num_macros; ++i)
662     {
663       insns[i].base = &ib[i];
664       insns[i].opcode = &oc[i];
665       @arch@_cgen_build_insn_regex (& insns[i]);
666     }
667   cd->macro_insn_table.init_entries = insns;
668   cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
669   cd->macro_insn_table.num_init_entries = num_macros;
670
671   oc = & @arch@_cgen_insn_opcode_table[0];
672   insns = (CGEN_INSN *) cd->insn_table.init_entries;
673   for (i = 0; i < MAX_INSNS; ++i)
674     {
675       insns[i].opcode = &oc[i];
676       @arch@_cgen_build_insn_regex (& insns[i]);
677     }
678
679   cd->sizeof_fields = sizeof (CGEN_FIELDS);
680   cd->set_fields_bitsize = set_fields_bitsize;
681
682   cd->asm_hash_p = asm_hash_insn_p;
683   cd->asm_hash = asm_hash_insn;
684   cd->asm_hash_size = CGEN_ASM_HASH_SIZE;
685
686   cd->dis_hash_p = dis_hash_insn_p;
687   cd->dis_hash = dis_hash_insn;
688   cd->dis_hash_size = CGEN_DIS_HASH_SIZE;
689 }
690 "
691    )
692 )
693 \f
694 ; Top level C code generators
695
696 ; FIXME: Create enum objects for all the enums we explicitly declare here.
697 ; Then they'd be usable and we wouldn't have to special case them here.
698
699 (define (cgen-opc.h)
700   (logit 1 "Generating " (current-arch-name) "-opc.h ...\n")
701   (string-write
702    (gen-c-copyright "Instruction opcode header for @arch@."
703                   CURRENT-COPYRIGHT CURRENT-PACKAGE)
704    "\
705 #ifndef @ARCH@_OPC_H
706 #define @ARCH@_OPC_H
707
708 "
709    (lambda () (gen-extra-opc.h (opc-file-path) (current-arch-name)))
710    /gen-insn-enum
711    /gen-ifield-decls
712    /gen-init-macros
713    "
714
715 #endif /* @ARCH@_OPC_H */
716 "
717    )
718 )
719
720 ; This file contains the instruction opcode table.
721
722 (define (cgen-opc.c)
723   (logit 1 "Generating " (current-arch-name) "-opc.c ...\n")
724   (string-write
725    (gen-c-copyright "Instruction opcode table for @arch@."
726                   CURRENT-COPYRIGHT CURRENT-PACKAGE)
727    "\
728 #include \"sysdep.h\"
729 #include \"ansidecl.h\"
730 #include \"bfd.h\"
731 #include \"symcat.h\"
732 #include \"@prefix@-desc.h\"
733 #include \"@prefix@-opc.h\"
734 #include \"libiberty.h\"
735 \n"
736    (lambda () (gen-extra-opc.c (opc-file-path) (current-arch-name)))
737    /gen-hash-decls
738    /gen-ifmt-table
739    /gen-insn-opcode-table
740    /gen-macro-insn-table
741    /gen-hash-fns
742    /gen-opcode-init-fn
743    )
744 )