udb 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.data/cfgs/mc100-32-full-example.yaml +0 -35
  3. data/.data/cfgs/qc_iu.yaml +0 -33
  4. data/.data/cfgs/rv32-riscv-tests.yaml +5 -1
  5. data/.data/cfgs/rv64-riscv-tests.yaml +4 -1
  6. data/.data/spec/std/isa/inst/F/fadd.s.yaml +16 -1
  7. data/.data/spec/std/isa/inst/F/fclass.s.yaml +7 -0
  8. data/.data/spec/std/isa/inst/F/fcvt.l.s.yaml +3 -0
  9. data/.data/spec/std/isa/inst/F/fcvt.lu.s.yaml +3 -0
  10. data/.data/spec/std/isa/inst/F/fcvt.s.l.yaml +4 -0
  11. data/.data/spec/std/isa/inst/F/fcvt.s.lu.yaml +4 -0
  12. data/.data/spec/std/isa/inst/F/fcvt.w.s.yaml +1 -1
  13. data/.data/spec/std/isa/inst/F/fcvt.wu.s.yaml +1 -1
  14. data/.data/spec/std/isa/inst/F/fdiv.s.yaml +4 -0
  15. data/.data/spec/std/isa/inst/F/feq.s.yaml +1 -1
  16. data/.data/spec/std/isa/inst/F/fle.s.yaml +14 -7
  17. data/.data/spec/std/isa/inst/F/fleq.s.yaml +30 -0
  18. data/.data/spec/std/isa/inst/F/flt.s.yaml +13 -8
  19. data/.data/spec/std/isa/inst/F/fltq.s.yaml +21 -0
  20. data/.data/spec/std/isa/inst/F/fmadd.s.yaml +4 -0
  21. data/.data/spec/std/isa/inst/F/fmax.s.yaml +30 -0
  22. data/.data/spec/std/isa/inst/F/fmin.s.yaml +30 -0
  23. data/.data/spec/std/isa/inst/F/fmsub.s.yaml +4 -0
  24. data/.data/spec/std/isa/inst/F/fmul.s.yaml +4 -0
  25. data/.data/spec/std/isa/inst/F/fnmadd.s.yaml +7 -0
  26. data/.data/spec/std/isa/inst/F/fnmsub.s.yaml +4 -0
  27. data/.data/spec/std/isa/inst/F/fsqrt.s.yaml +4 -0
  28. data/.data/spec/std/isa/isa/fp.idl +911 -101
  29. data/.data/spec/std/isa/isa/globals.isa +2 -0
  30. data/.data/spec/std/isa/isa/util.idl +22 -0
  31. data/.data/spec/std/isa/param/SCOUNTENABLE_EN.yaml +1 -1
  32. data/lib/udb/cfg_arch.rb +42 -6
  33. data/lib/udb/condition.rb +66 -2
  34. data/lib/udb/logic.rb +27 -1
  35. data/lib/udb/version.rb +1 -1
  36. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f633f98551a4aa2c5d06e7d0be863a75ca5d4809c9ca5da6588969608395792
4
- data.tar.gz: 9a0d1549e91a1267534f0a9579d94b1ee4e3de41eb3bafe23bd0c9be5b1961d8
3
+ metadata.gz: e3ee0e5cbe7e1f156b670b2851038ac508058f5ded02fcfa77b1d37dfd3b2801
4
+ data.tar.gz: d29e24404ee97a185b1d77a364e6d9f62d7d803e6f5cdb8f023554e61610f9e0
5
5
  SHA512:
6
- metadata.gz: d3a982c3050f9de63c98daee99156d70d40bef14dc7f91ca2b4ecd8f8635aba9c1b138a4d876726400b4feebd77848fa456dd23834af6fb12b0333ecea368498
7
- data.tar.gz: 308312a745f2187e722b796eeb7b2c465119bf1f982bb4361066bd624b95775bbbde6ec2604cfd08846a86d2a43646ae0836e561cd0730cdc97f1812bf0aedab
6
+ metadata.gz: da552e97506e8c03646f6d3c8d9da8dc6ee4d69f4d73d4766595d831ae92e7cfc12930bb71b42853582ad94f14e23c08c5b2912da1f522ed5d209d6f573f8717
7
+ data.tar.gz: 4de7021d90135149aa34fcf3dc9c1028b41a21eb7fcc7a7fbd0d5afb9bbc5b71398a37e57a969196ba3daafebfaa9465fc82b849fe0cf3d7b66e58f5fca099c4
@@ -161,38 +161,3 @@ params:
161
161
  false,
