OSDN Git Service

gdb/testsuite/
[pf3gnuchains/pf3gnuchains3x.git] / cgen / opc-ibld.scm
1 ; Instruction builder support.
2 ; Copyright (C) 2000, 2001, 2005, 2009 Red Hat, Inc.
3 ; This file is part of CGEN.
4
5 ; Instruction field support.
6
7 (define (/gen-fget-switch)
8   (logit 2 "Generating field get switch ...\n")
9   (string-list
10    "\
11 int @arch@_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
12 bfd_vma @arch@_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
13
14 /* Getting values from cgen_fields is handled by a collection of functions.
15    They are distinguished by the type of the VALUE argument they return.
16    TODO: floating point, inlining support, remove cases where result type
17    not appropriate.  */
18
19 int
20 @arch@_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
21                              int opindex,
22                              const CGEN_FIELDS * fields)
23 {
24   int value;
25
26   switch (opindex)
27     {
28 "
29    (gen-switch 'fget)
30 "
31     default :
32       /* xgettext:c-format */
33       fprintf (stderr, _(\"Unrecognized field %d while getting int operand.\\n\"),
34                        opindex);
35       abort ();
36   }
37
38   return value;
39 }
40
41 bfd_vma
42 @arch@_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
43                              int opindex,
44                              const CGEN_FIELDS * fields)
45 {
46   bfd_vma value;
47
48   switch (opindex)
49     {
50 "
51    (gen-switch 'fget)
52 "
53     default :
54       /* xgettext:c-format */
55       fprintf (stderr, _(\"Unrecognized field %d while getting vma operand.\\n\"),
56                        opindex);
57       abort ();
58   }
59
60   return value;
61 }
62 \n")
63 )
64
65 (define (/gen-fset-switch)
66   (logit 2 "Generating field set switch ...\n")
67   (string-list
68    "\
69 void @arch@_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
70 void @arch@_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
71
72 /* Stuffing values in cgen_fields is handled by a collection of functions.
73    They are distinguished by the type of the VALUE argument they accept.
74    TODO: floating point, inlining support, remove cases where argument type
75    not appropriate.  */
76
77 void
78 @arch@_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
79                              int opindex,
80                              CGEN_FIELDS * fields,
81                              int value)
82 {
83   switch (opindex)
84     {
85 "
86    (gen-switch 'fset)
87 "
88     default :
89       /* xgettext:c-format */
90       fprintf (stderr, _(\"Unrecognized field %d while setting int operand.\\n\"),
91                        opindex);
92       abort ();
93   }
94 }
95
96 void
97 @arch@_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
98                              int opindex,
99                              CGEN_FIELDS * fields,
100                              bfd_vma value)
101 {
102   switch (opindex)
103     {
104 "
105    (gen-switch 'fset)
106 "
107     default :
108       /* xgettext:c-format */
109       fprintf (stderr, _(\"Unrecognized field %d while setting vma operand.\\n\"),
110                        opindex);
111       abort ();
112   }
113 }
114 \n")
115 )
116 \f
117 ; Utilities of cgen-ibld.h.
118
119 ; Return a list of operands the assembler syntax uses.
120 ; This is a subset of the fields of the insn.
121
122 (define (ifmt-opcode-operands ifmt)
123   (map ifld-get-value
124        (find (lambda (elm) (not (number? (ifld-get-value elm))))
125              (ifmt-ifields ifmt)))
126 )
127
128 ; Subroutine of gen-insn-builders to generate the builder for one insn.
129 ; FIXME: wip.
130
131 (define (gen-insn-builder insn)
132   (let* ((ifmt (insn-ifmt insn))
133          (operands (ifmt-opcode-operands ifmt))
134          (length (ifmt-length ifmt)))
135     (gen-obj-sanitize
136      insn
137      (string-append
138       "#define @ARCH@_IBLD_"
139       (string-upcase (gen-sym insn))
140       "(endian, buf, lenp"
141       (gen-c-args (map gen-sym operands))
142       ")\n"
143       "\n")))
144 )
145
146 (define (gen-insn-builders)
147   (string-write
148    "\
149 /* For each insn there is an @ARCH@_IBLD_<NAME> macro that builds the
150    instruction in the supplied buffer.  For architectures where it's
151    possible to represent all machine codes as host integer values it
152    would be nicer to have these return the instruction rather than store
153    it in BUF.  For consistency with variable length ISA's this does not.  */
154
155 "
156    (lambda () (string-write-map gen-insn-builder (current-insn-list)))
157    )
158 )
159 \f
160 ; Generate the C code for dealing with operands.
161
162 (define (/gen-insert-switch)
163   (logit 2 "Generating insert switch ...\n")
164   (string-list
165    "\
166 const char * @arch@_cgen_insert_operand
167   (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
168
169 /* Main entry point for operand insertion.
170
171    This function is basically just a big switch statement.  Earlier versions
172    used tables to look up the function to use, but
173    - if the table contains both assembler and disassembler functions then
174      the disassembler contains much of the assembler and vice-versa,
175    - there's a lot of inlining possibilities as things grow,
176    - using a switch statement avoids the function call overhead.
177
178    This function could be moved into `parse_insn_normal', but keeping it
179    separate makes clear the interface between `parse_insn_normal' and each of
180    the handlers.  It's also needed by GAS to insert operands that couldn't be
181    resolved during parsing.  */
182
183 const char *
184 @arch@_cgen_insert_operand (CGEN_CPU_DESC cd,
185                              int opindex,
186                              CGEN_FIELDS * fields,
187                              CGEN_INSN_BYTES_PTR buffer,
188                              bfd_vma pc ATTRIBUTE_UNUSED)
189 {
190   const char * errmsg = NULL;
191   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
192
193   switch (opindex)
194     {
195 "
196    (gen-switch 'insert)
197 "
198     default :
199       /* xgettext:c-format */
200       fprintf (stderr, _(\"Unrecognized field %d while building insn.\\n\"),
201                opindex);
202       abort ();
203   }
204
205   return errmsg;
206 }\n\n")
207 )
208
209 (define (/gen-extract-switch)
210   (logit 2 "Generating extract switch ...\n")
211   (string-list
212    "\
213 int @arch@_cgen_extract_operand
214   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
215
216 /* Main entry point for operand extraction.
217    The result is <= 0 for error, >0 for success.
218    ??? Actual values aren't well defined right now.
219
220    This function is basically just a big switch statement.  Earlier versions
221    used tables to look up the function to use, but
222    - if the table contains both assembler and disassembler functions then
223      the disassembler contains much of the assembler and vice-versa,
224    - there's a lot of inlining possibilities as things grow,
225    - using a switch statement avoids the function call overhead.
226
227    This function could be moved into `print_insn_normal', but keeping it
228    separate makes clear the interface between `print_insn_normal' and each of
229    the handlers.  */
230
231 int
232 @arch@_cgen_extract_operand (CGEN_CPU_DESC cd,
233                              int opindex,
234                              CGEN_EXTRACT_INFO *ex_info,
235                              CGEN_INSN_INT insn_value,
236                              CGEN_FIELDS * fields,
237                              bfd_vma pc)
238 {
239   /* Assume success (for those operands that are nops).  */
240   int length = 1;
241   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
242
243   switch (opindex)
244     {
245 "
246    (gen-switch 'extract)
247 "
248     default :
249       /* xgettext:c-format */
250       fprintf (stderr, _(\"Unrecognized field %d while decoding insn.\\n\"),
251                opindex);
252       abort ();
253     }
254
255   return length;
256 }\n\n")
257 )
258 \f
259 ; Utilities of cgen-ibld.in.
260
261 ; Emit a function to call to initialize the ibld tables.
262
263 (define (/gen-ibld-init-fn)
264   (string-write
265    "\
266 /* Function to call before using the instruction builder tables.  */
267
268 void
269 @arch@_cgen_init_ibld_table (CGEN_CPU_DESC cd)
270 {
271   cd->insert_handlers = & @arch@_cgen_insert_handlers[0];
272   cd->extract_handlers = & @arch@_cgen_extract_handlers[0];
273
274   cd->insert_operand = @arch@_cgen_insert_operand;
275   cd->extract_operand = @arch@_cgen_extract_operand;
276
277   cd->get_int_operand = @arch@_cgen_get_int_operand;
278   cd->set_int_operand = @arch@_cgen_set_int_operand;
279   cd->get_vma_operand = @arch@_cgen_get_vma_operand;
280   cd->set_vma_operand = @arch@_cgen_set_vma_operand;
281 }
282 "
283    )
284 )
285 \f
286 ; Generate the C header for building instructions.
287
288 (define (cgen-ibld.h)
289   (logit 1 "Generating " (current-arch-name) "-ibld.h ...\n")
290   (string-write
291    (gen-c-copyright "Instruction builder for @arch@."
292                   CURRENT-COPYRIGHT CURRENT-PACKAGE)
293    "\
294 #ifndef @ARCH@_IBLD_H
295 #define @ARCH@_IBLD_H
296
297 "
298    (lambda () (gen-extra-ibld.h (opc-file-path) (current-arch-name)))
299    "\n"
300    gen-insn-builders
301    "
302 #endif /* @ARCH@_IBLD_H */
303 "
304    )
305 )
306
307 ; Generate the C support for building instructions.
308
309 (define (cgen-ibld.in)
310   (logit 1 "Generating " (current-arch-name) "-ibld.in ...\n")
311   (string-write
312    ; No need for copyright, appended to file with one.
313    "\n"
314    /gen-insert-switch
315    /gen-extract-switch
316    (lambda () (gen-handler-table "insert" opc-insert-handlers))
317    (lambda () (gen-handler-table "extract" opc-extract-handlers))
318    /gen-fget-switch
319    /gen-fset-switch
320    /gen-ibld-init-fn
321    )
322 )