78 changed files with 353 additions and 0 deletions
@ -0,0 +1,128 @@ |
|||
#include "cvt16.h" |
|||
|
|||
#define H_BIAS (UINT16_C(0xf)) |
|||
#define H_F_MASK (UINT16_C(0x03FF)) |
|||
#define H_E_MASK (UINT16_C(0x7C00)) |
|||
#define H_E_SHIFT (10) |
|||
#define H_S_MASK (UINT16_C(0x8000)) |
|||
|
|||
#define H_QNAN (H_F_MASK) |
|||
|
|||
#define S_BIAS (UINT32_C(0x7F)) |
|||
#define S_F_MASK (UINT32_C(0x007fffff)) |
|||
#define S_E_MASK (UINT32_C(0x7f800000)) |
|||
#define S_E_SHIFT (23) |
|||
#define S_S_MASK (UINT32_C(0x80000000)) |
|||
|
|||
#define S_QNAN (S_F_MASK) |
|||
|
|||
#define PAD (S_E_SHIFT - H_E_SHIFT) |
|||
|
|||
uint_fast32_t cvt_hs(uint_fast16_t x) |
|||
{ |
|||
#define MSB (UINT32_C(0x00800000)) |
|||
uint_fast32_t frac, exp, sign; |
|||
frac = (x & H_F_MASK) << PAD; |
|||
exp = (x & H_E_MASK); |
|||
sign = (x & H_S_MASK); |
|||
|
|||
switch (exp) { |
|||
case 0: |
|||
if (frac) { /* Denormal */ |
|||
exp = S_BIAS - 14; |
|||
/* Adjust fraction for implicit leading 1-bit */ |
|||
for (; !(frac & MSB); frac <<= 1, exp--); |
|||
frac &= ~(MSB); |
|||
exp <<= S_E_SHIFT; |
|||
} |
|||
break; |
|||
|
|||
case H_E_MASK: /* Infinity and NaN */ |
|||
exp = S_E_MASK; |
|||
if (frac) { /* Set padding bits for NaN */ |
|||
frac |= (1 << PAD) - 1; |
|||
} |
|||
break; |
|||
default: |
|||
exp += (S_BIAS - H_BIAS) << H_E_SHIFT; /* Re-bias */ |
|||
exp <<= PAD; |
|||
} |
|||
return (sign << 16) | exp | frac; |
|||
#undef MSB |
|||
} |
|||
|
|||
enum riscv_rm { |
|||
RNE = 0, /* Round to nearest; ties to even */ |
|||
RTZ = 1, /* Round towards zero (truncate) */ |
|||
RDN = 2, /* Round towards negative infinity (down) */ |
|||
RUP = 3, /* Round towards positive infinity (up) */ |
|||
RMM = 4, /* Round to nearest; ties to max magnitude */ |
|||
}; |
|||
|
|||
/*
|
|||
* LSB : frac[13] |
|||
* Guard bit (G): frac[12] |
|||
* Round bit (R): frac[11] |
|||
* Sticky bit (S): OR of frac[10..0] |
|||
* |
|||
* RTZ: |
|||
* truncate |
|||
* RUP: |
|||
* 000 : exact |
|||
* else : round up |
|||
* RDN: |
|||
* 000 : exact |
|||
* else : round down |
|||
* RNE: |
|||
* 0xx : round down |
|||
* 100 : tie; round up if LSB is 1 |
|||
* 101 : round up |
|||
* 110 : round up |
|||
* 111 : round up |
|||
*/ |
|||
uint_fast16_t cvt_sh(uint_fast32_t x, int rm) |
|||
{ |
|||
#define MSB UINT16_C(0x0400) |
|||
uint_fast32_t frac, exp, sign; |
|||
int e; |
|||
sign = (x & S_S_MASK) >> 16; |
|||
exp = (x & S_E_MASK); |
|||
if (exp && exp != S_E_MASK) { |
|||
int inc; |
|||
inc = 0; |
|||
switch (rm) { |
|||
case RNE: |
|||
/* Round up if G is set and either R, S,
|
|||
or the bit before G is non-zero */ |
|||
inc = (x & 0x1000) && (x & 0x2fff); |
|||
break; |
|||
case RUP: |
|||
inc = ((x & 0x1fff) != 0) && (!sign); |
|||
break; |
|||
case RDN: |
|||
inc = ((x & 0x1fff) != 0) && sign; |
|||
break; |
|||
} |
|||
x += inc << PAD; |
|||
exp = (x & S_E_MASK); |
|||
} |
|||
frac = (x & S_F_MASK) >> PAD; |
|||
|
|||
e = (exp >> S_E_SHIFT) - S_BIAS; |
|||
if (e < -24) { /* Round to zero */ |
|||
return sign; |
|||
} else if (e < -14) { /* Denormal */ |
|||
frac = (frac | MSB) >> (-e - 14); |
|||
return sign | frac; |
|||
} else if (e < 16) { |
|||
exp = (e + H_BIAS) << H_E_SHIFT; |
|||
} else if (e < 127) { /* Round to infinity */ |
|||
exp = H_E_MASK; |
|||
frac = 0; |
|||
} else { |
|||
/* Infinity and NaN */ |
|||
} |
|||
return sign | exp | frac; |
|||
#undef MSB |
|||
} |
|||
|
|||
@ -0,0 +1,9 @@ |
|||
#ifndef _CVT16_H |
|||
#define _CVT16_H |
|||
|
|||
#include <cstdint> |
|||
|
|||
extern uint_fast32_t cvt_hs(uint_fast16_t); |
|||
extern uint_fast16_t cvt_sh(uint_fast32_t, int); |
|||
|
|||
#endif |
|||
@ -0,0 +1,15 @@ |
|||
#ifndef _DECODE_HWACHA_UT_HALF_H |
|||
#define _DECODE_HWACHA_UT_HALF_H |
|||
|
|||
#include "decode_hwacha_ut.h" |
|||
#include "cvt16.h" |
|||
|
|||
#define HFRS1 cvt_hs(FRS1) |
|||
#define HFRS2 cvt_hs(FRS2) |
|||
#define HFRS3 cvt_hs(FRS3) |
|||
|
|||
#define WRITE_HFRD(value) write_frd(h, insn, UTIDX, cvt_sh(value, RM)) |
|||
|
|||
#define sext16(x) ((sreg_t)(int16_t)(x)) |
|||
|
|||
#endif |
|||
@ -0,0 +1,25 @@ |
|||
// See LICENSE for license details.
|
|||
|
|||
#include "config.h" |
|||
#include "processor.h" |
|||
#include "mmu.h" |
|||
#include "softfloat.h" |
|||
#include "platform.h" // softfloat isNaNF32UI, etc. |
|||
#include "internals.h" // ditto |
|||
#include "hwacha.h" |
|||
#include "decode_hwacha_ut_half.h" |
|||
#include "cvt16.h" |
|||
#include <assert.h> |
|||
|
|||
reg_t hwacha_NAME(processor_t* p, insn_t insn, reg_t pc) |
|||
{ |
|||
int xprlen = 64; |
|||
reg_t npc = sext_xprlen(pc + insn_length(OPCODE)); |
|||
hwacha_t* h = static_cast<hwacha_t*>(p->get_extension()); |
|||
do { |
|||
#include "insns_ut_half/NAME.h" |
|||
WRITE_UTIDX(UTIDX+1); |
|||
} while (UTIDX < VL); |
|||
WRITE_UTIDX(0); |
|||
return npc; |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
uint32_t prec = u.r.funct; |
|||
switch (prec) { |
|||
case 16: |
|||
case 32: |
|||
case 64: |
|||
WRITE_PREC(prec); |
|||
break; |
|||
|
|||
default: |
|||
h->take_exception(HWACHA_CAUSE_ILLEGAL_CFG, 2); |
|||
break; |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_mulAdd(HFRS1, 0x3f800000, HFRS2)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_FRD(f32_to_f64(HFRS1)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f64_to_f32(FRS1)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,5 @@ |
|||
require_xpr64; |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(i64_to_f32(RS1)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,5 @@ |
|||
require_xpr64; |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(ui64_to_f32(RS1)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,3 @@ |
|||
require_fp; |
|||
WRITE_FRD(cvt_sh(FRS1, RM)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(i32_to_f32((int32_t)RS1)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(ui32_to_f32((uint32_t)RS1)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,5 @@ |
|||
require_xpr64; |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_RD(f32_to_i64(HFRS1, RM, true)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,5 @@ |
|||
require_xpr64; |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_RD(f32_to_ui64(HFRS1, RM, true)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,3 @@ |
|||
require_fp; |
|||
WRITE_FRD(HFRS1); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_RD(sext32(f32_to_i32(HFRS1, RM, true))); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_RD(sext32(f32_to_ui32(HFRS1, RM, true))); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_div(HFRS1, HFRS2)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,3 @@ |
|||
require_fp; |
|||
WRITE_RD(f32_eq(HFRS1, HFRS2)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,3 @@ |
|||
require_fp; |
|||
WRITE_RD(f32_le(HFRS1, HFRS2)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,2 @@ |
|||
require_fp; |
|||
WRITE_FRD(MMU.load_int16(RS1 + insn.i_imm())); |
|||
@ -0,0 +1,3 @@ |
|||
require_fp; |
|||
WRITE_RD(f32_lt(HFRS1, HFRS2)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_mulAdd(HFRS1, HFRS2, HFRS3)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
WRITE_HFRD(isNaNF32UI(HFRS2) || f32_le_quiet(HFRS2,HFRS1) /* && FRS1 not NaN */ |
|||
? HFRS1 : HFRS2); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
WRITE_HFRD(isNaNF32UI(HFRS2) || f32_lt_quiet(HFRS1,HFRS2) /* && FRS1 not NaN */ |
|||
? HFRS1 : HFRS2); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_mulAdd(HFRS1, HFRS2, HFRS3 ^ (uint32_t)INT32_MIN)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_mulAdd(HFRS1, HFRS2, (HFRS1 ^ HFRS2) & (uint32_t)INT32_MIN)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,2 @@ |
|||
require_fp; |
|||
WRITE_FRD(RS1); |
|||
@ -0,0 +1,2 @@ |
|||
require_fp; |
|||
WRITE_RD(sext16(FRS1)); |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_mulAdd(HFRS1 ^ (uint32_t)INT32_MIN, HFRS2, HFRS3 ^ (uint32_t)INT32_MIN)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_mulAdd(HFRS1 ^ (uint32_t)INT32_MIN, HFRS2, HFRS3)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,2 @@ |
|||
require_fp; |
|||
WRITE_FRD((FRS1 &~ (uint16_t)INT16_MIN) | (FRS2 & (uint16_t)INT16_MIN)); |
|||
@ -0,0 +1,2 @@ |
|||
require_fp; |
|||
WRITE_FRD((FRS1 &~ (uint32_t)INT32_MIN) | ((~FRS2) & (uint32_t)INT32_MIN)); |
|||
@ -0,0 +1,2 @@ |
|||
require_fp; |
|||
WRITE_FRD(FRS1 ^ (FRS2 & (uint16_t)INT16_MIN)); |
|||
@ -0,0 +1,2 @@ |
|||
require_fp; |
|||
MMU.store_uint16(RS1 + insn.s_imm(), FRS2); |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_sqrt(HFRS1)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,4 @@ |
|||
require_fp; |
|||
softfloat_roundingMode = RM; |
|||
WRITE_HFRD(f32_mulAdd(HFRS1, 0x3f800000, HFRS2 ^ (uint32_t)INT32_MIN)); |
|||
set_fp_exceptions; |
|||
@ -0,0 +1,33 @@ |
|||
DECLARE_INSN(ut_fcvt_h_lu, 0x6c000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fmin_h, 0xc4000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_fcvt_wu_h, 0x5c000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fdiv_h, 0x1c000053, 0xfe00007f) |
|||
DECLARE_INSN(ut_fcvt_h_wu, 0x7c000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fsgnj_h, 0x2c000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_fnmsub_h, 0x400004b, 0x600007f) |
|||
DECLARE_INSN(ut_fle_h, 0xbc000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_fcvt_l_h, 0x44000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fnmadd_h, 0x400004f, 0x600007f) |
|||
DECLARE_INSN(ut_fcvt_h_s, 0x90000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fcvt_h_w, 0x74000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fcvt_d_h, 0x8c000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fmax_h, 0xcc000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_fcvt_lu_h, 0x4c000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fcvt_h_l, 0x64000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fmv_x_h, 0xe4000053, 0xfff0707f) |
|||
DECLARE_INSN(ut_fcvt_h_d, 0x92000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_flt_h, 0xb4000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_fadd_h, 0x4000053, 0xfe00007f) |
|||
DECLARE_INSN(ut_fcvt_s_h, 0x84000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fcvt_w_h, 0x54000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fmul_h, 0x14000053, 0xfe00007f) |
|||
DECLARE_INSN(ut_fmadd_h, 0x4000043, 0x600007f) |
|||
DECLARE_INSN(ut_fsqrt_h, 0x24000053, 0xfff0007f) |
|||
DECLARE_INSN(ut_fsgnjn_h, 0x34000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_fsub_h, 0xc000053, 0xfe00007f) |
|||
DECLARE_INSN(ut_fsh, 0x1027, 0x707f) |
|||
DECLARE_INSN(ut_fsgnjx_h, 0x3c000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_flh, 0x1007, 0x707f) |
|||
DECLARE_INSN(ut_fmsub_h, 0x4000047, 0x600007f) |
|||
DECLARE_INSN(ut_feq_h, 0xac000053, 0xfe00707f) |
|||
DECLARE_INSN(ut_fmv_h_x, 0xf4000053, 0xfff0707f) |
|||
Loading…
Reference in new issue