OSDN Git Service

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