1 //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/SystemZMCTargetDesc.h" 10 #include "TargetInfo/SystemZTargetInfo.h" 11 #include "llvm/MC/MCDecoderOps.h" 12 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 13 #include "llvm/MC/MCInst.h" 14 #include "llvm/MC/MCSubtargetInfo.h" 15 #include "llvm/MC/TargetRegistry.h" 16 #include "llvm/Support/Compiler.h" 17 #include "llvm/Support/MathExtras.h" 18 #include <cassert> 19 #include <cstdint> 20 21 using namespace llvm; 22 23 #define DEBUG_TYPE "systemz-disassembler" 24 25 typedef MCDisassembler::DecodeStatus DecodeStatus; 26 27 namespace { 28 29 class SystemZDisassembler : public MCDisassembler { 30 public: 31 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 32 : MCDisassembler(STI, Ctx) {} 33 ~SystemZDisassembler() override = default; 34 35 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 36 ArrayRef<uint8_t> Bytes, uint64_t Address, 37 raw_ostream &CStream) const override; 38 }; 39 40 } // end anonymous namespace 41 42 static MCDisassembler *createSystemZDisassembler(const Target &T, 43 const MCSubtargetInfo &STI, 44 MCContext &Ctx) { 45 return new SystemZDisassembler(STI, Ctx); 46 } 47 48 // NOLINTNEXTLINE(readability-identifier-naming) 49 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void 50 LLVMInitializeSystemZDisassembler() { 51 // Register the disassembler. 52 TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(), 53 createSystemZDisassembler); 54 } 55 56 /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 57 /// immediate Value in the MCInst. 58 /// 59 /// @param Value - The immediate Value, has had any PC adjustment made by 60 /// the caller. 61 /// @param isBranch - If the instruction is a branch instruction 62 /// @param Address - The starting address of the instruction 63 /// @param Offset - The byte offset to this immediate in the instruction 64 /// @param Width - The byte width of this immediate in the instruction 65 /// 66 /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was 67 /// called then that function is called to get any symbolic information for the 68 /// immediate in the instruction using the Address, Offset and Width. If that 69 /// returns non-zero then the symbolic information it returns is used to create 70 /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() 71 /// returns zero and isBranch is true then a symbol look up for immediate Value 72 /// is done and if a symbol is found an MCExpr is created with that, else 73 /// an MCExpr with the immediate Value is created. This function returns true 74 /// if it adds an operand to the MCInst and false otherwise. 75 static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch, 76 uint64_t Address, uint64_t Offset, 77 uint64_t Width, MCInst &MI, 78 const MCDisassembler *Decoder) { 79 return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset, 80 Width, /*InstSize=*/0); 81 } 82 83 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 84 const unsigned *Regs, unsigned Size, 85 bool IsAddr = false) { 86 assert(RegNo < Size && "Invalid register"); 87 if (IsAddr && RegNo == 0) { 88 RegNo = SystemZ::NoRegister; 89 } else { 90 RegNo = Regs[RegNo]; 91 if (RegNo == 0) 92 return MCDisassembler::Fail; 93 } 94 Inst.addOperand(MCOperand::createReg(RegNo)); 95 return MCDisassembler::Success; 96 } 97 98 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 99 uint64_t Address, 100 const MCDisassembler *Decoder) { 101 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16); 102 } 103 104 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 105 uint64_t Address, 106 const MCDisassembler *Decoder) { 107 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16); 108 } 109 110 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 111 uint64_t Address, 112 const MCDisassembler *Decoder) { 113 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 114 } 115 116 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 117 uint64_t Address, 118 const MCDisassembler *Decoder) { 119 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16); 120 } 121 122 static DecodeStatus 123 DecodeADDR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 124 const MCDisassembler *Decoder) { 125 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true); 126 } 127 128 static DecodeStatus 129 DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 130 const MCDisassembler *Decoder) { 131 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true); 132 } 133 134 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 135 uint64_t Address, 136 const MCDisassembler *Decoder) { 137 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16); 138 } 139 140 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 141 uint64_t Address, 142 const MCDisassembler *Decoder) { 143 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16); 144 } 145 146 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 147 uint64_t Address, 148 const MCDisassembler *Decoder) { 149 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16); 150 } 151 152 static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 153 uint64_t Address, 154 const MCDisassembler *Decoder) { 155 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32); 156 } 157 158 static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 159 uint64_t Address, 160 const MCDisassembler *Decoder) { 161 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32); 162 } 163 164 static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 165 uint64_t Address, 166 const MCDisassembler *Decoder) { 167 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32); 168 } 169 170 static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 171 uint64_t Address, 172 const MCDisassembler *Decoder) { 173 return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16); 174 } 175 176 static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 177 uint64_t Address, 178 const MCDisassembler *Decoder) { 179 return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16); 180 } 181 182 template<unsigned N> 183 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 184 if (!isUInt<N>(Imm)) 185 return MCDisassembler::Fail; 186 Inst.addOperand(MCOperand::createImm(Imm)); 187 return MCDisassembler::Success; 188 } 189 190 template<unsigned N> 191 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 192 if (!isUInt<N>(Imm)) 193 return MCDisassembler::Fail; 194 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 195 return MCDisassembler::Success; 196 } 197 198 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, 199 uint64_t Address, 200 const MCDisassembler *Decoder) { 201 return decodeUImmOperand<1>(Inst, Imm); 202 } 203 204 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, 205 uint64_t Address, 206 const MCDisassembler *Decoder) { 207 return decodeUImmOperand<2>(Inst, Imm); 208 } 209 210 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, 211 uint64_t Address, 212 const MCDisassembler *Decoder) { 213 return decodeUImmOperand<3>(Inst, Imm); 214 } 215 216 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 217 uint64_t Address, 218 const MCDisassembler *Decoder) { 219 return decodeUImmOperand<4>(Inst, Imm); 220 } 221 222 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 223 uint64_t Address, 224 const MCDisassembler *Decoder) { 225 return decodeUImmOperand<8>(Inst, Imm); 226 } 227 228 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, 229 uint64_t Address, 230 const MCDisassembler *Decoder) { 231 return decodeUImmOperand<12>(Inst, Imm); 232 } 233 234 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 235 uint64_t Address, 236 const MCDisassembler *Decoder) { 237 return decodeUImmOperand<16>(Inst, Imm); 238 } 239 240 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 241 uint64_t Address, 242 const MCDisassembler *Decoder) { 243 return decodeUImmOperand<32>(Inst, Imm); 244 } 245 246 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 247 uint64_t Address, 248 const MCDisassembler *Decoder) { 249 return decodeSImmOperand<8>(Inst, Imm); 250 } 251 252 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 253 uint64_t Address, 254 const MCDisassembler *Decoder) { 255 return decodeSImmOperand<16>(Inst, Imm); 256 } 257 258 static DecodeStatus decodeS20ImmOperand(MCInst &Inst, uint64_t Imm, 259 uint64_t Address, 260 const MCDisassembler *Decoder) { 261 return decodeSImmOperand<20>(Inst, Imm); 262 } 263 264 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 265 uint64_t Address, 266 const MCDisassembler *Decoder) { 267 return decodeSImmOperand<32>(Inst, Imm); 268 } 269 270 template <unsigned N> 271 static DecodeStatus decodeLenOperand(MCInst &Inst, uint64_t Imm, 272 uint64_t Address, 273 const MCDisassembler *Decoder) { 274 if (!isUInt<N>(Imm)) 275 return MCDisassembler::Fail; 276 Inst.addOperand(MCOperand::createImm(Imm + 1)); 277 return MCDisassembler::Success; 278 } 279 280 template <unsigned N> 281 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 282 uint64_t Address, bool isBranch, 283 const MCDisassembler *Decoder) { 284 assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 285 uint64_t Value = SignExtend64<N>(Imm) * 2; 286 287 if (!tryAddingSymbolicOperand(Value + Address, isBranch, Address, 2, N / 8, 288 Inst, Decoder)) 289 Inst.addOperand(MCOperand::createImm(Value)); 290 291 return MCDisassembler::Success; 292 } 293 294 static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm, 295 uint64_t Address, 296 const MCDisassembler *Decoder) { 297 return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder); 298 } 299 300 static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm, 301 uint64_t Address, 302 const MCDisassembler *Decoder) { 303 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder); 304 } 305 306 static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm, 307 uint64_t Address, 308 const MCDisassembler *Decoder) { 309 return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder); 310 } 311 312 static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm, 313 uint64_t Address, 314 const MCDisassembler *Decoder) { 315 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder); 316 } 317 318 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 319 uint64_t Address, 320 const MCDisassembler *Decoder) { 321 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder); 322 } 323 324 #include "SystemZGenDisassemblerTables.inc" 325 326 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 327 ArrayRef<uint8_t> Bytes, 328 uint64_t Address, 329 raw_ostream &CS) const { 330 CommentStream = &CS; 331 332 // Get the first two bytes of the instruction. 333 Size = 0; 334 if (Bytes.size() < 2) 335 return MCDisassembler::Fail; 336 337 // The top 2 bits of the first byte specify the size. 338 const uint8_t *Table; 339 if (Bytes[0] < 0x40) { 340 Size = 2; 341 Table = DecoderTable16; 342 } else if (Bytes[0] < 0xc0) { 343 Size = 4; 344 Table = DecoderTable32; 345 } else { 346 Size = 6; 347 Table = DecoderTable48; 348 } 349 350 // Read any remaining bytes. 351 if (Bytes.size() < Size) { 352 Size = Bytes.size(); 353 return MCDisassembler::Fail; 354 } 355 356 // Construct the instruction. 357 uint64_t Inst = 0; 358 for (uint64_t I = 0; I < Size; ++I) 359 Inst = (Inst << 8) | Bytes[I]; 360 361 return decodeInstruction(Table, MI, Inst, Address, this, STI); 362 } 363