qemu/target/hexagon/printinsn.c
<<
>>
Prefs
   1/*
   2 *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
   3 *
   4 *  This program is free software; you can redistribute it and/or modify
   5 *  it under the terms of the GNU General Public License as published by
   6 *  the Free Software Foundation; either version 2 of the License, or
   7 *  (at your option) any later version.
   8 *
   9 *  This program is distributed in the hope that it will be useful,
  10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 *  GNU General Public License for more details.
  13 *
  14 *  You should have received a copy of the GNU General Public License
  15 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  16 */
  17
  18#include "qemu/osdep.h"
  19#include "attribs.h"
  20#include "printinsn.h"
  21#include "insn.h"
  22#include "reg_fields.h"
  23#include "internal.h"
  24
  25static const char *sreg2str(unsigned int reg)
  26{
  27    if (reg < TOTAL_PER_THREAD_REGS) {
  28        return hexagon_regnames[reg];
  29    } else {
  30        return "???";
  31    }
  32}
  33
  34static const char *creg2str(unsigned int reg)
  35{
  36    return sreg2str(reg + HEX_REG_SA0);
  37}
  38
  39static void snprintinsn(GString *buf, Insn *insn)
  40{
  41    switch (insn->opcode) {
  42#define DEF_VECX_PRINTINFO(TAG, FMT, ...) DEF_PRINTINFO(TAG, FMT, __VA_ARGS__)
  43#define DEF_PRINTINFO(TAG, FMT, ...) \
  44    case TAG: \
  45        g_string_append_printf(buf, FMT, __VA_ARGS__); \
  46        break;
  47#include "printinsn_generated.h.inc"
  48#undef DEF_VECX_PRINTINFO
  49#undef DEF_PRINTINFO
  50    }
  51}
  52
  53void snprint_a_pkt_disas(GString *buf, Packet *pkt, uint32_t *words,
  54                         target_ulong pc)
  55{
  56    bool has_endloop0 = false;
  57    bool has_endloop1 = false;
  58    bool has_endloop01 = false;
  59
  60    for (int i = 0; i < pkt->num_insns; i++) {
  61        if (pkt->insn[i].part1) {
  62            continue;
  63        }
  64
  65        /* We'll print the endloop's at the end of the packet */
  66        if (pkt->insn[i].opcode == J2_endloop0) {
  67            has_endloop0 = true;
  68            continue;
  69        }
  70        if (pkt->insn[i].opcode == J2_endloop1) {
  71            has_endloop1 = true;
  72            continue;
  73        }
  74        if (pkt->insn[i].opcode == J2_endloop01) {
  75            has_endloop01 = true;
  76            continue;
  77        }
  78
  79        g_string_append_printf(buf, "0x" TARGET_FMT_lx "\t", words[i]);
  80
  81        if (i == 0) {
  82            g_string_append(buf, "{");
  83        }
  84
  85        g_string_append(buf, "\t");
  86        snprintinsn(buf, &(pkt->insn[i]));
  87
  88        if (i < pkt->num_insns - 1) {
  89            /*
  90             * Subinstructions are two instructions encoded
  91             * in the same word. Print them on the same line.
  92             */
  93            if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN)) {
  94                g_string_append(buf, "; ");
  95                snprintinsn(buf, &(pkt->insn[i + 1]));
  96                i++;
  97            } else if (pkt->insn[i + 1].opcode != J2_endloop0 &&
  98                       pkt->insn[i + 1].opcode != J2_endloop1 &&
  99                       pkt->insn[i + 1].opcode != J2_endloop01) {
 100                pc += 4;
 101                g_string_append_printf(buf, "\n0x" TARGET_FMT_lx ":  ", pc);
 102            }
 103        }
 104    }
 105    g_string_append(buf, " }");
 106    if (has_endloop0) {
 107        g_string_append(buf, "  :endloop0");
 108    }
 109    if (has_endloop1) {
 110        g_string_append(buf, "  :endloop1");
 111    }
 112    if (has_endloop01) {
 113        g_string_append(buf, "  :endloop01");
 114    }
 115}
 116
 117void snprint_a_pkt_debug(GString *buf, Packet *pkt)
 118{
 119    int slot, opcode;
 120
 121    if (pkt->num_insns > 1) {
 122        g_string_append(buf, "\n{\n");
 123    }
 124
 125    for (int i = 0; i < pkt->num_insns; i++) {
 126        if (pkt->insn[i].part1) {
 127            continue;
 128        }
 129        g_string_append(buf, "\t");
 130        snprintinsn(buf, &(pkt->insn[i]));
 131
 132        if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN)) {
 133            g_string_append(buf, " //subinsn");
 134        }
 135        if (pkt->insn[i].extension_valid) {
 136            g_string_append(buf, " //constant extended");
 137        }
 138        slot = pkt->insn[i].slot;
 139        opcode = pkt->insn[i].opcode;
 140        g_string_append_printf(buf, " //slot=%d:tag=%s\n",
 141                               slot, opcode_names[opcode]);
 142    }
 143    if (pkt->num_insns > 1) {
 144        g_string_append(buf, "}\n");
 145    }
 146}
 147