blob: ce617b77c32257ec77ed0ae33e4536f5f342eb70 [file] [log] [blame]
Nguyen Anh Quynhc80d8402014-05-26 23:02:48 +08001//===-- XCoreInstPrinter.cpp - Convert XCore MCInst to assembly syntax --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This class prints an XCore MCInst to a .s file.
11//
12//===----------------------------------------------------------------------===//
13
14/* Capstone Disassembly Engine */
15/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
16
17#ifdef CAPSTONE_HAS_XCORE
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <inttypes.h>
23
24#include "XCoreInstPrinter.h"
25#include "../../MCInst.h"
26#include "../../utils.h"
27#include "../../SStream.h"
28#include "../../MCRegisterInfo.h"
29#include "../../MathExtras.h"
30#include "XCoreMapping.h"
31
32static const char *getRegisterName(unsigned RegNo);
33
34void XCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
35{
36 /*
37 if (((cs_struct *)ud)->detail != CS_OPT_ON)
38 return;
39 */
40}
41
42static void set_mem_access(MCInst *MI, bool status, int reg)
43{
44 if (MI->csh->detail != CS_OPT_ON)
45 return;
46
47 MI->csh->doing_mem = status;
48 if (status) {
49 if (reg != 0xffff && reg != -0xffff) {
50 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_MEM;
51 if (reg) {
52 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = reg;
53 } else {
54 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = XCORE_REG_INVALID;
55 }
56 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = XCORE_REG_INVALID;
57 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = 0;
58 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = 1;
59 } else {
60 // the last op should be the memory base
61 MI->flat_insn.xcore.op_count--;
62 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_MEM;
63 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].reg;
64 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = XCORE_REG_INVALID;
65 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = 0;
66 if (reg > 0)
67 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = 1;
68 else
69 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = -1;
70 }
71 } else {
72 // done, create the next operand slot
73 MI->flat_insn.xcore.op_count++;
74 }
75}
76
77static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
78{
79 if (MCOperand_isReg(MO)) {
80 unsigned reg;
81
82 reg = MCOperand_getReg(MO);
83 SStream_concat(O, "%s", getRegisterName(reg));
84
85 if (MI->csh->detail) {
86 if (MI->csh->doing_mem) {
87 if (MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base == ARM_REG_INVALID)
88 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = reg;
89 else
90 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = reg;
91 } else {
92 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_REG;
93 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].reg = reg;
94 MI->flat_insn.xcore.op_count++;
95 }
96 }
97 } else if (MCOperand_isImm(MO)) {
98 int32_t Imm = (int32_t)MCOperand_getImm(MO);
99
100 if (Imm >= 0) {
101 if (Imm > HEX_THRESHOLD)
102 SStream_concat(O, "0x%x", Imm);
103 else
104 SStream_concat(O, "%u", Imm);
105 } else {
106 if (Imm < -HEX_THRESHOLD)
107 SStream_concat(O, "-0x%x", -Imm);
108 else
109 SStream_concat(O, "-%u", -Imm);
110 }
111
112 if (MI->csh->detail) {
113 if (MI->csh->doing_mem) {
114 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = Imm;
115 } else {
116 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_IMM;
117 MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].imm = Imm;
118 MI->flat_insn.xcore.op_count++;
119 }
120 }
121 }
122}
123
124static void printOperand(MCInst *MI, int OpNum, SStream *O)
125{
126 _printOperand(MI, MCInst_getOperand(MI, OpNum), O);
127}
128
129static void printInlineJT(MCInst *MI, int OpNum, SStream *O)
130{
131}
132
133static void printInlineJT32(MCInst *MI, int OpNum, SStream *O)
134{
135}
136
137#define PRINT_ALIAS_INSTR
138#include "XCoreGenAsmWriter.inc"
139
140void XCore_printInst(MCInst *MI, SStream *O, void *Info)
141{
142 printInstruction(MI, O, Info);
143}
144
145#endif