[PATCH] D46423: [WIP, RISCV] Support .option relax and .option norelax

Shiva Chen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 20 02:23:28 PDT 2018


shiva0217 added a comment.
Herald added a subscriber: jocewei.

We may need to find a way to indicate the `.option norelax` effective scope to handle the following case.

  .option norelax
   call f1
  .option relax
   call f2
  .option norelax
   call f3

In this case, only call f2 should insert R_RISCV_RELAX relocation type.

One possible solution would be record the no relax flag to MCInst Flag and don't emit  R_RISCV_RELAX  if the instruction contains the flag.
Something like:

   class RISCVAsmParser : public MCTargetAsmParser {
  +  bool NoRelaxLocStart = false;
     SMLoc getLoc() const { return getParser().getTok().getLoc(); }
   
  @@ -1117,6 +1118,34 @@ bool RISCVAsmParser::parseDirectiveOption() {
       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");
  +
  +    // Update AsmBackend with new STI
  +    getTargetStreamer().getStreamer().getAssemblerPtr()->getBackend()
  +          .setSTI(getSTI());
  +    NoRelaxLocStart = false;
  +    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");
  +    NoRelaxLocStart = true;
  +    return false;
  +  }
  +
  @@ -1244,6 +1273,9 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
                                         MCStreamer &Out) {
     Inst.setLoc(IDLoc);
  
  +  if (NoRelaxLocStart)
  +    Inst.setFlags(0x11);
  
  +++ b/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
  @@ -258,7 +258,7 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
         MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
     ++MCNumFixups;
  
  -  if (EnableRelax) {
  +  if (EnableRelax && (MI.getFlags() != 0x11)) {

And only setting relax back to AsmBackend when parsing `.option relax`,
In this way, when the file contains .option relax/norelax interleaving,
the relaxation result could be correct and the instruction within `.option norelax` won't do relax due to lack of R_RISCV_RELAX.
Any thoughts?


Repository:
  rL LLVM

https://reviews.llvm.org/D46423





More information about the llvm-commits mailing list