mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
[mips] Improve support for the .set at/noat assembler directives.
Summary: Made the following changes: Added calls to emitDirectiveSetNoAt() and emitDirectiveSetAt(). Added special emit function for .set at=$reg, emitDirectiveSetAtWithArg(unsigned RegNo). Improved parsing error checks for .set at. Refactored parser code for .set at. Improved testing of both directives. Improved code readability and comments. Reviewers: dsanders Reviewed By: dsanders Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D7176 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229097 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7ea33e53c7
commit
94b64060af
@ -3276,67 +3276,84 @@ bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
|
||||
bool MipsAsmParser::parseSetNoAtDirective() {
|
||||
MCAsmParser &Parser = getParser();
|
||||
// Line should look like: ".set noat".
|
||||
// set at reg to 0.
|
||||
|
||||
// Set the $at register to $0.
|
||||
AssemblerOptions.back()->setATReg(0);
|
||||
// eat noat
|
||||
Parser.Lex();
|
||||
|
||||
Parser.Lex(); // Eat "noat".
|
||||
|
||||
// If this is not the end of the statement, report an error.
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
reportParseError("unexpected token, expected end of statement");
|
||||
return false;
|
||||
}
|
||||
|
||||
getTargetStreamer().emitDirectiveSetNoAt();
|
||||
Parser.Lex(); // Consume the EndOfStatement.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::parseSetAtDirective() {
|
||||
// Line can be: ".set at", which sets $at to $1
|
||||
// or ".set at=$reg", which sets $at to $reg.
|
||||
MCAsmParser &Parser = getParser();
|
||||
// Line can be .set at - defaults to $1
|
||||
// or .set at=$reg
|
||||
int AtRegNo;
|
||||
getParser().Lex();
|
||||
Parser.Lex(); // Eat "at".
|
||||
|
||||
if (getLexer().is(AsmToken::EndOfStatement)) {
|
||||
// No register was specified, so we set $at to $1.
|
||||
AssemblerOptions.back()->setATReg(1);
|
||||
|
||||
getTargetStreamer().emitDirectiveSetAt();
|
||||
Parser.Lex(); // Consume the EndOfStatement.
|
||||
return false;
|
||||
} else if (getLexer().is(AsmToken::Equal)) {
|
||||
getParser().Lex(); // Eat the '='.
|
||||
if (getLexer().isNot(AsmToken::Dollar)) {
|
||||
}
|
||||
|
||||
if (getLexer().isNot(AsmToken::Equal)) {
|
||||
reportParseError("unexpected token, expected equals sign");
|
||||
return false;
|
||||
}
|
||||
Parser.Lex(); // Eat "=".
|
||||
|
||||
if (getLexer().isNot(AsmToken::Dollar)) {
|
||||
if (getLexer().is(AsmToken::EndOfStatement)) {
|
||||
reportParseError("no register specified");
|
||||
return false;
|
||||
} else {
|
||||
reportParseError("unexpected token, expected dollar sign '$'");
|
||||
return false;
|
||||
}
|
||||
Parser.Lex(); // Eat the '$'.
|
||||
const AsmToken &Reg = Parser.getTok();
|
||||
if (Reg.is(AsmToken::Identifier)) {
|
||||
AtRegNo = matchCPURegisterName(Reg.getIdentifier());
|
||||
} else if (Reg.is(AsmToken::Integer)) {
|
||||
AtRegNo = Reg.getIntVal();
|
||||
} else {
|
||||
reportParseError("unexpected token, expected identifier or integer");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Parser.Lex(); // Eat "$".
|
||||
|
||||
if (AtRegNo < 0 || AtRegNo > 31) {
|
||||
reportParseError("unexpected token in statement");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
|
||||
reportParseError("invalid register");
|
||||
return false;
|
||||
}
|
||||
getParser().Lex(); // Eat the register.
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
reportParseError("unexpected token, expected end of statement");
|
||||
return false;
|
||||
}
|
||||
Parser.Lex(); // Consume the EndOfStatement.
|
||||
return false;
|
||||
// Find out what "reg" is.
|
||||
unsigned AtRegNo;
|
||||
const AsmToken &Reg = Parser.getTok();
|
||||
if (Reg.is(AsmToken::Identifier)) {
|
||||
AtRegNo = matchCPURegisterName(Reg.getIdentifier());
|
||||
} else if (Reg.is(AsmToken::Integer)) {
|
||||
AtRegNo = Reg.getIntVal();
|
||||
} else {
|
||||
reportParseError("unexpected token in statement");
|
||||
reportParseError("unexpected token, expected identifier or integer");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if $reg is a valid register. If it is, set $at to $reg.
|
||||
if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
|
||||
reportParseError("invalid register");
|
||||
return false;
|
||||
}
|
||||
Parser.Lex(); // Eat "reg".
|
||||
|
||||
// If this is not the end of the statement, report an error.
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
reportParseError("unexpected token, expected end of statement");
|
||||
return false;
|
||||
}
|
||||
|
||||
getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
|
||||
|
||||
Parser.Lex(); // Consume the EndOfStatement.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::parseSetReorderDirective() {
|
||||
|
@ -43,6 +43,9 @@ void MipsTargetStreamer::emitDirectiveSetNoMacro() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetMsa() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetNoMsa() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
|
||||
forbidModuleDirective();
|
||||
}
|
||||
void MipsTargetStreamer::emitDirectiveSetNoAt() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {}
|
||||
void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {}
|
||||
@ -144,6 +147,11 @@ void MipsTargetAsmStreamer::emitDirectiveSetAt() {
|
||||
MipsTargetStreamer::emitDirectiveSetAt();
|
||||
}
|
||||
|
||||
void MipsTargetAsmStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
|
||||
OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
|
||||
MipsTargetStreamer::emitDirectiveSetAtWithArg(RegNo);
|
||||
}
|
||||
|
||||
void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
|
||||
OS << "\t.set\tnoat\n";
|
||||
MipsTargetStreamer::emitDirectiveSetNoAt();
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
virtual void emitDirectiveSetMsa();
|
||||
virtual void emitDirectiveSetNoMsa();
|
||||
virtual void emitDirectiveSetAt();
|
||||
virtual void emitDirectiveSetAtWithArg(unsigned RegNo);
|
||||
virtual void emitDirectiveSetNoAt();
|
||||
virtual void emitDirectiveEnd(StringRef Name);
|
||||
|
||||
@ -145,6 +146,7 @@ public:
|
||||
void emitDirectiveSetMsa() override;
|
||||
void emitDirectiveSetNoMsa() override;
|
||||
void emitDirectiveSetAt() override;
|
||||
void emitDirectiveSetAtWithArg(unsigned RegNo) override;
|
||||
void emitDirectiveSetNoAt() override;
|
||||
void emitDirectiveEnd(StringRef Name) override;
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
# CHECK: lui $1, 1
|
||||
# CHECK: addu $1, $1, $2
|
||||
# CHECK: lw $2, 0($1)
|
||||
# CHECK-LABEL: test2:
|
||||
# CHECK: .set noat
|
||||
test1:
|
||||
lw $2, 65536($2)
|
||||
|
||||
@ -20,6 +22,8 @@ test2:
|
||||
# CHECK: lui $1, 1
|
||||
# CHECK: addu $1, $1, $2
|
||||
# CHECK: lw $2, 0($1)
|
||||
# CHECK-LABEL: test4:
|
||||
# CHECK: .set at=$0
|
||||
test3:
|
||||
.set at
|
||||
lw $2, 65536($2)
|
||||
|
@ -15,6 +15,16 @@ foo:
|
||||
# WARNINGS: :[[@LINE+2]]:11: warning: used $at without ".set noat"
|
||||
.set at=$1
|
||||
jr $1
|
||||
|
||||
# CHECK: jr $1 # encoding: [0x08,0x00,0x20,0x00]
|
||||
# WARNINGS: :[[@LINE+2]]:11: warning: used $at without ".set noat"
|
||||
.set at=$at
|
||||
jr $at
|
||||
|
||||
# CHECK: jr $1 # encoding: [0x08,0x00,0x20,0x00]
|
||||
# WARNINGS: :[[@LINE+2]]:11: warning: used $at without ".set noat"
|
||||
.set at=$at
|
||||
jr $1
|
||||
# WARNINGS-NOT: warning: used $at without ".set noat"
|
||||
|
||||
# CHECK: jr $1 # encoding: [0x08,0x00,0x20,0x00]
|
||||
|
@ -4,156 +4,187 @@
|
||||
# for ".set at" and set the correct value.
|
||||
.text
|
||||
foo:
|
||||
# CHECK: .set at=$1
|
||||
# CHECK: lui $1, 1
|
||||
# CHECK: addu $1, $1, $2
|
||||
# CHECK: lw $2, 0($1)
|
||||
.set at=$1
|
||||
lw $2, 65536($2)
|
||||
# CHECK: .set at=$2
|
||||
# CHECK: lui $2, 1
|
||||
# CHECK: addu $2, $2, $1
|
||||
# CHECK: lw $1, 0($2)
|
||||
.set at=$2
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$3
|
||||
# CHECK: lui $3, 1
|
||||
# CHECK: addu $3, $3, $1
|
||||
# CHECK: lw $1, 0($3)
|
||||
.set at=$3
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$4
|
||||
# CHECK: lui $4, 1
|
||||
# CHECK: addu $4, $4, $1
|
||||
# CHECK: lw $1, 0($4)
|
||||
.set at=$a0
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$5
|
||||
# CHECK: lui $5, 1
|
||||
# CHECK: addu $5, $5, $1
|
||||
# CHECK: lw $1, 0($5)
|
||||
.set at=$a1
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$6
|
||||
# CHECK: lui $6, 1
|
||||
# CHECK: addu $6, $6, $1
|
||||
# CHECK: lw $1, 0($6)
|
||||
.set at=$a2
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$7
|
||||
# CHECK: lui $7, 1
|
||||
# CHECK: addu $7, $7, $1
|
||||
# CHECK: lw $1, 0($7)
|
||||
.set at=$a3
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$8
|
||||
# CHECK: lui $8, 1
|
||||
# CHECK: addu $8, $8, $1
|
||||
# CHECK: lw $1, 0($8)
|
||||
.set at=$8
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$9
|
||||
# CHECK: lui $9, 1
|
||||
# CHECK: addu $9, $9, $1
|
||||
# CHECK: lw $1, 0($9)
|
||||
.set at=$9
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$10
|
||||
# CHECK: lui $10, 1
|
||||
# CHECK: addu $10, $10, $1
|
||||
# CHECK: lw $1, 0($10)
|
||||
.set at=$10
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$11
|
||||
# CHECK: lui $11, 1
|
||||
# CHECK: addu $11, $11, $1
|
||||
# CHECK: lw $1, 0($11)
|
||||
.set at=$11
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$12
|
||||
# CHECK: lui $12, 1
|
||||
# CHECK: addu $12, $12, $1
|
||||
# CHECK: lw $1, 0($12)
|
||||
.set at=$12
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$13
|
||||
# CHECK: lui $13, 1
|
||||
# CHECK: addu $13, $13, $1
|
||||
# CHECK: lw $1, 0($13)
|
||||
.set at=$13
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$14
|
||||
# CHECK: lui $14, 1
|
||||
# CHECK: addu $14, $14, $1
|
||||
# CHECK: lw $1, 0($14)
|
||||
.set at=$14
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$15
|
||||
# CHECK: lui $15, 1
|
||||
# CHECK: addu $15, $15, $1
|
||||
# CHECK: lw $1, 0($15)
|
||||
.set at=$15
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$16
|
||||
# CHECK: lui $16, 1
|
||||
# CHECK: addu $16, $16, $1
|
||||
# CHECK: lw $1, 0($16)
|
||||
.set at=$s0
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$17
|
||||
# CHECK: lui $17, 1
|
||||
# CHECK: addu $17, $17, $1
|
||||
# CHECK: lw $1, 0($17)
|
||||
.set at=$s1
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$18
|
||||
# CHECK: lui $18, 1
|
||||
# CHECK: addu $18, $18, $1
|
||||
# CHECK: lw $1, 0($18)
|
||||
.set at=$s2
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$19
|
||||
# CHECK: lui $19, 1
|
||||
# CHECK: addu $19, $19, $1
|
||||
# CHECK: lw $1, 0($19)
|
||||
.set at=$s3
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$20
|
||||
# CHECK: lui $20, 1
|
||||
# CHECK: addu $20, $20, $1
|
||||
# CHECK: lw $1, 0($20)
|
||||
.set at=$s4
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$21
|
||||
# CHECK: lui $21, 1
|
||||
# CHECK: addu $21, $21, $1
|
||||
# CHECK: lw $1, 0($21)
|
||||
.set at=$s5
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$22
|
||||
# CHECK: lui $22, 1
|
||||
# CHECK: addu $22, $22, $1
|
||||
# CHECK: lw $1, 0($22)
|
||||
.set at=$s6
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$23
|
||||
# CHECK: lui $23, 1
|
||||
# CHECK: addu $23, $23, $1
|
||||
# CHECK: lw $1, 0($23)
|
||||
.set at=$s7
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$24
|
||||
# CHECK: lui $24, 1
|
||||
# CHECK: addu $24, $24, $1
|
||||
# CHECK: lw $1, 0($24)
|
||||
.set at=$24
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$25
|
||||
# CHECK: lui $25, 1
|
||||
# CHECK: addu $25, $25, $1
|
||||
# CHECK: lw $1, 0($25)
|
||||
.set at=$25
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$26
|
||||
# CHECK: lui $26, 1
|
||||
# CHECK: addu $26, $26, $1
|
||||
# CHECK: lw $1, 0($26)
|
||||
.set at=$26
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$27
|
||||
# CHECK: lui $27, 1
|
||||
# CHECK: addu $27, $27, $1
|
||||
# CHECK: lw $1, 0($27)
|
||||
.set at=$27
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$28
|
||||
# CHECK: lui $gp, 1
|
||||
# CHECK: addu $gp, $gp, $1
|
||||
# CHECK: lw $1, 0($gp)
|
||||
.set at=$gp
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$30
|
||||
# CHECK: lui $fp, 1
|
||||
# CHECK: addu $fp, $fp, $1
|
||||
# CHECK: lw $1, 0($fp)
|
||||
.set at=$fp
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$29
|
||||
# CHECK: lui $sp, 1
|
||||
# CHECK: addu $sp, $sp, $1
|
||||
# CHECK: lw $1, 0($sp)
|
||||
.set at=$sp
|
||||
lw $1, 65536($1)
|
||||
# CHECK: .set at=$31
|
||||
# CHECK: lui $ra, 1
|
||||
# CHECK: addu $ra, $ra, $1
|
||||
# CHECK: lw $1, 0($ra)
|
||||
|
29
test/MC/Mips/set-at-noat-bad-syntax.s
Normal file
29
test/MC/Mips/set-at-noat-bad-syntax.s
Normal file
@ -0,0 +1,29 @@
|
||||
# RUN: not llvm-mc %s -triple=mips-unknown-unknown -mcpu=mips32 2>%t1
|
||||
# RUN: FileCheck %s < %t1
|
||||
|
||||
.set at~
|
||||
# CHECK: error: unexpected token, expected equals sign
|
||||
|
||||
.set at=
|
||||
# CHECK: error: no register specified
|
||||
|
||||
.set at=~
|
||||
# CHECK: error: unexpected token, expected dollar sign '$'
|
||||
|
||||
.set at=$
|
||||
# CHECK: error: unexpected token, expected identifier or integer
|
||||
|
||||
.set at=$-4
|
||||
# CHECK: error: unexpected token, expected identifier or integer
|
||||
|
||||
.set at=$1000
|
||||
# CHECK: error: invalid register
|
||||
|
||||
.set at=$foo
|
||||
# CHECK: error: invalid register
|
||||
|
||||
.set at=$2bar
|
||||
# CHECK: error: unexpected token, expected end of statement
|
||||
|
||||
.set noat bar
|
||||
# CHECK: error: unexpected token, expected end of statement
|
Loading…
Reference in New Issue
Block a user