[llvm] 5f23686 - [RISCV][AsmParser] Implement .option (no)pic
Roger Ferrer Ibanez via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 17 05:14:14 PDT 2020
Author: Roger Ferrer Ibanez
Date: 2020-04-17T12:08:30Z
New Revision: 5f236864124d3b6f29689b8779a1e880df970a1c
URL: https://github.com/llvm/llvm-project/commit/5f236864124d3b6f29689b8779a1e880df970a1c
DIFF: https://github.com/llvm/llvm-project/commit/5f236864124d3b6f29689b8779a1e880df970a1c.diff
LOG: [RISCV][AsmParser] Implement .option (no)pic
Differential Revision: https://reviews.llvm.org/D77867
Added:
llvm/test/CodeGen/RISCV/option-nopic.ll
llvm/test/CodeGen/RISCV/option-pic.ll
llvm/test/MC/RISCV/option-nopic.s
llvm/test/MC/RISCV/option-pic.s
Modified:
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
llvm/test/MC/RISCV/option-pushpop.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 388b55a83195..0f284710f79c 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -51,9 +51,16 @@ STATISTIC(RISCVNumInstrsCompressed,
namespace {
struct RISCVOperand;
+struct ParserOptionsSet {
+ bool IsPicEnabled;
+};
+
class RISCVAsmParser : public MCTargetAsmParser {
SmallVector<FeatureBitset, 4> FeatureBitStack;
+ SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
+ ParserOptionsSet ParserOptions;
+
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); }
@@ -170,10 +177,15 @@ class RISCVAsmParser : public MCTargetAsmParser {
}
void pushFeatureBits() {
+ assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
+ "These two stacks must be kept synchronized");
FeatureBitStack.push_back(getSTI().getFeatureBits());
+ ParserOptionsStack.push_back(ParserOptions);
}
bool popFeatureBits() {
+ assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
+ "These two stacks must be kept synchronized");
if (FeatureBitStack.empty())
return true;
@@ -181,8 +193,11 @@ class RISCVAsmParser : public MCTargetAsmParser {
copySTI().setFeatureBits(FeatureBits);
setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
+ ParserOptions = ParserOptionsStack.pop_back_val();
+
return false;
}
+
public:
enum RISCVMatchResultTy {
Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
@@ -216,6 +231,9 @@ class RISCVAsmParser : public MCTargetAsmParser {
"doesn't support the D instruction set extension (ignoring "
"target-abi)\n";
}
+
+ const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
+ ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
}
};
@@ -1668,6 +1686,30 @@ bool RISCVAsmParser::parseDirectiveOption() {
return false;
}
+ if (Option == "pic") {
+ getTargetStreamer().emitDirectiveOptionPIC();
+
+ Parser.Lex();
+ if (Parser.getTok().isNot(AsmToken::EndOfStatement))
+ return Error(Parser.getTok().getLoc(),
+ "unexpected token, expected end of statement");
+
+ ParserOptions.IsPicEnabled = true;
+ return false;
+ }
+
+ if (Option == "nopic") {
+ getTargetStreamer().emitDirectiveOptionNoPIC();
+
+ Parser.Lex();
+ if (Parser.getTok().isNot(AsmToken::EndOfStatement))
+ return Error(Parser.getTok().getLoc(),
+ "unexpected token, expected end of statement");
+
+ ParserOptions.IsPicEnabled = false;
+ return false;
+ }
+
if (Option == "relax") {
getTargetStreamer().emitDirectiveOptionRelax();
@@ -1931,8 +1973,7 @@ void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
const MCExpr *Symbol = Inst.getOperand(1).getExpr();
unsigned SecondOpcode;
RISCVMCExpr::VariantKind VKHi;
- // FIXME: Should check .option (no)pic when implemented
- if (getContext().getObjectFileInfo()->isPositionIndependent()) {
+ if (ParserOptions.IsPicEnabled) {
SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
} else {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 8382edf09231..079dc919928a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -66,6 +66,8 @@ MCELFStreamer &RISCVTargetELFStreamer::getStreamer() {
void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
+void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
+void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
index 0221392054ce..392c87054d43 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
@@ -97,6 +97,8 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer {
void emitDirectiveOptionPush() override;
void emitDirectiveOptionPop() override;
+ void emitDirectiveOptionPIC() override;
+ void emitDirectiveOptionNoPIC() override;
void emitDirectiveOptionRVC() override;
void emitDirectiveOptionNoRVC() override;
void emitDirectiveOptionRelax() override;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
index b5b59c1227f6..4865d9d212fe 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
@@ -61,6 +61,14 @@ void RISCVTargetAsmStreamer::emitDirectiveOptionPop() {
OS << "\t.option\tpop\n";
}
+void RISCVTargetAsmStreamer::emitDirectiveOptionPIC() {
+ OS << "\t.option\tpic\n";
+}
+
+void RISCVTargetAsmStreamer::emitDirectiveOptionNoPIC() {
+ OS << "\t.option\tnopic\n";
+}
+
void RISCVTargetAsmStreamer::emitDirectiveOptionRVC() {
OS << "\t.option\trvc\n";
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
index f7c8db2edb01..94b324030154 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
@@ -21,6 +21,8 @@ class RISCVTargetStreamer : public MCTargetStreamer {
virtual void emitDirectiveOptionPush() = 0;
virtual void emitDirectiveOptionPop() = 0;
+ virtual void emitDirectiveOptionPIC() = 0;
+ virtual void emitDirectiveOptionNoPIC() = 0;
virtual void emitDirectiveOptionRVC() = 0;
virtual void emitDirectiveOptionNoRVC() = 0;
virtual void emitDirectiveOptionRelax() = 0;
@@ -49,6 +51,8 @@ class RISCVTargetAsmStreamer : public RISCVTargetStreamer {
void emitDirectiveOptionPush() override;
void emitDirectiveOptionPop() override;
+ void emitDirectiveOptionPIC() override;
+ void emitDirectiveOptionNoPIC() override;
void emitDirectiveOptionRVC() override;
void emitDirectiveOptionNoRVC() override;
void emitDirectiveOptionRelax() override;
diff --git a/llvm/test/CodeGen/RISCV/option-nopic.ll b/llvm/test/CodeGen/RISCV/option-nopic.ll
new file mode 100644
index 000000000000..681ace8ce64f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/option-nopic.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=riscv32 -filetype=obj --relocation-model=pic < %s\
+; RUN: | llvm-objdump --triple=riscv32 --mattr=+c -d -M no-aliases -\
+; RUN: | FileCheck -check-prefix=CHECK %s
+
+; This test demonstrates that .option nopic has no effect on codegen when
+; emitting an ELF directly.
+
+ at symbol = global i32 zeroinitializer
+
+define i32 @get_symbol() nounwind {
+; CHECK-LABEL: <get_symbol>:
+; CHECK: auipc a0, 0
+; CHECK: lw a0, 0(a0)
+; CHECK: lw a0, 0(a0)
+ tail call void asm sideeffect ".option nopic", ""()
+ %v = load i32, i32* @symbol
+ ret i32 %v
+}
diff --git a/llvm/test/CodeGen/RISCV/option-pic.ll b/llvm/test/CodeGen/RISCV/option-pic.ll
new file mode 100644
index 000000000000..0810936d7bb5
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/option-pic.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=riscv32 -filetype=obj < %s\
+; RUN: | llvm-objdump --triple=riscv32 --mattr=+c -d -M no-aliases -\
+; RUN: | FileCheck -check-prefix=CHECK %s
+
+; This test demonstrates that .option pic has no effect on codegen when
+; emitting an ELF directly.
+
+ at symbol = global i32 zeroinitializer
+
+define i32 @get_symbol() nounwind {
+; CHECK-LABEL: <get_symbol>:
+; CHECK: lui a0, 0
+; CHECK: lw a0, 0(a0)
+ tail call void asm sideeffect ".option pic", ""()
+ %v = load i32, i32* @symbol
+ ret i32 %v
+}
diff --git a/llvm/test/MC/RISCV/option-nopic.s b/llvm/test/MC/RISCV/option-nopic.s
new file mode 100644
index 000000000000..7673b0455619
--- /dev/null
+++ b/llvm/test/MC/RISCV/option-nopic.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases < %s \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases \
+# RUN: -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -position-independent < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases < %s \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases \
+# RUN: -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -position-independent < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+.option nopic
+# CHECK-INST: .option nopic
+
+la s0, symbol
+# CHECK-INST: auipc s0, %pcrel_hi(symbol)
+# CHECK-INST: addi s0, s0, %pcrel_lo(.Lpcrel_hi0)
+# CHECK-RELOC: R_RISCV_PCREL_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi0 0x0
+
diff --git a/llvm/test/MC/RISCV/option-pic.s b/llvm/test/MC/RISCV/option-pic.s
new file mode 100644
index 000000000000..37d643c32483
--- /dev/null
+++ b/llvm/test/MC/RISCV/option-pic.s
@@ -0,0 +1,28 @@
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases < %s \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv32 -mattr=-relax -riscv-no-aliases \
+# RUN: -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -position-independent < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases < %s \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 -mattr=-relax -riscv-no-aliases \
+# RUN: -position-independent < %s | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -position-independent < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+.option pic
+# CHECK-INST: .option pic
+
+la s0, symbol
+# CHECK-INST: auipc s0, %got_pcrel_hi(symbol)
+# CHECK-INST: l{{[wd]}} s0, %pcrel_lo(.Lpcrel_hi0)(s0)
+# CHECK-RELOC: R_RISCV_GOT_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi0 0x0
diff --git a/llvm/test/MC/RISCV/option-pushpop.s b/llvm/test/MC/RISCV/option-pushpop.s
index 0754a74c58a3..96101dbc6376 100644
--- a/llvm/test/MC/RISCV/option-pushpop.s
+++ b/llvm/test/MC/RISCV/option-pushpop.s
@@ -72,3 +72,45 @@ call baz
# CHECK-BYTES: 13 04 c1 3f
# CHECK-ALIAS: addi s0, sp, 1020
addi s0, sp, 1020
+
+.option push # Push pic=false
+# CHECK-INST: .option push
+
+.option pic
+# CHECK-INST: .option pic
+
+la s0, symbol
+# CHECK-INST: auipc s0, %got_pcrel_hi(symbol)
+# CHECK-INST: l{{[wd]}} s0, %pcrel_lo(.Lpcrel_hi0)(s0)
+# CHECK-RELOC: R_RISCV_GOT_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi0 0x0
+
+.option push # Push pic=true
+# CHECK-INST: .option push
+
+.option nopic
+# CHECK-INST: .option nopic
+
+la s0, symbol
+# CHECK-INST: auipc s0, %pcrel_hi(symbol)
+# CHECK-INST: addi s0, s0, %pcrel_lo(.Lpcrel_hi1)
+# CHECK-RELOC: R_RISCV_PCREL_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi1 0x0
+
+.option pop # Push pic=true
+# CHECK-INST: .option pop
+
+la s0, symbol
+# CHECK-INST: auipc s0, %got_pcrel_hi(symbol)
+# CHECK-INST: l{{[wd]}} s0, %pcrel_lo(.Lpcrel_hi2)(s0)
+# CHECK-RELOC: R_RISCV_GOT_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi2 0x0
+
+.option pop # Push pic=false
+# CHECK-INST: .option pop
+
+la s0, symbol
+# CHECK-INST: auipc s0, %pcrel_hi(symbol)
+# CHECK-INST: addi s0, s0, %pcrel_lo(.Lpcrel_hi3)
+# CHECK-RELOC: R_RISCV_PCREL_HI20 symbol 0x0
+# CHECK-RELOC: R_RISCV_PCREL_LO12_I .Lpcrel_hi3 0x0
More information about the llvm-commits
mailing list