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