mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-07-23 05:23:59 +00:00
Add missing thirdparty files
This commit is contained in:
238
thirdparty/capstone/arch/ARM/ARMDisassemblerExtension.c
vendored
Normal file
238
thirdparty/capstone/arch/ARM/ARMDisassemblerExtension.c
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
|
||||
/* Rot127 <unisono@quyllur.org>, 2022-2023 */
|
||||
|
||||
#include "ARMDisassemblerExtension.h"
|
||||
#include "ARMBaseInfo.h"
|
||||
|
||||
bool ITBlock_push_back(ARM_ITBlock *it, char v)
|
||||
{
|
||||
if (it->size >= sizeof(it->ITStates)) {
|
||||
// TODO: consider warning user.
|
||||
it->size = 0;
|
||||
}
|
||||
it->ITStates[it->size] = v;
|
||||
it->size++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true if the current instruction is in an IT block
|
||||
bool ITBlock_instrInITBlock(ARM_ITBlock *it)
|
||||
{
|
||||
return (it->size > 0);
|
||||
}
|
||||
|
||||
// Returns true if current instruction is the last instruction in an IT block
|
||||
bool ITBlock_instrLastInITBlock(ARM_ITBlock *it)
|
||||
{
|
||||
return (it->size == 1);
|
||||
}
|
||||
|
||||
// Returns the condition code for instruction in IT block
|
||||
unsigned ITBlock_getITCC(ARM_ITBlock *it)
|
||||
{
|
||||
unsigned CC = ARMCC_AL;
|
||||
|
||||
if (ITBlock_instrInITBlock(it))
|
||||
CC = it->ITStates[it->size - 1];
|
||||
|
||||
return CC;
|
||||
}
|
||||
|
||||
// Advances the IT block state to the next T or E
|
||||
void ITBlock_advanceITState(ARM_ITBlock *it)
|
||||
{
|
||||
it->size--;
|
||||
}
|
||||
|
||||
// Called when decoding an IT instruction. Sets the IT state for the following
|
||||
// instructions that for the IT block. Firstcond and Mask correspond to the
|
||||
// fields in the IT instruction encoding.
|
||||
void ITBlock_setITState(ARM_ITBlock *it, char Firstcond, char Mask)
|
||||
{
|
||||
// (3 - the number of trailing zeros) is the number of then / else.
|
||||
unsigned NumTZ = CountTrailingZeros_8(Mask);
|
||||
unsigned char CCBits = (unsigned char)(Firstcond & 0xf);
|
||||
assert(NumTZ <= 3 && "Invalid IT mask!");
|
||||
// push condition codes onto the stack the correct order for the pops
|
||||
for (unsigned Pos = NumTZ + 1; Pos <= 3; ++Pos) {
|
||||
unsigned Else = (Mask >> Pos) & 1;
|
||||
ITBlock_push_back(it, CCBits ^ Else);
|
||||
}
|
||||
ITBlock_push_back(it, CCBits);
|
||||
}
|
||||
|
||||
bool VPTBlock_push_back(ARM_VPTBlock *it, char v)
|
||||
{
|
||||
if (it->size >= sizeof(it->VPTStates)) {
|
||||
// TODO: consider warning user.
|
||||
it->size = 0;
|
||||
}
|
||||
it->VPTStates[it->size] = v;
|
||||
it->size++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VPTBlock_instrInVPTBlock(ARM_VPTBlock *VPT)
|
||||
{
|
||||
return VPT->size > 0;
|
||||
}
|
||||
|
||||
unsigned VPTBlock_getVPTPred(ARM_VPTBlock *VPT)
|
||||
{
|
||||
unsigned Pred = ARMVCC_None;
|
||||
if (VPTBlock_instrInVPTBlock(VPT))
|
||||
Pred = VPT->VPTStates[VPT->size - 1];
|
||||
return Pred;
|
||||
}
|
||||
|
||||
void VPTBlock_advanceVPTState(ARM_VPTBlock *VPT)
|
||||
{
|
||||
VPT->size--;
|
||||
}
|
||||
|
||||
void VPTBlock_setVPTState(ARM_VPTBlock *VPT, char Mask)
|
||||
{
|
||||
// (3 - the number of trailing zeros) is the number of then / else.
|
||||
unsigned NumTZ = CountTrailingZeros_8(Mask);
|
||||
assert(NumTZ <= 3 && "Invalid VPT mask!");
|
||||
// push predicates onto the stack the correct order for the pops
|
||||
for (unsigned Pos = NumTZ + 1; Pos <= 3; ++Pos) {
|
||||
bool T = ((Mask >> Pos) & 1) == 0;
|
||||
if (T)
|
||||
VPTBlock_push_back(VPT, ARMVCC_Then);
|
||||
else
|
||||
VPTBlock_push_back(VPT, ARMVCC_Else);
|
||||
}
|
||||
VPTBlock_push_back(VPT, ARMVCC_Then);
|
||||
}
|
||||
|
||||
/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
|
||||
|
||||
bool Check(DecodeStatus *Out, DecodeStatus In)
|
||||
{
|
||||
switch (In) {
|
||||
case MCDisassembler_Success:
|
||||
// Out stays the same.
|
||||
return true;
|
||||
case MCDisassembler_SoftFail:
|
||||
*Out = In;
|
||||
return true;
|
||||
case MCDisassembler_Fail:
|
||||
*Out = In;
|
||||
return false;
|
||||
default: // never reached
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Imported from ARMBaseInstrInfo.h
|
||||
//
|
||||
/// isValidCoprocessorNumber - decide whether an explicit coprocessor
|
||||
/// number is legal in generic instructions like CDP. The answer can
|
||||
/// vary with the subtarget.
|
||||
bool isValidCoprocessorNumber(MCInst *Inst, unsigned Num)
|
||||
{
|
||||
// In Armv7 and Armv8-M CP10 and CP11 clash with VFP/NEON, however, the
|
||||
// coprocessor is still valid for CDP/MCR/MRC and friends. Allowing it is
|
||||
// useful for code which is shared with older architectures which do not
|
||||
// know the new VFP/NEON mnemonics.
|
||||
|
||||
// Armv8-A disallows everything *other* than 111x (CP14 and CP15).
|
||||
if (ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops) &&
|
||||
(Num & 0xE) != 0xE)
|
||||
return false;
|
||||
|
||||
// Armv8.1-M disallows 100x (CP8,CP9) and 111x (CP14,CP15)
|
||||
// which clash with MVE.
|
||||
if (ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8_1MMainlineOps) &&
|
||||
((Num & 0xE) == 0x8 || (Num & 0xE) == 0xE))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Imported from ARMMCTargetDesc.h
|
||||
bool ARM_isVpred(arm_op_type op)
|
||||
{
|
||||
return op == ARM_OP_VPRED_R || op == ARM_OP_VPRED_N;
|
||||
}
|
||||
|
||||
// Imported from ARMBaseInstrInfo.h
|
||||
//
|
||||
// This table shows the VPT instruction variants, i.e. the different
|
||||
// mask field encodings, see also B5.6. Predication/conditional execution in
|
||||
// the ArmARM.
|
||||
bool isVPTOpcode(int Opc)
|
||||
{
|
||||
return Opc == ARM_MVE_VPTv16i8 || Opc == ARM_MVE_VPTv16u8 ||
|
||||
Opc == ARM_MVE_VPTv16s8 || Opc == ARM_MVE_VPTv8i16 ||
|
||||
Opc == ARM_MVE_VPTv8u16 || Opc == ARM_MVE_VPTv8s16 ||
|
||||
Opc == ARM_MVE_VPTv4i32 || Opc == ARM_MVE_VPTv4u32 ||
|
||||
Opc == ARM_MVE_VPTv4s32 || Opc == ARM_MVE_VPTv4f32 ||
|
||||
Opc == ARM_MVE_VPTv8f16 || Opc == ARM_MVE_VPTv16i8r ||
|
||||
Opc == ARM_MVE_VPTv16u8r || Opc == ARM_MVE_VPTv16s8r ||
|
||||
Opc == ARM_MVE_VPTv8i16r || Opc == ARM_MVE_VPTv8u16r ||
|
||||
Opc == ARM_MVE_VPTv8s16r || Opc == ARM_MVE_VPTv4i32r ||
|
||||
Opc == ARM_MVE_VPTv4u32r || Opc == ARM_MVE_VPTv4s32r ||
|
||||
Opc == ARM_MVE_VPTv4f32r || Opc == ARM_MVE_VPTv8f16r ||
|
||||
Opc == ARM_MVE_VPST;
|
||||
}
|
||||
|
||||
// Imported from ARMMCTargetDesc.cpp
|
||||
bool ARM_isCDECoproc(size_t Coproc, const MCInst *MI)
|
||||
{
|
||||
// Unfortunately we don't have ARMTargetInfo in the disassembler, so we have
|
||||
// to rely on feature bits.
|
||||
if (Coproc >= 8)
|
||||
return false;
|
||||
|
||||
return ARM_getFeatureBits(MI->csh->mode,
|
||||
ARM_FeatureCoprocCDE0 + Coproc);
|
||||
}
|
||||
|
||||
// Hacky: enable all features for disassembler
|
||||
bool ARM_getFeatureBits(unsigned int mode, unsigned int feature)
|
||||
{
|
||||
if (feature == ARM_ModeThumb) {
|
||||
if (mode & CS_MODE_THUMB)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (feature == ARM_FeatureDFB)
|
||||
return false;
|
||||
|
||||
if (feature == ARM_FeatureRAS)
|
||||
return false;
|
||||
|
||||
if (feature == ARM_FeatureMClass && (mode & CS_MODE_MCLASS) == 0)
|
||||
return false;
|
||||
|
||||
if ((feature == ARM_HasMVEIntegerOps || feature == ARM_HasMVEFloatOps ||
|
||||
feature == ARM_FeatureMVEVectorCostFactor1 ||
|
||||
feature == ARM_FeatureMVEVectorCostFactor2 ||
|
||||
feature == ARM_FeatureMVEVectorCostFactor4) &&
|
||||
(mode & CS_MODE_MCLASS) == 0)
|
||||
return false;
|
||||
|
||||
if ((feature == ARM_HasV8Ops || feature == ARM_HasV8_1MMainlineOps ||
|
||||
feature == ARM_HasV8_1aOps || feature == ARM_HasV8_2aOps ||
|
||||
feature == ARM_HasV8_3aOps || feature == ARM_HasV8_4aOps ||
|
||||
feature == ARM_HasV8_5aOps || feature == ARM_HasV8_6aOps ||
|
||||
feature == ARM_HasV8_7aOps || feature == ARM_HasV8_8aOps ||
|
||||
feature == ARM_HasV8_9aOps) &&
|
||||
(mode & CS_MODE_V8) == 0)
|
||||
return false;
|
||||
|
||||
if (feature >= ARM_FeatureCoprocCDE0 &&
|
||||
feature <= ARM_FeatureCoprocCDE7)
|
||||
// We currently have no way to detect CDE (Custom-Datapath-Extension)
|
||||
// coprocessors.
|
||||
return false;
|
||||
|
||||
// we support everything
|
||||
return true;
|
||||
}
|
Reference in New Issue
Block a user