1 //===- LanaiDisassembler.cpp - Disassembler for Lanai -----------*- 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 // This file is part of the Lanai Disassembler. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "LanaiDisassembler.h" 15 16 #include "Lanai.h" 17 #include "LanaiSubtarget.h" 18 #include "llvm/MC/MCFixedLenDisassembler.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCSubtargetInfo.h" 21 #include "llvm/Support/MathExtras.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 using namespace llvm; 25 26 typedef MCDisassembler::DecodeStatus DecodeStatus; 27 28 namespace llvm { 29 Target &getTheLanaiTarget(); 30 } 31 32 static MCDisassembler *createLanaiDisassembler(const Target & /*T*/, 33 const MCSubtargetInfo &STI, 34 MCContext &Ctx) { 35 return new LanaiDisassembler(STI, Ctx); 36 } 37 38 extern "C" void LLVMInitializeLanaiDisassembler() { 39 // Register the disassembler 40 TargetRegistry::RegisterMCDisassembler(getTheLanaiTarget(), 41 createLanaiDisassembler); 42 } 43 44 LanaiDisassembler::LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 45 : MCDisassembler(STI, Ctx) {} 46 47 // Forward declare because the autogenerated code will reference this. 48 // Definition is further down. 49 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 50 uint64_t Address, 51 const void *Decoder); 52 53 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn, 54 uint64_t Address, const void *Decoder); 55 56 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn, 57 uint64_t Address, const void *Decoder); 58 59 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn, 60 uint64_t Address, const void *Decoder); 61 62 static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address, 63 const void *Decoder); 64 65 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, 66 uint64_t Address, 67 const void *Decoder); 68 69 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn, 70 uint64_t Address, const void *Decoder); 71 72 #include "LanaiGenDisassemblerTables.inc" 73 74 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t &Size, 75 uint32_t &Insn) { 76 // We want to read exactly 4 bytes of data. 77 if (Bytes.size() < 4) { 78 Size = 0; 79 return MCDisassembler::Fail; 80 } 81 82 // Encoded as big-endian 32-bit word in the stream. 83 Insn = 84 (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0); 85 86 return MCDisassembler::Success; 87 } 88 89 static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn) { 90 unsigned AluOp = LPAC::ADD; 91 // Fix up for pre and post operations. 92 int PqShift = -1; 93 if (isRMOpcode(Instr.getOpcode())) 94 PqShift = 16; 95 else if (isSPLSOpcode(Instr.getOpcode())) 96 PqShift = 10; 97 else if (isRRMOpcode(Instr.getOpcode())) { 98 PqShift = 16; 99 // Determine RRM ALU op. 100 AluOp = (Insn >> 8) & 0x7; 101 if (AluOp == 7) 102 // Handle JJJJJ 103 // 0b10000 or 0b11000 104 AluOp |= 0x20 | (((Insn >> 3) & 0xf) << 1); 105 } 106 107 if (PqShift != -1) { 108 unsigned PQ = (Insn >> PqShift) & 0x3; 109 switch (PQ) { 110 case 0x0: 111 if (Instr.getOperand(2).isReg()) { 112 Instr.getOperand(2).setReg(Lanai::R0); 113 } 114 if (Instr.getOperand(2).isImm()) 115 Instr.getOperand(2).setImm(0); 116 break; 117 case 0x1: 118 AluOp = LPAC::makePostOp(AluOp); 119 break; 120 case 0x2: 121 break; 122 case 0x3: 123 AluOp = LPAC::makePreOp(AluOp); 124 break; 125 } 126 Instr.addOperand(MCOperand::createImm(AluOp)); 127 } 128 } 129 130 DecodeStatus LanaiDisassembler::getInstruction( 131 MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, 132 raw_ostream & /*VStream*/, raw_ostream & /*CStream*/) const { 133 uint32_t Insn; 134 135 DecodeStatus Result = readInstruction32(Bytes, Size, Insn); 136 137 if (Result == MCDisassembler::Fail) 138 return MCDisassembler::Fail; 139 140 // Call auto-generated decoder function 141 Result = 142 decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI); 143 144 if (Result != MCDisassembler::Fail) { 145 PostOperandDecodeAdjust(Instr, Insn); 146 Size = 4; 147 return Result; 148 } 149 150 return MCDisassembler::Fail; 151 } 152 153 static const unsigned GPRDecoderTable[] = { 154 Lanai::R0, Lanai::R1, Lanai::PC, Lanai::R3, Lanai::SP, Lanai::FP, 155 Lanai::R6, Lanai::R7, Lanai::RV, Lanai::R9, Lanai::RR1, Lanai::RR2, 156 Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17, 157 Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23, 158 Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29, 159 Lanai::R30, Lanai::R31}; 160 161 DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, 162 uint64_t /*Address*/, 163 const void * /*Decoder*/) { 164 if (RegNo > 31) 165 return MCDisassembler::Fail; 166 167 unsigned Reg = GPRDecoderTable[RegNo]; 168 Inst.addOperand(MCOperand::createReg(Reg)); 169 return MCDisassembler::Success; 170 } 171 172 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn, 173 uint64_t Address, const void *Decoder) { 174 // RI memory values encoded using 23 bits: 175 // 5 bit register, 16 bit constant 176 unsigned Register = (Insn >> 18) & 0x1f; 177 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register])); 178 unsigned Offset = (Insn & 0xffff); 179 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset))); 180 181 return MCDisassembler::Success; 182 } 183 184 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn, 185 uint64_t Address, const void *Decoder) { 186 // RR memory values encoded using 20 bits: 187 // 5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ 188 unsigned Register = (Insn >> 15) & 0x1f; 189 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register])); 190 Register = (Insn >> 10) & 0x1f; 191 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register])); 192 193 return MCDisassembler::Success; 194 } 195 196 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn, 197 uint64_t Address, const void *Decoder) { 198 // RI memory values encoded using 17 bits: 199 // 5 bit register, 10 bit constant 200 unsigned Register = (Insn >> 12) & 0x1f; 201 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register])); 202 unsigned Offset = (Insn & 0x3ff); 203 Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset))); 204 205 return MCDisassembler::Success; 206 } 207 208 static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch, 209 uint64_t Address, uint64_t Offset, 210 uint64_t Width, MCInst &MI, 211 const void *Decoder) { 212 const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder); 213 return Dis->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset, 214 Width); 215 } 216 217 static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address, 218 const void *Decoder) { 219 if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI, 220 Decoder)) 221 MI.addOperand(MCOperand::createImm(Insn)); 222 return MCDisassembler::Success; 223 } 224 225 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn, 226 uint64_t Address, const void *Decoder) { 227 unsigned Offset = (Insn & 0xffff); 228 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset))); 229 230 return MCDisassembler::Success; 231 } 232 233 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val, 234 uint64_t Address, 235 const void *Decoder) { 236 if (Val >= LPCC::UNKNOWN) 237 return MCDisassembler::Fail; 238 Inst.addOperand(MCOperand::createImm(Val)); 239 return MCDisassembler::Success; 240 } 241