HDLRuby 2.2.14 → 2.3.1

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.
@@ -39,6 +39,7 @@ module HDLRuby::Low
39
39
  ## Find an inner object by +name+.
40
40
  # NOTE: return nil if not found.
41
41
  def get_by_name(name)
42
+ # puts "getbyname for name=#{name} with self=#{self}"
42
43
  # Ensure the name is a symbol.
43
44
  name = name.to_sym
44
45
  # Look in the signals.
@@ -90,7 +91,7 @@ module HDLRuby::Low
90
91
 
91
92
  ## Tells if it is a reference to a systemI signal.
92
93
  def from_systemI?
93
- return self.ref.from_systemI
94
+ return self.ref.from_systemI?
94
95
  end
95
96
  end
96
97
 
@@ -102,7 +103,7 @@ module HDLRuby::Low
102
103
 
103
104
  ## Tells if it is a reference to a systemI signal.
104
105
  def from_systemI?
105
- return self.ref.from_systemI
106
+ return self.ref.from_systemI?
106
107
  end
107
108
  end
108
109
 
@@ -114,16 +115,17 @@ module HDLRuby::Low
114
115
 
115
116
  ## Tells if it is a reference to a systemI signal.
116
117
  def from_systemI?
117
- # puts "from_systemI? for #{self.name}"
118
118
  # Look for the owner from the name hierarchy.
119
119
  if self.ref.is_a?(RefName) then
120
120
  # Look in the parent hierachy for the sub reference name.
121
121
  parent = self.parent
122
+ # puts "self.ref.name=#{self.ref.name}"
122
123
  while parent
124
+ # puts "parent=#{parent}"
123
125
  if parent.respond_to?(:get_by_name) then
124
126
  found = parent.get_by_name(self.ref.name)
125
127
  # puts "found is a :#{found.class}"
126
- return found.is_a?(SystemI)
128
+ return found.is_a?(SystemI) if found
127
129
  end
128
130
  parent = parent.parent
129
131
  end
@@ -151,6 +153,7 @@ module HDLRuby::Low
151
153
  parent = self.parent
152
154
  # puts "parent=#{parent}"
153
155
  while parent
156
+ # puts "parent=#{parent}"
154
157
  if parent.respond_to?(:get_by_name) then
155
158
  found = parent.get_by_name(self.name)
156
159
  return found if found
@@ -187,11 +187,13 @@ module HDLRuby::Low
187
187
  # Generate the assignment.
188
188
  block.add_statement(
189
189
  Transmit.new(ref.clone,
190
- RefIndex.new(aux.type.base, aux.clone, idx)))
190
+ # RefIndex.new(aux.type.base, aux.clone, idx)))
191
+ RefIndex.new(bit, aux.clone, idx)))
191
192
  else
192
193
  # Multi-bits.
193
194
  # Compute the type of the right value.
194
- rtype = TypeVector.new(:"",aux.type.base,range)
195
+ # rtype = TypeVector.new(:"",aux.type.base,range)
196
+ rtype = TypeVector.new(:"",bit,range)
195
197
  # Generate the range.
196
198
  range = Value.new(Integer,range.first) ..
197
199
  Value.new(Integer,range.last)
@@ -272,11 +274,13 @@ module HDLRuby::Low
272
274
  # Generate the assignment.
273
275
  block.add_statement(
274
276
  Transmit.new(ref.clone,
275
- RefIndex.new(aux.type.base, aux.clone, idx)))
277
+ # RefIndex.new(aux.type.base, aux.clone, idx)))
278
+ RefIndex.new(bit, aux.clone, idx)))
276
279
  else
277
280
  # Multi-bits.
278
281
  # Compute the type of the right value.
279
- rtype = TypeVector.new(:"",aux.type.base,range)
282
+ # rtype = TypeVector.new(:"",aux.type.base,range)
283
+ rtype = TypeVector.new(:"",bit,range)
280
284
  # Generate the range.
281
285
  range = Value.new(Integer,range.first) ..
282
286
  Value.new(Integer,range.last)
@@ -76,19 +76,21 @@ module HDLRuby
76
76
 
77
77
  # Addition.
78
78
  def +(type)
