~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to VEX/priv/guest-ppc/toIR.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrés Roldán
  • Date: 2008-06-13 02:31:40 UTC
  • mto: (1.4.1 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20080613023140-iwk33rz9rhvfkr96
Import upstream version 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
   This file is part of LibVEX, a library for dynamic binary
11
11
   instrumentation and translation.
12
12
 
13
 
   Copyright (C) 2004-2006 OpenWorks LLP.  All rights reserved.
 
13
   Copyright (C) 2004-2007 OpenWorks LLP.  All rights reserved.
14
14
 
15
15
   This library is made available under a dual licensing scheme.
16
16
 
75
75
       Non-Java mode would give us more inaccuracy, as our intermediate
76
76
       results would then be zeroed, too.
77
77
 
78
 
   - 64-bit mode: AbiHints for the stack red zone are only emitted for
 
78
   - AbiHints for the stack red zone are only emitted for
79
79
       unconditional calls and returns (bl, blr).  They should also be
80
80
       emitted for conditional calls and returns, but we don't have a 
81
81
       way to express that right now.  Ah well.
102
102
      7C210B78 (or 1,1,1)   %R3 = client_request ( %R4 )
103
103
      7C421378 (or 2,2,2)   %R3 = guest_NRADDR
104
104
      7C631B78 (or 3,3,3)   branch-and-link-to-noredir %R11
105
 
      7C842378 (or 4,4,4)   %R3 = guest_NRADDR_GPR2 (64-bit mode only)
 
105
      7C842378 (or 4,4,4)   %R3 = guest_NRADDR_GPR2
106
106
 
107
107
   Any other bytes following the 16-byte preamble are illegal and
108
108
   constitute a failure in instruction decoding.  This all assumes
168
168
   translated. */
169
169
static Addr64 guest_CIA_curr_instr;
170
170
 
171
 
/* The IRBB* into which we're generating code. */
172
 
static IRBB* irbb;
 
171
/* The IRSB* into which we're generating code. */
 
172
static IRSB* irsb;
173
173
 
174
174
/* Is our guest binary 32 or 64bit?  Set at each call to
175
175
   disInstr_PPC below. */
178
178
// Given a pointer to a function as obtained by "& functionname" in C,
179
179
// produce a pointer to the actual entry point for the function.  For
180
180
// most platforms it's the identity function.  Unfortunately, on
181
 
// ppc64-linux it isn't (sigh).
182
 
static void* fnptr_to_fnentry( void* f )
 
181
// ppc64-linux it isn't (sigh) and ditto for ppc32-aix5 and
 
182
// ppc64-aix5.
 
183
static void* fnptr_to_fnentry( VexAbiInfo* vbi, void* f )
183
184
{
184
 
#if defined(__powerpc64__)
185
 
   /* f is a pointer to a 3-word function descriptor, of which
186
 
      the first word is the entry address. */
187
 
   ULong* fdescr = (ULong*)f;
188
 
   return (void*)(fdescr[0]);
189
 
#else
190
 
   return f;
191
 
#endif
 
185
   if (vbi->host_ppc_calls_use_fndescrs) {
 
186
      /* f is a pointer to a 3-word function descriptor, of which the
 
187
         first word is the entry address. */
 
188
      /* note, this is correct even with cross-jitting, since this is
 
189
         purely a host issue, not a guest one. */
 
190
      HWord* fdescr = (HWord*)f;
 
191
      return (void*)(fdescr[0]);
 
192
   } else {
 
193
      /* Simple; "& f" points directly at the code for f. */
 
194
      return f;
 
195
   }
192
196
}
193
197
 
194
198
 
213
217
   (mode64 ? offsetof(VexGuestPPC64State, _x) : \
214
218
             offsetof(VexGuestPPC32State, _x))
215
219
 
216
 
#define OFFB_CIA        offsetofPPCGuestState(guest_CIA)
217
 
#define OFFB_LR         offsetofPPCGuestState(guest_LR)
218
 
#define OFFB_CTR        offsetofPPCGuestState(guest_CTR)
219
 
#define OFFB_XER_SO     offsetofPPCGuestState(guest_XER_SO)
220
 
#define OFFB_XER_OV     offsetofPPCGuestState(guest_XER_OV)
221
 
#define OFFB_XER_CA     offsetofPPCGuestState(guest_XER_CA)
222
 
#define OFFB_XER_BC     offsetofPPCGuestState(guest_XER_BC)
223
 
#define OFFB_FPROUND    offsetofPPCGuestState(guest_FPROUND)
224
 
#define OFFB_VRSAVE     offsetofPPCGuestState(guest_VRSAVE)
225
 
#define OFFB_VSCR       offsetofPPCGuestState(guest_VSCR)
226
 
#define OFFB_EMWARN     offsetofPPCGuestState(guest_EMWARN)
227
 
#define OFFB_TISTART    offsetofPPCGuestState(guest_TISTART)
228
 
#define OFFB_TILEN      offsetofPPCGuestState(guest_TILEN)
229
 
#define OFFB_RESVN      offsetofPPCGuestState(guest_RESVN)
230
 
#define OFFB_NRADDR     offsetofPPCGuestState(guest_NRADDR)
231
 
 
232
 
/* This only exists in the 64-bit guest state */
233
 
#define OFFB64_NRADDR_GPR2 \
234
 
                        offsetof(VexGuestPPC64State,guest_NRADDR_GPR2)
 
220
#define OFFB_CIA         offsetofPPCGuestState(guest_CIA)
 
221
#define OFFB_CIA_AT_SC   offsetofPPCGuestState(guest_CIA_AT_SC)
 
222
#define OFFB_SPRG3_RO    offsetofPPCGuestState(guest_SPRG3_RO)
 
223
#define OFFB_LR          offsetofPPCGuestState(guest_LR)
 
224
#define OFFB_CTR         offsetofPPCGuestState(guest_CTR)
 
225
#define OFFB_XER_SO      offsetofPPCGuestState(guest_XER_SO)
 
226
#define OFFB_XER_OV      offsetofPPCGuestState(guest_XER_OV)
 
227
#define OFFB_XER_CA      offsetofPPCGuestState(guest_XER_CA)
 
228
#define OFFB_XER_BC      offsetofPPCGuestState(guest_XER_BC)
 
229
#define OFFB_FPROUND     offsetofPPCGuestState(guest_FPROUND)
 
230
#define OFFB_VRSAVE      offsetofPPCGuestState(guest_VRSAVE)
 
231
#define OFFB_VSCR        offsetofPPCGuestState(guest_VSCR)
 
232
#define OFFB_EMWARN      offsetofPPCGuestState(guest_EMWARN)
 
233
#define OFFB_TISTART     offsetofPPCGuestState(guest_TISTART)
 
234
#define OFFB_TILEN       offsetofPPCGuestState(guest_TILEN)
 
235
#define OFFB_RESVN       offsetofPPCGuestState(guest_RESVN)
 
236
#define OFFB_NRADDR      offsetofPPCGuestState(guest_NRADDR)
 
237
#define OFFB_NRADDR_GPR2 offsetofPPCGuestState(guest_NRADDR_GPR2)
235
238
 
236
239
 
237
240
/*------------------------------------------------------------*/
324
327
    PPC_GST_TISTART,// For icbi: start of area to invalidate
325
328
    PPC_GST_TILEN,  // For icbi: length of area to invalidate
326
329
    PPC_GST_RESVN,  // For lwarx/stwcx.
 
330
    PPC_GST_CIA_AT_SC, // the CIA of the most recently executed SC insn
 
331
    PPC_GST_SPRG3_RO, // SPRG3
327
332
    PPC_GST_MAX
328
333
} PPC_GST;
329
334
 
392
397
/*--- ppc32/64 insn stream.                                ---*/
393
398
/*------------------------------------------------------------*/
394
399
 
395
 
/* Add a statement to the list held by "irbb". */
 
400
/* Add a statement to the list held by "irsb". */
396
401
static void stmt ( IRStmt* st )
397
402
{
398
 
   addStmtToIRBB( irbb, st );
 
403
   addStmtToIRSB( irsb, st );
399
404
}
400
405
 
401
406
/* Generate a new temporary of the given type. */
402
407
static IRTemp newTemp ( IRType ty )
403
408
{
404
409
   vassert(isPlausibleIRType(ty));
405
 
   return newIRTemp( irbb->tyenv, ty );
 
410
   return newIRTemp( irsb->tyenv, ty );
406
411
}
407
412
 
408
413
/* Various simple conversions */
456
461
 
457
462
static void assign ( IRTemp dst, IRExpr* e )
458
463
{
459
 
   stmt( IRStmt_Tmp(dst, e) );
 
464
   stmt( IRStmt_WrTmp(dst, e) );
460
465
}
461
466
 
462
467
static void storeBE ( IRExpr* addr, IRExpr* data )
463
468
{
464
 
   vassert(typeOfIRExpr(irbb->tyenv, addr) == Ity_I32 ||
465
 
           typeOfIRExpr(irbb->tyenv, addr) == Ity_I64);
 
469
   vassert(typeOfIRExpr(irsb->tyenv, addr) == Ity_I32 ||
 
470
           typeOfIRExpr(irsb->tyenv, addr) == Ity_I64);
466
471
   stmt( IRStmt_Store(Iend_BE,addr,data) );
467
472
}
468
473
 
489
494
 
490
495
static IRExpr* mkexpr ( IRTemp tmp )
491
496
{
492
 
   return IRExpr_Tmp(tmp);
 
497
   return IRExpr_RdTmp(tmp);
493
498
}
494
499
 
495
500
static IRExpr* mkU8 ( UChar i )
519
524
 
520
525
static IRExpr* mkOR1 ( IRExpr* arg1, IRExpr* arg2 )
521
526
{
522
 
   vassert(typeOfIRExpr(irbb->tyenv, arg1) == Ity_I1);
523
 
   vassert(typeOfIRExpr(irbb->tyenv, arg2) == Ity_I1);
 
527
   vassert(typeOfIRExpr(irsb->tyenv, arg1) == Ity_I1);
 
528
   vassert(typeOfIRExpr(irsb->tyenv, arg2) == Ity_I1);
524
529
   return unop(Iop_32to1, binop(Iop_Or32, unop(Iop_1Uto32, arg1), 
525
530
                                          unop(Iop_1Uto32, arg2)));
526
531
}
527
532
 
528
533
static IRExpr* mkAND1 ( IRExpr* arg1, IRExpr* arg2 )
529
534
{
530
 
   vassert(typeOfIRExpr(irbb->tyenv, arg1) == Ity_I1);
531
 
   vassert(typeOfIRExpr(irbb->tyenv, arg2) == Ity_I1);
 
535
   vassert(typeOfIRExpr(irsb->tyenv, arg1) == Ity_I1);
 
536
   vassert(typeOfIRExpr(irsb->tyenv, arg2) == Ity_I1);
532
537
   return unop(Iop_32to1, binop(Iop_And32, unop(Iop_1Uto32, arg1), 
533
538
                                           unop(Iop_1Uto32, arg2)));
534
539
}
539
544
{
540
545
   IRTemp ones8x16 = newTemp(Ity_V128);
541
546
 
542
 
   vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128);
 
