Coverage Report

Created: 2025-08-26 06:30

/src/capstonenext/arch/Sparc/SparcMapping.c
Line
Count
Source (jump to first uncovered line)
1
/* Capstone Disassembly Engine */
2
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
3
4
#ifdef CAPSTONE_HAS_SPARC
5
6
#include <stdio.h> // debug
7
#include <string.h>
8
9
#include "../../Mapping.h"
10
#include "../../utils.h"
11
#include "../../cs_simple_types.h"
12
13
#include "SparcMapping.h"
14
15
void Sparc_init_cs_detail(MCInst *MI)
16
48.0k
{
17
48.0k
  if (!detail_is_set(MI)) {
18
0
    return;
19
0
  }
20
48.0k
  memset(get_detail(MI), 0, offsetof(cs_detail, sparc) + sizeof(cs_sparc));
21
48.0k
  Sparc_get_detail(MI)->cc = SPARC_CC_UNDEF;
22
48.0k
  Sparc_get_detail(MI)->cc_field = SPARC_CC_FIELD_NONE;
23
48.0k
}
24
25
const insn_map sparc_insns[] = {
26
#include "SparcGenCSMappingInsn.inc"
27
};
28
29
void Sparc_set_instr_map_data(MCInst *MI)
30
48.0k
{
31
48.0k
  map_cs_id(MI, sparc_insns, ARR_SIZE(sparc_insns));
32
48.0k
  map_implicit_reads(MI, sparc_insns);
33
48.0k
  map_implicit_writes(MI, sparc_insns);
34
48.0k
  map_groups(MI, sparc_insns);
35
48.0k
  const sparc_suppl_info *suppl_info =
36
48.0k
    map_get_suppl_info(MI, sparc_insns);
37
48.0k
  if (suppl_info) {
38
48.0k
    Sparc_get_detail(MI)->format = suppl_info->form;
39
48.0k
  }
40
48.0k
}
41
42
/// Adds details which are not defined consistently as LLVM operands like
43
/// condition codes for alias instructions or branch hint bits.
44
static void Sparc_add_bit_details(MCInst *MI, const uint8_t *Bytes,
45
          size_t BytesLen)
