aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/arch/SystemZ/SystemZInstPrinter.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /capstone/arch/SystemZ/SystemZInstPrinter.c
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'capstone/arch/SystemZ/SystemZInstPrinter.c')
-rw-r--r--capstone/arch/SystemZ/SystemZInstPrinter.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/capstone/arch/SystemZ/SystemZInstPrinter.c b/capstone/arch/SystemZ/SystemZInstPrinter.c
new file mode 100644
index 000000000..0d992dcb0
--- /dev/null
+++ b/capstone/arch/SystemZ/SystemZInstPrinter.c
@@ -0,0 +1,433 @@
+//===-- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class prints an SystemZ MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
+
+#ifdef CAPSTONE_HAS_SYSZ
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <capstone/platform.h>
+
+#include "SystemZInstPrinter.h"
+#include "../../MCInst.h"
+#include "../../utils.h"
+#include "../../SStream.h"
+#include "../../MCRegisterInfo.h"
+#include "../../MathExtras.h"
+#include "SystemZMapping.h"
+
+static const char *getRegisterName(unsigned RegNo);
+
+void SystemZ_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
+{
+ /*
+ if (((cs_struct *)ud)->detail != CS_OPT_ON)
+ return;
+ */
+}
+
+static void printAddress(MCInst *MI, unsigned Base, int64_t Disp, unsigned Index, SStream *O)
+{
+ printInt64(O, Disp);
+
+ if (Base) {
+ SStream_concat0(O, "(");
+ if (Index)
+ SStream_concat(O, "%%%s, ", getRegisterName(Index));
+ SStream_concat(O, "%%%s)", getRegisterName(Base));
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+ } else if (!Index) {
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Disp;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+ } else {
+ SStream_concat(O, "(%%%s)", getRegisterName(Index));
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+ }
+}
+
+static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
+{
+ if (MCOperand_isReg(MO)) {
+ unsigned reg;
+
+ reg = MCOperand_getReg(MO);
+ SStream_concat(O, "%%%s", getRegisterName(reg));
+ reg = SystemZ_map_register(reg);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_REG;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].reg = reg;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+ } else if (MCOperand_isImm(MO)) {
+ int64_t Imm = MCOperand_getImm(MO);
+
+ printInt64(O, Imm);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Imm;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+ }
+}
+
+static void printU1ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<1>(Value) && "Invalid u1imm argument");
+ printInt64(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU2ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<2>(Value) && "Invalid u2imm argument");
+ printInt64(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU3ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<3>(Value) && "Invalid u4imm argument");
+ printInt64(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU4ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<4>(Value) && "Invalid u4imm argument");
+ printInt64(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU6ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ uint32_t Value = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<6>(Value) && "Invalid u6imm argument");
+
+ printUInt32(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printS8ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int8_t Value = (int8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isInt<8>(Value) && "Invalid s8imm argument");
+
+ if (Value >= 0) {
+ if (Value > HEX_THRESHOLD)
+ SStream_concat(O, "0x%x", Value);
+ else
+ SStream_concat(O, "%u", Value);
+ } else {
+ if (Value < -HEX_THRESHOLD)
+ SStream_concat(O, "-0x%x", -Value);
+ else
+ SStream_concat(O, "-%u", -Value);
+ }
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU8ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ uint8_t Value = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<8>(Value) && "Invalid u8imm argument");
+
+ if (Value > HEX_THRESHOLD)
+ SStream_concat(O, "0x%x", Value);
+ else
+ SStream_concat(O, "%u", Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU12ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<12>(Value) && "Invalid u12imm argument");
+ printInt64(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printS16ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int16_t Value = (int16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isInt<16>(Value) && "Invalid s16imm argument");
+
+ if (Value >= 0) {
+ if (Value > HEX_THRESHOLD)
+ SStream_concat(O, "0x%x", Value);
+ else
+ SStream_concat(O, "%u", Value);
+ } else {
+ if (Value < -HEX_THRESHOLD)
+ SStream_concat(O, "-0x%x", -Value);
+ else
+ SStream_concat(O, "-%u", -Value);
+ }
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU16ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ uint16_t Value = (uint16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<16>(Value) && "Invalid u16imm argument");
+
+ if (Value > HEX_THRESHOLD)
+ SStream_concat(O, "0x%x", Value);
+ else
+ SStream_concat(O, "%u", Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printS32ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int32_t Value = (int32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isInt<32>(Value) && "Invalid s32imm argument");
+
+ printInt32(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU32ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ uint32_t Value = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<32>(Value) && "Invalid u32imm argument");
+
+ printUInt32(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printU48ImmOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(isUInt<48>(Value) && "Invalid u48imm argument");
+ printInt64(O, Value);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printPCRelOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ MCOperand *MO = MCInst_getOperand(MI, OpNum);
+
+ if (MCOperand_isImm(MO)) {
+ int64_t imm = (int64_t)MCOperand_getImm(MO);
+
+ printInt64(O, imm);
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = imm;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+ }
+}
+
+static void printPCRelTLSOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ // Output the PC-relative operand.
+ printPCRelOperand(MI, OpNum, O);
+}
+
+static void printOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ _printOperand(MI, MCInst_getOperand(MI, OpNum), O);
+}
+
+static void printBDAddrOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
+ MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)), 0, O);
+}
+
+static void printBDXAddrOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
+ MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)),
+ MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O);
+}
+
+static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
+ uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
+ uint64_t Length = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 2));
+
+ if (Disp > HEX_THRESHOLD)
+ SStream_concat(O, "0x%"PRIx64, Disp);
+ else
+ SStream_concat(O, "%"PRIu64, Disp);
+
+ if (Length > HEX_THRESHOLD)
+ SStream_concat(O, "(0x%"PRIx64, Length);
+ else
+ SStream_concat(O, "(%"PRIu64, Length);
+
+ if (Base)
+ SStream_concat(O, ", %%%s", getRegisterName(Base));
+ SStream_concat0(O, ")");
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = Length;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printBDRAddrOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
+ uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
+ uint64_t Length = MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2));
+
+ if (Disp > HEX_THRESHOLD)
+ SStream_concat(O, "0x%"PRIx64, Disp);
+ else
+ SStream_concat(O, "%"PRIu64, Disp);
+
+ SStream_concat0(O, "(");
+ SStream_concat(O, "%%%s", getRegisterName(Length));
+
+ if (Base)
+ SStream_concat(O, ", %%%s", getRegisterName(Base));
+ SStream_concat0(O, ")");
+
+ if (MI->csh->detail) {
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = (uint8_t)SystemZ_map_register(Length);
+ MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp;
+ MI->flat_insn->detail->sysz.op_count++;
+ }
+}
+
+static void printBDVAddrOperand(MCInst *MI, int OpNum, SStream *O)
+{
+ printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
+ MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)),
+ MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O);
+}
+
+static void printCond4Operand(MCInst *MI, int OpNum, SStream *O)
+{
+ static const char *const CondNames[] = {
+ "o", "h", "nle", "l", "nhe", "lh", "ne",
+ "e", "nlh", "he", "nl", "le", "nh", "no"
+ };
+
+ uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
+ // assert(Imm > 0 && Imm < 15 && "Invalid condition");
+ SStream_concat0(O, CondNames[Imm - 1]);
+
+ if (MI->csh->detail)
+ MI->flat_insn->detail->sysz.cc = (sysz_cc)Imm;
+}
+
+#define PRINT_ALIAS_INSTR
+#include "SystemZGenAsmWriter.inc"
+
+void SystemZ_printInst(MCInst *MI, SStream *O, void *Info)
+{
+ printInstruction(MI, O, Info);
+}
+
+#endif