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