Coverage Report

Created: 2024-08-21 06:24

/src/capstonenext/arch/XCore/XCoreInstPrinter.c
Line
Count
Source (jump to first uncovered line)
1
//===-- 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-2015 */
16
17
#ifdef CAPSTONE_HAS_XCORE
18
19
#ifdef _MSC_VER
20
#pragma warning(disable : 4996)     // disable MSVC's warning on strcpy()
21
#pragma warning(disable : 28719)    // disable MSVC's warning on strcpy()
22
#endif
23
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <capstone/platform.h>
28
29
#include "XCoreInstPrinter.h"
30
#include "../../MCInst.h"
31
#include "../../utils.h"
32
#include "../../SStream.h"
33
#include "../../MCRegisterInfo.h"
34
#include "../../MathExtras.h"
35
#include "XCoreMapping.h"
36
37
static const char *getRegisterName(unsigned RegNo);
38
39
void XCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
40
84.0k
{
41
  /*
42
     if (((cs_struct *)ud)->detail != CS_OPT_ON)
43
     return;
44
   */
45
84.0k
}
46
47
// stw sed, sp[3]
48
void XCore_insn_extract(MCInst *MI, const char *code)
49
3.16k
{
50
3.16k
  int id;
51
3.16k
  char *p, *p2;
52
3.16k
  char tmp[128];
53
54
3.16k
  strcpy(tmp, code); // safe because code is way shorter than 128 bytes
55
56
  // find the first space
57
3.16k
  p = strchr(tmp, ' ');
58
3.16k
  if (p) {
59
2.84k
    p++;
60
    // find the next ','
61
2.84k
    p2 = strchr(p, ',');
62
2.84k
    if (p2) {
63
2.84k
      *p2 = '\0';
64
2.84k
      id = XCore_reg_id(p);
65
2.84k
      if (id) {
66
        // register
67
1.96k
        if (MI->csh->detail_opt) {
68
1.96k
          MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
69
1.96k
          MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = id;
70
1.96k
          MI->flat_insn->detail->xcore.op_count++;
71
1.96k
        }
72
1.96k
      }
73
      // next should be register, or memory?
74
      // skip space
75
2.84k
      p2++;
76
5.69k
      while(*p2 && *p2 == ' ')
77
2.84k
        p2++;
78
2.84k
      if (*p2) {
79
        // find '['
80
2.84k
        p = p2;
81
8.60k
        while(*p && *p != '[')
82
5.75k
          p++;
83
2.84k
        if (*p) {
84
          // this is '['
85
1.91k
          *p = '\0';
86
1.91k
          id = XCore_reg_id(p2);
87
1.91k
          if (id) {
88
            // base register
89
1.91k
            if (MI->csh->detail_opt) {
90
1.91k
              MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM;
91
1.91k
              MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)id;
92
1.91k
              MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID;
93
1.91k
              MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0;
94
1.91k
              MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = 1;
95
1.91k
            }
96
97
1.91k
            p++;
98
1.91k
            p2 = p;
99
            // until ']'
100
3.82k
            while(*p && *p != ']')
101
1.91k
              p++;
102
1.91k
            if (*p) {
103
1.91k
              *p = '\0';
104
              // p2 is either index, or disp
105
1.91k
              id = XCore_reg_id(p2);
106
1.91k
              if (id) {
107
                // index register
108
0
                if (MI->csh->detail_opt) {
109
0
                  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)id;
110
0
                }
111
1.91k
              } else {
112
                // a number means disp
113
1.91k
                if (MI->csh->detail_opt) {
114
1.91k
                  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = atoi(p2);
115
1.91k
                }
116
1.91k
              }
117
1.91k
            }
118
119
1.91k
            if (MI->csh->detail_opt) {
120
1.91k
              MI->flat_insn->detail->xcore.op_count++;
121
1.91k
            }
122
1.91k
          }
123
1.91k
        } else {
124
          // a register?
125
935
          id = XCore_reg_id(p2);
126
935
          if (id) {
127
            // register
128
935
            if (MI->csh->detail_opt) {
129
935
              MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
130
935
              MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = id;
131
935
              MI->flat_insn->detail->xcore.op_count++;
132
935
            }
133
935
          }
134
935
        }
135
2.84k
      }
136
2.84k
    } else {
137
0
      id = XCore_reg_id(p);
138
0
      if (id) {
139
        // register
140
0
        if (MI->csh->detail_opt) {
141
0
          MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
142
0
          MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = id;
143
0
          MI->flat_insn->detail->xcore.op_count++;
144
0
        }
145
0
      }
146
0
    }
