Index: lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -27,12 +27,13 @@ namespace { class RISCVAsmBackend : public MCAsmBackend { + const MCSubtargetInfo &STI; uint8_t OSABI; bool Is64Bit; public: - RISCVAsmBackend(uint8_t OSABI, bool Is64Bit) - : MCAsmBackend(), OSABI(OSABI), Is64Bit(Is64Bit) {} + RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit) + : MCAsmBackend(), STI(STI), OSABI(OSABI), Is64Bit(Is64Bit) {} ~RISCVAsmBackend() override {} void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, @@ -88,14 +89,26 @@ }; bool RISCVAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { - // Once support for the compressed instruction set is added, we will be able - // to conditionally support 16-bit NOPs - if ((Count % 4) != 0) - return false; - + bool HasStdExtC = STI.getFeatureBits()[RISCV::FeatureStdExtC]; + + if (HasStdExtC) { + if ((Count % 2) != 0) + return false; + } else { + if ((Count % 4) != 0) + return false; + } // The canonical nop on RISC-V is addi x0, x0, 0 - for (uint64_t i = 0; i < Count; i += 4) - OW->write32(0x13); + uint64_t Nop32Count = Count / 4; + for (uint64_t i = Nop32Count; i != 0; --i) + OW->write32(0x13); + + // The canonical nop on RVC is c.nop + if (HasStdExtC) { + uint64_t Nop16Count = (Count - Nop32Count * 4) / 2; + for (uint64_t i = Nop16Count; i != 0; --i) + OW->write16(0x01); + } return true; } @@ -235,5 +248,5 @@ const MCTargetOptions &Options) { const Triple &TT = STI.getTargetTriple(); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); - return new RISCVAsmBackend(OSABI, TT.isArch64Bit()); + return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit()); } Index: test/MC/RISCV/cnop.s =================================================================== --- /dev/null +++ test/MC/RISCV/cnop.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c < %s \ +# RUN: | llvm-objdump -mattr=+c -d - | FileCheck -check-prefix=CHECK-INST %s + +# alpha and main are 8 byte alignment +# but the alpha function's size is 6 +# So assembler will insert a c.nop to make sure 8 byte alignment. + + .text + .p2align 3 + .type alpha,@function +alpha: +# BB#0: + addi sp, sp, -16 + c.lw a0, 0(a0) +# CHECK-INST: c.nop +.Lfunc_end0: + .size alpha, .Lfunc_end0-alpha + # -- End function + .globl main + .p2align 3 + .type main,@function +main: # @main +# BB#0: +.Lfunc_end1: + .size main, .Lfunc_end1-main + # -- End function