1/* 2 * RISC-V translation routines for the RV64M Standard Extension. 3 * 4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu 5 * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de 6 * Bastian Koppelmann, kbastian@mail.uni-paderborn.de 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2 or later, as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along with 18 * this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 22static bool trans_mul(DisasContext *ctx, arg_mul *a) 23{ 24 REQUIRE_EXT(ctx, RVM); 25 return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl); 26} 27 28static void gen_mulh(TCGv ret, TCGv s1, TCGv s2) 29{ 30 TCGv discard = tcg_temp_new(); 31 32 tcg_gen_muls2_tl(discard, ret, s1, s2); 33 tcg_temp_free(discard); 34} 35 36static bool trans_mulh(DisasContext *ctx, arg_mulh *a) 37{ 38 REQUIRE_EXT(ctx, RVM); 39 return gen_arith(ctx, a, EXT_NONE, gen_mulh); 40} 41 42static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a) 43{ 44 REQUIRE_EXT(ctx, RVM); 45 return gen_arith(ctx, a, EXT_NONE, gen_mulhsu); 46} 47 48static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2) 49{ 50 TCGv discard = tcg_temp_new(); 51 52 tcg_gen_mulu2_tl(discard, ret, s1, s2); 53 tcg_temp_free(discard); 54} 55 56static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a) 57{ 58 REQUIRE_EXT(ctx, RVM); 59 return gen_arith(ctx, a, EXT_NONE, gen_mulhu); 60} 61 62static bool trans_div(DisasContext *ctx, arg_div *a) 63{ 64 REQUIRE_EXT(ctx, RVM); 65 return gen_arith(ctx, a, EXT_SIGN, gen_div); 66} 67 68static bool trans_divu(DisasContext *ctx, arg_divu *a) 69{ 70 REQUIRE_EXT(ctx, RVM); 71 return gen_arith(ctx, a, EXT_ZERO, gen_divu); 72} 73 74static bool trans_rem(DisasContext *ctx, arg_rem *a) 75{ 76 REQUIRE_EXT(ctx, RVM); 77 return gen_arith(ctx, a, EXT_SIGN, gen_rem); 78} 79 80static bool trans_remu(DisasContext *ctx, arg_remu *a) 81{ 82 REQUIRE_EXT(ctx, RVM); 83 return gen_arith(ctx, a, EXT_ZERO, gen_remu); 84} 85 86static bool trans_mulw(DisasContext *ctx, arg_mulw *a) 87{ 88 REQUIRE_64BIT(ctx); 89 REQUIRE_EXT(ctx, RVM); 90 ctx->w = true; 91 return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl); 92} 93 94static bool trans_divw(DisasContext *ctx, arg_divw *a) 95{ 96 REQUIRE_64BIT(ctx); 97 REQUIRE_EXT(ctx, RVM); 98 ctx->w = true; 99 return gen_arith(ctx, a, EXT_SIGN, gen_div); 100} 101 102static bool trans_divuw(DisasContext *ctx, arg_divuw *a) 103{ 104 REQUIRE_64BIT(ctx); 105 REQUIRE_EXT(ctx, RVM); 106 ctx->w = true; 107 return gen_arith(ctx, a, EXT_ZERO, gen_divu); 108} 109 110static bool trans_remw(DisasContext *ctx, arg_remw *a) 111{ 112 REQUIRE_64BIT(ctx); 113 REQUIRE_EXT(ctx, RVM); 114 ctx->w = true; 115 return gen_arith(ctx, a, EXT_SIGN, gen_rem); 116} 117 118static bool trans_remuw(DisasContext *ctx, arg_remuw *a) 119{ 120 REQUIRE_64BIT(ctx); 121 REQUIRE_EXT(ctx, RVM); 122 ctx->w = true; 123 return gen_arith(ctx, a, EXT_ZERO, gen_remu); 124} 125