1 //===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst instructions----===//
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
7 //===----------------------------------------------------------------------===//
9 #define DEBUG_TYPE "mcasmparser"
11 #include "HexagonTargetStreamer.h"
12 #include "MCTargetDesc/HexagonMCChecker.h"
13 #include "MCTargetDesc/HexagonMCELFStreamer.h"
14 #include "MCTargetDesc/HexagonMCExpr.h"
15 #include "MCTargetDesc/HexagonMCInstrInfo.h"
16 #include "MCTargetDesc/HexagonMCTargetDesc.h"
17 #include "MCTargetDesc/HexagonShuffler.h"
18 #include "TargetInfo/HexagonTargetInfo.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/Twine.h"
24 #include "llvm/BinaryFormat/ELF.h"
25 #include "llvm/MC/MCAssembler.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCDirectives.h"
28 #include "llvm/MC/MCELFStreamer.h"
29 #include "llvm/MC/MCExpr.h"
30 #include "llvm/MC/MCInst.h"
31 #include "llvm/MC/MCParser/MCAsmLexer.h"
32 #include "llvm/MC/MCParser/MCAsmParser.h"
33 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
34 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
35 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
36 #include "llvm/MC/MCRegisterInfo.h"
37 #include "llvm/MC/MCSectionELF.h"
38 #include "llvm/MC/MCStreamer.h"
39 #include "llvm/MC/MCSubtargetInfo.h"
40 #include "llvm/MC/MCSymbol.h"
41 #include "llvm/MC/MCValue.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Debug.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/Format.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/SMLoc.h"
49 #include "llvm/Support/SourceMgr.h"
50 #include "llvm/Support/TargetRegistry.h"
51 #include "llvm/Support/raw_ostream.h"
63 static cl::opt
<bool> WarnMissingParenthesis(
64 "mwarn-missing-parenthesis",
65 cl::desc("Warn for missing parenthesis around predicate registers"),
67 static cl::opt
<bool> ErrorMissingParenthesis(
68 "merror-missing-parenthesis",
69 cl::desc("Error for missing parenthesis around predicate registers"),
71 static cl::opt
<bool> WarnSignedMismatch(
72 "mwarn-sign-mismatch",
73 cl::desc("Warn for mismatching a signed and unsigned value"),
75 static cl::opt
<bool> WarnNoncontigiousRegister(
76 "mwarn-noncontigious-register",
77 cl::desc("Warn for register names that arent contigious"), cl::init(true));
78 static cl::opt
<bool> ErrorNoncontigiousRegister(
79 "merror-noncontigious-register",
80 cl::desc("Error for register names that aren't contigious"),
85 struct HexagonOperand
;
87 class HexagonAsmParser
: public MCTargetAsmParser
{
89 HexagonTargetStreamer
&getTargetStreamer() {
90 MCTargetStreamer
&TS
= *Parser
.getStreamer().getTargetStreamer();
91 return static_cast<HexagonTargetStreamer
&>(TS
);
98 MCAsmParser
&getParser() const { return Parser
; }
99 MCAssembler
*getAssembler() const {
100 MCAssembler
*Assembler
= nullptr;
101 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
102 if (!Parser
.getStreamer().hasRawTextSupport()) {
103 MCELFStreamer
*MES
= static_cast<MCELFStreamer
*>(&Parser
.getStreamer());
104 Assembler
= &MES
->getAssembler();
109 MCAsmLexer
&getLexer() const { return Parser
.getLexer(); }
111 bool equalIsAsmAssignment() override
{ return false; }
112 bool isLabel(AsmToken
&Token
) override
;
114 void Warning(SMLoc L
, const Twine
&Msg
) { Parser
.Warning(L
, Msg
); }
115 bool Error(SMLoc L
, const Twine
&Msg
) { return Parser
.Error(L
, Msg
); }
116 bool ParseDirectiveFalign(unsigned Size
, SMLoc L
);
118 bool ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
119 bool ParseDirectiveSubsection(SMLoc L
);
120 bool ParseDirectiveComm(bool IsLocal
, SMLoc L
);
121 bool RegisterMatchesArch(unsigned MatchNum
) const;
123 bool matchBundleOptions();
124 bool handleNoncontigiousRegister(bool Contigious
, SMLoc
&Loc
);
125 bool finishBundle(SMLoc IDLoc
, MCStreamer
&Out
);
126 void canonicalizeImmediates(MCInst
&MCI
);
127 bool matchOneInstruction(MCInst
&MCB
, SMLoc IDLoc
,
128 OperandVector
&InstOperands
, uint64_t &ErrorInfo
,
129 bool MatchingInlineAsm
);
130 void eatToEndOfPacket();
131 bool MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
132 OperandVector
&Operands
, MCStreamer
&Out
,
134 bool MatchingInlineAsm
) override
;
136 unsigned validateTargetOperandClass(MCParsedAsmOperand
&Op
,
137 unsigned Kind
) override
;
138 bool OutOfRange(SMLoc IDLoc
, long long Val
, long long Max
);
139 int processInstruction(MCInst
&Inst
, OperandVector
const &Operands
,
142 // Check if we have an assembler and, if so, set the ELF e_header flags.
143 void chksetELFHeaderEFlags(unsigned flags
) {
145 getAssembler()->setELFHeaderEFlags(flags
);
148 unsigned matchRegister(StringRef Name
);
150 /// @name Auto-generated Match Functions
153 #define GET_ASSEMBLER_HEADER
154 #include "HexagonGenAsmMatcher.inc"
159 HexagonAsmParser(const MCSubtargetInfo
&_STI
, MCAsmParser
&_Parser
,
160 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
161 : MCTargetAsmParser(Options
, _STI
, MII
), Parser(_Parser
),
163 MCB
.setOpcode(Hexagon::BUNDLE
);
164 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
166 Parser
.addAliasForDirective(".half", ".2byte");
167 Parser
.addAliasForDirective(".hword", ".2byte");
168 Parser
.addAliasForDirective(".word", ".4byte");
170 MCAsmParserExtension::Initialize(_Parser
);
173 bool splitIdentifier(OperandVector
&Operands
);
174 bool parseOperand(OperandVector
&Operands
);
175 bool parseInstruction(OperandVector
&Operands
);
176 bool implicitExpressionLocation(OperandVector
&Operands
);
177 bool parseExpressionOrOperand(OperandVector
&Operands
);
178 bool parseExpression(MCExpr
const *&Expr
);
180 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
181 SMLoc NameLoc
, OperandVector
&Operands
) override
{
182 llvm_unreachable("Unimplemented");
185 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
, AsmToken ID
,
186 OperandVector
&Operands
) override
;
188 bool ParseDirective(AsmToken DirectiveID
) override
;
191 /// HexagonOperand - Instances of this class represent a parsed Hexagon machine
193 struct HexagonOperand
: public MCParsedAsmOperand
{
194 enum KindTy
{ Token
, Immediate
, Register
} Kind
;
197 SMLoc StartLoc
, EndLoc
;
213 OperandVector
*SubInsts
;
222 HexagonOperand(KindTy K
, MCContext
&Context
)
223 : MCParsedAsmOperand(), Kind(K
), Context(Context
) {}
226 HexagonOperand(const HexagonOperand
&o
)
227 : MCParsedAsmOperand(), Context(o
.Context
) {
229 StartLoc
= o
.StartLoc
;
244 /// getStartLoc - Get the location of the first token of this operand.
245 SMLoc
getStartLoc() const override
{ return StartLoc
; }
247 /// getEndLoc - Get the location of the last token of this operand.
248 SMLoc
getEndLoc() const override
{ return EndLoc
; }
250 unsigned getReg() const override
{
251 assert(Kind
== Register
&& "Invalid access!");
255 const MCExpr
*getImm() const {
256 assert(Kind
== Immediate
&& "Invalid access!");
260 bool isToken() const override
{ return Kind
== Token
; }
261 bool isImm() const override
{ return Kind
== Immediate
; }
262 bool isMem() const override
{ llvm_unreachable("No isMem"); }
263 bool isReg() const override
{ return Kind
== Register
; }
265 bool CheckImmRange(int immBits
, int zeroBits
, bool isSigned
,
266 bool isRelocatable
, bool Extendable
) const {
267 if (Kind
== Immediate
) {
268 const MCExpr
*myMCExpr
= &HexagonMCInstrInfo::getExpr(*getImm());
269 if (HexagonMCInstrInfo::mustExtend(*Imm
.Val
) && !Extendable
)
272 if (myMCExpr
->evaluateAsAbsolute(Res
)) {
273 int bits
= immBits
+ zeroBits
;
274 // Field bit range is zerobits + bits
275 // zeroBits must be 0
276 if (Res
& ((1 << zeroBits
) - 1))
279 if (Res
< (1LL << (bits
- 1)) && Res
>= -(1LL << (bits
- 1)))
285 return ((uint64_t)Res
< (uint64_t)(1ULL << bits
));
287 const int64_t high_bit_set
= 1ULL << 63;
288 const uint64_t mask
= (high_bit_set
>> (63 - bits
));
289 return (((uint64_t)Res
& mask
) == mask
);
292 } else if (myMCExpr
->getKind() == MCExpr::SymbolRef
&& isRelocatable
)
294 else if (myMCExpr
->getKind() == MCExpr::Binary
||
295 myMCExpr
->getKind() == MCExpr::Unary
)
301 bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
302 bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
303 bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
304 bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }
306 bool ism32_0Imm() const { return true; }
308 bool isf32Imm() const { return false; }
309 bool isf64Imm() const { return false; }
310 bool iss32_0Imm() const { return true; }
311 bool iss31_1Imm() const { return true; }
312 bool iss30_2Imm() const { return true; }
313 bool iss29_3Imm() const { return true; }
314 bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
315 bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }
316 bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
317 bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
318 bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
319 bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
320 bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
321 bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
322 bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
323 bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
324 bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
325 bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
327 bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
328 bool isu32_0Imm() const { return true; }
329 bool isu31_1Imm() const { return true; }
330 bool isu30_2Imm() const { return true; }
331 bool isu29_3Imm() const { return true; }
332 bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
333 bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
334 bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
335 bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
336 bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
337 bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
338 bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
339 bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
340 bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
341 bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
342 bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
343 bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
344 bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
345 bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
346 bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
347 bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
348 bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
349 bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
350 bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
351 bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
352 bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
353 bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
354 bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
356 bool isn1Const() const {
360 if (!getImm()->evaluateAsAbsolute(Value
))
364 bool iss11_0Imm() const {
365 return CheckImmRange(11 + 26, 0, true, true, true);
367 bool iss11_1Imm() const {
368 return CheckImmRange(11 + 26, 1, true, true, true);
370 bool iss11_2Imm() const {
371 return CheckImmRange(11 + 26, 2, true, true, true);
373 bool iss11_3Imm() const {
374 return CheckImmRange(11 + 26, 3, true, true, true);
376 bool isu32_0MustExt() const { return isImm(); }
378 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
379 assert(N
== 1 && "Invalid number of operands!");
380 Inst
.addOperand(MCOperand::createReg(getReg()));
383 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
384 assert(N
== 1 && "Invalid number of operands!");
385 Inst
.addOperand(MCOperand::createExpr(getImm()));
388 void addSignedImmOperands(MCInst
&Inst
, unsigned N
) const {
389 assert(N
== 1 && "Invalid number of operands!");
390 HexagonMCExpr
*Expr
=
391 const_cast<HexagonMCExpr
*>(cast
<HexagonMCExpr
>(getImm()));
393 if (!Expr
->evaluateAsAbsolute(Value
)) {
394 Inst
.addOperand(MCOperand::createExpr(Expr
));
397 int64_t Extended
= SignExtend64(Value
, 32);
398 HexagonMCExpr
*NewExpr
= HexagonMCExpr::create(
399 MCConstantExpr::create(Extended
, Context
), Context
);
400 if ((Extended
< 0) != (Value
< 0))
401 NewExpr
->setSignMismatch();
402 NewExpr
->setMustExtend(Expr
->mustExtend());
403 NewExpr
->setMustNotExtend(Expr
->mustNotExtend());
404 Inst
.addOperand(MCOperand::createExpr(NewExpr
));
407 void addn1ConstOperands(MCInst
&Inst
, unsigned N
) const {
408 addImmOperands(Inst
, N
);
411 StringRef
getToken() const {
412 assert(Kind
== Token
&& "Invalid access!");
413 return StringRef(Tok
.Data
, Tok
.Length
);
416 void print(raw_ostream
&OS
) const override
;
418 static std::unique_ptr
<HexagonOperand
> CreateToken(MCContext
&Context
,
419 StringRef Str
, SMLoc S
) {
420 HexagonOperand
*Op
= new HexagonOperand(Token
, Context
);
421 Op
->Tok
.Data
= Str
.data();
422 Op
->Tok
.Length
= Str
.size();
425 return std::unique_ptr
<HexagonOperand
>(Op
);
428 static std::unique_ptr
<HexagonOperand
>
429 CreateReg(MCContext
&Context
, unsigned RegNum
, SMLoc S
, SMLoc E
) {
430 HexagonOperand
*Op
= new HexagonOperand(Register
, Context
);
431 Op
->Reg
.RegNum
= RegNum
;
434 return std::unique_ptr
<HexagonOperand
>(Op
);
437 static std::unique_ptr
<HexagonOperand
>
438 CreateImm(MCContext
&Context
, const MCExpr
*Val
, SMLoc S
, SMLoc E
) {
439 HexagonOperand
*Op
= new HexagonOperand(Immediate
, Context
);
443 return std::unique_ptr
<HexagonOperand
>(Op
);
447 } // end anonymous namespace
449 void HexagonOperand::print(raw_ostream
&OS
) const {
452 getImm()->print(OS
, nullptr);
456 OS
<< getReg() << ">";
459 OS
<< "'" << getToken() << "'";
464 bool HexagonAsmParser::finishBundle(SMLoc IDLoc
, MCStreamer
&Out
) {
465 LLVM_DEBUG(dbgs() << "Bundle:");
466 LLVM_DEBUG(MCB
.dump_pretty(dbgs()));
467 LLVM_DEBUG(dbgs() << "--\n");
470 // Check the bundle for errors.
471 const MCRegisterInfo
*RI
= getContext().getRegisterInfo();
472 HexagonMCChecker
Check(getContext(), MII
, getSTI(), MCB
, *RI
);
474 bool CheckOk
= HexagonMCInstrInfo::canonicalizePacket(MII
, getSTI(),
479 if (HexagonMCInstrInfo::bundleSize(MCB
) == 0) {
480 assert(!HexagonMCInstrInfo::isInnerLoop(MCB
));
481 assert(!HexagonMCInstrInfo::isOuterLoop(MCB
));
482 // Empty packets are valid yet aren't emitted
485 Out
.EmitInstruction(MCB
, getSTI());
487 // If compounding and duplexing didn't reduce the size below
488 // 4 or less we have a packet that is too big.
489 if (HexagonMCInstrInfo::bundleSize(MCB
) > HEXAGON_PACKET_SIZE
) {
490 Error(IDLoc
, "invalid instruction packet: out of slots");
492 return true; // Error
495 return false; // No error
498 bool HexagonAsmParser::matchBundleOptions() {
499 MCAsmParser
&Parser
= getParser();
501 if (!Parser
.getTok().is(AsmToken::Colon
))
504 char const *MemNoShuffMsg
=
505 "invalid instruction packet: mem_noshuf specifier not "
506 "supported with this architecture";
507 StringRef Option
= Parser
.getTok().getString();
508 auto IDLoc
= Parser
.getTok().getLoc();
509 if (Option
.compare_lower("endloop01") == 0) {
510 HexagonMCInstrInfo::setInnerLoop(MCB
);
511 HexagonMCInstrInfo::setOuterLoop(MCB
);
512 } else if (Option
.compare_lower("endloop0") == 0) {
513 HexagonMCInstrInfo::setInnerLoop(MCB
);
514 } else if (Option
.compare_lower("endloop1") == 0) {
515 HexagonMCInstrInfo::setOuterLoop(MCB
);
516 } else if (Option
.compare_lower("mem_noshuf") == 0) {
517 if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf
])
518 HexagonMCInstrInfo::setMemReorderDisabled(MCB
);
520 return getParser().Error(IDLoc
, MemNoShuffMsg
);
522 return getParser().Error(IDLoc
, llvm::Twine("'") + Option
+
523 "' is not a valid bundle option");
528 // For instruction aliases, immediates are generated rather than
529 // MCConstantExpr. Convert them for uniform MCExpr.
530 // Also check for signed/unsigned mismatches and warn
531 void HexagonAsmParser::canonicalizeImmediates(MCInst
&MCI
) {
533 NewInst
.setOpcode(MCI
.getOpcode());
534 for (MCOperand
&I
: MCI
)
536 int64_t Value(I
.getImm());
537 NewInst
.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
538 MCConstantExpr::create(Value
, getContext()), getContext())));
540 if (I
.isExpr() && cast
<HexagonMCExpr
>(I
.getExpr())->signMismatch() &&
542 Warning(MCI
.getLoc(), "Signed/Unsigned mismatch");
543 NewInst
.addOperand(I
);
548 bool HexagonAsmParser::matchOneInstruction(MCInst
&MCI
, SMLoc IDLoc
,
549 OperandVector
&InstOperands
,
551 bool MatchingInlineAsm
) {
552 // Perform matching with tablegen asmmatcher generated function
554 MatchInstructionImpl(InstOperands
, MCI
, ErrorInfo
, MatchingInlineAsm
);
555 if (result
== Match_Success
) {
557 canonicalizeImmediates(MCI
);
558 result
= processInstruction(MCI
, InstOperands
, IDLoc
);
560 LLVM_DEBUG(dbgs() << "Insn:");
561 LLVM_DEBUG(MCI
.dump_pretty(dbgs()));
562 LLVM_DEBUG(dbgs() << "\n\n");
567 // Create instruction operand for bundle instruction
568 // Break this into a separate function Code here is less readable
569 // Think about how to get an instruction error to report correctly.
570 // SMLoc will return the "{"
576 case Match_MissingFeature
:
577 return Error(IDLoc
, "invalid instruction");
578 case Match_MnemonicFail
:
579 return Error(IDLoc
, "unrecognized instruction");
580 case Match_InvalidOperand
:
581 case Match_InvalidTiedOperand
:
582 SMLoc ErrorLoc
= IDLoc
;
583 if (ErrorInfo
!= ~0U) {
584 if (ErrorInfo
>= InstOperands
.size())
585 return Error(IDLoc
, "too few operands for instruction");
587 ErrorLoc
= (static_cast<HexagonOperand
*>(InstOperands
[ErrorInfo
].get()))
589 if (ErrorLoc
== SMLoc())
592 return Error(ErrorLoc
, "invalid operand for instruction");
594 llvm_unreachable("Implement any new match types added!");
597 void HexagonAsmParser::eatToEndOfPacket() {
599 MCAsmLexer
&Lexer
= getLexer();
600 while (!Lexer
.is(AsmToken::RCurly
))
606 bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
607 OperandVector
&Operands
,
610 bool MatchingInlineAsm
) {
613 MCB
.addOperand(MCOperand::createImm(0));
615 HexagonOperand
&FirstOperand
= static_cast<HexagonOperand
&>(*Operands
[0]);
616 if (FirstOperand
.isToken() && FirstOperand
.getToken() == "{") {
617 assert(Operands
.size() == 1 && "Brackets should be by themselves");
619 getParser().Error(IDLoc
, "Already in a packet");
626 if (FirstOperand
.isToken() && FirstOperand
.getToken() == "}") {
627 assert(Operands
.size() == 1 && "Brackets should be by themselves");
629 getParser().Error(IDLoc
, "Not in a packet");
633 if (matchBundleOptions())
635 return finishBundle(IDLoc
, Out
);
637 MCInst
*SubInst
= new (getParser().getContext()) MCInst
;
638 if (matchOneInstruction(*SubInst
, IDLoc
, Operands
, ErrorInfo
,
639 MatchingInlineAsm
)) {
644 HexagonMCInstrInfo::extendIfNeeded(
645 getParser().getContext(), MII
, MCB
, *SubInst
);
646 MCB
.addOperand(MCOperand::createInst(SubInst
));
648 return finishBundle(IDLoc
, Out
);
652 /// ParseDirective parses the Hexagon specific directives
653 bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID
) {
654 StringRef IDVal
= DirectiveID
.getIdentifier();
655 if (IDVal
.lower() == ".falign")
656 return ParseDirectiveFalign(256, DirectiveID
.getLoc());
657 if ((IDVal
.lower() == ".lcomm") || (IDVal
.lower() == ".lcommon"))
658 return ParseDirectiveComm(true, DirectiveID
.getLoc());
659 if ((IDVal
.lower() == ".comm") || (IDVal
.lower() == ".common"))
660 return ParseDirectiveComm(false, DirectiveID
.getLoc());
661 if (IDVal
.lower() == ".subsection")
662 return ParseDirectiveSubsection(DirectiveID
.getLoc());
666 bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L
) {
667 const MCExpr
*Subsection
= nullptr;
670 assert((getLexer().isNot(AsmToken::EndOfStatement
)) &&
671 "Invalid subsection directive");
672 getParser().parseExpression(Subsection
);
674 if (!Subsection
->evaluateAsAbsolute(Res
))
675 return Error(L
, "Cannot evaluate subsection number");
677 if (getLexer().isNot(AsmToken::EndOfStatement
))
678 return TokError("unexpected token in directive");
680 // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
681 // negative subsections together and in the same order but at the opposite
682 // end of the section. Only legacy hexagon-gcc created assembly code
683 // used negative subsections.
684 if ((Res
< 0) && (Res
> -8193))
685 Subsection
= HexagonMCExpr::create(
686 MCConstantExpr::create(8192 + Res
, getContext()), getContext());
688 getStreamer().SubSection(Subsection
);
692 /// ::= .falign [expression]
693 bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size
, SMLoc L
) {
695 int64_t MaxBytesToFill
= 15;
697 // if there is an argument
698 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
702 // Make sure we have a number (false is returned if expression is a number)
703 if (!getParser().parseExpression(Value
)) {
704 // Make sure this is a number that is in range
705 auto *MCE
= cast
<MCConstantExpr
>(Value
);
706 uint64_t IntValue
= MCE
->getValue();
707 if (!isUIntN(Size
, IntValue
) && !isIntN(Size
, IntValue
))
708 return Error(ExprLoc
, "literal value out of range (256) for falign");
709 MaxBytesToFill
= IntValue
;
712 return Error(ExprLoc
, "not a valid expression for falign directive");
716 getTargetStreamer().emitFAlign(16, MaxBytesToFill
);
722 // This is largely a copy of AsmParser's ParseDirectiveComm extended to
723 // accept a 3rd argument, AccessAlignment which indicates the smallest
724 // memory access made to the symbol, expressed in bytes. If no
725 // AccessAlignment is specified it defaults to the Alignment Value.
727 // .lcomm Symbol, Length, Alignment, AccessAlignment
728 bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal
, SMLoc Loc
) {
729 // FIXME: need better way to detect if AsmStreamer (upstream removed
731 if (getStreamer().hasRawTextSupport())
732 return true; // Only object file output requires special treatment.
735 if (getParser().parseIdentifier(Name
))
736 return TokError("expected identifier in directive");
737 // Handle the identifier as the key symbol.
738 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
740 if (getLexer().isNot(AsmToken::Comma
))
741 return TokError("unexpected token in directive");
745 SMLoc SizeLoc
= getLexer().getLoc();
746 if (getParser().parseAbsoluteExpression(Size
))
749 int64_t ByteAlignment
= 1;
750 SMLoc ByteAlignmentLoc
;
751 if (getLexer().is(AsmToken::Comma
)) {
753 ByteAlignmentLoc
= getLexer().getLoc();
754 if (getParser().parseAbsoluteExpression(ByteAlignment
))
756 if (!isPowerOf2_64(ByteAlignment
))
757 return Error(ByteAlignmentLoc
, "alignment must be a power of 2");
760 int64_t AccessAlignment
= 0;
761 if (getLexer().is(AsmToken::Comma
)) {
762 // The optional access argument specifies the size of the smallest memory
763 // access to be made to the symbol, expressed in bytes.
764 SMLoc AccessAlignmentLoc
;
766 AccessAlignmentLoc
= getLexer().getLoc();
767 if (getParser().parseAbsoluteExpression(AccessAlignment
))
770 if (!isPowerOf2_64(AccessAlignment
))
771 return Error(AccessAlignmentLoc
, "access alignment must be a power of 2");
774 if (getLexer().isNot(AsmToken::EndOfStatement
))
775 return TokError("unexpected token in '.comm' or '.lcomm' directive");
779 // NOTE: a size of zero for a .comm should create a undefined symbol
780 // but a size of .lcomm creates a bss symbol of size zero.
782 return Error(SizeLoc
, "invalid '.comm' or '.lcomm' directive size, can't "
783 "be less than zero");
785 // NOTE: The alignment in the directive is a power of 2 value, the assembler
786 // may internally end up wanting an alignment in bytes.
787 // FIXME: Diagnose overflow.
788 if (ByteAlignment
< 0)
789 return Error(ByteAlignmentLoc
, "invalid '.comm' or '.lcomm' directive "
790 "alignment, can't be less than zero");
792 if (!Sym
->isUndefined())
793 return Error(Loc
, "invalid symbol redefinition");
795 HexagonMCELFStreamer
&HexagonELFStreamer
=
796 static_cast<HexagonMCELFStreamer
&>(getStreamer());
798 HexagonELFStreamer
.HexagonMCEmitLocalCommonSymbol(Sym
, Size
, ByteAlignment
,
803 HexagonELFStreamer
.HexagonMCEmitCommonSymbol(Sym
, Size
, ByteAlignment
,
808 // validate register against architecture
809 bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum
) const {
810 if (HexagonMCRegisterClasses
[Hexagon::V62RegsRegClassID
].contains(MatchNum
))
811 if (!getSTI().getFeatureBits()[Hexagon::ArchV62
])
816 // extern "C" void LLVMInitializeHexagonAsmLexer();
818 /// Force static initialization.
819 extern "C" void LLVMInitializeHexagonAsmParser() {
820 RegisterMCAsmParser
<HexagonAsmParser
> X(getTheHexagonTarget());
823 #define GET_MATCHER_IMPLEMENTATION
824 #define GET_REGISTER_MATCHER
825 #include "HexagonGenAsmMatcher.inc"
827 static bool previousEqual(OperandVector
&Operands
, size_t Index
,
829 if (Index
>= Operands
.size())
831 MCParsedAsmOperand
&Operand
= *Operands
[Operands
.size() - Index
- 1];
832 if (!Operand
.isToken())
834 return static_cast<HexagonOperand
&>(Operand
).getToken().equals_lower(String
);
837 static bool previousIsLoop(OperandVector
&Operands
, size_t Index
) {
838 return previousEqual(Operands
, Index
, "loop0") ||
839 previousEqual(Operands
, Index
, "loop1") ||
840 previousEqual(Operands
, Index
, "sp1loop0") ||
841 previousEqual(Operands
, Index
, "sp2loop0") ||
842 previousEqual(Operands
, Index
, "sp3loop0");
845 bool HexagonAsmParser::splitIdentifier(OperandVector
&Operands
) {
846 AsmToken
const &Token
= getParser().getTok();
847 StringRef String
= Token
.getString();
848 SMLoc Loc
= Token
.getLoc();
851 std::pair
<StringRef
, StringRef
> HeadTail
= String
.split('.');
852 if (!HeadTail
.first
.empty())
854 HexagonOperand::CreateToken(getContext(), HeadTail
.first
, Loc
));
855 if (!HeadTail
.second
.empty())
856 Operands
.push_back(HexagonOperand::CreateToken(
857 getContext(), String
.substr(HeadTail
.first
.size(), 1), Loc
));
858 String
= HeadTail
.second
;
859 } while (!String
.empty());
863 bool HexagonAsmParser::parseOperand(OperandVector
&Operands
) {
867 MCAsmLexer
&Lexer
= getLexer();
868 if (!ParseRegister(Register
, Begin
, End
)) {
869 if (!ErrorMissingParenthesis
)
877 if (previousEqual(Operands
, 0, "if")) {
878 if (WarnMissingParenthesis
)
879 Warning(Begin
, "Missing parenthesis around predicate register");
880 static char const *LParen
= "(";
881 static char const *RParen
= ")";
883 HexagonOperand::CreateToken(getContext(), LParen
, Begin
));
885 HexagonOperand::CreateReg(getContext(), Register
, Begin
, End
));
886 const AsmToken
&MaybeDotNew
= Lexer
.getTok();
887 if (MaybeDotNew
.is(AsmToken::TokenKind::Identifier
) &&
888 MaybeDotNew
.getString().equals_lower(".new"))
889 splitIdentifier(Operands
);
891 HexagonOperand::CreateToken(getContext(), RParen
, Begin
));
894 if (previousEqual(Operands
, 0, "!") &&
895 previousEqual(Operands
, 1, "if")) {
896 if (WarnMissingParenthesis
)
897 Warning(Begin
, "Missing parenthesis around predicate register");
898 static char const *LParen
= "(";
899 static char const *RParen
= ")";
900 Operands
.insert(Operands
.end() - 1, HexagonOperand::CreateToken(
901 getContext(), LParen
, Begin
));
903 HexagonOperand::CreateReg(getContext(), Register
, Begin
, End
));
904 const AsmToken
&MaybeDotNew
= Lexer
.getTok();
905 if (MaybeDotNew
.is(AsmToken::TokenKind::Identifier
) &&
906 MaybeDotNew
.getString().equals_lower(".new"))
907 splitIdentifier(Operands
);
909 HexagonOperand::CreateToken(getContext(), RParen
, Begin
));
915 HexagonOperand::CreateReg(getContext(), Register
, Begin
, End
));
918 return splitIdentifier(Operands
);
921 bool HexagonAsmParser::isLabel(AsmToken
&Token
) {
922 MCAsmLexer
&Lexer
= getLexer();
923 AsmToken
const &Second
= Lexer
.getTok();
924 AsmToken Third
= Lexer
.peekTok();
925 StringRef String
= Token
.getString();
926 if (Token
.is(AsmToken::TokenKind::LCurly
) ||
927 Token
.is(AsmToken::TokenKind::RCurly
))
929 // special case for parsing vwhist256:sat
930 if (String
.lower() == "vwhist256" && Second
.is(AsmToken::Colon
) &&
931 Third
.getString().lower() == "sat")
933 if (!Token
.is(AsmToken::TokenKind::Identifier
))
935 if (!matchRegister(String
.lower()))
937 assert(Second
.is(AsmToken::Colon
));
938 StringRef
Raw(String
.data(), Third
.getString().data() - String
.data() +
939 Third
.getString().size());
940 std::string Collapsed
= Raw
;
941 Collapsed
.erase(llvm::remove_if(Collapsed
, isspace
), Collapsed
.end());
942 StringRef Whole
= Collapsed
;
943 std::pair
<StringRef
, StringRef
> DotSplit
= Whole
.split('.');
944 if (!matchRegister(DotSplit
.first
.lower()))
949 bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious
,
951 if (!Contigious
&& ErrorNoncontigiousRegister
) {
952 Error(Loc
, "Register name is not contigious");
955 if (!Contigious
&& WarnNoncontigiousRegister
)
956 Warning(Loc
, "Register name is not contigious");
960 bool HexagonAsmParser::ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
,
962 MCAsmLexer
&Lexer
= getLexer();
963 StartLoc
= getLexer().getLoc();
964 SmallVector
<AsmToken
, 5> Lookahead
;
965 StringRef
RawString(Lexer
.getTok().getString().data(), 0);
966 bool Again
= Lexer
.is(AsmToken::Identifier
);
967 bool NeededWorkaround
= false;
969 AsmToken
const &Token
= Lexer
.getTok();
970 RawString
= StringRef(RawString
.data(), Token
.getString().data() -
972 Token
.getString().size());
973 Lookahead
.push_back(Token
);
975 bool Contigious
= Lexer
.getTok().getString().data() ==
976 Lookahead
.back().getString().data() +
977 Lookahead
.back().getString().size();
978 bool Type
= Lexer
.is(AsmToken::Identifier
) || Lexer
.is(AsmToken::Dot
) ||
979 Lexer
.is(AsmToken::Integer
) || Lexer
.is(AsmToken::Real
) ||
980 Lexer
.is(AsmToken::Colon
);
982 Lexer
.is(AsmToken::Colon
) || Lookahead
.back().is(AsmToken::Colon
);
983 Again
= (Contigious
&& Type
) || (Workaround
&& Type
);
984 NeededWorkaround
= NeededWorkaround
|| (Again
&& !(Contigious
&& Type
));
986 std::string Collapsed
= RawString
;
987 Collapsed
.erase(llvm::remove_if(Collapsed
, isspace
), Collapsed
.end());
988 StringRef FullString
= Collapsed
;
989 std::pair
<StringRef
, StringRef
> DotSplit
= FullString
.split('.');
990 unsigned DotReg
= matchRegister(DotSplit
.first
.lower());
991 if (DotReg
!= Hexagon::NoRegister
&& RegisterMatchesArch(DotReg
)) {
992 if (DotSplit
.second
.empty()) {
994 EndLoc
= Lexer
.getLoc();
995 if (handleNoncontigiousRegister(!NeededWorkaround
, StartLoc
))
1000 size_t First
= RawString
.find('.');
1001 StringRef
DotString (RawString
.data() + First
, RawString
.size() - First
);
1002 Lexer
.UnLex(AsmToken(AsmToken::Identifier
, DotString
));
1003 EndLoc
= Lexer
.getLoc();
1004 if (handleNoncontigiousRegister(!NeededWorkaround
, StartLoc
))
1009 std::pair
<StringRef
, StringRef
> ColonSplit
= StringRef(FullString
).split(':');
1010 unsigned ColonReg
= matchRegister(ColonSplit
.first
.lower());
1011 if (ColonReg
!= Hexagon::NoRegister
&& RegisterMatchesArch(DotReg
)) {
1013 Lexer
.UnLex(Lookahead
.back());
1014 Lookahead
.pop_back();
1015 } while (!Lookahead
.empty () && !Lexer
.is(AsmToken::Colon
));
1017 EndLoc
= Lexer
.getLoc();
1018 if (handleNoncontigiousRegister(!NeededWorkaround
, StartLoc
))
1022 while (!Lookahead
.empty()) {
1023 Lexer
.UnLex(Lookahead
.back());
1024 Lookahead
.pop_back();
1029 bool HexagonAsmParser::implicitExpressionLocation(OperandVector
&Operands
) {
1030 if (previousEqual(Operands
, 0, "call"))
1032 if (previousEqual(Operands
, 0, "jump"))
1033 if (!getLexer().getTok().is(AsmToken::Colon
))
1035 if (previousEqual(Operands
, 0, "(") && previousIsLoop(Operands
, 1))
1037 if (previousEqual(Operands
, 1, ":") && previousEqual(Operands
, 2, "jump") &&
1038 (previousEqual(Operands
, 0, "nt") || previousEqual(Operands
, 0, "t")))
1043 bool HexagonAsmParser::parseExpression(MCExpr
const *&Expr
) {
1044 SmallVector
<AsmToken
, 4> Tokens
;
1045 MCAsmLexer
&Lexer
= getLexer();
1047 static char const *Comma
= ",";
1049 Tokens
.emplace_back(Lexer
.getTok());
1051 switch (Tokens
.back().getKind()) {
1052 case AsmToken::TokenKind::Hash
:
1053 if (Tokens
.size() > 1)
1054 if ((Tokens
.end() - 2)->getKind() == AsmToken::TokenKind::Plus
) {
1055 Tokens
.insert(Tokens
.end() - 2,
1056 AsmToken(AsmToken::TokenKind::Comma
, Comma
));
1060 case AsmToken::TokenKind::RCurly
:
1061 case AsmToken::TokenKind::EndOfStatement
:
1062 case AsmToken::TokenKind::Eof
:
1069 while (!Tokens
.empty()) {
1070 Lexer
.UnLex(Tokens
.back());
1073 SMLoc Loc
= Lexer
.getLoc();
1074 return getParser().parseExpression(Expr
, Loc
);
1077 bool HexagonAsmParser::parseExpressionOrOperand(OperandVector
&Operands
) {
1078 if (implicitExpressionLocation(Operands
)) {
1079 MCAsmParser
&Parser
= getParser();
1080 SMLoc Loc
= Parser
.getLexer().getLoc();
1081 MCExpr
const *Expr
= nullptr;
1082 bool Error
= parseExpression(Expr
);
1083 Expr
= HexagonMCExpr::create(Expr
, getContext());
1086 HexagonOperand::CreateImm(getContext(), Expr
, Loc
, Loc
));
1089 return parseOperand(Operands
);
1092 /// Parse an instruction.
1093 bool HexagonAsmParser::parseInstruction(OperandVector
&Operands
) {
1094 MCAsmParser
&Parser
= getParser();
1095 MCAsmLexer
&Lexer
= getLexer();
1097 AsmToken
const &Token
= Parser
.getTok();
1098 switch (Token
.getKind()) {
1100 case AsmToken::EndOfStatement
: {
1104 case AsmToken::LCurly
: {
1105 if (!Operands
.empty())
1107 Operands
.push_back(HexagonOperand::CreateToken(
1108 getContext(), Token
.getString(), Token
.getLoc()));
1112 case AsmToken::RCurly
: {
1113 if (Operands
.empty()) {
1114 Operands
.push_back(HexagonOperand::CreateToken(
1115 getContext(), Token
.getString(), Token
.getLoc()));
1120 case AsmToken::Comma
: {
1124 case AsmToken::EqualEqual
:
1125 case AsmToken::ExclaimEqual
:
1126 case AsmToken::GreaterEqual
:
1127 case AsmToken::GreaterGreater
:
1128 case AsmToken::LessEqual
:
1129 case AsmToken::LessLess
: {
1130 Operands
.push_back(HexagonOperand::CreateToken(
1131 getContext(), Token
.getString().substr(0, 1), Token
.getLoc()));
1132 Operands
.push_back(HexagonOperand::CreateToken(
1133 getContext(), Token
.getString().substr(1, 1), Token
.getLoc()));
1137 case AsmToken::Hash
: {
1138 bool MustNotExtend
= false;
1139 bool ImplicitExpression
= implicitExpressionLocation(Operands
);
1140 SMLoc ExprLoc
= Lexer
.getLoc();
1141 if (!ImplicitExpression
)
1142 Operands
.push_back(HexagonOperand::CreateToken(
1143 getContext(), Token
.getString(), Token
.getLoc()));
1145 bool MustExtend
= false;
1146 bool HiOnly
= false;
1147 bool LoOnly
= false;
1148 if (Lexer
.is(AsmToken::Hash
)) {
1151 } else if (ImplicitExpression
)
1152 MustNotExtend
= true;
1153 AsmToken
const &Token
= Parser
.getTok();
1154 if (Token
.is(AsmToken::Identifier
)) {
1155 StringRef String
= Token
.getString();
1156 if (String
.lower() == "hi") {
1158 } else if (String
.lower() == "lo") {
1161 if (HiOnly
|| LoOnly
) {
1162 AsmToken LParen
= Lexer
.peekTok();
1163 if (!LParen
.is(AsmToken::LParen
)) {
1171 MCExpr
const *Expr
= nullptr;
1172 if (parseExpression(Expr
))
1175 MCContext
&Context
= Parser
.getContext();
1176 assert(Expr
!= nullptr);
1177 if (Expr
->evaluateAsAbsolute(Value
)) {
1179 Expr
= MCBinaryExpr::createLShr(
1180 Expr
, MCConstantExpr::create(16, Context
), Context
);
1181 if (HiOnly
|| LoOnly
)
1182 Expr
= MCBinaryExpr::createAnd(
1183 Expr
, MCConstantExpr::create(0xffff, Context
), Context
);
1186 if (Expr
->evaluateAsRelocatable(Value
, nullptr, nullptr)) {
1187 if (!Value
.isAbsolute()) {
1188 switch (Value
.getAccessVariant()) {
1189 case MCSymbolRefExpr::VariantKind::VK_TPREL
:
1190 case MCSymbolRefExpr::VariantKind::VK_DTPREL
:
1191 // Don't lazy extend these expression variants
1192 MustNotExtend
= !MustExtend
;
1200 Expr
= HexagonMCExpr::create(Expr
, Context
);
1201 HexagonMCInstrInfo::setMustNotExtend(*Expr
, MustNotExtend
);
1202 HexagonMCInstrInfo::setMustExtend(*Expr
, MustExtend
);
1203 std::unique_ptr
<HexagonOperand
> Operand
=
1204 HexagonOperand::CreateImm(getContext(), Expr
, ExprLoc
, ExprLoc
);
1205 Operands
.push_back(std::move(Operand
));
1211 if (parseExpressionOrOperand(Operands
))
1216 bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo
&Info
,
1217 StringRef Name
, AsmToken ID
,
1218 OperandVector
&Operands
) {
1219 getLexer().UnLex(ID
);
1220 return parseInstruction(Operands
);
1223 static MCInst
makeCombineInst(int opCode
, MCOperand
&Rdd
, MCOperand
&MO1
,
1226 TmpInst
.setOpcode(opCode
);
1227 TmpInst
.addOperand(Rdd
);
1228 TmpInst
.addOperand(MO1
);
1229 TmpInst
.addOperand(MO2
);
1234 // Define this matcher function after the auto-generated include so we
1235 // have the match class enum definitions.
1236 unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand
&AsmOp
,
1238 HexagonOperand
*Op
= static_cast<HexagonOperand
*>(&AsmOp
);
1243 return Op
->isImm() && Op
->Imm
.Val
->evaluateAsAbsolute(Value
) && Value
== 0
1245 : Match_InvalidOperand
;
1249 return Op
->isImm() && Op
->Imm
.Val
->evaluateAsAbsolute(Value
) && Value
== 1
1251 : Match_InvalidOperand
;
1254 if (Op
->Kind
== HexagonOperand::Token
&& Kind
!= InvalidMatchClass
) {
1255 StringRef myStringRef
= StringRef(Op
->Tok
.Data
, Op
->Tok
.Length
);
1256 if (matchTokenString(myStringRef
.lower()) == (MatchClassKind
)Kind
)
1257 return Match_Success
;
1258 if (matchTokenString(myStringRef
.upper()) == (MatchClassKind
)Kind
)
1259 return Match_Success
;
1262 LLVM_DEBUG(dbgs() << "Unmatched Operand:");
1263 LLVM_DEBUG(Op
->dump());
1264 LLVM_DEBUG(dbgs() << "\n");
1266 return Match_InvalidOperand
;
1269 // FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1270 bool HexagonAsmParser::OutOfRange(SMLoc IDLoc
, long long Val
, long long Max
) {
1272 raw_string_ostream
ES(errStr
);
1273 ES
<< "value " << Val
<< "(" << format_hex(Val
, 0) << ") out of range: ";
1277 ES
<< Max
<< "-" << (-Max
- 1);
1278 return Parser
.printError(IDLoc
, ES
.str());
1281 int HexagonAsmParser::processInstruction(MCInst
&Inst
,
1282 OperandVector
const &Operands
,
1284 MCContext
&Context
= getParser().getContext();
1285 const MCRegisterInfo
*RI
= getContext().getRegisterInfo();
1286 std::string r
= "r";
1287 std::string v
= "v";
1288 std::string Colon
= ":";
1290 bool is32bit
= false; // used to distinguish between CONST32 and CONST64
1291 switch (Inst
.getOpcode()) {
1293 if (HexagonMCInstrInfo::getDesc(MII
, Inst
).isPseudo()) {
1294 SMDiagnostic Diag
= getSourceManager().GetMessage(
1295 IDLoc
, SourceMgr::DK_Error
,
1296 "Found pseudo instruction with no expansion");
1297 Diag
.print("", errs());
1298 report_fatal_error("Invalid pseudo instruction");
1302 case Hexagon::J2_trap1
:
1303 if (!getSTI().getFeatureBits()[Hexagon::ArchV65
]) {
1304 MCOperand
&Rx
= Inst
.getOperand(0);
1305 MCOperand
&Ry
= Inst
.getOperand(1);
1306 if (Rx
.getReg() != Hexagon::R0
|| Ry
.getReg() != Hexagon::R0
) {
1307 Error(IDLoc
, "trap1 can only have register r0 as operand");
1308 return Match_InvalidOperand
;
1313 case Hexagon::A2_iconst
: {
1314 Inst
.setOpcode(Hexagon::A2_addi
);
1315 MCOperand Reg
= Inst
.getOperand(0);
1316 MCOperand S27
= Inst
.getOperand(1);
1317 HexagonMCInstrInfo::setMustNotExtend(*S27
.getExpr());
1318 HexagonMCInstrInfo::setS27_2_reloc(*S27
.getExpr());
1320 Inst
.addOperand(Reg
);
1321 Inst
.addOperand(MCOperand::createReg(Hexagon::R0
));
1322 Inst
.addOperand(S27
);
1325 case Hexagon::M4_mpyrr_addr
:
1326 case Hexagon::S4_addi_asl_ri
:
1327 case Hexagon::S4_addi_lsr_ri
:
1328 case Hexagon::S4_andi_asl_ri
:
1329 case Hexagon::S4_andi_lsr_ri
:
1330 case Hexagon::S4_ori_asl_ri
:
1331 case Hexagon::S4_ori_lsr_ri
:
1332 case Hexagon::S4_or_andix
:
1333 case Hexagon::S4_subi_asl_ri
:
1334 case Hexagon::S4_subi_lsr_ri
: {
1335 MCOperand
&Ry
= Inst
.getOperand(0);
1336 MCOperand
&src
= Inst
.getOperand(2);
1337 if (RI
->getEncodingValue(Ry
.getReg()) != RI
->getEncodingValue(src
.getReg()))
1338 return Match_InvalidOperand
;
1342 case Hexagon::C2_cmpgei
: {
1343 MCOperand
&MO
= Inst
.getOperand(2);
1344 MO
.setExpr(HexagonMCExpr::create(
1345 MCBinaryExpr::createSub(MO
.getExpr(),
1346 MCConstantExpr::create(1, Context
), Context
),
1348 Inst
.setOpcode(Hexagon::C2_cmpgti
);
1352 case Hexagon::C2_cmpgeui
: {
1353 MCOperand
&MO
= Inst
.getOperand(2);
1355 bool Success
= MO
.getExpr()->evaluateAsAbsolute(Value
);
1357 assert(Success
&& "Assured by matcher");
1360 MCOperand
&Pd
= Inst
.getOperand(0);
1361 MCOperand
&Rt
= Inst
.getOperand(1);
1362 TmpInst
.setOpcode(Hexagon::C2_cmpeq
);
1363 TmpInst
.addOperand(Pd
);
1364 TmpInst
.addOperand(Rt
);
1365 TmpInst
.addOperand(Rt
);
1368 MO
.setExpr(HexagonMCExpr::create(
1369 MCBinaryExpr::createSub(MO
.getExpr(),
1370 MCConstantExpr::create(1, Context
), Context
),
1372 Inst
.setOpcode(Hexagon::C2_cmpgtui
);
1377 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1378 case Hexagon::A2_tfrp
: {
1379 MCOperand
&MO
= Inst
.getOperand(1);
1380 unsigned int RegPairNum
= RI
->getEncodingValue(MO
.getReg());
1381 std::string R1
= r
+ utostr(RegPairNum
+ 1);
1383 MO
.setReg(matchRegister(Reg1
));
1384 // Add a new operand for the second register in the pair.
1385 std::string R2
= r
+ utostr(RegPairNum
);
1387 Inst
.addOperand(MCOperand::createReg(matchRegister(Reg2
)));
1388 Inst
.setOpcode(Hexagon::A2_combinew
);
1392 case Hexagon::A2_tfrpt
:
1393 case Hexagon::A2_tfrpf
: {
1394 MCOperand
&MO
= Inst
.getOperand(2);
1395 unsigned int RegPairNum
= RI
->getEncodingValue(MO
.getReg());
1396 std::string R1
= r
+ utostr(RegPairNum
+ 1);
1398 MO
.setReg(matchRegister(Reg1
));
1399 // Add a new operand for the second register in the pair.
1400 std::string R2
= r
+ utostr(RegPairNum
);
1402 Inst
.addOperand(MCOperand::createReg(matchRegister(Reg2
)));
1403 Inst
.setOpcode((Inst
.getOpcode() == Hexagon::A2_tfrpt
)
1404 ? Hexagon::C2_ccombinewt
1405 : Hexagon::C2_ccombinewf
);
1408 case Hexagon::A2_tfrptnew
:
1409 case Hexagon::A2_tfrpfnew
: {
1410 MCOperand
&MO
= Inst
.getOperand(2);
1411 unsigned int RegPairNum
= RI
->getEncodingValue(MO
.getReg());
1412 std::string R1
= r
+ utostr(RegPairNum
+ 1);
1414 MO
.setReg(matchRegister(Reg1
));
1415 // Add a new operand for the second register in the pair.
1416 std::string R2
= r
+ utostr(RegPairNum
);
1418 Inst
.addOperand(MCOperand::createReg(matchRegister(Reg2
)));
1419 Inst
.setOpcode((Inst
.getOpcode() == Hexagon::A2_tfrptnew
)
1420 ? Hexagon::C2_ccombinewnewt
1421 : Hexagon::C2_ccombinewnewf
);
1425 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
1426 case Hexagon::V6_vassignp
: {
1427 MCOperand
&MO
= Inst
.getOperand(1);
1428 unsigned int RegPairNum
= RI
->getEncodingValue(MO
.getReg());
1429 std::string R1
= v
+ utostr(RegPairNum
+ 1);
1430 MO
.setReg(MatchRegisterName(R1
));
1431 // Add a new operand for the second register in the pair.
1432 std::string R2
= v
+ utostr(RegPairNum
);
1433 Inst
.addOperand(MCOperand::createReg(MatchRegisterName(R2
)));
1434 Inst
.setOpcode(Hexagon::V6_vcombine
);
1438 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1439 case Hexagon::CONST32
:
1442 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1443 case Hexagon::CONST64
:
1444 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1445 if (!Parser
.getStreamer().hasRawTextSupport()) {
1446 MCELFStreamer
*MES
= static_cast<MCELFStreamer
*>(&Parser
.getStreamer());
1447 MCOperand
&MO_1
= Inst
.getOperand(1);
1448 MCOperand
&MO_0
= Inst
.getOperand(0);
1450 // push section onto section stack
1453 std::string myCharStr
;
1454 MCSectionELF
*mySection
;
1456 // check if this as an immediate or a symbol
1458 bool Absolute
= MO_1
.getExpr()->evaluateAsAbsolute(Value
);
1460 // Create a new section - one for each constant
1461 // Some or all of the zeros are replaced with the given immediate.
1463 std::string myImmStr
= utohexstr(static_cast<uint32_t>(Value
));
1464 myCharStr
= StringRef(".gnu.linkonce.l4.CONST_00000000")
1465 .drop_back(myImmStr
.size())
1469 std::string myImmStr
= utohexstr(Value
);
1470 myCharStr
= StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1471 .drop_back(myImmStr
.size())
1476 mySection
= getContext().getELFSection(myCharStr
, ELF::SHT_PROGBITS
,
1477 ELF::SHF_ALLOC
| ELF::SHF_WRITE
);
1478 } else if (MO_1
.isExpr()) {
1479 // .lita - for expressions
1480 myCharStr
= ".lita";
1481 mySection
= getContext().getELFSection(myCharStr
, ELF::SHT_PROGBITS
,
1482 ELF::SHF_ALLOC
| ELF::SHF_WRITE
);
1484 llvm_unreachable("unexpected type of machine operand!");
1486 MES
->SwitchSection(mySection
);
1487 unsigned byteSize
= is32bit
? 4 : 8;
1488 getStreamer().EmitCodeAlignment(byteSize
, byteSize
);
1492 // for symbols, get rid of prepended ".gnu.linkonce.lx."
1494 // emit symbol if needed
1496 Sym
= getContext().getOrCreateSymbol(StringRef(myCharStr
.c_str() + 16));
1497 if (Sym
->isUndefined()) {
1498 getStreamer().EmitLabel(Sym
);
1499 getStreamer().EmitSymbolAttribute(Sym
, MCSA_Global
);
1500 getStreamer().EmitIntValue(Value
, byteSize
);
1502 } else if (MO_1
.isExpr()) {
1503 const char *StringStart
= nullptr;
1504 const char *StringEnd
= nullptr;
1505 if (*Operands
[4]->getStartLoc().getPointer() == '#') {
1506 StringStart
= Operands
[5]->getStartLoc().getPointer();
1507 StringEnd
= Operands
[6]->getStartLoc().getPointer();
1508 } else { // no pound
1509 StringStart
= Operands
[4]->getStartLoc().getPointer();
1510 StringEnd
= Operands
[5]->getStartLoc().getPointer();
1513 unsigned size
= StringEnd
- StringStart
;
1514 std::string DotConst
= ".CONST_";
1515 Sym
= getContext().getOrCreateSymbol(DotConst
+
1516 StringRef(StringStart
, size
));
1518 if (Sym
->isUndefined()) {
1519 // case where symbol is not yet defined: emit symbol
1520 getStreamer().EmitLabel(Sym
);
1521 getStreamer().EmitSymbolAttribute(Sym
, MCSA_Local
);
1522 getStreamer().EmitValue(MO_1
.getExpr(), 4);
1525 llvm_unreachable("unexpected type of machine operand!");
1531 if (is32bit
) // 32 bit
1532 TmpInst
.setOpcode(Hexagon::L2_loadrigp
);
1534 TmpInst
.setOpcode(Hexagon::L2_loadrdgp
);
1536 TmpInst
.addOperand(MO_0
);
1537 TmpInst
.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
1538 MCSymbolRefExpr::create(Sym
, getContext()), getContext())));
1544 // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1545 case Hexagon::A2_tfrpi
: {
1546 MCOperand
&Rdd
= Inst
.getOperand(0);
1547 MCOperand
&MO
= Inst
.getOperand(1);
1549 int sVal
= (MO
.getExpr()->evaluateAsAbsolute(Value
) && Value
< 0) ? -1 : 0;
1550 MCOperand
imm(MCOperand::createExpr(
1551 HexagonMCExpr::create(MCConstantExpr::create(sVal
, Context
), Context
)));
1552 Inst
= makeCombineInst(Hexagon::A2_combineii
, Rdd
, imm
, MO
);
1556 // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1557 case Hexagon::TFRI64_V4
: {
1558 MCOperand
&Rdd
= Inst
.getOperand(0);
1559 MCOperand
&MO
= Inst
.getOperand(1);
1561 if (MO
.getExpr()->evaluateAsAbsolute(Value
)) {
1562 int s8
= Hi_32(Value
);
1564 OutOfRange(IDLoc
, s8
, -128);
1565 MCOperand
imm(MCOperand::createExpr(HexagonMCExpr::create(
1566 MCConstantExpr::create(s8
, Context
), Context
))); // upper 32
1567 auto Expr
= HexagonMCExpr::create(
1568 MCConstantExpr::create(Lo_32(Value
), Context
), Context
);
1569 HexagonMCInstrInfo::setMustExtend(
1570 *Expr
, HexagonMCInstrInfo::mustExtend(*MO
.getExpr()));
1571 MCOperand
imm2(MCOperand::createExpr(Expr
)); // lower 32
1572 Inst
= makeCombineInst(Hexagon::A4_combineii
, Rdd
, imm
, imm2
);
1574 MCOperand
imm(MCOperand::createExpr(HexagonMCExpr::create(
1575 MCConstantExpr::create(0, Context
), Context
))); // upper 32
1576 Inst
= makeCombineInst(Hexagon::A4_combineii
, Rdd
, imm
, MO
);
1581 // Handle $Rdd = combine(##imm, #imm)"
1582 case Hexagon::TFRI64_V2_ext
: {
1583 MCOperand
&Rdd
= Inst
.getOperand(0);
1584 MCOperand
&MO1
= Inst
.getOperand(1);
1585 MCOperand
&MO2
= Inst
.getOperand(2);
1587 if (MO2
.getExpr()->evaluateAsAbsolute(Value
)) {
1589 if (s8
< -128 || s8
> 127)
1590 OutOfRange(IDLoc
, s8
, -128);
1592 Inst
= makeCombineInst(Hexagon::A2_combineii
, Rdd
, MO1
, MO2
);
1596 // Handle $Rdd = combine(#imm, ##imm)"
1597 case Hexagon::A4_combineii
: {
1598 MCOperand
&Rdd
= Inst
.getOperand(0);
1599 MCOperand
&MO1
= Inst
.getOperand(1);
1601 if (MO1
.getExpr()->evaluateAsAbsolute(Value
)) {
1603 if (s8
< -128 || s8
> 127)
1604 OutOfRange(IDLoc
, s8
, -128);
1606 MCOperand
&MO2
= Inst
.getOperand(2);
1607 Inst
= makeCombineInst(Hexagon::A4_combineii
, Rdd
, MO1
, MO2
);
1611 case Hexagon::S2_tableidxb_goodsyntax
:
1612 Inst
.setOpcode(Hexagon::S2_tableidxb
);
1615 case Hexagon::S2_tableidxh_goodsyntax
: {
1617 MCOperand
&Rx
= Inst
.getOperand(0);
1618 MCOperand
&Rs
= Inst
.getOperand(2);
1619 MCOperand
&Imm4
= Inst
.getOperand(3);
1620 MCOperand
&Imm6
= Inst
.getOperand(4);
1621 Imm6
.setExpr(HexagonMCExpr::create(
1622 MCBinaryExpr::createSub(Imm6
.getExpr(),
1623 MCConstantExpr::create(1, Context
), Context
),
1625 TmpInst
.setOpcode(Hexagon::S2_tableidxh
);
1626 TmpInst
.addOperand(Rx
);
1627 TmpInst
.addOperand(Rx
);
1628 TmpInst
.addOperand(Rs
);
1629 TmpInst
.addOperand(Imm4
);
1630 TmpInst
.addOperand(Imm6
);
1635 case Hexagon::S2_tableidxw_goodsyntax
: {
1637 MCOperand
&Rx
= Inst
.getOperand(0);
1638 MCOperand
&Rs
= Inst
.getOperand(2);
1639 MCOperand
&Imm4
= Inst
.getOperand(3);
1640 MCOperand
&Imm6
= Inst
.getOperand(4);
1641 Imm6
.setExpr(HexagonMCExpr::create(
1642 MCBinaryExpr::createSub(Imm6
.getExpr(),
1643 MCConstantExpr::create(2, Context
), Context
),
1645 TmpInst
.setOpcode(Hexagon::S2_tableidxw
);
1646 TmpInst
.addOperand(Rx
);
1647 TmpInst
.addOperand(Rx
);
1648 TmpInst
.addOperand(Rs
);
1649 TmpInst
.addOperand(Imm4
);
1650 TmpInst
.addOperand(Imm6
);
1655 case Hexagon::S2_tableidxd_goodsyntax
: {
1657 MCOperand
&Rx
= Inst
.getOperand(0);
1658 MCOperand
&Rs
= Inst
.getOperand(2);
1659 MCOperand
&Imm4
= Inst
.getOperand(3);
1660 MCOperand
&Imm6
= Inst
.getOperand(4);
1661 Imm6
.setExpr(HexagonMCExpr::create(
1662 MCBinaryExpr::createSub(Imm6
.getExpr(),
1663 MCConstantExpr::create(3, Context
), Context
),
1665 TmpInst
.setOpcode(Hexagon::S2_tableidxd
);
1666 TmpInst
.addOperand(Rx
);
1667 TmpInst
.addOperand(Rx
);
1668 TmpInst
.addOperand(Rs
);
1669 TmpInst
.addOperand(Imm4
);
1670 TmpInst
.addOperand(Imm6
);
1675 case Hexagon::M2_mpyui
:
1676 Inst
.setOpcode(Hexagon::M2_mpyi
);
1678 case Hexagon::M2_mpysmi
: {
1680 MCOperand
&Rd
= Inst
.getOperand(0);
1681 MCOperand
&Rs
= Inst
.getOperand(1);
1682 MCOperand
&Imm
= Inst
.getOperand(2);
1684 MCExpr
const &Expr
= *Imm
.getExpr();
1685 bool Absolute
= Expr
.evaluateAsAbsolute(Value
);
1687 return Match_InvalidOperand
;
1688 if (!HexagonMCInstrInfo::mustExtend(Expr
) &&
1689 ((Value
<= -256) || Value
>= 256))
1690 return Match_InvalidOperand
;
1691 if (Value
< 0 && Value
> -256) {
1692 Imm
.setExpr(HexagonMCExpr::create(
1693 MCConstantExpr::create(Value
* -1, Context
), Context
));
1694 TmpInst
.setOpcode(Hexagon::M2_mpysin
);
1696 TmpInst
.setOpcode(Hexagon::M2_mpysip
);
1697 TmpInst
.addOperand(Rd
);
1698 TmpInst
.addOperand(Rs
);
1699 TmpInst
.addOperand(Imm
);
1704 case Hexagon::S2_asr_i_r_rnd_goodsyntax
: {
1705 MCOperand
&Imm
= Inst
.getOperand(2);
1708 bool Absolute
= Imm
.getExpr()->evaluateAsAbsolute(Value
);
1710 return Match_InvalidOperand
;
1711 if (Value
== 0) { // convert to $Rd = $Rs
1712 TmpInst
.setOpcode(Hexagon::A2_tfr
);
1713 MCOperand
&Rd
= Inst
.getOperand(0);
1714 MCOperand
&Rs
= Inst
.getOperand(1);
1715 TmpInst
.addOperand(Rd
);
1716 TmpInst
.addOperand(Rs
);
1718 Imm
.setExpr(HexagonMCExpr::create(
1719 MCBinaryExpr::createSub(Imm
.getExpr(),
1720 MCConstantExpr::create(1, Context
), Context
),
1722 TmpInst
.setOpcode(Hexagon::S2_asr_i_r_rnd
);
1723 MCOperand
&Rd
= Inst
.getOperand(0);
1724 MCOperand
&Rs
= Inst
.getOperand(1);
1725 TmpInst
.addOperand(Rd
);
1726 TmpInst
.addOperand(Rs
);
1727 TmpInst
.addOperand(Imm
);
1733 case Hexagon::S2_asr_i_p_rnd_goodsyntax
: {
1734 MCOperand
&Rdd
= Inst
.getOperand(0);
1735 MCOperand
&Rss
= Inst
.getOperand(1);
1736 MCOperand
&Imm
= Inst
.getOperand(2);
1738 bool Absolute
= Imm
.getExpr()->evaluateAsAbsolute(Value
);
1740 return Match_InvalidOperand
;
1741 if (Value
== 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1743 unsigned int RegPairNum
= RI
->getEncodingValue(Rss
.getReg());
1744 std::string R1
= r
+ utostr(RegPairNum
+ 1);
1746 Rss
.setReg(matchRegister(Reg1
));
1747 // Add a new operand for the second register in the pair.
1748 std::string R2
= r
+ utostr(RegPairNum
);
1750 TmpInst
.setOpcode(Hexagon::A2_combinew
);
1751 TmpInst
.addOperand(Rdd
);
1752 TmpInst
.addOperand(Rss
);
1753 TmpInst
.addOperand(MCOperand::createReg(matchRegister(Reg2
)));
1756 Imm
.setExpr(HexagonMCExpr::create(
1757 MCBinaryExpr::createSub(Imm
.getExpr(),
1758 MCConstantExpr::create(1, Context
), Context
),
1760 Inst
.setOpcode(Hexagon::S2_asr_i_p_rnd
);
1765 case Hexagon::A4_boundscheck
: {
1766 MCOperand
&Rs
= Inst
.getOperand(1);
1767 unsigned int RegNum
= RI
->getEncodingValue(Rs
.getReg());
1768 if (RegNum
& 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1769 Inst
.setOpcode(Hexagon::A4_boundscheck_hi
);
1770 std::string Name
= r
+ utostr(RegNum
) + Colon
+ utostr(RegNum
- 1);
1771 StringRef RegPair
= Name
;
1772 Rs
.setReg(matchRegister(RegPair
));
1774 Inst
.setOpcode(Hexagon::A4_boundscheck_lo
);
1775 std::string Name
= r
+ utostr(RegNum
+ 1) + Colon
+ utostr(RegNum
);
1776 StringRef RegPair
= Name
;
1777 Rs
.setReg(matchRegister(RegPair
));
1782 case Hexagon::A2_addsp
: {
1783 MCOperand
&Rs
= Inst
.getOperand(1);
1784 unsigned int RegNum
= RI
->getEncodingValue(Rs
.getReg());
1785 if (RegNum
& 1) { // Odd mapped to raw:hi
1786 Inst
.setOpcode(Hexagon::A2_addsph
);
1787 std::string Name
= r
+ utostr(RegNum
) + Colon
+ utostr(RegNum
- 1);
1788 StringRef RegPair
= Name
;
1789 Rs
.setReg(matchRegister(RegPair
));
1790 } else { // Even mapped raw:lo
1791 Inst
.setOpcode(Hexagon::A2_addspl
);
1792 std::string Name
= r
+ utostr(RegNum
+ 1) + Colon
+ utostr(RegNum
);
1793 StringRef RegPair
= Name
;
1794 Rs
.setReg(matchRegister(RegPair
));
1799 case Hexagon::M2_vrcmpys_s1
: {
1800 MCOperand
&Rt
= Inst
.getOperand(2);
1801 unsigned int RegNum
= RI
->getEncodingValue(Rt
.getReg());
1802 if (RegNum
& 1) { // Odd mapped to sat:raw:hi
1803 Inst
.setOpcode(Hexagon::M2_vrcmpys_s1_h
);
1804 std::string Name
= r
+ utostr(RegNum
) + Colon
+ utostr(RegNum
- 1);
1805 StringRef RegPair
= Name
;
1806 Rt
.setReg(matchRegister(RegPair
));
1807 } else { // Even mapped sat:raw:lo
1808 Inst
.setOpcode(Hexagon::M2_vrcmpys_s1_l
);
1809 std::string Name
= r
+ utostr(RegNum
+ 1) + Colon
+ utostr(RegNum
);
1810 StringRef RegPair
= Name
;
1811 Rt
.setReg(matchRegister(RegPair
));
1816 case Hexagon::M2_vrcmpys_acc_s1
: {
1818 MCOperand
&Rxx
= Inst
.getOperand(0);
1819 MCOperand
&Rss
= Inst
.getOperand(2);
1820 MCOperand
&Rt
= Inst
.getOperand(3);
1821 unsigned int RegNum
= RI
->getEncodingValue(Rt
.getReg());
1822 if (RegNum
& 1) { // Odd mapped to sat:raw:hi
1823 TmpInst
.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h
);
1824 std::string Name
= r
+ utostr(RegNum
) + Colon
+ utostr(RegNum
- 1);
1825 StringRef RegPair
= Name
;
1826 Rt
.setReg(matchRegister(RegPair
));
1827 } else { // Even mapped sat:raw:lo
1828 TmpInst
.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l
);
1829 std::string Name
= r
+ utostr(RegNum
+ 1) + Colon
+ utostr(RegNum
);
1830 StringRef RegPair
= Name
;
1831 Rt
.setReg(matchRegister(RegPair
));
1833 // Registers are in different positions
1834 TmpInst
.addOperand(Rxx
);
1835 TmpInst
.addOperand(Rxx
);
1836 TmpInst
.addOperand(Rss
);
1837 TmpInst
.addOperand(Rt
);
1842 case Hexagon::M2_vrcmpys_s1rp
: {
1843 MCOperand
&Rt
= Inst
.getOperand(2);
1844 unsigned int RegNum
= RI
->getEncodingValue(Rt
.getReg());
1845 if (RegNum
& 1) { // Odd mapped to rnd:sat:raw:hi
1846 Inst
.setOpcode(Hexagon::M2_vrcmpys_s1rp_h
);
1847 std::string Name
= r
+ utostr(RegNum
) + Colon
+ utostr(RegNum
- 1);
1848 StringRef RegPair
= Name
;
1849 Rt
.setReg(matchRegister(RegPair
));
1850 } else { // Even mapped rnd:sat:raw:lo
1851 Inst
.setOpcode(Hexagon::M2_vrcmpys_s1rp_l
);
1852 std::string Name
= r
+ utostr(RegNum
+ 1) + Colon
+ utostr(RegNum
);
1853 StringRef RegPair
= Name
;
1854 Rt
.setReg(matchRegister(RegPair
));
1859 case Hexagon::S5_asrhub_rnd_sat_goodsyntax
: {
1860 MCOperand
&Imm
= Inst
.getOperand(2);
1862 bool Absolute
= Imm
.getExpr()->evaluateAsAbsolute(Value
);
1864 return Match_InvalidOperand
;
1866 Inst
.setOpcode(Hexagon::S2_vsathub
);
1868 Imm
.setExpr(HexagonMCExpr::create(
1869 MCBinaryExpr::createSub(Imm
.getExpr(),
1870 MCConstantExpr::create(1, Context
), Context
),
1872 Inst
.setOpcode(Hexagon::S5_asrhub_rnd_sat
);
1877 case Hexagon::S5_vasrhrnd_goodsyntax
: {
1878 MCOperand
&Rdd
= Inst
.getOperand(0);
1879 MCOperand
&Rss
= Inst
.getOperand(1);
1880 MCOperand
&Imm
= Inst
.getOperand(2);
1882 bool Absolute
= Imm
.getExpr()->evaluateAsAbsolute(Value
);
1884 return Match_InvalidOperand
;
1887 unsigned int RegPairNum
= RI
->getEncodingValue(Rss
.getReg());
1888 std::string R1
= r
+ utostr(RegPairNum
+ 1);
1890 Rss
.setReg(matchRegister(Reg1
));
1891 // Add a new operand for the second register in the pair.
1892 std::string R2
= r
+ utostr(RegPairNum
);
1894 TmpInst
.setOpcode(Hexagon::A2_combinew
);
1895 TmpInst
.addOperand(Rdd
);
1896 TmpInst
.addOperand(Rss
);
1897 TmpInst
.addOperand(MCOperand::createReg(matchRegister(Reg2
)));
1900 Imm
.setExpr(HexagonMCExpr::create(
1901 MCBinaryExpr::createSub(Imm
.getExpr(),
1902 MCConstantExpr::create(1, Context
), Context
),
1904 Inst
.setOpcode(Hexagon::S5_vasrhrnd
);
1909 case Hexagon::A2_not
: {
1911 MCOperand
&Rd
= Inst
.getOperand(0);
1912 MCOperand
&Rs
= Inst
.getOperand(1);
1913 TmpInst
.setOpcode(Hexagon::A2_subri
);
1914 TmpInst
.addOperand(Rd
);
1915 TmpInst
.addOperand(MCOperand::createExpr(
1916 HexagonMCExpr::create(MCConstantExpr::create(-1, Context
), Context
)));
1917 TmpInst
.addOperand(Rs
);
1921 case Hexagon::PS_loadrubabs
:
1922 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(1).getExpr()))
1923 Inst
.setOpcode(Hexagon::L2_loadrubgp
);
1925 case Hexagon::PS_loadrbabs
:
1926 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(1).getExpr()))
1927 Inst
.setOpcode(Hexagon::L2_loadrbgp
);
1929 case Hexagon::PS_loadruhabs
:
1930 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(1).getExpr()))
1931 Inst
.setOpcode(Hexagon::L2_loadruhgp
);
1933 case Hexagon::PS_loadrhabs
:
1934 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(1).getExpr()))
1935 Inst
.setOpcode(Hexagon::L2_loadrhgp
);
1937 case Hexagon::PS_loadriabs
:
1938 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(1).getExpr()))
1939 Inst
.setOpcode(Hexagon::L2_loadrigp
);
1941 case Hexagon::PS_loadrdabs
:
1942 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(1).getExpr()))
1943 Inst
.setOpcode(Hexagon::L2_loadrdgp
);
1945 case Hexagon::PS_storerbabs
:
1946 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1947 Inst
.setOpcode(Hexagon::S2_storerbgp
);
1949 case Hexagon::PS_storerhabs
:
1950 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1951 Inst
.setOpcode(Hexagon::S2_storerhgp
);
1953 case Hexagon::PS_storerfabs
:
1954 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1955 Inst
.setOpcode(Hexagon::S2_storerfgp
);
1957 case Hexagon::PS_storeriabs
:
1958 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1959 Inst
.setOpcode(Hexagon::S2_storerigp
);
1961 case Hexagon::PS_storerdabs
:
1962 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1963 Inst
.setOpcode(Hexagon::S2_storerdgp
);
1965 case Hexagon::PS_storerbnewabs
:
1966 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1967 Inst
.setOpcode(Hexagon::S2_storerbnewgp
);
1969 case Hexagon::PS_storerhnewabs
:
1970 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1971 Inst
.setOpcode(Hexagon::S2_storerhnewgp
);
1973 case Hexagon::PS_storerinewabs
:
1974 if (!HexagonMCInstrInfo::mustExtend(*Inst
.getOperand(0).getExpr()))
1975 Inst
.setOpcode(Hexagon::S2_storerinewgp
);
1977 case Hexagon::A2_zxtb
: {
1978 Inst
.setOpcode(Hexagon::A2_andir
);
1980 MCOperand::createExpr(MCConstantExpr::create(255, Context
)));
1985 return Match_Success
;
1988 unsigned HexagonAsmParser::matchRegister(StringRef Name
) {
1989 if (unsigned Reg
= MatchRegisterName(Name
))
1991 return MatchRegisterAltName(Name
);