79
- # Resolve the type class.
80
- resolved = self.resolve(type)
81
- # New type range: largest range + 1
82
- bounds = [ self.range.first.to_i, type.range.first.to_i,
83
- self.range.last.to_i, type.range.last.to_i ]
84
- res_lsb = bounds.min
85
- res_msb = bounds.max + 1
86
- # Create and return the new type: its endianess is the one of self
87
- if self.range.first.to_i > self.range.last.to_i then
88
- return resolved.make(:"",resolved.base,res_msb..res_lsb)
89
- else
90
- return resolved.make(:"",resolved.base,res_lsb..res_msb)
91
- end
79
+ # # Resolve the type class.
80
+ # resolved = self.resolve(type)
81
+ # # New type range: largest range + 1
82
+ # bounds = [ self.range.first.to_i, type.range.first.to_i,
83
+ # self.range.last.to_i, type.range.last.to_i ]
84
+ # res_lsb = bounds.min
85
+ # res_msb = bounds.max + 1
86
+ # # Create and return the new type: its endianess is the one of self
87
+ # if self.range.first.to_i > self.range.last.to_i then
88
+ # return resolved.make(:"",resolved.base,res_msb..res_lsb)
89
+ # else
90
+ # return resolved.make(:"",resolved.base,res_lsb..res_msb)
91
+ # end
92
+ # The result is the resolve result now!
93
+ return self.resolve(type)
92
94
  end
93
95
 
94
96
  # Subtraction
@@ -96,36 +98,40 @@ module HDLRuby
96
98
 
97
99
  # Multiplication
98
100
  def *(type)
99
- # Resolve the type class.
100
- resolved = self.resolve(type)
101
- # New type range: largest range * 2
102
- bounds = [ self.range.first.to_i, type.range.first.to_i,
103
- self.range.last.to_i, type.range.last.to_i ]
104
- res_lsb = bounds.min
105
- res_msb = bounds.max * 2
106
- # Create and return the new type: its endianess is the one of self
107
- if self.range.first.to_i > self.range.last.to_i then
108
- return resolved.make(:"",resolved.base,res_msb..res_lsb)
109
- else
110
- return resolved.make(:"",resolved.base,res_lsb..res_msb)
111
- end
101
+ # # Resolve the type class.
102
+ # resolved = self.resolve(type)
103
+ # # New type range: largest range * 2
104
+ # bounds = [ self.range.first.to_i, type.range.first.to_i,
105
+ # self.range.last.to_i, type.range.last.to_i ]
106
+ # res_lsb = bounds.min
107
+ # res_msb = bounds.max * 2
108
+ # # Create and return the new type: its endianess is the one of self
109
+ # if self.range.first.to_i > self.range.last.to_i then
110
+ # return resolved.make(:"",resolved.base,res_msb..res_lsb)
111
+ # else
112
+ # return resolved.make(:"",resolved.base,res_lsb..res_msb)
113
+ # end
114
+ # The result is the resolve result now!
115
+ return self.resolve(type)
112
116
  end
113
117
 
114
118
  # Division
115
119
  def /(type)
116
- # Resolve the type class.
117
- resolved = self.resolve(type)
118
- # New type range: largest range
119
- bounds = [ self.range.first.to_i, type.range.first.to_i,
120
- self.range.last.to_i, type.range.last.to_i ]
121
- res_lsb = bounds.min
122
- res_msb = bounds.max
123
- # Create and return the new type: its endianess is the one of self
124
- if self.range.first.to_i > self.range.last.to_i then
125
- return resolved.make(:"",resolved.base,res_msb..res_lsb)
126
- else
127
- return resolved.make(:"",resolved.base,res_lsb..res_msb)
128
- end
120
+ # # Resolve the type class.
121
+ # resolved = self.resolve(type)
122
+ # # New type range: largest range
123
+ # bounds = [ self.range.first.to_i, type.range.first.to_i,
124
+ # self.range.last.to_i, type.range.last.to_i ]
125
+ # res_lsb = bounds.min
126
+ # res_msb = bounds.max
127
+ # # Create and return the new type: its endianess is the one of self
128
+ # if self.range.first.to_i > self.range.last.to_i then
129
+ # return resolved.make(:"",resolved.base,res_msb..res_lsb)
130
+ # else
131
+ # return resolved.make(:"",resolved.base,res_lsb..res_msb)
132
+ # end
133
+ # The result is the resolve result now!
134
+ return self.resolve(type)
129
135
  end
130
136
 
131
137
  # Modulo
@@ -151,26 +157,28 @@ module HDLRuby
151
157
 
152
158
  # And
153
159
  def &(type)
