* cgen-asm.in (insert_normal): Use CGEN_BOOL_ATTR.
[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 static unsigned long
281 insert_spe (insn, value, errmsg)
282      unsigned long insn;
283      unsigned long value;
284      const char ** errmsg;
285 {
286   if (value != 3)
287     *errmsg = "invalid register for stack adjustment";
288
289   return insn & (~ 0x180000);
290 }
291
292 static unsigned long
293 extract_spe (insn, invalid)
294      unsigned long insn;
295      int *         invalid;
296 {
297   return 3;
298 }
299
300 /* end-sanitize-v850e */
301 /* start-sanitize-v850eq */
302
303 static unsigned long
304 insert_i5div (insn, value, errmsg)
305      unsigned long insn;
306      unsigned long value;
307      const char ** errmsg;
308 {
309   if (value > 0x1ff)
310     *errmsg = "value out of range";
311
312   if (value & 1)
313     *errmsg = "value must be even";
314
315   value = 32 - value;
316   
317   return insn | ((value & 0x1e) << 17);
318 }
319
320 static unsigned long
321 extract_i5div (insn, invalid)
322      unsigned long insn;
323      int *         invalid;
324 {
325   unsigned long ret = insn & 0x3c0000;
326
327   ret >>= 17;
328
329   ret = 32 - ret;
330   
331   return ret;
332 }
333
334 /* end-sanitize-v850eq */
335
336 \f
337 /* Warning: code in gas/config/tc-v850.c examines the contents of this array.
338    If you change any of the values here, be sure to look for side effects in
339    that code. */
340 const struct v850_operand v850_operands[] =
341 {
342 #define UNUSED  0
343   { 0, 0, NULL, NULL, 0 }, 
344
345 /* The R1 field in a format 1, 6, 7, or 9 insn. */
346 #define R1      (UNUSED + 1)
347   { 5, 0, NULL, NULL, V850_OPERAND_REG }, 
348
349 /* As above, but register 0 is not allowed.  */
350 #define R1_NOTR0 (R1 + 1)
351   { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, 
352
353 /* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */
354 #define R2      (R1_NOTR0 + 1)
355   { 5, 11, NULL, NULL, V850_OPERAND_REG },
356
357 /* As above, but register 0 is not allowed.  */
358 #define R2_NOTR0 (R2 + 1)
359   { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
360
361 /* The imm5 field in a format 2 insn. */
362 #define I5      (R2_NOTR0 + 1)
363   { 5, 0, NULL, NULL, V850_OPERAND_SIGNED }, 
364
365 /* The unsigned imm5 field in a format 2 insn. */
366 #define I5U     (I5 + 1)
367   { 5, 0, NULL, NULL, 0 },
368
369 /* The imm16 field in a format 6 insn. */
370 #define I16     (I5U + 1)
371   { 16, 16, NULL, NULL, V850_OPERAND_SIGNED }, 
372
373 /* The signed disp7 field in a format 4 insn. */
374 #define D7      (I16 + 1)
375   { 7, 0, NULL, NULL, 0},
376
377 /* The disp16 field in a format 6 insn. */
378 #define D16_15  (D7 + 1)
379   { 15, 17, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED }, 
380
381 /* The 3 bit immediate field in format 8 insn.  */
382 #define B3      (D16_15 + 1)
383   { 3, 11, NULL, NULL, 0 },
384
385 /* The 4 bit condition code in a setf instruction */
386 #define CCCC    (B3 + 1)
387   { 4, 0, NULL, NULL, V850_OPERAND_CC },
388
389 /* The unsigned DISP8 field in a format 4 insn. */
390 #define D8_7    (CCCC + 1)
391   { 7, 0, insert_d8_7, extract_d8_7, 0 },
392
393 /* The unsigned DISP8 field in a format 4 insn. */
394 #define D8_6    (D8_7 + 1)
395   { 6, 1, insert_d8_6, extract_d8_6, 0 },
396
397 /* System register operands.  */
398 #define SR1     (D8_6 + 1)
399   { 5, 0, NULL, NULL, V850_OPERAND_SRG },
400
401 /* EP Register.  */
402 #define EP      (SR1 + 1)
403   { 0, 0, NULL, NULL, V850_OPERAND_EP },
404
405 /* The imm16 field (unsigned) in a format 6 insn. */
406 #define I16U    (EP + 1)
407   { 16, 16, NULL, NULL, 0}, 
408
409 /* The R2 field as a system register.  */
410 #define SR2     (I16U + 1)
411   { 5, 11, NULL, NULL, V850_OPERAND_SRG },
412
413 /* The disp16 field in a format 8 insn. */
414 #define D16     (SR2 + 1)
415   { 16, 16, NULL, NULL, V850_OPERAND_SIGNED }, 
416
417 /* The DISP22 field in a format 4 insn, relaxable. */
418 #define D9_RELAX        (D16 + 1)
419   { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP },
420
421 /* The DISP22 field in a format 4 insn.
422
423    This _must_ follow D9_RELAX; the assembler assumes that the longer
424    version immediately follows the shorter version for relaxing.  */
425 #define D22     (D9_RELAX + 1)
426   { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP },
427
428 /* start-sanitize-v850e */
429   
430 /* The signed disp4 field in a format 4 insn. */
431 #define D4      (D22 + 1)
432   { 4, 0, NULL, NULL, 0},
433
434 /* The unsigned disp5 field in a format 4 insn. */
435 #define D5_4    (D4 + 1)
436   { 4, 0, insert_d5_4, extract_d5_4, 0 },
437
438 /* The disp16 field in an format 7 unsigned byte load insn. */
439 #define D16_16  (D5_4 + 1)
440   { -1, 0xfffe0020, insert_d16_16, extract_d16_16, 0 }, 
441
442 /* Third register in conditional moves. */
443 #define R3      (D16_16 + 1)
444   { 5, 27, NULL, NULL, V850_OPERAND_REG },
445
446 /* Condition code in conditional moves.  */
447 #define MOVCC   (R3 + 1)
448   { 4, 17, NULL, NULL, V850_OPERAND_CC },
449
450 /* The imm9 field in a multiply word. */
451 #define I9      (MOVCC + 1)
452   { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED }, 
453
454 /* The unsigned imm9 field in a multiply word. */
455 #define U9      (I9 + 1)
456   { 9, 0, insert_u9, extract_u9, 0 }, 
457
458 /* A list of registers in a prepare/dispose instruction.  */
459 #define LIST12  (U9 + 1)
460   { -1, 0xffe00001, NULL, NULL, V850E_PUSH_POP }, 
461
462 /* The IMM6 field in a call instruction. */
463 #define I6      (LIST12 + 1)
464   { 6, 0, NULL, NULL, 0 }, 
465
466 /* The 16 bit immediate following a 32 bit instruction.  */
467 #define IMM16   (I6 + 1)
468   { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850E_IMMEDIATE16 }, 
469
470 /* The 32 bit immediate following a 32 bit instruction.  */
471 #define IMM32   (IMM16 + 1)
472   { 0, 0, NULL, NULL, V850E_IMMEDIATE32 }, 
473
474 /* The imm5 field in a push/pop instruction. */
475 #define IMM5    (IMM32 + 1)
476   { 5, 1, NULL, NULL, 0 }, 
477
478 /* Reg2 in dispose instruction. */
479 #define R2DISPOSE       (IMM5 + 1)
480   { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
481
482 /* Stack pointer in prepare instruction. */
483 #define SP      (R2DISPOSE + 1)
484   { 2, 19, insert_spe, extract_spe, V850_OPERAND_REG },
485
486 /* end-sanitize-v850e */
487 /* start-sanitize-v850eq */
488
489 /* The IMM5 field in a divide N step instruction. */
490 #define I5DIV   (SP + 1)
491   { 9, 0, insert_i5div, extract_i5div, V850_OPERAND_SIGNED }, 
492
493   /* The list of registers in a PUSHMH/POPMH instruction.  */
494 #define LIST18_H (I5DIV + 1)
495   { -1, 0xfff8000f, NULL, NULL, V850E_PUSH_POP }, 
496
497   /* The list of registers in a PUSHML/POPML instruction.  */
498 #define LIST18_L (LIST18_H + 1)
499   { -1, 0xfff8001f, NULL, NULL, V850E_PUSH_POP }, /* The setting of the 4th bit is a flag to disassmble() in v850-dis.c */
500
501 /* end-sanitize-v850eq */
502 } ; 
503
504 \f
505 /* reg-reg instruction format (Format I) */
506 #define IF1     {R1, R2}
507
508 /* imm-reg instruction format (Format II) */
509 #define IF2     {I5, R2}
510
511 /* conditional branch instruction format (Format III) */
512 #define IF3     {D9_RELAX}
513
514 /* 3 operand instruction (Format VI) */
515 #define IF6     {I16, R1, R2}
516
517 /* 3 operand instruction (Format VI) */
518 #define IF6U    {I16U, R1, R2}
519
520
521 \f
522 /* The opcode table.
523
524    The format of the opcode table is:
525
526    NAME         OPCODE                  MASK                   { OPERANDS }        MEMOP    PROCESSOR
527
528    NAME is the name of the instruction.
529    OPCODE is the instruction opcode.
530    MASK is the opcode mask; this is used to tell the disassembler
531      which bits in the actual opcode must match OPCODE.
532    OPERANDS is the list of operands.
533    MEMOP specifies which operand (if any) is a memory operand.
534    PROCESSOR specifies which CPUs support the opcode.
535    
536    The disassembler reads the table in order and prints the first
537    instruction which matches, so this table is sorted to put more
538    specific instructions before more general instructions.  It is also
539    sorted by major opcode.
540
541    The table is also sorted by name.  This is used by the assembler.
542    When parsing an instruction the assembler finds the first occurance
543    of the name of the instruciton in this table and then attempts to
544    match the instruction's arguments with description of the operands
545    associated with the entry it has just found in this table.  If the
546    match fails the assembler looks at the next entry in this table.
547    If that entry has the same name as the previous entry, then it
548    tries to match the instruction against that entry and so on.  This
549    is how the assembler copes with multiple, different formats of the
550    same instruction.  */
551
552 const struct v850_opcode v850_opcodes[] =
553 {
554 { "breakpoint", 0xffff,                 0xffff,                 {UNUSED},               0, PROCESSOR_ALL },
555
556 { "jmp",        one (0x0060),           one (0xffe0),           {R1},                   1, PROCESSOR_ALL },
557   
558 /* load/store instructions */
559 /* start-sanitize-v850eq */
560 { "sld.bu",     one (0x0300),           one (0x0780),           {D7,   EP,   R2_NOTR0}, 1, PROCESSOR_V850EQ },
561 /* end-sanitize-v850eq */
562 /* start-sanitize-v850e */
563 { "sld.bu",     one (0x0060),           one (0x07f0),           {D4,   EP,   R2_NOTR0}, 1, PROCESSOR_V850E },
564 /* end-sanitize-v850e */
565   
566 /* start-sanitize-v850eq */
567 { "sld.hu",     one (0x0400),           one (0x0780),           {D8_7, EP,   R2_NOTR0}, 1, PROCESSOR_V850EQ },
568 /* end-sanitize-v850eq */
569 /* start-sanitize-v850e */
570 { "sld.hu",     one (0x0070),           one (0x07f0),           {D5_4, EP,   R2_NOTR0}, 1, PROCESSOR_V850E },
571 /* end-sanitize-v850e */
572   
573 /* start-sanitize-v850eq */
574 { "sld.b",      one (0x0060),           one (0x07f0),           {D4,   EP,   R2},       1, PROCESSOR_V850EQ },
575 /* end-sanitize-v850eq */
576 /* start-sanitize-v850e */
577 { "sld.b",      one (0x0300),           one (0x0780),           {D7,   EP,   R2},       1, PROCESSOR_V850E },
578 /* end-sanitize-v850e */
579 { "sld.b",      one (0x0300),           one (0x0780),           {D7,   EP,   R2},       1, PROCESSOR_V850 },
580
581 /* start-sanitize-v850eq */
582 { "sld.h",      one (0x0070),           one (0x07f0),           {D5_4, EP,   R2},       1, PROCESSOR_V850EQ },
583 /* end-sanitize-v850eq */
584 /* start-sanitize-v850e */
585 { "sld.h",      one (0x0400),           one (0x0780),           {D8_7, EP,   R2},       1, PROCESSOR_V850E },
586 /* end-sanitize-v850e */
587   
588 { "sld.h",      one (0x0400),           one (0x0780),           {D8_7, EP,   R2},       1, PROCESSOR_V850 },
589 { "sld.w",      one (0x0500),           one (0x0781),           {D8_6, EP,   R2},       1, PROCESSOR_ALL },
590 { "sst.b",      one (0x0380),           one (0x0780),           {R2,   D7,   EP},       2, PROCESSOR_ALL },
591 { "sst.h",      one (0x0480),           one (0x0780),           {R2,   D8_7, EP},       2, PROCESSOR_ALL },
592 { "sst.w",      one (0x0501),           one (0x0781),           {R2,   D8_6, EP},       2, PROCESSOR_ALL },
593
594 /* start-sanitize-v850eq */
595 { "pushml",     two (0x07e0, 0x0001),   two (0xfff0, 0x0007),   {LIST18_L},             0, PROCESSOR_V850EQ },
596 { "pushmh",     two (0x07e0, 0x0003),   two (0xfff0, 0x0007),   {LIST18_H},             0, PROCESSOR_V850EQ },
597 { "popml",      two (0x07f0, 0x0001),   two (0xfff0, 0x0007),   {LIST18_L},             0, PROCESSOR_V850EQ },
598 { "popmh",      two (0x07f0, 0x0003),   two (0xfff0, 0x0007),   {LIST18_H},             0, PROCESSOR_V850EQ },
599 /* end-sanitize-v850eq */
600   
601 /* start-sanitize-v850e */  
602 { "prepare",    two (0x0780, 0x0003),   two (0xffc0, 0x001f),   {LIST12, IMM5, SP},     0, PROCESSOR_NOT_V850 },
603 { "prepare",    two (0x0780, 0x000b),   two (0xffc0, 0x001f),   {LIST12, IMM5, IMM16},  0, PROCESSOR_NOT_V850 },
604 { "prepare",    two (0x0780, 0x0013),   two (0xffc0, 0x001f),   {LIST12, IMM5, IMM16},  0, PROCESSOR_NOT_V850 },
605 { "prepare",    two (0x0780, 0x001b),   two (0xffc0, 0x001f),   {LIST12, IMM5, IMM32},  0, PROCESSOR_NOT_V850 },
606 { "prepare",    two (0x0780, 0x0001),   two (0xffc0, 0x001f),   {LIST12, IMM5},         0, PROCESSOR_NOT_V850 },
607 { "dispose",    one (0x0640),           one (0xffc0),           {IMM5, LIST12, R2DISPOSE},0, PROCESSOR_NOT_V850 },
608 { "dispose",    two (0x0640, 0x0000),   two (0xffc0, 0x001f),   {IMM5, LIST12},         0, PROCESSOR_NOT_V850 },
609 /* end-sanitize-v850e */
610
611 { "ld.b",       two (0x0700, 0x0000),   two (0x07e0, 0x0000),   {D16, R1, R2},          1, PROCESSOR_ALL },
612 { "ld.h",       two (0x0720, 0x0000),   two (0x07e0, 0x0001),   {D16_15, R1, R2},       1, PROCESSOR_ALL },
613 { "ld.w",       two (0x0720, 0x0001),   two (0x07e0, 0x0001),   {D16_15, R1, R2},       1, PROCESSOR_ALL },
614 /* start-sanitize-v850e */
615 { "ld.bu",      two (0x0780, 0x0001),   two (0x07c0, 0x0001),   {D16_16, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },
616 { "ld.hu",      two (0x07e0, 0x0001),   two (0x07e0, 0x0001),   {D16_15, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },  
617 /* end-sanitize-v850e */
618 { "st.b",       two (0x0740, 0x0000),   two (0x07e0, 0x0000),   {R2, D16, R1},          2, PROCESSOR_ALL },
619 { "st.h",       two (0x0760, 0x0000),   two (0x07e0, 0x0001),   {R2, D16_15, R1},       2, PROCESSOR_ALL },
620 { "st.w",       two (0x0760, 0x0001),   two (0x07e0, 0x0001),   {R2, D16_15, R1},       2, PROCESSOR_ALL },
621
622 /* start-sanitize-v850e */
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 /* end-sanitize-v850e */
637
638 /* arithmetic operation instructions */
639 { "setf",       two (0x07e0, 0x0000),   two (0x07f0, 0xffff),   {CCCC, R2},             0, PROCESSOR_ALL },
640 /* start-sanitize-v850e */
641 { "cmov",       two (0x07e0, 0x0320),   two (0x07e0, 0x07e1),   {MOVCC, R1, R2, R3},    0, PROCESSOR_NOT_V850 },
642 { "cmov",       two (0x07e0, 0x0300),   two (0x07e0, 0x07e1),   {MOVCC, I5, R2, R3},    0, PROCESSOR_NOT_V850 },
643
644 { "mul",        two (0x07e0, 0x0220),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
645 { "mul",        two (0x07e0, 0x0240),   two (0x07e0, 0x07c3),   {I9, R2, R3},           0, PROCESSOR_NOT_V850 },
646 { "mulu",       two (0x07e0, 0x0222),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
647 { "mulu",       two (0x07e0, 0x0242),   two (0x07e0, 0x07c3),   {U9, R2, R3},           0, PROCESSOR_NOT_V850 },
648
649 { "div",        two (0x07e0, 0x02c0),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
650 { "divu",       two (0x07e0, 0x02c2),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
651 { "divhu",      two (0x07e0, 0x0282),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
652 { "divh",       two (0x07e0, 0x0280),   two (0x07e0, 0x07ff),   {R1, R2, R3},           0, PROCESSOR_NOT_V850 },
653 /* end-sanitize-v850e */
654 { "divh",       OP  (0x02),             OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
655   
656 /* start-sanitize-v850eq */
657 { "divhn",      two (0x07e0, 0x0280),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
658 { "divhun",     two (0x07e0, 0x0282),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
659 { "divn",       two (0x07e0, 0x02c0),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
660 { "divun",      two (0x07e0, 0x02c2),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
661 { "sdivhn",     two (0x07e0, 0x0180),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
662 { "sdivhun",    two (0x07e0, 0x0182),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
663 { "sdivn",      two (0x07e0, 0x01c0),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
664 { "sdivun",     two (0x07e0, 0x01c2),   two (0x07e0, 0x07c3),   {I5DIV, R1, R2, R3},    0, PROCESSOR_V850EQ },
665 /* end-sanitize-v850eq */
666   
667 { "nop",        one (0x00),             one (0xffff),           {0},                    0, PROCESSOR_ALL },
668 { "mov",        OP  (0x10),             OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
669 /* start-sanitize-v850e */
670 { "mov",        one (0x0620),           one (0xffe0),           {IMM32, R1_NOTR0},      0, PROCESSOR_NOT_V850 },
671 /* end-sanitize-v850e */
672 { "mov",        OP  (0x00),             OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
673 { "movea",      OP  (0x31),             OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
674 { "movhi",      OP  (0x32),             OP_MASK,                {I16U, R1, R2_NOTR0},   0, PROCESSOR_ALL },
675 { "add",        OP  (0x0e),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
676 { "add",        OP  (0x12),             OP_MASK,                IF2,                    0, PROCESSOR_ALL },
677 { "addi",       OP  (0x30),             OP_MASK,                IF6,                    0, PROCESSOR_ALL },
678 { "sub",        OP  (0x0d),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
679 { "subr",       OP  (0x0c),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
680 { "mulh",       OP  (0x17),             OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
681 { "mulh",       OP  (0x07),             OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
682 { "mulhi",      OP  (0x37),             OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
683 { "cmp",        OP  (0x0f),             OP_MASK,                IF1,                    0, PROCESSOR_ALL },
684 { "cmp",        OP  (0x13),             OP_MASK,                IF2,                    0, PROCESSOR_ALL },
685   
686 /* saturated operation instructions */
687 { "satadd",     OP (0x11),              OP_MASK,                {I5, R2_NOTR0},         0, PROCESSOR_ALL },
688 { "satadd",     OP (0x06),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
689 { "satsub",     OP (0x05),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
690 { "satsubi",    OP (0x33),              OP_MASK,                {I16, R1, R2_NOTR0},    0, PROCESSOR_ALL },
691 { "satsubr",    OP (0x04),              OP_MASK,                {R1, R2_NOTR0},         0, PROCESSOR_ALL },
692
693 /* logical operation instructions */
694 { "tst",        OP (0x0b),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
695 { "or",         OP (0x08),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
696 { "ori",        OP (0x34),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
697 { "and",        OP (0x0a),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
698 { "andi",       OP (0x36),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
699 { "xor",        OP (0x09),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
700 { "xori",       OP (0x35),              OP_MASK,                IF6U,                   0, PROCESSOR_ALL },
701 { "not",        OP (0x01),              OP_MASK,                IF1,                    0, PROCESSOR_ALL },
702 { "sar",        OP (0x15),              OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
703 { "sar",        two (0x07e0, 0x00a0),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
704 { "shl",        OP  (0x16),             OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
705 { "shl",        two (0x07e0, 0x00c0),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
706 { "shr",        OP  (0x14),             OP_MASK,                {I5U, R2},              0, PROCESSOR_ALL },
707 { "shr",        two (0x07e0, 0x0080),   two (0x07e0, 0xffff),   {R1,  R2},              0, PROCESSOR_ALL },
708 /* start-sanitize-v850e */
709 { "sasf",       two (0x07e0, 0x0200),   two (0x07f0, 0xffff),   {CCCC, R2},             0, PROCESSOR_NOT_V850 },
710 /* end-sanitize-v850e */
711
712 /* branch instructions */
713         /* signed integer */
714 { "bgt",        BOP (0xf),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
715 { "bge",        BOP (0xe),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
716 { "blt",        BOP (0x6),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
717 { "ble",        BOP (0x7),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
718         /* unsigned integer */
719 { "bh",         BOP (0xb),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
720 { "bnh",        BOP (0x3),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
721 { "bl",         BOP (0x1),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
722 { "bnl",        BOP (0x9),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
723         /* common */
724 { "be",         BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
725 { "bne",        BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
726         /* others */
727 { "bv",         BOP (0x0),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
728 { "bnv",        BOP (0x8),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
729 { "bn",         BOP (0x4),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
730 { "bp",         BOP (0xc),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
731 { "bc",         BOP (0x1),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
732 { "bnc",        BOP (0x9),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
733 { "bz",         BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
734 { "bnz",        BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
735 { "br",         BOP (0x5),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
736 { "bsa",        BOP (0xd),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
737
738 /* Branch macros.
739
740    We use the short form in the opcode/mask fields.  The assembler
741    will twiddle bits as necessary if the long form is needed.  */
742
743         /* signed integer */
744 { "jgt",        BOP (0xf),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
745 { "jge",        BOP (0xe),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
746 { "jlt",        BOP (0x6),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
747 { "jle",        BOP (0x7),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
748         /* unsigned integer */
749 { "jh",         BOP (0xb),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
750 { "jnh",        BOP (0x3),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
751 { "jl",         BOP (0x1),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
752 { "jnl",        BOP (0x9),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
753         /* common */
754 { "je",         BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
755 { "jne",        BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
756         /* others */
757 { "jv",         BOP (0x0),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
758 { "jnv",        BOP (0x8),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
759 { "jn",         BOP (0x4),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
760 { "jp",         BOP (0xc),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
761 { "jc",         BOP (0x1),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
762 { "jnc",        BOP (0x9),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
763 { "jz",         BOP (0x2),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
764 { "jnz",        BOP (0xa),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
765 { "jsa",        BOP (0xd),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
766 { "jbr",        BOP (0x5),              BOP_MASK,               IF3,                    0, PROCESSOR_ALL },
767   
768 { "jr",         one (0x0780),           two (0xffc0, 0x0001),   {D22},                  0, PROCESSOR_ALL },
769 { "jarl",       one (0x0780),           two (0x07c0, 0x0001),   {D22, R2},              0, PROCESSOR_ALL}, 
770
771 /* bit manipulation instructions */
772 { "set1",       two (0x07c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
773 /* start-sanitize-v850e */
774 { "set1",       two (0x07e0, 0x00e0),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
775 /* end-sanitize-v850e */
776 { "not1",       two (0x47c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
777 /* start-sanitize-v850e */
778 { "not1",       two (0x07e0, 0x00e2),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
779 /* end-sanitize-v850e */
780 { "clr1",       two (0x87c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
781 /* start-sanitize-v850e */
782 { "clr1",       two (0x07e0, 0x00e4),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
783 /* end-sanitize-v850e */
784 { "tst1",       two (0xc7c0, 0x0000),   two (0xc7e0, 0x0000),   {B3, D16, R1},          2, PROCESSOR_ALL },
785 /* start-sanitize-v850e */
786 { "tst1",       two (0x07e0, 0x00e6),   two (0x07e0, 0xffff),   {R2, R1},               2, PROCESSOR_NOT_V850 },
787 /* end-sanitize-v850e */
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 { 0, 0, 0, {0}, 0, 0 },
798
799 } ;
800
801 const int v850_num_opcodes =
802   sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
803