1dc268d07Schristos /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */
2a1ba9ba4Schristos /* Instruction building/extraction support for or1k. -*- C -*-
3a1ba9ba4Schristos
4a1ba9ba4Schristos THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
5a1ba9ba4Schristos - the resultant file is machine generated, cgen-ibld.in isn't
6a1ba9ba4Schristos
7*184b2d41Schristos Copyright (C) 1996-2020 Free Software Foundation, Inc.
8a1ba9ba4Schristos
9a1ba9ba4Schristos This file is part of libopcodes.
10a1ba9ba4Schristos
11a1ba9ba4Schristos This library is free software; you can redistribute it and/or modify
12a1ba9ba4Schristos it under the terms of the GNU General Public License as published by
13a1ba9ba4Schristos the Free Software Foundation; either version 3, or (at your option)
14a1ba9ba4Schristos any later version.
15a1ba9ba4Schristos
16a1ba9ba4Schristos It is distributed in the hope that it will be useful, but WITHOUT
17a1ba9ba4Schristos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18a1ba9ba4Schristos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19a1ba9ba4Schristos License for more details.
20a1ba9ba4Schristos
21a1ba9ba4Schristos You should have received a copy of the GNU General Public License
22a1ba9ba4Schristos along with this program; if not, write to the Free Software Foundation, Inc.,
23a1ba9ba4Schristos 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
24a1ba9ba4Schristos
25a1ba9ba4Schristos /* ??? Eventually more and more of this stuff can go to cpu-independent files.
26a1ba9ba4Schristos Keep that in mind. */
27a1ba9ba4Schristos
28a1ba9ba4Schristos #include "sysdep.h"
29a1ba9ba4Schristos #include <stdio.h>
30a1ba9ba4Schristos #include "ansidecl.h"
31a1ba9ba4Schristos #include "dis-asm.h"
32a1ba9ba4Schristos #include "bfd.h"
33a1ba9ba4Schristos #include "symcat.h"
34a1ba9ba4Schristos #include "or1k-desc.h"
35a1ba9ba4Schristos #include "or1k-opc.h"
36a1ba9ba4Schristos #include "cgen/basic-modes.h"
37a1ba9ba4Schristos #include "opintl.h"
38a1ba9ba4Schristos #include "safe-ctype.h"
39a1ba9ba4Schristos
40a1ba9ba4Schristos #undef min
41a1ba9ba4Schristos #define min(a,b) ((a) < (b) ? (a) : (b))
42a1ba9ba4Schristos #undef max
43a1ba9ba4Schristos #define max(a,b) ((a) > (b) ? (a) : (b))
44a1ba9ba4Schristos
45a1ba9ba4Schristos /* Used by the ifield rtx function. */
46a1ba9ba4Schristos #define FLD(f) (fields->f)
47a1ba9ba4Schristos
48a1ba9ba4Schristos static const char * insert_normal
49a1ba9ba4Schristos (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
50a1ba9ba4Schristos unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
51a1ba9ba4Schristos static const char * insert_insn_normal
52a1ba9ba4Schristos (CGEN_CPU_DESC, const CGEN_INSN *,
53a1ba9ba4Schristos CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
54a1ba9ba4Schristos static int extract_normal
55a1ba9ba4Schristos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
56a1ba9ba4Schristos unsigned int, unsigned int, unsigned int, unsigned int,
57a1ba9ba4Schristos unsigned int, unsigned int, bfd_vma, long *);
58a1ba9ba4Schristos static int extract_insn_normal
59a1ba9ba4Schristos (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
60a1ba9ba4Schristos CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
61a1ba9ba4Schristos #if CGEN_INT_INSN_P
62a1ba9ba4Schristos static void put_insn_int_value
63a1ba9ba4Schristos (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
64a1ba9ba4Schristos #endif
65a1ba9ba4Schristos #if ! CGEN_INT_INSN_P
66a1ba9ba4Schristos static CGEN_INLINE void insert_1
67a1ba9ba4Schristos (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
68a1ba9ba4Schristos static CGEN_INLINE int fill_cache
69a1ba9ba4Schristos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
70a1ba9ba4Schristos static CGEN_INLINE long extract_1
71a1ba9ba4Schristos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
72a1ba9ba4Schristos #endif
73a1ba9ba4Schristos
74a1ba9ba4Schristos /* Operand insertion. */
75a1ba9ba4Schristos
76a1ba9ba4Schristos #if ! CGEN_INT_INSN_P
77a1ba9ba4Schristos
78a1ba9ba4Schristos /* Subroutine of insert_normal. */
79a1ba9ba4Schristos
80a1ba9ba4Schristos static CGEN_INLINE void
insert_1(CGEN_CPU_DESC cd,unsigned long value,int start,int length,int word_length,unsigned char * bufp)81a1ba9ba4Schristos insert_1 (CGEN_CPU_DESC cd,
82a1ba9ba4Schristos unsigned long value,
83a1ba9ba4Schristos int start,
84a1ba9ba4Schristos int length,
85a1ba9ba4Schristos int word_length,
86a1ba9ba4Schristos unsigned char *bufp)
87a1ba9ba4Schristos {
88a1ba9ba4Schristos unsigned long x, mask;
89a1ba9ba4Schristos int shift;
90a1ba9ba4Schristos
91*184b2d41Schristos x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
92a1ba9ba4Schristos
93a1ba9ba4Schristos /* Written this way to avoid undefined behaviour. */
94*184b2d41Schristos mask = (1UL << (length - 1) << 1) - 1;
95a1ba9ba4Schristos if (CGEN_INSN_LSB0_P)
96a1ba9ba4Schristos shift = (start + 1) - length;
97a1ba9ba4Schristos else
98a1ba9ba4Schristos shift = (word_length - (start + length));
99a1ba9ba4Schristos x = (x & ~(mask << shift)) | ((value & mask) << shift);
100a1ba9ba4Schristos
101*184b2d41Schristos cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x, cd->endian);
102a1ba9ba4Schristos }
103a1ba9ba4Schristos
104a1ba9ba4Schristos #endif /* ! CGEN_INT_INSN_P */
105a1ba9ba4Schristos
106a1ba9ba4Schristos /* Default insertion routine.
107a1ba9ba4Schristos
108a1ba9ba4Schristos ATTRS is a mask of the boolean attributes.
109a1ba9ba4Schristos WORD_OFFSET is the offset in bits from the start of the insn of the value.
110a1ba9ba4Schristos WORD_LENGTH is the length of the word in bits in which the value resides.
111a1ba9ba4Schristos START is the starting bit number in the word, architecture origin.
112a1ba9ba4Schristos LENGTH is the length of VALUE in bits.
113a1ba9ba4Schristos TOTAL_LENGTH is the total length of the insn in bits.
114a1ba9ba4Schristos
115a1ba9ba4Schristos The result is an error message or NULL if success. */
116a1ba9ba4Schristos
117a1ba9ba4Schristos /* ??? This duplicates functionality with bfd's howto table and
118a1ba9ba4Schristos bfd_install_relocation. */
119a1ba9ba4Schristos /* ??? This doesn't handle bfd_vma's. Create another function when
120a1ba9ba4Schristos necessary. */
121a1ba9ba4Schristos
122a1ba9ba4Schristos static const char *
insert_normal(CGEN_CPU_DESC cd,long value,unsigned int attrs,unsigned int word_offset,unsigned int start,unsigned int length,unsigned int word_length,unsigned int total_length,CGEN_INSN_BYTES_PTR buffer)123a1ba9ba4Schristos insert_normal (CGEN_CPU_DESC cd,
124a1ba9ba4Schristos long value,
125a1ba9ba4Schristos unsigned int attrs,
126a1ba9ba4Schristos unsigned int word_offset,
127a1ba9ba4Schristos unsigned int start,
128a1ba9ba4Schristos unsigned int length,
129a1ba9ba4Schristos unsigned int word_length,
130a1ba9ba4Schristos unsigned int total_length,
131a1ba9ba4Schristos CGEN_INSN_BYTES_PTR buffer)
132a1ba9ba4Schristos {
133a1ba9ba4Schristos static char errbuf[100];
134*184b2d41Schristos unsigned long mask;
135a1ba9ba4Schristos
136a1ba9ba4Schristos /* If LENGTH is zero, this operand doesn't contribute to the value. */
137a1ba9ba4Schristos if (length == 0)
138a1ba9ba4Schristos return NULL;
139a1ba9ba4Schristos
140*184b2d41Schristos /* Written this way to avoid undefined behaviour. */
141*184b2d41Schristos mask = (1UL << (length - 1) << 1) - 1;
142*184b2d41Schristos
143a1ba9ba4Schristos if (word_length > 8 * sizeof (CGEN_INSN_INT))
144a1ba9ba4Schristos abort ();
145a1ba9ba4Schristos
146a1ba9ba4Schristos /* For architectures with insns smaller than the base-insn-bitsize,
147a1ba9ba4Schristos word_length may be too big. */
148a1ba9ba4Schristos if (cd->min_insn_bitsize < cd->base_insn_bitsize)
149a1ba9ba4Schristos {
150a1ba9ba4Schristos if (word_offset == 0
151a1ba9ba4Schristos && word_length > total_length)
152a1ba9ba4Schristos word_length = total_length;
153a1ba9ba4Schristos }
154a1ba9ba4Schristos
155a1ba9ba4Schristos /* Ensure VALUE will fit. */
156a1ba9ba4Schristos if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
157a1ba9ba4Schristos {
158*184b2d41Schristos long minval = - (1UL << (length - 1));
159a1ba9ba4Schristos unsigned long maxval = mask;
160a1ba9ba4Schristos
161a1ba9ba4Schristos if ((value > 0 && (unsigned long) value > maxval)
162a1ba9ba4Schristos || value < minval)
163a1ba9ba4Schristos {
164a1ba9ba4Schristos /* xgettext:c-format */
165a1ba9ba4Schristos sprintf (errbuf,
166a1ba9ba4Schristos _("operand out of range (%ld not between %ld and %lu)"),
167a1ba9ba4Schristos value, minval, maxval);
168a1ba9ba4Schristos return errbuf;
169a1ba9ba4Schristos }
170a1ba9ba4Schristos }
171a1ba9ba4Schristos else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
172a1ba9ba4Schristos {
173a1ba9ba4Schristos unsigned long maxval = mask;
174a1ba9ba4Schristos unsigned long val = (unsigned long) value;
175a1ba9ba4Schristos
176a1ba9ba4Schristos /* For hosts with a word size > 32 check to see if value has been sign
177a1ba9ba4Schristos extended beyond 32 bits. If so then ignore these higher sign bits
178a1ba9ba4Schristos as the user is attempting to store a 32-bit signed value into an
179a1ba9ba4Schristos unsigned 32-bit field which is allowed. */
180a1ba9ba4Schristos if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
181a1ba9ba4Schristos val &= 0xFFFFFFFF;
182a1ba9ba4Schristos
183a1ba9ba4Schristos if (val > maxval)
184a1ba9ba4Schristos {
185a1ba9ba4Schristos /* xgettext:c-format */
186a1ba9ba4Schristos sprintf (errbuf,
187a1ba9ba4Schristos _("operand out of range (0x%lx not between 0 and 0x%lx)"),
188a1ba9ba4Schristos val, maxval);
189a1ba9ba4Schristos return errbuf;
190a1ba9ba4Schristos }
191a1ba9ba4Schristos }
192a1ba9ba4Schristos else
193a1ba9ba4Schristos {
194a1ba9ba4Schristos if (! cgen_signed_overflow_ok_p (cd))
195a1ba9ba4Schristos {
196*184b2d41Schristos long minval = - (1UL << (length - 1));
197*184b2d41Schristos long maxval = (1UL << (length - 1)) - 1;
198a1ba9ba4Schristos
199a1ba9ba4Schristos if (value < minval || value > maxval)
200a1ba9ba4Schristos {
201a1ba9ba4Schristos sprintf
202a1ba9ba4Schristos /* xgettext:c-format */
203a1ba9ba4Schristos (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
204a1ba9ba4Schristos value, minval, maxval);
205a1ba9ba4Schristos return errbuf;
206a1ba9ba4Schristos }
207a1ba9ba4Schristos }
208a1ba9ba4Schristos }
209a1ba9ba4Schristos
210a1ba9ba4Schristos #if CGEN_INT_INSN_P
211a1ba9ba4Schristos
212a1ba9ba4Schristos {
213b2396a7bSchristos int shift_within_word, shift_to_word, shift;
214a1ba9ba4Schristos
215b2396a7bSchristos /* How to shift the value to BIT0 of the word. */
216b2396a7bSchristos shift_to_word = total_length - (word_offset + word_length);
217b2396a7bSchristos
218b2396a7bSchristos /* How to shift the value to the field within the word. */
219a1ba9ba4Schristos if (CGEN_INSN_LSB0_P)
220b2396a7bSchristos shift_within_word = start + 1 - length;
221a1ba9ba4Schristos else
222b2396a7bSchristos shift_within_word = word_length - start - length;
223b2396a7bSchristos
224b2396a7bSchristos /* The total SHIFT, then mask in the value. */
225b2396a7bSchristos shift = shift_to_word + shift_within_word;
226a1ba9ba4Schristos *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
227a1ba9ba4Schristos }
228a1ba9ba4Schristos
229a1ba9ba4Schristos #else /* ! CGEN_INT_INSN_P */
230a1ba9ba4Schristos
231a1ba9ba4Schristos {
232a1ba9ba4Schristos unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
233a1ba9ba4Schristos
234a1ba9ba4Schristos insert_1 (cd, value, start, length, word_length, bufp);
235a1ba9ba4Schristos }
236a1ba9ba4Schristos
237a1ba9ba4Schristos #endif /* ! CGEN_INT_INSN_P */
238a1ba9ba4Schristos
239a1ba9ba4Schristos return NULL;
240a1ba9ba4Schristos }
241a1ba9ba4Schristos
242a1ba9ba4Schristos /* Default insn builder (insert handler).
243a1ba9ba4Schristos The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
244a1ba9ba4Schristos that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
245a1ba9ba4Schristos recorded in host byte order, otherwise BUFFER is an array of bytes
246a1ba9ba4Schristos and the value is recorded in target byte order).
247a1ba9ba4Schristos The result is an error message or NULL if success. */
248a1ba9ba4Schristos
249a1ba9ba4Schristos static const char *
insert_insn_normal(CGEN_CPU_DESC cd,const CGEN_INSN * insn,CGEN_FIELDS * fields,CGEN_INSN_BYTES_PTR buffer,bfd_vma pc)250a1ba9ba4Schristos insert_insn_normal (CGEN_CPU_DESC cd,
251a1ba9ba4Schristos const CGEN_INSN * insn,
252a1ba9ba4Schristos CGEN_FIELDS * fields,
253a1ba9ba4Schristos CGEN_INSN_BYTES_PTR buffer,
254a1ba9ba4Schristos bfd_vma pc)
255a1ba9ba4Schristos {
256a1ba9ba4Schristos const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
257a1ba9ba4Schristos unsigned long value;
258a1ba9ba4Schristos const CGEN_SYNTAX_CHAR_TYPE * syn;
259a1ba9ba4Schristos
260a1ba9ba4Schristos CGEN_INIT_INSERT (cd);
261a1ba9ba4Schristos value = CGEN_INSN_BASE_VALUE (insn);
262a1ba9ba4Schristos
263a1ba9ba4Schristos /* If we're recording insns as numbers (rather than a string of bytes),
264a1ba9ba4Schristos target byte order handling is deferred until later. */
265a1ba9ba4Schristos
266a1ba9ba4Schristos #if CGEN_INT_INSN_P
267a1ba9ba4Schristos
268a1ba9ba4Schristos put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
269a1ba9ba4Schristos CGEN_FIELDS_BITSIZE (fields), value);
270a1ba9ba4Schristos
271a1ba9ba4Schristos #else
272a1ba9ba4Schristos
273a1ba9ba4Schristos cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
274a1ba9ba4Schristos (unsigned) CGEN_FIELDS_BITSIZE (fields)),
275*184b2d41Schristos value, cd->insn_endian);
276a1ba9ba4Schristos
277a1ba9ba4Schristos #endif /* ! CGEN_INT_INSN_P */
278a1ba9ba4Schristos
279a1ba9ba4Schristos /* ??? It would be better to scan the format's fields.
280a1ba9ba4Schristos Still need to be able to insert a value based on the operand though;
281a1ba9ba4Schristos e.g. storing a branch displacement that got resolved later.
282a1ba9ba4Schristos Needs more thought first. */
283a1ba9ba4Schristos
284a1ba9ba4Schristos for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
285a1ba9ba4Schristos {
286a1ba9ba4Schristos const char *errmsg;
287a1ba9ba4Schristos
288a1ba9ba4Schristos if (CGEN_SYNTAX_CHAR_P (* syn))
289a1ba9ba4Schristos continue;
290a1ba9ba4Schristos
291a1ba9ba4Schristos errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
292a1ba9ba4Schristos fields, buffer, pc);
293a1ba9ba4Schristos if (errmsg)
294a1ba9ba4Schristos return errmsg;
295a1ba9ba4Schristos }
296a1ba9ba4Schristos
297a1ba9ba4Schristos return NULL;
298a1ba9ba4Schristos }
299a1ba9ba4Schristos
300a1ba9ba4Schristos #if CGEN_INT_INSN_P
301a1ba9ba4Schristos /* Cover function to store an insn value into an integral insn. Must go here
302a1ba9ba4Schristos because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
303a1ba9ba4Schristos
304a1ba9ba4Schristos static void
put_insn_int_value(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,CGEN_INSN_BYTES_PTR buf,int length,int insn_length,CGEN_INSN_INT value)305a1ba9ba4Schristos put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
306a1ba9ba4Schristos CGEN_INSN_BYTES_PTR buf,
307a1ba9ba4Schristos int length,
308a1ba9ba4Schristos int insn_length,
309a1ba9ba4Schristos CGEN_INSN_INT value)
310a1ba9ba4Schristos {
311a1ba9ba4Schristos /* For architectures with insns smaller than the base-insn-bitsize,
312a1ba9ba4Schristos length may be too big. */
313a1ba9ba4Schristos if (length > insn_length)
314a1ba9ba4Schristos *buf = value;
315a1ba9ba4Schristos else
316a1ba9ba4Schristos {
317a1ba9ba4Schristos int shift = insn_length - length;
318a1ba9ba4Schristos /* Written this way to avoid undefined behaviour. */
319*184b2d41Schristos CGEN_INSN_INT mask = length == 0 ? 0 : (1UL << (length - 1) << 1) - 1;
320a1ba9ba4Schristos
321a1ba9ba4Schristos *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
322a1ba9ba4Schristos }
323a1ba9ba4Schristos }
324a1ba9ba4Schristos #endif
325a1ba9ba4Schristos
326a1ba9ba4Schristos /* Operand extraction. */
327a1ba9ba4Schristos
328a1ba9ba4Schristos #if ! CGEN_INT_INSN_P
329a1ba9ba4Schristos
330a1ba9ba4Schristos /* Subroutine of extract_normal.
331a1ba9ba4Schristos Ensure sufficient bytes are cached in EX_INFO.
332a1ba9ba4Schristos OFFSET is the offset in bytes from the start of the insn of the value.
333a1ba9ba4Schristos BYTES is the length of the needed value.
334a1ba9ba4Schristos Returns 1 for success, 0 for failure. */
335a1ba9ba4Schristos
336a1ba9ba4Schristos static CGEN_INLINE int
fill_cache(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,CGEN_EXTRACT_INFO * ex_info,int offset,int bytes,bfd_vma pc)337a1ba9ba4Schristos fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
338a1ba9ba4Schristos CGEN_EXTRACT_INFO *ex_info,
339a1ba9ba4Schristos int offset,
340a1ba9ba4Schristos int bytes,
341a1ba9ba4Schristos bfd_vma pc)
342a1ba9ba4Schristos {
343a1ba9ba4Schristos /* It's doubtful that the middle part has already been fetched so
344a1ba9ba4Schristos we don't optimize that case. kiss. */
345a1ba9ba4Schristos unsigned int mask;
346a1ba9ba4Schristos disassemble_info *info = (disassemble_info *) ex_info->dis_info;
347a1ba9ba4Schristos
348a1ba9ba4Schristos /* First do a quick check. */
349a1ba9ba4Schristos mask = (1 << bytes) - 1;
350a1ba9ba4Schristos if (((ex_info->valid >> offset) & mask) == mask)
351a1ba9ba4Schristos return 1;
352a1ba9ba4Schristos
353a1ba9ba4Schristos /* Search for the first byte we need to read. */
354a1ba9ba4Schristos for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
355a1ba9ba4Schristos if (! (mask & ex_info->valid))
356a1ba9ba4Schristos break;
357a1ba9ba4Schristos
358a1ba9ba4Schristos if (bytes)
359a1ba9ba4Schristos {
360a1ba9ba4Schristos int status;
361a1ba9ba4Schristos
362a1ba9ba4Schristos pc += offset;
363a1ba9ba4Schristos status = (*info->read_memory_func)
364a1ba9ba4Schristos (pc, ex_info->insn_bytes + offset, bytes, info);
365a1ba9ba4Schristos
366a1ba9ba4Schristos if (status != 0)
367a1ba9ba4Schristos {
368a1ba9ba4Schristos (*info->memory_error_func) (status, pc, info);
369a1ba9ba4Schristos return 0;
370a1ba9ba4Schristos }
371a1ba9ba4Schristos
372a1ba9ba4Schristos ex_info->valid |= ((1 << bytes) - 1) << offset;
373a1ba9ba4Schristos }
374a1ba9ba4Schristos
375a1ba9ba4Schristos return 1;
376a1ba9ba4Schristos }
377a1ba9ba4Schristos
378a1ba9ba4Schristos /* Subroutine of extract_normal. */
379a1ba9ba4Schristos
380a1ba9ba4Schristos static CGEN_INLINE long
extract_1(CGEN_CPU_DESC cd,CGEN_EXTRACT_INFO * ex_info ATTRIBUTE_UNUSED,int start,int length,int word_length,unsigned char * bufp,bfd_vma pc ATTRIBUTE_UNUSED)381a1ba9ba4Schristos extract_1 (CGEN_CPU_DESC cd,
382a1ba9ba4Schristos CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
383a1ba9ba4Schristos int start,
384a1ba9ba4Schristos int length,
385a1ba9ba4Schristos int word_length,
386a1ba9ba4Schristos unsigned char *bufp,
387a1ba9ba4Schristos bfd_vma pc ATTRIBUTE_UNUSED)
388a1ba9ba4Schristos {
389a1ba9ba4Schristos unsigned long x;
390a1ba9ba4Schristos int shift;
391a1ba9ba4Schristos
392*184b2d41Schristos x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
393a1ba9ba4Schristos
394a1ba9ba4Schristos if (CGEN_INSN_LSB0_P)
395a1ba9ba4Schristos shift = (start + 1) - length;
396a1ba9ba4Schristos else
397a1ba9ba4Schristos shift = (word_length - (start + length));
398a1ba9ba4Schristos return x >> shift;
399a1ba9ba4Schristos }
400a1ba9ba4Schristos
401a1ba9ba4Schristos #endif /* ! CGEN_INT_INSN_P */
402a1ba9ba4Schristos
403a1ba9ba4Schristos /* Default extraction routine.
404a1ba9ba4Schristos
405a1ba9ba4Schristos INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
406a1ba9ba4Schristos or sometimes less for cases like the m32r where the base insn size is 32
407a1ba9ba4Schristos but some insns are 16 bits.
408a1ba9ba4Schristos ATTRS is a mask of the boolean attributes. We only need `SIGNED',
409a1ba9ba4Schristos but for generality we take a bitmask of all of them.
410a1ba9ba4Schristos WORD_OFFSET is the offset in bits from the start of the insn of the value.
411a1ba9ba4Schristos WORD_LENGTH is the length of the word in bits in which the value resides.
412a1ba9ba4Schristos START is the starting bit number in the word, architecture origin.
413a1ba9ba4Schristos LENGTH is the length of VALUE in bits.
414a1ba9ba4Schristos TOTAL_LENGTH is the total length of the insn in bits.
415a1ba9ba4Schristos
416a1ba9ba4Schristos Returns 1 for success, 0 for failure. */
417a1ba9ba4Schristos
418a1ba9ba4Schristos /* ??? The return code isn't properly used. wip. */
419a1ba9ba4Schristos
420a1ba9ba4Schristos /* ??? This doesn't handle bfd_vma's. Create another function when
421a1ba9ba4Schristos necessary. */
422a1ba9ba4Schristos
423a1ba9ba4Schristos static int
extract_normal(CGEN_CPU_DESC cd,CGEN_EXTRACT_INFO * ex_info,CGEN_INSN_INT insn_value,unsigned int attrs,unsigned int word_offset,unsigned int start,unsigned int length,unsigned int word_length,unsigned int total_length,bfd_vma pc,long * valuep)424a1ba9ba4Schristos extract_normal (CGEN_CPU_DESC cd,
425a1ba9ba4Schristos #if ! CGEN_INT_INSN_P
426a1ba9ba4Schristos CGEN_EXTRACT_INFO *ex_info,
427a1ba9ba4Schristos #else
428a1ba9ba4Schristos CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
429a1ba9ba4Schristos #endif
430a1ba9ba4Schristos CGEN_INSN_INT insn_value,
431a1ba9ba4Schristos unsigned int attrs,
432a1ba9ba4Schristos unsigned int word_offset,
433a1ba9ba4Schristos unsigned int start,
434a1ba9ba4Schristos unsigned int length,
435a1ba9ba4Schristos unsigned int word_length,
436a1ba9ba4Schristos unsigned int total_length,
437a1ba9ba4Schristos #if ! CGEN_INT_INSN_P
438a1ba9ba4Schristos bfd_vma pc,
439a1ba9ba4Schristos #else
440a1ba9ba4Schristos bfd_vma pc ATTRIBUTE_UNUSED,
441a1ba9ba4Schristos #endif
442a1ba9ba4Schristos long *valuep)
443a1ba9ba4Schristos {
444a1ba9ba4Schristos long value, mask;
445a1ba9ba4Schristos
446a1ba9ba4Schristos /* If LENGTH is zero, this operand doesn't contribute to the value
447a1ba9ba4Schristos so give it a standard value of zero. */
448a1ba9ba4Schristos if (length == 0)
449a1ba9ba4Schristos {
450a1ba9ba4Schristos *valuep = 0;
451a1ba9ba4Schristos return 1;
452a1ba9ba4Schristos }
453a1ba9ba4Schristos
454a1ba9ba4Schristos if (word_length > 8 * sizeof (CGEN_INSN_INT))
455a1ba9ba4Schristos abort ();
456a1ba9ba4Schristos
457a1ba9ba4Schristos /* For architectures with insns smaller than the insn-base-bitsize,
458a1ba9ba4Schristos word_length may be too big. */
459a1ba9ba4Schristos if (cd->min_insn_bitsize < cd->base_insn_bitsize)
460a1ba9ba4Schristos {
461a1ba9ba4Schristos if (word_offset + word_length > total_length)
462a1ba9ba4Schristos word_length = total_length - word_offset;
463a1ba9ba4Schristos }
464a1ba9ba4Schristos
465a1ba9ba4Schristos /* Does the value reside in INSN_VALUE, and at the right alignment? */
466a1ba9ba4Schristos
467a1ba9ba4Schristos if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
468a1ba9ba4Schristos {
469a1ba9ba4Schristos if (CGEN_INSN_LSB0_P)
470a1ba9ba4Schristos value = insn_value >> ((word_offset + start + 1) - length);
471a1ba9ba4Schristos else
472a1ba9ba4Schristos value = insn_value >> (total_length - ( word_offset + start + length));
473a1ba9ba4Schristos }
474a1ba9ba4Schristos
475a1ba9ba4Schristos #if ! CGEN_INT_INSN_P
476a1ba9ba4Schristos
477a1ba9ba4Schristos else
478a1ba9ba4Schristos {
479a1ba9ba4Schristos unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
480a1ba9ba4Schristos
481a1ba9ba4Schristos if (word_length > 8 * sizeof (CGEN_INSN_INT))
482a1ba9ba4Schristos abort ();
483a1ba9ba4Schristos
484a1ba9ba4Schristos if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
485*184b2d41Schristos {
486*184b2d41Schristos *valuep = 0;
487a1ba9ba4Schristos return 0;
488*184b2d41Schristos }
489a1ba9ba4Schristos
490a1ba9ba4Schristos value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
491a1ba9ba4Schristos }
492a1ba9ba4Schristos
493a1ba9ba4Schristos #endif /* ! CGEN_INT_INSN_P */
494a1ba9ba4Schristos
495a1ba9ba4Schristos /* Written this way to avoid undefined behaviour. */
496*184b2d41Schristos mask = (1UL << (length - 1) << 1) - 1;
497a1ba9ba4Schristos
498a1ba9ba4Schristos value &= mask;
499a1ba9ba4Schristos /* sign extend? */
500a1ba9ba4Schristos if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
501*184b2d41Schristos && (value & (1UL << (length - 1))))
502a1ba9ba4Schristos value |= ~mask;
503a1ba9ba4Schristos
504a1ba9ba4Schristos *valuep = value;
505a1ba9ba4Schristos
506a1ba9ba4Schristos return 1;
507a1ba9ba4Schristos }
508a1ba9ba4Schristos
509a1ba9ba4Schristos /* Default insn extractor.
510a1ba9ba4Schristos
511a1ba9ba4Schristos INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
512a1ba9ba4Schristos The extracted fields are stored in FIELDS.
513a1ba9ba4Schristos EX_INFO is used to handle reading variable length insns.
514a1ba9ba4Schristos Return the length of the insn in bits, or 0 if no match,
515a1ba9ba4Schristos or -1 if an error occurs fetching data (memory_error_func will have
516a1ba9ba4Schristos been called). */
517a1ba9ba4Schristos
518a1ba9ba4Schristos static int
extract_insn_normal(CGEN_CPU_DESC cd,const CGEN_INSN * insn,CGEN_EXTRACT_INFO * ex_info,CGEN_INSN_INT insn_value,CGEN_FIELDS * fields,bfd_vma pc)519a1ba9ba4Schristos extract_insn_normal (CGEN_CPU_DESC cd,
520a1ba9ba4Schristos const CGEN_INSN *insn,
521a1ba9ba4Schristos CGEN_EXTRACT_INFO *ex_info,
522a1ba9ba4Schristos CGEN_INSN_INT insn_value,
523a1ba9ba4Schristos CGEN_FIELDS *fields,
524a1ba9ba4Schristos bfd_vma pc)
525a1ba9ba4Schristos {
526a1ba9ba4Schristos const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
527a1ba9ba4Schristos const CGEN_SYNTAX_CHAR_TYPE *syn;
528a1ba9ba4Schristos
529a1ba9ba4Schristos CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
530a1ba9ba4Schristos
531a1ba9ba4Schristos CGEN_INIT_EXTRACT (cd);
532a1ba9ba4Schristos
533a1ba9ba4Schristos for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
534a1ba9ba4Schristos {
535a1ba9ba4Schristos int length;
536a1ba9ba4Schristos
537a1ba9ba4Schristos if (CGEN_SYNTAX_CHAR_P (*syn))
538a1ba9ba4Schristos continue;
539a1ba9ba4Schristos
540a1ba9ba4Schristos length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
541a1ba9ba4Schristos ex_info, insn_value, fields, pc);
542a1ba9ba4Schristos if (length <= 0)
543a1ba9ba4Schristos return length;
544a1ba9ba4Schristos }
545a1ba9ba4Schristos
546a1ba9ba4Schristos /* We recognized and successfully extracted this insn. */
547a1ba9ba4Schristos return CGEN_INSN_BITSIZE (insn);
548a1ba9ba4Schristos }
549a1ba9ba4Schristos
550a1ba9ba4Schristos /* Machine generated code added here. */
551a1ba9ba4Schristos
552a1ba9ba4Schristos const char * or1k_cgen_insert_operand
553a1ba9ba4Schristos (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
554a1ba9ba4Schristos
555a1ba9ba4Schristos /* Main entry point for operand insertion.
556a1ba9ba4Schristos
557a1ba9ba4Schristos This function is basically just a big switch statement. Earlier versions
558a1ba9ba4Schristos used tables to look up the function to use, but
559a1ba9ba4Schristos - if the table contains both assembler and disassembler functions then
560a1ba9ba4Schristos the disassembler contains much of the assembler and vice-versa,
561a1ba9ba4Schristos - there's a lot of inlining possibilities as things grow,
562a1ba9ba4Schristos - using a switch statement avoids the function call overhead.
563a1ba9ba4Schristos
564a1ba9ba4Schristos This function could be moved into `parse_insn_normal', but keeping it
565a1ba9ba4Schristos separate makes clear the interface between `parse_insn_normal' and each of
566a1ba9ba4Schristos the handlers. It's also needed by GAS to insert operands that couldn't be
567a1ba9ba4Schristos resolved during parsing. */
568a1ba9ba4Schristos
569a1ba9ba4Schristos const char *
or1k_cgen_insert_operand(CGEN_CPU_DESC cd,int opindex,CGEN_FIELDS * fields,CGEN_INSN_BYTES_PTR buffer,bfd_vma pc ATTRIBUTE_UNUSED)570a1ba9ba4Schristos or1k_cgen_insert_operand (CGEN_CPU_DESC cd,
571a1ba9ba4Schristos int opindex,
572a1ba9ba4Schristos CGEN_FIELDS * fields,
573a1ba9ba4Schristos CGEN_INSN_BYTES_PTR buffer,
574a1ba9ba4Schristos bfd_vma pc ATTRIBUTE_UNUSED)
575a1ba9ba4Schristos {
576a1ba9ba4Schristos const char * errmsg = NULL;
577a1ba9ba4Schristos unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
578a1ba9ba4Schristos
579a1ba9ba4Schristos switch (opindex)
580a1ba9ba4Schristos {
581dc268d07Schristos case OR1K_OPERAND_DISP21 :
582dc268d07Schristos {
583dc268d07Schristos long value = fields->f_disp21;
584*184b2d41Schristos value = ((((SI) (value) >> (13))) - (((SI) (pc) >> (13))));
585dc268d07Schristos errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, buffer);
586dc268d07Schristos }
587dc268d07Schristos break;
588a1ba9ba4Schristos case OR1K_OPERAND_DISP26 :
589a1ba9ba4Schristos {
590a1ba9ba4Schristos long value = fields->f_disp26;
591*184b2d41Schristos value = ((SI) (((value) - (pc))) >> (2));
592a1ba9ba4Schristos errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 25, 26, 32, total_length, buffer);
593a1ba9ba4Schristos }
594a1ba9ba4Schristos break;
595a1ba9ba4Schristos case OR1K_OPERAND_RA :
596a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
597a1ba9ba4Schristos break;
598*184b2d41Schristos case OR1K_OPERAND_RAD32F :
599*184b2d41Schristos {
600*184b2d41Schristos {
601*184b2d41Schristos FLD (f_r2) = ((FLD (f_rad32)) & (31));
602*184b2d41Schristos FLD (f_raoff_9_1) = ((((SI) (FLD (f_rad32)) >> (5))) & (1));
603*184b2d41Schristos }
604*184b2d41Schristos errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
605*184b2d41Schristos if (errmsg)
606*184b2d41Schristos break;
607*184b2d41Schristos errmsg = insert_normal (cd, fields->f_raoff_9_1, 0, 0, 9, 1, 32, total_length, buffer);
608*184b2d41Schristos if (errmsg)
609*184b2d41Schristos break;
610*184b2d41Schristos }
611*184b2d41Schristos break;
612*184b2d41Schristos case OR1K_OPERAND_RADI :
613*184b2d41Schristos {
614*184b2d41Schristos {
615*184b2d41Schristos FLD (f_r2) = ((FLD (f_rad32)) & (31));
616*184b2d41Schristos FLD (f_raoff_9_1) = ((((SI) (FLD (f_rad32)) >> (5))) & (1));
617*184b2d41Schristos }
618*184b2d41Schristos errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
619*184b2d41Schristos if (errmsg)
620*184b2d41Schristos break;
621*184b2d41Schristos errmsg = insert_normal (cd, fields->f_raoff_9_1, 0, 0, 9, 1, 32, total_length, buffer);
622*184b2d41Schristos if (errmsg)
623*184b2d41Schristos break;
624*184b2d41Schristos }
625a1ba9ba4Schristos break;
626a1ba9ba4Schristos case OR1K_OPERAND_RASF :
627a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_r2, 0, 0, 20, 5, 32, total_length, buffer);
628a1ba9ba4Schristos break;
629a1ba9ba4Schristos case OR1K_OPERAND_RB :
630a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
631a1ba9ba4Schristos break;
632*184b2d41Schristos case OR1K_OPERAND_RBD32F :
633*184b2d41Schristos {
634*184b2d41Schristos {
635*184b2d41Schristos FLD (f_r3) = ((FLD (f_rbd32)) & (31));
636*184b2d41Schristos FLD (f_rboff_8_1) = ((((SI) (FLD (f_rbd32)) >> (5))) & (1));
637*184b2d41Schristos }
638*184b2d41Schristos errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
639*184b2d41Schristos if (errmsg)
640*184b2d41Schristos break;
641*184b2d41Schristos errmsg = insert_normal (cd, fields->f_rboff_8_1, 0, 0, 8, 1, 32, total_length, buffer);
642*184b2d41Schristos if (errmsg)
643*184b2d41Schristos break;
644*184b2d41Schristos }
645*184b2d41Schristos break;
646*184b2d41Schristos case OR1K_OPERAND_RBDI :
647*184b2d41Schristos {
648*184b2d41Schristos {
649*184b2d41Schristos FLD (f_r3) = ((FLD (f_rbd32)) & (31));
650*184b2d41Schristos FLD (f_rboff_8_1) = ((((SI) (FLD (f_rbd32)) >> (5))) & (1));
651*184b2d41Schristos }
652*184b2d41Schristos errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
653*184b2d41Schristos if (errmsg)
654*184b2d41Schristos break;
655*184b2d41Schristos errmsg = insert_normal (cd, fields->f_rboff_8_1, 0, 0, 8, 1, 32, total_length, buffer);
656*184b2d41Schristos if (errmsg)
657*184b2d41Schristos break;
658*184b2d41Schristos }
659a1ba9ba4Schristos break;
660a1ba9ba4Schristos case OR1K_OPERAND_RBSF :
661a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_r3, 0, 0, 15, 5, 32, total_length, buffer);
662a1ba9ba4Schristos break;
663a1ba9ba4Schristos case OR1K_OPERAND_RD :
664a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
665a1ba9ba4Schristos break;
666*184b2d41Schristos case OR1K_OPERAND_RDD32F :
667*184b2d41Schristos {
668*184b2d41Schristos {
669*184b2d41Schristos FLD (f_r1) = ((FLD (f_rdd32)) & (31));
670*184b2d41Schristos FLD (f_rdoff_10_1) = ((((SI) (FLD (f_rdd32)) >> (5))) & (1));
671*184b2d41Schristos }
672a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
673*184b2d41Schristos if (errmsg)
674*184b2d41Schristos break;
675*184b2d41Schristos errmsg = insert_normal (cd, fields->f_rdoff_10_1, 0, 0, 10, 1, 32, total_length, buffer);
676*184b2d41Schristos if (errmsg)
677*184b2d41Schristos break;
678*184b2d41Schristos }
679*184b2d41Schristos break;
680*184b2d41Schristos case OR1K_OPERAND_RDDI :
681*184b2d41Schristos {
682*184b2d41Schristos {
683*184b2d41Schristos FLD (f_r1) = ((FLD (f_rdd32)) & (31));
684*184b2d41Schristos FLD (f_rdoff_10_1) = ((((SI) (FLD (f_rdd32)) >> (5))) & (1));
685*184b2d41Schristos }
686*184b2d41Schristos errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
687*184b2d41Schristos if (errmsg)
688*184b2d41Schristos break;
689*184b2d41Schristos errmsg = insert_normal (cd, fields->f_rdoff_10_1, 0, 0, 10, 1, 32, total_length, buffer);
690*184b2d41Schristos if (errmsg)
691*184b2d41Schristos break;
692*184b2d41Schristos }
693a1ba9ba4Schristos break;
694a1ba9ba4Schristos case OR1K_OPERAND_RDSF :
695a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_r1, 0, 0, 25, 5, 32, total_length, buffer);
696a1ba9ba4Schristos break;
697a1ba9ba4Schristos case OR1K_OPERAND_SIMM16 :
698a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_SIGN_OPT), 0, 15, 16, 32, total_length, buffer);
699a1ba9ba4Schristos break;
700a1ba9ba4Schristos case OR1K_OPERAND_SIMM16_SPLIT :
701a1ba9ba4Schristos {
702a1ba9ba4Schristos {
703a1ba9ba4Schristos FLD (f_imm16_25_5) = ((((INT) (FLD (f_simm16_split)) >> (11))) & (31));
704a1ba9ba4Schristos FLD (f_imm16_10_11) = ((FLD (f_simm16_split)) & (2047));
705a1ba9ba4Schristos }
706a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_imm16_25_5, 0, 0, 25, 5, 32, total_length, buffer);
707a1ba9ba4Schristos if (errmsg)
708a1ba9ba4Schristos break;
709a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_imm16_10_11, 0, 0, 10, 11, 32, total_length, buffer);
710a1ba9ba4Schristos if (errmsg)
711a1ba9ba4Schristos break;
712a1ba9ba4Schristos }
713a1ba9ba4Schristos break;
714a1ba9ba4Schristos case OR1K_OPERAND_UIMM16 :
715a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 15, 16, 32, total_length, buffer);
716a1ba9ba4Schristos break;
717a1ba9ba4Schristos case OR1K_OPERAND_UIMM16_SPLIT :
718a1ba9ba4Schristos {
719a1ba9ba4Schristos {
720a1ba9ba4Schristos FLD (f_imm16_25_5) = ((((UINT) (FLD (f_uimm16_split)) >> (11))) & (31));
721a1ba9ba4Schristos FLD (f_imm16_10_11) = ((FLD (f_uimm16_split)) & (2047));
722a1ba9ba4Schristos }
723a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_imm16_25_5, 0, 0, 25, 5, 32, total_length, buffer);
724a1ba9ba4Schristos if (errmsg)
725a1ba9ba4Schristos break;
726a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_imm16_10_11, 0, 0, 10, 11, 32, total_length, buffer);
727a1ba9ba4Schristos if (errmsg)
728a1ba9ba4Schristos break;
729a1ba9ba4Schristos }
730a1ba9ba4Schristos break;
731a1ba9ba4Schristos case OR1K_OPERAND_UIMM6 :
732a1ba9ba4Schristos errmsg = insert_normal (cd, fields->f_uimm6, 0, 0, 5, 6, 32, total_length, buffer);
733a1ba9ba4Schristos break;
734a1ba9ba4Schristos
735a1ba9ba4Schristos default :
736a1ba9ba4Schristos /* xgettext:c-format */
737dc268d07Schristos opcodes_error_handler
738dc268d07Schristos (_("internal error: unrecognized field %d while building insn"),
739a1ba9ba4Schristos opindex);
740a1ba9ba4Schristos abort ();
741a1ba9ba4Schristos }
742a1ba9ba4Schristos
743a1ba9ba4Schristos return errmsg;
744a1ba9ba4Schristos }
745a1ba9ba4Schristos
746a1ba9ba4Schristos int or1k_cgen_extract_operand
747a1ba9ba4Schristos (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
748a1ba9ba4Schristos
749a1ba9ba4Schristos /* Main entry point for operand extraction.
750a1ba9ba4Schristos The result is <= 0 for error, >0 for success.
751a1ba9ba4Schristos ??? Actual values aren't well defined right now.
752a1ba9ba4Schristos
753a1ba9ba4Schristos This function is basically just a big switch statement. Earlier versions
754a1ba9ba4Schristos used tables to look up the function to use, but
755a1ba9ba4Schristos - if the table contains both assembler and disassembler functions then
756a1ba9ba4Schristos the disassembler contains much of the assembler and vice-versa,
757a1ba9ba4Schristos - there's a lot of inlining possibilities as things grow,
758a1ba9ba4Schristos - using a switch statement avoids the function call overhead.
759a1ba9ba4Schristos
760a1ba9ba4Schristos This function could be moved into `print_insn_normal', but keeping it
761a1ba9ba4Schristos separate makes clear the interface between `print_insn_normal' and each of
762a1ba9ba4Schristos the handlers. */
763a1ba9ba4Schristos
764a1ba9ba4Schristos int
or1k_cgen_extract_operand(CGEN_CPU_DESC cd,int opindex,CGEN_EXTRACT_INFO * ex_info,CGEN_INSN_INT insn_value,CGEN_FIELDS * fields,bfd_vma pc)765a1ba9ba4Schristos or1k_cgen_extract_operand (CGEN_CPU_DESC cd,
766a1ba9ba4Schristos int opindex,
767a1ba9ba4Schristos CGEN_EXTRACT_INFO *ex_info,
768a1ba9ba4Schristos CGEN_INSN_INT insn_value,
769a1ba9ba4Schristos CGEN_FIELDS * fields,
770a1ba9ba4Schristos bfd_vma pc)
771a1ba9ba4Schristos {
772a1ba9ba4Schristos /* Assume success (for those operands that are nops). */
773a1ba9ba4Schristos int length = 1;
774a1ba9ba4Schristos unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
775a1ba9ba4Schristos
776a1ba9ba4Schristos switch (opindex)
777a1ba9ba4Schristos {
778dc268d07Schristos case OR1K_OPERAND_DISP21 :
779dc268d07Schristos {
780dc268d07Schristos long value;
781dc268d07Schristos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, pc, & value);
782*184b2d41Schristos value = ((((value) + (((SI) (pc) >> (13))))) * (8192));
783dc268d07Schristos fields->f_disp21 = value;
784dc268d07Schristos }
785dc268d07Schristos break;
786a1ba9ba4Schristos case OR1K_OPERAND_DISP26 :
787a1ba9ba4Schristos {
788a1ba9ba4Schristos long value;
789a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 25, 26, 32, total_length, pc, & value);
790*184b2d41Schristos value = ((((value) * (4))) + (pc));
791a1ba9ba4Schristos fields->f_disp26 = value;
792a1ba9ba4Schristos }
793a1ba9ba4Schristos break;
794a1ba9ba4Schristos case OR1K_OPERAND_RA :
795a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
796a1ba9ba4Schristos break;
797*184b2d41Schristos case OR1K_OPERAND_RAD32F :
798*184b2d41Schristos {
799*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
800*184b2d41Schristos if (length <= 0) break;
801*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 1, 32, total_length, pc, & fields->f_raoff_9_1);
802*184b2d41Schristos if (length <= 0) break;
803*184b2d41Schristos FLD (f_rad32) = ((FLD (f_r2)) | (((FLD (f_raoff_9_1)) << (5))));
804*184b2d41Schristos }
805*184b2d41Schristos break;
806*184b2d41Schristos case OR1K_OPERAND_RADI :
807*184b2d41Schristos {
808*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
809*184b2d41Schristos if (length <= 0) break;
810*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 1, 32, total_length, pc, & fields->f_raoff_9_1);
811*184b2d41Schristos if (length <= 0) break;
812*184b2d41Schristos FLD (f_rad32) = ((FLD (f_r2)) | (((FLD (f_raoff_9_1)) << (5))));
813*184b2d41Schristos }
814a1ba9ba4Schristos break;
815a1ba9ba4Schristos case OR1K_OPERAND_RASF :
816a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_r2);
817a1ba9ba4Schristos break;
818a1ba9ba4Schristos case OR1K_OPERAND_RB :
819a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
820a1ba9ba4Schristos break;
821*184b2d41Schristos case OR1K_OPERAND_RBD32F :
822*184b2d41Schristos {
823*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
824*184b2d41Schristos if (length <= 0) break;
825*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_rboff_8_1);
826*184b2d41Schristos if (length <= 0) break;
827*184b2d41Schristos FLD (f_rbd32) = ((FLD (f_r3)) | (((FLD (f_rboff_8_1)) << (5))));
828*184b2d41Schristos }
829*184b2d41Schristos break;
830*184b2d41Schristos case OR1K_OPERAND_RBDI :
831*184b2d41Schristos {
832*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
833*184b2d41Schristos if (length <= 0) break;
834*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_rboff_8_1);
835*184b2d41Schristos if (length <= 0) break;
836*184b2d41Schristos FLD (f_rbd32) = ((FLD (f_r3)) | (((FLD (f_rboff_8_1)) << (5))));
837*184b2d41Schristos }
838a1ba9ba4Schristos break;
839a1ba9ba4Schristos case OR1K_OPERAND_RBSF :
840a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_r3);
841a1ba9ba4Schristos break;
842a1ba9ba4Schristos case OR1K_OPERAND_RD :
843a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
844a1ba9ba4Schristos break;
845*184b2d41Schristos case OR1K_OPERAND_RDD32F :
846*184b2d41Schristos {
847a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
848*184b2d41Schristos if (length <= 0) break;
849*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_rdoff_10_1);
850*184b2d41Schristos if (length <= 0) break;
851*184b2d41Schristos FLD (f_rdd32) = ((FLD (f_r1)) | (((FLD (f_rdoff_10_1)) << (5))));
852*184b2d41Schristos }
853*184b2d41Schristos break;
854*184b2d41Schristos case OR1K_OPERAND_RDDI :
855*184b2d41Schristos {
856*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
857*184b2d41Schristos if (length <= 0) break;
858*184b2d41Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_rdoff_10_1);
859*184b2d41Schristos if (length <= 0) break;
860*184b2d41Schristos FLD (f_rdd32) = ((FLD (f_r1)) | (((FLD (f_rdoff_10_1)) << (5))));
861*184b2d41Schristos }
862a1ba9ba4Schristos break;
863a1ba9ba4Schristos case OR1K_OPERAND_RDSF :
864a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_r1);
865a1ba9ba4Schristos break;
866a1ba9ba4Schristos case OR1K_OPERAND_SIMM16 :
867a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_SIGN_OPT), 0, 15, 16, 32, total_length, pc, & fields->f_simm16);
868a1ba9ba4Schristos break;
869a1ba9ba4Schristos case OR1K_OPERAND_SIMM16_SPLIT :
870a1ba9ba4Schristos {
871a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_imm16_25_5);
872a1ba9ba4Schristos if (length <= 0) break;
873a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_imm16_10_11);
874a1ba9ba4Schristos if (length <= 0) break;
875a1ba9ba4Schristos FLD (f_simm16_split) = ((HI) (UINT) (((((FLD (f_imm16_25_5)) << (11))) | (FLD (f_imm16_10_11)))));
876a1ba9ba4Schristos }
877a1ba9ba4Schristos break;
878a1ba9ba4Schristos case OR1K_OPERAND_UIMM16 :
879a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_uimm16);
880a1ba9ba4Schristos break;
881a1ba9ba4Schristos case OR1K_OPERAND_UIMM16_SPLIT :
882a1ba9ba4Schristos {
883a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_imm16_25_5);
884a1ba9ba4Schristos if (length <= 0) break;
885a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 11, 32, total_length, pc, & fields->f_imm16_10_11);
886a1ba9ba4Schristos if (length <= 0) break;
887a1ba9ba4Schristos FLD (f_uimm16_split) = ((UHI) (UINT) (((((FLD (f_imm16_25_5)) << (11))) | (FLD (f_imm16_10_11)))));
888a1ba9ba4Schristos }
889a1ba9ba4Schristos break;
890a1ba9ba4Schristos case OR1K_OPERAND_UIMM6 :
891a1ba9ba4Schristos length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_uimm6);
892a1ba9ba4Schristos break;
893a1ba9ba4Schristos
894a1ba9ba4Schristos default :
895a1ba9ba4Schristos /* xgettext:c-format */
896dc268d07Schristos opcodes_error_handler
897dc268d07Schristos (_("internal error: unrecognized field %d while decoding insn"),
898a1ba9ba4Schristos opindex);
899a1ba9ba4Schristos abort ();
900a1ba9ba4Schristos }
901a1ba9ba4Schristos
902a1ba9ba4Schristos return length;
903a1ba9ba4Schristos }
904a1ba9ba4Schristos
905a1ba9ba4Schristos cgen_insert_fn * const or1k_cgen_insert_handlers[] =
906a1ba9ba4Schristos {
907a1ba9ba4Schristos insert_insn_normal,
908a1ba9ba4Schristos };
909a1ba9ba4Schristos
910a1ba9ba4Schristos cgen_extract_fn * const or1k_cgen_extract_handlers[] =
911a1ba9ba4Schristos {
912a1ba9ba4Schristos extract_insn_normal,
913a1ba9ba4Schristos };
914a1ba9ba4Schristos
915a1ba9ba4Schristos int or1k_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
916a1ba9ba4Schristos bfd_vma or1k_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
917a1ba9ba4Schristos
918a1ba9ba4Schristos /* Getting values from cgen_fields is handled by a collection of functions.
919a1ba9ba4Schristos They are distinguished by the type of the VALUE argument they return.
920a1ba9ba4Schristos TODO: floating point, inlining support, remove cases where result type
921a1ba9ba4Schristos not appropriate. */
922a1ba9ba4Schristos
923a1ba9ba4Schristos int
or1k_cgen_get_int_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,const CGEN_FIELDS * fields)924a1ba9ba4Schristos or1k_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
925a1ba9ba4Schristos int opindex,
926a1ba9ba4Schristos const CGEN_FIELDS * fields)
927a1ba9ba4Schristos {
928a1ba9ba4Schristos int value;
929a1ba9ba4Schristos
930a1ba9ba4Schristos switch (opindex)
931a1ba9ba4Schristos {
932dc268d07Schristos case OR1K_OPERAND_DISP21 :
933dc268d07Schristos value = fields->f_disp21;
934dc268d07Schristos break;
935a1ba9ba4Schristos case OR1K_OPERAND_DISP26 :
936a1ba9ba4Schristos value = fields->f_disp26;
937a1ba9ba4Schristos break;
938a1ba9ba4Schristos case OR1K_OPERAND_RA :
939a1ba9ba4Schristos value = fields->f_r2;
940a1ba9ba4Schristos break;
941*184b2d41Schristos case OR1K_OPERAND_RAD32F :
942*184b2d41Schristos value = fields->f_rad32;
943*184b2d41Schristos break;
944*184b2d41Schristos case OR1K_OPERAND_RADI :
945*184b2d41Schristos value = fields->f_rad32;
946a1ba9ba4Schristos break;
947a1ba9ba4Schristos case OR1K_OPERAND_RASF :
948a1ba9ba4Schristos value = fields->f_r2;
949a1ba9ba4Schristos break;
950a1ba9ba4Schristos case OR1K_OPERAND_RB :
951a1ba9ba4Schristos value = fields->f_r3;
952a1ba9ba4Schristos break;
953*184b2d41Schristos case OR1K_OPERAND_RBD32F :
954*184b2d41Schristos value = fields->f_rbd32;
955*184b2d41Schristos break;
956*184b2d41Schristos case OR1K_OPERAND_RBDI :
957*184b2d41Schristos value = fields->f_rbd32;
958a1ba9ba4Schristos break;
959a1ba9ba4Schristos case OR1K_OPERAND_RBSF :
960a1ba9ba4Schristos value = fields->f_r3;
961a1ba9ba4Schristos break;
962a1ba9ba4Schristos case OR1K_OPERAND_RD :
963a1ba9ba4Schristos value = fields->f_r1;
964a1ba9ba4Schristos break;
965*184b2d41Schristos case OR1K_OPERAND_RDD32F :
966*184b2d41Schristos value = fields->f_rdd32;
967*184b2d41Schristos break;
968*184b2d41Schristos case OR1K_OPERAND_RDDI :
969*184b2d41Schristos value = fields->f_rdd32;
970a1ba9ba4Schristos break;
971a1ba9ba4Schristos case OR1K_OPERAND_RDSF :
972a1ba9ba4Schristos value = fields->f_r1;
973a1ba9ba4Schristos break;
974a1ba9ba4Schristos case OR1K_OPERAND_SIMM16 :
975a1ba9ba4Schristos value = fields->f_simm16;
976a1ba9ba4Schristos break;
977a1ba9ba4Schristos case OR1K_OPERAND_SIMM16_SPLIT :
978a1ba9ba4Schristos value = fields->f_simm16_split;
979a1ba9ba4Schristos break;
980a1ba9ba4Schristos case OR1K_OPERAND_UIMM16 :
981a1ba9ba4Schristos value = fields->f_uimm16;
982a1ba9ba4Schristos break;
983a1ba9ba4Schristos case OR1K_OPERAND_UIMM16_SPLIT :
984a1ba9ba4Schristos value = fields->f_uimm16_split;
985a1ba9ba4Schristos break;
986a1ba9ba4Schristos case OR1K_OPERAND_UIMM6 :
987a1ba9ba4Schristos value = fields->f_uimm6;
988a1ba9ba4Schristos break;
989a1ba9ba4Schristos
990a1ba9ba4Schristos default :
991a1ba9ba4Schristos /* xgettext:c-format */
992dc268d07Schristos opcodes_error_handler
993dc268d07Schristos (_("internal error: unrecognized field %d while getting int operand"),
994a1ba9ba4Schristos opindex);
995a1ba9ba4Schristos abort ();
996a1ba9ba4Schristos }
997a1ba9ba4Schristos
998a1ba9ba4Schristos return value;
999a1ba9ba4Schristos }
1000a1ba9ba4Schristos
1001a1ba9ba4Schristos bfd_vma
or1k_cgen_get_vma_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,const CGEN_FIELDS * fields)1002a1ba9ba4Schristos or1k_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1003a1ba9ba4Schristos int opindex,
1004a1ba9ba4Schristos const CGEN_FIELDS * fields)
1005a1ba9ba4Schristos {
1006a1ba9ba4Schristos bfd_vma value;
1007a1ba9ba4Schristos
1008a1ba9ba4Schristos switch (opindex)
1009a1ba9ba4Schristos {
1010dc268d07Schristos case OR1K_OPERAND_DISP21 :
1011dc268d07Schristos value = fields->f_disp21;
1012dc268d07Schristos break;
1013a1ba9ba4Schristos case OR1K_OPERAND_DISP26 :
1014a1ba9ba4Schristos value = fields->f_disp26;
1015a1ba9ba4Schristos break;
1016a1ba9ba4Schristos case OR1K_OPERAND_RA :
1017a1ba9ba4Schristos value = fields->f_r2;
1018a1ba9ba4Schristos break;
1019*184b2d41Schristos case OR1K_OPERAND_RAD32F :
1020*184b2d41Schristos value = fields->f_rad32;
1021*184b2d41Schristos break;
1022*184b2d41Schristos case OR1K_OPERAND_RADI :
1023*184b2d41Schristos value = fields->f_rad32;
1024a1ba9ba4Schristos break;
1025a1ba9ba4Schristos case OR1K_OPERAND_RASF :
1026a1ba9ba4Schristos value = fields->f_r2;
1027a1ba9ba4Schristos break;
1028a1ba9ba4Schristos case OR1K_OPERAND_RB :
1029a1ba9ba4Schristos value = fields->f_r3;
1030a1ba9ba4Schristos break;
1031*184b2d41Schristos case OR1K_OPERAND_RBD32F :
1032*184b2d41Schristos value = fields->f_rbd32;
1033*184b2d41Schristos break;
1034*184b2d41Schristos case OR1K_OPERAND_RBDI :
1035*184b2d41Schristos value = fields->f_rbd32;
1036a1ba9ba4Schristos break;
1037a1ba9ba4Schristos case OR1K_OPERAND_RBSF :
1038a1ba9ba4Schristos value = fields->f_r3;
1039a1ba9ba4Schristos break;
1040a1ba9ba4Schristos case OR1K_OPERAND_RD :
1041a1ba9ba4Schristos value = fields->f_r1;
1042a1ba9ba4Schristos break;
1043*184b2d41Schristos case OR1K_OPERAND_RDD32F :
1044*184b2d41Schristos value = fields->f_rdd32;
1045*184b2d41Schristos break;
1046*184b2d41Schristos case OR1K_OPERAND_RDDI :
1047*184b2d41Schristos value = fields->f_rdd32;
1048a1ba9ba4Schristos break;
1049a1ba9ba4Schristos case OR1K_OPERAND_RDSF :
1050a1ba9ba4Schristos value = fields->f_r1;
1051a1ba9ba4Schristos break;
1052a1ba9ba4Schristos case OR1K_OPERAND_SIMM16 :
1053a1ba9ba4Schristos value = fields->f_simm16;
1054a1ba9ba4Schristos break;
1055a1ba9ba4Schristos case OR1K_OPERAND_SIMM16_SPLIT :
1056a1ba9ba4Schristos value = fields->f_simm16_split;
1057a1ba9ba4Schristos break;
1058a1ba9ba4Schristos case OR1K_OPERAND_UIMM16 :
1059a1ba9ba4Schristos value = fields->f_uimm16;
1060a1ba9ba4Schristos break;
1061a1ba9ba4Schristos case OR1K_OPERAND_UIMM16_SPLIT :
1062a1ba9ba4Schristos value = fields->f_uimm16_split;
1063a1ba9ba4Schristos break;
1064a1ba9ba4Schristos case OR1K_OPERAND_UIMM6 :
1065a1ba9ba4Schristos value = fields->f_uimm6;
1066a1ba9ba4Schristos break;
1067a1ba9ba4Schristos
1068a1ba9ba4Schristos default :
1069a1ba9ba4Schristos /* xgettext:c-format */
1070dc268d07Schristos opcodes_error_handler
1071dc268d07Schristos (_("internal error: unrecognized field %d while getting vma operand"),
1072a1ba9ba4Schristos opindex);
1073a1ba9ba4Schristos abort ();
1074a1ba9ba4Schristos }
1075a1ba9ba4Schristos
1076a1ba9ba4Schristos return value;
1077a1ba9ba4Schristos }
1078a1ba9ba4Schristos
1079a1ba9ba4Schristos void or1k_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1080a1ba9ba4Schristos void or1k_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1081a1ba9ba4Schristos
1082a1ba9ba4Schristos /* Stuffing values in cgen_fields is handled by a collection of functions.
1083a1ba9ba4Schristos They are distinguished by the type of the VALUE argument they accept.
1084a1ba9ba4Schristos TODO: floating point, inlining support, remove cases where argument type
1085a1ba9ba4Schristos not appropriate. */
1086a1ba9ba4Schristos
1087a1ba9ba4Schristos void
or1k_cgen_set_int_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,CGEN_FIELDS * fields,int value)1088a1ba9ba4Schristos or1k_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1089a1ba9ba4Schristos int opindex,
1090a1ba9ba4Schristos CGEN_FIELDS * fields,
1091a1ba9ba4Schristos int value)
1092a1ba9ba4Schristos {
1093a1ba9ba4Schristos switch (opindex)
1094a1ba9ba4Schristos {
1095dc268d07Schristos case OR1K_OPERAND_DISP21 :
1096dc268d07Schristos fields->f_disp21 = value;
1097dc268d07Schristos break;
1098a1ba9ba4Schristos case OR1K_OPERAND_DISP26 :
1099a1ba9ba4Schristos fields->f_disp26 = value;
1100a1ba9ba4Schristos break;
1101a1ba9ba4Schristos case OR1K_OPERAND_RA :
1102a1ba9ba4Schristos fields->f_r2 = value;
1103a1ba9ba4Schristos break;
1104*184b2d41Schristos case OR1K_OPERAND_RAD32F :
1105*184b2d41Schristos fields->f_rad32 = value;
1106*184b2d41Schristos break;
1107*184b2d41Schristos case OR1K_OPERAND_RADI :
1108*184b2d41Schristos fields->f_rad32 = value;
1109a1ba9ba4Schristos break;
1110a1ba9ba4Schristos case OR1K_OPERAND_RASF :
1111a1ba9ba4Schristos fields->f_r2 = value;
1112a1ba9ba4Schristos break;
1113a1ba9ba4Schristos case OR1K_OPERAND_RB :
1114a1ba9ba4Schristos fields->f_r3 = value;
1115a1ba9ba4Schristos break;
1116*184b2d41Schristos case OR1K_OPERAND_RBD32F :
1117*184b2d41Schristos fields->f_rbd32 = value;
1118*184b2d41Schristos break;
1119*184b2d41Schristos case OR1K_OPERAND_RBDI :
1120*184b2d41Schristos fields->f_rbd32 = value;
1121a1ba9ba4Schristos break;
1122a1ba9ba4Schristos case OR1K_OPERAND_RBSF :
1123a1ba9ba4Schristos fields->f_r3 = value;
1124a1ba9ba4Schristos break;
1125a1ba9ba4Schristos case OR1K_OPERAND_RD :
1126a1ba9ba4Schristos fields->f_r1 = value;
1127a1ba9ba4Schristos break;
1128*184b2d41Schristos case OR1K_OPERAND_RDD32F :
1129*184b2d41Schristos fields->f_rdd32 = value;
1130*184b2d41Schristos break;
1131*184b2d41Schristos case OR1K_OPERAND_RDDI :
1132*184b2d41Schristos fields->f_rdd32 = value;
1133a1ba9ba4Schristos break;
1134a1ba9ba4Schristos case OR1K_OPERAND_RDSF :
1135a1ba9ba4Schristos fields->f_r1 = value;
1136a1ba9ba4Schristos break;
1137a1ba9ba4Schristos case OR1K_OPERAND_SIMM16 :
1138a1ba9ba4Schristos fields->f_simm16 = value;
1139a1ba9ba4Schristos break;
1140a1ba9ba4Schristos case OR1K_OPERAND_SIMM16_SPLIT :
1141a1ba9ba4Schristos fields->f_simm16_split = value;
1142a1ba9ba4Schristos break;
1143a1ba9ba4Schristos case OR1K_OPERAND_UIMM16 :
1144a1ba9ba4Schristos fields->f_uimm16 = value;
1145a1ba9ba4Schristos break;
1146a1ba9ba4Schristos case OR1K_OPERAND_UIMM16_SPLIT :
1147a1ba9ba4Schristos fields->f_uimm16_split = value;
1148a1ba9ba4Schristos break;
1149a1ba9ba4Schristos case OR1K_OPERAND_UIMM6 :
1150a1ba9ba4Schristos fields->f_uimm6 = value;
1151a1ba9ba4Schristos break;
1152a1ba9ba4Schristos
1153a1ba9ba4Schristos default :
1154a1ba9ba4Schristos /* xgettext:c-format */
1155dc268d07Schristos opcodes_error_handler
1156dc268d07Schristos (_("internal error: unrecognized field %d while setting int operand"),
1157a1ba9ba4Schristos opindex);
1158a1ba9ba4Schristos abort ();
1159a1ba9ba4Schristos }
1160a1ba9ba4Schristos }
1161a1ba9ba4Schristos
1162a1ba9ba4Schristos void
or1k_cgen_set_vma_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,CGEN_FIELDS * fields,bfd_vma value)1163a1ba9ba4Schristos or1k_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1164a1ba9ba4Schristos int opindex,
1165a1ba9ba4Schristos CGEN_FIELDS * fields,
1166a1ba9ba4Schristos bfd_vma value)
1167a1ba9ba4Schristos {
1168a1ba9ba4Schristos switch (opindex)
1169a1ba9ba4Schristos {
1170dc268d07Schristos case OR1K_OPERAND_DISP21 :
1171dc268d07Schristos fields->f_disp21 = value;
1172dc268d07Schristos break;
1173a1ba9ba4Schristos case OR1K_OPERAND_DISP26 :
1174a1ba9ba4Schristos fields->f_disp26 = value;
1175a1ba9ba4Schristos break;
1176a1ba9ba4Schristos case OR1K_OPERAND_RA :
1177a1ba9ba4Schristos fields->f_r2 = value;
1178a1ba9ba4Schristos break;
1179*184b2d41Schristos case OR1K_OPERAND_RAD32F :
1180*184b2d41Schristos fields->f_rad32 = value;
1181*184b2d41Schristos break;
1182*184b2d41Schristos case OR1K_OPERAND_RADI :
1183*184b2d41Schristos fields->f_rad32 = value;
1184a1ba9ba4Schristos break;
1185a1ba9ba4Schristos case OR1K_OPERAND_RASF :
1186a1ba9ba4Schristos fields->f_r2 = value;
1187a1ba9ba4Schristos break;
1188a1ba9ba4Schristos case OR1K_OPERAND_RB :
1189a1ba9ba4Schristos fields->f_r3 = value;
1190a1ba9ba4Schristos break;
1191*184b2d41Schristos case OR1K_OPERAND_RBD32F :
1192*184b2d41Schristos fields->f_rbd32 = value;
1193*184b2d41Schristos break;
1194*184b2d41Schristos case OR1K_OPERAND_RBDI :
1195*184b2d41Schristos fields->f_rbd32 = value;
1196a1ba9ba4Schristos break;
1197a1ba9ba4Schristos case OR1K_OPERAND_RBSF :
1198a1ba9ba4Schristos fields->f_r3 = value;
1199a1ba9ba4Schristos break;
1200a1ba9ba4Schristos case OR1K_OPERAND_RD :
1201a1ba9ba4Schristos fields->f_r1 = value;
1202a1ba9ba4Schristos break;
1203*184b2d41Schristos case OR1K_OPERAND_RDD32F :
1204*184b2d41Schristos fields->f_rdd32 = value;
1205*184b2d41Schristos break;
1206*184b2d41Schristos case OR1K_OPERAND_RDDI :
1207*184b2d41Schristos fields->f_rdd32 = value;
1208a1ba9ba4Schristos break;
1209a1ba9ba4Schristos case OR1K_OPERAND_RDSF :
1210a1ba9ba4Schristos fields->f_r1 = value;
1211a1ba9ba4Schristos break;
1212a1ba9ba4Schristos case OR1K_OPERAND_SIMM16 :
1213a1ba9ba4Schristos fields->f_simm16 = value;
1214a1ba9ba4Schristos break;
1215a1ba9ba4Schristos case OR1K_OPERAND_SIMM16_SPLIT :
1216a1ba9ba4Schristos fields->f_simm16_split = value;
1217a1ba9ba4Schristos break;
1218a1ba9ba4Schristos case OR1K_OPERAND_UIMM16 :
1219a1ba9ba4Schristos fields->f_uimm16 = value;
1220a1ba9ba4Schristos break;
1221a1ba9ba4Schristos case OR1K_OPERAND_UIMM16_SPLIT :
1222a1ba9ba4Schristos fields->f_uimm16_split = value;
1223a1ba9ba4Schristos break;
1224a1ba9ba4Schristos case OR1K_OPERAND_UIMM6 :
1225a1ba9ba4Schristos fields->f_uimm6 = value;
1226a1ba9ba4Schristos break;
1227a1ba9ba4Schristos
1228a1ba9ba4Schristos default :
1229a1ba9ba4Schristos /* xgettext:c-format */
1230dc268d07Schristos opcodes_error_handler
1231dc268d07Schristos (_("internal error: unrecognized field %d while setting vma operand"),
1232a1ba9ba4Schristos opindex);
1233a1ba9ba4Schristos abort ();
1234a1ba9ba4Schristos }
1235a1ba9ba4Schristos }
1236a1ba9ba4Schristos
1237a1ba9ba4Schristos /* Function to call before using the instruction builder tables. */
1238a1ba9ba4Schristos
1239a1ba9ba4Schristos void
or1k_cgen_init_ibld_table(CGEN_CPU_DESC cd)1240a1ba9ba4Schristos or1k_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1241a1ba9ba4Schristos {
1242a1ba9ba4Schristos cd->insert_handlers = & or1k_cgen_insert_handlers[0];
1243a1ba9ba4Schristos cd->extract_handlers = & or1k_cgen_extract_handlers[0];
1244a1ba9ba4Schristos
1245a1ba9ba4Schristos cd->insert_operand = or1k_cgen_insert_operand;
1246a1ba9ba4Schristos cd->extract_operand = or1k_cgen_extract_operand;
1247a1ba9ba4Schristos
1248a1ba9ba4Schristos cd->get_int_operand = or1k_cgen_get_int_operand;
1249a1ba9ba4Schristos cd->set_int_operand = or1k_cgen_set_int_operand;
1250a1ba9ba4Schristos cd->get_vma_operand = or1k_cgen_get_vma_operand;
1251a1ba9ba4Schristos cd->set_vma_operand = or1k_cgen_set_vma_operand;
1252a1ba9ba4Schristos }
1253