1 //===------ SparcDisassembler.cpp - Disassembler for PowerPC ------*- 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 /* Capstone Disassembly Engine */ 11 /* By Nguyen Anh Quynh <aquynh (at) gmail.com>, 2013-2014 */ 12 13 #ifdef CAPSTONE_HAS_SPARC 14 15 #include <stdio.h> // DEBUG 16 #include <stdlib.h> 17 #include <string.h> 18 19 #include "../../cs_priv.h" 20 #include "../../utils.h" 21 22 #include "../../MCInst.h" 23 #include "../../MCInstrDesc.h" 24 #include "../../MCFixedLenDisassembler.h" 25 #include "../../MCRegisterInfo.h" 26 #include "../../MCDisassembler.h" 27 #include "../../MathExtras.h" 28 29 30 #define GET_REGINFO_MC_DESC 31 #define GET_REGINFO_ENUM 32 #include "SparcGenRegisterInfo.inc" 33 static const unsigned IntRegDecoderTable[] = { 34 SP_G0, SP_G1, SP_G2, SP_G3, 35 SP_G4, SP_G5, SP_G6, SP_G7, 36 SP_O0, SP_O1, SP_O2, SP_O3, 37 SP_O4, SP_O5, SP_O6, SP_O7, 38 SP_L0, SP_L1, SP_L2, SP_L3, 39 SP_L4, SP_L5, SP_L6, SP_L7, 40 SP_I0, SP_I1, SP_I2, SP_I3, 41 SP_I4, SP_I5, SP_I6, SP_I7 42 }; 43 44 static const unsigned FPRegDecoderTable[] = { 45 SP_F0, SP_F1, SP_F2, SP_F3, 46 SP_F4, SP_F5, SP_F6, SP_F7, 47 SP_F8, SP_F9, SP_F10, SP_F11, 48 SP_F12, SP_F13, SP_F14, SP_F15, 49 SP_F16, SP_F17, SP_F18, SP_F19, 50 SP_F20, SP_F21, SP_F22, SP_F23, 51 SP_F24, SP_F25, SP_F26, SP_F27, 52 SP_F28, SP_F29, SP_F30, SP_F31 53 }; 54 55 static const unsigned DFPRegDecoderTable[] = { 56 SP_D0, SP_D16, SP_D1, SP_D17, 57 SP_D2, SP_D18, SP_D3, SP_D19, 58 SP_D4, SP_D20, SP_D5, SP_D21, 59 SP_D6, SP_D22, SP_D7, SP_D23, 60 SP_D8, SP_D24, SP_D9, SP_D25, 61 SP_D10, SP_D26, SP_D11, SP_D27, 62 SP_D12, SP_D28, SP_D13, SP_D29, 63 SP_D14, SP_D30, SP_D15, SP_D31 64 }; 65 66 static const unsigned QFPRegDecoderTable[] = { 67 SP_Q0, SP_Q8, ~0U, ~0U, 68 SP_Q1, SP_Q9, ~0U, ~0U, 69 SP_Q2, SP_Q10, ~0U, ~0U, 70 SP_Q3, SP_Q11, ~0U, ~0U, 71 SP_Q4, SP_Q12, ~0U, ~0U, 72 SP_Q5, SP_Q13, ~0U, ~0U, 73 SP_Q6, SP_Q14, ~0U, ~0U, 74 SP_Q7, SP_Q15, ~0U, ~0U 75 }; 76 77 static const unsigned FCCRegDecoderTable[] = { 78 SP_FCC0, SP_FCC1, SP_FCC2, SP_FCC3 79 }; 80 81 static uint64_t getFeatureBits(int mode) 82 { 83 // support everything 84 return (uint64_t)-1; 85 } 86 87 static DecodeStatus DecodeIntRegsRegisterClass(MCInst *Inst, unsigned RegNo, 88 uint64_t Address, const void *Decoder) 89 { 90 unsigned Reg; 91 92 if (RegNo > 31) 93 return MCDisassembler_Fail; 94 95 Reg = IntRegDecoderTable[RegNo]; 96 MCOperand_CreateReg0(Inst, Reg); 97 98 return MCDisassembler_Success; 99 } 100 101 static DecodeStatus DecodeI64RegsRegisterClass(MCInst *Inst, unsigned RegNo, 102 uint64_t Address, const void *Decoder) 103 { 104 unsigned Reg; 105 106 if (RegNo > 31) 107 return MCDisassembler_Fail; 108 109 Reg = IntRegDecoderTable[RegNo]; 110 MCOperand_CreateReg0(Inst, Reg); 111 112 return MCDisassembler_Success; 113 } 114 115 static DecodeStatus DecodeFPRegsRegisterClass(MCInst *Inst, unsigned RegNo, 116 uint64_t Address, const void *Decoder) 117 { 118 unsigned Reg; 119 120 if (RegNo > 31) 121 return MCDisassembler_Fail; 122 123 Reg = FPRegDecoderTable[RegNo]; 124 MCOperand_CreateReg0(Inst, Reg); 125 126 return MCDisassembler_Success; 127 } 128 129 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst *Inst, unsigned RegNo, 130 uint64_t Address, const void *Decoder) 131 { 132 unsigned Reg; 133 134 if (RegNo > 31) 135 return MCDisassembler_Fail; 136 137 Reg = DFPRegDecoderTable[RegNo]; 138 MCOperand_CreateReg0(Inst, Reg); 139 140 return MCDisassembler_Success; 141 } 142 143 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst *Inst, unsigned RegNo, 144 uint64_t Address, const void *Decoder) 145 { 146 unsigned Reg; 147 148 if (RegNo > 31) 149 return MCDisassembler_Fail; 150 151 Reg = QFPRegDecoderTable[RegNo]; 152 if (Reg == ~0U) 153 return MCDisassembler_Fail; 154 155 MCOperand_CreateReg0(Inst, Reg); 156 157 return MCDisassembler_Success; 158 } 159 160 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst *Inst, unsigned RegNo, 161 uint64_t Address, const void *Decoder) 162 { 163 if (RegNo > 3) 164 return MCDisassembler_Fail; 165 166 MCOperand_CreateReg0(Inst, FCCRegDecoderTable[RegNo]); 167 168 return MCDisassembler_Success; 169 } 170 171 172 static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address, 173 const void *Decoder); 174 static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address, 175 const void *Decoder); 176 static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address, 177 const void *Decoder); 178 static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address, 179 const void *Decoder); 180 static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn, 181 uint64_t Address, const void *Decoder); 182 static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn, 183 uint64_t Address, const void *Decoder); 184 static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn, 185 uint64_t Address, const void *Decoder); 186 static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn, 187 uint64_t Address, const void *Decoder); 188 static DecodeStatus DecodeCall(MCInst *Inst, unsigned insn, 189 uint64_t Address, const void *Decoder); 190 static DecodeStatus DecodeSIMM13(MCInst *Inst, unsigned insn, 191 uint64_t Address, const void *Decoder); 192 static DecodeStatus DecodeJMPL(MCInst *Inst, unsigned insn, uint64_t Address, 193 const void *Decoder); 194 static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address, 195 const void *Decoder); 196 static DecodeStatus DecodeSWAP(MCInst *Inst, unsigned insn, uint64_t Address, 197 const void *Decoder); 198 199 200 #define GET_SUBTARGETINFO_ENUM 201 #include "SparcGenSubtargetInfo.inc" 202 #include "SparcGenDisassemblerTables.inc" 203 204 /// readInstruction - read four bytes and return 32 bit word. 205 static DecodeStatus readInstruction32(const uint8_t *code, size_t len, uint32_t *Insn) 206 { 207 uint8_t Bytes[4]; 208 209 if (len < 4) 210 // not enough data 211 return MCDisassembler_Fail; 212 213 memcpy(Bytes, code, 4); 214 215 // Encoded as a big-endian 32-bit word in the stream. 216 *Insn = (Bytes[3] << 0) | 217 (Bytes[2] << 8) | 218 (Bytes[1] << 16) | 219 (Bytes[0] << 24); 220 221 return MCDisassembler_Success; 222 } 223 224 bool Sparc_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI, 225 uint16_t *size, uint64_t address, void *info) 226 { 227 uint32_t Insn; 228 DecodeStatus Result; 229 230 Result = readInstruction32(code, code_len, &Insn); 231 if (Result == MCDisassembler_Fail) 232 return false; 233 234 if (MI->flat_insn->detail) { 235 memset(MI->flat_insn->detail, 0, sizeof(cs_detail)); 236 } 237 238 Result = decodeInstruction_4(DecoderTableSparc32, MI, Insn, address, 239 (MCRegisterInfo *)info, 0); 240 if (Result != MCDisassembler_Fail) { 241 *size = 4; 242 return true; 243 } 244 245 return false; 246 } 247 248 typedef DecodeStatus (*DecodeFunc)(MCInst *MI, unsigned insn, uint64_t Address, 249 const void *Decoder); 250 251 static DecodeStatus DecodeMem(MCInst *MI, unsigned insn, uint64_t Address, 252 const void *Decoder, 253 bool isLoad, DecodeFunc DecodeRD) 254 { 255 DecodeStatus status; 256 unsigned rd = fieldFromInstruction_4(insn, 25, 5); 257 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5); 258 bool isImm = fieldFromInstruction_4(insn, 13, 1) != 0; 259 unsigned rs2 = 0; 260 unsigned simm13 = 0; 261 262 if (isImm) 263 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); 264 else 265 rs2 = fieldFromInstruction_4(insn, 0, 5); 266 267 if (isLoad) { 268 status = DecodeRD(MI, rd, Address, Decoder); 269 if (status != MCDisassembler_Success) 270 return status; 271 } 272 273 // Decode rs1. 274 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 275 if (status != MCDisassembler_Success) 276 return status; 277 278 // Decode imm|rs2. 279 if (isImm) 280 MCOperand_CreateImm0(MI, simm13); 281 else { 282 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 283 if (status != MCDisassembler_Success) 284 return status; 285 } 286 287 if (!isLoad) { 288 status = DecodeRD(MI, rd, Address, Decoder); 289 if (status != MCDisassembler_Success) 290 return status; 291 } 292 293 return MCDisassembler_Success; 294 } 295 296 static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address, 297 const void *Decoder) 298 { 299 return DecodeMem(Inst, insn, Address, Decoder, true, 300 DecodeIntRegsRegisterClass); 301 } 302 303 static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address, 304 const void *Decoder) 305 { 306 return DecodeMem(Inst, insn, Address, Decoder, true, 307 DecodeFPRegsRegisterClass); 308 } 309 310 static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address, 311 const void *Decoder) 312 { 313 return DecodeMem(Inst, insn, Address, Decoder, true, 314 DecodeDFPRegsRegisterClass); 315 } 316 317 static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address, 318 const void *Decoder) 319 { 320 return DecodeMem(Inst, insn, Address, Decoder, true, 321 DecodeQFPRegsRegisterClass); 322 } 323 324 static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn, 325 uint64_t Address, const void *Decoder) 326 { 327 return DecodeMem(Inst, insn, Address, Decoder, false, 328 DecodeIntRegsRegisterClass); 329 } 330 331 static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn, uint64_t Address, 332 const void *Decoder) 333 { 334 return DecodeMem(Inst, insn, Address, Decoder, false, 335 DecodeFPRegsRegisterClass); 336 } 337 338 static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn, 339 uint64_t Address, const void *Decoder) 340 { 341 return DecodeMem(Inst, insn, Address, Decoder, false, 342 DecodeDFPRegsRegisterClass); 343 } 344 345 static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn, 346 uint64_t Address, const void *Decoder) 347 { 348 return DecodeMem(Inst, insn, Address, Decoder, false, 349 DecodeQFPRegsRegisterClass); 350 } 351 352 static DecodeStatus DecodeCall(MCInst *MI, unsigned insn, 353 uint64_t Address, const void *Decoder) 354 { 355 unsigned tgt = fieldFromInstruction_4(insn, 0, 30); 356 tgt <<= 2; 357 358 MCOperand_CreateImm0(MI, tgt); 359 360 return MCDisassembler_Success; 361 } 362 363 static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn, 364 uint64_t Address, const void *Decoder) 365 { 366 unsigned tgt = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); 367 368 MCOperand_CreateImm0(MI, tgt); 369 370 return MCDisassembler_Success; 371 } 372 373 static DecodeStatus DecodeJMPL(MCInst *MI, unsigned insn, uint64_t Address, 374 const void *Decoder) 375 { 376 DecodeStatus status; 377 unsigned rd = fieldFromInstruction_4(insn, 25, 5); 378 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5); 379 unsigned isImm = fieldFromInstruction_4(insn, 13, 1); 380 unsigned rs2 = 0; 381 unsigned simm13 = 0; 382 383 if (isImm) 384 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); 385 else 386 rs2 = fieldFromInstruction_4(insn, 0, 5); 387 388 // Decode RD. 389 status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 390 if (status != MCDisassembler_Success) 391 return status; 392 393 // Decode RS1. 394 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 395 if (status != MCDisassembler_Success) 396 return status; 397 398 // Decode RS1 | SIMM13. 399 if (isImm) 400 MCOperand_CreateImm0(MI, simm13); 401 else { 402 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 403 if (status != MCDisassembler_Success) 404 return status; 405 } 406 407 return MCDisassembler_Success; 408 } 409 410 static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address, 411 const void *Decoder) 412 { 413 DecodeStatus status; 414 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5); 415 unsigned isImm = fieldFromInstruction_4(insn, 13, 1); 416 unsigned rs2 = 0; 417 unsigned simm13 = 0; 418 if (isImm) 419 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); 420 else 421 rs2 = fieldFromInstruction_4(insn, 0, 5); 422 423 // Decode RS1. 424 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 425 if (status != MCDisassembler_Success) 426 return status; 427 428 // Decode RS2 | SIMM13. 429 if (isImm) 430 MCOperand_CreateImm0(MI, simm13); 431 else { 432 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 433 if (status != MCDisassembler_Success) 434 return status; 435 } 436 437 return MCDisassembler_Success; 438 } 439 440 static DecodeStatus DecodeSWAP(MCInst *MI, unsigned insn, uint64_t Address, 441 const void *Decoder) 442 { 443 DecodeStatus status; 444 unsigned rd = fieldFromInstruction_4(insn, 25, 5); 445 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5); 446 unsigned isImm = fieldFromInstruction_4(insn, 13, 1); 447 unsigned rs2 = 0; 448 unsigned simm13 = 0; 449 450 if (isImm) 451 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); 452 else 453 rs2 = fieldFromInstruction_4(insn, 0, 5); 454 455 // Decode RD. 456 status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); 457 if (status != MCDisassembler_Success) 458 return status; 459 460 // Decode RS1. 461 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); 462 if (status != MCDisassembler_Success) 463 return status; 464 465 // Decode RS1 | SIMM13. 466 if (isImm) 467 MCOperand_CreateImm0(MI, simm13); 468 else { 469 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); 470 if (status != MCDisassembler_Success) 471 return status; 472 } 473 474 return MCDisassembler_Success; 475 } 476 477 void Sparc_init(MCRegisterInfo *MRI) 478 { 479 /* 480 InitMCRegisterInfo(SparcRegDesc, 119, RA, PC, 481 SparcMCRegisterClasses, 8, 482 SparcRegUnitRoots, 483 86, 484 SparcRegDiffLists, 485 SparcRegStrings, 486 SparcSubRegIdxLists, 487 7, 488 SparcSubRegIdxRanges, 489 SparcRegEncodingTable); 490 */ 491 492 MCRegisterInfo_InitMCRegisterInfo(MRI, SparcRegDesc, 119, 493 0, 0, 494 SparcMCRegisterClasses, 8, 495 0, 0, 496 SparcRegDiffLists, 497 0, 498 SparcSubRegIdxLists, 7, 499 0); 500 } 501 502 #endif 503