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