/* Produce the name of an integer register, for printing purposes.
reg is a number in the range 0 .. 15 that has been generated from a
3-bit reg-field number and a REX extension bit. irregular denotes
- the case where sz==1 and no REX byte is present. */
+ the case where sz==1 and no REX byte is present and where the denoted
+ sub-register is bits 15:8 of the containing 64-bit register. */
static
const HChar* nameIReg ( Int sz, UInt reg, Bool irregular )
static const HChar* ireg8_names[16]
= { "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
"%r8b", "%r9b", "%r10b","%r11b","%r12b","%r13b","%r14b","%r15b" };
- static const HChar* ireg8_irregular[8]
- = { "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh" };
+ static const HChar* ireg8_irregular[4]
+ = { "%ah", "%ch", "%dh", "%bh" };
vassert(reg < 16);
if (sz == 1) {
if (irregular)
- vassert(reg < 8);
+ vassert(reg >= 4 && reg < 8);
} else {
vassert(irregular == False);
}
case 4: return ireg32_names[reg];
case 2: return ireg16_names[reg];
case 1: if (irregular) {
- return ireg8_irregular[reg];
+ vassert(reg >= 4 && reg < 8);
+ return ireg8_irregular[reg - 4];
} else {
return ireg8_names[reg];
}
vassert(reg < 16);
if (sz == 1) {
if (irregular)
- vassert(reg < 8);
+ vassert(reg >= 4 && reg < 8);
} else {
vassert(irregular == False);
}
static IRExpr* getIRegCL ( void )
{
vassert(host_endness == VexEndnessLE);
- return IRExpr_Get( OFFB_RCX, Ity_I8 );
+ return unop(Iop_64to8, IRExpr_Get( OFFB_RCX, Ity_I64 ));
}
{
vassert(host_endness == VexEndnessLE);
switch (sz) {
- case 1: return IRExpr_Get( OFFB_RAX, Ity_I8 );
- case 2: return IRExpr_Get( OFFB_RAX, Ity_I16 );
+ case 1: return unop(Iop_64to8, IRExpr_Get( OFFB_RAX, Ity_I64 ));
+ case 2: return unop(Iop_64to16, IRExpr_Get( OFFB_RAX, Ity_I64 ));
case 4: return unop(Iop_64to32, IRExpr_Get( OFFB_RAX, Ity_I64 ));
case 8: return IRExpr_Get( OFFB_RAX, Ity_I64 );
default: vpanic("getIRegRAX(amd64)");
{
vassert(host_endness == VexEndnessLE);
switch (sz) {
- case 1: return IRExpr_Get( OFFB_RDX, Ity_I8 );
- case 2: return IRExpr_Get( OFFB_RDX, Ity_I16 );
+ case 1: return unop(Iop_64to8, IRExpr_Get( OFFB_RDX, Ity_I64 ));
+ case 2: return unop(Iop_64to16, IRExpr_Get( OFFB_RDX, Ity_I64 ));
case 4: return unop(Iop_64to32, IRExpr_Get( OFFB_RDX, Ity_I64 ));
case 8: return IRExpr_Get( OFFB_RDX, Ity_I64 );
default: vpanic("getIRegRDX(amd64)");
static IRExpr* getIReg16 ( UInt regno )
{
vassert(host_endness == VexEndnessLE);
- return IRExpr_Get( integerGuestReg64Offset(regno),
- Ity_I16 );
+ return unop(Iop_64to16,
+ IRExpr_Get( integerGuestReg64Offset(regno),
+ Ity_I64 ));
}
static void putIReg16 ( UInt regno, IRExpr* e )
{
vassert(lo3bits < 8);
vassert(IS_VALID_PFX(pfx));
- vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1);
- if (sz == 4) {
- sz = 8;
- return unop(Iop_64to32,
- IRExpr_Get(
- offsetIReg( sz, lo3bits | (getRexB(pfx) << 3),
- False/*!irregular*/ ),
- szToITy(sz)
- )
- );
- } else {
- return IRExpr_Get(
- offsetIReg( sz, lo3bits | (getRexB(pfx) << 3),
- toBool(sz==1 && !haveREX(pfx)) ),
- szToITy(sz)
- );
+ UInt regNo = (getRexB(pfx) << 3) | lo3bits;
+ switch (sz) {
+ case 8: {
+ return IRExpr_Get(
+ offsetIReg( 8, regNo, False/*!irregular*/ ),
+ Ity_I64
+ );
+ }
+ case 4: {
+ return unop(Iop_64to32,
+ IRExpr_Get(
+ offsetIReg( 8, regNo, False/*!irregular*/ ),
+ Ity_I64
+ ));
+ }
+ case 2: {
+ return unop(Iop_64to16,
+ IRExpr_Get(
+ offsetIReg( 8, regNo, False/*!irregular*/ ),
+ Ity_I64
+ ));
+ }
+ case 1: {
+ Bool irregular = !haveREX(pfx) && regNo >= 4 && regNo < 8;
+ if (irregular) {
+ return IRExpr_Get(
+ offsetIReg( 1, regNo, True/*irregular*/ ),
+ Ity_I8
+ );
+ } else {
+ return unop(Iop_64to8,
+ IRExpr_Get(
+ offsetIReg( 8, regNo, False/*!irregular*/ ),
+ Ity_I64
+ ));
+ }
+ }
+ default: {
+ vpanic("getIRegRexB");
+ }
}
}
vassert(IS_VALID_PFX(pfx));
vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1);
vassert(typeOfIRExpr(irsb->tyenv, e) == szToITy(sz));
+ Bool irregular = sz == 1 && !haveREX(pfx) && lo3bits >= 4 && lo3bits < 8;
stmt( IRStmt_Put(
- offsetIReg( sz, lo3bits | (getRexB(pfx) << 3),
- toBool(sz==1 && !haveREX(pfx)) ),
+ offsetIReg( sz, lo3bits | (getRexB(pfx) << 3), irregular ),
sz==4 ? unop(Iop_32Uto64,e) : e
));
}
vassert(IS_VALID_PFX(pfx));
vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1);
reg = gregOfRexRM( pfx, mod_reg_rm );
- return offsetIReg( sz, reg, toBool(sz == 1 && !haveREX(pfx)) );
+ Bool irregular = sz == 1 && !haveREX(pfx) && reg >= 4 && reg < 8;
+ return offsetIReg( sz, reg, irregular );
}
static
IRExpr* getIRegG ( Int sz, Prefix pfx, UChar mod_reg_rm )
{
- if (sz == 4) {
- sz = 8;
- return unop(Iop_64to32,
- IRExpr_Get( offsetIRegG( sz, pfx, mod_reg_rm ),
- szToITy(sz) ));
- } else {
- return IRExpr_Get( offsetIRegG( sz, pfx, mod_reg_rm ),
- szToITy(sz) );
+ switch (sz) {
+ case 8: {
+ return IRExpr_Get( offsetIRegG( 8, pfx, mod_reg_rm ), Ity_I64 );
+ }
+ case 4: {
+ return unop(Iop_64to32,
+ IRExpr_Get( offsetIRegG( 8, pfx, mod_reg_rm ), Ity_I64 ));
+ }
+ case 2: {
+ return unop(Iop_64to16,
+ IRExpr_Get( offsetIRegG( 8, pfx, mod_reg_rm ), Ity_I64 ));
+ }
+ case 1: {
+ UInt regNo = gregOfRexRM( pfx, mod_reg_rm );
+ Bool irregular = !haveREX(pfx) && regNo >= 4 && regNo < 8;
+ if (irregular) {
+ return IRExpr_Get( offsetIRegG( 1, pfx, mod_reg_rm ), Ity_I8 );
+ } else {
+ return unop(Iop_64to8,
+ IRExpr_Get( offsetIRegG( 8, pfx, mod_reg_rm ),
+ Ity_I64 ));
+ }
+ }
+ default: {
+ vpanic("getIRegG");
+ }
}
}
static
const HChar* nameIRegG ( Int sz, Prefix pfx, UChar mod_reg_rm )
{
- return nameIReg( sz, gregOfRexRM(pfx,mod_reg_rm),
- toBool(sz==1 && !haveREX(pfx)) );
+ UInt regNo = gregOfRexRM( pfx, mod_reg_rm );
+ Bool irregular = sz == 1 && !haveREX(pfx) && regNo >= 4 && regNo < 8;
+ return nameIReg( sz, gregOfRexRM(pfx,mod_reg_rm), irregular );
}
static
IRExpr* getIRegV ( Int sz, Prefix pfx )
{
+ vassert(sz == 8 || sz == 4);
if (sz == 4) {
- sz = 8;
return unop(Iop_64to32,
- IRExpr_Get( offsetIReg( sz, getVexNvvvv(pfx), False ),
- szToITy(sz) ));
+ IRExpr_Get( offsetIReg( 8, getVexNvvvv(pfx), False ),
+ Ity_I64 ));
+ } else if (sz == 2) {
+ return unop(Iop_64to16,
+ IRExpr_Get( offsetIReg( 8, getVexNvvvv(pfx), False ),
+ Ity_I64 ));
} else {
return IRExpr_Get( offsetIReg( sz, getVexNvvvv(pfx), False ),
szToITy(sz) );
static
void putIRegV ( Int sz, Prefix pfx, IRExpr* e )
{
+ vassert(sz == 8 || sz == 4);
vassert(typeOfIRExpr(irsb->tyenv,e) == szToITy(sz));
if (sz == 4) {
e = unop(Iop_32Uto64,e);
static
const HChar* nameIRegV ( Int sz, Prefix pfx )
{
+ vassert(sz == 8 || sz == 4);
return nameIReg( sz, getVexNvvvv(pfx), False );
}
vassert(IS_VALID_PFX(pfx));
vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1);
reg = eregOfRexRM( pfx, mod_reg_rm );
- return offsetIReg( sz, reg, toBool(sz == 1 && !haveREX(pfx)) );
+ Bool irregular = sz == 1 && !haveREX(pfx) && (reg >= 4 && reg < 8);
+ return offsetIReg( sz, reg, irregular );
}
-static
+static
IRExpr* getIRegE ( Int sz, Prefix pfx, UChar mod_reg_rm )
{
- if (sz == 4) {
- sz = 8;
- return unop(Iop_64to32,
- IRExpr_Get( offsetIRegE( sz, pfx, mod_reg_rm ),
- szToITy(sz) ));
- } else {
- return IRExpr_Get( offsetIRegE( sz, pfx, mod_reg_rm ),
- szToITy(sz) );
+ switch (sz) {
+ case 8: {
+ return IRExpr_Get( offsetIRegE( 8, pfx, mod_reg_rm ), Ity_I64 );
+ }
+ case 4: {
+ return unop(Iop_64to32,
+ IRExpr_Get( offsetIRegE( 8, pfx, mod_reg_rm ), Ity_I64 ));
+ }
+ case 2: {
+ return unop(Iop_64to16,
+ IRExpr_Get( offsetIRegE( 8, pfx, mod_reg_rm ), Ity_I64 ));
+ }
+ case 1: {
+ UInt regNo = eregOfRexRM( pfx, mod_reg_rm );
+ Bool irregular = !haveREX(pfx) && regNo >= 4 && regNo < 8;
+ if (irregular) {
+ return IRExpr_Get( offsetIRegE( 1, pfx, mod_reg_rm ), Ity_I8 );
+ } else {
+ return unop(Iop_64to8,
+ IRExpr_Get( offsetIRegE( 8, pfx, mod_reg_rm ),
+ Ity_I64 ));
+ }
+ }
+ default: {
+ vpanic("getIRegE");
+ }
}
}
static
const HChar* nameIRegE ( Int sz, Prefix pfx, UChar mod_reg_rm )
{
- return nameIReg( sz, eregOfRexRM(pfx,mod_reg_rm),
- toBool(sz==1 && !haveREX(pfx)) );
+ UInt regNo = eregOfRexRM( pfx, mod_reg_rm );
+ Bool irregular = sz == 1 && !haveREX(pfx) && regNo >= 4 && regNo < 8;
+ return nameIReg( sz, eregOfRexRM(pfx,mod_reg_rm), irregular );
}