Junning Wu via llvm-dev
2020-Apr-07 00:50 UTC
[llvm-dev] [RISC-V]How to change the behavior of register allocation for RISC-V inline assembly
*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?* -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200407/0746669a/attachment.html>
Aaron Smith via llvm-dev
2020-Apr-07 01:52 UTC
[llvm-dev] [RISC-V]How to change the behavior of register allocation for RISC-V inline assembly
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>