147
2.84k
  }
148
3.16k
}
149
150
static void set_mem_access(MCInst *MI, bool status, int reg)
151
167k
{
152
167k
  if (MI->csh->detail_opt != CS_OPT_ON)
153
0
    return;
154
155
167k
  MI->csh->doing_mem = status;
156
167k
  if (status) {
157
42.7k
    if (reg != 0xffff && reg != -0xffff) {
158
24.5k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM;
159
24.5k
      if (reg) {
160
8.11k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)reg;
161
16.4k
      } else {
162
16.4k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = XCORE_REG_INVALID;
163
16.4k
      }
164
24.5k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID;
165
24.5k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0;
166
24.5k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = 1;
167
24.5k
    } else {
168
      // the last op should be the memory base
169
18.1k
      MI->flat_insn->detail->xcore.op_count--;
170
18.1k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM;
171
18.1k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg;
172
18.1k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID;
173
18.1k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0;
174
18.1k
      if (reg > 0)
175
17.3k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = 1;
176
818
      else
177
818
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = -1;
178
18.1k
    }
179
124k
  } else {
180
124k
    if (reg) {
181
3.69k
      MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)reg;
182
      // done, create the next operand slot
183
3.69k
      MI->flat_insn->detail->xcore.op_count++;
184
3.69k
    }
185
124k
  }
186
167k
}
187
188
static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
189
202k
{
190
202k
  if (MCOperand_isReg(MO)) {
191
156k
    unsigned reg;
192
193
156k
    reg = MCOperand_getReg(MO);
194
156k
    SStream_concat0(O, getRegisterName(reg));
195
196
156k
    if (MI->csh->detail_opt) {
197
156k
      if (MI->csh->doing_mem) {
198
17.5k
        if (MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base == ARM_REG_INVALID)
199
11.9k
          MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)reg;
200
5.51k
        else
201
5.51k
          MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)reg;
202
139k
      } else {
203
139k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
204
139k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = reg;
205
139k
        MI->flat_insn->detail->xcore.op_count++;
206
139k
      }
207
156k
    }
208
156k
  } else if (MCOperand_isImm(MO)) {
209
45.4k
    int32_t Imm = (int32_t)MCOperand_getImm(MO);
210
211
45.4k
    printInt32(O, Imm);
212
213
45.4k
    if (MI->csh->detail_opt) {
214
45.4k
      if (MI->csh->doing_mem) {
215
23.3k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = Imm;
216
23.3k
      } else {
217
22.1k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_IMM;
218
22.1k
        MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].imm = Imm;
219
22.1k
        MI->flat_insn->detail->xcore.op_count++;
220
22.1k
      }
221
45.4k
    }
222
45.4k
  }
223
202k
}
224
225
static void printOperand(MCInst *MI, int OpNum, SStream *O)
226
202k
{
227
202k
  if (OpNum >= MI->size)
228
0
    return;
229
230
202k
  _printOperand(MI, MCInst_getOperand(MI, OpNum), O);
231
202k
}
232
233
static void printInlineJT(MCInst *MI, int OpNum, SStream *O)
234
0
{
235
0
}
236
237
static void printInlineJT32(MCInst *MI, int OpNum, SStream *O)
238
0
{
239
0
}
240
241
#define PRINT_ALIAS_INSTR
242
#include "XCoreGenAsmWriter.inc"
243
244
void XCore_printInst(MCInst *MI, SStream *O, void *Info)
245
84.0k
{
246
84.0k
  printInstruction(MI, O, Info);
247
84.0k
  set_mem_access(MI, false, 0);
248
84.0k
}
249
250
#endif