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