HDLRuby 2.2.13 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -8
- data/lib/HDLRuby/hdr_samples/linear_test.rb +235 -0
- data/lib/HDLRuby/hdr_samples/memory_test.rb +272 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +2 -2
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +96 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +3 -2
- data/lib/HDLRuby/hdr_samples/with_linear.rb +166 -0
- data/lib/HDLRuby/hdr_samples/with_loop.rb +69 -0
- data/lib/HDLRuby/hdr_samples/with_memory.rb +13 -3
- data/lib/HDLRuby/hdrcc.rb +1 -1
- data/lib/HDLRuby/hruby_high.rb +12 -4
- data/lib/HDLRuby/hruby_low.rb +25 -28
- data/lib/HDLRuby/hruby_low2c.rb +10 -5
- data/lib/HDLRuby/hruby_low2high.rb +1 -1
- data/lib/HDLRuby/hruby_low2vhd.rb +63 -48
- data/lib/HDLRuby/hruby_low_fix_types.rb +4 -2
- data/lib/HDLRuby/hruby_low_mutable.rb +2 -1
- data/lib/HDLRuby/hruby_low_resolve.rb +7 -4
- data/lib/HDLRuby/hruby_low_without_concat.rb +8 -4
- data/lib/HDLRuby/hruby_types.rb +82 -72
- data/lib/HDLRuby/hruby_verilog.rb +9 -1
- data/lib/HDLRuby/sim/hruby_sim.h +21 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +254 -18
- data/lib/HDLRuby/std/channel.rb +140 -40
- data/lib/HDLRuby/std/fixpoint.rb +15 -6
- data/lib/HDLRuby/std/linear.rb +317 -0
- data/lib/HDLRuby/std/loop.rb +101 -0
- data/lib/HDLRuby/std/memory.rb +1159 -45
- data/lib/HDLRuby/std/task.rb +850 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +10 -2
@@ -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
|
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
|
data/lib/HDLRuby/sim/hruby_sim.h
CHANGED
@@ -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
|
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
|
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 =
|
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
|
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
|
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 =
|
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
|
-
|
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. */
|