HDLRuby 2.2.16 → 2.3.3
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.
- checksums.yaml +4 -4
- data/README.md +33 -21
- 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_channel.rb +49 -8
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +3 -2
- data/lib/HDLRuby/hdr_samples/with_linear.rb +48 -25
- 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 +8 -12
- data/lib/HDLRuby/hruby_check.rb +25 -1
- data/lib/HDLRuby/hruby_high.rb +6 -0
- data/lib/HDLRuby/hruby_low.rb +43 -9
- data/lib/HDLRuby/hruby_low2c.rb +9 -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 +6 -2
- data/lib/HDLRuby/hruby_low_resolve.rb +5 -3
- 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 +7 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +83 -6
- data/lib/HDLRuby/sim/hruby_sim_core.c +2 -0
- data/lib/HDLRuby/std/channel.rb +336 -158
- data/lib/HDLRuby/std/fixpoint.rb +50 -39
- data/lib/HDLRuby/std/linear.rb +68 -0
- data/lib/HDLRuby/std/loop.rb +101 -0
- data/lib/HDLRuby/std/memory.rb +1002 -32
- data/lib/HDLRuby/std/task.rb +850 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
@@ -294,6 +294,8 @@ module HDLRuby::Low
|
|
294
294
|
# Is there a type to match?
|
295
295
|
if type then
|
296
296
|
# Yes, update the concat to the type.
|
297
|
+
# Get the real type in case of typedef.
|
298
|
+
type = type.def while type.is_a?(TypeDef)
|
297
299
|
# Is it an array type?
|
298
300
|
if type.is_a?(TypeVector) then
|
299
301
|
# Yes, update the concat without subcasting.
|
@@ -302,14 +304,16 @@ module HDLRuby::Low
|
|
302
304
|
end)
|
303
305
|
else
|
304
306
|
# No, it should be a tuple.
|
305
|
-
return Concat.new(type,
|
307
|
+
return Concat.new(type,
|
308
|
+
self.each_expression.map.with_index do
|
306
309
|
|expr,i|
|
307
310
|
expr.explicit_types(type.get_type(i))
|
308
311
|
end)
|
309
312
|
end
|
310
313
|
else
|
311
314
|
# No, recurse on the sub expressions.
|
312
|
-
return Concat.new(self.type,
|
315
|
+
return Concat.new(self.type,
|
316
|
+
self.each_expression.map do |expr|
|
313
317
|
expr.explicit_types
|
314
318
|
end)
|
315
319
|
end
|
@@ -91,7 +91,7 @@ module HDLRuby::Low
|
|
91
91
|
|
92
92
|
## Tells if it is a reference to a systemI signal.
|
93
93
|
def from_systemI?
|
94
|
-
return self.ref.from_systemI
|
94
|
+
return self.ref.from_systemI?
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -103,7 +103,7 @@ module HDLRuby::Low
|
|
103
103
|
|
104
104
|
## Tells if it is a reference to a systemI signal.
|
105
105
|
def from_systemI?
|
106
|
-
return self.ref.from_systemI
|
106
|
+
return self.ref.from_systemI?
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -119,11 +119,13 @@ module HDLRuby::Low
|
|
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
|
@@ -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)
|
data/lib/HDLRuby/hruby_types.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
89
|
-
else
|
90
|
-
|
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
|
-
|
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
|
-
|
109
|
-
else
|
110
|
-
|
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
|
-
|
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
|
-
|
126
|
-
else
|
127
|
-
|
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
|
-
|
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
|
-
|
171
|
-
else
|
172
|
-
|
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
|
-
|
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
|
-
|
224
|
-
else
|
225
|
-
|
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
|
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
|
@@ -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
|
@@ -393,6 +397,9 @@ static Value set_undefined_bitstring(Value dst) {
|
|
393
397
|
|
394
398
|
/* set the type and size of the destination. */
|
395
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);
|
396
403
|
|
397
404
|
/* Get access to the destination data. */
|
398
405
|
char* dst_data = dst->data_str;
|
@@ -600,7 +607,7 @@ static Value mul_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
|
600
607
|
dst->type = src0->type;
|
601
608
|
dst->numeric = 1;
|
602
609
|
|
603
|
-
/* Perform the
|
610
|
+
/* Perform the multiplication. */
|
604
611
|
dst->data_int = value2integer(src0) * value2integer(src1);
|
605
612
|
return dst;
|
606
613
|
}
|
@@ -616,12 +623,29 @@ static Value div_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
|
616
623
|
dst->type = src0->type;
|
617
624
|
dst->numeric = 1;
|
618
625
|
|
619
|
-
/* Perform the
|
626
|
+
/* Perform the division. */
|
620
627
|
dst->data_int = value2integer(src0) / value2integer(src1);
|
621
628
|
return dst;
|
622
629
|
}
|
623
630
|
|
624
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
|
+
|
625
649
|
/** Computes the lesser comparision of two defined bitstring values.
|
626
650
|
* @param src0 the first source value of the addition
|
627
651
|
* @param src1 the second source value of the addition
|
@@ -1411,7 +1435,10 @@ fix_numeric_type(Type type, unsigned long long val) {
|
|
1411
1435
|
/* Get the width of the type. */
|
1412
1436
|
int width = type_width(type);
|
1413
1437
|
/* Compute the base mask. */
|
1414
|
-
unsigned long long mask = ((unsigned long long)(-1)) << width;
|
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;
|
1415
1442
|
// printf("width=%i val=%llu mask=%llx\n",width,val,mask);
|
1416
1443
|
|
1417
1444
|
/* Is the type signed? */
|
@@ -1512,6 +1539,23 @@ static Value div_value_numeric(Value src0, Value src1, Value dst) {
|
|
1512
1539
|
}
|
1513
1540
|
|
1514
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);
|
1555
|
+
return dst;
|
1556
|
+
}
|
1557
|
+
|
1558
|
+
|
1515
1559
|
/** Computes the NOT of a numeric value.
|
1516
1560
|
* @param src the source value of the not
|
1517
1561
|
* @param dst the destination value
|
@@ -1686,7 +1730,7 @@ static Value concat_value_numeric_array(int num, int dir,
|
|
1686
1730
|
unsigned int i,pos;
|
1687
1731
|
/* Compute the bit width of the destination. */
|
1688
1732
|
unsigned int width = 0;
|
1689
|
-
// 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));
|
1690
1734
|
for(i=0; i<num; ++i) width += type_width(args[i]->type);
|
1691
1735
|
|
1692
1736
|
/* Sets state of the destination using the bit width. */
|
@@ -1710,6 +1754,7 @@ static Value concat_value_numeric_array(int num, int dir,
|
|
1710
1754
|
pos += arg_width;
|
1711
1755
|
}
|
1712
1756
|
/* Return the destination. */
|
1757
|
+
// printf("Result is dst=%llx\n",dst->data_int);
|
1713
1758
|
return dst;
|
1714
1759
|
}
|
1715
1760
|
|
@@ -1720,6 +1765,7 @@ static Value concat_value_numeric_array(int num, int dir,
|
|
1720
1765
|
* @param dst the destination value
|
1721
1766
|
* @return dst */
|
1722
1767
|
static Value cast_value_numeric(Value src, Type type, Value dst) {
|
1768
|
+
// printf("cast_value_numeric with src=%llx",src->data_int);
|
1723
1769
|
/* Copy the source to the destination. */
|
1724
1770
|
dst->data_int = src->data_int;
|
1725
1771
|
/* Update the destination type to the cast. */
|
@@ -1779,6 +1825,7 @@ static int same_content_value_range_numeric(Value value0,
|
|
1779
1825
|
* @return dst */
|
1780
1826
|
Value read_range_numeric(Value value, long long first, long long last,
|
1781
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); */
|
1782
1829
|
/* Ensure first is the smaller. */
|
1783
1830
|
if (first > last) {
|
1784
1831
|
long long tmp = last;
|
@@ -1791,15 +1838,18 @@ Value read_range_numeric(Value value, long long first, long long last,
|
|
1791
1838
|
unsigned long long bw = type_width(base);
|
1792
1839
|
/* Scale the range according to the base type. */
|
1793
1840
|
first *= bw;
|
1841
|
+
last *= bw;
|
1794
1842
|
length *= bw;
|
1795
|
-
|
1843
|
+
/* printf("first=%lld last=%lld bw=%llu length=%lld\n",first,last,bw,length); */
|
1796
1844
|
|
1797
1845
|
/* Set the type and size of the destination from the type of the source.*/
|
1798
1846
|
dst->type = make_type_vector(get_type_bit(),length);
|
1799
1847
|
dst->numeric = 1;
|
1800
1848
|
|
1801
1849
|
/* Compute the read mask. */
|
1802
|
-
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;
|
1803
1853
|
/* Performs the read. */
|
1804
1854
|
unsigned long long data = (value->data_int & mask) >> first;
|
1805
1855
|
/* Write it to the destination. */
|
@@ -1995,6 +2045,33 @@ Value div_value(Value src0, Value src1, Value dst) {
|
|
1995
2045
|
}
|
1996
2046
|
|
1997
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
|
+
|
1998
2075
|
/** Computes the NOT of a general value.
|
1999
2076
|
* @param src the source value of the not
|
2000
2077
|
* @param dst the destination value
|