diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 445599fb9b770..bb75aec44ef8e 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -152,6 +152,9 @@ Changes to the RISC-V Backend handlers. * When the experimental extension `Xqcili` is enabled, `qc.e.li` and `qc.li` may now be used to materialize immediates. +* Adds assembler support for ``.option exact``, which disables automatic compression, + and branch and linker relaxation. This can be disabled with ``.option noexact``, + which is also the default. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 05997cf78c6b1..0d40fb5614009 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -3205,6 +3205,26 @@ bool RISCVAsmParser::parseDirectiveOption() { return false; } + if (Option == "exact") { + if (Parser.parseEOL()) + return true; + + getTargetStreamer().emitDirectiveOptionExact(); + setFeatureBits(RISCV::FeatureExactAssembly, "exact-asm"); + clearFeatureBits(RISCV::FeatureRelax, "relax"); + return false; + } + + if (Option == "noexact") { + if (Parser.parseEOL()) + return true; + + getTargetStreamer().emitDirectiveOptionNoExact(); + clearFeatureBits(RISCV::FeatureExactAssembly, "exact-asm"); + setFeatureBits(RISCV::FeatureRelax, "relax"); + return false; + } + if (Option == "rvc") { if (Parser.parseEOL()) return true; @@ -3261,9 +3281,10 @@ bool RISCVAsmParser::parseDirectiveOption() { } // Unknown option. - Warning(Parser.getTok().getLoc(), "unknown option, expected 'push', 'pop', " - "'rvc', 'norvc', 'arch', 'relax' or " - "'norelax'"); + Warning(Parser.getTok().getLoc(), + "unknown option, expected 'push', 'pop', " + "'rvc', 'norvc', 'arch', 'relax', 'norelax', " + "'exact', or 'noexact'"); Parser.eatToEndOfStatement(); return false; } @@ -3473,10 +3494,13 @@ bool RISCVAsmParser::parseDirectiveVariantCC() { void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { MCInst CInst; - bool Res = RISCVRVC::compress(CInst, Inst, getSTI()); + bool Res = false; + const MCSubtargetInfo &STI = getSTI(); + if (!STI.hasFeature(RISCV::FeatureExactAssembly)) + Res = RISCVRVC::compress(CInst, Inst, STI); if (Res) ++RISCVNumInstrsCompressed; - S.emitInstruction((Res ? CInst : Inst), getSTI()); + S.emitInstruction((Res ? CInst : Inst), STI); } void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index c1ee785a13e29..0cedbd9b8eb8d 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -171,8 +171,39 @@ bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced( } } +// Given a compressed control flow instruction this function returns +// the expanded instruction. +static unsigned getRelaxedOpcode(unsigned Op) { + switch (Op) { + default: + return Op; + case RISCV::C_BEQZ: + return RISCV::BEQ; + case RISCV::C_BNEZ: + return RISCV::BNE; + case RISCV::C_J: + case RISCV::C_JAL: // fall through. + return RISCV::JAL; + case RISCV::BEQ: + return RISCV::PseudoLongBEQ; + case RISCV::BNE: + return RISCV::PseudoLongBNE; + case RISCV::BLT: + return RISCV::PseudoLongBLT; + case RISCV::BGE: + return RISCV::PseudoLongBGE; + case RISCV::BLTU: + return RISCV::PseudoLongBLTU; + case RISCV::BGEU: + return RISCV::PseudoLongBGEU; + } +} + void RISCVAsmBackend::relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const { + if (STI.hasFeature(RISCV::FeatureExactAssembly)) + return; + MCInst Res; switch (Inst.getOpcode()) { default: @@ -341,36 +372,14 @@ std::pair RISCVAsmBackend::relaxLEB128(const MCAssembler &Asm, return std::make_pair(Expr.evaluateKnownAbsolute(Value, Asm), false); } -// Given a compressed control flow instruction this function returns -// the expanded instruction. -unsigned RISCVAsmBackend::getRelaxedOpcode(unsigned Op) const { - switch (Op) { - default: - return Op; - case RISCV::C_BEQZ: - return RISCV::BEQ; - case RISCV::C_BNEZ: - return RISCV::BNE; - case RISCV::C_J: - case RISCV::C_JAL: // fall through. - return RISCV::JAL; - case RISCV::BEQ: - return RISCV::PseudoLongBEQ; - case RISCV::BNE: - return RISCV::PseudoLongBNE; - case RISCV::BLT: - return RISCV::PseudoLongBLT; - case RISCV::BGE: - return RISCV::PseudoLongBGE; - case RISCV::BLTU: - return RISCV::PseudoLongBLTU; - case RISCV::BGEU: - return RISCV::PseudoLongBGEU; - } -} - bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const { + // This function has access to two STIs, the member of the AsmBackend, and the + // one passed as an argument. The latter is more specific, so we query it for + // specific features. + if (STI.hasFeature(RISCV::FeatureExactAssembly)) + return false; + return getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode(); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index df5ffe7bc91e9..f5e8d340d9bce 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -81,7 +81,6 @@ class RISCVAsmBackend : public MCAsmBackend { bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const override; - unsigned getRelaxedOpcode(unsigned Op) const; void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp index 9eabc61331832..5a81c829e3a89 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -47,14 +47,16 @@ RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() { return static_cast(Streamer); } -void RISCVTargetELFStreamer::emitDirectiveOptionPush() {} -void RISCVTargetELFStreamer::emitDirectiveOptionPop() {} +void RISCVTargetELFStreamer::emitDirectiveOptionExact() {} +void RISCVTargetELFStreamer::emitDirectiveOptionNoExact() {} void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {} -void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {} -void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {} +void RISCVTargetELFStreamer::emitDirectiveOptionPop() {} +void RISCVTargetELFStreamer::emitDirectiveOptionPush() {} void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} +void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {} +void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {} void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h index e1765805b4a26..98948cd3e9493 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -56,14 +56,16 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer { RISCVELFStreamer &getStreamer(); RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); - void emitDirectiveOptionPush() override; - void emitDirectiveOptionPop() override; + void emitDirectiveOptionExact() override; + void emitDirectiveOptionNoExact() override; void emitDirectiveOptionPIC() override; void emitDirectiveOptionNoPIC() override; - void emitDirectiveOptionRVC() override; - void emitDirectiveOptionNoRVC() override; + void emitDirectiveOptionPop() override; + void emitDirectiveOptionPush() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; + void emitDirectiveOptionRVC() override; + void emitDirectiveOptionNoRVC() override; void emitDirectiveVariantCC(MCSymbol &Symbol) override; void finish() override; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp index ce64c61034901..5785f7da88898 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -33,16 +33,18 @@ RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} void RISCVTargetStreamer::finish() { finishAttributeSection(); } void RISCVTargetStreamer::reset() {} -void RISCVTargetStreamer::emitDirectiveOptionPush() {} -void RISCVTargetStreamer::emitDirectiveOptionPop() {} +void RISCVTargetStreamer::emitDirectiveOptionArch( + ArrayRef Args) {} +void RISCVTargetStreamer::emitDirectiveOptionExact() {} +void RISCVTargetStreamer::emitDirectiveOptionNoExact() {} void RISCVTargetStreamer::emitDirectiveOptionPIC() {} void RISCVTargetStreamer::emitDirectiveOptionNoPIC() {} -void RISCVTargetStreamer::emitDirectiveOptionRVC() {} -void RISCVTargetStreamer::emitDirectiveOptionNoRVC() {} +void RISCVTargetStreamer::emitDirectiveOptionPop() {} +void RISCVTargetStreamer::emitDirectiveOptionPush() {} void RISCVTargetStreamer::emitDirectiveOptionRelax() {} void RISCVTargetStreamer::emitDirectiveOptionNoRelax() {} -void RISCVTargetStreamer::emitDirectiveOptionArch( - ArrayRef Args) {} +void RISCVTargetStreamer::emitDirectiveOptionRVC() {} +void RISCVTargetStreamer::emitDirectiveOptionNoRVC() {} void RISCVTargetStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {} void RISCVTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} void RISCVTargetStreamer::finishAttributeSection() {} @@ -125,6 +127,14 @@ void RISCVTargetAsmStreamer::emitDirectiveOptionNoRVC() { OS << "\t.option\tnorvc\n"; } +void RISCVTargetAsmStreamer::emitDirectiveOptionExact() { + OS << "\t.option\texact\n"; +} + +void RISCVTargetAsmStreamer::emitDirectiveOptionNoExact() { + OS << "\t.option\tnoexact\n"; +} + void RISCVTargetAsmStreamer::emitDirectiveOptionRelax() { OS << "\t.option\trelax\n"; } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h index cb8bc21cb6355..169cb0f79ba78 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h @@ -41,15 +41,17 @@ class RISCVTargetStreamer : public MCTargetStreamer { void finish() override; virtual void reset(); - virtual void emitDirectiveOptionPush(); - virtual void emitDirectiveOptionPop(); + virtual void emitDirectiveOptionArch(ArrayRef Args); + virtual void emitDirectiveOptionExact(); + virtual void emitDirectiveOptionNoExact(); virtual void emitDirectiveOptionPIC(); virtual void emitDirectiveOptionNoPIC(); - virtual void emitDirectiveOptionRVC(); - virtual void emitDirectiveOptionNoRVC(); + virtual void emitDirectiveOptionPop(); + virtual void emitDirectiveOptionPush(); virtual void emitDirectiveOptionRelax(); virtual void emitDirectiveOptionNoRelax(); - virtual void emitDirectiveOptionArch(ArrayRef Args); + virtual void emitDirectiveOptionRVC(); + virtual void emitDirectiveOptionNoRVC(); virtual void emitDirectiveVariantCC(MCSymbol &Symbol); virtual void emitAttribute(unsigned Attribute, unsigned Value); virtual void finishAttributeSection(); @@ -78,15 +80,17 @@ class RISCVTargetAsmStreamer : public RISCVTargetStreamer { public: RISCVTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); - void emitDirectiveOptionPush() override; - void emitDirectiveOptionPop() override; + void emitDirectiveOptionArch(ArrayRef Args) override; + void emitDirectiveOptionExact() override; + void emitDirectiveOptionNoExact() override; void emitDirectiveOptionPIC() override; void emitDirectiveOptionNoPIC() override; - void emitDirectiveOptionRVC() override; - void emitDirectiveOptionNoRVC() override; + void emitDirectiveOptionPop() override; + void emitDirectiveOptionPush() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; - void emitDirectiveOptionArch(ArrayRef Args) override; + void emitDirectiveOptionRVC() override; + void emitDirectiveOptionNoRVC() override; void emitDirectiveVariantCC(MCSymbol &Symbol) override; }; diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 5ed3ed917aa4c..5a41330da0af2 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1496,6 +1496,10 @@ def FeatureRelax : SubtargetFeature<"relax", "EnableLinkerRelax", "true", "Enable Linker relaxation.">; +def FeatureExactAssembly + : SubtargetFeature<"exact-asm", "EnableExactAssembly", "true", + "Enable Exact Assembly (Disables Compression and Relaxation)">; + foreach i = {1-31} in def FeatureReserveX#i : SubtargetFeature<"reserve-x"#i, "UserReservedRegister[RISCV::X"#i#"]", diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll index e8b46b8d78523..5d0b7e0e256e3 100644 --- a/llvm/test/CodeGen/RISCV/features-info.ll +++ b/llvm/test/CodeGen/RISCV/features-info.ll @@ -14,6 +14,7 @@ ; CHECK-NEXT: disable-latency-sched-heuristic - Disable latency scheduling heuristic. ; CHECK-NEXT: dlen-factor-2 - Vector unit DLEN(data path width) is half of VLEN. ; CHECK-NEXT: e - 'E' (Embedded Instruction Set with 16 GPRs). +; CHECK-NEXT: exact-asm - Enable Exact Assembly (Disables Compression and Relaxation). ; CHECK-NEXT: experimental - Experimental intrinsics. ; CHECK-NEXT: experimental-p - 'P' ('Base P' (Packed SIMD)). ; CHECK-NEXT: experimental-rvm23u32 - RISC-V experimental-rvm23u32 profile. diff --git a/llvm/test/CodeGen/RISCV/option-exact-inlineasm.ll b/llvm/test/CodeGen/RISCV/option-exact-inlineasm.ll new file mode 100644 index 0000000000000..cc1097d06a96f --- /dev/null +++ b/llvm/test/CodeGen/RISCV/option-exact-inlineasm.ll @@ -0,0 +1,20 @@ +; RUN: llc -mtriple=riscv32 -mattr=+relax,+c %s --filetype=obj -o - \ +; RUN: | llvm-objdump --triple=riscv32 --mattr=+c -M no-aliases -dr - \ +; RUN: | FileCheck %s + +define i32 @foo(ptr noundef %f) nounwind { +; CHECK-LABEL: : +; CHECK: auipc ra, 0x0 +; CHECK-NEXT: R_RISCV_CALL_PLT undefined +; CHECK-NEXT: jalr ra, 0x0(ra) +; CHECK-NEXT: lw a0, 0x0(a0) +; CHECK-NEXT: c.jr ra + +entry: + %0 = tail call i32 asm sideeffect " + .option exact + call undefined@plt + lw $0, ($1) + .option noexact", "=^cr,^cr"(ptr %f) + ret i32 %0 +} diff --git a/llvm/test/MC/RISCV/option-exact.s b/llvm/test/MC/RISCV/option-exact.s new file mode 100644 index 0000000000000..f90bd00621c42 --- /dev/null +++ b/llvm/test/MC/RISCV/option-exact.s @@ -0,0 +1,128 @@ +# RUN: llvm-mc -triple riscv32 -show-encoding -mattr=+c,+relax \ +# RUN: -M no-aliases %s | FileCheck -check-prefixes=CHECK-ASM,CHECK-INST %s +# RUN: llvm-mc -triple riscv32 -filetype=obj -mattr=+c,+relax %s \ +# RUN: | llvm-objdump --triple=riscv32 --mattr=+c -dr --no-print-imm-hex -M no-aliases - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJDUMP,CHECK-INST %s + +# RUN: llvm-mc -triple riscv64 -show-encoding \ +# RUN: -M no-aliases -mattr=+c,+relax %s \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM %s +# RUN: llvm-mc -triple riscv64 -filetype=obj -mattr=+c,+relax %s \ +# RUN: | llvm-objdump --triple=riscv64 --mattr=+c -dr --no-print-imm-hex -M no-aliases - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJDUMP,CHECK-INST %s + +## `.option exact` disables a variety of assembler behaviour: +## - automatic compression +## - branch relaxation (of short branches to longer equivalent sequences) +## - linker relaxation (emitting R_RISCV_RELAX) +## `.option noexact` enables these behaviours again. It is also the default. + +# CHECK-OBJDUMP: 4108 +# CHECK-INST: c.lw a0, 0(a0) +# CHECK-ASM: # encoding: [0x08,0x41] +lw a0, 0(a0) + +# CHECK-OBJDUMP: 4108 +# CHECK-INST: c.lw a0, 0(a0) +# CHECK-ASM: # encoding: [0x08,0x41] +c.lw a0, 0(a0) + +# CHECK-ASM: call undefined +# CHECK-ASM-SAME: # encoding: [0x97'A',A,A,A,0xe7'A',0x80'A',A,A] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_call_plt +# CHECK-ASM-NEXT: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax +# CHECK-OBJDUMP: auipc ra, 0 +# CHECK-OBJDUMP-NEXT: R_RISCV_CALL_PLT undefined +# CHECK-OBJDUMP-NEXT: R_RISCV_RELAX *ABS* +# CHECK-OBJDUMP-NEXT: jalr ra +call undefined@plt + +# CHECK-ASM: beq a0, a1, undefined +# CHECK-ASM-SAME: # encoding: [0x63'A',A,0xb5'A',A] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_branch +# CHECK-OBJDUMP: bne a0, a1, 0x14 +# CHECK-OBJDUMP-NEXT: jal zero, 0x10 +# CHECK-OBJDUMP-NEXT: R_RISCV_JAL undefined +beq a0, a1, undefined + +# CHECK-ASM: c.j undefined +# CHECK-ASM-SAME: # encoding: [0bAAAAAA01,0b101AAAAA] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_rvc_jump +# CHECK-OBJDUMP: jal zero, 0x14 +# CHECK-OBJDUMP-NEXT: R_RISCV_JAL undefined +c.j undefined + +# CHECK-ASM: .option exact +.option exact + +# CHECK-OBJDUMP: 00052503 +# CHECK-INST: lw a0, 0(a0) +# CHECK-ASM: # encoding: [0x03,0x25,0x05,0x00] +lw a0, 0(a0) + +# CHECK-OBJDUMP: 4108 +# CHECK-INST: c.lw a0, 0(a0) +# CHECK-ASM: # encoding: [0x08,0x41] +c.lw a0, 0(a0) + +# CHECK-ASM: call undefined +# CHECK-ASM-SAME: # encoding: [0x97'A',A,A,A,0xe7'A',0x80'A',A,A] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_call_plt +# CHECK-ASM-NOT: fixup_riscv_relax +# CHECK-OBJDUMP: auipc ra, 0 +# CHECK-OBJDUMP-NEXT: R_RISCV_CALL_PLT undefined +# CHECK-OBJDUMP-NOT: R_RISCV_RELAX +# CHECK-OBJDUMP-NEXT: jalr ra, 0(ra) +call undefined@plt + +# CHECK-ASM: beq a0, a1, undefined +# CHECK-ASM-SAME: # encoding: [0x63'A',A,0xb5'A',A] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_branch +# CHECK-OBJDUMP: beq a0, a1, 0x26 +# CHECK-OBJDUMP-NEXT: R_RISCV_BRANCH undefined +beq a0, a1, undefined + +# CHECK-ASM: c.j undefined +# CHECK-ASM-SAME: # encoding: [0bAAAAAA01,0b101AAAAA] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_rvc_jump +# CHECK-OBJDUMP: c.j 0x2a +# CHECK-OBJDUMP-NEXT: R_RISCV_RVC_JUMP undefined +c.j undefined + +# CHECK-ASM: .option noexact +.option noexact + +# CHECK-OBJDUMP: 4108 +# CHECK-INST: c.lw a0, 0(a0) +# CHECK-ASM: # encoding: [0x08,0x41] +lw a0, 0(a0) + +# CHECK-OBJDUMP: 4108 +# CHECK-INST: c.lw a0, 0(a0) +# CHECK-ASM: # encoding: [0x08,0x41] +c.lw a0, 0(a0) + +# CHECK-ASM: call undefined +# CHECK-ASM-SAME: # encoding: [0x97'A',A,A,A,0xe7'A',0x80'A',A,A] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_call_plt +# CHECK-ASM-NEXT: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax +# CHECK-OBJDUMP: auipc ra, 0 +# CHECK-OBJDUMP-NEXT: R_RISCV_CALL_PLT undefined +# CHECK-OBJDUMP-NEXT: R_RISCV_RELAX *ABS* +# CHECK-OBJDUMP-NEXT: jalr ra, 0(ra) +call undefined@plt + +# CHECK-ASM: beq a0, a1, undefined +# CHECK-ASM-SAME: # encoding: [0x63'A',A,0xb5'A',A] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_branch +# CHECK-OBJDUMP: bne a0, a1, 0x40 +# CHECK-OBJDUMP-NEXT: jal zero, 0x3c +# CHECK-OBJDUMP-NEXT: R_RISCV_JAL undefined +beq a0, a1, undefined + +# CHECK-ASM: c.j undefined +# CHECK-ASM-SAME: # encoding: [0bAAAAAA01,0b101AAAAA] +# CHECK-ASM-NEXT: fixup A - offset: 0, value: undefined, kind: fixup_riscv_rvc_jump +# CHECK-OBJDUMP: jal zero, 0x40 +# CHECK-OBJDUMP-NEXT: R_RISCV_JAL undefined +c.j undefined diff --git a/llvm/test/MC/RISCV/option-invalid.s b/llvm/test/MC/RISCV/option-invalid.s index 7f6de5f38c528..27cc97bda360f 100644 --- a/llvm/test/MC/RISCV/option-invalid.s +++ b/llvm/test/MC/RISCV/option-invalid.s @@ -53,7 +53,7 @@ # CHECK: :[[#@LINE+1]]:13: error: expected newline .option rvc foo -# CHECK: :[[#@LINE+1]]:12: warning: unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'arch', 'relax' or 'norelax' +# CHECK: :[[#@LINE+1]]:12: warning: unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'arch', 'relax', 'norelax', 'exact', or 'noexact' .option bar # CHECK: :[[#@LINE+1]]:12: error: .option pop with no .option push