[llvm-dev] [RFC] Implementing a general purpose 64-bit target (RISC-V 64-bit) with i64 as the only legal integer type (original) (raw)

Alex Bradbury via llvm-dev llvm-dev at lists.llvm.org
Wed Oct 3 02:27:21 PDT 2018


Purpose of this RFC

This RFC describes the challenges of modelling the 64-bit RISC-V target (RV64) and details the two most obvious implementation choices:

  1. Having i64 as the only legal integer type
  2. Introducing i32 subregisters

I've worked on implementing both approaches and fleshed out a pretty complete implementation of 1), which is my preferred option. With this RFC, I would welcome further feedback and insight, as well as suggestions or comments on the target-independent modifications (e.g. TargetInstrInfo hooks) I suggest as worthwhile.

Background: RV64

The RISC-V instruction set is structured as a set of bases (RV32I, RV32E, RV64I, RV128I) with a series of optional extensions (e.g. M for multiply/divide, A for atomics, F+D for single+double precision floating point). It's important to note that RV64I is not just RV32I with some additional instructions, it's a completely different base where operations work on 64-bit rather than 32-bit values. RV64I also introduces 10 new instructions: ld/sd (64-bit load/store), addiw, slliw, srliw, sraiw, addw, subw, sllw, srlw, sraw. The *W instructions all produce a sign-extended result and take the lower 32-bits of their operands as inputs. Unlike MIPS64, there is no requirement that inputs to these *W are sign-extended in order to avoid unpredictable behaviour.

Background: RISC-V backend implementation.

Other backends aiming to support both 32-bit and 64-bit architecture variants handle this by defining two versions of each instruction with overlapping encodings, with one marked as isCodeGenOnly. This leads to unwanted duplication, both in terms of tablegen descriptions and throughout the C++ implementation of the backend (e.g. any code checking for RISCV::ADD would also want to check for RISCV::ADD64). Fortunately we can avoid this thanks to the work Krzysztof Parzyszek contributed to support variable-sized register classes <http://lists.llvm.org/pipermail/llvm-dev/2016-September/105027.html>. The in-tree RISC-V backend exploits this, parameterising the base instruction definitions by XLEN (the size of the general purpose registers).

Option 1: Have i64 as the only legal type

Approach

Every register class in RISCVRegisterInfo.td is parameterised by XLenVT, which is i32 for RV32 and i64 for RV64. No subregisters are defined, meaning i32 is not a legal type. Patterns for the *W instructions tend to look something like:

def : Pat<(sext_inreg (add GPR:$rs1, GPR:$rs2), i32),
          (ADDW GPR:$rs1, GPR:$rs2)>;

Essentially all patterns for RV32I are also valid for RV64I.

Changes needed

Questions

Does anyone have any reservations about this approach of having i64 as the only legal type?

Some of the target hooks could perhaps be replaced with more heroics in the backend. What are people's feelings here?

Option 2: Model 32-bit subregs

Approach

Define 32-bit subregisters for the GPRs that can be used in patterns and instruction definitions. The following node types are potentially useful:

You end up with patterns like:

def : Pat<(anyext GPR32:$reg),
          (SUBREG_TO_REG (i64 0), GPR32:$reg, sub_32)>;

def : Pat<(trunc GPR:$reg), (EXTRACT_SUBREG GPR:$reg, sub_32)>;

def : Pat<(add GPR32:$src, GPR32:$src2), (ADDW GPR32:$src, GPR32:$src2)>;

def : Pat<(add GPR32:$rs1, simm12_i32:$imm12), (ADDIW GPR32:$rs1, simm12_i32:$imm12)>;

Changes needed

I'm sure solutions are possible, but given that the i64-only approach seems to work very well, I'm not sure it's worth pushing further.

Conclusion

Taking full advantage of support for variable-sized register classes and sticking with i64 as the only legal integer type seems very workable and is definitely my preference based on the work I've done. I'd be really interested if anyone has any particular concerns or advice, or feedback on the suggested new target hooks.

Best,

Alex Bradbury, lowRISC CIC



More information about the llvm-dev mailing list