46
48.0k
{
47
48.0k
  if (!Bytes || BytesLen < 4 || !detail_is_set(MI)) {
48
645
    return;
49
645
  }
50
47.4k
  uint32_t insn = readBytes32(MI, Bytes);
51
52
  // CC field
53
47.4k
  cs_sparc *detail = Sparc_get_detail(MI);
54
47.4k
  switch (detail->format) {
55
31.8k
  default:
56
31.8k
    break;
57
31.8k
  case SPARC_INSN_FORM_F2_2: {
58
    // This format is used either by B or FB instructions.
59
    // The op2 == 6 for the FB and 2 for B.
60
    // This is the only indicator we have here to determine which CC field is used
61
    // if we don't want big switch cases.
62
    //
63
    // See: Opcode Maps - Table 39 - Sparc V9 ISA
64
6.16k
    size_t op2 = get_insn_field_r(insn, 22, 24);
65
6.16k
    detail->cc_field = op2 == 6 ? SPARC_CC_FIELD_FCC0 : SPARC_CC_FIELD_ICC;
66
6.16k
    break;
67
0
  }
68
6.63k
  case SPARC_INSN_FORM_F2_3:
69
6.63k
    detail->cc_field = get_insn_field_r(insn, 20, 21);
70
6.63k
    if (get_insn_field_r(insn, 22, 24) == 1) {
71
      // BPcc and FBPcc encode their fields in two bits.
72
      // BPcc needs the upper bit set to match our CC field enum.
73
4.10k
      detail->cc_field |= 0x4;
74
4.10k
    }
75
6.63k
    break;
76
506
  case SPARC_INSN_FORM_TRAPSP:
77
506
    detail->cc_field = 0x4 | get_insn_field_r(insn, 11, 12);
78
506
    break;
79
1.04k
  case SPARC_INSN_FORM_F4_1:
80
1.62k
  case SPARC_INSN_FORM_F4_2:
81
1.62k
    detail->cc_field = get_insn_field_r(insn, 11, 12);
82
1.62k
    detail->cc_field |= get_insn_field_r(insn, 18, 18) << 2;
83
1.62k
    break;
84
643
  case SPARC_INSN_FORM_F4_3:
85
643
    detail->cc_field = get_insn_field_r(insn, 11, 13);
86
643
    break;
87
47.4k
  }
88
89
  // Condition codes
90
47.4k
  switch (detail->format) {
91
25.0k
  default:
92
25.0k
    break;
93
25.0k
  case SPARC_INSN_FORM_F2_1:
94
11.2k
  case SPARC_INSN_FORM_F2_2:
95
17.8k
  case SPARC_INSN_FORM_F2_3:
96
18.3k
  case SPARC_INSN_FORM_TRAPSP: {
97
    // cond
98
    // Alias instructions don't define the conditions as operands.
99
    // We need to add them here to the details again.
100
18.3k
    sparc_cc cc = get_insn_field_r(insn, 25, 28);
101
18.3k
    if (MCInst_getOpcode(MI) == Sparc_CBCOND ||
102
18.3k
        MCInst_getOpcode(MI) == Sparc_CBCONDA) {
103
3.80k
      cc += SPARC_CC_CPCC_BEGIN;
104
3.80k
    }
105
18.3k
    detail->cc = cc;
106
18.3k
    break;
107
17.8k
  }
108
1.04k
  case SPARC_INSN_FORM_F4_1:
109
1.62k
  case SPARC_INSN_FORM_F4_2:
110
2.27k
  case SPARC_INSN_FORM_F4_3: {
111
2.27k
    sparc_cc cc = get_insn_field_r(insn, 14, 17);
112
2.27k
    detail->cc = cc;
113
2.27k
    break;
114
1.62k
  }
115
1.57k
  case SPARC_INSN_FORM_F2_4: {
116
    // cond
117
    // Alias instructions don't define the conditions as operands.
118
    // We need to add them here to the details again.
119
1.57k
    sparc_cc rcc = get_insn_field_r(insn, 25, 27);
120
1.57k
    detail->cc = rcc + SPARC_CC_REG_BEGIN;
121
1.57k
    break;
122
1.62k
  }
123
88
  case SPARC_INSN_FORM_F4_4R:
124
197
  case SPARC_INSN_FORM_F4_4I: {
125
197
    sparc_cc rcc = get_insn_field_r(insn, 10, 12);
126
197
    detail->cc = rcc + SPARC_CC_REG_BEGIN;
127
197
    break;
128
88
  }
129
47.4k
  }
130
47.4k
  switch (detail->cc_field) {
131
31.8k
  default:
132
39.0k
  case SPARC_CC_FIELD_ICC:
133
41.3k
  case SPARC_CC_FIELD_XCC:
134
41.3k
    break;
135
3.45k
  case SPARC_CC_FIELD_FCC0:
136
4.51k
  case SPARC_CC_FIELD_FCC1:
137
4.94k
  case SPARC_CC_FIELD_FCC2:
138
6.10k
  case SPARC_CC_FIELD_FCC3:
139
6.10k
    detail->cc += SPARC_CC_FCC_BEGIN;
140
6.10k
    break;
141
47.4k
  }
142
143
  // Hints
144
47.4k
  switch (detail->format) {
145
33.0k
  default:
146
33.0k
    break;
147
33.0k
  case SPARC_INSN_FORM_F2_2:
148
6.16k
    detail->hint = get_insn_field_r(insn, 29, 29);
149
6.16k
    break;
150
6.63k
  case SPARC_INSN_FORM_F2_3:
151
8.20k
  case SPARC_INSN_FORM_F2_4:
152
8.20k
    detail->hint = get_insn_field_r(insn, 29, 29);
153
8.20k
    detail->hint |=
154
8.20k
      get_insn_field_r(insn, 19, 19) == 0 ? SPARC_HINT_PN :
155
8.20k
                    SPARC_HINT_PT;
156
8.20k
    break;
157
47.4k
  }
158
47.4k
}
159
160
bool Sparc_getInstruction(csh handle, const uint8_t *code, size_t code_len,
161
        MCInst *instr, uint16_t *size, uint64_t address,
162
        void *info)
