Add ABFD argument to sim_open call. Pass through to sim_config so
[deliverable/binutils-gdb.git] / sim / v850 / simops.c
CommitLineData
22c1c7dd
JL
1#include <signal.h>
2#include "v850_sim.h"
3#include "simops.h"
9909e232 4#include "sys/syscall.h"
1d00ce83 5#include "bfd.h"
96851909 6#include <errno.h>
87e43259 7#if !defined(__GO32__) && !defined(_WIN32)
c500c074 8#include <sys/stat.h>
8824fb45 9#include <sys/times.h>
7fc45edb 10#include <sys/time.h>
87e43259 11#endif
22c1c7dd 12
70caad98
NC
13enum op_types
14{
ead4a3f1
MM
15 OP_UNKNOWN,
16 OP_NONE,
17 OP_TRAP,
18 OP_REG,
19 OP_REG_REG,
20 OP_REG_REG_CMP,
21 OP_REG_REG_MOVE,
22 OP_IMM_REG,
23 OP_IMM_REG_CMP,
24 OP_IMM_REG_MOVE,
25 OP_COND_BR,
26 OP_LOAD16,
27 OP_STORE16,
28 OP_LOAD32,
29 OP_STORE32,
30 OP_JUMP,
31 OP_IMM_REG_REG,
32 OP_UIMM_REG_REG,
33 OP_BIT,
34 OP_EX1,
35 OP_EX2,
36 OP_LDSR,
70caad98
NC
37 OP_STSR,
38/* start-sanitize-v850e */
39 OP_BIT_CHANGE,
40 OP_REG_REG_REG,
41 OP_REG_REG3,
42/* end-sanitize-v850e */
43/* start-sanitize-v850eq */
44 OP_IMM_REG_REG_REG,
45 OP_PUSHPOP1,
46 OP_PUSHPOP2,
47 OP_PUSHPOP3,
48/* end-sanitize-v850eq */
ead4a3f1
MM
49};
50
70caad98
NC
51/* start-sanitize-v850e */
52/* This is an array of the bit positions of registers r20 .. r31 in that order in a prepare/dispose instruction. */
53static int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 };
54/* end-sanitize-v850e */
55/* start-sanitize-v850eq */
56/* This is an array of the bit positions of registers r16 .. r31 in that order in a push/pop instruction. */
57static int type2_regs[16] = { 3, 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
58/* This is an array of the bit positions of registers r1 .. r15 in that order in a push/pop instruction. */
59static int type3_regs[15] = { 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21};
60/* end-sanitize-v850eq */
61
ead4a3f1
MM
62#ifdef DEBUG
63static void trace_input PARAMS ((char *name, enum op_types type, int size));
64static void trace_output PARAMS ((enum op_types result));
1d00ce83
MM
65static int init_text_p = 0;
66static asection *text;
67static bfd_vma text_start;
68static bfd_vma text_end;
70caad98 69extern bfd *prog_bfd;
ead4a3f1
MM
70
71#ifndef SIZE_INSTRUCTION
72#define SIZE_INSTRUCTION 6
73#endif
74
75#ifndef SIZE_OPERANDS
76#define SIZE_OPERANDS 16
77#endif
78
79#ifndef SIZE_VALUES
80#define SIZE_VALUES 11
81#endif
82
1d00ce83
MM
83#ifndef SIZE_LOCATION
84#define SIZE_LOCATION 40
85#endif
86
70caad98 87
ead4a3f1
MM
88static void
89trace_input (name, type, size)
90 char *name;
91 enum op_types type;
92 int size;
93{
1d00ce83
MM
94 char buf[1024];
95 char *p;
ead4a3f1
MM
96 uint32 values[3];
97 int num_values, i;
98 char *cond;
1d00ce83
MM
99 asection *s;
100 const char *filename;
101 const char *functionname;
102 unsigned int linenumber;
ead4a3f1
MM
103
104 if ((v850_debug & DEBUG_TRACE) == 0)
105 return;
106
1d00ce83
MM
107 buf[0] = '\0';
108 if (!init_text_p)
109 {
110 init_text_p = 1;
70caad98
NC
111 for (s = prog_bfd->sections; s; s = s->next)
112 if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
1d00ce83
MM
113 {
114 text = s;
70caad98
NC
115 text_start = bfd_get_section_vma (prog_bfd, s);
116 text_end = text_start + bfd_section_size (prog_bfd, s);
1d00ce83
MM
117 break;
118 }
119 }
120
121 if (text && PC >= text_start && PC < text_end)
122 {
123 filename = (const char *)0;
124 functionname = (const char *)0;
125 linenumber = 0;
70caad98 126 if (bfd_find_nearest_line (prog_bfd, text, (struct symbol_cache_entry **)0, PC - text_start,
1d00ce83
MM
127 &filename, &functionname, &linenumber))
128 {
129 p = buf;
130 if (linenumber)
131 {
132 sprintf (p, "Line %5d ", linenumber);
133 p += strlen (p);
134 }
135
136 if (functionname)
137 {
138 sprintf (p, "Func %s ", functionname);
139 p += strlen (p);
140 }
141 else if (filename)
142 {
143 char *q = (char *) strrchr (filename, '/');
144 sprintf (p, "File %s ", (q) ? q+1 : filename);
145 p += strlen (p);
146 }
147
148 if (*p == ' ')
149 *p = '\0';
150 }
151 }
152
153 (*v850_callback->printf_filtered) (v850_callback, "0x%.8x: %-*.*s %-*s",
ead4a3f1 154 (unsigned)PC,
1d00ce83 155 SIZE_LOCATION, SIZE_LOCATION, buf,
ead4a3f1
MM
156 SIZE_INSTRUCTION, name);
157
158 switch (type)
159 {
160 default:
161 case OP_UNKNOWN:
162 case OP_NONE:
163 strcpy (buf, "unknown");
164 break;
165
166 case OP_TRAP:
167 sprintf (buf, "%d", OP[0]);
168 break;
169
170 case OP_REG:
171 sprintf (buf, "r%d", OP[0]);
172 break;
173
174 case OP_REG_REG:
175 case OP_REG_REG_CMP:
176 case OP_REG_REG_MOVE:
177 sprintf (buf, "r%d,r%d", OP[0], OP[1]);
178 break;
179
180 case OP_IMM_REG:
181 case OP_IMM_REG_CMP:
182 case OP_IMM_REG_MOVE:
96851909 183 sprintf (buf, "%d,r%d", OP[0], OP[1]);
ead4a3f1
MM
184 break;
185
186 case OP_COND_BR:
187 sprintf (buf, "%d", SEXT9 (OP[0]));
188 break;
189
190 case OP_LOAD16:
0a89af6e 191 sprintf (buf, "%d[r30],r%d", OP[1] * size, OP[0]);
ead4a3f1
MM
192 break;
193
194 case OP_STORE16:
0a89af6e 195 sprintf (buf, "r%d,%d[r30]", OP[0], OP[1] * size);
ead4a3f1
MM
196 break;
197
198 case OP_LOAD32:
96851909 199 sprintf (buf, "%d[r%d],r%d", SEXT16 (OP[2]) & ~0x1, OP[0], OP[1]);
ead4a3f1
MM
200 break;
201
202 case OP_STORE32:
96851909 203 sprintf (buf, "r%d,%d[r%d]", OP[1], SEXT16 (OP[2] & ~0x1), OP[0]);
ead4a3f1
MM
204 break;
205
206 case OP_JUMP:
207 sprintf (buf, "%d,r%d", SEXT22 (OP[0]), OP[1]);
208 break;
209
210 case OP_IMM_REG_REG:
211 sprintf (buf, "%d,r%d,r%d", SEXT16 (OP[0]), OP[1], OP[2]);
212 break;
213
214 case OP_UIMM_REG_REG:
215 sprintf (buf, "%d,r%d,r%d", OP[0] & 0xffff, OP[1], OP[2]);
216 break;
217
218 case OP_BIT:
219 sprintf (buf, "%d,%d[r%d]", OP[1] & 0x7, SEXT16 (OP[2]), OP[0]);
220 break;
221
222 case OP_EX1:
223 switch (OP[0] & 0xf)
224 {
225 default: cond = "?"; break;
226 case 0x0: cond = "v"; break;
227 case 0x1: cond = "c"; break;
228 case 0x2: cond = "z"; break;
229 case 0x3: cond = "nh"; break;
230 case 0x4: cond = "s"; break;
231 case 0x5: cond = "t"; break;
232 case 0x6: cond = "lt"; break;
233 case 0x7: cond = "le"; break;
234 case 0x8: cond = "nv"; break;
235 case 0x9: cond = "nc"; break;
236 case 0xa: cond = "nz"; break;
237 case 0xb: cond = "h"; break;
238 case 0xc: cond = "ns"; break;
239 case 0xd: cond = "sa"; break;
240 case 0xe: cond = "ge"; break;
241 case 0xf: cond = "gt"; break;
242 }
243
244 sprintf (buf, "%s,r%d", cond, OP[1]);
245 break;
246
247 case OP_EX2:
248 strcpy (buf, "EX2");
249 break;
250
251 case OP_LDSR:
252 case OP_STSR:
253 sprintf (buf, "r%d,s%d", OP[0], OP[1]);
254 break;
70caad98
NC
255
256 case OP_PUSHPOP1:
257 for (i = 0; i < 12; i++)
258 if (OP[3] & (1 << type1_regs[i]))
259 strcat (buf, "r%d ", i + 20);
260 break;
261
262 case OP_PUSHPOP2:
263 for (i = 0; i < 16; i++)
264 if (OP[3] & (1 << type2_regs[i]))
265 strcat (buf, "r%d ", i + 16);
266 if (OP[3] & (1 << 19))
267 strcat (buf, "F/EIPC, F/EIPSW " );
268 break;
269
270 case OP_PUSHPOP3:
271 for (i = 0; i < 15; i++)
272 if (OP[3] & (1 << type3_regs[i]))
273 strcat (buf, "r%d ", i + 1);
274 if (OP[3] & (1 << 3))
275 strcat (buf, "PSW " );
276 if (OP[3] & (1 << 19))
277 strcat (buf, "F/EIPC, F/EIPSW " );
278 break;
279
280 case OP_BIT_CHANGE:
281 sprintf (buf, "r%d, [r%d]", OP[1], OP[0] );
282 break;
ead4a3f1
MM
283 }
284
285 if ((v850_debug & DEBUG_VALUES) == 0)
286 {
287 (*v850_callback->printf_filtered) (v850_callback, "%s\n", buf);
288 }
289 else
290 {
291 (*v850_callback->printf_filtered) (v850_callback, "%-*s", SIZE_OPERANDS, buf);
292 switch (type)
293 {
294 default:
295 case OP_UNKNOWN:
296 case OP_NONE:
297 case OP_TRAP:
298 num_values = 0;
299 break;
300
301 case OP_REG:
302 case OP_REG_REG_MOVE:
303 values[0] = State.regs[OP[0]];
304 num_values = 1;
305 break;
306
70caad98 307 case OP_BIT_CHANGE:
ead4a3f1
MM
308 case OP_REG_REG:
309 case OP_REG_REG_CMP:
310 values[0] = State.regs[OP[1]];
311 values[1] = State.regs[OP[0]];
312 num_values = 2;
313 break;
314
315 case OP_IMM_REG:
316 case OP_IMM_REG_CMP:
317 values[0] = SEXT5 (OP[0]);
318 values[1] = OP[1];
319 num_values = 2;
320 break;
321
322 case OP_IMM_REG_MOVE:
323 values[0] = SEXT5 (OP[0]);
324 num_values = 1;
325 break;
326
327 case OP_COND_BR:
328 values[0] = State.pc;
329 values[1] = SEXT9 (OP[0]);
ee3f2d4f 330 values[2] = PSW;
ead4a3f1
MM
331 num_values = 3;
332 break;
333
334 case OP_LOAD16:
0a89af6e 335 values[0] = OP[1] * size;
ead4a3f1
MM
336 values[1] = State.regs[30];
337 num_values = 2;
338 break;
339
340 case OP_STORE16:
341 values[0] = State.regs[OP[0]];
0a89af6e 342 values[1] = OP[1] * size;
ead4a3f1
MM
343 values[2] = State.regs[30];
344 num_values = 3;
345 break;
346
347 case OP_LOAD32:
348 values[0] = SEXT16 (OP[2]);
349 values[1] = State.regs[OP[0]];
350 num_values = 2;
351 break;
352
353 case OP_STORE32:
354 values[0] = State.regs[OP[1]];
355 values[1] = SEXT16 (OP[2]);
356 values[2] = State.regs[OP[0]];
357 num_values = 3;
358 break;
359
360 case OP_JUMP:
361 values[0] = SEXT22 (OP[0]);
362 values[1] = State.pc;
363 num_values = 2;
364 break;
365
366 case OP_IMM_REG_REG:
367 values[0] = SEXT16 (OP[0]) << size;
368 values[1] = State.regs[OP[1]];
369 num_values = 2;
370 break;
371
372 case OP_UIMM_REG_REG:
373 values[0] = (OP[0] & 0xffff) << size;
374 values[1] = State.regs[OP[1]];
375 num_values = 2;
376 break;
377
378 case OP_BIT:
379 num_values = 0;
380 break;
381
382 case OP_EX1:
ee3f2d4f 383 values[0] = PSW;
ead4a3f1
MM
384 num_values = 1;
385 break;
386
387 case OP_EX2:
388 num_values = 0;
389 break;
390
391 case OP_LDSR:
392 values[0] = State.regs[OP[0]];
393 num_values = 1;
394 break;
395
396 case OP_STSR:
397 values[0] = State.sregs[OP[1]];
398 num_values = 1;
399 }
400
401 for (i = 0; i < num_values; i++)
402 (*v850_callback->printf_filtered) (v850_callback, "%*s0x%.8lx", SIZE_VALUES - 10, "", values[i]);
403
404 while (i++ < 3)
405 (*v850_callback->printf_filtered) (v850_callback, "%*s", SIZE_VALUES, "");
406 }
407}
408
409static void
410trace_output (result)
411 enum op_types result;
412{
413 if ((v850_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES))
414 {
415 switch (result)
416 {
417 default:
418 case OP_UNKNOWN:
419 case OP_NONE:
420 case OP_TRAP:
421 case OP_REG:
422 case OP_REG_REG_CMP:
423 case OP_IMM_REG_CMP:
424 case OP_COND_BR:
425 case OP_STORE16:
426 case OP_STORE32:
427 case OP_BIT:
428 case OP_EX2:
429 break;
430
431 case OP_LOAD16:
432 case OP_STSR:
433 (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx",
434 (unsigned long)State.regs[OP[0]]);
435 break;
436
437 case OP_REG_REG:
438 case OP_REG_REG_MOVE:
439 case OP_IMM_REG:
440 case OP_IMM_REG_MOVE:
441 case OP_LOAD32:
442 case OP_EX1:
443 (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx",
444 (unsigned long)State.regs[OP[1]]);
445 break;
446
447 case OP_IMM_REG_REG:
448 case OP_UIMM_REG_REG:
449 (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx",
450 (unsigned long)State.regs[OP[2]]);
451 break;
452
453 case OP_JUMP:
454 if (OP[1] != 0)
455 (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx",
456 (unsigned long)State.regs[OP[1]]);
457 break;
458
459 case OP_LDSR:
460 (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx",
461 (unsigned long)State.sregs[OP[1]]);
462 break;
463 }
464
465 (*v850_callback->printf_filtered) (v850_callback, "\n");
466 }
467}
468
469#else
da86a4fa 470#define trace_input(NAME, IN1, IN2)
ead4a3f1 471#define trace_output(RESULT)
70caad98
NC
472
473//#define trace_input(NAME, IN1, IN2) fprintf (stderr, NAME "\n" );
474
ead4a3f1
MM
475#endif
476
70caad98
NC
477\f
478/* Returns 1 if the specific condition is met, returns 0 otherwise. */
479static unsigned int
480condition_met (unsigned code)
481{
482 unsigned int psw = PSW;
483
484 switch (code & 0xf)
485 {
486 case 0x0: return ((psw & PSW_OV) != 0);
487 case 0x1: return ((psw & PSW_CY) != 0);
488 case 0x2: return ((psw & PSW_Z) != 0);
489 case 0x3: return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0);
490 case 0x4: return ((psw & PSW_S) != 0);
491 /*case 0x5: return 1;*/
492 case 0x6: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0);
493 case 0x7: return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) != 0);
494 case 0x8: return ((psw & PSW_OV) == 0);
495 case 0x9: return ((psw & PSW_CY) == 0);
496 case 0xa: return ((psw & PSW_Z) == 0);
497 case 0xb: return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0);
498 case 0xc: return ((psw & PSW_S) == 0);
499 case 0xd: return ((psw & PSW_SAT) != 0);
500 case 0xe: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0);
501 case 0xf: return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) == 0);
502 }
503
504 return 1;
505}
506
70caad98
NC
507static unsigned long
508Add32 (unsigned long a1, unsigned long a2, int * carry)
509{
510 unsigned long result = (a1 + a2);
511
512 * carry = (result < a1);
513
514 return result;
515}
516
517static void
518Multiply64 (boolean sign, unsigned long op0)
519{
520 unsigned long op1;
521 unsigned long lo;
522 unsigned long mid1;
523 unsigned long mid2;
524 unsigned long hi;
525 unsigned long RdLo;
526 unsigned long RdHi;
527 int carry;
528
529 op1 = State.regs[ OP[1] ];
530
531 if (sign)
532 {
533 /* Compute sign of result and adjust operands if necessary. */
534
535 sign = (op0 ^ op1) & 0x80000000;
536
537 if (((signed long) op0) < 0)
538 op0 = - op0;
539
540 if (((signed long) op1) < 0)
541 op1 = - op1;
542 }
543
544 /* We can split the 32x32 into four 16x16 operations. This ensures
545 that we do not lose precision on 32bit only hosts: */
546 lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF));
547 mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
548 mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF));
549 hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
550
551 /* We now need to add all of these results together, taking care
552 to propogate the carries from the additions: */
553 RdLo = Add32 (lo, (mid1 << 16), & carry);
554 RdHi = carry;
555 RdLo = Add32 (RdLo, (mid2 << 16), & carry);
556 RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
557
558 if (sign)
559 {
560 /* Negate result if necessary. */
561
562 RdLo = ~ RdLo;
563 RdHi = ~ RdHi;
564 if (RdLo == 0xFFFFFFFF)
565 {
566 RdLo = 0;
567 RdHi += 1;
568 }
569 else
570 RdLo += 1;
571 }
572
573 State.regs[ OP[1] ] = RdLo;
574 State.regs[ OP[2] >> 11 ] = RdHi;
575
576 return;
577}
70caad98 578
ead4a3f1 579\f
28647e4c 580/* sld.b */
70caad98 581int
28647e4c 582OP_300 ()
22c1c7dd 583{
70caad98
NC
584 unsigned long result;
585
586 result = load_mem (State.regs[30] + (OP[3] & 0x7f), 1);
3cb6bf78 587
70caad98
NC
588/* start-sanitize-v850eq */
589#ifdef ARCH_v850eq
590 trace_input ("sld.bu", OP_LOAD16, 1);
591
592 State.regs[ OP[1] ] = result;
593#else
594/* end-sanitize-v850eq */
ead4a3f1 595 trace_input ("sld.b", OP_LOAD16, 1);
70caad98
NC
596
597 State.regs[ OP[1] ] = SEXT8 (result);
598/* start-sanitize-v850eq */
599#endif
600/* end-sanitize-v850eq */
601
ead4a3f1 602 trace_output (OP_LOAD16);
70caad98
NC
603
604 return 2;
22c1c7dd
JL
605}
606
28647e4c 607/* sld.h */
70caad98 608int
28647e4c
JL
609OP_400 ()
610{
70caad98
NC
611 unsigned long result;
612
613 result = load_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 2);
3cb6bf78 614
70caad98
NC
615/* start-sanitize-v850eq */
616#ifdef ARCH_v850eq
617 trace_input ("sld.hu", OP_LOAD16, 2);
618
619 State.regs[ OP[1] ] = result;
620#else
621/* end-sanitize-v850eq */
ead4a3f1 622 trace_input ("sld.h", OP_LOAD16, 2);
70caad98
NC
623
624 State.regs[ OP[1] ] = SEXT16 (result);
625/* start-sanitize-v850eq */
626#endif
627/* end-sanitize-v850eq */
628
ead4a3f1 629 trace_output (OP_LOAD16);
70caad98
NC
630
631 return 2;
28647e4c
JL
632}
633
634/* sld.w */
70caad98 635int
28647e4c 636OP_500 ()
22c1c7dd 637{
ead4a3f1 638 trace_input ("sld.w", OP_LOAD16, 4);
70caad98
NC
639
640 State.regs[ OP[1] ] = load_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 4);
641
ead4a3f1 642 trace_output (OP_LOAD16);
70caad98
NC
643
644 return 2;
22c1c7dd
JL
645}
646
28647e4c 647/* sst.b */
70caad98 648int
28647e4c
JL
649OP_380 ()
650{
ead4a3f1 651 trace_input ("sst.b", OP_STORE16, 1);
70caad98
NC
652
653 store_mem (State.regs[30] + (OP[3] & 0x7f), 1, State.regs[ OP[1] ]);
654
ead4a3f1 655 trace_output (OP_STORE16);
70caad98
NC
656
657 return 2;
28647e4c
JL
658}
659
660/* sst.h */
70caad98 661int
28647e4c
JL
662OP_480 ()
663{
ead4a3f1 664 trace_input ("sst.h", OP_STORE16, 2);
70caad98
NC
665
666 store_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 2, State.regs[ OP[1] ]);
667
ead4a3f1 668 trace_output (OP_STORE16);
70caad98
NC
669
670 return 2;
28647e4c
JL
671}
672
673/* sst.w */
70caad98 674int
28647e4c
JL
675OP_501 ()
676{
ead4a3f1 677 trace_input ("sst.w", OP_STORE16, 4);
70caad98
NC
678
679 store_mem (State.regs[30] + ((OP[3] & 0x7e) << 1), 4, State.regs[ OP[1] ]);
680
ead4a3f1 681 trace_output (OP_STORE16);
70caad98
NC
682
683 return 2;
28647e4c
JL
684}
685
686/* ld.b */
70caad98 687int
28647e4c
JL
688OP_700 ()
689{
70caad98 690 int adr;
28647e4c 691
ead4a3f1 692 trace_input ("ld.b", OP_LOAD32, 1);
70caad98
NC
693
694 adr = State.regs[ OP[0] ] + SEXT16 (OP[2]);
695
696 State.regs[ OP[1] ] = SEXT8 (load_mem (adr, 1));
697
ead4a3f1 698 trace_output (OP_LOAD32);
70caad98
NC
699
700 return 4;
28647e4c
JL
701}
702
703/* ld.h */
70caad98 704int
28647e4c
JL
705OP_720 ()
706{
70caad98 707 int adr;
28647e4c 708
ead4a3f1 709 trace_input ("ld.h", OP_LOAD32, 2);
70caad98
NC
710
711 adr = State.regs[ OP[0] ] + SEXT16 (OP[2]);
712 adr &= ~0x1;
713
714 State.regs[ OP[1] ] = SEXT16 (load_mem (adr, 2));
715
ead4a3f1 716 trace_output (OP_LOAD32);
70caad98
NC
717
718 return 4;
28647e4c
JL
719}
720
721/* ld.w */
70caad98 722int
28647e4c
JL
723OP_10720 ()
724{
70caad98 725 int adr;
28647e4c 726
ead4a3f1 727 trace_input ("ld.w", OP_LOAD32, 4);
70caad98
NC
728
729 adr = State.regs[ OP[0] ] + SEXT16 (OP[2] & ~1);
730 adr &= ~0x3;
731
732 State.regs[ OP[1] ] = load_mem (adr, 4);
733
ead4a3f1 734 trace_output (OP_LOAD32);
70caad98
NC
735
736 return 4;
28647e4c
JL
737}
738
739/* st.b */
70caad98 740int
28647e4c
JL
741OP_740 ()
742{
ead4a3f1 743 trace_input ("st.b", OP_STORE32, 1);
70caad98
NC
744
745 store_mem (State.regs[ OP[0] ] + SEXT16 (OP[2]), 1, State.regs[ OP[1] ]);
746
ead4a3f1 747 trace_output (OP_STORE32);
70caad98
NC
748
749 return 4;
28647e4c
JL
750}
751
752/* st.h */
70caad98 753int
22c1c7dd
JL
754OP_760 ()
755{
70caad98
NC
756 int adr;
757
ead4a3f1 758 trace_input ("st.h", OP_STORE32, 2);
70caad98
NC
759
760 adr = State.regs[ OP[0] ] + SEXT16 (OP[2]);
761 adr &= ~1;
762
763 store_mem (adr, 2, State.regs[ OP[1] ]);
764
ead4a3f1 765 trace_output (OP_STORE32);
70caad98
NC
766
767 return 4;
28647e4c
JL
768}
769
770/* st.w */
70caad98 771int
28647e4c
JL
772OP_10760 ()
773{
70caad98
NC
774 int adr;
775
ead4a3f1 776 trace_input ("st.w", OP_STORE32, 4);
70caad98
NC
777
778 adr = State.regs[ OP[0] ] + SEXT16 (OP[2] & ~1);
779 adr &= ~3;
780
781 store_mem (adr, 4, State.regs[ OP[1] ]);
782
ead4a3f1 783 trace_output (OP_STORE32);
70caad98
NC
784
785 return 4;
22c1c7dd
JL
786}
787
70caad98
NC
788static int
789branch (int code)
22c1c7dd 790{
ead4a3f1
MM
791 unsigned int psw;
792 int op0;
22c1c7dd 793
70caad98 794 trace_input ("Bcond", OP_COND_BR, 0);
ead4a3f1 795 trace_output (OP_COND_BR);
70caad98
NC
796
797 if (condition_met (code))
798 return SEXT9 (((OP[3] & 0x70) >> 3) | ((OP[3] & 0xf800) >> 7));
799 else
800 return 2;
801}
802
803/* bv disp9 */
804int
805OP_580 ()
806{
807 return branch (0);
22c1c7dd
JL
808}
809
2108e864 810/* bl disp9 */
70caad98 811int
22c1c7dd
JL
812OP_581 ()
813{
70caad98 814 return branch (1);
22c1c7dd
JL
815}
816
2108e864 817/* be disp9 */
70caad98 818int
22c1c7dd
JL
819OP_582 ()
820{
70caad98 821 return branch (2);
22c1c7dd
JL
822}
823
2108e864 824/* bnh disp 9*/
70caad98 825int
22c1c7dd
JL
826OP_583 ()
827{
70caad98 828 return branch (3);
22c1c7dd
JL
829}
830
2108e864 831/* bn disp9 */
70caad98 832int
22c1c7dd
JL
833OP_584 ()
834{
70caad98 835 return branch (4);
22c1c7dd
JL
836}
837
2108e864 838/* br disp9 */
70caad98 839int
22c1c7dd
JL
840OP_585 ()
841{
70caad98 842 return branch (5);
22c1c7dd
JL
843}
844
2108e864 845/* blt disp9 */
70caad98 846int
22c1c7dd
JL
847OP_586 ()
848{
70caad98 849 return branch (6);
22c1c7dd
JL
850}
851
2108e864 852/* ble disp9 */
70caad98 853int
22c1c7dd
JL
854OP_587 ()
855{
70caad98 856 return branch (7);
22c1c7dd
JL
857}
858
2108e864 859/* bnv disp9 */
70caad98 860int
22c1c7dd
JL
861OP_588 ()
862{
70caad98 863 return branch (8);
22c1c7dd
JL
864}
865
2108e864 866/* bnl disp9 */
70caad98 867int
22c1c7dd
JL
868OP_589 ()
869{
70caad98 870 return branch (9);
22c1c7dd
JL
871}
872
2108e864 873/* bne disp9 */
70caad98 874int
22c1c7dd
JL
875OP_58A ()
876{
70caad98 877 return branch (10);
22c1c7dd
JL
878}
879
2108e864 880/* bh disp9 */
70caad98 881int
22c1c7dd
JL
882OP_58B ()
883{
70caad98 884 return branch (11);
22c1c7dd
JL
885}
886
2108e864 887/* bp disp9 */
70caad98 888int
2108e864 889OP_58C ()
22c1c7dd 890{
70caad98 891 return branch (12);
22c1c7dd
JL
892}
893
2108e864 894/* bsa disp9 */
70caad98 895int
22c1c7dd
JL
896OP_58D ()
897{
70caad98 898 return branch (13);
22c1c7dd
JL
899}
900
2108e864 901/* bge disp9 */
70caad98 902int
22c1c7dd
JL
903OP_58E ()
904{
70caad98 905 return branch (14);
22c1c7dd
JL
906}
907
2108e864 908/* bgt disp9 */
70caad98 909int
22c1c7dd
JL
910OP_58F ()
911{
70caad98 912 return branch (15);
22c1c7dd
JL
913}
914
e9b6cbac 915/* jmp [reg1] */
70caad98
NC
916/* sld.bu disp4[ep], reg2 */
917int
e9b6cbac 918OP_60 ()
22c1c7dd 919{
70caad98
NC
920 if (OP[1] == 0)
921 {
922 trace_input ("jmp", OP_REG, 0);
923
924 PC = State.regs[ OP[0] ];
925
926 trace_output (OP_REG);
927
928 return 0; /* Add nothing to the PC, we have already done it. */
929 }
930/* start-sanitize-v850e */
931 else
932 {
933 unsigned long result;
934
935 result = load_mem (State.regs[30] + (OP[3] & 0xf), 1);
936
937/* start-sanitize-v850eq */
938#ifdef ARCH_v850eq
939 trace_input ("sld.b", OP_LOAD16, 1);
940
941 State.regs[ OP[1] ] = SEXT8 (result);
942#else
943/* end-sanitize-v850eq */
944 trace_input ("sld.bu", OP_LOAD16, 1);
945
946 State.regs[ OP[1] ] = result;
947/* start-sanitize-v850eq */
948#endif
949/* end-sanitize-v850eq */
950
951 trace_output (OP_LOAD16);
952
953 return 2;
954 }
955/* end-sanitize-v850e */
22c1c7dd
JL
956}
957
70caad98
NC
958/* jarl/jr disp22, reg */
959int
e9b6cbac
JL
960OP_780 ()
961{
70caad98 962 trace_input ("jarl/jr", OP_JUMP, 0);
e9b6cbac 963
70caad98
NC
964 if (OP[ 1 ] != 0)
965 State.regs[ OP[1] ] = PC + 4;
966
ead4a3f1 967 trace_output (OP_JUMP);
70caad98
NC
968
969 return SEXT22 (((OP[3] & 0x3f) << 16) | OP[2]);
e9b6cbac 970}
22c1c7dd 971
0ef0eba5 972/* add reg, reg */
70caad98 973int
1fe983dc 974OP_1C0 ()
22c1c7dd 975{
0ef0eba5 976 unsigned int op0, op1, result, z, s, cy, ov;
22c1c7dd 977
ead4a3f1 978 trace_input ("add", OP_REG_REG, 0);
70caad98 979
0ef0eba5 980 /* Compute the result. */
70caad98
NC
981
982 op0 = State.regs[ OP[0] ];
983 op1 = State.regs[ OP[1] ];
984
0ef0eba5 985 result = op0 + op1;
1fe983dc 986
0ef0eba5
JL
987 /* Compute the condition codes. */
988 z = (result == 0);
989 s = (result & 0x80000000);
990 cy = (result < op0 || result < op1);
991 ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
992 && (op0 & 0x80000000) != (result & 0x80000000));
993
994 /* Store the result and condition codes. */
995 State.regs[OP[1]] = result;
ee3f2d4f
MM
996 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
997 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
614f1c68 998 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
ead4a3f1 999 trace_output (OP_REG_REG);
70caad98
NC
1000
1001 return 2;
0ef0eba5
JL
1002}
1003
1004/* add sign_extend(imm5), reg */
70caad98 1005int
1fe983dc 1006OP_240 ()
22c1c7dd 1007{
0ef0eba5
JL
1008 unsigned int op0, op1, result, z, s, cy, ov;
1009 int temp;
1fe983dc 1010
ead4a3f1
MM
1011 trace_input ("add", OP_IMM_REG, 0);
1012
0ef0eba5 1013 /* Compute the result. */
ead4a3f1 1014 temp = SEXT5 (OP[0]);
0ef0eba5
JL
1015 op0 = temp;
1016 op1 = State.regs[OP[1]];
1017 result = op0 + op1;
1018
1019 /* Compute the condition codes. */
1020 z = (result == 0);
1021 s = (result & 0x80000000);
1022 cy = (result < op0 || result < op1);
1023 ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
1024 && (op0 & 0x80000000) != (result & 0x80000000));
22c1c7dd 1025
0ef0eba5
JL
1026 /* Store the result and condition codes. */
1027 State.regs[OP[1]] = result;
ee3f2d4f
MM
1028 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1029 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
0ef0eba5 1030 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
ead4a3f1 1031 trace_output (OP_IMM_REG);
70caad98
NC
1032
1033 return 2;
0ef0eba5 1034}
1fe983dc 1035
0ef0eba5 1036/* addi sign_extend(imm16), reg, reg */
70caad98 1037int
1fe983dc 1038OP_600 ()
22c1c7dd 1039{
0ef0eba5 1040 unsigned int op0, op1, result, z, s, cy, ov;
0ef0eba5 1041
ead4a3f1
MM
1042 trace_input ("addi", OP_IMM_REG_REG, 0);
1043
0ef0eba5 1044 /* Compute the result. */
70caad98
NC
1045
1046 op0 = SEXT16 (OP[2]);
1047 op1 = State.regs[ OP[0] ];
0ef0eba5
JL
1048 result = op0 + op1;
1049
1050 /* Compute the condition codes. */
1051 z = (result == 0);
1052 s = (result & 0x80000000);
1053 cy = (result < op0 || result < op1);
1054 ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
1055 && (op0 & 0x80000000) != (result & 0x80000000));
1056
1057 /* Store the result and condition codes. */
70caad98 1058 State.regs[OP[1]] = result;
ee3f2d4f
MM
1059 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1060 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
0ef0eba5 1061 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
ead4a3f1 1062 trace_output (OP_IMM_REG_REG);
70caad98
NC
1063
1064 return 4;
22c1c7dd
JL
1065}
1066
aabce0f4 1067/* sub reg1, reg2 */
70caad98 1068int
1fe983dc 1069OP_1A0 ()
22c1c7dd 1070{
aabce0f4
JL
1071 unsigned int op0, op1, result, z, s, cy, ov;
1072
ead4a3f1 1073 trace_input ("sub", OP_REG_REG, 0);
aabce0f4 1074 /* Compute the result. */
70caad98
NC
1075 op0 = State.regs[ OP[0] ];
1076 op1 = State.regs[ OP[1] ];
aabce0f4 1077 result = op1 - op0;
22c1c7dd 1078
aabce0f4
JL
1079 /* Compute the condition codes. */
1080 z = (result == 0);
1081 s = (result & 0x80000000);
d81352b8 1082 cy = (op1 < op0);
aabce0f4
JL
1083 ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
1084 && (op1 & 0x80000000) != (result & 0x80000000));
1fe983dc 1085
aabce0f4
JL
1086 /* Store the result and condition codes. */
1087 State.regs[OP[1]] = result;
ee3f2d4f
MM
1088 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1089 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
aabce0f4 1090 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
ead4a3f1 1091 trace_output (OP_REG_REG);
70caad98
NC
1092
1093 return 2;
aabce0f4
JL
1094}
1095
1096/* subr reg1, reg2 */
70caad98 1097int
1fe983dc 1098OP_180 ()
22c1c7dd 1099{
aabce0f4 1100 unsigned int op0, op1, result, z, s, cy, ov;
22c1c7dd 1101
ead4a3f1 1102 trace_input ("subr", OP_REG_REG, 0);
aabce0f4 1103 /* Compute the result. */
70caad98
NC
1104 op0 = State.regs[ OP[0] ];
1105 op1 = State.regs[ OP[1] ];
aabce0f4 1106 result = op0 - op1;
e98e3b2c 1107
aabce0f4
JL
1108 /* Compute the condition codes. */
1109 z = (result == 0);
1110 s = (result & 0x80000000);
d81352b8 1111 cy = (op0 < op1);
aabce0f4
JL
1112 ov = ((op0 & 0x80000000) != (op1 & 0x80000000)
1113 && (op0 & 0x80000000) != (result & 0x80000000));
1114
1115 /* Store the result and condition codes. */
1116 State.regs[OP[1]] = result;
ee3f2d4f
MM
1117 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1118 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
aabce0f4 1119 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
ead4a3f1 1120 trace_output (OP_REG_REG);
70caad98
NC
1121
1122 return 2;
aabce0f4
JL
1123}
1124
70caad98 1125/* sxh reg1 */
aabce0f4 1126/* mulh reg1, reg2 */
70caad98 1127int
e98e3b2c 1128OP_E0 ()
22c1c7dd 1129{
70caad98
NC
1130/* start-sanitize-v850e */
1131 if (OP[1] == 0)
1132 {
1133 trace_input ("sxh", OP_REG, 0);
1134
1135 State.regs[ OP[0] ] = SEXT16 (State.regs[ OP[0] ]);
e98e3b2c 1136
70caad98
NC
1137 trace_output (OP_REG);
1138 }
1139 else
1140/* end-sanitize-v850e */
1141 {
1142 trace_input ("mulh", OP_REG_REG, 0);
1143
1144 State.regs[ OP[1] ] = (SEXT16 (State.regs[ OP[1] ]) * SEXT16 (State.regs[ OP[0] ]));
1145
1146 trace_output (OP_REG_REG);
1147 }
1148
1149 return 2;
1150}
1151
1152/* mulh sign_extend(imm5), reg2 */
1153int
1154OP_2E0 ()
22c1c7dd 1155{
ead4a3f1 1156 trace_input ("mulh", OP_IMM_REG, 0);
70caad98
NC
1157
1158 State.regs[ OP[1] ] = SEXT16 (State.regs[ OP[1] ]) * SEXT5 (OP[0]);
1159
ead4a3f1 1160 trace_output (OP_IMM_REG);
70caad98
NC
1161
1162 return 2;
22c1c7dd
JL
1163}
1164
aabce0f4 1165/* mulhi imm16, reg1, reg2 */
70caad98 1166int
e98e3b2c
JL
1167OP_6E0 ()
1168{
70caad98
NC
1169 if (OP[1] == 0)
1170 {
1171 }
1172 else
1173 {
1174 trace_input ("mulhi", OP_IMM_REG_REG, 0);
1175
1176 State.regs[ OP[1] ] = SEXT16 (State.regs[ OP[0] ]) * SEXT16 (OP[2]);
1177
1178 trace_output (OP_IMM_REG_REG);
1179 }
1180
1181 return 4;
e98e3b2c
JL
1182}
1183
aabce0f4 1184/* divh reg1, reg2 */
70caad98
NC
1185/* switch reg1 */
1186int
e98e3b2c 1187OP_40 ()
22c1c7dd 1188{
70caad98
NC
1189/* start-sanitize-v850e */
1190 if (OP[1] == 0)
1191 {
1192 unsigned long adr;
ead4a3f1 1193
70caad98
NC
1194 trace_input ("switch", OP_REG, 0);
1195
1196 adr = State.pc + 2 + (State.regs[ OP[0] ] << 1);
1197 State.pc = State.pc + 2 + (SEXT16 (load_mem (adr, 2)) << 1);
aabce0f4 1198
70caad98 1199 trace_output (OP_REG);
aabce0f4
JL
1200 }
1201 else
70caad98 1202/* end-sanitize-v850e */
9fca2fd3 1203 {
70caad98
NC
1204 unsigned int op0, op1, result, ov, s, z;
1205 int temp;
aabce0f4 1206
70caad98 1207 trace_input ("divh", OP_REG_REG, 0);
aabce0f4 1208
70caad98
NC
1209 /* Compute the result. */
1210 temp = SEXT16 (State.regs[ OP[0] ]);
1211 op0 = temp;
1212 op1 = State.regs[OP[1]];
1213
1214 if (op0 == 0xffffffff && op1 == 0x80000000)
1215 {
1216 result = 0x80000000;
1217 ov = 1;
1218 }
1219 else if (op0 != 0)
1220 {
1221 result = op1 / op0;
1222 ov = 0;
1223 }
1224 else
1225 {
1226 result = 0x0;
1227 ov = 1;
1228 }
1229
1230 /* Compute the condition codes. */
1231 z = (result == 0);
1232 s = (result & 0x80000000);
1233
1234 /* Store the result and condition codes. */
1235 State.regs[OP[1]] = result;
1236 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1237 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1238 | (ov ? PSW_OV : 0));
1239 trace_output (OP_REG_REG);
1240 }
1241
1242 return 2;
22c1c7dd
JL
1243}
1244
3095b8df 1245/* cmp reg, reg */
70caad98 1246int
3095b8df
JL
1247OP_1E0 ()
1248{
1249 unsigned int op0, op1, result, z, s, cy, ov;
1250
ead4a3f1 1251 trace_input ("cmp", OP_REG_REG_CMP, 0);
3095b8df 1252 /* Compute the result. */
70caad98
NC
1253 op0 = State.regs[ OP[0] ];
1254 op1 = State.regs[ OP[1] ];
3095b8df
JL
1255 result = op1 - op0;
1256
1257 /* Compute the condition codes. */
1258 z = (result == 0);
1259 s = (result & 0x80000000);
d81352b8 1260 cy = (op1 < op0);
3095b8df
JL
1261 ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
1262 && (op1 & 0x80000000) != (result & 0x80000000));
1263
1264 /* Set condition codes. */
ee3f2d4f
MM
1265 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1266 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
3095b8df 1267 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
ead4a3f1 1268 trace_output (OP_REG_REG_CMP);
70caad98
NC
1269
1270 return 2;
3095b8df
JL
1271}
1272
1273/* cmp sign_extend(imm5), reg */
70caad98 1274int
3095b8df
JL
1275OP_260 ()
1276{
1277 unsigned int op0, op1, result, z, s, cy, ov;
1278 int temp;
1279
1280 /* Compute the result. */
ead4a3f1
MM
1281 trace_input ("cmp", OP_IMM_REG_CMP, 0);
1282 temp = SEXT5 (OP[0]);
3095b8df
JL
1283 op0 = temp;
1284 op1 = State.regs[OP[1]];
1285 result = op1 - op0;
1286
1287 /* Compute the condition codes. */
1288 z = (result == 0);
1289 s = (result & 0x80000000);
d81352b8 1290 cy = (op1 < op0);
3095b8df
JL
1291 ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
1292 && (op1 & 0x80000000) != (result & 0x80000000));
1293
1294 /* Set condition codes. */
ee3f2d4f
MM
1295 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1296 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
3095b8df 1297 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
ead4a3f1 1298 trace_output (OP_IMM_REG_CMP);
70caad98
NC
1299
1300 return 2;
3095b8df
JL
1301}
1302
1303/* setf cccc,reg2 */
70caad98 1304int
3095b8df
JL
1305OP_7E0 ()
1306{
ead4a3f1 1307 trace_input ("setf", OP_EX1, 0);
3095b8df 1308
70caad98 1309 State.regs[ OP[1] ] = condition_met (OP[0]);
3095b8df 1310
ead4a3f1 1311 trace_output (OP_EX1);
70caad98
NC
1312
1313 return 4;
3095b8df
JL
1314}
1315
70caad98 1316/* zxh reg1 */
dca41ba7 1317/* satadd reg,reg */
70caad98 1318int
dca41ba7
JL
1319OP_C0 ()
1320{
70caad98
NC
1321/* start-sanitize-v850e */
1322 if (OP[1] == 0)
1323 {
1324 trace_input ("zxh", OP_REG, 0);
1325
1326 State.regs[ OP[0] ] &= 0xffff;
dca41ba7 1327
70caad98
NC
1328 trace_output (OP_REG);
1329 }
1330 else
1331/* end-sanitize-v850e */
1332 {
1333 unsigned int op0, op1, result, z, s, cy, ov, sat;
1334
1335 trace_input ("satadd", OP_REG_REG, 0);
1336 /* Compute the result. */
1337 op0 = State.regs[ OP[0] ];
1338 op1 = State.regs[ OP[1] ];
1339 result = op0 + op1;
1340
1341 /* Compute the condition codes. */
1342 z = (result == 0);
1343 s = (result & 0x80000000);
1344 cy = (result < op0 || result < op1);
1345 ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
1346 && (op0 & 0x80000000) != (result & 0x80000000));
1347 sat = ov;
1348
1349 /* Store the result and condition codes. */
1350 State.regs[OP[1]] = result;
1351 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1352 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1353 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
1354 | (sat ? PSW_SAT : 0));
1355
1356 /* Handle saturated results. */
1357 if (sat && s)
1358 State.regs[OP[1]] = 0x80000000;
1359 else if (sat)
1360 State.regs[OP[1]] = 0x7fffffff;
1361 trace_output (OP_REG_REG);
1362 }
dca41ba7 1363
70caad98 1364 return 2;
dca41ba7
JL
1365}
1366
1367/* satadd sign_extend(imm5), reg */
70caad98 1368int
dca41ba7
JL
1369OP_220 ()
1370{
1371 unsigned int op0, op1, result, z, s, cy, ov, sat;
1372
1373 int temp;
1374
ead4a3f1
MM
1375 trace_input ("satadd", OP_IMM_REG, 0);
1376
dca41ba7 1377 /* Compute the result. */
ead4a3f1 1378 temp = SEXT5 (OP[0]);
dca41ba7
JL
1379 op0 = temp;
1380 op1 = State.regs[OP[1]];
1381 result = op0 + op1;
1382
1383 /* Compute the condition codes. */
1384 z = (result == 0);
1385 s = (result & 0x80000000);
1386 cy = (result < op0 || result < op1);
1387 ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
1388 && (op0 & 0x80000000) != (result & 0x80000000));
1389 sat = ov;
1390
1391 /* Store the result and condition codes. */
1392 State.regs[OP[1]] = result;
ee3f2d4f
MM
1393 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1394 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
dca41ba7
JL
1395 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
1396 | (sat ? PSW_SAT : 0));
1397
1398 /* Handle saturated results. */
0e4ccc58 1399 if (sat && s)
dca41ba7
JL
1400 State.regs[OP[1]] = 0x80000000;
1401 else if (sat)
1402 State.regs[OP[1]] = 0x7fffffff;
ead4a3f1 1403 trace_output (OP_IMM_REG);
70caad98
NC
1404
1405 return 2;
dca41ba7
JL
1406}
1407
1408/* satsub reg1, reg2 */
70caad98
NC
1409/* sxb reg1 */
1410int
dca41ba7
JL
1411OP_A0 ()
1412{
70caad98
NC
1413/* start-sanitize-v850e */
1414 if (OP[1] == 0)
1415 {
1416 trace_input ("sxb", OP_REG, 0);
dca41ba7 1417
70caad98 1418 State.regs[ OP[0] ] = SEXT8 (State.regs[ OP[0] ]);
dca41ba7 1419
70caad98
NC
1420 trace_output (OP_REG);
1421 }
1422 else
1423/* end-sanitize-v850e */
1424 {
1425 unsigned int op0, op1, result, z, s, cy, ov, sat;
1426
1427 trace_input ("satsub", OP_REG_REG, 0);
1428
1429 /* Compute the result. */
1430 op0 = State.regs[ OP[0] ];
1431 op1 = State.regs[ OP[1] ];
1432 result = op1 - op0;
1433
1434 /* Compute the condition codes. */
1435 z = (result == 0);
1436 s = (result & 0x80000000);
1437 cy = (op1 < op0);
1438 ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
1439 && (op1 & 0x80000000) != (result & 0x80000000));
1440 sat = ov;
1441
1442 /* Store the result and condition codes. */
1443 State.regs[OP[1]] = result;
1444 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1445 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1446 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
1447 | (sat ? PSW_SAT : 0));
1448
1449 /* Handle saturated results. */
1450 if (sat && s)
1451 State.regs[OP[1]] = 0x80000000;
1452 else if (sat)
1453 State.regs[OP[1]] = 0x7fffffff;
1454 trace_output (OP_REG_REG);
1455 }
dca41ba7 1456
70caad98 1457 return 2;
dca41ba7
JL
1458}
1459
1460/* satsubi sign_extend(imm16), reg */
70caad98 1461int
dca41ba7
JL
1462OP_660 ()
1463{
1464 unsigned int op0, op1, result, z, s, cy, ov, sat;
1465 int temp;
1466
ead4a3f1
MM
1467 trace_input ("satsubi", OP_IMM_REG, 0);
1468
dca41ba7 1469 /* Compute the result. */
70caad98 1470 temp = SEXT16 (OP[2]);
dca41ba7 1471 op0 = temp;
70caad98 1472 op1 = State.regs[ OP[0] ];
dca41ba7
JL
1473 result = op1 - op0;
1474
1475 /* Compute the condition codes. */
1476 z = (result == 0);
1477 s = (result & 0x80000000);
d81352b8 1478 cy = (op1 < op0);
dca41ba7
JL
1479 ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
1480 && (op1 & 0x80000000) != (result & 0x80000000));
1481 sat = ov;
1482
1483 /* Store the result and condition codes. */
1484 State.regs[OP[1]] = result;
ee3f2d4f
MM
1485 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1486 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
dca41ba7
JL
1487 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
1488 | (sat ? PSW_SAT : 0));
1489
1490 /* Handle saturated results. */
0e4ccc58 1491 if (sat && s)
dca41ba7
JL
1492 State.regs[OP[1]] = 0x80000000;
1493 else if (sat)
1494 State.regs[OP[1]] = 0x7fffffff;
ead4a3f1 1495 trace_output (OP_IMM_REG);
70caad98
NC
1496
1497 return 4;
dca41ba7
JL
1498}
1499
ead4a3f1 1500/* satsubr reg,reg */
70caad98
NC
1501/* zxb reg1 */
1502int
dca41ba7
JL
1503OP_80 ()
1504{
70caad98
NC
1505/* start-sanitize-v850e */
1506 if (OP[1] == 0)
1507 {
1508 trace_input ("zxb", OP_REG, 0);
dca41ba7 1509
70caad98 1510 State.regs[ OP[0] ] &= 0xff;
dca41ba7 1511
70caad98
NC
1512 trace_output (OP_REG);
1513 }
1514 else
1515/* end-sanitize-v850e */
1516 {
1517 unsigned int op0, op1, result, z, s, cy, ov, sat;
1518
1519 trace_input ("satsubr", OP_REG_REG, 0);
1520
1521 /* Compute the result. */
1522 op0 = State.regs[ OP[0] ];
1523 op1 = State.regs[ OP[1] ];
1524 result = op0 - op1;
1525
1526 /* Compute the condition codes. */
1527 z = (result == 0);
1528 s = (result & 0x80000000);
1529 cy = (result < op0);
1530 ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
1531 && (op1 & 0x80000000) != (result & 0x80000000));
1532 sat = ov;
1533
1534 /* Store the result and condition codes. */
1535 State.regs[OP[1]] = result;
1536 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
1537 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
1538 | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
1539 | (sat ? PSW_SAT : 0));
1540
1541 /* Handle saturated results. */
1542 if (sat && s)
1543 State.regs[OP[1]] = 0x80000000;
1544 else if (sat)
1545 State.regs[OP[1]] = 0x7fffffff;
1546 trace_output (OP_REG_REG);
1547 }
dca41ba7 1548
70caad98 1549 return 2;
dca41ba7
JL
1550}
1551
3095b8df 1552/* tst reg,reg */
70caad98 1553int
3095b8df
JL
1554OP_160 ()
1555{
9fca2fd3 1556 unsigned int op0, op1, result, z, s;
3095b8df 1557
ead4a3f1
MM
1558 trace_input ("tst", OP_REG_REG_CMP, 0);
1559
3095b8df 1560 /* Compute the result. */
70caad98
NC
1561 op0 = State.regs[ OP[0] ];
1562 op1 = State.regs[ OP[1] ];
3095b8df
JL
1563 result = op0 & op1;
1564
1565 /* Compute the condition codes. */
1566 z = (result == 0);
1567 s = (result & 0x80000000);
1568
1569 /* Store the condition codes. */
ee3f2d4f
MM
1570 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1571 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
ead4a3f1 1572 trace_output (OP_REG_REG_CMP);
70caad98
NC
1573
1574 return 2;
3095b8df
JL
1575}
1576
1fe983dc 1577/* mov reg, reg */
70caad98 1578int
22c1c7dd
JL
1579OP_0 ()
1580{
ead4a3f1 1581 trace_input ("mov", OP_REG_REG_MOVE, 0);
70caad98
NC
1582
1583 State.regs[ OP[1] ] = State.regs[ OP[0] ];
1584
ead4a3f1 1585 trace_output (OP_REG_REG_MOVE);
70caad98
NC
1586
1587 return 2;
22c1c7dd
JL
1588}
1589
1fe983dc 1590/* mov sign_extend(imm5), reg */
70caad98
NC
1591/* callt imm6 */
1592int
1fe983dc 1593OP_200 ()
22c1c7dd 1594{
70caad98
NC
1595/* start-sanitize-v850e */
1596 if (OP[1] == 0)
1597 {
1598 unsigned long adr;
1599
1600 trace_input ("callt", OP_LOAD16, 1);
1601
1602 CTPC = PC + 2;
1603 CTPSW = PSW;
1604
1605 adr = CTBP + ((OP[3] & 0x3f) << 1);
1606
1607 PC = CTBP + load_mem (adr, 1);
1608
1609 trace_output (OP_LOAD16);
1610
1611 return 0;
1612 }
1613 else
1614/* end-sanitize-v850e */
1615 {
1616 int value = SEXT5 (OP[0]);
1fe983dc 1617
70caad98
NC
1618 trace_input ("mov", OP_IMM_REG_MOVE, 0);
1619
1620 State.regs[ OP[1] ] = value;
1621
1622 trace_output (OP_IMM_REG_MOVE);
1623
1624 return 2;
1625 }
22c1c7dd
JL
1626}
1627
70caad98 1628/* mov imm32, reg1 */
1fe983dc 1629/* movea sign_extend(imm16), reg, reg */
70caad98 1630int
1fe983dc 1631OP_620 ()
22c1c7dd 1632{
70caad98
NC
1633/* start-sanitize-v850e */
1634 if (OP[1] == 0)
1635 {
1636 trace_input ("mov", OP_IMM32_REG, 4);
1fe983dc 1637
70caad98
NC
1638 State.regs[ OP[0] ] = load_mem (PC + 2, 4);
1639
1640 trace_output (OP_IMM32_REG);
1641
1642 return 6;
1643 }
1644 else
1645/* end-sanitize-v850e */
1646 {
1647 trace_input ("movea", OP_IMM_REG_REG, 0);
1648
1649 State.regs[ OP[1] ] = State.regs[ OP[0] ] + SEXT16 (OP[2]);
1650
1651 trace_output (OP_IMM_REG_REG);
1652
1653 return 4;
1654 }
22c1c7dd
JL
1655}
1656
70caad98 1657/* dispose imm5, list12 [, reg1] */
1fe983dc 1658/* movhi imm16, reg, reg */
70caad98 1659int
1fe983dc 1660OP_640 ()
22c1c7dd 1661{
70caad98 1662/* start-sanitize-v850e */
1fe983dc 1663
70caad98
NC
1664 if (OP[1] == 0)
1665 {
1666 int i;
1667
1668 trace_input ("dispose", OP_PUSHPOP1, 0);
1669
1670 SP += (OP[3] & 0x3e) << 1;
1671
60616228
NC
1672 /* Load the registers with lower number registers being retrieved from higher addresses. */
1673 for (i = 12; i--;)
70caad98
NC
1674 if ((OP[3] & (1 << type1_regs[ i ])))
1675 {
1676 State.regs[ 20 + i ] = load_mem (SP, 4);
1677 SP += 4;
1678 }
1679
1680 if ((OP[3] & 0x1f0000) != 0)
1681 {
1682 PC = State.regs[ (OP[3] >> 16) & 0x1f];
1683 return 0;
1684 }
1685
1686 trace_output (OP_PUSHPOP1);
1687 }
1688 else
1689/* end-sanitize-v850e */
1690 {
1691 trace_input ("movhi", OP_UIMM_REG_REG, 16);
1692
1693 State.regs[ OP[1] ] = State.regs[ OP[0] ] + OP[2] << 16;
1694
1695 trace_output (OP_UIMM_REG_REG);
1696 }
1697
1698 return 4;
22c1c7dd
JL
1699}
1700
35404c7d 1701/* sar zero_extend(imm5),reg1 */
70caad98 1702int
77553374 1703OP_2A0 ()
22c1c7dd 1704{
9fca2fd3 1705 unsigned int op0, op1, result, z, s, cy;
77553374 1706
ead4a3f1 1707 trace_input ("sar", OP_IMM_REG, 0);
70caad98
NC
1708 op0 = OP[0];
1709 op1 = State.regs[ OP[1] ];
35404c7d 1710 result = (signed)op1 >> op0;
77553374 1711
35404c7d
JL
1712 /* Compute the condition codes. */
1713 z = (result == 0);
1714 s = (result & 0x80000000);
1715 cy = (op1 & (1 << (op0 - 1)));
22c1c7dd 1716
35404c7d 1717 /* Store the result and condition codes. */
70caad98 1718 State.regs[ OP[1] ] = result;
ee3f2d4f
MM
1719 PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1720 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
9fca2fd3 1721 | (cy ? PSW_CY : 0));
ead4a3f1 1722 trace_output (OP_IMM_REG);
70caad98
NC
1723
1724 return 2;
35404c7d 1725}
77553374 1726
35404c7d 1727/* sar reg1, reg2 */
70caad98 1728int
77553374 1729OP_A007E0 ()
22c1c7dd 1730{
9fca2fd3 1731 unsigned int op0, op1, result, z, s, cy;
77553374 1732
ead4a3f1 1733 trace_input ("sar", OP_REG_REG, 0);
70caad98
NC
1734
1735 op0 = State.regs[ OP[0] ] & 0x1f;
1736 op1 = State.regs[ OP[1] ];
35404c7d 1737 result = (signed)op1 >> op0;
77553374 1738
35404c7d
JL
1739 /* Compute the condition codes. */
1740 z = (result == 0);
1741 s = (result & 0x80000000);
1742 cy = (op1 & (1 << (op0 - 1)));
22c1c7dd 1743
35404c7d
JL
1744 /* Store the result and condition codes. */
1745 State.regs[OP[1]] = result;
ee3f2d4f
MM
1746 PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1747 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
35404c7d 1748 | (cy ? PSW_CY : 0));
ead4a3f1 1749 trace_output (OP_REG_REG);
70caad98
NC
1750
1751 return 4;
35404c7d 1752}
77553374 1753
35404c7d 1754/* shl zero_extend(imm5),reg1 */
70caad98 1755int
22c1c7dd 1756OP_2C0 ()
77553374 1757{
9fca2fd3 1758 unsigned int op0, op1, result, z, s, cy;
35404c7d 1759
ead4a3f1 1760 trace_input ("shl", OP_IMM_REG, 0);
70caad98
NC
1761 op0 = OP[0];
1762 op1 = State.regs[ OP[1] ];
35404c7d
JL
1763 result = op1 << op0;
1764
1765 /* Compute the condition codes. */
1766 z = (result == 0);
1767 s = (result & 0x80000000);
1768 cy = (op1 & (1 << (32 - op0)));
77553374 1769
35404c7d
JL
1770 /* Store the result and condition codes. */
1771 State.regs[OP[1]] = result;
ee3f2d4f
MM
1772 PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1773 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
35404c7d 1774 | (cy ? PSW_CY : 0));
ead4a3f1 1775 trace_output (OP_IMM_REG);
70caad98
NC
1776
1777 return 2;
35404c7d 1778}
77553374 1779
35404c7d 1780/* shl reg1, reg2 */
70caad98 1781int
77553374
JL
1782OP_C007E0 ()
1783{
9fca2fd3 1784 unsigned int op0, op1, result, z, s, cy;
77553374 1785
ead4a3f1 1786 trace_input ("shl", OP_REG_REG, 0);
70caad98
NC
1787 op0 = State.regs[ OP[0] ] & 0x1f;
1788 op1 = State.regs[ OP[1] ];
35404c7d
JL
1789 result = op1 << op0;
1790
1791 /* Compute the condition codes. */
1792 z = (result == 0);
1793 s = (result & 0x80000000);
1794 cy = (op1 & (1 << (32 - op0)));
1795
1796 /* Store the result and condition codes. */
1797 State.regs[OP[1]] = result;
ee3f2d4f
MM
1798 PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1799 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
35404c7d 1800 | (cy ? PSW_CY : 0));
ead4a3f1 1801 trace_output (OP_REG_REG);
70caad98
NC
1802
1803 return 4;
35404c7d 1804}
77553374 1805
35404c7d 1806/* shr zero_extend(imm5),reg1 */
70caad98 1807int
77553374
JL
1808OP_280 ()
1809{
9fca2fd3 1810 unsigned int op0, op1, result, z, s, cy;
77553374 1811
ead4a3f1 1812 trace_input ("shr", OP_IMM_REG, 0);
70caad98
NC
1813 op0 = OP[0];
1814 op1 = State.regs[ OP[1] ];
35404c7d 1815 result = op1 >> op0;
77553374 1816
35404c7d
JL
1817 /* Compute the condition codes. */
1818 z = (result == 0);
1819 s = (result & 0x80000000);
1820 cy = (op1 & (1 << (op0 - 1)));
1821
1822 /* Store the result and condition codes. */
1823 State.regs[OP[1]] = result;
ee3f2d4f
MM
1824 PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1825 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
35404c7d 1826 | (cy ? PSW_CY : 0));
ead4a3f1 1827 trace_output (OP_IMM_REG);
70caad98
NC
1828
1829 return 2;
35404c7d
JL
1830}
1831
1832/* shr reg1, reg2 */
70caad98 1833int
77553374
JL
1834OP_8007E0 ()
1835{
9fca2fd3 1836 unsigned int op0, op1, result, z, s, cy;
35404c7d 1837
ead4a3f1 1838 trace_input ("shr", OP_REG_REG, 0);
70caad98
NC
1839 op0 = State.regs[ OP[0] ] & 0x1f;
1840 op1 = State.regs[ OP[1] ];
35404c7d
JL
1841 result = op1 >> op0;
1842
1843 /* Compute the condition codes. */
1844 z = (result == 0);
1845 s = (result & 0x80000000);
1846 cy = (op1 & (1 << (op0 - 1)));
1847
1848 /* Store the result and condition codes. */
1849 State.regs[OP[1]] = result;
ee3f2d4f
MM
1850 PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
1851 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
35404c7d 1852 | (cy ? PSW_CY : 0));
ead4a3f1 1853 trace_output (OP_REG_REG);
70caad98
NC
1854
1855 return 4;
77553374
JL
1856}
1857
0ef0eba5 1858/* or reg, reg */
70caad98 1859int
1fe983dc
JL
1860OP_100 ()
1861{
9fca2fd3 1862 unsigned int op0, op1, result, z, s;
1fe983dc 1863
ead4a3f1
MM
1864 trace_input ("or", OP_REG_REG, 0);
1865
0ef0eba5 1866 /* Compute the result. */
70caad98
NC
1867 op0 = State.regs[ OP[0] ];
1868 op1 = State.regs[ OP[1] ];
0ef0eba5 1869 result = op0 | op1;
1fe983dc 1870
0ef0eba5
JL
1871 /* Compute the condition codes. */
1872 z = (result == 0);
1873 s = (result & 0x80000000);
1874
1875 /* Store the result and condition codes. */
1876 State.regs[OP[1]] = result;
ee3f2d4f
MM
1877 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1878 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
ead4a3f1 1879 trace_output (OP_REG_REG);
70caad98
NC
1880
1881 return 2;
0ef0eba5
JL
1882}
1883
1884/* ori zero_extend(imm16), reg, reg */
70caad98 1885int
1fe983dc
JL
1886OP_680 ()
1887{
9fca2fd3 1888 unsigned int op0, op1, result, z, s;
1fe983dc 1889
ead4a3f1 1890 trace_input ("ori", OP_UIMM_REG_REG, 0);
70caad98
NC
1891 op0 = OP[2];
1892 op1 = State.regs[ OP[0] ];
0ef0eba5 1893 result = op0 | op1;
1fe983dc 1894
0ef0eba5
JL
1895 /* Compute the condition codes. */
1896 z = (result == 0);
1897 s = (result & 0x80000000);
1fe983dc 1898
0ef0eba5 1899 /* Store the result and condition codes. */
70caad98 1900 State.regs[OP[1]] = result;
ee3f2d4f
MM
1901 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1902 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
ead4a3f1 1903 trace_output (OP_UIMM_REG_REG);
70caad98
NC
1904
1905 return 4;
0ef0eba5
JL
1906}
1907
1908/* and reg, reg */
70caad98 1909int
22c1c7dd
JL
1910OP_140 ()
1911{
9fca2fd3 1912 unsigned int op0, op1, result, z, s;
22c1c7dd 1913
ead4a3f1
MM
1914 trace_input ("and", OP_REG_REG, 0);
1915
0ef0eba5 1916 /* Compute the result. */
70caad98
NC
1917 op0 = State.regs[ OP[0] ];
1918 op1 = State.regs[ OP[1] ];
0ef0eba5 1919 result = op0 & op1;
1fe983dc 1920
0ef0eba5
JL
1921 /* Compute the condition codes. */
1922 z = (result == 0);
1923 s = (result & 0x80000000);
1924
1925 /* Store the result and condition codes. */
1926 State.regs[OP[1]] = result;
ee3f2d4f
MM
1927 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1928 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
ead4a3f1 1929 trace_output (OP_REG_REG);
70caad98
NC
1930
1931 return 2;
0ef0eba5
JL
1932}
1933
1934/* andi zero_extend(imm16), reg, reg */
70caad98 1935int
1fe983dc
JL
1936OP_6C0 ()
1937{
70caad98 1938 unsigned int result, z;
1fe983dc 1939
ead4a3f1 1940 trace_input ("andi", OP_UIMM_REG_REG, 0);
70caad98
NC
1941
1942 result = OP[2] & State.regs[ OP[0] ];
1fe983dc 1943
0ef0eba5
JL
1944 /* Compute the condition codes. */
1945 z = (result == 0);
1fe983dc 1946
0ef0eba5 1947 /* Store the result and condition codes. */
70caad98
NC
1948 State.regs[ OP[1] ] = result;
1949
ee3f2d4f
MM
1950 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1951 PSW |= (z ? PSW_Z : 0);
70caad98 1952
ead4a3f1 1953 trace_output (OP_UIMM_REG_REG);
70caad98
NC
1954
1955 return 4;
0ef0eba5
JL
1956}
1957
1958/* xor reg, reg */
70caad98 1959int
1fe983dc 1960OP_120 ()
22c1c7dd 1961{
9fca2fd3 1962 unsigned int op0, op1, result, z, s;
1fe983dc 1963
ead4a3f1
MM
1964 trace_input ("xor", OP_REG_REG, 0);
1965
0ef0eba5 1966 /* Compute the result. */
70caad98
NC
1967 op0 = State.regs[ OP[0] ];
1968 op1 = State.regs[ OP[1] ];
0ef0eba5 1969 result = op0 ^ op1;
1fe983dc 1970
0ef0eba5
JL
1971 /* Compute the condition codes. */
1972 z = (result == 0);
1973 s = (result & 0x80000000);
1974
1975 /* Store the result and condition codes. */
1976 State.regs[OP[1]] = result;
ee3f2d4f
MM
1977 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
1978 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
ead4a3f1 1979 trace_output (OP_REG_REG);
70caad98
NC
1980
1981 return 2;
0ef0eba5
JL
1982}
1983
1984/* xori zero_extend(imm16), reg, reg */
70caad98 1985int
1fe983dc
JL
1986OP_6A0 ()
1987{
9fca2fd3 1988 unsigned int op0, op1, result, z, s;
0ef0eba5 1989
ead4a3f1 1990 trace_input ("xori", OP_UIMM_REG_REG, 0);
70caad98
NC
1991 op0 = OP[2];
1992 op1 = State.regs[ OP[0] ];
0ef0eba5
JL
1993 result = op0 ^ op1;
1994
1995 /* Compute the condition codes. */
1996 z = (result == 0);
1997 s = (result & 0x80000000);
1998
1999 /* Store the result and condition codes. */
70caad98 2000 State.regs[OP[1]] = result;
ee3f2d4f
MM
2001 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2002 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
ead4a3f1 2003 trace_output (OP_UIMM_REG_REG);
70caad98
NC
2004
2005 return 4;
0ef0eba5
JL
2006}
2007
2008/* not reg1, reg2 */
70caad98 2009int
0ef0eba5
JL
2010OP_20 ()
2011{
9fca2fd3 2012 unsigned int op0, result, z, s;
0ef0eba5 2013
ead4a3f1 2014 trace_input ("not", OP_REG_REG_MOVE, 0);
0ef0eba5 2015 /* Compute the result. */
70caad98 2016 op0 = State.regs[ OP[0] ];
0ef0eba5
JL
2017 result = ~op0;
2018
2019 /* Compute the condition codes. */
2020 z = (result == 0);
2021 s = (result & 0x80000000);
1fe983dc 2022
0ef0eba5
JL
2023 /* Store the result and condition codes. */
2024 State.regs[OP[1]] = result;
ee3f2d4f
MM
2025 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2026 PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
ead4a3f1 2027 trace_output (OP_REG_REG_MOVE);
70caad98
NC
2028
2029 return 2;
22c1c7dd
JL
2030}
2031
28647e4c 2032/* set1 */
70caad98 2033int
28647e4c 2034OP_7C0 ()
1fe983dc 2035{
83fc3bac 2036 unsigned int op0, op1, op2;
9fca2fd3 2037 int temp;
83fc3bac 2038
ead4a3f1 2039 trace_input ("set1", OP_BIT, 0);
70caad98 2040 op0 = State.regs[ OP[0] ];
83fc3bac 2041 op1 = OP[1] & 0x7;
ead4a3f1 2042 temp = SEXT16 (OP[2]);
83fc3bac 2043 op2 = temp;
96851909 2044 temp = load_mem (op0 + op2, 1);
ee3f2d4f 2045 PSW &= ~PSW_Z;
83fc3bac 2046 if ((temp & (1 << op1)) == 0)
ee3f2d4f 2047 PSW |= PSW_Z;
787d66bb 2048 temp |= (1 << op1);
96851909 2049 store_mem (op0 + op2, 1, temp);
ead4a3f1 2050 trace_output (OP_BIT);
70caad98
NC
2051
2052 return 4;
1fe983dc
JL
2053}
2054
28647e4c 2055/* not1 */
70caad98 2056int
28647e4c 2057OP_47C0 ()
1fe983dc 2058{
83fc3bac 2059 unsigned int op0, op1, op2;
9fca2fd3 2060 int temp;
83fc3bac 2061
ead4a3f1 2062 trace_input ("not1", OP_BIT, 0);
70caad98 2063 op0 = State.regs[ OP[0] ];
83fc3bac 2064 op1 = OP[1] & 0x7;
ead4a3f1 2065 temp = SEXT16 (OP[2]);
83fc3bac 2066 op2 = temp;
96851909 2067 temp = load_mem (op0 + op2, 1);
ee3f2d4f 2068 PSW &= ~PSW_Z;
83fc3bac 2069 if ((temp & (1 << op1)) == 0)
ee3f2d4f 2070 PSW |= PSW_Z;
787d66bb 2071 temp ^= (1 << op1);
96851909 2072 store_mem (op0 + op2, 1, temp);
ead4a3f1 2073 trace_output (OP_BIT);
70caad98
NC
2074
2075 return 4;
1fe983dc
JL
2076}
2077
28647e4c 2078/* clr1 */
70caad98 2079int
28647e4c
JL
2080OP_87C0 ()
2081{
83fc3bac 2082 unsigned int op0, op1, op2;
9fca2fd3 2083 int temp;
83fc3bac 2084
ead4a3f1 2085 trace_input ("clr1", OP_BIT, 0);
70caad98 2086 op0 = State.regs[ OP[0] ];
83fc3bac 2087 op1 = OP[1] & 0x7;
ead4a3f1 2088 temp = SEXT16 (OP[2]);
83fc3bac 2089 op2 = temp;
96851909 2090 temp = load_mem (op0 + op2, 1);
ee3f2d4f 2091 PSW &= ~PSW_Z;
83fc3bac 2092 if ((temp & (1 << op1)) == 0)
ee3f2d4f 2093 PSW |= PSW_Z;
83fc3bac 2094 temp &= ~(1 << op1);
96851909 2095 store_mem (op0 + op2, 1, temp);
ead4a3f1 2096 trace_output (OP_BIT);
70caad98
NC
2097
2098 return 4;
28647e4c
JL
2099}
2100
2101/* tst1 */
70caad98 2102int
28647e4c 2103OP_C7C0 ()
1fe983dc 2104{
83fc3bac 2105 unsigned int op0, op1, op2;
9fca2fd3 2106 int temp;
83fc3bac 2107
ead4a3f1 2108 trace_input ("tst1", OP_BIT, 0);
70caad98 2109 op0 = State.regs[ OP[0] ];
83fc3bac 2110 op1 = OP[1] & 0x7;
ead4a3f1 2111 temp = SEXT16 (OP[2]);
83fc3bac 2112 op2 = temp;
96851909 2113 temp = load_mem (op0 + op2, 1);
ee3f2d4f 2114 PSW &= ~PSW_Z;
83fc3bac 2115 if ((temp & (1 << op1)) == 0)
ee3f2d4f 2116 PSW |= PSW_Z;
ead4a3f1 2117 trace_output (OP_BIT);
70caad98
NC
2118
2119 return 4;
1fe983dc 2120}
e98e3b2c 2121
88777ce2 2122/* breakpoint */
70caad98 2123int
88777ce2
SG
2124OP_FFFF ()
2125{
2126 State.exception = SIGTRAP;
70caad98 2127 return -4;
88777ce2
SG
2128}
2129
3095b8df 2130/* di */
70caad98 2131int
e98e3b2c
JL
2132OP_16007E0 ()
2133{
ead4a3f1 2134 trace_input ("di", OP_NONE, 0);
ee3f2d4f 2135 PSW |= PSW_ID;
ead4a3f1 2136 trace_output (OP_NONE);
70caad98
NC
2137
2138 return 4;
e98e3b2c
JL
2139}
2140
3095b8df 2141/* ei */
70caad98 2142int
e98e3b2c
JL
2143OP_16087E0 ()
2144{
ead4a3f1 2145 trace_input ("ei", OP_NONE, 0);
ee3f2d4f 2146 PSW &= ~PSW_ID;
ead4a3f1 2147 trace_output (OP_NONE);
70caad98
NC
2148
2149 return 4;
e98e3b2c
JL
2150}
2151
ee3f2d4f 2152/* halt */
70caad98 2153int
e98e3b2c
JL
2154OP_12007E0 ()
2155{
ead4a3f1 2156 trace_input ("halt", OP_NONE, 0);
ee3f2d4f 2157 /* FIXME this should put processor into a mode where NMI still handled */
d81352b8 2158 State.exception = SIGQUIT;
ead4a3f1 2159 trace_output (OP_NONE);
70caad98
NC
2160
2161 return 4;
e98e3b2c
JL
2162}
2163
ee3f2d4f 2164/* reti */
70caad98 2165int
e98e3b2c
JL
2166OP_14007E0 ()
2167{
ead4a3f1
MM
2168 trace_input ("reti", OP_NONE, 0);
2169 trace_output (OP_NONE);
96851909 2170
ee3f2d4f
MM
2171 /* Restore for NMI if only NP on, otherwise is interrupt or exception. */
2172 if ((PSW & (PSW_NP | PSW_EP)) == PSW_NP)
2173 {
2174 PC = FEPC - 4;
2175 PSW = FEPSW;
96851909
SG
2176 }
2177 else
2178 {
ee3f2d4f
MM
2179 PC = EIPC - 4;
2180 PSW = EIPSW;
96851909 2181 }
70caad98
NC
2182
2183 return 0;
e98e3b2c
JL
2184}
2185
ee3f2d4f 2186/* trap */
70caad98 2187int
e98e3b2c
JL
2188OP_10007E0 ()
2189{
ead4a3f1
MM
2190 trace_input ("trap", OP_TRAP, 0);
2191 trace_output (OP_TRAP);
2192
96851909 2193 /* Trap 31 is used for simulating OS I/O functions */
d81352b8 2194
96851909 2195 if (OP[0] == 31)
d81352b8 2196 {
d81352b8
JL
2197 int save_errno = errno;
2198 errno = 0;
2199
2200/* Registers passed to trap 0 */
2201
2202#define FUNC State.regs[6] /* function number, return value */
2203#define PARM1 State.regs[7] /* optional parm 1 */
2204#define PARM2 State.regs[8] /* optional parm 2 */
2205#define PARM3 State.regs[9] /* optional parm 3 */
2206
2207/* Registers set by trap 0 */
2208
2209#define RETVAL State.regs[10] /* return value */
2210#define RETERR State.regs[11] /* return error code */
2211
2212/* Turn a pointer in a register into a pointer into real memory. */
2213
96851909 2214#define MEMPTR(x) (map (x))
d81352b8
JL
2215
2216 switch (FUNC)
2217 {
d81352b8
JL
2218#if !defined(__GO32__) && !defined(_WIN32)
2219 case SYS_fork:
2220 RETVAL = fork ();
2221 break;
2222 case SYS_execve:
2223 RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
2224 (char **)MEMPTR (PARM3));
2225 break;
87e43259 2226#ifdef SYS_execv
d81352b8
JL
2227 case SYS_execv:
2228 RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL);
2229 break;
87e43259 2230#endif
9909e232 2231#if 0
d81352b8
JL
2232 case SYS_pipe:
2233 {
2234 reg_t buf;
2235 int host_fd[2];
2236
2237 buf = PARM1;
2238 RETVAL = pipe (host_fd);
2239 SW (buf, host_fd[0]);
2240 buf += sizeof(uint16);
2241 SW (buf, host_fd[1]);
2242 }
2243 break;
2244
2245 case SYS_wait:
2246 {
2247 int status;
2248
2249 RETVAL = wait (&status);
2250 SW (PARM1, status);
2251 }
2252 break;
9909e232 2253#endif
d81352b8
JL
2254#endif
2255
2256 case SYS_read:
2257 RETVAL = v850_callback->read (v850_callback, PARM1, MEMPTR (PARM2),
2258 PARM3);
2259 break;
d81352b8
JL
2260 case SYS_write:
2261 if (PARM1 == 1)
2262 RETVAL = (int)v850_callback->write_stdout (v850_callback,
2263 MEMPTR (PARM2), PARM3);
2264 else
2265 RETVAL = (int)v850_callback->write (v850_callback, PARM1,
2266 MEMPTR (PARM2), PARM3);
2267 break;
d81352b8
JL
2268 case SYS_lseek:
2269 RETVAL = v850_callback->lseek (v850_callback, PARM1, PARM2, PARM3);
2270 break;
2271 case SYS_close:
2272 RETVAL = v850_callback->close (v850_callback, PARM1);
2273 break;
2274 case SYS_open:
2275 RETVAL = v850_callback->open (v850_callback, MEMPTR (PARM1), PARM2);
2276 break;
d81352b8 2277 case SYS_exit:
6ec96a02
MM
2278 if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0)
2279 State.exception = PARM1 & 0xffff; /* get signal encoded by kill */
2280 else if (PARM1 == 0xdead)
2281 State.exception = SIGABRT; /* old libraries */
2282 else
2283 State.exception = SIG_V850_EXIT; /* PARM1 has exit status encoded */
d81352b8
JL
2284 break;
2285
87e43259 2286#if !defined(__GO32__) && !defined(_WIN32)
d81352b8
JL
2287 case SYS_stat: /* added at hmsi */
2288 /* stat system call */
2289 {
2290 struct stat host_stat;
2291 reg_t buf;
2292
2293 RETVAL = stat (MEMPTR (PARM1), &host_stat);
2294
2295 buf = PARM2;
2296
c500c074
JL
2297 /* Just wild-assed guesses. */
2298 store_mem (buf, 2, host_stat.st_dev);
2299 store_mem (buf + 2, 2, host_stat.st_ino);
2300 store_mem (buf + 4, 4, host_stat.st_mode);
2301 store_mem (buf + 8, 2, host_stat.st_nlink);
2302 store_mem (buf + 10, 2, host_stat.st_uid);
2303 store_mem (buf + 12, 2, host_stat.st_gid);
2304 store_mem (buf + 14, 2, host_stat.st_rdev);
2305 store_mem (buf + 16, 4, host_stat.st_size);
2306 store_mem (buf + 20, 4, host_stat.st_atime);
2307 store_mem (buf + 28, 4, host_stat.st_mtime);
2308 store_mem (buf + 36, 4, host_stat.st_ctime);
d81352b8
JL
2309 }
2310 break;
2311
2312 case SYS_chown:
2313 RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3);
2314 break;
2315 case SYS_chmod:
2316 RETVAL = chmod (MEMPTR (PARM1), PARM2);
2317 break;
87e43259 2318#ifdef SYS_time
6803f89b 2319 case SYS_time:
ee3f2d4f
MM
2320 {
2321 time_t now;
2322 RETVAL = time (&now);
2323 store_mem (PARM1, 4, now);
2324 }
6803f89b 2325 break;
87e43259
AC
2326#endif
2327#ifdef SYS_times
8824fb45
JL
2328 case SYS_times:
2329 {
2330 struct tms tms;
2331 RETVAL = times (&tms);
2332 store_mem (PARM1, 4, tms.tms_utime);
2333 store_mem (PARM1 + 4, 4, tms.tms_stime);
2334 store_mem (PARM1 + 8, 4, tms.tms_cutime);
2335 store_mem (PARM1 + 12, 4, tms.tms_cstime);
2336 break;
2337 }
87e43259 2338#endif
8824fb45
JL
2339 case SYS_gettimeofday:
2340 {
2341 struct timeval t;
2342 struct timezone tz;
2343 RETVAL = gettimeofday (&t, &tz);
2344 store_mem (PARM1, 4, t.tv_sec);
2345 store_mem (PARM1 + 4, 4, t.tv_usec);
2346 store_mem (PARM2, 4, tz.tz_minuteswest);
2347 store_mem (PARM2 + 4, 4, tz.tz_dsttime);
2348 break;
2349 }
87e43259 2350#ifdef SYS_utime
d81352b8
JL
2351 case SYS_utime:
2352 /* Cast the second argument to void *, to avoid type mismatch
2353 if a prototype is present. */
2354 RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2));
2355 break;
87e43259
AC
2356#endif
2357#endif
d81352b8
JL
2358 default:
2359 abort ();
2360 }
2361 RETERR = errno;
2362 errno = save_errno;
70caad98
NC
2363
2364 return 4;
d81352b8 2365 }
96851909
SG
2366 else
2367 { /* Trap 0 -> 30 */
ee3f2d4f
MM
2368 EIPC = PC + 4;
2369 EIPSW = PSW;
2370 /* Mask out EICC */
2371 ECR &= 0xffff0000;
2372 ECR |= 0x40 + OP[0];
2373 /* Flag that we are now doing exception processing. */
2374 PSW |= PSW_EP | PSW_ID;
96851909 2375 PC = ((OP[0] < 0x10) ? 0x40 : 0x50) - 4;
70caad98
NC
2376
2377 return 0;
d81352b8 2378 }
e98e3b2c
JL
2379}
2380
614f1c68 2381/* ldsr, reg,reg */
70caad98 2382int
e98e3b2c
JL
2383OP_2007E0 ()
2384{
ead4a3f1 2385 trace_input ("ldsr", OP_LDSR, 0);
70caad98
NC
2386
2387 State.sregs[ OP[1] ] = State.regs[ OP[0] ];
2388
ead4a3f1 2389 trace_output (OP_LDSR);
70caad98
NC
2390
2391 return 4;
e98e3b2c
JL
2392}
2393
ee3f2d4f 2394/* stsr */
70caad98 2395int
e98e3b2c
JL
2396OP_4007E0 ()
2397{
614f1c68
JL
2398 unsigned int op0;
2399
ead4a3f1 2400 trace_input ("stsr", OP_STSR, 0);
70caad98
NC
2401
2402 State.regs[ OP[1] ] = State.sregs[ OP[0] ];
2403
ead4a3f1 2404 trace_output (OP_STSR);
70caad98
NC
2405
2406 return 4;
2407}
2408
2409/* tst1 reg2, [reg1] */
2410int
2411OP_E607E0 (void)
2412{
2413 int temp;
2414
2415 trace_input ("tst1", OP_BIT_LOAD, 1);
2416
2417 temp = load_mem (State.regs[ OP[0] ], 1);
2418
2419 PSW &= ~PSW_Z;
2420 if ((temp & (1 << State.regs[ OP[1] & 0x7 ])) == 0)
2421 PSW |= PSW_Z;
2422
2423 trace_output (OP_BIT_LOAD);
2424
2425 return 4;
2426}
2427
64ad9cec
NC
2428/* mulu reg1, reg2, reg3 */
2429int
2430OP_22207E0 (void)
2431{
2432 trace_input ("mulu", OP_REG_REG_REG, 0);
2433
2434 Multiply64 (false, State.regs[ OP[0] ]);
2435
2436 trace_output (OP_REG_REG_REG);
2437
2438 return 4;
2439}
2440
70caad98
NC
2441/* start-sanitize-v850e */
2442
2443#define BIT_CHANGE_OP( name, binop ) \
2444 unsigned int bit; \
2445 unsigned int temp; \
2446 \
2447 trace_input (name, OP_BIT_CHANGE, 0); \
2448 \
2449 bit = 1 << State.regs[ OP[1] & 0x7 ]; \
2450 temp = load_mem (State.regs[ OP[0] ], 1); \
2451 \
2452 PSW &= ~PSW_Z; \
2453 if ((temp & bit) == 0) \
2454 PSW |= PSW_Z; \
2455 temp binop bit; \
2456 \
2457 store_mem (State.regs[ OP[0] ], 1, temp); \
2458 \
2459 trace_output (OP_BIT_CHANGE); \
2460 \
2461 return 4;
2462
2463/* clr1 reg2, [reg1] */
2464int
2465OP_E407E0 (void)
2466{
2467 BIT_CHANGE_OP ("clr1", &= ~ );
2468}
2469
2470/* not1 reg2, [reg1] */
2471int
2472OP_E207E0 (void)
2473{
2474 BIT_CHANGE_OP ("not1", ^= );
e98e3b2c 2475}
70caad98
NC
2476
2477/* set1 */
2478int
2479OP_E007E0 (void)
2480{
2481 BIT_CHANGE_OP ("set1", |= );
2482}
2483
2484/* sasf */
2485int
2486OP_20007E0 (void)
2487{
2488 trace_input ("sasf", OP_EX1, 0);
2489
2490 State.regs[ OP[1] ] = (State.regs[ OP[1] ] << 1) | condition_met (OP[0]);
2491
2492 trace_output (OP_EX1);
2493
2494 return 4;
2495}
2496/* end-sanitize-v850e */
2497
2498/* start-sanitize-v850eq */
64ad9cec
NC
2499/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
2500static void
2501divun
2502(
2503 unsigned int N,
2504 unsigned long int als,
2505 unsigned long int sfi,
2506 unsigned long int * quotient_ptr,
2507 unsigned long int * remainder_ptr,
2508 boolean * overflow_ptr
2509)
2510{
2511 unsigned long ald = sfi >> N - 1;
2512 unsigned long alo = als;
2513 unsigned int Q = 1;
2514 unsigned int C;
2515 unsigned int S = 0;
2516 unsigned int i;
2517 unsigned int R1 = 1;
2518 unsigned int OV;
2519 unsigned int DBZ = (als == 0) ? 1 : 0;
2520 unsigned long alt = Q ? ~als : als;
2521
2522 /* 1st Loop */
2523 alo = ald + alt + Q;
2524 C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
2525 C = C ^ Q;
2526 Q = ~(C ^ S) & 1;
2527 R1 = (alo == 0) ? 0 : (R1 & Q);
2528 if ((S ^ (alo>>31)) && !C)
2529 {
2530 DBZ = 1;
2531 }
2532 S = alo >> 31;
2533 sfi = (sfi << (32-N+1)) | Q;
2534 ald = (alo << 1) | (sfi >> 31);
2535
2536 /* 2nd - N-1th Loop */
2537 for (i = 2; i < N; i++)
2538 {
2539 alt = Q ? ~als : als;
2540 alo = ald + alt + Q;
2541 C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
2542 C = C ^ Q;
2543 Q = ~(C ^ S) & 1;
2544 R1 = (alo == 0) ? 0 : (R1 & Q);
2545 if ((S ^ (alo>>31)) && !C && !DBZ)
2546 {
2547 DBZ = 1;
2548 }
2549 S = alo >> 31;
2550 sfi = (sfi << 1) | Q;
2551 ald = (alo << 1) | (sfi >> 31);
2552 }
2553
2554 /* Nth Loop */
2555 alt = Q ? ~als : als;
2556 alo = ald + alt + Q;
2557 C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
2558 C = C ^ Q;
2559 Q = ~(C ^ S) & 1;
2560 R1 = (alo == 0) ? 0 : (R1 & Q);
2561 if ((S ^ (alo>>31)) && !C)
2562 {
2563 DBZ = 1;
2564 }
2565
2566 * quotient_ptr = (sfi << 1) | Q;
2567 * remainder_ptr = Q ? alo : (alo + als);
2568 * overflow_ptr = DBZ | R1;
2569}
2570
2571/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
2572static void
2573divn
2574(
2575 unsigned int N,
2576 unsigned long int als,
2577 unsigned long int sfi,
2578 signed long int * quotient_ptr,
2579 signed long int * remainder_ptr,
2580 boolean * overflow_ptr
2581)
2582{
2583 unsigned long ald = (signed long) sfi >> (N - 1);
2584 unsigned long alo = als;
2585 unsigned int SS = als >> 31;
2586 unsigned int SD = sfi >> 31;
2587 unsigned int R1 = 1;
2588 unsigned int OV;
2589 unsigned int DBZ = als == 0 ? 1 : 0;
2590 unsigned int Q = ~(SS ^ SD) & 1;
2591 unsigned int C;
2592 unsigned int S;
2593 unsigned int i;
2594 unsigned long alt = Q ? ~als : als;
2595
2596
2597 /* 1st Loop */
2598
2599 alo = ald + alt + Q;
2600 C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
2601 Q = C ^ SS;
2602 R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
2603 S = alo >> 31;
2604 sfi = (sfi << (32-N+1)) | Q;
2605 ald = (alo << 1) | (sfi >> 31);
2606 if ((alo >> 31) ^ (ald >> 31))
2607 {
2608 DBZ = 1;
2609 }
2610
2611 /* 2nd - N-1th Loop */
2612
2613 for (i = 2; i < N; i++)
2614 {
2615 alt = Q ? ~als : als;
2616 alo = ald + alt + Q;
2617 C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
2618 Q = C ^ SS;
2619 R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
2620 S = alo >> 31;
2621 sfi = (sfi << 1) | Q;
2622 ald = (alo << 1) | (sfi >> 31);
2623 if ((alo >> 31) ^ (ald >> 31))
2624 {
2625 DBZ = 1;
2626 }
2627 }
2628
2629 /* Nth Loop */
2630 alt = Q ? ~als : als;
2631 alo = ald + alt + Q;
2632 C = (alt >> 31) & (ald >> 31) | ((alt >> 31) ^ (ald >> 31)) & (~alo >> 31);
2633 Q = C ^ SS;
2634 R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
2635 sfi = (sfi << (32-N+1));
2636 ald = alo;
2637
2638 /* End */
2639 if (alo != 0)
2640 {
2641 alt = Q ? ~als : als;
2642 alo = ald + alt + Q;
2643 }
2644 R1 = R1 & ((~alo >> 31) ^ SD);
2645 if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald;
2646 if (N != 32)
2647 ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q;
2648 else
2649 ald = sfi = sfi | Q;
2650
2651 OV = DBZ | ((alo == 0) ? 0 : R1);
2652
2653 * remainder_ptr = alo;
2654
2655 /* Adj */
2656 if ((alo != 0) && ((SS ^ SD) ^ R1) || (alo == 0) && (SS ^ R1))
2657 alo = ald + 1;
2658 else
2659 alo = ald;
2660
2661 OV = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31));
2662
2663 * quotient_ptr = alo;
2664 * overflow_ptr = OV;
2665}
2666
70caad98
NC
2667/* sdivun imm5, reg1, reg2, reg3 */
2668int
2669OP_1C207E0 (void)
2670{
64ad9cec
NC
2671 unsigned long int quotient;
2672 unsigned long int remainder;
2673 unsigned long int divide_by;
2674 unsigned long int divide_this;
2675 boolean overflow = false;
2676 unsigned int imm5;
70caad98
NC
2677
2678 trace_input ("sdivun", OP_IMM_REG_REG_REG, 0);
2679
2680 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2681
64ad9cec
NC
2682 divide_by = State.regs[ OP[0] ];
2683 divide_this = State.regs[ OP[1] ] << imm5;
70caad98 2684
64ad9cec 2685 divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 2686
64ad9cec
NC
2687 State.regs[ OP[1] ] = quotient;
2688 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
2689
2690 /* Set condition codes. */
2691 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2692
2693 if (overflow) PSW |= PSW_OV;
2694 if (quotient == 0) PSW |= PSW_Z;
60616228 2695 if (quotient & 0x80000000) PSW |= PSW_S;
70caad98
NC
2696
2697 trace_output (OP_IMM_REG_REG_REG);
2698
2699 return 4;
2700}
2701
2702/* sdivn imm5, reg1, reg2, reg3 */
2703int
2704OP_1C007E0 (void)
2705{
64ad9cec
NC
2706 signed long int quotient;
2707 signed long int remainder;
2708 signed long int divide_by;
2709 signed long int divide_this;
2710 boolean overflow = false;
2711 unsigned int imm5;
70caad98
NC
2712
2713 trace_input ("sdivn", OP_IMM_REG_REG_REG, 0);
2714
2715 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2716
64ad9cec
NC
2717 divide_by = State.regs[ OP[0] ];
2718 divide_this = State.regs[ OP[1] ] << imm5;
70caad98 2719
64ad9cec 2720 divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 2721
64ad9cec
NC
2722 State.regs[ OP[1] ] = quotient;
2723 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
2724
2725 /* Set condition codes. */
2726 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2727
2728 if (overflow) PSW |= PSW_OV;
2729 if (quotient == 0) PSW |= PSW_Z;
2730 if (quotient < 0) PSW |= PSW_S;
2731
2732 trace_output (OP_IMM_REG_REG_REG);
2733
2734 return 4;
2735}
2736
2737/* sdivhun imm5, reg1, reg2, reg3 */
2738int
2739OP_18207E0 (void)
2740{
64ad9cec
NC
2741 unsigned long int quotient;
2742 unsigned long int remainder;
2743 unsigned long int divide_by;
2744 unsigned long int divide_this;
2745 boolean overflow = false;
2746 unsigned int imm5;
70caad98
NC
2747
2748 trace_input ("sdivhun", OP_IMM_REG_REG_REG, 0);
2749
2750 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2751
64ad9cec
NC
2752 divide_by = State.regs[ OP[0] ] & 0xffff;
2753 divide_this = State.regs[ OP[1] ] << imm5;
70caad98 2754
64ad9cec 2755 divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 2756
64ad9cec
NC
2757 State.regs[ OP[1] ] = quotient;
2758 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
2759
2760 /* Set condition codes. */
2761 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2762
2763 if (overflow) PSW |= PSW_OV;
2764 if (quotient == 0) PSW |= PSW_Z;
60616228 2765 if (quotient & 0x80000000) PSW |= PSW_S;
70caad98
NC
2766
2767 trace_output (OP_IMM_REG_REG_REG);
2768
2769 return 4;
2770}
2771
2772/* sdivhn imm5, reg1, reg2, reg3 */
2773int
2774OP_18007E0 (void)
2775{
64ad9cec
NC
2776 signed long int quotient;
2777 signed long int remainder;
2778 signed long int divide_by;
2779 signed long int divide_this;
2780 boolean overflow = false;
2781 unsigned int imm5;
70caad98
NC
2782
2783 trace_input ("sdivhn", OP_IMM_REG_REG_REG, 0);
2784
2785 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2786
64ad9cec
NC
2787 divide_by = SEXT16 (State.regs[ OP[0] ]);
2788 divide_this = State.regs[ OP[1] ] << imm5;
70caad98 2789
64ad9cec 2790 divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 2791
64ad9cec
NC
2792 State.regs[ OP[1] ] = quotient;
2793 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
2794
2795 /* Set condition codes. */
2796 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2797
2798 if (overflow) PSW |= PSW_OV;
2799 if (quotient == 0) PSW |= PSW_Z;
2800 if (quotient < 0) PSW |= PSW_S;
2801
2802 trace_output (OP_IMM_REG_REG_REG);
2803
2804 return 4;
2805}
2806/* end-sanitize-v850eq */
2807
2808/* start-sanitize-v850e */
2809/* divu reg1, reg2, reg3 */
70caad98
NC
2810int
2811OP_2C207E0 (void)
2812{
2813 unsigned long int quotient;
2814 unsigned long int remainder;
64ad9cec
NC
2815 unsigned long int divide_by;
2816 unsigned long int divide_this;
70caad98
NC
2817 boolean overflow = false;
2818
2819 if ((OP[3] & 0x3c0000) == 0)
2820 {
2821 trace_input ("divu", OP_REG_REG_REG, 0);
2822
2823 /* Compute the result. */
2824
64ad9cec
NC
2825 divide_by = State.regs[ OP[0] ];
2826 divide_this = State.regs[ OP[1] ];
70caad98 2827
64ad9cec 2828 if (divide_by == 0)
70caad98
NC
2829 {
2830 overflow = true;
64ad9cec 2831 divide_by = 1;
70caad98
NC
2832 }
2833
64ad9cec
NC
2834 State.regs[ OP[1] ] = quotient = divide_this / divide_by;
2835 State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
70caad98
NC
2836
2837 /* Set condition codes. */
2838 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2839
2840 if (overflow) PSW |= PSW_OV;
2841 if (quotient == 0) PSW |= PSW_Z;
60616228 2842 if (quotient & 0x80000000) PSW |= PSW_S;
70caad98
NC
2843
2844 trace_output (OP_REG_REG_REG);
2845 }
2846/* start-sanitize-v850eq */
64ad9cec 2847/* divun imm5, reg1, reg2, reg3 */
70caad98
NC
2848 else
2849 {
2850 unsigned int imm5;
2851
2852 trace_input ("divun", OP_IMM_REG_REG_REG, 0);
2853
2854 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2855
64ad9cec
NC
2856 divide_by = State.regs[ OP[0] ];
2857 divide_this = State.regs[ OP[1] ];
70caad98 2858
64ad9cec 2859 divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 2860
64ad9cec
NC
2861 State.regs[ OP[1] ] = quotient;
2862 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
2863
2864 /* Set condition codes. */
2865 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2866
2867 if (overflow) PSW |= PSW_OV;
2868 if (quotient == 0) PSW |= PSW_Z;
60616228 2869 if (quotient & 0x80000000) PSW |= PSW_S;
70caad98
NC
2870
2871 trace_output (OP_IMM_REG_REG_REG);
2872 }
2873/* end-sanitize-v850eq */
2874
2875 return 4;
2876}
2877
2878/* div reg1, reg2, reg3 */
70caad98
NC
2879int
2880OP_2C007E0 (void)
2881{
2882 signed long int quotient;
2883 signed long int remainder;
64ad9cec
NC
2884 signed long int divide_by;
2885 signed long int divide_this;
70caad98
NC
2886 boolean overflow = false;
2887
2888 if ((OP[3] & 0x3c0000) == 0)
2889 {
2890 trace_input ("div", OP_REG_REG_REG, 0);
2891
2892 /* Compute the result. */
2893
64ad9cec
NC
2894 divide_by = State.regs[ OP[0] ];
2895 divide_this = State.regs[ OP[1] ];
70caad98 2896
64ad9cec 2897 if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
70caad98 2898 {
64ad9cec
NC
2899 overflow = true;
2900 divide_by = 1;
70caad98
NC
2901 }
2902
64ad9cec
NC
2903 State.regs[ OP[1] ] = quotient = divide_this / divide_by;
2904 State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
70caad98
NC
2905
2906 /* Set condition codes. */
2907 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2908
2909 if (overflow) PSW |= PSW_OV;
2910 if (quotient == 0) PSW |= PSW_Z;
2911 if (quotient < 0) PSW |= PSW_S;
2912
2913 trace_output (OP_REG_REG_REG);
2914 }
2915/* start-sanitize-v850eq */
64ad9cec 2916/* divn imm5, reg1, reg2, reg3 */
70caad98
NC
2917 else
2918 {
2919 unsigned int imm5;
2920
2921 trace_input ("divn", OP_IMM_REG_REG_REG, 0);
2922
2923 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2924
64ad9cec
NC
2925 divide_by = State.regs[ OP[0] ];
2926 divide_this = State.regs[ OP[1] ];
70caad98 2927
64ad9cec 2928 divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 2929
64ad9cec
NC
2930 State.regs[ OP[1] ] = quotient;
2931 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
2932
2933 /* Set condition codes. */
2934 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2935
2936 if (overflow) PSW |= PSW_OV;
2937 if (quotient == 0) PSW |= PSW_Z;
2938 if (quotient < 0) PSW |= PSW_S;
2939
2940 trace_output (OP_IMM_REG_REG_REG);
2941 }
2942/* end-sanitize-v850eq */
2943
2944 return 4;
2945}
2946
2947/* divhu reg1, reg2, reg3 */
70caad98
NC
2948int
2949OP_28207E0 (void)
2950{
2951 unsigned long int quotient;
2952 unsigned long int remainder;
64ad9cec
NC
2953 unsigned long int divide_by;
2954 unsigned long int divide_this;
70caad98
NC
2955 boolean overflow = false;
2956
2957 if ((OP[3] & 0x3c0000) == 0)
2958 {
2959 trace_input ("divhu", OP_REG_REG_REG, 0);
2960
2961 /* Compute the result. */
2962
64ad9cec
NC
2963 divide_by = State.regs[ OP[0] ] & 0xffff;
2964 divide_this = State.regs[ OP[1] ];
70caad98 2965
64ad9cec 2966 if (divide_by == 0)
70caad98
NC
2967 {
2968 overflow = true;
64ad9cec 2969 divide_by = 1;
70caad98
NC
2970 }
2971
64ad9cec
NC
2972 State.regs[ OP[1] ] = quotient = divide_this / divide_by;
2973 State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
70caad98
NC
2974
2975 /* Set condition codes. */
2976 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
2977
2978 if (overflow) PSW |= PSW_OV;
2979 if (quotient == 0) PSW |= PSW_Z;
60616228 2980 if (quotient & 0x80000000) PSW |= PSW_S;
70caad98
NC
2981
2982 trace_output (OP_REG_REG_REG);
2983 }
2984/* start-sanitize-v850eq */
64ad9cec 2985/* divhun imm5, reg1, reg2, reg3 */
70caad98
NC
2986 else
2987 {
2988 unsigned int imm5;
2989
2990 trace_input ("divhun", OP_IMM_REG_REG_REG, 0);
2991
2992 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
2993
64ad9cec
NC
2994 divide_by = State.regs[ OP[0] ] & 0xffff;
2995 divide_this = State.regs[ OP[1] ];
70caad98 2996
64ad9cec 2997 divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 2998
64ad9cec
NC
2999 State.regs[ OP[1] ] = quotient;
3000 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
3001
3002 /* Set condition codes. */
3003 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
3004
3005 if (overflow) PSW |= PSW_OV;
3006 if (quotient == 0) PSW |= PSW_Z;
60616228 3007 if (quotient & 0x80000000) PSW |= PSW_S;
70caad98
NC
3008
3009 trace_output (OP_IMM_REG_REG_REG);
3010 }
3011/* end-sanitize-v850eq */
3012
3013 return 4;
3014}
3015
3016/* divh reg1, reg2, reg3 */
70caad98
NC
3017int
3018OP_28007E0 (void)
3019{
3020 signed long int quotient;
3021 signed long int remainder;
64ad9cec
NC
3022 signed long int divide_by;
3023 signed long int divide_this;
70caad98
NC
3024 boolean overflow = false;
3025
3026 if ((OP[3] & 0x3c0000) == 0)
3027 {
3028 trace_input ("divh", OP_REG_REG_REG, 0);
3029
3030 /* Compute the result. */
3031
64ad9cec
NC
3032 divide_by = State.regs[ OP[0] ];
3033 divide_this = SEXT16 (State.regs[ OP[1] ]);
70caad98 3034
64ad9cec 3035 if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
70caad98
NC
3036 {
3037 overflow = true;
64ad9cec 3038 divide_by = 1;
70caad98
NC
3039 }
3040
64ad9cec
NC
3041 State.regs[ OP[1] ] = quotient = divide_this / divide_by;
3042 State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
70caad98
NC
3043
3044 /* Set condition codes. */
3045 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
3046
3047 if (overflow) PSW |= PSW_OV;
3048 if (quotient == 0) PSW |= PSW_Z;
3049 if (quotient < 0) PSW |= PSW_S;
3050
3051 trace_output (OP_REG_REG_REG);
3052 }
3053/* start-sanitize-v850eq */
64ad9cec 3054/* divhn imm5, reg1, reg2, reg3 */
70caad98
NC
3055 else
3056 {
3057 unsigned int imm5;
3058
3059 trace_input ("divhn", OP_IMM_REG_REG_REG, 0);
3060
3061 imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
3062
64ad9cec
NC
3063 divide_by = SEXT16 (State.regs[ OP[0] ]);
3064 divide_this = State.regs[ OP[1] ];
70caad98 3065
64ad9cec 3066 divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
70caad98 3067
64ad9cec
NC
3068 State.regs[ OP[1] ] = quotient;
3069 State.regs[ OP[2] >> 11 ] = remainder;
70caad98
NC
3070
3071 /* Set condition codes. */
3072 PSW &= ~(PSW_Z | PSW_S | PSW_OV);
3073
3074 if (overflow) PSW |= PSW_OV;
3075 if (quotient == 0) PSW |= PSW_Z;
3076 if (quotient < 0) PSW |= PSW_S;
3077
3078 trace_output (OP_IMM_REG_REG_REG);
3079 }
3080/* end-sanitize-v850eq */
3081
3082 return 4;
3083}
3084
3085/* mulu imm9, reg2, reg3 */
3086int
3087OP_24207E0 (void)
3088{
3089 trace_input ("mulu", OP_IMM_REG_REG, 0);
3090
3091 Multiply64 (false, (OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0));
3092
3093 trace_output (OP_IMM_REG_REG);
3094
3095 return 4;
3096}
3097
70caad98
NC
3098/* mul imm9, reg2, reg3 */
3099int
3100OP_24007E0 (void)
3101{
3102 trace_input ("mul", OP_IMM_REG_REG, 0);
3103
3104 Multiply64 (true, (OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0));
3105
3106 trace_output (OP_IMM_REG_REG);
3107
3108 return 4;
3109}
3110
3111/* cmov imm5, reg2, reg3 */
3112int
3113OP_30007E0 (void)
3114{
3115 trace_input ("cmov", OP_IMM_REG_REG, 0);
3116
3117 State.regs[ OP[2] >> 11 ] = condition_met (OP[0]) ? SEXT5( OP[0] ) : State.regs[ OP[1] ];
3118
3119 trace_output (OP_IMM_REG_REG);
3120
3121 return 4;
3122
3123}
3124
3125/* ctret */
3126int
3127OP_14407E0 (void)
3128{
3129 trace_input ("ctret", OP_NONE, 0);
3130
3131 PC = CTPC;
3132 PSW = CTPSW;
3133
3134 trace_output (OP_NONE);
3135
3136 return 0;
3137}
3138
3139/* hsw */
3140int
3141OP_34407E0 (void)
3142{
3143 unsigned long value;
3144
3145 trace_input ("hsw", OP_REG_REG3, 0);
3146
3147 value = State.regs[ OP[ 1 ] ];
3148 value >>= 16;
3149 value |= (State.regs[ OP[ 1 ] ] << 16);
3150
3151 State.regs[ OP[2] >> 11 ] = value;
3152
3153 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
3154
3155 if (value == 0) PSW |= PSW_Z;
3156 if (value & 0x80000000) PSW |= PSW_S;
3157 if (((value & 0xffff) == 0) || (value & 0xffff0000) == 0) PSW |= PSW_CY;
3158
3159 trace_output (OP_REG_REG3);
3160
3161 return 4;
3162}
3163
3164#define WORDHASNULLBYTE(x) (((x) - 0x01010101) & ~(x)&0x80808080)
3165
3166/* bsw */
3167int
3168OP_34007E0 (void)
3169{
3170 unsigned long value;
3171
3172 trace_input ("bsw", OP_REG_REG3, 0);
3173
3174 value = State.regs[ OP[ 1 ] ];
3175 value >>= 24;
3176 value |= (State.regs[ OP[ 1 ] ] << 24);
3177 value |= ((State.regs[ OP[ 1 ] ] << 8) & 0x00ff0000);
3178 value |= ((State.regs[ OP[ 1 ] ] >> 8) & 0x0000ff00);
3179
3180 State.regs[ OP[2] >> 11 ] = value;
3181
3182 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
3183
3184 if (value == 0) PSW |= PSW_Z;
3185 if (value & 0x80000000) PSW |= PSW_S;
3186 if (WORDHASNULLBYTE (value)) PSW |= PSW_CY;
3187
3188 trace_output (OP_REG_REG3);
3189
3190 return 4;
3191}
3192
3193/* bsh */
3194int
3195OP_34207E0 (void)
3196{
3197 unsigned long value;
3198
3199 trace_input ("bsh", OP_REG_REG3, 0);
3200
3201 value = State.regs[ OP[ 1 ] ];
3202 value >>= 8;
3203 value |= ((State.regs[ OP[ 1 ] ] << 8) & 0xff00ff00);
3204 value |= ((State.regs[ OP[ 1 ] ] >> 8) & 0x000000ff);
3205
3206 State.regs[ OP[2] >> 11 ] = value;
3207
3208 PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
3209
3210 if (value == 0) PSW |= PSW_Z;
3211 if (value & 0x80000000) PSW |= PSW_S;
60616228 3212 if (((value & 0xff) == 0) || (value & 0x00ff) == 0) PSW |= PSW_CY;
70caad98
NC
3213
3214 trace_output (OP_REG_REG3);
3215
3216 return 4;
3217}
3218
3219/* pushml list18 */
3220/* ld.hu */
3221int
3222OP_107E0 (void)
3223{
3224 if (OP[ 1 ] == 0)
3225 {
3226 int i;
3227
3228 trace_input ("pushml", OP_PUSHPOP3, 0);
3229
60616228
NC
3230 /* Store the registers with lower number registers being placed at higher addresses. */
3231 for (i = 0; i < 15; i++)
3232 if ((OP[3] & (1 << type3_regs[ i ])))
3233 {
3234 SP -= 4;
3235 store_mem (SP & ~ 3, 4, State.regs[ i + 1 ]);
3236 }
3237
3238 if (OP[3] & (1 << 3))
3239 {
3240 SP -= 4;
3241
3242 store_mem (SP & ~ 3, 4, PSW);
3243 }
3244
70caad98
NC
3245 if (OP[3] & (1 << 19))
3246 {
3247 SP -= 8;
3248
3249 if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
3250 {
3251 store_mem ((SP + 4) & ~ 3, 4, FEPC);
3252 store_mem ( SP & ~ 3, 4, FEPSW);
3253 }
3254 else
3255 {
3256 store_mem ((SP + 4) & ~ 3, 4, EIPC);
3257 store_mem ( SP & ~ 3, 4, EIPSW);
3258 }
3259 }
3260
70caad98
NC
3261 trace_output (OP_PUSHPOP2);
3262 }
3263 else
3264 {
3265 int adr;
3266
3267 trace_input ("ld.hu", OP_LOAD32, 2);
3268
3269 adr = State.regs[ OP[0] ] + SEXT16 (OP[2] & ~1);
3270 adr &= ~0x1;
3271
3272 State.regs[ OP[1] ] = load_mem (adr, 2);
3273
3274 trace_output (OP_LOAD32);
3275 }
3276
3277 return 4;
3278}
3279
3280/* prepare list12, imm5 */
3281/* ld.bu */
3282int
3283OP_10780 (void)
3284{
3285 if (OP[ 1 ] == 0)
3286 {
3287 int i;
3288
3289 trace_input ("prepare", OP_PUSHPOP1, 0);
3290
60616228
NC
3291 /* Store the registers with lower number registers being placed at higher addresses. */
3292 for (i = 0; i < 12; i++)
70caad98
NC
3293 if ((OP[3] & (1 << type1_regs[ i ])))
3294 {
3295 SP -= 4;
3296 store_mem (SP, 4, State.regs[ 20 + i ]);
3297 }
3298
3299 SP -= (OP[3] & 0x3e) << 1;
3300
3301 trace_output (OP_PUSHPOP1);
3302 }
3303 else
3304 {
3305 int adr;
3306
3307 trace_input ("ld.bu", OP_LOAD32, 1);
3308
3309 adr = State.regs[ OP[0] ] + SEXT16 (OP[2] & ~1) | ((OP[3] >> 5) & 1);
3310
3311 State.regs[ OP[1] ] = load_mem (adr, 1);
3312
3313 trace_output (OP_LOAD32);
3314 }
3315
3316 return 4;
3317}
3318
3319/* prepare list12, imm5, imm32 */
3320int
3321OP_1B0780 (void)
3322{
3323 int i;
3324
3325 trace_input ("prepare", OP_PUSHPOP1, 0);
3326
60616228
NC
3327 /* Store the registers with lower number registers being placed at higher addresses. */
3328 for (i = 0; i < 12; i++)
70caad98
NC
3329 if ((OP[3] & (1 << type1_regs[ i ])))
3330 {
3331 SP -= 4;
3332 store_mem (SP, 4, State.regs[ 20 + i ]);
3333 }
3334
3335 SP -= (OP[3] & 0x3e) << 1;
3336
3337 EP = load_mem (PC + 4, 4);
3338
3339 trace_output (OP_PUSHPOP1);
3340
3341 return 8;
3342}
3343
3344/* prepare list12, imm5, imm16-32 */
3345int
3346OP_130780 (void)
3347{
3348 int i;
3349
3350 trace_input ("prepare", OP_PUSHPOP1, 0);
3351
60616228
NC
3352 /* Store the registers with lower number registers being placed at higher addresses. */
3353 for (i = 0; i < 12; i++)
70caad98
NC
3354 if ((OP[3] & (1 << type1_regs[ i ])))
3355 {
3356 SP -= 4;
3357 store_mem (SP, 4, State.regs[ 20 + i ]);
3358 }
3359
3360 SP -= (OP[3] & 0x3e) << 1;
3361
3362 EP = load_mem (PC + 4, 2) << 16;
3363
3364 trace_output (OP_PUSHPOP1);
3365
3366 return 6;
3367}
3368
3369/* prepare list12, imm5, imm16 */
3370int
3371OP_B0780 (void)
3372{
3373 int i;
3374
3375 trace_input ("prepare", OP_PUSHPOP1, 0);
3376
60616228
NC
3377 /* Store the registers with lower number registers being placed at higher addresses. */
3378 for (i = 0; i < 12; i++)
70caad98
NC
3379 if ((OP[3] & (1 << type1_regs[ i ])))
3380 {
3381 SP -= 4;
3382 store_mem (SP, 4, State.regs[ 20 + i ]);
3383 }
3384
3385 SP -= (OP[3] & 0x3e) << 1;
3386
3387 EP = SEXT16 (load_mem (PC + 4, 2));
3388
3389 trace_output (OP_PUSHPOP1);
3390
3391 return 6;
3392}
3393
3394/* prepare list12, imm5, sp */
3395int
3396OP_30780 (void)
3397{
3398 int i;
3399
3400 trace_input ("prepare", OP_PUSHPOP1, 0);
3401
60616228
NC
3402 /* Store the registers with lower number registers being placed at higher addresses. */
3403 for (i = 0; i < 12; i++)
70caad98
NC
3404 if ((OP[3] & (1 << type1_regs[ i ])))
3405 {
3406 SP -= 4;
3407 store_mem (SP, 4, State.regs[ 20 + i ]);
3408 }
3409
3410 SP -= (OP[3] & 0x3e) << 1;
3411
3412 EP = SP;
3413
3414 trace_output (OP_PUSHPOP1);
3415
3416 return 4;
3417}
3418
64ad9cec
NC
3419/* sld.hu */
3420int
3421OP_70 (void)
3422{
3423 unsigned long result;
3424
3425 result = load_mem (State.regs[30] + ((OP[3] & 0xf) << 1), 2);
3426
3427/* start-sanitize-v850eq */
3428#ifdef ARCH_v850eq
3429 trace_input ("sld.h", OP_LOAD16, 2);
3430
3431 State.regs[ OP[1] ] = SEXT16 (result);
3432#else
3433/* end-sanitize-v850eq */
3434 trace_input ("sld.hu", OP_LOAD16, 2);
3435
3436 State.regs[ OP[1] ] = result;
3437/* start-sanitize-v850eq */
3438#endif
3439/* end-sanitize-v850eq */
3440
3441 trace_output (OP_LOAD16);
3442
3443 return 2;
3444}
3445
3446/* cmov reg1, reg2, reg3 */
3447int
3448OP_32007E0 (void)
3449{
3450 trace_input ("cmov", OP_REG_REG_REG, 0);
3451
3452 State.regs[ OP[2] >> 11 ] = condition_met (OP[0]) ? State.regs[ OP[0] ] : State.regs[ OP[1] ];
3453
3454 trace_output (OP_REG_REG_REG);
3455
3456 return 4;
3457}
3458
3459/* mul reg1, reg2, reg3 */
3460int
3461OP_22007E0 (void)
3462{
3463 trace_input ("mul", OP_REG_REG_REG, 0);
3464
3465 Multiply64 (true, State.regs[ OP[0] ]);
3466
3467 trace_output (OP_REG_REG_REG);
3468
3469 return 4;
3470}
3471
70caad98
NC
3472/* end-sanitize-v850e */
3473/* start-sanitize-v850eq */
3474
3475/* popmh list18 */
3476int
3477OP_307F0 (void)
3478{
3479 int i;
3480
3481 trace_input ("popmh", OP_PUSHPOP2, 0);
3482
70caad98
NC
3483 if (OP[3] & (1 << 19))
3484 {
3485 if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
3486 {
3487 FEPSW = load_mem ( SP & ~ 3, 4);
3488 FEPC = load_mem ((SP + 4) & ~ 3, 4);
3489 }
3490 else
3491 {
3492 EIPSW = load_mem ( SP & ~ 3, 4);
3493 EIPC = load_mem ((SP + 4) & ~ 3, 4);
3494 }
3495
3496 SP += 8;
3497 }
3498
60616228
NC
3499 /* Load the registers with lower number registers being retrieved from higher addresses. */
3500 for (i = 16; i--;)
3501 if ((OP[3] & (1 << type2_regs[ i ])))
3502 {
3503 State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4);
3504 SP += 4;
3505 }
3506
70caad98
NC
3507 trace_output (OP_PUSHPOP2);
3508
3509 return 4;
3510}
3511
3512/* popml lsit18 */
3513int
3514OP_107F0 (void)
3515{
3516 int i;
3517
3518 trace_input ("popml", OP_PUSHPOP3, 0);
3519
70caad98
NC
3520 if (OP[3] & (1 << 19))
3521 {
3522 if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
3523 {
3524 FEPSW = load_mem ( SP & ~ 3, 4);
3525 FEPC = load_mem ((SP + 4) & ~ 3, 4);
3526 }
3527 else
3528 {
3529 EIPSW = load_mem ( SP & ~ 3, 4);
3530 EIPC = load_mem ((SP + 4) & ~ 3, 4);
3531 }
3532
3533 SP += 8;
3534 }
3535
60616228
NC
3536 if (OP[3] & (1 << 3))
3537 {
3538 PSW = load_mem (SP & ~ 3, 4);
3539 SP += 4;
3540 }
3541
3542 /* Load the registers with lower number registers being retrieved from higher addresses. */
3543 for (i = 15; i--;)
3544 if ((OP[3] & (1 << type3_regs[ i ])))
3545 {
3546 State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4);
3547 SP += 4;
3548 }
3549
70caad98
NC
3550 trace_output (OP_PUSHPOP2);
3551}
3552
3553/* pushmh list18 */
3554int
3555OP_307E0 (void)
3556{
3557 int i;
3558
3559 trace_input ("pushmh", OP_PUSHPOP2, 0);
3560
60616228
NC
3561 /* Store the registers with lower number registers being placed at higher addresses. */
3562 for (i = 0; i < 16; i++)
3563 if ((OP[3] & (1 << type2_regs[ i ])))
3564 {
3565 SP -= 4;
3566 store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]);
3567 }
3568
70caad98
NC
3569 if (OP[3] & (1 << 19))
3570 {
3571 SP -= 8;
3572
3573 if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
3574 {
3575 store_mem ((SP + 4) & ~ 3, 4, FEPC);
3576 store_mem ( SP & ~ 3, 4, FEPSW);
3577 }
3578 else
3579 {
3580 store_mem ((SP + 4) & ~ 3, 4, EIPC);
3581 store_mem ( SP & ~ 3, 4, EIPSW);
3582 }
3583 }
3584
70caad98
NC
3585 trace_output (OP_PUSHPOP2);
3586
3587 return 4;
3588}
3589
3590/* end-sanitize-v850eq */
This page took 0.223539 seconds and 4 git commands to generate.