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