Index: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1055,9 +1055,33 @@ return false; } + if (Option == "relax") { + getTargetStreamer().emitDirectiveOptionRelax(); + + Parser.Lex(); + if (Parser.getTok().isNot(AsmToken::EndOfStatement)) + return Error(Parser.getTok().getLoc(), + "unexpected token, expected end of statement"); + + setFeatureBits(RISCV::FeatureRelax, "relax"); + return false; + } + + if (Option == "norelax") { + getTargetStreamer().emitDirectiveOptionNoRelax(); + + Parser.Lex(); + if (Parser.getTok().isNot(AsmToken::EndOfStatement)) + return Error(Parser.getTok().getLoc(), + "unexpected token, expected end of statement"); + + clearFeatureBits(RISCV::FeatureRelax, "relax"); + return false; + } + // Unknown option. Warning(Parser.getTok().getLoc(), - "unknown option, expected 'rvc' or 'norvc'"); + "unknown option, expected 'rvc', 'norvc', 'relax' or 'norelax'"); Parser.eatToEndOfStatement(); return false; } Index: lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -22,6 +22,8 @@ virtual void emitDirectiveOptionRVC(); virtual void emitDirectiveOptionNoRVC(); + virtual void emitDirectiveOptionRelax(); + virtual void emitDirectiveOptionNoRelax(); }; } #endif Index: lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -40,3 +40,5 @@ void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {} +void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} +void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} Index: lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h +++ lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h @@ -20,6 +20,8 @@ virtual void emitDirectiveOptionRVC() = 0; virtual void emitDirectiveOptionNoRVC() = 0; + virtual void emitDirectiveOptionRelax() = 0; + virtual void emitDirectiveOptionNoRelax() = 0; }; // This part is for ascii assembly output @@ -31,6 +33,8 @@ void emitDirectiveOptionRVC() override; void emitDirectiveOptionNoRVC() override; + void emitDirectiveOptionRelax() override; + void emitDirectiveOptionNoRelax() override; }; } Index: lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -30,3 +30,11 @@ void RISCVTargetAsmStreamer::emitDirectiveOptionNoRVC() { OS << "\t.option\tnorvc\n"; } + +void RISCVTargetAsmStreamer::emitDirectiveOptionRelax() { + OS << "\t.option\trelax\n"; +} + +void RISCVTargetAsmStreamer::emitDirectiveOptionNoRelax() { + OS << "\t.option\tnorelax\n"; +} Index: test/MC/RISCV/option-invalid.s =================================================================== --- test/MC/RISCV/option-invalid.s +++ test/MC/RISCV/option-invalid.s @@ -13,5 +13,5 @@ # CHECK: error: unexpected token, expected end of statement .option rvc foo -# CHECK: warning: unknown option, expected 'rvc' or 'norvc' +# CHECK: warning: unknown option, expected 'rvc', 'norvc', 'relax' or 'norelax' .option bar Index: test/MC/RISCV/option-relax.s =================================================================== --- /dev/null +++ test/MC/RISCV/option-relax.s @@ -0,0 +1,27 @@ +# RUN: llvm-mc -triple riscv32 < %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 riscv64 < %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 + +# CHECK-INST: call foo +# CHECK-RELOC: R_RISCV_CALL foo 0x0 +call foo + +.option relax +# CHECK-INST: .option relax +# CHECK-INST: call bar +# CHECK-RELOC-NEXT: R_RISCV_CALL bar 0x0 +# CHECK-RELOC-NEXT: R_RISCV_RELAX bar 0x0 +call bar + +.option norelax +# CHECK-INST: .option norelax +# CHECK-INST: call baz +# CHECK-RELOC: R_RISCV_CALL baz 0x0 +# CHECK-RELOC-NOT: R_RISCV_RELAX baz 0x0 +call baz