Added FLEN parameterization for RV32/64 F and D instructions
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include "xlen.h"
|
||||
|
||||
constexpr uint32_t count_leading_zeros(uint32_t value) {
|
||||
return value ? __builtin_clz(value) : 32;
|
||||
@@ -71,10 +72,11 @@ inline uint64_t bit_getw(uint64_t bits, uint32_t start, uint32_t end) {
|
||||
}
|
||||
|
||||
// Apply integer sign extension
|
||||
inline uint32_t sext32(uint32_t word, uint32_t width) {
|
||||
inline uintx_t sext(uintx_t word, uint32_t width) {
|
||||
assert(width > 1);
|
||||
assert(width <= 32);
|
||||
uint32_t mask = (1 << width) - 1;
|
||||
uintx_t unity = 1;
|
||||
uintx_t mask = (unity << width) - 1;
|
||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||
}
|
||||
|
||||
@@ -86,14 +88,15 @@ inline uint64_t sext64(uint64_t word, uint64_t width) {
|
||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||
}
|
||||
|
||||
inline __uint128_t sext128(__uint128_t word, uint32_t width) {
|
||||
inline uintm_t sext_mul(uintm_t word, uint32_t width) {
|
||||
assert(width > 1);
|
||||
assert(width <= 128);
|
||||
__uint128_t unity = 1;
|
||||
__uint128_t mask = (unity << width) - 1;
|
||||
assert(width <= 32);
|
||||
uintm_t unity = 1;
|
||||
uintm_t mask = (unity << width) - 1;
|
||||
return ((word >> (width - 1)) & 0x1) ? (word | ~mask) : word;
|
||||
}
|
||||
|
||||
inline uint64_t nan_box(uint32_t word) {
|
||||
return word | 0xFFFFFFFF00000000;
|
||||
inline uintf_t nan_box(uint32_t word) {
|
||||
uintf_t mask = uintf_t(0xffffffff00000000);
|
||||
return word | mask;
|
||||
}
|
||||
@@ -300,10 +300,12 @@ uint64_t rv_fle_d(uint64_t a, uint64_t b, uint32_t* fflags) {
|
||||
|
||||
uint32_t rv_feq_s(uint64_t a, uint64_t b, uint32_t* fflags) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Either a or b isn't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) || (b >> 32 != 0xffffffff)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto r = f32_eq(to_float32_t(a), to_float32_t(b));
|
||||
if (fflags) { *fflags = get_fflags(); }
|
||||
@@ -436,6 +438,7 @@ uint64_t rv_fclss_d(uint64_t a) {
|
||||
|
||||
uint32_t rv_fsgnj_s(uint64_t a, uint64_t b) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Both a and b aren't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) && (b >> 32 != 0xffffffff)) {
|
||||
return 0x7fc00000;
|
||||
@@ -447,6 +450,7 @@ uint32_t rv_fsgnj_s(uint64_t a, uint64_t b) {
|
||||
// b is NaN boxed but a isn't
|
||||
if(a >> 32 != 0xffffffff)
|
||||
return 0xffc00000;
|
||||
#endif
|
||||
|
||||
int sign = b & F32_SIGN;
|
||||
int r = sign | (a & ~F32_SIGN);
|
||||
@@ -464,6 +468,7 @@ uint64_t rv_fsgnj_d(uint64_t a, uint64_t b) {
|
||||
|
||||
uint32_t rv_fsgnjn_s(uint64_t a, uint64_t b) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Both a and b aren't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) && (b >> 32 != 0xffffffff)) {
|
||||
return 0x7fc00000;
|
||||
@@ -475,6 +480,7 @@ uint32_t rv_fsgnjn_s(uint64_t a, uint64_t b) {
|
||||
// b is NaN boxed but a isn't
|
||||
if(a >> 32 != 0xffffffff)
|
||||
return 0xffc00000;
|
||||
#endif
|
||||
|
||||
int sign = ~b & F32_SIGN;
|
||||
int r = sign | (a & ~F32_SIGN);
|
||||
@@ -492,6 +498,7 @@ uint64_t rv_fsgnjn_d(uint64_t a, uint64_t b) {
|
||||
|
||||
uint32_t rv_fsgnjx_s(uint64_t a, uint64_t b) {
|
||||
|
||||
#if FLEN == 64
|
||||
// Both a and b aren't NaN boxed
|
||||
if ((a >> 32 != 0xffffffff) && (b >> 32 != 0xffffffff)) {
|
||||
return 0x7fc00000;
|
||||
@@ -503,7 +510,8 @@ uint32_t rv_fsgnjx_s(uint64_t a, uint64_t b) {
|
||||
// b is NaN boxed but a isn't
|
||||
if(a >> 32 != 0xffffffff)
|
||||
return 0xffc00000;
|
||||
|
||||
#endif
|
||||
|
||||
int sign1 = a & F32_SIGN;
|
||||
int sign2 = b & F32_SIGN;
|
||||
int r = (sign1 ^ sign2) | (a & ~F32_SIGN);
|
||||
|
||||
35
sim/common/xlen.h
Normal file
35
sim/common/xlen.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef XLEN
|
||||
#define XLEN 32
|
||||
#endif
|
||||
|
||||
#ifndef FLEN
|
||||
#define FLEN 32
|
||||
#endif
|
||||
|
||||
#if XLEN == 32
|
||||
#define uintx_t uint32_t
|
||||
#define intx_t int32_t
|
||||
#define intm_t int64_t
|
||||
#define uintm_t uint64_t
|
||||
#elif XLEN == 64
|
||||
#define uintx_t uint64_t
|
||||
#define intx_t int64_t
|
||||
#define intm_t __int128_t
|
||||
#define uintm_t __uint128_t
|
||||
#else
|
||||
#error unsupported XLEN
|
||||
#endif
|
||||
|
||||
#if FLEN >= XLEN
|
||||
#if FLEN == 32
|
||||
#define uintf_t uint32_t
|
||||
#elif FLEN == 64
|
||||
#define uintf_t uint64_t
|
||||
#else
|
||||
#error unsupported FLEN
|
||||
#endif
|
||||
#else
|
||||
#error unsupported FLEN
|
||||
#endif
|
||||
Reference in New Issue
Block a user