* v850-opc.c (insert_d22, extract_d22): New functions.
[deliverable/binutils-gdb.git] / opcodes / v850-opc.c
CommitLineData
6d1e1ee8
C
1#include "ansidecl.h"
2#include "opcode/v850.h"
3
4f235110
C
4/* Local insertion and extraction functions. */
5static unsigned long insert_d9 PARAMS ((unsigned long, long, const char **));
6static long extract_d9 PARAMS ((unsigned long, int *));
574b9cb3
JL
7static unsigned long insert_d22 PARAMS ((unsigned long, long, const char **));
8static long extract_d22 PARAMS ((unsigned long, int *));
4f235110 9
6d1e1ee8
C
10/* regular opcode */
11#define OP(x) ((x & 0x3f) << 5)
12#define OP_MASK OP(0x3f)
13
14/* conditional branch opcode */
15#define BOP(x) ((0x0b << 7) | (x & 0x0f))
16#define BOP_MASK ((0x0b << 7) | 0x0f)
17
18/* one-word opcodes */
19#define one(x) ((unsigned int) (x))
20
21/* two-word opcodes */
b1e897a9 22#define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16))
6d1e1ee8
C
23
24
25\f
26const struct v850_operand v850_operands[] = {
27#define UNUSED 0
69463cbb 28 { 0, 0, 0, 0, 0 },
6d1e1ee8
C
29
30/* The R1 field in a format 1, 6, 7, or 9 insn. */
31#define R1 (UNUSED+1)
69463cbb 32 { 5, 0, 0, 0, V850_OPERAND_REG },
6d1e1ee8
C
33
34/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */
35#define R2 (R1+1)
69463cbb 36 { 5, 11, 0, 0, V850_OPERAND_REG },
6d1e1ee8
C
37
38/* The IMM5 field in a format 2 insn. */
39#define I5 (R2+1)
dbc6a8f6
C
40 { 5, 0, 0, 0, V850_OPERAND_SIGNED },
41
42#define I5U (I5+1)
43 { 5, 0, 0, 0, 0 },
6d1e1ee8 44
4f235110 45/* The IMM16 field in a format 6 insn. */
dbc6a8f6 46#define I16 (I5U+1)
e7dd7775 47 { 16, 16, 0, 0, V850_OPERAND_SIGNED },
6d1e1ee8 48
4be84c49
JL
49/* The signed DISP7 field in a format 4 insn. */
50#define D7S (I16+1)
51 { 7, 0, 0, 0, V850_OPERAND_SIGNED },
6d1e1ee8 52
4f235110 53/* The DISP9 field in a format 3 insn. */
4be84c49 54#define D9 (D7S+1)
d44b697b 55 { 9, 0, insert_d9, extract_d9, V850_OPERAND_SIGNED },
6d1e1ee8
C
56
57/* The DISP16 field in a format 6 insn. */
4f235110 58#define D16 (D9+1)
9ab069ea 59 { 16, 16, 0, 0, V850_OPERAND_SIGNED },
6d1e1ee8
C
60
61/* The DISP22 field in a format 4 insn. */
62#define D22 (D16+1)
574b9cb3 63 { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED },
7c8157dd
JL
64
65#define B3 (D22+1)
66/* The 3 bit immediate field in format 8 insn. */
3c72ab70 67 { 3, 11, 0, 0, 0 },
69463cbb
C
68
69#define CCCC (B3+1)
70/* The 4 bit condition code in a setf instruction */
4be84c49
JL
71 { 4, 0, 0, 0, V850_OPERAND_CC },
72
73/* The unsigned DISP8 field in a format 4 insn. */
74#define D8 (CCCC+1)
75 { 8, 0, 0, 0, 0 },
76
e41c99bd
JL
77/* System register operands. */
78#define SR1 (D8+1)
d3edb57f
JL
79 { 5, 0, 0, 0, V850_OPERAND_SRG },
80
81/* EP Register. */
82#define EP (SR1+1)
e7dd7775
JL
83 { 0, 0, 0, 0, V850_OPERAND_EP },
84
85/* The IMM16 field (unsigned0 in a format 6 insn. */
86#define I16U (EP+1)
87 { 16, 16, 0, 0, 0},
e9ebb364
JL
88
89/* The R2 field as a system register. */
90#define SR2 (I16U+1)
91 { 5, 11, 0, 0, V850_OPERAND_SRG },
92
6d1e1ee8
C
93} ;
94
95\f
96/* reg-reg instruction format (Format I) */
97#define IF1 {R1, R2}
98
99/* imm-reg instruction format (Format II) */
100#define IF2 {I5, R2}
101
102/* conditional branch instruction format (Format III) */
4f235110 103#define IF3 {D9}
6d1e1ee8
C
104
105/* 16-bit load/store instruction (Format IV) */
d3edb57f
JL
106#define IF4A {D7S, EP, R2}
107#define IF4B {R2, D7S, EP}
108#define IF4C {D8, EP, R2}
109#define IF4D {R2, D8, EP}
6d1e1ee8
C
110
111/* Jump instruction (Format V) */
112#define IF5 {D22}
113
114/* 3 operand instruction (Format VI) */
e89a42c1 115#define IF6 {I16, R1, R2}
6d1e1ee8 116
e7dd7775
JL
117/* 3 operand instruction (Format VI) */
118#define IF6U {I16U, R1, R2}
119
6d1e1ee8 120/* 32-bit load/store instruction (Format VII) */
e89a42c1
C
121#define IF7A {D16, R1, R2}
122#define IF7B {R2, D16, R1}
6d1e1ee8 123
b10e29f4 124/* Bit manipulation function. */
6d1e1ee8
C
125
126
127\f
128/* The opcode table.
129
130 The format of the opcode table is:
131
132 NAME OPCODE MASK { OPERANDS }
133
134 NAME is the name of the instruction.
135 OPCODE is the instruction opcode.
136 MASK is the opcode mask; this is used to tell the disassembler
137 which bits in the actual opcode must match OPCODE.
138 OPERANDS is the list of operands.
139
140 The disassembler reads the table in order and prints the first
141 instruction which matches, so this table is sorted to put more
142 specific instructions before more general instructions. It is also
143 sorted by major opcode. */
144
145const struct v850_opcode v850_opcodes[] = {
146/* load/store instructions */
fb6da868
JL
147{ "sld.b", one(0x0300), one(0x0780), IF4A, 2 },
148{ "sld.h", one(0x0400), one(0x0780), IF4A, 2 },
e7f3e5fb
JL
149{ "sld.w", one(0x0500), one(0x0781), IF4A, 2 },
150{ "sst.b", one(0x0380), one(0x0780), IF4B, 2 },
151{ "sst.h", one(0x0480), one(0x0780), IF4D, 2 },
152{ "sst.w", one(0x0501), one(0x0781), IF4D, 2 },
280d40df 153
fb6da868
JL
154{ "ld.b", two(0x0700,0x0000), two (0x07e0,0x0000), IF7A, 4 },
155{ "ld.h", two(0x0720,0x0000), two (0x07e0,0x0001), IF7A, 4 },
156{ "ld.w", two(0x0720,0x0001), two (0x07e0,0x0001), IF7A, 4 },
157{ "st.b", two(0x0740,0x0000), two (0x07e0,0x0000), IF7B, 4 },
158{ "st.h", two(0x0760,0x0000), two (0x07e0,0x0001), IF7B, 4 },
159{ "st.w", two(0x0760,0x0001), two (0x07e0,0x0001), IF7B, 4 },
6d1e1ee8
C
160
161/* arithmetic operation instructions */
280d40df 162{ "mov", OP(0x00), OP_MASK, IF1, 2 },
18c97701 163{ "mov", OP(0x10), OP_MASK, IF2, 2 },
280d40df 164{ "movea", OP(0x31), OP_MASK, IF6, 4 },
18c97701 165{ "movhi", OP(0x32), OP_MASK, IF6, 4 },
280d40df
JL
166{ "add", OP(0x0e), OP_MASK, IF1, 2 },
167{ "add", OP(0x12), OP_MASK, IF2, 2 },
168{ "addi", OP(0x30), OP_MASK, IF6, 4 },
169{ "sub", OP(0x0d), OP_MASK, IF1, 2 },
170{ "subr", OP(0x0c), OP_MASK, IF1, 2 },
171{ "mulh", OP(0x07), OP_MASK, IF1, 2 },
172{ "mulh", OP(0x17), OP_MASK, IF2, 2 },
173{ "mulhi", OP(0x37), OP_MASK, IF6, 4 },
174{ "divh", OP(0x02), OP_MASK, IF1, 2 },
175{ "cmp", OP(0x0f), OP_MASK, IF1, 2 },
176{ "cmp", OP(0x13), OP_MASK, IF2, 2 },
6c1fc4d3 177{ "setf", two(0x07e0,0x0000), two(0x07f0,0xffff), {CCCC,R2}, 4 },
6d1e1ee8
C
178
179/* saturated operation instructions */
280d40df
JL
180{ "satadd", OP(0x06), OP_MASK, IF1, 2 },
181{ "satadd", OP(0x11), OP_MASK, IF2, 2 },
182{ "satsub", OP(0x05), OP_MASK, IF1, 2 },
183{ "satsubi", OP(0x33), OP_MASK, IF6, 4 },
184{ "satsubr", OP(0x04), OP_MASK, IF1, 2 },
6d1e1ee8
C
185
186/* logical operation instructions */
280d40df
JL
187{ "tst", OP(0x0b), OP_MASK, IF1, 2 },
188{ "or", OP(0x08), OP_MASK, IF1, 2 },
e7dd7775 189{ "ori", OP(0x34), OP_MASK, IF6U, 4 },
280d40df 190{ "and", OP(0x0a), OP_MASK, IF1, 2 },
e7dd7775 191{ "andi", OP(0x36), OP_MASK, IF6U, 4 },
280d40df 192{ "xor", OP(0x09), OP_MASK, IF1, 2 },
e7dd7775 193{ "xori", OP(0x35), OP_MASK, IF6U, 4 },
38c7a450 194{ "not", OP(0x01), OP_MASK, IF1, 2 },
280d40df
JL
195{ "sar", OP(0x15), OP_MASK, {I5U, R2}, 2 },
196{ "sar", two(0x07e0,0x00a0), two(0x07e0,0xffff), {R1,R2}, 4 },
197{ "shl", OP(0x16), OP_MASK, {I5U, R2}, 2 },
198{ "shl", two(0x07e0,0x00c0), two(0x07e0,0xffff), {R1,R2}, 4 },
199{ "shr", OP(0x14), OP_MASK, {I5U, R2}, 2 },
200{ "shr", two(0x07e0,0x0080), two(0x07e0,0xffff), {R1,R2}, 4 },
6d1e1ee8
C
201
202/* branch instructions */
6bc33c7f 203 /* signed integer */
280d40df
JL
204{ "bgt", BOP(0xf), BOP_MASK, IF3, 2 },
205{ "bge", BOP(0xe), BOP_MASK, IF3, 2 },
206{ "blt", BOP(0x6), BOP_MASK, IF3, 2 },
207{ "ble", BOP(0x7), BOP_MASK, IF3, 2 },
6bc33c7f 208 /* unsigned integer */
280d40df
JL
209{ "bh", BOP(0xb), BOP_MASK, IF3, 2 },
210{ "bnh", BOP(0x3), BOP_MASK, IF3, 2 },
211{ "bl", BOP(0x1), BOP_MASK, IF3, 2 },
212{ "bnl", BOP(0x9), BOP_MASK, IF3, 2 },
6bc33c7f 213 /* common */
280d40df
JL
214{ "be", BOP(0x2), BOP_MASK, IF3, 2 },
215{ "bne", BOP(0xa), BOP_MASK, IF3, 2 },
6bc33c7f 216 /* others */
280d40df
JL
217{ "bv", BOP(0x0), BOP_MASK, IF3, 2 },
218{ "bnv", BOP(0x8), BOP_MASK, IF3, 2 },
219{ "bn", BOP(0x4), BOP_MASK, IF3, 2 },
220{ "bp", BOP(0xc), BOP_MASK, IF3, 2 },
221{ "bc", BOP(0x1), BOP_MASK, IF3, 2 },
222{ "bnc", BOP(0x9), BOP_MASK, IF3, 2 },
223{ "bz", BOP(0x2), BOP_MASK, IF3, 2 },
224{ "bnz", BOP(0xa), BOP_MASK, IF3, 2 },
225{ "br", BOP(0x5), BOP_MASK, IF3, 2 },
226{ "bsa", BOP(0xd), BOP_MASK, IF3, 2 },
227
85b52013 228{ "jmp", one(0x0060), one(0xffe0), { R1}, 2 },
280d40df
JL
229{ "jarl", one(0x0780), one(0xf83f), { D22, R2 }, 4 },
230{ "jr", one(0x0780), one(0xffe0), { D22 }, 4 },
6d1e1ee8 231
6d1e1ee8 232/* bit manipulation instructions */
280d40df
JL
233{ "set1", two(0x07c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
234{ "not1", two(0x47c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
235{ "clr1", two(0x87c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
236{ "tst1", two(0xc7c0,0x0000), two(0xc7e0,0x0000), {B3, D16, R1}, 4 },
6d1e1ee8
C
237
238/* special instructions */
280d40df
JL
239{ "di", two(0x07e0,0x0160), two(0xffff,0xffff), {0}, 4 },
240{ "ei", two(0x87e0,0x0160), two(0xffff,0xffff), {0}, 4 },
241{ "halt", two(0x07e0,0x0120), two(0xffff,0xffff), {0}, 4 },
242{ "reti", two(0x07e0,0x0140), two(0xffff,0xffff), {0}, 4 },
c262d7d8 243{ "trap", two(0x07e0,0x0100), two(0xffe0,0xffff), {I5U}, 4 },
e9ebb364 244{ "ldsr", two(0x07e0,0x0020), two(0x07e0,0xffff), {R1,SR2}, 4 },
e41c99bd 245{ "stsr", two(0x07e0,0x0040), two(0x07e0,0xffff), {SR1,R2}, 4 },
e7f3e5fb 246{ "nop", one(0x00), one(0xffff), {0}, 2 },
e7dd7775 247{ 0, 0, 0, {0}, 0 },
6d1e1ee8
C
248
249} ;
250
251const int v850_num_opcodes =
252 sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
253
4f235110
C
254\f
255/* The functions used to insert and extract complicated operands. */
256
257static unsigned long
258insert_d9 (insn, value, errmsg)
259 unsigned long insn;
260 long value;
261 const char **errmsg;
262{
574b9cb3 263 if (value > 255 || value <= -256)
4f235110
C
264 *errmsg = "value out of range";
265
266 return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
267}
268
269static long
270extract_d9 (insn, invalid)
271 unsigned long insn;
272 int *invalid;
273{
274 long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
275
276 if ((insn & 0x8000) != 0)
277 ret -= 0x0200;
278
279 return ret;
280}
574b9cb3
JL
281
282static unsigned long
283insert_d22 (insn, value, errmsg)
284 unsigned long insn;
285 long value;
286 const char **errmsg;
287{
288 if (value > 0xfffff || value <= -0x100000)
289 *errmsg = "value out of range";
290
291 return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
292}
293
294static long
295extract_d22 (insn, invalid)
296 unsigned long insn;
297 int *invalid;
298{
299 int ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
300
301 return ((ret << 10) >> 10);
302}
This page took 0.040147 seconds and 4 git commands to generate.