154
- # puts "compute types with=#{self} and #{type}"
155
- # Resolve the type class.
156
- resolved = self.resolve(type)
157
-
158
- # Logical operation on non-vector types are kept as is.
159
- return resolved unless resolved.is_a?(TypeVector)
160
-
161
- # Otherwise the range is computed.
162
- # New type range: largest range
163
- bounds = [ self.range.first.to_i, type.range.first.to_i,
164
- self.range.last.to_i, type.range.last.to_i ]
165
- # puts "bounds=#{bounds}"
166
- res_lsb = bounds.min
167
- res_msb = bounds.max
168
- # Create and return the new type: its endianess is the one of self
169
- if self.range.first.to_i > self.range.last.to_i then
170
- return resolved.make(:"",resolved.base,res_msb..res_lsb)
171
- else
172
- return resolved.make(:"",resolved.base,res_lsb..res_msb)
173
- end
160
+ # # puts "compute types with=#{self} and #{type}"
161
+ # # Resolve the type class.
162
+ # resolved = self.resolve(type)
163
+ #
164
+ # # Logical operation on non-vector types are kept as is.
165
+ # return resolved unless resolved.is_a?(TypeVector)
166
+
167
+ # # Otherwise the range is computed.
168
+ # # New type range: largest range
169
+ # bounds = [ self.range.first.to_i, type.range.first.to_i,
170
+ # self.range.last.to_i, type.range.last.to_i ]
171
+ # # puts "bounds=#{bounds}"
172
+ # res_lsb = bounds.min
173
+ # res_msb = bounds.max
174
+ # # Create and return the new type: its endianess is the one of self
175
+ # if self.range.first.to_i > self.range.last.to_i then
176
+ # return resolved.make(:"",resolved.base,res_msb..res_lsb)
177
+ # else
178
+ # return resolved.make(:"",resolved.base,res_lsb..res_msb)
179
+ # end
180
+ # The result is the resolve result now!
181
+ return self.resolve(type)
174
182
  end
175
183
 
176
184
  # Or
@@ -211,19 +219,21 @@ module HDLRuby
211
219
 
212
220
  # Shift left
213
221
  def <<(type)
214
- # The result type is the type of left.
215
- resolved = self
216
- # New type range: 2**(type width) times self range
217
- bounds = [ self.range.first.to_i, self.range.last.to_i ]
218
- res_lsb = bounds.min
219
- res_msb = bounds.max +
220
- (2 ** ((type.range.last-type.range.first).abs))
221
- # Create and return the new type: its endianess is the one of self
222
- if self.range.first.to_i > self.range.last.to_i then
223
- return resolved.make(:"",resolved.base,res_msb..res_lsb)
224
- else
225
- return resolved.make(:"",resolved.base,res_lsb..res_msb)
226
- end
222
+ # # The result type is the type of left.
223
+ # resolved = self
224
+ # # New type range: 2**(type width) times self range
225
+ # bounds = [ self.range.first.to_i, self.range.last.to_i ]
226
+ # res_lsb = bounds.min
227
+ # res_msb = bounds.max +
228
+ # (2 ** ((type.range.last-type.range.first).abs))
229
+ # # Create and return the new type: its endianess is the one of self
230
+ # if self.range.first.to_i > self.range.last.to_i then
231
+ # return resolved.make(:"",resolved.base,res_msb..res_lsb)
232
+ # else
233
+ # return resolved.make(:"",resolved.base,res_lsb..res_msb)
234
+ # end
235
+ # The result is the resolve result now!
236
+ return self.resolve(type)
227
237
  end
228
238
 
229
239
  alias_method :ls, :<<
@@ -1630,12 +1630,20 @@ end
1630
1630
  # If it is signed, it outputs signed.
1631
1631
  # Enhance Type with generation of verilog code.
1632
1632
  class Type
1633
- # Converts the system to Verilog code.
1633
+ # Converts the type to Verilog code.
1634
1634
  def to_verilog
1635
1635
  return self.name == :signed ? "#{self.name.to_s} " : ""
1636
1636
  end
1637
1637
  end
1638
1638
 
1639
+ # Replace type by refered type.
1640
+ class TypeDef
1641
+ # Converts the type to verilog code.
1642
+ def to_verilog
1643
+ return self.def.to_verilog
1644
+ end
1645
+ end
1646
+
1639
1647
  # Use it when collecting.
1640
1648
  class Concat
1641
1649
  def to_verilog
@@ -157,6 +157,13 @@ extern Value mul_value(Value src0, Value src1, Value dst);
157
157
  * @return dst */
158
158
  extern Value div_value(Value src0, Value src1, Value dst);
159
159
 
160
+ /** Computes the modulo of two general values.
161
+ * @param src0 the first source value of the addition
162
+ * @param src1 the second source value of the addition
163
+ * @param dst the destination value
164
+ * @return dst */
165
+ extern Value mod_value(Value src0, Value src1, Value dst);
166
+
160
167
  /** Computes the not of a value.
161
168
  * @param src the source value of the not
162
169
  * @param dst the destination value
@@ -205,6 +212,20 @@ Value shift_right_value(Value src0, Value src1, Value dst);
205
212
  * @return dst */
206
213
  extern Value equal_value(Value src0, Value src1, Value dst);
207
214
 
