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