163
48.0k
{
164
48.0k
  Sparc_init_cs_detail(instr);
165
48.0k
  bool Result = Sparc_LLVM_getInstruction(handle, code, code_len, instr,
166
48.0k
            size, address,
167
48.0k
            info) != MCDisassembler_Fail;
168
48.0k
  Sparc_set_instr_map_data(instr);
169
170
48.0k
  Sparc_add_bit_details(instr, code, code_len);
171
48.0k
  return Result;
172
48.0k
}
173
174
void Sparc_init_mri(MCRegisterInfo *MRI)
175
1.70k
{
176
1.70k
  MCRegisterInfo_InitMCRegisterInfo(
177
1.70k
    MRI, SparcRegDesc, sizeof(SparcRegDesc), 0, 0,
178
1.70k
    SparcMCRegisterClasses, ARR_SIZE(SparcMCRegisterClasses), 0, 0,
179
1.70k
    SparcRegDiffLists, 0, SparcSubRegIdxLists,
180
1.70k
    ARR_SIZE(SparcSubRegIdxLists), 0);
181
1.70k
}
182
183
const char *Sparc_reg_name(csh handle, unsigned int reg)
184
19.5k
{
185
19.5k
  int syntax_opt = ((cs_struct *)(uintptr_t)handle)->syntax;
186
187
19.5k
  if (syntax_opt & CS_OPT_SYNTAX_NOREGNAME) {
188
0
    return Sparc_LLVM_getRegisterName(reg, Sparc_NoRegAltName);
189
0
  }
190
19.5k
  return Sparc_LLVM_getRegisterName(reg, Sparc_RegNamesStateReg);
191
19.5k
}
192
193
void Sparc_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
194
47.0k
{
195
  // Not used by Sparc. Information is set after disassembly.
196
47.0k
}
197
198
static const char *const insn_name_maps[] = {
199
#include "SparcGenCSMappingInsnName.inc"
200
};
201
202
#ifndef CAPSTONE_DIET
203
static const name_map insn_alias_mnem_map[] = {
204
#include "SparcGenCSAliasMnemMap.inc"
205
  { SPARC_INS_ALIAS_CALL, "call" },
206
  { SPARC_INS_ALIAS_END, NULL },
207
};
208
#endif
209
210
static void insert_op(MCInst *MI, unsigned index, cs_sparc_op op)
211
1.17k
{
212
1.17k
  if (!detail_is_set(MI)) {
213
0
    return;
214
0
  }
215
1.17k
  Sparc_check_safe_inc(MI);
216
217
1.17k
  cs_sparc_op *ops = Sparc_get_detail(MI)->operands;
218
1.17k
  int i = Sparc_get_detail(MI)->op_count;
219
1.17k
  if (index == -1) {
220
1.03k
    ops[i] = op;
221
1.03k
    Sparc_inc_op_count(MI);
222
1.03k
    return;
223
1.03k
  }
224
276
  for (; i > 0 && i > index; --i) {
225
138
    ops[i] = ops[i - 1];
226
138
  }
227
138
  ops[index] = op;
228
138
  Sparc_inc_op_count(MI);
229
138
}
230
231
/// Inserts a register to the detail operands at @index.
232
/// Already present operands are moved.
233
/// If @index is -1 the operand is appended.
234
static void Sparc_insert_detail_op_reg_at(MCInst *MI, unsigned index, sparc_reg Reg,
235
         cs_ac_type access)
236
1.17k
{
237
1.17k
  if (!detail_is_set(MI))
238
0
    return;
239
240
1.17k
  cs_sparc_op op = { 0 };
241
1.17k
  op.type = SPARC_OP_REG;
242
1.17k
  op.reg = Reg;
243
1.17k
  op.access = access;
244
1.17k
  insert_op(MI, index, op);
245
1.17k
}
246
247
static void Sparc_correct_details(MCInst *MI)
248
47.0k
{
249
47.0k
  if (!detail_is_set(MI)) {
250
0
    return;
251
0
  }
252
47.0k
  switch (MCInst_getOpcode(MI)) {
253
45.3k
  default:
254
45.3k
    return;
255
45.3k
  case Sparc_LDSTUBri:
256
118
  case Sparc_LDSTUBrr:
257
422
  case Sparc_LDSTUBAri:
258
572
  case Sparc_LDSTUBArr:
259
    // The memory gets written back with ones
260
    // but there is not write back memory operand defined
261
    // (if even possible).
262
572
    Sparc_get_detail(MI)->operands[0].access = CS_AC_READ_WRITE;
263
572
    break;
264
37
  case Sparc_RDPSR:
265
37
    Sparc_insert_detail_op_reg_at(MI, 0, SPARC_REG_PSR, CS_AC_READ);
266
37
    break;
267
20
  case Sparc_PWRPSRri:
268
90
  case Sparc_PWRPSRrr:
269
238
  case Sparc_WRPSRri:
270
825
  case Sparc_WRPSRrr:
271
825
    Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_PSR, CS_AC_WRITE);
272
825
    break;
273
91
  case Sparc_RDWIM:
274
91
    Sparc_insert_detail_op_reg_at(MI, 0, SPARC_REG_WIM, CS_AC_READ);
275
91
    break;
276
23
  case Sparc_WRWIMri:
277
112
  case Sparc_WRWIMrr:
278
112
    Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_WIM, CS_AC_WRITE);
