@@ -43,12 +43,12 @@ namespace {
4343class HexagonDisassembler : public MCDisassembler {
4444public:
4545 std::unique_ptr<MCInstrInfo const > const MCII;
46- std::unique_ptr<MCInst * > CurrentBundle;
46+ mutable std::unique_ptr<MCInst> CurrentBundle;
4747 mutable MCInst const *CurrentExtender;
4848
4949 HexagonDisassembler (const MCSubtargetInfo &STI, MCContext &Ctx,
5050 MCInstrInfo const *MCII)
51- : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst * ),
51+ : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(nullptr ),
5252 CurrentExtender (nullptr ) {}
5353
5454 DecodeStatus getSingleInstruction (MCInst &Instr, MCInst &MCB,
@@ -57,7 +57,23 @@ class HexagonDisassembler : public MCDisassembler {
5757 DecodeStatus getInstruction (MCInst &Instr, uint64_t &Size,
5858 ArrayRef<uint8_t > Bytes, uint64_t Address,
5959 raw_ostream &CStream) const override ;
60+
61+ DecodeStatus getInstructionBundle (MCInst &Instr, uint64_t &Size,
62+ ArrayRef<uint8_t > Bytes, uint64_t Address,
63+ raw_ostream &CStream) const override ;
64+
6065 void remapInstruction (MCInst &Instr) const ;
66+
67+ private:
68+ bool makeBundle (ArrayRef<uint8_t > Bytes, uint64_t Address,
69+ uint64_t &BytesToSkip, raw_ostream &CS) const ;
70+
71+ void resetBundle () const {
72+ CurrentBundle.reset ();
73+ CurrentInstruction = nullptr ;
74+ }
75+
76+ mutable MCOperand *CurrentInstruction = nullptr ;
6177};
6278
6379static uint64_t fullValue (HexagonDisassembler const &Disassembler, MCInst &MI,
@@ -171,43 +187,88 @@ LLVMInitializeHexagonDisassembler() {
171187 createHexagonDisassembler);
172188}
173189
174- DecodeStatus HexagonDisassembler::getInstruction (MCInst &MI, uint64_t &Size,
175- ArrayRef<uint8_t > Bytes,
176- uint64_t Address,
177- raw_ostream &CS) const {
178- CommentStream = &CS;
179-
180- DecodeStatus Result = DecodeStatus::Success;
190+ bool HexagonDisassembler::makeBundle (ArrayRef<uint8_t > Bytes, uint64_t Address,
191+ uint64_t &BytesToSkip,
192+ raw_ostream &CS) const {
181193 bool Complete = false ;
182- Size = 0 ;
194+ DecodeStatus Result = DecodeStatus::Success ;
183195
184- * CurrentBundle = &MI ;
185- MI. setOpcode (Hexagon::BUNDLE);
186- MI. addOperand (MCOperand::createImm (0 ));
196+ CurrentBundle. reset ( new MCInst) ;
197+ CurrentBundle-> setOpcode (Hexagon::BUNDLE);
198+ CurrentBundle-> addOperand (MCOperand::createImm (0 ));
187199 while (Result == Success && !Complete) {
188200 if (Bytes.size () < HEXAGON_INSTR_SIZE)
189- return MCDisassembler::Fail ;
201+ return false ;
190202 MCInst *Inst = getContext ().createMCInst ();
191- Result = getSingleInstruction (*Inst, MI, Bytes, Address, CS, Complete);
192- MI.addOperand (MCOperand::createInst (Inst));
193- Size += HEXAGON_INSTR_SIZE;
203+ Result = getSingleInstruction (*Inst, *CurrentBundle, Bytes, Address, CS,
204+ Complete);
205+ CurrentBundle->addOperand (MCOperand::createInst (Inst));
206+ BytesToSkip += HEXAGON_INSTR_SIZE;
194207 Bytes = Bytes.slice (HEXAGON_INSTR_SIZE);
195208 }
196209 if (Result == MCDisassembler::Fail)
197- return Result ;
198- if (Size > HEXAGON_MAX_PACKET_SIZE)
199- return MCDisassembler::Fail ;
210+ return false ;
211+ if (BytesToSkip > HEXAGON_MAX_PACKET_SIZE)
212+ return false ;
200213
201214 const auto ArchSTI = Hexagon_MC::getArchSubtarget (&STI);
202215 const auto STI_ = (ArchSTI != nullptr ) ? *ArchSTI : STI;
203- HexagonMCChecker Checker (getContext (), *MCII, STI_, MI ,
216+ HexagonMCChecker Checker (getContext (), *MCII, STI_, *CurrentBundle ,
204217 *getContext ().getRegisterInfo (), false );
205218 if (!Checker.check ())
206- return MCDisassembler::Fail;
207- remapInstruction (MI);
219+ return false ;
220+ remapInstruction (*CurrentBundle);
221+ return true ;
222+ }
223+
224+ DecodeStatus HexagonDisassembler::getInstruction (MCInst &MI, uint64_t &Size,
225+ ArrayRef<uint8_t > Bytes,
226+ uint64_t Address,
227+ raw_ostream &CS) const {
228+ CommentStream = &CS;
229+
230+ Size = 0 ;
231+ uint64_t BytesToSkip = 0 ;
232+
233+ if (!CurrentBundle) {
234+ if (!makeBundle (Bytes, Address, BytesToSkip, CS)) {
235+ Size = BytesToSkip;
236+ resetBundle ();
237+ return MCDisassembler::Fail;
238+ }
239+ CurrentInstruction = (CurrentBundle->begin () + 1 );
240+ }
241+
242+ MI = *(CurrentInstruction->getInst ());
243+ Size = HEXAGON_INSTR_SIZE;
244+ if (++CurrentInstruction == CurrentBundle->end ())
245+ resetBundle ();
208246 return MCDisassembler::Success;
209247}
210248
249+ DecodeStatus HexagonDisassembler::getInstructionBundle (MCInst &MI,
250+ uint64_t &Size,
251+ ArrayRef<uint8_t > Bytes,
252+ uint64_t Address,
253+ raw_ostream &CS) const {
254+ CommentStream = &CS;
255+ Size = 0 ;
256+ uint64_t BytesToSkip = 0 ;
257+ assert (!CurrentBundle);
258+
259+ if (!makeBundle (Bytes, Address, BytesToSkip, CS)) {
260+ Size = BytesToSkip;
261+ resetBundle ();
262+ return MCDisassembler::Fail;
263+ }
264+
265+ MI = *CurrentBundle;
266+ Size = HEXAGON_INSTR_SIZE * HexagonMCInstrInfo::bundleSize (MI);
267+ resetBundle ();
268+
269+ return Success;
270+ }
271+
211272void HexagonDisassembler::remapInstruction (MCInst &Instr) const {
212273 for (auto I: HexagonMCInstrInfo::bundleInstructions (Instr)) {
213274 auto &MI = const_cast <MCInst &>(*I.getInst ());
@@ -482,7 +543,7 @@ DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
482543 unsigned Offset = 1 ;
483544 bool Vector = HexagonMCInstrInfo::isVector (*MCII, MI);
484545 bool PrevVector = false ;
485- auto Instructions = HexagonMCInstrInfo::bundleInstructions (** CurrentBundle);
546+ auto Instructions = HexagonMCInstrInfo::bundleInstructions (*CurrentBundle);
486547 auto i = Instructions.end () - 1 ;
487548 for (auto n = Instructions.begin () - 1 ;; --i, ++Offset) {
488549 if (i == n)
0 commit comments