1// See LICENSE for license details. 2 3#include "emulation.h" 4 5#ifndef __riscv_muldiv 6 7#if __riscv_xlen == 64 8typedef __int128 double_int; 9#else 10typedef int64_t double_int; 11#endif 12 13// These routines rely on the compiler to turn these operations into libcalls 14// when not natively supported. So work on making those go fast. 15 16DECLARE_EMULATION_FUNC(emulate_mul_div) 17{ 18 uintptr_t rs1 = GET_RS1(insn, regs), rs2 = GET_RS2(insn, regs), val; 19 20 if ((insn & MASK_MUL) == MATCH_MUL) 21 val = rs1 * rs2; 22 else if ((insn & MASK_DIV) == MATCH_DIV) 23 val = (intptr_t)rs1 / (intptr_t)rs2; 24 else if ((insn & MASK_DIVU) == MATCH_DIVU) 25 val = rs1 / rs2; 26 else if ((insn & MASK_REM) == MATCH_REM) 27 val = (intptr_t)rs1 % (intptr_t)rs2; 28 else if ((insn & MASK_REMU) == MATCH_REMU) 29 val = rs1 % rs2; 30 else if ((insn & MASK_MULH) == MATCH_MULH) 31 val = ((double_int)(intptr_t)rs1 * (double_int)(intptr_t)rs2) >> (8 * sizeof(rs1)); 32 else if ((insn & MASK_MULHU) == MATCH_MULHU) 33 val = ((double_int)rs1 * (double_int)rs2) >> (8 * sizeof(rs1)); 34 else if ((insn & MASK_MULHSU) == MATCH_MULHSU) 35 val = ((double_int)(intptr_t)rs1 * (double_int)rs2) >> (8 * sizeof(rs1)); 36 else 37 return truly_illegal_insn(regs, mcause, mepc, mstatus, insn); 38 39 SET_RD(insn, regs, val); 40} 41 42#if __riscv_xlen == 64 43 44DECLARE_EMULATION_FUNC(emulate_mul_div32) 45{ 46 uint32_t rs1 = GET_RS1(insn, regs), rs2 = GET_RS2(insn, regs); 47 int32_t val; 48 49 if ((insn & MASK_MULW) == MATCH_MULW) 50 val = rs1 * rs2; 51 else if ((insn & MASK_DIVW) == MATCH_DIVW) 52 val = (int32_t)rs1 / (int32_t)rs2; 53 else if ((insn & MASK_DIVUW) == MATCH_DIVUW) 54 val = rs1 / rs2; 55 else if ((insn & MASK_REMW) == MATCH_REMW) 56 val = (int32_t)rs1 % (int32_t)rs2; 57 else if ((insn & MASK_REMUW) == MATCH_REMUW) 58 val = rs1 % rs2; 59 else 60 return truly_illegal_insn(regs, mcause, mepc, mstatus, insn); 61 62 SET_RD(insn, regs, val); 63} 64 65#endif 66#endif 67