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 virtual DecodeStatus getInstruction(MCInst &instr,
32 const MemoryObject ®ion,
35 raw_ostream &cStream) const LLVM_OVERRIDE;
37 } // end anonymous namespace
39 static MCDisassembler *createSystemZDisassembler(const Target &T,
40 const MCSubtargetInfo &STI) {
41 return new SystemZDisassembler(STI);
44 extern "C" void LLVMInitializeSystemZDisassembler() {
45 // Register the disassembler.
46 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
47 createSystemZDisassembler);
50 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
52 bool isAddress = false) {
53 assert(RegNo < 16 && "Invalid register");
54 if (!isAddress || RegNo) {
57 return MCDisassembler::Fail;
59 Inst.addOperand(MCOperand::CreateReg(RegNo));
60 return MCDisassembler::Success;
63 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
65 const void *Decoder) {
66 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs);
69 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
71 const void *Decoder) {
72 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
75 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
77 const void *Decoder) {
78 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs);
81 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
83 const void *Decoder) {
84 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, true);
87 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
89 const void *Decoder) {
90 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs);
93 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
95 const void *Decoder) {
96 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs);
99 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
101 const void *Decoder) {
102 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs);
106 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
107 assert(isUInt<N>(Imm) && "Invalid immediate");
108 Inst.addOperand(MCOperand::CreateImm(Imm));
109 return MCDisassembler::Success;
113 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
114 assert(isUInt<N>(Imm) && "Invalid immediate");
115 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm)));
116 return MCDisassembler::Success;
119 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
121 const void *Decoder) {
122 return decodeUImmOperand<4>(Inst, Imm);
125 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
126 uint64_t Address, const void *Decoder) {
127 return decodeUImmOperand<4>(Inst, Imm);
130 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
131 uint64_t Address, const void *Decoder) {
132 return decodeUImmOperand<6>(Inst, Imm);
135 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
136 uint64_t Address, const void *Decoder) {
137 return decodeUImmOperand<8>(Inst, Imm);
140 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
141 uint64_t Address, const void *Decoder) {
142 return decodeUImmOperand<16>(Inst, Imm);
145 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
146 uint64_t Address, const void *Decoder) {
147 return decodeUImmOperand<32>(Inst, Imm);
150 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
151 uint64_t Address, const void *Decoder) {
152 return decodeSImmOperand<8>(Inst, Imm);
155 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
156 uint64_t Address, const void *Decoder) {
157 return decodeSImmOperand<16>(Inst, Imm);
160 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
161 uint64_t Address, const void *Decoder) {
162 return decodeSImmOperand<32>(Inst, Imm);
166 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
168 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
169 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address));
170 return MCDisassembler::Success;
173 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
175 const void *Decoder) {
176 return decodePCDBLOperand<16>(Inst, Imm, Address);
179 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
181 const void *Decoder) {
182 return decodePCDBLOperand<32>(Inst, Imm, Address);
185 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
186 const unsigned *Regs) {
187 uint64_t Base = Field >> 12;
188 uint64_t Disp = Field & 0xfff;
189 assert(Base < 16 && "Invalid BDAddr12");
190 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
191 Inst.addOperand(MCOperand::CreateImm(Disp));
192 return MCDisassembler::Success;
195 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
196 const unsigned *Regs) {
197 uint64_t Base = Field >> 20;
198 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
199 assert(Base < 16 && "Invalid BDAddr20");
200 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
201 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
202 return MCDisassembler::Success;
205 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
206 const unsigned *Regs) {
207 uint64_t Index = Field >> 16;
208 uint64_t Base = (Field >> 12) & 0xf;
209 uint64_t Disp = Field & 0xfff;
210 assert(Index < 16 && "Invalid BDXAddr12");
211 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
212 Inst.addOperand(MCOperand::CreateImm(Disp));
213 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
214 return MCDisassembler::Success;
217 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
218 const unsigned *Regs) {
219 uint64_t Index = Field >> 24;
220 uint64_t Base = (Field >> 20) & 0xf;
221 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
222 assert(Index < 16 && "Invalid BDXAddr20");
223 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
224 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
225 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
226 return MCDisassembler::Success;
229 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
230 const unsigned *Regs) {
231 uint64_t Length = Field >> 16;
232 uint64_t Base = (Field >> 12) & 0xf;
233 uint64_t Disp = Field & 0xfff;
234 assert(Length < 256 && "Invalid BDLAddr12Len8");
235 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
236 Inst.addOperand(MCOperand::CreateImm(Disp));
237 Inst.addOperand(MCOperand::CreateImm(Length + 1));
238 return MCDisassembler::Success;
241 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
243 const void *Decoder) {
244 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
247 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
249 const void *Decoder) {
250 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
253 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
255 const void *Decoder) {
256 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
259 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
261 const void *Decoder) {
262 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
265 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
267 const void *Decoder) {
268 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
271 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
273 const void *Decoder) {
274 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
277 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
280 const void *Decoder) {
281 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
284 #include "SystemZGenDisassemblerTables.inc"
286 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
287 const MemoryObject &Region,
290 raw_ostream &cs) const {
291 // Get the first two bytes of the instruction.
294 if (Region.readBytes(Address, 2, Bytes) == -1)
295 return MCDisassembler::Fail;
297 // The top 2 bits of the first byte specify the size.
298 const uint8_t *Table;
299 if (Bytes[0] < 0x40) {
301 Table = DecoderTable16;
302 } else if (Bytes[0] < 0xc0) {
304 Table = DecoderTable32;
307 Table = DecoderTable48;
310 // Read any remaining bytes.
311 if (Size > 2 && Region.readBytes(Address + 2, Size - 2, Bytes + 2) == -1)
312 return MCDisassembler::Fail;
314 // Construct the instruction.
316 for (uint64_t I = 0; I < Size; ++I)
317 Inst = (Inst << 8) | Bytes[I];
319 return decodeInstruction(Table, MI, Inst, Address, this, STI);