* ppc-opc.c (insert_li): Give an error if the offset has the two
[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)
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 },
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 },
299
09478dc3
JL
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 },
6d1e1ee8 303
6d1e1ee8 304/* bit manipulation instructions */
09478dc3
JL
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 },
6d1e1ee8
C
309
310/* special instructions */
09478dc3
JL
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 },
e7dd7775 318{ 0, 0, 0, {0}, 0 },
6d1e1ee8
C
319
320} ;
321
322const int v850_num_opcodes =
323 sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
324
4f235110
C
325\f
326/* The functions used to insert and extract complicated operands. */
327
328static unsigned long
329insert_d9 (insn, value, errmsg)
330 unsigned long insn;
331 long value;
332 const char **errmsg;
333{
072b27ea 334 if (value > 0xff || value < -0x100)
fb8c25a3
JL
335 *errmsg = "branch value out of range";
336
337 if ((value % 2) != 0)
338 *errmsg = "branch to odd offset";
4f235110
C
339
340 return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
341}
342
343static long
344extract_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}
574b9cb3
JL
355
356static unsigned long
357insert_d22 (insn, value, errmsg)
358 unsigned long insn;
359 long value;
360 const char **errmsg;
361{
072b27ea 362 if (value > 0x1fffff || value < -0x200000)
c6b9c135 363 *errmsg = "branch value out of range";
574b9cb3 364
fb8c25a3
JL
365 if ((value % 2) != 0)
366 *errmsg = "branch to odd offset";
367
574b9cb3
JL
368 return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
369}
370
371static long
372extract_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}
c6b9c135
JL
380
381static unsigned long
382insert_d16_15 (insn, value, errmsg)
383 unsigned long insn;
384 long value;
385 const char **errmsg;
386{
072b27ea 387 if (value > 0x7fff || value < -0x8000)
c6b9c135
JL
388 *errmsg = "value out of range";
389
390 if ((value % 2) != 0)
b2194164 391 *errmsg = "load/store half/word at odd offset";
c6b9c135
JL
392
393 return (insn | ((value & 0xfffe) << 16));
394}
395
396static long
397extract_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}
b2194164
JL
405
406static unsigned long
407insert_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
423static long
424extract_d8_7 (insn, invalid)
425 unsigned long insn;
426 int *invalid;
427{
428 int ret = (insn & 0x7f);
429
430 return ret << 1;
431}
432
433static unsigned long
434insert_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
244558e3 445 value >>= 1;
b2194164
JL
446
447 return (insn | (value & 0x7e));
448}
449
450static long
451extract_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.051249 seconds and 4 git commands to generate.