aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
diff options
context:
space:
mode:
authorColin LeMahieu <colinl@codeaurora.org>2015-05-29 14:44:13 +0000
committerColin LeMahieu <colinl@codeaurora.org>2015-05-29 14:44:13 +0000
commit68d967d92ed502c75cdbbd1914ba39b8d9baa9f8 (patch)
tree07f54d02e639469fb17d4fb10a3d7e5d622187e3 /llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
parent10d238751e4e887fb7dc5142da04f640fb3504f8 (diff)
downloadllvm-68d967d92ed502c75cdbbd1914ba39b8d9baa9f8.zip
llvm-68d967d92ed502c75cdbbd1914ba39b8d9baa9f8.tar.gz
llvm-68d967d92ed502c75cdbbd1914ba39b8d9baa9f8.tar.bz2
[Hexagon] Disassembling, printing, and emitting instructions a whole-bundle at a time which is the semantic unit for Hexagon. Fixing tests to use the new format. Disabling tests in the direct object emission path for a followup patch.
llvm-svn: 238556
Diffstat (limited to 'llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp62
1 files changed, 53 insertions, 9 deletions
diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
index a60d1e4..81f2632 100644
--- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
+++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
@@ -7,9 +7,11 @@
//
//===----------------------------------------------------------------------===//
+#include "Hexagon.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
+
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCExpr.h"
@@ -27,6 +29,7 @@
#include <vector>
using namespace llvm;
+using namespace Hexagon;
#define DEBUG_TYPE "hexagon-disassembler"
@@ -37,9 +40,14 @@ namespace {
/// \brief Hexagon disassembler for all Hexagon platforms.
class HexagonDisassembler : public MCDisassembler {
public:
+ std::unique_ptr<MCInst *> CurrentBundle;
HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx)
- : MCDisassembler(STI, Ctx) {}
+ : MCDisassembler(STI, Ctx), CurrentBundle(new MCInst *) {}
+ DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &VStream, raw_ostream &CStream,
+ bool &Complete) const;
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &VStream,
@@ -191,17 +199,53 @@ DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
uint64_t Address,
raw_ostream &os,
raw_ostream &cs) const {
- Size = 4;
- if (Bytes.size() < 4)
- return MCDisassembler::Fail;
+ DecodeStatus Result = DecodeStatus::Success;
+ bool Complete = false;
+ Size = 0;
+
+ *CurrentBundle = &MI;
+ MI.setOpcode(Hexagon::BUNDLE);
+ MI.addOperand(MCOperand::createImm(0));
+ while (Result == Success && Complete == false)
+ {
+ if (Bytes.size() < HEXAGON_INSTR_SIZE)
+ return MCDisassembler::Fail;
+ MCInst * Inst = new (getContext()) MCInst;
+ Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
+ MI.addOperand(MCOperand::createInst(Inst));
+ Size += HEXAGON_INSTR_SIZE;
+ Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
+ }
+ return Result;
+}
- uint32_t insn =
+DecodeStatus HexagonDisassembler::getSingleInstruction(
+ MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &os, raw_ostream &cs, bool &Complete) const {
+ assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
+
+ uint32_t Instruction =
llvm::support::endian::read<uint32_t, llvm::support::little,
llvm::support::unaligned>(Bytes.data());
- // Remove parse bits.
- insn &= ~static_cast<uint32_t>(HexagonII::InstParseBits::INST_PARSE_MASK);
- DecodeStatus Result = decodeInstruction(DecoderTable32, MI, insn, Address, this, STI);
- HexagonMCInstrInfo::AppendImplicitOperands(MI);
+ auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
+ if ((Instruction & HexagonII::INST_PARSE_MASK) ==
+ HexagonII::INST_PARSE_LOOP_END) {
+ if (BundleSize == 0)
+ HexagonMCInstrInfo::setInnerLoop(MCB);
+ else if (BundleSize == 1)
+ HexagonMCInstrInfo::setOuterLoop(MCB);
+ else
+ return DecodeStatus::Fail;
+ }
+
+ DecodeStatus Result = DecodeStatus::Success;
+ if ((Instruction & HexagonII::INST_PARSE_MASK) ==
+ HexagonII::INST_PARSE_PACKET_END)
+ Complete = true;
+ // Calling the auto-generated decoder function.
+ Result =
+ decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
+
return Result;
}