Set V850_OPERAND_ADJUST_SHORT_MEMORY flag on sst.{h,w}/sld.{h,w} instructions
[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, V850_OPERAND_ADJUST_SHORT_MEMORY },
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, V850_OPERAND_ADJUST_SHORT_MEMORY },
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 { "jbr", BOP(0x5), BOP_MASK, IF3, 0 },
300
301 { "jmp", one(0x0060), one(0xffe0), { R1}, 1 },
302 { "jr", one(0x0780), two(0xffc0,0x0001),{ D22 }, 0 },
303 { "jarl", one(0x0780), two(0x07c0,0x0001),{ D22, R2 }, 0 },
304
305 /* bit manipulation instructions */
306 { "set1", two(0x07c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 2 },
307 { "not1", two(0x47c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 2 },
308 { "clr1", two(0x87c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 2 },
309 { "tst1", two(0xc7c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 2 },
310
311 /* special instructions */
312 { "di", two(0x07e0,0x0160), two(0xffff,0xffff), {0}, 0 },
313 { "ei", two(0x87e0,0x0160), two(0xffff,0xffff), {0}, 0 },
314 { "halt", two(0x07e0,0x0120), two(0xffff,0xffff), {0}, 0 },
315 { "reti", two(0x07e0,0x0140), two(0xffff,0xffff), {0}, 0 },
316 { "trap", two(0x07e0,0x0100), two(0xffe0,0xffff), {I5U}, 0 },
317 { "ldsr", two(0x07e0,0x0020), two(0x07e0,0xffff), {R1,SR2}, 0 },
318 { "stsr", two(0x07e0,0x0040), two(0x07e0,0xffff), {SR1,R2}, 0 },
319 { 0, 0, 0, {0}, 0 },
320
321 } ;
322
323 const int v850_num_opcodes =
324 sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
325
326 \f
327 /* The functions used to insert and extract complicated operands. */
328
329 static unsigned long
330 insert_d9 (insn, value, errmsg)
331 unsigned long insn;
332 long value;
333 const char **errmsg;
334 {
335 if (value > 0xff || value < -0x100)
336 *errmsg = "branch value out of range";
337
338 if ((value % 2) != 0)
339 *errmsg = "branch to odd offset";
340
341 return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
342 }
343
344 static long
345 extract_d9 (insn, invalid)
346 unsigned long insn;
347 int *invalid;
348 {
349 long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
350
351 if ((insn & 0x8000) != 0)
352 ret -= 0x0200;
353
354 return ret;
355 }
356
357 static unsigned long
358 insert_d22 (insn, value, errmsg)
359 unsigned long insn;
360 long value;
361 const char **errmsg;
362 {
363 if (value > 0x1fffff || value < -0x200000)
364 *errmsg = "branch value out of range";
365
366 if ((value % 2) != 0)
367 *errmsg = "branch to odd offset";
368
369 return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
370 }
371
372 static long
373 extract_d22 (insn, invalid)
374 unsigned long insn;
375 int *invalid;
376 {
377 int ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
378
379 return ((ret << 10) >> 10);
380 }
381
382 static unsigned long
383 insert_d16_15 (insn, value, errmsg)
384 unsigned long insn;
385 long value;
386 const char **errmsg;
387 {
388 if (value > 0x7fff || value < -0x8000)
389 *errmsg = "value out of range";
390
391 if ((value % 2) != 0)
392 *errmsg = "load/store half/word at odd offset";
393
394 return (insn | ((value & 0xfffe) << 16));
395 }
396
397 static long
398 extract_d16_15 (insn, invalid)
399 unsigned long insn;
400 int *invalid;
401 {
402 int ret = ((insn & 0xfffe0000) >> 16);
403
404 return ((ret << 16) >> 16);
405 }
406
407 static unsigned long
408 insert_d8_7 (insn, value, errmsg)
409 unsigned long insn;
410 long value;
411 const char **errmsg;
412 {
413 if (value > 0xff || value < 0)
414 *errmsg = "short load/store half value out of range";
415
416 if ((value % 2) != 0)
417 *errmsg = "short load/store half at odd offset";
418
419 value >>= 1;
420
421 return (insn | (value & 0x7f));
422 }
423
424 static long
425 extract_d8_7 (insn, invalid)
426 unsigned long insn;
427 int *invalid;
428 {
429 int ret = (insn & 0x7f);
430
431 return ret << 1;
432 }
433
434 static unsigned long
435 insert_d8_6 (insn, value, errmsg)
436 unsigned long insn;
437 long value;
438 const char **errmsg;
439 {
440 if (value > 0xff || value < 0)
441 *errmsg = "short load/store word value out of range";
442
443 if ((value % 4) != 0)
444 *errmsg = "short load/store word at odd offset";
445
446 value >>= 1;
447
448 return (insn | (value & 0x7e));
449 }
450
451 static long
452 extract_d8_6 (insn, invalid)
453 unsigned long insn;
454 int *invalid;
455 {
456 int ret = (insn & 0x7e);
457
458 return ret << 1;
459 }
This page took 0.085601 seconds and 5 git commands to generate.