Page MenuHomePhabricator

[RISCV] Add support for RVC HINT instructions

Authored by luismarques on May 29 2019, 7:16 AM.



Adds assembler support for RVC HINT instructions.

The hint instructions are enabled by default (if the standard C extension is enabled). To disable them pass -mattr=-rvc-hints. This "enabled by default" behavior was achieved by adding the FeatureRVCHints to the RV32/RV64 ProcessorModels. Setting the RISCVSubtarget member flags default value to true doesn't work for all tool flows (e.g. using llvm-mc for a .s -> .o).

The (non-hint) C_NOP definition now has a let Inst{6-2} = 0. That's necessary to ensure that e.g. c.addi x0, 7 would not be decoded as a plain c.nop.

The (non-hint) C_ADDI_NOP instruction is also added by this patch, since it fits the overall theme of the patch. That instruction definition is necessary to add support for writing a c.nop in its extended form of c.addi x0, 0.

Diff Detail


Event Timeline

luismarques created this revision.May 29 2019, 7:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 29 2019, 7:16 AM
shiva0217 added inline comments.Jun 4 2019, 10:49 PM
577 ↗(On Diff #201901)

We could remove "let isAsmParserOnly = 1" and add "let Inst{11} = 0". So tablegen won't complain the encoding ambiguous and will invoke DecodeGPRX0RegisterClass in

luismarques marked an inline comment as done.Jun 17 2019, 6:56 AM
luismarques added inline comments.
577 ↗(On Diff #201901)

If I do that then the (non-hint) instruction instruction is decoded as <unknown>.
To correctly decode both the regular and the hint instructions wouldn't we need to add support for decoding based on the operand classes?

shiva0217 added inline comments.Jun 18 2019, 11:46 PM
577 ↗(On Diff #201901)

Oh, I think you're right.
We could define "let Inst{11-7} = 0;" and the decoder method "let DecoderMethod = "DecodeC_LI_HINT";"
So only C_LI_HINT will match the decoder "DecodeC_LI_HINT" and using the decoder to add X0 register.
Something like

static DecodeStatus DecodeC_LI_HINT(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) {
  DecodeStatus S = MCDisassembler::Success;

  unsigned Rd = fieldFromInstruction(Insn, 7, 5);
  uint64_t Simm6 = fieldFromInstruction(Insn, 2, 5) |
                   fieldFromInstruction(Insn, 12, 1) << 5;

  DecodeGPRRegisterClass(Inst, 0, Address, Decoder);

  if (decodeSImmOperand<6>(Inst, Simm6, Address, Decoder) ==
      MCDisassembler::Fail) {
    return MCDisassembler::Fail;

  return S;

And some of the decoder methods might be shared if the hint instructions have the same format.

lenary added a subscriber: lenary.Jul 31 2019, 9:15 AM

Between this and D65205 we have duplicated some of the isImmZero stuff. This will need to be resolved with a rebase when one of these patches lands.

luismarques edited the summary of this revision. (Show Details)

Adds MC layer support, using the approach suggested by Shiva (thanks!), and updates the tests to test that additional support.
Updates the summary, so it no longer says MC layer support is missing.

asb accepted this revision.Aug 19 2019, 5:57 AM

Looks good to me, thanks! We may later review whether the ability to enable/disable these hints is worth it or not (I know I'd been in favour from the start, but looking at it with fresh eyes I'm not sure it's fully necessary), but this is a useful step forwards.

This revision is now accepted and ready to land.Aug 19 2019, 5:57 AM
asb added inline comments.Aug 19 2019, 5:58 AM
25 ↗(On Diff #214981)

Nit: we typically get rid of the multiple spaces after the mnemonic as shown in this line and others

luismarques retitled this revision from [RISCV] Add assembler support for RVC HINT instructions to [RISCV] Add support for RVC HINT instructions.Aug 21 2019, 6:59 AM
This revision was automatically updated to reflect the committed changes.