0004-target-riscv-Implement-zfh-extension.patch 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. From 9db41d30248bce990151f2c06c65abb845a844a8 Mon Sep 17 00:00:00 2001
  2. From: Kito Cheng <kito.cheng@sifive.com>
  3. Date: Thu, 26 Mar 2020 21:55:37 +0800
  4. Subject: [PATCH 004/107] target/riscv: Implement zfh extension.
  5. Signed-off-by: Kito Cheng <kito.cheng@sifive.com>
  6. Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
  7. ---
  8. target/riscv/fpu_helper.c | 180 ++++++++
  9. target/riscv/helper.h | 34 ++
  10. target/riscv/insn32-64.decode | 6 +
  11. target/riscv/insn32.decode | 32 ++
  12. target/riscv/insn_trans/trans_rvzfh.c.inc | 535 ++++++++++++++++++++++
  13. target/riscv/internals.h | 16 +
  14. target/riscv/translate.c | 18 +
  15. 7 files changed, 821 insertions(+)
  16. create mode 100644 target/riscv/insn_trans/trans_rvzfh.c.inc
  17. diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
  18. index 5d2cec3de3..09d37c1384 100644
  19. --- a/target/riscv/fpu_helper.c
  20. +++ b/target/riscv/fpu_helper.c
  21. @@ -81,6 +81,15 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
  22. set_float_rounding_mode(softrm, &env->fp_status);
  23. }
  24. +static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
  25. + uint64_t rs3, int flags)
  26. +{
  27. + float16 frs1 = check_nanbox_h(rs1);
  28. + float16 frs2 = check_nanbox_h(rs2);
  29. + float16 frs3 = check_nanbox_h(rs3);
  30. + return nanbox_h(float16_muladd(frs1, frs2, frs3, flags, &env->fp_status));
  31. +}
  32. +
  33. static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
  34. uint64_t rs3, int flags)
  35. {
  36. @@ -102,6 +111,12 @@ uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  37. return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
  38. }
  39. +uint64_t helper_fmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  40. + uint64_t frs3)
  41. +{
  42. + return do_fmadd_h(env, frs1, frs2, frs3, 0);
  43. +}
  44. +
  45. uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  46. uint64_t frs3)
  47. {
  48. @@ -115,6 +130,12 @@ uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  49. &env->fp_status);
  50. }
  51. +uint64_t helper_fmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  52. + uint64_t frs3)
  53. +{
  54. + return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_c);
  55. +}
  56. +
  57. uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  58. uint64_t frs3)
  59. {
  60. @@ -128,6 +149,12 @@ uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  61. &env->fp_status);
  62. }
  63. +uint64_t helper_fnmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  64. + uint64_t frs3)
  65. +{
  66. + return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_product);
  67. +}
  68. +
  69. uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  70. uint64_t frs3)
  71. {
  72. @@ -142,6 +169,13 @@ uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  73. float_muladd_negate_product, &env->fp_status);
  74. }
  75. +uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  76. + uint64_t frs3)
  77. +{
  78. + return do_fmadd_h(env, frs1, frs2, frs3,
  79. + float_muladd_negate_c | float_muladd_negate_product);
  80. +}
  81. +
  82. uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  83. {
  84. float32 frs1 = check_nanbox_s(rs1);
  85. @@ -366,3 +400,149 @@ target_ulong helper_fclass_d(uint64_t frs1)
  86. {
  87. return fclass_d(frs1);
  88. }
  89. +
  90. +uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  91. +{
  92. + float16 frs1 = check_nanbox_h(rs1);
  93. + float16 frs2 = check_nanbox_h(rs2);
  94. + return nanbox_h(float16_add(frs1, frs2, &env->fp_status));
  95. +}
  96. +
  97. +uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  98. +{
  99. + float16 frs1 = check_nanbox_h(rs1);
  100. + float16 frs2 = check_nanbox_h(rs2);
  101. + return nanbox_h(float16_sub(frs1, frs2, &env->fp_status));
  102. +}
  103. +
  104. +uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  105. +{
  106. + float16 frs1 = check_nanbox_h(rs1);
  107. + float16 frs2 = check_nanbox_h(rs2);
  108. + return nanbox_h(float16_mul(frs1, frs2, &env->fp_status));
  109. +}
  110. +
  111. +uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  112. +{
  113. + float16 frs1 = check_nanbox_h(rs1);
  114. + float16 frs2 = check_nanbox_h(rs2);
  115. + return nanbox_h(float16_div(frs1, frs2, &env->fp_status));
  116. +}
  117. +
  118. +uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  119. +{
  120. + float16 frs1 = check_nanbox_h(rs1);
  121. + float16 frs2 = check_nanbox_h(rs2);
  122. + return nanbox_h(float16_minnum_noprop(frs1, frs2, &env->fp_status));
  123. +}
  124. +
  125. +uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  126. +{
  127. + float16 frs1 = check_nanbox_h(rs1);
  128. + float16 frs2 = check_nanbox_h(rs2);
  129. + return nanbox_h(float16_maxnum_noprop(frs1, frs2, &env->fp_status));
  130. +}
  131. +
  132. +uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
  133. +{
  134. + float16 frs1 = check_nanbox_h(rs1);
  135. + return nanbox_h(float16_sqrt(frs1, &env->fp_status));
  136. +}
  137. +
  138. +target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  139. +{
  140. + float16 frs1 = check_nanbox_h(rs1);
  141. + float16 frs2 = check_nanbox_h(rs2);
  142. + return float16_le(frs1, frs2, &env->fp_status);
  143. +}
  144. +
  145. +target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  146. +{
  147. + float16 frs1 = check_nanbox_h(rs1);
  148. + float16 frs2 = check_nanbox_h(rs2);
  149. + return float16_lt(frs1, frs2, &env->fp_status);
  150. +}
  151. +
  152. +target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
  153. +{
  154. + float16 frs1 = check_nanbox_h(rs1);
  155. + float16 frs2 = check_nanbox_h(rs2);
  156. + return float16_eq_quiet(frs1, frs2, &env->fp_status);
  157. +}
  158. +
  159. +target_ulong helper_fclass_h(uint64_t rs1)
  160. +{
  161. + float16 frs1 = check_nanbox_h(rs1);
  162. + return fclass_h(frs1);
  163. +}
  164. +
  165. +target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
  166. +{
  167. + float16 frs1 = check_nanbox_h(rs1);
  168. + return float16_to_int32(frs1, &env->fp_status);
  169. +}
  170. +
  171. +target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1)
  172. +{
  173. + float16 frs1 = check_nanbox_h(rs1);
  174. + return (int32_t)float16_to_uint32(frs1, &env->fp_status);
  175. +}
  176. +
  177. +#if defined(TARGET_RISCV64)
  178. +uint64_t helper_fcvt_l_h(CPURISCVState *env, uint64_t rs1)
  179. +{
  180. + float16 frs1 = check_nanbox_h(rs1);
  181. + return float16_to_int64(frs1, &env->fp_status);
  182. +}
  183. +
  184. +uint64_t helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1)
  185. +{
  186. + float16 frs1 = check_nanbox_h(rs1);
  187. + return float16_to_uint64(frs1, &env->fp_status);
  188. +}
  189. +#endif
  190. +
  191. +uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1)
  192. +{
  193. + return nanbox_h(int32_to_float16((int32_t)rs1, &env->fp_status));
  194. +}
  195. +
  196. +uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1)
  197. +{
  198. + return nanbox_h(uint32_to_float16((uint32_t)rs1, &env->fp_status));
  199. +}
  200. +
  201. +#if defined(TARGET_RISCV64)
  202. +uint64_t helper_fcvt_h_l(CPURISCVState *env, uint64_t rs1)
  203. +{
  204. + return nanbox_h(int64_to_float16(rs1, &env->fp_status));
  205. +}
  206. +
  207. +uint64_t helper_fcvt_h_lu(CPURISCVState *env, uint64_t rs1)
  208. +{
  209. + return nanbox_h(uint64_to_float16(rs1, &env->fp_status));
  210. +}
  211. +#endif
  212. +
  213. +uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1)
  214. +{
  215. + float32 frs1 = check_nanbox_s(rs1);
  216. + return nanbox_h(float32_to_float16(frs1, true, &env->fp_status));
  217. +}
  218. +
  219. +uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1)
  220. +{
  221. + float16 frs1 = check_nanbox_h(rs1);
  222. + return nanbox_s(float16_to_float32(frs1, true, &env->fp_status));
  223. +}
  224. +
  225. +uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1)
  226. +{
  227. + return nanbox_h(float64_to_float16(rs1, true, &env->fp_status));
  228. +}
  229. +
  230. +uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1)
  231. +{
  232. + float16 frs1 = check_nanbox_h(rs1);
  233. + return float16_to_float64(frs1, true, &env->fp_status);
  234. +}
  235. diff --git a/target/riscv/helper.h b/target/riscv/helper.h
  236. index e3f3f41e89..1104a3540a 100644
  237. --- a/target/riscv/helper.h
  238. +++ b/target/riscv/helper.h
  239. @@ -7,12 +7,16 @@ DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
  240. /* Floating Point - fused */
  241. DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  242. DEF_HELPER_FLAGS_4(fmadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  243. +DEF_HELPER_FLAGS_4(fmadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  244. DEF_HELPER_FLAGS_4(fmsub_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  245. DEF_HELPER_FLAGS_4(fmsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  246. +DEF_HELPER_FLAGS_4(fmsub_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  247. DEF_HELPER_FLAGS_4(fnmsub_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  248. DEF_HELPER_FLAGS_4(fnmsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  249. +DEF_HELPER_FLAGS_4(fnmsub_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  250. DEF_HELPER_FLAGS_4(fnmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  251. DEF_HELPER_FLAGS_4(fnmadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  252. +DEF_HELPER_FLAGS_4(fnmadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
  253. /* Floating Point - Single Precision */
  254. DEF_HELPER_FLAGS_3(fadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
  255. @@ -58,6 +62,36 @@ DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, i64)
  256. DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, i64)
  257. DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
  258. +/* Floating Point - Half Precision */
  259. +DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
  260. +DEF_HELPER_FLAGS_3(fsub_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
  261. +DEF_HELPER_FLAGS_3(fmul_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
  262. +DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
  263. +DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
  264. +DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
  265. +DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64)
  266. +DEF_HELPER_FLAGS_3(fle_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
  267. +DEF_HELPER_FLAGS_3(flt_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
  268. +DEF_HELPER_FLAGS_3(feq_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
  269. +DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64)
  270. +DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64)
  271. +DEF_HELPER_FLAGS_2(fcvt_d_h, TCG_CALL_NO_RWG, i64, env, i64)
  272. +DEF_HELPER_FLAGS_2(fcvt_h_d, TCG_CALL_NO_RWG, i64, env, i64)
  273. +DEF_HELPER_FLAGS_2(fcvt_w_h, TCG_CALL_NO_RWG, tl, env, i64)
  274. +DEF_HELPER_FLAGS_2(fcvt_wu_h, TCG_CALL_NO_RWG, tl, env, i64)
  275. +#if defined(TARGET_RISCV64)
  276. +DEF_HELPER_FLAGS_2(fcvt_l_h, TCG_CALL_NO_RWG, tl, env, i64)
  277. +DEF_HELPER_FLAGS_2(fcvt_lu_h, TCG_CALL_NO_RWG, tl, env, i64)
  278. +#endif
  279. +DEF_HELPER_FLAGS_2(fcvt_h_w, TCG_CALL_NO_RWG, i64, env, tl)
  280. +DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl)
  281. +#if defined(TARGET_RISCV64)
  282. +DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
  283. +DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
  284. +#endif
  285. +DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64)
  286. +
  287. +
  288. /* Special functions */
  289. DEF_HELPER_3(csrrw, tl, env, tl, tl)
  290. DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
  291. diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
  292. index 8157dee8b7..1f5d0b7a5c 100644
  293. --- a/target/riscv/insn32-64.decode
  294. +++ b/target/riscv/insn32-64.decode
  295. @@ -86,3 +86,9 @@ fmv_d_x 1111001 00000 ..... 000 ..... 1010011 @r2
  296. hlv_wu 0110100 00001 ..... 100 ..... 1110011 @r2
  297. hlv_d 0110110 00000 ..... 100 ..... 1110011 @r2
  298. hsv_d 0110111 ..... ..... 100 00000 1110011 @r2_s
  299. +
  300. +# *** RV64Zfh Standard Extension (in addition to RV32Zfh) ***
  301. +fcvt_l_h 1100010 00010 ..... ... ..... 1010011 @r2_rm
  302. +fcvt_lu_h 1100010 00011 ..... ... ..... 1010011 @r2_rm
  303. +fcvt_h_l 1101010 00010 ..... ... ..... 1010011 @r2_rm
  304. +fcvt_h_lu 1101010 00011 ..... ... ..... 1010011 @r2_rm
  305. diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
  306. index 84080dd18c..8d9064a7a0 100644
  307. --- a/target/riscv/insn32.decode
  308. +++ b/target/riscv/insn32.decode
  309. @@ -592,3 +592,35 @@ vcompress_vm 010111 - ..... ..... 010 ..... 1010111 @r
  310. vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm
  311. vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
  312. +
  313. +# *** RV32Zfh Extension ***
  314. +flh ............ ..... 001 ..... 0000111 @i
  315. +fsh ....... ..... ..... 001 ..... 0100111 @s
  316. +fmadd_h ..... 10 ..... ..... ... ..... 1000011 @r4_rm
  317. +fmsub_h ..... 10 ..... ..... ... ..... 1000111 @r4_rm
  318. +fnmsub_h ..... 10 ..... ..... ... ..... 1001011 @r4_rm
  319. +fnmadd_h ..... 10 ..... ..... ... ..... 1001111 @r4_rm
  320. +fadd_h 0000010 ..... ..... ... ..... 1010011 @r_rm
  321. +fsub_h 0000110 ..... ..... ... ..... 1010011 @r_rm
  322. +fmul_h 0001010 ..... ..... ... ..... 1010011 @r_rm
  323. +fdiv_h 0001110 ..... ..... ... ..... 1010011 @r_rm
  324. +fsqrt_h 0101110 00000 ..... ... ..... 1010011 @r2_rm
  325. +fsgnj_h 0010010 ..... ..... 000 ..... 1010011 @r
  326. +fsgnjn_h 0010010 ..... ..... 001 ..... 1010011 @r
  327. +fsgnjx_h 0010010 ..... ..... 010 ..... 1010011 @r
  328. +fmin_h 0010110 ..... ..... 000 ..... 1010011 @r
  329. +fmax_h 0010110 ..... ..... 001 ..... 1010011 @r
  330. +fcvt_h_s 0100010 00000 ..... ... ..... 1010011 @r2_rm
  331. +fcvt_s_h 0100000 00010 ..... ... ..... 1010011 @r2_rm
  332. +fcvt_h_d 0100010 00001 ..... ... ..... 1010011 @r2_rm
  333. +fcvt_d_h 0100001 00010 ..... ... ..... 1010011 @r2_rm
  334. +fcvt_w_h 1100010 00000 ..... ... ..... 1010011 @r2_rm
  335. +fcvt_wu_h 1100010 00001 ..... ... ..... 1010011 @r2_rm
  336. +fmv_x_h 1110010 00000 ..... 000 ..... 1010011 @r2
  337. +feq_h 1010010 ..... ..... 010 ..... 1010011 @r
  338. +flt_h 1010010 ..... ..... 001 ..... 1010011 @r
  339. +fle_h 1010010 ..... ..... 000 ..... 1010011 @r
  340. +fclass_h 1110010 00000 ..... 001 ..... 1010011 @r2
  341. +fcvt_h_w 1101010 00000 ..... ... ..... 1010011 @r2_rm
  342. +fcvt_h_wu 1101010 00001 ..... ... ..... 1010011 @r2_rm
  343. +fmv_h_x 1111010 00000 ..... 000 ..... 1010011 @r2
  344. diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
  345. new file mode 100644
  346. index 0000000000..4c483f6372
  347. --- /dev/null
  348. +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
  349. @@ -0,0 +1,535 @@
  350. +/*
  351. + * RISC-V translation routines for the RV64Zfh Standard Extension.
  352. + *
  353. + * Copyright (c) 2020 Chih-Min Chao, chihmin.chao@sifive.com
  354. + *
  355. + * This program is free software; you can redistribute it and/or modify it
  356. + * under the terms and conditions of the GNU General Public License,
  357. + * version 2 or later, as published by the Free Software Foundation.
  358. + *
  359. + * This program is distributed in the hope it will be useful, but WITHOUT
  360. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  361. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  362. + * more details.
  363. + *
  364. + * You should have received a copy of the GNU General Public License along with
  365. + * this program. If not, see <http://www.gnu.org/licenses/>.
  366. + */
  367. +
  368. +#define REQUIRE_ZFH(ctx) do { \
  369. + return ctx->ext_zfh; \
  370. +} while (0)
  371. +
  372. +static bool trans_flh(DisasContext *ctx, arg_flh *a)
  373. +{
  374. + REQUIRE_FPU;
  375. + REQUIRE_ZFH(ctx);
  376. +
  377. + TCGv t0 = tcg_temp_new();
  378. + gen_get_gpr(t0, a->rs1);
  379. +
  380. + tcg_gen_addi_tl(t0, t0, a->imm);
  381. +
  382. + tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUW);
  383. +
  384. + gen_nanbox_h(cpu_fpr[a->rd], cpu_fpr[a->rd]);
  385. +
  386. + mark_fs_dirty(ctx);
  387. + tcg_temp_free(t0);
  388. + return true;
  389. +}
  390. +
  391. +static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
  392. +{
  393. + REQUIRE_FPU;
  394. + REQUIRE_ZFH(ctx);
  395. +
  396. + TCGv t0 = tcg_temp_new();
  397. + gen_get_gpr(t0, a->rs1);
  398. + tcg_gen_addi_tl(t0, t0, a->imm);
  399. +
  400. + tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUW);
  401. +
  402. + mark_fs_dirty(ctx);
  403. + tcg_temp_free(t0);
  404. + return true;
  405. +}
  406. +
  407. +static bool trans_fmadd_h(DisasContext *ctx, arg_fmadd_h *a)
  408. +{
  409. + REQUIRE_FPU;
  410. + REQUIRE_ZFH(ctx);
  411. + gen_set_rm(ctx, a->rm);
  412. + gen_helper_fmadd_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
  413. + cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
  414. + mark_fs_dirty(ctx);
  415. + return true;
  416. +}
  417. +
  418. +static bool trans_fmsub_h(DisasContext *ctx, arg_fmsub_h *a)
  419. +{
  420. + REQUIRE_FPU;
  421. + REQUIRE_ZFH(ctx);
  422. + gen_set_rm(ctx, a->rm);
  423. + gen_helper_fmsub_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
  424. + cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
  425. + mark_fs_dirty(ctx);
  426. + return true;
  427. +}
  428. +
  429. +static bool trans_fnmsub_h(DisasContext *ctx, arg_fnmsub_h *a)
  430. +{
  431. + REQUIRE_FPU;
  432. + REQUIRE_ZFH(ctx);
  433. + gen_set_rm(ctx, a->rm);
  434. + gen_helper_fnmsub_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
  435. + cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
  436. + mark_fs_dirty(ctx);
  437. + return true;
  438. +}
  439. +
  440. +static bool trans_fnmadd_h(DisasContext *ctx, arg_fnmadd_h *a)
  441. +{
  442. + REQUIRE_FPU;
  443. + REQUIRE_ZFH(ctx);
  444. + gen_set_rm(ctx, a->rm);
  445. + gen_helper_fnmadd_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
  446. + cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
  447. + mark_fs_dirty(ctx);
  448. + return true;
  449. +}
  450. +
  451. +static bool trans_fadd_h(DisasContext *ctx, arg_fadd_h *a)
  452. +{
  453. + REQUIRE_FPU;
  454. + REQUIRE_ZFH(ctx);
  455. +
  456. + gen_set_rm(ctx, a->rm);
  457. + gen_helper_fadd_h(cpu_fpr[a->rd], cpu_env,
  458. + cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
  459. + mark_fs_dirty(ctx);
  460. + return true;
  461. +}
  462. +
  463. +static bool trans_fsub_h(DisasContext *ctx, arg_fsub_h *a)
  464. +{
  465. + REQUIRE_FPU;
  466. + REQUIRE_ZFH(ctx);
  467. +
  468. + gen_set_rm(ctx, a->rm);
  469. + gen_helper_fsub_h(cpu_fpr[a->rd], cpu_env,
  470. + cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
  471. + mark_fs_dirty(ctx);
  472. + return true;
  473. +}
  474. +
  475. +static bool trans_fmul_h(DisasContext *ctx, arg_fmul_h *a)
  476. +{
  477. + REQUIRE_FPU;
  478. + REQUIRE_ZFH(ctx);
  479. +
  480. + gen_set_rm(ctx, a->rm);
  481. + gen_helper_fmul_h(cpu_fpr[a->rd], cpu_env,
  482. + cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
  483. + mark_fs_dirty(ctx);
  484. + return true;
  485. +}
  486. +
  487. +static bool trans_fdiv_h(DisasContext *ctx, arg_fdiv_h *a)
  488. +{
  489. + REQUIRE_FPU;
  490. + REQUIRE_ZFH(ctx);
  491. +
  492. + gen_set_rm(ctx, a->rm);
  493. + gen_helper_fdiv_h(cpu_fpr[a->rd], cpu_env,
  494. + cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
  495. + mark_fs_dirty(ctx);
  496. + return true;
  497. +}
  498. +
  499. +static bool trans_fsqrt_h(DisasContext *ctx, arg_fsqrt_h *a)
  500. +{
  501. + REQUIRE_FPU;
  502. + REQUIRE_ZFH(ctx);
  503. +
  504. + gen_set_rm(ctx, a->rm);
  505. + gen_helper_fsqrt_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
  506. + mark_fs_dirty(ctx);
  507. + return true;
  508. +}
  509. +
  510. +static bool trans_fsgnj_h(DisasContext *ctx, arg_fsgnj_h *a)
  511. +{
  512. + REQUIRE_FPU;
  513. + REQUIRE_ZFH(ctx);
  514. +
  515. + if (a->rs1 == a->rs2) { /* FMOV */
  516. + gen_check_nanbox_h(cpu_fpr[a->rd], cpu_fpr[a->rs1]);
  517. + } else {
  518. + TCGv_i64 rs1 = tcg_temp_new_i64();
  519. + TCGv_i64 rs2 = tcg_temp_new_i64();
  520. +
  521. + gen_check_nanbox_h(rs1, cpu_fpr[a->rs1]);
  522. + gen_check_nanbox_h(rs2, cpu_fpr[a->rs2]);
  523. +
  524. + /* This formulation retains the nanboxing of rs2. */
  525. + tcg_gen_deposit_i64(cpu_fpr[a->rd], rs2, rs1, 0, 15);
  526. + tcg_temp_free_i64(rs1);
  527. + tcg_temp_free_i64(rs2);
  528. + }
  529. +
  530. + mark_fs_dirty(ctx);
  531. + return true;
  532. +}
  533. +
  534. +static bool trans_fsgnjn_h(DisasContext *ctx, arg_fsgnjn_h *a)
  535. +{
  536. + TCGv_i64 rs1, rs2, mask;
  537. +
  538. + REQUIRE_FPU;
  539. + REQUIRE_ZFH(ctx);
  540. +
  541. + rs1 = tcg_temp_new_i64();
  542. + gen_check_nanbox_h(rs1, cpu_fpr[a->rs1]);
  543. +
  544. + if (a->rs1 == a->rs2) { /* FNEG */
  545. + tcg_gen_xori_i64(cpu_fpr[a->rd], rs1, MAKE_64BIT_MASK(15, 1));
  546. + } else {
  547. + rs2 = tcg_temp_new_i64();
  548. + gen_check_nanbox_h(rs2, cpu_fpr[a->rs2]);
  549. +
  550. + /*
  551. + * Replace bit 15 in rs1 with inverse in rs2.
  552. + * This formulation retains the nanboxing of rs1.
  553. + */
  554. + mask = tcg_const_i64(~MAKE_64BIT_MASK(15, 1));
  555. + tcg_gen_not_i64(rs2, rs2);
  556. + tcg_gen_andc_i64(rs2, rs2, mask);
  557. + tcg_gen_and_i64(rs1, mask, rs1);
  558. + tcg_gen_or_i64(cpu_fpr[a->rd], rs1, rs2);
  559. +
  560. + tcg_temp_free_i64(mask);
  561. + tcg_temp_free_i64(rs2);
  562. + }
  563. + mark_fs_dirty(ctx);
  564. + return true;
  565. +}
  566. +
  567. +static bool trans_fsgnjx_h(DisasContext *ctx, arg_fsgnjx_h *a)
  568. +{
  569. + TCGv_i64 rs1, rs2;
  570. +
  571. + REQUIRE_FPU;
  572. + REQUIRE_ZFH(ctx);
  573. +
  574. + rs1 = tcg_temp_new_i64();
  575. + gen_check_nanbox_s(rs1, cpu_fpr[a->rs1]);
  576. +
  577. + if (a->rs1 == a->rs2) { /* FABS */
  578. + tcg_gen_andi_i64(cpu_fpr[a->rd], rs1, ~MAKE_64BIT_MASK(15, 1));
  579. + } else {
  580. + rs2 = tcg_temp_new_i64();
  581. + gen_check_nanbox_s(rs2, cpu_fpr[a->rs2]);
  582. +
  583. + /*
  584. + * Xor bit 15 in rs1 with that in rs2.
  585. + * This formulation retains the nanboxing of rs1.
  586. + */
  587. + tcg_gen_andi_i64(rs2, rs2, MAKE_64BIT_MASK(15, 1));
  588. + tcg_gen_xor_i64(cpu_fpr[a->rd], rs1, rs2);
  589. +
  590. + tcg_temp_free_i64(rs2);
  591. + }
  592. +
  593. + mark_fs_dirty(ctx);
  594. + return true;
  595. +}
  596. +
  597. +static bool trans_fmin_h(DisasContext *ctx, arg_fmin_h *a)
  598. +{
  599. + REQUIRE_FPU;
  600. + REQUIRE_ZFH(ctx);
  601. +
  602. + gen_helper_fmin_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
  603. + cpu_fpr[a->rs2]);
  604. + mark_fs_dirty(ctx);
  605. + return true;
  606. +}
  607. +
  608. +static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a)
  609. +{
  610. + REQUIRE_FPU;
  611. + REQUIRE_ZFH(ctx);
  612. +
  613. + gen_helper_fmax_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
  614. + cpu_fpr[a->rs2]);
  615. + mark_fs_dirty(ctx);
  616. + return true;
  617. +}
  618. +
  619. +static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
  620. +{
  621. + REQUIRE_FPU;
  622. + REQUIRE_ZFH(ctx);
  623. +
  624. + gen_set_rm(ctx, a->rm);
  625. + gen_helper_fcvt_s_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
  626. +
  627. + mark_fs_dirty(ctx);
  628. +
  629. + return true;
  630. +}
  631. +
  632. +static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
  633. +{
  634. + REQUIRE_FPU;
  635. + REQUIRE_ZFH(ctx);
  636. + REQUIRE_EXT(ctx, RVD);
  637. +
  638. + gen_set_rm(ctx, a->rm);
  639. + gen_helper_fcvt_d_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
  640. +
  641. + mark_fs_dirty(ctx);
  642. +
  643. +
  644. + return true;
  645. +}
  646. +
  647. +static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
  648. +{
  649. + REQUIRE_FPU;
  650. + REQUIRE_ZFH(ctx);
  651. +
  652. + gen_set_rm(ctx, a->rm);
  653. + gen_helper_fcvt_h_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
  654. +
  655. + mark_fs_dirty(ctx);
  656. +
  657. + return true;
  658. +}
  659. +
  660. +static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a)
  661. +{
  662. + REQUIRE_FPU;
  663. + REQUIRE_ZFH(ctx);
  664. + REQUIRE_EXT(ctx, RVD);
  665. +
  666. + gen_set_rm(ctx, a->rm);
  667. + gen_helper_fcvt_h_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
  668. +
  669. + mark_fs_dirty(ctx);
  670. +
  671. + return true;
  672. +}
  673. +
  674. +static bool trans_feq_h(DisasContext *ctx, arg_feq_h *a)
  675. +{
  676. + REQUIRE_FPU;
  677. + REQUIRE_ZFH(ctx);
  678. + TCGv t0 = tcg_temp_new();
  679. + gen_helper_feq_h(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
  680. + gen_set_gpr(a->rd, t0);
  681. + tcg_temp_free(t0);
  682. + return true;
  683. +}
  684. +
  685. +static bool trans_flt_h(DisasContext *ctx, arg_flt_h *a)
  686. +{
  687. + REQUIRE_FPU;
  688. + REQUIRE_ZFH(ctx);
  689. + TCGv t0 = tcg_temp_new();
  690. + gen_helper_flt_h(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
  691. + gen_set_gpr(a->rd, t0);
  692. + tcg_temp_free(t0);
  693. + return true;
  694. +}
  695. +
  696. +static bool trans_fle_h(DisasContext *ctx, arg_fle_h *a)
  697. +{
  698. + REQUIRE_FPU;
  699. + REQUIRE_ZFH(ctx);
  700. + TCGv t0 = tcg_temp_new();
  701. + gen_helper_fle_h(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
  702. + gen_set_gpr(a->rd, t0);
  703. + tcg_temp_free(t0);
  704. + return true;
  705. +}
  706. +
  707. +static bool trans_fclass_h(DisasContext *ctx, arg_fclass_h *a)
  708. +{
  709. + REQUIRE_FPU;
  710. + REQUIRE_ZFH(ctx);
  711. +
  712. + TCGv t0 = tcg_temp_new();
  713. +
  714. + gen_helper_fclass_h(t0, cpu_fpr[a->rs1]);
  715. +
  716. + gen_set_gpr(a->rd, t0);
  717. + tcg_temp_free(t0);
  718. +
  719. + return true;
  720. +}
  721. +
  722. +static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a)
  723. +{
  724. + REQUIRE_FPU;
  725. + REQUIRE_ZFH(ctx);
  726. +
  727. + TCGv t0 = tcg_temp_new();
  728. + gen_set_rm(ctx, a->rm);
  729. + gen_helper_fcvt_w_h(t0, cpu_env, cpu_fpr[a->rs1]);
  730. + gen_set_gpr(a->rd, t0);
  731. + tcg_temp_free(t0);
  732. +
  733. + return true;
  734. +}
  735. +
  736. +static bool trans_fcvt_wu_h(DisasContext *ctx, arg_fcvt_wu_h *a)
  737. +{
  738. + REQUIRE_FPU;
  739. + REQUIRE_ZFH(ctx);
  740. +
  741. + TCGv t0 = tcg_temp_new();
  742. + gen_set_rm(ctx, a->rm);
  743. + gen_helper_fcvt_wu_h(t0, cpu_env, cpu_fpr[a->rs1]);
  744. + gen_set_gpr(a->rd, t0);
  745. + tcg_temp_free(t0);
  746. +
  747. + return true;
  748. +}
  749. +
  750. +static bool trans_fcvt_h_w(DisasContext *ctx, arg_fcvt_h_w *a)
  751. +{
  752. + REQUIRE_FPU;
  753. + REQUIRE_ZFH(ctx);
  754. +
  755. + TCGv t0 = tcg_temp_new();
  756. + gen_get_gpr(t0, a->rs1);
  757. +
  758. + gen_set_rm(ctx, a->rm);
  759. + gen_helper_fcvt_h_w(cpu_fpr[a->rd], cpu_env, t0);
  760. +
  761. + mark_fs_dirty(ctx);
  762. + tcg_temp_free(t0);
  763. +
  764. + return true;
  765. +}
  766. +
  767. +static bool trans_fcvt_h_wu(DisasContext *ctx, arg_fcvt_h_wu *a)
  768. +{
  769. + REQUIRE_FPU;
  770. + REQUIRE_ZFH(ctx);
  771. +
  772. + TCGv t0 = tcg_temp_new();
  773. + gen_get_gpr(t0, a->rs1);
  774. +
  775. + gen_set_rm(ctx, a->rm);
  776. + gen_helper_fcvt_h_wu(cpu_fpr[a->rd], cpu_env, t0);
  777. +
  778. + mark_fs_dirty(ctx);
  779. + tcg_temp_free(t0);
  780. +
  781. + return true;
  782. +}
  783. +
  784. +static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
  785. +{
  786. + REQUIRE_FPU;
  787. + REQUIRE_ZFH(ctx);
  788. +
  789. + TCGv t0 = tcg_temp_new();
  790. +
  791. +#if defined(TARGET_RISCV64)
  792. + tcg_gen_ext16s_tl(t0, cpu_fpr[a->rs1]); // 16 bits->64 bits
  793. +#else
  794. + tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]); //16 bits->32 bits
  795. + tcg_gen_ext16s_tl(t0, t0);
  796. +#endif
  797. +
  798. + gen_set_gpr(a->rd, t0);
  799. + tcg_temp_free(t0);
  800. +
  801. + return true;
  802. +}
  803. +
  804. +static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a)
  805. +{
  806. + REQUIRE_FPU;
  807. + REQUIRE_ZFH(ctx);
  808. +
  809. + TCGv t0 = tcg_temp_new();
  810. + gen_get_gpr(t0, a->rs1);
  811. +
  812. + tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0);
  813. + gen_nanbox_h(cpu_fpr[a->rd], cpu_fpr[a->rd]);
  814. +
  815. + mark_fs_dirty(ctx);
  816. + tcg_temp_free(t0);
  817. +
  818. + return true;
  819. +}
  820. +
  821. +#ifdef TARGET_RISCV64
  822. +
  823. +static bool trans_fcvt_l_h(DisasContext *ctx, arg_fcvt_l_h *a)
  824. +{
  825. + REQUIRE_FPU;
  826. + REQUIRE_ZFH(ctx);
  827. +
  828. + TCGv t0 = tcg_temp_new();
  829. + gen_set_rm(ctx, a->rm);
  830. + gen_helper_fcvt_l_h(t0, cpu_env, cpu_fpr[a->rs1]);
  831. + gen_set_gpr(a->rd, t0);
  832. + tcg_temp_free(t0);
  833. +
  834. + return true;
  835. +}
  836. +
  837. +static bool trans_fcvt_lu_h(DisasContext *ctx, arg_fcvt_lu_h *a)
  838. +{
  839. + REQUIRE_FPU;
  840. + REQUIRE_ZFH(ctx);
  841. +
  842. + TCGv t0 = tcg_temp_new();
  843. + gen_set_rm(ctx, a->rm);
  844. + gen_helper_fcvt_lu_h(t0, cpu_env, cpu_fpr[a->rs1]);
  845. + gen_set_gpr(a->rd, t0);
  846. + tcg_temp_free(t0);
  847. +
  848. + return true;
  849. +}
  850. +
  851. +static bool trans_fcvt_h_l(DisasContext *ctx, arg_fcvt_h_l *a)
  852. +{
  853. + REQUIRE_FPU;
  854. + REQUIRE_ZFH(ctx);
  855. +
  856. + TCGv t0 = tcg_temp_new();
  857. + gen_get_gpr(t0, a->rs1);
  858. +
  859. + gen_set_rm(ctx, a->rm);
  860. + gen_helper_fcvt_h_l(cpu_fpr[a->rd], cpu_env, t0);
  861. +
  862. + mark_fs_dirty(ctx);
  863. + tcg_temp_free(t0);
  864. +
  865. + return true;
  866. +}
  867. +
  868. +static bool trans_fcvt_h_lu(DisasContext *ctx, arg_fcvt_h_lu *a)
  869. +{
  870. + REQUIRE_FPU;
  871. + REQUIRE_ZFH(ctx);
  872. +
  873. + TCGv t0 = tcg_temp_new();
  874. + gen_get_gpr(t0, a->rs1);
  875. +
  876. + gen_set_rm(ctx, a->rm);
  877. + gen_helper_fcvt_h_lu(cpu_fpr[a->rd], cpu_env, t0);
  878. +
  879. + mark_fs_dirty(ctx);
  880. + tcg_temp_free(t0);
  881. +
  882. + return true;
  883. +}
  884. +#endif
  885. diff --git a/target/riscv/internals.h b/target/riscv/internals.h
  886. index b15ad394bb..bce91da11a 100644
  887. --- a/target/riscv/internals.h
  888. +++ b/target/riscv/internals.h
  889. @@ -58,4 +58,20 @@ static inline float32 check_nanbox_s(uint64_t f)
  890. }
  891. }
  892. +static inline uint64_t nanbox_h(float16 f)
  893. +{
  894. + return f | MAKE_64BIT_MASK(16, 48);
  895. +}
  896. +
  897. +static inline float16 check_nanbox_h(uint64_t f)
  898. +{
  899. + uint64_t mask = MAKE_64BIT_MASK(16, 48);
  900. +
  901. + if (likely((f & mask) == mask)) {
  902. + return (uint16_t)f;
  903. + } else {
  904. + return 0x7E00u; /* default qnan */
  905. + }
  906. +}
  907. +
  908. #endif
  909. diff --git a/target/riscv/translate.c b/target/riscv/translate.c
  910. index 2f9f5ccc62..045475a63b 100644
  911. --- a/target/riscv/translate.c
  912. +++ b/target/riscv/translate.c
  913. @@ -56,6 +56,7 @@ typedef struct DisasContext {
  914. to reset this known value. */
  915. int frm;
  916. bool ext_ifencei;
  917. + bool ext_zfh;
  918. bool hlsx;
  919. /* vector extension */
  920. bool vill;
  921. @@ -89,6 +90,11 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
  922. tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32));
  923. }
  924. +static void gen_nanbox_h(TCGv_i64 out, TCGv_i64 in)
  925. +{
  926. + tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(16, 48));
  927. +}
  928. +
  929. /*
  930. * A narrow n-bit operation, where n < FLEN, checks that input operands
  931. * are correctly Nan-boxed, i.e., all upper FLEN - n bits are 1.
  932. @@ -97,6 +103,16 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
  933. *
  934. * Here, the result is always nan-boxed, even the canonical nan.
  935. */
  936. +static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in)
  937. +{
  938. + TCGv_i64 t_max = tcg_const_i64(0xffffffffffff0000ull);
  939. + TCGv_i64 t_nan = tcg_const_i64(0xffffffffffff7e00ull);
  940. +
  941. + tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
  942. + tcg_temp_free_i64(t_max);
  943. + tcg_temp_free_i64(t_nan);
  944. +}
  945. +
  946. static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
  947. {
  948. TCGv_i64 t_max = tcg_const_i64(0xffffffff00000000ull);
  949. @@ -589,6 +605,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
  950. #include "insn_trans/trans_rvd.c.inc"
  951. #include "insn_trans/trans_rvh.c.inc"
  952. #include "insn_trans/trans_rvv.c.inc"
  953. +#include "insn_trans/trans_rvzfh.c.inc"
  954. #include "insn_trans/trans_privileged.c.inc"
  955. /* Include the auto-generated decoder for 16 bit insn */
  956. @@ -640,6 +657,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
  957. ctx->misa = env->misa;
  958. ctx->frm = -1; /* unknown rounding mode */
  959. ctx->ext_ifencei = cpu->cfg.ext_ifencei;
  960. + ctx->ext_zfh = cpu->cfg.ext_zfh;
  961. ctx->vlen = cpu->cfg.vlen;
  962. ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
  963. ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
  964. --
  965. 2.33.1