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