HDLRuby 2.2.14 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -8
- data/lib/HDLRuby/hdr_samples/linear_test.rb +235 -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 +6 -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 +103 -32
- 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 +1000 -30
- data/lib/HDLRuby/std/task.rb +850 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +9 -2
@@ -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)
|
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
|
@@ -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. */
|