547
   vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128);
543
548
   vassert(vEvn && *vEvn == IRTemp_INVALID);
544
549
   vassert(vOdd && *vOdd == IRTemp_INVALID);
545
550
   *vEvn = newTemp(Ity_V128);
557
562
{
558
563
   IRTemp ones8x16 = newTemp(Ity_V128);
559
564
 
560
 
   vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128);
 
565
   vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128);
561
566
   vassert(vEvn && *vEvn == IRTemp_INVALID);
562
567
   vassert(vOdd && *vOdd == IRTemp_INVALID);
563
568
   *vEvn = newTemp(Ity_V128);
575
580
{
576
581
   IRTemp ones16x8 = newTemp(Ity_V128);
577
582
 
578
 
   vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128);
 
583
   vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128);
579
584
   vassert(vEvn && *vEvn == IRTemp_INVALID);
580
585
   vassert(vOdd && *vOdd == IRTemp_INVALID);
581
586
   *vEvn = newTemp(Ity_V128);
593
598
{
594
599
   IRTemp ones16x8 = newTemp(Ity_V128);
595
600
 
596
 
   vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128);
 
601
   vassert(typeOfIRExpr(irsb->tyenv, vIn) == Ity_V128);
597
602
   vassert(vEvn && *vEvn == IRTemp_INVALID);
598
603
   vassert(vOdd && *vOdd == IRTemp_INVALID);
599
604
   *vEvn = newTemp(Ity_V128);
614
619
   IRTemp hi64 = newTemp(Ity_I64);
615
620
   IRTemp lo64 = newTemp(Ity_I64);
616
621
 
617
 
   vassert(typeOfIRExpr(irbb->tyenv, t128) == Ity_V128);
 
622
   vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128);
618
623
   vassert(t0 && *t0 == IRTemp_INVALID);
619
624
   vassert(t1 && *t1 == IRTemp_INVALID);
620
625
   vassert(t2 && *t2 == IRTemp_INVALID);
641
646
   IRTemp hi64 = newTemp(Ity_I64);
642
647
   IRTemp lo64 = newTemp(Ity_I64);
643
648
 
644
 
   vassert(typeOfIRExpr(irbb->tyenv, t128) == Ity_V128);
 
649
   vassert(typeOfIRExpr(irsb->tyenv, t128) == Ity_V128);
645
650
   vassert(t0 && *t0 == IRTemp_INVALID);
646
651
   vassert(t1 && *t1 == IRTemp_INVALID);
647
652
   vassert(t2 && *t2 == IRTemp_INVALID);
665
670
   IRTemp hi32 = newTemp(Ity_I32);
666
671
   IRTemp lo32 = newTemp(Ity_I32);
667
672
 
668
 
   vassert(typeOfIRExpr(irbb->tyenv, t64) == Ity_I64);
 
673
   vassert(typeOfIRExpr(irsb->tyenv, t64) == Ity_I64);
669
674
 
670
675
   assign( hi32, unop(Iop_64HIto32, t64));
671
676
   assign( lo32, unop(Iop_64to32,   t64));
688
693
   IRTemp hi32 = newTemp(Ity_I32);
689
694
   IRTemp lo32 = newTemp(Ity_I32);
690
695
 
691
 
   vassert(typeOfIRExpr(irbb->tyenv, t64) == Ity_I64);
 
696
   vassert(typeOfIRExpr(irsb->tyenv, t64) == Ity_I64);
692
697
 
693
698
   assign( hi32, unop(Iop_64HIto32, t64));
694
699
   assign( lo32, unop(Iop_64to32,   t64));
706
711
static IRExpr* mkV128from4x64S ( IRExpr* t3, IRExpr* t2,
707
712
                                 IRExpr* t1, IRExpr* t0 )
708
713
{
709
 
   vassert(typeOfIRExpr(irbb->tyenv, t3) == Ity_I64);
710
 
   vassert(typeOfIRExpr(irbb->tyenv, t2) == Ity_I64);
711
 
   vassert(typeOfIRExpr(irbb->tyenv, t1) == Ity_I64);
712
 
   vassert(typeOfIRExpr(irbb->tyenv, t0) == Ity_I64);
 
714
   vassert(typeOfIRExpr(irsb->tyenv, t3) == Ity_I64);
 
715
   vassert(typeOfIRExpr(irsb->tyenv, t2) == Ity_I64);
 
716
   vassert(typeOfIRExpr(irsb->tyenv, t1) == Ity_I64);
 
717
   vassert(typeOfIRExpr(irsb->tyenv, t0) == Ity_I64);
713
718
   return binop(Iop_64HLtoV128,
714
719
                binop(Iop_32HLto64,
715
720
                      mkQNarrow64Sto32( t3 ),
723
728
static IRExpr* mkV128from4x64U ( IRExpr* t3, IRExpr* t2,
724
729
                                 IRExpr* t1, IRExpr* t0 )
725
730
{
726
 
   vassert(typeOfIRExpr(irbb->tyenv, t3) == Ity_I64);
727
 
   vassert(typeOfIRExpr(irbb->tyenv, t2) == Ity_I64);
728
 
   vassert(typeOfIRExpr(irbb->tyenv, t1) == Ity_I64);
729
 
   vassert(typeOfIRExpr(irbb->tyenv, t0) == Ity_I64);
 
731
   vassert(typeOfIRExpr(irsb->tyenv, t3) == Ity_I64);
 
732
   vassert(typeOfIRExpr(irsb->tyenv, t2) == Ity_I64);
 
733
   vassert(typeOfIRExpr(irsb->tyenv, t1) == Ity_I64);
 
734
   vassert(typeOfIRExpr(irsb->tyenv, t0) == Ity_I64);
730
735
   return binop(Iop_64HLtoV128,
731
736
                binop(Iop_32HLto64,
732
737
                      mkQNarrow64Uto32( t3 ),
759
764
 
760
765
static IRExpr* /* :: Ity_I64 */ mk64lo32Sto64 ( IRExpr* src )
761
766
{
762
 
   vassert(typeOfIRExpr(irbb->tyenv, src) == Ity_I64);
 
767
   vassert(typeOfIRExpr(irsb->tyenv, src) == Ity_I64);
763
768
   return unop(Iop_32Sto64, unop(Iop_64to32, src));
764
769
}
765
770
 
766
771
static IRExpr* /* :: Ity_I64 */ mk64lo32Uto64 ( IRExpr* src )
767
772
{
768
 
   vassert(typeOfIRExpr(irbb->tyenv, src) == Ity_I64);
 
773
   vassert(typeOfIRExpr(irsb->tyenv, src) == Ity_I64);
769
774
   return unop(Iop_32Uto64, unop(Iop_64to32, src));
770
775
}
771
776
 
778
783
           op8 == Iop_Or8    || op8 == Iop_And8   || op8 == Iop_Xor8 ||
779
784
           op8 == Iop_Shl8   || op8 == Iop_Shr8   || op8 == Iop_Sar8 ||
780
785
           op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 ||
781
 
           op8 == Iop_Not8   || op8 == Iop_Neg8 );
 
786
           op8 == Iop_Not8 );
782
787
   adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : (ty==Ity_I32 ? 2 : 3));
783
788
   return adj + op8;
784
789
}
932
937
{
933
938
   IRType ty = mode64 ? Ity_I64 : Ity_I32;
934
939
   vassert(archreg < 32);
935
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == ty );
 
940
   vassert(typeOfIRExpr(irsb->tyenv, e) == ty );
936
941
   stmt( IRStmt_Put(integerGuestRegOffset(archreg), e) );
937
942
}
938
943
 
989
994
static void putFReg ( UInt archreg, IRExpr* e )
990
995
{
991
996
   vassert(archreg < 32);
992
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_F64);
 
997
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
993
998
   stmt( IRStmt_Put(floatGuestRegOffset(archreg), e) );
994
999
}
995
1000
 
1046
1051
static void putVReg ( UInt archreg, IRExpr* e )
1047
1052
{
1048
1053
   vassert(archreg < 32);
1049
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_V128);
 
1054
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_V128);
1050
1055
   stmt( IRStmt_Put(vectorGuestRegOffset(archreg), e) );
1051
1056
}
1052
1057
 
1085
1090
                                          IRExpr* rot_amt )
