Revision c8c2227e target-mips/op_helper.c
b/target-mips/op_helper.c | ||
---|---|---|
308 | 308 |
} |
309 | 309 |
#endif |
310 | 310 |
|
311 |
#ifdef TARGET_WORDS_BIGENDIAN |
|
312 |
#define GET_LMASK(v) ((v) & 3) |
|
313 |
#define GET_OFFSET(addr, offset) (addr + (offset)) |
|
314 |
#else |
|
315 |
#define GET_LMASK(v) (((v) & 3) ^ 3) |
|
316 |
#define GET_OFFSET(addr, offset) (addr - (offset)) |
|
317 |
#endif |
|
318 |
|
|
319 |
void do_lwl(int mem_idx) |
|
320 |
{ |
|
321 |
target_ulong tmp; |
|
322 |
|
|
323 |
#ifdef CONFIG_USER_ONLY |
|
324 |
#define ldfun ldub_raw |
|
325 |
#else |
|
326 |
int (*ldfun)(target_ulong); |
|
327 |
|
|
328 |
switch (mem_idx) |
|
329 |
{ |
|
330 |
case 0: ldfun = ldub_kernel; break; |
|
331 |
case 1: ldfun = ldub_super; break; |
|
332 |
default: |
|
333 |
case 2: ldfun = ldub_user; break; |
|
334 |
} |
|
335 |
#endif |
|
336 |
tmp = ldfun(T0); |
|
337 |
T1 = (T1 & 0x00FFFFFF) | (tmp << 24); |
|
338 |
|
|
339 |
if (GET_LMASK(T0) <= 2) { |
|
340 |
tmp = ldfun(GET_OFFSET(T0, 1)); |
|
341 |
T1 = (T1 & 0xFF00FFFF) | (tmp << 16); |
|
342 |
} |
|
343 |
|
|
344 |
if (GET_LMASK(T0) <= 1) { |
|
345 |
tmp = ldfun(GET_OFFSET(T0, 2)); |
|
346 |
T1 = (T1 & 0xFFFF00FF) | (tmp << 8); |
|
347 |
} |
|
348 |
|
|
349 |
if (GET_LMASK(T0) == 0) { |
|
350 |
tmp = ldfun(GET_OFFSET(T0, 3)); |
|
351 |
T1 = (T1 & 0xFFFFFF00) | tmp; |
|
352 |
} |
|
353 |
T1 = (int32_t)T1; |
|
354 |
} |
|
355 |
|
|
356 |
void do_lwr(int mem_idx) |
|
357 |
{ |
|
358 |
target_ulong tmp; |
|
359 |
|
|
360 |
#ifdef CONFIG_USER_ONLY |
|
361 |
#define ldfun ldub_raw |
|
362 |
#else |
|
363 |
int (*ldfun)(target_ulong); |
|
364 |
|
|
365 |
switch (mem_idx) |
|
366 |
{ |
|
367 |
case 0: ldfun = ldub_kernel; break; |
|
368 |
case 1: ldfun = ldub_super; break; |
|
369 |
default: |
|
370 |
case 2: ldfun = ldub_user; break; |
|
371 |
} |
|
372 |
#endif |
|
373 |
tmp = ldfun(T0); |
|
374 |
T1 = (T1 & 0xFFFFFF00) | tmp; |
|
375 |
|
|
376 |
if (GET_LMASK(T0) >= 1) { |
|
377 |
tmp = ldfun(GET_OFFSET(T0, -1)); |
|
378 |
T1 = (T1 & 0xFFFF00FF) | (tmp << 8); |
|
379 |
} |
|
380 |
|
|
381 |
if (GET_LMASK(T0) >= 2) { |
|
382 |
tmp = ldfun(GET_OFFSET(T0, -2)); |
|
383 |
T1 = (T1 & 0xFF00FFFF) | (tmp << 16); |
|
384 |
} |
|
385 |
|
|
386 |
if (GET_LMASK(T0) == 3) { |
|
387 |
tmp = ldfun(GET_OFFSET(T0, -3)); |
|
388 |
T1 = (T1 & 0x00FFFFFF) | (tmp << 24); |
|
389 |
} |
|
390 |
T1 = (int32_t)T1; |
|
391 |
} |
|
392 |
|
|
393 |
void do_swl(int mem_idx) |
|
394 |
{ |
|
395 |
#ifdef CONFIG_USER_ONLY |
|
396 |
#define stfun stb_raw |
|
397 |
#else |
|
398 |
void (*stfun)(target_ulong, int); |
|
399 |
|
|
400 |
switch (mem_idx) |
|
401 |
{ |
|
402 |
case 0: stfun = stb_kernel; break; |
|
403 |
case 1: stfun = stb_super; break; |
|
404 |
default: |
|
405 |
case 2: stfun = stb_user; break; |
|
406 |
} |
|
407 |
#endif |
|
408 |
stfun(T0, (uint8_t)(T1 >> 24)); |
|
409 |
|
|
410 |
if (GET_LMASK(T0) <= 2) |
|
411 |
stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16)); |
|
412 |
|
|
413 |
if (GET_LMASK(T0) <= 1) |
|
414 |
stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8)); |
|
415 |
|
|
416 |
if (GET_LMASK(T0) == 0) |
|
417 |
stfun(GET_OFFSET(T0, 3), (uint8_t)T1); |
|
418 |
} |
|
419 |
|
|
420 |
void do_swr(int mem_idx) |
|
421 |
{ |
|
422 |
#ifdef CONFIG_USER_ONLY |
|
423 |
#define stfun stb_raw |
|
424 |
#else |
|
425 |
void (*stfun)(target_ulong, int); |
|
426 |
|
|
427 |
switch (mem_idx) |
|
428 |
{ |
|
429 |
case 0: stfun = stb_kernel; break; |
|
430 |
case 1: stfun = stb_super; break; |
|
431 |
default: |
|
432 |
case 2: stfun = stb_user; break; |
|
433 |
} |
|
434 |
#endif |
|
435 |
stfun(T0, (uint8_t)T1); |
|
436 |
|
|
437 |
if (GET_LMASK(T0) >= 1) |
|
438 |
stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); |
|
439 |
|
|
440 |
if (GET_LMASK(T0) >= 2) |
|
441 |
stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); |
|
442 |
|
|
443 |
if (GET_LMASK(T0) == 3) |
|
444 |
stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); |
|
445 |
} |
|
446 |
|
|
447 |
#if defined(TARGET_MIPS64) |
|
448 |
/* "half" load and stores. We must do the memory access inline, |
|
449 |
or fault handling won't work. */ |
|
450 |
|
|
451 |
#ifdef TARGET_WORDS_BIGENDIAN |
|
452 |
#define GET_LMASK64(v) ((v) & 7) |
|
453 |
#else |
|
454 |
#define GET_LMASK64(v) (((v) & 7) ^ 7) |
|
455 |
#endif |
|
456 |
|
|
457 |
void do_ldl(int mem_idx) |
|
458 |
{ |
|
459 |
uint64_t tmp; |
|
460 |
|
|
461 |
#ifdef CONFIG_USER_ONLY |
|
462 |
#define ldfun ldub_raw |
|
463 |
#else |
|
464 |
target_ulong (*ldfun)(target_ulong); |
|
465 |
|
|
466 |
switch (mem_idx) |
|
467 |
{ |
|
468 |
case 0: ldfun = ldub_kernel; break; |
|
469 |
case 1: ldfun = ldub_super; break; |
|
470 |
default: |
|
471 |
case 2: ldfun = ldub_user; break; |
|
472 |
} |
|
473 |
#endif |
|
474 |
tmp = ldfun(T0); |
|
475 |
T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); |
|
476 |
|
|
477 |
if (GET_LMASK64(T0) <= 6) { |
|
478 |
tmp = ldfun(GET_OFFSET(T0, 1)); |
|
479 |
T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); |
|
480 |
} |
|
481 |
|
|
482 |
if (GET_LMASK64(T0) <= 5) { |
|
483 |
tmp = ldfun(GET_OFFSET(T0, 2)); |
|
484 |
T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); |
|
485 |
} |
|
486 |
|
|
487 |
if (GET_LMASK64(T0) <= 4) { |
|
488 |
tmp = ldfun(GET_OFFSET(T0, 3)); |
|
489 |
T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); |
|
490 |
} |
|
491 |
|
|
492 |
if (GET_LMASK64(T0) <= 3) { |
|
493 |
tmp = ldfun(GET_OFFSET(T0, 4)); |
|
494 |
T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); |
|
495 |
} |
|
496 |
|
|
497 |
if (GET_LMASK64(T0) <= 2) { |
|
498 |
tmp = ldfun(GET_OFFSET(T0, 5)); |
|
499 |
T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); |
|
500 |
} |
|
501 |
|
|
502 |
if (GET_LMASK64(T0) <= 1) { |
|
503 |
tmp = ldfun(GET_OFFSET(T0, 6)); |
|
504 |
T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); |
|
505 |
} |
|
506 |
|
|
507 |
if (GET_LMASK64(T0) == 0) { |
|
508 |
tmp = ldfun(GET_OFFSET(T0, 7)); |
|
509 |
T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; |
|
510 |
} |
|
511 |
} |
|
512 |
|
|
513 |
void do_ldr(int mem_idx) |
|
514 |
{ |
|
515 |
uint64_t tmp; |
|
516 |
|
|
517 |
#ifdef CONFIG_USER_ONLY |
|
518 |
#define ldfun ldub_raw |
|
519 |
#else |
|
520 |
target_ulong (*ldfun)(target_ulong); |
|
521 |
|
|
522 |
switch (mem_idx) |
|
523 |
{ |
|
524 |
case 0: ldfun = ldub_kernel; break; |
|
525 |
case 1: ldfun = ldub_super; break; |
|
526 |
default: |
|
527 |
case 2: ldfun = ldub_user; break; |
|
528 |
} |
|
529 |
#endif |
|
530 |
tmp = ldfun(T0); |
|
531 |
T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; |
|
532 |
|
|
533 |
if (GET_LMASK64(T0) >= 1) { |
|
534 |
tmp = ldfun(GET_OFFSET(T0, -1)); |
|
535 |
T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); |
|
536 |
} |
|
537 |
|
|
538 |
if (GET_LMASK64(T0) >= 2) { |
|
539 |
tmp = ldfun(GET_OFFSET(T0, -2)); |
|
540 |
T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); |
|
541 |
} |
|
542 |
|
|
543 |
if (GET_LMASK64(T0) >= 3) { |
|
544 |
tmp = ldfun(GET_OFFSET(T0, -3)); |
|
545 |
T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); |
|
546 |
} |
|
547 |
|
|
548 |
if (GET_LMASK64(T0) >= 4) { |
|
549 |
tmp = ldfun(GET_OFFSET(T0, -4)); |
|
550 |
T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); |
|
551 |
} |
|
552 |
|
|
553 |
if (GET_LMASK64(T0) >= 5) { |
|
554 |
tmp = ldfun(GET_OFFSET(T0, -5)); |
|
555 |
T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); |
|
556 |
} |
|
557 |
|
|
558 |
if (GET_LMASK64(T0) >= 6) { |
|
559 |
tmp = ldfun(GET_OFFSET(T0, -6)); |
|
560 |
T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); |
|
561 |
} |
|
562 |
|
|
563 |
if (GET_LMASK64(T0) == 7) { |
|
564 |
tmp = ldfun(GET_OFFSET(T0, -7)); |
|
565 |
T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); |
|
566 |
} |
|
567 |
} |
|
568 |
|
|
569 |
void do_sdl(int mem_idx) |
|
570 |
{ |
|
571 |
#ifdef CONFIG_USER_ONLY |
|
572 |
#define stfun stb_raw |
|
573 |
#else |
|
574 |
void (*stfun)(target_ulong, int); |
|
575 |
|
|
576 |
switch (mem_idx) |
|
577 |
{ |
|
578 |
case 0: stfun = stb_kernel; break; |
|
579 |
case 1: stfun = stb_super; break; |
|
580 |
default: |
|
581 |
case 2: stfun = stb_user; break; |
|
582 |
} |
|
583 |
#endif |
|
584 |
stfun(T0, (uint8_t)(T1 >> 56)); |
|
585 |
|
|
586 |
if (GET_LMASK64(T0) <= 6) |
|
587 |
stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48)); |
|
588 |
|
|
589 |
if (GET_LMASK64(T0) <= 5) |
|
590 |
stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40)); |
|
591 |
|
|
592 |
if (GET_LMASK64(T0) <= 4) |
|
593 |
stfun(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32)); |
|
594 |
|
|
595 |
if (GET_LMASK64(T0) <= 3) |
|
596 |
stfun(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24)); |
|
597 |
|
|
598 |
if (GET_LMASK64(T0) <= 2) |
|
599 |
stfun(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16)); |
|
600 |
|
|
601 |
if (GET_LMASK64(T0) <= 1) |
|
602 |
stfun(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8)); |
|
603 |
|
|
604 |
if (GET_LMASK64(T0) <= 0) |
|
605 |
stfun(GET_OFFSET(T0, 7), (uint8_t)T1); |
|
606 |
} |
|
607 |
|
|
608 |
void do_sdr(int mem_idx) |
|
609 |
{ |
|
610 |
#ifdef CONFIG_USER_ONLY |
|
611 |
#define stfun stb_raw |
|
612 |
#else |
|
613 |
void (*stfun)(target_ulong, int); |
|
614 |
|
|
615 |
switch (mem_idx) |
|
616 |
{ |
|
617 |
case 0: stfun = stb_kernel; break; |
|
618 |
case 1: stfun = stb_super; break; |
|
619 |
default: |
|
620 |
case 2: stfun = stb_user; break; |
|
621 |
} |
|
622 |
#endif |
|
623 |
stfun(T0, (uint8_t)T1); |
|
624 |
|
|
625 |
if (GET_LMASK64(T0) >= 1) |
|
626 |
stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); |
|
627 |
|
|
628 |
if (GET_LMASK64(T0) >= 2) |
|
629 |
stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); |
|
630 |
|
|
631 |
if (GET_LMASK64(T0) >= 3) |
|
632 |
stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); |
|
633 |
|
|
634 |
if (GET_LMASK64(T0) >= 4) |
|
635 |
stfun(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32)); |
|
636 |
|
|
637 |
if (GET_LMASK64(T0) >= 5) |
|
638 |
stfun(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40)); |
|
639 |
|
|
640 |
if (GET_LMASK64(T0) >= 6) |
|
641 |
stfun(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48)); |
|
642 |
|
|
643 |
if (GET_LMASK64(T0) == 7) |
|
644 |
stfun(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56)); |
|
645 |
} |
|
646 |
#endif /* TARGET_MIPS64 */ |
|
647 |
|
|
311 | 648 |
#ifdef CONFIG_USER_ONLY |
312 | 649 |
void do_mfc0_random (void) |
313 | 650 |
{ |
Also available in: Unified diff