Commit | Line | Data |
---|---|---|
3d3d428f | 1 | /* cr16-opc.c -- Table of opcodes for the CR16 processor. |
2571583a | 2 | Copyright (C) 2007-2017 Free Software Foundation, Inc. |
3d3d428f NC |
3 | Contributed by M R Swami Reddy (MR.Swami.Reddy@nsc.com) |
4 | ||
9b201bb5 | 5 | This file is part of the GNU opcodes library. |
3d3d428f | 6 | |
9b201bb5 NC |
7 | This library is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3, or (at your option) | |
10 | any later version. | |
3d3d428f | 11 | |
9b201bb5 NC |
12 | It is distributed in the hope that it will be useful, but WITHOUT |
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 | License for more details. | |
3d3d428f NC |
16 | |
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software Foundation, | |
19 | Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
20 | ||
21 | #include <stdio.h> | |
22 | #include "libiberty.h" | |
23 | #include "symcat.h" | |
24 | #include "opcode/cr16.h" | |
25 | ||
26 | const inst cr16_instruction[] = | |
27 | { | |
28 | /* Create an arithmetic instruction - INST[bw]. */ | |
29 | #define ARITH_BYTE_INST(NAME, OPC, OP1) \ | |
30 | /* opc8 imm4 r */ \ | |
31 | {NAME, 1, OPC, 24, ARITH_BYTE_INS, {{uimm4_1,20}, {regr,16}}}, \ | |
32 | /* opc8 imm16 r */ \ | |
33 | {NAME, 2, (OPC<<4)+0xB, 20, ARITH_BYTE_INS, {{OP1,0}, {regr,16}}}, \ | |
34 | /* opc8 r r */ \ | |
35 | {NAME, 1, OPC+0x1, 24, ARITH_BYTE_INS, {{regr,20}, {regr,16}}} | |
36 | ||
accf4463 | 37 | /* For Logical operations, allow unsigned imm16 also. */ |
3d3d428f NC |
38 | #define ARITH1_BYTE_INST(NAME, OPC, OP1) \ |
39 | /* opc8 imm16 r */ \ | |
40 | {NAME, 2, (OPC<<4)+0xB, 20, ARITH_BYTE_INS, {{OP1,0}, {regr,16}}} | |
41 | ||
42 | ||
43 | ARITH_BYTE_INST ("andb", 0x20, uimm16), | |
44 | ARITH1_BYTE_INST ("andb", 0x20, imm16), | |
45 | ARITH_BYTE_INST ("andw", 0x22, uimm16), | |
46 | ARITH1_BYTE_INST ("andw", 0x22, imm16), | |
47 | ||
48 | ARITH_BYTE_INST ("orb", 0x24, uimm16), | |
49 | ARITH1_BYTE_INST ("orb", 0x24, imm16), | |
50 | ARITH_BYTE_INST ("orw", 0x26, uimm16), | |
51 | ARITH1_BYTE_INST ("orw", 0x26, imm16), | |
52 | ||
53 | ARITH_BYTE_INST ("xorb", 0x28, uimm16), | |
54 | ARITH1_BYTE_INST ("xorb", 0x28, imm16), | |
55 | ARITH_BYTE_INST ("xorw", 0x2A, uimm16), | |
56 | ARITH1_BYTE_INST ("xorw", 0x2A, imm16), | |
57 | ||
58 | ARITH_BYTE_INST ("addub", 0x2C, imm16), | |
59 | ARITH_BYTE_INST ("adduw", 0x2E, imm16), | |
60 | ARITH_BYTE_INST ("addb", 0x30, imm16), | |
61 | ARITH_BYTE_INST ("addw", 0x32, imm16), | |
62 | ARITH_BYTE_INST ("addcb", 0x34, imm16), | |
63 | ARITH_BYTE_INST ("addcw", 0x36, imm16), | |
64 | ||
65 | ARITH_BYTE_INST ("subb", 0x38, imm16), | |
66 | ARITH_BYTE_INST ("subw", 0x3A, imm16), | |
67 | ARITH_BYTE_INST ("subcb", 0x3C, imm16), | |
68 | ARITH_BYTE_INST ("subcw", 0x3E, imm16), | |
69 | ||
70 | ARITH_BYTE_INST ("cmpb", 0x50, imm16), | |
71 | ARITH_BYTE_INST ("cmpw", 0x52, imm16), | |
72 | ||
73 | ARITH_BYTE_INST ("movb", 0x58, imm16), | |
74 | ARITH_BYTE_INST ("movw", 0x5A, imm16), | |
75 | ||
76 | ARITH_BYTE_INST ("mulb", 0x64, imm16), | |
77 | ARITH_BYTE_INST ("mulw", 0x66, imm16), | |
78 | ||
79 | #define ARITH_BYTE_INST1(NAME, OPC) \ | |
80 | /* opc8 r r */ \ | |
81 | {NAME, 1, OPC, 24, ARITH_BYTE_INS, {{regr,20}, {regr,16}}} | |
82 | ||
83 | ARITH_BYTE_INST1 ("movxb", 0x5C), | |
84 | ARITH_BYTE_INST1 ("movzb", 0x5D), | |
85 | ARITH_BYTE_INST1 ("mulsb", 0x0B), | |
86 | ||
87 | #define ARITH_BYTE_INST2(NAME, OPC) \ | |
88 | /* opc8 r rp */ \ | |
89 | {NAME, 1, OPC, 24, ARITH_BYTE_INS, {{regr,20}, {regp,16}}} | |
90 | ||
91 | ARITH_BYTE_INST2 ("movxw", 0x5E), | |
92 | ARITH_BYTE_INST2 ("movzw", 0x5F), | |
93 | ARITH_BYTE_INST2 ("mulsw", 0x62), | |
94 | ARITH_BYTE_INST2 ("muluw", 0x63), | |
95 | ||
96 | /* Create an arithmetic instruction - INST[d]- with 3 types. */ | |
97 | #define ARITH_INST_D(NAME, OPC) \ | |
98 | /* opc8 imm4 rp */ \ | |
99 | {NAME, 1, OPC, 24, ARITH_INS, {{uimm4_1,20}, {regp,16}}}, \ | |
100 | /* opc8 imm16 rp */ \ | |
101 | {NAME, 2, (OPC<<4)+0xB, 20, ARITH_INS, {{imm16,0}, {regp,16}}}, \ | |
102 | /* opc8 rp rp */ \ | |
103 | {NAME, 1, OPC+1, 24, ARITH_INS, {{regp,20}, {regp,16}}} | |
104 | ||
105 | /* Create an arithmetic instruction - INST[d]-20 bit types. */ | |
106 | #define ARITH_INST20(NAME, OPC) \ | |
107 | /* opc8 uimm20 rp */ \ | |
108 | {NAME, 2, OPC, 24, ARITH_INS, {{uimm20,0}, {regp,20}}} | |
109 | ||
110 | /* Create an arithmetic instruction - INST[d]-32 bit types. */ | |
111 | #define ARITH_INST32(NAME, OPC, OP1) \ | |
112 | /* opc12 imm32 rp */ \ | |
113 | {NAME, 3, OPC, 20, ARITH_INS, {{OP1,0}, {regp,16}}} | |
114 | ||
115 | /* Create an arithmetic instruction - INST[d]-32bit types(reg pairs).*/ | |
116 | #define ARITH_INST32RP(NAME, OPC) \ | |
117 | /* opc24 rp rp */ \ | |
118 | {NAME, 2, OPC, 12, ARITH_INS, {{regp,4}, {regp,0}}} | |
119 | ||
120 | ARITH_INST_D ("movd", 0x54), | |
121 | ARITH_INST20 ("movd", 0x05), | |
122 | ARITH_INST32 ("movd", 0x007, imm32), | |
123 | ARITH_INST_D ("addd", 0x60), | |
124 | ARITH_INST20 ("addd", 0x04), | |
125 | ARITH_INST32 ("addd", 0x002, imm32), | |
126 | ARITH_INST32 ("subd", 0x003, imm32), | |
127 | ARITH_INST32RP ("subd", 0x0014C), | |
128 | ARITH_INST_D ("cmpd", 0x56), | |
129 | ARITH_INST32 ("cmpd", 0x009, imm32), | |
130 | ARITH_INST32 ("andd", 0x004, uimm32), | |
131 | ARITH_INST32RP ("andd", 0x0014B), | |
132 | ARITH_INST32 ("ord", 0x005, uimm32), | |
133 | ARITH_INST32RP ("ord", 0x00149), | |
134 | ARITH_INST32 ("xord", 0x006, uimm32), | |
135 | ARITH_INST32RP ("xord", 0x0014A), | |
136 | ||
137 | /* Create a shift instruction. */ | |
138 | #define SHIFT_INST_A(NAME, OPC1, OPC2, SHIFT, OP1, OP2) \ | |
139 | /* opc imm r */ \ | |
140 | {NAME, 1, OPC1, SHIFT, SHIFT_INS, {{OP1,20}, {OP2,16}}}, \ | |
141 | /* opc imm r */ \ | |
142 | {NAME, 1, OPC1+1, SHIFT, SHIFT_INS, {{OP1,20}, {OP2,16}}},\ | |
143 | /* opc r r */ \ | |
144 | {NAME, 1, OPC2, 24, SHIFT_INS, {{regr,20}, {OP2,16}}} | |
145 | ||
146 | SHIFT_INST_A("ashub", 0x80, 0x41, 23, imm4, regr), | |
147 | SHIFT_INST_A("ashud", 0x26, 0x48, 25, imm6, regp), | |
148 | SHIFT_INST_A("ashuw", 0x42, 0x45, 24, imm5, regr), | |
149 | ||
150 | #define SHIFT_INST_L(NAME, OPC1, OPC2, SHIFT, OP1, OP2) \ | |
151 | /* opc imm r */ \ | |
152 | {NAME, 1, OPC1, SHIFT, SHIFT_INS, {{OP1,20}, {OP2,16}}}, \ | |
153 | /* opc r r */ \ | |
154 | {NAME, 1, OPC2, 24, SHIFT_INS, {{regr,20}, {OP2,16}}} | |
155 | ||
156 | SHIFT_INST_L("lshb", 0x13, 0x44, 23, imm4, regr), | |
157 | SHIFT_INST_L("lshd", 0x25, 0x47, 25, imm6, regp), | |
158 | SHIFT_INST_L("lshw", 0x49, 0x46, 24, imm5, regr), | |
159 | ||
160 | /* Create a conditional branch instruction. */ | |
161 | #define BRANCH_INST(NAME, OPC) \ | |
162 | /* opc4 c4 dispe9 */ \ | |
7fac7ff4 | 163 | {NAME, 1, OPC, 28, BRANCH_INS | RELAXABLE, {{cc,20}, {dispe9,16}}},\ |
3d3d428f | 164 | /* opc4 c4 disps17 */ \ |
7fac7ff4 | 165 | {NAME, 2, ((OPC<<4)+0x8), 24, BRANCH_INS | RELAXABLE, {{cc,20}, {disps17,0}}},\ |
3d3d428f | 166 | /* opc4 c4 disps25 */ \ |
7fac7ff4 | 167 | {NAME, 3, (OPC<<4), 16 , BRANCH_INS | RELAXABLE, {{cc,4}, {disps25,16}}} |
3d3d428f NC |
168 | |
169 | BRANCH_INST ("b", 0x1), | |
170 | ||
171 | /* Create a 'Branch if Equal to 0' instruction. */ | |
172 | #define BRANCH_NEQ_INST(NAME, OPC) \ | |
173 | /* opc8 disps5 r */ \ | |
174 | {NAME, 1, OPC, 24, BRANCH_NEQ_INS, {{regr,16}, {disps5,20}}} | |
175 | ||
176 | BRANCH_NEQ_INST ("beq0b", 0x0C), | |
177 | BRANCH_NEQ_INST ("bne0b", 0x0D), | |
178 | BRANCH_NEQ_INST ("beq0w", 0x0E), | |
179 | BRANCH_NEQ_INST ("bne0w", 0x0F), | |
180 | ||
181 | ||
182 | /* Create an instruction using a single register operand. */ | |
183 | #define REG1_INST(NAME, OPC) \ | |
184 | /* opc8 c4 r */ \ | |
185 | {NAME, 1, OPC, 20, NO_TYPE_INS, {{regr,16}}} | |
186 | ||
187 | #define REGP1_INST(NAME, OPC) \ | |
188 | /* opc8 c4 r */ \ | |
189 | {NAME, 1, OPC, 20, NO_TYPE_INS, {{regp,16}}} | |
190 | ||
191 | /* Same as REG1_INST, with additional FLAGS. */ | |
192 | #define REG1_FLAG_INST(NAME, OPC, FLAGS) \ | |
193 | /* opc8 c4 r */ \ | |
194 | {NAME, 1, OPC, 20, NO_TYPE_INS | FLAGS, {{regp,16}}} | |
195 | ||
196 | /* JCond instructions */ | |
197 | REGP1_INST ("jeq", 0x0A0), | |
198 | REGP1_INST ("jne", 0x0A1), | |
199 | REGP1_INST ("jcs", 0x0A2), | |
200 | REGP1_INST ("jcc", 0x0A3), | |
201 | REGP1_INST ("jhi", 0x0A4), | |
202 | REGP1_INST ("jls", 0x0A5), | |
203 | REGP1_INST ("jgt", 0x0A6), | |
204 | REGP1_INST ("jle", 0x0A7), | |
205 | REGP1_INST ("jfs", 0x0A8), | |
206 | REGP1_INST ("jfc", 0x0A9), | |
207 | REGP1_INST ("jlo", 0x0AA), | |
208 | REGP1_INST ("jhs", 0x0AB), | |
209 | REGP1_INST ("jlt", 0x0AC), | |
210 | REGP1_INST ("jge", 0x0AD), | |
211 | REGP1_INST ("jump", 0x0AE), | |
212 | REGP1_INST ("jusr", 0x0AF), | |
213 | ||
214 | /* SCond instructions */ | |
215 | REG1_INST ("seq", 0x080), | |
216 | REG1_INST ("sne", 0x081), | |
217 | REG1_INST ("scs", 0x082), | |
218 | REG1_INST ("scc", 0x083), | |
219 | REG1_INST ("shi", 0x084), | |
220 | REG1_INST ("sls", 0x085), | |
221 | REG1_INST ("sgt", 0x086), | |
222 | REG1_INST ("sle", 0x087), | |
223 | REG1_INST ("sfs", 0x088), | |
224 | REG1_INST ("sfc", 0x089), | |
225 | REG1_INST ("slo", 0x08A), | |
226 | REG1_INST ("shs", 0x08B), | |
227 | REG1_INST ("slt", 0x08C), | |
228 | REG1_INST ("sge", 0x08D), | |
229 | ||
230 | ||
231 | /* Create an instruction using two register operands. */ | |
232 | #define REG3_INST(NAME, OPC) \ | |
233 | /* opc24 r r rp */ \ | |
234 | {NAME, 2, OPC, 12, NO_TYPE_INS, {{regr,4}, {regr,0}, {regp,8}}} | |
235 | ||
236 | /* MULTIPLY INSTRUCTIONS */ | |
237 | REG3_INST ("macqw", 0x0014d), | |
238 | REG3_INST ("macuw", 0x0014e), | |
239 | REG3_INST ("macsw", 0x0014f), | |
240 | ||
241 | /* Create a branch instruction. */ | |
242 | #define BR_INST(NAME, OPC) \ | |
243 | /* opc12 ra disps25 */ \ | |
244 | {NAME, 2, OPC, 24, NO_TYPE_INS, {{rra,0}, {disps25,0}}} | |
245 | ||
246 | #define BR_INST_RP(NAME, OPC) \ | |
247 | /* opc8 rp disps25 */ \ | |
248 | {NAME, 3, OPC, 12, NO_TYPE_INS, {{regp,4}, {disps25,16}}} | |
249 | ||
250 | BR_INST ("bal", 0xC0), | |
251 | BR_INST_RP ("bal", 0x00102), | |
252 | ||
253 | #define REGPP2_INST(NAME, OPC) \ | |
254 | /* opc16 rp rp */ \ | |
255 | {NAME, 2, OPC, 12, NO_TYPE_INS, {{regp,0}, {regp,4}}} | |
256 | /* Jump and link instructions. */ | |
257 | REGP1_INST ("jal",0x00D), | |
258 | REGPP2_INST ("jal",0x00148), | |
259 | ||
260 | ||
261 | /* Instructions including a register list (opcode is represented as a mask). */ | |
262 | #define REGLIST_INST(NAME, OPC, TYPE) \ | |
263 | /* opc7 r count3 RA */ \ | |
264 | {NAME,1, (OPC<<1)+1, 23, TYPE, {{uimm3_1,20},{regr,16},{regr,0}}}, \ | |
265 | /* opc8 r count3 */ \ | |
266 | {NAME, 1, OPC, 24, TYPE, {{uimm3_1,20}, {regr,16}}}, \ | |
267 | /* opc12 RA */ \ | |
268 | {NAME, 1, (OPC<<8)+0x1E, 16, TYPE, {{regr,0}}} | |
269 | ||
270 | REGLIST_INST ("push", 0x01, (NO_TYPE_INS | REG_LIST)), | |
271 | REGLIST_INST ("pop", 0x02, (NO_TYPE_INS | REG_LIST)), | |
272 | REGLIST_INST ("popret", 0x03, (NO_TYPE_INS | REG_LIST)), | |
273 | ||
274 | {"loadm", 1, 0x14, 19, NO_TYPE_INS | REG_LIST, {{uimm3_1,16}}}, | |
275 | {"loadmp", 1, 0x15, 19, NO_TYPE_INS | REG_LIST, {{uimm3_1,16}}}, | |
276 | {"storm", 1, 0x16, 19, NO_TYPE_INS | REG_LIST, {{uimm3_1,16}}}, | |
277 | {"stormp", 1, 0x17, 19, NO_TYPE_INS | REG_LIST, {{uimm3_1,16}}}, | |
278 | ||
279 | /* Processor Regsiter Manipulation instructions */ | |
280 | /* opc16 reg, preg */ | |
281 | {"lpr", 2, 0x00140, 12, NO_TYPE_INS, {{regr,0}, {pregr,4}}}, | |
282 | /* opc16 regp, pregp */ | |
283 | {"lprd", 2, 0x00141, 12, NO_TYPE_INS, {{regp,0}, {pregrp,4}}}, | |
284 | /* opc16 preg, reg */ | |
285 | {"spr", 2, 0x00142, 12, NO_TYPE_INS, {{pregr,4}, {regr,0}}}, | |
286 | /* opc16 pregp, regp */ | |
287 | {"sprd", 2, 0x00143, 12, NO_TYPE_INS, {{pregrp,4}, {regp,0}}}, | |
288 | ||
289 | /* Miscellaneous. */ | |
290 | /* opc12 ui4 */ | |
291 | {"excp", 1, 0x00C, 20, NO_TYPE_INS, {{uimm4,16}}}, | |
292 | ||
293 | /* Create a bit-b instruction. */ | |
294 | #define CSTBIT_INST_B(NAME, OP, OPC1, OPC2, OPC3, OPC4) \ | |
295 | /* opcNN iN abs20 */ \ | |
296 | {NAME, 2, (OPC3+1), 23, CSTBIT_INS, {{OP,20},{abs20,0}}}, \ | |
297 | /* opcNN iN abs24 */ \ | |
298 | {NAME, 3, (OPC2+3), 12, CSTBIT_INS, {{OP,4},{abs24,16}}}, \ | |
299 | /* opcNN iN (Rindex)abs20 */ \ | |
300 | {NAME, 2, OPC1, 24, CSTBIT_INS, {{OP,20}, {rindex7_abs20,0}}}, \ | |
301 | /* opcNN iN (prp) disps14(RPbase) */ \ | |
302 | {NAME, 2, OPC4, 22, CSTBIT_INS, {{OP,4},{rpindex_disps14,0}}}, \ | |
303 | /* opcNN iN disps20(Rbase) */ \ | |
304 | {NAME, 3, OPC2, 12, CSTBIT_INS, {{OP,4}, {rbase_disps20,16}}}, \ | |
305 | /* opcNN iN (rp) disps0(RPbase) */ \ | |
306 | {NAME, 1, OPC3-2, 23, CSTBIT_INS, {{OP,20}, {rpbase_disps0,16}}}, \ | |
307 | /* opcNN iN (rp) disps16(RPBase) */ \ | |
308 | {NAME, 2, OPC3, 23, CSTBIT_INS, {{OP,20}, {rpbase_disps16,0}}}, \ | |
309 | /* opcNN iN (rp) disps20(RPBase) */ \ | |
310 | {NAME, 3, (OPC2+1), 12, CSTBIT_INS, {{OP,4}, {rpbase_disps20,16}}}, \ | |
311 | /* opcNN iN rrp (Rindex)disps20(RPbase) */ \ | |
312 | {NAME, 3, (OPC2+2), 12, CSTBIT_INS, {{OP,4}, {rpindex_disps20,16}}} | |
313 | ||
314 | CSTBIT_INST_B ("cbitb", uimm3, 0x68, 0x00104, 0xD6, 0x1AA), | |
315 | CSTBIT_INST_B ("sbitb", uimm3, 0x70, 0x00108, 0xE6, 0x1CA), | |
316 | CSTBIT_INST_B ("tbitb", uimm3, 0x78, 0x0010C, 0xF6, 0x1EA), | |
317 | ||
318 | /* Create a bit-w instruction. */ | |
319 | #define CSTBIT_INST_W(NAME, OP, OPC1, OPC2, OPC3, OPC4) \ | |
320 | /* opcNN iN abs20 */ \ | |
321 | {NAME, 2, OPC1+6, 24, CSTBIT_INS, {{OP,20},{abs20,0}}}, \ | |
322 | /* opcNN iN abs24 */ \ | |
323 | {NAME, 3, OPC2+3, 12, CSTBIT_INS, {{OP,4},{abs24,16}}}, \ | |
324 | /* opcNN iN (Rindex)abs20 */ \ | |
325 | {NAME, 2, OPC3, 25, CSTBIT_INS, {{OP,20}, {rindex8_abs20,0}}}, \ | |
326 | /* opcNN iN (prp) disps14(RPbase) */ \ | |
327 | {NAME, 2, OPC4, 22, CSTBIT_INS, {{OP,4},{rpindex_disps14,0}}}, \ | |
328 | /* opcNN iN disps20(Rbase) */ \ | |
329 | {NAME, 3, OPC2, 12, CSTBIT_INS, {{OP,4}, {rbase_disps20,16}}}, \ | |
330 | /* opcNN iN (rp) disps0(RPbase) */ \ | |
331 | {NAME, 1, OPC1+5, 24, CSTBIT_INS, {{OP,20}, {rpbase_disps0,16}}}, \ | |
332 | /* opcNN iN (rp) disps16(RPBase) */ \ | |
333 | {NAME, 2, OPC1, 24, CSTBIT_INS, {{OP,20}, {rpbase_disps16,0}}}, \ | |
334 | /* opcNN iN (rp) disps20(RPBase) */ \ | |
335 | {NAME, 3, OPC2+1, 12, CSTBIT_INS, {{OP,4}, {rpbase_disps20,16}}}, \ | |
336 | /* opcNN iN rrp (Rindex)disps20(RPbase) */ \ | |
337 | {NAME, 3, OPC2+2, 12, CSTBIT_INS, {{OP,4}, {rpindex_disps20,16}}} | |
338 | ||
339 | CSTBIT_INST_W ("cbitw", uimm4, 0x69, 0x00114, 0x36, 0x1AB), | |
340 | CSTBIT_INST_W ("sbitw", uimm4, 0x71, 0x00118, 0x3A, 0x1CB), | |
341 | CSTBIT_INST_W ("tbitw", uimm4, 0x79, 0x0011C, 0x3E, 0x1EB), | |
342 | ||
343 | /* tbit cnt */ | |
344 | {"tbit", 1, 0x06, 24, CSTBIT_INS, {{uimm4,20}, {regr,16}}}, | |
345 | /* tbit reg reg */ | |
346 | {"tbit", 1, 0x07, 24, CSTBIT_INS, {{regr,20}, {regr,16}}}, | |
347 | ||
348 | ||
349 | /* Load instructions (from memory to register). */ | |
350 | #define LD_REG_INST(NAME, OPC1, OPC2, OPC3, OPC4, OPC5, OP_S, OP_D) \ | |
351 | /* opc8 reg abs20 */ \ | |
352 | {NAME, 2, OPC3, 24, LD_STOR_INS, {{abs20,0}, {OP_D,20}}}, \ | |
353 | /* opc20 reg abs24 */ \ | |
354 | {NAME, 3, OPC1+3, 12, LD_STOR_INS, {{abs24,16}, {OP_D,4}}}, \ | |
355 | /* opc7 reg rindex8_abs20 */ \ | |
356 | {NAME, 2, OPC5, 25, LD_STOR_INS, {{rindex8_abs20,0}, {OP_D,20}}}, \ | |
357 | /* opc4 reg disps4(RPbase) */ \ | |
358 | {NAME, 1, (OPC2>>4), 28, LD_STOR_INS, {{OP_S,24}, {OP_D,20}}}, \ | |
359 | /* opcNN reg disps0(RPbase) */ \ | |
360 | {NAME, 1, OPC2, 24, LD_STOR_INS, {{rpindex_disps0,0}, {OP_D,20}}}, \ | |
361 | /* opc reg disps14(RPbase) */ \ | |
362 | {NAME, 2, OPC4, 22, LD_STOR_INS, {{rpindex_disps14,0}, {OP_D,20}}}, \ | |
363 | /* opc reg -disps20(Rbase) */ \ | |
364 | {NAME, 3, OPC1+0x60, 12, LD_STOR_INS, {{rbase_dispe20,16}, {OP_D,4}}}, \ | |
365 | /* opc reg disps20(Rbase) */ \ | |
366 | {NAME, 3, OPC1, 12, LD_STOR_INS, {{rbase_disps20,16}, {OP_D,4}}}, \ | |
367 | /* opc reg (rp) disps16(RPbase) */ \ | |
368 | {NAME, 2, OPC2+1, 24, LD_STOR_INS, {{rpbase_disps16,0}, {OP_D,20}}}, \ | |
369 | /* opc16 reg (rp) disps20(RPbase) */ \ | |
370 | {NAME, 3, OPC1+1, 12, LD_STOR_INS, {{rpbase_disps20,16}, {OP_D,4}}}, \ | |
371 | /* op reg (rp) -disps20(RPbase) */ \ | |
372 | {NAME, 3, OPC1+0x61, 12, LD_STOR_INS, {{rpbase_dispe20,16}, {OP_D,4}}}, \ | |
373 | /* opc reg rrp (Rindex)disps20(RPbase) */ \ | |
374 | {NAME, 3, (OPC1+2), 12, LD_STOR_INS, {{rpindex_disps20,16}, {OP_D,4}}} | |
375 | ||
376 | LD_REG_INST ("loadb", 0x00124, 0xBE, 0x88, 0x219, 0x45, rpbase_disps4, regr), | |
377 | LD_REG_INST ("loadd", 0x00128, 0xAE, 0x87, 0x21A, 0x46, rpbase_dispe4, regp), | |
378 | LD_REG_INST ("loadw", 0x0012C, 0x9E, 0x89, 0x21B, 0x47, rpbase_dispe4, regr), | |
379 | ||
380 | /* Store instructions (from reg to memory). */ | |
381 | #define ST_REG_INST(NAME, OPC1, OPC2, OPC3, OPC4, OPC5, OP_D, OP_S) \ | |
382 | /* opc8 reg abs20 */ \ | |
383 | {NAME, 2, OPC3, 24, LD_STOR_INS, {{OP_S,20}, {abs20,0}}}, \ | |
384 | /* opc20 reg abs24 */ \ | |
385 | {NAME, 3, OPC1+3, 12, LD_STOR_INS, {{OP_S,4}, {abs24,16}}}, \ | |
386 | /* opc7 reg rindex8_abs20 */ \ | |
387 | {NAME, 2, OPC5, 25, LD_STOR_INS, {{OP_S,20}, {rindex8_abs20,0}}}, \ | |
388 | /* opc4 reg disps4(RPbase) */ \ | |
389 | {NAME, 1, (OPC2>>4), 28, LD_STOR_INS, {{OP_S,20}, {OP_D,24}}}, \ | |
390 | /* opcNN reg disps0(RPbase) */ \ | |
391 | {NAME, 1, OPC2, 24, LD_STOR_INS, {{OP_S,20}, {rpindex_disps0,0}}}, \ | |
392 | /* opc reg disps14(RPbase) */ \ | |
393 | {NAME, 2, OPC4, 22, LD_STOR_INS, {{OP_S,20}, {rpindex_disps14,0}}}, \ | |
394 | /* opc reg -disps20(Rbase) */ \ | |
395 | {NAME, 3, OPC1+0x60, 12, LD_STOR_INS, {{OP_S,4}, {rbase_dispe20,16}}}, \ | |
396 | /* opc reg disps20(Rbase) */ \ | |
397 | {NAME, 3, OPC1, 12, LD_STOR_INS, {{OP_S,4}, {rbase_disps20,16}}}, \ | |
398 | /* opc reg disps16(RPbase) */ \ | |
399 | {NAME, 2, OPC2+1, 24, LD_STOR_INS, {{OP_S,20}, {rpbase_disps16,0}}}, \ | |
400 | /* opc16 reg disps20(RPbase) */ \ | |
401 | {NAME, 3, OPC1+1, 12, LD_STOR_INS, {{OP_S,4}, {rpbase_disps20,16}}}, \ | |
402 | /* op reg (rp) -disps20(RPbase) */ \ | |
403 | {NAME, 3, OPC1+0x61, 12, LD_STOR_INS, {{OP_S,4}, {rpbase_dispe20,16}}}, \ | |
404 | /* opc reg rrp (Rindex)disps20(RPbase) */ \ | |
405 | {NAME, 3, OPC1+2, 12, LD_STOR_INS, {{OP_S,4}, {rpindex_disps20,16}}} | |
406 | ||
407 | ||
408 | /* Store instructions (from imm to memory). */ | |
409 | #define ST_IMM_INST(NAME, OPC1, OPC2, OPC3, OPC4) \ | |
410 | /* opcNN iN abs20 */ \ | |
411 | {NAME, 2, OPC1, 24, LD_STOR_INS, {{uimm4,20},{abs20,0}}}, \ | |
412 | /* opcNN iN abs24 */ \ | |
413 | {NAME, 3, OPC2+3, 12, LD_STOR_INS, {{uimm4,4},{abs24,16}}}, \ | |
414 | /* opcNN iN (Rindex)abs20 */ \ | |
415 | {NAME, 2, OPC3, 25, LD_STOR_INS, {{uimm4,20}, {rindex8_abs20,0}}}, \ | |
416 | /* opcNN iN (prp) disps14(RPbase) */ \ | |
417 | {NAME, 2, OPC4, 22, LD_STOR_INS, {{uimm4,4},{rpindex_disps14,0}}}, \ | |
418 | /* opcNN iN (rp) disps0(RPbase) */ \ | |
419 | {NAME, 1, OPC1+1, 24, LD_STOR_INS, {{uimm4,20}, {rpbase_disps0,16}}}, \ | |
420 | /* opcNN iN disps20(Rbase) */ \ | |
421 | {NAME, 3, OPC2, 12, LD_STOR_INS, {{uimm4,4}, {rbase_disps20,16}}}, \ | |
422 | /* opcNN iN (rp) disps16(RPBase) */ \ | |
423 | {NAME, 2, OPC1+2, 24, LD_STOR_INS, {{uimm4,20}, {rpbase_disps16,0}}}, \ | |
424 | /* opcNN iN (rp) disps20(RPBase) */ \ | |
425 | {NAME, 3, OPC2+1, 12, LD_STOR_INS, {{uimm4,4}, {rpbase_disps20,16}}}, \ | |
426 | /* opcNN iN rrp (Rindex)disps20(RPbase) */ \ | |
427 | {NAME, 3, OPC2+2, 12, LD_STOR_INS, {{uimm4,4}, {rpindex_disps20,16}}} | |
428 | ||
429 | ST_REG_INST ("storb", 0x00134, 0xFE, 0xC8, 0x319, 0x65, rpbase_disps4, regr), | |
430 | ST_IMM_INST ("storb", 0x81, 0x00120, 0x42, 0x218), | |
431 | ST_REG_INST ("stord", 0x00138, 0xEE, 0xC7, 0x31A, 0x66, rpbase_dispe4, regp), | |
432 | ST_REG_INST ("storw", 0x0013C, 0xDE, 0xC9, 0x31B, 0x67, rpbase_dispe4, regr), | |
433 | ST_IMM_INST ("storw", 0xC1, 0x00130, 0x62, 0x318), | |
434 | ||
435 | /* Create instruction with no operands. */ | |
436 | #define NO_OP_INST(NAME, OPC) \ | |
437 | /* opc16 */ \ | |
438 | {NAME, 1, OPC, 16, 0, {{0, 0}}} | |
439 | ||
440 | NO_OP_INST ("cinv[i]", 0x000A), | |
441 | NO_OP_INST ("cinv[i,u]", 0x000B), | |
442 | NO_OP_INST ("cinv[d]", 0x000C), | |
443 | NO_OP_INST ("cinv[d,u]", 0x000D), | |
444 | NO_OP_INST ("cinv[d,i]", 0x000E), | |
445 | NO_OP_INST ("cinv[d,i,u]", 0x000F), | |
446 | NO_OP_INST ("nop", 0x2C00), | |
447 | NO_OP_INST ("retx", 0x0003), | |
448 | NO_OP_INST ("di", 0x0004), | |
449 | NO_OP_INST ("ei", 0x0005), | |
450 | NO_OP_INST ("wait", 0x0006), | |
451 | NO_OP_INST ("eiwait", 0x0007), | |
452 | ||
453 | {NULL, 0, 0, 0, 0, {{0, 0}}} | |
454 | }; | |
455 | ||
456 | const unsigned int cr16_num_opcodes = ARRAY_SIZE (cr16_instruction); | |
457 | ||
458 | /* Macro to build a reg_entry, which have an opcode image : | |
459 | For example : | |
460 | REG(u4, 0x84, CR16_U_REGTYPE) | |
461 | is interpreted as : | |
2b4e983c RM |
462 | {"u4", u4, 0x84, CR16_U_REGTYPE} |
463 | The union initializer (second member) always refers to the first | |
464 | member of the union, so cast NAME to that type to avoid possible | |
465 | compiler warnings when used for CR16_P_REGTYPE cases. */ | |
466 | #define REG(NAME, N, TYPE) {STRINGX(NAME), {(reg) NAME}, N, TYPE} | |
3d3d428f NC |
467 | |
468 | #define REGP(NAME, BNAME, N, TYPE) {STRINGX(NAME), {BNAME}, N, TYPE} | |
469 | ||
470 | const reg_entry cr16_regtab[] = | |
471 | { /* Build a general purpose register r<N>. */ | |
472 | #define REG_R(N) REG(CONCAT2(r,N), N, CR16_R_REGTYPE) | |
473 | ||
474 | REG_R(0), REG_R(1), REG_R(2), REG_R(3), | |
475 | REG_R(4), REG_R(5), REG_R(6), REG_R(7), | |
476 | REG_R(8), REG_R(9), REG_R(10), REG_R(11), | |
477 | REG_R(12), REG_R(13), REG_R(14), REG_R(15), | |
478 | REG(r12_L, 12, CR16_R_REGTYPE), | |
479 | REG(r13_L, 13, CR16_R_REGTYPE), | |
480 | REG(ra, 0xe, CR16_R_REGTYPE), | |
481 | REG(sp, 0xf, CR16_R_REGTYPE), | |
482 | REG(sp_L, 0xf, CR16_R_REGTYPE), | |
483 | REG(RA, 0xe, CR16_R_REGTYPE), | |
484 | }; | |
485 | ||
486 | const reg_entry cr16_regptab[] = | |
487 | { /* Build a general purpose register r<N>. */ | |
488 | ||
489 | #define REG_RP(M,N) REGP((CONCAT2(r,M),CONCAT2(r,N)), CONCAT2(r,N), N, CR16_RP_REGTYPE) | |
490 | ||
491 | REG_RP(1,0), REG_RP(2,1), REG_RP(3,2), REG_RP(4,3), | |
492 | REG_RP(5,4), REG_RP(6,5), REG_RP(7,6), REG_RP(8,7), | |
493 | REG_RP(9,8), REG_RP(10,9), REG_RP(11,10), REG_RP(12,11), | |
494 | REG((r12), 0xc, CR16_RP_REGTYPE), | |
495 | REG((r13), 0xd, CR16_RP_REGTYPE), | |
496 | //REG((r14), 0xe, CR16_RP_REGTYPE), | |
497 | REG((ra), 0xe, CR16_RP_REGTYPE), | |
498 | REG((sp), 0xf, CR16_RP_REGTYPE), | |
499 | }; | |
500 | ||
501 | ||
502 | const unsigned int cr16_num_regs = ARRAY_SIZE (cr16_regtab) ; | |
503 | const unsigned int cr16_num_regps = ARRAY_SIZE (cr16_regptab) ; | |
504 | ||
505 | const reg_entry cr16_pregtab[] = | |
506 | { | |
507 | /* Build a processor register. */ | |
508 | REG(dbs, 0x0, CR16_P_REGTYPE), | |
509 | REG(dsr, 0x1, CR16_P_REGTYPE), | |
510 | REG(dcrl, 0x2, CR16_P_REGTYPE), | |
511 | REG(dcrh, 0x3, CR16_P_REGTYPE), | |
512 | REG(car0l, 0x4, CR16_P_REGTYPE), | |
513 | REG(car0h, 0x5, CR16_P_REGTYPE), | |
514 | REG(car1l, 0x6, CR16_P_REGTYPE), | |
515 | REG(car1h, 0x7, CR16_P_REGTYPE), | |
516 | REG(cfg, 0x8, CR16_P_REGTYPE), | |
517 | REG(psr, 0x9, CR16_P_REGTYPE), | |
518 | REG(intbasel, 0xa, CR16_P_REGTYPE), | |
519 | REG(intbaseh, 0xb, CR16_P_REGTYPE), | |
520 | REG(ispl, 0xc, CR16_P_REGTYPE), | |
521 | REG(isph, 0xd, CR16_P_REGTYPE), | |
522 | REG(uspl, 0xe, CR16_P_REGTYPE), | |
523 | REG(usph, 0xf, CR16_P_REGTYPE), | |
524 | }; | |
525 | ||
526 | const reg_entry cr16_pregptab[] = | |
527 | { | |
528 | REG(dbs, 0, CR16_P_REGTYPE), | |
529 | REG(dsr, 1, CR16_P_REGTYPE), | |
530 | REG(dcr, 2, CR16_P_REGTYPE), | |
531 | REG(car0, 4, CR16_P_REGTYPE), | |
532 | REG(car1, 6, CR16_P_REGTYPE), | |
533 | REG(cfg, 8, CR16_P_REGTYPE), | |
534 | REG(psr, 9, CR16_P_REGTYPE), | |
535 | REG(intbase, 10, CR16_P_REGTYPE), | |
536 | REG(isp, 12, CR16_P_REGTYPE), | |
537 | REG(usp, 14, CR16_P_REGTYPE), | |
538 | }; | |
539 | ||
540 | const unsigned int cr16_num_pregs = ARRAY_SIZE (cr16_pregtab); | |
541 | const unsigned int cr16_num_pregps = ARRAY_SIZE (cr16_pregptab); | |
542 | ||
543 | const char *cr16_b_cond_tab[]= | |
544 | { | |
545 | "eq","ne","cs","cc","hi","ls","gt","le","fs","fc", | |
546 | "lo","hs","lt","ge","r", "???" | |
547 | }; | |
548 | ||
549 | const unsigned int cr16_num_cc = ARRAY_SIZE (cr16_b_cond_tab); | |
550 | ||
551 | /* CR16 operands table. */ | |
552 | const operand_entry cr16_optab[] = | |
553 | { | |
554 | /* Index 0 is dummy, so we can count the instruction's operands. */ | |
555 | {0, nullargs, 0}, /* dummy */ | |
556 | {3, arg_ic, OP_SIGNED}, /* imm3 */ | |
557 | {4, arg_ic, OP_SIGNED}, /* imm4 */ | |
558 | {5, arg_ic, OP_SIGNED}, /* imm5 */ | |
559 | {6, arg_ic, OP_SIGNED}, /* imm6 */ | |
560 | {16, arg_ic, OP_SIGNED}, /* imm16 */ | |
561 | {20, arg_ic, OP_SIGNED}, /* imm20 */ | |
562 | {32, arg_ic, OP_SIGNED}, /* imm32 */ | |
563 | {3, arg_ic, OP_UNSIGNED}, /* uimm3 */ | |
564 | {3, arg_ic, OP_UNSIGNED|OP_DEC}, /* uimm3_1 */ | |
565 | {4, arg_ic, OP_UNSIGNED}, /* uimm4 */ | |
566 | {4, arg_ic, OP_UNSIGNED|OP_ESC}, /* uimm4_1 */ | |
567 | {5, arg_ic, OP_UNSIGNED}, /* uimm5 */ | |
568 | {16, arg_ic, OP_UNSIGNED}, /* uimm16 */ | |
569 | {20, arg_ic, OP_UNSIGNED}, /* uimm20 */ | |
570 | {32, arg_ic, OP_UNSIGNED}, /* uimm32 */ | |
571 | {5, arg_c, OP_EVEN|OP_SHIFT_DEC|OP_SIGNED}, /* disps5 */ | |
572 | {16, arg_c, OP_EVEN|OP_UNSIGNED}, /* disps17 */ | |
573 | {24, arg_c, OP_EVEN|OP_UNSIGNED}, /* disps25 */ | |
574 | {8, arg_c, OP_EVEN|OP_UNSIGNED}, /* dispe9 */ | |
575 | {20, arg_c, OP_UNSIGNED|OP_ABS20}, /* abs20 */ | |
576 | {24, arg_c, OP_UNSIGNED|OP_ABS24}, /* abs24 */ | |
577 | {4, arg_rp, 0}, /* rra */ | |
578 | {4, arg_rbase, 0}, /* rbase */ | |
579 | {20, arg_cr, OP_UNSIGNED}, /* rbase_disps20 */ | |
580 | {21, arg_cr, OP_NEG}, /* rbase_dispe20 */ | |
581 | {0, arg_crp, 0}, /* rpbase_disps0 */ | |
582 | {4, arg_crp, OP_EVEN|OP_SHIFT|OP_UNSIGNED|OP_ESC1},/* rpbase_dispe4 */ | |
583 | {4, arg_crp, OP_UNSIGNED|OP_ESC1}, /* rpbase_disps4 */ | |
584 | {16, arg_crp, OP_UNSIGNED}, /* rpbase_disps16 */ | |
585 | {20, arg_crp, OP_UNSIGNED}, /* rpbase_disps20 */ | |
586 | {21, arg_crp, OP_NEG}, /* rpbase_dispe20 */ | |
587 | {20, arg_idxr, OP_UNSIGNED}, /* rindex7_abs20 */ | |
588 | {20, arg_idxr, OP_UNSIGNED}, /* rindex8_abs20 */ | |
589 | {0, arg_idxrp, OP_UNSIGNED}, /* rpindex_disps0 */ | |
590 | {14, arg_idxrp, OP_UNSIGNED}, /* rpindex_disps14 */ | |
591 | {20, arg_idxrp, OP_UNSIGNED}, /* rpindex_disps20 */ | |
592 | {4, arg_r, 0}, /* regr */ | |
593 | {4, arg_rp, 0}, /* reg pair */ | |
594 | {4, arg_pr, 0}, /* proc reg */ | |
595 | {4, arg_prp, 0}, /* 32 bit proc reg */ | |
596 | {4, arg_cc, OP_UNSIGNED} /* cc - code */ | |
597 | }; | |
598 | ||
796d5313 | 599 | const unsigned int cr16_num_optab = ARRAY_SIZE (cr16_optab); |
3d3d428f NC |
600 | |
601 | /* CR16 traps/interrupts. */ | |
602 | const trap_entry cr16_traps[] = | |
603 | { | |
604 | {"svc", 5}, {"dvz", 6}, {"flg", 7}, {"bpt", 8}, {"trc", 9}, | |
605 | {"und", 10}, {"iad", 12}, {"dbg",14}, {"ise",15} | |
606 | }; | |
607 | ||
608 | const unsigned int cr16_num_traps = ARRAY_SIZE (cr16_traps); | |
609 | ||
610 | /* CR16 instructions that don't have arguments. */ | |
611 | const char * cr16_no_op_insn[] = | |
612 | { | |
613 | "cinv[i]", "cinv[i,u]", "cinv[d]", "cinv[d,u]", "cinv[d,i]", "cinv[d,i,u]", | |
614 | "di", "ei", "eiwait", "nop", "retx", "wait", NULL | |
615 | }; |