]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/v850-opc.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[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 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