[PATCH] D50496: [RISCV] Implment pseudo instructions for load/store from a symbol address.

James Clarke via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 4 06:37:18 PST 2018


jrtc27 added inline comments.


================
Comment at: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp:1230
+///   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
+const MCExpr *RISCVAsmParser::emitLoadSymbolAddress(const MCExpr *Symbol,
+                                                    const MCOperand &TmpReg,
----------------
kito-cheng wrote:
> rogfer01 wrote:
> > Suggestion: what about renaming it `emitLoadSymbolAddressHi`, it might look like the full symbol address will be computed otherwise. Then you can rename the new `emitLoadWithSymbol` to just `emitLoadSymbol`.
> Thanks your suggestion, naming is always hard to me :P
It strikes me that, apart from choosing the opcode (add/load/store) and store having a temporary register, `emitLoadLocalAddress`/`emitLoadSymbol`/`emitStoreSymbol` all do exactly the same thing. Can we not move all that into `emitLoadSymbolAddressHi`, rename it appropriately (something like `emitAuipcInstPair` as an idea) and then remove `emitLoadLocalAddress`/`emitLoadSymbol`/`emitStoreSymbol`? Then `processInstruction` would look something like:

```
  // ...
  case RISCV::PseudoLLA:
    emitAuipcInstPair(Inst, RISCV::ADDI, IDLoc, Out);
    return false;
  case RISCV::PseudoLB:
    emitAuipcInstPair(Inst, RISCV::LB, IDLoc, Out);
    return false;
  // ...
  case RISCV::PseudoSB:
    emitAuipcInstPair(Inst, RISCV::SB, IDLoc, Out);
    return false;
  // ...
```

Note that `Inst.getNumOperands()` tells you whether there is a temporary register to use.

Alternatively, you can make `emitAuipcInstPair` take `unsigned Opcode, MCOperand DestReg, MCOperand TmpReg, MCExpr *Symbol, SMLoc IDLoc, MCStreamer &Out` and keep your wrappers, but their only job is to unpack `DestReg`, `Symbol` and `TmpReg` (set to `DestReg` for add/load). I'd still push the opcode selection out into `processInstruction` as you already have to enumerate the pseudo opcodes there. Then you'd have something like:

```
void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
                                          MCStreamer &Out) {
  // The local load address pseudo-instruction "lla" is used in PC-relative
  // addressing of symbols:
  //   lla rdest, symbol
  // expands to
  //   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
  //             ADDI rdest, %pcrel_lo(TmpLabel)
  MCOperand DestReg = Inst.getOperand(0);
  const MCExpr *Symbol = Inst.getOperand(1).getExpr();
  emitAuipcInstPair(RISCV::ADDI, DestReg, DestReg, Symbol, IDLoc, Out);
}

void RISCVAsmParser::emitLoadSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
                                    MCStreamer &Out) {
  // The load pseudo-instruction does a pc-relative load with
  // a symbol.
  //
  // The expansion looks like this
  //
  //   TmpLabel: AUIPC rd, %pcrel_hi(symbol)
  //             LX    rd, %pcrel_lo(TmpLabel)(rd)
  MCOperand DestReg = Inst.getOperand(0);
  const MCExpr *Symbol = Inst.getOperand(1).getExpr();
  emitAuipcInstPair(Opcode, DestReg, DestReg, Symbol, IDLoc, Out);
}

void RISCVAsmParser::emitStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
                                    MCStreamer &Out) {
  // The store pseudo-instruction does a pc-relative store with
  // a symbol.
  //
  // The expansion looks like this
  //
  //   TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
  //             SX    rd, %pcrel_lo(TmpLabel)(tmp)
  MCOperand DestReg = Inst.getOperand(0);
  MCOperand TmpReg = Inst.getOperand(1);
  const MCExpr *Symbol = Inst.getOperand(2).getExpr();
  emitAuipcInstPair(Opcode, DestReg, TmpReg, Symbol, IDLoc, Out);
}
```

Although we can be smart and distinguish between stores and non-stores as described above, I'm actually leaning towards this one as it's a bit more explicit, clearer, and will catch cases where we do something stupid (e.g. stores without a temporary register).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D50496/new/

https://reviews.llvm.org/D50496





More information about the llvm-commits mailing list