mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
factor out shared functionality into base class
This commit is contained in:
@@ -30,6 +30,13 @@ class AArch64ArchBase : public virtual ArchBase {
|
||||
llvm::Triple Triple(void) const override;
|
||||
|
||||
|
||||
// Align/Minimum/Maximum number of bytes in an instruction.
|
||||
uint64_t MinInstructionAlign(const DecodingContext &) const override;
|
||||
uint64_t MinInstructionSize(const DecodingContext &) const override;
|
||||
uint64_t MaxInstructionSize(const DecodingContext &,
|
||||
bool permit_fuse_idioms) const override;
|
||||
|
||||
|
||||
void PopulateRegisterTable(void) const override;
|
||||
// Populate a just-initialized lifted function function with architecture-
|
||||
// specific variables.
|
||||
|
||||
+4
-414
@@ -31,6 +31,8 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "remill/Arch/AArch64/AArch64Base.h"
|
||||
|
||||
#define REMILL_AARCH_STRICT_REGNUM
|
||||
|
||||
#include <remill/Arch/ArchBase.h>
|
||||
@@ -106,42 +108,17 @@ Instruction::Category InstCategory(const aarch64::InstData &inst) {
|
||||
}
|
||||
}
|
||||
|
||||
class AArch64Arch final : public DefaultContextAndLifter {
|
||||
class AArch64Arch final : public AArch64ArchBase, DefaultContextAndLifter {
|
||||
public:
|
||||
AArch64Arch(llvm::LLVMContext *context_, OSName os_name_,
|
||||
ArchName arch_name_);
|
||||
|
||||
virtual ~AArch64Arch(void);
|
||||
|
||||
// Returns the name of the stack pointer register.
|
||||
std::string_view StackPointerRegisterName(void) const final;
|
||||
|
||||
// Returns the name of the program counter register.
|
||||
std::string_view ProgramCounterRegisterName(void) const final;
|
||||
|
||||
// Decode an instruction.
|
||||
bool ArchDecodeInstruction(uint64_t address, std::string_view instr_bytes,
|
||||
Instruction &inst) const final;
|
||||
|
||||
// Align/Minimum/Maximum number of bytes in an instruction.
|
||||
uint64_t MinInstructionAlign(const DecodingContext &) const final;
|
||||
uint64_t MinInstructionSize(const DecodingContext &) const final;
|
||||
uint64_t MaxInstructionSize(const DecodingContext &,
|
||||
bool permit_fuse_idioms) const final;
|
||||
|
||||
llvm::Triple Triple(void) const final;
|
||||
llvm::DataLayout DataLayout(void) const final;
|
||||
|
||||
// Default calling convention for this architecture.
|
||||
llvm::CallingConv::ID DefaultCallingConv(void) const final;
|
||||
|
||||
// Populate the table of register information.
|
||||
void PopulateRegisterTable(void) const final;
|
||||
|
||||
// Populate a just-initialized lifted function function with architecture-
|
||||
// specific variables.
|
||||
void FinishLiftedFunctionInitialization(llvm::Module *module,
|
||||
llvm::Function *bb_func) const final;
|
||||
|
||||
private:
|
||||
AArch64Arch(void) = delete;
|
||||
@@ -150,389 +127,11 @@ class AArch64Arch final : public DefaultContextAndLifter {
|
||||
AArch64Arch::AArch64Arch(llvm::LLVMContext *context_, OSName os_name_,
|
||||
ArchName arch_name_)
|
||||
: ArchBase(context_, os_name_, arch_name_),
|
||||
AArch64ArchBase(context_, os_name_, arch_name_),
|
||||
DefaultContextAndLifter(context_, os_name_, arch_name_) {}
|
||||
|
||||
AArch64Arch::~AArch64Arch(void) {}
|
||||
|
||||
// Default calling convention for this architecture.
|
||||
llvm::CallingConv::ID AArch64Arch::DefaultCallingConv(void) const {
|
||||
return llvm::CallingConv::C;
|
||||
}
|
||||
|
||||
// Populate the table of register information.
|
||||
void AArch64Arch::PopulateRegisterTable(void) const {
|
||||
|
||||
reg_by_offset.resize(sizeof(AArch64State));
|
||||
|
||||
#define OFFSET_OF(type, access) \
|
||||
(reinterpret_cast<uintptr_t>(&reinterpret_cast<const volatile char &>( \
|
||||
static_cast<type *>(nullptr)->access)))
|
||||
|
||||
#define REG(name, access, type) \
|
||||
AddRegister(#name, type, OFFSET_OF(AArch64State, access), nullptr)
|
||||
|
||||
#define SUB_REG(name, access, type, parent_reg_name) \
|
||||
AddRegister(#name, type, OFFSET_OF(AArch64State, access), #parent_reg_name)
|
||||
|
||||
auto u8 = llvm::Type::getInt8Ty(*context);
|
||||
auto u16 = llvm::Type::getInt16Ty(*context);
|
||||
auto u32 = llvm::Type::getInt32Ty(*context);
|
||||
auto u64 = llvm::Type::getInt64Ty(*context);
|
||||
auto u128 = llvm::Type::getInt128Ty(*context);
|
||||
|
||||
auto v128u8 = llvm::ArrayType::get(u8, 128u / 8u);
|
||||
auto v128u16 = llvm::ArrayType::get(u16, 128u / 16u);
|
||||
auto v128u32 = llvm::ArrayType::get(u32, 128u / 32u);
|
||||
auto v128u64 = llvm::ArrayType::get(u64, 128u / 64u);
|
||||
auto v128u128 = llvm::ArrayType::get(u128, 128u / 128u);
|
||||
|
||||
REG(X0, gpr.x0.qword, u64);
|
||||
REG(X1, gpr.x1.qword, u64);
|
||||
REG(X2, gpr.x2.qword, u64);
|
||||
REG(X3, gpr.x3.qword, u64);
|
||||
REG(X4, gpr.x4.qword, u64);
|
||||
REG(X5, gpr.x5.qword, u64);
|
||||
REG(X6, gpr.x6.qword, u64);
|
||||
REG(X7, gpr.x7.qword, u64);
|
||||
REG(X8, gpr.x8.qword, u64);
|
||||
REG(X9, gpr.x9.qword, u64);
|
||||
REG(X10, gpr.x10.qword, u64);
|
||||
REG(X11, gpr.x11.qword, u64);
|
||||
REG(X12, gpr.x12.qword, u64);
|
||||
REG(X13, gpr.x13.qword, u64);
|
||||
REG(X14, gpr.x14.qword, u64);
|
||||
REG(X15, gpr.x15.qword, u64);
|
||||
REG(X16, gpr.x16.qword, u64);
|
||||
REG(X17, gpr.x17.qword, u64);
|
||||
REG(X18, gpr.x18.qword, u64);
|
||||
REG(X19, gpr.x19.qword, u64);
|
||||
REG(X20, gpr.x20.qword, u64);
|
||||
REG(X21, gpr.x21.qword, u64);
|
||||
REG(X22, gpr.x22.qword, u64);
|
||||
REG(X23, gpr.x23.qword, u64);
|
||||
REG(X24, gpr.x24.qword, u64);
|
||||
REG(X25, gpr.x25.qword, u64);
|
||||
REG(X26, gpr.x26.qword, u64);
|
||||
REG(X27, gpr.x27.qword, u64);
|
||||
REG(X28, gpr.x28.qword, u64);
|
||||
REG(X29, gpr.x29.qword, u64);
|
||||
REG(X30, gpr.x30.qword, u64);
|
||||
|
||||
SUB_REG(W0, gpr.x0.dword, u32, X0);
|
||||
SUB_REG(W1, gpr.x1.dword, u32, X1);
|
||||
SUB_REG(W2, gpr.x2.dword, u32, X2);
|
||||
SUB_REG(W3, gpr.x3.dword, u32, X3);
|
||||
SUB_REG(W4, gpr.x4.dword, u32, X4);
|
||||
SUB_REG(W5, gpr.x5.dword, u32, X5);
|
||||
SUB_REG(W6, gpr.x6.dword, u32, X6);
|
||||
SUB_REG(W7, gpr.x7.dword, u32, X7);
|
||||
SUB_REG(W8, gpr.x8.dword, u32, X8);
|
||||
SUB_REG(W9, gpr.x9.dword, u32, X9);
|
||||
SUB_REG(W10, gpr.x10.dword, u32, X10);
|
||||
SUB_REG(W11, gpr.x11.dword, u32, X11);
|
||||
SUB_REG(W12, gpr.x12.dword, u32, X12);
|
||||
SUB_REG(W13, gpr.x13.dword, u32, X13);
|
||||
SUB_REG(W14, gpr.x14.dword, u32, X14);
|
||||
SUB_REG(W15, gpr.x15.dword, u32, X15);
|
||||
SUB_REG(W16, gpr.x16.dword, u32, X16);
|
||||
SUB_REG(W17, gpr.x17.dword, u32, X17);
|
||||
SUB_REG(W18, gpr.x18.dword, u32, X18);
|
||||
SUB_REG(W19, gpr.x19.dword, u32, X19);
|
||||
SUB_REG(W20, gpr.x20.dword, u32, X20);
|
||||
SUB_REG(W21, gpr.x21.dword, u32, X21);
|
||||
SUB_REG(W22, gpr.x22.dword, u32, X22);
|
||||
SUB_REG(W23, gpr.x23.dword, u32, X23);
|
||||
SUB_REG(W24, gpr.x24.dword, u32, X24);
|
||||
SUB_REG(W25, gpr.x25.dword, u32, X25);
|
||||
SUB_REG(W26, gpr.x26.dword, u32, X26);
|
||||
SUB_REG(W27, gpr.x27.dword, u32, X27);
|
||||
SUB_REG(W28, gpr.x28.dword, u32, X28);
|
||||
SUB_REG(W29, gpr.x29.dword, u32, X29);
|
||||
SUB_REG(W30, gpr.x30.dword, u32, X30);
|
||||
|
||||
REG(PC, gpr.pc.qword, u64);
|
||||
SUB_REG(WPC, gpr.pc.dword, u32, PC);
|
||||
|
||||
REG(SP, gpr.sp.qword, u64);
|
||||
SUB_REG(WSP, gpr.sp.dword, u32, SP);
|
||||
|
||||
SUB_REG(LP, gpr.x30.qword, u64, X30);
|
||||
SUB_REG(WLP, gpr.x30.dword, u32, LP);
|
||||
|
||||
REG(V0, simd.v[0].bytes.elems[0], v128u8);
|
||||
REG(V1, simd.v[1].bytes.elems[0], v128u8);
|
||||
REG(V2, simd.v[2].bytes.elems[0], v128u8);
|
||||
REG(V3, simd.v[3].bytes.elems[0], v128u8);
|
||||
REG(V4, simd.v[4].bytes.elems[0], v128u8);
|
||||
REG(V5, simd.v[5].bytes.elems[0], v128u8);
|
||||
REG(V6, simd.v[6].bytes.elems[0], v128u8);
|
||||
REG(V7, simd.v[7].bytes.elems[0], v128u8);
|
||||
REG(V8, simd.v[8].bytes.elems[0], v128u8);
|
||||
REG(V9, simd.v[9].bytes.elems[0], v128u8);
|
||||
REG(V10, simd.v[10].bytes.elems[0], v128u8);
|
||||
REG(V11, simd.v[11].bytes.elems[0], v128u8);
|
||||
REG(V12, simd.v[12].bytes.elems[0], v128u8);
|
||||
REG(V13, simd.v[13].bytes.elems[0], v128u8);
|
||||
REG(V14, simd.v[14].bytes.elems[0], v128u8);
|
||||
REG(V15, simd.v[15].bytes.elems[0], v128u8);
|
||||
REG(V16, simd.v[16].bytes.elems[0], v128u8);
|
||||
REG(V17, simd.v[17].bytes.elems[0], v128u8);
|
||||
REG(V18, simd.v[18].bytes.elems[0], v128u8);
|
||||
REG(V19, simd.v[19].bytes.elems[0], v128u8);
|
||||
REG(V20, simd.v[20].bytes.elems[0], v128u8);
|
||||
REG(V21, simd.v[21].bytes.elems[0], v128u8);
|
||||
REG(V22, simd.v[22].bytes.elems[0], v128u8);
|
||||
REG(V23, simd.v[23].bytes.elems[0], v128u8);
|
||||
REG(V24, simd.v[24].bytes.elems[0], v128u8);
|
||||
REG(V25, simd.v[25].bytes.elems[0], v128u8);
|
||||
REG(V26, simd.v[26].bytes.elems[0], v128u8);
|
||||
REG(V27, simd.v[27].bytes.elems[0], v128u8);
|
||||
REG(V28, simd.v[28].bytes.elems[0], v128u8);
|
||||
REG(V29, simd.v[29].bytes.elems[0], v128u8);
|
||||
REG(V30, simd.v[30].bytes.elems[0], v128u8);
|
||||
REG(V31, simd.v[31].bytes.elems[0], v128u8);
|
||||
|
||||
SUB_REG(B0, simd.v[0].bytes.elems[0], v128u8, V0);
|
||||
SUB_REG(B1, simd.v[1].bytes.elems[0], v128u8, V1);
|
||||
SUB_REG(B2, simd.v[2].bytes.elems[0], v128u8, V2);
|
||||
SUB_REG(B3, simd.v[3].bytes.elems[0], v128u8, V3);
|
||||
SUB_REG(B4, simd.v[4].bytes.elems[0], v128u8, V4);
|
||||
SUB_REG(B5, simd.v[5].bytes.elems[0], v128u8, V5);
|
||||
SUB_REG(B6, simd.v[6].bytes.elems[0], v128u8, V6);
|
||||
SUB_REG(B7, simd.v[7].bytes.elems[0], v128u8, V7);
|
||||
SUB_REG(B8, simd.v[8].bytes.elems[0], v128u8, V8);
|
||||
SUB_REG(B9, simd.v[9].bytes.elems[0], v128u8, V9);
|
||||
SUB_REG(B10, simd.v[10].bytes.elems[0], v128u8, V10);
|
||||
SUB_REG(B11, simd.v[11].bytes.elems[0], v128u8, V11);
|
||||
SUB_REG(B12, simd.v[12].bytes.elems[0], v128u8, V12);
|
||||
SUB_REG(B13, simd.v[13].bytes.elems[0], v128u8, V13);
|
||||
SUB_REG(B14, simd.v[14].bytes.elems[0], v128u8, V14);
|
||||
SUB_REG(B15, simd.v[15].bytes.elems[0], v128u8, V15);
|
||||
SUB_REG(B16, simd.v[16].bytes.elems[0], v128u8, V16);
|
||||
SUB_REG(B17, simd.v[17].bytes.elems[0], v128u8, V17);
|
||||
SUB_REG(B18, simd.v[18].bytes.elems[0], v128u8, V18);
|
||||
SUB_REG(B19, simd.v[19].bytes.elems[0], v128u8, V19);
|
||||
SUB_REG(B20, simd.v[20].bytes.elems[0], v128u8, V20);
|
||||
SUB_REG(B21, simd.v[21].bytes.elems[0], v128u8, V21);
|
||||
SUB_REG(B22, simd.v[22].bytes.elems[0], v128u8, V22);
|
||||
SUB_REG(B23, simd.v[23].bytes.elems[0], v128u8, V23);
|
||||
SUB_REG(B24, simd.v[24].bytes.elems[0], v128u8, V24);
|
||||
SUB_REG(B25, simd.v[25].bytes.elems[0], v128u8, V25);
|
||||
SUB_REG(B26, simd.v[26].bytes.elems[0], v128u8, V26);
|
||||
SUB_REG(B27, simd.v[27].bytes.elems[0], v128u8, V27);
|
||||
SUB_REG(B28, simd.v[28].bytes.elems[0], v128u8, V28);
|
||||
SUB_REG(B29, simd.v[29].bytes.elems[0], v128u8, V29);
|
||||
SUB_REG(B30, simd.v[30].bytes.elems[0], v128u8, V30);
|
||||
SUB_REG(B31, simd.v[31].bytes.elems[0], v128u8, V31);
|
||||
|
||||
SUB_REG(H0, simd.v[0].words.elems[0], v128u16, V0);
|
||||
SUB_REG(H1, simd.v[1].words.elems[0], v128u16, V1);
|
||||
SUB_REG(H2, simd.v[2].words.elems[0], v128u16, V2);
|
||||
SUB_REG(H3, simd.v[3].words.elems[0], v128u16, V3);
|
||||
SUB_REG(H4, simd.v[4].words.elems[0], v128u16, V4);
|
||||
SUB_REG(H5, simd.v[5].words.elems[0], v128u16, V5);
|
||||
SUB_REG(H6, simd.v[6].words.elems[0], v128u16, V6);
|
||||
SUB_REG(H7, simd.v[7].words.elems[0], v128u16, V7);
|
||||
SUB_REG(H8, simd.v[8].words.elems[0], v128u16, V8);
|
||||
SUB_REG(H9, simd.v[9].words.elems[0], v128u16, V9);
|
||||
SUB_REG(H10, simd.v[10].words.elems[0], v128u16, V10);
|
||||
SUB_REG(H11, simd.v[11].words.elems[0], v128u16, V11);
|
||||
SUB_REG(H12, simd.v[12].words.elems[0], v128u16, V12);
|
||||
SUB_REG(H13, simd.v[13].words.elems[0], v128u16, V13);
|
||||
SUB_REG(H14, simd.v[14].words.elems[0], v128u16, V14);
|
||||
SUB_REG(H15, simd.v[15].words.elems[0], v128u16, V15);
|
||||
SUB_REG(H16, simd.v[16].words.elems[0], v128u16, V16);
|
||||
SUB_REG(H17, simd.v[17].words.elems[0], v128u16, V17);
|
||||
SUB_REG(H18, simd.v[18].words.elems[0], v128u16, V18);
|
||||
SUB_REG(H19, simd.v[19].words.elems[0], v128u16, V19);
|
||||
SUB_REG(H20, simd.v[20].words.elems[0], v128u16, V20);
|
||||
SUB_REG(H21, simd.v[21].words.elems[0], v128u16, V21);
|
||||
SUB_REG(H22, simd.v[22].words.elems[0], v128u16, V22);
|
||||
SUB_REG(H23, simd.v[23].words.elems[0], v128u16, V23);
|
||||
SUB_REG(H24, simd.v[24].words.elems[0], v128u16, V24);
|
||||
SUB_REG(H25, simd.v[25].words.elems[0], v128u16, V25);
|
||||
SUB_REG(H26, simd.v[26].words.elems[0], v128u16, V26);
|
||||
SUB_REG(H27, simd.v[27].words.elems[0], v128u16, V27);
|
||||
SUB_REG(H28, simd.v[28].words.elems[0], v128u16, V28);
|
||||
SUB_REG(H29, simd.v[29].words.elems[0], v128u16, V29);
|
||||
SUB_REG(H30, simd.v[30].words.elems[0], v128u16, V30);
|
||||
SUB_REG(H31, simd.v[31].words.elems[0], v128u16, V31);
|
||||
|
||||
SUB_REG(S0, simd.v[0].dwords.elems[0], v128u32, V0);
|
||||
SUB_REG(S1, simd.v[1].dwords.elems[0], v128u32, V1);
|
||||
SUB_REG(S2, simd.v[2].dwords.elems[0], v128u32, V2);
|
||||
SUB_REG(S3, simd.v[3].dwords.elems[0], v128u32, V3);
|
||||
SUB_REG(S4, simd.v[4].dwords.elems[0], v128u32, V4);
|
||||
SUB_REG(S5, simd.v[5].dwords.elems[0], v128u32, V5);
|
||||
SUB_REG(S6, simd.v[6].dwords.elems[0], v128u32, V6);
|
||||
SUB_REG(S7, simd.v[7].dwords.elems[0], v128u32, V7);
|
||||
SUB_REG(S8, simd.v[8].dwords.elems[0], v128u32, V8);
|
||||
SUB_REG(S9, simd.v[9].dwords.elems[0], v128u32, V9);
|
||||
SUB_REG(S10, simd.v[10].dwords.elems[0], v128u32, V10);
|
||||
SUB_REG(S11, simd.v[11].dwords.elems[0], v128u32, V11);
|
||||
SUB_REG(S12, simd.v[12].dwords.elems[0], v128u32, V12);
|
||||
SUB_REG(S13, simd.v[13].dwords.elems[0], v128u32, V13);
|
||||
SUB_REG(S14, simd.v[14].dwords.elems[0], v128u32, V14);
|
||||
SUB_REG(S15, simd.v[15].dwords.elems[0], v128u32, V15);
|
||||
SUB_REG(S16, simd.v[16].dwords.elems[0], v128u32, V16);
|
||||
SUB_REG(S17, simd.v[17].dwords.elems[0], v128u32, V17);
|
||||
SUB_REG(S18, simd.v[18].dwords.elems[0], v128u32, V18);
|
||||
SUB_REG(S19, simd.v[19].dwords.elems[0], v128u32, V19);
|
||||
SUB_REG(S20, simd.v[20].dwords.elems[0], v128u32, V20);
|
||||
SUB_REG(S21, simd.v[21].dwords.elems[0], v128u32, V21);
|
||||
SUB_REG(S22, simd.v[22].dwords.elems[0], v128u32, V22);
|
||||
SUB_REG(S23, simd.v[23].dwords.elems[0], v128u32, V23);
|
||||
SUB_REG(S24, simd.v[24].dwords.elems[0], v128u32, V24);
|
||||
SUB_REG(S25, simd.v[25].dwords.elems[0], v128u32, V25);
|
||||
SUB_REG(S26, simd.v[26].dwords.elems[0], v128u32, V26);
|
||||
SUB_REG(S27, simd.v[27].dwords.elems[0], v128u32, V27);
|
||||
SUB_REG(S28, simd.v[28].dwords.elems[0], v128u32, V28);
|
||||
SUB_REG(S29, simd.v[29].dwords.elems[0], v128u32, V29);
|
||||
SUB_REG(S30, simd.v[30].dwords.elems[0], v128u32, V30);
|
||||
SUB_REG(S31, simd.v[31].dwords.elems[0], v128u32, V31);
|
||||
|
||||
SUB_REG(D0, simd.v[0].qwords.elems[0], v128u64, V0);
|
||||
SUB_REG(D1, simd.v[1].qwords.elems[0], v128u64, V1);
|
||||
SUB_REG(D2, simd.v[2].qwords.elems[0], v128u64, V2);
|
||||
SUB_REG(D3, simd.v[3].qwords.elems[0], v128u64, V3);
|
||||
SUB_REG(D4, simd.v[4].qwords.elems[0], v128u64, V4);
|
||||
SUB_REG(D5, simd.v[5].qwords.elems[0], v128u64, V5);
|
||||
SUB_REG(D6, simd.v[6].qwords.elems[0], v128u64, V6);
|
||||
SUB_REG(D7, simd.v[7].qwords.elems[0], v128u64, V7);
|
||||
SUB_REG(D8, simd.v[8].qwords.elems[0], v128u64, V8);
|
||||
SUB_REG(D9, simd.v[9].qwords.elems[0], v128u64, V9);
|
||||
SUB_REG(D10, simd.v[10].qwords.elems[0], v128u64, V10);
|
||||
SUB_REG(D11, simd.v[11].qwords.elems[0], v128u64, V11);
|
||||
SUB_REG(D12, simd.v[12].qwords.elems[0], v128u64, V12);
|
||||
SUB_REG(D13, simd.v[13].qwords.elems[0], v128u64, V13);
|
||||
SUB_REG(D14, simd.v[14].qwords.elems[0], v128u64, V14);
|
||||
SUB_REG(D15, simd.v[15].qwords.elems[0], v128u64, V15);
|
||||
SUB_REG(D16, simd.v[16].qwords.elems[0], v128u64, V16);
|
||||
SUB_REG(D17, simd.v[17].qwords.elems[0], v128u64, V17);
|
||||
SUB_REG(D18, simd.v[18].qwords.elems[0], v128u64, V18);
|
||||
SUB_REG(D19, simd.v[19].qwords.elems[0], v128u64, V19);
|
||||
SUB_REG(D20, simd.v[20].qwords.elems[0], v128u64, V20);
|
||||
SUB_REG(D21, simd.v[21].qwords.elems[0], v128u64, V21);
|
||||
SUB_REG(D22, simd.v[22].qwords.elems[0], v128u64, V22);
|
||||
SUB_REG(D23, simd.v[23].qwords.elems[0], v128u64, V23);
|
||||
SUB_REG(D24, simd.v[24].qwords.elems[0], v128u64, V24);
|
||||
SUB_REG(D25, simd.v[25].qwords.elems[0], v128u64, V25);
|
||||
SUB_REG(D26, simd.v[26].qwords.elems[0], v128u64, V26);
|
||||
SUB_REG(D27, simd.v[27].qwords.elems[0], v128u64, V27);
|
||||
SUB_REG(D28, simd.v[28].qwords.elems[0], v128u64, V28);
|
||||
SUB_REG(D29, simd.v[29].qwords.elems[0], v128u64, V29);
|
||||
SUB_REG(D30, simd.v[30].qwords.elems[0], v128u64, V30);
|
||||
SUB_REG(D31, simd.v[31].qwords.elems[0], v128u64, V31);
|
||||
|
||||
SUB_REG(Q0, simd.v[0].dqwords.elems[0], v128u128, V0);
|
||||
SUB_REG(Q1, simd.v[1].dqwords.elems[0], v128u128, V1);
|
||||
SUB_REG(Q2, simd.v[2].dqwords.elems[0], v128u128, V2);
|
||||
SUB_REG(Q3, simd.v[3].dqwords.elems[0], v128u128, V3);
|
||||
SUB_REG(Q4, simd.v[4].dqwords.elems[0], v128u128, V4);
|
||||
SUB_REG(Q5, simd.v[5].dqwords.elems[0], v128u128, V5);
|
||||
SUB_REG(Q6, simd.v[6].dqwords.elems[0], v128u128, V6);
|
||||
SUB_REG(Q7, simd.v[7].dqwords.elems[0], v128u128, V7);
|
||||
SUB_REG(Q8, simd.v[8].dqwords.elems[0], v128u128, V8);
|
||||
SUB_REG(Q9, simd.v[9].dqwords.elems[0], v128u128, V9);
|
||||
SUB_REG(Q10, simd.v[10].dqwords.elems[0], v128u128, V10);
|
||||
SUB_REG(Q11, simd.v[11].dqwords.elems[0], v128u128, V11);
|
||||
SUB_REG(Q12, simd.v[12].dqwords.elems[0], v128u128, V12);
|
||||
SUB_REG(Q13, simd.v[13].dqwords.elems[0], v128u128, V13);
|
||||
SUB_REG(Q14, simd.v[14].dqwords.elems[0], v128u128, V14);
|
||||
SUB_REG(Q15, simd.v[15].dqwords.elems[0], v128u128, V15);
|
||||
SUB_REG(Q16, simd.v[16].dqwords.elems[0], v128u128, V16);
|
||||
SUB_REG(Q17, simd.v[17].dqwords.elems[0], v128u128, V17);
|
||||
SUB_REG(Q18, simd.v[18].dqwords.elems[0], v128u128, V18);
|
||||
SUB_REG(Q19, simd.v[19].dqwords.elems[0], v128u128, V19);
|
||||
SUB_REG(Q20, simd.v[20].dqwords.elems[0], v128u128, V20);
|
||||
SUB_REG(Q21, simd.v[21].dqwords.elems[0], v128u128, V21);
|
||||
SUB_REG(Q22, simd.v[22].dqwords.elems[0], v128u128, V22);
|
||||
SUB_REG(Q23, simd.v[23].dqwords.elems[0], v128u128, V23);
|
||||
SUB_REG(Q24, simd.v[24].dqwords.elems[0], v128u128, V24);
|
||||
SUB_REG(Q25, simd.v[25].dqwords.elems[0], v128u128, V25);
|
||||
SUB_REG(Q26, simd.v[26].dqwords.elems[0], v128u128, V26);
|
||||
SUB_REG(Q27, simd.v[27].dqwords.elems[0], v128u128, V27);
|
||||
SUB_REG(Q28, simd.v[28].dqwords.elems[0], v128u128, V28);
|
||||
SUB_REG(Q29, simd.v[29].dqwords.elems[0], v128u128, V29);
|
||||
SUB_REG(Q30, simd.v[30].dqwords.elems[0], v128u128, V30);
|
||||
SUB_REG(Q31, simd.v[31].dqwords.elems[0], v128u128, V31);
|
||||
|
||||
REG(TPIDR_EL0, sr.tpidr_el0.qword, u64);
|
||||
REG(TPIDRRO_EL0, sr.tpidrro_el0.qword, u64);
|
||||
}
|
||||
|
||||
// Populate a just-initialized lifted function function with architecture-
|
||||
// specific variables.
|
||||
void AArch64Arch::FinishLiftedFunctionInitialization(
|
||||
llvm::Module *module, llvm::Function *bb_func) const {
|
||||
|
||||
auto &context = module->getContext();
|
||||
auto u32 = llvm::Type::getInt32Ty(context);
|
||||
auto u64 = llvm::Type::getInt64Ty(context);
|
||||
|
||||
auto addr = u64;
|
||||
auto zero_u32 = llvm::Constant::getNullValue(u32);
|
||||
auto zero_u64 = llvm::Constant::getNullValue(u64);
|
||||
|
||||
const auto entry_block = &bb_func->getEntryBlock();
|
||||
llvm::IRBuilder<> ir(entry_block);
|
||||
|
||||
const auto pc_arg = NthArgument(bb_func, kPCArgNum);
|
||||
const auto state_ptr_arg = NthArgument(bb_func, kStatePointerArgNum);
|
||||
llvm::StringRef next_pc_name(kNextPCVariableName.data(),
|
||||
kNextPCVariableName.size());
|
||||
ir.CreateStore(pc_arg, ir.CreateAlloca(addr, nullptr, next_pc_name));
|
||||
|
||||
ir.CreateStore(zero_u32, ir.CreateAlloca(u32, nullptr, "WZR"));
|
||||
ir.CreateStore(zero_u64, ir.CreateAlloca(u64, nullptr, "XZR"));
|
||||
ir.CreateAlloca(u32, nullptr, "IGNORE_WRITE_TO_WZR");
|
||||
ir.CreateAlloca(u64, nullptr, "IGNORE_WRITE_TO_XZR");
|
||||
ir.CreateAlloca(u64, nullptr, "SUPPRESS_WRITEBACK");
|
||||
|
||||
(void) this->RegisterByName(kPCVariableName)->AddressOf(state_ptr_arg, ir);
|
||||
}
|
||||
|
||||
// TODO(pag): Eventually handle Thumb2 and unaligned addresses.
|
||||
uint64_t AArch64Arch::MinInstructionAlign(const DecodingContext &) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint64_t AArch64Arch::MinInstructionSize(const DecodingContext &) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// Maximum number of bytes in an instruction for this particular architecture.
|
||||
uint64_t AArch64Arch::MaxInstructionSize(const DecodingContext &, bool) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
llvm::Triple AArch64Arch::Triple(void) const {
|
||||
auto triple = BasicTriple();
|
||||
switch (arch_name) {
|
||||
case kArchAArch64LittleEndian: triple.setArch(llvm::Triple::aarch64); break;
|
||||
|
||||
default:
|
||||
LOG(FATAL) << "Cannot get triple for non-AArch64 architecture "
|
||||
<< GetArchName(arch_name);
|
||||
break;
|
||||
}
|
||||
return triple;
|
||||
}
|
||||
|
||||
llvm::DataLayout AArch64Arch::DataLayout(void) const {
|
||||
std::string dl;
|
||||
switch (arch_name) {
|
||||
case kArchAArch64LittleEndian:
|
||||
dl = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(FATAL) << "Cannot get data layout for non-AArch64 architecture "
|
||||
<< GetArchName(arch_name);
|
||||
break;
|
||||
}
|
||||
return llvm::DataLayout(dl);
|
||||
}
|
||||
|
||||
enum RegClass {
|
||||
kRegX, // 64-bit int.
|
||||
@@ -1204,15 +803,6 @@ static uint64_t VFPExpandImmToFloat64(uint64_t imm) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the name of the stack pointer register.
|
||||
std::string_view AArch64Arch::StackPointerRegisterName(void) const {
|
||||
return "SP";
|
||||
}
|
||||
|
||||
// Returns the name of the program counter register.
|
||||
std::string_view AArch64Arch::ProgramCounterRegisterName(void) const {
|
||||
return "PC";
|
||||
}
|
||||
|
||||
bool AArch64Arch::ArchDecodeInstruction(uint64_t address,
|
||||
std::string_view inst_bytes,
|
||||
|
||||
@@ -0,0 +1,398 @@
|
||||
#include <glog/logging.h>
|
||||
#include <remill/Arch/AArch64/AArch64Base.h>
|
||||
#include <remill/Arch/Name.h>
|
||||
#include <remill/BC/ABI.h>
|
||||
#include <remill/BC/Util.h>
|
||||
|
||||
namespace remill {
|
||||
// Returns the name of the stack pointer register.
|
||||
std::string_view AArch64ArchBase::StackPointerRegisterName(void) const {
|
||||
return "SP";
|
||||
}
|
||||
|
||||
// Returns the name of the program counter register.
|
||||
std::string_view AArch64ArchBase::ProgramCounterRegisterName(void) const {
|
||||
return "PC";
|
||||
}
|
||||
|
||||
uint64_t AArch64ArchBase::MinInstructionAlign(const DecodingContext &) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint64_t AArch64ArchBase::MinInstructionSize(const DecodingContext &) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// Maximum number of bytes in an instruction for this particular architecture.
|
||||
uint64_t AArch64ArchBase::MaxInstructionSize(const DecodingContext &,
|
||||
bool) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
// Populate a just-initialized lifted function function with architecture-
|
||||
// specific variables.
|
||||
void AArch64ArchBase::FinishLiftedFunctionInitialization(
|
||||
llvm::Module *module, llvm::Function *bb_func) const {
|
||||
|
||||
auto &context = module->getContext();
|
||||
auto u32 = llvm::Type::getInt32Ty(context);
|
||||
auto u64 = llvm::Type::getInt64Ty(context);
|
||||
|
||||
auto addr = u64;
|
||||
auto zero_u32 = llvm::Constant::getNullValue(u32);
|
||||
auto zero_u64 = llvm::Constant::getNullValue(u64);
|
||||
|
||||
const auto entry_block = &bb_func->getEntryBlock();
|
||||
llvm::IRBuilder<> ir(entry_block);
|
||||
|
||||
const auto pc_arg = NthArgument(bb_func, kPCArgNum);
|
||||
const auto state_ptr_arg = NthArgument(bb_func, kStatePointerArgNum);
|
||||
llvm::StringRef next_pc_name(kNextPCVariableName.data(),
|
||||
kNextPCVariableName.size());
|
||||
ir.CreateStore(pc_arg, ir.CreateAlloca(addr, nullptr, next_pc_name));
|
||||
|
||||
ir.CreateStore(zero_u32, ir.CreateAlloca(u32, nullptr, "WZR"));
|
||||
ir.CreateStore(zero_u64, ir.CreateAlloca(u64, nullptr, "XZR"));
|
||||
ir.CreateAlloca(u32, nullptr, "IGNORE_WRITE_TO_WZR");
|
||||
ir.CreateAlloca(u64, nullptr, "IGNORE_WRITE_TO_XZR");
|
||||
ir.CreateAlloca(u64, nullptr, "SUPPRESS_WRITEBACK");
|
||||
|
||||
(void) this->RegisterByName(kPCVariableName)->AddressOf(state_ptr_arg, ir);
|
||||
}
|
||||
|
||||
llvm::Triple AArch64ArchBase::Triple(void) const {
|
||||
auto triple = BasicTriple();
|
||||
switch (arch_name) {
|
||||
case kArchAArch64LittleEndian: triple.setArch(llvm::Triple::aarch64); break;
|
||||
|
||||
default:
|
||||
LOG(FATAL) << "Cannot get triple for non-AArch64 architecture "
|
||||
<< GetArchName(arch_name);
|
||||
break;
|
||||
}
|
||||
return triple;
|
||||
}
|
||||
|
||||
llvm::DataLayout AArch64ArchBase::DataLayout(void) const {
|
||||
std::string dl;
|
||||
switch (arch_name) {
|
||||
case kArchAArch64LittleEndian:
|
||||
dl = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128";
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(FATAL) << "Cannot get data layout for non-AArch64 architecture "
|
||||
<< GetArchName(arch_name);
|
||||
break;
|
||||
}
|
||||
return llvm::DataLayout(dl);
|
||||
}
|
||||
|
||||
// Default calling convention for this architecture.
|
||||
llvm::CallingConv::ID AArch64ArchBase::DefaultCallingConv(void) const {
|
||||
return llvm::CallingConv::C;
|
||||
}
|
||||
|
||||
// Populate the table of register information.
|
||||
void AArch64ArchBase::PopulateRegisterTable(void) const {
|
||||
|
||||
reg_by_offset.resize(sizeof(AArch64State));
|
||||
|
||||
#define OFFSET_OF(type, access) \
|
||||
(reinterpret_cast<uintptr_t>(&reinterpret_cast<const volatile char &>( \
|
||||
static_cast<type *>(nullptr)->access)))
|
||||
|
||||
#define REG(name, access, type) \
|
||||
AddRegister(#name, type, OFFSET_OF(AArch64State, access), nullptr)
|
||||
|
||||
#define SUB_REG(name, access, type, parent_reg_name) \
|
||||
AddRegister(#name, type, OFFSET_OF(AArch64State, access), #parent_reg_name)
|
||||
|
||||
auto u8 = llvm::Type::getInt8Ty(*context);
|
||||
auto u16 = llvm::Type::getInt16Ty(*context);
|
||||
auto u32 = llvm::Type::getInt32Ty(*context);
|
||||
auto u64 = llvm::Type::getInt64Ty(*context);
|
||||
auto u128 = llvm::Type::getInt128Ty(*context);
|
||||
|
||||
auto v128u8 = llvm::ArrayType::get(u8, 128u / 8u);
|
||||
auto v128u16 = llvm::ArrayType::get(u16, 128u / 16u);
|
||||
auto v128u32 = llvm::ArrayType::get(u32, 128u / 32u);
|
||||
auto v128u64 = llvm::ArrayType::get(u64, 128u / 64u);
|
||||
auto v128u128 = llvm::ArrayType::get(u128, 128u / 128u);
|
||||
|
||||
REG(X0, gpr.x0.qword, u64);
|
||||
REG(X1, gpr.x1.qword, u64);
|
||||
REG(X2, gpr.x2.qword, u64);
|
||||
REG(X3, gpr.x3.qword, u64);
|
||||
REG(X4, gpr.x4.qword, u64);
|
||||
REG(X5, gpr.x5.qword, u64);
|
||||
REG(X6, gpr.x6.qword, u64);
|
||||
REG(X7, gpr.x7.qword, u64);
|
||||
REG(X8, gpr.x8.qword, u64);
|
||||
REG(X9, gpr.x9.qword, u64);
|
||||
REG(X10, gpr.x10.qword, u64);
|
||||
REG(X11, gpr.x11.qword, u64);
|
||||
REG(X12, gpr.x12.qword, u64);
|
||||
REG(X13, gpr.x13.qword, u64);
|
||||
REG(X14, gpr.x14.qword, u64);
|
||||
REG(X15, gpr.x15.qword, u64);
|
||||
REG(X16, gpr.x16.qword, u64);
|
||||
REG(X17, gpr.x17.qword, u64);
|
||||
REG(X18, gpr.x18.qword, u64);
|
||||
REG(X19, gpr.x19.qword, u64);
|
||||
REG(X20, gpr.x20.qword, u64);
|
||||
REG(X21, gpr.x21.qword, u64);
|
||||
REG(X22, gpr.x22.qword, u64);
|
||||
REG(X23, gpr.x23.qword, u64);
|
||||
REG(X24, gpr.x24.qword, u64);
|
||||
REG(X25, gpr.x25.qword, u64);
|
||||
REG(X26, gpr.x26.qword, u64);
|
||||
REG(X27, gpr.x27.qword, u64);
|
||||
REG(X28, gpr.x28.qword, u64);
|
||||
REG(X29, gpr.x29.qword, u64);
|
||||
REG(X30, gpr.x30.qword, u64);
|
||||
|
||||
SUB_REG(W0, gpr.x0.dword, u32, X0);
|
||||
SUB_REG(W1, gpr.x1.dword, u32, X1);
|
||||
SUB_REG(W2, gpr.x2.dword, u32, X2);
|
||||
SUB_REG(W3, gpr.x3.dword, u32, X3);
|
||||
SUB_REG(W4, gpr.x4.dword, u32, X4);
|
||||
SUB_REG(W5, gpr.x5.dword, u32, X5);
|
||||
SUB_REG(W6, gpr.x6.dword, u32, X6);
|
||||
SUB_REG(W7, gpr.x7.dword, u32, X7);
|
||||
SUB_REG(W8, gpr.x8.dword, u32, X8);
|
||||
SUB_REG(W9, gpr.x9.dword, u32, X9);
|
||||
SUB_REG(W10, gpr.x10.dword, u32, X10);
|
||||
SUB_REG(W11, gpr.x11.dword, u32, X11);
|
||||
SUB_REG(W12, gpr.x12.dword, u32, X12);
|
||||
SUB_REG(W13, gpr.x13.dword, u32, X13);
|
||||
SUB_REG(W14, gpr.x14.dword, u32, X14);
|
||||
SUB_REG(W15, gpr.x15.dword, u32, X15);
|
||||
SUB_REG(W16, gpr.x16.dword, u32, X16);
|
||||
SUB_REG(W17, gpr.x17.dword, u32, X17);
|
||||
SUB_REG(W18, gpr.x18.dword, u32, X18);
|
||||
SUB_REG(W19, gpr.x19.dword, u32, X19);
|
||||
SUB_REG(W20, gpr.x20.dword, u32, X20);
|
||||
SUB_REG(W21, gpr.x21.dword, u32, X21);
|
||||
SUB_REG(W22, gpr.x22.dword, u32, X22);
|
||||
SUB_REG(W23, gpr.x23.dword, u32, X23);
|
||||
SUB_REG(W24, gpr.x24.dword, u32, X24);
|
||||
SUB_REG(W25, gpr.x25.dword, u32, X25);
|
||||
SUB_REG(W26, gpr.x26.dword, u32, X26);
|
||||
SUB_REG(W27, gpr.x27.dword, u32, X27);
|
||||
SUB_REG(W28, gpr.x28.dword, u32, X28);
|
||||
SUB_REG(W29, gpr.x29.dword, u32, X29);
|
||||
SUB_REG(W30, gpr.x30.dword, u32, X30);
|
||||
|
||||
REG(PC, gpr.pc.qword, u64);
|
||||
SUB_REG(WPC, gpr.pc.dword, u32, PC);
|
||||
|
||||
REG(SP, gpr.sp.qword, u64);
|
||||
SUB_REG(WSP, gpr.sp.dword, u32, SP);
|
||||
|
||||
SUB_REG(LP, gpr.x30.qword, u64, X30);
|
||||
SUB_REG(WLP, gpr.x30.dword, u32, LP);
|
||||
|
||||
REG(V0, simd.v[0].bytes.elems[0], v128u8);
|
||||
REG(V1, simd.v[1].bytes.elems[0], v128u8);
|
||||
REG(V2, simd.v[2].bytes.elems[0], v128u8);
|
||||
REG(V3, simd.v[3].bytes.elems[0], v128u8);
|
||||
REG(V4, simd.v[4].bytes.elems[0], v128u8);
|
||||
REG(V5, simd.v[5].bytes.elems[0], v128u8);
|
||||
REG(V6, simd.v[6].bytes.elems[0], v128u8);
|
||||
REG(V7, simd.v[7].bytes.elems[0], v128u8);
|
||||
REG(V8, simd.v[8].bytes.elems[0], v128u8);
|
||||
REG(V9, simd.v[9].bytes.elems[0], v128u8);
|
||||
REG(V10, simd.v[10].bytes.elems[0], v128u8);
|
||||
REG(V11, simd.v[11].bytes.elems[0], v128u8);
|
||||
REG(V12, simd.v[12].bytes.elems[0], v128u8);
|
||||
REG(V13, simd.v[13].bytes.elems[0], v128u8);
|
||||
REG(V14, simd.v[14].bytes.elems[0], v128u8);
|
||||
REG(V15, simd.v[15].bytes.elems[0], v128u8);
|
||||
REG(V16, simd.v[16].bytes.elems[0], v128u8);
|
||||
REG(V17, simd.v[17].bytes.elems[0], v128u8);
|
||||
REG(V18, simd.v[18].bytes.elems[0], v128u8);
|
||||
REG(V19, simd.v[19].bytes.elems[0], v128u8);
|
||||
REG(V20, simd.v[20].bytes.elems[0], v128u8);
|
||||
REG(V21, simd.v[21].bytes.elems[0], v128u8);
|
||||
REG(V22, simd.v[22].bytes.elems[0], v128u8);
|
||||
REG(V23, simd.v[23].bytes.elems[0], v128u8);
|
||||
REG(V24, simd.v[24].bytes.elems[0], v128u8);
|
||||
REG(V25, simd.v[25].bytes.elems[0], v128u8);
|
||||
REG(V26, simd.v[26].bytes.elems[0], v128u8);
|
||||
REG(V27, simd.v[27].bytes.elems[0], v128u8);
|
||||
REG(V28, simd.v[28].bytes.elems[0], v128u8);
|
||||
REG(V29, simd.v[29].bytes.elems[0], v128u8);
|
||||
REG(V30, simd.v[30].bytes.elems[0], v128u8);
|
||||
REG(V31, simd.v[31].bytes.elems[0], v128u8);
|
||||
|
||||
SUB_REG(B0, simd.v[0].bytes.elems[0], v128u8, V0);
|
||||
SUB_REG(B1, simd.v[1].bytes.elems[0], v128u8, V1);
|
||||
SUB_REG(B2, simd.v[2].bytes.elems[0], v128u8, V2);
|
||||
SUB_REG(B3, simd.v[3].bytes.elems[0], v128u8, V3);
|
||||
SUB_REG(B4, simd.v[4].bytes.elems[0], v128u8, V4);
|
||||
SUB_REG(B5, simd.v[5].bytes.elems[0], v128u8, V5);
|
||||
SUB_REG(B6, simd.v[6].bytes.elems[0], v128u8, V6);
|
||||
SUB_REG(B7, simd.v[7].bytes.elems[0], v128u8, V7);
|
||||
SUB_REG(B8, simd.v[8].bytes.elems[0], v128u8, V8);
|
||||
SUB_REG(B9, simd.v[9].bytes.elems[0], v128u8, V9);
|
||||
SUB_REG(B10, simd.v[10].bytes.elems[0], v128u8, V10);
|
||||
SUB_REG(B11, simd.v[11].bytes.elems[0], v128u8, V11);
|
||||
SUB_REG(B12, simd.v[12].bytes.elems[0], v128u8, V12);
|
||||
SUB_REG(B13, simd.v[13].bytes.elems[0], v128u8, V13);
|
||||
SUB_REG(B14, simd.v[14].bytes.elems[0], v128u8, V14);
|
||||
SUB_REG(B15, simd.v[15].bytes.elems[0], v128u8, V15);
|
||||
SUB_REG(B16, simd.v[16].bytes.elems[0], v128u8, V16);
|
||||
SUB_REG(B17, simd.v[17].bytes.elems[0], v128u8, V17);
|
||||
SUB_REG(B18, simd.v[18].bytes.elems[0], v128u8, V18);
|
||||
SUB_REG(B19, simd.v[19].bytes.elems[0], v128u8, V19);
|
||||
SUB_REG(B20, simd.v[20].bytes.elems[0], v128u8, V20);
|
||||
SUB_REG(B21, simd.v[21].bytes.elems[0], v128u8, V21);
|
||||
SUB_REG(B22, simd.v[22].bytes.elems[0], v128u8, V22);
|
||||
SUB_REG(B23, simd.v[23].bytes.elems[0], v128u8, V23);
|
||||
SUB_REG(B24, simd.v[24].bytes.elems[0], v128u8, V24);
|
||||
SUB_REG(B25, simd.v[25].bytes.elems[0], v128u8, V25);
|
||||
SUB_REG(B26, simd.v[26].bytes.elems[0], v128u8, V26);
|
||||
SUB_REG(B27, simd.v[27].bytes.elems[0], v128u8, V27);
|
||||
SUB_REG(B28, simd.v[28].bytes.elems[0], v128u8, V28);
|
||||
SUB_REG(B29, simd.v[29].bytes.elems[0], v128u8, V29);
|
||||
SUB_REG(B30, simd.v[30].bytes.elems[0], v128u8, V30);
|
||||
SUB_REG(B31, simd.v[31].bytes.elems[0], v128u8, V31);
|
||||
|
||||
SUB_REG(H0, simd.v[0].words.elems[0], v128u16, V0);
|
||||
SUB_REG(H1, simd.v[1].words.elems[0], v128u16, V1);
|
||||
SUB_REG(H2, simd.v[2].words.elems[0], v128u16, V2);
|
||||
SUB_REG(H3, simd.v[3].words.elems[0], v128u16, V3);
|
||||
SUB_REG(H4, simd.v[4].words.elems[0], v128u16, V4);
|
||||
SUB_REG(H5, simd.v[5].words.elems[0], v128u16, V5);
|
||||
SUB_REG(H6, simd.v[6].words.elems[0], v128u16, V6);
|
||||
SUB_REG(H7, simd.v[7].words.elems[0], v128u16, V7);
|
||||
SUB_REG(H8, simd.v[8].words.elems[0], v128u16, V8);
|
||||
SUB_REG(H9, simd.v[9].words.elems[0], v128u16, V9);
|
||||
SUB_REG(H10, simd.v[10].words.elems[0], v128u16, V10);
|
||||
SUB_REG(H11, simd.v[11].words.elems[0], v128u16, V11);
|
||||
SUB_REG(H12, simd.v[12].words.elems[0], v128u16, V12);
|
||||
SUB_REG(H13, simd.v[13].words.elems[0], v128u16, V13);
|
||||
SUB_REG(H14, simd.v[14].words.elems[0], v128u16, V14);
|
||||
SUB_REG(H15, simd.v[15].words.elems[0], v128u16, V15);
|
||||
SUB_REG(H16, simd.v[16].words.elems[0], v128u16, V16);
|
||||
SUB_REG(H17, simd.v[17].words.elems[0], v128u16, V17);
|
||||
SUB_REG(H18, simd.v[18].words.elems[0], v128u16, V18);
|
||||
SUB_REG(H19, simd.v[19].words.elems[0], v128u16, V19);
|
||||
SUB_REG(H20, simd.v[20].words.elems[0], v128u16, V20);
|
||||
SUB_REG(H21, simd.v[21].words.elems[0], v128u16, V21);
|
||||
SUB_REG(H22, simd.v[22].words.elems[0], v128u16, V22);
|
||||
SUB_REG(H23, simd.v[23].words.elems[0], v128u16, V23);
|
||||
SUB_REG(H24, simd.v[24].words.elems[0], v128u16, V24);
|
||||
SUB_REG(H25, simd.v[25].words.elems[0], v128u16, V25);
|
||||
SUB_REG(H26, simd.v[26].words.elems[0], v128u16, V26);
|
||||
SUB_REG(H27, simd.v[27].words.elems[0], v128u16, V27);
|
||||
SUB_REG(H28, simd.v[28].words.elems[0], v128u16, V28);
|
||||
SUB_REG(H29, simd.v[29].words.elems[0], v128u16, V29);
|
||||
SUB_REG(H30, simd.v[30].words.elems[0], v128u16, V30);
|
||||
SUB_REG(H31, simd.v[31].words.elems[0], v128u16, V31);
|
||||
|
||||
SUB_REG(S0, simd.v[0].dwords.elems[0], v128u32, V0);
|
||||
SUB_REG(S1, simd.v[1].dwords.elems[0], v128u32, V1);
|
||||
SUB_REG(S2, simd.v[2].dwords.elems[0], v128u32, V2);
|
||||
SUB_REG(S3, simd.v[3].dwords.elems[0], v128u32, V3);
|
||||
SUB_REG(S4, simd.v[4].dwords.elems[0], v128u32, V4);
|
||||
SUB_REG(S5, simd.v[5].dwords.elems[0], v128u32, V5);
|
||||
SUB_REG(S6, simd.v[6].dwords.elems[0], v128u32, V6);
|
||||
SUB_REG(S7, simd.v[7].dwords.elems[0], v128u32, V7);
|
||||
SUB_REG(S8, simd.v[8].dwords.elems[0], v128u32, V8);
|
||||
SUB_REG(S9, simd.v[9].dwords.elems[0], v128u32, V9);
|
||||
SUB_REG(S10, simd.v[10].dwords.elems[0], v128u32, V10);
|
||||
SUB_REG(S11, simd.v[11].dwords.elems[0], v128u32, V11);
|
||||
SUB_REG(S12, simd.v[12].dwords.elems[0], v128u32, V12);
|
||||
SUB_REG(S13, simd.v[13].dwords.elems[0], v128u32, V13);
|
||||
SUB_REG(S14, simd.v[14].dwords.elems[0], v128u32, V14);
|
||||
SUB_REG(S15, simd.v[15].dwords.elems[0], v128u32, V15);
|
||||
SUB_REG(S16, simd.v[16].dwords.elems[0], v128u32, V16);
|
||||
SUB_REG(S17, simd.v[17].dwords.elems[0], v128u32, V17);
|
||||
SUB_REG(S18, simd.v[18].dwords.elems[0], v128u32, V18);
|
||||
SUB_REG(S19, simd.v[19].dwords.elems[0], v128u32, V19);
|
||||
SUB_REG(S20, simd.v[20].dwords.elems[0], v128u32, V20);
|
||||
SUB_REG(S21, simd.v[21].dwords.elems[0], v128u32, V21);
|
||||
SUB_REG(S22, simd.v[22].dwords.elems[0], v128u32, V22);
|
||||
SUB_REG(S23, simd.v[23].dwords.elems[0], v128u32, V23);
|
||||
SUB_REG(S24, simd.v[24].dwords.elems[0], v128u32, V24);
|
||||
SUB_REG(S25, simd.v[25].dwords.elems[0], v128u32, V25);
|
||||
SUB_REG(S26, simd.v[26].dwords.elems[0], v128u32, V26);
|
||||
SUB_REG(S27, simd.v[27].dwords.elems[0], v128u32, V27);
|
||||
SUB_REG(S28, simd.v[28].dwords.elems[0], v128u32, V28);
|
||||
SUB_REG(S29, simd.v[29].dwords.elems[0], v128u32, V29);
|
||||
SUB_REG(S30, simd.v[30].dwords.elems[0], v128u32, V30);
|
||||
SUB_REG(S31, simd.v[31].dwords.elems[0], v128u32, V31);
|
||||
|
||||
SUB_REG(D0, simd.v[0].qwords.elems[0], v128u64, V0);
|
||||
SUB_REG(D1, simd.v[1].qwords.elems[0], v128u64, V1);
|
||||
SUB_REG(D2, simd.v[2].qwords.elems[0], v128u64, V2);
|
||||
SUB_REG(D3, simd.v[3].qwords.elems[0], v128u64, V3);
|
||||
SUB_REG(D4, simd.v[4].qwords.elems[0], v128u64, V4);
|
||||
SUB_REG(D5, simd.v[5].qwords.elems[0], v128u64, V5);
|
||||
SUB_REG(D6, simd.v[6].qwords.elems[0], v128u64, V6);
|
||||
SUB_REG(D7, simd.v[7].qwords.elems[0], v128u64, V7);
|
||||
SUB_REG(D8, simd.v[8].qwords.elems[0], v128u64, V8);
|
||||
SUB_REG(D9, simd.v[9].qwords.elems[0], v128u64, V9);
|
||||
SUB_REG(D10, simd.v[10].qwords.elems[0], v128u64, V10);
|
||||
SUB_REG(D11, simd.v[11].qwords.elems[0], v128u64, V11);
|
||||
SUB_REG(D12, simd.v[12].qwords.elems[0], v128u64, V12);
|
||||
SUB_REG(D13, simd.v[13].qwords.elems[0], v128u64, V13);
|
||||
SUB_REG(D14, simd.v[14].qwords.elems[0], v128u64, V14);
|
||||
SUB_REG(D15, simd.v[15].qwords.elems[0], v128u64, V15);
|
||||
SUB_REG(D16, simd.v[16].qwords.elems[0], v128u64, V16);
|
||||
SUB_REG(D17, simd.v[17].qwords.elems[0], v128u64, V17);
|
||||
SUB_REG(D18, simd.v[18].qwords.elems[0], v128u64, V18);
|
||||
SUB_REG(D19, simd.v[19].qwords.elems[0], v128u64, V19);
|
||||
SUB_REG(D20, simd.v[20].qwords.elems[0], v128u64, V20);
|
||||
SUB_REG(D21, simd.v[21].qwords.elems[0], v128u64, V21);
|
||||
SUB_REG(D22, simd.v[22].qwords.elems[0], v128u64, V22);
|
||||
SUB_REG(D23, simd.v[23].qwords.elems[0], v128u64, V23);
|
||||
SUB_REG(D24, simd.v[24].qwords.elems[0], v128u64, V24);
|
||||
SUB_REG(D25, simd.v[25].qwords.elems[0], v128u64, V25);
|
||||
SUB_REG(D26, simd.v[26].qwords.elems[0], v128u64, V26);
|
||||
SUB_REG(D27, simd.v[27].qwords.elems[0], v128u64, V27);
|
||||
SUB_REG(D28, simd.v[28].qwords.elems[0], v128u64, V28);
|
||||
SUB_REG(D29, simd.v[29].qwords.elems[0], v128u64, V29);
|
||||
SUB_REG(D30, simd.v[30].qwords.elems[0], v128u64, V30);
|
||||
SUB_REG(D31, simd.v[31].qwords.elems[0], v128u64, V31);
|
||||
|
||||
SUB_REG(Q0, simd.v[0].dqwords.elems[0], v128u128, V0);
|
||||
SUB_REG(Q1, simd.v[1].dqwords.elems[0], v128u128, V1);
|
||||
SUB_REG(Q2, simd.v[2].dqwords.elems[0], v128u128, V2);
|
||||
SUB_REG(Q3, simd.v[3].dqwords.elems[0], v128u128, V3);
|
||||
SUB_REG(Q4, simd.v[4].dqwords.elems[0], v128u128, V4);
|
||||
SUB_REG(Q5, simd.v[5].dqwords.elems[0], v128u128, V5);
|
||||
SUB_REG(Q6, simd.v[6].dqwords.elems[0], v128u128, V6);
|
||||
SUB_REG(Q7, simd.v[7].dqwords.elems[0], v128u128, V7);
|
||||
SUB_REG(Q8, simd.v[8].dqwords.elems[0], v128u128, V8);
|
||||
SUB_REG(Q9, simd.v[9].dqwords.elems[0], v128u128, V9);
|
||||
SUB_REG(Q10, simd.v[10].dqwords.elems[0], v128u128, V10);
|
||||
SUB_REG(Q11, simd.v[11].dqwords.elems[0], v128u128, V11);
|
||||
SUB_REG(Q12, simd.v[12].dqwords.elems[0], v128u128, V12);
|
||||
SUB_REG(Q13, simd.v[13].dqwords.elems[0], v128u128, V13);
|
||||
SUB_REG(Q14, simd.v[14].dqwords.elems[0], v128u128, V14);
|
||||
SUB_REG(Q15, simd.v[15].dqwords.elems[0], v128u128, V15);
|
||||
SUB_REG(Q16, simd.v[16].dqwords.elems[0], v128u128, V16);
|
||||
SUB_REG(Q17, simd.v[17].dqwords.elems[0], v128u128, V17);
|
||||
SUB_REG(Q18, simd.v[18].dqwords.elems[0], v128u128, V18);
|
||||
SUB_REG(Q19, simd.v[19].dqwords.elems[0], v128u128, V19);
|
||||
SUB_REG(Q20, simd.v[20].dqwords.elems[0], v128u128, V20);
|
||||
SUB_REG(Q21, simd.v[21].dqwords.elems[0], v128u128, V21);
|
||||
SUB_REG(Q22, simd.v[22].dqwords.elems[0], v128u128, V22);
|
||||
SUB_REG(Q23, simd.v[23].dqwords.elems[0], v128u128, V23);
|
||||
SUB_REG(Q24, simd.v[24].dqwords.elems[0], v128u128, V24);
|
||||
SUB_REG(Q25, simd.v[25].dqwords.elems[0], v128u128, V25);
|
||||
SUB_REG(Q26, simd.v[26].dqwords.elems[0], v128u128, V26);
|
||||
SUB_REG(Q27, simd.v[27].dqwords.elems[0], v128u128, V27);
|
||||
SUB_REG(Q28, simd.v[28].dqwords.elems[0], v128u128, V28);
|
||||
SUB_REG(Q29, simd.v[29].dqwords.elems[0], v128u128, V29);
|
||||
SUB_REG(Q30, simd.v[30].dqwords.elems[0], v128u128, V30);
|
||||
SUB_REG(Q31, simd.v[31].dqwords.elems[0], v128u128, V31);
|
||||
|
||||
REG(TPIDR_EL0, sr.tpidr_el0.qword, u64);
|
||||
REG(TPIDRRO_EL0, sr.tpidrro_el0.qword, u64);
|
||||
}
|
||||
} // namespace remill
|
||||
Reference in New Issue
Block a user