162
162
  false,
163
163
  ]
164
- SCOUNTENABLE_EN:
165
- [
166
- false,
167
- false,
168
- false,
169
- false,
170
- false,
171
- false,
172
- false,
173
- false,
174
- false,
175
- false,
176
- false,
177
- false,
178
- false,
179
- false,
180
- false,
181
- false,
182
- false,
183
- false,
184
- false,
185
- false,
186
- false,
187
- false,
188
- false,
189
- false,
190
- false,
191
- false,
192
- false,
193
- false,
194
- false,
195
- false,
196
- false,
197
- false,
198
- ]
@@ -115,39 +115,6 @@ params:
115
115
  - false # HPM29
116
116
  - false # HPM30
117
117
  - false # HPM31
118
- SCOUNTENABLE_EN:
119
- - false # CY
120
- - false # empty
121
- - false # IR
122
- - false # HPM3
123
- - false # HPM4
124
- - false # HPM5
125
- - false # HPM6
126
- - false # HPM7
127
- - false # HPM8
128
- - false # HPM9
129
- - false # HPM10
130
- - false # HPM11
131
- - false # HPM12
132
- - false # HPM13
133
- - false # HPM14
134
- - false # HPM15
135
- - false # HPM16
136
- - false # HPM17
137
- - false # HPM18
138
- - false # HPM19
139
- - false # HPM20
140
- - false # HPM21
141
- - false # HPM22
142
- - false # HPM23
143
- - false # HPM24
144
- - false # HPM25
145
- - false # HPM26
146
- - false # HPM27
147
- - false # HPM28
148
- - false # HPM29
149
- - false # HPM30
150
- - false # HPM31
151
118
  COUNTINHIBIT_EN:
152
119
  - true # CY
153
120
  - false # empty
@@ -19,6 +19,8 @@ implemented_extensions:
19
19
  - [U, "1.0.0"]
20
20
  - [Zifencei, "2.0.0"]
21
21
  - [Sv32, "1.11.0"]
22
+ - [F, "2.2.0"]
23
+ - [Zcf, "1.0"]
22
24
 
23
25
  params:
24
26
  MXLEN: 32
@@ -191,7 +193,7 @@ params:
191
193
  TRAP_ON_ECALL_FROM_S: true
192
194
  TRAP_ON_SFENCE_VMA_WHEN_SATP_MODE_IS_READ_ONLY: false
193
195
  MSTATUS_VS_LEGAL_VALUES: [0]
194
- MSTATUS_FS_LEGAL_VALUES: [0]
196
+ MSTATUS_FS_LEGAL_VALUES: [3, 2, 1, 0]
195
197
  MSTATUS_TVM_IMPLEMENTED: false
196
198
  NUM_PMP_ENTRIES: 16
197
199
  PMP_GRANULARITY: 12
@@ -240,3 +242,5 @@ params:
240
242
  # MSTATEEN_CSRIND_TYPE: rw
241
243
  # MSTATEEN_IMSIC_TYPE: rw
242
244
  # MSTATEEN_JVT_TYPE: rw
245
+ HW_MSTATUS_FS_DIRTY_UPDATE: precise
246
+ MUTABLE_MISA_F: false
@@ -19,6 +19,7 @@ implemented_extensions:
19
19
  - [Zifencei, "2.0.0"]
20
20
  - [Sv39, "1.11.0"]
21
21
  - [Zca, "1.0.0"]
22
+ - [F, "2.2.0"]
22
23
 
23
24
  params:
24
25
  MXLEN: 64
@@ -191,7 +192,7 @@ params:
191
192
  TRAP_ON_ECALL_FROM_U: true
192
193
  TRAP_ON_SFENCE_VMA_WHEN_SATP_MODE_IS_READ_ONLY: false
193
194
  MSTATUS_VS_LEGAL_VALUES: [0]
194
- MSTATUS_FS_LEGAL_VALUES: [0]
195
+ MSTATUS_FS_LEGAL_VALUES: [3, 2, 1, 0]
195
196
  MSTATUS_TVM_IMPLEMENTED: false
196
197
  NUM_PMP_ENTRIES: 16
197
198
  PMP_GRANULARITY: 12
@@ -199,6 +200,8 @@ params:
199
200
  U_MODE_ENDIANNESS: little
