Commit | Line | Data |
---|---|---|
ee3f2d4f MM |
1 | #include "config.h" |
2 | ||
22c1c7dd | 3 | #include <signal.h> |
ee3f2d4f MM |
4 | #ifdef HAVE_UNISTD_H |
5 | #include <unistd.h> | |
6 | #endif | |
22c1c7dd JL |
7 | #include "v850_sim.h" |
8 | #include "simops.h" | |
9909e232 | 9 | #include "sys/syscall.h" |
1d00ce83 | 10 | #include "bfd.h" |
96851909 | 11 | #include <errno.h> |
c500c074 | 12 | #include <sys/stat.h> |
8824fb45 | 13 | #include <sys/times.h> |
7fc45edb | 14 | #include <sys/time.h> |
22c1c7dd | 15 | |
ead4a3f1 MM |
16 | enum op_types { |
17 | OP_UNKNOWN, | |
18 | OP_NONE, | |
19 | OP_TRAP, | |
20 | OP_REG, | |
21 | OP_REG_REG, | |
22 | OP_REG_REG_CMP, | |
23 | OP_REG_REG_MOVE, | |
24 | OP_IMM_REG, | |
25 | OP_IMM_REG_CMP, | |
26 | OP_IMM_REG_MOVE, | |
27 | OP_COND_BR, | |
28 | OP_LOAD16, | |
29 | OP_STORE16, | |
30 | OP_LOAD32, | |
31 | OP_STORE32, | |
32 | OP_JUMP, | |
33 | OP_IMM_REG_REG, | |
34 | OP_UIMM_REG_REG, | |
35 | OP_BIT, | |
36 | OP_EX1, | |
37 | OP_EX2, | |
38 | OP_LDSR, | |
39 | OP_STSR | |
40 | }; | |
41 | ||
42 | #ifdef DEBUG | |
43 | static void trace_input PARAMS ((char *name, enum op_types type, int size)); | |
44 | static void trace_output PARAMS ((enum op_types result)); | |
1d00ce83 MM |
45 | static int init_text_p = 0; |
46 | static asection *text; | |
47 | static bfd_vma text_start; | |
48 | static bfd_vma text_end; | |
da86a4fa | 49 | extern bfd *exec_bfd; |
ead4a3f1 MM |
50 | |
51 | #ifndef SIZE_INSTRUCTION | |
52 | #define SIZE_INSTRUCTION 6 | |
53 | #endif | |
54 | ||
55 | #ifndef SIZE_OPERANDS | |
56 | #define SIZE_OPERANDS 16 | |
57 | #endif | |
58 | ||
59 | #ifndef SIZE_VALUES | |
60 | #define SIZE_VALUES 11 | |
61 | #endif | |
62 | ||
1d00ce83 MM |
63 | #ifndef SIZE_LOCATION |
64 | #define SIZE_LOCATION 40 | |
65 | #endif | |
66 | ||
ead4a3f1 MM |
67 | static void |
68 | trace_input (name, type, size) | |
69 | char *name; | |
70 | enum op_types type; | |
71 | int size; | |
72 | { | |
1d00ce83 MM |
73 | char buf[1024]; |
74 | char *p; | |
ead4a3f1 MM |
75 | uint32 values[3]; |
76 | int num_values, i; | |
77 | char *cond; | |
1d00ce83 MM |
78 | asection *s; |
79 | const char *filename; | |
80 | const char *functionname; | |
81 | unsigned int linenumber; | |
ead4a3f1 MM |
82 | |
83 | if ((v850_debug & DEBUG_TRACE) == 0) | |
84 | return; | |
85 | ||
1d00ce83 MM |
86 | buf[0] = '\0'; |
87 | if (!init_text_p) | |
88 | { | |
89 | init_text_p = 1; | |
da86a4fa JL |
90 | for (s = exec_bfd->sections; s; s = s->next) |
91 | if (strcmp (bfd_get_section_name (exec_bfd, s), ".text") == 0) | |
1d00ce83 MM |
92 | { |
93 | text = s; | |
da86a4fa JL |
94 | text_start = bfd_get_section_vma (exec_bfd, s); |
95 | text_end = text_start + bfd_section_size (exec_bfd, s); | |
1d00ce83 MM |
96 | break; |
97 | } | |
98 | } | |
99 | ||
100 | if (text && PC >= text_start && PC < text_end) | |
101 | { | |
102 | filename = (const char *)0; | |
103 | functionname = (const char *)0; | |
104 | linenumber = 0; | |
da86a4fa | 105 | if (bfd_find_nearest_line (exec_bfd, text, (struct symbol_cache_entry **)0, PC - text_start, |
1d00ce83 MM |
106 | &filename, &functionname, &linenumber)) |
107 | { | |
108 | p = buf; | |
109 | if (linenumber) | |
110 | { | |
111 | sprintf (p, "Line %5d ", linenumber); | |
112 | p += strlen (p); | |
113 | } | |
114 | ||
115 | if (functionname) | |
116 | { | |
117 | sprintf (p, "Func %s ", functionname); | |
118 | p += strlen (p); | |
119 | } | |
120 | else if (filename) | |
121 | { | |
122 | char *q = (char *) strrchr (filename, '/'); | |
123 | sprintf (p, "File %s ", (q) ? q+1 : filename); | |
124 | p += strlen (p); | |
125 | } | |
126 | ||
127 | if (*p == ' ') | |
128 | *p = '\0'; | |
129 | } | |
130 | } | |
131 | ||
132 | (*v850_callback->printf_filtered) (v850_callback, "0x%.8x: %-*.*s %-*s", | |
ead4a3f1 | 133 | (unsigned)PC, |
1d00ce83 | 134 | SIZE_LOCATION, SIZE_LOCATION, buf, |
ead4a3f1 MM |
135 | SIZE_INSTRUCTION, name); |
136 | ||
137 | switch (type) | |
138 | { | |
139 | default: | |
140 | case OP_UNKNOWN: | |
141 | case OP_NONE: | |
142 | strcpy (buf, "unknown"); | |
143 | break; | |
144 | ||
145 | case OP_TRAP: | |
146 | sprintf (buf, "%d", OP[0]); | |
147 | break; | |
148 | ||
149 | case OP_REG: | |
150 | sprintf (buf, "r%d", OP[0]); | |
151 | break; | |
152 | ||
153 | case OP_REG_REG: | |
154 | case OP_REG_REG_CMP: | |
155 | case OP_REG_REG_MOVE: | |
156 | sprintf (buf, "r%d,r%d", OP[0], OP[1]); | |
157 | break; | |
158 | ||
159 | case OP_IMM_REG: | |
160 | case OP_IMM_REG_CMP: | |
161 | case OP_IMM_REG_MOVE: | |
96851909 | 162 | sprintf (buf, "%d,r%d", OP[0], OP[1]); |
ead4a3f1 MM |
163 | break; |
164 | ||
165 | case OP_COND_BR: | |
166 | sprintf (buf, "%d", SEXT9 (OP[0])); | |
167 | break; | |
168 | ||
169 | case OP_LOAD16: | |
0a89af6e | 170 | sprintf (buf, "%d[r30],r%d", OP[1] * size, OP[0]); |
ead4a3f1 MM |
171 | break; |
172 | ||
173 | case OP_STORE16: | |
0a89af6e | 174 | sprintf (buf, "r%d,%d[r30]", OP[0], OP[1] * size); |
ead4a3f1 MM |
175 | break; |
176 | ||
177 | case OP_LOAD32: | |
96851909 | 178 | sprintf (buf, "%d[r%d],r%d", SEXT16 (OP[2]) & ~0x1, OP[0], OP[1]); |
ead4a3f1 MM |
179 | break; |
180 | ||
181 | case OP_STORE32: | |
96851909 | 182 | sprintf (buf, "r%d,%d[r%d]", OP[1], SEXT16 (OP[2] & ~0x1), OP[0]); |
ead4a3f1 MM |
183 | break; |
184 | ||
185 | case OP_JUMP: | |
186 | sprintf (buf, "%d,r%d", SEXT22 (OP[0]), OP[1]); | |
187 | break; | |
188 | ||
189 | case OP_IMM_REG_REG: | |
190 | sprintf (buf, "%d,r%d,r%d", SEXT16 (OP[0]), OP[1], OP[2]); | |
191 | break; | |
192 | ||
193 | case OP_UIMM_REG_REG: | |
194 | sprintf (buf, "%d,r%d,r%d", OP[0] & 0xffff, OP[1], OP[2]); | |
195 | break; | |
196 | ||
197 | case OP_BIT: | |
198 | sprintf (buf, "%d,%d[r%d]", OP[1] & 0x7, SEXT16 (OP[2]), OP[0]); | |
199 | break; | |
200 | ||
201 | case OP_EX1: | |
202 | switch (OP[0] & 0xf) | |
203 | { | |
204 | default: cond = "?"; break; | |
205 | case 0x0: cond = "v"; break; | |
206 | case 0x1: cond = "c"; break; | |
207 | case 0x2: cond = "z"; break; | |
208 | case 0x3: cond = "nh"; break; | |
209 | case 0x4: cond = "s"; break; | |
210 | case 0x5: cond = "t"; break; | |
211 | case 0x6: cond = "lt"; break; | |
212 | case 0x7: cond = "le"; break; | |
213 | case 0x8: cond = "nv"; break; | |
214 | case 0x9: cond = "nc"; break; | |
215 | case 0xa: cond = "nz"; break; | |
216 | case 0xb: cond = "h"; break; | |
217 | case 0xc: cond = "ns"; break; | |
218 | case 0xd: cond = "sa"; break; | |
219 | case 0xe: cond = "ge"; break; | |
220 | case 0xf: cond = "gt"; break; | |
221 | } | |
222 | ||
223 | sprintf (buf, "%s,r%d", cond, OP[1]); | |
224 | break; | |
225 | ||
226 | case OP_EX2: | |
227 | strcpy (buf, "EX2"); | |
228 | break; | |
229 | ||
230 | case OP_LDSR: | |
231 | case OP_STSR: | |
232 | sprintf (buf, "r%d,s%d", OP[0], OP[1]); | |
233 | break; | |
234 | } | |
235 | ||
236 | if ((v850_debug & DEBUG_VALUES) == 0) | |
237 | { | |
238 | (*v850_callback->printf_filtered) (v850_callback, "%s\n", buf); | |
239 | } | |
240 | else | |
241 | { | |
242 | (*v850_callback->printf_filtered) (v850_callback, "%-*s", SIZE_OPERANDS, buf); | |
243 | switch (type) | |
244 | { | |
245 | default: | |
246 | case OP_UNKNOWN: | |
247 | case OP_NONE: | |
248 | case OP_TRAP: | |
249 | num_values = 0; | |
250 | break; | |
251 | ||
252 | case OP_REG: | |
253 | case OP_REG_REG_MOVE: | |
254 | values[0] = State.regs[OP[0]]; | |
255 | num_values = 1; | |
256 | break; | |
257 | ||
258 | case OP_REG_REG: | |
259 | case OP_REG_REG_CMP: | |
260 | values[0] = State.regs[OP[1]]; | |
261 | values[1] = State.regs[OP[0]]; | |
262 | num_values = 2; | |
263 | break; | |
264 | ||
265 | case OP_IMM_REG: | |
266 | case OP_IMM_REG_CMP: | |
267 | values[0] = SEXT5 (OP[0]); | |
268 | values[1] = OP[1]; | |
269 | num_values = 2; | |
270 | break; | |
271 | ||
272 | case OP_IMM_REG_MOVE: | |
273 | values[0] = SEXT5 (OP[0]); | |
274 | num_values = 1; | |
275 | break; | |
276 | ||
277 | case OP_COND_BR: | |
278 | values[0] = State.pc; | |
279 | values[1] = SEXT9 (OP[0]); | |
ee3f2d4f | 280 | values[2] = PSW; |
ead4a3f1 MM |
281 | num_values = 3; |
282 | break; | |
283 | ||
284 | case OP_LOAD16: | |
0a89af6e | 285 | values[0] = OP[1] * size; |
ead4a3f1 MM |
286 | values[1] = State.regs[30]; |
287 | num_values = 2; | |
288 | break; | |
289 | ||
290 | case OP_STORE16: | |
291 | values[0] = State.regs[OP[0]]; | |
0a89af6e | 292 | values[1] = OP[1] * size; |
ead4a3f1 MM |
293 | values[2] = State.regs[30]; |
294 | num_values = 3; | |
295 | break; | |
296 | ||
297 | case OP_LOAD32: | |
298 | values[0] = SEXT16 (OP[2]); | |
299 | values[1] = State.regs[OP[0]]; | |
300 | num_values = 2; | |
301 | break; | |
302 | ||
303 | case OP_STORE32: | |
304 | values[0] = State.regs[OP[1]]; | |
305 | values[1] = SEXT16 (OP[2]); | |
306 | values[2] = State.regs[OP[0]]; | |
307 | num_values = 3; | |
308 | break; | |
309 | ||
310 | case OP_JUMP: | |
311 | values[0] = SEXT22 (OP[0]); | |
312 | values[1] = State.pc; | |
313 | num_values = 2; | |
314 | break; | |
315 | ||
316 | case OP_IMM_REG_REG: | |
317 | values[0] = SEXT16 (OP[0]) << size; | |
318 | values[1] = State.regs[OP[1]]; | |
319 | num_values = 2; | |
320 | break; | |
321 | ||
322 | case OP_UIMM_REG_REG: | |
323 | values[0] = (OP[0] & 0xffff) << size; | |
324 | values[1] = State.regs[OP[1]]; | |
325 | num_values = 2; | |
326 | break; | |
327 | ||
328 | case OP_BIT: | |
329 | num_values = 0; | |
330 | break; | |
331 | ||
332 | case OP_EX1: | |
ee3f2d4f | 333 | values[0] = PSW; |
ead4a3f1 MM |
334 | num_values = 1; |
335 | break; | |
336 | ||
337 | case OP_EX2: | |
338 | num_values = 0; | |
339 | break; | |
340 | ||
341 | case OP_LDSR: | |
342 | values[0] = State.regs[OP[0]]; | |
343 | num_values = 1; | |
344 | break; | |
345 | ||
346 | case OP_STSR: | |
347 | values[0] = State.sregs[OP[1]]; | |
348 | num_values = 1; | |
349 | } | |
350 | ||
351 | for (i = 0; i < num_values; i++) | |
352 | (*v850_callback->printf_filtered) (v850_callback, "%*s0x%.8lx", SIZE_VALUES - 10, "", values[i]); | |
353 | ||
354 | while (i++ < 3) | |
355 | (*v850_callback->printf_filtered) (v850_callback, "%*s", SIZE_VALUES, ""); | |
356 | } | |
357 | } | |
358 | ||
359 | static void | |
360 | trace_output (result) | |
361 | enum op_types result; | |
362 | { | |
363 | if ((v850_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES)) | |
364 | { | |
365 | switch (result) | |
366 | { | |
367 | default: | |
368 | case OP_UNKNOWN: | |
369 | case OP_NONE: | |
370 | case OP_TRAP: | |
371 | case OP_REG: | |
372 | case OP_REG_REG_CMP: | |
373 | case OP_IMM_REG_CMP: | |
374 | case OP_COND_BR: | |
375 | case OP_STORE16: | |
376 | case OP_STORE32: | |
377 | case OP_BIT: | |
378 | case OP_EX2: | |
379 | break; | |
380 | ||
381 | case OP_LOAD16: | |
382 | case OP_STSR: | |
383 | (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", | |
384 | (unsigned long)State.regs[OP[0]]); | |
385 | break; | |
386 | ||
387 | case OP_REG_REG: | |
388 | case OP_REG_REG_MOVE: | |
389 | case OP_IMM_REG: | |
390 | case OP_IMM_REG_MOVE: | |
391 | case OP_LOAD32: | |
392 | case OP_EX1: | |
393 | (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", | |
394 | (unsigned long)State.regs[OP[1]]); | |
395 | break; | |
396 | ||
397 | case OP_IMM_REG_REG: | |
398 | case OP_UIMM_REG_REG: | |
399 | (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", | |
400 | (unsigned long)State.regs[OP[2]]); | |
401 | break; | |
402 | ||
403 | case OP_JUMP: | |
404 | if (OP[1] != 0) | |
405 | (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", | |
406 | (unsigned long)State.regs[OP[1]]); | |
407 | break; | |
408 | ||
409 | case OP_LDSR: | |
410 | (*v850_callback->printf_filtered) (v850_callback, " :: 0x%.8lx", | |
411 | (unsigned long)State.sregs[OP[1]]); | |
412 | break; | |
413 | } | |
414 | ||
415 | (*v850_callback->printf_filtered) (v850_callback, "\n"); | |
416 | } | |
417 | } | |
418 | ||
419 | #else | |
da86a4fa | 420 | #define trace_input(NAME, IN1, IN2) |
ead4a3f1 MM |
421 | #define trace_output(RESULT) |
422 | #endif | |
423 | ||
424 | \f | |
28647e4c | 425 | /* sld.b */ |
22c1c7dd | 426 | void |
28647e4c | 427 | OP_300 () |
22c1c7dd | 428 | { |
9fca2fd3 | 429 | unsigned int op2; |
3cb6bf78 JL |
430 | int result, temp; |
431 | ||
ead4a3f1 | 432 | trace_input ("sld.b", OP_LOAD16, 1); |
3cb6bf78 | 433 | temp = OP[1]; |
0a89af6e | 434 | temp &= 0x7f; |
3cb6bf78 | 435 | op2 = temp; |
96851909 | 436 | result = load_mem (State.regs[30] + op2, 1); |
ead4a3f1 MM |
437 | State.regs[OP[0]] = SEXT8 (result); |
438 | trace_output (OP_LOAD16); | |
22c1c7dd JL |
439 | } |
440 | ||
28647e4c | 441 | /* sld.h */ |
22c1c7dd | 442 | void |
28647e4c JL |
443 | OP_400 () |
444 | { | |
9fca2fd3 | 445 | unsigned int op2; |
3cb6bf78 JL |
446 | int result, temp; |
447 | ||
ead4a3f1 | 448 | trace_input ("sld.h", OP_LOAD16, 2); |
3cb6bf78 | 449 | temp = OP[1]; |
0a89af6e | 450 | temp &= 0x7f; |
3cb6bf78 | 451 | op2 = temp << 1; |
96851909 | 452 | result = load_mem (State.regs[30] + op2, 2); |
ead4a3f1 MM |
453 | State.regs[OP[0]] = SEXT16 (result); |
454 | trace_output (OP_LOAD16); | |
28647e4c JL |
455 | } |
456 | ||
457 | /* sld.w */ | |
458 | void | |
459 | OP_500 () | |
22c1c7dd | 460 | { |
9fca2fd3 | 461 | unsigned int op2; |
3cb6bf78 JL |
462 | int result, temp; |
463 | ||
ead4a3f1 | 464 | trace_input ("sld.w", OP_LOAD16, 4); |
3cb6bf78 | 465 | temp = OP[1]; |
f0099789 | 466 | temp &= 0x7e; |
85c09b05 | 467 | op2 = temp << 1; |
96851909 | 468 | result = load_mem (State.regs[30] + op2, 4); |
3cb6bf78 | 469 | State.regs[OP[0]] = result; |
ead4a3f1 | 470 | trace_output (OP_LOAD16); |
22c1c7dd JL |
471 | } |
472 | ||
28647e4c JL |
473 | /* sst.b */ |
474 | void | |
475 | OP_380 () | |
476 | { | |
9fca2fd3 JL |
477 | unsigned int op0, op1; |
478 | int temp; | |
3cb6bf78 | 479 | |
ead4a3f1 | 480 | trace_input ("sst.b", OP_STORE16, 1); |
3cb6bf78 JL |
481 | op0 = State.regs[OP[0]]; |
482 | temp = OP[1]; | |
0a89af6e | 483 | temp &= 0x7f; |
3cb6bf78 | 484 | op1 = temp; |
96851909 | 485 | store_mem (State.regs[30] + op1, 1, op0); |
ead4a3f1 | 486 | trace_output (OP_STORE16); |
28647e4c JL |
487 | } |
488 | ||
489 | /* sst.h */ | |
490 | void | |
491 | OP_480 () | |
492 | { | |
9fca2fd3 JL |
493 | unsigned int op0, op1; |
494 | int temp; | |
3cb6bf78 | 495 | |
ead4a3f1 | 496 | trace_input ("sst.h", OP_STORE16, 2); |
3cb6bf78 JL |
497 | op0 = State.regs[OP[0]]; |
498 | temp = OP[1]; | |
0a89af6e | 499 | temp &= 0x7f; |
3cb6bf78 | 500 | op1 = temp << 1; |
96851909 | 501 | store_mem (State.regs[30] + op1, 2, op0); |
ead4a3f1 | 502 | trace_output (OP_STORE16); |
28647e4c JL |
503 | } |
504 | ||
505 | /* sst.w */ | |
506 | void | |
507 | OP_501 () | |
508 | { | |
9fca2fd3 JL |
509 | unsigned int op0, op1; |
510 | int temp; | |
3cb6bf78 | 511 | |
ead4a3f1 | 512 | trace_input ("sst.w", OP_STORE16, 4); |
3cb6bf78 JL |
513 | op0 = State.regs[OP[0]]; |
514 | temp = OP[1]; | |
f0099789 | 515 | temp &= 0x7e; |
85c09b05 | 516 | op1 = temp << 1; |
96851909 | 517 | store_mem (State.regs[30] + op1, 4, op0); |
ead4a3f1 | 518 | trace_output (OP_STORE16); |
28647e4c JL |
519 | } |
520 | ||
521 | /* ld.b */ | |
522 | void | |
523 | OP_700 () | |
524 | { | |
9fca2fd3 | 525 | unsigned int op0, op2; |
28647e4c JL |
526 | int result, temp; |
527 | ||
ead4a3f1 | 528 | trace_input ("ld.b", OP_LOAD32, 1); |
28647e4c | 529 | op0 = State.regs[OP[0]]; |
ead4a3f1 | 530 | temp = SEXT16 (OP[2]); |
28647e4c | 531 | op2 = temp; |
96851909 | 532 | result = load_mem (op0 + op2, 1); |
ead4a3f1 MM |
533 | State.regs[OP[1]] = SEXT8 (result); |
534 | trace_output (OP_LOAD32); | |
28647e4c JL |
535 | } |
536 | ||
537 | /* ld.h */ | |
538 | void | |
539 | OP_720 () | |
540 | { | |
9fca2fd3 | 541 | unsigned int op0, op2; |
28647e4c JL |
542 | int result, temp; |
543 | ||
ead4a3f1 | 544 | trace_input ("ld.h", OP_LOAD32, 2); |
28647e4c | 545 | op0 = State.regs[OP[0]]; |
ead4a3f1 | 546 | temp = SEXT16 (OP[2]); |
28647e4c JL |
547 | temp &= ~0x1; |
548 | op2 = temp; | |
96851909 | 549 | result = load_mem (op0 + op2, 2); |
ead4a3f1 MM |
550 | State.regs[OP[1]] = SEXT16 (result); |
551 | trace_output (OP_LOAD32); | |
28647e4c JL |
552 | } |
553 | ||
554 | /* ld.w */ | |
555 | void | |
556 | OP_10720 () | |
557 | { | |
9fca2fd3 | 558 | unsigned int op0, op2; |
28647e4c JL |
559 | int result, temp; |
560 | ||
ead4a3f1 | 561 | trace_input ("ld.w", OP_LOAD32, 4); |
28647e4c | 562 | op0 = State.regs[OP[0]]; |
ead4a3f1 | 563 | temp = SEXT16 (OP[2]); |
28647e4c JL |
564 | temp &= ~0x1; |
565 | op2 = temp; | |
96851909 | 566 | result = load_mem (op0 + op2, 4); |
28647e4c | 567 | State.regs[OP[1]] = result; |
ead4a3f1 | 568 | trace_output (OP_LOAD32); |
28647e4c JL |
569 | } |
570 | ||
571 | /* st.b */ | |
572 | void | |
573 | OP_740 () | |
574 | { | |
575 | unsigned int op0, op1, op2; | |
9fca2fd3 | 576 | int temp; |
28647e4c | 577 | |
ead4a3f1 | 578 | trace_input ("st.b", OP_STORE32, 1); |
28647e4c JL |
579 | op0 = State.regs[OP[0]]; |
580 | op1 = State.regs[OP[1]]; | |
ead4a3f1 | 581 | temp = SEXT16 (OP[2]); |
28647e4c | 582 | op2 = temp; |
96851909 | 583 | store_mem (op0 + op2, 1, op1); |
ead4a3f1 | 584 | trace_output (OP_STORE32); |
28647e4c JL |
585 | } |
586 | ||
587 | /* st.h */ | |
22c1c7dd JL |
588 | void |
589 | OP_760 () | |
590 | { | |
28647e4c | 591 | unsigned int op0, op1, op2; |
9fca2fd3 | 592 | int temp; |
28647e4c | 593 | |
ead4a3f1 | 594 | trace_input ("st.h", OP_STORE32, 2); |
28647e4c JL |
595 | op0 = State.regs[OP[0]]; |
596 | op1 = State.regs[OP[1]]; | |
ead4a3f1 | 597 | temp = SEXT16 (OP[2] & ~0x1); |
28647e4c | 598 | op2 = temp; |
96851909 | 599 | store_mem (op0 + op2, 2, op1); |
ead4a3f1 | 600 | trace_output (OP_STORE32); |
28647e4c JL |
601 | } |
602 | ||
603 | /* st.w */ | |
604 | void | |
605 | OP_10760 () | |
606 | { | |
607 | unsigned int op0, op1, op2; | |
9fca2fd3 | 608 | int temp; |
28647e4c | 609 | |
ead4a3f1 | 610 | trace_input ("st.w", OP_STORE32, 4); |
28647e4c JL |
611 | op0 = State.regs[OP[0]]; |
612 | op1 = State.regs[OP[1]]; | |
ead4a3f1 | 613 | temp = SEXT16 (OP[2] & ~0x1); |
28647e4c | 614 | op2 = temp; |
96851909 | 615 | store_mem (op0 + op2, 4, op1); |
ead4a3f1 | 616 | trace_output (OP_STORE32); |
22c1c7dd JL |
617 | } |
618 | ||
2108e864 | 619 | /* bv disp9 */ |
22c1c7dd JL |
620 | void |
621 | OP_580 () | |
622 | { | |
ead4a3f1 MM |
623 | unsigned int psw; |
624 | int op0; | |
22c1c7dd | 625 | |
ead4a3f1 MM |
626 | trace_input ("bv", OP_COND_BR, 0); |
627 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 628 | psw = PSW; |
2108e864 JL |
629 | |
630 | if ((psw & PSW_OV) != 0) | |
631 | State.pc += op0; | |
632 | else | |
633 | State.pc += 2; | |
ead4a3f1 | 634 | trace_output (OP_COND_BR); |
22c1c7dd JL |
635 | } |
636 | ||
2108e864 | 637 | /* bl disp9 */ |
22c1c7dd JL |
638 | void |
639 | OP_581 () | |
640 | { | |
ead4a3f1 MM |
641 | unsigned int psw; |
642 | int op0; | |
2108e864 | 643 | |
ead4a3f1 MM |
644 | trace_input ("bl", OP_COND_BR, 0); |
645 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 646 | psw = PSW; |
2108e864 JL |
647 | |
648 | if ((psw & PSW_CY) != 0) | |
649 | State.pc += op0; | |
650 | else | |
651 | State.pc += 2; | |
ead4a3f1 | 652 | trace_output (OP_COND_BR); |
22c1c7dd JL |
653 | } |
654 | ||
2108e864 | 655 | /* be disp9 */ |
22c1c7dd JL |
656 | void |
657 | OP_582 () | |
658 | { | |
ead4a3f1 MM |
659 | unsigned int psw; |
660 | int op0; | |
2108e864 | 661 | |
ead4a3f1 MM |
662 | trace_input ("be", OP_COND_BR, 0); |
663 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 664 | psw = PSW; |
2108e864 JL |
665 | |
666 | if ((psw & PSW_Z) != 0) | |
667 | State.pc += op0; | |
668 | else | |
669 | State.pc += 2; | |
ead4a3f1 | 670 | trace_output (OP_COND_BR); |
22c1c7dd JL |
671 | } |
672 | ||
2108e864 | 673 | /* bnh disp 9*/ |
22c1c7dd JL |
674 | void |
675 | OP_583 () | |
676 | { | |
ead4a3f1 MM |
677 | unsigned int psw; |
678 | int op0; | |
2108e864 | 679 | |
ead4a3f1 MM |
680 | trace_input ("bnh", OP_COND_BR, 0); |
681 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 682 | psw = PSW; |
2108e864 JL |
683 | |
684 | if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0) | |
685 | State.pc += op0; | |
686 | else | |
687 | State.pc += 2; | |
ead4a3f1 | 688 | trace_output (OP_COND_BR); |
22c1c7dd JL |
689 | } |
690 | ||
2108e864 | 691 | /* bn disp9 */ |
22c1c7dd JL |
692 | void |
693 | OP_584 () | |
694 | { | |
ead4a3f1 MM |
695 | unsigned int psw; |
696 | int op0; | |
2108e864 | 697 | |
ead4a3f1 MM |
698 | trace_input ("bn", OP_COND_BR, 0); |
699 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 700 | psw = PSW; |
2108e864 JL |
701 | |
702 | if ((psw & PSW_S) != 0) | |
703 | State.pc += op0; | |
704 | else | |
705 | State.pc += 2; | |
ead4a3f1 | 706 | trace_output (OP_COND_BR); |
22c1c7dd JL |
707 | } |
708 | ||
2108e864 | 709 | /* br disp9 */ |
22c1c7dd JL |
710 | void |
711 | OP_585 () | |
712 | { | |
ead4a3f1 MM |
713 | unsigned int psw; |
714 | int op0; | |
2108e864 | 715 | |
ead4a3f1 MM |
716 | trace_input ("br", OP_COND_BR, 0); |
717 | op0 = SEXT9 (OP[0]); | |
2108e864 | 718 | State.pc += op0; |
ead4a3f1 | 719 | trace_output (OP_COND_BR); |
22c1c7dd JL |
720 | } |
721 | ||
2108e864 | 722 | /* blt disp9 */ |
22c1c7dd JL |
723 | void |
724 | OP_586 () | |
725 | { | |
ead4a3f1 MM |
726 | unsigned int psw; |
727 | int op0; | |
2108e864 | 728 | |
ead4a3f1 MM |
729 | trace_input ("blt", OP_COND_BR, 0); |
730 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 731 | psw = PSW; |
2108e864 JL |
732 | |
733 | if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0) | |
734 | State.pc += op0; | |
735 | else | |
736 | State.pc += 2; | |
ead4a3f1 | 737 | trace_output (OP_COND_BR); |
22c1c7dd JL |
738 | } |
739 | ||
2108e864 | 740 | /* ble disp9 */ |
22c1c7dd JL |
741 | void |
742 | OP_587 () | |
743 | { | |
ead4a3f1 MM |
744 | unsigned int psw; |
745 | int op0; | |
2108e864 | 746 | |
ead4a3f1 MM |
747 | trace_input ("ble", OP_COND_BR, 0); |
748 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 749 | psw = PSW; |
2108e864 JL |
750 | |
751 | if ((((psw & PSW_Z) != 0) | |
752 | || (((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0))) != 0) | |
753 | State.pc += op0; | |
754 | else | |
755 | State.pc += 2; | |
ead4a3f1 | 756 | trace_output (OP_COND_BR); |
22c1c7dd JL |
757 | } |
758 | ||
2108e864 | 759 | /* bnv disp9 */ |
22c1c7dd JL |
760 | void |
761 | OP_588 () | |
762 | { | |
ead4a3f1 MM |
763 | unsigned int psw; |
764 | int op0; | |
2108e864 | 765 | |
ead4a3f1 MM |
766 | trace_input ("bnv", OP_COND_BR, 0); |
767 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 768 | psw = PSW; |
2108e864 JL |
769 | |
770 | if ((psw & PSW_OV) == 0) | |
771 | State.pc += op0; | |
772 | else | |
773 | State.pc += 2; | |
ead4a3f1 | 774 | trace_output (OP_COND_BR); |
22c1c7dd JL |
775 | } |
776 | ||
2108e864 | 777 | /* bnl disp9 */ |
22c1c7dd JL |
778 | void |
779 | OP_589 () | |
780 | { | |
ead4a3f1 MM |
781 | unsigned int psw; |
782 | int op0; | |
2108e864 | 783 | |
ead4a3f1 MM |
784 | trace_input ("bnl", OP_COND_BR, 0); |
785 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 786 | psw = PSW; |
2108e864 JL |
787 | |
788 | if ((psw & PSW_CY) == 0) | |
789 | State.pc += op0; | |
790 | else | |
791 | State.pc += 2; | |
ead4a3f1 | 792 | trace_output (OP_COND_BR); |
22c1c7dd JL |
793 | } |
794 | ||
2108e864 | 795 | /* bne disp9 */ |
22c1c7dd JL |
796 | void |
797 | OP_58A () | |
798 | { | |
ead4a3f1 MM |
799 | unsigned int psw; |
800 | int op0; | |
2108e864 | 801 | |
ead4a3f1 MM |
802 | trace_input ("bne", OP_COND_BR, 0); |
803 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 804 | psw = PSW; |
2108e864 JL |
805 | |
806 | if ((psw & PSW_Z) == 0) | |
807 | State.pc += op0; | |
808 | else | |
809 | State.pc += 2; | |
ead4a3f1 | 810 | trace_output (OP_COND_BR); |
22c1c7dd JL |
811 | } |
812 | ||
2108e864 | 813 | /* bh disp9 */ |
22c1c7dd JL |
814 | void |
815 | OP_58B () | |
816 | { | |
ead4a3f1 MM |
817 | unsigned int psw; |
818 | int op0; | |
22c1c7dd | 819 | |
ead4a3f1 MM |
820 | trace_input ("bh", OP_COND_BR, 0); |
821 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 822 | psw = PSW; |
2108e864 JL |
823 | |
824 | if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0) | |
825 | State.pc += op0; | |
826 | else | |
827 | State.pc += 2; | |
ead4a3f1 | 828 | trace_output (OP_COND_BR); |
22c1c7dd JL |
829 | } |
830 | ||
2108e864 | 831 | /* bp disp9 */ |
22c1c7dd | 832 | void |
2108e864 | 833 | OP_58C () |
22c1c7dd | 834 | { |
ead4a3f1 MM |
835 | unsigned int psw; |
836 | int op0; | |
22c1c7dd | 837 | |
ead4a3f1 MM |
838 | trace_input ("bp", OP_COND_BR, 0); |
839 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 840 | psw = PSW; |
2108e864 JL |
841 | |
842 | if ((psw & PSW_S) == 0) | |
843 | State.pc += op0; | |
844 | else | |
845 | State.pc += 2; | |
ead4a3f1 | 846 | trace_output (OP_COND_BR); |
22c1c7dd JL |
847 | } |
848 | ||
2108e864 | 849 | /* bsa disp9 */ |
22c1c7dd JL |
850 | void |
851 | OP_58D () | |
852 | { | |
ead4a3f1 MM |
853 | unsigned int psw; |
854 | int op0; | |
2108e864 | 855 | |
ead4a3f1 MM |
856 | trace_input ("bsa", OP_COND_BR, 0); |
857 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 858 | psw = PSW; |
2108e864 JL |
859 | |
860 | if ((psw & PSW_SAT) != 0) | |
861 | State.pc += op0; | |
862 | else | |
863 | State.pc += 2; | |
ead4a3f1 | 864 | trace_output (OP_COND_BR); |
22c1c7dd JL |
865 | } |
866 | ||
2108e864 | 867 | /* bge disp9 */ |
22c1c7dd JL |
868 | void |
869 | OP_58E () | |
870 | { | |
ead4a3f1 MM |
871 | unsigned int psw; |
872 | int op0; | |
2108e864 | 873 | |
ead4a3f1 MM |
874 | trace_input ("bge", OP_COND_BR, 0); |
875 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 876 | psw = PSW; |
2108e864 JL |
877 | |
878 | if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0) | |
879 | State.pc += op0; | |
880 | else | |
881 | State.pc += 2; | |
ead4a3f1 | 882 | trace_output (OP_COND_BR); |
22c1c7dd JL |
883 | } |
884 | ||
2108e864 | 885 | /* bgt disp9 */ |
22c1c7dd JL |
886 | void |
887 | OP_58F () | |
888 | { | |
ead4a3f1 MM |
889 | unsigned int psw; |
890 | int op0; | |
2108e864 | 891 | |
ead4a3f1 MM |
892 | trace_input ("bgt", OP_COND_BR, 0); |
893 | op0 = SEXT9 (OP[0]); | |
ee3f2d4f | 894 | psw = PSW; |
2108e864 JL |
895 | |
896 | if ((((psw & PSW_Z) != 0) | |
897 | || (((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0))) == 0) | |
898 | State.pc += op0; | |
899 | else | |
900 | State.pc += 2; | |
ead4a3f1 | 901 | trace_output (OP_COND_BR); |
22c1c7dd JL |
902 | } |
903 | ||
e9b6cbac | 904 | /* jmp [reg1] */ |
22c1c7dd | 905 | void |
e9b6cbac | 906 | OP_60 () |
22c1c7dd | 907 | { |
e9b6cbac | 908 | /* interp.c will bump this by +2, so correct for it here. */ |
ead4a3f1 | 909 | trace_input ("jmp", OP_REG, 0); |
e9b6cbac | 910 | State.pc = State.regs[OP[0]] - 2; |
ead4a3f1 | 911 | trace_output (OP_REG); |
22c1c7dd JL |
912 | } |
913 | ||
e9b6cbac JL |
914 | /* jarl disp22, reg */ |
915 | void | |
916 | OP_780 () | |
917 | { | |
918 | unsigned int op0, opc; | |
919 | int temp; | |
920 | ||
ead4a3f1 MM |
921 | trace_input ("jarl", OP_JUMP, 0); |
922 | temp = SEXT22 (OP[0]); | |
e9b6cbac JL |
923 | op0 = temp; |
924 | opc = State.pc; | |
925 | ||
926 | State.pc += temp; | |
927 | ||
928 | /* Gross. jarl X,r0 is really jr and doesn't save its result. */ | |
929 | if (OP[1] != 0) | |
930 | State.regs[OP[1]] = opc + 4; | |
ead4a3f1 | 931 | trace_output (OP_JUMP); |
e9b6cbac | 932 | } |
22c1c7dd | 933 | |
0ef0eba5 | 934 | /* add reg, reg */ |
22c1c7dd | 935 | void |
1fe983dc | 936 | OP_1C0 () |
22c1c7dd | 937 | { |
0ef0eba5 | 938 | unsigned int op0, op1, result, z, s, cy, ov; |
22c1c7dd | 939 | |
ead4a3f1 | 940 | trace_input ("add", OP_REG_REG, 0); |
0ef0eba5 JL |
941 | /* Compute the result. */ |
942 | op0 = State.regs[OP[0]]; | |
943 | op1 = State.regs[OP[1]]; | |
944 | result = op0 + op1; | |
1fe983dc | 945 | |
0ef0eba5 JL |
946 | /* Compute the condition codes. */ |
947 | z = (result == 0); | |
948 | s = (result & 0x80000000); | |
949 | cy = (result < op0 || result < op1); | |
950 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
951 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
952 | ||
953 | /* Store the result and condition codes. */ | |
954 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
955 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
956 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
614f1c68 | 957 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
ead4a3f1 | 958 | trace_output (OP_REG_REG); |
0ef0eba5 JL |
959 | } |
960 | ||
961 | /* add sign_extend(imm5), reg */ | |
22c1c7dd | 962 | void |
1fe983dc | 963 | OP_240 () |
22c1c7dd | 964 | { |
0ef0eba5 JL |
965 | unsigned int op0, op1, result, z, s, cy, ov; |
966 | int temp; | |
1fe983dc | 967 | |
ead4a3f1 MM |
968 | trace_input ("add", OP_IMM_REG, 0); |
969 | ||
0ef0eba5 | 970 | /* Compute the result. */ |
ead4a3f1 | 971 | temp = SEXT5 (OP[0]); |
0ef0eba5 JL |
972 | op0 = temp; |
973 | op1 = State.regs[OP[1]]; | |
974 | result = op0 + op1; | |
975 | ||
976 | /* Compute the condition codes. */ | |
977 | z = (result == 0); | |
978 | s = (result & 0x80000000); | |
979 | cy = (result < op0 || result < op1); | |
980 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
981 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
22c1c7dd | 982 | |
0ef0eba5 JL |
983 | /* Store the result and condition codes. */ |
984 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
985 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
986 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
0ef0eba5 | 987 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
ead4a3f1 | 988 | trace_output (OP_IMM_REG); |
0ef0eba5 | 989 | } |
1fe983dc | 990 | |
0ef0eba5 | 991 | /* addi sign_extend(imm16), reg, reg */ |
22c1c7dd | 992 | void |
1fe983dc | 993 | OP_600 () |
22c1c7dd | 994 | { |
0ef0eba5 JL |
995 | unsigned int op0, op1, result, z, s, cy, ov; |
996 | int temp; | |
997 | ||
ead4a3f1 MM |
998 | trace_input ("addi", OP_IMM_REG_REG, 0); |
999 | ||
0ef0eba5 | 1000 | /* Compute the result. */ |
ead4a3f1 | 1001 | temp = SEXT16 (OP[0]); |
0ef0eba5 JL |
1002 | op0 = temp; |
1003 | op1 = State.regs[OP[1]]; | |
1004 | result = op0 + op1; | |
1005 | ||
1006 | /* Compute the condition codes. */ | |
1007 | z = (result == 0); | |
1008 | s = (result & 0x80000000); | |
1009 | cy = (result < op0 || result < op1); | |
1010 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
1011 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
1012 | ||
1013 | /* Store the result and condition codes. */ | |
1014 | State.regs[OP[2]] = result; | |
ee3f2d4f MM |
1015 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1016 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
0ef0eba5 | 1017 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
ead4a3f1 | 1018 | trace_output (OP_IMM_REG_REG); |
22c1c7dd JL |
1019 | } |
1020 | ||
aabce0f4 | 1021 | /* sub reg1, reg2 */ |
22c1c7dd | 1022 | void |
1fe983dc | 1023 | OP_1A0 () |
22c1c7dd | 1024 | { |
aabce0f4 JL |
1025 | unsigned int op0, op1, result, z, s, cy, ov; |
1026 | ||
ead4a3f1 | 1027 | trace_input ("sub", OP_REG_REG, 0); |
aabce0f4 JL |
1028 | /* Compute the result. */ |
1029 | op0 = State.regs[OP[0]]; | |
1030 | op1 = State.regs[OP[1]]; | |
1031 | result = op1 - op0; | |
22c1c7dd | 1032 | |
aabce0f4 JL |
1033 | /* Compute the condition codes. */ |
1034 | z = (result == 0); | |
1035 | s = (result & 0x80000000); | |
d81352b8 | 1036 | cy = (op1 < op0); |
aabce0f4 JL |
1037 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
1038 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
1fe983dc | 1039 | |
aabce0f4 JL |
1040 | /* Store the result and condition codes. */ |
1041 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1042 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1043 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
aabce0f4 | 1044 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
ead4a3f1 | 1045 | trace_output (OP_REG_REG); |
aabce0f4 JL |
1046 | } |
1047 | ||
1048 | /* subr reg1, reg2 */ | |
22c1c7dd | 1049 | void |
1fe983dc | 1050 | OP_180 () |
22c1c7dd | 1051 | { |
aabce0f4 | 1052 | unsigned int op0, op1, result, z, s, cy, ov; |
22c1c7dd | 1053 | |
ead4a3f1 | 1054 | trace_input ("subr", OP_REG_REG, 0); |
aabce0f4 JL |
1055 | /* Compute the result. */ |
1056 | op0 = State.regs[OP[0]]; | |
1057 | op1 = State.regs[OP[1]]; | |
1058 | result = op0 - op1; | |
e98e3b2c | 1059 | |
aabce0f4 JL |
1060 | /* Compute the condition codes. */ |
1061 | z = (result == 0); | |
1062 | s = (result & 0x80000000); | |
d81352b8 | 1063 | cy = (op0 < op1); |
aabce0f4 JL |
1064 | ov = ((op0 & 0x80000000) != (op1 & 0x80000000) |
1065 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
1066 | ||
1067 | /* Store the result and condition codes. */ | |
1068 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1069 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1070 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
aabce0f4 | 1071 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
ead4a3f1 | 1072 | trace_output (OP_REG_REG); |
aabce0f4 JL |
1073 | } |
1074 | ||
1075 | /* mulh reg1, reg2 */ | |
22c1c7dd | 1076 | void |
e98e3b2c | 1077 | OP_E0 () |
22c1c7dd | 1078 | { |
ead4a3f1 | 1079 | trace_input ("mulh", OP_REG_REG, 0); |
e98e3b2c | 1080 | State.regs[OP[1]] = ((State.regs[OP[1]] & 0xffff) |
fb8eb42b | 1081 | * (State.regs[OP[0]] & 0xffff)); |
ead4a3f1 | 1082 | trace_output (OP_REG_REG); |
22c1c7dd JL |
1083 | } |
1084 | ||
e98e3b2c JL |
1085 | /* mulh sign_extend(imm5), reg2 |
1086 | ||
1087 | Condition codes */ | |
22c1c7dd | 1088 | void |
e98e3b2c | 1089 | OP_2E0 () |
22c1c7dd | 1090 | { |
ead4a3f1 | 1091 | int value = SEXT5 (OP[0]); |
e98e3b2c | 1092 | |
ead4a3f1 | 1093 | trace_input ("mulh", OP_IMM_REG, 0); |
e98e3b2c | 1094 | State.regs[OP[1]] = (State.regs[OP[1]] & 0xffff) * value; |
ead4a3f1 | 1095 | trace_output (OP_IMM_REG); |
22c1c7dd JL |
1096 | } |
1097 | ||
aabce0f4 | 1098 | /* mulhi imm16, reg1, reg2 */ |
22c1c7dd | 1099 | void |
e98e3b2c JL |
1100 | OP_6E0 () |
1101 | { | |
ead4a3f1 | 1102 | int value = OP[0] & 0xffff; |
e98e3b2c | 1103 | |
ead4a3f1 | 1104 | trace_input ("mulhi", OP_IMM_REG_REG, 0); |
fb8eb42b | 1105 | State.regs[OP[2]] = (State.regs[OP[1]] & 0xffff) * value; |
ead4a3f1 | 1106 | trace_output (OP_IMM_REG_REG); |
e98e3b2c JL |
1107 | } |
1108 | ||
aabce0f4 | 1109 | /* divh reg1, reg2 */ |
e98e3b2c JL |
1110 | void |
1111 | OP_40 () | |
22c1c7dd | 1112 | { |
9fca2fd3 | 1113 | unsigned int op0, op1, result, ov, s, z; |
aabce0f4 JL |
1114 | int temp; |
1115 | ||
ead4a3f1 MM |
1116 | trace_input ("divh", OP_REG_REG, 0); |
1117 | ||
aabce0f4 | 1118 | /* Compute the result. */ |
ead4a3f1 | 1119 | temp = SEXT16 (State.regs[OP[0]]); |
aabce0f4 JL |
1120 | op0 = temp; |
1121 | op1 = State.regs[OP[1]]; | |
1122 | ||
1123 | if (op0 == 0xffffffff && op1 == 0x80000000) | |
1124 | { | |
1125 | result = 0x80000000; | |
1126 | ov = 1; | |
1127 | } | |
1128 | else if (op0 != 0) | |
1129 | { | |
1130 | result = op1 / op0; | |
1131 | ov = 0; | |
1132 | } | |
1133 | else | |
9fca2fd3 JL |
1134 | { |
1135 | result = 0x0; | |
1136 | ov = 1; | |
1137 | } | |
aabce0f4 JL |
1138 | |
1139 | /* Compute the condition codes. */ | |
1140 | z = (result == 0); | |
1141 | s = (result & 0x80000000); | |
1142 | ||
1143 | /* Store the result and condition codes. */ | |
1144 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1145 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1146 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
aabce0f4 | 1147 | | (ov ? PSW_OV : 0)); |
ead4a3f1 | 1148 | trace_output (OP_REG_REG); |
22c1c7dd JL |
1149 | } |
1150 | ||
3095b8df JL |
1151 | /* cmp reg, reg */ |
1152 | void | |
1153 | OP_1E0 () | |
1154 | { | |
1155 | unsigned int op0, op1, result, z, s, cy, ov; | |
1156 | ||
ead4a3f1 | 1157 | trace_input ("cmp", OP_REG_REG_CMP, 0); |
3095b8df JL |
1158 | /* Compute the result. */ |
1159 | op0 = State.regs[OP[0]]; | |
1160 | op1 = State.regs[OP[1]]; | |
1161 | result = op1 - op0; | |
1162 | ||
1163 | /* Compute the condition codes. */ | |
1164 | z = (result == 0); | |
1165 | s = (result & 0x80000000); | |
d81352b8 | 1166 | cy = (op1 < op0); |
3095b8df JL |
1167 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
1168 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
1169 | ||
1170 | /* Set condition codes. */ | |
ee3f2d4f MM |
1171 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1172 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
3095b8df | 1173 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
ead4a3f1 | 1174 | trace_output (OP_REG_REG_CMP); |
3095b8df JL |
1175 | } |
1176 | ||
1177 | /* cmp sign_extend(imm5), reg */ | |
1178 | void | |
1179 | OP_260 () | |
1180 | { | |
1181 | unsigned int op0, op1, result, z, s, cy, ov; | |
1182 | int temp; | |
1183 | ||
1184 | /* Compute the result. */ | |
ead4a3f1 MM |
1185 | trace_input ("cmp", OP_IMM_REG_CMP, 0); |
1186 | temp = SEXT5 (OP[0]); | |
3095b8df JL |
1187 | op0 = temp; |
1188 | op1 = State.regs[OP[1]]; | |
1189 | result = op1 - op0; | |
1190 | ||
1191 | /* Compute the condition codes. */ | |
1192 | z = (result == 0); | |
1193 | s = (result & 0x80000000); | |
d81352b8 | 1194 | cy = (op1 < op0); |
3095b8df JL |
1195 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
1196 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
1197 | ||
1198 | /* Set condition codes. */ | |
ee3f2d4f MM |
1199 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1200 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
3095b8df | 1201 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
ead4a3f1 | 1202 | trace_output (OP_IMM_REG_CMP); |
3095b8df JL |
1203 | } |
1204 | ||
1205 | /* setf cccc,reg2 */ | |
1206 | void | |
1207 | OP_7E0 () | |
1208 | { | |
1209 | /* Hack alert. We turn off a bit in op0 since we really only | |
1210 | wanted 4 bits. */ | |
9fca2fd3 | 1211 | unsigned int op0, psw, result = 0; |
3095b8df | 1212 | |
ead4a3f1 | 1213 | trace_input ("setf", OP_EX1, 0); |
3095b8df | 1214 | op0 = OP[0] & 0xf; |
ee3f2d4f | 1215 | psw = PSW; |
3095b8df JL |
1216 | |
1217 | switch (op0) | |
1218 | { | |
1219 | case 0x0: | |
1220 | result = ((psw & PSW_OV) != 0); | |
1221 | break; | |
1222 | case 0x1: | |
1223 | result = ((psw & PSW_CY) != 0); | |
1224 | break; | |
1225 | case 0x2: | |
1226 | result = ((psw & PSW_Z) != 0); | |
1227 | break; | |
1228 | case 0x3: | |
1229 | result = ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0); | |
1230 | break; | |
1231 | case 0x4: | |
1232 | result = ((psw & PSW_S) != 0); | |
1233 | break; | |
1234 | case 0x5: | |
1235 | result = 1; | |
1236 | break; | |
1237 | case 0x6: | |
1238 | result = ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0); | |
1239 | break; | |
1240 | case 0x7: | |
1241 | result = (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) | |
1242 | || ((psw & PSW_Z) != 0)) != 0); | |
1243 | break; | |
1244 | case 0x8: | |
1245 | result = ((psw & PSW_OV) == 0); | |
1246 | break; | |
1247 | case 0x9: | |
1248 | result = ((psw & PSW_CY) == 0); | |
1249 | break; | |
1250 | case 0xa: | |
1251 | result = ((psw & PSW_Z) == 0); | |
1252 | break; | |
1253 | case 0xb: | |
1254 | result = ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0); | |
1255 | break; | |
1256 | case 0xc: | |
1257 | result = ((psw & PSW_S) == 0); | |
1258 | break; | |
1259 | case 0xd: | |
1260 | result = ((psw & PSW_SAT) != 0); | |
1261 | break; | |
1262 | case 0xe: | |
1263 | result = ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0); | |
1264 | break; | |
1265 | case 0xf: | |
1266 | result = (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) | |
1267 | || ((psw & PSW_Z) != 0)) == 0); | |
1268 | break; | |
1269 | } | |
1270 | ||
1271 | State.regs[OP[1]] = result; | |
ead4a3f1 | 1272 | trace_output (OP_EX1); |
3095b8df JL |
1273 | } |
1274 | ||
dca41ba7 JL |
1275 | /* satadd reg,reg */ |
1276 | void | |
1277 | OP_C0 () | |
1278 | { | |
1279 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
1280 | ||
ead4a3f1 | 1281 | trace_input ("satadd", OP_REG_REG, 0); |
dca41ba7 JL |
1282 | /* Compute the result. */ |
1283 | op0 = State.regs[OP[0]]; | |
1284 | op1 = State.regs[OP[1]]; | |
1285 | result = op0 + op1; | |
1286 | ||
1287 | /* Compute the condition codes. */ | |
1288 | z = (result == 0); | |
1289 | s = (result & 0x80000000); | |
1290 | cy = (result < op0 || result < op1); | |
1291 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
1292 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
1293 | sat = ov; | |
1294 | ||
1295 | /* Store the result and condition codes. */ | |
1296 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1297 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1298 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
1299 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
1300 | | (sat ? PSW_SAT : 0)); | |
1301 | ||
1302 | /* Handle saturated results. */ | |
0e4ccc58 | 1303 | if (sat && s) |
dca41ba7 JL |
1304 | State.regs[OP[1]] = 0x80000000; |
1305 | else if (sat) | |
1306 | State.regs[OP[1]] = 0x7fffffff; | |
ead4a3f1 | 1307 | trace_output (OP_REG_REG); |
dca41ba7 JL |
1308 | } |
1309 | ||
1310 | /* satadd sign_extend(imm5), reg */ | |
1311 | void | |
1312 | OP_220 () | |
1313 | { | |
1314 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
1315 | ||
1316 | int temp; | |
1317 | ||
ead4a3f1 MM |
1318 | trace_input ("satadd", OP_IMM_REG, 0); |
1319 | ||
dca41ba7 | 1320 | /* Compute the result. */ |
ead4a3f1 | 1321 | temp = SEXT5 (OP[0]); |
dca41ba7 JL |
1322 | op0 = temp; |
1323 | op1 = State.regs[OP[1]]; | |
1324 | result = op0 + op1; | |
1325 | ||
1326 | /* Compute the condition codes. */ | |
1327 | z = (result == 0); | |
1328 | s = (result & 0x80000000); | |
1329 | cy = (result < op0 || result < op1); | |
1330 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
1331 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
1332 | sat = ov; | |
1333 | ||
1334 | /* Store the result and condition codes. */ | |
1335 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1336 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1337 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
1338 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
1339 | | (sat ? PSW_SAT : 0)); | |
1340 | ||
1341 | /* Handle saturated results. */ | |
0e4ccc58 | 1342 | if (sat && s) |
dca41ba7 JL |
1343 | State.regs[OP[1]] = 0x80000000; |
1344 | else if (sat) | |
1345 | State.regs[OP[1]] = 0x7fffffff; | |
ead4a3f1 | 1346 | trace_output (OP_IMM_REG); |
dca41ba7 JL |
1347 | } |
1348 | ||
1349 | /* satsub reg1, reg2 */ | |
1350 | void | |
1351 | OP_A0 () | |
1352 | { | |
1353 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
1354 | ||
ead4a3f1 MM |
1355 | trace_input ("satsub", OP_REG_REG, 0); |
1356 | ||
dca41ba7 JL |
1357 | /* Compute the result. */ |
1358 | op0 = State.regs[OP[0]]; | |
1359 | op1 = State.regs[OP[1]]; | |
1360 | result = op1 - op0; | |
1361 | ||
1362 | /* Compute the condition codes. */ | |
1363 | z = (result == 0); | |
1364 | s = (result & 0x80000000); | |
d81352b8 | 1365 | cy = (op1 < op0); |
dca41ba7 JL |
1366 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
1367 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
1368 | sat = ov; | |
1369 | ||
1370 | /* Store the result and condition codes. */ | |
1371 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1372 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1373 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
1374 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
1375 | | (sat ? PSW_SAT : 0)); | |
1376 | ||
1377 | /* Handle saturated results. */ | |
0e4ccc58 | 1378 | if (sat && s) |
dca41ba7 JL |
1379 | State.regs[OP[1]] = 0x80000000; |
1380 | else if (sat) | |
1381 | State.regs[OP[1]] = 0x7fffffff; | |
ead4a3f1 | 1382 | trace_output (OP_REG_REG); |
dca41ba7 JL |
1383 | } |
1384 | ||
1385 | /* satsubi sign_extend(imm16), reg */ | |
1386 | void | |
1387 | OP_660 () | |
1388 | { | |
1389 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
1390 | int temp; | |
1391 | ||
ead4a3f1 MM |
1392 | trace_input ("satsubi", OP_IMM_REG, 0); |
1393 | ||
dca41ba7 | 1394 | /* Compute the result. */ |
ead4a3f1 | 1395 | temp = SEXT16 (OP[0]); |
dca41ba7 JL |
1396 | op0 = temp; |
1397 | op1 = State.regs[OP[1]]; | |
1398 | result = op1 - op0; | |
1399 | ||
1400 | /* Compute the condition codes. */ | |
1401 | z = (result == 0); | |
1402 | s = (result & 0x80000000); | |
d81352b8 | 1403 | cy = (op1 < op0); |
dca41ba7 JL |
1404 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
1405 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
1406 | sat = ov; | |
1407 | ||
1408 | /* Store the result and condition codes. */ | |
1409 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1410 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1411 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
1412 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
1413 | | (sat ? PSW_SAT : 0)); | |
1414 | ||
1415 | /* Handle saturated results. */ | |
0e4ccc58 | 1416 | if (sat && s) |
dca41ba7 JL |
1417 | State.regs[OP[1]] = 0x80000000; |
1418 | else if (sat) | |
1419 | State.regs[OP[1]] = 0x7fffffff; | |
ead4a3f1 | 1420 | trace_output (OP_IMM_REG); |
dca41ba7 JL |
1421 | } |
1422 | ||
ead4a3f1 | 1423 | /* satsubr reg,reg */ |
dca41ba7 JL |
1424 | void |
1425 | OP_80 () | |
1426 | { | |
1427 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
1428 | ||
ead4a3f1 MM |
1429 | trace_input ("satsubr", OP_REG_REG, 0); |
1430 | ||
dca41ba7 JL |
1431 | /* Compute the result. */ |
1432 | op0 = State.regs[OP[0]]; | |
1433 | op1 = State.regs[OP[1]]; | |
1434 | result = op0 - op1; | |
1435 | ||
1436 | /* Compute the condition codes. */ | |
1437 | z = (result == 0); | |
1438 | s = (result & 0x80000000); | |
d81352b8 | 1439 | cy = (result < op0); |
dca41ba7 JL |
1440 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
1441 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
1442 | sat = ov; | |
1443 | ||
1444 | /* Store the result and condition codes. */ | |
1445 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1446 | PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
1447 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
1448 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
1449 | | (sat ? PSW_SAT : 0)); | |
1450 | ||
1451 | /* Handle saturated results. */ | |
0e4ccc58 | 1452 | if (sat && s) |
dca41ba7 JL |
1453 | State.regs[OP[1]] = 0x80000000; |
1454 | else if (sat) | |
1455 | State.regs[OP[1]] = 0x7fffffff; | |
ead4a3f1 | 1456 | trace_output (OP_REG_REG); |
dca41ba7 JL |
1457 | } |
1458 | ||
3095b8df JL |
1459 | /* tst reg,reg */ |
1460 | void | |
1461 | OP_160 () | |
1462 | { | |
9fca2fd3 | 1463 | unsigned int op0, op1, result, z, s; |
3095b8df | 1464 | |
ead4a3f1 MM |
1465 | trace_input ("tst", OP_REG_REG_CMP, 0); |
1466 | ||
3095b8df JL |
1467 | /* Compute the result. */ |
1468 | op0 = State.regs[OP[0]]; | |
1469 | op1 = State.regs[OP[1]]; | |
1470 | result = op0 & op1; | |
1471 | ||
1472 | /* Compute the condition codes. */ | |
1473 | z = (result == 0); | |
1474 | s = (result & 0x80000000); | |
1475 | ||
1476 | /* Store the condition codes. */ | |
ee3f2d4f MM |
1477 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1478 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
ead4a3f1 | 1479 | trace_output (OP_REG_REG_CMP); |
3095b8df JL |
1480 | } |
1481 | ||
1fe983dc | 1482 | /* mov reg, reg */ |
22c1c7dd JL |
1483 | void |
1484 | OP_0 () | |
1485 | { | |
ead4a3f1 | 1486 | trace_input ("mov", OP_REG_REG_MOVE, 0); |
1fe983dc | 1487 | State.regs[OP[1]] = State.regs[OP[0]]; |
ead4a3f1 | 1488 | trace_output (OP_REG_REG_MOVE); |
22c1c7dd JL |
1489 | } |
1490 | ||
1fe983dc | 1491 | /* mov sign_extend(imm5), reg */ |
22c1c7dd | 1492 | void |
1fe983dc | 1493 | OP_200 () |
22c1c7dd | 1494 | { |
ead4a3f1 | 1495 | int value = SEXT5 (OP[0]); |
1fe983dc | 1496 | |
ead4a3f1 | 1497 | trace_input ("mov", OP_IMM_REG_MOVE, 0); |
1fe983dc | 1498 | State.regs[OP[1]] = value; |
ead4a3f1 | 1499 | trace_output (OP_IMM_REG_MOVE); |
22c1c7dd JL |
1500 | } |
1501 | ||
1fe983dc JL |
1502 | /* movea sign_extend(imm16), reg, reg */ |
1503 | ||
22c1c7dd | 1504 | void |
1fe983dc | 1505 | OP_620 () |
22c1c7dd | 1506 | { |
ead4a3f1 | 1507 | int value = SEXT16 (OP[0]); |
1fe983dc | 1508 | |
ead4a3f1 | 1509 | trace_input ("movea", OP_IMM_REG_REG, 0); |
1fe983dc | 1510 | State.regs[OP[2]] = State.regs[OP[1]] + value; |
ead4a3f1 | 1511 | trace_output (OP_IMM_REG_REG); |
22c1c7dd JL |
1512 | } |
1513 | ||
1fe983dc | 1514 | /* movhi imm16, reg, reg */ |
22c1c7dd | 1515 | void |
1fe983dc | 1516 | OP_640 () |
22c1c7dd | 1517 | { |
ead4a3f1 | 1518 | uint32 value = (OP[0] & 0xffff) << 16; |
1fe983dc | 1519 | |
ead4a3f1 | 1520 | trace_input ("movhi", OP_UIMM_REG_REG, 16); |
1fe983dc | 1521 | State.regs[OP[2]] = State.regs[OP[1]] + value; |
ead4a3f1 | 1522 | trace_output (OP_UIMM_REG_REG); |
22c1c7dd JL |
1523 | } |
1524 | ||
35404c7d | 1525 | /* sar zero_extend(imm5),reg1 */ |
22c1c7dd | 1526 | void |
77553374 | 1527 | OP_2A0 () |
22c1c7dd | 1528 | { |
9fca2fd3 | 1529 | unsigned int op0, op1, result, z, s, cy; |
77553374 | 1530 | |
ead4a3f1 | 1531 | trace_input ("sar", OP_IMM_REG, 0); |
35404c7d JL |
1532 | op0 = OP[0] & 0x1f; |
1533 | op1 = State.regs[OP[1]]; | |
1534 | result = (signed)op1 >> op0; | |
77553374 | 1535 | |
35404c7d JL |
1536 | /* Compute the condition codes. */ |
1537 | z = (result == 0); | |
1538 | s = (result & 0x80000000); | |
1539 | cy = (op1 & (1 << (op0 - 1))); | |
22c1c7dd | 1540 | |
35404c7d JL |
1541 | /* Store the result and condition codes. */ |
1542 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1543 | PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1544 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
9fca2fd3 | 1545 | | (cy ? PSW_CY : 0)); |
ead4a3f1 | 1546 | trace_output (OP_IMM_REG); |
35404c7d | 1547 | } |
77553374 | 1548 | |
35404c7d | 1549 | /* sar reg1, reg2 */ |
22c1c7dd | 1550 | void |
77553374 | 1551 | OP_A007E0 () |
22c1c7dd | 1552 | { |
9fca2fd3 | 1553 | unsigned int op0, op1, result, z, s, cy; |
77553374 | 1554 | |
ead4a3f1 | 1555 | trace_input ("sar", OP_REG_REG, 0); |
35404c7d JL |
1556 | op0 = State.regs[OP[0]] & 0x1f; |
1557 | op1 = State.regs[OP[1]]; | |
1558 | result = (signed)op1 >> op0; | |
77553374 | 1559 | |
35404c7d JL |
1560 | /* Compute the condition codes. */ |
1561 | z = (result == 0); | |
1562 | s = (result & 0x80000000); | |
1563 | cy = (op1 & (1 << (op0 - 1))); | |
22c1c7dd | 1564 | |
35404c7d JL |
1565 | /* Store the result and condition codes. */ |
1566 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1567 | PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1568 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d | 1569 | | (cy ? PSW_CY : 0)); |
ead4a3f1 | 1570 | trace_output (OP_REG_REG); |
35404c7d | 1571 | } |
77553374 | 1572 | |
35404c7d | 1573 | /* shl zero_extend(imm5),reg1 */ |
22c1c7dd JL |
1574 | void |
1575 | OP_2C0 () | |
77553374 | 1576 | { |
9fca2fd3 | 1577 | unsigned int op0, op1, result, z, s, cy; |
35404c7d | 1578 | |
ead4a3f1 | 1579 | trace_input ("shl", OP_IMM_REG, 0); |
35404c7d JL |
1580 | op0 = OP[0] & 0x1f; |
1581 | op1 = State.regs[OP[1]]; | |
1582 | result = op1 << op0; | |
1583 | ||
1584 | /* Compute the condition codes. */ | |
1585 | z = (result == 0); | |
1586 | s = (result & 0x80000000); | |
1587 | cy = (op1 & (1 << (32 - op0))); | |
77553374 | 1588 | |
35404c7d JL |
1589 | /* Store the result and condition codes. */ |
1590 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1591 | PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1592 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d | 1593 | | (cy ? PSW_CY : 0)); |
ead4a3f1 | 1594 | trace_output (OP_IMM_REG); |
35404c7d | 1595 | } |
77553374 | 1596 | |
35404c7d | 1597 | /* shl reg1, reg2 */ |
77553374 JL |
1598 | void |
1599 | OP_C007E0 () | |
1600 | { | |
9fca2fd3 | 1601 | unsigned int op0, op1, result, z, s, cy; |
77553374 | 1602 | |
ead4a3f1 | 1603 | trace_input ("shl", OP_REG_REG, 0); |
35404c7d JL |
1604 | op0 = State.regs[OP[0]] & 0x1f; |
1605 | op1 = State.regs[OP[1]]; | |
1606 | result = op1 << op0; | |
1607 | ||
1608 | /* Compute the condition codes. */ | |
1609 | z = (result == 0); | |
1610 | s = (result & 0x80000000); | |
1611 | cy = (op1 & (1 << (32 - op0))); | |
1612 | ||
1613 | /* Store the result and condition codes. */ | |
1614 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1615 | PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1616 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d | 1617 | | (cy ? PSW_CY : 0)); |
ead4a3f1 | 1618 | trace_output (OP_REG_REG); |
35404c7d | 1619 | } |
77553374 | 1620 | |
35404c7d | 1621 | /* shr zero_extend(imm5),reg1 */ |
77553374 JL |
1622 | void |
1623 | OP_280 () | |
1624 | { | |
9fca2fd3 | 1625 | unsigned int op0, op1, result, z, s, cy; |
77553374 | 1626 | |
ead4a3f1 | 1627 | trace_input ("shr", OP_IMM_REG, 0); |
35404c7d JL |
1628 | op0 = OP[0] & 0x1f; |
1629 | op1 = State.regs[OP[1]]; | |
1630 | result = op1 >> op0; | |
77553374 | 1631 | |
35404c7d JL |
1632 | /* Compute the condition codes. */ |
1633 | z = (result == 0); | |
1634 | s = (result & 0x80000000); | |
1635 | cy = (op1 & (1 << (op0 - 1))); | |
1636 | ||
1637 | /* Store the result and condition codes. */ | |
1638 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1639 | PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1640 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d | 1641 | | (cy ? PSW_CY : 0)); |
ead4a3f1 | 1642 | trace_output (OP_IMM_REG); |
35404c7d JL |
1643 | } |
1644 | ||
1645 | /* shr reg1, reg2 */ | |
77553374 JL |
1646 | void |
1647 | OP_8007E0 () | |
1648 | { | |
9fca2fd3 | 1649 | unsigned int op0, op1, result, z, s, cy; |
35404c7d | 1650 | |
ead4a3f1 | 1651 | trace_input ("shr", OP_REG_REG, 0); |
35404c7d JL |
1652 | op0 = State.regs[OP[0]] & 0x1f; |
1653 | op1 = State.regs[OP[1]]; | |
1654 | result = op1 >> op0; | |
1655 | ||
1656 | /* Compute the condition codes. */ | |
1657 | z = (result == 0); | |
1658 | s = (result & 0x80000000); | |
1659 | cy = (op1 & (1 << (op0 - 1))); | |
1660 | ||
1661 | /* Store the result and condition codes. */ | |
1662 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1663 | PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1664 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d | 1665 | | (cy ? PSW_CY : 0)); |
ead4a3f1 | 1666 | trace_output (OP_REG_REG); |
77553374 JL |
1667 | } |
1668 | ||
0ef0eba5 | 1669 | /* or reg, reg */ |
1fe983dc JL |
1670 | void |
1671 | OP_100 () | |
1672 | { | |
9fca2fd3 | 1673 | unsigned int op0, op1, result, z, s; |
1fe983dc | 1674 | |
ead4a3f1 MM |
1675 | trace_input ("or", OP_REG_REG, 0); |
1676 | ||
0ef0eba5 JL |
1677 | /* Compute the result. */ |
1678 | op0 = State.regs[OP[0]]; | |
1679 | op1 = State.regs[OP[1]]; | |
1680 | result = op0 | op1; | |
1fe983dc | 1681 | |
0ef0eba5 JL |
1682 | /* Compute the condition codes. */ |
1683 | z = (result == 0); | |
1684 | s = (result & 0x80000000); | |
1685 | ||
1686 | /* Store the result and condition codes. */ | |
1687 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1688 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1689 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
ead4a3f1 | 1690 | trace_output (OP_REG_REG); |
0ef0eba5 JL |
1691 | } |
1692 | ||
1693 | /* ori zero_extend(imm16), reg, reg */ | |
1fe983dc JL |
1694 | void |
1695 | OP_680 () | |
1696 | { | |
9fca2fd3 | 1697 | unsigned int op0, op1, result, z, s; |
1fe983dc | 1698 | |
ead4a3f1 | 1699 | trace_input ("ori", OP_UIMM_REG_REG, 0); |
0ef0eba5 JL |
1700 | op0 = OP[0] & 0xffff; |
1701 | op1 = State.regs[OP[1]]; | |
1702 | result = op0 | op1; | |
1fe983dc | 1703 | |
0ef0eba5 JL |
1704 | /* Compute the condition codes. */ |
1705 | z = (result == 0); | |
1706 | s = (result & 0x80000000); | |
1fe983dc | 1707 | |
0ef0eba5 JL |
1708 | /* Store the result and condition codes. */ |
1709 | State.regs[OP[2]] = result; | |
ee3f2d4f MM |
1710 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1711 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
ead4a3f1 | 1712 | trace_output (OP_UIMM_REG_REG); |
0ef0eba5 JL |
1713 | } |
1714 | ||
1715 | /* and reg, reg */ | |
22c1c7dd JL |
1716 | void |
1717 | OP_140 () | |
1718 | { | |
9fca2fd3 | 1719 | unsigned int op0, op1, result, z, s; |
22c1c7dd | 1720 | |
ead4a3f1 MM |
1721 | trace_input ("and", OP_REG_REG, 0); |
1722 | ||
0ef0eba5 JL |
1723 | /* Compute the result. */ |
1724 | op0 = State.regs[OP[0]]; | |
1725 | op1 = State.regs[OP[1]]; | |
1726 | result = op0 & op1; | |
1fe983dc | 1727 | |
0ef0eba5 JL |
1728 | /* Compute the condition codes. */ |
1729 | z = (result == 0); | |
1730 | s = (result & 0x80000000); | |
1731 | ||
1732 | /* Store the result and condition codes. */ | |
1733 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1734 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1735 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
ead4a3f1 | 1736 | trace_output (OP_REG_REG); |
0ef0eba5 JL |
1737 | } |
1738 | ||
1739 | /* andi zero_extend(imm16), reg, reg */ | |
22c1c7dd | 1740 | void |
1fe983dc JL |
1741 | OP_6C0 () |
1742 | { | |
9fca2fd3 | 1743 | unsigned int op0, op1, result, z; |
1fe983dc | 1744 | |
ead4a3f1 | 1745 | trace_input ("andi", OP_UIMM_REG_REG, 0); |
0ef0eba5 JL |
1746 | op0 = OP[0] & 0xffff; |
1747 | op1 = State.regs[OP[1]]; | |
1748 | result = op0 & op1; | |
1fe983dc | 1749 | |
0ef0eba5 JL |
1750 | /* Compute the condition codes. */ |
1751 | z = (result == 0); | |
1fe983dc | 1752 | |
0ef0eba5 JL |
1753 | /* Store the result and condition codes. */ |
1754 | State.regs[OP[2]] = result; | |
ee3f2d4f MM |
1755 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1756 | PSW |= (z ? PSW_Z : 0); | |
ead4a3f1 | 1757 | trace_output (OP_UIMM_REG_REG); |
0ef0eba5 JL |
1758 | } |
1759 | ||
1760 | /* xor reg, reg */ | |
1fe983dc JL |
1761 | void |
1762 | OP_120 () | |
22c1c7dd | 1763 | { |
9fca2fd3 | 1764 | unsigned int op0, op1, result, z, s; |
1fe983dc | 1765 | |
ead4a3f1 MM |
1766 | trace_input ("xor", OP_REG_REG, 0); |
1767 | ||
0ef0eba5 JL |
1768 | /* Compute the result. */ |
1769 | op0 = State.regs[OP[0]]; | |
1770 | op1 = State.regs[OP[1]]; | |
1771 | result = op0 ^ op1; | |
1fe983dc | 1772 | |
0ef0eba5 JL |
1773 | /* Compute the condition codes. */ |
1774 | z = (result == 0); | |
1775 | s = (result & 0x80000000); | |
1776 | ||
1777 | /* Store the result and condition codes. */ | |
1778 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1779 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1780 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
ead4a3f1 | 1781 | trace_output (OP_REG_REG); |
0ef0eba5 JL |
1782 | } |
1783 | ||
1784 | /* xori zero_extend(imm16), reg, reg */ | |
1fe983dc JL |
1785 | void |
1786 | OP_6A0 () | |
1787 | { | |
9fca2fd3 | 1788 | unsigned int op0, op1, result, z, s; |
0ef0eba5 | 1789 | |
ead4a3f1 | 1790 | trace_input ("xori", OP_UIMM_REG_REG, 0); |
0ef0eba5 JL |
1791 | op0 = OP[0] & 0xffff; |
1792 | op1 = State.regs[OP[1]]; | |
1793 | result = op0 ^ op1; | |
1794 | ||
1795 | /* Compute the condition codes. */ | |
1796 | z = (result == 0); | |
1797 | s = (result & 0x80000000); | |
1798 | ||
1799 | /* Store the result and condition codes. */ | |
1800 | State.regs[OP[2]] = result; | |
ee3f2d4f MM |
1801 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1802 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
ead4a3f1 | 1803 | trace_output (OP_UIMM_REG_REG); |
0ef0eba5 JL |
1804 | } |
1805 | ||
1806 | /* not reg1, reg2 */ | |
1807 | void | |
1808 | OP_20 () | |
1809 | { | |
9fca2fd3 | 1810 | unsigned int op0, result, z, s; |
0ef0eba5 | 1811 | |
ead4a3f1 | 1812 | trace_input ("not", OP_REG_REG_MOVE, 0); |
0ef0eba5 JL |
1813 | /* Compute the result. */ |
1814 | op0 = State.regs[OP[0]]; | |
1815 | result = ~op0; | |
1816 | ||
1817 | /* Compute the condition codes. */ | |
1818 | z = (result == 0); | |
1819 | s = (result & 0x80000000); | |
1fe983dc | 1820 | |
0ef0eba5 JL |
1821 | /* Store the result and condition codes. */ |
1822 | State.regs[OP[1]] = result; | |
ee3f2d4f MM |
1823 | PSW &= ~(PSW_Z | PSW_S | PSW_OV); |
1824 | PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
ead4a3f1 | 1825 | trace_output (OP_REG_REG_MOVE); |
22c1c7dd JL |
1826 | } |
1827 | ||
28647e4c | 1828 | /* set1 */ |
1fe983dc | 1829 | void |
28647e4c | 1830 | OP_7C0 () |
1fe983dc | 1831 | { |
83fc3bac | 1832 | unsigned int op0, op1, op2; |
9fca2fd3 | 1833 | int temp; |
83fc3bac | 1834 | |
ead4a3f1 | 1835 | trace_input ("set1", OP_BIT, 0); |
83fc3bac JL |
1836 | op0 = State.regs[OP[0]]; |
1837 | op1 = OP[1] & 0x7; | |
ead4a3f1 | 1838 | temp = SEXT16 (OP[2]); |
83fc3bac | 1839 | op2 = temp; |
96851909 | 1840 | temp = load_mem (op0 + op2, 1); |
ee3f2d4f | 1841 | PSW &= ~PSW_Z; |
83fc3bac | 1842 | if ((temp & (1 << op1)) == 0) |
ee3f2d4f | 1843 | PSW |= PSW_Z; |
787d66bb | 1844 | temp |= (1 << op1); |
96851909 | 1845 | store_mem (op0 + op2, 1, temp); |
ead4a3f1 | 1846 | trace_output (OP_BIT); |
1fe983dc JL |
1847 | } |
1848 | ||
28647e4c | 1849 | /* not1 */ |
1fe983dc | 1850 | void |
28647e4c | 1851 | OP_47C0 () |
1fe983dc | 1852 | { |
83fc3bac | 1853 | unsigned int op0, op1, op2; |
9fca2fd3 | 1854 | int temp; |
83fc3bac | 1855 | |
ead4a3f1 | 1856 | trace_input ("not1", OP_BIT, 0); |
83fc3bac JL |
1857 | op0 = State.regs[OP[0]]; |
1858 | op1 = OP[1] & 0x7; | |
ead4a3f1 | 1859 | temp = SEXT16 (OP[2]); |
83fc3bac | 1860 | op2 = temp; |
96851909 | 1861 | temp = load_mem (op0 + op2, 1); |
ee3f2d4f | 1862 | PSW &= ~PSW_Z; |
83fc3bac | 1863 | if ((temp & (1 << op1)) == 0) |
ee3f2d4f | 1864 | PSW |= PSW_Z; |
787d66bb | 1865 | temp ^= (1 << op1); |
96851909 | 1866 | store_mem (op0 + op2, 1, temp); |
ead4a3f1 | 1867 | trace_output (OP_BIT); |
1fe983dc JL |
1868 | } |
1869 | ||
28647e4c | 1870 | /* clr1 */ |
1fe983dc | 1871 | void |
28647e4c JL |
1872 | OP_87C0 () |
1873 | { | |
83fc3bac | 1874 | unsigned int op0, op1, op2; |
9fca2fd3 | 1875 | int temp; |
83fc3bac | 1876 | |
ead4a3f1 | 1877 | trace_input ("clr1", OP_BIT, 0); |
83fc3bac JL |
1878 | op0 = State.regs[OP[0]]; |
1879 | op1 = OP[1] & 0x7; | |
ead4a3f1 | 1880 | temp = SEXT16 (OP[2]); |
83fc3bac | 1881 | op2 = temp; |
96851909 | 1882 | temp = load_mem (op0 + op2, 1); |
ee3f2d4f | 1883 | PSW &= ~PSW_Z; |
83fc3bac | 1884 | if ((temp & (1 << op1)) == 0) |
ee3f2d4f | 1885 | PSW |= PSW_Z; |
83fc3bac | 1886 | temp &= ~(1 << op1); |
96851909 | 1887 | store_mem (op0 + op2, 1, temp); |
ead4a3f1 | 1888 | trace_output (OP_BIT); |
28647e4c JL |
1889 | } |
1890 | ||
1891 | /* tst1 */ | |
1892 | void | |
1893 | OP_C7C0 () | |
1fe983dc | 1894 | { |
83fc3bac | 1895 | unsigned int op0, op1, op2; |
9fca2fd3 | 1896 | int temp; |
83fc3bac | 1897 | |
ead4a3f1 | 1898 | trace_input ("tst1", OP_BIT, 0); |
83fc3bac JL |
1899 | op0 = State.regs[OP[0]]; |
1900 | op1 = OP[1] & 0x7; | |
ead4a3f1 | 1901 | temp = SEXT16 (OP[2]); |
83fc3bac | 1902 | op2 = temp; |
96851909 | 1903 | temp = load_mem (op0 + op2, 1); |
ee3f2d4f | 1904 | PSW &= ~PSW_Z; |
83fc3bac | 1905 | if ((temp & (1 << op1)) == 0) |
ee3f2d4f | 1906 | PSW |= PSW_Z; |
ead4a3f1 | 1907 | trace_output (OP_BIT); |
1fe983dc | 1908 | } |
e98e3b2c | 1909 | |
88777ce2 SG |
1910 | /* breakpoint */ |
1911 | void | |
1912 | OP_FFFF () | |
1913 | { | |
1914 | State.exception = SIGTRAP; | |
1915 | PC -= 4; | |
1916 | } | |
1917 | ||
3095b8df | 1918 | /* di */ |
e98e3b2c JL |
1919 | void |
1920 | OP_16007E0 () | |
1921 | { | |
ead4a3f1 | 1922 | trace_input ("di", OP_NONE, 0); |
ee3f2d4f | 1923 | PSW |= PSW_ID; |
ead4a3f1 | 1924 | trace_output (OP_NONE); |
e98e3b2c JL |
1925 | } |
1926 | ||
3095b8df | 1927 | /* ei */ |
e98e3b2c JL |
1928 | void |
1929 | OP_16087E0 () | |
1930 | { | |
ead4a3f1 | 1931 | trace_input ("ei", OP_NONE, 0); |
ee3f2d4f | 1932 | PSW &= ~PSW_ID; |
ead4a3f1 | 1933 | trace_output (OP_NONE); |
e98e3b2c JL |
1934 | } |
1935 | ||
ee3f2d4f | 1936 | /* halt */ |
e98e3b2c JL |
1937 | void |
1938 | OP_12007E0 () | |
1939 | { | |
ead4a3f1 | 1940 | trace_input ("halt", OP_NONE, 0); |
ee3f2d4f | 1941 | /* FIXME this should put processor into a mode where NMI still handled */ |
d81352b8 | 1942 | State.exception = SIGQUIT; |
ead4a3f1 | 1943 | trace_output (OP_NONE); |
e98e3b2c JL |
1944 | } |
1945 | ||
ee3f2d4f | 1946 | /* reti */ |
e98e3b2c JL |
1947 | void |
1948 | OP_14007E0 () | |
1949 | { | |
ead4a3f1 MM |
1950 | trace_input ("reti", OP_NONE, 0); |
1951 | trace_output (OP_NONE); | |
96851909 | 1952 | |
ee3f2d4f MM |
1953 | /* Restore for NMI if only NP on, otherwise is interrupt or exception. */ |
1954 | if ((PSW & (PSW_NP | PSW_EP)) == PSW_NP) | |
1955 | { | |
1956 | PC = FEPC - 4; | |
1957 | PSW = FEPSW; | |
96851909 SG |
1958 | } |
1959 | else | |
1960 | { | |
ee3f2d4f MM |
1961 | PC = EIPC - 4; |
1962 | PSW = EIPSW; | |
96851909 | 1963 | } |
e98e3b2c JL |
1964 | } |
1965 | ||
ee3f2d4f | 1966 | /* trap */ |
e98e3b2c JL |
1967 | void |
1968 | OP_10007E0 () | |
1969 | { | |
ead4a3f1 MM |
1970 | trace_input ("trap", OP_TRAP, 0); |
1971 | trace_output (OP_TRAP); | |
1972 | ||
96851909 | 1973 | /* Trap 31 is used for simulating OS I/O functions */ |
d81352b8 | 1974 | |
96851909 | 1975 | if (OP[0] == 31) |
d81352b8 | 1976 | { |
d81352b8 JL |
1977 | int save_errno = errno; |
1978 | errno = 0; | |
1979 | ||
1980 | /* Registers passed to trap 0 */ | |
1981 | ||
1982 | #define FUNC State.regs[6] /* function number, return value */ | |
1983 | #define PARM1 State.regs[7] /* optional parm 1 */ | |
1984 | #define PARM2 State.regs[8] /* optional parm 2 */ | |
1985 | #define PARM3 State.regs[9] /* optional parm 3 */ | |
1986 | ||
1987 | /* Registers set by trap 0 */ | |
1988 | ||
1989 | #define RETVAL State.regs[10] /* return value */ | |
1990 | #define RETERR State.regs[11] /* return error code */ | |
1991 | ||
1992 | /* Turn a pointer in a register into a pointer into real memory. */ | |
1993 | ||
96851909 | 1994 | #define MEMPTR(x) (map (x)) |
d81352b8 JL |
1995 | |
1996 | switch (FUNC) | |
1997 | { | |
d81352b8 JL |
1998 | #if !defined(__GO32__) && !defined(_WIN32) |
1999 | case SYS_fork: | |
2000 | RETVAL = fork (); | |
2001 | break; | |
2002 | case SYS_execve: | |
2003 | RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), | |
2004 | (char **)MEMPTR (PARM3)); | |
2005 | break; | |
2006 | case SYS_execv: | |
2007 | RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL); | |
2008 | break; | |
9909e232 | 2009 | #if 0 |
d81352b8 JL |
2010 | case SYS_pipe: |
2011 | { | |
2012 | reg_t buf; | |
2013 | int host_fd[2]; | |
2014 | ||
2015 | buf = PARM1; | |
2016 | RETVAL = pipe (host_fd); | |
2017 | SW (buf, host_fd[0]); | |
2018 | buf += sizeof(uint16); | |
2019 | SW (buf, host_fd[1]); | |
2020 | } | |
2021 | break; | |
2022 | ||
2023 | case SYS_wait: | |
2024 | { | |
2025 | int status; | |
2026 | ||
2027 | RETVAL = wait (&status); | |
2028 | SW (PARM1, status); | |
2029 | } | |
2030 | break; | |
9909e232 | 2031 | #endif |
d81352b8 JL |
2032 | #endif |
2033 | ||
2034 | case SYS_read: | |
2035 | RETVAL = v850_callback->read (v850_callback, PARM1, MEMPTR (PARM2), | |
2036 | PARM3); | |
2037 | break; | |
d81352b8 JL |
2038 | case SYS_write: |
2039 | if (PARM1 == 1) | |
2040 | RETVAL = (int)v850_callback->write_stdout (v850_callback, | |
2041 | MEMPTR (PARM2), PARM3); | |
2042 | else | |
2043 | RETVAL = (int)v850_callback->write (v850_callback, PARM1, | |
2044 | MEMPTR (PARM2), PARM3); | |
2045 | break; | |
d81352b8 JL |
2046 | case SYS_lseek: |
2047 | RETVAL = v850_callback->lseek (v850_callback, PARM1, PARM2, PARM3); | |
2048 | break; | |
2049 | case SYS_close: | |
2050 | RETVAL = v850_callback->close (v850_callback, PARM1); | |
2051 | break; | |
2052 | case SYS_open: | |
2053 | RETVAL = v850_callback->open (v850_callback, MEMPTR (PARM1), PARM2); | |
2054 | break; | |
d81352b8 | 2055 | case SYS_exit: |
6ec96a02 MM |
2056 | if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0) |
2057 | State.exception = PARM1 & 0xffff; /* get signal encoded by kill */ | |
2058 | else if (PARM1 == 0xdead) | |
2059 | State.exception = SIGABRT; /* old libraries */ | |
2060 | else | |
2061 | State.exception = SIG_V850_EXIT; /* PARM1 has exit status encoded */ | |
d81352b8 JL |
2062 | break; |
2063 | ||
d81352b8 JL |
2064 | case SYS_stat: /* added at hmsi */ |
2065 | /* stat system call */ | |
2066 | { | |
2067 | struct stat host_stat; | |
2068 | reg_t buf; | |
2069 | ||
2070 | RETVAL = stat (MEMPTR (PARM1), &host_stat); | |
2071 | ||
2072 | buf = PARM2; | |
2073 | ||
c500c074 JL |
2074 | /* Just wild-assed guesses. */ |
2075 | store_mem (buf, 2, host_stat.st_dev); | |
2076 | store_mem (buf + 2, 2, host_stat.st_ino); | |
2077 | store_mem (buf + 4, 4, host_stat.st_mode); | |
2078 | store_mem (buf + 8, 2, host_stat.st_nlink); | |
2079 | store_mem (buf + 10, 2, host_stat.st_uid); | |
2080 | store_mem (buf + 12, 2, host_stat.st_gid); | |
2081 | store_mem (buf + 14, 2, host_stat.st_rdev); | |
2082 | store_mem (buf + 16, 4, host_stat.st_size); | |
2083 | store_mem (buf + 20, 4, host_stat.st_atime); | |
2084 | store_mem (buf + 28, 4, host_stat.st_mtime); | |
2085 | store_mem (buf + 36, 4, host_stat.st_ctime); | |
d81352b8 JL |
2086 | } |
2087 | break; | |
2088 | ||
2089 | case SYS_chown: | |
2090 | RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3); | |
2091 | break; | |
2092 | case SYS_chmod: | |
2093 | RETVAL = chmod (MEMPTR (PARM1), PARM2); | |
2094 | break; | |
6803f89b | 2095 | case SYS_time: |
ee3f2d4f MM |
2096 | { |
2097 | time_t now; | |
2098 | RETVAL = time (&now); | |
2099 | store_mem (PARM1, 4, now); | |
2100 | } | |
6803f89b | 2101 | break; |
8824fb45 JL |
2102 | case SYS_times: |
2103 | { | |
2104 | struct tms tms; | |
2105 | RETVAL = times (&tms); | |
2106 | store_mem (PARM1, 4, tms.tms_utime); | |
2107 | store_mem (PARM1 + 4, 4, tms.tms_stime); | |
2108 | store_mem (PARM1 + 8, 4, tms.tms_cutime); | |
2109 | store_mem (PARM1 + 12, 4, tms.tms_cstime); | |
2110 | break; | |
2111 | } | |
2112 | case SYS_gettimeofday: | |
2113 | { | |
2114 | struct timeval t; | |
2115 | struct timezone tz; | |
2116 | RETVAL = gettimeofday (&t, &tz); | |
2117 | store_mem (PARM1, 4, t.tv_sec); | |
2118 | store_mem (PARM1 + 4, 4, t.tv_usec); | |
2119 | store_mem (PARM2, 4, tz.tz_minuteswest); | |
2120 | store_mem (PARM2 + 4, 4, tz.tz_dsttime); | |
2121 | break; | |
2122 | } | |
d81352b8 JL |
2123 | case SYS_utime: |
2124 | /* Cast the second argument to void *, to avoid type mismatch | |
2125 | if a prototype is present. */ | |
2126 | RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2)); | |
2127 | break; | |
d81352b8 JL |
2128 | default: |
2129 | abort (); | |
2130 | } | |
2131 | RETERR = errno; | |
2132 | errno = save_errno; | |
d81352b8 | 2133 | } |
96851909 SG |
2134 | else |
2135 | { /* Trap 0 -> 30 */ | |
ee3f2d4f MM |
2136 | EIPC = PC + 4; |
2137 | EIPSW = PSW; | |
2138 | /* Mask out EICC */ | |
2139 | ECR &= 0xffff0000; | |
2140 | ECR |= 0x40 + OP[0]; | |
2141 | /* Flag that we are now doing exception processing. */ | |
2142 | PSW |= PSW_EP | PSW_ID; | |
96851909 | 2143 | PC = ((OP[0] < 0x10) ? 0x40 : 0x50) - 4; |
d81352b8 | 2144 | } |
e98e3b2c JL |
2145 | } |
2146 | ||
614f1c68 | 2147 | /* ldsr, reg,reg */ |
e98e3b2c JL |
2148 | void |
2149 | OP_2007E0 () | |
2150 | { | |
614f1c68 JL |
2151 | unsigned int op0; |
2152 | ||
ead4a3f1 | 2153 | trace_input ("ldsr", OP_LDSR, 0); |
614f1c68 JL |
2154 | op0 = State.regs[OP[0]]; |
2155 | State.sregs[OP[1]] = op0; | |
ead4a3f1 | 2156 | trace_output (OP_LDSR); |
e98e3b2c JL |
2157 | } |
2158 | ||
ee3f2d4f | 2159 | /* stsr */ |
e98e3b2c JL |
2160 | void |
2161 | OP_4007E0 () | |
2162 | { | |
614f1c68 JL |
2163 | unsigned int op0; |
2164 | ||
ead4a3f1 | 2165 | trace_input ("stsr", OP_STSR, 0); |
614f1c68 JL |
2166 | op0 = State.sregs[OP[1]]; |
2167 | State.regs[OP[0]] = op0; | |
ead4a3f1 | 2168 | trace_output (OP_STSR); |
e98e3b2c | 2169 | } |