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/MemoryObject.h"
16 #include "llvm/Support/TargetRegistry.h"
20 typedef MCDisassembler::DecodeStatus DecodeStatus;
23 class SystemZDisassembler : public MCDisassembler {
25 SystemZDisassembler(const MCSubtargetInfo &STI)
26 : MCDisassembler(STI) {}
27 virtual ~SystemZDisassembler() {}
29 // Override MCDisassembler.
30 DecodeStatus getInstruction(MCInst &instr, uint64_t &size,
31 const MemoryObject ®ion, uint64_t address,
33 raw_ostream &cStream) const override;
35 } // end anonymous namespace
37 static MCDisassembler *createSystemZDisassembler(const Target &T,
38 const MCSubtargetInfo &STI) {
39 return new SystemZDisassembler(STI);
42 extern "C" void LLVMInitializeSystemZDisassembler() {
43 // Register the disassembler.
44 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
45 createSystemZDisassembler);
48 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
49 const unsigned *Regs) {
50 assert(RegNo < 16 && "Invalid register");
53 return MCDisassembler::Fail;
54 Inst.addOperand(MCOperand::CreateReg(RegNo));
55 return MCDisassembler::Success;
58 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
60 const void *Decoder) {
61 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs);
64 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
66 const void *Decoder) {
67 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs);
70 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
72 const void *Decoder) {
73 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
76 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
78 const void *Decoder) {
79 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs);
82 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
84 const void *Decoder) {
85 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
88 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
90 const void *Decoder) {
91 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs);
94 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
96 const void *Decoder) {
97 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs);
100 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
102 const void *Decoder) {
103 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs);
107 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
108 assert(isUInt<N>(Imm) && "Invalid immediate");
109 Inst.addOperand(MCOperand::CreateImm(Imm));
110 return MCDisassembler::Success;
114 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
115 assert(isUInt<N>(Imm) && "Invalid immediate");
116 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm)));
117 return MCDisassembler::Success;
120 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
122 const void *Decoder) {
123 return decodeUImmOperand<4>(Inst, Imm);
126 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
127 uint64_t Address, const void *Decoder) {
128 return decodeUImmOperand<4>(Inst, Imm);
131 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
132 uint64_t Address, const void *Decoder) {
133 return decodeUImmOperand<6>(Inst, Imm);
136 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
137 uint64_t Address, const void *Decoder) {
138 return decodeUImmOperand<8>(Inst, Imm);
141 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
142 uint64_t Address, const void *Decoder) {
143 return decodeUImmOperand<16>(Inst, Imm);
146 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
147 uint64_t Address, const void *Decoder) {
148 return decodeUImmOperand<32>(Inst, Imm);
151 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
152 uint64_t Address, const void *Decoder) {
153 return decodeSImmOperand<8>(Inst, Imm);
156 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
157 uint64_t Address, const void *Decoder) {
158 return decodeSImmOperand<16>(Inst, Imm);
161 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
162 uint64_t Address, const void *Decoder) {
163 return decodeSImmOperand<32>(Inst, Imm);
167 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
169 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
170 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address));
171 return MCDisassembler::Success;
174 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
176 const void *Decoder) {
177 return decodePCDBLOperand<16>(Inst, Imm, Address);
180 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
182 const void *Decoder) {
183 return decodePCDBLOperand<32>(Inst, Imm, Address);
186 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
187 const unsigned *Regs) {
188 uint64_t Base = Field >> 12;
189 uint64_t Disp = Field & 0xfff;
190 assert(Base < 16 && "Invalid BDAddr12");
191 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
192 Inst.addOperand(MCOperand::CreateImm(Disp));
193 return MCDisassembler::Success;
196 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
197 const unsigned *Regs) {
198 uint64_t Base = Field >> 20;
199 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
200 assert(Base < 16 && "Invalid BDAddr20");
201 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
202 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
203 return MCDisassembler::Success;
206 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
207 const unsigned *Regs) {
208 uint64_t Index = Field >> 16;
209 uint64_t Base = (Field >> 12) & 0xf;
210 uint64_t Disp = Field & 0xfff;
211 assert(Index < 16 && "Invalid BDXAddr12");
212 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
213 Inst.addOperand(MCOperand::CreateImm(Disp));
214 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
215 return MCDisassembler::Success;
218 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
219 const unsigned *Regs) {
220 uint64_t Index = Field >> 24;
221 uint64_t Base = (Field >> 20) & 0xf;
222 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
223 assert(Index < 16 && "Invalid BDXAddr20");
224 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
225 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
226 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
227 return MCDisassembler::Success;
230 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
231 const unsigned *Regs) {
232 uint64_t Length = Field >> 16;
233 uint64_t Base = (Field >> 12) & 0xf;
234 uint64_t Disp = Field & 0xfff;
235 assert(Length < 256 && "Invalid BDLAddr12Len8");
236 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
237 Inst.addOperand(MCOperand::CreateImm(Disp));
238 Inst.addOperand(MCOperand::CreateImm(Length + 1));
239 return MCDisassembler::Success;
242 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
244 const void *Decoder) {
245 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
248 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
250 const void *Decoder) {
251 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
254 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
256 const void *Decoder) {
257 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
260 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
262 const void *Decoder) {
263 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
266 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
268 const void *Decoder) {
269 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
272 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
274 const void *Decoder) {
275 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
278 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
281 const void *Decoder) {
282 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
285 #include "SystemZGenDisassemblerTables.inc"
287 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
288 const MemoryObject &Region,
291 raw_ostream &cs) const {
292 // Get the first two bytes of the instruction.
295 if (Region.readBytes(Address, 2, Bytes) == -1)
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 (Size > 2 && Region.readBytes(Address + 2, Size - 2, Bytes + 2) == -1)
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);