1 // license:BSD-3-Clause
2 // copyright-holders:Ryan Holtz
3 /***************************************************************************
4 
5     e132xsfe.cpp
6 
7     Front end for Hyperstone recompiler
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "e132xsfe.h"
13 #include "32xsdefs.h"
14 
15 #define FE_FP ((m_cpu->m_core->global_regs[1] & 0xfe000000) >> 25)
16 #define FE_FL (m_cpu->m_core->fl_lut[((m_cpu->m_core->global_regs[1] >> 21) & 0xf)])
17 #define FE_DST_CODE ((op & 0xf0) >> 4)
18 #define FE_SRC_CODE (op & 0x0f)
19 #define SR_CODE     (1 << 1)
20 
21 /***************************************************************************
22     INSTRUCTION PARSERS
23 ***************************************************************************/
24 
e132xs_frontend(hyperstone_device * e132xs,uint32_t window_start,uint32_t window_end,uint32_t max_sequence)25 e132xs_frontend::e132xs_frontend(hyperstone_device *e132xs, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
26 	: drc_frontend(*e132xs, window_start, window_end, max_sequence)
27 	, m_cpu(e132xs)
28 {
29 }
30 
read_word(opcode_desc & desc)31 inline uint16_t e132xs_frontend::read_word(opcode_desc &desc)
32 {
33 	return m_cpu->m_pr16(desc.physpc);
34 }
35 
read_imm1(opcode_desc & desc)36 inline uint16_t e132xs_frontend::read_imm1(opcode_desc &desc)
37 {
38 	return m_cpu->m_pr16(desc.physpc + 2);
39 }
40 
read_imm2(opcode_desc & desc)41 inline uint16_t e132xs_frontend::read_imm2(opcode_desc &desc)
42 {
43 	return m_cpu->m_pr16(desc.physpc + 4);
44 }
45 
read_ldstxx_imm(opcode_desc & desc)46 inline uint32_t e132xs_frontend::read_ldstxx_imm(opcode_desc &desc)
47 {
48 	const uint16_t imm1 = read_imm1(desc);
49 	uint32_t extra_s;
50 	if (imm1 & 0x8000)
51 	{
52 		extra_s = read_imm2(desc);
53 		extra_s |= ((imm1 & 0xfff) << 16);
54 
55 		if (imm1 & 0x4000)
56 			extra_s |= 0xf0000000;
57 	}
58 	else
59 	{
60 		extra_s = imm1 & 0xfff;
61 
62 		if (imm1 & 0x4000)
63 			extra_s |= 0xfffff000;
64 	}
65 	return extra_s;
66 }
67 
read_limm(opcode_desc & desc,uint16_t op)68 inline uint32_t e132xs_frontend::read_limm(opcode_desc &desc, uint16_t op)
69 {
70 	static const int32_t immediate_values[16] =
71 	{
72 		16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000),
73 		-8, -7, -6, -5, -4, -3, -2, -1
74 	};
75 
76 	uint8_t nybble = op & 0xf;
77 	switch (nybble)
78 	{
79 		case 0:
80 			return 16;
81 		case 1:
82 			desc.length = 6;
83 			return (read_imm1(desc) << 16) | read_imm2(desc);
84 		case 2:
85 			desc.length = 4;
86 			return read_imm1(desc);
87 		case 3:
88 			desc.length = 4;
89 			return 0xffff0000 | read_imm1(desc);
90 		default:
91 			return immediate_values[nybble];
92 	}
93 }
94 
decode_pcrel(opcode_desc & desc,uint16_t op)95 inline int32_t e132xs_frontend::decode_pcrel(opcode_desc &desc, uint16_t op)
96 {
97 	if (op & 0x80)
98 	{
99 		uint16_t next = read_imm1(desc);
100 
101 		desc.length = 4;
102 
103 		int32_t offset = (op & 0x7f) << 16;
104 		offset |= (next & 0xfffe);
105 
106 		if (next & 1)
107 			offset |= 0xff800000;
108 
109 		return offset;
110 	}
111 	else
112 	{
113 		int32_t offset = op & 0x7e;
114 		if (op & 1)
115 			offset |= 0xffffff80;
116 		return offset;
117 	}
118 }
119 
decode_call(opcode_desc & desc)120 inline int32_t e132xs_frontend::decode_call(opcode_desc &desc)
121 {
122 	const uint16_t imm_1 = read_imm1(desc);
123 	int32_t extra_s = 0;
124 	if (imm_1 & 0x8000)
125 	{
126 		desc.length = 6;
127 		extra_s = read_imm2(desc);
128 		extra_s |= ((imm_1 & 0x3fff) << 16);
129 
130 		if (imm_1 & 0x4000)
131 			extra_s |= 0xc0000000;
132 	}
133 	else
134 	{
135 		desc.length = 4;
136 		extra_s = imm_1 & 0x3fff;
137 		if (imm_1 & 0x4000)
138 			extra_s |= 0xffffc000;
139 	}
140 	return extra_s;
141 }
142 
143 
144 /*-------------------------------------------------
145     describe - build a description of a single
146     instruction
147 -------------------------------------------------*/
148 
describe(opcode_desc & desc,const opcode_desc * prev)149 bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
150 {
151 	uint16_t op = desc.opptr.w[0] = read_word(desc);
152 
153 	/* most instructions are 2 bytes and a single cycle */
154 	desc.length = 2;
155 	desc.delayslots = 0;
156 
157 	const uint32_t fp = FE_FP;
158 	const uint32_t gdst_code = FE_DST_CODE;
159 	const uint32_t gdstf_code = gdst_code + 1;
160 	const uint32_t gsrc_code = FE_SRC_CODE;
161 	const uint32_t gsrcf_code = gsrc_code + 1;
162 	const uint32_t ldst_code = (gdst_code + fp) & 0x1f;
163 	const uint32_t ldstf_code = (gdstf_code + fp) & 0x1f;
164 	const uint32_t lsrc_code = (gsrc_code + fp) & 0x1f;
165 	const uint32_t lsrcf_code = (gsrcf_code + fp) & 0x1f;
166 	const uint32_t ldst_group = 1 + (((FE_DST_CODE + fp) & 0x20) >> 5);
167 	const uint32_t ldstf_group = 1 + (((FE_DST_CODE + fp + 1) & 0x20) >> 5);
168 	const uint32_t lsrc_group = 1 + (((FE_SRC_CODE + fp) & 0x20) >> 5);
169 	const uint32_t lsrcf_group = 1 + ((FE_SRC_CODE + fp + 1) >> 5);
170 
171 	switch (op >> 8)
172 	{
173 		case 0x00: // chk global,global
174 			desc.regin[0] |= 1 << gdst_code;
175 			desc.regin[0] |= 1 << gsrc_code;
176 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
177 			break;
178 		case 0x01: // chk global,local
179 			desc.regin[0] |= SR_CODE;
180 			desc.regin[0] |= 1 << gdst_code;
181 			desc.regin[lsrc_group] |= 1 << lsrc_code;
182 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
183 			break;
184 		case 0x02: // chk local,global
185 			desc.regin[0] |= SR_CODE;
186 			desc.regin[ldst_group] |= 1 << ldst_code;
187 			desc.regin[0] |= 1 << gsrc_code;
188 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
189 			break;
190 		case 0x03: // chk local,local
191 			desc.regin[0] |= SR_CODE;
192 			desc.regin[ldst_group] |= 1 << ldst_code;
193 			desc.regin[lsrc_group] |= 1 << lsrc_code;
194 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
195 			break;
196 		case 0x04: // movd global,global
197 			desc.regin[0] |= 1 << gsrc_code;
198 			desc.regin[0] |= 1 << gsrcf_code;
199 			desc.regout[0] |= 1 << gdst_code;
200 			desc.regout[0] |= 1 << gdstf_code;
201 			if (gdst_code == 0)
202 			{
203 				desc.regout[1] = 0xffffffff;
204 				desc.regout[2] = 0xffffffff;
205 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
206 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
207 			}
208 			desc.regout[0] |= SR_CODE;
209 			break;
210 		case 0x05: // movd global,local
211 			desc.regin[0] |= SR_CODE;
212 			desc.regin[lsrc_group] |= 1 << lsrc_code;
213 			desc.regin[lsrcf_group] |= 1 << lsrcf_code;
214 			desc.regout[0] |= 1 << gdst_code;
215 			desc.regout[0] |= 1 << gdstf_code;
216 			if (gdst_code == 0)
217 			{
218 				desc.regout[1] = 0xffffffff;
219 				desc.regout[2] = 0xffffffff;
220 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
221 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
222 			}
223 			desc.regout[0] |= SR_CODE;
224 			break;
225 		case 0x06: // movd local,global
226 			desc.regin[0] |= SR_CODE;
227 			desc.regin[0] |= 1 << gsrc_code;
228 			desc.regin[0] |= 1 << gsrcf_code;
229 			desc.regout[ldst_group] |= 1 << ldst_code;
230 			desc.regout[ldstf_group] |= 1 << ldstf_code;
231 			desc.regout[0] |= SR_CODE;
232 			break;
233 		case 0x07: // movd local,local
234 			desc.regin[0] |= SR_CODE;
235 			desc.regin[lsrc_group] |= 1 << lsrc_code;
236 			desc.regin[lsrcf_group] |= 1 << lsrcf_code;
237 			desc.regout[ldst_group] |= 1 << ldst_code;
238 			desc.regout[ldstf_group] |= 1 << ldstf_code;
239 			desc.regout[0] |= SR_CODE;
240 			break;
241 		case 0x08: // divu global,global
242 		case 0x0c: // divs global,global
243 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
244 			desc.regin[0] |= 1 << gsrc_code;
245 			desc.regin[0] |= 1 << gdst_code;
246 			desc.regin[0] |= 1 << gdstf_code;
247 			desc.regout[0] |= 1 << gdst_code;
248 			desc.regout[0] |= 1 << gdstf_code;
249 			desc.regout[0] |= SR_CODE;
250 			break;
251 		case 0x09: // divu global,local
252 		case 0x0d: // divs global,local
253 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
254 			desc.regin[0] |= SR_CODE;
255 			desc.regin[lsrc_group] |= 1 << lsrc_code;
256 			desc.regin[0] |= 1 << gdst_code;
257 			desc.regin[0] |= 1 << gdstf_code;
258 			desc.regout[0] |= 1 << gdst_code;
259 			desc.regout[0] |= 1 << gdstf_code;
260 			desc.regout[0] |= SR_CODE;
261 			break;
262 		case 0x0a: // divu local,global
263 		case 0x0e: // divs local,global
264 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
265 			desc.regin[0] |= SR_CODE;
266 			desc.regin[0] |= 1 << gsrc_code;
267 			desc.regin[ldst_group] |= 1 << ldst_code;
268 			desc.regin[ldstf_group] |= 1 << ldstf_code;
269 			desc.regout[ldst_group] |= 1 << ldst_code;
270 			desc.regout[ldstf_group] |= 1 << ldstf_code;
271 			desc.regout[0] |= SR_CODE;
272 			break;
273 		case 0x0b: // divu local,local
274 		case 0x0f: // divs local,local
275 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
276 			desc.regin[0] |= SR_CODE;
277 			desc.regin[lsrc_group] |= 1 << lsrc_code;
278 			desc.regin[ldst_group] |= 1 << ldst_code;
279 			desc.regin[ldstf_group] |= 1 << ldstf_code;
280 			desc.regout[ldst_group] |= 1 << ldst_code;
281 			desc.regout[ldstf_group] |= 1 << ldstf_code;
282 			desc.regout[0] |= SR_CODE;
283 			break;
284 		case 0x10: // xm global,global
285 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
286 			desc.regin[0] |= 1 << gsrc_code;
287 			desc.regout[0] |= 1 << gdst_code;
288 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
289 			break;
290 		case 0x11: // xm global,local
291 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
292 			desc.regin[0] |= SR_CODE;
293 			desc.regin[lsrc_group] |= 1 << lsrc_code;
294 			desc.regout[0] |= 1 << gdst_code;
295 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
296 			break;
297 		case 0x12: // xm local,global
298 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
299 			desc.regin[0] |= SR_CODE;
300 			desc.regin[0] |= 1 << gsrc_code;
301 			desc.regout[ldst_group] |= 1 << ldst_code;
302 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
303 			break;
304 		case 0x13: // xm local,local
305 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
306 			desc.regin[0] |= SR_CODE;
307 			desc.regin[lsrc_group] |= 1 << lsrc_code;
308 			desc.regout[ldst_group] |= 1 << ldst_code;
309 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
310 			break;
311 		case 0x14: // mask global,global
312 			desc.regin[0] |= 1 << gsrc_code;
313 			desc.regout[0] |= 1 << gdst_code;
314 			desc.regout[0] |= SR_CODE;
315 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
316 			break;
317 		case 0x15: // mask global,local
318 			desc.regin[0] |= SR_CODE;
319 			desc.regin[lsrc_group] |= 1 << lsrc_code;
320 			desc.regout[0] |= 1 << gdst_code;
321 			desc.regout[0] |= SR_CODE;
322 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
323 			break;
324 		case 0x16: // mask local,global
325 			desc.regin[0] |= SR_CODE;
326 			desc.regin[0] |= 1 << gsrc_code;
327 			desc.regout[ldst_group] |= 1 << ldst_code;
328 			desc.regout[0] |= SR_CODE;
329 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
330 			break;
331 		case 0x17: // mask local,local
332 			desc.regin[0] |= SR_CODE;
333 			desc.regin[lsrc_group] |= 1 << lsrc_code;
334 			desc.regout[ldst_group] |= 1 << ldst_code;
335 			desc.regout[0] |= SR_CODE;
336 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
337 			break;
338 		case 0x18: // sum global,global
339 		case 0x1c: // sums global,global
340 			desc.regin[0] |= 1 << gsrc_code;
341 			desc.regout[0] |= 1 << gdst_code;
342 			desc.regout[0] |= SR_CODE;
343 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
344 			if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
345 			break;
346 		case 0x19: // sum global,local
347 		case 0x1d: // sums global,local
348 			desc.regin[0] |= SR_CODE;
349 			desc.regin[lsrc_group] |= 1 << lsrc_code;
350 			desc.regout[0] |= 1 << gdst_code;
351 			desc.regout[0] |= SR_CODE;
352 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
353 			if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
354 			break;
355 		case 0x1a: // sum local,global
356 		case 0x1e: // sums local,global
357 			desc.regin[0] |= SR_CODE;
358 			desc.regin[0] |= 1 << gsrc_code;
359 			desc.regout[ldst_group] |= 1 << ldst_code;
360 			desc.regout[0] |= SR_CODE;
361 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
362 			if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
363 			break;
364 		case 0x1b: // sum local,local
365 		case 0x1f: // sums local,local
366 			desc.regin[0] |= SR_CODE;
367 			desc.regin[lsrc_group] |= 1 << lsrc_code;
368 			desc.regout[ldst_group] |= 1 << ldst_code;
369 			desc.regout[0] |= SR_CODE;
370 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
371 			if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
372 			break;
373 		case 0x20: // cmp global,global
374 		case 0x30: // cmpb global,global
375 			desc.regin[0] |= 1 << gsrc_code;
376 			desc.regin[0] |= 1 << gdst_code;
377 			desc.regout[0] |= SR_CODE;
378 			break;
379 		case 0x21: // cmp global,local
380 		case 0x31: // cmpb global,local
381 			desc.regin[0] |= SR_CODE;
382 			desc.regin[lsrc_group] |= 1 << lsrc_code;
383 			desc.regin[0] |= 1 << gdst_code;
384 			desc.regout[0] |= SR_CODE;
385 			break;
386 		case 0x22: // cmp local,global
387 		case 0x32: // cmpb local,global
388 			desc.regin[0] |= SR_CODE;
389 			desc.regin[0] |= 1 << gsrc_code;
390 			desc.regin[ldst_group] |= 1 << ldst_code;
391 			desc.regout[0] |= SR_CODE;
392 			break;
393 		case 0x23: // cmp local,local
394 		case 0x33: // cmpb local,local
395 			desc.regin[0] |= SR_CODE;
396 			desc.regin[lsrc_group] |= 1 << lsrc_code;
397 			desc.regin[ldst_group] |= 1 << ldst_code;
398 			desc.regout[0] |= SR_CODE;
399 			break;
400 		case 0x24: // mov global,global
401 			desc.regin[0] |= SR_CODE;
402 			desc.regin[0] |= 1 << gsrc_code;
403 			desc.regin[0] |= 1 << (gsrc_code + 16);
404 			desc.regout[0] |= 1 << gdst_code;
405 			desc.regout[0] |= SR_CODE;
406 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
407 			if (gdst_code == PC_REGISTER)
408 			{
409 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
410 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
411 			}
412 			else if (gdst_code == 5) // TPR_REGISTER & 0xf
413 			{
414 				desc.flags |= OPFLAG_END_SEQUENCE;
415 			}
416 			break;
417 		case 0x25: // mov global,local
418 			desc.regin[0] |= SR_CODE;
419 			desc.regin[lsrc_group] |= 1 << lsrc_code;
420 			desc.regout[0] |= 1 << gdst_code;
421 			desc.regout[0] |= SR_CODE;
422 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
423 			if (gdst_code == PC_REGISTER)
424 			{
425 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
426 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
427 			}
428 			else if (gdst_code == 5) // TPR_REGISTER & 0xf
429 			{
430 				desc.flags |= OPFLAG_END_SEQUENCE;
431 			}
432 			break;
433 		case 0x26: // mov local,global
434 			desc.regin[0] |= SR_CODE;
435 			desc.regin[0] |= 1 << gsrc_code;
436 			desc.regin[0] |= 1 << (gsrc_code + 16);
437 			desc.regout[ldst_group] |= 1 << ldst_code;
438 			desc.regout[0] |= SR_CODE;
439 			break;
440 		case 0x27: // mov local,local
441 			desc.regin[0] |= SR_CODE;
442 			desc.regin[lsrc_group] |= 1 << lsrc_code;
443 			desc.regout[ldst_group] |= 1 << ldst_code;
444 			desc.regout[0] |= SR_CODE;
445 			break;
446 		case 0x28: // add global,global
447 		case 0x2c: // adds global,global
448 		case 0x48: // sub global,global
449 		case 0x4c: // subs global,global
450 			desc.regin[0] |= 1 << gsrc_code;
451 			desc.regin[0] |= 1 << gdst_code;
452 			desc.regout[0] |= 1 << gdst_code;
453 			desc.regout[0] |= SR_CODE;
454 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
455 			if (gdst_code == PC_REGISTER)
456 			{
457 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
458 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
459 			}
460 			break;
461 		case 0x29: // add global,local
462 		case 0x2d: // adds global,local
463 		case 0x49: // sub global,local
464 		case 0x4d: // subs global,local
465 			desc.regin[0] |= SR_CODE;
466 			desc.regin[lsrc_group] |= 1 << lsrc_code;
467 			desc.regin[0] |= 1 << gdst_code;
468 			desc.regout[0] |= 1 << gdst_code;
469 			desc.regout[0] |= SR_CODE;
470 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
471 			if (gdst_code == PC_REGISTER)
472 			{
473 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
474 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
475 			}
476 			break;
477 		case 0x2a: // add local,global
478 		case 0x2e: // adds local,global
479 		case 0x4a: // sub local,global
480 		case 0x4e: // subs local,global
481 			desc.regin[0] |= SR_CODE;
482 			desc.regin[0] |= 1 << gsrc_code;
483 			desc.regin[ldst_group] |= 1 << ldst_code;
484 			desc.regout[ldst_group] |= 1 << ldst_code;
485 			desc.regout[0] |= SR_CODE;
486 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
487 			break;
488 		case 0x2b: // add local,local
489 		case 0x2f: // adds local,local
490 		case 0x4b: // sub local,local
491 		case 0x4f: // subs local,local
492 			desc.regin[0] |= SR_CODE;
493 			desc.regin[lsrc_group] |= 1 << lsrc_code;
494 			desc.regin[ldst_group] |= 1 << ldst_code;
495 			desc.regout[ldst_group] |= 1 << ldst_code;
496 			desc.regout[0] |= SR_CODE;
497 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
498 			break;
499 		case 0x34: // andn global,global
500 		case 0x38: // or global,global
501 		case 0x3c: // xor global,global
502 		case 0x54: // and global,global
503 			desc.regin[0] |= 1 << gsrc_code;
504 			desc.regin[0] |= 1 << gdst_code;
505 			desc.regout[0] |= 1 << gdst_code;
506 			desc.regout[0] |= SR_CODE;
507 			if (gdst_code == PC_REGISTER)
508 			{
509 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
510 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
511 			}
512 			break;
513 		case 0x35: // andn global,local
514 		case 0x39: // or global,local
515 		case 0x3d: // xor global,local
516 		case 0x55: // and global,local
517 			desc.regin[0] |= SR_CODE;
518 			desc.regin[lsrc_group] |= 1 << lsrc_code;
519 			desc.regin[0] |= 1 << gdst_code;
520 			desc.regout[0] |= 1 << gdst_code;
521 			desc.regout[0] |= SR_CODE;
522 			if (gdst_code == PC_REGISTER)
523 			{
524 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
525 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
526 			}
527 			break;
528 		case 0x36: // andn local,global
529 		case 0x3a: // or local,global
530 		case 0x3e: // xor local,global
531 		case 0x56: // and local,global
532 			desc.regin[0] |= SR_CODE;
533 			desc.regin[0] |= 1 << gsrc_code;
534 			desc.regin[ldst_group] |= 1 << ldst_code;
535 			desc.regout[ldst_group] |= 1 << ldst_code;
536 			desc.regout[0] |= SR_CODE;
537 			break;
538 		case 0x37: // andn local,local
539 		case 0x3b: // or local,local
540 		case 0x3f: // xor local,local
541 		case 0x57: // and local,local
542 			desc.regin[0] |= SR_CODE;
543 			desc.regin[lsrc_group] |= 1 << lsrc_code;
544 			desc.regin[ldst_group] |= 1 << ldst_code;
545 			desc.regout[ldst_group] |= 1 << ldst_code;
546 			desc.regout[0] |= SR_CODE;
547 			break;
548 		case 0x40: // subc global,global
549 		case 0x50: // addc global,global
550 			desc.regin[0] |= SR_CODE;
551 			desc.regin[0] |= 1 << gsrc_code;
552 			desc.regin[0] |= 1 << gdst_code;
553 			desc.regout[0] |= 1 << gdst_code;
554 			desc.regout[0] |= SR_CODE;
555 			if (gdst_code == PC_REGISTER)
556 			{
557 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
558 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
559 			}
560 			break;
561 		case 0x41: // subc global,local
562 		case 0x51: // addc global,local
563 			desc.regin[0] |= SR_CODE;
564 			desc.regin[lsrc_group] |= 1 << lsrc_code;
565 			desc.regin[0] |= 1 << gdst_code;
566 			desc.regout[0] |= 1 << gdst_code;
567 			desc.regout[0] |= SR_CODE;
568 			if (gdst_code == PC_REGISTER)
569 			{
570 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
571 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
572 			}
573 			break;
574 		case 0x42: // subc local,global
575 		case 0x52: // addc local,global
576 			desc.regin[0] |= SR_CODE;
577 			desc.regin[0] |= 1 << gsrc_code;
578 			desc.regin[ldst_group] |= 1 << ldst_code;
579 			desc.regout[ldst_group] |= 1 << ldst_code;
580 			desc.regout[0] |= SR_CODE;
581 			break;
582 		case 0x43: // subc local,local
583 		case 0x53: // addc local,local
584 			desc.regin[0] |= SR_CODE;
585 			desc.regin[lsrc_group] |= 1 << lsrc_code;
586 			desc.regin[ldst_group] |= 1 << ldst_code;
587 			desc.regout[ldst_group] |= 1 << ldst_code;
588 			desc.regout[0] |= SR_CODE;
589 			break;
590 		case 0x44: // not global,global
591 		case 0x58: // neg global,global
592 			desc.regin[0] |= 1 << gsrc_code;
593 			desc.regout[0] |= 1 << gdst_code;
594 			desc.regout[0] |= SR_CODE;
595 			if (gdst_code == PC_REGISTER)
596 			{
597 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
598 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
599 			}
600 			break;
601 		case 0x45: // not global,local
602 		case 0x59: // neg global,local
603 			desc.regin[0] |= SR_CODE;
604 			desc.regin[lsrc_group] |= 1 << lsrc_code;
605 			desc.regout[0] |= 1 << gdst_code;
606 			desc.regout[0] |= SR_CODE;
607 			if (gdst_code == PC_REGISTER)
608 			{
609 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
610 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
611 			}
612 			break;
613 		case 0x46: // not local,global
614 		case 0x5a: // neg local,global
615 			desc.regin[0] |= SR_CODE;
616 			desc.regin[0] |= 1 << gsrc_code;
617 			desc.regout[ldst_group] |= 1 << ldst_code;
618 			desc.regout[0] |= SR_CODE;
619 			break;
620 		case 0x47: // not local,local
621 		case 0x5b: // neg local,local
622 			desc.regin[0] |= SR_CODE;
623 			desc.regin[lsrc_group] |= 1 << lsrc_code;
624 			desc.regout[ldst_group] |= 1 << ldst_code;
625 			desc.regout[0] |= SR_CODE;
626 			break;
627 		case 0x5c: // negs global,global
628 			desc.regin[0] |= 1 << gsrc_code;
629 			desc.regout[0] |= 1 << gdst_code;
630 			desc.regout[0] |= SR_CODE;
631 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
632 			if (gdst_code == PC_REGISTER)
633 			{
634 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
635 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
636 			}
637 			break;
638 		case 0x5d: // negs global,local
639 			desc.regin[0] |= SR_CODE;
640 			desc.regin[lsrc_group] |= 1 << lsrc_code;
641 			desc.regout[0] |= 1 << gdst_code;
642 			desc.regout[0] |= SR_CODE;
643 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
644 			if (gdst_code == PC_REGISTER)
645 			{
646 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
647 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
648 			}
649 			break;
650 		case 0x5e: // negs local,global
651 			desc.regin[0] |= SR_CODE;
652 			desc.regin[0] |= 1 << gsrc_code;
653 			desc.regout[ldst_group] |= 1 << ldst_code;
654 			desc.regout[0] |= SR_CODE;
655 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
656 			break;
657 		case 0x5f: // negs local,local
658 			desc.regin[0] |= SR_CODE;
659 			desc.regin[lsrc_group] |= 1 << lsrc_code;
660 			desc.regout[ldst_group] |= 1 << ldst_code;
661 			desc.regout[0] |= SR_CODE;
662 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
663 			break;
664 		case 0x60: // cmpi global,simm
665 		case 0x70: // cmpbi global,simm
666 			desc.regout[0] |= 1 << gdst_code;
667 			desc.regout[0] |= SR_CODE;
668 			break;
669 		case 0x61: // cmpi global,limm
670 		case 0x71: // cmpbi global,limm
671 			desc.regout[0] |= 1 << gdst_code;
672 			desc.regout[0] |= SR_CODE;
673 			desc.length = hyperstone_device::imm_length(op) << 1;
674 			break;
675 		case 0x62: // cmpi local,simm
676 		case 0x72: // cmpbi local,simm
677 			desc.regin[0] |= SR_CODE;
678 			desc.regout[ldst_group] |= 1 << ldst_code;
679 			desc.regout[0] |= SR_CODE;
680 			break;
681 		case 0x63: // cmpi local,limm
682 		case 0x73: // cmpbi local,limm
683 			desc.regin[0] |= SR_CODE;
684 			desc.regout[ldst_group] |= 1 << ldst_code;
685 			desc.regout[0] |= SR_CODE;
686 			desc.length = hyperstone_device::imm_length(op) << 1;
687 			break;
688 		case 0x64: // movi global,simm
689 			desc.regin[0] |= SR_CODE;
690 			desc.regout[0] |= 1 << gdst_code;
691 			desc.regout[0] |= 1 << (gdst_code + 16);
692 			desc.regout[0] |= SR_CODE;
693 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
694 			if (gdst_code == PC_REGISTER)
695 			{
696 				desc.targetpc = op & 0xf;
697 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
698 			}
699 			else if (gdst_code == 5) // TPR_REGISTER & 0xf
700 			{
701 				desc.flags |= OPFLAG_END_SEQUENCE;
702 			}
703 			break;
704 		case 0x65: // movi global,limm
705 			desc.regin[0] |= SR_CODE;
706 			desc.regout[0] |= 1 << gdst_code;
707 			desc.regout[0] |= 1 << (gdst_code + 16);
708 			desc.regout[0] |= SR_CODE;
709 			desc.length = hyperstone_device::imm_length(op) << 1;
710 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
711 			if (gdst_code == PC_REGISTER)
712 			{
713 				desc.targetpc = read_limm(desc, op);
714 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
715 			}
716 			else if (gdst_code == 5) // TPR_REGISTER & 0xf
717 			{
718 				desc.flags |= OPFLAG_END_SEQUENCE;
719 			}
720 			break;
721 		case 0x66: // movi local,simm
722 			desc.regin[0] |= SR_CODE;
723 			desc.regout[ldst_group] |= 1 << ldst_code;
724 			desc.regout[0] |= SR_CODE;
725 			break;
726 		case 0x67: // movi local,limm
727 			desc.regin[0] |= SR_CODE;
728 			desc.regout[ldst_group] |= 1 << ldst_code;
729 			desc.regout[0] |= SR_CODE;
730 			desc.length = hyperstone_device::imm_length(op) << 1;
731 			break;
732 		case 0x68: // addi global,simm
733 		case 0x6c: // addsi global,simm
734 			desc.regin[0] |= SR_CODE;
735 			desc.regin[0] |= 1 << gdst_code;
736 			desc.regout[0] |= 1 << gdst_code;
737 			desc.regout[0] |= SR_CODE;
738 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
739 			if (gdst_code == PC_REGISTER)
740 			{
741 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
742 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
743 			}
744 			break;
745 		case 0x69: // addi global,limm
746 		case 0x6d: // addsi global,limm
747 			desc.regin[0] |= SR_CODE;
748 			desc.regin[0] |= 1 << gdst_code;
749 			desc.regout[0] |= 1 << gdst_code;
750 			desc.regout[0] |= SR_CODE;
751 			desc.length = hyperstone_device::imm_length(op) << 1;
752 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
753 			if (gdst_code == PC_REGISTER)
754 			{
755 				desc.targetpc = desc.pc + desc.length + read_limm(desc, op);
756 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
757 			}
758 			break;
759 		case 0x6a: // addi local,simm
760 		case 0x6e: // addsi local,simm
761 			desc.regin[0] |= SR_CODE;
762 			desc.regin[ldst_group] |= 1 << ldst_code;
763 			desc.regout[ldst_group] |= 1 << ldst_code;
764 			desc.regout[0] |= SR_CODE;
765 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
766 			break;
767 		case 0x6b: // addi local,limm
768 		case 0x6f: // addsi local,limm
769 			desc.regin[0] |= SR_CODE;
770 			desc.regin[ldst_group] |= 1 << ldst_code;
771 			desc.regout[ldst_group] |= 1 << ldst_code;
772 			desc.regout[0] |= SR_CODE;
773 			desc.length = hyperstone_device::imm_length(op) << 1;
774 			if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
775 			break;
776 		case 0x74: // andni global,simm
777 		case 0x78: // ori global,simm
778 		case 0x7c: // xori global,simm
779 			desc.regin[0] |= SR_CODE;
780 			desc.regin[0] |= 1 << gdst_code;
781 			desc.regout[0] |= 1 << gdst_code;
782 			desc.regout[0] |= SR_CODE;
783 			if (gdst_code == PC_REGISTER)
784 			{
785 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
786 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
787 			}
788 			break;
789 		case 0x75: // andni global,limm
790 		case 0x79: // ori global,limm
791 		case 0x7d: // xori global,limm
792 			desc.regin[0] |= SR_CODE;
793 			desc.regin[0] |= 1 << gdst_code;
794 			desc.regout[0] |= 1 << gdst_code;
795 			desc.regout[0] |= SR_CODE;
796 			desc.length = hyperstone_device::imm_length(op) << 1;
797 			if (gdst_code == PC_REGISTER)
798 			{
799 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
800 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
801 			}
802 			break;
803 		case 0x76: // andni local,simm
804 		case 0x7a: // ori local,simm
805 		case 0x7e: // xori local,simm
806 			desc.regin[0] |= SR_CODE;
807 			desc.regin[ldst_group] |= 1 << ldst_code;
808 			desc.regout[ldst_group] |= 1 << ldst_code;
809 			desc.regout[0] |= SR_CODE;
810 			break;
811 		case 0x77: // andni local,limm
812 		case 0x7b: // ori local,limm
813 		case 0x7f: // xori local,limm
814 			desc.regin[0] |= SR_CODE;
815 			desc.regin[ldst_group] |= 1 << ldst_code;
816 			desc.regout[ldst_group] |= 1 << ldst_code;
817 			desc.regout[0] |= SR_CODE;
818 			desc.length = hyperstone_device::imm_length(op) << 1;
819 			break;
820 		case 0x80: case 0x81: // shrdi
821 		case 0x84: case 0x85: // sardi
822 		case 0x88: case 0x89: // shldi
823 			desc.regin[0] |= SR_CODE;
824 			desc.regout[ldst_group] |= 1 << ldst_code;
825 			desc.regout[ldstf_group] |= 1 << ldstf_code;
826 			desc.regout[0] |= SR_CODE;
827 			break;
828 		case 0x82: // shrd
829 		case 0x86: // sard
830 		case 0x8a: // shld
831 			desc.regin[0] |= SR_CODE;
832 			desc.regin[lsrc_group] |= 1 << lsrc_code;
833 			desc.regout[ldst_group] |= 1 << ldst_code;
834 			desc.regout[ldstf_group] |= 1 << ldstf_code;
835 			desc.regout[0] |= SR_CODE;
836 			break;
837 		case 0x83: // shr
838 		case 0x87: // sar
839 		case 0x8b: // shl
840 		case 0x8f: // rol
841 			desc.regin[0] |= SR_CODE;
842 			desc.regin[lsrc_group] |= 1 << lsrc_code;
843 			desc.regout[ldst_group] |= 1 << ldst_code;
844 			desc.regout[0] |= SR_CODE;
845 			break;
846 		case 0x8c: case 0x8d: // reserved
847 			return false;
848 		case 0x8e: // testlz
849 			desc.regin[0] |= SR_CODE;
850 			desc.regin[lsrc_group] |= 1 << lsrc_code;
851 			desc.regout[ldst_group] |= 1 << ldst_code;
852 			break;
853 		case 0x90: // ldxx1 global,global
854 		{
855 			const uint16_t imm1 = read_imm1(desc);
856 			const uint32_t extra_s = read_ldstxx_imm(desc);
857 
858 			desc.regin[0] |= 1 << gdst_code;
859 			desc.regout[0] |= 1 << gsrc_code;
860 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
861 
862 			desc.length = (imm1 & 0x8000) ? 6 : 4;
863 			desc.flags |= OPFLAG_READS_MEMORY;
864 			if (gdst_code == PC_REGISTER)
865 			{
866 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
867 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
868 			}
869 			break;
870 		}
871 		case 0x91: // ldxx1 global,local
872 		{
873 			const uint16_t imm1 = read_imm1(desc);
874 			const uint32_t extra_s = read_ldstxx_imm(desc);
875 
876 			desc.regin[0] |= SR_CODE;
877 			desc.regin[0] |= 1 << gdst_code;
878 			desc.regout[lsrc_group] |= 1 << lsrc_code;
879 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code;
880 
881 			desc.length = (imm1 & 0x8000) ? 6 : 4;
882 			desc.flags |= OPFLAG_READS_MEMORY;
883 			if (gdst_code == PC_REGISTER)
884 			{
885 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
886 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
887 			}
888 			break;
889 		}
890 		case 0x92: // ldxx1 local,global
891 		{
892 			const uint16_t imm1 = read_imm1(desc);
893 			const uint32_t extra_s = read_ldstxx_imm(desc);
894 
895 			desc.regin[0] |= SR_CODE;
896 			desc.regin[ldst_group] |= 1 << ldst_code;
897 			desc.regout[0] |= 1 << gsrc_code;
898 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
899 
900 			desc.length = (imm1 & 0x8000) ? 6 : 4;
901 			desc.flags |= OPFLAG_READS_MEMORY;
902 			break;
903 		}
904 		case 0x93: // ldxx1 local,local
905 		{
906 			const uint16_t imm1 = read_imm1(desc);
907 			const uint32_t extra_s = read_ldstxx_imm(desc);
908 
909 			desc.regin[0] |= SR_CODE;
910 			desc.regin[ldst_group] |= 1 << ldst_code;
911 			desc.regout[lsrc_group] |= 1 << lsrc_code;
912 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code;
913 
914 			desc.length = (imm1 & 0x8000) ? 6 : 4;
915 			desc.flags |= OPFLAG_READS_MEMORY;
916 			break;
917 		}
918 		case 0x94: // ldxx2 global,global
919 		{
920 			const uint16_t imm1 = read_imm1(desc);
921 			const uint32_t extra_s = read_ldstxx_imm(desc);
922 
923 			desc.regin[0] |= 1 << gdst_code;
924 			desc.regout[0] |= 1 << gdst_code;
925 			desc.regout[0] |= 1 << gsrc_code;
926 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
927 
928 			desc.length = (imm1 & 0x8000) ? 6 : 4;
929 			desc.flags |= OPFLAG_READS_MEMORY;
930 			if (gdst_code == PC_REGISTER)
931 			{
932 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
933 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
934 			}
935 			break;
936 		}
937 		case 0x95: // ldxx2 global,local
938 		{
939 			const uint16_t imm1 = read_imm1(desc);
940 			const uint32_t extra_s = read_ldstxx_imm(desc);
941 
942 			desc.regin[0] |= SR_CODE;
943 			desc.regin[0] |= 1 << gdst_code;
944 			desc.regout[0] |= 1 << gdst_code;
945 			desc.regout[lsrc_group] |= 1 << lsrc_code;
946 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code;
947 
948 			desc.length = (imm1 & 0x8000) ? 6 : 4;
949 			desc.flags |= OPFLAG_READS_MEMORY;
950 			if (gdst_code == PC_REGISTER)
951 			{
952 				desc.targetpc = BRANCH_TARGET_DYNAMIC;
953 				desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
954 			}
955 			break;
956 		}
957 		case 0x96: // ldxx2 local,global
958 		{
959 			const uint16_t imm1 = read_imm1(desc);
960 			const uint32_t extra_s = read_ldstxx_imm(desc);
961 
962 			desc.regin[0] |= SR_CODE;
963 			desc.regin[ldst_group] |= 1 << ldst_code;
964 			desc.regout[ldst_group] |= 1 << ldst_code;
965 			desc.regout[0] |= 1 << gsrc_code;
966 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
967 
968 			desc.length = (imm1 & 0x8000) ? 6 : 4;
969 			desc.flags |= OPFLAG_READS_MEMORY;
970 			break;
971 		}
972 		case 0x97: // ldxx2 local,local
973 		{
974 			const uint16_t imm1 = read_imm1(desc);
975 			const uint32_t extra_s = read_ldstxx_imm(desc);
976 
977 			desc.regin[0] |= SR_CODE;
978 			desc.regin[ldst_group] |= 1 << ldst_code;
979 			desc.regout[ldst_group] |= 1 << ldst_code;
980 			desc.regout[lsrc_group] |= 1 << lsrc_code;
981 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code;
982 
983 			desc.length = (imm1 & 0x8000) ? 6 : 4;
984 			desc.flags |= OPFLAG_READS_MEMORY;
985 			break;
986 		}
987 		case 0x98: // stxx1 global,global
988 		{
989 			const uint16_t imm1 = read_imm1(desc);
990 			const uint32_t extra_s = read_ldstxx_imm(desc);
991 
992 			desc.regin[0] |= 1 << gdst_code;
993 			desc.regin[0] |= 1 << gsrc_code;
994 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
995 
996 			desc.length = (imm1 & 0x8000) ? 6 : 4;
997 			desc.flags |= OPFLAG_WRITES_MEMORY;
998 			break;
999 		}
1000 		case 0x99: // stxx1 global,local
1001 		{
1002 			const uint16_t imm1 = read_imm1(desc);
1003 			const uint32_t extra_s = read_ldstxx_imm(desc);
1004 
1005 			desc.regin[0] |= SR_CODE;
1006 			desc.regin[0] |= 1 << gdst_code;
1007 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1008 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code;
1009 
1010 			desc.length = (imm1 & 0x8000) ? 6 : 4;
1011 			desc.flags |= OPFLAG_WRITES_MEMORY;
1012 			break;
1013 		}
1014 		case 0x9a: // stxx1 local,global
1015 		{
1016 			const uint16_t imm1 = read_imm1(desc);
1017 			const uint32_t extra_s = read_ldstxx_imm(desc);
1018 
1019 			desc.regin[0] |= SR_CODE;
1020 			desc.regin[ldst_group] |= 1 << ldst_code;
1021 			desc.regin[0] |= 1 << gsrc_code;
1022 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
1023 
1024 			desc.length = (imm1 & 0x8000) ? 6 : 4;
1025 			desc.flags |= OPFLAG_WRITES_MEMORY;
1026 			break;
1027 		}
1028 		case 0x9b: // stxx1 local,local
1029 		{
1030 			const uint16_t imm1 = read_imm1(desc);
1031 			const uint32_t extra_s = read_ldstxx_imm(desc);
1032 
1033 			desc.regin[0] |= SR_CODE;
1034 			desc.regin[ldst_group] |= 1 << ldst_code;
1035 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1036 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code;
1037 
1038 			desc.length = (imm1 & 0x8000) ? 6 : 4;
1039 			desc.flags |= OPFLAG_WRITES_MEMORY;
1040 			break;
1041 		}
1042 		case 0x9c: // stxx2 global,global
1043 		{
1044 			const uint16_t imm1 = read_imm1(desc);
1045 			const uint32_t extra_s = read_ldstxx_imm(desc);
1046 
1047 			desc.regin[0] |= 1 << gdst_code;
1048 			desc.regin[0] |= 1 << gsrc_code;
1049 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
1050 			desc.regout[0] |= 1 << gdst_code;
1051 
1052 			desc.length = (imm1 & 0x8000) ? 6 : 4;
1053 			desc.flags |= OPFLAG_WRITES_MEMORY;
1054 			break;
1055 		}
1056 		case 0x9d: // stxx2 global,local
1057 		{
1058 			const uint16_t imm1 = read_imm1(desc);
1059 			const uint32_t extra_s = read_ldstxx_imm(desc);
1060 
1061 			desc.regin[0] |= SR_CODE;
1062 			desc.regin[0] |= 1 << gdst_code;
1063 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1064 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code;
1065 			desc.regout[0] |= 1 << gdst_code;
1066 
1067 			desc.length = (imm1 & 0x8000) ? 6 : 4;
1068 			desc.flags |= OPFLAG_WRITES_MEMORY;
1069 			break;
1070 		}
1071 		case 0x9e: // stxx2 local,global
1072 		{
1073 			const uint16_t imm1 = read_imm1(desc);
1074 			const uint32_t extra_s = read_ldstxx_imm(desc);
1075 
1076 			desc.regin[0] |= SR_CODE;
1077 			desc.regin[ldst_group] |= 1 << ldst_code;
1078 			desc.regin[0] |= 1 << gsrc_code;
1079 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
1080 			desc.regout[ldst_group] |= 1 << ldst_code;
1081 
1082 			desc.length = (imm1 & 0x8000) ? 6 : 4;
1083 			desc.flags |= OPFLAG_WRITES_MEMORY;
1084 			break;
1085 		}
1086 		case 0x9f: // stxx2 local,local
1087 		{
1088 			const uint16_t imm1 = read_imm1(desc);
1089 			const uint32_t extra_s = read_ldstxx_imm(desc);
1090 
1091 			desc.regin[0] |= SR_CODE;
1092 			desc.regin[ldst_group] |= 1 << ldst_code;
1093 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1094 			if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code;
1095 			desc.regout[ldst_group] |= 1 << ldst_code;
1096 
1097 			desc.length = (imm1 & 0x8000) ? 6 : 4;
1098 			desc.flags |= OPFLAG_WRITES_MEMORY;
1099 			break;
1100 		}
1101 		case 0xa0: // shri global (lo n)
1102 		case 0xa1: // shri global (hi n)
1103 		case 0xa4: // sari global (lo n)
1104 		case 0xa5: // sari global (hi n)
1105 		case 0xa8: // shli global (lo n)
1106 		case 0xa9: // shli global (hi n)
1107 			desc.regin[0] |= 1 << gdst_code;
1108 			desc.regout[0] |= 1 << gdst_code;
1109 			desc.regout[0] |= SR_CODE;
1110 			break;
1111 		case 0xa2: // shri local (lo n)
1112 		case 0xa3: // shri local (hi n)
1113 		case 0xa6: // sari local (lo n)
1114 		case 0xa7: // sari local (hi n)
1115 		case 0xaa: // shli local (lo n)
1116 		case 0xab: // shli local (hi n)
1117 			desc.regin[0] |= SR_CODE;
1118 			desc.regin[ldst_group] |= 1 << ldst_code;
1119 			desc.regout[ldst_group] |= 1 << ldst_code;
1120 			desc.regout[0] |= SR_CODE;
1121 			break;
1122 		case 0xac: case 0xad: case 0xae: case 0xaf: // reserved
1123 			return false;
1124 		case 0xb0: // mulu global,global
1125 		case 0xb4: // muls global,global
1126 			desc.regin[0] |= 1 << gsrc_code;
1127 			desc.regin[0] |= 1 << gdst_code;
1128 			desc.regout[0] |= 1 << gdst_code;
1129 			desc.regout[0] |= 1 << gdstf_code;
1130 			desc.regout[0] |= SR_CODE;
1131 			break;
1132 		case 0xb1: // mulu global,local
1133 		case 0xb5: // muls global,local
1134 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1135 			desc.regin[0] |= 1 << gdst_code;
1136 			desc.regout[0] |= 1 << gdst_code;
1137 			desc.regout[0] |= 1 << gdstf_code;
1138 			desc.regout[0] |= SR_CODE;
1139 			break;
1140 		case 0xb2: // mulu local,global
1141 		case 0xb6: // muls local,global
1142 			desc.regin[0] |= 1 << gsrc_code;
1143 			desc.regin[ldst_group] |= 1 << ldst_code;
1144 			desc.regout[ldst_group] |= 1 << ldst_code;
1145 			desc.regout[ldstf_group] |= 1 << ldstf_code;
1146 			desc.regout[0] |= SR_CODE;
1147 			break;
1148 		case 0xb3: // mulu local,local
1149 		case 0xb7: // muls local,local
1150 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1151 			desc.regin[ldst_group] |= 1 << ldst_code;
1152 			desc.regout[ldst_group] |= 1 << ldst_code;
1153 			desc.regout[ldstf_group] |= 1 << ldstf_code;
1154 			desc.regout[0] |= SR_CODE;
1155 			break;
1156 		case 0xb8: // set global (lo n)
1157 		case 0xb9: // set global (hi n)
1158 			desc.regin[0] |= SR_CODE;
1159 			desc.regout[0] |= 1 << gdst_code;
1160 			break;
1161 		case 0xba: // set local (lo n)
1162 		case 0xbb: // set local (hi n)
1163 			desc.regout[ldst_group] |= 1 << ldst_code;
1164 			break;
1165 		case 0xbc: // mul global,global
1166 			desc.regin[0] |= 1 << gsrc_code;
1167 			desc.regin[0] |= 1 << gdst_code;
1168 			desc.regout[0] |= 1 << gdst_code;
1169 			desc.regout[0] |= SR_CODE;
1170 			break;
1171 		case 0xbd: // muls global,local
1172 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1173 			desc.regin[0] |= 1 << gdst_code;
1174 			desc.regout[0] |= 1 << gdst_code;
1175 			desc.regout[0] |= SR_CODE;
1176 			break;
1177 		case 0xbe: // muls local,global
1178 			desc.regin[0] |= 1 << gsrc_code;
1179 			desc.regin[ldst_group] |= 1 << ldst_code;
1180 			desc.regout[ldst_group] |= 1 << ldst_code;
1181 			desc.regout[0] |= SR_CODE;
1182 			break;
1183 		case 0xbf: // mulu local,local
1184 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1185 			desc.regin[ldst_group] |= 1 << ldst_code;
1186 			desc.regout[ldst_group] |= 1 << ldst_code;
1187 			desc.regout[0] |= SR_CODE;
1188 			break;
1189 		case 0xc0: case 0xc1: case 0xc2: case 0xc3: // software
1190 		case 0xc4: case 0xc5: case 0xc6: case 0xc7: // software
1191 		case 0xc8: case 0xc9: case 0xca: case 0xcb: // software
1192 		case 0xcc: case 0xcd: // software
1193 		{
1194 			desc.regin[0] |= SR_CODE;
1195 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1196 			desc.regin[lsrcf_group] |= 1 << lsrcf_code;
1197 
1198 			const uint32_t reg = FE_FP + FE_FL;
1199 			desc.regout[1 + (((reg + 0) & 0x20) >> 5)] |= 1 << ((reg + 0) & 0x1f);
1200 			desc.regout[1 + (((reg + 1) & 0x20) >> 5)] |= 1 << ((reg + 1) & 0x1f);
1201 			desc.regout[1 + (((reg + 2) & 0x20) >> 5)] |= 1 << ((reg + 2) & 0x1f);
1202 			desc.regout[1 + (((reg + 3) & 0x20) >> 5)] |= 1 << ((reg + 3) & 0x1f);
1203 			desc.regout[1 + (((reg + 4) & 0x20) >> 5)] |= 1 << ((reg + 4) & 0x1f);
1204 
1205 			desc.regout[0] |= SR_CODE;
1206 
1207 			desc.targetpc = BRANCH_TARGET_DYNAMIC;
1208 			desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
1209 			break;
1210 		}
1211 		case 0xce: // extend - 4 bytes
1212 			desc.regin[0] |= SR_CODE;
1213 			desc.regin[0] |= (3 << 14); // global regs 14, 15
1214 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1215 			desc.regin[ldst_group] |= 1 << ldst_code;
1216 			desc.regout[0] |= (3 << 14); // global regs 14, 15
1217 			desc.length = 4;
1218 			break;
1219 		case 0xcf: // do
1220 			return false;
1221 		case 0xd0: // ldwr global
1222 		case 0xd4: // ldwp global
1223 			desc.regin[0] |= SR_CODE;
1224 			desc.regin[ldst_group] |= 1 << ldst_code;
1225 			desc.regout[0] |= 1 << gsrc_code;
1226 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1227 			desc.flags |= OPFLAG_READS_MEMORY;
1228 			break;
1229 		case 0xd1: // ldwr local
1230 		case 0xd5: // ldwp local
1231 			desc.regin[0] |= SR_CODE;
1232 			desc.regin[ldst_group] |= 1 << ldst_code;
1233 			desc.regout[lsrc_group] |= 1 << lsrc_code;
1234 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1235 			desc.flags |= OPFLAG_READS_MEMORY;
1236 			break;
1237 		case 0xd2: // lddr global
1238 		case 0xd6: // lddp global
1239 			desc.regin[0] |= SR_CODE;
1240 			desc.regin[ldst_group] |= 1 << ldst_code;
1241 			desc.regout[0] |= 1 << gsrc_code;
1242 			desc.regout[0] |= 1 << gsrcf_code;
1243 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1244 			desc.flags |= OPFLAG_READS_MEMORY;
1245 			break;
1246 		case 0xd3: // lddr local
1247 		case 0xd7: // lddp local
1248 			desc.regin[0] |= SR_CODE;
1249 			desc.regin[ldst_group] |= 1 << ldst_code;
1250 			desc.regout[lsrc_group] |= 1 << lsrc_code;
1251 			desc.regout[lsrcf_group] |= 1 << lsrcf_code;
1252 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1253 			desc.flags |= OPFLAG_READS_MEMORY;
1254 			break;
1255 		case 0xd8: // stwr global
1256 		case 0xdc: // stwp global
1257 			desc.regin[0] |= SR_CODE;
1258 			desc.regin[ldst_group] |= 1 << ldst_code;
1259 			desc.regin[0] |= 1 << gsrc_code;
1260 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1261 			desc.flags |= OPFLAG_WRITES_MEMORY;
1262 			break;
1263 		case 0xd9: // stwr local
1264 		case 0xdd: // stwp local
1265 			desc.regin[0] |= SR_CODE;
1266 			desc.regin[ldst_group] |= 1 << ldst_code;
1267 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1268 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1269 			desc.flags |= OPFLAG_WRITES_MEMORY;
1270 			break;
1271 		case 0xda: // stdr global
1272 		case 0xde: // stdp global
1273 			desc.regin[0] |= SR_CODE;
1274 			desc.regin[ldst_group] |= 1 << ldst_code;
1275 			desc.regin[0] |= 1 << gsrc_code;
1276 			desc.regin[0] |= 1 << gsrcf_code;
1277 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1278 			desc.flags |= OPFLAG_WRITES_MEMORY;
1279 			break;
1280 		case 0xdb: // stdr local
1281 		case 0xdf: // stdp local
1282 			desc.regin[0] |= SR_CODE;
1283 			desc.regin[ldst_group] |= 1 << ldst_code;
1284 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1285 			desc.regin[lsrcf_group] |= 1 << lsrcf_code;
1286 			if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code;
1287 			desc.flags |= OPFLAG_WRITES_MEMORY;
1288 			break;
1289 		case 0xe0: case 0xe1: case 0xe2: case 0xe3: // dbv, dbnv, dbe, dbne - could be 4 bytes (pcrel)
1290 		case 0xe4: case 0xe5: case 0xe6: case 0xe7: // dbc, dbnc, dbse, dbht - could be 4 bytes (pcrel)
1291 		case 0xe8: case 0xe9: case 0xea: case 0xeb: // dbn, dbnn, dblt, dbgt - could be 4 bytes (pcrel)
1292 			decode_pcrel(desc, op);
1293 			desc.regin[0] |= SR_CODE;
1294 			desc.targetpc = BRANCH_TARGET_DYNAMIC;
1295 			desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
1296 			desc.delayslots = 1;
1297 			desc.length = (op & 0x80) ? 4 : 2;
1298 			break;
1299 		case 0xec: // dbr
1300 			decode_pcrel(desc, op);
1301 			desc.targetpc = BRANCH_TARGET_DYNAMIC;
1302 			desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
1303 			desc.delayslots = 1;
1304 			desc.length = (op & 0x80) ? 4 : 2;
1305 			break;
1306 		case 0xed: // frame
1307 			desc.regin[0] |= SR_CODE;
1308 			desc.regin[1] = 0xffffffff;
1309 			desc.regin[2] = 0xffffffff;
1310 			desc.regout[0] |= SR_CODE;
1311 			desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE;
1312 			break;
1313 		case 0xee: // call global
1314 			desc.regin[0] |= SR_CODE;
1315 			desc.regin[0] |= 1 << gsrc_code;
1316 			desc.regout[ldst_group] |= 1 << ldst_code;
1317 			desc.regout[ldstf_group] |= 1 << ldstf_code;
1318 			desc.targetpc = BRANCH_TARGET_DYNAMIC;
1319 			desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
1320 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
1321 			break;
1322 		case 0xef: // call local
1323 			desc.regin[0] |= SR_CODE;
1324 			desc.regin[lsrc_group] |= 1 << lsrc_code;
1325 			desc.regout[ldst_group] |= 1 << ldst_code;
1326 			desc.regout[ldstf_group] |= 1 << ldstf_code;
1327 			desc.targetpc = BRANCH_TARGET_DYNAMIC;
1328 			desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
1329 			desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
1330 			break;
1331 		case 0xf0: case 0xf1: case 0xf2: case 0xf3: // bv, bnv, be, bne
1332 		case 0xf4: case 0xf5: case 0xf6: case 0xf7: // bc, bnc, bse, bht
1333 		case 0xf8: case 0xf9: case 0xfa: case 0xfb: // bn, bnn, blt, bgt
1334 			decode_pcrel(desc, op);
1335 			desc.regin[0] |= SR_CODE;
1336 			desc.targetpc = BRANCH_TARGET_DYNAMIC;
1337 			desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
1338 			desc.length = (op & 0x80) ? 4 : 2;
1339 			break;
1340 		case 0xfc: // br
1341 		{
1342 			int32_t offset = decode_pcrel(desc, op);
1343 			desc.targetpc = (desc.pc + desc.length) + offset;
1344 			desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
1345 			desc.length = (op & 0x80) ? 4 : 2;
1346 			break;
1347 		}
1348 		case 0xfd: case 0xfe: case 0xff: // trap
1349 			desc.regin[0] |= SR_CODE;
1350 			desc.targetpc = BRANCH_TARGET_DYNAMIC;
1351 			desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
1352 			break;
1353 	}
1354 	return true;
1355 }
1356