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