File: common.sail

package info (click to toggle)
sail-ocaml 0.19.1%2Bdfsg5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,008 kB
  • sloc: ml: 75,941; ansic: 8,848; python: 1,342; exp: 560; sh: 474; makefile: 218; cpp: 36
file content (122 lines) | stat: -rw-r--r-- 4,639 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*==========================================================================*/
/*     Sail                                                                 */
/*                                                                          */
/* Copyright 2024 Intel Corporation                                         */
/*   Pan Li - pan2.li@intel.com                                             */
/*                                                                          */
/*  SPDX-License-Identifier: BSD-2-Clause                                   */
/*==========================================================================*/

$ifndef _FLOAT_COMMON
$define _FLOAT_COMMON

/* Floating point types definition */
type fp_exception_flags = bits(5) /* Floating-point exception flags. */
type fp_rounding_modes = bits(5) /* Floating-point rounding modes. */
type fp_bits = { 'n, 'n in {16, 32, 64, 128}. bits('n) } /* Floating-point in bits. */
type fp_bits_x2 = { 'n, 'n in {16, 32, 64, 128}. (bits('n), bits('n)) } /* Floating point x2 tuple */
type fp_bool_and_flags = (bool, fp_exception_flags) /* Floating point bool and exception flags tuple */

/* Floating point constants */
let fp_eflag_none           : fp_exception_flags = 0b00000
let fp_eflag_invalid        : fp_exception_flags = 0b00001
let fp_eflag_divide_by_zero : fp_exception_flags = 0b00010
let fp_eflag_oveflow        : fp_exception_flags = 0b00100
let fp_eflag_underflow      : fp_exception_flags = 0b01000
let fp_eflag_inexact        : fp_exception_flags = 0b10000

let fp_eflag_overflow_and_inexact : fp_exception_flags = fp_eflag_oveflow | fp_eflag_inexact

let fp_rounding_rne     : fp_rounding_modes = 0b00001
let fp_rounding_rna     : fp_rounding_modes = 0b00010
let fp_rounding_rdn     : fp_rounding_modes = 0b00011
let fp_rounding_rup     : fp_rounding_modes = 0b00100
let fp_rounding_rtz     : fp_rounding_modes = 0b00101
let fp_rounding_default : fp_rounding_modes = fp_rounding_rne

/* Floating point global variables */
register fp_rounding_global : fp_rounding_modes = fp_rounding_default

/* Floating point struct */
struct float_bits('n : Int) = {
  sign     : bits(1),
  exp      : bits(if  'n == 16
                  then 5
                  else (if   'n == 32
                        then 8
                        else (if   'n == 64
                              then 11
                              else 15))),
  mantissa : bits(if  'n == 16
                  then 10
                  else (if   'n == 32
                        then 23
                        else (if   'n == 64
                              then 52
                              else 112))),
}

/* The val func implementations */
val      float_decompose : forall 'n, 'n in { 16, 32, 64, 128 }. bits('n) -> float_bits('n)
function float_decompose(op) = {
  match 'n {
    16 => struct {
      sign     = op[15..15],
      exp      = op[14..10],
      mantissa = op[9..0],
    },
    32 => struct {
      sign     = op[31..31],
      exp      = op[30..23],
      mantissa = op[22..0],
    },
    64 => struct {
      sign      = op[63..63],
      exp       = op[62..52],
      mantissa  = op[51..0],
    },
    128 => struct {
      sign      = op[127..127],
      exp       = op[126..112],
      mantissa  = op[111..0],
    }
  }
}

val      float_compose : forall 'n, 'n in { 16, 32, 64, 128 }. float_bits('n) -> bits('n)
function float_compose(op) = op.sign @ op.exp @ op.mantissa

val      float_has_max_exp : forall 'n, 'n in { 16, 32, 64, 128 }. bits('n) -> bool
function float_has_max_exp (op) = {
  let fp = float_decompose (op);
  let bitsize = length (op);
  let one = sail_zero_extend ([bitone], bitsize);
  let two = sail_shiftleft (one, 1);
  let max_exp = sub_bits (sail_shiftleft (one, length (fp.exp)), two);
  let has_max = max_exp == sail_zero_extend (fp.exp, bitsize);

  has_max;
}

val      not : forall ('p : Bool). bool('p) -> bool(not('p))
function not(b) = not_bool(b)

val      is_lowest_one : forall 'n, 0 < 'n. bits('n) -> bool
function is_lowest_one (op) = op[0] == bitone

val      is_highest_one : forall 'n, 0 < 'n. bits('n) -> bool
function is_highest_one (op) = op['n - 1] == bitone

val      is_all_ones : forall 'n, 0 < 'n. bits('n) -> bool
function is_all_ones (op) = op == sail_ones ('n)

val      is_lowest_zero : forall 'n, 0 < 'n. bits('n) -> bool
function is_lowest_zero (op) = op[0] == bitzero

val      is_highest_zero : forall 'n, 0 < 'n. bits('n) -> bool
function is_highest_zero (op) = op['n - 1] == bitzero

val      is_all_zeros : forall 'n, 0 < 'n. bits('n) -> bool
function is_all_zeros (op) = op == sail_zeros ('n)

$endif