mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 21:00:29 +00:00
[SystemZ] Improve AsmParser handling of invalid instructions
Previously, an invalid instruction like: foo %r1, %r0 would generate the rather odd error message: ....: error: unknown token in expression foo %r1, %r0 ^ We now get the more informative: ....: error: invalid instruction foo %r1, %r0 ^ The same would happen if an address were used where a register was expected. We now get "invalid operand for instruction" instead. llvm-svn: 182644
This commit is contained in:
parent
8adb53208b
commit
1fe54d3978
@ -44,6 +44,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum OperandKind {
|
enum OperandKind {
|
||||||
|
KindInvalid,
|
||||||
KindToken,
|
KindToken,
|
||||||
KindReg,
|
KindReg,
|
||||||
KindAccessReg,
|
KindAccessReg,
|
||||||
@ -108,6 +109,9 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Create particular kinds of operand.
|
// Create particular kinds of operand.
|
||||||
|
static SystemZOperand *createInvalid(SMLoc StartLoc, SMLoc EndLoc) {
|
||||||
|
return new SystemZOperand(KindInvalid, StartLoc, EndLoc);
|
||||||
|
}
|
||||||
static SystemZOperand *createToken(StringRef Str, SMLoc Loc) {
|
static SystemZOperand *createToken(StringRef Str, SMLoc Loc) {
|
||||||
SystemZOperand *Op = new SystemZOperand(KindToken, Loc, Loc);
|
SystemZOperand *Op = new SystemZOperand(KindToken, Loc, Loc);
|
||||||
Op->Token.Data = Str.data();
|
Op->Token.Data = Str.data();
|
||||||
@ -279,9 +283,8 @@ private:
|
|||||||
|
|
||||||
bool parseRegister(Register &Reg);
|
bool parseRegister(Register &Reg);
|
||||||
|
|
||||||
OperandMatchResultTy
|
bool parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
|
||||||
parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
|
bool IsAddress = false);
|
||||||
bool IsAddress = false);
|
|
||||||
|
|
||||||
OperandMatchResultTy
|
OperandMatchResultTy
|
||||||
parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
@ -289,6 +292,11 @@ private:
|
|||||||
SystemZOperand::RegisterKind Kind,
|
SystemZOperand::RegisterKind Kind,
|
||||||
bool IsAddress = false);
|
bool IsAddress = false);
|
||||||
|
|
||||||
|
bool parseAddress(unsigned &Base, const MCExpr *&Disp,
|
||||||
|
unsigned &Index, const unsigned *Regs,
|
||||||
|
SystemZOperand::RegisterKind RegKind,
|
||||||
|
bool HasIndex);
|
||||||
|
|
||||||
OperandMatchResultTy
|
OperandMatchResultTy
|
||||||
parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
const unsigned *Regs, SystemZOperand::RegisterKind RegKind,
|
const unsigned *Regs, SystemZOperand::RegisterKind RegKind,
|
||||||
@ -411,22 +419,22 @@ bool SystemZAsmParser::parseRegister(Register &Reg) {
|
|||||||
|
|
||||||
// Eat the % prefix.
|
// Eat the % prefix.
|
||||||
if (Parser.getTok().isNot(AsmToken::Percent))
|
if (Parser.getTok().isNot(AsmToken::Percent))
|
||||||
return true;
|
return Error(Parser.getTok().getLoc(), "register expected");
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
// Expect a register name.
|
// Expect a register name.
|
||||||
if (Parser.getTok().isNot(AsmToken::Identifier))
|
if (Parser.getTok().isNot(AsmToken::Identifier))
|
||||||
return true;
|
return Error(Reg.StartLoc, "invalid register");
|
||||||
|
|
||||||
// Check that there's a prefix.
|
// Check that there's a prefix.
|
||||||
StringRef Name = Parser.getTok().getString();
|
StringRef Name = Parser.getTok().getString();
|
||||||
if (Name.size() < 2)
|
if (Name.size() < 2)
|
||||||
return true;
|
return Error(Reg.StartLoc, "invalid register");
|
||||||
char Prefix = Name[0];
|
char Prefix = Name[0];
|
||||||
|
|
||||||
// Treat the rest of the register name as a register number.
|
// 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))
|
||||||
return true;
|
return Error(Reg.StartLoc, "invalid register");
|
||||||
|
|
||||||
// Look for valid combinations of prefix and number.
|
// Look for valid combinations of prefix and number.
|
||||||
if (Prefix == 'r' && Reg.Num < 16)
|
if (Prefix == 'r' && Reg.Num < 16)
|
||||||
@ -436,7 +444,7 @@ bool SystemZAsmParser::parseRegister(Register &Reg) {
|
|||||||
else if (Prefix == 'a' && Reg.Num < 16)
|
else if (Prefix == 'a' && Reg.Num < 16)
|
||||||
Reg.Group = RegAccess;
|
Reg.Group = RegAccess;
|
||||||
else
|
else
|
||||||
return true;
|
return Error(Reg.StartLoc, "invalid register");
|
||||||
|
|
||||||
Reg.EndLoc = Parser.getTok().getLoc();
|
Reg.EndLoc = Parser.getTok().getLoc();
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
@ -447,30 +455,19 @@ bool SystemZAsmParser::parseRegister(Register &Reg) {
|
|||||||
// the raw register number to LLVM numbering, with zero entries indicating
|
// the raw register number to LLVM numbering, with zero entries indicating
|
||||||
// an invalid register. IsAddress says whether the register appears in an
|
// an invalid register. IsAddress says whether the register appears in an
|
||||||
// address context.
|
// address context.
|
||||||
SystemZAsmParser::OperandMatchResultTy
|
bool SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
|
||||||
SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
|
const unsigned *Regs, bool IsAddress) {
|
||||||
const unsigned *Regs, bool IsAddress) {
|
if (parseRegister(Reg))
|
||||||
if (Parser.getTok().isNot(AsmToken::Percent))
|
return true;
|
||||||
return MatchOperand_NoMatch;
|
if (Reg.Group != Group)
|
||||||
if (parseRegister(Reg)) {
|
return Error(Reg.StartLoc, "invalid operand for instruction");
|
||||||
Error(Reg.StartLoc, "invalid register");
|
if (Regs && Regs[Reg.Num] == 0)
|
||||||
return MatchOperand_ParseFail;
|
return Error(Reg.StartLoc, "invalid register pair");
|
||||||
}
|
if (Reg.Num == 0 && IsAddress)
|
||||||
if (Reg.Group != Group) {
|
return Error(Reg.StartLoc, "%r0 used in an address");
|
||||||
Error(Reg.StartLoc, "invalid operand for instruction");
|
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
}
|
|
||||||
if (Regs && Regs[Reg.Num] == 0) {
|
|
||||||
Error(Reg.StartLoc, "invalid register pair");
|
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
}
|
|
||||||
if (Reg.Num == 0 && IsAddress) {
|
|
||||||
Error(Reg.StartLoc, "%r0 used in an address");
|
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
}
|
|
||||||
if (Regs)
|
if (Regs)
|
||||||
Reg.Num = Regs[Reg.Num];
|
Reg.Num = Regs[Reg.Num];
|
||||||
return MatchOperand_Success;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a register and add it to Operands. The other arguments are as above.
|
// Parse a register and add it to Operands. The other arguments are as above.
|
||||||
@ -479,64 +476,75 @@ SystemZAsmParser::parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
|||||||
RegisterGroup Group, const unsigned *Regs,
|
RegisterGroup Group, const unsigned *Regs,
|
||||||
SystemZOperand::RegisterKind Kind,
|
SystemZOperand::RegisterKind Kind,
|
||||||
bool IsAddress) {
|
bool IsAddress) {
|
||||||
Register Reg;
|
if (Parser.getTok().isNot(AsmToken::Percent))
|
||||||
OperandMatchResultTy Result = parseRegister(Reg, Group, Regs, IsAddress);
|
|
||||||
if (Result == MatchOperand_Success)
|
|
||||||
Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
|
|
||||||
Reg.StartLoc, Reg.EndLoc));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse a memory operand and add it to Operands. Regs maps asm register
|
|
||||||
// numbers to LLVM address registers and RegKind says what kind of address
|
|
||||||
// register we're using (ADDR32Reg or ADDR64Reg). HasIndex says whether
|
|
||||||
// the address allows index registers.
|
|
||||||
SystemZAsmParser::OperandMatchResultTy
|
|
||||||
SystemZAsmParser::parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
|
||||||
const unsigned *Regs,
|
|
||||||
SystemZOperand::RegisterKind RegKind,
|
|
||||||
bool HasIndex) {
|
|
||||||
SMLoc StartLoc = Parser.getTok().getLoc();
|
|
||||||
|
|
||||||
// Parse the displacement, which must always be present.
|
|
||||||
const MCExpr *Disp;
|
|
||||||
if (getParser().parseExpression(Disp))
|
|
||||||
return MatchOperand_NoMatch;
|
return MatchOperand_NoMatch;
|
||||||
|
|
||||||
|
Register Reg;
|
||||||
|
if (parseRegister(Reg, Group, Regs, IsAddress))
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
|
||||||
|
Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
|
||||||
|
Reg.StartLoc, Reg.EndLoc));
|
||||||
|
return MatchOperand_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse a memory operand into Base, Disp and Index. Regs maps asm
|
||||||
|
// register numbers to LLVM register numbers and RegKind says what kind
|
||||||
|
// of address register we're using (ADDR32Reg or ADDR64Reg). HasIndex
|
||||||
|
// says whether the address allows index registers.
|
||||||
|
bool SystemZAsmParser::parseAddress(unsigned &Base, const MCExpr *&Disp,
|
||||||
|
unsigned &Index, const unsigned *Regs,
|
||||||
|
SystemZOperand::RegisterKind RegKind,
|
||||||
|
bool HasIndex) {
|
||||||
|
// Parse the displacement, which must always be present.
|
||||||
|
if (getParser().parseExpression(Disp))
|
||||||
|
return true;
|
||||||
|
|
||||||
// Parse the optional base and index.
|
// Parse the optional base and index.
|
||||||
unsigned Index = 0;
|
Index = 0;
|
||||||
unsigned Base = 0;
|
Base = 0;
|
||||||
if (getLexer().is(AsmToken::LParen)) {
|
if (getLexer().is(AsmToken::LParen)) {
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
// Parse the first register.
|
// Parse the first register.
|
||||||
Register Reg;
|
Register Reg;
|
||||||
OperandMatchResultTy Result = parseRegister(Reg, RegGR, Regs, true);
|
if (parseRegister(Reg, RegGR, Regs, RegKind))
|
||||||
if (Result != MatchOperand_Success)
|
return true;
|
||||||
return Result;
|
|
||||||
|
|
||||||
// Check whether there's a second register. If so, the one that we
|
// Check whether there's a second register. If so, the one that we
|
||||||
// just parsed was the index.
|
// just parsed was the index.
|
||||||
if (getLexer().is(AsmToken::Comma)) {
|
if (getLexer().is(AsmToken::Comma)) {
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
if (!HasIndex) {
|
if (!HasIndex)
|
||||||
Error(Reg.StartLoc, "invalid use of indexed addressing");
|
return Error(Reg.StartLoc, "invalid use of indexed addressing");
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
}
|
|
||||||
|
|
||||||
Index = Reg.Num;
|
Index = Reg.Num;
|
||||||
Result = parseRegister(Reg, RegGR, Regs, true);
|
if (parseRegister(Reg, RegGR, Regs, RegKind))
|
||||||
if (Result != MatchOperand_Success)
|
return true;
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
Base = Reg.Num;
|
Base = Reg.Num;
|
||||||
|
|
||||||
// Consume the closing bracket.
|
// Consume the closing bracket.
|
||||||
if (getLexer().isNot(AsmToken::RParen))
|
if (getLexer().isNot(AsmToken::RParen))
|
||||||
return MatchOperand_NoMatch;
|
return Error(Parser.getTok().getLoc(), "unexpected token in address");
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse a memory operand and add it to Operands. The other arguments
|
||||||
|
// are as above.
|
||||||
|
SystemZAsmParser::OperandMatchResultTy
|
||||||
|
SystemZAsmParser::parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
|
const unsigned *Regs,
|
||||||
|
SystemZOperand::RegisterKind RegKind,
|
||||||
|
bool HasIndex) {
|
||||||
|
SMLoc StartLoc = Parser.getTok().getLoc();
|
||||||
|
unsigned Base, Index;
|
||||||
|
const MCExpr *Disp;
|
||||||
|
if (parseAddress(Base, Disp, Index, Regs, RegKind, HasIndex))
|
||||||
|
return MatchOperand_ParseFail;
|
||||||
|
|
||||||
SMLoc EndLoc =
|
SMLoc EndLoc =
|
||||||
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
||||||
@ -551,11 +559,9 @@ bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
|
|||||||
|
|
||||||
bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
|
bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
|
||||||
SMLoc &EndLoc) {
|
SMLoc &EndLoc) {
|
||||||
if (Parser.getTok().isNot(AsmToken::Percent))
|
|
||||||
return Error(Parser.getTok().getLoc(), "register expected");
|
|
||||||
Register Reg;
|
Register Reg;
|
||||||
if (parseRegister(Reg))
|
if (parseRegister(Reg))
|
||||||
return Error(Reg.StartLoc, "invalid register");
|
return true;
|
||||||
if (Reg.Group == RegGR)
|
if (Reg.Group == RegGR)
|
||||||
RegNo = SystemZMC::GR64Regs[Reg.Num];
|
RegNo = SystemZMC::GR64Regs[Reg.Num];
|
||||||
else if (Reg.Group == RegFP)
|
else if (Reg.Group == RegFP)
|
||||||
@ -616,15 +622,34 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
|||||||
if (ResTy == MatchOperand_ParseFail)
|
if (ResTy == MatchOperand_ParseFail)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// The only other type of operand is an immediate.
|
// Check for a register. All real register operands should have used
|
||||||
const MCExpr *Expr;
|
// a context-dependent parse routine, which gives the required register
|
||||||
|
// class. The code is here to mop up other cases, like those where
|
||||||
|
// the instruction isn't recognized.
|
||||||
|
if (Parser.getTok().is(AsmToken::Percent)) {
|
||||||
|
Register Reg;
|
||||||
|
if (parseRegister(Reg))
|
||||||
|
return true;
|
||||||
|
Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The only other type of operand is an immediate or address. As above,
|
||||||
|
// real address operands should have used a context-dependent parse routine,
|
||||||
|
// so we treat any plain expression as an immediate.
|
||||||
SMLoc StartLoc = Parser.getTok().getLoc();
|
SMLoc StartLoc = Parser.getTok().getLoc();
|
||||||
if (getParser().parseExpression(Expr))
|
unsigned Base, Index;
|
||||||
|
const MCExpr *Expr;
|
||||||
|
if (parseAddress(Base, Expr, Index, SystemZMC::GR64Regs,
|
||||||
|
SystemZOperand::ADDR64Reg, true))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
SMLoc EndLoc =
|
SMLoc EndLoc =
|
||||||
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
||||||
Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
|
if (Base || Index)
|
||||||
|
Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
|
||||||
|
else
|
||||||
|
Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,13 +708,17 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
|
|
||||||
SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
|
SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
|
||||||
parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
|
if (Parser.getTok().isNot(AsmToken::Percent))
|
||||||
|
return MatchOperand_NoMatch;
|
||||||
|
|
||||||
Register Reg;
|
Register Reg;
|
||||||
OperandMatchResultTy Result = parseRegister(Reg, RegAccess, 0);
|
if (parseRegister(Reg, RegAccess, 0))
|
||||||
if (Result == MatchOperand_Success)
|
return MatchOperand_ParseFail;
|
||||||
Operands.push_back(SystemZOperand::createAccessReg(Reg.Num,
|
|
||||||
Reg.StartLoc,
|
Operands.push_back(SystemZOperand::createAccessReg(Reg.Num,
|
||||||
Reg.EndLoc));
|
Reg.StartLoc,
|
||||||
return Result;
|
Reg.EndLoc));
|
||||||
|
return MatchOperand_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
|
SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#CHECK: lr %r0,%a1
|
#CHECK: lr %r0,%a1
|
||||||
#CHECK: error: invalid operand for instruction
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: lr %r0,0
|
#CHECK: lr %r0,0
|
||||||
#CHECK: error: unexpected token in argument list
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: lr %r0,0(%r1)
|
#CHECK: lr %r0,0(%r1)
|
||||||
|
|
||||||
lr %f0,%r1
|
lr %f0,%r1
|
||||||
@ -35,7 +35,7 @@
|
|||||||
#CHECK: lgr %r0,%a1
|
#CHECK: lgr %r0,%a1
|
||||||
#CHECK: error: invalid operand for instruction
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: lgr %r0,0
|
#CHECK: lgr %r0,0
|
||||||
#CHECK: error: unexpected token in argument list
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: lgr %r0,0(%r1)
|
#CHECK: lgr %r0,0(%r1)
|
||||||
|
|
||||||
lgr %f0,%r1
|
lgr %f0,%r1
|
||||||
@ -73,7 +73,7 @@
|
|||||||
#CHECK: dlr %r0,%a1
|
#CHECK: dlr %r0,%a1
|
||||||
#CHECK: error: invalid operand for instruction
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: dlr %r0,0
|
#CHECK: dlr %r0,0
|
||||||
#CHECK: error: unexpected token in argument list
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: dlr %r0,0(%r1)
|
#CHECK: dlr %r0,0(%r1)
|
||||||
|
|
||||||
dlr %r1,%r0
|
dlr %r1,%r0
|
||||||
@ -103,7 +103,7 @@
|
|||||||
#CHECK: ler %f0,%a1
|
#CHECK: ler %f0,%a1
|
||||||
#CHECK: error: invalid operand for instruction
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: ler %f0,0
|
#CHECK: ler %f0,0
|
||||||
#CHECK: error: unexpected token in argument list
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: ler %f0,0(%r1)
|
#CHECK: ler %f0,0(%r1)
|
||||||
|
|
||||||
ler %r0,%f1
|
ler %r0,%f1
|
||||||
@ -125,7 +125,7 @@
|
|||||||
#CHECK: ldr %f0,%a1
|
#CHECK: ldr %f0,%a1
|
||||||
#CHECK: error: invalid operand for instruction
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: ldr %f0,0
|
#CHECK: ldr %f0,0
|
||||||
#CHECK: error: unexpected token in argument list
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: ldr %f0,0(%r1)
|
#CHECK: ldr %f0,0(%r1)
|
||||||
|
|
||||||
ldr %r0,%f1
|
ldr %r0,%f1
|
||||||
@ -163,7 +163,7 @@
|
|||||||
#CHECK: lxr %f0,%a1
|
#CHECK: lxr %f0,%a1
|
||||||
#CHECK: error: invalid operand for instruction
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: lxr %f0,0
|
#CHECK: lxr %f0,0
|
||||||
#CHECK: error: unexpected token in argument list
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: lxr %f0,0(%r1)
|
#CHECK: lxr %f0,0(%r1)
|
||||||
|
|
||||||
lxr %f2,%f0
|
lxr %f2,%f0
|
||||||
@ -189,7 +189,7 @@
|
|||||||
#CHECK: ear %r0,%f0
|
#CHECK: ear %r0,%f0
|
||||||
#CHECK: error: invalid operand for instruction
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: ear %r0,0
|
#CHECK: ear %r0,0
|
||||||
#CHECK: error: unexpected token in argument list
|
#CHECK: error: invalid operand for instruction
|
||||||
#CHECK: ear %r0,0(%r1)
|
#CHECK: ear %r0,0(%r1)
|
||||||
|
|
||||||
ear %r0,%r0
|
ear %r0,%r0
|
||||||
|
70
test/MC/SystemZ/tokens.s
Normal file
70
test/MC/SystemZ/tokens.s
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# RUN: not llvm-mc -triple s390x-linux-gnu < %s 2> %t
|
||||||
|
# RUN: FileCheck < %t %s
|
||||||
|
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo 100, 200
|
||||||
|
#CHECK: error: register expected
|
||||||
|
#CHECK: foo 100(, 200
|
||||||
|
#CHECK: error: register expected
|
||||||
|
#CHECK: foo 100(0), 200
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: foo 100(%a0), 200
|
||||||
|
#CHECK: error: %r0 used in an address
|
||||||
|
#CHECK: foo 100(%r0), 200
|
||||||
|
#CHECK: error: invalid operand
|
||||||
|
#CHECK: foo 100(%r1,%a0), 200
|
||||||
|
#CHECK: error: %r0 used in an address
|
||||||
|
#CHECK: foo 100(%r1,%r0), 200
|
||||||
|
#CHECK: error: unexpected token in address
|
||||||
|
#CHECK: foo 100(%r1,%r2, 200
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo 100(%r1,%r2), 200
|
||||||
|
#CHECK: error: unexpected token in argument list
|
||||||
|
#CHECK: foo 100(%r1,%r2)(, 200
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo %r0, 200
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo %r15, 200
|
||||||
|
#CHECK: error: invalid register
|
||||||
|
#CHECK: foo %r16, 200
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo %f0, 200
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo %f15, 200
|
||||||
|
#CHECK: error: invalid register
|
||||||
|
#CHECK: foo %f16, 200
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo %a0, 200
|
||||||
|
#CHECK: error: invalid instruction
|
||||||
|
#CHECK: foo %a15, 200
|
||||||
|
#CHECK: error: invalid register
|
||||||
|
#CHECK: foo %a16, 200
|
||||||
|
#CHECK: error: invalid register
|
||||||
|
#CHECK: foo %c, 200
|
||||||
|
#CHECK: error: invalid register
|
||||||
|
#CHECK: foo %, 200
|
||||||
|
#CHECK: error: unknown token in expression
|
||||||
|
#CHECK: foo {, 200
|
||||||
|
|
||||||
|
foo 100, 200
|
||||||
|
foo 100(, 200
|
||||||
|
foo 100(0), 200
|
||||||
|
foo 100(%a0), 200
|
||||||
|
foo 100(%r0), 200
|
||||||
|
foo 100(%r1,%a0), 200
|
||||||
|
foo 100(%r1,%r0), 200
|
||||||
|
foo 100(%r1,%r2, 200
|
||||||
|
foo 100(%r1,%r2), 200
|
||||||
|
foo 100(%r1,%r2)(, 200
|
||||||
|
foo %r0, 200
|
||||||
|
foo %r15, 200
|
||||||
|
foo %r16, 200
|
||||||
|
foo %f0, 200
|
||||||
|
foo %f15, 200
|
||||||
|
foo %f16, 200
|
||||||
|
foo %a0, 200
|
||||||
|
foo %a15, 200
|
||||||
|
foo %a16, 200
|
||||||
|
foo %c, 200
|
||||||
|
foo %, 200
|
||||||
|
foo {, 200
|
Loading…
Reference in New Issue
Block a user