200
201
  UXLEN: [64]
201
202
  MSTATEEN_ENVCFG_TYPE: rw
203
+ HW_MSTATUS_FS_DIRTY_UPDATE: precise
204
+ MUTABLE_MISA_F: false
202
205
  HPM_COUNTER_EN:
203
206
  [
204
207
  false,
@@ -34,4 +34,19 @@ data_independent_timing: true
34
34
  operation(): |
35
35
  check_f_ok($encoding);
36
36
  RoundingMode mode = rm_to_mode(rm, $encoding);
37
- f[fd] = f32_add(f[fs1], f[fs2], mode);
37
+ Bits<32> a = f[fs1];
38
+ Bits<32> b = f[fs2];
39
+
40
+ if (implemented?(ExtensionName::D)) {
41
+ # check for incorrectly NaN-boxed inputs
42
+ if (f[fs1][63:32] != 32'hffffffff) {
43
+ a = SP_CANONICAL_NAN;
44
+ }
45
+ if (f[fs2][63:32] != 32'hffffffff) {
46
+ b = SP_CANONICAL_NAN;
47
+ }
48
+ }
49
+
50
+ f[fd] = f32_add(a, b, mode);
51
+
52
+ mark_f_state_dirty();
@@ -53,6 +53,13 @@ operation(): |
53
53
 
54
54
  Bits<32> sp_value = f[fs1][31:0];
55
55
 
56
+ if (implemented?(ExtensionName::D)) {
57
+ # check for an incorrectly NaN-boxed value
58
+ if (f[fs1][63:32] != 32'hffffffff) {
59
+ sp_value = SP_CANONICAL_NAN;
60
+ }
61
+ }
62
+
56
63
  if (is_sp_neg_inf?(sp_value)) {
57
64
  X[xd] = 1 << 0;
58
65
  } else if (is_sp_neg_norm?(sp_value)) {
@@ -32,3 +32,6 @@ access:
32
32
  vu: always
33
33
  data_independent_timing: true
34
34
  operation(): |
35
+ check_f_ok($encoding);
36
+ RoundingMode rounding_mode = rm_to_mode(rm, $encoding);
37
+ X[xd] = f32_to_i64(f[fs1], rounding_mode);
@@ -32,3 +32,6 @@ access:
32
32
  vu: always
33
33
  data_independent_timing: true
34
34
  operation(): |
35
+ check_f_ok($encoding);
36
+ RoundingMode rounding_mode = rm_to_mode(rm, $encoding);
37
+ X[xd] = f32_to_ui64(f[fs1], rounding_mode);
@@ -32,3 +32,7 @@ access:
32
32
  vu: always
33
33
  data_independent_timing: true
34
34
  operation(): |
35
+ check_f_ok($encoding);
36
+ RoundingMode rounding_mode = rm_to_mode(rm, $encoding);
37
+ f[fd] = i64_to_f32(X[xs1], rounding_mode);
38
+ mark_f_state_dirty();
@@ -31,3 +31,7 @@ access:
31
31
  vu: always
32
32
  data_independent_timing: true
33
33
  operation(): |
34
+ check_f_ok($encoding);
35
+ RoundingMode rounding_mode = rm_to_mode(rm, $encoding);
36
+ f[fd] = ui64_to_f32(X[xs1], rounding_mode);
37
+ mark_f_state_dirty();
@@ -60,4 +60,4 @@ data_independent_timing: true
60
60
  operation(): |
61
61
  check_f_ok($encoding);
62
62
  RoundingMode rounding_mode = rm_to_mode(rm, $encoding);
63
- X[xd] = f32_to_i32(f[fs1], rounding_mode);
63
+ X[xd] = $signed(f32_to_i32(f[fs1], rounding_mode));
@@ -59,4 +59,4 @@ data_independent_timing: true
59
59
  operation(): |
60
60
  check_f_ok($encoding);
61
61
  RoundingMode rounding_mode = rm_to_mode(rm, $encoding);
62
- X[xd] = f32_to_ui32(f[fs1], rounding_mode);
62
+ X[xd] = $signed(f32_to_ui32(f[fs1], rounding_mode));
@@ -32,3 +32,7 @@ access:
32
32
  vu: always
33
33
  data_independent_timing: true
34
34
  operation(): |
35
+ check_f_ok($encoding);
36
+ RoundingMode mode = rm_to_mode(rm, $encoding);
37
+ f[fd] = f32_div(f[fs1], f[fs2], mode);
38
+ mark_f_state_dirty();
@@ -35,7 +35,7 @@ operation(): |
35
35
  check_f_ok($encoding);
36
36
 
37
37
  Bits<32> sp_value_a = f[fs1][31:0];
38
- Bits<32> sp_value_b = f[fs1][31:0];
38
+ Bits<32> sp_value_b = f[fs2][31:0];
39
39
 
40
40
  if (is_sp_nan?(sp_value_a) || is_sp_nan?(sp_value_b)) {
41
41
  if (is_sp_signaling_nan?(sp_value_a) || is_sp_signaling_nan?(sp_value_b)) {
@@ -36,15 +36,22 @@ operation(): |
36
36
 
37
37
  Bits<32> sp_value_a = f[fs1][31:0];
38
38
  Bits<32> sp_value_b = f[fs2][31:0];
39
+ Bits<1> sign_a = sp_value_a[31];
40
+ Bits<1> sign_b = sp_value_b[31];
39
41
 
40
42
  if (is_sp_nan?(sp_value_a) || is_sp_nan?(sp_value_b)) {
41
- if (is_sp_signaling_nan?(sp_value_a) || is_sp_signaling_nan?(sp_value_b)) {
42
- set_fp_flag(FpFlag::NV);
43
- }
43
+ set_fp_flag(FpFlag::NV);
44
44
  X[xd] = 0;
45
45
  } else {
46
- X[xd] = (
47
- (sp_value_a == sp_value_b)
48
- || ((sp_value_a | sp_value_b)[30:0] == 0) # pos 0 is equal to neg zero
49
- ) ? 1 : 0;
46
+ if (sign_a != sign_b) {
47
+ X[xd] = (
48
+ (sign_a == 1) || # b is pos and a neg
49
+ ((sp_value_a[30:0] | sp_value_b[30:0]) == 0) # both are zero (one pos, one neg)
50
+ ) ? 1 : 0;
51
+ } else {
52
+ X[xd] = (
53
+ (sp_value_a == sp_value_b) || # a and b are equal
54
+ (sign_a ^ ((sp_value_a < sp_value_b) ? 1 : 0)) == 1 # a < b
55
+ ) ? 1 : 0;
56
+ }
50
57
  }
@@ -30,3 +30,33 @@ access:
30
30
  vu: always
31
31
  data_independent_timing: true
32
32
  operation(): |
33
+ check_f_ok($encoding);
34
+
35
+ Bits<32> sp_value_a = f[fs1][31:0];
36
+ Bits<32> sp_value_b = f[fs2][31:0];
37
+
38
+ if (is_sp_nan?(sp_value_a) || is_sp_nan?(sp_value_b)) {
39
+ # Quiet comparison: only set NV for signaling NaN
40
+ if (is_sp_signaling_nan?(sp_value_a) || is_sp_signaling_nan?(sp_value_b)) {
41
+ set_fp_flag(FpFlag::NV);
42
+ }
43
+ X[xd] = 0;
44
+ } else {
45
+ Boolean sign_a = sp_value_a[31] == 1;
46
+ Boolean sign_b = sp_value_b[31] == 1;
47
+
48
+ # Check equality first (including -0.0 == +0.0)
49
+ Boolean a_eq_b =
50
+ (sp_value_a == sp_value_b)
51
+ || ((sp_value_a | sp_value_b)[30:0] == 0);
52
+
53
+ # Check a < b
54
+ Boolean a_lt_b;
55
+ if (sign_a != sign_b) {
56
+ a_lt_b = sign_a && ((sp_value_a[30:0] | sp_value_b[30:0]) != 0);
57
+ } else {
58
+ a_lt_b = (sp_value_a != sp_value_b) && (sign_a != (sp_value_a < sp_value_b));
59
+ }
60
+
61
+ X[xd] = (a_lt_b || a_eq_b) ? 1 : 0;
62
+ }
@@ -36,17 +36,22 @@ operation(): |
36
36
 
37
37
  Bits<32> sp_value_a = f[fs1][31:0];
38
38
  Bits<32> sp_value_b = f[fs2][31:0];
39
+ Bits<1> sign_a = sp_value_a[31];
40
+ Bits<1> sign_b = sp_value_b[31];
39
41
 
40
42
  if (is_sp_nan?(sp_value_a) || is_sp_nan?(sp_value_b)) {
41
43
  set_fp_flag(FpFlag::NV);
42
44
  X[xd] = 0;
43
45
  } else {
44
- Boolean sign_a = sp_value_a[31] == 1;
45
- Boolean sign_b = sp_value_b[31] == 1;
46
-
47
- Boolean a_lt_b =
48
- (sign_a != sign_b)
49
- ? (sign_a && ((sp_value_a[30:0] | sp_value_b[30:0]) != 0)) # opposite sign, a is negative. a is less than b as long as both are not zero
50
- : ((sp_value_a != sp_value_b) && (sign_a != (sp_value_a < sp_value_b)));
51
- X[xd] = a_lt_b ? 1 : 0;
46
+ if (sign_a != sign_b) {
47
+ X[xd] = (
48
+ (sign_a == 1) # a is neg and b is pos
49
+ && ((sp_value_a[30:0] | sp_value_b[30:0]) != 0) # a and b are not both zero
50
+ ) ? 1 : 0;
51
+ } else {
52
+ X[xd] = (
53
+ (sp_value_a != sp_value_b) # a and b are not equal
54
+ && ((sign_a ^ ((sp_value_a < sp_value_b) ? 1 : 0)) != 0)# a < b
55
+ ) ? 1 : 0;
56
+ }
52
57
  }
@@ -30,3 +30,24 @@ access:
30
30
  vu: always
31
31
  data_independent_timing: true
32
32
  operation(): |
33
+ check_f_ok($encoding);
34
+
35
+ Bits<32> sp_value_a = f[fs1][31:0];
36
+ Bits<32> sp_value_b = f[fs2][31:0];
37
+
38
+ if (is_sp_nan?(sp_value_a) || is_sp_nan?(sp_value_b)) {
39
+ # Quiet comparison: only set NV for signaling NaN
40
+ if (is_sp_signaling_nan?(sp_value_a) || is_sp_signaling_nan?(sp_value_b)) {
41
+ set_fp_flag(FpFlag::NV);
42
+ }
43
+ X[xd] = 0;
44
+ } else {
45
+ Boolean sign_a = sp_value_a[31] == 1;
46
+ Boolean sign_b = sp_value_b[31] == 1;
47
+
48
+ Boolean a_lt_b =
49
+ (sign_a != sign_b)
50
+ ? (sign_a && ((sp_value_a[30:0] | sp_value_b[30:0]) != 0))
51
+ : ((sp_value_a != sp_value_b) && (sign_a != (sp_value_a < sp_value_b)));
52
+ X[xd] = a_lt_b ? 1 : 0;
53
+ }
@@ -33,3 +33,7 @@ access:
33
33
  vu: always
34
34
  data_independent_timing: true
35
35
  operation(): |
36
+ check_f_ok($encoding);
37
+ RoundingMode mode = rm_to_mode(rm, $encoding);
38
+ f[fd] = f32_muladd(f[fs1], f[fs2], f[fs3], F32MulAddOp::Softfloat_mulAdd_addC, mode);
39
+ mark_f_state_dirty();
@@ -39,3 +39,33 @@ access:
39
39
  vu: always
40
40
  data_independent_timing: true
41
41
  operation(): |
42
+ check_f_ok($encoding);
43
+
44
+ Bits<32> sp_value_a = f[fs1][31:0];
45
+ Bits<32> sp_value_b = f[fs2][31:0];
46
+
47
+ if (is_sp_nan?(sp_value_a) || is_sp_nan?(sp_value_b)) {
48
+ if (is_sp_signaling_nan?(sp_value_a) || is_sp_signaling_nan?(sp_value_b)) {
49
+ set_fp_flag(FpFlag::NV);
50
+ }
51
+ # If both are NaN, return canonical NaN; otherwise return the non-NaN operand
52
+ if (is_sp_nan?(sp_value_a) && is_sp_nan?(sp_value_b)) {
53
+ f[fd] = SP_CANONICAL_NAN;
54
+ } else if (is_sp_nan?(sp_value_a)) {
55
+ f[fd] = sp_value_b;
56
+ } else {
57
+ f[fd] = sp_value_a;
58
+ }
59
+ } else {
60
+ Boolean sign_a = sp_value_a[31] == 1;
61
+ Boolean sign_b = sp_value_b[31] == 1;
62
+ Boolean a_lt_b;
63
+ if (sign_a != sign_b) {
64
+ # -0.0 is considered less than +0.0, so it's not a special case
65
+ a_lt_b = sign_a;
66
+ } else {
67
+ a_lt_b = (sp_value_a != sp_value_b) && (sign_a != (sp_value_a < sp_value_b));
68
+ }
69
+ f[fd] = a_lt_b ? sp_value_b : sp_value_a;
70
+ }
71
+ mark_f_state_dirty();
@@ -39,3 +39,33 @@ access:
39
39
  vu: always
40
40
  data_independent_timing: true
41
41
  operation(): |
42
+ check_f_ok($encoding);
43
+
44
+ Bits<32> sp_value_a = f[fs1][31:0];
45
+ Bits<32> sp_value_b = f[fs2][31:0];
46
+
47
+ if (is_sp_nan?(sp_value_a) || is_sp_nan?(sp_value_b)) {
48
+ if (is_sp_signaling_nan?(sp_value_a) || is_sp_signaling_nan?(sp_value_b)) {
49
+ set_fp_flag(FpFlag::NV);
50
+ }
51
+ # If both are NaN, return canonical NaN; otherwise return the non-NaN operand
52
+ if (is_sp_nan?(sp_value_a) && is_sp_nan?(sp_value_b)) {
53
+ f[fd] = SP_CANONICAL_NAN;
54
+ } else if (is_sp_nan?(sp_value_a)) {
55
+ f[fd] = sp_value_b;
56
+ } else {
57
+ f[fd] = sp_value_a;
58
+ }
59
+ } else {
60
+ Boolean sign_a = sp_value_a[31] == 1;
61
+ Boolean sign_b = sp_value_b[31] == 1;
62
+ Boolean a_lt_b;
63
+ if (sign_a != sign_b) {
64
+ # -0.0 is considered less than +0.0, so it's not a special case
65
+ a_lt_b = sign_a;
66
+ } else {
67
+ a_lt_b = (sp_value_a != sp_value_b) && (sign_a != (sp_value_a < sp_value_b));
68
+ }
69
+ f[fd] = a_lt_b ? sp_value_a : sp_value_b;
70
+ }
71
+ mark_f_state_dirty();
@@ -33,3 +33,7 @@ access:
33
33
  vu: always
34
34
  data_independent_timing: true
35
35
  operation(): |
36
+ check_f_ok($encoding);
37
+ RoundingMode mode = rm_to_mode(rm, $encoding);
38
+ f[fd] = f32_muladd(f[fs1], f[fs2], f[fs3], F32MulAddOp::Softfloat_mulAdd_subC, mode);
39
+ mark_f_state_dirty();
@@ -32,3 +32,7 @@ access:
32
32
  vu: always
33
33
  data_independent_timing: true
34
34
  operation(): |
35
+ check_f_ok($encoding);
36
+ RoundingMode mode = rm_to_mode(rm, $encoding);
37
+ f[fd] = f32_mul(f[fs1], f[fs2], mode);
38
+ mark_f_state_dirty();
@@ -34,3 +34,10 @@ access:
34
34
  vu: always
35
35
  data_independent_timing: true
36
36
  operation(): |
37
+ check_f_ok($encoding);
38
+ RoundingMode mode = rm_to_mode(rm, $encoding);
39
+ # fnmadd: -(fs1 * fs2) - fs3 = -(fs1 * fs2) + (-fs3)
40
+ # Negate fs3 by flipping its sign bit, then use subProd op
41
+ Bits<32> fs3_negated = f[fs3][31:0] ^ 32'h80000000;
42
+ f[fd] = f32_muladd(f[fs1], f[fs2], fs3_negated, F32MulAddOp::Softfloat_mulAdd_subProd, mode);
43
+ mark_f_state_dirty();
@@ -34,3 +34,7 @@ access:
34
34
  vu: always
35
35
  data_independent_timing: true
36
36
  operation(): |
37
+ check_f_ok($encoding);
38
+ RoundingMode mode = rm_to_mode(rm, $encoding);
39
+ f[fd] = f32_muladd(f[fs1], f[fs2], f[fs3], F32MulAddOp::Softfloat_mulAdd_subProd, mode);
40
+ mark_f_state_dirty();
@@ -29,3 +29,7 @@ access:
29
29
  vu: always
30
30
  data_independent_timing: true
31
31
  operation(): |
32
+ check_f_ok($encoding);
33
+ RoundingMode mode = rm_to_mode(rm, $encoding);
34
+ f[fd] = f32_sqrt(f[fs1], mode);
35
+ mark_f_state_dirty();