1//===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "SystemZ.h" 11#include "llvm/MC/MCDisassembler/MCDisassembler.h" 12#include "llvm/MC/MCFixedLenDisassembler.h" 13#include "llvm/MC/MCInst.h" 14#include "llvm/MC/MCSubtargetInfo.h" 15#include "llvm/Support/TargetRegistry.h" 16 17using namespace llvm; 18 19#define DEBUG_TYPE "systemz-disassembler" 20 21typedef MCDisassembler::DecodeStatus DecodeStatus; 22 23namespace { 24class SystemZDisassembler : public MCDisassembler { 25public: 26 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 27 : MCDisassembler(STI, Ctx) {} 28 ~SystemZDisassembler() override {} 29 30 DecodeStatus getInstruction(MCInst &instr, uint64_t &Size, 31 ArrayRef<uint8_t> Bytes, uint64_t Address, 32 raw_ostream &VStream, 33 raw_ostream &CStream) const override; 34}; 35} // end anonymous namespace 36 37static MCDisassembler *createSystemZDisassembler(const Target &T, 38 const MCSubtargetInfo &STI, 39 MCContext &Ctx) { 40 return new SystemZDisassembler(STI, Ctx); 41} 42 43extern "C" void LLVMInitializeSystemZDisassembler() { 44 // Register the disassembler. 45 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget, 46 createSystemZDisassembler); 47} 48 49/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 50/// immediate Value in the MCInst. 51/// 52/// @param Value - The immediate Value, has had any PC adjustment made by 53/// the caller. 54/// @param isBranch - If the instruction is a branch instruction 55/// @param Address - The starting address of the instruction 56/// @param Offset - The byte offset to this immediate in the instruction 57/// @param Width - The byte width of this immediate in the instruction 58/// 59/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was 60/// called then that function is called to get any symbolic information for the 61/// immediate in the instruction using the Address, Offset and Width. If that 62/// returns non-zero then the symbolic information it returns is used to create 63/// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() 64/// returns zero and isBranch is true then a symbol look up for immediate Value 65/// is done and if a symbol is found an MCExpr is created with that, else 66/// an MCExpr with the immediate Value is created. This function returns true 67/// if it adds an operand to the MCInst and false otherwise. 68static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 69 uint64_t Address, uint64_t Offset, 70 uint64_t Width, MCInst &MI, 71 const void *Decoder) { 72 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 73 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 74 Offset, Width); 75} 76 77static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 78 const unsigned *Regs, unsigned Size) { 79 assert(RegNo < Size && "Invalid register"); 80 RegNo = Regs[RegNo]; 81 if (RegNo == 0) 82 return MCDisassembler::Fail; 83 Inst.addOperand(MCOperand::createReg(RegNo)); 84 return MCDisassembler::Success; 85} 86 87static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 88 uint64_t Address, 89 const void *Decoder) { 90 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16); 91} 92 93static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 94 uint64_t Address, 95 const void *Decoder) { 96 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16); 97} 98 99static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 100 uint64_t Address, 101 const void *Decoder) { 102 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 103} 104 105static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 106 uint64_t Address, 107 const void *Decoder) { 108 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16); 109} 110 111static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 112 uint64_t Address, 113 const void *Decoder) { 114 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 115} 116 117static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 118 uint64_t Address, 119 const void *Decoder) { 120 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16); 121} 122 123static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 124 uint64_t Address, 125 const void *Decoder) { 126 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16); 127} 128 129static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 130 uint64_t Address, 131 const void *Decoder) { 132 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16); 133} 134 135static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 136 uint64_t Address, 137 const void *Decoder) { 138 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32); 139} 140 141static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 142 uint64_t Address, 143 const void *Decoder) { 144 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32); 145} 146 147static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 148 uint64_t Address, 149 const void *Decoder) { 150 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32); 151} 152 153template<unsigned N> 154static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 155 if (!isUInt<N>(Imm)) 156 return MCDisassembler::Fail; 157 Inst.addOperand(MCOperand::createImm(Imm)); 158 return MCDisassembler::Success; 159} 160 161template<unsigned N> 162static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 163 if (!isUInt<N>(Imm)) 164 return MCDisassembler::Fail; 165 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 166 return MCDisassembler::Success; 167} 168 169static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, 170 uint64_t Address, 171 const void *Decoder) { 172 return decodeUImmOperand<4>(Inst, Imm); 173} 174 175static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, 176 uint64_t Address, const void *Decoder) { 177 return decodeUImmOperand<1>(Inst, Imm); 178} 179 180static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, 181 uint64_t Address, const void *Decoder) { 182 return decodeUImmOperand<2>(Inst, Imm); 183} 184 185static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, 186 uint64_t Address, const void *Decoder) { 187 return decodeUImmOperand<3>(Inst, Imm); 188} 189 190static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 191 uint64_t Address, const void *Decoder) { 192 return decodeUImmOperand<4>(Inst, Imm); 193} 194 195static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 196 uint64_t Address, const void *Decoder) { 197 return decodeUImmOperand<6>(Inst, Imm); 198} 199 200static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 201 uint64_t Address, const void *Decoder) { 202 return decodeUImmOperand<8>(Inst, Imm); 203} 204 205static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, 206 uint64_t Address, const void *Decoder) { 207 return decodeUImmOperand<12>(Inst, Imm); 208} 209 210static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 211 uint64_t Address, const void *Decoder) { 212 return decodeUImmOperand<16>(Inst, Imm); 213} 214 215static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 216 uint64_t Address, const void *Decoder) { 217 return decodeUImmOperand<32>(Inst, Imm); 218} 219 220static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 221 uint64_t Address, const void *Decoder) { 222 return decodeSImmOperand<8>(Inst, Imm); 223} 224 225static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 226 uint64_t Address, const void *Decoder) { 227 return decodeSImmOperand<16>(Inst, Imm); 228} 229 230static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 231 uint64_t Address, const void *Decoder) { 232 return decodeSImmOperand<32>(Inst, Imm); 233} 234 235template<unsigned N> 236static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 237 uint64_t Address, 238 bool isBranch, 239 const void *Decoder) { 240 assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 241 uint64_t Value = SignExtend64<N>(Imm) * 2 + Address; 242 243 if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8, 244 Inst, Decoder)) 245 Inst.addOperand(MCOperand::createImm(Value)); 246 247 return MCDisassembler::Success; 248} 249 250static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm, 251 uint64_t Address, 252 const void *Decoder) { 253 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder); 254} 255 256static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm, 257 uint64_t Address, 258 const void *Decoder) { 259 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder); 260} 261 262static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 263 uint64_t Address, 264 const void *Decoder) { 265 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder); 266} 267 268static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 269 const unsigned *Regs) { 270 uint64_t Base = Field >> 12; 271 uint64_t Disp = Field & 0xfff; 272 assert(Base < 16 && "Invalid BDAddr12"); 273 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 274 Inst.addOperand(MCOperand::createImm(Disp)); 275 return MCDisassembler::Success; 276} 277 278static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 279 const unsigned *Regs) { 280 uint64_t Base = Field >> 20; 281 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 282 assert(Base < 16 && "Invalid BDAddr20"); 283 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 284 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 285 return MCDisassembler::Success; 286} 287 288static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 289 const unsigned *Regs) { 290 uint64_t Index = Field >> 16; 291 uint64_t Base = (Field >> 12) & 0xf; 292 uint64_t Disp = Field & 0xfff; 293 assert(Index < 16 && "Invalid BDXAddr12"); 294 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 295 Inst.addOperand(MCOperand::createImm(Disp)); 296 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 297 return MCDisassembler::Success; 298} 299 300static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 301 const unsigned *Regs) { 302 uint64_t Index = Field >> 24; 303 uint64_t Base = (Field >> 20) & 0xf; 304 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 305 assert(Index < 16 && "Invalid BDXAddr20"); 306 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 307 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 308 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 309 return MCDisassembler::Success; 310} 311 312static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 313 const unsigned *Regs) { 314 uint64_t Length = Field >> 16; 315 uint64_t Base = (Field >> 12) & 0xf; 316 uint64_t Disp = Field & 0xfff; 317 assert(Length < 256 && "Invalid BDLAddr12Len8"); 318 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 319 Inst.addOperand(MCOperand::createImm(Disp)); 320 Inst.addOperand(MCOperand::createImm(Length + 1)); 321 return MCDisassembler::Success; 322} 323 324static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field, 325 const unsigned *Regs) { 326 uint64_t Index = Field >> 16; 327 uint64_t Base = (Field >> 12) & 0xf; 328 uint64_t Disp = Field & 0xfff; 329 assert(Index < 32 && "Invalid BDVAddr12"); 330 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 331 Inst.addOperand(MCOperand::createImm(Disp)); 332 Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index])); 333 return MCDisassembler::Success; 334} 335 336static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 337 uint64_t Address, 338 const void *Decoder) { 339 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 340} 341 342static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 343 uint64_t Address, 344 const void *Decoder) { 345 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 346} 347 348static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 349 uint64_t Address, 350 const void *Decoder) { 351 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 352} 353 354static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 355 uint64_t Address, 356 const void *Decoder) { 357 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 358} 359 360static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 361 uint64_t Address, 362 const void *Decoder) { 363 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 364} 365 366static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 367 uint64_t Address, 368 const void *Decoder) { 369 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 370} 371 372static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, 373 uint64_t Field, 374 uint64_t Address, 375 const void *Decoder) { 376 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 377} 378 379static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 380 uint64_t Address, 381 const void *Decoder) { 382 return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 383} 384 385#include "SystemZGenDisassemblerTables.inc" 386 387DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 388 ArrayRef<uint8_t> Bytes, 389 uint64_t Address, 390 raw_ostream &OS, 391 raw_ostream &CS) const { 392 // Get the first two bytes of the instruction. 393 Size = 0; 394 if (Bytes.size() < 2) 395 return MCDisassembler::Fail; 396 397 // The top 2 bits of the first byte specify the size. 398 const uint8_t *Table; 399 if (Bytes[0] < 0x40) { 400 Size = 2; 401 Table = DecoderTable16; 402 } else if (Bytes[0] < 0xc0) { 403 Size = 4; 404 Table = DecoderTable32; 405 } else { 406 Size = 6; 407 Table = DecoderTable48; 408 } 409 410 // Read any remaining bytes. 411 if (Bytes.size() < Size) 412 return MCDisassembler::Fail; 413 414 // Construct the instruction. 415 uint64_t Inst = 0; 416 for (uint64_t I = 0; I < Size; ++I) 417 Inst = (Inst << 8) | Bytes[I]; 418 419 return decodeInstruction(Table, MI, Inst, Address, this, STI); 420} 421