Add code to emulate UXTH Arm instruction.

llvm-svn: 126954
This commit is contained in:
Caroline Tice 2011-03-03 18:48:58 +00:00
parent 9c35f321c6
commit c8d0d3ae0b
1 changed files with 87 additions and 2 deletions

View File

@ -7667,6 +7667,88 @@ EmulateInstructionARM::EmulateUXTB (ARMEncoding encoding)
return true;
}
// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
// register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
bool
EmulateInstructionARM::EmulateUXTH (ARMEncoding encoding)
{
#if 0
if ConditionPassed() then
EncodingSpecificOperations();
rotated = ROR(R[m], rotation);
R[d] = ZeroExtend(rotated<15:0>, 32);
#endif
bool success = false;
const uint32_t opcode = OpcodeAsUnsigned (&success);
if (!success)
return false;
if (ConditionPassed ())
{
uint32_t d;
uint32_t m;
uint32_t rotation;
switch (encoding)
{
case eEncodingT1:
// d = UInt(Rd); m = UInt(Rm); rotation = 0;
d = Bits32 (opcode, 2, 0);
m = Bits32 (opcode, 5, 3);
rotation = 0;
break;
case eEncodingT2:
// d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:000);
d = Bits32 (opcode, 11, 8);
m = Bits32 (opcode, 3, 0);
rotation = Bits32 (opcode, 5, 4) << 3;
// if BadReg(d) || BadReg(m) then UNPREDICTABLE;
if (BadReg (d) || BadReg (m))
return false;
break;
case eEncodingA1:
// d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:000);
d = Bits32 (opcode, 15, 12);
m = Bits32 (opcode, 3, 0);
rotation = Bits32 (opcode, 11, 10) << 3;
// if d == 15 || m == 15 then UNPREDICTABLE;
if ((d == 15) || (m == 15))
return false;
break;
default:
return false;
}
uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
if (!success)
return false;
// rotated = ROR(R[m], rotation);
uint64_t rotated = ROR (Rm, rotation);
// R[d] = ZeroExtend(rotated<15:0>, 32);
Register source_reg;
source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
EmulateInstruction::Context context;
context.type = eContextRegisterLoad;
context.SetRegister (source_reg);
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
return false;
}
return true;
}
// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
// and writes the result to the destination register. It can optionally update the condition flags based on
// the result.
@ -9064,7 +9146,8 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
//----------------------------------------------------------------------
{ 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
{ 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
{ 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }
{ 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
{ 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }
};
static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
@ -9343,7 +9426,9 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
{ 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
{ 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
{ 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
{ 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }
{ 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
{ 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
{ 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }
};