qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

m128_helper.c (3020B)


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