mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[mips] Implement .cpadd directive
This directive inserts code to add $gp to the argument's register when support for position independent code is enabled. For example, this code: .cpadd $4 expands to: addu $4, $4, $gp
This commit is contained in:
parent
d2c968e63d
commit
01b3e42958
@ -361,6 +361,7 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
bool parseSetArchDirective();
|
||||
bool parseSetFeature(uint64_t Feature);
|
||||
bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
|
||||
bool parseDirectiveCpAdd(SMLoc Loc);
|
||||
bool parseDirectiveCpLoad(SMLoc Loc);
|
||||
bool parseDirectiveCpLocal(SMLoc Loc);
|
||||
bool parseDirectiveCpRestore(SMLoc Loc);
|
||||
@ -7632,6 +7633,31 @@ bool MipsAsmParser::isPicAndNotNxxAbi() {
|
||||
return inPicMode() && !(isABI_N32() || isABI_N64());
|
||||
}
|
||||
|
||||
bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
|
||||
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
|
||||
OperandMatchResultTy ResTy = parseAnyRegister(Reg);
|
||||
if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
|
||||
reportParseError("expected register");
|
||||
return false;
|
||||
}
|
||||
|
||||
MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
|
||||
if (!RegOpnd.isGPRAsmReg()) {
|
||||
reportParseError(RegOpnd.getStartLoc(), "invalid register");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
getParser().Lex(); // Consume the EndOfStatement.
|
||||
|
||||
getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
|
||||
if (AssemblerOptions.back()->isReorder())
|
||||
Warning(Loc, ".cpload should be inside a noreorder section");
|
||||
@ -8544,6 +8570,10 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
StringRef IDVal = DirectiveID.getString();
|
||||
|
||||
if (IDVal == ".cpadd") {
|
||||
parseDirectiveCpAdd(DirectiveID.getLoc());
|
||||
return false;
|
||||
}
|
||||
if (IDVal == ".cpload") {
|
||||
parseDirectiveCpLoad(DirectiveID.getLoc());
|
||||
return false;
|
||||
|
@ -111,6 +111,7 @@ void MipsTargetStreamer::emitDirectiveSetDspr2() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetMips3D() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetNoMips3D() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveCpAdd(unsigned RegNo) {}
|
||||
void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
|
||||
void MipsTargetStreamer::emitDirectiveCpLocal(unsigned RegNo) {
|
||||
// .cplocal $reg
|
||||
@ -662,6 +663,12 @@ void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
|
||||
OS << "," << FPUTopSavedRegOff << '\n';
|
||||
}
|
||||
|
||||
void MipsTargetAsmStreamer::emitDirectiveCpAdd(unsigned RegNo) {
|
||||
OS << "\t.cpadd\t$"
|
||||
<< StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
|
||||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) {
|
||||
OS << "\t.cpload\t$"
|
||||
<< StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
|
||||
@ -1120,6 +1127,17 @@ void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
|
||||
FPROffset = FPUTopSavedRegOff;
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDirectiveCpAdd(unsigned RegNo) {
|
||||
// .cpadd $reg
|
||||
// This directive inserts code to add $gp to the argument's register
|
||||
// when support for position independent code is enabled.
|
||||
if (!Pic)
|
||||
return;
|
||||
|
||||
emitAddu(RegNo, RegNo, GPReg, getABI().IsN64(), &STI);
|
||||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
|
||||
// .cpload $reg
|
||||
// This directive expands to:
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
virtual void emitDirectiveSetHardFloat();
|
||||
|
||||
// PIC support
|
||||
virtual void emitDirectiveCpAdd(unsigned RegNo);
|
||||
virtual void emitDirectiveCpLoad(unsigned RegNo);
|
||||
virtual void emitDirectiveCpLocal(unsigned RegNo);
|
||||
virtual bool emitDirectiveCpRestore(int Offset,
|
||||
@ -273,6 +274,7 @@ public:
|
||||
void emitDirectiveSetHardFloat() override;
|
||||
|
||||
// PIC support
|
||||
void emitDirectiveCpAdd(unsigned RegNo) override;
|
||||
void emitDirectiveCpLoad(unsigned RegNo) override;
|
||||
void emitDirectiveCpLocal(unsigned RegNo) override;
|
||||
|
||||
@ -345,6 +347,7 @@ public:
|
||||
void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override;
|
||||
|
||||
// PIC support
|
||||
void emitDirectiveCpAdd(unsigned RegNo) override;
|
||||
void emitDirectiveCpLoad(unsigned RegNo) override;
|
||||
void emitDirectiveCpLocal(unsigned RegNo) override;
|
||||
bool emitDirectiveCpRestore(int Offset, function_ref<unsigned()> GetATReg,
|
||||
|
13
test/MC/Mips/cpadd-bad.s
Normal file
13
test/MC/Mips/cpadd-bad.s
Normal file
@ -0,0 +1,13 @@
|
||||
# RUN: not llvm-mc -triple=mips-unknown-linux-gnu %s 2>&1 | FileCheck %s
|
||||
# RUN: not llvm-mc -triple=mips64-unknown-linux-gnuabin32 %s 2>&1 | FileCheck %s
|
||||
# RUN: not llvm-mc -triple=mips64-unknown-linux-gnu %s 2>&1 | FileCheck %s
|
||||
|
||||
.text
|
||||
.cpadd $32
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: invalid register
|
||||
.cpadd $foo
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected register
|
||||
.cpadd bar
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected register
|
||||
.cpadd $25 foobar
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected token, expected end of statement
|
29
test/MC/Mips/cpadd.s
Normal file
29
test/MC/Mips/cpadd.s
Normal file
@ -0,0 +1,29 @@
|
||||
# RUN: llvm-mc -triple=mips-unknown-linux-gnu -position-independent %s \
|
||||
# RUN: | FileCheck -check-prefix=ASM %s
|
||||
# RUN: llvm-mc -triple=mips64-unknown-linux-gnu -position-independent %s \
|
||||
# RUN: | FileCheck -check-prefix=ASM %s
|
||||
# RUN: llvm-mc -triple=mips-unknown-linux-gnu %s \
|
||||
# RUN: | FileCheck -check-prefix=ASM %s
|
||||
|
||||
# RUN: llvm-mc -triple=mips-unknown-linux-gnu \
|
||||
# RUN: -position-independent -filetype=obj -o - %s \
|
||||
# RUN: | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ32-PIC %s
|
||||
# RUN: llvm-mc -triple=mips64-unknown-linux-gnu \
|
||||
# RUN: -position-independent -filetype=obj -o - %s \
|
||||
# RUN: | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ64-PIC %s
|
||||
|
||||
# RUN: llvm-mc -triple=mips-unknown-linux-gnu \
|
||||
# RUN: -filetype=obj -o - %s \
|
||||
# RUN: | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ32-NPIC %s
|
||||
# RUN: llvm-mc -triple=mips64-unknown-linux-gnu \
|
||||
# RUN: -filetype=obj -o - %s \
|
||||
# RUN: | llvm-objdump -d -r - | FileCheck -check-prefix=OBJ64-NPIC %s
|
||||
|
||||
# ASM: .cpadd $4
|
||||
# OBJ32-PIC: addu $4, $4, $gp
|
||||
# OBJ64-PIC: daddu $4, $4, $gp
|
||||
# OBJ32-NPIC-NOT: addu
|
||||
# OBJ64-NPIC-NOT: daddu
|
||||
|
||||
.text
|
||||
.cpadd $4
|
Loading…
Reference in New Issue
Block a user