279
112
    break;
280
10
  case Sparc_RDTBR:
281
10
    Sparc_insert_detail_op_reg_at(MI, 0, SPARC_REG_TBR, CS_AC_READ);
282
10
    break;
283
69
  case Sparc_WRTBRri:
284
95
  case Sparc_WRTBRrr:
285
95
    Sparc_insert_detail_op_reg_at(MI, -1, SPARC_REG_TBR, CS_AC_WRITE);
286
95
    break;
287
47.0k
  }
288
47.0k
}
289
290
void Sparc_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
291
47.0k
{
292
47.0k
  MCRegisterInfo *MRI = (MCRegisterInfo *)info;
293
47.0k
  MI->MRI = MRI;
294
47.0k
  MI->flat_insn->usesAliasDetails = map_use_alias_details(MI);
295
47.0k
  Sparc_LLVM_printInst(MI, MI->address, "", O);
296
297
47.0k
#ifndef CAPSTONE_DIET
298
47.0k
  map_set_alias_id(MI, O, insn_alias_mnem_map,
299
47.0k
       ARR_SIZE(insn_alias_mnem_map));
300
47.0k
  Sparc_correct_details(MI);
301
47.0k
#endif
302
47.0k
}
303
304
const char *Sparc_insn_name(csh handle, unsigned int id)
305
47.0k
{
306
47.0k
#ifndef CAPSTONE_DIET
307
47.0k
  if (id < SPARC_INS_ALIAS_END && id > SPARC_INS_ALIAS_BEGIN) {
308
0
    if (id - SPARC_INS_ALIAS_BEGIN >= ARR_SIZE(insn_alias_mnem_map))
309
0
      return NULL;
310
311
0
    return insn_alias_mnem_map[id - SPARC_INS_ALIAS_BEGIN - 1].name;
312
0
  }
313
47.0k
  if (id >= SPARC_INS_ENDING)
314
0
    return NULL;
315
316
47.0k
  if (id < ARR_SIZE(insn_name_maps))
317
47.0k
    return insn_name_maps[id];
318
  // not found
319
0
  return NULL;
320
#else
321
  return NULL;
322
#endif
323
47.0k
}
324
325
#ifndef CAPSTONE_DIET
326
static const name_map group_name_maps[] = {
327
  { SPARC_GRP_INVALID, NULL },
328
329
  { SPARC_GRP_JUMP, "jump" },
330
  { SPARC_GRP_CALL, "call" },
331
  { SPARC_GRP_RET, "return" },
332
  { SPARC_GRP_INT, "int" },
333
  { SPARC_GRP_IRET, "iret" },
334
  { SPARC_GRP_PRIVILEGE, "privilege" },
335
  { SPARC_GRP_BRANCH_RELATIVE, "branch_relative" },
336
337
// architecture-specific groups
338
#include "SparcGenCSFeatureName.inc"
339
};
340
#endif
341
342
const char *Sparc_group_name(csh handle, unsigned int id)
343
113k
{
344
113k
#ifndef CAPSTONE_DIET
345
113k
  return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
346
#else
347
  return NULL;
348
#endif
349
113k
}
350
351
static const map_insn_ops insn_operands[] = {
352
#include "SparcGenCSMappingInsnOp.inc"
353
};
354
355
void Sparc_set_detail_op_imm(MCInst *MI, unsigned OpNum, sparc_op_type ImmType,
356
           int64_t Imm)
