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
107
107
Any other bytes following the 16-byte preamble are illegal and
108
108
constitute a failure in instruction decoding. This all assumes
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
183
static void* fnptr_to_fnentry( VexAbiInfo* vbi, void* f )
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]);
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]);
193
/* Simple; "& f" points directly at the code for f. */
213
217
(mode64 ? offsetof(VexGuestPPC64State, _x) : \
214
218
offsetof(VexGuestPPC32State, _x))
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)
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)
237
240
/*------------------------------------------------------------*/
392
397
/*--- ppc32/64 insn stream. ---*/
393
398
/*------------------------------------------------------------*/
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 )
398
addStmtToIRBB( irbb, st );
403
addStmtToIRSB( irsb, st );
401
406
/* Generate a new temporary of the given type. */
402
407
static IRTemp newTemp ( IRType ty )
404
409
vassert(isPlausibleIRType(ty));
405
return newIRTemp( irbb->tyenv, ty );
410
return newIRTemp( irsb->tyenv, ty );
408
413
/* Various simple conversions */
457
462
static void assign ( IRTemp dst, IRExpr* e )
459
stmt( IRStmt_Tmp(dst, e) );
464
stmt( IRStmt_WrTmp(dst, e) );
462
467
static void storeBE ( IRExpr* addr, IRExpr* data )
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) );
520
525
static IRExpr* mkOR1 ( IRExpr* arg1, IRExpr* arg2 )
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)));
528
533
static IRExpr* mkAND1 ( IRExpr* arg1, IRExpr* arg2 )
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)));
706
711
static IRExpr* mkV128from4x64S ( IRExpr* t3, IRExpr* t2,
707
712
IRExpr* t1, IRExpr* t0 )
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 )
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 ),
760
765
static IRExpr* /* :: Ity_I64 */ mk64lo32Sto64 ( IRExpr* src )
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));
766
771
static IRExpr* /* :: Ity_I64 */ mk64lo32Uto64 ( IRExpr* src )
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));
1198
1203
vpanic("addr_align(ppc)");
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) );
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).
1211
static void make_redzone_AbiHint ( HChar* who )
1216
static void make_redzone_AbiHint ( VexAbiInfo* vbi, HChar* who )
1218
Int szB = vbi->guest_stack_redzone_size;
1213
1219
if (0) vex_printf("AbiHint: %s\n", who);
1215
stmt( IRStmt_AbiHint(
1216
binop(Iop_Sub64, getIReg(1), mkU64(288)),
1223
stmt( IRStmt_AbiHint(
1224
binop(Iop_Sub64, getIReg(1), mkU64(szB)),
1228
stmt( IRStmt_AbiHint(
1229
binop(Iop_Sub32, getIReg(1), mkU32(szB)),
1256
1270
static void putCR321 ( UInt cr, IRExpr* e )
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) );
1263
1277
static void putCR0 ( UInt cr, IRExpr* e )
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) );
1368
1382
static IRExpr* getXER_SO ( void );
1369
1383
static void set_CR0 ( IRExpr* result )
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);
1374
1388
putCR321( 0, unop(Iop_64to8,
1375
1389
binop(Iop_CmpORD64S, result, mkU64(0))) );
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);
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
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);
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
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))) );
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)) );
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)) );
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)) );
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)) );
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)) );
3411
/* later: deal with special case:
3412
(msk_imm + sh_imm == 63) => SHR(63 - sh_imm) */
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)) );
3449
&& sh_imm + msk_imm == 63 && sh_imm >= 1 && sh_imm <= 63) {
3450
/* special-case the ,n,63-n form as that is just
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)) );
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)) );
3421
/* later: deal with special case:
3422
(msk_imm == sh_imm) => SHL(sh_imm) */
3424
3464
case 0x3: { // rldimi (Rotl DWord Imm, Mask Insert, PPC64 p560)
3425
3465
IRTemp rA_orig = newTemp(ty);
4265
4309
putGST( PPC_GST_LR, e_nia );
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)" );
4270
4316
if (resteerOkFn( callback_opaque, tgt )) {
4271
4317
dres->whatNext = Dis_Resteer;
4272
4318
dres->continueAt = tgt;
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);
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)" );
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);
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
4553
static Bool do_trap ( UChar TO,
4554
IRExpr* argL0, IRExpr* argR0, Addr64 cia )
4507
4556
IRTemp argL, argR;
4508
4557
IRExpr *argLe, *argRe, *cond, *tmp;
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;
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);
4521
4572
const UChar b11100 = 0x1C;
4522
4573
const UChar b00111 = 0x07;
4576
vassert( typeOfIRExpr(irsb->tyenv, argL0) == Ity_I32 );
4577
vassert( typeOfIRExpr(irsb->tyenv, argR0) == Ity_I32 );
4579
vassert( typeOfIRExpr(irsb->tyenv, argL0) == Ity_I64 );
4580
vassert( typeOfIRExpr(irsb->tyenv, argR0) == Ity_I64 );
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),
4530
4590
mode64 ? IRConst_U64(cia) : IRConst_U32((UInt)cia)
4532
4592
return True; /* unconditional trap */
4536
4596
argL = newTemp(Ity_I32);
4537
4597
argR = newTemp(Ity_I32);
4538
assign( argL, mode64 ? mkSzNarrow32(Ity_I64,argL0)
4540
assign( argR, mkU32( (UInt)argR0 ));
4543
4599
argL = newTemp(Ity_I64);
4544
4600
argR = newTemp(Ity_I64);
4545
assign( argL, argL0 );
4546
assign( argR, mkU64( argR0 ));
4603
assign( argL, argL0 );
4604
assign( argR, argR0 );
4548
4606
argLe = mkexpr(argL);
4549
4607
argRe = mkexpr(argR);
4551
4610
if (TO & 16) { // L <s R
4552
4611
tmp = binop(opAND, binop(opCMPORDS, argLe, argRe), const8);
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;
4689
static Bool dis_trap ( UInt theInstr,
4690
/*OUT*/DisResult* dres )
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;
4701
if (ifieldBIT0(theInstr) != 0)
4705
case 0x004: // tw (Trap Word, PPC64 p540)
4706
uncond = do_trap( TO,
4707
mode64 ? unop(Iop_64to32, getIReg(rA_addr))
4709
mode64 ? unop(Iop_64to32, getIReg(rB_addr))
4713
DIP("tweq r%u,r%u\n", (UInt)rA_addr, (UInt)rB_addr);
4715
DIP("tw%d r%u,r%u\n", (Int)TO, (UInt)rA_addr, (UInt)rB_addr);
4718
case 0x044: // td (Trap Doubleword, PPC64 p534)
4721
uncond = do_trap( TO, getIReg(rA_addr), getIReg(rB_addr), cia );
4723
DIP("tdeq r%u,r%u\n", (UInt)rA_addr, (UInt)rB_addr);
4725
DIP("td%d r%u,r%u\n", (Int)TO, (UInt)rA_addr, (UInt)rB_addr);
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;
4639
4757
// sc (System Call, PPC32 p504)
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 ) );
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;
4648
4773
dres->whatNext = Dis_StopHere;
5290
5415
putIReg( rD_addr, mkSzWiden32(ty, getGST( PPC_GST_VRSAVE ),
5291
5416
/* Signed */False) );
5420
DIP("mfspr r%u, SPRG3(readonly)\n", rD_addr);
5421
putIReg( rD_addr, getGST( PPC_GST_SPRG3_RO ) );
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(
5434
"ppc32g_dirtyhelper_MFSPR_268_269",
5436
(vbi, &ppc32g_dirtyhelper_MFSPR_268_269),
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);
5295
5447
vex_printf("dis_proc_ctl(ppc)(mfspr,SPR)(0x%x)\n", SPR);
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 ) );
6506
//zz IRTemp tmp = newTemp(Ity_I32);
6508
//zz if (b21to22 != 0 || b11to17 != 0 || flag_rC != 0) {
6509
//zz vex_printf("dis_fp_scr(ppc)(instr,mcrfs)\n");
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 );
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);
6659
if (b21to22 != 0 || b11to17 != 0 || flag_rC != 0) {
6660
vex_printf("dis_fp_scr(ppc)(instr,mcrfs)\n");
6663
DIP("mcrfs crf%d,crf%d\n", crfD, crfS);
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))),
6670
putGST_field( PPC_GST_CR, mkexpr(tmp), crfD );
6518
6674
case 0x046: { // mtfsb0 (Move to FPSCR Bit 0, PPC32 p478)
6519
6675
// Bit crbD of the FPSCR is cleared.
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");
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");
6638
6792
case 0x336: // dss (Data Stream Stop, AV p114)
6639
6793
if (rA_addr != 0 || rB_addr != 0) {
6740
6892
d = unsafeIRDirty_0_N (
6742
6894
"ppc32g_dirtyhelper_LVS",
6743
fnptr_to_fnentry(&ppc32g_dirtyhelper_LVS),
6895
fnptr_to_fnentry(vbi, &ppc32g_dirtyhelper_LVS),
6746
6898
d = unsafeIRDirty_0_N (
6748
6900
"ppc64g_dirtyhelper_LVS",
6749
fnptr_to_fnentry(&ppc64g_dirtyhelper_LVS),
6901
fnptr_to_fnentry(vbi, &ppc64g_dirtyhelper_LVS),
6752
6904
DIP("lvsl v%d,r%u,r%u\n", vD_addr, rA_addr, rB_addr);
6773
6925
d = unsafeIRDirty_0_N (
6775
6927
"ppc32g_dirtyhelper_LVS",
6776
fnptr_to_fnentry(&ppc32g_dirtyhelper_LVS),
6928
fnptr_to_fnentry(vbi, &ppc32g_dirtyhelper_LVS),
6779
6931
d = unsafeIRDirty_0_N (
6781
6933
"ppc64g_dirtyhelper_LVS",
6782
fnptr_to_fnentry(&ppc64g_dirtyhelper_LVS),
6934
fnptr_to_fnentry(vbi, &ppc64g_dirtyhelper_LVS),
6785
6937
DIP("lvsr v%d,r%u,r%u\n", vD_addr, rA_addr, rB_addr);
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");
6915
// STORE(vS, 16, addr_align( mkexpr(EA), 16 ));
7063
storeBE( addr_align( mkexpr(EA), 16 ), mkexpr(vS) );
6919
7067
vex_printf("dis_av_store(ppc)(opc2)\n");
8787
8936
DIP("branch-and-link-to-noredir r11\n");
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;
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");
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;
8806
8953
/* We don't know what it is. Set opc1/opc2 so decode_failure
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;
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;
8878
9026
/* Trap Instructions */
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;
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;
9137
9286
/* Integer Load and Store with Byte Reverse 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;
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;
9337
/* Trap Instructions */
9338
case 0x004: case 0x044: // tw, td
9339
if (dis_trap(theInstr, &dres)) goto decode_success;
9340
goto decode_failure;
9196
9342
/* Floating Point Load Instructions */
9197
9343
case 0x217: case 0x237: case 0x257: // lfsx, lfsux, lfdx