Patch [2/3] in series to add support for SVE's gather load instructions
that use scalar+vector addressing modes:
- Patch [1/3]: https://reviews.llvm.org/D45951
- Patch [2/3]: https://reviews.llvm.org/D46023
- Patch [3/3]: https://reviews.llvm.org/D45958
Paths
| Differential D46023
[AArch64][SVE] Asm: Support for gather LD1/LDFF1 (scalar + vector) load instructions. ClosedPublic Authored by sdesmalen on Apr 24 2018, 10:42 AM.
Details Summary Patch [2/3] in series to add support for SVE's gather load instructions
Diff Detail Event Timelinesdesmalen mentioned this in D45952: [AArch64][SVE] Asm: Support for gather LD1/LDFF1 (scalar + vector (32bit elts, unscaled)) load instructions..Apr 24 2018, 10:47 AM sdesmalen mentioned this in D45953: [AArch64][SVE] Asm: Support for gather LD1/LDFF1 (scalar + vector (32bit elts, scaled)) load instructions.. sdesmalen mentioned this in D45954: [AArch64][SVE] Asm: Support for gather LD1/LDFF1 (scalar + vector (64bit elts, unscaled)) load instructions.. sdesmalen mentioned this in D45955: [AArch64][SVE] Asm: Support for gather LD1/LDFF1 (scalar + vector (64bit elts, scaled)) load instructions..
Comment Actions
Comment Actions Thanks for combining the 64 bit classes! LGTM
This revision is now accepted and ready to land.Apr 25 2018, 2:30 AM Closed by commit rL330928: [AArch64][SVE] Asm: Support for gather LD1/LDFF1 (scalar + vector) load… (authored by s.desmalen). · Explain WhyApr 26 2018, 1:23 AM This revision was automatically updated to reflect the committed changes.
Revision Contents
Diff 143874 lib/Target/AArch64/AArch64SVEInstrInfo.td
lib/Target/AArch64/SVEInstrFormats.td
test/MC/AArch64/SVE/ld1b.s
test/MC/AArch64/SVE/ld1d.s
test/MC/AArch64/SVE/ld1h.s
test/MC/AArch64/SVE/ld1sb.s
test/MC/AArch64/SVE/ld1sh.s
test/MC/AArch64/SVE/ld1sw.s
test/MC/AArch64/SVE/ld1w.s
test/MC/AArch64/SVE/ldff1b.s
test/MC/AArch64/SVE/ldff1d-diagnostics.s
test/MC/AArch64/SVE/ldff1d.s
test/MC/AArch64/SVE/ldff1h.s
test/MC/AArch64/SVE/ldff1sb.s
test/MC/AArch64/SVE/ldff1sh-diagnostics.s
test/MC/AArch64/SVE/ldff1sh.s
test/MC/AArch64/SVE/ldff1sw-diagnostics.s
test/MC/AArch64/SVE/ldff1sw.s
test/MC/AArch64/SVE/ldff1w-diagnostics.s
test/MC/AArch64/SVE/ldff1w.s
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Thanks for restructuring this Sander, it is easier to get a completer picture now! I think there are still some repetitive classes. I think it would be possible to have a single class dealing with 32 and 64 bit gather & unsized operands, like the diff below. The parameters of sve_mem_gld would need documenting (and one or 2 might be implied by others).
+class sve_mem_gld<bits<4> opc, bit xs, bit scaled, bit ns, bits<7> type, RegisterOperand sz, string asm, + RegisterOperand zprext> +: I<(outs sz:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), + asm, "\t$Zt, $Pg/z, [$Rn, $Zm]", + "", + []>, Sched<[]> { + bits<3> Pg; + bits<5> Rn; + bits<5> Zm; + bits<5> Zt; + let Inst{31-25} = type; + let Inst{24-23} = opc{3-2}; + let Inst{22} = xs; + let Inst{21} = scaled; + let Inst{20-16} = Zm; + let Inst{15} = ns; + let Inst{14-13} = opc{1-0}; + let Inst{12-10} = Pg; + let Inst{9-5} = Rn; + let Inst{4-0} = Zt; + + let mayLoad = 1; + let Defs = !if(!eq(opc{0}, 1), [FFR], []); + let Uses = !if(!eq(opc{0}, 1), [FFR], []); +} + +//===----------------------------------------------------------------------===// +// SVE Memory - 32-bit Gather and Unsized Contiguous Group +//===----------------------------------------------------------------------===// +multiclass sve_mem_32b_gld_sv_32_scaled<bits<4> opc, string asm, + RegisterOperand sxtw_opnd, + RegisterOperand uxtw_opnd> { + def _UXTW_SCALED_REAL : sve_mem_gld<opc, 0, 1, 0, 0b1000010, Z_s, asm, uxtw_opnd>; + def _SXTW_SCALED_REAL : sve_mem_gld<opc, 1, 1, 0, 0b1000010, Z_s, asm, sxtw_opnd>; + + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>; + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>; +} + +multiclass sve_mem_32b_gld_vs_32_unscaled<bits<4> opc, string asm, + RegisterOperand sxtw_opnd, + RegisterOperand uxtw_opnd> { + def _UXTW_REAL : sve_mem_gld<opc, 0, 0, 0, 0b1000010, Z_s, asm, uxtw_opnd>; + def _SXTW_REAL : sve_mem_gld<opc, 1, 0, 0, 0b1000010, Z_s, asm, sxtw_opnd>; + + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _UXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>; + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _SXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>; +} + + +//===----------------------------------------------------------------------===// +// SVE Memory - 64-bit Gather Group +//===----------------------------------------------------------------------===// + +multiclass sve_mem_64b_gld_sv_32_scaled<bits<4> opc, string asm, + RegisterOperand sxtw_opnd, + RegisterOperand uxtw_opnd> { + def _UXTW_SCALED_REAL : sve_mem_gld<opc, 0, 1, 0, 0b1100010, Z_d, asm, uxtw_opnd>; + def _SXTW_SCALED_REAL : sve_mem_gld<opc, 1, 1, 0, 0b1100010, Z_d, asm, sxtw_opnd>; + + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>; + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>; +} + +multiclass sve_mem_64b_gld_vs_32_unscaled<bits<4> opc, string asm, + RegisterOperand sxtw_opnd, + RegisterOperand uxtw_opnd> { + def _UXTW_REAL : sve_mem_gld<opc, 0, 0, 0, 0b1100010, Z_d, asm, uxtw_opnd>; + def _SXTW_REAL : sve_mem_gld<opc, 1, 0, 0, 0b1100010, Z_d, asm, sxtw_opnd>; + + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _UXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>; + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _SXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>; +} + +multiclass sve_mem_64b_gld_sv2_64_scaled<bits<4> opc, string asm, + RegisterOperand zprext> { + def _SCALED_REAL : sve_mem_gld<opc, 1, 1, 1, 0b1100010, Z_d, asm, zprext>; + + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>; +} + +multiclass sve_mem_64b_gld_vs2_64_unscaled<bits<4> opc, string asm> { + def _REAL : sve_mem_gld<opc, 1, 0, 1, 0b1100010, Z_d, asm, ZPR64ExtLSL8>; + + def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]", + (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>; +}