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