1*b3a5d1fbSFrédéric Pétrot /*
2*b3a5d1fbSFrédéric Pétrot * RISC-V Emulation Helpers for QEMU.
3*b3a5d1fbSFrédéric Pétrot *
4*b3a5d1fbSFrédéric Pétrot * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5*b3a5d1fbSFrédéric Pétrot * Copyright (c) 2017-2018 SiFive, Inc.
6*b3a5d1fbSFrédéric Pétrot *
7*b3a5d1fbSFrédéric Pétrot * This program is free software; you can redistribute it and/or modify it
8*b3a5d1fbSFrédéric Pétrot * under the terms and conditions of the GNU General Public License,
9*b3a5d1fbSFrédéric Pétrot * version 2 or later, as published by the Free Software Foundation.
10*b3a5d1fbSFrédéric Pétrot *
11*b3a5d1fbSFrédéric Pétrot * This program is distributed in the hope it will be useful, but WITHOUT
12*b3a5d1fbSFrédéric Pétrot * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*b3a5d1fbSFrédéric Pétrot * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14*b3a5d1fbSFrédéric Pétrot * more details.
15*b3a5d1fbSFrédéric Pétrot *
16*b3a5d1fbSFrédéric Pétrot * You should have received a copy of the GNU General Public License along with
17*b3a5d1fbSFrédéric Pétrot * this program. If not, see <http://www.gnu.org/licenses/>.
18*b3a5d1fbSFrédéric Pétrot */
19*b3a5d1fbSFrédéric Pétrot
20*b3a5d1fbSFrédéric Pétrot #include "qemu/osdep.h"
21*b3a5d1fbSFrédéric Pétrot #include "cpu.h"
22*b3a5d1fbSFrédéric Pétrot #include "exec/helper-proto.h"
23*b3a5d1fbSFrédéric Pétrot
HELPER(divu_i128)24*b3a5d1fbSFrédéric Pétrot target_ulong HELPER(divu_i128)(CPURISCVState *env,
25*b3a5d1fbSFrédéric Pétrot target_ulong ul, target_ulong uh,
26*b3a5d1fbSFrédéric Pétrot target_ulong vl, target_ulong vh)
27*b3a5d1fbSFrédéric Pétrot {
28*b3a5d1fbSFrédéric Pétrot target_ulong ql, qh;
29*b3a5d1fbSFrédéric Pétrot Int128 q;
30*b3a5d1fbSFrédéric Pétrot
31*b3a5d1fbSFrédéric Pétrot if (vl == 0 && vh == 0) { /* Handle special behavior on div by zero */
32*b3a5d1fbSFrédéric Pétrot ql = ~0x0;
33*b3a5d1fbSFrédéric Pétrot qh = ~0x0;
34*b3a5d1fbSFrédéric Pétrot } else {
35*b3a5d1fbSFrédéric Pétrot q = int128_divu(int128_make128(ul, uh), int128_make128(vl, vh));
36*b3a5d1fbSFrédéric Pétrot ql = int128_getlo(q);
37*b3a5d1fbSFrédéric Pétrot qh = int128_gethi(q);
38*b3a5d1fbSFrédéric Pétrot }
39*b3a5d1fbSFrédéric Pétrot
40*b3a5d1fbSFrédéric Pétrot env->retxh = qh;
41*b3a5d1fbSFrédéric Pétrot return ql;
42*b3a5d1fbSFrédéric Pétrot }
43*b3a5d1fbSFrédéric Pétrot
HELPER(remu_i128)44*b3a5d1fbSFrédéric Pétrot target_ulong HELPER(remu_i128)(CPURISCVState *env,
45*b3a5d1fbSFrédéric Pétrot target_ulong ul, target_ulong uh,
46*b3a5d1fbSFrédéric Pétrot target_ulong vl, target_ulong vh)
47*b3a5d1fbSFrédéric Pétrot {
48*b3a5d1fbSFrédéric Pétrot target_ulong rl, rh;
49*b3a5d1fbSFrédéric Pétrot Int128 r;
50*b3a5d1fbSFrédéric Pétrot
51*b3a5d1fbSFrédéric Pétrot if (vl == 0 && vh == 0) {
52*b3a5d1fbSFrédéric Pétrot rl = ul;
53*b3a5d1fbSFrédéric Pétrot rh = uh;
54*b3a5d1fbSFrédéric Pétrot } else {
55*b3a5d1fbSFrédéric Pétrot r = int128_remu(int128_make128(ul, uh), int128_make128(vl, vh));
56*b3a5d1fbSFrédéric Pétrot rl = int128_getlo(r);
57*b3a5d1fbSFrédéric Pétrot rh = int128_gethi(r);
58*b3a5d1fbSFrédéric Pétrot }
59*b3a5d1fbSFrédéric Pétrot
60*b3a5d1fbSFrédéric Pétrot env->retxh = rh;
61*b3a5d1fbSFrédéric Pétrot return rl;
62*b3a5d1fbSFrédéric Pétrot }
63*b3a5d1fbSFrédéric Pétrot
HELPER(divs_i128)64*b3a5d1fbSFrédéric Pétrot target_ulong HELPER(divs_i128)(CPURISCVState *env,
65*b3a5d1fbSFrédéric Pétrot target_ulong ul, target_ulong uh,
66*b3a5d1fbSFrédéric Pétrot target_ulong vl, target_ulong vh)
67*b3a5d1fbSFrédéric Pétrot {
68*b3a5d1fbSFrédéric Pétrot target_ulong qh, ql;
69*b3a5d1fbSFrédéric Pétrot Int128 q;
70*b3a5d1fbSFrédéric Pétrot
71*b3a5d1fbSFrédéric Pétrot if (vl == 0 && vh == 0) { /* Div by zero check */
72*b3a5d1fbSFrédéric Pétrot ql = ~0x0;
73*b3a5d1fbSFrédéric Pétrot qh = ~0x0;
74*b3a5d1fbSFrédéric Pétrot } else if (uh == (1ULL << (TARGET_LONG_BITS - 1)) && ul == 0 &&
75*b3a5d1fbSFrédéric Pétrot vh == ~0x0 && vl == ~0x0) {
76*b3a5d1fbSFrédéric Pétrot /* Signed div overflow check (-2**127 / -1) */
77*b3a5d1fbSFrédéric Pétrot ql = ul;
78*b3a5d1fbSFrédéric Pétrot qh = uh;
79*b3a5d1fbSFrédéric Pétrot } else {
80*b3a5d1fbSFrédéric Pétrot q = int128_divs(int128_make128(ul, uh), int128_make128(vl, vh));
81*b3a5d1fbSFrédéric Pétrot ql = int128_getlo(q);
82*b3a5d1fbSFrédéric Pétrot qh = int128_gethi(q);
83*b3a5d1fbSFrédéric Pétrot }
84*b3a5d1fbSFrédéric Pétrot
85*b3a5d1fbSFrédéric Pétrot env->retxh = qh;
86*b3a5d1fbSFrédéric Pétrot return ql;
87*b3a5d1fbSFrédéric Pétrot }
88*b3a5d1fbSFrédéric Pétrot
HELPER(rems_i128)89*b3a5d1fbSFrédéric Pétrot target_ulong HELPER(rems_i128)(CPURISCVState *env,
90*b3a5d1fbSFrédéric Pétrot target_ulong ul, target_ulong uh,
91*b3a5d1fbSFrédéric Pétrot target_ulong vl, target_ulong vh)
92*b3a5d1fbSFrédéric Pétrot {
93*b3a5d1fbSFrédéric Pétrot target_ulong rh, rl;
94*b3a5d1fbSFrédéric Pétrot Int128 r;
95*b3a5d1fbSFrédéric Pétrot
96*b3a5d1fbSFrédéric Pétrot if (vl == 0 && vh == 0) {
97*b3a5d1fbSFrédéric Pétrot rl = ul;
98*b3a5d1fbSFrédéric Pétrot rh = uh;
99*b3a5d1fbSFrédéric Pétrot } else {
100*b3a5d1fbSFrédéric Pétrot r = int128_rems(int128_make128(ul, uh), int128_make128(vl, vh));
101*b3a5d1fbSFrédéric Pétrot rl = int128_getlo(r);
102*b3a5d1fbSFrédéric Pétrot rh = int128_gethi(r);
103*b3a5d1fbSFrédéric Pétrot }
104*b3a5d1fbSFrédéric Pétrot
105*b3a5d1fbSFrédéric Pétrot env->retxh = rh;
106*b3a5d1fbSFrédéric Pétrot return rl;
107*b3a5d1fbSFrédéric Pétrot }
108