* v850-dis.c (disassemble): Handle insertion of ',', '[' and
[platform/upstream/binutils.git] / opcodes / v850-opc.c
1 #include "ansidecl.h"
2 #include "opcode/v850.h"
3
4 /* Local insertion and extraction functions.  */
5 static unsigned long insert_d9 PARAMS ((unsigned long, long, const char **));
6 static long extract_d9 PARAMS ((unsigned long, int *));
7 static unsigned long insert_d22 PARAMS ((unsigned long, long, const char **));
8 static long extract_d22 PARAMS ((unsigned long, int *));
9 static unsigned long insert_d16_15 PARAMS ((unsigned long, long,
10                                             const char **));
11 static long extract_d16_15 PARAMS ((unsigned long, int *));
12 static unsigned long insert_d8_7 PARAMS ((unsigned long, long, const char **));
13 static long extract_d8_7 PARAMS ((unsigned long, int *));
14 static unsigned long insert_d8_6 PARAMS ((unsigned long, long, const char **));
15 static long extract_d8_6 PARAMS ((unsigned long, int *));
16
17 /* regular opcode */
18 #define OP(x)           ((x & 0x3f) << 5)
19 #define OP_MASK         OP(0x3f)
20
21 /* conditional branch opcode */
22 #define BOP(x)          ((0x0b << 7) | (x & 0x0f))
23 #define BOP_MASK        ((0x0f << 7) | 0x0f)
24
25 /* one-word opcodes */
26 #define one(x)          ((unsigned int) (x))
27
28 /* two-word opcodes */
29 #define two(x,y)        ((unsigned int) (x) | ((unsigned int) (y) << 16))
30
31
32 \f
33 const struct v850_operand v850_operands[] = {
34 #define UNUSED  0
35   { 0, 0, 0, 0, 0 }, 
36
37 /* The R1 field in a format 1, 6, 7, or 9 insn. */
38 #define R1      (UNUSED+1)
39   { 5, 0, 0, 0, V850_OPERAND_REG }, 
40
41 /* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */
42 #define R2      (R1+1)
43   { 5, 11, 0, 0, V850_OPERAND_REG },
44
45 /* The IMM5 field in a format 2 insn. */
46 #define I5      (R2+1)
47   { 5, 0, 0, 0, V850_OPERAND_SIGNED }, 
48
49 #define I5U     (I5+1)
50   { 5, 0, 0, 0, 0 },
51
52 /* The IMM16 field in a format 6 insn. */
53 #define I16     (I5U+1)
54   { 16, 16, 0, 0, V850_OPERAND_SIGNED }, 
55
56 /* The signed DISP7 field in a format 4 insn. */
57 #define D7      (I16+1)
58   { 7, 0, 0, 0, 0},
59
60 /* The DISP9 field in a format 3 insn. */
61 #define D9      (D7+1)
62   { 9, 0, insert_d9, extract_d9, V850_OPERAND_SIGNED },
63
64 /* The DISP16 field in a format 6 insn. */
65 #define D16_15  (D9+1)
66   { 16, 16, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED }, 
67
68 /* The DISP22 field in a format 4 insn. */
69 #define D22     (D16_15+1)
70   { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED },
71
72 #define B3      (D22+1)
73 /* The 3 bit immediate field in format 8 insn.  */
74   { 3, 11, 0, 0, 0 },
75
76 #define CCCC    (B3+1)
77 /* The 4 bit condition code in a setf instruction */
78   { 4, 0, 0, 0, V850_OPERAND_CC },
79
80 /* The unsigned DISP8_7 field in a format 4 insn. */
81 #define D8_7    (CCCC+1)
82   { 8, 0, insert_d8_7, extract_d8_7, 0 },
83
84 /* The unsigned DISP8_6 field in a format 4 insn. */
85 #define D8_6    (D8_7+1)
86   { 8, 0, insert_d8_6, extract_d8_6, 0 },
87
88 /* System register operands.  */
89 #define SR1     (D8_6+1)
90   { 5, 0, 0, 0, V850_OPERAND_SRG },
91
92 /* EP Register.  */
93 #define EP      (SR1+1)
94   { 0, 0, 0, 0, V850_OPERAND_EP },
95
96 /* The IMM16 field (unsigned0 in a format 6 insn. */
97 #define I16U    (EP+1)
98   { 16, 16, 0, 0, 0}, 
99
100 /* The R2 field as a system register.  */
101 #define SR2     (I16U+1)
102   { 5, 11, 0, 0, V850_OPERAND_SRG },
103
104 /* The DISP16 field in a format 8 insn. */
105 #define D16     (SR2+1)
106   { 16, 16, 0, 0, V850_OPERAND_SIGNED }, 
107
108 } ; 
109
110 \f
111 /* reg-reg instruction format (Format I) */
112 #define IF1     {R1, R2}
113
114 /* imm-reg instruction format (Format II) */
115 #define IF2     {I5, R2}
116
117 /* conditional branch instruction format (Format III) */
118 #define IF3     {D9}
119
120 /* 16-bit load/store instruction (Format IV) */
121 #define IF4A    {D7, EP, R2}
122 #define IF4B    {R2, D7, EP}
123 #define IF4C    {D8_7, EP, R2}
124 #define IF4D    {R2, D8_7, EP}
125 #define IF4E    {D8_6, EP, R2}
126 #define IF4F    {R2, D8_6, EP}
127
128 /* Jump instruction (Format V) */
129 #define IF5     {D22}
130
131 /* 3 operand instruction (Format VI) */
132 #define IF6     {I16, R1, R2}
133
134 /* 3 operand instruction (Format VI) */
135 #define IF6U    {I16U, R1, R2}
136
137 /* 32-bit load/store half/word instruction (Format VII) */
138 #define IF7A    {D16_15, R1, R2}
139 #define IF7B    {R2, D16_15, R1}
140
141 /* 32-bit load/store byte instruction (Format VII) */
142 #define IF7C    {D16, R1, R2}
143 #define IF7D    {R2, D16, R1}
144
145 /* Bit manipulation function.  */
146
147
148 \f
149 /* The opcode table.
150
151    The format of the opcode table is:
152
153    NAME         OPCODE          MASK            { OPERANDS }
154
155    NAME is the name of the instruction.
156    OPCODE is the instruction opcode.
157    MASK is the opcode mask; this is used to tell the disassembler
158      which bits in the actual opcode must match OPCODE.
159    OPERANDS is the list of operands.
160
161    The disassembler reads the table in order and prints the first
162    instruction which matches, so this table is sorted to put more
163    specific instructions before more general instructions.  It is also
164    sorted by major opcode.  */
165
166 const struct v850_opcode v850_opcodes[] = {
167 /* load/store instructions */
168 { "sld.b",      one(0x0300),            one(0x0780),    IF4A, 1 },
169 { "sld.h",      one(0x0400),            one(0x0780),    IF4C, 1 },
170 { "sld.w",      one(0x0500),            one(0x0781),    IF4E, 1 },
171 { "sst.b",      one(0x0380),            one(0x0780),    IF4B, 2 },
172 { "sst.h",      one(0x0480),            one(0x0780),    IF4D, 2 },
173 { "sst.w",      one(0x0501),            one(0x0781),    IF4F, 2 },
174
175 { "ld.b",       two(0x0700,0x0000),     two (0x07e0,0x0000),    IF7C, 1 },
176 { "ld.h",       two(0x0720,0x0000),     two (0x07e0,0x0001),    IF7A, 1 },
177 { "ld.w",       two(0x0720,0x0001),     two (0x07e0,0x0001),    IF7A, 1 },
178 { "st.b",       two(0x0740,0x0000),     two (0x07e0,0x0000),    IF7D, 2 },
179 { "st.h",       two(0x0760,0x0000),     two (0x07e0,0x0001),    IF7B, 2 },
180 { "st.w",       two(0x0760,0x0001),     two (0x07e0,0x0001),    IF7B, 2 },
181
182 /* arithmetic operation instructions */
183 { "nop",        one(0x00),              one(0xffff),            {0}, 0 },
184 { "mov",        OP(0x00),               OP_MASK,        IF1, 0 },
185 { "mov",        OP(0x10),               OP_MASK,        IF2, 0 },
186 { "movea",      OP(0x31),               OP_MASK,        IF6, 0 },
187 { "movhi",      OP(0x32),               OP_MASK,        IF6, 0 },
188 { "add",        OP(0x0e),               OP_MASK,        IF1, 0 },
189 { "add",        OP(0x12),               OP_MASK,        IF2, 0 },
190 { "addi",       OP(0x30),               OP_MASK,        IF6, 0 },
191 { "sub",        OP(0x0d),               OP_MASK,        IF1, 0 },
192 { "subr",       OP(0x0c),               OP_MASK,        IF1, 0 },
193 { "mulh",       OP(0x07),               OP_MASK,        IF1, 0 },
194 { "mulh",       OP(0x17),               OP_MASK,        IF2, 0 },
195 { "mulhi",      OP(0x37),               OP_MASK,        IF6, 0 },
196 { "divh",       OP(0x02),               OP_MASK,        IF1, 0 },
197 { "cmp",        OP(0x0f),               OP_MASK,        IF1, 0 },
198 { "cmp",        OP(0x13),               OP_MASK,        IF2, 0 },
199 { "setf",       two(0x07e0,0x0000),     two(0x07f0,0xffff), {CCCC,R2}, 0 },
200
201 /* saturated operation instructions */
202 { "satadd",     OP(0x06),               OP_MASK,        IF1, 0 },
203 { "satadd",     OP(0x11),               OP_MASK,        IF2, 0 },
204 { "satsub",     OP(0x05),               OP_MASK,        IF1, 0 },
205 { "satsubi",    OP(0x33),               OP_MASK,        IF6, 0 },
206 { "satsubr",    OP(0x04),               OP_MASK,        IF1, 0 },
207
208 /* logical operation instructions */
209 { "tst",        OP(0x0b),               OP_MASK,        IF1, 0 },
210 { "or",         OP(0x08),               OP_MASK,        IF1, 0 },
211 { "ori",        OP(0x34),               OP_MASK,        IF6U, 0 },
212 { "and",        OP(0x0a),               OP_MASK,        IF1, 0 },
213 { "andi",       OP(0x36),               OP_MASK,        IF6U, 0 },
214 { "xor",        OP(0x09),               OP_MASK,        IF1, 0 },
215 { "xori",       OP(0x35),               OP_MASK,        IF6U, 0 },
216 { "not",        OP(0x01),               OP_MASK,        IF1, 0 },
217 { "sar",        OP(0x15),               OP_MASK,        {I5U, R2}, 0 },
218 { "sar",        two(0x07e0,0x00a0),     two(0x07e0,0xffff),     {R1,R2}, 0 },
219 { "shl",        OP(0x16),               OP_MASK,                {I5U, R2}, 0 },
220 { "shl",        two(0x07e0,0x00c0),     two(0x07e0,0xffff),     {R1,R2}, 0 },
221 { "shr",        OP(0x14),               OP_MASK,                {I5U, R2}, 0 },
222 { "shr",        two(0x07e0,0x0080),     two(0x07e0,0xffff),     {R1,R2}, 0 },
223
224 /* branch instructions */
225         /* signed integer */
226 { "bgt",        BOP(0xf),               BOP_MASK,       IF3, 0 },
227 { "bge",        BOP(0xe),               BOP_MASK,       IF3, 0 },
228 { "blt",        BOP(0x6),               BOP_MASK,       IF3, 0 },
229 { "ble",        BOP(0x7),               BOP_MASK,       IF3, 0 },
230         /* unsigned integer */
231 { "bh",         BOP(0xb),               BOP_MASK,       IF3, 0 },
232 { "bnh",        BOP(0x3),               BOP_MASK,       IF3, 0 },
233 { "bl",         BOP(0x1),               BOP_MASK,       IF3, 0 },
234 { "bnl",        BOP(0x9),               BOP_MASK,       IF3, 0 },
235         /* common */
236 { "be",         BOP(0x2),               BOP_MASK,       IF3, 0 },
237 { "bne",        BOP(0xa),               BOP_MASK,       IF3, 0 },
238         /* others */
239 { "bv",         BOP(0x0),               BOP_MASK,       IF3, 0 },
240 { "bnv",        BOP(0x8),               BOP_MASK,       IF3, 0 },
241 { "bn",         BOP(0x4),               BOP_MASK,       IF3, 0 },
242 { "bp",         BOP(0xc),               BOP_MASK,       IF3, 0 },
243 { "bc",         BOP(0x1),               BOP_MASK,       IF3, 0 },
244 { "bnc",        BOP(0x9),               BOP_MASK,       IF3, 0 },
245 { "bz",         BOP(0x2),               BOP_MASK,       IF3, 0 },
246 { "bnz",        BOP(0xa),               BOP_MASK,       IF3, 0 },
247 { "br",         BOP(0x5),               BOP_MASK,       IF3, 0 },
248 { "bsa",        BOP(0xd),               BOP_MASK,       IF3, 0 },
249
250 { "jmp",        one(0x0060),            one(0xffe0),    { R1}, 1 },
251 { "jr",         one(0x0780),            two(0xffc0,0x0001),{ D22 }, 0 },
252 { "jarl",       one(0x0780),            two(0x07c0,0x0001),{ D22, R2 }, 0 }, 
253
254 /* bit manipulation instructions */
255 { "set1",       two(0x07c0,0x0000),     two(0xc7e0,0x0000),     {B3, D16, R1}, 2 },
256 { "not1",       two(0x47c0,0x0000),     two(0xc7e0,0x0000),     {B3, D16, R1}, 2 },
257 { "clr1",       two(0x87c0,0x0000),     two(0xc7e0,0x0000),     {B3, D16, R1}, 2 },
258 { "tst1",       two(0xc7c0,0x0000),     two(0xc7e0,0x0000),     {B3, D16, R1}, 2 },
259
260 /* special instructions */
261 { "di",         two(0x07e0,0x0160),     two(0xffff,0xffff),     {0}, 0 },
262 { "ei",         two(0x87e0,0x0160),     two(0xffff,0xffff),     {0}, 0 },
263 { "halt",       two(0x07e0,0x0120),     two(0xffff,0xffff),     {0}, 0 },
264 { "reti",       two(0x07e0,0x0140),     two(0xffff,0xffff),     {0}, 0 },
265 { "trap",       two(0x07e0,0x0100),     two(0xffe0,0xffff),     {I5U}, 0 },
266 { "ldsr",       two(0x07e0,0x0020),     two(0x07e0,0xffff),     {R1,SR2}, 0 },
267 { "stsr",       two(0x07e0,0x0040),     two(0x07e0,0xffff),     {SR1,R2}, 0 },
268 { 0, 0, 0, {0}, 0 },
269
270 } ;
271
272 const int v850_num_opcodes =
273   sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
274
275 \f
276 /* The functions used to insert and extract complicated operands.  */
277
278 static unsigned long
279 insert_d9 (insn, value, errmsg)
280      unsigned long insn;
281      long value;
282      const char **errmsg;
283 {
284   if (value > 255 || value <= -256)
285     *errmsg = "branch value out of range";
286
287   if ((value % 2) != 0)
288     *errmsg = "branch to odd offset";
289
290   return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
291 }
292
293 static long
294 extract_d9 (insn, invalid)
295      unsigned long insn;
296      int *invalid;
297 {
298   long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
299
300   if ((insn & 0x8000) != 0)
301     ret -= 0x0200;
302
303   return ret;
304 }
305
306 static unsigned long
307 insert_d22 (insn, value, errmsg)
308      unsigned long insn;
309      long value;
310      const char **errmsg;
311 {
312   if (value > 0xfffff || value <= -0x100000)
313     *errmsg = "branch value out of range";
314
315   if ((value % 2) != 0)
316     *errmsg = "branch to odd offset";
317
318   return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
319 }
320
321 static long
322 extract_d22 (insn, invalid)
323      unsigned long insn;
324      int *invalid;
325 {
326   int ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
327
328   return ((ret << 10) >> 10);
329 }
330
331 static unsigned long
332 insert_d16_15 (insn, value, errmsg)
333      unsigned long insn;
334      long value;
335      const char **errmsg;
336 {
337   if (value > 0x7fff || value <= -0x8000)
338     *errmsg = "value out of range";
339
340   if ((value % 2) != 0)
341     *errmsg = "load/store half/word at odd offset";
342
343   return (insn | ((value & 0xfffe) << 16));
344 }
345
346 static long
347 extract_d16_15 (insn, invalid)
348      unsigned long insn;
349      int *invalid;
350 {
351   int ret = ((insn & 0xfffe0000) >> 16);
352
353   return ((ret << 16) >> 16);
354 }
355
356 static unsigned long
357 insert_d8_7 (insn, value, errmsg)
358      unsigned long insn;
359      long value;
360      const char **errmsg;
361 {
362   if (value > 0xff || value < 0)
363     *errmsg = "short load/store half value out of range";
364
365   if ((value % 2) != 0)
366     *errmsg = "short load/store half at odd offset";
367
368   value >>= 1;
369
370   return (insn | (value & 0x7f));
371 }
372
373 static long
374 extract_d8_7 (insn, invalid)
375      unsigned long insn;
376      int *invalid;
377 {
378   int ret = (insn & 0x7f);
379
380   return ret << 1;
381 }
382
383 static unsigned long
384 insert_d8_6 (insn, value, errmsg)
385      unsigned long insn;
386      long value;
387      const char **errmsg;
388 {
389   if (value > 0xff || value < 0)
390     *errmsg = "short load/store word value out of range";
391
392   if ((value % 4) != 0)
393     *errmsg = "short load/store word at odd offset";
394
395   value >>= 1;
396
397   return (insn | (value & 0x7e));
398 }
399
400 static long
401 extract_d8_6 (insn, invalid)
402      unsigned long insn;
403      int *invalid;
404 {
405   int ret = (insn & 0x7e);
406
407   return ret << 1;
408 }