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