diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /capstone/arch/SystemZ/SystemZDisassembler.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'capstone/arch/SystemZ/SystemZDisassembler.c')
-rw-r--r-- | capstone/arch/SystemZ/SystemZDisassembler.c | 484 |
1 files changed, 484 insertions, 0 deletions
diff --git a/capstone/arch/SystemZ/SystemZDisassembler.c b/capstone/arch/SystemZ/SystemZDisassembler.c new file mode 100644 index 000000000..a64a85c4d --- /dev/null +++ b/capstone/arch/SystemZ/SystemZDisassembler.c @@ -0,0 +1,484 @@ +//===------ SystemZDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ + +#ifdef CAPSTONE_HAS_SYSZ + +#include <stdio.h> // DEBUG +#include <stdlib.h> +#include <string.h> + +#include "../../cs_priv.h" +#include "../../utils.h" + +#include "SystemZDisassembler.h" + +#include "../../MCInst.h" +#include "../../MCInstrDesc.h" +#include "../../MCFixedLenDisassembler.h" +#include "../../MCRegisterInfo.h" +#include "../../MCDisassembler.h" +#include "../../MathExtras.h" + +#include "SystemZMCTargetDesc.h" + +static uint64_t getFeatureBits(int mode) +{ + // support everything + return (uint64_t)-1; +} + +static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, const unsigned *Regs) +{ + //assert(RegNo < 16 && "Invalid register"); + RegNo = Regs[RegNo]; + if (RegNo == 0) + return MCDisassembler_Fail; + + MCOperand_CreateReg0(Inst, (unsigned)RegNo); + return MCDisassembler_Success; +} + +static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs); +} + +static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs); +} + +static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs); +} + +static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs); +} + +static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs); +} + +static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs); +} + +static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs); +} + +static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs); +} + +static DecodeStatus DecodeVR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_VR32Regs); +} + +static DecodeStatus DecodeVR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_VR64Regs); +} + +static DecodeStatus DecodeVR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_VR128Regs); +} + +static DecodeStatus DecodeAR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_AR32Regs); +} + +static DecodeStatus DecodeCR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + return decodeRegisterClass(Inst, RegNo, SystemZMC_CR64Regs); +} + +static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm) +{ + //assert(isUInt<N>(Imm) && "Invalid immediate"); + MCOperand_CreateImm0(Inst, Imm); + return MCDisassembler_Success; +} + +static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm, unsigned N) +{ + //assert(isUInt<N>(Imm) && "Invalid immediate"); + MCOperand_CreateImm0(Inst, SignExtend64(Imm, N)); + return MCDisassembler_Success; +} + +static DecodeStatus decodeU1ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU2ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU3ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU6ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU12ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeUImmOperand(Inst, Imm); +} + +static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeSImmOperand(Inst, Imm, 8); +} + +static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeSImmOperand(Inst, Imm, 16); +} + +static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, const void *Decoder) +{ + return decodeSImmOperand(Inst, Imm, 32); +} + +static DecodeStatus decodePCDBLOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, unsigned N) +{ + //assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); + MCOperand_CreateImm0(Inst, SignExtend64(Imm, N) * 2 + Address); + return MCDisassembler_Success; +} + +static DecodeStatus decodePC12DBLBranchOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, + const void *Decoder) +{ + return decodePCDBLOperand(Inst, Imm, Address, 12); +} + +static DecodeStatus decodePC16DBLBranchOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, + const void *Decoder) +{ + return decodePCDBLOperand(Inst, Imm, Address, 16); +} + +static DecodeStatus decodePC24DBLBranchOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, + const void *Decoder) +{ + return decodePCDBLOperand(Inst, Imm, Address, 24); +} + +static DecodeStatus decodePC32DBLBranchOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, + const void *Decoder) +{ + return decodePCDBLOperand(Inst, Imm, Address, 32); +} + +static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm, + uint64_t Address, + const void *Decoder) +{ + return decodePCDBLOperand(Inst, Imm, Address, 32); +} + +static DecodeStatus decodeBDAddr12Operand(MCInst *Inst, uint64_t Field, + const unsigned *Regs) +{ + uint64_t Base = Field >> 12; + uint64_t Disp = Field & 0xfff; + //assert(Base < 16 && "Invalid BDAddr12"); + + MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]); + MCOperand_CreateImm0(Inst, Disp); + + return MCDisassembler_Success; +} + +static DecodeStatus decodeBDAddr20Operand(MCInst *Inst, uint64_t Field, + const unsigned *Regs) +{ + uint64_t Base = Field >> 20; + uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); + //assert(Base < 16 && "Invalid BDAddr20"); + + MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]); + MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20)); + return MCDisassembler_Success; +} + +static DecodeStatus decodeBDXAddr12Operand(MCInst *Inst, uint64_t Field, + const unsigned *Regs) +{ + uint64_t Index = Field >> 16; + uint64_t Base = (Field >> 12) & 0xf; + uint64_t Disp = Field & 0xfff; + + //assert(Index < 16 && "Invalid BDXAddr12"); + MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]); + MCOperand_CreateImm0(Inst, Disp); + MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]); + + return MCDisassembler_Success; +} + +static DecodeStatus decodeBDXAddr20Operand(MCInst *Inst, uint64_t Field, + const unsigned *Regs) +{ + uint64_t Index = Field >> 24; + uint64_t Base = (Field >> 20) & 0xf; + uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); + + //assert(Index < 16 && "Invalid BDXAddr20"); + MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]); + MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20)); + MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]); + + return MCDisassembler_Success; +} + +static DecodeStatus decodeBDLAddr12Len8Operand(MCInst *Inst, uint64_t Field, + const unsigned *Regs) +{ + uint64_t Length = Field >> 16; + uint64_t Base = (Field >> 12) & 0xf; + uint64_t Disp = Field & 0xfff; + //assert(Length < 256 && "Invalid BDLAddr12Len8"); + + MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]); + MCOperand_CreateImm0(Inst, Disp); + MCOperand_CreateImm0(Inst, Length + 1); + + return MCDisassembler_Success; +} + +static DecodeStatus decodeBDRAddr12Operand(MCInst *Inst, uint64_t Field, + const unsigned *Regs) +{ + uint64_t Length = Field >> 16; + uint64_t Base = (Field >> 12) & 0xf; + uint64_t Disp = Field & 0xfff; + //assert(Length < 16 && "Invalid BDRAddr12"); + + MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]); + MCOperand_CreateImm0(Inst, Disp); + MCOperand_CreateReg0(Inst, Regs[Length]); + + return MCDisassembler_Success; +} + +static DecodeStatus decodeBDVAddr12Operand(MCInst *Inst, uint64_t Field, + const unsigned *Regs) +{ + uint64_t Index = Field >> 16; + uint64_t Base = (Field >> 12) & 0xf; + uint64_t Disp = Field & 0xfff; + //assert(Index < 32 && "Invalid BDVAddr12"); + + MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]); + MCOperand_CreateImm0(Inst, Disp); + MCOperand_CreateReg0(Inst, SystemZMC_VR128Regs[Index]); + + return MCDisassembler_Success; +} + +static DecodeStatus decodeBDAddr32Disp12Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR32Regs); +} + +static DecodeStatus decodeBDAddr32Disp20Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR32Regs); +} + +static DecodeStatus decodeBDAddr64Disp12Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR64Regs); +} + +static DecodeStatus decodeBDAddr64Disp20Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR64Regs); +} + +static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDXAddr12Operand(Inst, Field, SystemZMC_GR64Regs); +} + +static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDXAddr20Operand(Inst, Field, SystemZMC_GR64Regs); +} + +static DecodeStatus decodeBDLAddr64Disp12Len4Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs); +} + +static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs); +} + +static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDRAddr12Operand(Inst, Field, SystemZMC_GR64Regs); +} + +static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst *Inst, uint64_t Field, + uint64_t Address, const void *Decoder) +{ + return decodeBDVAddr12Operand(Inst, Field, SystemZMC_GR64Regs); +} + + +#define GET_SUBTARGETINFO_ENUM +#include "SystemZGenSubtargetInfo.inc" +#include "SystemZGenDisassemblerTables.inc" +bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI, + uint16_t *size, uint64_t address, void *info) +{ + uint64_t Inst; + const uint8_t *Table; + uint16_t I; + + // The top 2 bits of the first byte specify the size. + if (*code < 0x40) { + *size = 2; + Table = DecoderTable16; + } else if (*code < 0xc0) { + *size = 4; + Table = DecoderTable32; + } else { + *size = 6; + Table = DecoderTable48; + } + + if (code_len < *size) + // short of input data + return false; + + if (MI->flat_insn->detail) { + memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sysz)+sizeof(cs_sysz)); + } + + // Construct the instruction. + Inst = 0; + for (I = 0; I < *size; ++I) + Inst = (Inst << 8) | code[I]; + + return decodeInstruction(Table, MI, Inst, address, info, 0); +} + +#define GET_REGINFO_ENUM +#define GET_REGINFO_MC_DESC +#include "SystemZGenRegisterInfo.inc" +void SystemZ_init(MCRegisterInfo *MRI) +{ + /* + InitMCRegisterInfo(SystemZRegDesc, 98, RA, PC, + SystemZMCRegisterClasses, 12, + SystemZRegUnitRoots, + 49, + SystemZRegDiffLists, + SystemZRegStrings, + SystemZSubRegIdxLists, + 7, + SystemZSubRegIdxRanges, + SystemZRegEncodingTable); + */ + + MCRegisterInfo_InitMCRegisterInfo(MRI, SystemZRegDesc, 194, + 0, 0, + SystemZMCRegisterClasses, 21, + 0, 0, + SystemZRegDiffLists, + 0, + SystemZSubRegIdxLists, 7, + 0); +} + +#endif |