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