Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 1 | //===-- AMDGPUDisassembler.cpp - Disassembler for AMDGPU ISA --------------===// |
| 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 | //===----------------------------------------------------------------------===// |
| 11 | // |
| 12 | /// \file |
| 13 | /// |
| 14 | /// This file contains definition for AMDGPU ISA disassembler |
| 15 | // |
| 16 | //===----------------------------------------------------------------------===// |
| 17 | |
| 18 | // ToDo: What to do with instruction suffixes (v_mov_b32 vs v_mov_b32_e32)? |
| 19 | |
| 20 | #include "AMDGPUDisassembler.h" |
| 21 | #include "AMDGPU.h" |
| 22 | #include "AMDGPURegisterInfo.h" |
| 23 | #include "Utils/AMDGPUBaseInfo.h" |
| 24 | |
| 25 | #include "llvm/MC/MCFixedLenDisassembler.h" |
| 26 | #include "llvm/MC/MCInst.h" |
| 27 | #include "llvm/MC/MCInstrDesc.h" |
| 28 | #include "llvm/MC/MCSubtargetInfo.h" |
| 29 | #include "llvm/Support/Debug.h" |
| 30 | #include "llvm/Support/TargetRegistry.h" |
| 31 | |
| 32 | |
| 33 | using namespace llvm; |
| 34 | |
| 35 | #define DEBUG_TYPE "amdgpu-disassembler" |
| 36 | |
| 37 | typedef llvm::MCDisassembler::DecodeStatus DecodeStatus; |
| 38 | |
| 39 | |
| 40 | static DecodeStatus DecodeVGPR_32RegisterClass(MCInst &Inst, unsigned Imm, |
| 41 | uint64_t Addr, const void *Decoder) { |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 42 | const AMDGPUDisassembler *Dis = |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 43 | static_cast<const AMDGPUDisassembler *>(Decoder); |
| 44 | return Dis->DecodeVGPR_32RegisterClass(Inst, Imm, Addr); |
| 45 | } |
| 46 | |
| 47 | static DecodeStatus DecodeVS_32RegisterClass(MCInst &Inst, unsigned Imm, |
| 48 | uint64_t Addr, const void *Decoder) { |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 49 | const AMDGPUDisassembler *Dis = |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 50 | static_cast<const AMDGPUDisassembler *>(Decoder); |
| 51 | return Dis->DecodeVS_32RegisterClass(Inst, Imm, Addr); |
| 52 | } |
| 53 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 54 | static DecodeStatus DecodeVS_64RegisterClass(MCInst &Inst, unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 55 | uint64_t Addr, const void *Decoder) { |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 56 | const AMDGPUDisassembler *Dis = |
| 57 | static_cast<const AMDGPUDisassembler *>(Decoder); |
| 58 | return Dis->DecodeVS_64RegisterClass(Inst, Imm, Addr); |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 59 | } |
| 60 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 61 | static DecodeStatus DecodeVReg_64RegisterClass(MCInst &Inst, unsigned Imm, |
| 62 | uint64_t Addr, const void *Decoder) { |
| 63 | const AMDGPUDisassembler *Dis = |
| 64 | static_cast<const AMDGPUDisassembler *>(Decoder); |
| 65 | return Dis->DecodeVReg_64RegisterClass(Inst, Imm, Addr); |
| 66 | } |
| 67 | |
| 68 | static DecodeStatus DecodeVReg_96RegisterClass(MCInst &Inst, unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 69 | uint64_t Addr, const void *Decoder) { |
| 70 | // ToDo |
| 71 | return MCDisassembler::Fail; |
| 72 | } |
| 73 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 74 | static DecodeStatus DecodeVReg_128RegisterClass(MCInst &Inst, unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 75 | uint64_t Addr, const void *Decoder) { |
| 76 | // ToDo |
| 77 | return MCDisassembler::Fail; |
| 78 | } |
| 79 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 80 | static DecodeStatus DecodeSReg_32RegisterClass(MCInst &Inst, unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 81 | uint64_t Addr, const void *Decoder) { |
| 82 | // ToDo |
| 83 | return MCDisassembler::Fail; |
| 84 | } |
| 85 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 86 | static DecodeStatus DecodeSReg_64RegisterClass(MCInst &Inst, unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 87 | uint64_t Addr, const void *Decoder) { |
| 88 | // ToDo |
| 89 | return MCDisassembler::Fail; |
| 90 | } |
| 91 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 92 | static DecodeStatus DecodeSReg_128RegisterClass(MCInst &Inst, unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 93 | uint64_t Addr, const void *Decoder) { |
| 94 | // ToDo |
| 95 | return MCDisassembler::Fail; |
| 96 | } |
| 97 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 98 | static DecodeStatus DecodeSReg_256RegisterClass(MCInst &Inst, unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 99 | uint64_t Addr, const void *Decoder) { |
| 100 | // ToDo |
| 101 | return MCDisassembler::Fail; |
| 102 | } |
| 103 | |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 104 | #define GET_SUBTARGETINFO_ENUM |
| 105 | #include "AMDGPUGenSubtargetInfo.inc" |
| 106 | #undef GET_SUBTARGETINFO_ENUM |
| 107 | |
| 108 | #include "AMDGPUGenDisassemblerTables.inc" |
| 109 | |
| 110 | //===----------------------------------------------------------------------===// |
| 111 | // |
| 112 | //===----------------------------------------------------------------------===// |
| 113 | |
| 114 | DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, |
| 115 | ArrayRef<uint8_t> Bytes, |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 116 | uint64_t Address, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 117 | raw_ostream &WS, |
| 118 | raw_ostream &CS) const { |
| 119 | CommentStream = &CS; |
| 120 | |
| 121 | // ToDo: AMDGPUDisassembler supports only VI ISA. |
| 122 | assert(AMDGPU::isVI(STI) && "Can disassemble only VI ISA."); |
| 123 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 124 | HasLiteral = false; |
| 125 | this->Bytes = Bytes; |
| 126 | |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 127 | // Try decode 32-bit instruction |
| 128 | if (Bytes.size() < 4) { |
| 129 | Size = 0; |
| 130 | return MCDisassembler::Fail; |
| 131 | } |
| 132 | uint32_t Insn = |
| 133 | (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0); |
| 134 | |
| 135 | // Calling the auto-generated decoder function. |
| 136 | DecodeStatus Result = |
| 137 | decodeInstruction(DecoderTableVI32, MI, Insn, Address, this, STI); |
| 138 | if (Result != MCDisassembler::Success) { |
| 139 | Size = 0; |
| 140 | return MCDisassembler::Fail; |
| 141 | } |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 142 | if (HasLiteral == true) { |
| 143 | Size = 8; |
| 144 | HasLiteral = false; |
| 145 | } else { |
| 146 | Size = 4; |
| 147 | } |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 148 | |
| 149 | return MCDisassembler::Success; |
| 150 | } |
| 151 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 152 | DecodeStatus AMDGPUDisassembler::DecodeImmedFloat(unsigned Imm, uint32_t &F) const { |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 153 | // ToDo: case 248: 1/(2*PI) - is allowed only on VI |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 154 | // ToDo: AMDGPUInstPrinter does not support 1/(2*PI). It consider 1/(2*PI) as |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 155 | // literal constant. |
| 156 | switch(Imm) { |
| 157 | case 240: F = FloatToBits(0.5f); return MCDisassembler::Success; |
| 158 | case 241: F = FloatToBits(-0.5f); return MCDisassembler::Success; |
| 159 | case 242: F = FloatToBits(1.0f); return MCDisassembler::Success; |
| 160 | case 243: F = FloatToBits(-1.0f); return MCDisassembler::Success; |
| 161 | case 244: F = FloatToBits(2.0f); return MCDisassembler::Success; |
| 162 | case 245: F = FloatToBits(-2.0f); return MCDisassembler::Success; |
| 163 | case 246: F = FloatToBits(4.0f); return MCDisassembler::Success; |
| 164 | case 247: F = FloatToBits(-4.0f); return MCDisassembler::Success; |
| 165 | case 248: F = 0x3e22f983; return MCDisassembler::Success; // 1/(2*PI) |
| 166 | default: return MCDisassembler::Fail; |
| 167 | } |
| 168 | } |
| 169 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 170 | DecodeStatus AMDGPUDisassembler::DecodeImmedDouble(unsigned Imm, uint64_t &D) const { |
| 171 | switch(Imm) { |
| 172 | case 240: D = DoubleToBits(0.5); return MCDisassembler::Success; |
| 173 | case 241: D = DoubleToBits(-0.5); return MCDisassembler::Success; |
| 174 | case 242: D = DoubleToBits(1.0); return MCDisassembler::Success; |
| 175 | case 243: D = DoubleToBits(-1.0); return MCDisassembler::Success; |
| 176 | case 244: D = DoubleToBits(2.0); return MCDisassembler::Success; |
| 177 | case 245: D = DoubleToBits(-2.0); return MCDisassembler::Success; |
| 178 | case 246: D = DoubleToBits(4.0); return MCDisassembler::Success; |
| 179 | case 247: D = DoubleToBits(-4.0); return MCDisassembler::Success; |
| 180 | case 248: D = 0x3fc45f306dc9c882; return MCDisassembler::Success; // 1/(2*PI) |
| 181 | default: return MCDisassembler::Fail; |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | DecodeStatus AMDGPUDisassembler::DecodeImmedInteger(unsigned Imm, |
| 186 | int64_t &I) const { |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 187 | if ((Imm >= 128) && (Imm <= 192)) { |
| 188 | I = Imm - 128; |
| 189 | return MCDisassembler::Success; |
| 190 | } else if ((Imm >= 193) && (Imm <= 208)) { |
| 191 | I = 192 - Imm; |
| 192 | return MCDisassembler::Success; |
| 193 | } |
| 194 | return MCDisassembler::Fail; |
| 195 | } |
| 196 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 197 | DecodeStatus AMDGPUDisassembler::DecodeVgprRegister(unsigned Val, |
| 198 | unsigned &RegID, |
| 199 | unsigned Size) const { |
| 200 | if (Val > (256 - Size / 32)) { |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 201 | return MCDisassembler::Fail; |
| 202 | } |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 203 | unsigned RegClassID; |
| 204 | switch (Size) { |
| 205 | case 32: RegClassID = AMDGPU::VGPR_32RegClassID; break; |
| 206 | case 64: RegClassID = AMDGPU::VReg_64RegClassID; break; |
| 207 | case 96: RegClassID = AMDGPU::VReg_96RegClassID; break; |
| 208 | case 128: RegClassID = AMDGPU::VReg_128RegClassID; break; |
| 209 | case 256: RegClassID = AMDGPU::VReg_256RegClassID; break; |
| 210 | case 512: RegClassID = AMDGPU::VReg_512RegClassID; break; |
| 211 | default: |
| 212 | return MCDisassembler::Fail; |
| 213 | } |
| 214 | |
| 215 | RegID = AMDGPUMCRegisterClasses[RegClassID].getRegister(Val); |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 216 | return MCDisassembler::Success; |
| 217 | } |
| 218 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 219 | DecodeStatus AMDGPUDisassembler::DecodeSgprRegister(unsigned Val, |
| 220 | unsigned &RegID, |
| 221 | unsigned Size) const { |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 222 | // ToDo: SI/CI have 104 SGPRs, VI - 102 |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 223 | unsigned RegClassID; |
| 224 | |
| 225 | switch (Size) { |
| 226 | case 32: |
| 227 | if (Val > 101) { |
| 228 | return MCDisassembler::Fail; |
| 229 | } |
| 230 | RegClassID = AMDGPU::SGPR_32RegClassID; |
| 231 | break; |
| 232 | case 64: |
| 233 | if ((Val % 2 != 0) || (Val > 100)) { |
| 234 | return MCDisassembler::Fail; |
| 235 | } |
| 236 | Val /= 2; |
| 237 | RegClassID = AMDGPU::SGPR_64RegClassID; |
| 238 | break; |
| 239 | case 128: |
| 240 | // ToDo: unclear if s[100:104] is available on VI. Can we use VCC as SGPR in |
| 241 | // this bundle? |
| 242 | if ((Val % 4 != 0) || (Val > 96)) { |
| 243 | return MCDisassembler::Fail; |
| 244 | } |
| 245 | Val /= 4; |
| 246 | RegClassID = AMDGPU::SReg_128RegClassID; |
| 247 | break; |
| 248 | case 256: |
| 249 | // ToDo: unclear if s[96:104] is available on VI. Can we use VCC as SGPR in |
| 250 | // this bundle? |
| 251 | if ((Val % 4 != 0) || (Val > 92)) { |
| 252 | return MCDisassembler::Fail; |
| 253 | } |
| 254 | Val /= 4; |
| 255 | RegClassID = AMDGPU::SReg_256RegClassID; |
| 256 | break; |
| 257 | case 512: |
| 258 | // ToDo: unclear if s[88:104] is available on VI. Can we use VCC as SGPR in |
| 259 | // this bundle? |
| 260 | if ((Val % 4 != 0) || (Val > 84)) { |
| 261 | return MCDisassembler::Fail; |
| 262 | } |
| 263 | Val /= 4; |
| 264 | RegClassID = AMDGPU::SReg_512RegClassID; |
| 265 | break; |
| 266 | default: |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 267 | return MCDisassembler::Fail; |
| 268 | } |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 269 | |
| 270 | RegID = AMDGPUMCRegisterClasses[RegClassID].getRegister(Val); |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 271 | return MCDisassembler::Success; |
| 272 | } |
| 273 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 274 | DecodeStatus AMDGPUDisassembler::DecodeSrc32Register(unsigned Val, |
| 275 | unsigned &RegID) const { |
| 276 | // ToDo: deal with out-of range registers |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 277 | using namespace AMDGPU; |
| 278 | if (Val <= 101) { |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 279 | return DecodeSgprRegister(Val, RegID, 32); |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 280 | } else if ((Val >= 256) && (Val <= 511)) { |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 281 | return DecodeVgprRegister(Val - 256, RegID, 32); |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 282 | } else { |
| 283 | switch(Val) { |
| 284 | case 102: RegID = getMCReg(FLAT_SCR_LO, STI); return MCDisassembler::Success; |
| 285 | case 103: RegID = getMCReg(FLAT_SCR_HI, STI); return MCDisassembler::Success; |
| 286 | // ToDo: no support for xnack_mask_lo/_hi register |
| 287 | case 104: |
| 288 | case 105: return MCDisassembler::Fail; |
| 289 | case 106: RegID = getMCReg(VCC_LO, STI); return MCDisassembler::Success; |
| 290 | case 107: RegID = getMCReg(VCC_HI, STI); return MCDisassembler::Success; |
| 291 | // ToDo: no support for tba_lo/_hi register |
| 292 | case 108: |
| 293 | case 109: return MCDisassembler::Fail; |
| 294 | // ToDo: no support for tma_lo/_hi register |
| 295 | case 110: |
| 296 | case 111: return MCDisassembler::Fail; |
| 297 | // ToDo: no support for ttmp[0:11] register |
| 298 | case 112: |
| 299 | case 113: |
| 300 | case 114: |
| 301 | case 115: |
| 302 | case 116: |
| 303 | case 117: |
| 304 | case 118: |
| 305 | case 119: |
| 306 | case 120: |
| 307 | case 121: |
| 308 | case 122: |
| 309 | case 123: return MCDisassembler::Fail; |
| 310 | case 124: RegID = getMCReg(M0, STI); return MCDisassembler::Success; |
| 311 | case 126: RegID = getMCReg(EXEC_LO, STI); return MCDisassembler::Success; |
| 312 | case 127: RegID = getMCReg(EXEC_HI, STI); return MCDisassembler::Success; |
| 313 | // ToDo: no support for vccz register |
| 314 | case 251: return MCDisassembler::Fail; |
| 315 | // ToDo: no support for execz register |
| 316 | case 252: return MCDisassembler::Fail; |
| 317 | case 253: RegID = getMCReg(SCC, STI); return MCDisassembler::Success; |
| 318 | default: return MCDisassembler::Fail; |
| 319 | } |
| 320 | } |
| 321 | return MCDisassembler::Fail; |
| 322 | } |
| 323 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 324 | DecodeStatus AMDGPUDisassembler::DecodeSrc64Register(unsigned Val, |
| 325 | unsigned &RegID) const { |
| 326 | // ToDo: deal with out-of range registers |
| 327 | using namespace AMDGPU; |
| 328 | if (Val <= 101) { |
| 329 | return DecodeSgprRegister(Val, RegID, 64); |
| 330 | } else if ((Val >= 256) && (Val <= 511)) { |
| 331 | return DecodeVgprRegister(Val - 256, RegID, 64); |
| 332 | } else { |
| 333 | switch(Val) { |
| 334 | case 102: RegID = getMCReg(FLAT_SCR, STI); return MCDisassembler::Success; |
| 335 | case 106: RegID = getMCReg(VCC, STI); return MCDisassembler::Success; |
| 336 | case 126: RegID = getMCReg(EXEC, STI); return MCDisassembler::Success; |
| 337 | default: return MCDisassembler::Fail; |
| 338 | } |
| 339 | } |
| 340 | return MCDisassembler::Fail; |
| 341 | } |
| 342 | |
| 343 | DecodeStatus AMDGPUDisassembler::DecodeLiteralConstant(MCInst &Inst, |
| 344 | uint64_t &Literal) const { |
| 345 | // For now all literal constants are supposed to be unsigned integer |
| 346 | // ToDo: deal with signed/unsigned 64-bit integer constants |
| 347 | // ToDo: deal with float/double constants |
| 348 | if (Bytes.size() < 8) { |
| 349 | return MCDisassembler::Fail; |
| 350 | } |
| 351 | Literal = |
| 352 | 0 | (Bytes[7] << 24) | (Bytes[6] << 16) | (Bytes[5] << 8) | (Bytes[4] << 0); |
| 353 | return MCDisassembler::Success; |
| 354 | } |
| 355 | |
| 356 | DecodeStatus AMDGPUDisassembler::DecodeVGPR_32RegisterClass(llvm::MCInst &Inst, |
| 357 | unsigned Imm, |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 358 | uint64_t Addr) const { |
| 359 | unsigned RegID; |
| 360 | if (DecodeVgprRegister(Imm, RegID) == MCDisassembler::Success) { |
| 361 | Inst.addOperand(MCOperand::createReg(RegID)); |
| 362 | return MCDisassembler::Success; |
| 363 | } |
| 364 | return MCDisassembler::Fail; |
| 365 | } |
| 366 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 367 | DecodeStatus AMDGPUDisassembler::DecodeVSRegisterClass(MCInst &Inst, |
| 368 | unsigned Imm, |
| 369 | uint64_t Addr, |
| 370 | bool Is32) const { |
| 371 | // ToDo: different opcodes allow different formats of this operands |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 372 | if ((Imm >= 128) && (Imm <= 208)) { |
| 373 | // immediate integer |
| 374 | int64_t Val; |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 375 | if (DecodeImmedInteger(Imm, Val) == MCDisassembler::Success) { |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 376 | Inst.addOperand(MCOperand::createImm(Val)); |
| 377 | return MCDisassembler::Success; |
| 378 | } |
| 379 | } else if ((Imm >= 240) && (Imm <= 248)) { |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 380 | // immediate float/double |
| 381 | uint64_t Val; |
| 382 | DecodeStatus status; |
| 383 | if (Is32) { |
| 384 | uint32_t Val32; |
| 385 | status = DecodeImmedFloat(Imm, Val32); |
| 386 | Val = static_cast<uint64_t>(Val32); |
| 387 | } else { |
| 388 | status = DecodeImmedDouble(Imm, Val); |
| 389 | } |
| 390 | if (status == MCDisassembler::Success) { |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 391 | Inst.addOperand(MCOperand::createImm(Val)); |
| 392 | return MCDisassembler::Success; |
| 393 | } |
| 394 | } else if (Imm == 254) { |
| 395 | // LDS direct |
| 396 | // ToDo: implement LDS direct read |
| 397 | } else if (Imm == 255) { |
| 398 | // literal constant |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 399 | HasLiteral = true; |
| 400 | uint64_t Literal; |
| 401 | if (DecodeLiteralConstant(Inst, Literal) == MCDisassembler::Success) { |
| 402 | Inst.addOperand(MCOperand::createImm(Literal)); |
| 403 | return MCDisassembler::Success; |
| 404 | } |
| 405 | return MCDisassembler::Fail; |
| 406 | } else if ((Imm == 125) || |
| 407 | ((Imm >= 209) && (Imm <= 239)) || |
| 408 | (Imm == 249) || |
| 409 | (Imm == 250) || |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 410 | (Imm >= 512)) { |
| 411 | // reserved |
| 412 | return MCDisassembler::Fail; |
| 413 | } else { |
| 414 | // register |
| 415 | unsigned RegID; |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 416 | DecodeStatus status = Is32 ? DecodeSrc32Register(Imm, RegID) |
| 417 | : DecodeSrc64Register(Imm, RegID); |
| 418 | if (status == MCDisassembler::Success) { |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 419 | Inst.addOperand(MCOperand::createReg(RegID)); |
| 420 | return MCDisassembler::Success; |
| 421 | } |
| 422 | } |
| 423 | return MCDisassembler::Fail; |
| 424 | } |
| 425 | |
Nikolay Haustov | 161a158 | 2016-02-25 16:09:14 +0000 | [diff] [blame] | 426 | DecodeStatus AMDGPUDisassembler::DecodeVS_32RegisterClass(MCInst &Inst, |
| 427 | unsigned Imm, |
| 428 | uint64_t Addr) const { |
| 429 | return DecodeVSRegisterClass(Inst, Imm, Addr, true); |
| 430 | } |
| 431 | |
| 432 | DecodeStatus AMDGPUDisassembler::DecodeVS_64RegisterClass(MCInst &Inst, |
| 433 | unsigned Imm, |
| 434 | uint64_t Addr) const { |
| 435 | return DecodeVSRegisterClass(Inst, Imm, Addr, false); |
| 436 | } |
| 437 | |
| 438 | DecodeStatus AMDGPUDisassembler::DecodeVReg_64RegisterClass(llvm::MCInst &Inst, |
| 439 | unsigned Imm, |
| 440 | uint64_t Addr) const { |
| 441 | unsigned RegID; |
| 442 | if (DecodeVgprRegister(Imm, RegID, 64) == MCDisassembler::Success) { |
| 443 | Inst.addOperand(MCOperand::createReg(RegID)); |
| 444 | return MCDisassembler::Success; |
| 445 | } |
| 446 | return MCDisassembler::Fail; |
| 447 | } |
| 448 | |
| 449 | |
| 450 | |
Tom Stellard | e1818af | 2016-02-18 03:42:32 +0000 | [diff] [blame] | 451 | static MCDisassembler *createAMDGPUDisassembler(const Target &T, |
| 452 | const MCSubtargetInfo &STI, |
| 453 | MCContext &Ctx) { |
| 454 | return new AMDGPUDisassembler(STI, Ctx); |
| 455 | } |
| 456 | |
| 457 | extern "C" void LLVMInitializeAMDGPUDisassembler() { |
| 458 | TargetRegistry::RegisterMCDisassembler(TheGCNTarget, createAMDGPUDisassembler); |
| 459 | } |