215
+ /** Computes the lesser comparision of two values.
216
+ * @param src0 the first source value of the addition
217
+ * @param src1 the second source value of the addition
218
+ * @param dst the destination value
219
+ * @return dst */
220
+ extern Value lesser_value(Value src0, Value src1, Value dst);
221
+
222
+ /** Computes the greater comparision of two values.
223
+ * @param src0 the first source value of the addition
224
+ * @param src1 the second source value of the addition
225
+ * @param dst the destination value
226
+ * @return dst */
227
+ extern Value greater_value(Value src0, Value src1, Value dst);
228
+
208
229
  /** Selects a value depending on a condition.
209
230
  * @param cond the condition to use for selecting a value
210
231
  * @param dst the destination value
@@ -5,6 +5,10 @@
5
5
  #include <limits.h>
6
6
  #include "hruby_sim.h"
7
7
 
8
+ #ifndef alloca
9
+ #define alloca(x) __builtin_alloca(x)
10
+ #endif
11
+
8
12
 
9
13
  /**
10
14
  * The HDLRuby simulation calculation engine, to be used with C code
@@ -284,6 +288,11 @@ Value make_set_value(Type type, int numeric, void* data) {
284
288
  // }
285
289
  // }
286
290
 
291
+ /* Defined after.*/
292
+ static unsigned long long
293
+ fix_numeric_type(Type type, unsigned long long val);
294
+
295
+
287
296
  /** Copies a value to another, the type of the destination is preserved.
288
297
  * @param src the source value
289
298
  * @param dst the destination value
@@ -296,7 +305,7 @@ Value copy_value(Value src, Value dst) {
296
305
  /* Copy the data. */