357
27.7k
{
358
27.7k
  if (!detail_is_set(MI))
359
0
    return;
360
27.7k
  CS_ASSERT_RET((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_IMM);
361
27.7k
  CS_ASSERT_RET(ImmType == SPARC_OP_IMM);
362
363
27.7k
  Sparc_get_detail_op(MI, 0)->type = ImmType;
364
27.7k
  Sparc_get_detail_op(MI, 0)->imm = Imm;
365
27.7k
  Sparc_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
366
27.7k
  Sparc_inc_op_count(MI);
367
27.7k
}
368
369
void Sparc_set_detail_op_reg(MCInst *MI, unsigned OpNum, sparc_reg Reg)
370
36.9k
{
371
36.9k
  if (!detail_is_set(MI))
372
0
    return;
373
36.9k
  CS_ASSERT_RET((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_REG);
374
375
36.9k
  switch (Reg) {
376
33.4k
  default:
377
33.4k
    Sparc_get_detail_op(MI, 0)->type = SPARC_OP_REG;
378
33.4k
    Sparc_get_detail_op(MI, 0)->reg = Reg;
379
33.4k
    Sparc_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
380
33.4k
    Sparc_inc_op_count(MI);
381
33.4k
    return;
382
  // The LLVM definition is inconsistent with the cc fields.
383
  // Sometimes they are encoded as register, sometimes not at all.
384
  // For Capstone they are always saved in the cc_field field for now.
385
0
  case SPARC_REG_ICC:
386
0
    Sparc_get_detail(MI)->cc_field = SPARC_CC_FIELD_ICC;
387
0
    break;
388
398
  case SPARC_REG_FCC0:
389
398
    Sparc_get_detail(MI)->cc_field = SPARC_CC_FIELD_FCC0;
390
398
    break;
391
1.06k
  case SPARC_REG_FCC1:
392
1.06k
    Sparc_get_detail(MI)->cc_field = SPARC_CC_FIELD_FCC1;
393
1.06k
    break;
394
878
  case SPARC_REG_FCC2:
395
878
    Sparc_get_detail(MI)->cc_field = SPARC_CC_FIELD_FCC2;
396
878
    break;
397
1.16k
  case SPARC_REG_FCC3:
398
1.16k
    Sparc_get_detail(MI)->cc_field = SPARC_CC_FIELD_FCC3;
399
1.16k
    break;
400
36.9k
  }
401
36.9k
}
402
403
static inline bool is_single_reg_mem_case(MCInst *MI, unsigned OpNo)
404
21.1k
{
405
21.1k
  if (map_get_op_type(MI, OpNo) != CS_OP_MEM_REG) {
406
5.75k
    return false;
407
5.75k
  }
408
15.4k
  cs_sparc_op *prev_op = Sparc_get_detail_op(MI, -1);
409
15.4k
  if (prev_op && prev_op->type == SPARC_OP_MEM) {
410
14.6k
    return false;
411
14.6k
  }
412
835
  if (MI->size == 1) {
413
0
    return true;
414
835
  } else if (MI->size > OpNo + 1 && Sparc_get_detail(MI)->operands[0].type != SPARC_OP_MEM) {
415
    // Next operand is not a memory operand (disponent or index reg).
416
669
    return !(map_get_op_type(MI, OpNo + 1) & SPARC_OP_MEM);
417
669
  }
418
166
  return false;
419
835
}
420
421
void Sparc_add_cs_detail_0(MCInst *MI, sparc_op_group op_group, unsigned OpNo)
422
115k
{
423
115k
  if (!detail_is_set(MI) || !map_fill_detail_ops(MI))
424
0
    return;
425
426
115k
  cs_op_type op_type = map_get_op_type(MI, OpNo);
427
428
115k
  switch (op_group) {
429
0
  default:
430
0
  case Sparc_OP_GROUP_GetPCX:
431
0
    printf("Operand group %d not handled!\n", op_group);
432
0
    return;
433
85.9k
  case Sparc_OP_GROUP_Operand:
434
85.9k
    if (op_type & CS_OP_MEM) {
435
21.1k
      if (is_single_reg_mem_case(MI, OpNo)) {
436
669
        Sparc_get_detail_op(MI, 0)->type = SPARC_OP_MEM;
437
669
        Sparc_get_detail_op(MI, 0)->mem.base =
438
669
          MCInst_getOpVal(MI, OpNo);
439
669
        Sparc_get_detail_op(MI, 0)->access =
440
669
          map_get_op_access(MI, OpNo);
441
669
        Sparc_inc_op_count(MI);
442
669
      }
443
21.1k
      break;
444
21.1k
    }
445
64.7k
    if (op_type == CS_OP_IMM) {
446
27.7k
      Sparc_set_detail_op_imm(MI, OpNo, SPARC_OP_IMM,
447
27.7k
            MCInst_getOpVal(MI, OpNo));
448
36.9k
    } else if (op_type == CS_OP_REG) {
449
36.9k
      Sparc_set_detail_op_reg(MI, OpNo,
450
36.9k
            MCInst_getOpVal(MI, OpNo));
451
36.9k
    } else {
452
0
      CS_ASSERT_RET(0 && "Op type not handled.");
453
0
    }
454
64.7k
    Sparc_get_detail_op(MI, 0)->access =
455
64.7k
      map_get_op_access(MI, OpNo);
456
64.7k
    break;
457
13.6k
  case Sparc_OP_GROUP_CCOperand: {
458
    // Handled in Sparc_add_bit_details().
459
13.6k
    break;
460
85.9k
  }
461
11.4k
  case Sparc_OP_GROUP_MemOperand: {
462
11.4k
    cs_sparc_op *prev_op = Sparc_get_detail_op(MI, -1);
463
11.4k
    if (prev_op && prev_op->type == SPARC_OP_MEM) {
464
      // Already added.
465
0
      break;
466
0
    }
467
11.4k
    MCOperand *Op1 = MCInst_getOperand(MI, (OpNo));
468
11.4k
    MCOperand *Op2 = MCInst_getOperand(MI, (OpNo + 1));
469
11.4k
    if (!MCOperand_isReg(Op1) ||
470
11.4k
        MCOperand_getReg(Op1) == Sparc_G0) {
471
      // Ignored
472
702
      return;
473
702
    }
474
10.7k
    Sparc_get_detail_op(MI, 0)->type = SPARC_OP_MEM;
475
10.7k
    Sparc_get_detail_op(MI, 0)->access =
476
10.7k
      map_get_op_access(MI, OpNo);
477
10.7k
    Sparc_get_detail_op(MI, 0)->mem.base = MCOperand_getReg(Op1);
478
479
10.7k
    if (MCOperand_isReg(Op2) && MCOperand_getReg(Op2) != Sparc_G0) {
480
3.85k
      Sparc_get_detail_op(MI, 0)->mem.index =
481
3.85k
        MCOperand_getReg(Op2);
482
6.89k
    } else if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) != 0) {
483
5.47k
      Sparc_get_detail_op(MI, 0)->mem.disp =
484
5.47k
        MCOperand_getImm(Op2);
485
5.47k
    }
486
10.7k
    Sparc_inc_op_count(MI);
487
10.7k
    break;
488
11.4k
  }
489
3.70k
  case Sparc_OP_GROUP_ASITag:
490
3.70k
    Sparc_get_detail_op(MI, 0)->type = SPARC_OP_ASI;
491
3.70k
    Sparc_get_detail_op(MI, 0)->access =
492
3.70k
      map_get_op_access(MI, OpNo);
493
3.70k
    Sparc_get_detail_op(MI, 0)->asi =
494
3.70k
      MCOperand_getImm(MCInst_getOperand(MI, OpNo));
495
3.70k
    Sparc_inc_op_count(MI);
496
3.70k
    break;
497
288
  case Sparc_OP_GROUP_MembarTag:
498
288
    Sparc_get_detail_op(MI, 0)->type = SPARC_OP_MEMBAR_TAG;
499
288
    Sparc_get_detail_op(MI, 0)->access =
500
288
      map_get_op_access(MI, OpNo);
501
288
    Sparc_get_detail_op(MI, 0)->membar_tag =
502
288
      MCOperand_getImm(MCInst_getOperand(MI, OpNo));
503
288
    Sparc_inc_op_count(MI);
504
288
    break;
505
115k
  }
506
115k
}
507
508
#endif