0033-target-riscv-rvv-1.0-take-fractional-LMUL-into-vecto.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. From bf3c1bd265917cfcfd93215d5eebfa9d154816da Mon Sep 17 00:00:00 2001
  2. From: Frank Chang <frank.chang@sifive.com>
  3. Date: Fri, 14 Aug 2020 17:31:34 +0800
  4. Subject: [PATCH 033/107] target/riscv: rvv-1.0: take fractional LMUL into
  5. vector max elements calculation
  6. Update vext_get_vlmax() and MAXSZ() to take fractional LMUL into
  7. calculation for RVV 1.0.
  8. Signed-off-by: Frank Chang <frank.chang@sifive.com>
  9. Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
  10. Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
  11. ---
  12. target/riscv/cpu.h | 43 ++++++++++++++++++-------
  13. target/riscv/insn_trans/trans_rvv.c.inc | 12 ++++++-
  14. 2 files changed, 42 insertions(+), 13 deletions(-)
  15. diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
  16. index 3835d22ca1..f773bae96b 100644
  17. --- a/target/riscv/cpu.h
  18. +++ b/target/riscv/cpu.h
  19. @@ -404,18 +404,27 @@ FIELD(TB_FLAGS, HLSX, 15, 1)
  20. bool riscv_cpu_is_32bit(CPURISCVState *env);
  21. /*
  22. - * A simplification for VLMAX
  23. - * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
  24. - * = (VLEN << LMUL) / (8 << SEW)
  25. - * = (VLEN << LMUL) >> (SEW + 3)
  26. - * = VLEN >> (SEW + 3 - LMUL)
  27. + * Encode LMUL to lmul as follows:
  28. + * LMUL vlmul lmul
  29. + * 1 000 0
  30. + * 2 001 1
  31. + * 4 010 2
  32. + * 8 011 3
  33. + * - 100 -
  34. + * 1/8 101 -3
  35. + * 1/4 110 -2
  36. + * 1/2 111 -1
  37. + *
  38. + * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
  39. + * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
  40. + * => VLMAX = vlen >> (1 + 3 - (-3))
  41. + * = 256 >> 7
  42. + * = 2
  43. */
  44. static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
  45. {
  46. - uint8_t sew, lmul;
  47. -
  48. - sew = FIELD_EX64(vtype, VTYPE, VSEW);
  49. - lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
  50. + uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
  51. + int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
  52. return cpu->cfg.vlen >> (sew + 3 - lmul);
  53. }
  54. @@ -428,12 +437,22 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
  55. *cs_base = 0;
  56. if (riscv_has_ext(env, RVV)) {
  57. + /*
  58. + * If env->vl equals to VLMAX, we can use generic vector operation
  59. + * expanders (GVEC) to accerlate the vector operations.
  60. + * However, as LMUL could be a fractional number. The maximum
  61. + * vector size can be operated might be less than 8 bytes,
  62. + * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
  63. + * only when maxsz >= 8 bytes.
  64. + */
  65. uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
  66. - bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
  67. + uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
  68. + uint32_t maxsz = vlmax << sew;
  69. + bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl)
  70. + && (maxsz >= 8);
  71. flags = FIELD_DP32(flags, TB_FLAGS, VILL,
  72. FIELD_EX64(env->vtype, VTYPE, VILL));
  73. - flags = FIELD_DP32(flags, TB_FLAGS, SEW,
  74. - FIELD_EX64(env->vtype, VTYPE, VSEW));
  75. + flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
  76. flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
  77. FIELD_EX64(env->vtype, VTYPE, VLMUL));
  78. flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
  79. diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
  80. index a992bd170d..71f2343d4d 100644
  81. --- a/target/riscv/insn_trans/trans_rvv.c.inc
  82. +++ b/target/riscv/insn_trans/trans_rvv.c.inc
  83. @@ -1268,7 +1268,17 @@ GEN_VEXT_AMO_TRANS(vamomaxuei64_v, MO_64, 35, rwdvm, amo_op, amo_check)
  84. /*
  85. *** Vector Integer Arithmetic Instructions
  86. */
  87. -#define MAXSZ(s) (s->vlen >> (3 - s->lmul))
  88. +
  89. +/*
  90. + * MAXSZ returns the maximum vector size can be operated in bytes,
  91. + * which is used in GVEC IR when vl_eq_vlmax flag is set to true
  92. + * to accerlate vector operation.
  93. + */
  94. +static inline uint32_t MAXSZ(DisasContext *s)
  95. +{
  96. + int scale = s->lmul - 3;
  97. + return scale < 0 ? s->vlen >> -scale : s->vlen << scale;
  98. +}
  99. static bool opivv_check(DisasContext *s, arg_rmrr *a)
  100. {
  101. --
  102. 2.33.1