1 //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "llvm/MC/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"
19 #define DEBUG_TYPE "systemz-disassembler"
21 typedef MCDisassembler::DecodeStatus DecodeStatus;
24 class SystemZDisassembler : public MCDisassembler {
26 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
27 : MCDisassembler(STI, Ctx) {}
28 virtual ~SystemZDisassembler() {}
30 DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
31 ArrayRef<uint8_t> Bytes, uint64_t Address,
33 raw_ostream &CStream) const override;
35 } // end anonymous namespace
37 static MCDisassembler *createSystemZDisassembler(const Target &T,
38 const MCSubtargetInfo &STI,
40 return new SystemZDisassembler(STI, Ctx);
43 extern "C" void LLVMInitializeSystemZDisassembler() {
44 // Register the disassembler.
45 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
46 createSystemZDisassembler);
49 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
50 const unsigned *Regs) {
51 assert(RegNo < 16 && "Invalid register");
54 return MCDisassembler::Fail;
55 Inst.addOperand(MCOperand::CreateReg(RegNo));
56 return MCDisassembler::Success;
59 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
61 const void *Decoder) {
62 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs);
65 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
67 const void *Decoder) {
68 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs);
71 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
73 const void *Decoder) {
74 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
77 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
79 const void *Decoder) {
80 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs);
83 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
85 const void *Decoder) {
86 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
89 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
91 const void *Decoder) {
92 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs);
95 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
97 const void *Decoder) {
98 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs);
101 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
103 const void *Decoder) {
104 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs);
108 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
109 assert(isUInt<N>(Imm) && "Invalid immediate");
110 Inst.addOperand(MCOperand::CreateImm(Imm));
111 return MCDisassembler::Success;
115 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
116 assert(isUInt<N>(Imm) && "Invalid immediate");
117 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm)));
118 return MCDisassembler::Success;
121 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
123 const void *Decoder) {
124 return decodeUImmOperand<4>(Inst, Imm);
127 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
128 uint64_t Address, const void *Decoder) {
129 return decodeUImmOperand<4>(Inst, Imm);
132 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
133 uint64_t Address, const void *Decoder) {
134 return decodeUImmOperand<6>(Inst, Imm);
137 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
138 uint64_t Address, const void *Decoder) {
139 return decodeUImmOperand<8>(Inst, Imm);
142 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
143 uint64_t Address, const void *Decoder) {
144 return decodeUImmOperand<16>(Inst, Imm);
147 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
148 uint64_t Address, const void *Decoder) {
149 return decodeUImmOperand<32>(Inst, Imm);
152 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
153 uint64_t Address, const void *Decoder) {
154 return decodeSImmOperand<8>(Inst, Imm);
157 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
158 uint64_t Address, const void *Decoder) {
159 return decodeSImmOperand<16>(Inst, Imm);
162 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
163 uint64_t Address, const void *Decoder) {
164 return decodeSImmOperand<32>(Inst, Imm);
168 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
170 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
171 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address));
172 return MCDisassembler::Success;
175 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
177 const void *Decoder) {
178 return decodePCDBLOperand<16>(Inst, Imm, Address);
181 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
183 const void *Decoder) {
184 return decodePCDBLOperand<32>(Inst, Imm, Address);
187 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
188 const unsigned *Regs) {
189 uint64_t Base = Field >> 12;
190 uint64_t Disp = Field & 0xfff;
191 assert(Base < 16 && "Invalid BDAddr12");
192 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
193 Inst.addOperand(MCOperand::CreateImm(Disp));
194 return MCDisassembler::Success;
197 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
198 const unsigned *Regs) {
199 uint64_t Base = Field >> 20;
200 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
201 assert(Base < 16 && "Invalid BDAddr20");
202 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
203 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
204 return MCDisassembler::Success;
207 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
208 const unsigned *Regs) {
209 uint64_t Index = Field >> 16;
210 uint64_t Base = (Field >> 12) & 0xf;
211 uint64_t Disp = Field & 0xfff;
212 assert(Index < 16 && "Invalid BDXAddr12");
213 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
214 Inst.addOperand(MCOperand::CreateImm(Disp));
215 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
216 return MCDisassembler::Success;
219 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
220 const unsigned *Regs) {
221 uint64_t Index = Field >> 24;
222 uint64_t Base = (Field >> 20) & 0xf;
223 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
224 assert(Index < 16 && "Invalid BDXAddr20");
225 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
226 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
227 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
228 return MCDisassembler::Success;
231 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
232 const unsigned *Regs) {
233 uint64_t Length = Field >> 16;
234 uint64_t Base = (Field >> 12) & 0xf;
235 uint64_t Disp = Field & 0xfff;
236 assert(Length < 256 && "Invalid BDLAddr12Len8");
237 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
238 Inst.addOperand(MCOperand::CreateImm(Disp));
239 Inst.addOperand(MCOperand::CreateImm(Length + 1));
240 return MCDisassembler::Success;
243 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
245 const void *Decoder) {
246 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
249 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
251 const void *Decoder) {
252 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
255 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
257 const void *Decoder) {
258 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
261 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
263 const void *Decoder) {
264 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
267 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
269 const void *Decoder) {
270 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
273 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
275 const void *Decoder) {
276 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
279 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
282 const void *Decoder) {
283 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
286 #include "SystemZGenDisassemblerTables.inc"
288 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
289 ArrayRef<uint8_t> Bytes,
292 raw_ostream &CS) const {
293 // Get the first two bytes of the instruction.
295 if (Bytes.size() < 2)
296 return MCDisassembler::Fail;
298 // The top 2 bits of the first byte specify the size.
299 const uint8_t *Table;
300 if (Bytes[0] < 0x40) {
302 Table = DecoderTable16;
303 } else if (Bytes[0] < 0xc0) {
305 Table = DecoderTable32;
308 Table = DecoderTable48;
311 // Read any remaining bytes.
312 if (Bytes.size() < Size)
313 return MCDisassembler::Fail;
315 // Construct the instruction.
317 for (uint64_t I = 0; I < Size; ++I)
318 Inst = (Inst << 8) | Bytes[I];
320 return decodeInstruction(Table, MI, Inst, Address, this, STI);