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