* v850-opc.c (insert_d8_7, extract_d8_7): New functions.
[deliverable/binutils-gdb.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 ((0x0b << 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, 2 },
169 { "sld.h", one(0x0400), one(0x0780), IF4C, 2 },
170 { "sld.w", one(0x0500), one(0x0781), IF4E, 2 },
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, 4 },
176 { "ld.h", two(0x0720,0x0000), two (0x07e0,0x0001), IF7A, 4 },
177 { "ld.w", two(0x0720,0x0001), two (0x07e0,0x0001), IF7A, 4 },
178 { "st.b", two(0x0740,0x0000), two (0x07e0,0x0000), IF7D, 4 },
179 { "st.h", two(0x0760,0x0000), two (0x07e0,0x0001), IF7B, 4 },
180 { "st.w", two(0x0760,0x0001), two (0x07e0,0x0001), IF7B, 4 },
181
182 /* arithmetic operation instructions */
183 { "mov", OP(0x00), OP_MASK, IF1, 2 },
184 { "mov", OP(0x10), OP_MASK, IF2, 2 },
185 { "movea", OP(0x31), OP_MASK, IF6, 4 },
186 { "movhi", OP(0x32), OP_MASK, IF6, 4 },
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 },
198 { "setf", two(0x07e0,0x0000), two(0x07f0,0xffff), {CCCC,R2}, 4 },
199
200 /* saturated operation instructions */
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 },
206
207 /* logical operation instructions */
208 { "tst", OP(0x0b), OP_MASK, IF1, 2 },
209 { "or", OP(0x08), OP_MASK, IF1, 2 },
210 { "ori", OP(0x34), OP_MASK, IF6U, 4 },
211 { "and", OP(0x0a), OP_MASK, IF1, 2 },
212 { "andi", OP(0x36), OP_MASK, IF6U, 4 },
213 { "xor", OP(0x09), OP_MASK, IF1, 2 },
214 { "xori", OP(0x35), OP_MASK, IF6U, 4 },
215 { "not", OP(0x01), OP_MASK, IF1, 2 },
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 },
222
223 /* branch instructions */
224 /* signed integer */
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 },
229 /* unsigned integer */
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 },
234 /* common */
235 { "be", BOP(0x2), BOP_MASK, IF3, 2 },
236 { "bne", BOP(0xa), BOP_MASK, IF3, 2 },
237 /* others */
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
249 { "jmp", one(0x0060), one(0xffe0), { R1}, 2 },
250 { "jarl", one(0x0780), one(0xf83f), { D22, R2 }, 4 },
251 { "jr", one(0x0780), one(0xffe0), { D22 }, 4 },
252
253 /* bit manipulation instructions */
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 },
258
259 /* special instructions */
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 },
264 { "trap", two(0x07e0,0x0100), two(0xffe0,0xffff), {I5U}, 4 },
265 { "ldsr", two(0x07e0,0x0020), two(0x07e0,0xffff), {R1,SR2}, 4 },
266 { "stsr", two(0x07e0,0x0040), two(0x07e0,0xffff), {SR1,R2}, 4 },
267 { "nop", one(0x00), one(0xffff), {0}, 2 },
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 }
This page took 0.045292 seconds and 5 git commands to generate.