@@ -43,12 +43,12 @@ namespace {
43
43
class HexagonDisassembler : public MCDisassembler {
44
44
public:
45
45
std::unique_ptr<MCInstrInfo const > const MCII;
46
- std::unique_ptr<MCInst * > CurrentBundle;
46
+ mutable std::unique_ptr<MCInst> CurrentBundle;
47
47
mutable MCInst const *CurrentExtender;
48
48
49
49
HexagonDisassembler (const MCSubtargetInfo &STI, MCContext &Ctx,
50
50
MCInstrInfo const *MCII)
51
- : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst * ),
51
+ : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(nullptr ),
52
52
CurrentExtender (nullptr ) {}
53
53
54
54
DecodeStatus getSingleInstruction (MCInst &Instr, MCInst &MCB,
@@ -57,7 +57,23 @@ class HexagonDisassembler : public MCDisassembler {
57
57
DecodeStatus getInstruction (MCInst &Instr, uint64_t &Size,
58
58
ArrayRef<uint8_t > Bytes, uint64_t Address,
59
59
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
+
60
65
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 ;
61
77
};
62
78
63
79
static uint64_t fullValue (HexagonDisassembler const &Disassembler, MCInst &MI,
@@ -171,43 +187,88 @@ LLVMInitializeHexagonDisassembler() {
171
187
createHexagonDisassembler);
172
188
}
173
189
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 {
181
193
bool Complete = false ;
182
- Size = 0 ;
194
+ DecodeStatus Result = DecodeStatus::Success ;
183
195
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 ));
187
199
while (Result == Success && !Complete) {
188
200
if (Bytes.size () < HEXAGON_INSTR_SIZE)
189
- return MCDisassembler::Fail ;
201
+ return false ;
190
202
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;
194
207
Bytes = Bytes.slice (HEXAGON_INSTR_SIZE);
195
208
}
196
209
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 ;
200
213
201
214
const auto ArchSTI = Hexagon_MC::getArchSubtarget (&STI);
202
215
const auto STI_ = (ArchSTI != nullptr ) ? *ArchSTI : STI;
203
- HexagonMCChecker Checker (getContext (), *MCII, STI_, MI ,
216
+ HexagonMCChecker Checker (getContext (), *MCII, STI_, *CurrentBundle ,
204
217
*getContext ().getRegisterInfo (), false );
205
218
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 ();
208
246
return MCDisassembler::Success;
209
247
}
210
248
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
+
211
272
void HexagonDisassembler::remapInstruction (MCInst &Instr) const {
212
273
for (auto I: HexagonMCInstrInfo::bundleInstructions (Instr)) {
213
274
auto &MI = const_cast <MCInst &>(*I.getInst ());
@@ -482,7 +543,7 @@ DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
482
543
unsigned Offset = 1 ;
483
544
bool Vector = HexagonMCInstrInfo::isVector (*MCII, MI);
484
545
bool PrevVector = false ;
485
- auto Instructions = HexagonMCInstrInfo::bundleInstructions (** CurrentBundle);
546
+ auto Instructions = HexagonMCInstrInfo::bundleInstructions (*CurrentBundle);
486
547
auto i = Instructions.end () - 1 ;
487
548
for (auto n = Instructions.begin () - 1 ;; --i, ++Offset) {
488
549
if (i == n)
0 commit comments