HDLRuby 2.2.16 → 2.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|