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