297
306
  if (src->numeric) {
298
307
  /* Numeric copy. */
299
- dst->data_int = src->data_int;
308
+ dst->data_int = fix_numeric_type(dst->type,src->data_int);
300
309
  } else {
301
310
  /* Resize the destination if required. */
302
311
  resize_value(dst,type_width(dst->type));
@@ -388,6 +397,9 @@ static Value set_undefined_bitstring(Value dst) {
388
397
 
389
398
  /* set the type and size of the destination. */
390
399
  dst->numeric = 0;
400
+ /* Ensures the buffer of dst has the write size (in cas it was a fromer
401
+ * numeric for example). */
402
+ resize_value(dst,width);
391
403
 
392
404
  /* Get access to the destination data. */
393
405
  char* dst_data = dst->data_str;
@@ -595,7 +607,7 @@ static Value mul_value_defined_bitstring(Value src0, Value src1, Value dst) {
595
607
  dst->type = src0->type;
596
608
  dst->numeric = 1;
597
609
 
598
- /* Perform the addition. */
610
+ /* Perform the multiplication. */
599
611
  dst->data_int = value2integer(src0) * value2integer(src1);
600
612
  return dst;
601
613
  }
@@ -611,12 +623,61 @@ static Value div_value_defined_bitstring(Value src0, Value src1, Value dst) {
611
623
  dst->type = src0->type;
612
624
  dst->numeric = 1;
613
625
 
614
- /* Perform the addition. */
626
+ /* Perform the division. */
615
627
  dst->data_int = value2integer(src0) / value2integer(src1);
616
628
  return dst;
617
629
  }
618
630
 
619
631
 
632
+ /** Computes the modulo of two defined bitstring values.
633
+ * @param src0 the first source value of the addition
634
+ * @param src1 the second source value of the addition
635
+ * @param dst the destination value
636
+ * @return dst */
637
+ static Value mod_value_defined_bitstring(Value src0, Value src1, Value dst) {
638
+ /* Sets state of the destination using the first source. */
639
+ dst->type = src0->type;
640
+ dst->numeric = 1;
641
+
642
+ /* Perform the modulo. */
643
+ // printf("modulo with src0=%lld src1=%lld, result=%lld\n",value2integer(src0),value2integer(src1),value2integer(src0) % value2integer(src1));
644
+ dst->data_int = value2integer(src0) % value2integer(src1);
645
+ return dst;
646
+ }
647
+
648
+
649
+ /** Computes the lesser comparision of two defined bitstring values.
650
+ * @param src0 the first source value of the addition
651
+ * @param src1 the second source value of the addition
652
+ * @param dst the destination value
653
+ * @return dst */
654
+ static Value lesser_value_defined_bitstring(Value src0, Value src1, Value dst) {
655
+ /* Sets state of the destination using the first source. */
656
+ dst->type = src0->type;
657
+ dst->numeric = 1;
658
+
659
+ /* Perform the comparison. */
660
+ dst->data_int = (value2integer(src0) < value2integer(src1));
661
+ return dst;
662
+ }
663
+
664
+
665
+ /** Computes the greater comparision of two defined bitstring values.
666
+ * @param src0 the first source value of the addition
667
+ * @param src1 the second source value of the addition
668
+ * @param dst the destination value
669
+ * @return dst */
670
+ static Value greater_value_defined_bitstring(Value src0, Value src1, Value dst) {
671
+ /* Sets state of the destination using the first source. */
672
+ dst->type = src0->type;
673
+ dst->numeric = 1;
674
+
675
+ /* Perform the comparison. */
676
+ dst->data_int = (value2integer(src0) > value2integer(src1));
677
+ return dst;
678
+ }
679
+
680
+
620
681
  /** Computes the NOT of a bitstring value.
621
682
  * @param src the source value of the not
622
683
  * @param dst the destination value
@@ -1364,6 +1425,40 @@ Value write_range_bitstring_no_z(Value src, long long first, long long last,
1364
1425
 
1365
1426
  /* ############# Start of the computation of numeric values. ############## */
1366
1427
 
1428
+ /** Fix the content of a numeric value according to its type so that
1429
+ * it can be used for C numeric computation.
1430
+ * @param type the type to fix the value to
1431
+ * @param val the value to fix
1432
+ * @return the rsulting value */
1433
+ static unsigned long long
1434
+ fix_numeric_type(Type type, unsigned long long val) {
1435
+ /* Get the width of the type. */
1436
+ int width = type_width(type);
1437
+ /* Compute the base mask. */
1438
+ // unsigned long long mask = ((unsigned long long)(-1)) << width;
1439
+ /* NOTE: (ull)-1 << 64 becomes (ull)-1 on Intel processors, this is
1440
+ * totally not what I expected (I expected 0). */
1441
+ unsigned long long mask = width == 64 ? 0 : ((unsigned long long)(-1)) << width;
1442
+ // printf("width=%i val=%llu mask=%llx\n",width,val,mask);
1443
+
1444
+ /* Is the type signed? */
1445
+ if (type->flags.sign) {
1446
+ /* Yes, perform sign extension. */
1447
+ int is_neg = (val >> (width-1)) & 1;
1448
+ // printf("is_neg=%i\n",is_neg);
1449
+ if (is_neg) {
1450
+ /* Negative sign extension. */
1451
+ return val | mask;
1452
+ } else {
1453
+ /* Positive sign extension. */
1454
+ return val & ~mask;
1455
+ }
1456
+ } else {
1457
+ /* No, perform a zero extension. */
1458
+ return val & ~mask;
1459
+ }
1460
+ }
1461
+
1367
1462
 
1368
1463
  /** Computes the neg of a numeric value.
1369
1464
  * @param src the source value of the not
@@ -1375,7 +1470,7 @@ static Value neg_value_numeric(Value src, Value dst) {
1375
1470
  dst->numeric = 1;
1376
1471
 
1377
1472
  /* Perform the negation. */
1378
- dst->data_int = -src->data_int;
1473
+ dst->data_int = fix_numeric_type(dst->type,-src->data_int);
1379
1474
  return dst;
1380
1475
  }
1381
1476
 
@@ -1391,7 +1486,7 @@ static Value add_value_numeric(Value src0, Value src1, Value dst) {
1391
1486
  dst->numeric = 1;
1392
1487
 
1393
1488
  /* Perform the addition. */
1394
- dst->data_int = src0->data_int + src1->data_int;
1489
+ dst->data_int = fix_numeric_type(dst->type,src0->data_int + src1->data_int);
1395
1490
  return dst;
1396
1491
  }
1397
1492
 
@@ -1407,7 +1502,7 @@ static Value sub_value_numeric(Value src0, Value src1, Value dst) {
1407
1502
  dst->numeric = 1;
1408
1503
 
1409
1504
  /* Perform the subtraction. */
1410
- dst->data_int = src0->data_int - src1->data_int;
1505
+ dst->data_int = fix_numeric_type(dst->type,src0->data_int - src1->data_int);
1411
1506
  return dst;
1412
1507
  }
1413
1508
 
@@ -1422,8 +1517,8 @@ static Value mul_value_numeric(Value src0, Value src1, Value dst) {
1422
1517
  dst->type = src0->type;
1423
1518
  dst->numeric = 1;
1424
1519
 
1425
- /* Perform the addition. */
1426
- dst->data_int = src0->data_int * src1->data_int;
1520
+ /* Perform the multiplication. */
1521
+ dst->data_int = fix_numeric_type(dst->type, src0->data_int * src1->data_int);
1427
1522
  return dst;
1428
1523
  }
1429
1524
 
@@ -1438,8 +1533,25 @@ static Value div_value_numeric(Value src0, Value src1, Value dst) {
1438
1533
  dst->type = src0->type;
1439
1534
  dst->numeric = 1;
1440
1535
 
1441
- /* Perform the addition. */
1442
- dst->data_int = src0->data_int / src1->data_int;
1536
+ /* Perform the division. */
1537
+ dst->data_int = fix_numeric_type(dst->type, src0->data_int / src1->data_int);
1538
+ return dst;
1539
+ }
1540
+
1541
+
1542
+ /** Computes the modulo of two numeric values.
1543
+ * @param src0 the first source value of the addition
1544
+ * @param src1 the second source value of the addition
1545
+ * @param dst the destination value
1546
+ * @return dst */
1547
+ static Value mod_value_numeric(Value src0, Value src1, Value dst) {
1548
+ /* Sets state of the destination using the first source. */
1549
+ dst->type = src0->type;
1550
+ dst->numeric = 1;
1551
+
1552
+ /* Perform the division. */
1553
+ // printf("modulo numeric with src0=%lld src1=%lld, result=%lld\n",src0->data_int, src1->data_int,src0->data_int % src1->data_int);
1554
+ dst->data_int = fix_numeric_type(dst->type, src0->data_int % src1->data_int);
1443
1555
  return dst;
1444
1556
  }
1445
1557
 
@@ -1454,7 +1566,7 @@ static Value not_value_numeric(Value src, Value dst) {
1454
1566
  dst->numeric = 1;
1455
1567
 
1456
1568
  /* Perform the not. */
1457
- dst->data_int = !src->data_int;
1569
+ dst->data_int = fix_numeric_type(dst->type,!src->data_int);
1458
1570
  return dst;
1459
1571
  }
1460
1572
 
@@ -1518,7 +1630,7 @@ static Value shift_left_value_numeric(Value src0, Value src1, Value dst) {
1518
1630
  dst->numeric = 1;
1519
1631
 
1520
1632
  /* Perform the left shift. */
1521
- dst->data_int = src0->data_int << src1->data_int;
1633
+ dst->data_int = fix_numeric_type(dst->type,src0->data_int << src1->data_int);
1522
1634
  return dst;
1523
1635
  }
1524
1636
 
@@ -1534,7 +1646,7 @@ static Value shift_right_value_numeric(Value src0, Value src1, Value dst) {
1534
1646
  dst->numeric = 1;
1535
1647
 
1536
1648
  /* Perform the right shift. */
1537
- dst->data_int = src0->data_int >> src1->data_int;
1649
+ dst->data_int = fix_numeric_type(dst->type,src0->data_int >> src1->data_int);
1538
1650
  return dst;
1539
1651
  }
1540
1652
 
@@ -1555,6 +1667,37 @@ static Value equal_value_numeric(Value src0, Value src1, Value dst) {
1555
1667
  }
1556
1668
 
1557
1669
 
1670
+ /** Computes the lesser comparision of two numeric values.
1671
+ * @param src0 the first source value of the addition
1672
+ * @param src1 the second source value of the addition
1673
+ * @param dst the destination value
1674
+ * @return the destination value */
1675
+ static Value lesser_value_numeric(Value src0, Value src1, Value dst) {
1676
+ /* Sets state of the destination using the first source. */
1677
+ dst->type = src0->type;
1678
+ dst->numeric = 1;
1679
+
1680
+ /* Perform the lesser. */
1681
+ dst->data_int = (src0->data_int < src1->data_int);
1682
+ return dst;
1683
+ }
1684
+
1685
+ /** Computes the greater comparision of two numeric values.
1686
+ * @param src0 the first source value of the addition
1687
+ * @param src1 the second source value of the addition
1688
+ * @param dst the destination value
1689
+ * @return the destination value */
1690
+ static Value greater_value_numeric(Value src0, Value src1, Value dst) {
1691
+ /* Sets state of the destination using the first source. */
1692
+ dst->type = src0->type;
1693
+ dst->numeric = 1;
1694
+
1695
+ /* Perform the lesser. */
1696
+ dst->data_int = (src0->data_int > src1->data_int);
1697
+ return dst;
1698
+ }
1699
+
1700
+
1558
1701
  /** Selects a value depending on a numeric condition.
1559
1702
  * @param cond the condition to use for selecting a value
1560
1703
  * @param dst the destination value (used only if new value is created).
@@ -1587,7 +1730,7 @@ static Value concat_value_numeric_array(int num, int dir,
1587
1730
  unsigned int i,pos;
1588
1731
  /* Compute the bit width of the destination. */
1589
1732
  unsigned int width = 0;
1590
- // printf("concat_value_numeric with dir=%d\n",dir);
1733
+ // printf("concat_value_numeric with dir=%d and width=%llu\n",dir,type_width(args[0]->type));
1591
1734
  for(i=0; i<num; ++i) width += type_width(args[i]->type);
1592
1735
 
1593
1736
  /* Sets state of the destination using the bit width. */
@@ -1611,6 +1754,7 @@ static Value concat_value_numeric_array(int num, int dir,
1611
1754
  pos += arg_width;
1612
1755
  }
1613
1756
  /* Return the destination. */
1757
+ // printf("Result is dst=%llx\n",dst->data_int);
1614
1758
  return dst;
1615
1759
  }
