More portability patches. Include sysdep.h everywhere.
[deliverable/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 "sysdep.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
This page took 0.05049 seconds and 5 git commands to generate.