1086
1091
{
1087
1092
   IRExpr *mask, *rot;
1088
 
   vassert(typeOfIRExpr(irbb->tyenv,rot_amt) == Ity_I8);
 
1093
   vassert(typeOfIRExpr(irsb->tyenv,rot_amt) == Ity_I8);
1089
1094
 
1090
 
   if (typeOfIRExpr(irbb->tyenv,src) == Ity_I64) {
 
1095
   if (typeOfIRExpr(irsb->tyenv,src) == Ity_I64) {
1091
1096
      // rot = (src << rot_amt) | (src >> (64-rot_amt))
1092
1097
      mask = binop(Iop_And8, rot_amt, mkU8(63));
1093
1098
      rot  = binop(Iop_Or64,
1119
1124
{
1120
1125
   IRExpr *mask, *rot32;
1121
1126
   vassert(mode64);       // used only in 64bit mode
1122
 
   vassert(typeOfIRExpr(irbb->tyenv,src64) == Ity_I64);
1123
 
   vassert(typeOfIRExpr(irbb->tyenv,rot_amt) == Ity_I8);
 
1127
   vassert(typeOfIRExpr(irsb->tyenv,src64) == Ity_I64);
 
1128
   vassert(typeOfIRExpr(irsb->tyenv,rot_amt) == Ity_I8);
1124
1129
 
1125
1130
   mask  = binop(Iop_And8, rot_amt, mkU8(31));
1126
1131
   rot32 = ROTL( unop(Iop_64to32, src64), rot_amt );
1198
1203
      vpanic("addr_align(ppc)");
1199
1204
   }
1200
1205
 
1201
 
   vassert(typeOfIRExpr(irbb->tyenv,addr) == ty);
 
1206
   vassert(typeOfIRExpr(irsb->tyenv,addr) == ty);
1202
1207
   return binop( mkSzOp(ty, Iop_And8), addr, mkSzImm(ty, mask) );
1203
1208
}
1204
1209
 
1205
1210
 
1206
 
/* Generate AbiHints which mark points at which the ELF ppc64 ABI says
1207
 
   that the stack red zone (viz, -288(r1) .. -1(r1)) becomes
1208
 
   undefined.  That is at function calls and returns.  Only in 64-bit
1209
 
   mode - ELF ppc32 doesn't have this "feature".
 
1211
/* Generate AbiHints which mark points at which the ELF or PowerOpen
 
1212
   ABIs say that the stack red zone (viz, -N(r1) .. -1(r1), for some
 
1213
   N) becomes undefined.  That is at function calls and returns.  ELF
 
1214
   ppc32 doesn't have this "feature" (how fortunate for it).
1210
1215
*/
1211
 
static void make_redzone_AbiHint ( HChar* who )
 
1216
static void make_redzone_AbiHint ( VexAbiInfo* vbi, HChar* who )
1212
1217
{
 
1218
   Int szB = vbi->guest_stack_redzone_size;
1213
1219
   if (0) vex_printf("AbiHint: %s\n", who);
1214
 
   vassert(mode64);
1215
 
   stmt( IRStmt_AbiHint( 
1216
 
            binop(Iop_Sub64, getIReg(1), mkU64(288)), 
1217
 
            288 
1218
 
   ));
 
1220
   vassert(szB >= 0);
 
1221
   if (szB > 0) {
 
1222
      if (mode64)
 
1223
         stmt( IRStmt_AbiHint( 
 
1224
                  binop(Iop_Sub64, getIReg(1), mkU64(szB)), 
 
1225
                  szB
 
1226
         ));
 
1227
      else
 
1228
         stmt( IRStmt_AbiHint( 
 
1229
                  binop(Iop_Sub32, getIReg(1), mkU32(szB)), 
 
1230
                  szB
 
1231
         ));
 
1232
   }
1219
1233
}
1220
1234
 
1221
1235
 
1256
1270
static void putCR321 ( UInt cr, IRExpr* e )
1257
1271
{
1258
1272
   vassert(cr < 8);
1259
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);
 
1273
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8);
1260
1274
   stmt( IRStmt_Put(guestCR321offset(cr), e) );
1261
1275
}
1262
1276
 
1263
1277
static void putCR0 ( UInt cr, IRExpr* e )
1264
1278
{
1265
1279
   vassert(cr < 8);
1266
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);
 
1280
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8);
1267
1281
   stmt( IRStmt_Put(guestCR0offset(cr), e) );
1268
1282
}
1269
1283
 
1308
1322
{
1309
1323
   UInt    n, off;
1310
1324
   IRExpr* safe;
1311
 
   vassert(typeOfIRExpr(irbb->tyenv,bit) == Ity_I32);
 
1325
   vassert(typeOfIRExpr(irsb->tyenv,bit) == Ity_I32);
1312
1326
   safe = binop(Iop_And32, bit, mkU32(1));
1313
1327
   n   = bi / 4;
1314
1328
   off = bi % 4;
1368
1382
static IRExpr* getXER_SO ( void );
1369
1383
static void set_CR0 ( IRExpr* result )
1370
1384
{
1371
 
   vassert(typeOfIRExpr(irbb->tyenv,result) == Ity_I32 ||
1372
 
           typeOfIRExpr(irbb->tyenv,result) == Ity_I64);
 
1385
   vassert(typeOfIRExpr(irsb->tyenv,result) == Ity_I32 ||
 
1386
           typeOfIRExpr(irsb->tyenv,result) == Ity_I64);
1373
1387
   if (mode64) {
1374
1388
      putCR321( 0, unop(Iop_64to8,
1375
1389
                        binop(Iop_CmpORD64S, result, mkU64(0))) );
1395
1409
   IRTemp rOnes  = newTemp(Ity_I8);
1396
1410
   IRTemp rZeros = newTemp(Ity_I8);
1397
1411
 
1398
 
   vassert(typeOfIRExpr(irbb->tyenv,result) == Ity_V128);
 
1412
   vassert(typeOfIRExpr(irsb->tyenv,result) == Ity_V128);
1399
1413
 
1400
1414
   assign( v0, result );
1401
1415
   assign( v1, binop(Iop_ShrV128, result, mkU8(32)) );
1437
1451
static void putXER_SO ( IRExpr* e )
1438
1452
{
1439
1453
   IRExpr* so;
1440
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);
 
1454
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8);
1441
1455
   so = binop(Iop_And8, e, mkU8(1));
1442
1456
   stmt( IRStmt_Put( OFFB_XER_SO, so ) );
1443
1457
}
1445
1459
static void putXER_OV ( IRExpr* e )
1446
1460
{
1447
1461
   IRExpr* ov;
1448
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);
 
1462
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8);
1449
1463
   ov = binop(Iop_And8, e, mkU8(1));
1450
1464
   stmt( IRStmt_Put( OFFB_XER_OV, ov ) );
1451
1465
}
1453
1467
static void putXER_CA ( IRExpr* e )
1454
1468
{
1455
1469
   IRExpr* ca;
1456
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);
 
1470
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8);
1457
1471
   ca = binop(Iop_And8, e, mkU8(1));
1458
1472
   stmt( IRStmt_Put( OFFB_XER_CA, ca ) );
1459
1473
}
1461
1475
static void putXER_BC ( IRExpr* e )
1462
1476
{
1463
1477
   IRExpr* bc;
1464
 
   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);
 
1478
   vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I8);
1465
1479
   bc = binop(Iop_And8, e, mkU8(0x7F));
1466
1480
   stmt( IRStmt_Put( OFFB_XER_BC, bc ) );
1467
1481
}
1513
1527
   IRTemp  t64;
1514
1528
   IRExpr* xer_ov;
1515
1529
   vassert(op < PPCG_FLAG_OP_NUMBER);
1516
 
   vassert(typeOfIRExpr(irbb->tyenv,res)  == Ity_I32);
1517
 
   vassert(typeOfIRExpr(irbb->tyenv,argL) == Ity_I32);
1518
 
   vassert(typeOfIRExpr(irbb->tyenv,argR) == Ity_I32);
 
1530
   vassert(typeOfIRExpr(irsb->tyenv,res)  == Ity_I32);
 
1531
   vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I32);
 
1532
   vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I32);
1519
1533
 
1520
1534
#  define INT32_MIN 0x80000000
1521
1535
 
