Add missing encodings for EmulateLDRRtRnImm (ARM insn emulation funciton).

llvm-svn: 128229
This commit is contained in:
Caroline Tice 2011-03-24 19:23:45 +00:00
parent 88903beaf5
commit 9b281e2214
1 changed files with 82 additions and 22 deletions

View File

@ -3761,19 +3761,76 @@ EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
uint32_t data; // the literal data value from memory load
bool add, index, wback;
switch (encoding) {
case eEncodingT1:
Rt = Bits32(opcode, 5, 3);
Rn = Bits32(opcode, 2, 0);
imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
// index = TRUE; add = TRUE; wback = FALSE
add = true;
index = true;
wback = false;
break;
default:
return false;
case eEncodingT1:
Rt = Bits32(opcode, 5, 3);
Rn = Bits32(opcode, 2, 0);
imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
// index = TRUE; add = TRUE; wback = FALSE
add = true;
index = true;
wback = false;
break;
case eEncodingT2:
// t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:00, 32);
Rt = Bits32 (opcode, 10, 8);
Rn = 13;
imm32 = Bits32 (opcode, 7, 0) << 2;
// index = TRUE; add = TRUE; wback = FALSE;
index = true;
add = true;
wback = false;
break;
case eEncodingT3:
// if Rn == 1111 then SEE LDR (literal);
// t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
Rt = Bits32 (opcode, 15, 12);
Rn = Bits32 (opcode, 19, 16);
imm32 = Bits32 (opcode, 11, 0);
// index = TRUE; add = TRUE; wback = FALSE;
index = true;
add = true;
wback = false;
// if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
if ((Rt == 15) && InITBlock() && !LastInITBlock())
return false;
break;
case eEncodingT4:
// if Rn == 1111 then SEE LDR (literal);
// if P == 1 && U == 1 && W == 0 then SEE LDRT;
// if Rn == 1101 && P == 0 && U == 1 && W == 1 && imm8 == 00000100 then SEE POP;
// if P == 0 && W == 0 then UNDEFINED;
if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
return false;
// t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
Rt = Bits32 (opcode, 15, 12);
Rn = Bits32 (opcode, 19, 16);
imm32 = Bits32 (opcode, 7, 0);
// index = (P == 1); add = (U == 1); wback = (W == 1);
index = BitIsSet (opcode, 10);
add = BitIsSet (opcode, 9);
wback = BitIsSet (opcode, 8);
// if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
return false;
break;
default:
return false;
}
uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success);
uint32_t base = ReadCoreReg (Rn, &success);
if (!success)
return false;
if (add)
@ -3783,13 +3840,13 @@ EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
address = (index ? offset_addr : base);
Register base_reg;
base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
if (wback)
{
EmulateInstruction::Context ctx;
ctx.type = EmulateInstruction::eContextRegisterPlusOffset;
Register dwarf_reg;
dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base));
ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
return false;
@ -3797,8 +3854,8 @@ EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
// Prepare to write to the Rt register.
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs ();
context.type = EmulateInstruction::eContextRegisterLoad;
context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
// Read memory from the address.
data = MemURead(context, address, 4, 0, &success);
@ -3821,7 +3878,7 @@ EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding)
return false;
}
else
return false;
WriteBits32Unknown (Rt);
}
return true;
}
@ -4504,7 +4561,7 @@ EmulateInstructionARM::EmulateSTRThumb (ARMEncoding encoding)
addr_t address;
// offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
uint32_t base_address = ReadCoreReg (n, &success);
if (!success)
return false;
@ -9763,8 +9820,11 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
{ 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
{ 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
{ 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
{ 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
// Thumb2 PC-relative load into register
{ 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
{ 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
{ 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
{ 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
// Thumb2 PC-relative load into register
{ 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
{ 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
{ 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },