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