44#ifndef __ARCH_RISCV_UTILITY_HH__
45#define __ARCH_RISCV_UTILITY_HH__
59#include "enums/RiscvType.hh"
89template<
typename T>
inline bool
99 && (
reinterpret_cast<uint32_t&
>(
val)&0x00400000);
102template<>
inline bool
106 && (
reinterpret_cast<uint64_t&
>(
val)&0x0008000000000000ULL);
109template<
typename T>
inline bool
115template<>
inline bool
119 && (
reinterpret_cast<uint32_t&
>(
val)&0x00200000);
122template<>
inline bool
126 && (
reinterpret_cast<uint64_t&
>(
val)&0x0004000000000000ULL);
143 std::stringstream str;
144 str <<
"?? (x" <<
reg.index() <<
')';
150 std::stringstream str;
151 str <<
"?? (f" <<
reg.index() <<
')';
157 std::stringstream str;
158 str <<
"?? (v" <<
reg.index() <<
')';
170template <
typename T>
inline std::make_unsigned_t<T>
174 return ((WideT)
rs1 *
rs2) >> (
sizeof(T) * 8);
177template <
typename T>
inline std::make_signed_t<T>
181 return ((WideT)
rs1 *
rs2) >> (
sizeof(T) * 8);
184template <
typename T>
inline std::make_signed_t<T>
188 return ((WideT)
rs1 *
rs2) >> (
sizeof(T) * 8);
191template<
typename T>
inline T
194 constexpr T kRsMin = std::numeric_limits<T>::min();
197 }
else if (
rs1 == kRsMin &&
rs2 == -1) {
204template<
typename T>
inline T
208 return std::numeric_limits<T>::max();
214template<
typename T>
inline T
217 constexpr T kRsMin = std::numeric_limits<T>::min();
220 }
else if (
rs1 == kRsMin &&
rs2 == -1) {
227template<
typename T>
inline T
237 return 8 <<
bits(vtype, 5, 3);
261 const bool per_reg =
false)
263 int64_t lmul = (int64_t)
sext<3>(
bits(vtype, 2, 0));
264 lmul = per_reg ? std::min<int64_t>(0, lmul) : lmul;
266 return vlen >> (
vsew + 3 - lmul);
278 int64_t lmul = (int64_t)
sext<3>(
bits(vtype, 2, 0));
279 return 1 << std::max<int64_t>(0, lmul);
285 vtype = (uint64_t)0 ^ (1UL << (
sizeof(
RegVal) * 8 - 1));
292 case 0b000:
return 8;
293 case 0b101:
return 16;
294 case 0b110:
return 32;
295 case 0b111:
return 64;
296 default: GEM5_UNREACHABLE;
309 static_assert(std::is_integral_v<T>);
310 int idx =
index / (
sizeof(T)*8);
311 int pos =
index % (
sizeof(T)*8);
312 return (
vs[idx] >> pos) & 1;
319 int index = floor(elem / num_fields);
320 static_assert(std::is_integral_v<T>);
321 int idx =
index / (
sizeof(T)*8);
322 int pos =
index % (
sizeof(T)*8);
323 return (
vs[idx] >> pos) & 1;
326template<
typename FloatType,
typename IntType = decltype(FloatType::v)>
auto
329 if constexpr(std::is_same_v<uint32_t, IntType>)
331 else if constexpr(std::is_same_v<uint64_t, IntType>)
333 else if constexpr(std::is_same_v<uint16_t, IntType>)
340template<
typename FloatType,
typename IntType = decltype(FloatType::v)>
auto
343 if constexpr(std::is_same_v<uint32_t, IntType>)
345 else if constexpr(std::is_same_v<uint64_t, IntType>)
347 else if constexpr(std::is_same_v<uint16_t, IntType>)
352template<
typename FloatType> FloatType
355 if constexpr(std::is_same_v<float32_t, FloatType>)
356 return f32_add(
a,
b);
357 else if constexpr(std::is_same_v<float64_t, FloatType>)
358 return f64_add(
a,
b);
359 else if constexpr(std::is_same_v<float16_t, FloatType>)
360 return f16_add(
a,
b);
364template<
typename FloatType> FloatType
367 if constexpr(std::is_same_v<float32_t, FloatType>)
368 return f32_sub(
a,
b);
369 else if constexpr(std::is_same_v<float64_t, FloatType>)
370 return f64_sub(
a,
b);
371 else if constexpr(std::is_same_v<float16_t, FloatType>)
372 return f16_sub(
a,
b);
376template<
typename FloatType> FloatType
379 if constexpr(std::is_same_v<float32_t, FloatType>)
380 return f32_min(
a,
b);
381 else if constexpr(std::is_same_v<float64_t, FloatType>)
382 return f64_min(
a,
b);
383 else if constexpr(std::is_same_v<float16_t, FloatType>)
384 return f16_min(
a,
b);
388template<
typename FloatType> FloatType
391 if constexpr(std::is_same_v<float32_t, FloatType>)
392 return f32_max(
a,
b);
393 else if constexpr(std::is_same_v<float64_t, FloatType>)
394 return f64_max(
a,
b);
395 else if constexpr(std::is_same_v<float16_t, FloatType>)
396 return f16_max(
a,
b);
400template<
typename FloatType> FloatType
403 if constexpr(std::is_same_v<float32_t, FloatType>)
404 return f32_div(
a,
b);
405 else if constexpr(std::is_same_v<float64_t, FloatType>)
406 return f64_div(
a,
b);
407 else if constexpr(std::is_same_v<float16_t, FloatType>)
408 return f16_div(
a,
b);
412template<
typename FloatType> FloatType
415 if constexpr(std::is_same_v<float32_t, FloatType>)
416 return f32_mul(
a,
b);
417 else if constexpr(std::is_same_v<float64_t, FloatType>)
418 return f64_mul(
a,
b);
419 else if constexpr(std::is_same_v<float16_t, FloatType>)
420 return f16_mul(
a,
b);
424template<
typename FloatType> FloatType
427 if constexpr(std::is_same_v<float32_t, FloatType>)
429 else if constexpr(std::is_same_v<float64_t, FloatType>)
431 else if constexpr(std::is_same_v<float16_t, FloatType>)
436template<
typename FloatType> FloatType
439 if constexpr(std::is_same_v<float32_t, FloatType>)
440 return f32_rsqrte7(
a);
441 else if constexpr(std::is_same_v<float64_t, FloatType>)
442 return f64_rsqrte7(
a);
443 else if constexpr(std::is_same_v<float16_t, FloatType>)
444 return f16_rsqrte7(
a);
448template<
typename FloatType> FloatType
451 if constexpr(std::is_same_v<float32_t, FloatType>)
452 return f32_recip7(
a);
453 else if constexpr(std::is_same_v<float64_t, FloatType>)
454 return f64_recip7(
a);
455 else if constexpr(std::is_same_v<float16_t, FloatType>)
456 return f16_recip7(
a);
460template<
typename FloatType> FloatType
463 if constexpr(std::is_same_v<float32_t, FloatType>)
464 return f32(f32_classify(
a));
465 else if constexpr(std::is_same_v<float64_t, FloatType>)
466 return f64(f64_classify(
a));
467 else if constexpr(std::is_same_v<float16_t, FloatType>)
468 return f16(f16_classify(
a));
472template<
typename FloatType> FloatType
475 if constexpr(std::is_same_v<float32_t, FloatType>)
477 else if constexpr(std::is_same_v<float64_t, FloatType>)
479 else if constexpr(std::is_same_v<float16_t, FloatType>)
484template<
typename FloatType>
bool
487 if constexpr(std::is_same_v<float32_t, FloatType>)
489 else if constexpr(std::is_same_v<float64_t, FloatType>)
491 else if constexpr(std::is_same_v<float16_t, FloatType>)
496template<
typename FloatType>
bool
499 if constexpr(std::is_same_v<float32_t, FloatType>)
501 else if constexpr(std::is_same_v<float64_t, FloatType>)
503 else if constexpr(std::is_same_v<float16_t, FloatType>)
508template<
typename FloatType>
bool
511 if constexpr(std::is_same_v<float32_t, FloatType>)
513 else if constexpr(std::is_same_v<float64_t, FloatType>)
515 else if constexpr(std::is_same_v<float16_t, FloatType>)
520template<
typename FloatType> FloatType
523 if constexpr(std::is_same_v<float32_t, FloatType>)
524 return f32_mulAdd(
a,
b,
c);
525 else if constexpr(std::is_same_v<float64_t, FloatType>)
526 return f64_mulAdd(
a,
b,
c);
527 else if constexpr(std::is_same_v<float16_t, FloatType>)
528 return f16_mulAdd(
a,
b,
c);
532template<
typename FloatType> FloatType
535 if constexpr(std::is_same_v<float32_t, FloatType>)
536 return f32(
a.v ^ uint32_t(
mask(31, 31)));
537 else if constexpr(std::is_same_v<float64_t, FloatType>)
539 else if constexpr(std::is_same_v<float16_t, FloatType>)
540 return f16(
a.v ^ uint16_t(
mask(15, 15)));
544template<typename FT, typename WFT = typename double_width<FT>::type> WFT
547 if constexpr(std::is_same_v<float32_t, FT>)
548 return f32_to_f64(
a);
549 else if constexpr(std::is_same_v<float16_t, FT>)
550 return f16_to_f32(
a);
554template<
typename FloatType,
typename IntType = decltype(FloatType::v)> IntType
557 if constexpr(std::is_same_v<float32_t, FloatType>)
558 return f32_to_ui32(
a,
mode,
true);
559 else if constexpr(std::is_same_v<float64_t, FloatType>)
560 return f64_to_ui64(
a,
mode,
true);
561 else if constexpr(std::is_same_v<float16_t, FloatType>)
562 return f16_to_ui16(
a,
mode,
true);
572 if constexpr(std::is_same_v<float32_t, FloatType>)
573 return f32_to_ui64(
a,
mode,
true);
574 else if constexpr(std::is_same_v<float16_t, FloatType>)
575 return f16_to_ui32(
a,
mode,
true);
585 if constexpr(std::is_same_v<float64_t, FloatType>)
586 return f64_to_ui32(
a,
mode,
true);
587 else if constexpr(std::is_same_v<float32_t, FloatType>)
588 return f32_to_ui16(
a,
mode,
true);
589 else if constexpr(std::is_same_v<float16_t, FloatType>)
590 return f16_to_ui8(
a,
mode,
true);
594template<
typename FloatType,
typename IntType = decltype(FloatType::v)> IntType
597 if constexpr(std::is_same_v<float32_t, FloatType>)
598 return (uint32_t)f32_to_i32(
a,
mode,
true);
599 else if constexpr(std::is_same_v<float64_t, FloatType>)
600 return (uint64_t)f64_to_i64(
a,
mode,
true);
601 else if constexpr(std::is_same_v<float16_t, FloatType>)
602 return (uint16_t)f16_to_i16(
a,
mode,
true);
612 if constexpr(std::is_same_v<float32_t, FloatType>)
613 return (uint64_t)f32_to_i64(
a,
mode,
true);
614 else if constexpr(std::is_same_v<float16_t, FloatType>)
615 return (uint32_t)f16_to_i32(
a,
mode,
true);
625 if constexpr(std::is_same_v<float64_t, FloatType>)
626 return (uint32_t)f64_to_i32(
a,
mode,
true);
627 else if constexpr(std::is_same_v<float32_t, FloatType>)
628 return (uint16_t)f32_to_i16(
a,
mode,
true);
629 else if constexpr(std::is_same_v<float16_t, FloatType>)
630 return (uint8_t)f16_to_i8(
a,
mode,
true);
634template<
typename FloatType,
typename IntType = decltype(FloatType::v)>
638 if constexpr(std::is_same_v<float32_t, FloatType>)
639 return ui32_to_f32(
a);
640 else if constexpr(std::is_same_v<float64_t, FloatType>)
641 return ui64_to_f64(
a);
642 else if constexpr(std::is_same_v<float16_t, FloatType>)
643 return ui32_to_f16(
a);
653 if constexpr(std::is_same_v<float64_t, FloatType>)
654 return ui32_to_f64(
a);
655 else if constexpr(std::is_same_v<float32_t, FloatType>)
656 return ui32_to_f32(
a);
657 else if constexpr(std::is_same_v<float16_t, FloatType>)
658 return ui32_to_f16(
a);
668 if constexpr(std::is_same_v<float32_t, FloatType>)
669 return ui64_to_f32(
a);
670 else if constexpr(std::is_same_v<float16_t, FloatType>)
671 return ui32_to_f16(
a);
675template<
typename FloatType,
typename IntType = decltype(FloatType::v)>
679 if constexpr(std::is_same_v<float32_t, FloatType>)
680 return i32_to_f32((int32_t)
a);
681 else if constexpr(std::is_same_v<float64_t, FloatType>)
682 return i64_to_f64((int64_t)
a);
683 else if constexpr(std::is_same_v<float16_t, FloatType>)
684 return i32_to_f16((int16_t)
a);
694 if constexpr(std::is_same_v<float64_t, FloatType>)
695 return i32_to_f64((int32_t)
a);
696 else if constexpr(std::is_same_v<float32_t, FloatType>)
697 return i32_to_f32((int16_t)
a);
698 else if constexpr(std::is_same_v<float16_t, FloatType>)
699 return i32_to_f16((int8_t)
a);
705 typename IntType = std::make_signed_t<
711 if constexpr(std::is_same_v<float32_t, FloatType>)
712 return i64_to_f32(
a);
713 else if constexpr(std::is_same_v<float16_t, FloatType>)
714 return i32_to_f16(
a);
724 if constexpr(std::is_same_v<float32_t, FloatType>)
725 return f32_to_f64(
a);
726 else if constexpr(std::is_same_v<float16_t, FloatType>)
727 return f16_to_f32(
a);
737 if constexpr(std::is_same_v<float64_t, FloatType>)
738 return f64_to_f32(
a);
739 else if constexpr(std::is_same_v<float32_t, FloatType>)
740 return f32_to_f16(
a);
745template<
typename T> T
748 using UT = std::make_unsigned_t<T>;
753 int sh =
sizeof(T) * 8 - 1;
755 ux = (
ux >>
sh) + (((UT)0x1 <<
sh) - 1);
757 if ((T) ((
ux ^ uy) | ~(uy ^ res)) >= 0) {
764template<
typename T> T
767 using UT = std::make_unsigned_t<T>;
772 int sh =
sizeof(T) * 8 - 1;
774 ux = (
ux >>
sh) + (((UT)0x1 <<
sh) - 1);
776 if ((T) ((
ux ^ uy) & (
ux ^ res)) < 0) {
783template<
typename T> T
797template<
typename T> T
802 bool t = !(res <=
x);
816template<
typename T> T
818 const uint64_t lsb = 1UL << gb;
819 const uint64_t lsb_half = lsb >> 1;
825 if ((result & lsb_half) &&
826 ((result & (lsb_half - 1)) || (result & lsb)))
832 if (result & (lsb - 1))
836 panic(
"Invalid xrm value %d", (
int)xrm);
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Register ID: describe an architectural register with its class and index.
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
#define panic(...)
This implements a cprintf based panic() function.
const std::vector< std::string > RegNames
const std::vector< std::string > RegNames
float32_t fsgnj32(float32_t a, float32_t b, bool n, bool x)
FloatType ui_to_nf(IntType a)
float16_t fsgnj16(float16_t a, float16_t b, bool n, bool x)
bool flt(FloatType a, FloatType b)
T sat_subu(T x, T y, bool *sat)
std::make_unsigned_t< T > mulhu(std::make_unsigned_t< T > rs1, std::make_unsigned_t< T > rs2)
FloatWType f_to_wf(FloatType a)
static constexpr float32_t f32(uint32_t v)
int elem_mask(const T *vs, const int index)
FloatType fclassify(FloatType a)
FloatType frsqrte7(FloatType a)
bool issignalingnan< double >(double val)
uint64_t vtype_VLMAX(const uint64_t vtype, const uint64_t vlen, const bool per_reg=false)
IntType f_to_i(FloatType a, uint_fast8_t mode)
std::make_signed_t< T > mulh(std::make_signed_t< T > rs1, std::make_signed_t< T > rs2)
int elem_mask_vseg(const T *vs, const int elem, const int num_fields)
IntType f_to_ni(FloatType a, uint_fast8_t mode)
IntType f_to_ui(FloatType a, uint_fast8_t mode)
FloatType fadd(FloatType a, FloatType b)
FloatType frecip7(FloatType a)
IntType f_to_wui(FloatType a, uint_fast8_t mode)
bool isquietnan< double >(double val)
static constexpr float16_t f16(uint16_t v)
bool issignalingnan(T val)
bool isquietnan< float >(float val)
std::string registerName(RegId reg)
FloatType fmadd(FloatType a, FloatType b, FloatType c)
FloatType i_to_f(IntType a)
const std::vector< std::string > VecRegNames
FloatType fmin(FloatType a, FloatType b)
bool feq(FloatType a, FloatType b)
bool fle(FloatType a, FloatType b)
auto ftype_freg(freg_t a) -> FloatType
std::make_signed_t< T > mulhsu(std::make_signed_t< T > rs1, std::make_unsigned_t< T > rs2)
uint64_t vtype_regs_per_group(const uint64_t vtype)
T int_rounding(T result, uint8_t xrm, unsigned gb)
Ref: https://github.com/riscv-software-src/riscv-isa-sim.
FloatType fmul(FloatType a, FloatType b)
FloatNType f_to_nf(FloatType a)
FloatType i_to_nf(IntType a)
T sat_add(T x, T y, bool *sat)
void vtype_set_vill(uint64_t &vtype)
int64_t vtype_vlmul(const uint64_t vtype)
static constexpr float64_t f64(uint64_t v)
FloatType fsub(FloatType a, FloatType b)
float64_t fsgnj64(float64_t a, float64_t b, bool n, bool x)
T sat_addu(T x, T y, bool *sat)
FloatType fsgnj(FloatType a, FloatType b, bool n, bool x)
FloatType i_to_wf(IntType a)
FloatType fneg(FloatType a)
FloatType fsqrt(FloatType a)
T sat_sub(T x, T y, bool *sat)
FloatType ui_to_wf(IntType a)
FloatType fmax(FloatType a, FloatType b)
bool issignalingnan< float >(float val)
IntType f_to_nui(FloatType a, uint_fast8_t mode)
uint64_t vtype_SEW(const uint64_t vtype)
FloatType fdiv(FloatType a, FloatType b)
auto ftype(IntType a) -> FloatType
IntType f_to_wi(FloatType a, uint_fast8_t mode)
FloatType ui_to_f(IntType a)
uint64_t width_EEW(uint64_t width)
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
@ FloatRegClass
Floating-point register.
@ VecRegClass
Vector Register.
@ IntRegClass
Integer register.
constexpr bool isnan(gem5::AMDGPU::fp16_e5m10_info a)