1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* -*- mode: C; c-basic-offset: 3; -*- */ 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------------------------------------------------*/ 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- begin s390_disasm.c ---*/ 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------------------------------------------------*/ 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov This file is part of Valgrind, a dynamic binary instrumentation 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov framework. 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright IBM Corp. 2010-2013 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov This program is free software; you can redistribute it and/or 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modify it under the terms of the GNU General Public License as 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov published by the Free Software Foundation; either version 2 of the 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov License, or (at your option) any later version. 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov This program is distributed in the hope that it will be useful, but 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov WITHOUT ANY WARRANTY; without even the implied warranty of 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov General Public License for more details. 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov You should have received a copy of the GNU General Public License 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov along with this program; if not, write to the Free Software 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 02110-1301, USA. 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov The GNU General Public License is contained in the file COPYING. 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Contributed by Florian Krohm */ 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdarg.h> 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "libvex_basictypes.h" 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "main_util.h" // vassert 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "main_globals.h" // vex_traceflags 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "s390_defs.h" // S390_MAX_MNEMONIC_LEN 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "s390_disasm.h" 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Return the mnemonic padded with blanks to its right */ 42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar * 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmnemonic(const HChar *mnm) 44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(vex_strlen(mnm) <= S390_MAX_MNEMONIC_LEN); 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vex_sprintf(buf, "%-*s", S390_MAX_MNEMONIC_LEN, mnm); 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return buf; 52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the name of a general purpose register for dis-assembly purposes. */ 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovgpr_operand(UInt archreg) 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov static const HChar names[16][5] = { 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%r0", "%r1", "%r2", "%r3", 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%r4", "%r5", "%r6", "%r7", 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%r8", "%r9", "%r10", "%r11", 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%r12", "%r13", "%r14", "%r15", 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }; 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(archreg < 16); 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return names[archreg]; 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the name of a floating point register for dis-assembly purposes. */ 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovfpr_operand(UInt archreg) 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov static const HChar names[16][5] = { 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%f0", "%f1", "%f2", "%f3", 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%f4", "%f5", "%f6", "%f7", 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%f8", "%f9", "%f10", "%f11", 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%f12", "%f13", "%f14", "%f15", 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }; 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(archreg < 16); 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return names[archreg]; 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the name of an access register for dis-assembly purposes. */ 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovar_operand(UInt archreg) 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov static const HChar names[16][5] = { 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%a0", "%a1", "%a2", "%a3", 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%a4", "%a5", "%a6", "%a7", 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%a8", "%a9", "%a10", "%a11", 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "%a12", "%a13", "%a14", "%a15", 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }; 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(archreg < 16); 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return names[archreg]; 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Build and return the extended mnemonic for the compare and branch 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov opcodes as introduced by z10. See also the opcodes in file 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov opcodes/s390-opc.txt (from binutils) that have a '$' in their name. */ 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovcab_operand(const HChar *base, UInt mask) 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar *to; 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar *from; 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov static const HChar suffix[8][3] = { 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "", "h", "l", "ne", "e", "nl", "nh", "" 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }; 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Guard against buffer overflow */ 122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(vex_strlen(base) + sizeof suffix[0] <= sizeof buf); 123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* strcpy(buf, from); */ 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (from = base, to = buf; *from; ++from, ++to) { 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *to = *from; 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* strcat(buf, suffix); */ 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (from = suffix[mask >> 1]; *from; ++from, ++to) { 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *to = *from; 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *to = '\0'; 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return buf; 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Common function used to construct a mnemonic based on a condition code 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mask. */ 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovconstruct_mnemonic(const HChar *prefix, const HChar *suffix, UInt mask) 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar *to; 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar *from; 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov static HChar mask_id[16][4] = { 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "", /* 0 -> unused */ 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "o", "h", "nle", "l", "nhe", "lh", "ne", 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "e", "nlh", "he", "nl", "le", "nh", "no", 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "" /* 15 -> unused */ 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }; 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Guard against buffer overflow */ 156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vassert(vex_strlen(prefix) + vex_strlen(suffix) + 157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sizeof mask_id[0] <= sizeof buf); 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* strcpy(buf, prefix); */ 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (from = prefix, to = buf; *from; ++from, ++to) { 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *to = *from; 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* strcat(buf, mask_id); */ 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (from = mask_id[mask]; *from; ++from, ++to) { 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *to = *from; 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* strcat(buf, suffix); */ 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (from = suffix; *from; ++from, ++to) { 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *to = *from; 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *to = '\0'; 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return buf; 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the special mnemonic for the BCR opcode */ 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovbcr_operand(UInt m1) 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 0) return "nopr"; 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 15) return "br"; 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return construct_mnemonic("b", "r", m1); 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the special mnemonic for the BC opcode */ 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovbc_operand(UInt m1) 191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 0) return "nop"; 193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 15) return "b"; 194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return construct_mnemonic("b", "", m1); 196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the special mnemonic for the BRC opcode */ 200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovbrc_operand(UInt m1) 202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 0) return "brc"; 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 15) return "j"; 205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return construct_mnemonic("j", "", m1); 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the special mnemonic for the BRCL opcode */ 211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovbrcl_operand(UInt m1) 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 0) return "brcl"; 215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m1 == 15) return "jg"; 216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return construct_mnemonic("jg", "", m1); 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the special mnemonic for a conditional load/store opcode */ 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const HChar * 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovcls_operand(Int kind, UInt mask) 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar *prefix; 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (kind) { 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOCR: prefix = "locr"; break; 229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOCGR: prefix = "locgr"; break; 230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOC: prefix = "loc"; break; 231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOCG: prefix = "locg"; break; 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_STOC: prefix = "stoc"; break; 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_STOCG: prefix = "stocg"; break; 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vpanic("cls_operand"); 236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return construct_mnemonic(prefix, "", mask); 239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* An operand with a base register, an index register, and a displacement. 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov If the displacement is signed, the rightmost 20 bit of D need to be 244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sign extended */ 245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HChar * 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovdxb_operand(HChar *p, UInt d, UInt x, UInt b, Bool displacement_is_signed) 247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (displacement_is_signed) { 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int displ = ((Int)d << 12) >> 12; /* sign extend */ 250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%d", displ); 252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%u", d); 254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (x != 0) { 256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "(%s", gpr_operand(x)); 257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (b != 0) { 258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ",%s", gpr_operand(b)); 259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ")"); 261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (b != 0) { 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "(%s)", gpr_operand(b)); 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return p; 268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* An operand with base register, unsigned length, and a 12-bit 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned displacement */ 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HChar * 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovudlb_operand(HChar *p, UInt d, UInt length, UInt b) 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%u", d); 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "(%u", length + 1); // actual length is +1 278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (b != 0) { 279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ",%s", gpr_operand(b)); 280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ")"); 282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return p; 284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* The first argument is the command that says how to write the disassembled 288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov insn. It is understood that the mnemonic comes first and that arguments 289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov are separated by a ','. The command holds the arguments. Each argument is 290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov encoded using a 4-bit S390_ARG_xyz value. The first argument is placed 291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov in the least significant bits of the command and so on. There are at most 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 5 arguments in an insn and a sentinel (S390_ARG_DONE) is needed to identify 293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the end of the argument list. 6 * 4 = 24 bits are required for the 294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov command. */ 295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid 296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovs390_disasm(UInt command, ...) 297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_list args; 299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt argkind; 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar buf[128]; /* holds the disassembled insn */ 301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar *p; 302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar separator; 303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int mask_suffix = -1; 304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_start(args, command); 306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = buf; 308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov separator = 0; 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (42) { 311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov argkind = command & 0xF; 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov command >>= 4; 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (argkind == S390_ARG_DONE) goto done; 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (argkind == S390_ARG_CABM) separator = 0; /* optional */ 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Write out the separator */ 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (separator) *p++ = separator; 320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* argument */ 322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (argkind) { 323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_MNM: 324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov p += vex_sprintf(p, "%s", mnemonic(va_arg(args, HChar *))); 325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov separator = ' '; 326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov continue; 327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_XMNM: { 329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt mask, kind; 330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar *mnm; 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov kind = va_arg(args, UInt); 333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov separator = ' '; 335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (kind) { 336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_BC: 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_BCR: 338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mask = va_arg(args, UInt); 339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mnm = kind == S390_XMNM_BCR ? bcr_operand(mask) : bc_operand(mask); 340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov p += vex_sprintf(p, "%s", mnemonic(mnm)); 341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* mask == 0 is a NOP and has no argument */ 342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (mask == 0) goto done; 343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_BRC: 346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_BRCL: 347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mask = va_arg(args, UInt); 348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mnm = kind == S390_XMNM_BRC ? brc_operand(mask) : brcl_operand(mask); 349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov p += vex_sprintf(p, "%s", mnemonic(mnm)); 350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* mask == 0 has no special mnemonic */ 352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (mask == 0) { 353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, " 0"); 354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov separator = ','; 355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_CAB: 359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mnm = va_arg(args, HChar *); 360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mask = va_arg(args, UInt); 361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov p += vex_sprintf(p, "%s", mnemonic(cab_operand(mnm, mask))); 362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOCR: 365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOCGR: 366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOC: 367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_LOCG: 368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_STOC: 369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_XMNM_STOCG: 370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mask = va_arg(args, UInt); 371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mnm = cls_operand(kind, mask); 372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov p += vex_sprintf(p, "%s", mnemonic(mnm)); 373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* There are no special opcodes when mask == 0 or 15. In that case 374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the integer mask is appended as the final operand */ 375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (mask == 0 || mask == 15) mask_suffix = mask; 376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov continue; 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_GPR: 382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%s", gpr_operand(va_arg(args, UInt))); 383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_FPR: 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%s", fpr_operand(va_arg(args, UInt))); 387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_AR: 390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%s", ar_operand(va_arg(args, UInt))); 391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_UINT: 394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%u", va_arg(args, UInt)); 395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_INT: 398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, "%d", (Int)(va_arg(args, UInt))); 399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_PCREL: { 402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int offset = (Int)(va_arg(args, UInt)); 403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Convert # halfwords to # bytes */ 405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov offset <<= 1; 406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (offset < 0) { 408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ".%d", offset); 409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ".+%u", offset); 411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_SDXB: { 416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt dh, dl, x, b; 417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov dh = va_arg(args, UInt); 419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov dl = va_arg(args, UInt); 420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov x = va_arg(args, UInt); 421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b = va_arg(args, UInt); 422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = dxb_operand(p, (dh << 12) | dl, x, b, 1 /* signed_displacement */); 424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_UDXB: { 428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt d, x, b; 429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov d = va_arg(args, UInt); 431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov x = va_arg(args, UInt); 432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b = va_arg(args, UInt); 433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = dxb_operand(p, d, x, b, 0 /* signed_displacement */); 435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_UDLB: { 439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt d, l, b; 440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov d = va_arg(args, UInt); 442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov l = va_arg(args, UInt); 443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b = va_arg(args, UInt); 444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = udlb_operand(p, d, l, b); 446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case S390_ARG_CABM: { 450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt mask; 451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov mask = va_arg(args, UInt) & 0xE; 453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (mask == 0 || mask == 14) { 454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ",%u", mask); 455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov separator = ','; 461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov done: 464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_end(args); 465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (mask_suffix != -1) 467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p += vex_sprintf(p, ",%d", mask_suffix); 468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *p = '\0'; 469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(p < buf + sizeof buf); /* detect buffer overwrite */ 471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Finally, write out the disassembled insn */ 473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vex_printf("%s\n", buf); 474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------------------------------------------------*/ 477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- end s390_disasm.c ---*/ 478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------------------------------------------------*/ 479