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