1a47842d1SChristoph Müllner/* 2a47842d1SChristoph Müllner * RISC-V translation routines for the Zfa Standard Extension. 3a47842d1SChristoph Müllner * 4a47842d1SChristoph Müllner * Copyright (c) 2023 Christoph Müllner, christoph.muellner@vrull.eu 5a47842d1SChristoph Müllner * 6a47842d1SChristoph Müllner * This program is free software; you can redistribute it and/or modify it 7a47842d1SChristoph Müllner * under the terms and conditions of the GNU General Public License, 8a47842d1SChristoph Müllner * version 2 or later, as published by the Free Software Foundation. 9a47842d1SChristoph Müllner * 10a47842d1SChristoph Müllner * This program is distributed in the hope it will be useful, but WITHOUT 11a47842d1SChristoph Müllner * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12a47842d1SChristoph Müllner * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13a47842d1SChristoph Müllner * more details. 14a47842d1SChristoph Müllner * 15a47842d1SChristoph Müllner * You should have received a copy of the GNU General Public License along with 16a47842d1SChristoph Müllner * this program. If not, see <http://www.gnu.org/licenses/>. 17a47842d1SChristoph Müllner */ 18a47842d1SChristoph Müllner 19a47842d1SChristoph Müllner#define REQUIRE_ZFA(ctx) do { \ 20a47842d1SChristoph Müllner if (!ctx->cfg_ptr->ext_zfa) { \ 21a47842d1SChristoph Müllner return false; \ 22a47842d1SChristoph Müllner } \ 23a47842d1SChristoph Müllner} while (0) 24a47842d1SChristoph Müllner 25a47842d1SChristoph Müllner#define REQUIRE_ZFH(ctx) do { \ 26a47842d1SChristoph Müllner if (!ctx->cfg_ptr->ext_zfh) { \ 27a47842d1SChristoph Müllner return false; \ 28a47842d1SChristoph Müllner } \ 29a47842d1SChristoph Müllner} while (0) 30a47842d1SChristoph Müllner 31a47842d1SChristoph Müllnerstatic bool trans_fli_s(DisasContext *ctx, arg_fli_s *a) 32a47842d1SChristoph Müllner{ 33a47842d1SChristoph Müllner REQUIRE_FPU; 34a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 35a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVF); 36a47842d1SChristoph Müllner 37a47842d1SChristoph Müllner /* Values below are NaN-boxed to avoid a gen_nanbox_s(). */ 38a47842d1SChristoph Müllner static const uint64_t fli_s_table[] = { 39a47842d1SChristoph Müllner 0xffffffffbf800000, /* -1.0 */ 40a47842d1SChristoph Müllner 0xffffffff00800000, /* minimum positive normal */ 41a47842d1SChristoph Müllner 0xffffffff37800000, /* 1.0 * 2^-16 */ 42a47842d1SChristoph Müllner 0xffffffff38000000, /* 1.0 * 2^-15 */ 43a47842d1SChristoph Müllner 0xffffffff3b800000, /* 1.0 * 2^-8 */ 44a47842d1SChristoph Müllner 0xffffffff3c000000, /* 1.0 * 2^-7 */ 45a47842d1SChristoph Müllner 0xffffffff3d800000, /* 1.0 * 2^-4 */ 46a47842d1SChristoph Müllner 0xffffffff3e000000, /* 1.0 * 2^-3 */ 47a47842d1SChristoph Müllner 0xffffffff3e800000, /* 0.25 */ 48a47842d1SChristoph Müllner 0xffffffff3ea00000, /* 0.3125 */ 49a47842d1SChristoph Müllner 0xffffffff3ec00000, /* 0.375 */ 50a47842d1SChristoph Müllner 0xffffffff3ee00000, /* 0.4375 */ 51a47842d1SChristoph Müllner 0xffffffff3f000000, /* 0.5 */ 52a47842d1SChristoph Müllner 0xffffffff3f200000, /* 0.625 */ 53a47842d1SChristoph Müllner 0xffffffff3f400000, /* 0.75 */ 54a47842d1SChristoph Müllner 0xffffffff3f600000, /* 0.875 */ 55a47842d1SChristoph Müllner 0xffffffff3f800000, /* 1.0 */ 56a47842d1SChristoph Müllner 0xffffffff3fa00000, /* 1.25 */ 57a47842d1SChristoph Müllner 0xffffffff3fc00000, /* 1.5 */ 58a47842d1SChristoph Müllner 0xffffffff3fe00000, /* 1.75 */ 59a47842d1SChristoph Müllner 0xffffffff40000000, /* 2.0 */ 60a47842d1SChristoph Müllner 0xffffffff40200000, /* 2.5 */ 61a47842d1SChristoph Müllner 0xffffffff40400000, /* 3 */ 62a47842d1SChristoph Müllner 0xffffffff40800000, /* 4 */ 63a47842d1SChristoph Müllner 0xffffffff41000000, /* 8 */ 64a47842d1SChristoph Müllner 0xffffffff41800000, /* 16 */ 65a47842d1SChristoph Müllner 0xffffffff43000000, /* 2^7 */ 66a47842d1SChristoph Müllner 0xffffffff43800000, /* 2^8 */ 67a47842d1SChristoph Müllner 0xffffffff47000000, /* 2^15 */ 68a47842d1SChristoph Müllner 0xffffffff47800000, /* 2^16 */ 69a47842d1SChristoph Müllner 0xffffffff7f800000, /* +inf */ 70a47842d1SChristoph Müllner 0xffffffff7fc00000, /* Canonical NaN */ 71a47842d1SChristoph Müllner }; 72a47842d1SChristoph Müllner 73a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 74a47842d1SChristoph Müllner tcg_gen_movi_i64(dest, fli_s_table[a->rs1]); 75a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 76a47842d1SChristoph Müllner 77a47842d1SChristoph Müllner mark_fs_dirty(ctx); 78a47842d1SChristoph Müllner return true; 79a47842d1SChristoph Müllner} 80a47842d1SChristoph Müllner 81a47842d1SChristoph Müllnerstatic bool trans_fli_d(DisasContext *ctx, arg_fli_d *a) 82a47842d1SChristoph Müllner{ 83a47842d1SChristoph Müllner REQUIRE_FPU; 84a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 85a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 86a47842d1SChristoph Müllner 87a47842d1SChristoph Müllner static const uint64_t fli_d_table[] = { 88a47842d1SChristoph Müllner 0xbff0000000000000, /* -1.0 */ 89a47842d1SChristoph Müllner 0x0010000000000000, /* minimum positive normal */ 90a47842d1SChristoph Müllner 0x3ef0000000000000, /* 1.0 * 2^-16 */ 91a47842d1SChristoph Müllner 0x3f00000000000000, /* 1.0 * 2^-15 */ 92a47842d1SChristoph Müllner 0x3f70000000000000, /* 1.0 * 2^-8 */ 93a47842d1SChristoph Müllner 0x3f80000000000000, /* 1.0 * 2^-7 */ 94a47842d1SChristoph Müllner 0x3fb0000000000000, /* 1.0 * 2^-4 */ 95a47842d1SChristoph Müllner 0x3fc0000000000000, /* 1.0 * 2^-3 */ 96a47842d1SChristoph Müllner 0x3fd0000000000000, /* 0.25 */ 97a47842d1SChristoph Müllner 0x3fd4000000000000, /* 0.3125 */ 98a47842d1SChristoph Müllner 0x3fd8000000000000, /* 0.375 */ 99a47842d1SChristoph Müllner 0x3fdc000000000000, /* 0.4375 */ 100a47842d1SChristoph Müllner 0x3fe0000000000000, /* 0.5 */ 101a47842d1SChristoph Müllner 0x3fe4000000000000, /* 0.625 */ 102a47842d1SChristoph Müllner 0x3fe8000000000000, /* 0.75 */ 103a47842d1SChristoph Müllner 0x3fec000000000000, /* 0.875 */ 104a47842d1SChristoph Müllner 0x3ff0000000000000, /* 1.0 */ 105a47842d1SChristoph Müllner 0x3ff4000000000000, /* 1.25 */ 106a47842d1SChristoph Müllner 0x3ff8000000000000, /* 1.5 */ 107a47842d1SChristoph Müllner 0x3ffc000000000000, /* 1.75 */ 108a47842d1SChristoph Müllner 0x4000000000000000, /* 2.0 */ 109a47842d1SChristoph Müllner 0x4004000000000000, /* 2.5 */ 110a47842d1SChristoph Müllner 0x4008000000000000, /* 3 */ 111a47842d1SChristoph Müllner 0x4010000000000000, /* 4 */ 112a47842d1SChristoph Müllner 0x4020000000000000, /* 8 */ 113a47842d1SChristoph Müllner 0x4030000000000000, /* 16 */ 114a47842d1SChristoph Müllner 0x4060000000000000, /* 2^7 */ 115a47842d1SChristoph Müllner 0x4070000000000000, /* 2^8 */ 116a47842d1SChristoph Müllner 0x40e0000000000000, /* 2^15 */ 117a47842d1SChristoph Müllner 0x40f0000000000000, /* 2^16 */ 118a47842d1SChristoph Müllner 0x7ff0000000000000, /* +inf */ 119a47842d1SChristoph Müllner 0x7ff8000000000000, /* Canonical NaN */ 120a47842d1SChristoph Müllner }; 121a47842d1SChristoph Müllner 122a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 123a47842d1SChristoph Müllner tcg_gen_movi_i64(dest, fli_d_table[a->rs1]); 124a47842d1SChristoph Müllner gen_set_fpr_d(ctx, a->rd, dest); 125a47842d1SChristoph Müllner 126a47842d1SChristoph Müllner mark_fs_dirty(ctx); 127a47842d1SChristoph Müllner return true; 128a47842d1SChristoph Müllner} 129a47842d1SChristoph Müllner 130a47842d1SChristoph Müllnerstatic bool trans_fli_h(DisasContext *ctx, arg_fli_h *a) 131a47842d1SChristoph Müllner{ 132a47842d1SChristoph Müllner REQUIRE_FPU; 133a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 134a47842d1SChristoph Müllner REQUIRE_ZFH(ctx); 135a47842d1SChristoph Müllner 136a47842d1SChristoph Müllner /* Values below are NaN-boxed to avoid a gen_nanbox_h(). */ 137a47842d1SChristoph Müllner static const uint64_t fli_h_table[] = { 138a47842d1SChristoph Müllner 0xffffffffffffbc00, /* -1.0 */ 139a47842d1SChristoph Müllner 0xffffffffffff0400, /* minimum positive normal */ 140a47842d1SChristoph Müllner 0xffffffffffff0100, /* 1.0 * 2^-16 */ 141a47842d1SChristoph Müllner 0xffffffffffff0200, /* 1.0 * 2^-15 */ 142a47842d1SChristoph Müllner 0xffffffffffff1c00, /* 1.0 * 2^-8 */ 143a47842d1SChristoph Müllner 0xffffffffffff2000, /* 1.0 * 2^-7 */ 144a47842d1SChristoph Müllner 0xffffffffffff2c00, /* 1.0 * 2^-4 */ 145a47842d1SChristoph Müllner 0xffffffffffff3000, /* 1.0 * 2^-3 */ 146a47842d1SChristoph Müllner 0xffffffffffff3400, /* 0.25 */ 147a47842d1SChristoph Müllner 0xffffffffffff3500, /* 0.3125 */ 148a47842d1SChristoph Müllner 0xffffffffffff3600, /* 0.375 */ 149a47842d1SChristoph Müllner 0xffffffffffff3700, /* 0.4375 */ 150a47842d1SChristoph Müllner 0xffffffffffff3800, /* 0.5 */ 151a47842d1SChristoph Müllner 0xffffffffffff3900, /* 0.625 */ 152a47842d1SChristoph Müllner 0xffffffffffff3a00, /* 0.75 */ 153a47842d1SChristoph Müllner 0xffffffffffff3b00, /* 0.875 */ 154a47842d1SChristoph Müllner 0xffffffffffff3c00, /* 1.0 */ 155a47842d1SChristoph Müllner 0xffffffffffff3d00, /* 1.25 */ 156a47842d1SChristoph Müllner 0xffffffffffff3e00, /* 1.5 */ 157a47842d1SChristoph Müllner 0xffffffffffff3f00, /* 1.75 */ 158a47842d1SChristoph Müllner 0xffffffffffff4000, /* 2.0 */ 159a47842d1SChristoph Müllner 0xffffffffffff4100, /* 2.5 */ 160a47842d1SChristoph Müllner 0xffffffffffff4200, /* 3 */ 161a47842d1SChristoph Müllner 0xffffffffffff4400, /* 4 */ 162a47842d1SChristoph Müllner 0xffffffffffff4800, /* 8 */ 163a47842d1SChristoph Müllner 0xffffffffffff4c00, /* 16 */ 164a47842d1SChristoph Müllner 0xffffffffffff5800, /* 2^7 */ 165a47842d1SChristoph Müllner 0xffffffffffff5c00, /* 2^8 */ 166a47842d1SChristoph Müllner 0xffffffffffff7800, /* 2^15 */ 167a47842d1SChristoph Müllner 0xffffffffffff7c00, /* 2^16 */ 168a47842d1SChristoph Müllner 0xffffffffffff7c00, /* +inf */ 169a47842d1SChristoph Müllner 0xffffffffffff7e00, /* Canonical NaN */ 170a47842d1SChristoph Müllner }; 171a47842d1SChristoph Müllner 172a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 173a47842d1SChristoph Müllner tcg_gen_movi_i64(dest, fli_h_table[a->rs1]); 174a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 175a47842d1SChristoph Müllner 176a47842d1SChristoph Müllner mark_fs_dirty(ctx); 177a47842d1SChristoph Müllner return true; 178a47842d1SChristoph Müllner} 179a47842d1SChristoph Müllner 180a47842d1SChristoph Müllnerstatic bool trans_fminm_s(DisasContext *ctx, arg_fminm_s *a) 181a47842d1SChristoph Müllner{ 182a47842d1SChristoph Müllner REQUIRE_FPU; 183a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 184a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVF); 185a47842d1SChristoph Müllner 186a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 187a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 188a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 189a47842d1SChristoph Müllner 190*ad75a51eSRichard Henderson gen_helper_fminm_s(dest, tcg_env, src1, src2); 191a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 192a47842d1SChristoph Müllner 193a47842d1SChristoph Müllner mark_fs_dirty(ctx); 194a47842d1SChristoph Müllner return true; 195a47842d1SChristoph Müllner} 196a47842d1SChristoph Müllner 197a47842d1SChristoph Müllnerstatic bool trans_fmaxm_s(DisasContext *ctx, arg_fmaxm_s *a) 198a47842d1SChristoph Müllner{ 199a47842d1SChristoph Müllner REQUIRE_FPU; 200a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 201a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVF); 202a47842d1SChristoph Müllner 203a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 204a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 205a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 206a47842d1SChristoph Müllner 207*ad75a51eSRichard Henderson gen_helper_fmaxm_s(dest, tcg_env, src1, src2); 208a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 209a47842d1SChristoph Müllner 210a47842d1SChristoph Müllner mark_fs_dirty(ctx); 211a47842d1SChristoph Müllner return true; 212a47842d1SChristoph Müllner} 213a47842d1SChristoph Müllner 214a47842d1SChristoph Müllnerstatic bool trans_fminm_d(DisasContext *ctx, arg_fminm_d *a) 215a47842d1SChristoph Müllner{ 216a47842d1SChristoph Müllner REQUIRE_FPU; 217a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 218a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 219a47842d1SChristoph Müllner 220a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 221a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 222a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 223a47842d1SChristoph Müllner 224*ad75a51eSRichard Henderson gen_helper_fminm_d(dest, tcg_env, src1, src2); 225a47842d1SChristoph Müllner gen_set_fpr_d(ctx, a->rd, dest); 226a47842d1SChristoph Müllner 227a47842d1SChristoph Müllner mark_fs_dirty(ctx); 228a47842d1SChristoph Müllner return true; 229a47842d1SChristoph Müllner} 230a47842d1SChristoph Müllner 231a47842d1SChristoph Müllnerstatic bool trans_fmaxm_d(DisasContext *ctx, arg_fmaxm_d *a) 232a47842d1SChristoph Müllner{ 233a47842d1SChristoph Müllner REQUIRE_FPU; 234a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 235a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 236a47842d1SChristoph Müllner 237a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 238a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 239a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 240a47842d1SChristoph Müllner 241*ad75a51eSRichard Henderson gen_helper_fmaxm_d(dest, tcg_env, src1, src2); 242a47842d1SChristoph Müllner gen_set_fpr_d(ctx, a->rd, dest); 243a47842d1SChristoph Müllner 244a47842d1SChristoph Müllner mark_fs_dirty(ctx); 245a47842d1SChristoph Müllner return true; 246a47842d1SChristoph Müllner} 247a47842d1SChristoph Müllner 248a47842d1SChristoph Müllnerstatic bool trans_fminm_h(DisasContext *ctx, arg_fminm_h *a) 249a47842d1SChristoph Müllner{ 250a47842d1SChristoph Müllner REQUIRE_FPU; 251a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 252a47842d1SChristoph Müllner REQUIRE_ZFH(ctx); 253a47842d1SChristoph Müllner 254a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 255a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 256a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 257a47842d1SChristoph Müllner 258*ad75a51eSRichard Henderson gen_helper_fminm_h(dest, tcg_env, src1, src2); 259a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 260a47842d1SChristoph Müllner 261a47842d1SChristoph Müllner mark_fs_dirty(ctx); 262a47842d1SChristoph Müllner return true; 263a47842d1SChristoph Müllner} 264a47842d1SChristoph Müllner 265a47842d1SChristoph Müllnerstatic bool trans_fmaxm_h(DisasContext *ctx, arg_fmaxm_h *a) 266a47842d1SChristoph Müllner{ 267a47842d1SChristoph Müllner REQUIRE_FPU; 268a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 269a47842d1SChristoph Müllner REQUIRE_ZFH(ctx); 270a47842d1SChristoph Müllner 271a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 272a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 273a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 274a47842d1SChristoph Müllner 275*ad75a51eSRichard Henderson gen_helper_fmaxm_h(dest, tcg_env, src1, src2); 276a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 277a47842d1SChristoph Müllner 278a47842d1SChristoph Müllner mark_fs_dirty(ctx); 279a47842d1SChristoph Müllner return true; 280a47842d1SChristoph Müllner} 281a47842d1SChristoph Müllner 282a47842d1SChristoph Müllnerstatic bool trans_fround_s(DisasContext *ctx, arg_fround_s *a) 283a47842d1SChristoph Müllner{ 284a47842d1SChristoph Müllner REQUIRE_FPU; 285a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 286a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVF); 287a47842d1SChristoph Müllner 288a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 289a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 290a47842d1SChristoph Müllner 291a47842d1SChristoph Müllner gen_set_rm(ctx, a->rm); 292*ad75a51eSRichard Henderson gen_helper_fround_s(dest, tcg_env, src1); 293a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 294a47842d1SChristoph Müllner 295a47842d1SChristoph Müllner mark_fs_dirty(ctx); 296a47842d1SChristoph Müllner return true; 297a47842d1SChristoph Müllner} 298a47842d1SChristoph Müllner 299a47842d1SChristoph Müllnerstatic bool trans_froundnx_s(DisasContext *ctx, arg_froundnx_s *a) 300a47842d1SChristoph Müllner{ 301a47842d1SChristoph Müllner REQUIRE_FPU; 302a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 303a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVF); 304a47842d1SChristoph Müllner 305a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 306a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 307a47842d1SChristoph Müllner 308a47842d1SChristoph Müllner gen_set_rm(ctx, a->rm); 309*ad75a51eSRichard Henderson gen_helper_froundnx_s(dest, tcg_env, src1); 310a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 311a47842d1SChristoph Müllner 312a47842d1SChristoph Müllner mark_fs_dirty(ctx); 313a47842d1SChristoph Müllner return true; 314a47842d1SChristoph Müllner} 315a47842d1SChristoph Müllner 316a47842d1SChristoph Müllnerstatic bool trans_fround_d(DisasContext *ctx, arg_fround_d *a) 317a47842d1SChristoph Müllner{ 318a47842d1SChristoph Müllner REQUIRE_FPU; 319a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 320a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 321a47842d1SChristoph Müllner 322a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 323a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 324a47842d1SChristoph Müllner 325a47842d1SChristoph Müllner gen_set_rm(ctx, a->rm); 326*ad75a51eSRichard Henderson gen_helper_fround_d(dest, tcg_env, src1); 327a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 328a47842d1SChristoph Müllner 329a47842d1SChristoph Müllner mark_fs_dirty(ctx); 330a47842d1SChristoph Müllner return true; 331a47842d1SChristoph Müllner} 332a47842d1SChristoph Müllner 333a47842d1SChristoph Müllnerstatic bool trans_froundnx_d(DisasContext *ctx, arg_froundnx_d *a) 334a47842d1SChristoph Müllner{ 335a47842d1SChristoph Müllner REQUIRE_FPU; 336a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 337a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 338a47842d1SChristoph Müllner 339a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 340a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 341a47842d1SChristoph Müllner 342a47842d1SChristoph Müllner gen_set_rm(ctx, a->rm); 343*ad75a51eSRichard Henderson gen_helper_froundnx_d(dest, tcg_env, src1); 344a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 345a47842d1SChristoph Müllner 346a47842d1SChristoph Müllner mark_fs_dirty(ctx); 347a47842d1SChristoph Müllner return true; 348a47842d1SChristoph Müllner} 349a47842d1SChristoph Müllner 350a47842d1SChristoph Müllnerstatic bool trans_fround_h(DisasContext *ctx, arg_fround_h *a) 351a47842d1SChristoph Müllner{ 352a47842d1SChristoph Müllner REQUIRE_FPU; 353a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 354a47842d1SChristoph Müllner REQUIRE_ZFH(ctx); 355a47842d1SChristoph Müllner 356a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 357a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 358a47842d1SChristoph Müllner 359a47842d1SChristoph Müllner gen_set_rm(ctx, a->rm); 360*ad75a51eSRichard Henderson gen_helper_fround_h(dest, tcg_env, src1); 361a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 362a47842d1SChristoph Müllner 363a47842d1SChristoph Müllner mark_fs_dirty(ctx); 364a47842d1SChristoph Müllner return true; 365a47842d1SChristoph Müllner} 366a47842d1SChristoph Müllner 367a47842d1SChristoph Müllnerstatic bool trans_froundnx_h(DisasContext *ctx, arg_froundnx_h *a) 368a47842d1SChristoph Müllner{ 369a47842d1SChristoph Müllner REQUIRE_FPU; 370a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 371a47842d1SChristoph Müllner REQUIRE_ZFH(ctx); 372a47842d1SChristoph Müllner 373a47842d1SChristoph Müllner TCGv_i64 dest = dest_fpr(ctx, a->rd); 374a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 375a47842d1SChristoph Müllner 376a47842d1SChristoph Müllner gen_set_rm(ctx, a->rm); 377*ad75a51eSRichard Henderson gen_helper_froundnx_h(dest, tcg_env, src1); 378a47842d1SChristoph Müllner gen_set_fpr_hs(ctx, a->rd, dest); 379a47842d1SChristoph Müllner 380a47842d1SChristoph Müllner mark_fs_dirty(ctx); 381a47842d1SChristoph Müllner return true; 382a47842d1SChristoph Müllner} 383a47842d1SChristoph Müllner 384a47842d1SChristoph Müllnerbool trans_fcvtmod_w_d(DisasContext *ctx, arg_fcvtmod_w_d *a) 385a47842d1SChristoph Müllner{ 386a47842d1SChristoph Müllner REQUIRE_FPU; 387a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 388a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 389a47842d1SChristoph Müllner 390a47842d1SChristoph Müllner TCGv dst = dest_gpr(ctx, a->rd); 391a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 392a47842d1SChristoph Müllner TCGv_i64 t1 = tcg_temp_new_i64(); 393a47842d1SChristoph Müllner 394a47842d1SChristoph Müllner /* Rounding mode is RTZ. */ 395a47842d1SChristoph Müllner gen_set_rm(ctx, RISCV_FRM_RTZ); 396*ad75a51eSRichard Henderson gen_helper_fcvtmod_w_d(t1, tcg_env, src1); 397a47842d1SChristoph Müllner tcg_gen_trunc_i64_tl(dst, t1); 398a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dst); 399a47842d1SChristoph Müllner 400a47842d1SChristoph Müllner return true; 401a47842d1SChristoph Müllner} 402a47842d1SChristoph Müllner 403a47842d1SChristoph Müllnerbool trans_fmvh_x_d(DisasContext *ctx, arg_fmvh_x_d *a) 404a47842d1SChristoph Müllner{ 405a47842d1SChristoph Müllner REQUIRE_FPU; 406a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 407a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 408a47842d1SChristoph Müllner REQUIRE_32BIT(ctx); 409a47842d1SChristoph Müllner 410a47842d1SChristoph Müllner TCGv dst = dest_gpr(ctx, a->rd); 411a47842d1SChristoph Müllner TCGv_i64 t1 = tcg_temp_new_i64(); 412a47842d1SChristoph Müllner tcg_gen_sari_i64(t1, cpu_fpr[a->rs1], 32); 413a47842d1SChristoph Müllner tcg_gen_trunc_i64_tl(dst, t1); 414a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dst); 415a47842d1SChristoph Müllner return true; 416a47842d1SChristoph Müllner} 417a47842d1SChristoph Müllner 418a47842d1SChristoph Müllnerbool trans_fmvp_d_x(DisasContext *ctx, arg_fmvp_d_x *a) 419a47842d1SChristoph Müllner{ 420a47842d1SChristoph Müllner REQUIRE_FPU; 421a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 422a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 423a47842d1SChristoph Müllner REQUIRE_32BIT(ctx); 424a47842d1SChristoph Müllner 425a47842d1SChristoph Müllner TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); 426a47842d1SChristoph Müllner TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); 427a47842d1SChristoph Müllner tcg_gen_concat_tl_i64(cpu_fpr[a->rd], src1, src2); 428a47842d1SChristoph Müllner 429a47842d1SChristoph Müllner mark_fs_dirty(ctx); 430a47842d1SChristoph Müllner return true; 431a47842d1SChristoph Müllner} 432a47842d1SChristoph Müllner 433a47842d1SChristoph Müllnerbool trans_fleq_s(DisasContext *ctx, arg_fleq_s *a) 434a47842d1SChristoph Müllner{ 435a47842d1SChristoph Müllner REQUIRE_FPU; 436a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 437a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVF); 438a47842d1SChristoph Müllner 439a47842d1SChristoph Müllner TCGv dest = dest_gpr(ctx, a->rd); 440a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 441a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 442a47842d1SChristoph Müllner 443*ad75a51eSRichard Henderson gen_helper_fleq_s(dest, tcg_env, src1, src2); 444a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dest); 445a47842d1SChristoph Müllner return true; 446a47842d1SChristoph Müllner} 447a47842d1SChristoph Müllner 448a47842d1SChristoph Müllnerbool trans_fltq_s(DisasContext *ctx, arg_fltq_s *a) 449a47842d1SChristoph Müllner{ 450a47842d1SChristoph Müllner REQUIRE_FPU; 451a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 452a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVF); 453a47842d1SChristoph Müllner 454a47842d1SChristoph Müllner TCGv dest = dest_gpr(ctx, a->rd); 455a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 456a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 457a47842d1SChristoph Müllner 458*ad75a51eSRichard Henderson gen_helper_fltq_s(dest, tcg_env, src1, src2); 459a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dest); 460a47842d1SChristoph Müllner return true; 461a47842d1SChristoph Müllner} 462a47842d1SChristoph Müllner 463a47842d1SChristoph Müllnerbool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a) 464a47842d1SChristoph Müllner{ 465a47842d1SChristoph Müllner REQUIRE_FPU; 466a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 467a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 468a47842d1SChristoph Müllner 469a47842d1SChristoph Müllner TCGv dest = dest_gpr(ctx, a->rd); 470a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 471a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 472a47842d1SChristoph Müllner 473*ad75a51eSRichard Henderson gen_helper_fleq_d(dest, tcg_env, src1, src2); 474a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dest); 475a47842d1SChristoph Müllner return true; 476a47842d1SChristoph Müllner} 477a47842d1SChristoph Müllner 478a47842d1SChristoph Müllnerbool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a) 479a47842d1SChristoph Müllner{ 480a47842d1SChristoph Müllner REQUIRE_FPU; 481a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 482a47842d1SChristoph Müllner REQUIRE_EXT(ctx, RVD); 483a47842d1SChristoph Müllner 484a47842d1SChristoph Müllner TCGv dest = dest_gpr(ctx, a->rd); 485a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 486a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 487a47842d1SChristoph Müllner 488*ad75a51eSRichard Henderson gen_helper_fltq_d(dest, tcg_env, src1, src2); 489a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dest); 490a47842d1SChristoph Müllner return true; 491a47842d1SChristoph Müllner} 492a47842d1SChristoph Müllner 493a47842d1SChristoph Müllnerbool trans_fleq_h(DisasContext *ctx, arg_fleq_h *a) 494a47842d1SChristoph Müllner{ 495a47842d1SChristoph Müllner REQUIRE_FPU; 496a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 497a47842d1SChristoph Müllner REQUIRE_ZFH(ctx); 498a47842d1SChristoph Müllner 499a47842d1SChristoph Müllner TCGv dest = dest_gpr(ctx, a->rd); 500a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 501a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 502a47842d1SChristoph Müllner 503*ad75a51eSRichard Henderson gen_helper_fleq_h(dest, tcg_env, src1, src2); 504a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dest); 505a47842d1SChristoph Müllner return true; 506a47842d1SChristoph Müllner} 507a47842d1SChristoph Müllner 508a47842d1SChristoph Müllnerbool trans_fltq_h(DisasContext *ctx, arg_fltq_h *a) 509a47842d1SChristoph Müllner{ 510a47842d1SChristoph Müllner REQUIRE_FPU; 511a47842d1SChristoph Müllner REQUIRE_ZFA(ctx); 512a47842d1SChristoph Müllner REQUIRE_ZFH(ctx); 513a47842d1SChristoph Müllner 514a47842d1SChristoph Müllner TCGv dest = dest_gpr(ctx, a->rd); 515a47842d1SChristoph Müllner TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 516a47842d1SChristoph Müllner TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2); 517a47842d1SChristoph Müllner 518*ad75a51eSRichard Henderson gen_helper_fltq_h(dest, tcg_env, src1, src2); 519a47842d1SChristoph Müllner gen_set_gpr(ctx, a->rd, dest); 520a47842d1SChristoph Müllner return true; 521a47842d1SChristoph Müllner} 522