Commit | Line | Data |
---|---|---|
22c1c7dd JL |
1 | #include <signal.h> |
2 | #include "v850_sim.h" | |
3 | #include "simops.h" | |
4 | ||
28647e4c | 5 | /* sld.b */ |
22c1c7dd | 6 | void |
28647e4c | 7 | OP_300 () |
22c1c7dd | 8 | { |
3cb6bf78 JL |
9 | unsigned int op0, op1, op2; |
10 | int result, temp; | |
11 | ||
12 | temp = OP[1]; | |
13 | temp = (temp << 25) >> 25; | |
14 | op2 = temp; | |
15 | result = get_byte (State.mem + State.regs[30] + op2); | |
16 | result = (result << 24) >> 24; | |
17 | State.regs[OP[0]] = result; | |
22c1c7dd JL |
18 | } |
19 | ||
28647e4c | 20 | /* sld.h */ |
22c1c7dd | 21 | void |
28647e4c JL |
22 | OP_400 () |
23 | { | |
3cb6bf78 JL |
24 | unsigned int op0, op1, op2; |
25 | int result, temp; | |
26 | ||
27 | temp = OP[1]; | |
28 | temp = (temp << 25) >> 25; | |
29 | op2 = temp << 1; | |
30 | result = get_half (State.mem + State.regs[30] + op2); | |
31 | result = (result << 16) >> 16; | |
32 | State.regs[OP[0]] = result; | |
28647e4c JL |
33 | } |
34 | ||
35 | /* sld.w */ | |
36 | void | |
37 | OP_500 () | |
22c1c7dd | 38 | { |
3cb6bf78 JL |
39 | unsigned int op0, op1, op2; |
40 | int result, temp; | |
41 | ||
42 | temp = OP[1]; | |
43 | temp = (temp << 25) >> 25; | |
44 | op2 = temp << 2; | |
45 | result = get_word (State.mem + State.regs[30] + op2); | |
46 | State.regs[OP[0]] = result; | |
22c1c7dd JL |
47 | } |
48 | ||
28647e4c JL |
49 | /* sst.b */ |
50 | void | |
51 | OP_380 () | |
52 | { | |
3cb6bf78 JL |
53 | unsigned int op0, op1, op2; |
54 | int result, temp; | |
55 | ||
56 | op0 = State.regs[OP[0]]; | |
57 | temp = OP[1]; | |
58 | temp = (temp << 25) >> 25; | |
59 | op1 = temp; | |
60 | put_byte (State.mem + State.regs[30] + op1, op0); | |
28647e4c JL |
61 | } |
62 | ||
63 | /* sst.h */ | |
64 | void | |
65 | OP_480 () | |
66 | { | |
3cb6bf78 JL |
67 | unsigned int op0, op1, op2; |
68 | int result, temp; | |
69 | ||
70 | op0 = State.regs[OP[0]]; | |
71 | temp = OP[1]; | |
72 | temp = (temp << 25) >> 25; | |
73 | op1 = temp << 1; | |
74 | put_half (State.mem + State.regs[30] + op1, op0); | |
28647e4c JL |
75 | } |
76 | ||
77 | /* sst.w */ | |
78 | void | |
79 | OP_501 () | |
80 | { | |
3cb6bf78 JL |
81 | unsigned int op0, op1, op2; |
82 | int result, temp; | |
83 | ||
84 | op0 = State.regs[OP[0]]; | |
85 | temp = OP[1]; | |
86 | temp = (temp << 25) >> 25; | |
87 | op1 = temp << 2; | |
88 | put_word (State.mem + State.regs[30] + op1, op0); | |
28647e4c JL |
89 | } |
90 | ||
91 | /* ld.b */ | |
92 | void | |
93 | OP_700 () | |
94 | { | |
95 | unsigned int op0, op1, op2; | |
96 | int result, temp; | |
97 | ||
98 | op0 = State.regs[OP[0]]; | |
99 | temp = OP[2]; | |
100 | temp = (temp << 16) >> 16; | |
101 | op2 = temp; | |
102 | result = get_byte (State.mem + op0 + op2); | |
103 | result = (result << 24) >> 24; | |
104 | State.regs[OP[1]] = result; | |
105 | } | |
106 | ||
107 | /* ld.h */ | |
108 | void | |
109 | OP_720 () | |
110 | { | |
111 | unsigned int op0, op1, op2; | |
112 | int result, temp; | |
113 | ||
114 | op0 = State.regs[OP[0]]; | |
3046d879 | 115 | temp = OP[2]; |
28647e4c JL |
116 | temp = (temp << 16) >> 16; |
117 | temp &= ~0x1; | |
118 | op2 = temp; | |
119 | result = get_half (State.mem + op0 + op2); | |
120 | result = (result << 16) >> 16; | |
121 | State.regs[OP[1]] = result; | |
122 | } | |
123 | ||
124 | /* ld.w */ | |
125 | void | |
126 | OP_10720 () | |
127 | { | |
128 | unsigned int op0, op1, op2; | |
129 | int result, temp; | |
130 | ||
131 | op0 = State.regs[OP[0]]; | |
3046d879 | 132 | temp = OP[2]; |
28647e4c JL |
133 | temp = (temp << 16) >> 16; |
134 | temp &= ~0x1; | |
135 | op2 = temp; | |
136 | result = get_word (State.mem + op0 + op2); | |
137 | State.regs[OP[1]] = result; | |
138 | } | |
139 | ||
140 | /* st.b */ | |
141 | void | |
142 | OP_740 () | |
143 | { | |
144 | unsigned int op0, op1, op2; | |
145 | int result, temp; | |
146 | ||
147 | op0 = State.regs[OP[0]]; | |
148 | op1 = State.regs[OP[1]]; | |
149 | temp = OP[2]; | |
150 | temp = (temp << 16) >> 16; | |
151 | op2 = temp; | |
152 | put_byte (State.mem + op0 + op2, op1); | |
153 | } | |
154 | ||
155 | /* st.h */ | |
22c1c7dd JL |
156 | void |
157 | OP_760 () | |
158 | { | |
28647e4c JL |
159 | unsigned int op0, op1, op2; |
160 | int result, temp; | |
161 | ||
162 | op0 = State.regs[OP[0]]; | |
163 | op1 = State.regs[OP[1]]; | |
164 | temp = OP[2]; | |
165 | temp &= ~0x1; | |
166 | temp = (temp << 16) >> 16; | |
167 | op2 = temp; | |
168 | put_half (State.mem + op0 + op2, op1); | |
169 | } | |
170 | ||
171 | /* st.w */ | |
172 | void | |
173 | OP_10760 () | |
174 | { | |
175 | unsigned int op0, op1, op2; | |
176 | int result, temp; | |
177 | ||
178 | op0 = State.regs[OP[0]]; | |
179 | op1 = State.regs[OP[1]]; | |
180 | temp = OP[2]; | |
181 | temp &= ~0x1; | |
182 | temp = (temp << 16) >> 16; | |
183 | op2 = temp; | |
184 | put_word (State.mem + op0 + op2, op1); | |
22c1c7dd JL |
185 | } |
186 | ||
2108e864 | 187 | /* bv disp9 */ |
22c1c7dd JL |
188 | void |
189 | OP_580 () | |
190 | { | |
2108e864 JL |
191 | unsigned int op0, psw; |
192 | int temp; | |
22c1c7dd | 193 | |
d81352b8 | 194 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 195 | psw = State.sregs[5]; |
2108e864 JL |
196 | |
197 | if ((psw & PSW_OV) != 0) | |
198 | State.pc += op0; | |
199 | else | |
200 | State.pc += 2; | |
22c1c7dd JL |
201 | } |
202 | ||
2108e864 | 203 | /* bl disp9 */ |
22c1c7dd JL |
204 | void |
205 | OP_581 () | |
206 | { | |
2108e864 JL |
207 | unsigned int op0, psw; |
208 | int temp; | |
209 | ||
d81352b8 | 210 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 211 | psw = State.sregs[5]; |
2108e864 JL |
212 | |
213 | if ((psw & PSW_CY) != 0) | |
214 | State.pc += op0; | |
215 | else | |
216 | State.pc += 2; | |
22c1c7dd JL |
217 | } |
218 | ||
2108e864 | 219 | /* be disp9 */ |
22c1c7dd JL |
220 | void |
221 | OP_582 () | |
222 | { | |
2108e864 JL |
223 | unsigned int op0, psw; |
224 | int temp; | |
225 | ||
d81352b8 | 226 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 227 | psw = State.sregs[5]; |
2108e864 JL |
228 | |
229 | if ((psw & PSW_Z) != 0) | |
230 | State.pc += op0; | |
231 | else | |
232 | State.pc += 2; | |
22c1c7dd JL |
233 | } |
234 | ||
2108e864 | 235 | /* bnh disp 9*/ |
22c1c7dd JL |
236 | void |
237 | OP_583 () | |
238 | { | |
2108e864 JL |
239 | unsigned int op0, psw; |
240 | int temp; | |
241 | ||
d81352b8 | 242 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 243 | psw = State.sregs[5]; |
2108e864 JL |
244 | |
245 | if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0) | |
246 | State.pc += op0; | |
247 | else | |
248 | State.pc += 2; | |
22c1c7dd JL |
249 | } |
250 | ||
2108e864 | 251 | /* bn disp9 */ |
22c1c7dd JL |
252 | void |
253 | OP_584 () | |
254 | { | |
2108e864 JL |
255 | unsigned int op0, psw; |
256 | int temp; | |
257 | ||
d81352b8 | 258 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 259 | psw = State.sregs[5]; |
2108e864 JL |
260 | |
261 | if ((psw & PSW_S) != 0) | |
262 | State.pc += op0; | |
263 | else | |
264 | State.pc += 2; | |
22c1c7dd JL |
265 | } |
266 | ||
2108e864 | 267 | /* br disp9 */ |
22c1c7dd JL |
268 | void |
269 | OP_585 () | |
270 | { | |
2108e864 JL |
271 | unsigned int op0; |
272 | int temp; | |
273 | ||
d81352b8 | 274 | op0 = ((signed)OP[0] << 23) >> 23; |
2108e864 | 275 | State.pc += op0; |
22c1c7dd JL |
276 | } |
277 | ||
2108e864 | 278 | /* blt disp9 */ |
22c1c7dd JL |
279 | void |
280 | OP_586 () | |
281 | { | |
2108e864 JL |
282 | unsigned int op0, psw; |
283 | int temp; | |
284 | ||
d81352b8 | 285 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 286 | psw = State.sregs[5]; |
2108e864 JL |
287 | |
288 | if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0) | |
289 | State.pc += op0; | |
290 | else | |
291 | State.pc += 2; | |
22c1c7dd JL |
292 | } |
293 | ||
2108e864 | 294 | /* ble disp9 */ |
22c1c7dd JL |
295 | void |
296 | OP_587 () | |
297 | { | |
2108e864 JL |
298 | unsigned int op0, psw; |
299 | int temp; | |
300 | ||
d81352b8 | 301 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 302 | psw = State.sregs[5]; |
2108e864 JL |
303 | |
304 | if ((((psw & PSW_Z) != 0) | |
305 | || (((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0))) != 0) | |
306 | State.pc += op0; | |
307 | else | |
308 | State.pc += 2; | |
22c1c7dd JL |
309 | } |
310 | ||
2108e864 | 311 | /* bnv disp9 */ |
22c1c7dd JL |
312 | void |
313 | OP_588 () | |
314 | { | |
2108e864 JL |
315 | unsigned int op0, psw; |
316 | int temp; | |
317 | ||
d81352b8 | 318 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 319 | psw = State.sregs[5]; |
2108e864 JL |
320 | |
321 | if ((psw & PSW_OV) == 0) | |
322 | State.pc += op0; | |
323 | else | |
324 | State.pc += 2; | |
22c1c7dd JL |
325 | } |
326 | ||
2108e864 | 327 | /* bnl disp9 */ |
22c1c7dd JL |
328 | void |
329 | OP_589 () | |
330 | { | |
2108e864 JL |
331 | unsigned int op0, psw; |
332 | int temp; | |
333 | ||
d81352b8 | 334 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 335 | psw = State.sregs[5]; |
2108e864 JL |
336 | |
337 | if ((psw & PSW_CY) == 0) | |
338 | State.pc += op0; | |
339 | else | |
340 | State.pc += 2; | |
22c1c7dd JL |
341 | } |
342 | ||
2108e864 | 343 | /* bne disp9 */ |
22c1c7dd JL |
344 | void |
345 | OP_58A () | |
346 | { | |
2108e864 JL |
347 | unsigned int op0, psw; |
348 | int temp; | |
349 | ||
d81352b8 | 350 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 351 | psw = State.sregs[5]; |
2108e864 JL |
352 | |
353 | if ((psw & PSW_Z) == 0) | |
354 | State.pc += op0; | |
355 | else | |
356 | State.pc += 2; | |
22c1c7dd JL |
357 | } |
358 | ||
2108e864 | 359 | /* bh disp9 */ |
22c1c7dd JL |
360 | void |
361 | OP_58B () | |
362 | { | |
2108e864 JL |
363 | unsigned int op0, psw; |
364 | int temp; | |
22c1c7dd | 365 | |
d81352b8 | 366 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 367 | psw = State.sregs[5]; |
2108e864 JL |
368 | |
369 | if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0) | |
370 | State.pc += op0; | |
371 | else | |
372 | State.pc += 2; | |
22c1c7dd JL |
373 | } |
374 | ||
2108e864 | 375 | /* bp disp9 */ |
22c1c7dd | 376 | void |
2108e864 | 377 | OP_58C () |
22c1c7dd | 378 | { |
2108e864 JL |
379 | unsigned int op0, psw; |
380 | int temp; | |
22c1c7dd | 381 | |
d81352b8 | 382 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 383 | psw = State.sregs[5]; |
2108e864 JL |
384 | |
385 | if ((psw & PSW_S) == 0) | |
386 | State.pc += op0; | |
387 | else | |
388 | State.pc += 2; | |
22c1c7dd JL |
389 | } |
390 | ||
2108e864 | 391 | /* bsa disp9 */ |
22c1c7dd JL |
392 | void |
393 | OP_58D () | |
394 | { | |
2108e864 JL |
395 | unsigned int op0, psw; |
396 | int temp; | |
397 | ||
d81352b8 | 398 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 399 | psw = State.sregs[5]; |
2108e864 JL |
400 | |
401 | if ((psw & PSW_SAT) != 0) | |
402 | State.pc += op0; | |
403 | else | |
404 | State.pc += 2; | |
22c1c7dd JL |
405 | } |
406 | ||
2108e864 | 407 | /* bge disp9 */ |
22c1c7dd JL |
408 | void |
409 | OP_58E () | |
410 | { | |
2108e864 JL |
411 | unsigned int op0, psw; |
412 | int temp; | |
413 | ||
d81352b8 | 414 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 415 | psw = State.sregs[5]; |
2108e864 JL |
416 | |
417 | if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0) | |
418 | State.pc += op0; | |
419 | else | |
420 | State.pc += 2; | |
22c1c7dd JL |
421 | } |
422 | ||
2108e864 | 423 | /* bgt disp9 */ |
22c1c7dd JL |
424 | void |
425 | OP_58F () | |
426 | { | |
2108e864 JL |
427 | unsigned int op0, psw; |
428 | int temp; | |
429 | ||
d81352b8 | 430 | op0 = ((signed)OP[0] << 23) >> 23; |
614f1c68 | 431 | psw = State.sregs[5]; |
2108e864 JL |
432 | |
433 | if ((((psw & PSW_Z) != 0) | |
434 | || (((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0))) == 0) | |
435 | State.pc += op0; | |
436 | else | |
437 | State.pc += 2; | |
22c1c7dd JL |
438 | } |
439 | ||
e9b6cbac | 440 | /* jmp [reg1] */ |
22c1c7dd | 441 | void |
e9b6cbac | 442 | OP_60 () |
22c1c7dd | 443 | { |
e9b6cbac JL |
444 | /* interp.c will bump this by +2, so correct for it here. */ |
445 | State.pc = State.regs[OP[0]] - 2; | |
22c1c7dd JL |
446 | } |
447 | ||
e9b6cbac JL |
448 | /* jarl disp22, reg */ |
449 | void | |
450 | OP_780 () | |
451 | { | |
452 | unsigned int op0, opc; | |
453 | int temp; | |
454 | ||
455 | temp = OP[0]; | |
456 | temp = (temp << 10) >> 10; | |
457 | op0 = temp; | |
458 | opc = State.pc; | |
459 | ||
460 | State.pc += temp; | |
461 | ||
462 | /* Gross. jarl X,r0 is really jr and doesn't save its result. */ | |
463 | if (OP[1] != 0) | |
464 | State.regs[OP[1]] = opc + 4; | |
465 | } | |
22c1c7dd | 466 | |
0ef0eba5 | 467 | /* add reg, reg */ |
22c1c7dd | 468 | void |
1fe983dc | 469 | OP_1C0 () |
22c1c7dd | 470 | { |
0ef0eba5 | 471 | unsigned int op0, op1, result, z, s, cy, ov; |
22c1c7dd | 472 | |
0ef0eba5 JL |
473 | /* Compute the result. */ |
474 | op0 = State.regs[OP[0]]; | |
475 | op1 = State.regs[OP[1]]; | |
476 | result = op0 + op1; | |
1fe983dc | 477 | |
0ef0eba5 JL |
478 | /* Compute the condition codes. */ |
479 | z = (result == 0); | |
480 | s = (result & 0x80000000); | |
481 | cy = (result < op0 || result < op1); | |
482 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
483 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
484 | ||
d81352b8 JL |
485 | /* According to the manual, 's' is inverted if 'ov' |
486 | is set. */ | |
487 | s = ov ? !s : s; | |
488 | ||
0ef0eba5 JL |
489 | /* Store the result and condition codes. */ |
490 | State.regs[OP[1]] = result; | |
614f1c68 JL |
491 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
492 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
493 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); | |
0ef0eba5 JL |
494 | } |
495 | ||
496 | /* add sign_extend(imm5), reg */ | |
22c1c7dd | 497 | void |
1fe983dc | 498 | OP_240 () |
22c1c7dd | 499 | { |
0ef0eba5 JL |
500 | unsigned int op0, op1, result, z, s, cy, ov; |
501 | int temp; | |
1fe983dc | 502 | |
0ef0eba5 JL |
503 | /* Compute the result. */ |
504 | temp = (OP[0] & 0x1f); | |
505 | temp = (temp << 27) >> 27; | |
506 | op0 = temp; | |
507 | op1 = State.regs[OP[1]]; | |
508 | result = op0 + op1; | |
509 | ||
510 | /* Compute the condition codes. */ | |
511 | z = (result == 0); | |
512 | s = (result & 0x80000000); | |
513 | cy = (result < op0 || result < op1); | |
514 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
515 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
22c1c7dd | 516 | |
d81352b8 JL |
517 | /* According to the manual, 's' is inverted if 'ov' |
518 | is set. */ | |
519 | s = ov ? !s : s; | |
520 | ||
0ef0eba5 JL |
521 | /* Store the result and condition codes. */ |
522 | State.regs[OP[1]] = result; | |
614f1c68 JL |
523 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
524 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
0ef0eba5 JL |
525 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
526 | } | |
1fe983dc | 527 | |
0ef0eba5 | 528 | /* addi sign_extend(imm16), reg, reg */ |
22c1c7dd | 529 | void |
1fe983dc | 530 | OP_600 () |
22c1c7dd | 531 | { |
0ef0eba5 JL |
532 | unsigned int op0, op1, result, z, s, cy, ov; |
533 | int temp; | |
534 | ||
535 | /* Compute the result. */ | |
536 | temp = (OP[0] & 0xffff); | |
537 | temp = (temp << 16) >> 16; | |
538 | op0 = temp; | |
539 | op1 = State.regs[OP[1]]; | |
540 | result = op0 + op1; | |
541 | ||
542 | /* Compute the condition codes. */ | |
543 | z = (result == 0); | |
544 | s = (result & 0x80000000); | |
545 | cy = (result < op0 || result < op1); | |
546 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
547 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
548 | ||
d81352b8 JL |
549 | /* According to the manual, 's' is inverted if 'ov' |
550 | is set. */ | |
551 | s = ov ? !s : s; | |
552 | ||
0ef0eba5 JL |
553 | /* Store the result and condition codes. */ |
554 | State.regs[OP[2]] = result; | |
614f1c68 JL |
555 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
556 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
0ef0eba5 | 557 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
22c1c7dd JL |
558 | } |
559 | ||
aabce0f4 | 560 | /* sub reg1, reg2 */ |
22c1c7dd | 561 | void |
1fe983dc | 562 | OP_1A0 () |
22c1c7dd | 563 | { |
aabce0f4 JL |
564 | unsigned int op0, op1, result, z, s, cy, ov; |
565 | ||
566 | /* Compute the result. */ | |
567 | op0 = State.regs[OP[0]]; | |
568 | op1 = State.regs[OP[1]]; | |
569 | result = op1 - op0; | |
22c1c7dd | 570 | |
aabce0f4 JL |
571 | /* Compute the condition codes. */ |
572 | z = (result == 0); | |
573 | s = (result & 0x80000000); | |
d81352b8 | 574 | cy = (op1 < op0); |
aabce0f4 JL |
575 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
576 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
1fe983dc | 577 | |
d81352b8 JL |
578 | /* According to the manual, 's' is inverted if 'ov' |
579 | is set. */ | |
580 | s = ov ? !s : s; | |
581 | ||
aabce0f4 JL |
582 | /* Store the result and condition codes. */ |
583 | State.regs[OP[1]] = result; | |
614f1c68 JL |
584 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
585 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
aabce0f4 | 586 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
aabce0f4 JL |
587 | } |
588 | ||
589 | /* subr reg1, reg2 */ | |
22c1c7dd | 590 | void |
1fe983dc | 591 | OP_180 () |
22c1c7dd | 592 | { |
aabce0f4 | 593 | unsigned int op0, op1, result, z, s, cy, ov; |
22c1c7dd | 594 | |
aabce0f4 JL |
595 | /* Compute the result. */ |
596 | op0 = State.regs[OP[0]]; | |
597 | op1 = State.regs[OP[1]]; | |
598 | result = op0 - op1; | |
e98e3b2c | 599 | |
aabce0f4 JL |
600 | /* Compute the condition codes. */ |
601 | z = (result == 0); | |
602 | s = (result & 0x80000000); | |
d81352b8 | 603 | cy = (op0 < op1); |
aabce0f4 JL |
604 | ov = ((op0 & 0x80000000) != (op1 & 0x80000000) |
605 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
606 | ||
d81352b8 JL |
607 | /* According to the manual, 's' is inverted if 'ov' |
608 | is set. */ | |
609 | s = ov ? !s : s; | |
610 | ||
aabce0f4 JL |
611 | /* Store the result and condition codes. */ |
612 | State.regs[OP[1]] = result; | |
614f1c68 JL |
613 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
614 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
aabce0f4 JL |
615 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
616 | } | |
617 | ||
618 | /* mulh reg1, reg2 */ | |
22c1c7dd | 619 | void |
e98e3b2c | 620 | OP_E0 () |
22c1c7dd | 621 | { |
e98e3b2c | 622 | State.regs[OP[1]] = ((State.regs[OP[1]] & 0xffff) |
fb8eb42b | 623 | * (State.regs[OP[0]] & 0xffff)); |
22c1c7dd JL |
624 | } |
625 | ||
e98e3b2c JL |
626 | /* mulh sign_extend(imm5), reg2 |
627 | ||
628 | Condition codes */ | |
22c1c7dd | 629 | void |
e98e3b2c | 630 | OP_2E0 () |
22c1c7dd | 631 | { |
e98e3b2c JL |
632 | int value = OP[0]; |
633 | ||
634 | value = (value << 27) >> 27; | |
635 | ||
636 | State.regs[OP[1]] = (State.regs[OP[1]] & 0xffff) * value; | |
22c1c7dd JL |
637 | } |
638 | ||
aabce0f4 | 639 | /* mulhi imm16, reg1, reg2 */ |
22c1c7dd | 640 | void |
e98e3b2c JL |
641 | OP_6E0 () |
642 | { | |
643 | int value = OP[0]; | |
644 | ||
645 | value = value & 0xffff; | |
646 | ||
fb8eb42b | 647 | State.regs[OP[2]] = (State.regs[OP[1]] & 0xffff) * value; |
e98e3b2c JL |
648 | } |
649 | ||
aabce0f4 | 650 | /* divh reg1, reg2 */ |
e98e3b2c JL |
651 | void |
652 | OP_40 () | |
22c1c7dd | 653 | { |
aabce0f4 JL |
654 | unsigned int op0, op1, result, z, s, cy, ov; |
655 | int temp; | |
656 | ||
657 | /* Compute the result. */ | |
658 | temp = State.regs[OP[0]] & 0xffff; | |
659 | temp = (temp << 16) >> 16; | |
660 | op0 = temp; | |
661 | op1 = State.regs[OP[1]]; | |
662 | ||
663 | if (op0 == 0xffffffff && op1 == 0x80000000) | |
664 | { | |
665 | result = 0x80000000; | |
666 | ov = 1; | |
667 | } | |
668 | else if (op0 != 0) | |
669 | { | |
670 | result = op1 / op0; | |
671 | ov = 0; | |
672 | } | |
673 | else | |
674 | ov = 1; | |
675 | ||
676 | /* Compute the condition codes. */ | |
677 | z = (result == 0); | |
678 | s = (result & 0x80000000); | |
679 | ||
680 | /* Store the result and condition codes. */ | |
681 | State.regs[OP[1]] = result; | |
614f1c68 JL |
682 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
683 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
aabce0f4 | 684 | | (ov ? PSW_OV : 0)); |
22c1c7dd JL |
685 | } |
686 | ||
3095b8df JL |
687 | /* cmp reg, reg */ |
688 | void | |
689 | OP_1E0 () | |
690 | { | |
691 | unsigned int op0, op1, result, z, s, cy, ov; | |
692 | ||
693 | /* Compute the result. */ | |
694 | op0 = State.regs[OP[0]]; | |
695 | op1 = State.regs[OP[1]]; | |
696 | result = op1 - op0; | |
697 | ||
698 | /* Compute the condition codes. */ | |
699 | z = (result == 0); | |
700 | s = (result & 0x80000000); | |
d81352b8 | 701 | cy = (op1 < op0); |
3095b8df JL |
702 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
703 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
704 | ||
705 | /* Set condition codes. */ | |
614f1c68 JL |
706 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
707 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
3095b8df JL |
708 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
709 | } | |
710 | ||
711 | /* cmp sign_extend(imm5), reg */ | |
712 | void | |
713 | OP_260 () | |
714 | { | |
715 | unsigned int op0, op1, result, z, s, cy, ov; | |
716 | int temp; | |
717 | ||
718 | /* Compute the result. */ | |
719 | temp = OP[0]; | |
720 | temp = (temp << 27) >> 27; | |
721 | op0 = temp; | |
722 | op1 = State.regs[OP[1]]; | |
723 | result = op1 - op0; | |
724 | ||
725 | /* Compute the condition codes. */ | |
726 | z = (result == 0); | |
727 | s = (result & 0x80000000); | |
d81352b8 | 728 | cy = (op1 < op0); |
3095b8df JL |
729 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
730 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
731 | ||
732 | /* Set condition codes. */ | |
614f1c68 JL |
733 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
734 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
3095b8df JL |
735 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
736 | } | |
737 | ||
738 | /* setf cccc,reg2 */ | |
739 | void | |
740 | OP_7E0 () | |
741 | { | |
742 | /* Hack alert. We turn off a bit in op0 since we really only | |
743 | wanted 4 bits. */ | |
744 | unsigned int op0, psw, result; | |
745 | ||
746 | op0 = OP[0] & 0xf; | |
614f1c68 | 747 | psw = State.sregs[5]; |
3095b8df JL |
748 | |
749 | switch (op0) | |
750 | { | |
751 | case 0x0: | |
752 | result = ((psw & PSW_OV) != 0); | |
753 | break; | |
754 | case 0x1: | |
755 | result = ((psw & PSW_CY) != 0); | |
756 | break; | |
757 | case 0x2: | |
758 | result = ((psw & PSW_Z) != 0); | |
759 | break; | |
760 | case 0x3: | |
761 | result = ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0); | |
762 | break; | |
763 | case 0x4: | |
764 | result = ((psw & PSW_S) != 0); | |
765 | break; | |
766 | case 0x5: | |
767 | result = 1; | |
768 | break; | |
769 | case 0x6: | |
770 | result = ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0); | |
771 | break; | |
772 | case 0x7: | |
773 | result = (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) | |
774 | || ((psw & PSW_Z) != 0)) != 0); | |
775 | break; | |
776 | case 0x8: | |
777 | result = ((psw & PSW_OV) == 0); | |
778 | break; | |
779 | case 0x9: | |
780 | result = ((psw & PSW_CY) == 0); | |
781 | break; | |
782 | case 0xa: | |
783 | result = ((psw & PSW_Z) == 0); | |
784 | break; | |
785 | case 0xb: | |
786 | result = ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0); | |
787 | break; | |
788 | case 0xc: | |
789 | result = ((psw & PSW_S) == 0); | |
790 | break; | |
791 | case 0xd: | |
792 | result = ((psw & PSW_SAT) != 0); | |
793 | break; | |
794 | case 0xe: | |
795 | result = ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0); | |
796 | break; | |
797 | case 0xf: | |
798 | result = (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) | |
799 | || ((psw & PSW_Z) != 0)) == 0); | |
800 | break; | |
801 | } | |
802 | ||
803 | State.regs[OP[1]] = result; | |
804 | } | |
805 | ||
dca41ba7 JL |
806 | /* satadd reg,reg */ |
807 | void | |
808 | OP_C0 () | |
809 | { | |
810 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
811 | ||
812 | /* Compute the result. */ | |
813 | op0 = State.regs[OP[0]]; | |
814 | op1 = State.regs[OP[1]]; | |
815 | result = op0 + op1; | |
816 | ||
817 | /* Compute the condition codes. */ | |
818 | z = (result == 0); | |
819 | s = (result & 0x80000000); | |
820 | cy = (result < op0 || result < op1); | |
821 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
822 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
823 | sat = ov; | |
824 | ||
825 | /* Store the result and condition codes. */ | |
826 | State.regs[OP[1]] = result; | |
614f1c68 JL |
827 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
828 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
829 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
830 | | (sat ? PSW_SAT : 0)); | |
831 | ||
832 | /* Handle saturated results. */ | |
0e4ccc58 | 833 | if (sat && s) |
dca41ba7 JL |
834 | State.regs[OP[1]] = 0x80000000; |
835 | else if (sat) | |
836 | State.regs[OP[1]] = 0x7fffffff; | |
837 | } | |
838 | ||
839 | /* satadd sign_extend(imm5), reg */ | |
840 | void | |
841 | OP_220 () | |
842 | { | |
843 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
844 | ||
845 | int temp; | |
846 | ||
847 | /* Compute the result. */ | |
848 | temp = (OP[0] & 0x1f); | |
849 | temp = (temp << 27) >> 27; | |
850 | op0 = temp; | |
851 | op1 = State.regs[OP[1]]; | |
852 | result = op0 + op1; | |
853 | ||
854 | /* Compute the condition codes. */ | |
855 | z = (result == 0); | |
856 | s = (result & 0x80000000); | |
857 | cy = (result < op0 || result < op1); | |
858 | ov = ((op0 & 0x80000000) == (op1 & 0x80000000) | |
859 | && (op0 & 0x80000000) != (result & 0x80000000)); | |
860 | sat = ov; | |
861 | ||
862 | /* Store the result and condition codes. */ | |
863 | State.regs[OP[1]] = result; | |
614f1c68 JL |
864 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
865 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
866 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
867 | | (sat ? PSW_SAT : 0)); | |
868 | ||
869 | /* Handle saturated results. */ | |
0e4ccc58 | 870 | if (sat && s) |
dca41ba7 JL |
871 | State.regs[OP[1]] = 0x80000000; |
872 | else if (sat) | |
873 | State.regs[OP[1]] = 0x7fffffff; | |
874 | } | |
875 | ||
876 | /* satsub reg1, reg2 */ | |
877 | void | |
878 | OP_A0 () | |
879 | { | |
880 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
881 | ||
882 | /* Compute the result. */ | |
883 | op0 = State.regs[OP[0]]; | |
884 | op1 = State.regs[OP[1]]; | |
885 | result = op1 - op0; | |
886 | ||
887 | /* Compute the condition codes. */ | |
888 | z = (result == 0); | |
889 | s = (result & 0x80000000); | |
d81352b8 | 890 | cy = (op1 < op0); |
dca41ba7 JL |
891 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
892 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
893 | sat = ov; | |
894 | ||
895 | /* Store the result and condition codes. */ | |
896 | State.regs[OP[1]] = result; | |
614f1c68 JL |
897 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
898 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
899 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
900 | | (sat ? PSW_SAT : 0)); | |
901 | ||
902 | /* Handle saturated results. */ | |
0e4ccc58 | 903 | if (sat && s) |
dca41ba7 JL |
904 | State.regs[OP[1]] = 0x80000000; |
905 | else if (sat) | |
906 | State.regs[OP[1]] = 0x7fffffff; | |
907 | } | |
908 | ||
909 | /* satsubi sign_extend(imm16), reg */ | |
910 | void | |
911 | OP_660 () | |
912 | { | |
913 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
914 | int temp; | |
915 | ||
916 | /* Compute the result. */ | |
917 | temp = (OP[0] & 0xffff); | |
918 | temp = (temp << 16) >> 16; | |
919 | op0 = temp; | |
920 | op1 = State.regs[OP[1]]; | |
921 | result = op1 - op0; | |
922 | ||
923 | /* Compute the condition codes. */ | |
924 | z = (result == 0); | |
925 | s = (result & 0x80000000); | |
d81352b8 | 926 | cy = (op1 < op0); |
dca41ba7 JL |
927 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
928 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
929 | sat = ov; | |
930 | ||
931 | /* Store the result and condition codes. */ | |
932 | State.regs[OP[1]] = result; | |
614f1c68 JL |
933 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
934 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
935 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
936 | | (sat ? PSW_SAT : 0)); | |
937 | ||
938 | /* Handle saturated results. */ | |
0e4ccc58 | 939 | if (sat && s) |
dca41ba7 JL |
940 | State.regs[OP[1]] = 0x80000000; |
941 | else if (sat) | |
942 | State.regs[OP[1]] = 0x7fffffff; | |
943 | } | |
944 | ||
945 | void | |
946 | OP_80 () | |
947 | { | |
948 | unsigned int op0, op1, result, z, s, cy, ov, sat; | |
949 | ||
950 | /* Compute the result. */ | |
951 | op0 = State.regs[OP[0]]; | |
952 | op1 = State.regs[OP[1]]; | |
953 | result = op0 - op1; | |
954 | ||
955 | /* Compute the condition codes. */ | |
956 | z = (result == 0); | |
957 | s = (result & 0x80000000); | |
d81352b8 | 958 | cy = (result < op0); |
dca41ba7 JL |
959 | ov = ((op1 & 0x80000000) != (op0 & 0x80000000) |
960 | && (op1 & 0x80000000) != (result & 0x80000000)); | |
961 | sat = ov; | |
962 | ||
963 | /* Store the result and condition codes. */ | |
964 | State.regs[OP[1]] = result; | |
614f1c68 JL |
965 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); |
966 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
dca41ba7 JL |
967 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) |
968 | | (sat ? PSW_SAT : 0)); | |
969 | ||
970 | /* Handle saturated results. */ | |
0e4ccc58 | 971 | if (sat && s) |
dca41ba7 JL |
972 | State.regs[OP[1]] = 0x80000000; |
973 | else if (sat) | |
974 | State.regs[OP[1]] = 0x7fffffff; | |
975 | } | |
976 | ||
3095b8df JL |
977 | /* tst reg,reg */ |
978 | void | |
979 | OP_160 () | |
980 | { | |
981 | unsigned int op0, op1, result, z, s, cy, ov; | |
982 | ||
983 | /* Compute the result. */ | |
984 | op0 = State.regs[OP[0]]; | |
985 | op1 = State.regs[OP[1]]; | |
986 | result = op0 & op1; | |
987 | ||
988 | /* Compute the condition codes. */ | |
989 | z = (result == 0); | |
990 | s = (result & 0x80000000); | |
991 | ||
992 | /* Store the condition codes. */ | |
614f1c68 JL |
993 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
994 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
3095b8df JL |
995 | } |
996 | ||
1fe983dc | 997 | /* mov reg, reg */ |
22c1c7dd JL |
998 | void |
999 | OP_0 () | |
1000 | { | |
1fe983dc | 1001 | State.regs[OP[1]] = State.regs[OP[0]]; |
22c1c7dd JL |
1002 | } |
1003 | ||
1fe983dc | 1004 | /* mov sign_extend(imm5), reg */ |
22c1c7dd | 1005 | void |
1fe983dc | 1006 | OP_200 () |
22c1c7dd | 1007 | { |
1fe983dc JL |
1008 | int value = OP[0]; |
1009 | ||
1010 | value = (value << 27) >> 27; | |
1011 | State.regs[OP[1]] = value; | |
22c1c7dd JL |
1012 | } |
1013 | ||
1fe983dc JL |
1014 | /* movea sign_extend(imm16), reg, reg */ |
1015 | ||
22c1c7dd | 1016 | void |
1fe983dc | 1017 | OP_620 () |
22c1c7dd | 1018 | { |
1fe983dc JL |
1019 | int value = OP[0]; |
1020 | ||
1021 | value = (value << 16) >> 16; | |
1022 | ||
1023 | State.regs[OP[2]] = State.regs[OP[1]] + value; | |
22c1c7dd JL |
1024 | } |
1025 | ||
1fe983dc | 1026 | /* movhi imm16, reg, reg */ |
22c1c7dd | 1027 | void |
1fe983dc | 1028 | OP_640 () |
22c1c7dd | 1029 | { |
1fe983dc JL |
1030 | int value = OP[0]; |
1031 | ||
1032 | value = (value & 0xffff) << 16; | |
1033 | ||
1034 | State.regs[OP[2]] = State.regs[OP[1]] + value; | |
22c1c7dd JL |
1035 | } |
1036 | ||
35404c7d | 1037 | /* sar zero_extend(imm5),reg1 */ |
22c1c7dd | 1038 | void |
77553374 | 1039 | OP_2A0 () |
22c1c7dd | 1040 | { |
35404c7d | 1041 | unsigned int op0, op1, result, z, s, cy, ov; |
77553374 | 1042 | |
35404c7d JL |
1043 | op0 = OP[0] & 0x1f; |
1044 | op1 = State.regs[OP[1]]; | |
1045 | result = (signed)op1 >> op0; | |
77553374 | 1046 | |
35404c7d JL |
1047 | /* Compute the condition codes. */ |
1048 | z = (result == 0); | |
1049 | s = (result & 0x80000000); | |
1050 | cy = (op1 & (1 << (op0 - 1))); | |
22c1c7dd | 1051 | |
35404c7d JL |
1052 | /* Store the result and condition codes. */ |
1053 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1054 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1055 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d JL |
1056 | | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); |
1057 | } | |
77553374 | 1058 | |
35404c7d | 1059 | /* sar reg1, reg2 */ |
22c1c7dd | 1060 | void |
77553374 | 1061 | OP_A007E0 () |
22c1c7dd | 1062 | { |
35404c7d | 1063 | unsigned int op0, op1, result, z, s, cy, ov; |
77553374 | 1064 | |
35404c7d JL |
1065 | op0 = State.regs[OP[0]] & 0x1f; |
1066 | op1 = State.regs[OP[1]]; | |
1067 | result = (signed)op1 >> op0; | |
77553374 | 1068 | |
35404c7d JL |
1069 | /* Compute the condition codes. */ |
1070 | z = (result == 0); | |
1071 | s = (result & 0x80000000); | |
1072 | cy = (op1 & (1 << (op0 - 1))); | |
22c1c7dd | 1073 | |
35404c7d JL |
1074 | /* Store the result and condition codes. */ |
1075 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1076 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1077 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d JL |
1078 | | (cy ? PSW_CY : 0)); |
1079 | } | |
77553374 | 1080 | |
35404c7d | 1081 | /* shl zero_extend(imm5),reg1 */ |
22c1c7dd JL |
1082 | void |
1083 | OP_2C0 () | |
77553374 | 1084 | { |
35404c7d JL |
1085 | unsigned int op0, op1, result, z, s, cy, ov; |
1086 | ||
1087 | op0 = OP[0] & 0x1f; | |
1088 | op1 = State.regs[OP[1]]; | |
1089 | result = op1 << op0; | |
1090 | ||
1091 | /* Compute the condition codes. */ | |
1092 | z = (result == 0); | |
1093 | s = (result & 0x80000000); | |
1094 | cy = (op1 & (1 << (32 - op0))); | |
77553374 | 1095 | |
35404c7d JL |
1096 | /* Store the result and condition codes. */ |
1097 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1098 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1099 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d JL |
1100 | | (cy ? PSW_CY : 0)); |
1101 | } | |
77553374 | 1102 | |
35404c7d | 1103 | /* shl reg1, reg2 */ |
77553374 JL |
1104 | void |
1105 | OP_C007E0 () | |
1106 | { | |
35404c7d | 1107 | unsigned int op0, op1, result, z, s, cy, ov; |
77553374 | 1108 | |
35404c7d JL |
1109 | op0 = State.regs[OP[0]] & 0x1f; |
1110 | op1 = State.regs[OP[1]]; | |
1111 | result = op1 << op0; | |
1112 | ||
1113 | /* Compute the condition codes. */ | |
1114 | z = (result == 0); | |
1115 | s = (result & 0x80000000); | |
1116 | cy = (op1 & (1 << (32 - op0))); | |
1117 | ||
1118 | /* Store the result and condition codes. */ | |
1119 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1120 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1121 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d JL |
1122 | | (cy ? PSW_CY : 0)); |
1123 | } | |
77553374 | 1124 | |
35404c7d | 1125 | /* shr zero_extend(imm5),reg1 */ |
77553374 JL |
1126 | void |
1127 | OP_280 () | |
1128 | { | |
35404c7d | 1129 | unsigned int op0, op1, result, z, s, cy, ov; |
77553374 | 1130 | |
35404c7d JL |
1131 | op0 = OP[0] & 0x1f; |
1132 | op1 = State.regs[OP[1]]; | |
1133 | result = op1 >> op0; | |
77553374 | 1134 | |
35404c7d JL |
1135 | /* Compute the condition codes. */ |
1136 | z = (result == 0); | |
1137 | s = (result & 0x80000000); | |
1138 | cy = (op1 & (1 << (op0 - 1))); | |
1139 | ||
1140 | /* Store the result and condition codes. */ | |
1141 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1142 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1143 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d JL |
1144 | | (cy ? PSW_CY : 0)); |
1145 | } | |
1146 | ||
1147 | /* shr reg1, reg2 */ | |
77553374 JL |
1148 | void |
1149 | OP_8007E0 () | |
1150 | { | |
35404c7d JL |
1151 | unsigned int op0, op1, result, z, s, cy, ov; |
1152 | ||
1153 | op0 = State.regs[OP[0]] & 0x1f; | |
1154 | op1 = State.regs[OP[1]]; | |
1155 | result = op1 >> op0; | |
1156 | ||
1157 | /* Compute the condition codes. */ | |
1158 | z = (result == 0); | |
1159 | s = (result & 0x80000000); | |
1160 | cy = (op1 & (1 << (op0 - 1))); | |
1161 | ||
1162 | /* Store the result and condition codes. */ | |
1163 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1164 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); |
1165 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | |
35404c7d | 1166 | | (cy ? PSW_CY : 0)); |
77553374 JL |
1167 | } |
1168 | ||
0ef0eba5 | 1169 | /* or reg, reg */ |
1fe983dc JL |
1170 | void |
1171 | OP_100 () | |
1172 | { | |
0ef0eba5 | 1173 | unsigned int op0, op1, result, z, s, cy, ov; |
1fe983dc | 1174 | |
0ef0eba5 JL |
1175 | /* Compute the result. */ |
1176 | op0 = State.regs[OP[0]]; | |
1177 | op1 = State.regs[OP[1]]; | |
1178 | result = op0 | op1; | |
1fe983dc | 1179 | |
0ef0eba5 JL |
1180 | /* Compute the condition codes. */ |
1181 | z = (result == 0); | |
1182 | s = (result & 0x80000000); | |
1183 | ||
1184 | /* Store the result and condition codes. */ | |
1185 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1186 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
1187 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
0ef0eba5 JL |
1188 | } |
1189 | ||
1190 | /* ori zero_extend(imm16), reg, reg */ | |
1fe983dc JL |
1191 | void |
1192 | OP_680 () | |
1193 | { | |
0ef0eba5 | 1194 | unsigned int op0, op1, result, z, s, cy, ov; |
1fe983dc | 1195 | |
0ef0eba5 JL |
1196 | op0 = OP[0] & 0xffff; |
1197 | op1 = State.regs[OP[1]]; | |
1198 | result = op0 | op1; | |
1fe983dc | 1199 | |
0ef0eba5 JL |
1200 | /* Compute the condition codes. */ |
1201 | z = (result == 0); | |
1202 | s = (result & 0x80000000); | |
1fe983dc | 1203 | |
0ef0eba5 JL |
1204 | /* Store the result and condition codes. */ |
1205 | State.regs[OP[2]] = result; | |
614f1c68 JL |
1206 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
1207 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
0ef0eba5 JL |
1208 | } |
1209 | ||
1210 | /* and reg, reg */ | |
22c1c7dd JL |
1211 | void |
1212 | OP_140 () | |
1213 | { | |
0ef0eba5 | 1214 | unsigned int op0, op1, result, z, s, cy, ov; |
22c1c7dd | 1215 | |
0ef0eba5 JL |
1216 | /* Compute the result. */ |
1217 | op0 = State.regs[OP[0]]; | |
1218 | op1 = State.regs[OP[1]]; | |
1219 | result = op0 & op1; | |
1fe983dc | 1220 | |
0ef0eba5 JL |
1221 | /* Compute the condition codes. */ |
1222 | z = (result == 0); | |
1223 | s = (result & 0x80000000); | |
1224 | ||
1225 | /* Store the result and condition codes. */ | |
1226 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1227 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
1228 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
0ef0eba5 JL |
1229 | } |
1230 | ||
1231 | /* andi zero_extend(imm16), reg, reg */ | |
22c1c7dd | 1232 | void |
1fe983dc JL |
1233 | OP_6C0 () |
1234 | { | |
0ef0eba5 | 1235 | unsigned int op0, op1, result, z, s, cy, ov; |
1fe983dc | 1236 | |
0ef0eba5 JL |
1237 | op0 = OP[0] & 0xffff; |
1238 | op1 = State.regs[OP[1]]; | |
1239 | result = op0 & op1; | |
1fe983dc | 1240 | |
0ef0eba5 JL |
1241 | /* Compute the condition codes. */ |
1242 | z = (result == 0); | |
1fe983dc | 1243 | |
0ef0eba5 JL |
1244 | /* Store the result and condition codes. */ |
1245 | State.regs[OP[2]] = result; | |
614f1c68 JL |
1246 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
1247 | State.sregs[5] |= (z ? PSW_Z : 0); | |
0ef0eba5 JL |
1248 | } |
1249 | ||
1250 | /* xor reg, reg */ | |
1fe983dc JL |
1251 | void |
1252 | OP_120 () | |
22c1c7dd | 1253 | { |
0ef0eba5 | 1254 | unsigned int op0, op1, result, z, s, cy, ov; |
1fe983dc | 1255 | |
0ef0eba5 JL |
1256 | /* Compute the result. */ |
1257 | op0 = State.regs[OP[0]]; | |
1258 | op1 = State.regs[OP[1]]; | |
1259 | result = op0 ^ op1; | |
1fe983dc | 1260 | |
0ef0eba5 JL |
1261 | /* Compute the condition codes. */ |
1262 | z = (result == 0); | |
1263 | s = (result & 0x80000000); | |
1264 | ||
1265 | /* Store the result and condition codes. */ | |
1266 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1267 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
1268 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
0ef0eba5 JL |
1269 | } |
1270 | ||
1271 | /* xori zero_extend(imm16), reg, reg */ | |
1fe983dc JL |
1272 | void |
1273 | OP_6A0 () | |
1274 | { | |
0ef0eba5 JL |
1275 | unsigned int op0, op1, result, z, s, cy, ov; |
1276 | ||
1277 | op0 = OP[0] & 0xffff; | |
1278 | op1 = State.regs[OP[1]]; | |
1279 | result = op0 ^ op1; | |
1280 | ||
1281 | /* Compute the condition codes. */ | |
1282 | z = (result == 0); | |
1283 | s = (result & 0x80000000); | |
1284 | ||
1285 | /* Store the result and condition codes. */ | |
1286 | State.regs[OP[2]] = result; | |
614f1c68 JL |
1287 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
1288 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
0ef0eba5 JL |
1289 | } |
1290 | ||
1291 | /* not reg1, reg2 */ | |
1292 | void | |
1293 | OP_20 () | |
1294 | { | |
1295 | unsigned int op0, result, z, s, cy, ov; | |
1296 | ||
1297 | /* Compute the result. */ | |
1298 | op0 = State.regs[OP[0]]; | |
1299 | result = ~op0; | |
1300 | ||
1301 | /* Compute the condition codes. */ | |
1302 | z = (result == 0); | |
1303 | s = (result & 0x80000000); | |
1fe983dc | 1304 | |
0ef0eba5 JL |
1305 | /* Store the result and condition codes. */ |
1306 | State.regs[OP[1]] = result; | |
614f1c68 JL |
1307 | State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_OV); |
1308 | State.sregs[5] |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); | |
22c1c7dd JL |
1309 | } |
1310 | ||
28647e4c | 1311 | /* set1 */ |
1fe983dc | 1312 | void |
28647e4c | 1313 | OP_7C0 () |
1fe983dc | 1314 | { |
83fc3bac JL |
1315 | unsigned int op0, op1, op2; |
1316 | int result, temp; | |
1317 | ||
1318 | op0 = State.regs[OP[0]]; | |
1319 | op1 = OP[1] & 0x7; | |
1320 | temp = OP[2]; | |
1321 | temp = (temp << 16) >> 16; | |
1322 | op2 = temp; | |
1323 | temp = get_byte (State.mem + op0 + op2); | |
1324 | State.sregs[5] &= ~PSW_Z; | |
1325 | if ((temp & (1 << op1)) == 0) | |
1326 | State.sregs[5] |= PSW_Z; | |
787d66bb | 1327 | temp |= (1 << op1); |
83fc3bac | 1328 | put_byte (State.mem + op0 + op2, temp); |
1fe983dc JL |
1329 | } |
1330 | ||
28647e4c | 1331 | /* not1 */ |
1fe983dc | 1332 | void |
28647e4c | 1333 | OP_47C0 () |
1fe983dc | 1334 | { |
83fc3bac JL |
1335 | unsigned int op0, op1, op2; |
1336 | int result, temp; | |
1337 | ||
1338 | op0 = State.regs[OP[0]]; | |
1339 | op1 = OP[1] & 0x7; | |
1340 | temp = OP[2]; | |
1341 | temp = (temp << 16) >> 16; | |
1342 | op2 = temp; | |
1343 | temp = get_byte (State.mem + op0 + op2); | |
1344 | State.sregs[5] &= ~PSW_Z; | |
1345 | if ((temp & (1 << op1)) == 0) | |
1346 | State.sregs[5] |= PSW_Z; | |
787d66bb | 1347 | temp ^= (1 << op1); |
83fc3bac | 1348 | put_byte (State.mem + op0 + op2, temp); |
1fe983dc JL |
1349 | } |
1350 | ||
28647e4c | 1351 | /* clr1 */ |
1fe983dc | 1352 | void |
28647e4c JL |
1353 | OP_87C0 () |
1354 | { | |
83fc3bac JL |
1355 | unsigned int op0, op1, op2; |
1356 | int result, temp; | |
1357 | ||
1358 | op0 = State.regs[OP[0]]; | |
1359 | op1 = OP[1] & 0x7; | |
1360 | temp = OP[2]; | |
1361 | temp = (temp << 16) >> 16; | |
1362 | op2 = temp; | |
1363 | temp = get_byte (State.mem + op0 + op2); | |
1364 | State.sregs[5] &= ~PSW_Z; | |
1365 | if ((temp & (1 << op1)) == 0) | |
1366 | State.sregs[5] |= PSW_Z; | |
1367 | temp &= ~(1 << op1); | |
1368 | put_byte (State.mem + op0 + op2, temp); | |
28647e4c JL |
1369 | } |
1370 | ||
1371 | /* tst1 */ | |
1372 | void | |
1373 | OP_C7C0 () | |
1fe983dc | 1374 | { |
83fc3bac JL |
1375 | unsigned int op0, op1, op2; |
1376 | int result, temp; | |
1377 | ||
1378 | op0 = State.regs[OP[0]]; | |
1379 | op1 = OP[1] & 0x7; | |
1380 | temp = OP[2]; | |
1381 | temp = (temp << 16) >> 16; | |
1382 | op2 = temp; | |
1383 | temp = get_byte (State.mem + op0 + op2); | |
1384 | State.sregs[5] &= ~PSW_Z; | |
1385 | if ((temp & (1 << op1)) == 0) | |
1386 | State.sregs[5] |= PSW_Z; | |
1fe983dc | 1387 | } |
e98e3b2c | 1388 | |
3095b8df | 1389 | /* di */ |
e98e3b2c JL |
1390 | void |
1391 | OP_16007E0 () | |
1392 | { | |
614f1c68 | 1393 | State.sregs[5] |= PSW_ID; |
e98e3b2c JL |
1394 | } |
1395 | ||
3095b8df | 1396 | /* ei */ |
e98e3b2c JL |
1397 | void |
1398 | OP_16087E0 () | |
1399 | { | |
614f1c68 | 1400 | State.sregs[5] &= ~PSW_ID; |
e98e3b2c JL |
1401 | } |
1402 | ||
1403 | /* halt, not supported */ | |
1404 | void | |
1405 | OP_12007E0 () | |
1406 | { | |
d81352b8 | 1407 | State.exception = SIGQUIT; |
e98e3b2c JL |
1408 | } |
1409 | ||
1410 | /* reti, not supported */ | |
1411 | void | |
1412 | OP_14007E0 () | |
1413 | { | |
1414 | abort (); | |
1415 | } | |
1416 | ||
1417 | /* trap, not supportd */ | |
1418 | void | |
1419 | OP_10007E0 () | |
1420 | { | |
d81352b8 JL |
1421 | extern int errno; |
1422 | ||
1423 | /* Trap 0 is used for simulating low-level I/O */ | |
1424 | ||
1425 | if (OP[0] == 0) | |
1426 | { | |
1427 | #if 0 | |
1428 | char *fstr = State.regs[2] + State.imem; | |
1429 | printf (fstr,State.regs[3],State.regs[4],State.regs[5]); | |
1430 | #else | |
1431 | int save_errno = errno; | |
1432 | errno = 0; | |
1433 | ||
1434 | /* Registers passed to trap 0 */ | |
1435 | ||
1436 | #define FUNC State.regs[6] /* function number, return value */ | |
1437 | #define PARM1 State.regs[7] /* optional parm 1 */ | |
1438 | #define PARM2 State.regs[8] /* optional parm 2 */ | |
1439 | #define PARM3 State.regs[9] /* optional parm 3 */ | |
1440 | ||
1441 | /* Registers set by trap 0 */ | |
1442 | ||
1443 | #define RETVAL State.regs[10] /* return value */ | |
1444 | #define RETERR State.regs[11] /* return error code */ | |
1445 | ||
1446 | /* Turn a pointer in a register into a pointer into real memory. */ | |
1447 | ||
1448 | #define MEMPTR(x) ((char *)((x) + State.mem)) | |
1449 | ||
1450 | ||
1451 | switch (FUNC) | |
1452 | { | |
1453 | #if 0 | |
1454 | #if !defined(__GO32__) && !defined(_WIN32) | |
1455 | case SYS_fork: | |
1456 | RETVAL = fork (); | |
1457 | break; | |
1458 | case SYS_execve: | |
1459 | RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), | |
1460 | (char **)MEMPTR (PARM3)); | |
1461 | break; | |
1462 | case SYS_execv: | |
1463 | RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL); | |
1464 | break; | |
1465 | case SYS_pipe: | |
1466 | { | |
1467 | reg_t buf; | |
1468 | int host_fd[2]; | |
1469 | ||
1470 | buf = PARM1; | |
1471 | RETVAL = pipe (host_fd); | |
1472 | SW (buf, host_fd[0]); | |
1473 | buf += sizeof(uint16); | |
1474 | SW (buf, host_fd[1]); | |
1475 | } | |
1476 | break; | |
1477 | ||
1478 | case SYS_wait: | |
1479 | { | |
1480 | int status; | |
1481 | ||
1482 | RETVAL = wait (&status); | |
1483 | SW (PARM1, status); | |
1484 | } | |
1485 | break; | |
1486 | #endif | |
1487 | ||
1488 | case SYS_read: | |
1489 | RETVAL = v850_callback->read (v850_callback, PARM1, MEMPTR (PARM2), | |
1490 | PARM3); | |
1491 | break; | |
1492 | #endif | |
1493 | case SYS_write: | |
1494 | if (PARM1 == 1) | |
1495 | RETVAL = (int)v850_callback->write_stdout (v850_callback, | |
1496 | MEMPTR (PARM2), PARM3); | |
1497 | else | |
1498 | RETVAL = (int)v850_callback->write (v850_callback, PARM1, | |
1499 | MEMPTR (PARM2), PARM3); | |
1500 | break; | |
1501 | #if 0 | |
1502 | case SYS_lseek: | |
1503 | RETVAL = v850_callback->lseek (v850_callback, PARM1, PARM2, PARM3); | |
1504 | break; | |
1505 | case SYS_close: | |
1506 | RETVAL = v850_callback->close (v850_callback, PARM1); | |
1507 | break; | |
1508 | case SYS_open: | |
1509 | RETVAL = v850_callback->open (v850_callback, MEMPTR (PARM1), PARM2); | |
1510 | break; | |
1511 | #endif | |
1512 | case SYS_exit: | |
1513 | /* EXIT - caller can look in PARM1 to work out the | |
1514 | reason */ | |
1515 | if (PARM1 == 0xdead || PARM1 == 0x1) | |
1516 | State.exception = SIGABRT; | |
1517 | else | |
1518 | State.exception = SIGQUIT; | |
1519 | break; | |
1520 | ||
1521 | #if 0 | |
1522 | case SYS_stat: /* added at hmsi */ | |
1523 | /* stat system call */ | |
1524 | { | |
1525 | struct stat host_stat; | |
1526 | reg_t buf; | |
1527 | ||
1528 | RETVAL = stat (MEMPTR (PARM1), &host_stat); | |
1529 | ||
1530 | buf = PARM2; | |
1531 | ||
1532 | /* The hard-coded offsets and sizes were determined by using | |
1533 | * the D10V compiler on a test program that used struct stat. | |
1534 | */ | |
1535 | SW (buf, host_stat.st_dev); | |
1536 | SW (buf+2, host_stat.st_ino); | |
1537 | SW (buf+4, host_stat.st_mode); | |
1538 | SW (buf+6, host_stat.st_nlink); | |
1539 | SW (buf+8, host_stat.st_uid); | |
1540 | SW (buf+10, host_stat.st_gid); | |
1541 | SW (buf+12, host_stat.st_rdev); | |
1542 | SLW (buf+16, host_stat.st_size); | |
1543 | SLW (buf+20, host_stat.st_atime); | |
1544 | SLW (buf+28, host_stat.st_mtime); | |
1545 | SLW (buf+36, host_stat.st_ctime); | |
1546 | } | |
1547 | break; | |
1548 | ||
1549 | case SYS_chown: | |
1550 | RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3); | |
1551 | break; | |
1552 | case SYS_chmod: | |
1553 | RETVAL = chmod (MEMPTR (PARM1), PARM2); | |
1554 | break; | |
1555 | case SYS_utime: | |
1556 | /* Cast the second argument to void *, to avoid type mismatch | |
1557 | if a prototype is present. */ | |
1558 | RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2)); | |
1559 | break; | |
1560 | #endif | |
1561 | default: | |
1562 | abort (); | |
1563 | } | |
1564 | RETERR = errno; | |
1565 | errno = save_errno; | |
1566 | #endif | |
1567 | } | |
1568 | else if (OP[0] == 1 ) | |
1569 | { | |
1570 | char *fstr = State.regs[2] + State.mem; | |
1571 | puts (fstr); | |
1572 | } | |
e98e3b2c JL |
1573 | } |
1574 | ||
614f1c68 | 1575 | /* ldsr, reg,reg */ |
e98e3b2c JL |
1576 | void |
1577 | OP_2007E0 () | |
1578 | { | |
614f1c68 JL |
1579 | unsigned int op0; |
1580 | ||
1581 | op0 = State.regs[OP[0]]; | |
1582 | State.sregs[OP[1]] = op0; | |
e98e3b2c JL |
1583 | } |
1584 | ||
1585 | /* stsr, not supported */ | |
1586 | void | |
1587 | OP_4007E0 () | |
1588 | { | |
614f1c68 JL |
1589 | unsigned int op0; |
1590 | ||
1591 | op0 = State.sregs[OP[1]]; | |
1592 | State.regs[OP[0]] = op0; | |
e98e3b2c JL |
1593 | } |
1594 |