epiphany-ibld.c revision 1.1.1.3 1 1.1 christos /* Instruction building/extraction support for epiphany. -*- C -*-
2 1.1 christos
3 1.1 christos THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4 1.1 christos - the resultant file is machine generated, cgen-ibld.in isn't
5 1.1 christos
6 1.1.1.3 christos Copyright (C) 1996-2016 Free Software Foundation, Inc.
7 1.1 christos
8 1.1 christos This file is part of libopcodes.
9 1.1 christos
10 1.1 christos This library is free software; you can redistribute it and/or modify
11 1.1 christos it under the terms of the GNU General Public License as published by
12 1.1 christos the Free Software Foundation; either version 3, or (at your option)
13 1.1 christos any later version.
14 1.1 christos
15 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
16 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 1.1 christos License for more details.
19 1.1 christos
20 1.1 christos You should have received a copy of the GNU General Public License
21 1.1 christos along with this program; if not, write to the Free Software Foundation, Inc.,
22 1.1 christos 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23 1.1 christos
24 1.1 christos /* ??? Eventually more and more of this stuff can go to cpu-independent files.
25 1.1 christos Keep that in mind. */
26 1.1 christos
27 1.1 christos #include "sysdep.h"
28 1.1 christos #include <stdio.h>
29 1.1 christos #include "ansidecl.h"
30 1.1 christos #include "dis-asm.h"
31 1.1 christos #include "bfd.h"
32 1.1 christos #include "symcat.h"
33 1.1 christos #include "epiphany-desc.h"
34 1.1 christos #include "epiphany-opc.h"
35 1.1 christos #include "cgen/basic-modes.h"
36 1.1 christos #include "opintl.h"
37 1.1 christos #include "safe-ctype.h"
38 1.1 christos
39 1.1 christos #undef min
40 1.1 christos #define min(a,b) ((a) < (b) ? (a) : (b))
41 1.1 christos #undef max
42 1.1 christos #define max(a,b) ((a) > (b) ? (a) : (b))
43 1.1 christos
44 1.1 christos /* Used by the ifield rtx function. */
45 1.1 christos #define FLD(f) (fields->f)
46 1.1 christos
47 1.1 christos static const char * insert_normal
48 1.1 christos (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
49 1.1 christos unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
50 1.1 christos static const char * insert_insn_normal
51 1.1 christos (CGEN_CPU_DESC, const CGEN_INSN *,
52 1.1 christos CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
53 1.1 christos static int extract_normal
54 1.1 christos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
55 1.1 christos unsigned int, unsigned int, unsigned int, unsigned int,
56 1.1 christos unsigned int, unsigned int, bfd_vma, long *);
57 1.1 christos static int extract_insn_normal
58 1.1 christos (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59 1.1 christos CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
60 1.1 christos #if CGEN_INT_INSN_P
61 1.1 christos static void put_insn_int_value
62 1.1 christos (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
63 1.1 christos #endif
64 1.1 christos #if ! CGEN_INT_INSN_P
65 1.1 christos static CGEN_INLINE void insert_1
66 1.1 christos (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
67 1.1 christos static CGEN_INLINE int fill_cache
68 1.1 christos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
69 1.1 christos static CGEN_INLINE long extract_1
70 1.1 christos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
71 1.1 christos #endif
72 1.1 christos
73 1.1 christos /* Operand insertion. */
75 1.1 christos
76 1.1 christos #if ! CGEN_INT_INSN_P
77 1.1 christos
78 1.1 christos /* Subroutine of insert_normal. */
79 1.1 christos
80 1.1 christos static CGEN_INLINE void
81 1.1 christos insert_1 (CGEN_CPU_DESC cd,
82 1.1 christos unsigned long value,
83 1.1 christos int start,
84 1.1 christos int length,
85 1.1 christos int word_length,
86 1.1 christos unsigned char *bufp)
87 1.1 christos {
88 1.1 christos unsigned long x,mask;
89 1.1 christos int shift;
90 1.1 christos
91 1.1 christos x = cgen_get_insn_value (cd, bufp, word_length);
92 1.1 christos
93 1.1 christos /* Written this way to avoid undefined behaviour. */
94 1.1 christos mask = (((1L << (length - 1)) - 1) << 1) | 1;
95 1.1 christos if (CGEN_INSN_LSB0_P)
96 1.1 christos shift = (start + 1) - length;
97 1.1 christos else
98 1.1 christos shift = (word_length - (start + length));
99 1.1 christos x = (x & ~(mask << shift)) | ((value & mask) << shift);
100 1.1 christos
101 1.1 christos cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
102 1.1 christos }
103 1.1 christos
104 1.1 christos #endif /* ! CGEN_INT_INSN_P */
105 1.1 christos
106 1.1 christos /* Default insertion routine.
107 1.1 christos
108 1.1 christos ATTRS is a mask of the boolean attributes.
109 1.1 christos WORD_OFFSET is the offset in bits from the start of the insn of the value.
110 1.1 christos WORD_LENGTH is the length of the word in bits in which the value resides.
111 1.1 christos START is the starting bit number in the word, architecture origin.
112 1.1 christos LENGTH is the length of VALUE in bits.
113 1.1 christos TOTAL_LENGTH is the total length of the insn in bits.
114 1.1 christos
115 1.1 christos The result is an error message or NULL if success. */
116 1.1 christos
117 1.1 christos /* ??? This duplicates functionality with bfd's howto table and
118 1.1 christos bfd_install_relocation. */
119 1.1 christos /* ??? This doesn't handle bfd_vma's. Create another function when
120 1.1 christos necessary. */
121 1.1 christos
122 1.1 christos static const char *
123 1.1 christos insert_normal (CGEN_CPU_DESC cd,
124 1.1 christos long value,
125 1.1 christos unsigned int attrs,
126 1.1 christos unsigned int word_offset,
127 1.1 christos unsigned int start,
128 1.1 christos unsigned int length,
129 1.1 christos unsigned int word_length,
130 1.1 christos unsigned int total_length,
131 1.1 christos CGEN_INSN_BYTES_PTR buffer)
132 1.1 christos {
133 1.1 christos static char errbuf[100];
134 1.1 christos /* Written this way to avoid undefined behaviour. */
135 1.1 christos unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
136 1.1 christos
137 1.1 christos /* If LENGTH is zero, this operand doesn't contribute to the value. */
138 1.1 christos if (length == 0)
139 1.1 christos return NULL;
140 1.1 christos
141 1.1 christos if (word_length > 8 * sizeof (CGEN_INSN_INT))
142 1.1 christos abort ();
143 1.1 christos
144 1.1 christos /* For architectures with insns smaller than the base-insn-bitsize,
145 1.1 christos word_length may be too big. */
146 1.1 christos if (cd->min_insn_bitsize < cd->base_insn_bitsize)
147 1.1 christos {
148 1.1 christos if (word_offset == 0
149 1.1 christos && word_length > total_length)
150 1.1 christos word_length = total_length;
151 1.1 christos }
152 1.1 christos
153 1.1 christos /* Ensure VALUE will fit. */
154 1.1 christos if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
155 1.1 christos {
156 1.1 christos long minval = - (1L << (length - 1));
157 1.1.1.3 christos unsigned long maxval = mask;
158 1.1 christos
159 1.1 christos if ((value > 0 && (unsigned long) value > maxval)
160 1.1 christos || value < minval)
161 1.1 christos {
162 1.1 christos /* xgettext:c-format */
163 1.1 christos sprintf (errbuf,
164 1.1 christos _("operand out of range (%ld not between %ld and %lu)"),
165 1.1 christos value, minval, maxval);
166 1.1 christos return errbuf;
167 1.1 christos }
168 1.1 christos }
169 1.1 christos else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
170 1.1 christos {
171 1.1 christos unsigned long maxval = mask;
172 1.1 christos unsigned long val = (unsigned long) value;
173 1.1 christos
174 1.1 christos /* For hosts with a word size > 32 check to see if value has been sign
175 1.1 christos extended beyond 32 bits. If so then ignore these higher sign bits
176 1.1 christos as the user is attempting to store a 32-bit signed value into an
177 1.1 christos unsigned 32-bit field which is allowed. */
178 1.1 christos if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
179 1.1 christos val &= 0xFFFFFFFF;
180 1.1 christos
181 1.1 christos if (val > maxval)
182 1.1 christos {
183 1.1 christos /* xgettext:c-format */
184 1.1 christos sprintf (errbuf,
185 1.1 christos _("operand out of range (0x%lx not between 0 and 0x%lx)"),
186 1.1 christos val, maxval);
187 1.1 christos return errbuf;
188 1.1 christos }
189 1.1 christos }
190 1.1 christos else
191 1.1 christos {
192 1.1 christos if (! cgen_signed_overflow_ok_p (cd))
193 1.1 christos {
194 1.1 christos long minval = - (1L << (length - 1));
195 1.1.1.3 christos long maxval = (1L << (length - 1)) - 1;
196 1.1 christos
197 1.1 christos if (value < minval || value > maxval)
198 1.1 christos {
199 1.1 christos sprintf
200 1.1 christos /* xgettext:c-format */
201 1.1 christos (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
202 1.1 christos value, minval, maxval);
203 1.1 christos return errbuf;
204 1.1 christos }
205 1.1 christos }
206 1.1 christos }
207 1.1 christos
208 1.1 christos #if CGEN_INT_INSN_P
209 1.1 christos
210 1.1.1.3 christos {
211 1.1 christos int shift_within_word, shift_to_word, shift;
212 1.1.1.3 christos
213 1.1.1.3 christos /* How to shift the value to BIT0 of the word. */
214 1.1.1.3 christos shift_to_word = total_length - (word_offset + word_length);
215 1.1.1.3 christos
216 1.1 christos /* How to shift the value to the field within the word. */
217 1.1.1.3 christos if (CGEN_INSN_LSB0_P)
218 1.1 christos shift_within_word = start + 1 - length;
219 1.1.1.3 christos else
220 1.1.1.3 christos shift_within_word = word_length - start - length;
221 1.1.1.3 christos
222 1.1.1.3 christos /* The total SHIFT, then mask in the value. */
223 1.1 christos shift = shift_to_word + shift_within_word;
224 1.1 christos *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
225 1.1 christos }
226 1.1 christos
227 1.1 christos #else /* ! CGEN_INT_INSN_P */
228 1.1 christos
229 1.1 christos {
230 1.1 christos unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
231 1.1 christos
232 1.1 christos insert_1 (cd, value, start, length, word_length, bufp);
233 1.1 christos }
234 1.1 christos
235 1.1 christos #endif /* ! CGEN_INT_INSN_P */
236 1.1 christos
237 1.1 christos return NULL;
238 1.1 christos }
239 1.1 christos
240 1.1 christos /* Default insn builder (insert handler).
241 1.1 christos The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
242 1.1 christos that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
243 1.1 christos recorded in host byte order, otherwise BUFFER is an array of bytes
244 1.1 christos and the value is recorded in target byte order).
245 1.1 christos The result is an error message or NULL if success. */
246 1.1 christos
247 1.1 christos static const char *
248 1.1 christos insert_insn_normal (CGEN_CPU_DESC cd,
249 1.1 christos const CGEN_INSN * insn,
250 1.1 christos CGEN_FIELDS * fields,
251 1.1 christos CGEN_INSN_BYTES_PTR buffer,
252 1.1 christos bfd_vma pc)
253 1.1 christos {
254 1.1 christos const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
255 1.1 christos unsigned long value;
256 1.1 christos const CGEN_SYNTAX_CHAR_TYPE * syn;
257 1.1 christos
258 1.1 christos CGEN_INIT_INSERT (cd);
259 1.1 christos value = CGEN_INSN_BASE_VALUE (insn);
260 1.1 christos
261 1.1 christos /* If we're recording insns as numbers (rather than a string of bytes),
262 1.1 christos target byte order handling is deferred until later. */
263 1.1 christos
264 1.1 christos #if CGEN_INT_INSN_P
265 1.1 christos
266 1.1 christos put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
267 1.1 christos CGEN_FIELDS_BITSIZE (fields), value);
268 1.1 christos
269 1.1 christos #else
270 1.1 christos
271 1.1 christos cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
272 1.1 christos (unsigned) CGEN_FIELDS_BITSIZE (fields)),
273 1.1 christos value);
274 1.1 christos
275 1.1 christos #endif /* ! CGEN_INT_INSN_P */
276 1.1 christos
277 1.1 christos /* ??? It would be better to scan the format's fields.
278 1.1 christos Still need to be able to insert a value based on the operand though;
279 1.1 christos e.g. storing a branch displacement that got resolved later.
280 1.1 christos Needs more thought first. */
281 1.1 christos
282 1.1 christos for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
283 1.1 christos {
284 1.1 christos const char *errmsg;
285 1.1 christos
286 1.1 christos if (CGEN_SYNTAX_CHAR_P (* syn))
287 1.1 christos continue;
288 1.1 christos
289 1.1 christos errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
290 1.1 christos fields, buffer, pc);
291 1.1 christos if (errmsg)
292 1.1 christos return errmsg;
293 1.1 christos }
294 1.1 christos
295 1.1 christos return NULL;
296 1.1 christos }
297 1.1 christos
298 1.1 christos #if CGEN_INT_INSN_P
299 1.1 christos /* Cover function to store an insn value into an integral insn. Must go here
300 1.1 christos because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
301 1.1 christos
302 1.1 christos static void
303 1.1 christos put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
304 1.1 christos CGEN_INSN_BYTES_PTR buf,
305 1.1 christos int length,
306 1.1 christos int insn_length,
307 1.1 christos CGEN_INSN_INT value)
308 1.1 christos {
309 1.1 christos /* For architectures with insns smaller than the base-insn-bitsize,
310 1.1 christos length may be too big. */
311 1.1 christos if (length > insn_length)
312 1.1 christos *buf = value;
313 1.1 christos else
314 1.1 christos {
315 1.1 christos int shift = insn_length - length;
316 1.1 christos /* Written this way to avoid undefined behaviour. */
317 1.1 christos CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
318 1.1 christos
319 1.1 christos *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
320 1.1 christos }
321 1.1 christos }
322 1.1 christos #endif
323 1.1 christos
324 1.1 christos /* Operand extraction. */
326 1.1 christos
327 1.1 christos #if ! CGEN_INT_INSN_P
328 1.1 christos
329 1.1 christos /* Subroutine of extract_normal.
330 1.1 christos Ensure sufficient bytes are cached in EX_INFO.
331 1.1 christos OFFSET is the offset in bytes from the start of the insn of the value.
332 1.1 christos BYTES is the length of the needed value.
333 1.1 christos Returns 1 for success, 0 for failure. */
334 1.1 christos
335 1.1 christos static CGEN_INLINE int
336 1.1 christos fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
337 1.1 christos CGEN_EXTRACT_INFO *ex_info,
338 1.1 christos int offset,
339 1.1 christos int bytes,
340 1.1 christos bfd_vma pc)
341 1.1 christos {
342 1.1 christos /* It's doubtful that the middle part has already been fetched so
343 1.1 christos we don't optimize that case. kiss. */
344 1.1 christos unsigned int mask;
345 1.1 christos disassemble_info *info = (disassemble_info *) ex_info->dis_info;
346 1.1 christos
347 1.1 christos /* First do a quick check. */
348 1.1 christos mask = (1 << bytes) - 1;
349 1.1 christos if (((ex_info->valid >> offset) & mask) == mask)
350 1.1 christos return 1;
351 1.1 christos
352 1.1 christos /* Search for the first byte we need to read. */
353 1.1 christos for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
354 1.1 christos if (! (mask & ex_info->valid))
355 1.1 christos break;
356 1.1 christos
357 1.1 christos if (bytes)
358 1.1 christos {
359 1.1 christos int status;
360 1.1 christos
361 1.1 christos pc += offset;
362 1.1 christos status = (*info->read_memory_func)
363 1.1 christos (pc, ex_info->insn_bytes + offset, bytes, info);
364 1.1 christos
365 1.1 christos if (status != 0)
366 1.1 christos {
367 1.1 christos (*info->memory_error_func) (status, pc, info);
368 1.1 christos return 0;
369 1.1 christos }
370 1.1 christos
371 1.1 christos ex_info->valid |= ((1 << bytes) - 1) << offset;
372 1.1 christos }
373 1.1 christos
374 1.1 christos return 1;
375 1.1 christos }
376 1.1 christos
377 1.1 christos /* Subroutine of extract_normal. */
378 1.1 christos
379 1.1 christos static CGEN_INLINE long
380 1.1 christos extract_1 (CGEN_CPU_DESC cd,
381 1.1 christos CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
382 1.1 christos int start,
383 1.1 christos int length,
384 1.1 christos int word_length,
385 1.1 christos unsigned char *bufp,
386 1.1 christos bfd_vma pc ATTRIBUTE_UNUSED)
387 1.1 christos {
388 1.1 christos unsigned long x;
389 1.1 christos int shift;
390 1.1 christos
391 1.1 christos x = cgen_get_insn_value (cd, bufp, word_length);
392 1.1 christos
393 1.1 christos if (CGEN_INSN_LSB0_P)
394 1.1 christos shift = (start + 1) - length;
395 1.1 christos else
396 1.1 christos shift = (word_length - (start + length));
397 1.1 christos return x >> shift;
398 1.1 christos }
399 1.1 christos
400 1.1 christos #endif /* ! CGEN_INT_INSN_P */
401 1.1 christos
402 1.1 christos /* Default extraction routine.
403 1.1 christos
404 1.1 christos INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
405 1.1 christos or sometimes less for cases like the m32r where the base insn size is 32
406 1.1 christos but some insns are 16 bits.
407 1.1 christos ATTRS is a mask of the boolean attributes. We only need `SIGNED',
408 1.1 christos but for generality we take a bitmask of all of them.
409 1.1 christos WORD_OFFSET is the offset in bits from the start of the insn of the value.
410 1.1 christos WORD_LENGTH is the length of the word in bits in which the value resides.
411 1.1 christos START is the starting bit number in the word, architecture origin.
412 1.1 christos LENGTH is the length of VALUE in bits.
413 1.1 christos TOTAL_LENGTH is the total length of the insn in bits.
414 1.1 christos
415 1.1 christos Returns 1 for success, 0 for failure. */
416 1.1 christos
417 1.1 christos /* ??? The return code isn't properly used. wip. */
418 1.1 christos
419 1.1 christos /* ??? This doesn't handle bfd_vma's. Create another function when
420 1.1 christos necessary. */
421 1.1 christos
422 1.1 christos static int
423 1.1 christos extract_normal (CGEN_CPU_DESC cd,
424 1.1 christos #if ! CGEN_INT_INSN_P
425 1.1 christos CGEN_EXTRACT_INFO *ex_info,
426 1.1 christos #else
427 1.1 christos CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
428 1.1 christos #endif
429 1.1 christos CGEN_INSN_INT insn_value,
430 1.1 christos unsigned int attrs,
431 1.1 christos unsigned int word_offset,
432 1.1 christos unsigned int start,
433 1.1 christos unsigned int length,
434 1.1 christos unsigned int word_length,
435 1.1 christos unsigned int total_length,
436 1.1 christos #if ! CGEN_INT_INSN_P
437 1.1 christos bfd_vma pc,
438 1.1 christos #else
439 1.1 christos bfd_vma pc ATTRIBUTE_UNUSED,
440 1.1 christos #endif
441 1.1 christos long *valuep)
442 1.1 christos {
443 1.1 christos long value, mask;
444 1.1 christos
445 1.1 christos /* If LENGTH is zero, this operand doesn't contribute to the value
446 1.1 christos so give it a standard value of zero. */
447 1.1 christos if (length == 0)
448 1.1 christos {
449 1.1 christos *valuep = 0;
450 1.1 christos return 1;
451 1.1 christos }
452 1.1 christos
453 1.1 christos if (word_length > 8 * sizeof (CGEN_INSN_INT))
454 1.1 christos abort ();
455 1.1 christos
456 1.1 christos /* For architectures with insns smaller than the insn-base-bitsize,
457 1.1 christos word_length may be too big. */
458 1.1 christos if (cd->min_insn_bitsize < cd->base_insn_bitsize)
459 1.1 christos {
460 1.1 christos if (word_offset + word_length > total_length)
461 1.1 christos word_length = total_length - word_offset;
462 1.1 christos }
463 1.1 christos
464 1.1 christos /* Does the value reside in INSN_VALUE, and at the right alignment? */
465 1.1 christos
466 1.1 christos if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
467 1.1 christos {
468 1.1 christos if (CGEN_INSN_LSB0_P)
469 1.1 christos value = insn_value >> ((word_offset + start + 1) - length);
470 1.1 christos else
471 1.1 christos value = insn_value >> (total_length - ( word_offset + start + length));
472 1.1 christos }
473 1.1 christos
474 1.1 christos #if ! CGEN_INT_INSN_P
475 1.1 christos
476 1.1 christos else
477 1.1 christos {
478 1.1 christos unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
479 1.1 christos
480 1.1 christos if (word_length > 8 * sizeof (CGEN_INSN_INT))
481 1.1 christos abort ();
482 1.1 christos
483 1.1 christos if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
484 1.1 christos return 0;
485 1.1 christos
486 1.1 christos value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
487 1.1 christos }
488 1.1 christos
489 1.1 christos #endif /* ! CGEN_INT_INSN_P */
490 1.1 christos
491 1.1 christos /* Written this way to avoid undefined behaviour. */
492 1.1 christos mask = (((1L << (length - 1)) - 1) << 1) | 1;
493 1.1 christos
494 1.1 christos value &= mask;
495 1.1 christos /* sign extend? */
496 1.1 christos if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
497 1.1 christos && (value & (1L << (length - 1))))
498 1.1 christos value |= ~mask;
499 1.1 christos
500 1.1 christos *valuep = value;
501 1.1 christos
502 1.1 christos return 1;
503 1.1 christos }
504 1.1 christos
505 1.1 christos /* Default insn extractor.
506 1.1 christos
507 1.1 christos INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
508 1.1 christos The extracted fields are stored in FIELDS.
509 1.1 christos EX_INFO is used to handle reading variable length insns.
510 1.1 christos Return the length of the insn in bits, or 0 if no match,
511 1.1 christos or -1 if an error occurs fetching data (memory_error_func will have
512 1.1 christos been called). */
513 1.1 christos
514 1.1 christos static int
515 1.1 christos extract_insn_normal (CGEN_CPU_DESC cd,
516 1.1 christos const CGEN_INSN *insn,
517 1.1 christos CGEN_EXTRACT_INFO *ex_info,
518 1.1 christos CGEN_INSN_INT insn_value,
519 1.1 christos CGEN_FIELDS *fields,
520 1.1 christos bfd_vma pc)
521 1.1 christos {
522 1.1 christos const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
523 1.1 christos const CGEN_SYNTAX_CHAR_TYPE *syn;
524 1.1 christos
525 1.1 christos CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
526 1.1 christos
527 1.1 christos CGEN_INIT_EXTRACT (cd);
528 1.1 christos
529 1.1 christos for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
530 1.1 christos {
531 1.1 christos int length;
532 1.1 christos
533 1.1 christos if (CGEN_SYNTAX_CHAR_P (*syn))
534 1.1 christos continue;
535 1.1 christos
536 1.1 christos length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
537 1.1 christos ex_info, insn_value, fields, pc);
538 1.1 christos if (length <= 0)
539 1.1 christos return length;
540 1.1 christos }
541 1.1 christos
542 1.1 christos /* We recognized and successfully extracted this insn. */
543 1.1 christos return CGEN_INSN_BITSIZE (insn);
544 1.1 christos }
545 1.1 christos
546 1.1 christos /* Machine generated code added here. */
548 1.1 christos
549 1.1 christos const char * epiphany_cgen_insert_operand
550 1.1 christos (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
551 1.1 christos
552 1.1 christos /* Main entry point for operand insertion.
553 1.1 christos
554 1.1 christos This function is basically just a big switch statement. Earlier versions
555 1.1 christos used tables to look up the function to use, but
556 1.1 christos - if the table contains both assembler and disassembler functions then
557 1.1 christos the disassembler contains much of the assembler and vice-versa,
558 1.1 christos - there's a lot of inlining possibilities as things grow,
559 1.1 christos - using a switch statement avoids the function call overhead.
560 1.1 christos
561 1.1 christos This function could be moved into `parse_insn_normal', but keeping it
562 1.1 christos separate makes clear the interface between `parse_insn_normal' and each of
563 1.1 christos the handlers. It's also needed by GAS to insert operands that couldn't be
564 1.1 christos resolved during parsing. */
565 1.1 christos
566 1.1 christos const char *
567 1.1 christos epiphany_cgen_insert_operand (CGEN_CPU_DESC cd,
568 1.1 christos int opindex,
569 1.1 christos CGEN_FIELDS * fields,
570 1.1 christos CGEN_INSN_BYTES_PTR buffer,
571 1.1 christos bfd_vma pc ATTRIBUTE_UNUSED)
572 1.1 christos {
573 1.1 christos const char * errmsg = NULL;
574 1.1 christos unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
575 1.1 christos
576 1.1 christos switch (opindex)
577 1.1 christos {
578 1.1 christos case EPIPHANY_OPERAND_DIRECTION :
579 1.1 christos errmsg = insert_normal (cd, fields->f_addsubx, 0, 0, 20, 1, 32, total_length, buffer);
580 1.1 christos break;
581 1.1 christos case EPIPHANY_OPERAND_DISP11 :
582 1.1 christos {
583 1.1 christos {
584 1.1 christos FLD (f_disp8) = ((((UINT) (FLD (f_disp11)) >> (3))) & (255));
585 1.1 christos FLD (f_disp3) = ((FLD (f_disp11)) & (7));
586 1.1 christos }
587 1.1 christos errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
588 1.1 christos if (errmsg)
589 1.1 christos break;
590 1.1 christos errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
591 1.1 christos if (errmsg)
592 1.1 christos break;
593 1.1 christos }
594 1.1 christos break;
595 1.1 christos case EPIPHANY_OPERAND_DISP3 :
596 1.1 christos errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
597 1.1 christos break;
598 1.1 christos case EPIPHANY_OPERAND_DPMI :
599 1.1 christos errmsg = insert_normal (cd, fields->f_subd, 0, 0, 24, 1, 32, total_length, buffer);
600 1.1 christos break;
601 1.1 christos case EPIPHANY_OPERAND_FRD :
602 1.1 christos errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
603 1.1 christos break;
604 1.1 christos case EPIPHANY_OPERAND_FRD6 :
605 1.1 christos {
606 1.1 christos {
607 1.1 christos FLD (f_rd) = ((FLD (f_rd6)) & (7));
608 1.1 christos FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
609 1.1 christos }
610 1.1 christos errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
611 1.1 christos if (errmsg)
612 1.1 christos break;
613 1.1 christos errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
614 1.1 christos if (errmsg)
615 1.1 christos break;
616 1.1 christos }
617 1.1 christos break;
618 1.1 christos case EPIPHANY_OPERAND_FRM :
619 1.1 christos errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
620 1.1 christos break;
621 1.1 christos case EPIPHANY_OPERAND_FRM6 :
622 1.1 christos {
623 1.1 christos {
624 1.1 christos FLD (f_rm) = ((FLD (f_rm6)) & (7));
625 1.1 christos FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
626 1.1 christos }
627 1.1 christos errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
628 1.1 christos if (errmsg)
629 1.1 christos break;
630 1.1 christos errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
631 1.1 christos if (errmsg)
632 1.1 christos break;
633 1.1 christos }
634 1.1 christos break;
635 1.1 christos case EPIPHANY_OPERAND_FRN :
636 1.1 christos errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
637 1.1 christos break;
638 1.1 christos case EPIPHANY_OPERAND_FRN6 :
639 1.1 christos {
640 1.1 christos {
641 1.1 christos FLD (f_rn) = ((FLD (f_rn6)) & (7));
642 1.1 christos FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
643 1.1 christos }
644 1.1 christos errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
645 1.1 christos if (errmsg)
646 1.1 christos break;
647 1.1 christos errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
648 1.1 christos if (errmsg)
649 1.1 christos break;
650 1.1 christos }
651 1.1 christos break;
652 1.1 christos case EPIPHANY_OPERAND_IMM16 :
653 1.1 christos {
654 1.1 christos {
655 1.1 christos FLD (f_imm8) = ((FLD (f_imm16)) & (255));
656 1.1 christos FLD (f_imm_27_8) = ((UINT) (FLD (f_imm16)) >> (8));
657 1.1 christos }
658 1.1 christos errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
659 1.1 christos if (errmsg)
660 1.1 christos break;
661 1.1 christos errmsg = insert_normal (cd, fields->f_imm_27_8, 0, 0, 27, 8, 32, total_length, buffer);
662 1.1 christos if (errmsg)
663 1.1 christos break;
664 1.1 christos }
665 1.1 christos break;
666 1.1 christos case EPIPHANY_OPERAND_IMM8 :
667 1.1 christos errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
668 1.1 christos break;
669 1.1 christos case EPIPHANY_OPERAND_RD :
670 1.1 christos errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
671 1.1 christos break;
672 1.1 christos case EPIPHANY_OPERAND_RD6 :
673 1.1 christos {
674 1.1 christos {
675 1.1 christos FLD (f_rd) = ((FLD (f_rd6)) & (7));
676 1.1 christos FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
677 1.1 christos }
678 1.1 christos errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
679 1.1 christos if (errmsg)
680 1.1 christos break;
681 1.1 christos errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
682 1.1 christos if (errmsg)
683 1.1 christos break;
684 1.1 christos }
685 1.1 christos break;
686 1.1 christos case EPIPHANY_OPERAND_RM :
687 1.1 christos errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
688 1.1 christos break;
689 1.1 christos case EPIPHANY_OPERAND_RM6 :
690 1.1 christos {
691 1.1 christos {
692 1.1 christos FLD (f_rm) = ((FLD (f_rm6)) & (7));
693 1.1 christos FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
694 1.1 christos }
695 1.1 christos errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
696 1.1 christos if (errmsg)
697 1.1 christos break;
698 1.1 christos errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
699 1.1 christos if (errmsg)
700 1.1 christos break;
701 1.1 christos }
702 1.1 christos break;
703 1.1 christos case EPIPHANY_OPERAND_RN :
704 1.1 christos errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
705 1.1 christos break;
706 1.1 christos case EPIPHANY_OPERAND_RN6 :
707 1.1 christos {
708 1.1 christos {
709 1.1 christos FLD (f_rn) = ((FLD (f_rn6)) & (7));
710 1.1 christos FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
711 1.1 christos }
712 1.1 christos errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
713 1.1 christos if (errmsg)
714 1.1 christos break;
715 1.1 christos errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
716 1.1 christos if (errmsg)
717 1.1 christos break;
718 1.1 christos }
719 1.1 christos break;
720 1.1 christos case EPIPHANY_OPERAND_SD :
721 1.1 christos errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
722 1.1 christos break;
723 1.1 christos case EPIPHANY_OPERAND_SD6 :
724 1.1 christos {
725 1.1 christos {
726 1.1 christos FLD (f_sd) = ((FLD (f_sd6)) & (7));
727 1.1 christos FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
728 1.1 christos }
729 1.1 christos errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
730 1.1 christos if (errmsg)
731 1.1 christos break;
732 1.1 christos errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
733 1.1 christos if (errmsg)
734 1.1 christos break;
735 1.1 christos }
736 1.1 christos break;
737 1.1 christos case EPIPHANY_OPERAND_SDDMA :
738 1.1 christos {
739 1.1 christos {
740 1.1 christos FLD (f_sd) = ((FLD (f_sd6)) & (7));
741 1.1 christos FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
742 1.1 christos }
743 1.1 christos errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
744 1.1 christos if (errmsg)
745 1.1 christos break;
746 1.1 christos errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
747 1.1 christos if (errmsg)
748 1.1 christos break;
749 1.1 christos }
750 1.1 christos break;
751 1.1 christos case EPIPHANY_OPERAND_SDMEM :
752 1.1 christos {
753 1.1 christos {
754 1.1 christos FLD (f_sd) = ((FLD (f_sd6)) & (7));
755 1.1 christos FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
756 1.1 christos }
757 1.1 christos errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
758 1.1 christos if (errmsg)
759 1.1 christos break;
760 1.1 christos errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
761 1.1 christos if (errmsg)
762 1.1 christos break;
763 1.1 christos }
764 1.1 christos break;
765 1.1 christos case EPIPHANY_OPERAND_SDMESH :
766 1.1 christos {
767 1.1 christos {
768 1.1 christos FLD (f_sd) = ((FLD (f_sd6)) & (7));
769 1.1 christos FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
770 1.1 christos }
771 1.1 christos errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
772 1.1 christos if (errmsg)
773 1.1 christos break;
774 1.1 christos errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
775 1.1 christos if (errmsg)
776 1.1 christos break;
777 1.1 christos }
778 1.1 christos break;
779 1.1 christos case EPIPHANY_OPERAND_SHIFT :
780 1.1 christos errmsg = insert_normal (cd, fields->f_shift, 0, 0, 9, 5, 32, total_length, buffer);
781 1.1 christos break;
782 1.1 christos case EPIPHANY_OPERAND_SIMM11 :
783 1.1 christos {
784 1.1 christos {
785 1.1 christos FLD (f_disp8) = ((255) & (((USI) (FLD (f_sdisp11)) >> (3))));
786 1.1 christos FLD (f_disp3) = ((FLD (f_sdisp11)) & (7));
787 1.1 christos }
788 1.1 christos errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
789 1.1 christos if (errmsg)
790 1.1 christos break;
791 1.1 christos errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
792 1.1 christos if (errmsg)
793 1.1 christos break;
794 1.1 christos }
795 1.1 christos break;
796 1.1 christos case EPIPHANY_OPERAND_SIMM24 :
797 1.1 christos {
798 1.1 christos long value = fields->f_simm24;
799 1.1 christos value = ((SI) (((value) - (pc))) >> (1));
800 1.1 christos errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 31, 24, 32, total_length, buffer);
801 1.1 christos }
802 1.1 christos break;
803 1.1 christos case EPIPHANY_OPERAND_SIMM3 :
804 1.1 christos errmsg = insert_normal (cd, fields->f_sdisp3, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, buffer);
805 1.1 christos break;
806 1.1 christos case EPIPHANY_OPERAND_SIMM8 :
807 1.1 christos {
808 1.1 christos long value = fields->f_simm8;
809 1.1 christos value = ((SI) (((value) - (pc))) >> (1));
810 1.1 christos errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, buffer);
811 1.1 christos }
812 1.1 christos break;
813 1.1 christos case EPIPHANY_OPERAND_SN :
814 1.1 christos errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
815 1.1 christos break;
816 1.1 christos case EPIPHANY_OPERAND_SN6 :
817 1.1 christos {
818 1.1 christos {
819 1.1 christos FLD (f_sn) = ((FLD (f_sn6)) & (7));
820 1.1 christos FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
821 1.1 christos }
822 1.1 christos errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
823 1.1 christos if (errmsg)
824 1.1 christos break;
825 1.1 christos errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
826 1.1 christos if (errmsg)
827 1.1 christos break;
828 1.1 christos }
829 1.1 christos break;
830 1.1 christos case EPIPHANY_OPERAND_SNDMA :
831 1.1 christos {
832 1.1 christos {
833 1.1 christos FLD (f_sn) = ((FLD (f_sn6)) & (7));
834 1.1 christos FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
835 1.1 christos }
836 1.1 christos errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
837 1.1 christos if (errmsg)
838 1.1 christos break;
839 1.1 christos errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
840 1.1 christos if (errmsg)
841 1.1 christos break;
842 1.1 christos }
843 1.1 christos break;
844 1.1 christos case EPIPHANY_OPERAND_SNMEM :
845 1.1 christos {
846 1.1 christos {
847 1.1 christos FLD (f_sn) = ((FLD (f_sn6)) & (7));
848 1.1 christos FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
849 1.1 christos }
850 1.1 christos errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
851 1.1 christos if (errmsg)
852 1.1 christos break;
853 1.1 christos errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
854 1.1 christos if (errmsg)
855 1.1 christos break;
856 1.1 christos }
857 1.1 christos break;
858 1.1 christos case EPIPHANY_OPERAND_SNMESH :
859 1.1 christos {
860 1.1 christos {
861 1.1 christos FLD (f_sn) = ((FLD (f_sn6)) & (7));
862 1.1 christos FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
863 1.1 christos }
864 1.1 christos errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
865 1.1 christos if (errmsg)
866 1.1 christos break;
867 1.1 christos errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
868 1.1 christos if (errmsg)
869 1.1 christos break;
870 1.1 christos }
871 1.1 christos break;
872 1.1 christos case EPIPHANY_OPERAND_SWI_NUM :
873 1.1 christos errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
874 1.1 christos break;
875 1.1 christos case EPIPHANY_OPERAND_TRAPNUM6 :
876 1.1 christos errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
877 1.1 christos break;
878 1.1 christos
879 1.1 christos default :
880 1.1 christos /* xgettext:c-format */
881 1.1 christos fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
882 1.1 christos opindex);
883 1.1 christos abort ();
884 1.1 christos }
885 1.1 christos
886 1.1 christos return errmsg;
887 1.1 christos }
888 1.1 christos
889 1.1 christos int epiphany_cgen_extract_operand
890 1.1 christos (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
891 1.1 christos
892 1.1 christos /* Main entry point for operand extraction.
893 1.1 christos The result is <= 0 for error, >0 for success.
894 1.1 christos ??? Actual values aren't well defined right now.
895 1.1 christos
896 1.1 christos This function is basically just a big switch statement. Earlier versions
897 1.1 christos used tables to look up the function to use, but
898 1.1 christos - if the table contains both assembler and disassembler functions then
899 1.1 christos the disassembler contains much of the assembler and vice-versa,
900 1.1 christos - there's a lot of inlining possibilities as things grow,
901 1.1 christos - using a switch statement avoids the function call overhead.
902 1.1 christos
903 1.1 christos This function could be moved into `print_insn_normal', but keeping it
904 1.1 christos separate makes clear the interface between `print_insn_normal' and each of
905 1.1 christos the handlers. */
906 1.1 christos
907 1.1 christos int
908 1.1 christos epiphany_cgen_extract_operand (CGEN_CPU_DESC cd,
909 1.1 christos int opindex,
910 1.1 christos CGEN_EXTRACT_INFO *ex_info,
911 1.1 christos CGEN_INSN_INT insn_value,
912 1.1 christos CGEN_FIELDS * fields,
913 1.1 christos bfd_vma pc)
914 1.1 christos {
915 1.1 christos /* Assume success (for those operands that are nops). */
916 1.1 christos int length = 1;
917 1.1 christos unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
918 1.1 christos
919 1.1 christos switch (opindex)
920 1.1 christos {
921 1.1 christos case EPIPHANY_OPERAND_DIRECTION :
922 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 1, 32, total_length, pc, & fields->f_addsubx);
923 1.1 christos break;
924 1.1 christos case EPIPHANY_OPERAND_DISP11 :
925 1.1 christos {
926 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
927 1.1 christos if (length <= 0) break;
928 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
929 1.1 christos if (length <= 0) break;
930 1.1 christos {
931 1.1 christos FLD (f_disp11) = ((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)));
932 1.1 christos }
933 1.1 christos }
934 1.1 christos break;
935 1.1 christos case EPIPHANY_OPERAND_DISP3 :
936 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
937 1.1 christos break;
938 1.1 christos case EPIPHANY_OPERAND_DPMI :
939 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_subd);
940 1.1 christos break;
941 1.1 christos case EPIPHANY_OPERAND_FRD :
942 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
943 1.1 christos break;
944 1.1 christos case EPIPHANY_OPERAND_FRD6 :
945 1.1 christos {
946 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
947 1.1 christos if (length <= 0) break;
948 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
949 1.1 christos if (length <= 0) break;
950 1.1 christos {
951 1.1 christos FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
952 1.1 christos }
953 1.1 christos }
954 1.1 christos break;
955 1.1 christos case EPIPHANY_OPERAND_FRM :
956 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
957 1.1 christos break;
958 1.1 christos case EPIPHANY_OPERAND_FRM6 :
959 1.1 christos {
960 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
961 1.1 christos if (length <= 0) break;
962 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
963 1.1 christos if (length <= 0) break;
964 1.1 christos {
965 1.1 christos FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
966 1.1 christos }
967 1.1 christos }
968 1.1 christos break;
969 1.1 christos case EPIPHANY_OPERAND_FRN :
970 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
971 1.1 christos break;
972 1.1 christos case EPIPHANY_OPERAND_FRN6 :
973 1.1 christos {
974 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
975 1.1 christos if (length <= 0) break;
976 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
977 1.1 christos if (length <= 0) break;
978 1.1 christos {
979 1.1 christos FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
980 1.1 christos }
981 1.1 christos }
982 1.1 christos break;
983 1.1 christos case EPIPHANY_OPERAND_IMM16 :
984 1.1 christos {
985 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
986 1.1 christos if (length <= 0) break;
987 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 27, 8, 32, total_length, pc, & fields->f_imm_27_8);
988 1.1 christos if (length <= 0) break;
989 1.1 christos {
990 1.1 christos FLD (f_imm16) = ((((FLD (f_imm_27_8)) << (8))) | (FLD (f_imm8)));
991 1.1 christos }
992 1.1 christos }
993 1.1 christos break;
994 1.1 christos case EPIPHANY_OPERAND_IMM8 :
995 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
996 1.1 christos break;
997 1.1 christos case EPIPHANY_OPERAND_RD :
998 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
999 1.1 christos break;
1000 1.1 christos case EPIPHANY_OPERAND_RD6 :
1001 1.1 christos {
1002 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
1003 1.1 christos if (length <= 0) break;
1004 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
1005 1.1 christos if (length <= 0) break;
1006 1.1 christos {
1007 1.1 christos FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
1008 1.1 christos }
1009 1.1 christos }
1010 1.1 christos break;
1011 1.1 christos case EPIPHANY_OPERAND_RM :
1012 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1013 1.1 christos break;
1014 1.1 christos case EPIPHANY_OPERAND_RM6 :
1015 1.1 christos {
1016 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
1017 1.1 christos if (length <= 0) break;
1018 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1019 1.1 christos if (length <= 0) break;
1020 1.1 christos {
1021 1.1 christos FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
1022 1.1 christos }
1023 1.1 christos }
1024 1.1 christos break;
1025 1.1 christos case EPIPHANY_OPERAND_RN :
1026 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1027 1.1 christos break;
1028 1.1 christos case EPIPHANY_OPERAND_RN6 :
1029 1.1 christos {
1030 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
1031 1.1 christos if (length <= 0) break;
1032 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1033 1.1 christos if (length <= 0) break;
1034 1.1 christos {
1035 1.1 christos FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
1036 1.1 christos }
1037 1.1 christos }
1038 1.1 christos break;
1039 1.1 christos case EPIPHANY_OPERAND_SD :
1040 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1041 1.1 christos break;
1042 1.1 christos case EPIPHANY_OPERAND_SD6 :
1043 1.1 christos {
1044 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1045 1.1 christos if (length <= 0) break;
1046 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1047 1.1 christos if (length <= 0) break;
1048 1.1 christos {
1049 1.1 christos FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1050 1.1 christos }
1051 1.1 christos }
1052 1.1 christos break;
1053 1.1 christos case EPIPHANY_OPERAND_SDDMA :
1054 1.1 christos {
1055 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1056 1.1 christos if (length <= 0) break;
1057 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1058 1.1 christos if (length <= 0) break;
1059 1.1 christos {
1060 1.1 christos FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1061 1.1 christos }
1062 1.1 christos }
1063 1.1 christos break;
1064 1.1 christos case EPIPHANY_OPERAND_SDMEM :
1065 1.1 christos {
1066 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1067 1.1 christos if (length <= 0) break;
1068 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1069 1.1 christos if (length <= 0) break;
1070 1.1 christos {
1071 1.1 christos FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1072 1.1 christos }
1073 1.1 christos }
1074 1.1 christos break;
1075 1.1 christos case EPIPHANY_OPERAND_SDMESH :
1076 1.1 christos {
1077 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1078 1.1 christos if (length <= 0) break;
1079 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1080 1.1 christos if (length <= 0) break;
1081 1.1 christos {
1082 1.1 christos FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1083 1.1 christos }
1084 1.1 christos }
1085 1.1 christos break;
1086 1.1 christos case EPIPHANY_OPERAND_SHIFT :
1087 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 5, 32, total_length, pc, & fields->f_shift);
1088 1.1 christos break;
1089 1.1 christos case EPIPHANY_OPERAND_SIMM11 :
1090 1.1 christos {
1091 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
1092 1.1 christos if (length <= 0) break;
1093 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
1094 1.1 christos if (length <= 0) break;
1095 1.1 christos {
1096 1.1 christos FLD (f_sdisp11) = ((SI) (((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) << (21))) >> (21));
1097 1.1 christos }
1098 1.1 christos }
1099 1.1 christos break;
1100 1.1 christos case EPIPHANY_OPERAND_SIMM24 :
1101 1.1 christos {
1102 1.1 christos long value;
1103 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 31, 24, 32, total_length, pc, & value);
1104 1.1 christos value = ((((value) << (1))) + (pc));
1105 1.1 christos fields->f_simm24 = value;
1106 1.1 christos }
1107 1.1 christos break;
1108 1.1 christos case EPIPHANY_OPERAND_SIMM3 :
1109 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, pc, & fields->f_sdisp3);
1110 1.1 christos break;
1111 1.1 christos case EPIPHANY_OPERAND_SIMM8 :
1112 1.1 christos {
1113 1.1 christos long value;
1114 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, pc, & value);
1115 1.1 christos value = ((((value) << (1))) + (pc));
1116 1.1 christos fields->f_simm8 = value;
1117 1.1 christos }
1118 1.1 christos break;
1119 1.1 christos case EPIPHANY_OPERAND_SN :
1120 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1121 1.1 christos break;
1122 1.1 christos case EPIPHANY_OPERAND_SN6 :
1123 1.1 christos {
1124 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1125 1.1 christos if (length <= 0) break;
1126 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1127 1.1 christos if (length <= 0) break;
1128 1.1 christos {
1129 1.1 christos FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1130 1.1 christos }
1131 1.1 christos }
1132 1.1 christos break;
1133 1.1 christos case EPIPHANY_OPERAND_SNDMA :
1134 1.1 christos {
1135 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1136 1.1 christos if (length <= 0) break;
1137 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1138 1.1 christos if (length <= 0) break;
1139 1.1 christos {
1140 1.1 christos FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1141 1.1 christos }
1142 1.1 christos }
1143 1.1 christos break;
1144 1.1 christos case EPIPHANY_OPERAND_SNMEM :
1145 1.1 christos {
1146 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1147 1.1 christos if (length <= 0) break;
1148 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1149 1.1 christos if (length <= 0) break;
1150 1.1 christos {
1151 1.1 christos FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1152 1.1 christos }
1153 1.1 christos }
1154 1.1 christos break;
1155 1.1 christos case EPIPHANY_OPERAND_SNMESH :
1156 1.1 christos {
1157 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1158 1.1 christos if (length <= 0) break;
1159 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1160 1.1 christos if (length <= 0) break;
1161 1.1 christos {
1162 1.1 christos FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1163 1.1 christos }
1164 1.1 christos }
1165 1.1 christos break;
1166 1.1 christos case EPIPHANY_OPERAND_SWI_NUM :
1167 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1168 1.1 christos break;
1169 1.1 christos case EPIPHANY_OPERAND_TRAPNUM6 :
1170 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1171 1.1 christos break;
1172 1.1 christos
1173 1.1 christos default :
1174 1.1 christos /* xgettext:c-format */
1175 1.1 christos fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
1176 1.1 christos opindex);
1177 1.1 christos abort ();
1178 1.1 christos }
1179 1.1 christos
1180 1.1.1.3 christos return length;
1181 1.1 christos }
1182 1.1 christos
1183 1.1 christos cgen_insert_fn * const epiphany_cgen_insert_handlers[] =
1184 1.1 christos {
1185 1.1.1.3 christos insert_insn_normal,
1186 1.1 christos };
1187 1.1 christos
1188 1.1 christos cgen_extract_fn * const epiphany_cgen_extract_handlers[] =
1189 1.1 christos {
1190 1.1 christos extract_insn_normal,
1191 1.1 christos };
1192 1.1 christos
1193 1.1 christos int epiphany_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1194 1.1 christos bfd_vma epiphany_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1195 1.1 christos
1196 1.1 christos /* Getting values from cgen_fields is handled by a collection of functions.
1197 1.1 christos They are distinguished by the type of the VALUE argument they return.
1198 1.1 christos TODO: floating point, inlining support, remove cases where result type
1199 1.1 christos not appropriate. */
1200 1.1 christos
1201 1.1 christos int
1202 1.1 christos epiphany_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1203 1.1 christos int opindex,
1204 1.1 christos const CGEN_FIELDS * fields)
1205 1.1 christos {
1206 1.1 christos int value;
1207 1.1 christos
1208 1.1 christos switch (opindex)
1209 1.1 christos {
1210 1.1 christos case EPIPHANY_OPERAND_DIRECTION :
1211 1.1 christos value = fields->f_addsubx;
1212 1.1 christos break;
1213 1.1 christos case EPIPHANY_OPERAND_DISP11 :
1214 1.1 christos value = fields->f_disp11;
1215 1.1 christos break;
1216 1.1 christos case EPIPHANY_OPERAND_DISP3 :
1217 1.1 christos value = fields->f_disp3;
1218 1.1 christos break;
1219 1.1 christos case EPIPHANY_OPERAND_DPMI :
1220 1.1 christos value = fields->f_subd;
1221 1.1 christos break;
1222 1.1 christos case EPIPHANY_OPERAND_FRD :
1223 1.1 christos value = fields->f_rd;
1224 1.1 christos break;
1225 1.1 christos case EPIPHANY_OPERAND_FRD6 :
1226 1.1 christos value = fields->f_rd6;
1227 1.1 christos break;
1228 1.1 christos case EPIPHANY_OPERAND_FRM :
1229 1.1 christos value = fields->f_rm;
1230 1.1 christos break;
1231 1.1 christos case EPIPHANY_OPERAND_FRM6 :
1232 1.1 christos value = fields->f_rm6;
1233 1.1 christos break;
1234 1.1 christos case EPIPHANY_OPERAND_FRN :
1235 1.1 christos value = fields->f_rn;
1236 1.1 christos break;
1237 1.1 christos case EPIPHANY_OPERAND_FRN6 :
1238 1.1 christos value = fields->f_rn6;
1239 1.1 christos break;
1240 1.1 christos case EPIPHANY_OPERAND_IMM16 :
1241 1.1 christos value = fields->f_imm16;
1242 1.1 christos break;
1243 1.1 christos case EPIPHANY_OPERAND_IMM8 :
1244 1.1 christos value = fields->f_imm8;
1245 1.1 christos break;
1246 1.1 christos case EPIPHANY_OPERAND_RD :
1247 1.1 christos value = fields->f_rd;
1248 1.1 christos break;
1249 1.1 christos case EPIPHANY_OPERAND_RD6 :
1250 1.1 christos value = fields->f_rd6;
1251 1.1 christos break;
1252 1.1 christos case EPIPHANY_OPERAND_RM :
1253 1.1 christos value = fields->f_rm;
1254 1.1 christos break;
1255 1.1 christos case EPIPHANY_OPERAND_RM6 :
1256 1.1 christos value = fields->f_rm6;
1257 1.1 christos break;
1258 1.1 christos case EPIPHANY_OPERAND_RN :
1259 1.1 christos value = fields->f_rn;
1260 1.1 christos break;
1261 1.1 christos case EPIPHANY_OPERAND_RN6 :
1262 1.1 christos value = fields->f_rn6;
1263 1.1 christos break;
1264 1.1 christos case EPIPHANY_OPERAND_SD :
1265 1.1 christos value = fields->f_sd;
1266 1.1 christos break;
1267 1.1 christos case EPIPHANY_OPERAND_SD6 :
1268 1.1 christos value = fields->f_sd6;
1269 1.1 christos break;
1270 1.1 christos case EPIPHANY_OPERAND_SDDMA :
1271 1.1 christos value = fields->f_sd6;
1272 1.1 christos break;
1273 1.1 christos case EPIPHANY_OPERAND_SDMEM :
1274 1.1 christos value = fields->f_sd6;
1275 1.1 christos break;
1276 1.1 christos case EPIPHANY_OPERAND_SDMESH :
1277 1.1 christos value = fields->f_sd6;
1278 1.1 christos break;
1279 1.1 christos case EPIPHANY_OPERAND_SHIFT :
1280 1.1 christos value = fields->f_shift;
1281 1.1 christos break;
1282 1.1 christos case EPIPHANY_OPERAND_SIMM11 :
1283 1.1 christos value = fields->f_sdisp11;
1284 1.1 christos break;
1285 1.1 christos case EPIPHANY_OPERAND_SIMM24 :
1286 1.1 christos value = fields->f_simm24;
1287 1.1 christos break;
1288 1.1 christos case EPIPHANY_OPERAND_SIMM3 :
1289 1.1 christos value = fields->f_sdisp3;
1290 1.1 christos break;
1291 1.1 christos case EPIPHANY_OPERAND_SIMM8 :
1292 1.1 christos value = fields->f_simm8;
1293 1.1 christos break;
1294 1.1 christos case EPIPHANY_OPERAND_SN :
1295 1.1 christos value = fields->f_sn;
1296 1.1 christos break;
1297 1.1 christos case EPIPHANY_OPERAND_SN6 :
1298 1.1 christos value = fields->f_sn6;
1299 1.1 christos break;
1300 1.1 christos case EPIPHANY_OPERAND_SNDMA :
1301 1.1 christos value = fields->f_sn6;
1302 1.1 christos break;
1303 1.1 christos case EPIPHANY_OPERAND_SNMEM :
1304 1.1 christos value = fields->f_sn6;
1305 1.1 christos break;
1306 1.1 christos case EPIPHANY_OPERAND_SNMESH :
1307 1.1 christos value = fields->f_sn6;
1308 1.1 christos break;
1309 1.1 christos case EPIPHANY_OPERAND_SWI_NUM :
1310 1.1 christos value = fields->f_trap_num;
1311 1.1 christos break;
1312 1.1 christos case EPIPHANY_OPERAND_TRAPNUM6 :
1313 1.1 christos value = fields->f_trap_num;
1314 1.1 christos break;
1315 1.1 christos
1316 1.1 christos default :
1317 1.1 christos /* xgettext:c-format */
1318 1.1 christos fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1319 1.1 christos opindex);
1320 1.1 christos abort ();
1321 1.1 christos }
1322 1.1 christos
1323 1.1 christos return value;
1324 1.1 christos }
1325 1.1 christos
1326 1.1 christos bfd_vma
1327 1.1 christos epiphany_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1328 1.1 christos int opindex,
1329 1.1 christos const CGEN_FIELDS * fields)
1330 1.1 christos {
1331 1.1 christos bfd_vma value;
1332 1.1 christos
1333 1.1 christos switch (opindex)
1334 1.1 christos {
1335 1.1 christos case EPIPHANY_OPERAND_DIRECTION :
1336 1.1 christos value = fields->f_addsubx;
1337 1.1 christos break;
1338 1.1 christos case EPIPHANY_OPERAND_DISP11 :
1339 1.1 christos value = fields->f_disp11;
1340 1.1 christos break;
1341 1.1 christos case EPIPHANY_OPERAND_DISP3 :
1342 1.1 christos value = fields->f_disp3;
1343 1.1 christos break;
1344 1.1 christos case EPIPHANY_OPERAND_DPMI :
1345 1.1 christos value = fields->f_subd;
1346 1.1 christos break;
1347 1.1 christos case EPIPHANY_OPERAND_FRD :
1348 1.1 christos value = fields->f_rd;
1349 1.1 christos break;
1350 1.1 christos case EPIPHANY_OPERAND_FRD6 :
1351 1.1 christos value = fields->f_rd6;
1352 1.1 christos break;
1353 1.1 christos case EPIPHANY_OPERAND_FRM :
1354 1.1 christos value = fields->f_rm;
1355 1.1 christos break;
1356 1.1 christos case EPIPHANY_OPERAND_FRM6 :
1357 1.1 christos value = fields->f_rm6;
1358 1.1 christos break;
1359 1.1 christos case EPIPHANY_OPERAND_FRN :
1360 1.1 christos value = fields->f_rn;
1361 1.1 christos break;
1362 1.1 christos case EPIPHANY_OPERAND_FRN6 :
1363 1.1 christos value = fields->f_rn6;
1364 1.1 christos break;
1365 1.1 christos case EPIPHANY_OPERAND_IMM16 :
1366 1.1 christos value = fields->f_imm16;
1367 1.1 christos break;
1368 1.1 christos case EPIPHANY_OPERAND_IMM8 :
1369 1.1 christos value = fields->f_imm8;
1370 1.1 christos break;
1371 1.1 christos case EPIPHANY_OPERAND_RD :
1372 1.1 christos value = fields->f_rd;
1373 1.1 christos break;
1374 1.1 christos case EPIPHANY_OPERAND_RD6 :
1375 1.1 christos value = fields->f_rd6;
1376 1.1 christos break;
1377 1.1 christos case EPIPHANY_OPERAND_RM :
1378 1.1 christos value = fields->f_rm;
1379 1.1 christos break;
1380 1.1 christos case EPIPHANY_OPERAND_RM6 :
1381 1.1 christos value = fields->f_rm6;
1382 1.1 christos break;
1383 1.1 christos case EPIPHANY_OPERAND_RN :
1384 1.1 christos value = fields->f_rn;
1385 1.1 christos break;
1386 1.1 christos case EPIPHANY_OPERAND_RN6 :
1387 1.1 christos value = fields->f_rn6;
1388 1.1 christos break;
1389 1.1 christos case EPIPHANY_OPERAND_SD :
1390 1.1 christos value = fields->f_sd;
1391 1.1 christos break;
1392 1.1 christos case EPIPHANY_OPERAND_SD6 :
1393 1.1 christos value = fields->f_sd6;
1394 1.1 christos break;
1395 1.1 christos case EPIPHANY_OPERAND_SDDMA :
1396 1.1 christos value = fields->f_sd6;
1397 1.1 christos break;
1398 1.1 christos case EPIPHANY_OPERAND_SDMEM :
1399 1.1 christos value = fields->f_sd6;
1400 1.1 christos break;
1401 1.1 christos case EPIPHANY_OPERAND_SDMESH :
1402 1.1 christos value = fields->f_sd6;
1403 1.1 christos break;
1404 1.1 christos case EPIPHANY_OPERAND_SHIFT :
1405 1.1 christos value = fields->f_shift;
1406 1.1 christos break;
1407 1.1 christos case EPIPHANY_OPERAND_SIMM11 :
1408 1.1 christos value = fields->f_sdisp11;
1409 1.1 christos break;
1410 1.1 christos case EPIPHANY_OPERAND_SIMM24 :
1411 1.1 christos value = fields->f_simm24;
1412 1.1 christos break;
1413 1.1 christos case EPIPHANY_OPERAND_SIMM3 :
1414 1.1 christos value = fields->f_sdisp3;
1415 1.1 christos break;
1416 1.1 christos case EPIPHANY_OPERAND_SIMM8 :
1417 1.1 christos value = fields->f_simm8;
1418 1.1 christos break;
1419 1.1 christos case EPIPHANY_OPERAND_SN :
1420 1.1 christos value = fields->f_sn;
1421 1.1 christos break;
1422 1.1 christos case EPIPHANY_OPERAND_SN6 :
1423 1.1 christos value = fields->f_sn6;
1424 1.1 christos break;
1425 1.1 christos case EPIPHANY_OPERAND_SNDMA :
1426 1.1 christos value = fields->f_sn6;
1427 1.1 christos break;
1428 1.1 christos case EPIPHANY_OPERAND_SNMEM :
1429 1.1 christos value = fields->f_sn6;
1430 1.1 christos break;
1431 1.1 christos case EPIPHANY_OPERAND_SNMESH :
1432 1.1 christos value = fields->f_sn6;
1433 1.1 christos break;
1434 1.1 christos case EPIPHANY_OPERAND_SWI_NUM :
1435 1.1 christos value = fields->f_trap_num;
1436 1.1 christos break;
1437 1.1 christos case EPIPHANY_OPERAND_TRAPNUM6 :
1438 1.1 christos value = fields->f_trap_num;
1439 1.1 christos break;
1440 1.1 christos
1441 1.1 christos default :
1442 1.1 christos /* xgettext:c-format */
1443 1.1 christos fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1444 1.1 christos opindex);
1445 1.1 christos abort ();
1446 1.1 christos }
1447 1.1 christos
1448 1.1 christos return value;
1449 1.1 christos }
1450 1.1 christos
1451 1.1 christos void epiphany_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1452 1.1 christos void epiphany_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1453 1.1 christos
1454 1.1 christos /* Stuffing values in cgen_fields is handled by a collection of functions.
1455 1.1 christos They are distinguished by the type of the VALUE argument they accept.
1456 1.1 christos TODO: floating point, inlining support, remove cases where argument type
1457 1.1 christos not appropriate. */
1458 1.1 christos
1459 1.1 christos void
1460 1.1 christos epiphany_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1461 1.1 christos int opindex,
1462 1.1 christos CGEN_FIELDS * fields,
1463 1.1 christos int value)
1464 1.1 christos {
1465 1.1 christos switch (opindex)
1466 1.1 christos {
1467 1.1 christos case EPIPHANY_OPERAND_DIRECTION :
1468 1.1 christos fields->f_addsubx = value;
1469 1.1 christos break;
1470 1.1 christos case EPIPHANY_OPERAND_DISP11 :
1471 1.1 christos fields->f_disp11 = value;
1472 1.1 christos break;
1473 1.1 christos case EPIPHANY_OPERAND_DISP3 :
1474 1.1 christos fields->f_disp3 = value;
1475 1.1 christos break;
1476 1.1 christos case EPIPHANY_OPERAND_DPMI :
1477 1.1 christos fields->f_subd = value;
1478 1.1 christos break;
1479 1.1 christos case EPIPHANY_OPERAND_FRD :
1480 1.1 christos fields->f_rd = value;
1481 1.1 christos break;
1482 1.1 christos case EPIPHANY_OPERAND_FRD6 :
1483 1.1 christos fields->f_rd6 = value;
1484 1.1 christos break;
1485 1.1 christos case EPIPHANY_OPERAND_FRM :
1486 1.1 christos fields->f_rm = value;
1487 1.1 christos break;
1488 1.1 christos case EPIPHANY_OPERAND_FRM6 :
1489 1.1 christos fields->f_rm6 = value;
1490 1.1 christos break;
1491 1.1 christos case EPIPHANY_OPERAND_FRN :
1492 1.1 christos fields->f_rn = value;
1493 1.1 christos break;
1494 1.1 christos case EPIPHANY_OPERAND_FRN6 :
1495 1.1 christos fields->f_rn6 = value;
1496 1.1 christos break;
1497 1.1 christos case EPIPHANY_OPERAND_IMM16 :
1498 1.1 christos fields->f_imm16 = value;
1499 1.1 christos break;
1500 1.1 christos case EPIPHANY_OPERAND_IMM8 :
1501 1.1 christos fields->f_imm8 = value;
1502 1.1 christos break;
1503 1.1 christos case EPIPHANY_OPERAND_RD :
1504 1.1 christos fields->f_rd = value;
1505 1.1 christos break;
1506 1.1 christos case EPIPHANY_OPERAND_RD6 :
1507 1.1 christos fields->f_rd6 = value;
1508 1.1 christos break;
1509 1.1 christos case EPIPHANY_OPERAND_RM :
1510 1.1 christos fields->f_rm = value;
1511 1.1 christos break;
1512 1.1 christos case EPIPHANY_OPERAND_RM6 :
1513 1.1 christos fields->f_rm6 = value;
1514 1.1 christos break;
1515 1.1 christos case EPIPHANY_OPERAND_RN :
1516 1.1 christos fields->f_rn = value;
1517 1.1 christos break;
1518 1.1 christos case EPIPHANY_OPERAND_RN6 :
1519 1.1 christos fields->f_rn6 = value;
1520 1.1 christos break;
1521 1.1 christos case EPIPHANY_OPERAND_SD :
1522 1.1 christos fields->f_sd = value;
1523 1.1 christos break;
1524 1.1 christos case EPIPHANY_OPERAND_SD6 :
1525 1.1 christos fields->f_sd6 = value;
1526 1.1 christos break;
1527 1.1 christos case EPIPHANY_OPERAND_SDDMA :
1528 1.1 christos fields->f_sd6 = value;
1529 1.1 christos break;
1530 1.1 christos case EPIPHANY_OPERAND_SDMEM :
1531 1.1 christos fields->f_sd6 = value;
1532 1.1 christos break;
1533 1.1 christos case EPIPHANY_OPERAND_SDMESH :
1534 1.1 christos fields->f_sd6 = value;
1535 1.1 christos break;
1536 1.1 christos case EPIPHANY_OPERAND_SHIFT :
1537 1.1 christos fields->f_shift = value;
1538 1.1 christos break;
1539 1.1 christos case EPIPHANY_OPERAND_SIMM11 :
1540 1.1 christos fields->f_sdisp11 = value;
1541 1.1 christos break;
1542 1.1 christos case EPIPHANY_OPERAND_SIMM24 :
1543 1.1 christos fields->f_simm24 = value;
1544 1.1 christos break;
1545 1.1 christos case EPIPHANY_OPERAND_SIMM3 :
1546 1.1 christos fields->f_sdisp3 = value;
1547 1.1 christos break;
1548 1.1 christos case EPIPHANY_OPERAND_SIMM8 :
1549 1.1 christos fields->f_simm8 = value;
1550 1.1 christos break;
1551 1.1 christos case EPIPHANY_OPERAND_SN :
1552 1.1 christos fields->f_sn = value;
1553 1.1 christos break;
1554 1.1 christos case EPIPHANY_OPERAND_SN6 :
1555 1.1 christos fields->f_sn6 = value;
1556 1.1 christos break;
1557 1.1 christos case EPIPHANY_OPERAND_SNDMA :
1558 1.1 christos fields->f_sn6 = value;
1559 1.1 christos break;
1560 1.1 christos case EPIPHANY_OPERAND_SNMEM :
1561 1.1 christos fields->f_sn6 = value;
1562 1.1 christos break;
1563 1.1 christos case EPIPHANY_OPERAND_SNMESH :
1564 1.1 christos fields->f_sn6 = value;
1565 1.1 christos break;
1566 1.1 christos case EPIPHANY_OPERAND_SWI_NUM :
1567 1.1 christos fields->f_trap_num = value;
1568 1.1 christos break;
1569 1.1 christos case EPIPHANY_OPERAND_TRAPNUM6 :
1570 1.1 christos fields->f_trap_num = value;
1571 1.1 christos break;
1572 1.1 christos
1573 1.1 christos default :
1574 1.1 christos /* xgettext:c-format */
1575 1.1 christos fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1576 1.1 christos opindex);
1577 1.1 christos abort ();
1578 1.1 christos }
1579 1.1 christos }
1580 1.1 christos
1581 1.1 christos void
1582 1.1 christos epiphany_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1583 1.1 christos int opindex,
1584 1.1 christos CGEN_FIELDS * fields,
1585 1.1 christos bfd_vma value)
1586 1.1 christos {
1587 1.1 christos switch (opindex)
1588 1.1 christos {
1589 1.1 christos case EPIPHANY_OPERAND_DIRECTION :
1590 1.1 christos fields->f_addsubx = value;
1591 1.1 christos break;
1592 1.1 christos case EPIPHANY_OPERAND_DISP11 :
1593 1.1 christos fields->f_disp11 = value;
1594 1.1 christos break;
1595 1.1 christos case EPIPHANY_OPERAND_DISP3 :
1596 1.1 christos fields->f_disp3 = value;
1597 1.1 christos break;
1598 1.1 christos case EPIPHANY_OPERAND_DPMI :
1599 1.1 christos fields->f_subd = value;
1600 1.1 christos break;
1601 1.1 christos case EPIPHANY_OPERAND_FRD :
1602 1.1 christos fields->f_rd = value;
1603 1.1 christos break;
1604 1.1 christos case EPIPHANY_OPERAND_FRD6 :
1605 1.1 christos fields->f_rd6 = value;
1606 1.1 christos break;
1607 1.1 christos case EPIPHANY_OPERAND_FRM :
1608 1.1 christos fields->f_rm = value;
1609 1.1 christos break;
1610 1.1 christos case EPIPHANY_OPERAND_FRM6 :
1611 1.1 christos fields->f_rm6 = value;
1612 1.1 christos break;
1613 1.1 christos case EPIPHANY_OPERAND_FRN :
1614 1.1 christos fields->f_rn = value;
1615 1.1 christos break;
1616 1.1 christos case EPIPHANY_OPERAND_FRN6 :
1617 1.1 christos fields->f_rn6 = value;
1618 1.1 christos break;
1619 1.1 christos case EPIPHANY_OPERAND_IMM16 :
1620 1.1 christos fields->f_imm16 = value;
1621 1.1 christos break;
1622 1.1 christos case EPIPHANY_OPERAND_IMM8 :
1623 1.1 christos fields->f_imm8 = value;
1624 1.1 christos break;
1625 1.1 christos case EPIPHANY_OPERAND_RD :
1626 1.1 christos fields->f_rd = value;
1627 1.1 christos break;
1628 1.1 christos case EPIPHANY_OPERAND_RD6 :
1629 1.1 christos fields->f_rd6 = value;
1630 1.1 christos break;
1631 1.1 christos case EPIPHANY_OPERAND_RM :
1632 1.1 christos fields->f_rm = value;
1633 1.1 christos break;
1634 1.1 christos case EPIPHANY_OPERAND_RM6 :
1635 1.1 christos fields->f_rm6 = value;
1636 1.1 christos break;
1637 1.1 christos case EPIPHANY_OPERAND_RN :
1638 1.1 christos fields->f_rn = value;
1639 1.1 christos break;
1640 1.1 christos case EPIPHANY_OPERAND_RN6 :
1641 1.1 christos fields->f_rn6 = value;
1642 1.1 christos break;
1643 1.1 christos case EPIPHANY_OPERAND_SD :
1644 1.1 christos fields->f_sd = value;
1645 1.1 christos break;
1646 1.1 christos case EPIPHANY_OPERAND_SD6 :
1647 1.1 christos fields->f_sd6 = value;
1648 1.1 christos break;
1649 1.1 christos case EPIPHANY_OPERAND_SDDMA :
1650 1.1 christos fields->f_sd6 = value;
1651 1.1 christos break;
1652 1.1 christos case EPIPHANY_OPERAND_SDMEM :
1653 1.1 christos fields->f_sd6 = value;
1654 1.1 christos break;
1655 1.1 christos case EPIPHANY_OPERAND_SDMESH :
1656 1.1 christos fields->f_sd6 = value;
1657 1.1 christos break;
1658 1.1 christos case EPIPHANY_OPERAND_SHIFT :
1659 1.1 christos fields->f_shift = value;
1660 1.1 christos break;
1661 1.1 christos case EPIPHANY_OPERAND_SIMM11 :
1662 1.1 christos fields->f_sdisp11 = value;
1663 1.1 christos break;
1664 1.1 christos case EPIPHANY_OPERAND_SIMM24 :
1665 1.1 christos fields->f_simm24 = value;
1666 1.1 christos break;
1667 1.1 christos case EPIPHANY_OPERAND_SIMM3 :
1668 1.1 christos fields->f_sdisp3 = value;
1669 1.1 christos break;
1670 1.1 christos case EPIPHANY_OPERAND_SIMM8 :
1671 1.1 christos fields->f_simm8 = value;
1672 1.1 christos break;
1673 1.1 christos case EPIPHANY_OPERAND_SN :
1674 1.1 christos fields->f_sn = value;
1675 1.1 christos break;
1676 1.1 christos case EPIPHANY_OPERAND_SN6 :
1677 1.1 christos fields->f_sn6 = value;
1678 1.1 christos break;
1679 1.1 christos case EPIPHANY_OPERAND_SNDMA :
1680 1.1 christos fields->f_sn6 = value;
1681 1.1 christos break;
1682 1.1 christos case EPIPHANY_OPERAND_SNMEM :
1683 1.1 christos fields->f_sn6 = value;
1684 1.1 christos break;
1685 1.1 christos case EPIPHANY_OPERAND_SNMESH :
1686 1.1 christos fields->f_sn6 = value;
1687 1.1 christos break;
1688 1.1 christos case EPIPHANY_OPERAND_SWI_NUM :
1689 1.1 christos fields->f_trap_num = value;
1690 1.1 christos break;
1691 1.1 christos case EPIPHANY_OPERAND_TRAPNUM6 :
1692 1.1 christos fields->f_trap_num = value;
1693 1.1 christos break;
1694 1.1 christos
1695 1.1 christos default :
1696 1.1 christos /* xgettext:c-format */
1697 1.1 christos fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1698 1.1 christos opindex);
1699 1.1 christos abort ();
1700 1.1 christos }
1701 1.1 christos }
1702 1.1 christos
1703 1.1 christos /* Function to call before using the instruction builder tables. */
1704 1.1 christos
1705 1.1 christos void
1706 1.1 christos epiphany_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1707 1.1 christos {
1708 1.1 christos cd->insert_handlers = & epiphany_cgen_insert_handlers[0];
1709 1.1 christos cd->extract_handlers = & epiphany_cgen_extract_handlers[0];
1710 1.1 christos
1711 1.1 christos cd->insert_operand = epiphany_cgen_insert_operand;
1712 1.1 christos cd->extract_operand = epiphany_cgen_extract_operand;
1713 1.1 christos
1714 1.1 christos cd->get_int_operand = epiphany_cgen_get_int_operand;
1715 1.1 christos cd->set_int_operand = epiphany_cgen_set_int_operand;
1716 cd->get_vma_operand = epiphany_cgen_get_vma_operand;
1717 cd->set_vma_operand = epiphany_cgen_set_vma_operand;
1718 }
1719