1616
1760
 
@@ -1621,6 +1765,7 @@ static Value concat_value_numeric_array(int num, int dir,
1621
1765
  * @param dst the destination value
1622
1766
  * @return dst */
1623
1767
  static Value cast_value_numeric(Value src, Type type, Value dst) {
1768
+ // printf("cast_value_numeric with src=%llx",src->data_int);
1624
1769
  /* Copy the source to the destination. */
1625
1770
  dst->data_int = src->data_int;
1626
1771
  /* Update the destination type to the cast. */
@@ -1680,6 +1825,7 @@ static int same_content_value_range_numeric(Value value0,
1680
1825
  * @return dst */
1681
1826
  Value read_range_numeric(Value value, long long first, long long last,
1682
1827
  Type base, Value dst) {
1828
+ /* printf("read_range_numeric with value=%llx and first=%llu and last=%llu\n",value->data_int,first,last); */
1683
1829
  /* Ensure first is the smaller. */
1684
1830
  if (first > last) {
1685
1831
  long long tmp = last;
@@ -1692,15 +1838,18 @@ Value read_range_numeric(Value value, long long first, long long last,
1692
1838
  unsigned long long bw = type_width(base);
1693
1839
  /* Scale the range according to the base type. */
1694
1840
  first *= bw;
1841
+ last *= bw;
1695
1842
  length *= bw;
1696
- // printf("first=%lld last=%lld bw=%llu length=%lld\n",first,last,bw,length);
1843
+ /* printf("first=%lld last=%lld bw=%llu length=%lld\n",first,last,bw,length); */
1697
1844
 
1698
1845
  /* Set the type and size of the destination from the type of the source.*/
1699
1846
  dst->type = make_type_vector(get_type_bit(),length);
1700
1847
  dst->numeric = 1;
1701
1848
 
1702
1849
  /* Compute the read mask. */
1703
- unsigned long long mask = ((-1LL) << first) & (~((-1LL) << (last+1)));
1850
+ // unsigned long long mask = ((-1LL) << first) & (~((-1LL) << (last+1)));
1851
+ /* NOTE: once again, << 64 does not work like expected. */
1852
+ unsigned long long mask = mask+bw < 64 ? (~((-1LL) << (last+bw))) : -1LL;
1704
1853
  /* Performs the read. */
1705
1854
  unsigned long long data = (value->data_int & mask) >> first;
1706
1855
  /* Write it to the destination. */
@@ -1719,6 +1868,7 @@ Value read_range_numeric(Value value, long long first, long long last,
1719
1868
  * @return dst */
1720
1869
  Value write_range_numeric(Value src, long long first, long long last,
1721
1870
  Value dst) {
1871
+ // printf("write_range_numeric\n");
1722
1872
  /* Ensure first is the smaller. */
1723
1873
  if (first > last) {
1724
1874
  long long tmp = last;
@@ -1730,6 +1880,7 @@ Value write_range_numeric(Value src, long long first, long long last,
1730
1880
  unsigned long long dst_width = type_width(dst->type);
1731
1881
  /* scale the range according to the base type of the destination. */
1732
1882
  unsigned long long bw = dst->type->base;
1883
+ // printf("src_width=%llu dst_wdith=%llu bw=%llu\n",src_width,dst_width,bw);
1733
1884
  first *= bw;
1734
1885
  last *= bw;
1735
1886
  /* If first is too large, end here. */
@@ -1737,11 +1888,13 @@ Value write_range_numeric(Value src, long long first, long long last,
1737
1888
  /* Adjust the last to fit the source and destination range. */
1738
1889
  if (last >= dst_width) last = dst_width-1;
1739
1890
  if (last-first >= src_width) last = src_width + first - 1;
1891
+ // printf("first=%lld last=%lld\n",first,last);
1740
1892
  /* Copy from the source. */
1741
- unsigned long long src_data = src->data_int & ~((-1LL) << (last-first));
1893
+ unsigned long long src_data = src->data_int & ~((-1LL) << (last-first+1));
1742
1894
  /* Cleans the destination where to place the data. */
1743
- unsigned long long mask = ((-1LL) << first) & ~((-1LL) << last);
1895
+ unsigned long long mask = ~(((-1LL) << first) & ~((-1LL) << (last+1)));
1744
1896
  unsigned long long dst_data = dst->data_int & mask;
1897
+ // printf("src_data=%llx mask=%llx dst_data=%llx\n",src_data,mask,dst_data);
1745
1898
  /* Write the data. */
1746
1899
  dst_data |= src_data << first;
1747
1900
  dst->data_int = dst_data;
@@ -1892,6 +2045,33 @@ Value div_value(Value src0, Value src1, Value dst) {
1892
2045
  }
1893
2046
 
1894
2047
 
2048
+ /** Computes the modulo of two general values.
2049
+ * @param src0 the first source value of the addition
2050
+ * @param src1 the second source value of the addition
2051
+ * @param dst the destination value
2052
+ * @return dst */
2053
+ Value mod_value(Value src0, Value src1, Value dst) {
2054
+ /* Might allocate a new value so save the current pool state. */
2055
+ unsigned int pos = get_value_pos();
2056
+ /* Do a numeric computation if possible, otherwise fallback to bitstring
2057
+ * computation. */
2058
+ if (src0->numeric && src1->numeric) {
2059
+ /* Both sources are numeric. */
2060
+ return mod_value_numeric(src0,src1,dst);
2061
+ } else if (is_defined_value(src0) && is_defined_value(src1)) {
2062
+ /* Both sources can be converted to numeric values. */
2063
+ return mod_value_defined_bitstring(src0,src1,dst);
2064
+ } else {
2065
+ /* Cannot compute (for now), simply undefines the destination. */
2066
+ /* First ensure dst has the right shape. */
2067
+ copy_value(src0,dst);
2068
+ /* Then make it undefined. */
2069
+ set_undefined_bitstring(dst);
2070
+ }
2071
+ return dst;
2072
+ }
2073
+
2074
+
1895
2075
  /** Computes the NOT of a general value.
1896
2076
  * @param src the source value of the not
1897
2077
  * @param dst the destination value
@@ -2111,6 +2291,60 @@ Value equal_value(Value src0, Value src1, Value dst) {
2111
2291
  }
2112
2292
 
2113
2293
 
2294
+ /** Computes the lesser comparision of two general values.
2295
+ * @param src0 the first source value of the addition
2296
+ * @param src1 the second source value of the addition
2297
+ * @param dst the destination value
2298
+ * @return dst */
2299
+ Value lesser_value(Value src0, Value src1, Value dst) {
2300
+ /* Might allocate a new value so save the current pool state. */
2301
+ unsigned int pos = get_value_pos();
2302
+ /* Do a numeric computation if possible, otherwise fallback to bitstring
2303
+ * computation. */
2304
+ if (src0->numeric && src1->numeric) {
2305
+ /* Both sources are numeric. */
2306
+ return lesser_value_numeric(src0,src1,dst);
2307
+ } else if (is_defined_value(src0) && is_defined_value(src1)) {
2308
+ /* Both sources can be converted to numeric values. */
2309
+ return lesser_value_defined_bitstring(src0,src1,dst);
2310
+ } else {
2311
+ /* Cannot compute (for now), simply undefines the destination. */
2312
+ /* First ensure dst has the right shape. */
2313
+ copy_value(src0,dst);
2314
+ /* Then make it undefined. */
2315
+ set_undefined_bitstring(dst);
2316
+ }
2317
+ return dst;
2318
+ }
2319
+
2320
+
2321
+ /** Computes the greater comparision of two general values.
2322
+ * @param src0 the first source value of the addition
2323
+ * @param src1 the second source value of the addition
2324
+ * @param dst the destination value
2325
+ * @return dst */
2326
+ Value greater_value(Value src0, Value src1, Value dst) {
2327
+ /* Might allocate a new value so save the current pool state. */
2328
+ unsigned int pos = get_value_pos();
2329
+ /* Do a numeric computation if possible, otherwise fallback to bitstring
2330
+ * computation. */
2331
+ if (src0->numeric && src1->numeric) {
2332
+ /* Both sources are numeric. */
2333
+ return greater_value_numeric(src0,src1,dst);
2334
+ } else if (is_defined_value(src0) && is_defined_value(src1)) {
2335
+ /* Both sources can be converted to numeric values. */
2336
+ return greater_value_defined_bitstring(src0,src1,dst);
2337
+ } else {
2338
+ /* Cannot compute (for now), simply undefines the destination. */
2339
+ /* First ensure dst has the right shape. */
2340
+ copy_value(src0,dst);
2341
+ /* Then make it undefined. */
2342
+ set_undefined_bitstring(dst);
2343
+ }
2344
+ return dst;
2345
+ }
2346
+
2347
+
2114
2348
  /** Selects a value depending on a general condition.
2115
2349
  * @param cond the condition to use for selecting a value
2116
2350
  * @param dst the destination value (used only if new value is created).
@@ -2460,6 +2694,7 @@ Value read_range(Value value, long long first, long long last, Type base,
2460
2694
  * @param dst the destination value
2461
2695
  * @return dst */
2462
2696
  Value write_range(Value src, long long first, long long last, Value dst) {
2697
+ // printf("write_range\n");
2463
2698
  /* Is the value numeric? */
2464
2699
  if ((src->numeric) && (dst->numeric)) {
2465
2700
  /* Yes, do a numeric range read. */
@@ -2485,6 +2720,7 @@ Value write_range(Value src, long long first, long long last, Value dst) {
2485
2720
  * @param dst the destination value
2486
2721
  * @return dst */
2487
2722
  Value write_range_no_z(Value src, long long first, long long last, Value dst) {
2723
+ // printf("write_range_no_z\n");
2488
2724
  /* Is the value numeric? */
2489
2725
  if ((src->numeric) && (dst->numeric)) {
2490
2726
  /* Yes, do a numeric range read. */