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