* v850-opc.c (insert_d8_7, extract_d8_7): New functions.
[deliverable/binutils-gdb.git] / opcodes / v850-opc.c
CommitLineData
6d1e1ee8
C
1#include "ansidecl.h"
2#include "opcode/v850.h"
3
4f235110
C
4/* Local insertion and extraction functions. */
5static unsigned long insert_d9 PARAMS ((unsigned long, long, const char **));
6static long extract_d9 PARAMS ((unsigned long, int *));
574b9cb3
JL
7static unsigned long insert_d22 PARAMS ((unsigned long, long, const char **));
8static long extract_d22 PARAMS ((unsigned long, int *));
c6b9c135
JL
9static unsigned long insert_d16_15 PARAMS ((unsigned long, long,
10 const char **));
11static long extract_d16_15 PARAMS ((unsigned long, int *));
b2194164
JL
12static unsigned long insert_d8_7 PARAMS ((unsigned long, long, const char **));
13static long extract_d8_7 PARAMS ((unsigned long, int *));
14static unsigned long insert_d8_6 PARAMS ((unsigned long, long, const char **));
15static long extract_d8_6 PARAMS ((unsigned long, int *));
4f235110 16
6d1e1ee8
C
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 ((0x0b << 7) | 0x0f)
24
25/* one-word opcodes */
26#define one(x) ((unsigned int) (x))
27
28/* two-word opcodes */
b1e897a9 29#define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16))
6d1e1ee8
C
30
31
32\f
33const struct v850_operand v850_operands[] = {
34#define UNUSED 0
69463cbb 35 { 0, 0, 0, 0, 0 },
6d1e1ee8
C
36
37/* The R1 field in a format 1, 6, 7, or 9 insn. */
38#define R1 (UNUSED+1)
69463cbb 39 { 5, 0, 0, 0, V850_OPERAND_REG },
6d1e1ee8
C
40
41/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */
42#define R2 (R1+1)
69463cbb 43 { 5, 11, 0, 0, V850_OPERAND_REG },
6d1e1ee8
C
44
45/* The IMM5 field in a format 2 insn. */
46#define I5 (R2+1)
dbc6a8f6
C
47 { 5, 0, 0, 0, V850_OPERAND_SIGNED },
48
49#define I5U (I5+1)
50 { 5, 0, 0, 0, 0 },
6d1e1ee8 51
4f235110 52/* The IMM16 field in a format 6 insn. */
dbc6a8f6 53#define I16 (I5U+1)
e7dd7775 54 { 16, 16, 0, 0, V850_OPERAND_SIGNED },
6d1e1ee8 55
4be84c49 56/* The signed DISP7 field in a format 4 insn. */
b2194164
JL
57#define D7 (I16+1)
58 { 7, 0, 0, 0, 0},
6d1e1ee8 59
4f235110 60/* The DISP9 field in a format 3 insn. */
b2194164 61#define D9 (D7+1)
d44b697b 62 { 9, 0, insert_d9, extract_d9, V850_OPERAND_SIGNED },
6d1e1ee8
C
63
64/* The DISP16 field in a format 6 insn. */
c6b9c135
JL
65#define D16_15 (D9+1)
66 { 16, 16, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED },
6d1e1ee8
C
67
68/* The DISP22 field in a format 4 insn. */
c6b9c135 69#define D22 (D16_15+1)
574b9cb3 70 { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED },
7c8157dd
JL
71
72#define B3 (D22+1)
73/* The 3 bit immediate field in format 8 insn. */
3c72ab70 74 { 3, 11, 0, 0, 0 },
69463cbb
C
75
76#define CCCC (B3+1)
77/* The 4 bit condition code in a setf instruction */
4be84c49
JL
78 { 4, 0, 0, 0, V850_OPERAND_CC },
79
b2194164
JL
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 },
4be84c49 87
e41c99bd 88/* System register operands. */
b2194164 89#define SR1 (D8_6+1)
d3edb57f
JL
90 { 5, 0, 0, 0, V850_OPERAND_SRG },
91
92/* EP Register. */
93#define EP (SR1+1)
e7dd7775
JL
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},
e9ebb364
JL
99
100/* The R2 field as a system register. */
101#define SR2 (I16U+1)
102 { 5, 11, 0, 0, V850_OPERAND_SRG },
103
c6b9c135
JL
104/* The DISP16 field in a format 8 insn. */
105#define D16 (SR2+1)
106 { 16, 16, 0, 0, V850_OPERAND_SIGNED },
107
6d1e1ee8
C
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) */
4f235110 118#define IF3 {D9}
6d1e1ee8
C
119
120/* 16-bit load/store instruction (Format IV) */
b2194164
JL
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}
6d1e1ee8
C
127
128/* Jump instruction (Format V) */
129#define IF5 {D22}
130
131/* 3 operand instruction (Format VI) */
e89a42c1 132#define IF6 {I16, R1, R2}
6d1e1ee8 133
e7dd7775
JL
134/* 3 operand instruction (Format VI) */
135#define IF6U {I16U, R1, R2}
136
c6b9c135
JL
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}
6d1e1ee8 144
b10e29f4 145/* Bit manipulation function. */
6d1e1ee8
C
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
166const struct v850_opcode v850_opcodes[] = {
167/* load/store instructions */
fb6da868 168{ "sld.b", one(0x0300), one(0x0780), IF4A, 2 },
b2194164
JL
169{ "sld.h", one(0x0400), one(0x0780), IF4C, 2 },
170{ "sld.w", one(0x0500), one(0x0781), IF4E, 2 },
e7f3e5fb
JL
171{ "sst.b", one(0x0380), one(0x0780), IF4B, 2 },
172{ "sst.h", one(0x0480), one(0x0780), IF4D, 2 },
b2194164 173{ "sst.w", one(0x0501), one(0x0781), IF4F, 2 },
280d40df 174
c6b9c135 175{ "ld.b", two(0x0700,0x0000), two (0x07e0,0x0000), IF7C, 4 },
fb6da868
JL
176{ "ld.h", two(0x0720,0x0000), two (0x07e0,0x0001), IF7A, 4 },
177{ "ld.w", two(0x0720,0x0001), two (0x07e0,0x0001), IF7A, 4 },
c6b9c135 178{ "st.b", two(0x0740,0x0000), two (0x07e0,0x0000), IF7D, 4 },
fb6da868
JL
179{ "st.h", two(0x0760,0x0000), two (0x07e0,0x0001), IF7B, 4 },
180{ "st.w", two(0x0760,0x0001), two (0x07e0,0x0001), IF7B, 4 },
6d1e1ee8
C
181
182/* arithmetic operation instructions */
280d40df 183{ "mov", OP(0x00), OP_MASK, IF1, 2 },
18c97701 184{ "mov", OP(0x10), OP_MASK, IF2, 2 },
280d40df 185{ "movea", OP(0x31), OP_MASK, IF6, 4 },
18c97701 186{ "movhi", OP(0x32), OP_MASK, IF6, 4 },
280d40df
JL
187{ "add", OP(0x0e), OP_MASK, IF1, 2 },
188{ "add", OP(0x12), OP_MASK, IF2, 2 },
189{ "addi", OP(0x30), OP_MASK, IF6, 4 },
190{ "sub", OP(0x0d), OP_MASK, IF1, 2 },
191{ "subr", OP(0x0c), OP_MASK, IF1, 2 },
192{ "mulh", OP(0x07), OP_MASK, IF1, 2 },
193{ "mulh", OP(0x17), OP_MASK, IF2, 2 },
194{ "mulhi", OP(0x37), OP_MASK, IF6, 4 },
195{ "divh", OP(0x02), OP_MASK, IF1, 2 },
196{ "cmp", OP(0x0f), OP_MASK, IF1, 2 },
197{ "cmp", OP(0x13), OP_MASK, IF2, 2 },
6c1fc4d3 198{ "setf", two(0x07e0,0x0000), two(0x07f0,0xffff), {CCCC,R2}, 4 },
6d1e1ee8
C
199
200/* saturated operation instructions */
280d40df
JL
201{ "satadd", OP(0x06), OP_MASK, IF1, 2 },
202{ "satadd", OP(0x11), OP_MASK, IF2, 2 },
203{ "satsub", OP(0x05), OP_MASK, IF1, 2 },
204{ "satsubi", OP(0x33), OP_MASK, IF6, 4 },
205{ "satsubr", OP(0x04), OP_MASK, IF1, 2 },
6d1e1ee8
C
206
207/* logical operation instructions */
280d40df
JL
208{ "tst", OP(0x0b), OP_MASK, IF1, 2 },
209{ "or", OP(0x08), OP_MASK, IF1, 2 },
e7dd7775 210{ "ori", OP(0x34), OP_MASK, IF6U, 4 },
280d40df 211{ "and", OP(0x0a), OP_MASK, IF1, 2 },
e7dd7775 212{ "andi", OP(0x36), OP_MASK, IF6U, 4 },
280d40df 213{ "xor", OP(0x09), OP_MASK, IF1, 2 },
e7dd7775 214{ "xori", OP(0x35), OP_MASK, IF6U, 4 },
38c7a450 215{ "not", OP(0x01), OP_MASK, IF1, 2 },
280d40df
JL
216{ "sar", OP(0x15), OP_MASK, {I5U, R2}, 2 },
217{ "sar", two(0x07e0,0x00a0), two(0x07e0,0xffff), {R1,R2}, 4 },
218{ "shl", OP(0x16), OP_MASK, {I5U, R2}, 2 },
219{ "shl", two(0x07e0,0x00c0), two(0x07e0,0xffff), {R1,R2}, 4 },
220{ "shr", OP(0x14), OP_MASK, {I5U, R2}, 2 },
221{ "shr", two(0x07e0,0x0080), two(0x07e0,0xffff), {R1,R2}, 4 },
6d1e1ee8
C
222
223/* branch instructions */
6bc33c7f 224 /* signed integer */
280d40df
JL
225{ "bgt", BOP(0xf), BOP_MASK, IF3, 2 },
226{ "bge", BOP(0xe), BOP_MASK, IF3, 2 },
227{ "blt", BOP(0x6), BOP_MASK, IF3, 2 },
228{ "ble", BOP(0x7), BOP_MASK, IF3, 2 },
6bc33c7f 229 /* unsigned integer */
280d40df
JL
230{ "bh", BOP(0xb), BOP_MASK, IF3, 2 },
231{ "bnh", BOP(0x3), BOP_MASK, IF3, 2 },
232{ "bl", BOP(0x1), BOP_MASK, IF3, 2 },
233{ "bnl", BOP(0x9), BOP_MASK, IF3, 2 },
6bc33c7f 234 /* common */
280d40df
JL
235{ "be", BOP(0x2), BOP_MASK, IF3, 2 },
236{ "bne", BOP(0xa), BOP_MASK, IF3, 2 },
6bc33c7f 237 /* others */
280d40df
JL
238{ "bv", BOP(0x0), BOP_MASK, IF3, 2 },
239{ "bnv", BOP(0x8), BOP_MASK, IF3, 2 },
240{ "bn", BOP(0x4), BOP_MASK, IF3, 2 },
241{ "bp", BOP(0xc), BOP_MASK, IF3, 2 },
242{ "bc", BOP(0x1), BOP_MASK, IF3, 2 },
243{ "bnc", BOP(0x9), BOP_MASK, IF3, 2 },
244{ "bz", BOP(0x2), BOP_MASK, IF3, 2 },
245{ "bnz", BOP(0xa), BOP_MASK, IF3, 2 },
246{ "br", BOP(0x5), BOP_MASK, IF3, 2 },
247{ "bsa", BOP(0xd), BOP_MASK, IF3, 2 },
248
85b52013 249{ "jmp", one(0x0060), one(0xffe0), { R1}, 2 },
280d40df
JL
250{ "jarl", one(0x0780), one(0xf83f), { D22, R2 }, 4 },
251{ "jr", one(0x0780), one(0xffe0), { D22 }, 4 },
6d1e1ee8 252
6d1e1ee8 253/* bit manipulation instructions */
280d40df
JL
254{ "set1", two(0x07c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
255{ "not1", two(0x47c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
256{ "clr1", two(0x87c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
257{ "tst1", two(0xc7c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
6d1e1ee8
C
258
259/* special instructions */
280d40df
JL
260{ "di", two(0x07e0,0x0160), two(0xffff,0xffff), {0}, 4 },
261{ "ei", two(0x87e0,0x0160), two(0xffff,0xffff), {0}, 4 },
262{ "halt", two(0x07e0,0x0120), two(0xffff,0xffff), {0}, 4 },
263{ "reti", two(0x07e0,0x0140), two(0xffff,0xffff), {0}, 4 },
c262d7d8 264{ "trap", two(0x07e0,0x0100), two(0xffe0,0xffff), {I5U}, 4 },
e9ebb364 265{ "ldsr", two(0x07e0,0x0020), two(0x07e0,0xffff), {R1,SR2}, 4 },
e41c99bd 266{ "stsr", two(0x07e0,0x0040), two(0x07e0,0xffff), {SR1,R2}, 4 },
e7f3e5fb 267{ "nop", one(0x00), one(0xffff), {0}, 2 },
e7dd7775 268{ 0, 0, 0, {0}, 0 },
6d1e1ee8
C
269
270} ;
271
272const int v850_num_opcodes =
273 sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
274
4f235110
C
275\f
276/* The functions used to insert and extract complicated operands. */
277
278static unsigned long
279insert_d9 (insn, value, errmsg)
280 unsigned long insn;
281 long value;
282 const char **errmsg;
283{
574b9cb3 284 if (value > 255 || value <= -256)
fb8c25a3
JL
285 *errmsg = "branch value out of range";
286
287 if ((value % 2) != 0)
288 *errmsg = "branch to odd offset";
4f235110
C
289
290 return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
291}
292
293static long
294extract_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}
574b9cb3
JL
305
306static unsigned long
307insert_d22 (insn, value, errmsg)
308 unsigned long insn;
309 long value;
310 const char **errmsg;
311{
312 if (value > 0xfffff || value <= -0x100000)
c6b9c135 313 *errmsg = "branch value out of range";
574b9cb3 314
fb8c25a3
JL
315 if ((value % 2) != 0)
316 *errmsg = "branch to odd offset";
317
574b9cb3
JL
318 return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
319}
320
321static long
322extract_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}
c6b9c135
JL
330
331static unsigned long
332insert_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)
b2194164 341 *errmsg = "load/store half/word at odd offset";
c6b9c135
JL
342
343 return (insn | ((value & 0xfffe) << 16));
344}
345
346static long
347extract_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}
b2194164
JL
355
356static unsigned long
357insert_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
373static long
374extract_d8_7 (insn, invalid)
375 unsigned long insn;
376 int *invalid;
377{
378 int ret = (insn & 0x7f);
379
380 return ret << 1;
381}
382
383static unsigned long
384insert_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
400static long
401extract_d8_6 (insn, invalid)
402 unsigned long insn;
403 int *invalid;
404{
405 int ret = (insn & 0x7e);
406
407 return ret << 1;
408}
This page took 0.044562 seconds and 4 git commands to generate.