forked from OSchip/llvm-project
Add two convenience functions: DecodeImmShiftThumb() and DecodeImmShiftARM() to ARMUtils.h.
Use them within EmulateInstructionARM.cpp to save repetitive typing. llvm-svn: 126247
This commit is contained in:
parent
b6ed369e77
commit
5f88bcc16a
|
@ -829,7 +829,7 @@ EmulateInstructionARM::EmulateMVNReg (ARMEncoding encoding)
|
|||
Rd = Bits32(opcode, 11, 8);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
// if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
|
||||
if ((BadReg(Rd) || BadReg(Rm)))
|
||||
return false;
|
||||
|
@ -837,7 +837,7 @@ EmulateInstructionARM::EmulateMVNReg (ARMEncoding encoding)
|
|||
Rd = Bits32(opcode, 15, 12);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -2128,7 +2128,7 @@ EmulateInstructionARM::EmulateADDReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -2245,7 +2245,7 @@ EmulateInstructionARM::EmulateCMNReg (ARMEncoding encoding)
|
|||
case eEncodingT2:
|
||||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
// if n == 15 || BadReg(m) then UNPREDICTABLE;
|
||||
if (Rn == 15 || BadReg(Rm))
|
||||
return false;
|
||||
|
@ -2253,7 +2253,7 @@ EmulateInstructionARM::EmulateCMNReg (ARMEncoding encoding)
|
|||
case eEncodingA1:
|
||||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -2380,7 +2380,7 @@ EmulateInstructionARM::EmulateCMPReg (ARMEncoding encoding)
|
|||
case eEncodingA1:
|
||||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -4588,7 +4588,7 @@ EmulateInstructionARM::EmulateADCReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
|
||||
return false;
|
||||
break;
|
||||
|
@ -4597,7 +4597,7 @@ EmulateInstructionARM::EmulateADCReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
// TODO: Emulate SUBS PC, LR and related instructions.
|
||||
if (Rd == 15 && setflags)
|
||||
return false;
|
||||
|
@ -4752,7 +4752,7 @@ EmulateInstructionARM::EmulateANDReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
// if Rd == '1111' && S == '1' then SEE TST (register);
|
||||
if (Rd == 15 && setflags)
|
||||
return EmulateTSTReg(eEncodingT2);
|
||||
|
@ -4764,7 +4764,7 @@ EmulateInstructionARM::EmulateANDReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
// TODO: Emulate SUBS PC, LR and related instructions.
|
||||
if (Rd == 15 && setflags)
|
||||
return false;
|
||||
|
@ -5651,8 +5651,8 @@ EmulateInstructionARM::EmulateEORReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
// if Rd == ‘1111’ && S == ‘1’ then SEE TEQ (register);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
// if Rd == '1111' && S == '1' then SEE TEQ (register);
|
||||
if (Rd == 15 && setflags)
|
||||
return EmulateTEQReg(eEncodingT1);
|
||||
if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
|
||||
|
@ -5663,7 +5663,7 @@ EmulateInstructionARM::EmulateEORReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
// if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
|
||||
// TODO: Emulate SUBS PC, LR and related instructions.
|
||||
if (Rd == 15 && setflags)
|
||||
|
@ -5820,8 +5820,8 @@ EmulateInstructionARM::EmulateORRReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
// if Rn == ‘1111’ then SEE MOV (register);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
// if Rn == '1111' then SEE MOV (register);
|
||||
if (Rn == 15)
|
||||
return EmulateMOVRdRm(eEncodingT3);
|
||||
if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
|
||||
|
@ -5832,7 +5832,7 @@ EmulateInstructionARM::EmulateORRReg (ARMEncoding encoding)
|
|||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
setflags = BitIsSet(opcode, 20);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
// TODO: Emulate SUBS PC, LR and related instructions.
|
||||
if (Rd == 15 && setflags)
|
||||
return false;
|
||||
|
@ -5957,14 +5957,14 @@ EmulateInstructionARM::EmulateTEQReg (ARMEncoding encoding)
|
|||
case eEncodingT1:
|
||||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
if (BadReg(Rn) || BadReg(Rm))
|
||||
return false;
|
||||
break;
|
||||
case eEncodingA1:
|
||||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -6090,14 +6090,14 @@ EmulateInstructionARM::EmulateTSTReg (ARMEncoding encoding)
|
|||
case eEncodingT2:
|
||||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
shift_n = DecodeImmShiftThumb(opcode, shift_t);
|
||||
if (BadReg(Rn) || BadReg(Rm))
|
||||
return false;
|
||||
break;
|
||||
case eEncodingA1:
|
||||
Rn = Bits32(opcode, 19, 16);
|
||||
Rm = Bits32(opcode, 3, 0);
|
||||
shift_n = DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
shift_n = DecodeImmShiftARM(opcode, shift_t);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -51,6 +51,20 @@ static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5,
|
|||
}
|
||||
}
|
||||
|
||||
// A8.6.35 CMP (register) -- Encoding T3
|
||||
// Convenience function.
|
||||
static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t)
|
||||
{
|
||||
return DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
|
||||
}
|
||||
|
||||
// A8.6.35 CMP (register) -- Encoding A1
|
||||
// Convenience function.
|
||||
static inline uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t)
|
||||
{
|
||||
return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
|
||||
}
|
||||
|
||||
static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, const uint32_t imm5)
|
||||
{
|
||||
ARM_ShifterType dont_care;
|
||||
|
@ -216,11 +230,11 @@ static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
|
|||
}
|
||||
|
||||
// (imm32, carry_out) = ARMExpandImm_C(imm12, carry_in)
|
||||
static inline uint32_t ARMExpandImm_C(uint32_t val, uint32_t carry_in, uint32_t &carry_out)
|
||||
static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
|
||||
{
|
||||
uint32_t imm32; // the expanded result
|
||||
uint32_t imm = bits(val, 7, 0); // immediate value
|
||||
uint32_t amt = 2 * bits(val, 11, 8); // rotate amount
|
||||
uint32_t imm32; // the expanded result
|
||||
uint32_t imm = bits(opcode, 7, 0); // immediate value
|
||||
uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount
|
||||
if (amt == 0)
|
||||
{
|
||||
imm32 = imm;
|
||||
|
@ -234,21 +248,21 @@ static inline uint32_t ARMExpandImm_C(uint32_t val, uint32_t carry_in, uint32_t
|
|||
return imm32;
|
||||
}
|
||||
|
||||
static inline uint32_t ARMExpandImm(uint32_t val)
|
||||
static inline uint32_t ARMExpandImm(uint32_t opcode)
|
||||
{
|
||||
// 'carry_in' argument to following function call does not affect the imm32 result.
|
||||
uint32_t carry_in = 0;
|
||||
uint32_t carry_out;
|
||||
return ARMExpandImm_C(val, carry_in, carry_out);
|
||||
return ARMExpandImm_C(opcode, carry_in, carry_out);
|
||||
}
|
||||
|
||||
// (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in)
|
||||
static inline uint32_t ThumbExpandImm_C(uint32_t val, uint32_t carry_in, uint32_t &carry_out)
|
||||
static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
|
||||
{
|
||||
uint32_t imm32; // the expaned result
|
||||
const uint32_t i = bit(val, 26);
|
||||
const uint32_t imm3 = bits(val, 14, 12);
|
||||
const uint32_t abcdefgh = bits(val, 7, 0);
|
||||
const uint32_t i = bit(opcode, 26);
|
||||
const uint32_t imm3 = bits(opcode, 14, 12);
|
||||
const uint32_t abcdefgh = bits(opcode, 7, 0);
|
||||
const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
|
||||
|
||||
if (bits(imm12, 11, 10) == 0)
|
||||
|
@ -281,28 +295,28 @@ static inline uint32_t ThumbExpandImm_C(uint32_t val, uint32_t carry_in, uint32_
|
|||
return imm32;
|
||||
}
|
||||
|
||||
static inline uint32_t ThumbExpandImm(uint32_t val)
|
||||
static inline uint32_t ThumbExpandImm(uint32_t opcode)
|
||||
{
|
||||
// 'carry_in' argument to following function call does not affect the imm32 result.
|
||||
uint32_t carry_in = 0;
|
||||
uint32_t carry_out;
|
||||
return ThumbExpandImm_C(val, carry_in, carry_out);
|
||||
return ThumbExpandImm_C(opcode, carry_in, carry_out);
|
||||
}
|
||||
|
||||
// imm32 = ZeroExtend(i:imm3:imm8, 32)
|
||||
static inline uint32_t ThumbImm12(uint32_t val)
|
||||
static inline uint32_t ThumbImm12(uint32_t opcode)
|
||||
{
|
||||
const uint32_t i = bit(val, 26);
|
||||
const uint32_t imm3 = bits(val, 14, 12);
|
||||
const uint32_t imm8 = bits(val, 7, 0);
|
||||
const uint32_t i = bit(opcode, 26);
|
||||
const uint32_t imm3 = bits(opcode, 14, 12);
|
||||
const uint32_t imm8 = bits(opcode, 7, 0);
|
||||
const uint32_t imm12 = i << 11 | imm3 << 8 | imm8;
|
||||
return imm12;
|
||||
}
|
||||
|
||||
// imm32 = ZeroExtend(imm7:'00', 32)
|
||||
static inline uint32_t ThumbImmScaled(uint32_t val)
|
||||
static inline uint32_t ThumbImmScaled(uint32_t opcode)
|
||||
{
|
||||
const uint32_t imm7 = bits(val, 6, 0);
|
||||
const uint32_t imm7 = bits(opcode, 6, 0);
|
||||
return imm7 * 4;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue