source: trunk/src/binutils/opcodes/v850-opc.c@ 524

Last change on this file since 524 was 10, checked in by bird, 22 years ago

Initial revision

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