0096-target-riscv-rvb-generalized-reverse.patch 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. From 24e52b9abc3cd034dd03736dfc2cbdd903cad3d6 Mon Sep 17 00:00:00 2001
  2. From: Frank Chang <frank.chang@sifive.com>
  3. Date: Tue, 20 Oct 2020 18:18:44 +0800
  4. Subject: [PATCH 096/107] target/riscv: rvb: generalized reverse
  5. Signed-off-by: Frank Chang <frank.chang@sifive.com>
  6. Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
  7. ---
  8. target/riscv/bitmanip_helper.c | 71 +++++++++++++++++++++++++
  9. target/riscv/helper.h | 6 +++
  10. target/riscv/insn32-64.decode | 2 +
  11. target/riscv/insn32.decode | 2 +
  12. target/riscv/insn_trans/trans_rvb.c.inc | 29 ++++++++++
  13. target/riscv/meson.build | 1 +
  14. target/riscv/translate.c | 28 ++++++++++
  15. 7 files changed, 139 insertions(+)
  16. create mode 100644 target/riscv/bitmanip_helper.c
  17. diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
  18. new file mode 100644
  19. index 0000000000..1d3235bc0d
  20. --- /dev/null
  21. +++ b/target/riscv/bitmanip_helper.c
  22. @@ -0,0 +1,71 @@
  23. +/*
  24. + * RISC-V Bitmanip Extension Helpers for QEMU.
  25. + *
  26. + * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com
  27. + * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com
  28. + *
  29. + * This program is free software; you can redistribute it and/or modify it
  30. + * under the terms and conditions of the GNU General Public License,
  31. + * version 2 or later, as published by the Free Software Foundation.
  32. + *
  33. + * This program is distributed in the hope it will be useful, but WITHOUT
  34. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  36. + * more details.
  37. + *
  38. + * You should have received a copy of the GNU General Public License along with
  39. + * this program. If not, see <http://www.gnu.org/licenses/>.
  40. + */
  41. +
  42. +#include "qemu/osdep.h"
  43. +#include "qemu/host-utils.h"
  44. +#include "exec/exec-all.h"
  45. +#include "exec/helper-proto.h"
  46. +#include "tcg/tcg.h"
  47. +
  48. +static const uint64_t adjacent_masks[] = {
  49. + dup_const(MO_8, 0x55),
  50. + dup_const(MO_8, 0x33),
  51. + dup_const(MO_8, 0x0f),
  52. + dup_const(MO_16, 0xff),
  53. + dup_const(MO_32, 0xffff),
  54. +#ifdef TARGET_RISCV64
  55. + UINT32_MAX
  56. +#endif
  57. +};
  58. +
  59. +static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift)
  60. +{
  61. + return ((x & mask) << shift) | ((x & ~mask) >> shift);
  62. +}
  63. +
  64. +static target_ulong do_grev(target_ulong rs1,
  65. + target_ulong rs2,
  66. + int bits)
  67. +{
  68. + target_ulong x = rs1;
  69. + int i, shift;
  70. +
  71. + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) {
  72. + if (rs2 & shift) {
  73. + x = do_swap(x, adjacent_masks[i], shift);
  74. + }
  75. + }
  76. +
  77. + return x;
  78. +}
  79. +
  80. +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2)
  81. +{
  82. + return do_grev(rs1, rs2, TARGET_LONG_BITS);
  83. +}
  84. +
  85. +/* RV64-only instruction */
  86. +#ifdef TARGET_RISCV64
  87. +
  88. +target_ulong HELPER(grevw)(target_ulong rs1, target_ulong rs2)
  89. +{
  90. + return do_grev(rs1, rs2, 32);
  91. +}
  92. +
  93. +#endif
  94. diff --git a/target/riscv/helper.h b/target/riscv/helper.h
  95. index 38721ea5ee..e810303aff 100644
  96. --- a/target/riscv/helper.h
  97. +++ b/target/riscv/helper.h
  98. @@ -92,6 +92,12 @@ DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
  99. #endif
  100. DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64)
  101. +/* Bitmanip */
  102. +DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl)
  103. +
  104. +#if defined(TARGET_RISCV64)
  105. +DEF_HELPER_FLAGS_2(grevw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
  106. +#endif
  107. /* Special functions */
  108. DEF_HELPER_3(csrrw, tl, env, tl, tl)
  109. diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
  110. index 52367decc1..18460e023d 100644
  111. --- a/target/riscv/insn32-64.decode
  112. +++ b/target/riscv/insn32-64.decode
  113. @@ -108,6 +108,7 @@ slow 0010000 .......... 001 ..... 0111011 @r
  114. srow 0010000 .......... 101 ..... 0111011 @r
  115. rorw 0110000 .......... 101 ..... 0111011 @r
  116. rolw 0110000 .......... 001 ..... 0111011 @r
  117. +grevw 0110100 .......... 101 ..... 0111011 @r
  118. bsetiw 0010100 .......... 001 ..... 0011011 @sh5
  119. bclriw 0100100 .......... 001 ..... 0011011 @sh5
  120. @@ -115,3 +116,4 @@ binviw 0110100 .......... 001 ..... 0011011 @sh5
  121. sloiw 0010000 .......... 001 ..... 0011011 @sh5
  122. sroiw 0010000 .......... 101 ..... 0011011 @sh5
  123. roriw 0110000 .......... 101 ..... 0011011 @sh5
  124. +greviw 0110100 .......... 101 ..... 0011011 @sh5
  125. diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
  126. index 312a53959e..95c31a362a 100644
  127. --- a/target/riscv/insn32.decode
  128. +++ b/target/riscv/insn32.decode
  129. @@ -715,6 +715,7 @@ slo 0010000 .......... 001 ..... 0110011 @r
  130. sro 0010000 .......... 101 ..... 0110011 @r
  131. ror 0110000 .......... 101 ..... 0110011 @r
  132. rol 0110000 .......... 001 ..... 0110011 @r
  133. +grev 0110100 .......... 101 ..... 0110011 @r
  134. bseti 00101. ........... 001 ..... 0010011 @sh
  135. bclri 01001. ........... 001 ..... 0010011 @sh
  136. @@ -723,3 +724,4 @@ bexti 01001. ........... 101 ..... 0010011 @sh
  137. sloi 00100. ........... 001 ..... 0010011 @sh
  138. sroi 00100. ........... 101 ..... 0010011 @sh
  139. rori 01100. ........... 101 ..... 0010011 @sh
  140. +grevi 01101. ........... 101 ..... 0010011 @sh
  141. diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
  142. index 8a46fde476..286643cd18 100644
  143. --- a/target/riscv/insn_trans/trans_rvb.c.inc
  144. +++ b/target/riscv/insn_trans/trans_rvb.c.inc
  145. @@ -197,6 +197,23 @@ static bool trans_rol(DisasContext *ctx, arg_rol *a)
  146. return gen_shift(ctx, a, tcg_gen_rotl_tl);
  147. }
  148. +static bool trans_grev(DisasContext *ctx, arg_grev *a)
  149. +{
  150. + REQUIRE_EXT(ctx, RVB);
  151. + return gen_shift(ctx, a, gen_helper_grev);
  152. +}
  153. +
  154. +static bool trans_grevi(DisasContext *ctx, arg_grevi *a)
  155. +{
  156. + REQUIRE_EXT(ctx, RVB);
  157. +
  158. + if (a->shamt >= TARGET_LONG_BITS) {
  159. + return false;
  160. + }
  161. +
  162. + return gen_grevi(ctx, a);
  163. +}
  164. +
  165. /* RV64-only instructions */
  166. #ifdef TARGET_RISCV64
  167. @@ -314,4 +331,16 @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
  168. return gen_shiftw(ctx, a, gen_rolw);
  169. }
  170. +static bool trans_grevw(DisasContext *ctx, arg_grevw *a)
  171. +{
  172. + REQUIRE_EXT(ctx, RVB);
  173. + return gen_shiftw(ctx, a, gen_grevw);
  174. +}
  175. +
  176. +static bool trans_greviw(DisasContext *ctx, arg_greviw *a)
  177. +{
  178. + REQUIRE_EXT(ctx, RVB);
  179. + return gen_shiftiw(ctx, a, gen_grevw);
  180. +}
  181. +
  182. #endif
  183. diff --git a/target/riscv/meson.build b/target/riscv/meson.build
  184. index 88ab850682..f7f921ab49 100644
  185. --- a/target/riscv/meson.build
  186. +++ b/target/riscv/meson.build
  187. @@ -21,6 +21,7 @@ riscv_ss.add(files(
  188. 'gdbstub.c',
  189. 'op_helper.c',
  190. 'vector_helper.c',
  191. + 'bitmanip_helper.c',
  192. 'translate.c',
  193. ))
  194. diff --git a/target/riscv/translate.c b/target/riscv/translate.c
  195. index 86f389ba01..b349bf76d9 100644
  196. --- a/target/riscv/translate.c
  197. +++ b/target/riscv/translate.c
  198. @@ -680,6 +680,28 @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
  199. tcg_gen_not_tl(ret, ret);
  200. }
  201. +static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
  202. +{
  203. + TCGv source1 = tcg_temp_new();
  204. + TCGv source2;
  205. +
  206. + gen_get_gpr(source1, a->rs1);
  207. +
  208. + if (a->shamt == (TARGET_LONG_BITS - 8)) {
  209. + /* rev8, byte swaps */
  210. + tcg_gen_bswap_tl(source1, source1);
  211. + } else {
  212. + source2 = tcg_temp_new();
  213. + tcg_gen_movi_tl(source2, a->shamt);
  214. + gen_helper_grev(source1, source1, source2);
  215. + tcg_temp_free(source2);
  216. + }
  217. +
  218. + gen_set_gpr(a->rd, source1);
  219. + tcg_temp_free(source1);
  220. + return true;
  221. +}
  222. +
  223. #ifdef TARGET_RISCV64
  224. static void gen_ctzw(TCGv ret, TCGv arg1)
  225. @@ -754,6 +776,12 @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
  226. tcg_temp_free_i32(t2);
  227. }
  228. +static void gen_grevw(TCGv ret, TCGv arg1, TCGv arg2)
  229. +{
  230. + tcg_gen_ext32u_tl(arg1, arg1);
  231. + gen_helper_grev(ret, arg1, arg2);
  232. +}
  233. +
  234. #endif
  235. static bool gen_arith(DisasContext *ctx, arg_r *a,
  236. --
  237. 2.33.1