diff options
Diffstat (limited to 'llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp | 386 |
1 files changed, 269 insertions, 117 deletions
diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index 607266d552a6..d5a3a19446c7 100644 --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -53,8 +53,6 @@ enum RegisterKind { GRH32Reg, GR64Reg, GR128Reg, - ADDR32Reg, - ADDR64Reg, FP32Reg, FP64Reg, FP128Reg, @@ -109,7 +107,7 @@ private: // Base + Disp + Index, where Base and Index are LLVM registers or 0. // MemKind says what type of memory this is and RegKind says what type - // the base register has (ADDR32Reg or ADDR64Reg). Length is the operand + // the base register has (GR32Reg or GR64Reg). Length is the operand // length for D(L,B)-style operands, otherwise it is null. struct MemOp { unsigned Base : 12; @@ -348,8 +346,8 @@ public: bool isGRX32() const { return false; } bool isGR64() const { return isReg(GR64Reg); } bool isGR128() const { return isReg(GR128Reg); } - bool isADDR32() const { return isReg(ADDR32Reg); } - bool isADDR64() const { return isReg(ADDR64Reg); } + bool isADDR32() const { return isReg(GR32Reg); } + bool isADDR64() const { return isReg(GR64Reg); } bool isADDR128() const { return false; } bool isFP32() const { return isReg(FP32Reg); } bool isFP64() const { return isReg(FP64Reg); } @@ -361,16 +359,16 @@ public: bool isAR32() const { return isReg(AR32Reg); } bool isCR64() const { return isReg(CR64Reg); } bool isAnyReg() const { return (isReg() || isImm(0, 15)); } - bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, ADDR32Reg); } - bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, ADDR32Reg); } - bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, ADDR64Reg); } - bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, ADDR64Reg); } - bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, ADDR64Reg); } - bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, ADDR64Reg); } - bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(ADDR64Reg); } - bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(ADDR64Reg); } - bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, ADDR64Reg); } - bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, ADDR64Reg); } + bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, GR32Reg); } + bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, GR32Reg); } + bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, GR64Reg); } + bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, GR64Reg); } + bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, GR64Reg); } + bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, GR64Reg); } + bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(GR64Reg); } + bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(GR64Reg); } + bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, GR64Reg); } + bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, GR64Reg); } bool isU1Imm() const { return isImm(0, 1); } bool isU2Imm() const { return isImm(0, 3); } bool isU3Imm() const { return isImm(0, 7); } @@ -405,26 +403,24 @@ private: SMLoc StartLoc, EndLoc; }; - bool parseRegister(Register &Reg); + bool parseRegister(Register &Reg, bool RestoreOnFailure = false); - bool parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs, - bool IsAddress = false); + bool parseIntegerRegister(Register &Reg, RegisterGroup Group); OperandMatchResultTy parseRegister(OperandVector &Operands, - RegisterGroup Group, const unsigned *Regs, RegisterKind Kind); OperandMatchResultTy parseAnyRegister(OperandVector &Operands); - bool parseAddress(bool &HaveReg1, Register &Reg1, - bool &HaveReg2, Register &Reg2, - const MCExpr *&Disp, const MCExpr *&Length); + bool parseAddress(bool &HaveReg1, Register &Reg1, bool &HaveReg2, + Register &Reg2, const MCExpr *&Disp, const MCExpr *&Length, + bool HasLength = false, bool HasVectorIndex = false); bool parseAddressRegister(Register &Reg); bool ParseDirectiveInsn(SMLoc L); OperandMatchResultTy parseAddress(OperandVector &Operands, - MemoryKind MemKind, const unsigned *Regs, + MemoryKind MemKind, RegisterKind RegKind); OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal, @@ -449,6 +445,10 @@ public: // Override MCTargetAsmParser. bool ParseDirective(AsmToken DirectiveID) override; bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; + bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, + bool RestoreOnFailure); + OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, + SMLoc &EndLoc) override; bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) override; bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, @@ -458,76 +458,78 @@ public: // Used by the TableGen code to parse particular operand types. OperandMatchResultTy parseGR32(OperandVector &Operands) { - return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, GR32Reg); + return parseRegister(Operands, GR32Reg); } OperandMatchResultTy parseGRH32(OperandVector &Operands) { - return parseRegister(Operands, RegGR, SystemZMC::GRH32Regs, GRH32Reg); + return parseRegister(Operands, GRH32Reg); } OperandMatchResultTy parseGRX32(OperandVector &Operands) { llvm_unreachable("GRX32 should only be used for pseudo instructions"); } OperandMatchResultTy parseGR64(OperandVector &Operands) { - return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, GR64Reg); + return parseRegister(Operands, GR64Reg); } OperandMatchResultTy parseGR128(OperandVector &Operands) { - return parseRegister(Operands, RegGR, SystemZMC::GR128Regs, GR128Reg); + return parseRegister(Operands, GR128Reg); } OperandMatchResultTy parseADDR32(OperandVector &Operands) { - return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, ADDR32Reg); + // For the AsmParser, we will accept %r0 for ADDR32 as well. + return parseRegister(Operands, GR32Reg); } OperandMatchResultTy parseADDR64(OperandVector &Operands) { - return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, ADDR64Reg); + // For the AsmParser, we will accept %r0 for ADDR64 as well. + return parseRegister(Operands, GR64Reg); } OperandMatchResultTy parseADDR128(OperandVector &Operands) { llvm_unreachable("Shouldn't be used as an operand"); } OperandMatchResultTy parseFP32(OperandVector &Operands) { - return parseRegister(Operands, RegFP, SystemZMC::FP32Regs, FP32Reg); + return parseRegister(Operands, FP32Reg); } OperandMatchResultTy parseFP64(OperandVector &Operands) { - return parseRegister(Operands, RegFP, SystemZMC::FP64Regs, FP64Reg); + return parseRegister(Operands, FP64Reg); } OperandMatchResultTy parseFP128(OperandVector &Operands) { - return parseRegister(Operands, RegFP, SystemZMC::FP128Regs, FP128Reg); + return parseRegister(Operands, FP128Reg); } OperandMatchResultTy parseVR32(OperandVector &Operands) { - return parseRegister(Operands, RegV, SystemZMC::VR32Regs, VR32Reg); + return parseRegister(Operands, VR32Reg); } OperandMatchResultTy parseVR64(OperandVector &Operands) { - return parseRegister(Operands, RegV, SystemZMC::VR64Regs, VR64Reg); + return parseRegister(Operands, VR64Reg); } OperandMatchResultTy parseVF128(OperandVector &Operands) { llvm_unreachable("Shouldn't be used as an operand"); } OperandMatchResultTy parseVR128(OperandVector &Operands) { - return parseRegister(Operands, RegV, SystemZMC::VR128Regs, VR128Reg); + return parseRegister(Operands, VR128Reg); } OperandMatchResultTy parseAR32(OperandVector &Operands) { - return parseRegister(Operands, RegAR, SystemZMC::AR32Regs, AR32Reg); + return parseRegister(Operands, AR32Reg); } OperandMatchResultTy parseCR64(OperandVector &Operands) { - return parseRegister(Operands, RegCR, SystemZMC::CR64Regs, CR64Reg); + return parseRegister(Operands, CR64Reg); } OperandMatchResultTy parseAnyReg(OperandVector &Operands) { return parseAnyRegister(Operands); } OperandMatchResultTy parseBDAddr32(OperandVector &Operands) { - return parseAddress(Operands, BDMem, SystemZMC::GR32Regs, ADDR32Reg); + return parseAddress(Operands, BDMem, GR32Reg); } OperandMatchResultTy parseBDAddr64(OperandVector &Operands) { - return parseAddress(Operands, BDMem, SystemZMC::GR64Regs, ADDR64Reg); + return parseAddress(Operands, BDMem, GR64Reg); } OperandMatchResultTy parseBDXAddr64(OperandVector &Operands) { - return parseAddress(Operands, BDXMem, SystemZMC::GR64Regs, ADDR64Reg); + return parseAddress(Operands, BDXMem, GR64Reg); } OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) { - return parseAddress(Operands, BDLMem, SystemZMC::GR64Regs, ADDR64Reg); + return parseAddress(Operands, BDLMem, GR64Reg); } OperandMatchResultTy parseBDRAddr64(OperandVector &Operands) { - return parseAddress(Operands, BDRMem, SystemZMC::GR64Regs, ADDR64Reg); + return parseAddress(Operands, BDRMem, GR64Reg); } OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) { - return parseAddress(Operands, BDVMem, SystemZMC::GR64Regs, ADDR64Reg); + return parseAddress(Operands, BDVMem, GR64Reg); } OperandMatchResultTy parsePCRel12(OperandVector &Operands) { return parsePCRel(Operands, -(1LL << 12), (1LL << 12) - 1, false); @@ -691,27 +693,37 @@ void SystemZOperand::print(raw_ostream &OS) const { } // Parse one register of the form %<prefix><number>. -bool SystemZAsmParser::parseRegister(Register &Reg) { +bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) { Reg.StartLoc = Parser.getTok().getLoc(); // Eat the % prefix. if (Parser.getTok().isNot(AsmToken::Percent)) return Error(Parser.getTok().getLoc(), "register expected"); + const AsmToken &PercentTok = Parser.getTok(); Parser.Lex(); // Expect a register name. - if (Parser.getTok().isNot(AsmToken::Identifier)) + if (Parser.getTok().isNot(AsmToken::Identifier)) { + if (RestoreOnFailure) + getLexer().UnLex(PercentTok); return Error(Reg.StartLoc, "invalid register"); + } // Check that there's a prefix. StringRef Name = Parser.getTok().getString(); - if (Name.size() < 2) + if (Name.size() < 2) { + if (RestoreOnFailure) + getLexer().UnLex(PercentTok); return Error(Reg.StartLoc, "invalid register"); + } char Prefix = Name[0]; // Treat the rest of the register name as a register number. - if (Name.substr(1).getAsInteger(10, Reg.Num)) + if (Name.substr(1).getAsInteger(10, Reg.Num)) { + if (RestoreOnFailure) + getLexer().UnLex(PercentTok); return Error(Reg.StartLoc, "invalid register"); + } // Look for valid combinations of prefix and number. if (Prefix == 'r' && Reg.Num < 16) @@ -724,49 +736,102 @@ bool SystemZAsmParser::parseRegister(Register &Reg) { Reg.Group = RegAR; else if (Prefix == 'c' && Reg.Num < 16) Reg.Group = RegCR; - else + else { + if (RestoreOnFailure) + getLexer().UnLex(PercentTok); return Error(Reg.StartLoc, "invalid register"); + } Reg.EndLoc = Parser.getTok().getLoc(); Parser.Lex(); return false; } -// Parse a register of group Group. If Regs is nonnull, use it to map -// the raw register number to LLVM numbering, with zero entries -// indicating an invalid register. IsAddress says whether the -// register appears in an address context. Allow FP Group if expecting -// RegV Group, since the f-prefix yields the FP group even while used -// with vector instructions. -bool SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group, - const unsigned *Regs, bool IsAddress) { - if (parseRegister(Reg)) - return true; - if (Reg.Group != Group && !(Reg.Group == RegFP && Group == RegV)) - return Error(Reg.StartLoc, "invalid operand for instruction"); - if (Regs && Regs[Reg.Num] == 0) - return Error(Reg.StartLoc, "invalid register pair"); - if (Reg.Num == 0 && IsAddress) - return Error(Reg.StartLoc, "%r0 used in an address"); - if (Regs) - Reg.Num = Regs[Reg.Num]; - return false; -} - -// Parse a register and add it to Operands. The other arguments are as above. +// Parse a register of kind Kind and add it to Operands. OperandMatchResultTy -SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterGroup Group, - const unsigned *Regs, RegisterKind Kind) { - if (Parser.getTok().isNot(AsmToken::Percent)) +SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterKind Kind) { + Register Reg; + RegisterGroup Group; + switch (Kind) { + case GR32Reg: + case GRH32Reg: + case GR64Reg: + case GR128Reg: + Group = RegGR; + break; + case FP32Reg: + case FP64Reg: + case FP128Reg: + Group = RegFP; + break; + case VR32Reg: + case VR64Reg: + case VR128Reg: + Group = RegV; + break; + case AR32Reg: + Group = RegAR; + break; + case CR64Reg: + Group = RegCR; + break; + } + + // Handle register names of the form %<prefix><number> + if (Parser.getTok().is(AsmToken::Percent)) { + if (parseRegister(Reg)) + return MatchOperand_ParseFail; + + // Check the parsed register group "Reg.Group" with the expected "Group" + // Have to error out if user specified wrong prefix. + switch (Group) { + case RegGR: + case RegFP: + case RegAR: + case RegCR: + if (Group != Reg.Group) { + Error(Reg.StartLoc, "invalid operand for instruction"); + return MatchOperand_ParseFail; + } + break; + case RegV: + if (Reg.Group != RegV && Reg.Group != RegFP) { + Error(Reg.StartLoc, "invalid operand for instruction"); + return MatchOperand_ParseFail; + } + break; + } + } else if (Parser.getTok().is(AsmToken::Integer)) { + if (parseIntegerRegister(Reg, Group)) + return MatchOperand_ParseFail; + } + // Otherwise we didn't match a register operand. + else return MatchOperand_NoMatch; - Register Reg; - bool IsAddress = (Kind == ADDR32Reg || Kind == ADDR64Reg); - if (parseRegister(Reg, Group, Regs, IsAddress)) + // Determine the LLVM register number according to Kind. + const unsigned *Regs; + switch (Kind) { + case GR32Reg: Regs = SystemZMC::GR32Regs; break; + case GRH32Reg: Regs = SystemZMC::GRH32Regs; break; + case GR64Reg: Regs = SystemZMC::GR64Regs; break; + case GR128Reg: Regs = SystemZMC::GR128Regs; break; + case FP32Reg: Regs = SystemZMC::FP32Regs; break; + case FP64Reg: Regs = SystemZMC::FP64Regs; break; + case FP128Reg: Regs = SystemZMC::FP128Regs; break; + case VR32Reg: Regs = SystemZMC::VR32Regs; break; + case VR64Reg: Regs = SystemZMC::VR64Regs; break; + case VR128Reg: Regs = SystemZMC::VR128Regs; break; + case AR32Reg: Regs = SystemZMC::AR32Regs; break; + case CR64Reg: Regs = SystemZMC::CR64Regs; break; + } + if (Regs[Reg.Num] == 0) { + Error(Reg.StartLoc, "invalid register pair"); return MatchOperand_ParseFail; + } - Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num, - Reg.StartLoc, Reg.EndLoc)); + Operands.push_back( + SystemZOperand::createReg(Kind, Regs[Reg.Num], Reg.StartLoc, Reg.EndLoc)); return MatchOperand_Success; } @@ -831,11 +896,39 @@ SystemZAsmParser::parseAnyRegister(OperandVector &Operands) { return MatchOperand_Success; } +bool SystemZAsmParser::parseIntegerRegister(Register &Reg, + RegisterGroup Group) { + Reg.StartLoc = Parser.getTok().getLoc(); + // We have an integer token + const MCExpr *Register; + if (Parser.parseExpression(Register)) + return true; + + const auto *CE = dyn_cast<MCConstantExpr>(Register); + if (!CE) + return true; + + int64_t MaxRegNum = (Group == RegV) ? 31 : 15; + int64_t Value = CE->getValue(); + if (Value < 0 || Value > MaxRegNum) { + Error(Parser.getTok().getLoc(), "invalid register"); + return true; + } + + // Assign the Register Number + Reg.Num = (unsigned)Value; + Reg.Group = Group; + Reg.EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + + // At this point, successfully parsed an integer register. + return false; +} + // Parse a memory operand into Reg1, Reg2, Disp, and Length. bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1, bool &HaveReg2, Register &Reg2, - const MCExpr *&Disp, - const MCExpr *&Length) { + const MCExpr *&Disp, const MCExpr *&Length, + bool HasLength, bool HasVectorIndex) { // Parse the displacement, which must always be present. if (getParser().parseExpression(Disp)) return true; @@ -844,6 +937,27 @@ bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1, HaveReg1 = false; HaveReg2 = false; Length = nullptr; + + // If we have a scenario as below: + // vgef %v0, 0(0), 0 + // This is an example of a "BDVMem" instruction type. + // + // So when we parse this as an integer register, the register group + // needs to be tied to "RegV". Usually when the prefix is passed in + // as %<prefix><reg-number> its easy to check which group it should belong to + // However, if we're passing in just the integer there's no real way to + // "check" what register group it should belong to. + // + // When the user passes in the register as an integer, the user assumes that + // the compiler is responsible for substituting it as the right kind of + // register. Whereas, when the user specifies a "prefix", the onus is on + // the user to make sure they pass in the right kind of register. + // + // The restriction only applies to the first Register (i.e. Reg1). Reg2 is + // always a general register. Reg1 should be of group RegV if "HasVectorIndex" + // (i.e. insn is of type BDVMem) is true. + RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR; + if (getLexer().is(AsmToken::LParen)) { Parser.Lex(); @@ -852,18 +966,47 @@ bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1, HaveReg1 = true; if (parseRegister(Reg1)) return true; + } + // So if we have an integer as the first token in ([tok1], ..), it could: + // 1. Refer to a "Register" (i.e X,R,V fields in BD[X|R|V]Mem type of + // instructions) + // 2. Refer to a "Length" field (i.e L field in BDLMem type of instructions) + else if (getLexer().is(AsmToken::Integer)) { + if (HasLength) { + // Instruction has a "Length" field, safe to parse the first token as + // the "Length" field + if (getParser().parseExpression(Length)) + return true; + } else { + // Otherwise, if the instruction has no "Length" field, parse the + // token as a "Register". We don't have to worry about whether the + // instruction is invalid here, because the caller will take care of + // error reporting. + HaveReg1 = true; + if (parseIntegerRegister(Reg1, RegGroup)) + return true; + } } else { - // Parse the length. - if (getParser().parseExpression(Length)) - return true; + // If its not an integer or a percent token, then if the instruction + // is reported to have a "Length" then, parse it as "Length". + if (HasLength) { + if (getParser().parseExpression(Length)) + return true; + } } // Check whether there's a second register. if (getLexer().is(AsmToken::Comma)) { Parser.Lex(); HaveReg2 = true; - if (parseRegister(Reg2)) - return true; + + if (getLexer().is(AsmToken::Integer)) { + if (parseIntegerRegister(Reg2, RegGR)) + return true; + } else { + if (parseRegister(Reg2)) + return true; + } } // Consume the closing bracket. @@ -883,9 +1026,6 @@ SystemZAsmParser::parseAddressRegister(Register &Reg) { } else if (Reg.Group != RegGR) { Error(Reg.StartLoc, "invalid address register"); return true; - } else if (Reg.Num == 0) { - Error(Reg.StartLoc, "%r0 used in an address"); - return true; } return false; } @@ -894,16 +1034,27 @@ SystemZAsmParser::parseAddressRegister(Register &Reg) { // are as above. OperandMatchResultTy SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind, - const unsigned *Regs, RegisterKind RegKind) { + RegisterKind RegKind) { SMLoc StartLoc = Parser.getTok().getLoc(); unsigned Base = 0, Index = 0, LengthReg = 0; Register Reg1, Reg2; bool HaveReg1, HaveReg2; const MCExpr *Disp; const MCExpr *Length; - if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length)) + + bool HasLength = (MemKind == BDLMem) ? true : false; + bool HasVectorIndex = (MemKind == BDVMem) ? true : false; + if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length, HasLength, + HasVectorIndex)) return MatchOperand_ParseFail; + const unsigned *Regs; + switch (RegKind) { + case GR32Reg: Regs = SystemZMC::GR32Regs; break; + case GR64Reg: Regs = SystemZMC::GR64Regs; break; + default: llvm_unreachable("invalid RegKind"); + } + switch (MemKind) { case BDMem: // If we have Reg1, it must be an address register. @@ -912,11 +1063,7 @@ SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind, return MatchOperand_ParseFail; Base = Regs[Reg1.Num]; } - // There must be no Reg2 or length. - if (Length) { - Error(StartLoc, "invalid use of length addressing"); - return MatchOperand_ParseFail; - } + // There must be no Reg2. if (HaveReg2) { Error(StartLoc, "invalid use of indexed addressing"); return MatchOperand_ParseFail; @@ -940,11 +1087,6 @@ SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind, return MatchOperand_ParseFail; Base = Regs[Reg2.Num]; } - // There must be no length. - if (Length) { - Error(StartLoc, "invalid use of length addressing"); - return MatchOperand_ParseFail; - } break; case BDLMem: // If we have Reg2, it must be an address register. @@ -977,11 +1119,6 @@ SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind, return MatchOperand_ParseFail; Base = Regs[Reg2.Num]; } - // There must be no length. - if (Length) { - Error(StartLoc, "invalid use of length addressing"); - return MatchOperand_ParseFail; - } break; case BDVMem: // We must have Reg1, and it must be a vector register. @@ -996,16 +1133,11 @@ SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind, return MatchOperand_ParseFail; Base = Regs[Reg2.Num]; } - // There must be no length. - if (Length) { - Error(StartLoc, "invalid use of length addressing"); - return MatchOperand_ParseFail; - } break; } SMLoc EndLoc = - SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp, Index, Length, LengthReg, StartLoc, EndLoc)); @@ -1118,15 +1250,15 @@ bool SystemZAsmParser::ParseDirectiveInsn(SMLoc L) { } // Emit as a regular instruction. - Parser.getStreamer().EmitInstruction(Inst, getSTI()); + Parser.getStreamer().emitInstruction(Inst, getSTI()); return false; } bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, - SMLoc &EndLoc) { + SMLoc &EndLoc, bool RestoreOnFailure) { Register Reg; - if (parseRegister(Reg)) + if (parseRegister(Reg, RestoreOnFailure)) return true; if (Reg.Group == RegGR) RegNo = SystemZMC::GR64Regs[Reg.Num]; @@ -1143,6 +1275,25 @@ bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, return false; } +bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, + SMLoc &EndLoc) { + return ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/false); +} + +OperandMatchResultTy SystemZAsmParser::tryParseRegister(unsigned &RegNo, + SMLoc &StartLoc, + SMLoc &EndLoc) { + bool Result = + ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/true); + bool PendingErrors = getParser().hasPendingError(); + getParser().clearPendingErrors(); + if (PendingErrors) + return MatchOperand_ParseFail; + if (Result) + return MatchOperand_NoMatch; + return MatchOperand_Success; +} + bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { @@ -1215,7 +1366,8 @@ bool SystemZAsmParser::parseOperand(OperandVector &Operands, bool HaveReg1, HaveReg2; const MCExpr *Expr; const MCExpr *Length; - if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length)) + if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length, + /*HasLength*/ true, /*HasVectorIndex*/ true)) return true; // If the register combination is not valid for any instruction, reject it. // Otherwise, fall back to reporting an unrecognized instruction. @@ -1252,7 +1404,7 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, switch (MatchResult) { case Match_Success: Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); + Out.emitInstruction(Inst, getSTI()); return false; case Match_MissingFeature: { @@ -1322,7 +1474,7 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal, } int64_t Value = CE->getValue(); MCSymbol *Sym = Ctx.createTempSymbol(); - Out.EmitLabel(Sym); + Out.emitLabel(Sym); const MCExpr *Base = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx); |