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