HDLRuby 2.2.14 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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. */