1624
1638
{
1625
1639
   IRExpr* xer_ov;
1626
1640
   vassert(op < PPCG_FLAG_OP_NUMBER);
1627
 
   vassert(typeOfIRExpr(irbb->tyenv,res)  == Ity_I64);
1628
 
   vassert(typeOfIRExpr(irbb->tyenv,argL) == Ity_I64);
1629
 
   vassert(typeOfIRExpr(irbb->tyenv,argR) == Ity_I64);
 
1641
   vassert(typeOfIRExpr(irsb->tyenv,res)  == Ity_I64);
 
1642
   vassert(typeOfIRExpr(irsb->tyenv,argL) == Ity_I64);
 
1643
   vassert(typeOfIRExpr(irsb->tyenv,argR) == Ity_I64);
1630
1644
 
1631
1645
#  define INT64_MIN 0x8000000000000000ULL
1632
1646
 
1743
1757
{
1744
1758
   IRExpr* xer_ca;
1745
1759
   vassert(op < PPCG_FLAG_OP_NUMBER);
1746
 
   vassert(typeOfIRExpr(irbb->tyenv,res)   == Ity_I32);
1747
 
   vassert(typeOfIRExpr(irbb->tyenv,argL)  == Ity_I32);
1748
 
   vassert(typeOfIRExpr(irbb->tyenv,argR)  == Ity_I32);
1749
 
   vassert(typeOfIRExpr(irbb->tyenv,oldca) == Ity_I32);
 
1760
   vassert(typeOfIRExpr(irsb->tyenv,res)   == Ity_I32);
 
1761
   vassert(typeOfIRExpr(irsb->tyenv,argL)  == Ity_I32);
 
1762
   vassert(typeOfIRExpr(irsb->tyenv,argR)  == Ity_I32);
 
1763
   vassert(typeOfIRExpr(irsb->tyenv,oldca) == Ity_I32);
1750
1764
 
1751
1765
   /* Incoming oldca is assumed to hold the values 0 or 1 only.  This
1752
1766
      seems reasonable given that it's always generated by
1861
1875
{
1862
1876
   IRExpr* xer_ca;
1863
1877
   vassert(op < PPCG_FLAG_OP_NUMBER);
1864
 
   vassert(typeOfIRExpr(irbb->tyenv,res)   == Ity_I64);
1865
 
   vassert(typeOfIRExpr(irbb->tyenv,argL)  == Ity_I64);
1866
 
   vassert(typeOfIRExpr(irbb->tyenv,argR)  == Ity_I64);
1867
 
   vassert(typeOfIRExpr(irbb->tyenv,oldca) == Ity_I64);
 
1878
   vassert(typeOfIRExpr(irsb->tyenv,res)   == Ity_I64);
 
1879
   vassert(typeOfIRExpr(irsb->tyenv,argL)  == Ity_I64);
 
1880
   vassert(typeOfIRExpr(irsb->tyenv,argR)  == Ity_I64);
 
1881
   vassert(typeOfIRExpr(irsb->tyenv,oldca) == Ity_I64);
1868
1882
 
1869
1883
   /* Incoming oldca is assumed to hold the values 0 or 1 only.  This
1870
1884
      seems reasonable given that it's always generated by
2051
2065
{
2052
2066
   IRType ty = mode64 ? Ity_I64 : Ity_I32;
2053
2067
   switch (reg) {
 
2068
   case PPC_GST_SPRG3_RO:
 
2069
      return IRExpr_Get( OFFB_SPRG3_RO, ty );
 
2070
 
 
2071
   case PPC_GST_CIA: 
 
2072
      return IRExpr_Get( OFFB_CIA, ty );
 
2073
 
2054
2074
   case PPC_GST_LR: 
2055
2075
      return IRExpr_Get( OFFB_LR, ty );
2056
2076
 
2178
2198
static void putGST ( PPC_GST reg, IRExpr* src )
2179
2199
{
2180
2200
   IRType ty     = mode64 ? Ity_I64 : Ity_I32;
2181
 
   IRType ty_src = typeOfIRExpr(irbb->tyenv,src );
 
2201
   IRType ty_src = typeOfIRExpr(irsb->tyenv,src );
2182
2202
   vassert( reg < PPC_GST_MAX );
2183
2203
   switch (reg) {
 
2204
   case PPC_GST_CIA_AT_SC: 
 
2205
      vassert( ty_src == ty );
 
2206
      stmt( IRStmt_Put( OFFB_CIA_AT_SC, src ) );
 
2207
      break;
2184
2208
   case PPC_GST_CIA: 
2185
2209
      vassert( ty_src == ty );
2186
2210
      stmt( IRStmt_Put( OFFB_CIA, src ) );
2242
2266
{
2243
2267
   IRType ty = mode64 ? Ity_I64 : Ity_I32;
2244
2268
   vassert( reg < PPC_GST_MAX );
2245
 
   vassert( typeOfIRExpr(irbb->tyenv,src ) == Ity_I32 );
 
2269
   vassert( typeOfIRExpr(irsb->tyenv,src ) == Ity_I32 );
2246
2270
   
2247
2271
   switch (reg) {
2248
2272
   case PPC_GST_FPSCR: {
2300
2324
{
2301
2325
   UInt shft, mask;
2302
2326
 
2303
 
   vassert( typeOfIRExpr(irbb->tyenv,src ) == Ity_I32 );
 
2327
   vassert( typeOfIRExpr(irsb->tyenv,src ) == Ity_I32 );
2304
2328
   vassert( fld < 8 );
2305
2329
   vassert( reg < PPC_GST_MAX );
2306
2330
   
2941
2965
            remove the false dependency, which has been known to cause
2942
2966
            memcheck to produce false errors. */
2943
2967
         if (rA_addr == rB_addr)
2944
 
            a = b = typeOfIRExpr(irbb->tyenv,a) == Ity_I64
 
2968
            a = b = typeOfIRExpr(irsb->tyenv,a) == Ity_I64
2945
2969
                    ? mkU64(0)  : mkU32(0);
2946
2970
         if (flag_L == 1) {
2947
2971
            putCR321(crfD, unop(Iop_64to8, binop(Iop_CmpORD64S, a, b)));
2960
2984
            remove the false dependency, which has been known to cause
2961
2985
            memcheck to produce false errors. */
2962
2986
         if (rA_addr == rB_addr)
2963
 
            a = b = typeOfIRExpr(irbb->tyenv,a) == Ity_I64
 
2987
            a = b = typeOfIRExpr(irsb->tyenv,a) == Ity_I64
2964
2988
                    ? mkU64(0)  : mkU32(0);
2965
2989
         if (flag_L == 1) {
2966
2990
            putCR321(crfD, unop(Iop_64to8, binop(Iop_CmpORD64U, a, b)));
3288
3312
      vassert(sh_imm  < 32);
3289
3313
 
3290
3314
      if (mode64) {
 
3315
         IRTemp rTmp = newTemp(Ity_I64);
3291
3316
         mask64 = MASK64(31-MaskEnd, 31-MaskBeg);
3292
3317
         DIP("rlwinm%s r%u,r%u,%d,%d,%d\n", flag_rC ? ".":"",
3293
3318
             rA_addr, rS_addr, sh_imm, MaskBeg, MaskEnd);
3295
3320
         // rA = ((tmp32 || tmp32) & mask64)
3296
3321
         r = ROTL( unop(Iop_64to32, mkexpr(rS) ), mkU8(sh_imm) );
3297
3322
         r = unop(Iop_32Uto64, r);
3298
 
         assign( rot, binop(Iop_Or64, r,
3299
 
                            binop(Iop_Shl64, r, mkU8(32))) );
 
3323
         assign( rTmp, r );
 
3324
         r = NULL;
 
3325
         assign( rot, binop(Iop_Or64, mkexpr(rTmp),
 
3326
                            binop(Iop_Shl64, mkexpr(rTmp), mkU8(32))) );
3300
3327
         assign( rA, binop(Iop_And64, mkexpr(rot), mkU64(mask64)) );
3301
3328
      }
3302
3329
      else {
3311
3338
            /* Special-case the ,32-n,n,31 form as that is just n-bit
3312
3339
               unsigned shift right, PPC32 p501 */
3313
3340
            DIP("srwi%s r%u,r%u,%d\n", flag_rC ? ".":"",
3314
 
                rA_addr, rS_addr, sh_imm);
 
3341
                rA_addr, rS_addr, MaskBeg);
3315
3342
            assign( rA, binop(Iop_Shr32, mkexpr(rS), mkU8(MaskBeg)) );
3316
3343
         }
3317
3344
         else {
3356
3383
      break;
3357
3384
   }
3358
3385
 
3359
 
 
3360
3386
   /* 64bit Integer Rotates */
3361
3387
   case 0x1E: {
3362
3388
      msk_imm = ((msk_imm & 1) << 5) | (msk_imm >> 1);
3402
3428
         */
3403
3429
         
3404
3430
      case 0x0: // rldicl (Rotl DWord Imm, Clear Left, PPC64 p558)
3405
 
         DIP("rldicl%s r%u,r%u,%u,%u\n", flag_rC ? ".":"",
3406
 
             rA_addr, rS_addr, sh_imm, msk_imm);
3407
 
         r = ROTL(mkexpr(rS), mkU8(sh_imm));
3408
 
         mask64 = MASK64(0, 63-msk_imm);
3409
 
         assign( rA, binop(Iop_And64, r, mkU64(mask64)) );
 
3431
         if (mode64
 
3432
             && sh_imm + msk_imm == 64 && msk_imm >= 1 && msk_imm <= 63) {
 
3433
            /* special-case the ,64-n,n form as that is just
 
3434
               unsigned shift-right by n */
 
3435
            DIP("srdi%s r%u,r%u,%u\n",
 
3436
                flag_rC ? ".":"", rA_addr, rS_addr, msk_imm);
 
3437
            assign( rA, binop(Iop_Shr64, mkexpr(rS), mkU8(msk_imm)) );
 
3438
         } else {
 
3439
            DIP("rldicl%s r%u,r%u,%u,%u\n", flag_rC ? ".":"",
 
3440
                rA_addr, rS_addr, sh_imm, msk_imm);
 
3441
            r = ROTL(mkexpr(rS), mkU8(sh_imm));
 
3442
            mask64 = MASK64(0, 63-msk_imm);
 
3443
            assign( rA, binop(Iop_And64, r, mkU64(mask64)) );
 
3444
         }
3410
3445
         break;
3411
 
         /* later: deal with special case:
3412
 
            (msk_imm + sh_imm == 63) => SHR(63 - sh_imm) */
3413
3446
         
3414
3447
      case 0x1: // rldicr (Rotl DWord Imm, Clear Right, PPC64 p559)
3415
 
         DIP("rldicr%s r%u,r%u,%u,%u\n", flag_rC ? ".":"",
3416
 
             rA_addr, rS_addr, sh_imm, msk_imm);
3417
 
         r = ROTL(mkexpr(rS), mkU8(sh_imm));
3418
 
         mask64 = MASK64(63-msk_imm, 63);
3419
 
         assign( rA, binop(Iop_And64, r, mkU64(mask64)) );
 
3448
         if (mode64 
 
3449
             && sh_imm + msk_imm == 63 && sh_imm >= 1 && sh_imm <= 63) {
 
3450
            /* special-case the ,n,63-n form as that is just
 
3451
               shift-left by n */
 
3452
            DIP("sldi%s r%u,r%u,%u\n",
 
3453
                flag_rC ? ".":"", rA_addr, rS_addr, sh_imm);
 
3454
            assign( rA, binop(Iop_Shl64, mkexpr(rS), mkU8(sh_imm)) );
 
3455
         } else {
 
3456
            DIP("rldicr%s r%u,r%u,%u,%u\n", flag_rC ? ".":"",
 
3457
                rA_addr, rS_addr, sh_imm, msk_imm);
 
3458
            r = ROTL(mkexpr(rS), mkU8(sh_imm));
 
3459
            mask64 = MASK64(63-msk_imm, 63);
 
3460
            assign( rA, binop(Iop_And64, r, mkU64(mask64)) );
 
3461
         }
3420
3462
         break;
3421
 
         /* later: deal with special case:
3422
 
            (msk_imm == sh_imm) => SHL(sh_imm) */
3423
3463
         
3424
3464
      case 0x3: { // rldimi (Rotl DWord Imm, Mask Insert, PPC64 p560)
3425
3465
         IRTemp rA_orig = newTemp(ty);
3479
3519
   case 0x1F: // register offset
3480
3520
      assign( EA, ea_rAor0_idxd( rA_addr, rB_addr ) );
3481
3521
      break;
3482
 
   case 0x3A: // immediate offset: 64bit
 
3522
   case 0x3A: // immediate offset: 64bit: ld/ldu/lwa: mask off
 
3523
              // lowest 2 bits of immediate before forming EA
3483
3524
      simm16 = simm16 & 0xFFFFFFFC;
3484
3525
   default:   // immediate offset
3485
3526
      assign( EA, ea_rAor0_simm( rA_addr, simm16  ) );
3671
3712
      }
3672
3713
      break;
3673
3714
 
3674
 
   /* DS Form - 64bit Loads */
 
3715
   /* DS Form - 64bit Loads.  In each case EA will have been formed
 
3716
      with the lowest 2 bits masked off the immediate offset. */
3675
3717
   case 0x3A:
3676
 
      switch (b1<<1 | b0) {
 
3718
      switch ((b1<<1) | b0) {
3677
3719
      case 0x0: // ld (Load DWord, PPC64 p472)
3678
3720
         DIP("ld r%u,%d(r%u)\n", rD_addr, simm16, rA_addr);
3679
3721
         putIReg( rD_addr, loadBE(Ity_I64, mkexpr(EA)) );
3685
3727
            return False;
3686
3728
         }
3687
3729
         DIP("ldu r%u,%d(r%u)\n", rD_addr, simm16, rA_addr);
3688
 
         simm16 = simm16 & ~0x3;
3689
3730
         putIReg( rD_addr, loadBE(Ity_I64, mkexpr(EA)) );
3690
3731
         putIReg( rA_addr, mkexpr(EA) );
3691
3732
         break;
3714
3755
/*
3715
3756
  Integer Store Instructions
3716
3757
*/
3717
 
static Bool dis_int_store ( UInt theInstr )
 
3758
static Bool dis_int_store ( UInt theInstr, VexAbiInfo* vbi )
3718
3759
{
3719
3760
   /* D-Form, X-Form, DS-Form */
3720
3761
   UChar opc1    = ifieldOPC(theInstr);
3739
3780
   case 0x1F: // register offset
3740
3781
      assign( EA, ea_rAor0_idxd( rA_addr, rB_addr ) );
3741
3782
      break;
3742
 
   case 0x3E: // immediate offset: 64bit
 
3783
   case 0x3E: // immediate offset: 64bit: std/stdu: mask off
 
3784
              // lowest 2 bits of immediate before forming EA
3743
3785
      simm16 = simm16 & 0xFFFFFFFC;
3744
3786
   default:   // immediate offset
3745
3787
      assign( EA, ea_rAor0_simm( rA_addr, simm16  ) );
3868
3910
      }
3869
3911
      break;
3870
3912
 
3871
 
   /* DS Form - 64bit Stores */
 
3913
   /* DS Form - 64bit Stores.  In each case EA will have been formed
 
3914
      with the lowest 2 bits masked off the immediate offset. */
3872
3915
   case 0x3E:
3873
 
      switch (b1<<1 | b0) {
 
3916
      switch ((b1<<1) | b0) {
3874
3917
      case 0x0: // std (Store DWord, PPC64 p580)
3875
3918
         DIP("std r%u,%d(r%u)\n", rS_addr, simm16, rA_addr);
3876
3919
         storeBE( mkexpr(EA), mkexpr(rS) );
4211
4254
  Integer Branch Instructions
4212
4255
*/
4213
4256
static Bool dis_branch ( UInt theInstr, 
 
4257
                         VexAbiInfo* vbi,
4214
4258
                         /*OUT*/DisResult* dres,
4215
4259
                         Bool (*resteerOkFn)(void*,Addr64),
4216
4260
                         void* callback_opaque )
4263
4307
 
4264
4308
      if (flag_LK) {
4265
4309
         putGST( PPC_GST_LR, e_nia );
4266
 
         if (mode64)
4267
 
            make_redzone_AbiHint( "branch-and-link (unconditional call)" );
 
4310
         if (vbi->guest_ppc_zap_RZ_at_bl
 
4311
             && vbi->guest_ppc_zap_RZ_at_bl( (ULong)tgt) )
 
4312
            make_redzone_AbiHint( vbi, 
 
4313
                                  "branch-and-link (unconditional call)" );
4268
4314
      }
4269
4315
 
4270
4316
      if (resteerOkFn( callback_opaque, tgt )) {
4271
4317
         dres->whatNext   = Dis_Resteer;
4272
4318
         dres->continueAt = tgt;
4273
4319
      } else {
4274
 
         irbb->jumpkind = flag_LK ? Ijk_Call : Ijk_Boring;
4275
 
         irbb->next     = mkSzImm(ty, tgt);
 
4320
         irsb->jumpkind = flag_LK ? Ijk_Call : Ijk_Boring;
 
4321
         irsb->next     = mkSzImm(ty, tgt);
4276
4322
      }
4277
4323
      break;
4278
4324
      
4310
4356
               flag_LK ? Ijk_Call : Ijk_Boring,
4311
4357
               mkSzConst(ty, tgt) ) );
4312
4358
      
4313
 
      irbb->jumpkind = Ijk_Boring;
4314
 
      irbb->next     = e_nia;
 
4359
      irsb->jumpkind = Ijk_Boring;
 
4360
      irsb->next     = e_nia;
4315
4361
      break;
4316
4362
      
4317
4363
   case 0x13:
4343
4389
                  Ijk_Boring,
4344
4390
                  c_nia ));
4345
4391
         
4346
 
         irbb->jumpkind = flag_LK ? Ijk_Call : Ijk_Boring;
4347
 
         irbb->next     = mkexpr(lr_old);
 
4392
         irsb->jumpkind = flag_LK ? Ijk_Call : Ijk_Boring;
 
4393
         irsb->next     = mkexpr(lr_old);
4348
4394
         break;
4349
4395
         
4350
4396
      case 0x010: { // bclr (Branch Cond. to Link Register, PPC32 p365) 
4378
4424
                  Ijk_Boring,
4379
4425
                  c_nia ));
4380
4426
 
4381
 
         if (vanilla_return && mode64)
4382
 
            make_redzone_AbiHint( "branch-to-lr (unconditional return)" );
 
4427
         if (vanilla_return && vbi->guest_ppc_zap_RZ_at_blr)
 
4428
            make_redzone_AbiHint( vbi, "branch-to-lr (unconditional return)" );
4383
4429
 
4384
4430
         /* blrl is pretty strange; it's like a return that sets the
4385
4431
            return address of its caller to the insn following this
4386
4432
            one.  Mark it as a return. */
4387
 
         irbb->jumpkind = Ijk_Ret;  /* was flag_LK ? Ijk_Call : Ijk_Ret; */
4388
 
         irbb->next     = mkexpr(lr_old);
 
4433
         irsb->jumpkind = Ijk_Ret;  /* was flag_LK ? Ijk_Call : Ijk_Ret; */
 
4434
         irsb->next     = mkexpr(lr_old);
4389
4435
         break;
4390
4436
      }
4391
4437
      default:
4500
4546
*/
4501
4547
 
4502
4548
/* Do the code generation for a trap.  Returned Bool is true iff
4503
 
   this is an unconditional trap. */
4504
 
static Bool do_trap ( Bool is_twi, UChar TO, 
4505
 
                      IRExpr* argL0, ULong argR0, Addr64 cia )
 
4549
   this is an unconditional trap.  If the two arg IRExpr*s are 
 
4550
   Ity_I32s then the comparison is 32-bit.  If they are Ity_I64s
 
4551
   then they are 64-bit, and we must be disassembling 64-bit
 
4552
   instructions. */
 
4553
static Bool do_trap ( UChar TO, 
 
4554
                      IRExpr* argL0, IRExpr* argR0, Addr64 cia )
4506
4555
{
4507
4556
   IRTemp argL, argR;
4508
4557
   IRExpr *argLe, *argRe, *cond, *tmp;
4509
4558
 
4510
 
   IROp    opAND     = is_twi ? Iop_And32     : Iop_And64;
4511
 
   IROp    opOR      = is_twi ? Iop_Or32      : Iop_Or64;
4512
 
   IROp    opCMPORDS = is_twi ? Iop_CmpORD32S : Iop_CmpORD64S;
4513
 
   IROp    opCMPORDU = is_twi ? Iop_CmpORD32U : Iop_CmpORD64U;
4514
 
   IROp    opCMPNE   = is_twi ? Iop_CmpNE32   : Iop_CmpNE64;
4515
 
   IROp    opCMPEQ   = is_twi ? Iop_CmpEQ32   : Iop_CmpEQ64;
4516
 
   IRExpr* const0    = is_twi ? mkU32(0)      : mkU64(0);
4517
 
   IRExpr* const2    = is_twi ? mkU32(2)      : mkU64(2);
4518
 
   IRExpr* const4    = is_twi ? mkU32(4)      : mkU64(4);
4519
 
   IRExpr* const8    = is_twi ? mkU32(8)      : mkU64(8);
 
4559
   Bool    is32bit = typeOfIRExpr(irsb->tyenv, argL0 ) == Ity_I32;
 
4560
 
 
4561
   IROp    opAND     = is32bit ? Iop_And32     : Iop_And64;
 
4562
   IROp    opOR      = is32bit ? Iop_Or32      : Iop_Or64;
 
4563
   IROp    opCMPORDS = is32bit ? Iop_CmpORD32S : Iop_CmpORD64S;
 
4564
   IROp    opCMPORDU = is32bit ? Iop_CmpORD32U : Iop_CmpORD64U;
 
4565
   IROp    opCMPNE   = is32bit ? Iop_CmpNE32   : Iop_CmpNE64;
 
4566
   IROp    opCMPEQ   = is32bit ? Iop_CmpEQ32   : Iop_CmpEQ64;
 
4567
   IRExpr* const0    = is32bit ? mkU32(0)      : mkU64(0);
 
4568
   IRExpr* const2    = is32bit ? mkU32(2)      : mkU64(2);
 
4569
   IRExpr* const4    = is32bit ? mkU32(4)      : mkU64(4);
 
4570
   IRExpr* const8    = is32bit ? mkU32(8)      : mkU64(8);
4520
4571
 
4521
4572
   const UChar b11100 = 0x1C;
4522
4573
   const UChar b00111 = 0x07;
4523
4574
 
 
4575
   if (is32bit) {
 
4576
      vassert( typeOfIRExpr(irsb->tyenv, argL0) == Ity_I32 );
 
4577
      vassert( typeOfIRExpr(irsb->tyenv, argR0) == Ity_I32 );
 
4578
   } else {
 
4579
      vassert( typeOfIRExpr(irsb->tyenv, argL0) == Ity_I64 );
 
4580
      vassert( typeOfIRExpr(irsb->tyenv, argR0) == Ity_I64 );
 
4581
      vassert( mode64 );
 
4582
   }
 
4583
 
4524
4584
   if ((TO & b11100) == b11100 || (TO & b00111) == b00111) {
4525
4585
      /* Unconditional trap.  Just do the exit without 
4526
4586
         testing the arguments. */
4527
4587
      stmt( IRStmt_Exit( 
4528
4588
               binop(opCMPEQ, const0, const0), 
4529
 
               Ijk_Trap,
 
4589
               Ijk_SigTRAP,
4530
4590
               mode64 ? IRConst_U64(cia) : IRConst_U32((UInt)cia) 
4531
4591
      ));
4532
4592
      return True; /* unconditional trap */
4533
4593
   }
4534
4594
 
4535
 
   if (is_twi) {
 
4595
   if (is32bit) {
4536
4596
      argL = newTemp(Ity_I32);
4537
4597
      argR = newTemp(Ity_I32);
4538
 
      assign( argL, mode64 ? mkSzNarrow32(Ity_I64,argL0)
4539
 
                           : argL0 );
4540
 
      assign( argR, mkU32( (UInt)argR0 ));
4541
4598
   } else {
4542
 
      vassert(mode64);
4543
4599
      argL = newTemp(Ity_I64);
4544
4600
      argR = newTemp(Ity_I64);
4545
 
      assign( argL, argL0 );
4546
 
      assign( argR, mkU64( argR0 ));
4547
4601
   }
 
4602
 
 
4603
   assign( argL, argL0 );
 
4604
   assign( argR, argR0 );
 
4605
 
4548
4606
   argLe = mkexpr(argL);
4549
4607
   argRe = mkexpr(argR);
 
4608
 
4550
4609
   cond = const0;
4551
4610
   if (TO & 16) { // L <s R
4552
4611
      tmp = binop(opAND, binop(opCMPORDS, argLe, argRe), const8);
4570
4629
   }
4571
4630
   stmt( IRStmt_Exit( 
4572
4631
            binop(opCMPNE, cond, const0), 
4573
 
            Ijk_Trap,
 
4632
            Ijk_SigTRAP,
4574
4633
            mode64 ? IRConst_U64(cia) : IRConst_U32((UInt)cia) 
4575
4634
   ));
4576
4635
   return False; /* not an unconditional trap */
4591
4650
 
4592
4651
   switch (opc1) {
4593
4652
   case 0x03: // twi  (Trap Word Immediate, PPC32 p548)
4594
 
      uncond = do_trap( True/*is_twi*/, TO, getIReg(rA_addr), simm16, cia );
 
4653
      uncond = do_trap( TO, 
 
4654
                        mode64 ? unop(Iop_64to32, getIReg(rA_addr)) 
 
4655
                               : getIReg(rA_addr),
 
4656
                        mkU32( (UInt)simm16 ),
 
4657
                        cia );
4595
4658
      if (TO == 4) {
4596
4659
         DIP("tweqi r%u,%d\n", (UInt)rA_addr, (Int)simm16);
4597
4660
      } else {
4601
4664
   case 0x02: // tdi
4602
4665
      if (!mode64)
4603
4666
         return False;
4604
 
      uncond = do_trap( False/*!is_twi*/, TO, getIReg(rA_addr), simm16, cia );
 
4667
      uncond = do_trap( TO, getIReg(rA_addr), mkU64( (ULong)simm16 ), cia );
4605
4668
      if (TO == 4) {
4606
4669
         DIP("tdeqi r%u,%d\n", (UInt)rA_addr, (Int)simm16);
4607
4670
      } else {
4615
4678
   if (uncond) {
4616
4679
      /* If the trap shows signs of being unconditional, don't
4617
4680
         continue decoding past it. */
4618
 
      irbb->next     = mkSzImm( ty, nextInsnAddr() );
4619
 
      irbb->jumpkind = Ijk_Boring;
 
4681
      irsb->next     = mkSzImm( ty, nextInsnAddr() );
 
4682
      irsb->jumpkind = Ijk_Boring;
 
4683
      dres->whatNext = Dis_StopHere;
 
4684
   }
 
4685
 
 
4686
   return True;
 
4687
}
 
4688
 
 
4689
static Bool dis_trap ( UInt theInstr,
 
4690
                        /*OUT*/DisResult* dres )
 
4691
{
 
4692
   /* X-Form */
 
4693
   UInt   opc2    = ifieldOPClo10(theInstr);
 
4694
   UChar  TO      = ifieldRegDS(theInstr);
 
4695
   UChar  rA_addr = ifieldRegA(theInstr);
 
4696
   UChar  rB_addr = ifieldRegB(theInstr);
 
4697
   Addr64 cia     = guest_CIA_curr_instr;
 
4698
   IRType ty      = mode64 ? Ity_I64 : Ity_I32;
 
4699
   Bool   uncond  = False;
 
4700
 
 
4701
   if (ifieldBIT0(theInstr) != 0)
 
4702
      return False;
 
4703
 
 
4704
   switch (opc2) {
 
4705
   case 0x004: // tw  (Trap Word, PPC64 p540)
 
4706
      uncond = do_trap( TO, 
 
4707
                        mode64 ? unop(Iop_64to32, getIReg(rA_addr)) 
 
4708
                               : getIReg(rA_addr),
 
4709
                        mode64 ? unop(Iop_64to32, getIReg(rB_addr)) 
 
4710
                               : getIReg(rB_addr),
 
4711
                        cia );
 
4712
      if (TO == 4) {
 
4713
         DIP("tweq r%u,r%u\n", (UInt)rA_addr, (UInt)rB_addr);
 
4714
      } else {
 
4715
         DIP("tw%d r%u,r%u\n", (Int)TO, (UInt)rA_addr, (UInt)rB_addr);
 
4716
      }
 
4717
      break;
 
4718
   case 0x044: // td (Trap Doubleword, PPC64 p534)
 
4719
      if (!mode64)
 
4720
         return False;
 
4721
      uncond = do_trap( TO, getIReg(rA_addr), getIReg(rB_addr), cia );
 
4722
      if (TO == 4) {
 
4723
         DIP("tdeq r%u,r%u\n", (UInt)rA_addr, (UInt)rB_addr);
 
4724
      } else {
 
4725
         DIP("td%d r%u,r%u\n", (Int)TO, (UInt)rA_addr, (UInt)rB_addr);
 
4726
      }
 
4727
      break;
 
4728
   default:
 
4729
      return False;
 
4730
   }
 
4731
 
 
4732
   if (uncond) {
 
4733
      /* If the trap shows signs of being unconditional, don't
 
4734
         continue decoding past it. */
 
4735
      irsb->next     = mkSzImm( ty, nextInsnAddr() );
 
4736
      irsb->jumpkind = Ijk_Boring;
4620
4737
      dres->whatNext = Dis_StopHere;
4621
4738
   }
4622
4739
 
4627
4744
/*
4628
4745
  System Linkage Instructions
4629
4746
*/
4630
 
static Bool dis_syslink ( UInt theInstr, DisResult* dres )
 
4747
static Bool dis_syslink ( UInt theInstr, 
 
4748
                          VexAbiInfo* abiinfo, DisResult* dres )
4631
4749
{
4632
4750
   IRType ty = mode64 ? Ity_I64 : Ity_I32;
4633
4751
 
4638
4756
 
4639
4757
   // sc  (System Call, PPC32 p504)
4640
4758
   DIP("sc\n");
4641
 
   
 
4759
 
 
4760
   /* Copy CIA into the CIA_AT_SC pseudo-register, so that on AIX
 
4761
      Valgrind can back the guest up to this instruction if it needs
 
4762
      to restart the syscall. */
 
4763
   putGST( PPC_GST_CIA_AT_SC, getGST( PPC_GST_CIA ) );
 
4764
 
4642
4765
   /* It's important that all ArchRegs carry their up-to-date value
4643
4766
      at this point.  So we declare an end-of-block here, which
4644
4767
      forces any TempRegs caching ArchRegs to be flushed. */
4645
 
   irbb->next     = mkSzImm( ty, nextInsnAddr() );
4646
 
   irbb->jumpkind = Ijk_Sys_syscall;
 
4768
   irsb->next     = abiinfo->guest_ppc_sc_continues_at_LR
 
4769
                       ? getGST( PPC_GST_LR )
 
4770
                       : mkSzImm( ty, nextInsnAddr() );
 
4771
   irsb->jumpkind = Ijk_Sys_syscall;
4647
4772
 
4648
4773
   dres->whatNext = Dis_StopHere;
4649
4774
   return True;
4691
4816
         return False;
4692
4817
      }
4693
4818
      DIP("isync\n");
4694
 
      stmt( IRStmt_MFence() );
 
4819
      stmt( IRStmt_MBE(Imbe_Fence) );
4695
4820
      break;
4696
4821
 
4697
4822
   /* X-Form */
4704
4829
         }
4705
4830
         DIP("eieio\n");
4706
4831
         /* Insert a memory fence, just to be on the safe side. */
4707
 
         stmt( IRStmt_MFence() );
 
4832
         stmt( IRStmt_MBE(Imbe_Fence) );
4708
4833
         break;
4709
4834
 
4710
4835
      case 0x014: // lwarx (Load Word and Reserve Indexed, PPC32 p458)
4793
4918
         DIP("%ssync\n", flag_L == 1 ? "lw" : "");
4794
4919
         /* Insert a memory fence.  It's sometimes important that these
4795
4920
            are carried through to the generated code. */
4796
 
         stmt( IRStmt_MFence() );
 
4921
         stmt( IRStmt_MBE(Imbe_Fence) );
4797
4922
         break;
4798
4923
 
4799
4924
      /* 64bit Memsync */
5099
5224
/* Generates code to swap the byte order in an Ity_I32. */
5100
5225
static IRExpr* /* :: Ity_I32 */ gen_byterev32 ( IRTemp t )
5101
5226
{
5102
 
   vassert(typeOfIRTemp(irbb->tyenv, t) == Ity_I32);
 
5227
   vassert(typeOfIRTemp(irsb->tyenv, t) == Ity_I32);
5103
5228
   return
5104
5229
      binop(Iop_Or32,
5105
5230
         binop(Iop_Shl32, mkexpr(t), mkU8(24)),
5118
5243
   and zeroes the upper half. */
5119
5244
static IRExpr* /* :: Ity_I32 */ gen_byterev16 ( IRTemp t )
5120
5245
{
5121
 
   vassert(typeOfIRTemp(irbb->tyenv, t) == Ity_I32);
 
5246
   vassert(typeOfIRTemp(irsb->tyenv, t) == Ity_I32);
5122
5247
   return
5123
5248
      binop(Iop_Or32,
5124
5249
         binop(Iop_And32, binop(Iop_Shl32, mkexpr(t), mkU8(8)),
5193
5318
/*
5194
5319
  Processor Control Instructions
5195
5320
*/
5196
 
static Bool dis_proc_ctl ( UInt theInstr )
 
5321
static Bool dis_proc_ctl ( VexAbiInfo* vbi, UInt theInstr )
5197
5322
{
5198
5323
   UChar opc1     = ifieldOPC(theInstr);
5199
5324
   
5290
5415
         putIReg( rD_addr, mkSzWiden32(ty, getGST( PPC_GST_VRSAVE ),
5291
5416
                                       /* Signed */False) );
5292
5417
         break;
5293
 
         
 
5418
 
 
5419
      case 0x103:
 
5420
         DIP("mfspr r%u, SPRG3(readonly)\n", rD_addr);
 
5421
         putIReg( rD_addr, getGST( PPC_GST_SPRG3_RO ) );
 
5422
         break;
 
5423
 
 
5424
      /* Even a lowly PPC7400 can run the associated helper, so no
 
5425
         obvious need for feature testing at this point. */
 
5426
      case 268 /* 0x10C */:
 
5427
      case 269 /* 0x10D */: {
 
5428
         UInt     arg  = SPR==268 ? 0 : 1;
 
5429
         IRTemp   val  = newTemp(Ity_I32);
 
5430
         IRExpr** args = mkIRExprVec_1( mkU32(arg) );
 
5431
         IRDirty* d    = unsafeIRDirty_1_N(
 
5432
                            val,
 
5433
                            0/*regparms*/,
 
5434
                            "ppc32g_dirtyhelper_MFSPR_268_269",
 
5435
                            fnptr_to_fnentry
 
5436
                               (vbi, &ppc32g_dirtyhelper_MFSPR_268_269),
 
5437
                            args
 
5438
                         );
 
5439
         /* execute the dirty call, dumping the result in val. */
 
5440
         stmt( IRStmt_Dirty(d) );
 
5441
         putIReg( rD_addr, mkexpr(val) );
 
5442
         DIP("mfspr r%u,%u", rD_addr, (UInt)SPR);
 
5443
         break;
 
5444
      }
 
5445
 
5294
5446
      default:
5295
5447
         vex_printf("dis_proc_ctl(ppc)(mfspr,SPR)(0x%x)\n", SPR);
5296
5448
         return False;
5304
5456
                              val, 
5305
5457
                              0/*regparms*/, 
5306
5458
                              "ppcg_dirtyhelper_MFTB", 
5307
 
                              fnptr_to_fnentry(&ppcg_dirtyhelper_MFTB), 
 
5459
                              fnptr_to_fnentry(vbi, &ppcg_dirtyhelper_MFTB), 
5308
5460
                              args );
5309
5461
      /* execute the dirty call, dumping the result in val. */
5310
5462
      stmt( IRStmt_Dirty(d) );
5430
5582
   }
5431
5583
 
5432
5584
   /* stay sane .. */
5433
 
   vassert(lineszB == 32 || lineszB == 128);
 
5585
   vassert(lineszB == 32 || lineszB == 64 || lineszB == 128);
5434
5586
   
5435
5587
   switch (opc2) {
5436
5588
//zz    case 0x2F6: // dcba (Data Cache Block Allocate, PPC32 p380)
5510
5662
      putGST( PPC_GST_TILEN, mkSzImm(ty, lineszB) );
5511
5663
 
5512
5664
      /* be paranoid ... */
5513
 
      stmt( IRStmt_MFence() );
 
5665
      stmt( IRStmt_MBE(Imbe_Fence) );
5514
5666
 
5515
 
      irbb->jumpkind = Ijk_TInval;
5516
 
      irbb->next     = mkSzImm(ty, nextInsnAddr());
 
5667
      irsb->jumpkind = Ijk_TInval;
 
5668
      irsb->next     = mkSzImm(ty, nextInsnAddr());
5517
5669
      dres->whatNext = Dis_StopHere;
5518
5670
      break;
5519
5671
   }
6497
6649
      break;
6498
6650
   }
6499
6651
 
6500
 
//zz    case 0x040: { // mcrfs (Move to Condition Register from FPSCR, PPC32 p465)
6501
 
//zz       UChar crfD    = toUChar( IFIELD( theInstr, 23, 3 ) );
6502
 
//zz       UChar b21to22 = toUChar( IFIELD( theInstr, 21, 2 ) );
6503
 
//zz       UChar crfS    = toUChar( IFIELD( theInstr, 18, 3 ) );
6504
 
//zz       UChar b11to17 = toUChar( IFIELD( theInstr, 11, 7 ) );
6505
 
//zz 
6506
 
//zz       IRTemp tmp = newTemp(Ity_I32);
6507
 
//zz 
6508
 
//zz       if (b21to22 != 0 || b11to17 != 0 || flag_rC != 0) {
6509
 
//zz          vex_printf("dis_fp_scr(ppc)(instr,mcrfs)\n");
6510
 
//zz          return False;
6511
 
//zz       }
6512
 
//zz       DIP("mcrfs crf%d,crf%d\n", crfD, crfS);
6513
 
//zz       assign( tmp, getGST_field( PPC_GST_FPSCR, crfS ) );
6514
 
//zz       putGST_field( PPC_GST_CR, mkexpr(tmp), crfD );
6515
 
//zz       break;
6516
 
//zz    }
 
6652
   case 0x040: { // mcrfs (Move to Condition Register from FPSCR, PPC32 p465)
 
6653
      UChar   crfD    = toUChar( IFIELD( theInstr, 23, 3 ) );
 
6654
      UChar   b21to22 = toUChar( IFIELD( theInstr, 21, 2 ) );
 
6655
      UChar   crfS    = toUChar( IFIELD( theInstr, 18, 3 ) );
 
6656
      UChar   b11to17 = toUChar( IFIELD( theInstr, 11, 7 ) );
 
6657
      IRTemp  tmp     = newTemp(Ity_I32);
 
6658
      IRExpr* fpscr_all;
 
6659
      if (b21to22 != 0 || b11to17 != 0 || flag_rC != 0) {
 
6660
         vex_printf("dis_fp_scr(ppc)(instr,mcrfs)\n");
 
6661
         return False;
 
6662
      }
 
6663
      DIP("mcrfs crf%d,crf%d\n", crfD, crfS);
 
6664
      vassert(crfD < 8);
 
6665
      vassert(crfS < 8);
 
6666
      fpscr_all = getGST_masked( PPC_GST_FPSCR, MASK_FPSCR_RN );
 
6667
      assign( tmp, binop(Iop_And32,
 
6668
                         binop(Iop_Shr32,fpscr_all,mkU8(4 * (7-crfS))),
 
6669
                        mkU32(0xF)) );
 
6670
      putGST_field( PPC_GST_CR, mkexpr(tmp), crfD );
 
6671
      break;
 
6672
   }
6517
6673
 
6518
6674
   case 0x046: { // mtfsb0 (Move to FPSCR Bit 0, PPC32 p478)
6519
6675
      // Bit crbD of the FPSCR is cleared.
6545
6701
   }
6546
6702
 
6547
6703
   case 0x247: { // mffs (Move from FPSCR, PPC32 p468)
6548
 
      UChar frD_addr = ifieldRegDS(theInstr);
6549
 
      UInt  b11to20  = IFIELD(theInstr, 11, 10);
 
6704
      UChar   frD_addr  = ifieldRegDS(theInstr);
 
6705
      UInt    b11to20   = IFIELD(theInstr, 11, 10);
 
6706
      IRExpr* fpscr_all = getGST_masked( PPC_GST_FPSCR, MASK_FPSCR_RN );
6550
6707
 
6551
6708
      if (b11to20 != 0) {
6552
6709
         vex_printf("dis_fp_scr(ppc)(instr,mffs)\n");
6555
6712
      DIP("mffs%s fr%u\n", flag_rC ? ".":"", frD_addr);
6556
6713
      putFReg( frD_addr,
6557
6714
          unop( Iop_ReinterpI64asF64,
6558
 
                unop( Iop_32Uto64, 
6559
 
                      getGST_masked( PPC_GST_FPSCR, MASK_FPSCR_RN ) )));
 
6715
                unop( Iop_32Uto64, fpscr_all )));
6560
6716
      break;
6561
6717
   }
6562
6718
 
6626
6782
   case 0x156: // dst (Data Stream Touch, AV p115)
6627
6783
      DIP("dst%s r%u,r%u,%d\n", flag_T ? "t" : "",
6628
6784
                                rA_addr, rB_addr, STRM);
6629
 
      DIP(" => not implemented\n");
6630
 
      return False;
 
6785
      break;
6631
6786
 
6632
6787
   case 0x176: // dstst (Data Stream Touch for Store, AV p117)
6633
6788
      DIP("dstst%s r%u,r%u,%d\n", flag_T ? "t" : "",
6634
6789
                                  rA_addr, rB_addr, STRM);
6635
 
      DIP(" => not implemented\n");
6636
 
      return False;
 
6790
      break;
6637
6791
 
6638
6792
   case 0x336: // dss (Data Stream Stop, AV p114)
6639
6793
      if (rA_addr != 0 || rB_addr != 0) {
6642
6796
      }
6643
6797
      if (flag_A == 0) {
6644
6798
         DIP("dss %d\n", STRM);
6645
 
         DIP(" => not implemented\n");
6646
6799
      } else {
6647
6800
         DIP("dssall\n");
6648
 
         DIP(" => not implemented\n");
6649
6801
      }
6650
 
      return False;
 
6802
      break;
6651
6803
 
6652
6804
   default:
6653
6805
      vex_printf("dis_av_datastream(ppc)(opc2)\n");
6704
6856
/*
6705
6857
  AltiVec Load Instructions
6706
6858
*/
6707
 
static Bool dis_av_load ( UInt theInstr )
 
6859
static Bool dis_av_load ( VexAbiInfo* vbi, UInt theInstr )
6708
6860
{
6709
6861
   /* X-Form */
6710
6862
   UChar opc1     = ifieldOPC(theInstr);
6740
6892
         d = unsafeIRDirty_0_N (
6741
6893
                        0/*regparms*/, 
6742
6894
                        "ppc32g_dirtyhelper_LVS",
6743
 
                        fnptr_to_fnentry(&ppc32g_dirtyhelper_LVS),
 
6895
                        fnptr_to_fnentry(vbi, &ppc32g_dirtyhelper_LVS),
6744
6896
                        args );
6745
6897
      } else {
6746
6898
         d = unsafeIRDirty_0_N (
6747
6899
                        0/*regparms*/, 
6748
6900
                        "ppc64g_dirtyhelper_LVS",
6749
 
                        fnptr_to_fnentry(&ppc64g_dirtyhelper_LVS),
 
6901
                        fnptr_to_fnentry(vbi, &ppc64g_dirtyhelper_LVS),
6750
6902
                        args );
6751
6903
      }
6752
6904
      DIP("lvsl v%d,r%u,r%u\n", vD_addr, rA_addr, rB_addr);
6773
6925
         d = unsafeIRDirty_0_N (
6774
6926
                        0/*regparms*/, 
6775
6927
                        "ppc32g_dirtyhelper_LVS",
6776
 
                        fnptr_to_fnentry(&ppc32g_dirtyhelper_LVS),
 
6928
                        fnptr_to_fnentry(vbi, &ppc32g_dirtyhelper_LVS),
6777
6929
                        args );
6778
6930
      } else {
6779
6931
         d = unsafeIRDirty_0_N (
6780
6932
                        0/*regparms*/, 
6781
6933
                        "ppc64g_dirtyhelper_LVS",
6782
 
                        fnptr_to_fnentry(&ppc64g_dirtyhelper_LVS),
 
6934
                        fnptr_to_fnentry(vbi, &ppc64g_dirtyhelper_LVS),
6783
6935
                        args );
6784
6936
      }
6785
6937
      DIP("lvsr v%d,r%u,r%u\n", vD_addr, rA_addr, rB_addr);
6820
6972
      break;
6821
6973
 
6822
6974
   case 0x167: // lvxl (Load Vector Indexed LRU, AV p128)
6823
 
     // XXX: lvxl gives explicit control over cache block replacement
6824
6975
      DIP("lvxl v%d,r%u,r%u\n", vD_addr, rA_addr, rB_addr);
6825
 
      DIP(" => not implemented\n");
6826
 
      return False;
 
6976
      putVReg( vD_addr, loadBE(Ity_V128, mkexpr(EA_align16)) );
 
6977
      break;
6827
6978
 
6828
6979
   default:
6829
6980
      vex_printf("dis_av_load(ppc)(opc2)\n");
6908
7059
      break;
6909
7060
 
6910
7061
   case 0x1E7: // stvxl (Store Vector Indexed LRU, AV p135)
6911
 
     // XXX: stvxl can give explicit control over cache block replacement
6912
7062
      DIP("stvxl v%d,r%u,r%u\n", vS_addr, rA_addr, rB_addr);
6913
 
      DIP(" => not implemented\n");
6914
 
      return False;
6915
 
//      STORE(vS, 16, addr_align( mkexpr(EA), 16 ));
6916
 
//      break;
 
7063
      storeBE( addr_align( mkexpr(EA), 16 ), mkexpr(vS) );
 
7064
      break;
6917
7065
 
6918
7066
   default:
6919
7067
      vex_printf("dis_av_store(ppc)(opc2)\n");
8690
8838
             Bool         (*resteerOkFn) ( /*opaque*/void*, Addr64 ),
8691
8839
             void*        callback_opaque,
8692
8840
             Long         delta64,
8693
 
             VexArchInfo* archinfo 
 
8841
             VexArchInfo* archinfo,
 
8842
             VexAbiInfo*  abiinfo
8694
8843
          )
8695
8844
{
8696
8845
   UChar     opc1;
8767
8916
            /* %R3 = client_request ( %R4 ) */
8768
8917
            DIP("r3 = client_request ( %%r4 )\n");
8769
8918
            delta += 20;
8770
 
            irbb->next     = mkSzImm( ty, guest_CIA_bbstart + delta );
8771
 
            irbb->jumpkind = Ijk_ClientReq;
 
8919
            irsb->next     = mkSzImm( ty, guest_CIA_bbstart + delta );
 
8920
            irsb->jumpkind = Ijk_ClientReq;
8772
8921
            dres.whatNext  = Dis_StopHere;
8773
8922
            goto decode_success;
8774
8923
         }
8787
8936
            DIP("branch-and-link-to-noredir r11\n");
8788
8937
            delta += 20;
8789
8938
            putGST( PPC_GST_LR, mkSzImm(ty, guest_CIA_bbstart + (Long)delta) );
8790
 
            irbb->next     = getIReg(11);
8791
 
            irbb->jumpkind = Ijk_NoRedir;
 
8939
            irsb->next     = getIReg(11);
 
8940
            irsb->jumpkind = Ijk_NoRedir;
8792
8941
            dres.whatNext  = Dis_StopHere;
8793
8942
            goto decode_success;
8794
8943
         }
8795
8944
         else
8796
 
         if (mode64 
8797
 
             && getUIntBigendianly(code+16) == 0x7C842378 /* or 4,4,4 */) {
 
8945
         if (getUIntBigendianly(code+16) == 0x7C842378 /* or 4,4,4 */) {
8798
8946
            /* %R3 = guest_NRADDR_GPR2 */
8799
8947
            DIP("r3 = guest_NRADDR_GPR2\n");
8800
8948
            delta += 20;
8801
8949
            dres.len = 20;
8802
 
            vassert(ty == Ity_I64);
8803
 
            putIReg(3, IRExpr_Get( OFFB64_NRADDR_GPR2, ty ));
 
8950
            putIReg(3, IRExpr_Get( OFFB_NRADDR_GPR2, ty ));
8804
8951
            goto decode_success;
8805
8952
         }
8806
8953
         /* We don't know what it is.  Set opc1/opc2 so decode_failure
8856
9003
   /* Integer Store Instructions */
8857
9004
   case 0x26: case 0x27: case 0x2C: // stb,  stbu, sth
8858
9005
   case 0x2D: case 0x24: case 0x25: // sthu, stw,  stwu
8859
 
      if (dis_int_store( theInstr )) goto decode_success;
 
9006
      if (dis_int_store( theInstr, abiinfo )) goto decode_success;
8860
9007
      goto decode_failure;
8861
9008
 
8862
9009
   /* Integer Load and Store Multiple Instructions */
8866
9013
 
8867
9014
   /* Branch Instructions */
8868
9015
   case 0x12: case 0x10: // b, bc
8869
 
      if (dis_branch(theInstr, &dres, resteerOkFn, callback_opaque)) 
 
9016
      if (dis_branch(theInstr, abiinfo, &dres, 
 
9017
                               resteerOkFn, callback_opaque)) 
8870
9018
         goto decode_success;
8871
9019
      goto decode_failure;
8872
9020
 
8873
9021
   /* System Linkage Instructions */
8874
9022
   case 0x11: // sc
8875
 
      if (dis_syslink(theInstr, &dres)) goto decode_success;
 
9023
      if (dis_syslink(theInstr, abiinfo, &dres)) goto decode_success;
8876
9024
      goto decode_failure;
8877
9025
 
8878
9026
   /* Trap Instructions */
8937
9085
   /* 64bit Integer Stores */
8938
9086
   case 0x3E:  // std, stdu
8939
9087
      if (!mode64) goto decode_failure;
8940
 
      if (dis_int_store( theInstr )) goto decode_success;
 
9088
      if (dis_int_store( theInstr, abiinfo )) goto decode_success;
8941
9089
      goto decode_failure;
8942
9090
 
8943
9091
   case 0x3F:
9004
9152
 
9005
9153
      /* Floating Point Status/Control Register Instructions */         
9006
9154
      case 0x026: // mtfsb1
9007
 
      /* case 0x040: // mcrfs */
 
9155
      case 0x040: // mcrfs
9008
9156
      case 0x046: // mtfsb0
9009
9157
      case 0x086: // mtfsfi
9010
9158
      case 0x247: // mffs
9029
9177
         
9030
9178
      /* Branch Instructions */
9031
9179
      case 0x210: case 0x010: // bcctr, bclr
9032
 
         if (dis_branch(theInstr, &dres, resteerOkFn, callback_opaque)) 
 
9180
         if (dis_branch(theInstr, abiinfo, &dres, 
 
9181
                                  resteerOkFn, callback_opaque)) 
9033
9182
            goto decode_success;
9034
9183
         goto decode_failure;
9035
9184
         
9125
9274
      /* Integer Store Instructions */
9126
9275
      case 0x0F7: case 0x0D7: case 0x1B7: // stbux, stbx,  sthux
9127
9276
      case 0x197: case 0x0B7: case 0x097: // sthx,  stwux, stwx
9128
 
         if (dis_int_store( theInstr )) goto decode_success;
 
9277
         if (dis_int_store( theInstr, abiinfo )) goto decode_success;
9129
9278
         goto decode_failure;
9130
9279
 
9131
9280
      /* 64bit Integer Store Instructions */
9132
9281
      case 0x0B5: case 0x095: // stdux, stdx
9133
9282
         if (!mode64) goto decode_failure;
9134
 
         if (dis_int_store( theInstr )) goto decode_success;
 
9283
         if (dis_int_store( theInstr, abiinfo )) goto decode_success;
9135
9284
         goto decode_failure;
9136
9285
 
9137
9286
      /* Integer Load and Store with Byte Reverse Instructions */
9147
9296
         Bool ok = dis_int_ldst_str( theInstr, &stopHere );
9148
9297
         if (!ok) goto decode_failure;
9149
9298
         if (stopHere) {
9150
 
            irbb->next     = mkSzImm(ty, nextInsnAddr());
9151
 
            irbb->jumpkind = Ijk_Boring;
 
9299
            irsb->next     = mkSzImm(ty, nextInsnAddr());
 
9300
            irsb->jumpkind = Ijk_Boring;
9152
9301
            dres.whatNext  = Dis_StopHere;
9153
9302
         }
9154
9303
         goto decode_success;
9169
9318
      /* Processor Control Instructions */
9170
9319
      case 0x200: case 0x013: case 0x153: // mcrxr, mfcr,  mfspr
9171
9320
      case 0x173: case 0x090: case 0x1D3: // mftb,  mtcrf, mtspr
9172
 
         if (dis_proc_ctl( theInstr )) goto decode_success;
 
9321
         if (dis_proc_ctl( abiinfo, theInstr )) goto decode_success;
9173
9322
         goto decode_failure;
9174
9323
 
9175
9324
      /* Cache Management Instructions */
9184
9333
//zz       case 0x136: case 0x1B6: // eciwx, ecowx
9185
9334
//zz          DIP("external control op => not implemented\n");
9186
9335
//zz          goto decode_failure;
9187
 
//zz 
9188
 
//zz       /* Trap Instructions */
9189
 
//zz       case 0x004:                         // tw
9190
 
//zz          DIP("trap op (tw) => not implemented\n");
9191
 
//zz          goto decode_failure;
9192
 
//zz       case 0x044:                         // td
9193
 
//zz          DIP("trap op (td) => not implemented\n");
9194
 
//zz          goto decode_failure;
 
9336
 
 
9337
      /* Trap Instructions */
 
9338
      case 0x004: case 0x044:             // tw,   td
 
9339
         if (dis_trap(theInstr, &dres)) goto decode_success;
 
9340
         goto decode_failure;
9195
9341
 
9196
9342
      /* Floating Point Load Instructions */
9197
9343
      case 0x217: case 0x237: case 0x257: // lfsx, lfsux, lfdx
9225
9371
      case 0x007: case 0x027: case 0x047: // lvebx, lvehx, lvewx
9226
9372
      case 0x067: case 0x167:             // lvx, lvxl
9227
9373
         if (!allow_V) goto decode_noV;
9228
 
         if (dis_av_load( theInstr )) goto decode_success;
 
9374
         if (dis_av_load( abiinfo, theInstr )) goto decode_success;
9229
9375
         goto decode_failure;
9230
9376
 
9231
9377
      /* AV Store */
9425
9571
      insn, but nevertheless be paranoid and update it again right
9426
9572
      now. */
9427
9573
   putGST( PPC_GST_CIA, mkSzImm(ty, guest_CIA_curr_instr) );
9428
 
   irbb->next     = mkSzImm(ty, guest_CIA_curr_instr);
9429
 
   irbb->jumpkind = Ijk_NoDecode;
 
9574
   irsb->next     = mkSzImm(ty, guest_CIA_curr_instr);
 
9575
   irsb->jumpkind = Ijk_NoDecode;
9430
9576
   dres.whatNext  = Dis_StopHere;
9431
9577
   dres.len       = 0;
9432
9578
   return dres;
9456
9602
/* Disassemble a single instruction into IR.  The instruction
9457
9603
   is located in host memory at &guest_code[delta]. */
9458
9604
 
9459
 
DisResult disInstr_PPC ( IRBB*        irbb_IN,
 
9605
DisResult disInstr_PPC ( IRSB*        irsb_IN,
9460
9606
                         Bool         put_IP,
9461
9607
                         Bool         (*resteerOkFn) ( void*, Addr64 ),
9462
9608
                         void*        callback_opaque,
9465
9611
                         Addr64       guest_IP,
9466
9612
                         VexArch      guest_arch,
9467
9613
                         VexArchInfo* archinfo,
 
9614
                         VexAbiInfo*  abiinfo,
9468
9615
                         Bool         host_bigendian_IN )
9469
9616
{
9470
9617
   IRType     ty;
9493
9640
 
9494
9641
   /* Set globals (see top of this file) */
9495
9642
   guest_code           = guest_code_IN;
9496
 
   irbb                 = irbb_IN;
 
9643
   irsb                 = irsb_IN;
9497
9644
   host_is_bigendian    = host_bigendian_IN;
9498
9645
 
9499
9646
   guest_CIA_curr_instr = mkSzAddr(ty, guest_IP);
9500
9647
   guest_CIA_bbstart    = mkSzAddr(ty, guest_IP - delta);
9501
9648
 
9502
9649
   dres = disInstr_PPC_WRK ( put_IP, resteerOkFn, callback_opaque,
9503
 
                             delta, archinfo );
 
9650
                             delta, archinfo, abiinfo );
9504
9651
 
9505
9652
   return dres;
9506
9653
}