1f7cc78ecSespie /* Assemble V850 instructions.
2*cf2f2c56Smiod Copyright 1996, 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
3f7cc78ecSespie
4f7cc78ecSespie This program is free software; you can redistribute it and/or modify
5f7cc78ecSespie it under the terms of the GNU General Public License as published by
6f7cc78ecSespie the Free Software Foundation; either version 2 of the License, or
7f7cc78ecSespie (at your option) any later version.
8f7cc78ecSespie
9f7cc78ecSespie This program is distributed in the hope that it will be useful,
10f7cc78ecSespie but WITHOUT ANY WARRANTY; without even the implied warranty of
11f7cc78ecSespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12f7cc78ecSespie GNU General Public License for more details.
13f7cc78ecSespie
14f7cc78ecSespie You should have received a copy of the GNU General Public License
15f7cc78ecSespie along with this program; if not, write to the Free Software
16f7cc78ecSespie Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17f7cc78ecSespie
18f7cc78ecSespie #include "sysdep.h"
19f7cc78ecSespie #include "opcode/v850.h"
20f7cc78ecSespie #include <stdio.h>
21f7cc78ecSespie #include "opintl.h"
22f7cc78ecSespie
23*cf2f2c56Smiod /* Regular opcodes. */
24f7cc78ecSespie #define OP(x) ((x & 0x3f) << 5)
25f7cc78ecSespie #define OP_MASK OP (0x3f)
26f7cc78ecSespie
27*cf2f2c56Smiod /* Conditional branch opcodes. */
28f7cc78ecSespie #define BOP(x) ((0x0b << 7) | (x & 0x0f))
29f7cc78ecSespie #define BOP_MASK ((0x0f << 7) | 0x0f)
30f7cc78ecSespie
31*cf2f2c56Smiod /* One-word opcodes. */
32f7cc78ecSespie #define one(x) ((unsigned int) (x))
33f7cc78ecSespie
34*cf2f2c56Smiod /* Two-word opcodes. */
35f7cc78ecSespie #define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16))
36f7cc78ecSespie
37d2201f2fSdrahn static long unsigned insert_d9 PARAMS ((long unsigned, long, const char **));
38d2201f2fSdrahn static long unsigned extract_d9 PARAMS ((long unsigned, int *));
39d2201f2fSdrahn static long unsigned insert_d22 PARAMS ((long unsigned, long, const char **));
40d2201f2fSdrahn static long unsigned extract_d22 PARAMS ((long unsigned, int *));
41d2201f2fSdrahn static long unsigned insert_d16_15 PARAMS ((long unsigned, long, const char **));
42d2201f2fSdrahn static long unsigned extract_d16_15 PARAMS ((long unsigned, int *));
43d2201f2fSdrahn static long unsigned insert_d8_7 PARAMS ((long unsigned, long, const char **));
44d2201f2fSdrahn static long unsigned extract_d8_7 PARAMS ((long unsigned, int *));
45d2201f2fSdrahn static long unsigned insert_d8_6 PARAMS ((long unsigned, long, const char **));
46d2201f2fSdrahn static long unsigned extract_d8_6 PARAMS ((long unsigned, int *));
47d2201f2fSdrahn static long unsigned insert_d5_4 PARAMS ((long unsigned, long, const char **));
48d2201f2fSdrahn static long unsigned extract_d5_4 PARAMS ((long unsigned, int *));
49d2201f2fSdrahn static long unsigned insert_d16_16 PARAMS ((long unsigned, long, const char **));
50d2201f2fSdrahn static long unsigned extract_d16_16 PARAMS ((long unsigned, int *));
51d2201f2fSdrahn static long unsigned insert_i9 PARAMS ((long unsigned, long, const char **));
52d2201f2fSdrahn static long unsigned extract_i9 PARAMS ((long unsigned, int *));
53d2201f2fSdrahn static long unsigned insert_u9 PARAMS ((long unsigned, long, const char **));
54d2201f2fSdrahn static long unsigned extract_u9 PARAMS ((long unsigned, int *));
55d2201f2fSdrahn static long unsigned insert_spe PARAMS ((long unsigned, long, const char **));
56d2201f2fSdrahn static long unsigned extract_spe PARAMS ((long unsigned, int *));
57d2201f2fSdrahn static long unsigned insert_i5div PARAMS ((long unsigned, long, const char **));
58d2201f2fSdrahn static long unsigned extract_i5div PARAMS ((long unsigned, int *));
59f7cc78ecSespie
60f7cc78ecSespie
61f7cc78ecSespie /* The functions used to insert and extract complicated operands. */
62f7cc78ecSespie
63f7cc78ecSespie /* Note: There is a conspiracy between these functions and
64f7cc78ecSespie v850_insert_operand() in gas/config/tc-v850.c. Error messages
65f7cc78ecSespie containing the string 'out of range' will be ignored unless a
66f7cc78ecSespie specific command line option is given to GAS. */
67f7cc78ecSespie
68f7cc78ecSespie static const char * not_valid = N_ ("displacement value is not in range and is not aligned");
69f7cc78ecSespie static const char * out_of_range = N_ ("displacement value is out of range");
70f7cc78ecSespie static const char * not_aligned = N_ ("displacement value is not aligned");
71f7cc78ecSespie
72f7cc78ecSespie static const char * immediate_out_of_range = N_ ("immediate value is out of range");
73f7cc78ecSespie
74f7cc78ecSespie static unsigned long
insert_d9(insn,value,errmsg)75f7cc78ecSespie insert_d9 (insn, value, errmsg)
76f7cc78ecSespie unsigned long insn;
77f7cc78ecSespie long value;
78f7cc78ecSespie const char ** errmsg;
79f7cc78ecSespie {
80f7cc78ecSespie if (value > 0xff || value < -0x100)
81f7cc78ecSespie {
82f7cc78ecSespie if ((value % 2) != 0)
83f7cc78ecSespie * errmsg = _("branch value not in range and to odd offset");
84f7cc78ecSespie else
85f7cc78ecSespie * errmsg = _("branch value out of range");
86f7cc78ecSespie }
87f7cc78ecSespie else if ((value % 2) != 0)
88f7cc78ecSespie * errmsg = _("branch to odd offset");
89f7cc78ecSespie
90f7cc78ecSespie return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
91f7cc78ecSespie }
92f7cc78ecSespie
93f7cc78ecSespie static unsigned long
extract_d9(insn,invalid)94f7cc78ecSespie extract_d9 (insn, invalid)
95f7cc78ecSespie unsigned long insn;
96d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
97f7cc78ecSespie {
98f7cc78ecSespie unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
99f7cc78ecSespie
100f7cc78ecSespie if ((insn & 0x8000) != 0)
101f7cc78ecSespie ret -= 0x0200;
102f7cc78ecSespie
103f7cc78ecSespie return ret;
104f7cc78ecSespie }
105f7cc78ecSespie
106f7cc78ecSespie static unsigned long
insert_d22(insn,value,errmsg)107f7cc78ecSespie insert_d22 (insn, value, errmsg)
108f7cc78ecSespie unsigned long insn;
109f7cc78ecSespie long value;
110f7cc78ecSespie const char ** errmsg;
111f7cc78ecSespie {
112f7cc78ecSespie if (value > 0x1fffff || value < -0x200000)
113f7cc78ecSespie {
114f7cc78ecSespie if ((value % 2) != 0)
115f7cc78ecSespie * errmsg = _("branch value not in range and to an odd offset");
116f7cc78ecSespie else
117f7cc78ecSespie * errmsg = _("branch value out of range");
118f7cc78ecSespie }
119f7cc78ecSespie else if ((value % 2) != 0)
120f7cc78ecSespie * errmsg = _("branch to odd offset");
121f7cc78ecSespie
122f7cc78ecSespie return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
123f7cc78ecSespie }
124f7cc78ecSespie
125f7cc78ecSespie static unsigned long
extract_d22(insn,invalid)126f7cc78ecSespie extract_d22 (insn, invalid)
127f7cc78ecSespie unsigned long insn;
128d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
129f7cc78ecSespie {
130f7cc78ecSespie signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
131f7cc78ecSespie
132f7cc78ecSespie return (unsigned long) ((ret << 10) >> 10);
133f7cc78ecSespie }
134f7cc78ecSespie
135f7cc78ecSespie static unsigned long
insert_d16_15(insn,value,errmsg)136f7cc78ecSespie insert_d16_15 (insn, value, errmsg)
137f7cc78ecSespie unsigned long insn;
138f7cc78ecSespie long value;
139f7cc78ecSespie const char ** errmsg;
140f7cc78ecSespie {
141f7cc78ecSespie if (value > 0x7fff || value < -0x8000)
142f7cc78ecSespie {
143f7cc78ecSespie if ((value % 2) != 0)
144f7cc78ecSespie * errmsg = _(not_valid);
145f7cc78ecSespie else
146f7cc78ecSespie * errmsg = _(out_of_range);
147f7cc78ecSespie }
148f7cc78ecSespie else if ((value % 2) != 0)
149f7cc78ecSespie * errmsg = _(not_aligned);
150f7cc78ecSespie
151f7cc78ecSespie return insn | ((value & 0xfffe) << 16);
152f7cc78ecSespie }
153f7cc78ecSespie
154f7cc78ecSespie static unsigned long
extract_d16_15(insn,invalid)155f7cc78ecSespie extract_d16_15 (insn, invalid)
156f7cc78ecSespie unsigned long insn;
157d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
158f7cc78ecSespie {
159f7cc78ecSespie signed long ret = (insn & 0xfffe0000);
160f7cc78ecSespie
161f7cc78ecSespie return ret >> 16;
162f7cc78ecSespie }
163f7cc78ecSespie
164f7cc78ecSespie static unsigned long
insert_d8_7(insn,value,errmsg)165f7cc78ecSespie insert_d8_7 (insn, value, errmsg)
166f7cc78ecSespie unsigned long insn;
167f7cc78ecSespie long value;
168f7cc78ecSespie const char ** errmsg;
169f7cc78ecSespie {
170f7cc78ecSespie if (value > 0xff || value < 0)
171f7cc78ecSespie {
172f7cc78ecSespie if ((value % 2) != 0)
173f7cc78ecSespie * errmsg = _(not_valid);
174f7cc78ecSespie else
175f7cc78ecSespie * errmsg = _(out_of_range);
176f7cc78ecSespie }
177f7cc78ecSespie else if ((value % 2) != 0)
178f7cc78ecSespie * errmsg = _(not_aligned);
179f7cc78ecSespie
180f7cc78ecSespie value >>= 1;
181f7cc78ecSespie
182f7cc78ecSespie return (insn | (value & 0x7f));
183f7cc78ecSespie }
184f7cc78ecSespie
185f7cc78ecSespie static unsigned long
extract_d8_7(insn,invalid)186f7cc78ecSespie extract_d8_7 (insn, invalid)
187f7cc78ecSespie unsigned long insn;
188d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
189f7cc78ecSespie {
190f7cc78ecSespie unsigned long ret = (insn & 0x7f);
191f7cc78ecSespie
192f7cc78ecSespie return ret << 1;
193f7cc78ecSespie }
194f7cc78ecSespie
195f7cc78ecSespie static unsigned long
insert_d8_6(insn,value,errmsg)196f7cc78ecSespie insert_d8_6 (insn, value, errmsg)
197f7cc78ecSespie unsigned long insn;
198f7cc78ecSespie long value;
199f7cc78ecSespie const char ** errmsg;
200f7cc78ecSespie {
201f7cc78ecSespie if (value > 0xff || value < 0)
202f7cc78ecSespie {
203f7cc78ecSespie if ((value % 4) != 0)
204f7cc78ecSespie *errmsg = _(not_valid);
205f7cc78ecSespie else
206f7cc78ecSespie * errmsg = _(out_of_range);
207f7cc78ecSespie }
208f7cc78ecSespie else if ((value % 4) != 0)
209f7cc78ecSespie * errmsg = _(not_aligned);
210f7cc78ecSespie
211f7cc78ecSespie value >>= 1;
212f7cc78ecSespie
213f7cc78ecSespie return (insn | (value & 0x7e));
214f7cc78ecSespie }
215f7cc78ecSespie
216f7cc78ecSespie static unsigned long
extract_d8_6(insn,invalid)217f7cc78ecSespie extract_d8_6 (insn, invalid)
218f7cc78ecSespie unsigned long insn;
219d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
220f7cc78ecSespie {
221f7cc78ecSespie unsigned long ret = (insn & 0x7e);
222f7cc78ecSespie
223f7cc78ecSespie return ret << 1;
224f7cc78ecSespie }
225f7cc78ecSespie
226f7cc78ecSespie static unsigned long
insert_d5_4(insn,value,errmsg)227f7cc78ecSespie insert_d5_4 (insn, value, errmsg)
228f7cc78ecSespie unsigned long insn;
229f7cc78ecSespie long value;
230f7cc78ecSespie const char ** errmsg;
231f7cc78ecSespie {
232f7cc78ecSespie if (value > 0x1f || value < 0)
233f7cc78ecSespie {
234f7cc78ecSespie if (value & 1)
235f7cc78ecSespie * errmsg = _(not_valid);
236f7cc78ecSespie else
237f7cc78ecSespie *errmsg = _(out_of_range);
238f7cc78ecSespie }
239f7cc78ecSespie else if (value & 1)
240f7cc78ecSespie * errmsg = _(not_aligned);
241f7cc78ecSespie
242f7cc78ecSespie value >>= 1;
243f7cc78ecSespie
244f7cc78ecSespie return (insn | (value & 0x0f));
245f7cc78ecSespie }
246f7cc78ecSespie
247f7cc78ecSespie static unsigned long
extract_d5_4(insn,invalid)248f7cc78ecSespie extract_d5_4 (insn, invalid)
249f7cc78ecSespie unsigned long insn;
250d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
251f7cc78ecSespie {
252f7cc78ecSespie unsigned long ret = (insn & 0x0f);
253f7cc78ecSespie
254f7cc78ecSespie return ret << 1;
255f7cc78ecSespie }
256f7cc78ecSespie
257f7cc78ecSespie static unsigned long
insert_d16_16(insn,value,errmsg)258f7cc78ecSespie insert_d16_16 (insn, value, errmsg)
259f7cc78ecSespie unsigned long insn;
260f7cc78ecSespie signed long value;
261f7cc78ecSespie const char ** errmsg;
262f7cc78ecSespie {
263f7cc78ecSespie if (value > 0x7fff || value < -0x8000)
264f7cc78ecSespie * errmsg = _(out_of_range);
265f7cc78ecSespie
266f7cc78ecSespie return (insn | ((value & 0xfffe) << 16) | ((value & 1) << 5));
267f7cc78ecSespie }
268f7cc78ecSespie
269f7cc78ecSespie static unsigned long
extract_d16_16(insn,invalid)270f7cc78ecSespie extract_d16_16 (insn, invalid)
271f7cc78ecSespie unsigned long insn;
272d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
273f7cc78ecSespie {
274f7cc78ecSespie signed long ret = insn & 0xfffe0000;
275f7cc78ecSespie
276f7cc78ecSespie ret >>= 16;
277f7cc78ecSespie
278f7cc78ecSespie ret |= ((insn & 0x20) >> 5);
279f7cc78ecSespie
280f7cc78ecSespie return ret;
281f7cc78ecSespie }
282f7cc78ecSespie
283f7cc78ecSespie static unsigned long
insert_i9(insn,value,errmsg)284f7cc78ecSespie insert_i9 (insn, value, errmsg)
285f7cc78ecSespie unsigned long insn;
286f7cc78ecSespie signed long value;
287f7cc78ecSespie const char ** errmsg;
288f7cc78ecSespie {
289f7cc78ecSespie if (value > 0xff || value < -0x100)
290f7cc78ecSespie * errmsg = _(immediate_out_of_range);
291f7cc78ecSespie
292f7cc78ecSespie return insn | ((value & 0x1e0) << 13) | (value & 0x1f);
293f7cc78ecSespie }
294f7cc78ecSespie
295f7cc78ecSespie static unsigned long
extract_i9(insn,invalid)296f7cc78ecSespie extract_i9 (insn, invalid)
297f7cc78ecSespie unsigned long insn;
298d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
299f7cc78ecSespie {
300f7cc78ecSespie signed long ret = insn & 0x003c0000;
301f7cc78ecSespie
302f7cc78ecSespie ret <<= 10;
303f7cc78ecSespie ret >>= 23;
304f7cc78ecSespie
305f7cc78ecSespie ret |= (insn & 0x1f);
306f7cc78ecSespie
307f7cc78ecSespie return ret;
308f7cc78ecSespie }
309f7cc78ecSespie
310f7cc78ecSespie static unsigned long
insert_u9(insn,v,errmsg)311d2201f2fSdrahn insert_u9 (insn, v, errmsg)
312f7cc78ecSespie unsigned long insn;
313d2201f2fSdrahn long v;
314f7cc78ecSespie const char ** errmsg;
315f7cc78ecSespie {
316d2201f2fSdrahn unsigned long value = (unsigned long) v;
317f7cc78ecSespie if (value > 0x1ff)
318f7cc78ecSespie * errmsg = _(immediate_out_of_range);
319f7cc78ecSespie
320f7cc78ecSespie return insn | ((value & 0x1e0) << 13) | (value & 0x1f);
321f7cc78ecSespie }
322f7cc78ecSespie
323f7cc78ecSespie static unsigned long
extract_u9(insn,invalid)324f7cc78ecSespie extract_u9 (insn, invalid)
325f7cc78ecSespie unsigned long insn;
326d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
327f7cc78ecSespie {
328f7cc78ecSespie unsigned long ret = insn & 0x003c0000;
329f7cc78ecSespie
330f7cc78ecSespie ret >>= 13;
331f7cc78ecSespie
332f7cc78ecSespie ret |= (insn & 0x1f);
333f7cc78ecSespie
334f7cc78ecSespie return ret;
335f7cc78ecSespie }
336f7cc78ecSespie
337f7cc78ecSespie static unsigned long
insert_spe(insn,v,errmsg)338d2201f2fSdrahn insert_spe (insn, v, errmsg)
339f7cc78ecSespie unsigned long insn;
340d2201f2fSdrahn long v;
341f7cc78ecSespie const char ** errmsg;
342f7cc78ecSespie {
343d2201f2fSdrahn unsigned long value = (unsigned long) v;
344d2201f2fSdrahn
345f7cc78ecSespie if (value != 3)
346f7cc78ecSespie * errmsg = _("invalid register for stack adjustment");
347f7cc78ecSespie
348f7cc78ecSespie return insn & (~ 0x180000);
349f7cc78ecSespie }
350f7cc78ecSespie
351f7cc78ecSespie static unsigned long
extract_spe(insn,invalid)352f7cc78ecSespie extract_spe (insn, invalid)
353d2201f2fSdrahn unsigned long insn ATTRIBUTE_UNUSED;
354d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
355f7cc78ecSespie {
356f7cc78ecSespie return 3;
357f7cc78ecSespie }
358f7cc78ecSespie
359f7cc78ecSespie static unsigned long
insert_i5div(insn,v,errmsg)360d2201f2fSdrahn insert_i5div (insn, v, errmsg)
361f7cc78ecSespie unsigned long insn;
362d2201f2fSdrahn long v;
363f7cc78ecSespie const char ** errmsg;
364f7cc78ecSespie {
365d2201f2fSdrahn unsigned long value = (unsigned long) v;
366d2201f2fSdrahn
367f7cc78ecSespie if (value > 0x1ff)
368f7cc78ecSespie {
369f7cc78ecSespie if (value & 1)
370f7cc78ecSespie * errmsg = _("immediate value not in range and not even");
371f7cc78ecSespie else
372f7cc78ecSespie * errmsg = _(immediate_out_of_range);
373f7cc78ecSespie }
374f7cc78ecSespie else if (value & 1)
375f7cc78ecSespie * errmsg = _("immediate value must be even");
376f7cc78ecSespie
377f7cc78ecSespie value = 32 - value;
378f7cc78ecSespie
379f7cc78ecSespie return insn | ((value & 0x1e) << 17);
380f7cc78ecSespie }
381f7cc78ecSespie
382f7cc78ecSespie static unsigned long
extract_i5div(insn,invalid)383f7cc78ecSespie extract_i5div (insn, invalid)
384f7cc78ecSespie unsigned long insn;
385d2201f2fSdrahn int * invalid ATTRIBUTE_UNUSED;
386f7cc78ecSespie {
387f7cc78ecSespie unsigned long ret = insn & 0x3c0000;
388f7cc78ecSespie
389f7cc78ecSespie ret >>= 17;
390f7cc78ecSespie
391f7cc78ecSespie ret = 32 - ret;
392f7cc78ecSespie
393f7cc78ecSespie return ret;
394f7cc78ecSespie }
395f7cc78ecSespie
396f7cc78ecSespie
397f7cc78ecSespie /* Warning: code in gas/config/tc-v850.c examines the contents of this array.
398f7cc78ecSespie If you change any of the values here, be sure to look for side effects in
399f7cc78ecSespie that code. */
400f7cc78ecSespie const struct v850_operand v850_operands[] =
401f7cc78ecSespie {
402f7cc78ecSespie #define UNUSED 0
403f7cc78ecSespie { 0, 0, NULL, NULL, 0 },
404f7cc78ecSespie
405f7cc78ecSespie /* The R1 field in a format 1, 6, 7, or 9 insn. */
406f7cc78ecSespie #define R1 (UNUSED + 1)
407f7cc78ecSespie { 5, 0, NULL, NULL, V850_OPERAND_REG },
408f7cc78ecSespie
409f7cc78ecSespie /* As above, but register 0 is not allowed. */
410f7cc78ecSespie #define R1_NOTR0 (R1 + 1)
411f7cc78ecSespie { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
412f7cc78ecSespie
413f7cc78ecSespie /* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */
414f7cc78ecSespie #define R2 (R1_NOTR0 + 1)
415f7cc78ecSespie { 5, 11, NULL, NULL, V850_OPERAND_REG },
416f7cc78ecSespie
417f7cc78ecSespie /* As above, but register 0 is not allowed. */
418f7cc78ecSespie #define R2_NOTR0 (R2 + 1)
419f7cc78ecSespie { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
420f7cc78ecSespie
421f7cc78ecSespie /* The imm5 field in a format 2 insn. */
422f7cc78ecSespie #define I5 (R2_NOTR0 + 1)
423f7cc78ecSespie { 5, 0, NULL, NULL, V850_OPERAND_SIGNED },
424f7cc78ecSespie
425f7cc78ecSespie /* The unsigned imm5 field in a format 2 insn. */
426f7cc78ecSespie #define I5U (I5 + 1)
427f7cc78ecSespie { 5, 0, NULL, NULL, 0 },
428f7cc78ecSespie
429f7cc78ecSespie /* The imm16 field in a format 6 insn. */
430f7cc78ecSespie #define I16 (I5U + 1)
431f7cc78ecSespie { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
432f7cc78ecSespie
433f7cc78ecSespie /* The signed disp7 field in a format 4 insn. */
434f7cc78ecSespie #define D7 (I16 + 1)
435f7cc78ecSespie { 7, 0, NULL, NULL, 0},
436f7cc78ecSespie
437f7cc78ecSespie /* The disp16 field in a format 6 insn. */
438f7cc78ecSespie #define D16_15 (D7 + 1)
439f7cc78ecSespie { 15, 17, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED },
440f7cc78ecSespie
441f7cc78ecSespie /* The 3 bit immediate field in format 8 insn. */
442f7cc78ecSespie #define B3 (D16_15 + 1)
443f7cc78ecSespie { 3, 11, NULL, NULL, 0 },
444f7cc78ecSespie
445f7cc78ecSespie /* The 4 bit condition code in a setf instruction */
446f7cc78ecSespie #define CCCC (B3 + 1)
447f7cc78ecSespie { 4, 0, NULL, NULL, V850_OPERAND_CC },
448f7cc78ecSespie
449f7cc78ecSespie /* The unsigned DISP8 field in a format 4 insn. */
450f7cc78ecSespie #define D8_7 (CCCC + 1)
451f7cc78ecSespie { 7, 0, insert_d8_7, extract_d8_7, 0 },
452f7cc78ecSespie
453f7cc78ecSespie /* The unsigned DISP8 field in a format 4 insn. */
454f7cc78ecSespie #define D8_6 (D8_7 + 1)
455f7cc78ecSespie { 6, 1, insert_d8_6, extract_d8_6, 0 },
456f7cc78ecSespie
457f7cc78ecSespie /* System register operands. */
458f7cc78ecSespie #define SR1 (D8_6 + 1)
459f7cc78ecSespie { 5, 0, NULL, NULL, V850_OPERAND_SRG },
460f7cc78ecSespie
461f7cc78ecSespie /* EP Register. */
462f7cc78ecSespie #define EP (SR1 + 1)
463f7cc78ecSespie { 0, 0, NULL, NULL, V850_OPERAND_EP },
464f7cc78ecSespie
465f7cc78ecSespie /* The imm16 field (unsigned) in a format 6 insn. */
466f7cc78ecSespie #define I16U (EP + 1)
467f7cc78ecSespie { 16, 16, NULL, NULL, 0},
468f7cc78ecSespie
469f7cc78ecSespie /* The R2 field as a system register. */
470f7cc78ecSespie #define SR2 (I16U + 1)
471f7cc78ecSespie { 5, 11, NULL, NULL, V850_OPERAND_SRG },
472f7cc78ecSespie
473f7cc78ecSespie /* The disp16 field in a format 8 insn. */
474f7cc78ecSespie #define D16 (SR2 + 1)
475f7cc78ecSespie { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
476f7cc78ecSespie
477f7cc78ecSespie /* The DISP9 field in a format 3 insn, relaxable. */
478f7cc78ecSespie #define D9_RELAX (D16 + 1)
479f7cc78ecSespie { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP },
480f7cc78ecSespie
481f7cc78ecSespie /* The DISP22 field in a format 4 insn, relaxable.
482f7cc78ecSespie This _must_ follow D9_RELAX; the assembler assumes that the longer
483f7cc78ecSespie version immediately follows the shorter version for relaxing. */
484f7cc78ecSespie #define D22 (D9_RELAX + 1)
485f7cc78ecSespie { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP },
486f7cc78ecSespie
487f7cc78ecSespie /* The signed disp4 field in a format 4 insn. */
488f7cc78ecSespie #define D4 (D22 + 1)
489f7cc78ecSespie { 4, 0, NULL, NULL, 0},
490f7cc78ecSespie
491f7cc78ecSespie /* The unsigned disp5 field in a format 4 insn. */
492f7cc78ecSespie #define D5_4 (D4 + 1)
493f7cc78ecSespie { 4, 0, insert_d5_4, extract_d5_4, 0 },
494f7cc78ecSespie
495f7cc78ecSespie /* The disp16 field in an format 7 unsigned byte load insn. */
496f7cc78ecSespie #define D16_16 (D5_4 + 1)
497f7cc78ecSespie { -1, 0xfffe0020, insert_d16_16, extract_d16_16, 0 },
498f7cc78ecSespie
499f7cc78ecSespie /* Third register in conditional moves. */
500f7cc78ecSespie #define R3 (D16_16 + 1)
501f7cc78ecSespie { 5, 27, NULL, NULL, V850_OPERAND_REG },
502f7cc78ecSespie
503f7cc78ecSespie /* Condition code in conditional moves. */
504f7cc78ecSespie #define MOVCC (R3 + 1)
505f7cc78ecSespie { 4, 17, NULL, NULL, V850_OPERAND_CC },
506f7cc78ecSespie
507f7cc78ecSespie /* The imm9 field in a multiply word. */
508f7cc78ecSespie #define I9 (MOVCC + 1)
509f7cc78ecSespie { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED },
510f7cc78ecSespie
511f7cc78ecSespie /* The unsigned imm9 field in a multiply word. */
512f7cc78ecSespie #define U9 (I9 + 1)
513f7cc78ecSespie { 9, 0, insert_u9, extract_u9, 0 },
514f7cc78ecSespie
515f7cc78ecSespie /* A list of registers in a prepare/dispose instruction. */
516f7cc78ecSespie #define LIST12 (U9 + 1)
517f7cc78ecSespie { -1, 0xffe00001, NULL, NULL, V850E_PUSH_POP },
518f7cc78ecSespie
519f7cc78ecSespie /* The IMM6 field in a call instruction. */
520f7cc78ecSespie #define I6 (LIST12 + 1)
521f7cc78ecSespie { 6, 0, NULL, NULL, 0 },
522f7cc78ecSespie
523f7cc78ecSespie /* The 16 bit immediate following a 32 bit instruction. */
524f7cc78ecSespie #define IMM16 (I6 + 1)
525f7cc78ecSespie { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850E_IMMEDIATE16 },
526f7cc78ecSespie
527f7cc78ecSespie /* The 32 bit immediate following a 32 bit instruction. */
528f7cc78ecSespie #define IMM32 (IMM16 + 1)
529f7cc78ecSespie { 0, 0, NULL, NULL, V850E_IMMEDIATE32 },
530f7cc78ecSespie
531f7cc78ecSespie /* The imm5 field in a push/pop instruction. */
532f7cc78ecSespie #define IMM5 (IMM32 + 1)
533f7cc78ecSespie { 5, 1, NULL, NULL, 0 },
534f7cc78ecSespie
535f7cc78ecSespie /* Reg2 in dispose instruction. */
536f7cc78ecSespie #define R2DISPOSE (IMM5 + 1)
537f7cc78ecSespie { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
538f7cc78ecSespie
539f7cc78ecSespie /* Stack pointer in prepare instruction. */
540f7cc78ecSespie #define SP (R2DISPOSE + 1)
541f7cc78ecSespie { 2, 19, insert_spe, extract_spe, V850_OPERAND_REG },
542f7cc78ecSespie
543f7cc78ecSespie /* The IMM5 field in a divide N step instruction. */
544f7cc78ecSespie #define I5DIV (SP + 1)
545f7cc78ecSespie { 9, 0, insert_i5div, extract_i5div, V850_OPERAND_SIGNED },
546f7cc78ecSespie
547f7cc78ecSespie /* The list of registers in a PUSHMH/POPMH instruction. */
548f7cc78ecSespie #define LIST18_H (I5DIV + 1)
549f7cc78ecSespie { -1, 0xfff8000f, NULL, NULL, V850E_PUSH_POP },
550f7cc78ecSespie
551f7cc78ecSespie /* The list of registers in a PUSHML/POPML instruction. */
552f7cc78ecSespie #define LIST18_L (LIST18_H + 1)
553*cf2f2c56Smiod /* The setting of the 4th bit is a flag to disassmble() in v850-dis.c. */
554*cf2f2c56Smiod { -1, 0xfff8001f, NULL, NULL, V850E_PUSH_POP },
555f7cc78ecSespie } ;
556f7cc78ecSespie
557f7cc78ecSespie
558*cf2f2c56Smiod /* Reg - Reg instruction format (Format I). */
559f7cc78ecSespie #define IF1 {R1, R2}
560f7cc78ecSespie
561*cf2f2c56Smiod /* Imm - Reg instruction format (Format II). */
562f7cc78ecSespie #define IF2 {I5, R2}
563f7cc78ecSespie
564*cf2f2c56Smiod /* Conditional branch instruction format (Format III). */
565f7cc78ecSespie #define IF3 {D9_RELAX}
566f7cc78ecSespie
567*cf2f2c56Smiod /* 3 operand instruction (Format VI). */
568f7cc78ecSespie #define IF6 {I16, R1, R2}
569f7cc78ecSespie
570*cf2f2c56Smiod /* 3 operand instruction (Format VI). */
571f7cc78ecSespie #define IF6U {I16U, R1, R2}
572f7cc78ecSespie
573f7cc78ecSespie
574f7cc78ecSespie
575f7cc78ecSespie /* The opcode table.
576f7cc78ecSespie
577f7cc78ecSespie The format of the opcode table is:
578f7cc78ecSespie
579f7cc78ecSespie NAME OPCODE MASK { OPERANDS } MEMOP PROCESSOR
580f7cc78ecSespie
581f7cc78ecSespie NAME is the name of the instruction.
582f7cc78ecSespie OPCODE is the instruction opcode.
583f7cc78ecSespie MASK is the opcode mask; this is used to tell the disassembler
584f7cc78ecSespie which bits in the actual opcode must match OPCODE.
585f7cc78ecSespie OPERANDS is the list of operands.
586f7cc78ecSespie MEMOP specifies which operand (if any) is a memory operand.
587f7cc78ecSespie PROCESSORS specifies which CPU(s) support the opcode.
588f7cc78ecSespie
589f7cc78ecSespie The disassembler reads the table in order and prints the first
590f7cc78ecSespie instruction which matches, so this table is sorted to put more
591f7cc78ecSespie specific instructions before more general instructions. It is also
592f7cc78ecSespie sorted by major opcode.
593f7cc78ecSespie
594f7cc78ecSespie The table is also sorted by name. This is used by the assembler.
595f7cc78ecSespie When parsing an instruction the assembler finds the first occurance
596f7cc78ecSespie of the name of the instruciton in this table and then attempts to
597f7cc78ecSespie match the instruction's arguments with description of the operands
598f7cc78ecSespie associated with the entry it has just found in this table. If the
599f7cc78ecSespie match fails the assembler looks at the next entry in this table.
600f7cc78ecSespie If that entry has the same name as the previous entry, then it
601f7cc78ecSespie tries to match the instruction against that entry and so on. This
602f7cc78ecSespie is how the assembler copes with multiple, different formats of the
603f7cc78ecSespie same instruction. */
604f7cc78ecSespie
605f7cc78ecSespie const struct v850_opcode v850_opcodes[] =
606f7cc78ecSespie {
607f7cc78ecSespie { "breakpoint", 0xffff, 0xffff, {UNUSED}, 0, PROCESSOR_ALL },
608*cf2f2c56Smiod { "dbtrap", one (0xf840), one (0xffff), {UNUSED}, 0, PROCESSOR_V850E1 },
609f7cc78ecSespie
610f7cc78ecSespie { "jmp", one (0x0060), one (0xffe0), {R1}, 1, PROCESSOR_ALL },
611f7cc78ecSespie
612*cf2f2c56Smiod /* Load/store instructions. */
613*cf2f2c56Smiod { "sld.bu", one (0x0060), one (0x07f0), {D4, EP, R2_NOTR0}, 1, PROCESSOR_V850E1 },
614f7cc78ecSespie { "sld.bu", one (0x0060), one (0x07f0), {D4, EP, R2_NOTR0}, 1, PROCESSOR_V850E },
615f7cc78ecSespie
616*cf2f2c56Smiod { "sld.hu", one (0x0070), one (0x07f0), {D5_4, EP, R2_NOTR0}, 1, PROCESSOR_V850E1 },
617f7cc78ecSespie { "sld.hu", one (0x0070), one (0x07f0), {D5_4, EP, R2_NOTR0}, 1, PROCESSOR_V850E },
618f7cc78ecSespie
619*cf2f2c56Smiod { "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850E1 },
620f7cc78ecSespie { "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850E },
621f7cc78ecSespie { "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850 },
622f7cc78ecSespie
623*cf2f2c56Smiod { "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850E1 },
624f7cc78ecSespie { "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850E },
625f7cc78ecSespie { "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850 },
626f7cc78ecSespie { "sld.w", one (0x0500), one (0x0781), {D8_6, EP, R2}, 1, PROCESSOR_ALL },
627f7cc78ecSespie { "sst.b", one (0x0380), one (0x0780), {R2, D7, EP}, 2, PROCESSOR_ALL },
628f7cc78ecSespie { "sst.h", one (0x0480), one (0x0780), {R2, D8_7, EP}, 2, PROCESSOR_ALL },
629f7cc78ecSespie { "sst.w", one (0x0501), one (0x0781), {R2, D8_6, EP}, 2, PROCESSOR_ALL },
630f7cc78ecSespie
631f7cc78ecSespie { "prepare", two (0x0780, 0x0003), two (0xffc0, 0x001f), {LIST12, IMM5, SP}, 0, PROCESSOR_NOT_V850 },
632f7cc78ecSespie { "prepare", two (0x0780, 0x000b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 },
633f7cc78ecSespie { "prepare", two (0x0780, 0x0013), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 },
634f7cc78ecSespie { "prepare", two (0x0780, 0x001b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM32}, 0, PROCESSOR_NOT_V850 },
635f7cc78ecSespie { "prepare", two (0x0780, 0x0001), two (0xffc0, 0x001f), {LIST12, IMM5}, 0, PROCESSOR_NOT_V850 },
636f7cc78ecSespie { "dispose", one (0x0640), one (0xffc0), {IMM5, LIST12, R2DISPOSE},0, PROCESSOR_NOT_V850 },
637f7cc78ecSespie { "dispose", two (0x0640, 0x0000), two (0xffc0, 0x001f), {IMM5, LIST12}, 0, PROCESSOR_NOT_V850 },
638f7cc78ecSespie
639f7cc78ecSespie { "ld.b", two (0x0700, 0x0000), two (0x07e0, 0x0000), {D16, R1, R2}, 1, PROCESSOR_ALL },
640f7cc78ecSespie { "ld.h", two (0x0720, 0x0000), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL },
641f7cc78ecSespie { "ld.w", two (0x0720, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL },
642f7cc78ecSespie { "ld.bu", two (0x0780, 0x0001), two (0x07c0, 0x0001), {D16_16, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },
643f7cc78ecSespie { "ld.hu", two (0x07e0, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },
644f7cc78ecSespie { "st.b", two (0x0740, 0x0000), two (0x07e0, 0x0000), {R2, D16, R1}, 2, PROCESSOR_ALL },
645f7cc78ecSespie { "st.h", two (0x0760, 0x0000), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL },
646f7cc78ecSespie { "st.w", two (0x0760, 0x0001), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL },
647f7cc78ecSespie
648*cf2f2c56Smiod /* Byte swap/extend instructions. */
649f7cc78ecSespie { "zxb", one (0x0080), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
650f7cc78ecSespie { "zxh", one (0x00c0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
651f7cc78ecSespie { "sxb", one (0x00a0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
652f7cc78ecSespie { "sxh", one (0x00e0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
653f7cc78ecSespie { "bsh", two (0x07e0, 0x0342), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 },
654f7cc78ecSespie { "bsw", two (0x07e0, 0x0340), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 },
655f7cc78ecSespie { "hsw", two (0x07e0, 0x0344), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 },
656f7cc78ecSespie
657*cf2f2c56Smiod /* Jump table instructions. */
658f7cc78ecSespie { "switch", one (0x0040), one (0xffe0), {R1}, 1, PROCESSOR_NOT_V850 },
659f7cc78ecSespie { "callt", one (0x0200), one (0xffc0), {I6}, 0, PROCESSOR_NOT_V850 },
660f7cc78ecSespie { "ctret", two (0x07e0, 0x0144), two (0xffff, 0xffff), {0}, 0, PROCESSOR_NOT_V850 },
661f7cc78ecSespie
662*cf2f2c56Smiod /* Arithmetic operation instructions. */
663f7cc78ecSespie { "setf", two (0x07e0, 0x0000), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_ALL },
664f7cc78ecSespie { "cmov", two (0x07e0, 0x0320), two (0x07e0, 0x07e1), {MOVCC, R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
665f7cc78ecSespie { "cmov", two (0x07e0, 0x0300), two (0x07e0, 0x07e1), {MOVCC, I5, R2, R3}, 0, PROCESSOR_NOT_V850 },
666f7cc78ecSespie
667f7cc78ecSespie { "mul", two (0x07e0, 0x0220), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
668f7cc78ecSespie { "mul", two (0x07e0, 0x0240), two (0x07e0, 0x07c3), {I9, R2, R3}, 0, PROCESSOR_NOT_V850 },
669f7cc78ecSespie { "mulu", two (0x07e0, 0x0222), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
670f7cc78ecSespie { "mulu", two (0x07e0, 0x0242), two (0x07e0, 0x07c3), {U9, R2, R3}, 0, PROCESSOR_NOT_V850 },
671f7cc78ecSespie
672f7cc78ecSespie { "div", two (0x07e0, 0x02c0), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
673f7cc78ecSespie { "divu", two (0x07e0, 0x02c2), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
674f7cc78ecSespie { "divhu", two (0x07e0, 0x0282), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
675f7cc78ecSespie { "divh", two (0x07e0, 0x0280), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
676f7cc78ecSespie { "divh", OP (0x02), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
677f7cc78ecSespie
678f7cc78ecSespie { "nop", one (0x00), one (0xffff), {0}, 0, PROCESSOR_ALL },
679f7cc78ecSespie { "mov", OP (0x10), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL },
680f7cc78ecSespie { "mov", one (0x0620), one (0xffe0), {IMM32, R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
681f7cc78ecSespie { "mov", OP (0x00), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
682f7cc78ecSespie { "movea", OP (0x31), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
683f7cc78ecSespie { "movhi", OP (0x32), OP_MASK, {I16U, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
684f7cc78ecSespie { "add", OP (0x0e), OP_MASK, IF1, 0, PROCESSOR_ALL },
685f7cc78ecSespie { "add", OP (0x12), OP_MASK, IF2, 0, PROCESSOR_ALL },
686f7cc78ecSespie { "addi", OP (0x30), OP_MASK, IF6, 0, PROCESSOR_ALL },
687f7cc78ecSespie { "sub", OP (0x0d), OP_MASK, IF1, 0, PROCESSOR_ALL },
688f7cc78ecSespie { "subr", OP (0x0c), OP_MASK, IF1, 0, PROCESSOR_ALL },
689f7cc78ecSespie { "mulh", OP (0x17), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL },
690f7cc78ecSespie { "mulh", OP (0x07), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
691f7cc78ecSespie { "mulhi", OP (0x37), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
692f7cc78ecSespie { "cmp", OP (0x0f), OP_MASK, IF1, 0, PROCESSOR_ALL },
693f7cc78ecSespie { "cmp", OP (0x13), OP_MASK, IF2, 0, PROCESSOR_ALL },
694f7cc78ecSespie
695*cf2f2c56Smiod /* Saturated operation instructions. */
696f7cc78ecSespie { "satadd", OP (0x11), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL },
697f7cc78ecSespie { "satadd", OP (0x06), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
698f7cc78ecSespie { "satsub", OP (0x05), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
699f7cc78ecSespie { "satsubi", OP (0x33), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
700f7cc78ecSespie { "satsubr", OP (0x04), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
701f7cc78ecSespie
702*cf2f2c56Smiod /* Logical operation instructions. */
703f7cc78ecSespie { "tst", OP (0x0b), OP_MASK, IF1, 0, PROCESSOR_ALL },
704f7cc78ecSespie { "or", OP (0x08), OP_MASK, IF1, 0, PROCESSOR_ALL },
705f7cc78ecSespie { "ori", OP (0x34), OP_MASK, IF6U, 0, PROCESSOR_ALL },
706f7cc78ecSespie { "and", OP (0x0a), OP_MASK, IF1, 0, PROCESSOR_ALL },
707f7cc78ecSespie { "andi", OP (0x36), OP_MASK, IF6U, 0, PROCESSOR_ALL },
708f7cc78ecSespie { "xor", OP (0x09), OP_MASK, IF1, 0, PROCESSOR_ALL },
709f7cc78ecSespie { "xori", OP (0x35), OP_MASK, IF6U, 0, PROCESSOR_ALL },
710f7cc78ecSespie { "not", OP (0x01), OP_MASK, IF1, 0, PROCESSOR_ALL },
711f7cc78ecSespie { "sar", OP (0x15), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL },
712f7cc78ecSespie { "sar", two (0x07e0, 0x00a0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL },
713f7cc78ecSespie { "shl", OP (0x16), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL },
714f7cc78ecSespie { "shl", two (0x07e0, 0x00c0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL },
715f7cc78ecSespie { "shr", OP (0x14), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL },
716f7cc78ecSespie { "shr", two (0x07e0, 0x0080), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL },
717f7cc78ecSespie { "sasf", two (0x07e0, 0x0200), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_NOT_V850 },
718f7cc78ecSespie
719*cf2f2c56Smiod /* Branch instructions. */
720*cf2f2c56Smiod /* Signed integer. */
721f7cc78ecSespie { "bgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL },
722f7cc78ecSespie { "bge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL },
723f7cc78ecSespie { "blt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL },
724f7cc78ecSespie { "ble", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL },
725*cf2f2c56Smiod /* Unsigned integer. */
726f7cc78ecSespie { "bh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL },
727f7cc78ecSespie { "bnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL },
728f7cc78ecSespie { "bl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
729f7cc78ecSespie { "bnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
730*cf2f2c56Smiod /* Common. */
731f7cc78ecSespie { "be", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
732f7cc78ecSespie { "bne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
733*cf2f2c56Smiod /* Others. */
734f7cc78ecSespie { "bv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL },
735f7cc78ecSespie { "bnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL },
736f7cc78ecSespie { "bn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL },
737f7cc78ecSespie { "bp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL },
738f7cc78ecSespie { "bc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
739f7cc78ecSespie { "bnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
740f7cc78ecSespie { "bz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
741f7cc78ecSespie { "bnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
742f7cc78ecSespie { "br", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL },
743f7cc78ecSespie { "bsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL },
744f7cc78ecSespie
745f7cc78ecSespie /* Branch macros.
746f7cc78ecSespie
747f7cc78ecSespie We use the short form in the opcode/mask fields. The assembler
748f7cc78ecSespie will twiddle bits as necessary if the long form is needed. */
749f7cc78ecSespie
750*cf2f2c56Smiod /* Signed integer. */
751f7cc78ecSespie { "jgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL },
752f7cc78ecSespie { "jge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL },
753f7cc78ecSespie { "jlt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL },
754f7cc78ecSespie { "jle", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL },
755*cf2f2c56Smiod /* Unsigned integer. */
756f7cc78ecSespie { "jh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL },
757f7cc78ecSespie { "jnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL },
758f7cc78ecSespie { "jl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
759f7cc78ecSespie { "jnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
760*cf2f2c56Smiod /* Common. */
761f7cc78ecSespie { "je", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
762f7cc78ecSespie { "jne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
763*cf2f2c56Smiod /* Others. */
764f7cc78ecSespie { "jv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL },
765f7cc78ecSespie { "jnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL },
766f7cc78ecSespie { "jn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL },
767f7cc78ecSespie { "jp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL },
768f7cc78ecSespie { "jc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
769f7cc78ecSespie { "jnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
770f7cc78ecSespie { "jz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
771f7cc78ecSespie { "jnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
772f7cc78ecSespie { "jsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL },
773f7cc78ecSespie { "jbr", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL },
774f7cc78ecSespie
775f7cc78ecSespie { "jr", one (0x0780), two (0xffc0, 0x0001), {D22}, 0, PROCESSOR_ALL },
776f7cc78ecSespie { "jarl", one (0x0780), two (0x07c0, 0x0001), {D22, R2}, 0, PROCESSOR_ALL},
777f7cc78ecSespie
778*cf2f2c56Smiod /* Bit manipulation instructions. */
779f7cc78ecSespie { "set1", two (0x07c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
780f7cc78ecSespie { "set1", two (0x07e0, 0x00e0), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
781f7cc78ecSespie { "not1", two (0x47c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
782f7cc78ecSespie { "not1", two (0x07e0, 0x00e2), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
783f7cc78ecSespie { "clr1", two (0x87c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
784f7cc78ecSespie { "clr1", two (0x07e0, 0x00e4), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
785f7cc78ecSespie { "tst1", two (0xc7c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
786f7cc78ecSespie { "tst1", two (0x07e0, 0x00e6), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
787f7cc78ecSespie
788*cf2f2c56Smiod /* Special instructions. */
789f7cc78ecSespie { "di", two (0x07e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
790f7cc78ecSespie { "ei", two (0x87e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
791f7cc78ecSespie { "halt", two (0x07e0, 0x0120), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
792f7cc78ecSespie { "reti", two (0x07e0, 0x0140), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
793f7cc78ecSespie { "trap", two (0x07e0, 0x0100), two (0xffe0, 0xffff), {I5U}, 0, PROCESSOR_ALL },
794f7cc78ecSespie { "ldsr", two (0x07e0, 0x0020), two (0x07e0, 0xffff), {R1, SR2}, 0, PROCESSOR_ALL },
795f7cc78ecSespie { "stsr", two (0x07e0, 0x0040), two (0x07e0, 0xffff), {SR1, R2}, 0, PROCESSOR_ALL },
796*cf2f2c56Smiod { "dbret", two (0x07e0, 0x0146), two (0xffff, 0xffff), {UNUSED}, 0, PROCESSOR_V850E1 },
797f7cc78ecSespie { 0, 0, 0, {0}, 0, 0 },
798f7cc78ecSespie
799f7cc78ecSespie } ;
800f7cc78ecSespie
801f7cc78ecSespie const int v850_num_opcodes =
802f7cc78ecSespie sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
803