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