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