[llvm-dev] [RISC-V]How to change the behavior of register allocation for RISC-V inline assembly

Aaron Smith via llvm-dev llvm-dev at lists.llvm.org
Mon Apr 6 18:52:26 PDT 2020


The register class for inline asm is determined by
RISCVTargetLowering::getRegForInlineAsmConstraint().
Maybe you need to modify that method to return your new register class.


On Mon, Apr 6, 2020 at 5:51 PM Junning Wu via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> *The problem is, I have an instruction named LQP, which load 4x32-bit from
> memory and store them into 4 consecutive GPRs, such as, LQP a0, a4, a5, 4,*
> * the loaded data will be stored in (a3,a2,a1,a0), the data address is
> 4(a4+a5).*
>
> *The RISC-V inline assembly like this:*
>
>   asm volatile
>   (
>     "lqp   %[z], %[x], %[y], 4\n\t"
>     : [z] "=r" (c)
>     : [x] "r" (a), [y] "r" (b)
>   ) ;
>
> *To get this done, I creat to GPR groups and change the LQP instruction's
> definition, like this:*
>
> def GPRA0 : RegisterClass<"RISCV", [XLenVT], 32, (add X10)> {
>   let RegInfos = RegInfoByHwMode<
>       [RV32,              RV64,              DefaultMode],
>       [RegInfo<32,32,32>, RegInfo<64,64,64>, RegInfo<32,32,32>]>;
> }
>
> def GPRNOA0A1A2A3 : RegisterClass<"RISCV", [XLenVT], 32, (add
>     (sequence "X%u", 14, 17),
>     (sequence "X%u", 5, 7),
>     (sequence "X%u", 28, 31),
>     (sequence "X%u", 8, 9),
>     (sequence "X%u", 18, 27),
>     (sequence "X%u", 0, 4)
>   )> {
>   let RegInfos = RegInfoByHwMode<
>       [RV32,              RV64,              DefaultMode],
>       [RegInfo<32,32,32>, RegInfo<64,64,64>, RegInfo<32,32,32>]>;
> }
>
> let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
> def LQP : RVInstRI<0b11, 0b000, OPC_HX_CUS0,
>                   (outs GPRA0:$rd), (ins GPRNOA0A1A2A3:$rs1,
> GPRNOA0A1A2A3:$rs2, simm5:$shift),
>                   "lqp", "$rd, $rs1, $rs2, $shift">, Sched<[]> {
>  bits<5> shift;
>  bits<5> rs1;
>  bits<5> rs2;
>  bits<5> rd;
>
>  let Inst{31-30} = 0b11;
>  let Inst{29-25} = shift;
>  let Inst{24-20} = rs2;
>  let Inst{19-15} = rs1;
>  let Inst{14-12} = 0b000;
>  let Inst{11-7} = rd;
>  let Opcode = OPC_HX_CUS0.Value;
> }
>
> *and the  DecodeStatus as well, *
>
> static DecodeStatus DecodeGPRA0RegisterClass(MCInst &Inst, uint64_t RegNo,
>                                                uint64_t Address,
>                                                const void *Decoder) {
>   if (RegNo != 10) {
>     return MCDisassembler::Fail;
>   }
>
>   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
> }
>
> static DecodeStatus DecodeGPRNOA0A1A2A3RegisterClass(MCInst &Inst,
> uint64_t RegNo,
>                                                uint64_t Address,
>                                                const void *Decoder) {
>   if (RegNo == 10 || RegNo == 11 || RegNo == 12 || RegNo == 13) {
>     return MCDisassembler::Fail;
>   }
>
>   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
> }
>
> static DecodeStatus DecodeGPRNOA0A1RegisterClass(MCInst &Inst, uint64_t
> RegNo,
>                                                uint64_t Address,
>                                                const void *Decoder) {
>   if (RegNo == 10 || RegNo == 11) {
>     return MCDisassembler::Fail;
>   }
>
>   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
> }
>
> *Rebuild LLVM+clang, and compile the above c code which got such an error:*
>
> clang -I./env -I./common -I./src/test_newinst
> -I/home/llvm/workspace/llvm/llvm-project/llvm_install/riscv32-unknown-elf/include
> -mcmodel=medany -static -std=gnu99 -fno-common -fno-builtin-printf
> -march=rv32imac -mabi=ilp32 -DMB_ADDR=0x11ffC -O3
> --target=riscv32-unknown-elf
> --sysroot=/home/llvm/workspace/riscv/riscv-tc-20200316/bin/riscv32-unknown-elf
> --gcc-toolchain=/home/llvm/workspace/riscv/riscv-tc-20200316 -o
> ./build/test_newinst/test_newinst ./src/test_newinst/main.c
> ./common/syscalls.c ./common/dev.c ./common/crt.S -static  -nostartfiles
> -lm -lgcc -T ./common/test.ld
>
> ./src/test_newinst/main.c:117:5: error: invalid operand for instruction
>     "lqp   %[z], %[x], %[y], 4\n\t"
>     ^
>
> <inline asm>:1:8: note: instantiated into assembly here
>         lqp   a2, a0, a1, 4
>
> *This error is obvious, and due to the Match_InvalidOperand, I wonder why
> the changes do not make any effect for LQP instruction.*
> *And I have checked the OperandInfo111[] and RISCVInsts[] for the LQP
> instruction, *
>
> static const MCOperandInfo OperandInfo111[] = { { RISCV::GPRA0RegClassID,
> 0, MCOI::OPERAND_REGISTER, 0 }, { RISCV::GPRNOA0A1A2A3RegClassID, 0,
> MCOI::OPERAND_REGISTER, 0 }, { RISCV::GPRNOA0A1A2A3RegClassID, 0,
> MCOI::OPERAND_REGISTER, 0 }, { -1, 0, RISCVOp::OPERAND_SIMM5, 0 }, };
>
> { 457, 4, 1, 4, 0, 0|(1ULL<<MCID::MayLoad), 0x12ULL, nullptr, nullptr,
> OperandInfo111, -1 ,nullptr },  // Inst #457 = LQP
>
> *Do I miss something or what I can do in this situation?*
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200406/555aa677/attachment.html>


More information about the llvm-dev mailing list