Set V850_OPERAND_ADJUST_SHORT_MEMORY flag on sst.{h,w}/sld.{h,w} instructions
[deliverable/binutils-gdb.git] / opcodes / v850-opc.c
CommitLineData
072b27ea
JL
1/* Assemble V850 instructions.
2 Copyright (C) 1996 Free Software Foundation, Inc.
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
6d1e1ee8
C
18#include "ansidecl.h"
19#include "opcode/v850.h"
20
4f235110
C
21/* Local insertion and extraction functions. */
22static unsigned long insert_d9 PARAMS ((unsigned long, long, const char **));
23static long extract_d9 PARAMS ((unsigned long, int *));
574b9cb3
JL
24static unsigned long insert_d22 PARAMS ((unsigned long, long, const char **));
25static long extract_d22 PARAMS ((unsigned long, int *));
c6b9c135
JL
26static unsigned long insert_d16_15 PARAMS ((unsigned long, long,
27 const char **));
28static long extract_d16_15 PARAMS ((unsigned long, int *));
b2194164
JL
29static unsigned long insert_d8_7 PARAMS ((unsigned long, long, const char **));
30static long extract_d8_7 PARAMS ((unsigned long, int *));
31static unsigned long insert_d8_6 PARAMS ((unsigned long, long, const char **));
32static long extract_d8_6 PARAMS ((unsigned long, int *));
4f235110 33
6d1e1ee8
C
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))
502535cf 40#define BOP_MASK ((0x0f << 7) | 0x0f)
6d1e1ee8
C
41
42/* one-word opcodes */
43#define one(x) ((unsigned int) (x))
44
45/* two-word opcodes */
b1e897a9 46#define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16))
6d1e1ee8
C
47
48
49\f
50const struct v850_operand v850_operands[] = {
51#define UNUSED 0
69463cbb 52 { 0, 0, 0, 0, 0 },
6d1e1ee8
C
53
54/* The R1 field in a format 1, 6, 7, or 9 insn. */
55#define R1 (UNUSED+1)
69463cbb 56 { 5, 0, 0, 0, V850_OPERAND_REG },
6d1e1ee8
C
57
58/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */
59#define R2 (R1+1)
69463cbb 60 { 5, 11, 0, 0, V850_OPERAND_REG },
6d1e1ee8
C
61
62/* The IMM5 field in a format 2 insn. */
63#define I5 (R2+1)
dbc6a8f6
C
64 { 5, 0, 0, 0, V850_OPERAND_SIGNED },
65
66#define I5U (I5+1)
67 { 5, 0, 0, 0, 0 },
6d1e1ee8 68
4f235110 69/* The IMM16 field in a format 6 insn. */
dbc6a8f6 70#define I16 (I5U+1)
e7dd7775 71 { 16, 16, 0, 0, V850_OPERAND_SIGNED },
6d1e1ee8 72
4be84c49 73/* The signed DISP7 field in a format 4 insn. */
b2194164
JL
74#define D7 (I16+1)
75 { 7, 0, 0, 0, 0},
6d1e1ee8 76
6d1e1ee8 77/* The DISP16 field in a format 6 insn. */
244558e3 78#define D16_15 (D7+1)
c6b9c135 79 { 16, 16, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED },
6d1e1ee8 80
244558e3 81#define B3 (D16_15+1)
7c8157dd 82/* The 3 bit immediate field in format 8 insn. */
3c72ab70 83 { 3, 11, 0, 0, 0 },
69463cbb
C
84
85#define CCCC (B3+1)
86/* The 4 bit condition code in a setf instruction */
4be84c49
JL
87 { 4, 0, 0, 0, V850_OPERAND_CC },
88
b2194164
JL
89/* The unsigned DISP8_7 field in a format 4 insn. */
90#define D8_7 (CCCC+1)
0068e79c 91 { 8, 0, insert_d8_7, extract_d8_7, V850_OPERAND_ADJUST_SHORT_MEMORY },
b2194164
JL
92
93/* The unsigned DISP8_6 field in a format 4 insn. */
94#define D8_6 (D8_7+1)
0068e79c 95 { 8, 0, insert_d8_6, extract_d8_6, V850_OPERAND_ADJUST_SHORT_MEMORY },
4be84c49 96
e41c99bd 97/* System register operands. */
b2194164 98#define SR1 (D8_6+1)
d3edb57f
JL
99 { 5, 0, 0, 0, V850_OPERAND_SRG },
100
101/* EP Register. */
102#define EP (SR1+1)
e7dd7775
JL
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},
e9ebb364
JL
108
109/* The R2 field as a system register. */
110#define SR2 (I16U+1)
111 { 5, 11, 0, 0, V850_OPERAND_SRG },
112
c6b9c135
JL
113/* The DISP16 field in a format 8 insn. */
114#define D16 (SR2+1)
115 { 16, 16, 0, 0, V850_OPERAND_SIGNED },
116
244558e3
JL
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
6d1e1ee8
C
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) */
244558e3 138#define IF3 {D9_RELAX}
6d1e1ee8
C
139
140/* 16-bit load/store instruction (Format IV) */
b2194164
JL
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}
6d1e1ee8
C
147
148/* Jump instruction (Format V) */
149#define IF5 {D22}
150
151/* 3 operand instruction (Format VI) */
e89a42c1 152#define IF6 {I16, R1, R2}
6d1e1ee8 153
e7dd7775
JL
154/* 3 operand instruction (Format VI) */
155#define IF6U {I16U, R1, R2}
156
c6b9c135
JL
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}
6d1e1ee8 164
b10e29f4 165/* Bit manipulation function. */
6d1e1ee8
C
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
186const struct v850_opcode v850_opcodes[] = {
072b27ea 187{ "breakpoint", 0xffff, 0xffff, 0, 0 },
6d1e1ee8 188/* load/store instructions */
09478dc3
JL
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 },
e7f3e5fb
JL
192{ "sst.b", one(0x0380), one(0x0780), IF4B, 2 },
193{ "sst.h", one(0x0480), one(0x0780), IF4D, 2 },
b2194164 194{ "sst.w", one(0x0501), one(0x0781), IF4F, 2 },
280d40df 195
09478dc3
JL
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 },
6d1e1ee8
C
202
203/* arithmetic operation instructions */
09478dc3
JL
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 },
6d1e1ee8
C
221
222/* saturated operation instructions */
09478dc3
JL
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 },
6d1e1ee8
C
228
229/* logical operation instructions */
09478dc3
JL
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 },
6d1e1ee8
C
244
245/* branch instructions */
6bc33c7f 246 /* signed integer */
09478dc3
JL
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 },
6bc33c7f 251 /* unsigned integer */
09478dc3
JL
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 },
6bc33c7f 256 /* common */
09478dc3
JL
257{ "be", BOP(0x2), BOP_MASK, IF3, 0 },
258{ "bne", BOP(0xa), BOP_MASK, IF3, 0 },
6bc33c7f 259 /* others */
09478dc3
JL
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
244558e3
JL
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
0f02ae6e
JL
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 },
0068e79c 299{ "jbr", BOP(0x5), BOP_MASK, IF3, 0 },
0f02ae6e 300
09478dc3
JL
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 },
6d1e1ee8 304
6d1e1ee8 305/* bit manipulation instructions */
09478dc3
JL
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 },
6d1e1ee8
C
310
311/* special instructions */
09478dc3
JL
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 },
e7dd7775 319{ 0, 0, 0, {0}, 0 },
6d1e1ee8
C
320
321} ;
322
323const int v850_num_opcodes =
324 sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
325
4f235110
C
326\f
327/* The functions used to insert and extract complicated operands. */
328
329static unsigned long
330insert_d9 (insn, value, errmsg)
331 unsigned long insn;
332 long value;
333 const char **errmsg;
334{
072b27ea 335 if (value > 0xff || value < -0x100)
fb8c25a3
JL
336 *errmsg = "branch value out of range";
337
338 if ((value % 2) != 0)
339 *errmsg = "branch to odd offset";
4f235110
C
340
341 return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
342}
343
344static long
345extract_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}
574b9cb3
JL
356
357static unsigned long
358insert_d22 (insn, value, errmsg)
359 unsigned long insn;
360 long value;
361 const char **errmsg;
362{
072b27ea 363 if (value > 0x1fffff || value < -0x200000)
c6b9c135 364 *errmsg = "branch value out of range";
574b9cb3 365
fb8c25a3
JL
366 if ((value % 2) != 0)
367 *errmsg = "branch to odd offset";
368
574b9cb3
JL
369 return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
370}
371
372static long
373extract_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}
c6b9c135
JL
381
382static unsigned long
383insert_d16_15 (insn, value, errmsg)
384 unsigned long insn;
385 long value;
386 const char **errmsg;
387{
072b27ea 388 if (value > 0x7fff || value < -0x8000)
c6b9c135
JL
389 *errmsg = "value out of range";
390
391 if ((value % 2) != 0)
b2194164 392 *errmsg = "load/store half/word at odd offset";
c6b9c135
JL
393
394 return (insn | ((value & 0xfffe) << 16));
395}
396
397static long
398extract_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}
b2194164
JL
406
407static unsigned long
408insert_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
424static long
425extract_d8_7 (insn, invalid)
426 unsigned long insn;
427 int *invalid;
428{
429 int ret = (insn & 0x7f);
430
431 return ret << 1;
432}
433
434static unsigned long
435insert_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
244558e3 446 value >>= 1;
b2194164
JL
447
448 return (insn | (value & 0x7e));
449}
450
451static long
452extract_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.059729 seconds and 4 git commands to generate.