HDLRuby 2.0.8
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/HDLRuby.gemspec +36 -0
- data/LICENSE.txt +21 -0
- data/README.md +2774 -0
- data/README.pdf +0 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/hdrcc +3 -0
- data/lib/HDLRuby/alcc.rb +137 -0
- data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
- data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
- data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
- data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
- data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
- data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
- data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
- data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
- data/lib/HDLRuby/hdr_samples/include.rb +14 -0
- data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
- data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
- data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
- data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
- data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
- data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
- data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
- data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
- data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
- data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
- data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
- data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
- data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
- data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
- data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
- data/lib/HDLRuby/hdrcc.rb +623 -0
- data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
- data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
- data/lib/HDLRuby/high_samples/adder.rb +21 -0
- data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
- data/lib/HDLRuby/high_samples/addsub.rb +33 -0
- data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
- data/lib/HDLRuby/high_samples/after.rb +28 -0
- data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
- data/lib/HDLRuby/high_samples/alu.rb +61 -0
- data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
- data/lib/HDLRuby/high_samples/before.rb +28 -0
- data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
- data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
- data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
- data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
- data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
- data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
- data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
- data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
- data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
- data/lib/HDLRuby/high_samples/case.rb +32 -0
- data/lib/HDLRuby/high_samples/case2.rb +30 -0
- data/lib/HDLRuby/high_samples/change.rb +23 -0
- data/lib/HDLRuby/high_samples/clocks.rb +35 -0
- data/lib/HDLRuby/high_samples/comparer.rb +21 -0
- data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
- data/lib/HDLRuby/high_samples/dff.rb +23 -0
- data/lib/HDLRuby/high_samples/each.rb +28 -0
- data/lib/HDLRuby/high_samples/exporter.rb +42 -0
- data/lib/HDLRuby/high_samples/functions.rb +60 -0
- data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
- data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
- data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
- data/lib/HDLRuby/high_samples/instance.rb +37 -0
- data/lib/HDLRuby/high_samples/memory.rb +64 -0
- data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
- data/lib/HDLRuby/high_samples/overload.rb +32 -0
- data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
- data/lib/HDLRuby/high_samples/ram.rb +27 -0
- data/lib/HDLRuby/high_samples/registers.rb +139 -0
- data/lib/HDLRuby/high_samples/rom.rb +23 -0
- data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
- data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
- data/lib/HDLRuby/high_samples/shift.rb +31 -0
- data/lib/HDLRuby/high_samples/shift2.rb +40 -0
- data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
- data/lib/HDLRuby/high_samples/test_all.sh +10 -0
- data/lib/HDLRuby/high_samples/typedef.rb +24 -0
- data/lib/HDLRuby/high_samples/values.rb +70 -0
- data/lib/HDLRuby/high_samples/vector.rb +22 -0
- data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
- data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
- data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
- data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
- data/lib/HDLRuby/hruby_bstr.rb +1085 -0
- data/lib/HDLRuby/hruby_check.rb +317 -0
- data/lib/HDLRuby/hruby_db.rb +432 -0
- data/lib/HDLRuby/hruby_error.rb +44 -0
- data/lib/HDLRuby/hruby_high.rb +4103 -0
- data/lib/HDLRuby/hruby_low.rb +4735 -0
- data/lib/HDLRuby/hruby_low2c.rb +1986 -0
- data/lib/HDLRuby/hruby_low2high.rb +738 -0
- data/lib/HDLRuby/hruby_low2seq.rb +248 -0
- data/lib/HDLRuby/hruby_low2sym.rb +126 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
- data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
- data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
- data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
- data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
- data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
- data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
- data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
- data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
- data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
- data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
- data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
- data/lib/HDLRuby/hruby_serializer.rb +398 -0
- data/lib/HDLRuby/hruby_tools.rb +37 -0
- data/lib/HDLRuby/hruby_types.rb +239 -0
- data/lib/HDLRuby/hruby_values.rb +64 -0
- data/lib/HDLRuby/hruby_verilog.rb +1888 -0
- data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
- data/lib/HDLRuby/low_samples/adder.yaml +97 -0
- data/lib/HDLRuby/low_samples/after.yaml +228 -0
- data/lib/HDLRuby/low_samples/before.yaml +223 -0
- data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
- data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
- data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
- data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
- data/lib/HDLRuby/low_samples/case.yaml +327 -0
- data/lib/HDLRuby/low_samples/change.yaml +135 -0
- data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
- data/lib/HDLRuby/low_samples/cloner.rb +22 -0
- data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
- data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
- data/lib/HDLRuby/low_samples/dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/each.yaml +1328 -0
- data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
- data/lib/HDLRuby/low_samples/functions.yaml +298 -0
- data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
- data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
- data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
- data/lib/HDLRuby/low_samples/memory.yaml +678 -0
- data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
- data/lib/HDLRuby/low_samples/overload.yaml +226 -0
- data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
- data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/ram.yaml +207 -0
- data/lib/HDLRuby/low_samples/registers.yaml +228 -0
- data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
- data/lib/HDLRuby/low_samples/shift.yaml +230 -0
- data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
- data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
- data/lib/HDLRuby/low_samples/test_all.sh +43 -0
- data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
- data/lib/HDLRuby/low_samples/values.yaml +577 -0
- data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/vector.yaml +56 -0
- data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
- data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
- data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
- data/lib/HDLRuby/sim/Makefile +19 -0
- data/lib/HDLRuby/sim/hruby_sim.h +590 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
- data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
- data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
- data/lib/HDLRuby/std/channel.rb +354 -0
- data/lib/HDLRuby/std/clocks.rb +165 -0
- data/lib/HDLRuby/std/counters.rb +82 -0
- data/lib/HDLRuby/std/decoder.rb +214 -0
- data/lib/HDLRuby/std/fsm.rb +516 -0
- data/lib/HDLRuby/std/pipeline.rb +220 -0
- data/lib/HDLRuby/std/reconf.rb +309 -0
- data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
- data/lib/HDLRuby/test_hruby_high.rb +594 -0
- data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
- data/lib/HDLRuby/test_hruby_low.rb +934 -0
- data/lib/HDLRuby/v_samples/adder.v +10 -0
- data/lib/HDLRuby/v_samples/dff.v +12 -0
- data/lib/HDLRuby/v_samples/ram.v +20 -0
- data/lib/HDLRuby/v_samples/rom.v +270 -0
- data/lib/HDLRuby/version.rb +3 -0
- data/lib/HDLRuby.rb +11 -0
- data/makedoc +1 -0
- data/metadata.yaml +4 -0
- metadata +299 -0
|
@@ -0,0 +1,2362 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
#include <stdarg.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
#include <limits.h>
|
|
6
|
+
#include "hruby_sim.h"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The HDLRuby simulation calculation engine, to be used with C code
|
|
11
|
+
* generated by hruby_low2c.
|
|
12
|
+
**/
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/* Helping macros. */
|
|
16
|
+
|
|
17
|
+
/* The number of bits in an int. */
|
|
18
|
+
#define INT_BIT (sizeof(int)*CHAR_BIT)
|
|
19
|
+
#define LONG_LONG_BIT (sizeof(long long)*CHAR_BIT)
|
|
20
|
+
|
|
21
|
+
/** The min between two values. */
|
|
22
|
+
#define min2(a,b) \
|
|
23
|
+
({ __typeof__ (a) _a = (a); \
|
|
24
|
+
__typeof__ (b) _b = (b); \
|
|
25
|
+
_a <= _b ? _a : _b; })
|
|
26
|
+
|
|
27
|
+
/** The min between three values. */
|
|
28
|
+
#define min3(a,b,c) \
|
|
29
|
+
({ __typeof__ (a) _a = (a); \
|
|
30
|
+
__typeof__ (b) _b = (b); \
|
|
31
|
+
__typeof__ (c) _c = (c); \
|
|
32
|
+
_a <= _b ? (_a <= _c ? _a : _c) : (_b <= _c ? _b : _c); })
|
|
33
|
+
|
|
34
|
+
/** Get the bit used for extending a bitstring value. */
|
|
35
|
+
#define bitstring_ext(v) \
|
|
36
|
+
({ __typeof__ (v) _v = (v); \
|
|
37
|
+
_v->type->flags.sign ? _v->data_str[type_width(v->type)-1] - '0' : 0; })
|
|
38
|
+
|
|
39
|
+
// /** Get the word used for extending a value in unsigned unsigned long long. */
|
|
40
|
+
// #define word_extL(v) \
|
|
41
|
+
// ({ __typeof__ (v) _v = (v); \
|
|
42
|
+
// _v->type->flags.sign ? (_v->data[_v->size-1] >> (INT_BIT-1)) ? ULLONG_MAX : 0 : 0; })
|
|
43
|
+
//
|
|
44
|
+
// /** Get the word used for extending a value in unsigned unsigned int. */
|
|
45
|
+
// #define word_ext(v) \
|
|
46
|
+
// ({ __typeof__ (v) _v = (v); \
|
|
47
|
+
// _v->type->flags.sign ? (_v->data[_v->size-1] >> (INT_BIT-1)) ? UINT_MAX : 0 : 0; })
|
|
48
|
+
|
|
49
|
+
/* The type engine: each type is simplified to a vector of X elements
|
|
50
|
+
* of Y bits. */
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/* The interface to the type engine. */
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
/* The hash table of existing types. */
|
|
59
|
+
#define HASH_TYPE_SIZE 1024
|
|
60
|
+
static List hash_type[HASH_TYPE_SIZE] = {};
|
|
61
|
+
|
|
62
|
+
/** Computes the hash value of a type.
|
|
63
|
+
* @param base the width of an element
|
|
64
|
+
* @param number the number of elements
|
|
65
|
+
* @param flags the flags of the type
|
|
66
|
+
* @return the resulting type. */
|
|
67
|
+
static int hash_value(unsigned long long base, unsigned long long number,
|
|
68
|
+
FlagsS flags) {
|
|
69
|
+
return ((base+flags.all)^(number)) & 1023;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Adds a type to the hash of types.
|
|
73
|
+
* @param type the type to add */
|
|
74
|
+
static void add_hash_type(Type type) {
|
|
75
|
+
/* Compute the hash value. */
|
|
76
|
+
int hvalue = hash_value(type->base,type->number,type->flags);
|
|
77
|
+
/* See if there is already an entry for this hash value. */
|
|
78
|
+
List entry = hash_type[hvalue];
|
|
79
|
+
if (!entry) {
|
|
80
|
+
/* No entry, create a new one. */
|
|
81
|
+
entry = malloc(sizeof(List));
|
|
82
|
+
entry = build_list(entry);
|
|
83
|
+
}
|
|
84
|
+
/* Adds the type to the entry. */
|
|
85
|
+
Elem elem = get_element(type);
|
|
86
|
+
add_list(entry,elem);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Gets a type from the hash of types.
|
|
90
|
+
* @param base the type of an element
|
|
91
|
+
* @param number the number of elements
|
|
92
|
+
* @return the resulting type */
|
|
93
|
+
static Type get_hash_type(Type base, unsigned long long number) {
|
|
94
|
+
/* Compute the width of the base. */
|
|
95
|
+
unsigned long long bw = type_width(base);
|
|
96
|
+
FlagsS flags = base->flags;
|
|
97
|
+
/* Compute the hash value. */
|
|
98
|
+
int hvalue = hash_value(bw,number,flags);
|
|
99
|
+
/* See if there is already an entry for this hash value and look
|
|
100
|
+
* for the type in it. */
|
|
101
|
+
List entry = hash_type[hvalue];
|
|
102
|
+
if (entry) {
|
|
103
|
+
/* Look into the entry for the type. */
|
|
104
|
+
Elem elem = entry->head;
|
|
105
|
+
while(elem) {
|
|
106
|
+
Type type = elem->data;
|
|
107
|
+
if ((type->base == bw) && (type->number == number) &&
|
|
108
|
+
(type->flags.all == flags.all)) {
|
|
109
|
+
/* The type is found. */
|
|
110
|
+
return type;
|
|
111
|
+
}
|
|
112
|
+
elem = elem->next;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/* The element is not found. */
|
|
116
|
+
return NULL;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
/** Computes the width in bits of a type.
|
|
121
|
+
* @param type the type to compute the width
|
|
122
|
+
* @return the resulting width in bits */
|
|
123
|
+
unsigned long long type_width(Type type) {
|
|
124
|
+
return type->base * type->number;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Gets the single bit type. */
|
|
128
|
+
Type get_type_bit() {
|
|
129
|
+
static TypeS type_bit = { 1ULL, 1ULL, { 0 } };
|
|
130
|
+
return &type_bit;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Gets the single signed bit type. */
|
|
134
|
+
Type get_type_signed() {
|
|
135
|
+
static TypeS type_sign = { 1ULL, 1ULL, { 1 } };
|
|
136
|
+
return &type_sign;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Creates a type by base type and number of elements.
|
|
140
|
+
* @param base the type of an element
|
|
141
|
+
* @number the number of elements */
|
|
142
|
+
Type make_type_vector(Type base, unsigned long long number) {
|
|
143
|
+
/* Create the type. */
|
|
144
|
+
Type type = calloc(sizeof(TypeS),1);
|
|
145
|
+
type->base = type_width(base);
|
|
146
|
+
type->number = number;
|
|
147
|
+
type->flags = base->flags;
|
|
148
|
+
/* Add it to the hash of types. */
|
|
149
|
+
add_hash_type(type);
|
|
150
|
+
/* Return the result. */
|
|
151
|
+
return type;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Gets a vector type by base type and number of elements.
|
|
155
|
+
* @param base the type of an element
|
|
156
|
+
* @param number the number of elements */
|
|
157
|
+
Type get_type_vector(Type base, unsigned long long number) {
|
|
158
|
+
Type type = get_hash_type(base,number);
|
|
159
|
+
if (type == NULL)
|
|
160
|
+
/* The type does not exist yet, create it. */
|
|
161
|
+
return make_type_vector(base,number);
|
|
162
|
+
else
|
|
163
|
+
/* The type already exists, return it. */
|
|
164
|
+
return type;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// /** Gets a vector type by width and number of elements.
|
|
168
|
+
// * @param base the width of an element
|
|
169
|
+
// * @param number the number of elements
|
|
170
|
+
// * @param flags the flags of the type */
|
|
171
|
+
// static Type get_type_vector_flat(unsigned long long base,
|
|
172
|
+
// unsigned long long number
|
|
173
|
+
// unsigned int flags){
|
|
174
|
+
// Type type = get_hash_type(base,number);
|
|
175
|
+
// if (type == NULL)
|
|
176
|
+
// /* The type does not exist yet, create it. */
|
|
177
|
+
// return make_type_vector_flat(base,number);
|
|
178
|
+
// else
|
|
179
|
+
// /* The type already exists, return it. */
|
|
180
|
+
// return type;
|
|
181
|
+
// }
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
/* The calculation engine. */
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
/* Creating and fill values. */
|
|
189
|
+
|
|
190
|
+
/** Creates a new value.
|
|
191
|
+
* @param type the type of the value
|
|
192
|
+
* @param numeric tells if the value is numeric or not
|
|
193
|
+
* @return the resulting value */
|
|
194
|
+
Value make_value(Type type, int numeric) {
|
|
195
|
+
/* Compute the size in words of the data contained in the value. */
|
|
196
|
+
unsigned long long width = type_width(type);
|
|
197
|
+
/* Allocate the value. */
|
|
198
|
+
Value res = calloc(sizeof(ValueS),1);
|
|
199
|
+
/* Allocates the data of the value. */
|
|
200
|
+
if (!numeric) {
|
|
201
|
+
/* Allocate the bit string and fill it with u (undefined) by default. */
|
|
202
|
+
res->data_str = malloc(sizeof(char)*width);
|
|
203
|
+
memset(res->data_str,'x',width);
|
|
204
|
+
/* And set its capacity to the type width. */
|
|
205
|
+
res->capacity = width;
|
|
206
|
+
} else {
|
|
207
|
+
res->capacity = 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* Initialize it. */
|
|
211
|
+
res->type = type;
|
|
212
|
+
res->numeric = numeric;
|
|
213
|
+
|
|
214
|
+
return res;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Make the size of a value able to store size ints.
|
|
218
|
+
* @note The content of the value is lost!
|
|
219
|
+
* @note do not change the type of the value, only its capacity.
|
|
220
|
+
* @praam value the value to change
|
|
221
|
+
* @param size the size to match */
|
|
222
|
+
void resize_value(Value value, int size) {
|
|
223
|
+
if (value->capacity < size) {
|
|
224
|
+
/* Resizing required, to limit frequent resize, double the
|
|
225
|
+
* required new capacity. */
|
|
226
|
+
/* Free the former data. */
|
|
227
|
+
free(value->data_str);
|
|
228
|
+
/* Reallocate it. */
|
|
229
|
+
value->data_str = calloc(sizeof(char),size*2);
|
|
230
|
+
/* Update the size. */
|
|
231
|
+
value->capacity = size*2;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Sets a value with data.
|
|
236
|
+
* @param value the value to fill
|
|
237
|
+
* @param numeric tell if the value is in numeric form or in bitstring form
|
|
238
|
+
* @param data the source data */
|
|
239
|
+
void set_value(Value value, int numeric, void* data) {
|
|
240
|
+
value->numeric = numeric;
|
|
241
|
+
if (numeric)
|
|
242
|
+
value->data_int = *((unsigned long long*)data);
|
|
243
|
+
else {
|
|
244
|
+
memcpy(value->data_str,data,type_width(value->type)*sizeof(char));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Makes and sets a value with data.
|
|
249
|
+
* @param type the type of the value
|
|
250
|
+
* @param numeric tell if the value is in numeric form or in bitstring form
|
|
251
|
+
* @param data the source data */
|
|
252
|
+
Value make_set_value(Type type, int numeric, void* data) {
|
|
253
|
+
Value value = make_value(type,numeric);
|
|
254
|
+
set_value(value,numeric,data);
|
|
255
|
+
return value;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
/* The interface to the value computation engine. */
|
|
262
|
+
|
|
263
|
+
/* ################### Value-kind independant computations. ############## */
|
|
264
|
+
|
|
265
|
+
// /** Check if a value can be converted to a numeric.
|
|
266
|
+
// * @param value the value to process
|
|
267
|
+
// * @return 1 in case of success, 0 otherwise */
|
|
268
|
+
// int is_numeric_value(Value value) {
|
|
269
|
+
// if (value->numeric) {
|
|
270
|
+
// /* The value is already numeric. */
|
|
271
|
+
// return 1;
|
|
272
|
+
// } else {
|
|
273
|
+
// /* Check if the value contains only 0 and 1. */
|
|
274
|
+
// unsigned long long width = type_width(value->type);
|
|
275
|
+
// unsigned long long i;
|
|
276
|
+
// char* data_str = value->data_str;
|
|
277
|
+
// for(i=0; i<width; ++i) {
|
|
278
|
+
// if (data_str[i] != '0' && data_str[i] != '1')
|
|
279
|
+
// /* Cannot be converted. */
|
|
280
|
+
// return 0;
|
|
281
|
+
// }
|
|
282
|
+
// /* Can convert so do it. */
|
|
283
|
+
// return 1;
|
|
284
|
+
// }
|
|
285
|
+
// }
|
|
286
|
+
|
|
287
|
+
/** Copies a value to another, the type of the destination is preserved.
|
|
288
|
+
* @param src the source value
|
|
289
|
+
* @param dst the destination value
|
|
290
|
+
* @return dst */
|
|
291
|
+
Value copy_value(Value src, Value dst) {
|
|
292
|
+
/* set the status of the destination from the source. */
|
|
293
|
+
if (dst->type == NULL)
|
|
294
|
+
dst->type = src->type;
|
|
295
|
+
dst->numeric = src->numeric;
|
|
296
|
+
/* Copy the data. */
|
|
297
|
+
if (src->numeric) {
|
|
298
|
+
/* Numeric copy. */
|
|
299
|
+
dst->data_int = src->data_int;
|
|
300
|
+
} else {
|
|
301
|
+
/* Resize the destination if required. */
|
|
302
|
+
resize_value(dst,type_width(dst->type));
|
|
303
|
+
/* Bitstring copy up to the end of dst or src. */
|
|
304
|
+
unsigned long long width = min2(type_width(src->type),type_width(dst->type));
|
|
305
|
+
memcpy(dst->data_str,src->data_str,width);
|
|
306
|
+
}
|
|
307
|
+
return dst;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* Declared afterward. */
|
|
311
|
+
static Value set_bitstring_value(Value src, Value dst);
|
|
312
|
+
|
|
313
|
+
/** Copies a value to another but without overwritting with Z, the type of
|
|
314
|
+
* the destination is preserved.
|
|
315
|
+
* @param src the source value
|
|
316
|
+
* @param dst the destination value
|
|
317
|
+
* @return dst */
|
|
318
|
+
extern Value copy_value_no_z(Value src, Value dst) {
|
|
319
|
+
/* set the status of the destination from the source. */
|
|
320
|
+
// dst->type = src->type;
|
|
321
|
+
/* Copy the data. */
|
|
322
|
+
if (src->numeric) {
|
|
323
|
+
/* Numeric copy. */
|
|
324
|
+
dst->data_int = src->data_int;
|
|
325
|
+
dst->numeric = 1;
|
|
326
|
+
} else {
|
|
327
|
+
/* Convert the destination to a bitstring. */
|
|
328
|
+
if (dst->numeric) {
|
|
329
|
+
dst = set_bitstring_value(dst,dst);
|
|
330
|
+
}
|
|
331
|
+
/* Bitstring copy up to the end of dst or src. */
|
|
332
|
+
unsigned long long width = min2(type_width(src->type),type_width(dst->type));
|
|
333
|
+
unsigned long long i;
|
|
334
|
+
/* Access the data. */
|
|
335
|
+
char* src_data = src->data_str;
|
|
336
|
+
char* dst_data = dst->data_str;
|
|
337
|
+
// printf("src_data=%s dst_data=%s\n",src_data,dst_data);
|
|
338
|
+
/* Perform the copy skipping the Z values. */
|
|
339
|
+
for(i=0; i<width; ++i) {
|
|
340
|
+
char b = src_data[i];
|
|
341
|
+
if (b!='z') dst_data[i] = b;
|
|
342
|
+
else if (dst_data[i] == 'x') dst_data[i] = b;
|
|
343
|
+
}
|
|
344
|
+
// printf("dst_data=%s\n",dst_data);
|
|
345
|
+
}
|
|
346
|
+
return dst;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
/* ############# Start of the computation of bitstring values. ############ */
|
|
351
|
+
|
|
352
|
+
/** Creates a bitstring value from a numeric value.
|
|
353
|
+
* @param src the numeric source value
|
|
354
|
+
* @param dst the destination value
|
|
355
|
+
* @return dst. */
|
|
356
|
+
static Value set_bitstring_value(Value src, Value dst) {
|
|
357
|
+
/* Compute the width in bits of the result. */
|
|
358
|
+
unsigned long long width = type_width(src->type);
|
|
359
|
+
unsigned long long i;
|
|
360
|
+
/* Resize dst to match the width. */
|
|
361
|
+
resize_value(dst,width);
|
|
362
|
+
/* set the type and size of the destination the the type of the source. */
|
|
363
|
+
dst->type = src->type;
|
|
364
|
+
dst->numeric = 0;
|
|
365
|
+
|
|
366
|
+
/* Access the data of the source and the destination. */
|
|
367
|
+
unsigned long long data_int = src->data_int;
|
|
368
|
+
char* data_str = dst->data_str;
|
|
369
|
+
|
|
370
|
+
/* Make the conversion. */
|
|
371
|
+
for(i=0; i < width; ++i) {
|
|
372
|
+
/* Get the bit from the source. */
|
|
373
|
+
char bit = (data_int >> i) & 1;
|
|
374
|
+
/* And write it. */
|
|
375
|
+
data_str[i] = bit + '0';
|
|
376
|
+
}
|
|
377
|
+
/* Return the destination. */
|
|
378
|
+
return dst;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
/** Computes the neg of a bitstring value.
|
|
383
|
+
* @param src the source value of the not
|
|
384
|
+
* @param dst the destination value
|
|
385
|
+
* @return dst */
|
|
386
|
+
static Value neg_value_bitstring(Value src, Value dst) {
|
|
387
|
+
/* Compute the width of the result in bits. */
|
|
388
|
+
unsigned long long width = type_width(src->type);
|
|
389
|
+
|
|
390
|
+
/* Update the destination capacity if required. */
|
|
391
|
+
resize_value(dst,width);
|
|
392
|
+
/* set the type and size of the destination the the type of the source. */
|
|
393
|
+
dst->type = src->type;
|
|
394
|
+
dst->numeric = 0;
|
|
395
|
+
|
|
396
|
+
/* Access the source and destination data. */
|
|
397
|
+
char* src_data = src->data_str;
|
|
398
|
+
char* dst_data = dst->data_str;
|
|
399
|
+
|
|
400
|
+
/* Performs the negation. */
|
|
401
|
+
unsigned long long count;
|
|
402
|
+
char carry = 1;
|
|
403
|
+
for(count = 0; count < width; ++count) {
|
|
404
|
+
/* Performs the negation. */
|
|
405
|
+
char d = src_data[count] - '0'; /* Get and convert to bit. */
|
|
406
|
+
char res;
|
|
407
|
+
if (d == (d&1)) { /* d is defined. */
|
|
408
|
+
res = d ^ carry;
|
|
409
|
+
carry = d & carry;
|
|
410
|
+
} else {
|
|
411
|
+
/* Undefined, end here. */
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
dst_data[count] = res;
|
|
415
|
+
}
|
|
416
|
+
/* The remaining bits are undefined. */
|
|
417
|
+
for(;count < width; ++count) {
|
|
418
|
+
dst_data[count] = 'x';
|
|
419
|
+
}
|
|
420
|
+
/* Return the destination. */
|
|
421
|
+
return dst;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
/** Computes the addition of two bitstring values.
|
|
426
|
+
* @param src0 the first source value of the addition
|
|
427
|
+
* @param src1 the second source value of the addition
|
|
428
|
+
* @param dst the destination value
|
|
429
|
+
* @return dst */
|
|
430
|
+
static Value add_value_bitstring(Value src0, Value src1, Value dst) {
|
|
431
|
+
/* Compute the width of sources in bits. */
|
|
432
|
+
unsigned long long width0 = type_width(src0->type);
|
|
433
|
+
unsigned long long width1 = type_width(src1->type);
|
|
434
|
+
|
|
435
|
+
/* Update the destination capacity if required. */
|
|
436
|
+
resize_value(dst,width0);
|
|
437
|
+
/* set the type and size of the destination the the type of the source. */
|
|
438
|
+
dst->type = src0->type;
|
|
439
|
+
dst->numeric = 0;
|
|
440
|
+
|
|
441
|
+
/* Get access to the data of the sources. */
|
|
442
|
+
char *src0_data = src0->data_str;
|
|
443
|
+
char *src1_data = src1->data_str;
|
|
444
|
+
/* Get access to the data of the destination. */
|
|
445
|
+
char *dst_data = dst->data_str;
|
|
446
|
+
|
|
447
|
+
/* Get the sign extension character of source 1 and convert it to a bit.*/
|
|
448
|
+
// int ext = src1->type->flags.sign ? src1_data[width1-1] - '0' : 0;
|
|
449
|
+
int ext = bitstring_ext(src1);
|
|
450
|
+
/* Perform the addition. */
|
|
451
|
+
unsigned long long count;
|
|
452
|
+
char carry = 0;
|
|
453
|
+
for(count = 0; count < width0; ++count) {
|
|
454
|
+
/* Performs the addition. */
|
|
455
|
+
char d0 = src0_data[count] - '0'; /* Get and convert to bit. */
|
|
456
|
+
char res;
|
|
457
|
+
if (count < width1) {
|
|
458
|
+
char d1 = src1_data[count] - '0';/* Get and convert to bit. */
|
|
459
|
+
if ((d0 == (d0&1)) && (d1 == (d1&1))) {
|
|
460
|
+
/* d0 and d1 are defined. */
|
|
461
|
+
res = d0 ^ d1 ^ carry;
|
|
462
|
+
carry = (d0&d1) | (d0&carry) | (d1&carry);
|
|
463
|
+
} else {
|
|
464
|
+
/* Either input bit is undefined, end here. */
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
} else {
|
|
468
|
+
/* All the bit of source 1 are used, go on using the sign
|
|
469
|
+
* extension. */
|
|
470
|
+
if (ext != (ext&1)) {
|
|
471
|
+
/* The sign extension is undefined, end here. */
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
if (d0 == (d0&1)) {
|
|
475
|
+
/* d0 is defined. */
|
|
476
|
+
res = d0 ^ ext ^ carry;
|
|
477
|
+
carry = (d0&ext) | (d0&carry) | (ext&carry);
|
|
478
|
+
} else {
|
|
479
|
+
/* d0 is undefined. */
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
dst_data[count] = res + '0';
|
|
484
|
+
}
|
|
485
|
+
/* The remaining bits are undefined. */
|
|
486
|
+
for(;count < width0; ++count) {
|
|
487
|
+
dst_data[count] = 'x';
|
|
488
|
+
}
|
|
489
|
+
/* Return the destination. */
|
|
490
|
+
return dst;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
/** Computes the subtraction of two bitstring values.
|
|
495
|
+
* @param src0 the first source value of the subtraction
|
|
496
|
+
* @param src1 the second source value of the subtraction
|
|
497
|
+
* @param dst the destination value
|
|
498
|
+
* @return dst */
|
|
499
|
+
static Value sub_value_bitstring(Value src0, Value src1, Value dst) {
|
|
500
|
+
/* Compute the width of sources in bits. */
|
|
501
|
+
unsigned long long width0 = type_width(src0->type);
|
|
502
|
+
unsigned long long width1 = type_width(src1->type);
|
|
503
|
+
|
|
504
|
+
/* Update the destination capacity if required. */
|
|
505
|
+
resize_value(dst,width0);
|
|
506
|
+
/* set the type and size of the destination the the type of the source. */
|
|
507
|
+
dst->type = src0->type;
|
|
508
|
+
dst->numeric = 0;
|
|
509
|
+
|
|
510
|
+
/* Get access to the data of the sources. */
|
|
511
|
+
char *src0_data = src0->data_str;
|
|
512
|
+
char *src1_data = src1->data_str;
|
|
513
|
+
/* Get access to the data of the destination. */
|
|
514
|
+
char *dst_data = dst->data_str;
|
|
515
|
+
|
|
516
|
+
/* Get the sign extension character of source 1 and convert it to a bit.*/
|
|
517
|
+
// int ext = src1->type->flags.sign ? src1_data[width1-1] - '0' : 0;
|
|
518
|
+
int ext = bitstring_ext(src1);
|
|
519
|
+
ext = !ext; /* For the subtraction: a + ~b + 1 */
|
|
520
|
+
/* Perform the subtraction. */
|
|
521
|
+
unsigned long long count;
|
|
522
|
+
char carry = 1; /* For the subtraction: a + ~b + 1 */
|
|
523
|
+
for(count = 0; count < width0; ++count) {
|
|
524
|
+
/* Performs the subtraction. */
|
|
525
|
+
char d0 = src0_data[count] - '0'; /* Get and convert to bit. */
|
|
526
|
+
char res;
|
|
527
|
+
if (count < width1) {
|
|
528
|
+
char d1 = src1_data[count] - '0';/* Get and convert to bit. */
|
|
529
|
+
if ((d0 == (d0&1)) && (d1 == (d1&1))) {
|
|
530
|
+
d1 = !d1; /* For the subtraction: a + ~b + 1 */
|
|
531
|
+
/* d0 and d1 are defined. */
|
|
532
|
+
res = d0 ^ (d1) ^ carry;
|
|
533
|
+
carry = (d0&d1) | (d0&carry) | (d1&carry);
|
|
534
|
+
} else {
|
|
535
|
+
/* Either input bit is undefined, end here. */
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
} else {
|
|
539
|
+
/* All the bit of source 1 are used, go on using the sign
|
|
540
|
+
* extension. */
|
|
541
|
+
if (ext != (ext&1)) {
|
|
542
|
+
/* The sign extension is undefined, end here. */
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
if (d0 == (d0&1)) {
|
|
546
|
+
/* d0 is defined. */
|
|
547
|
+
res = d0 ^ ext ^ carry;
|
|
548
|
+
carry = (d0&ext) | (d0&carry) | (ext&carry);
|
|
549
|
+
} else {
|
|
550
|
+
/* d0 is undefined. */
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
dst_data[count] = res + '0';
|
|
555
|
+
}
|
|
556
|
+
/* The remaining bits are undefined. */
|
|
557
|
+
for(;count < width0; ++count) {
|
|
558
|
+
dst_data[count] = 'x';
|
|
559
|
+
}
|
|
560
|
+
/* Return the destination. */
|
|
561
|
+
return dst;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
/** Computes the NOT of a bitstring value.
|
|
566
|
+
* @param src the source value of the not
|
|
567
|
+
* @param dst the destination value
|
|
568
|
+
* @return the destination value */
|
|
569
|
+
static Value not_value_bitstring(Value src, Value dst) {
|
|
570
|
+
/* Compute the width of the result in bits. */
|
|
571
|
+
unsigned long long width = type_width(src->type);
|
|
572
|
+
|
|
573
|
+
/* Update the destination capacity if required. */
|
|
574
|
+
resize_value(dst,width);
|
|
575
|
+
/* set the type and size of the destination the the type of the source. */
|
|
576
|
+
dst->type = src->type;
|
|
577
|
+
dst->numeric = 0;
|
|
578
|
+
|
|
579
|
+
/* Get access to the source and destination data. */
|
|
580
|
+
char* src_data = src->data_str;
|
|
581
|
+
char* dst_data = dst->data_str;
|
|
582
|
+
|
|
583
|
+
/* Performs the not. */
|
|
584
|
+
unsigned long long count;
|
|
585
|
+
for(count = 0; count < width; ++count) {
|
|
586
|
+
/* Performs the not. */
|
|
587
|
+
char d = src_data[count] - '0'; /* Get and convert to bit. */
|
|
588
|
+
char res;
|
|
589
|
+
if (d == (d&1)) { /* d is defined. */
|
|
590
|
+
res = !d;
|
|
591
|
+
} else {
|
|
592
|
+
/* res is undefined. */
|
|
593
|
+
res = 'x' - '0';
|
|
594
|
+
}
|
|
595
|
+
dst_data[count] = res + '0';
|
|
596
|
+
}
|
|
597
|
+
/* Return the destination. */
|
|
598
|
+
return dst;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
/** Computes the and of two bitstring values.
|
|
603
|
+
* @param src0 the first source value of the and
|
|
604
|
+
* @param src1 the second source value of the and
|
|
605
|
+
* @param dst the destination value
|
|
606
|
+
* @return dst */
|
|
607
|
+
static Value and_value_bitstring(Value src0, Value src1, Value dst) {
|
|
608
|
+
/* Compute the width of sources in bits. */
|
|
609
|
+
unsigned long long width0 = type_width(src0->type);
|
|
610
|
+
unsigned long long width1 = type_width(src1->type);
|
|
611
|
+
|
|
612
|
+
/* Update the destination capacity if required. */
|
|
613
|
+
resize_value(dst,width0);
|
|
614
|
+
/* set the type and size of the destination the the type of the source. */
|
|
615
|
+
dst->type = src0->type;
|
|
616
|
+
dst->numeric = 0;
|
|
617
|
+
|
|
618
|
+
/* Get access to the data of the sources. */
|
|
619
|
+
char *src0_data = src0->data_str;
|
|
620
|
+
char *src1_data = src1->data_str;
|
|
621
|
+
/* Get access to the data of the destination. */
|
|
622
|
+
char *dst_data = dst->data_str;
|
|
623
|
+
|
|
624
|
+
/* Get the sign extension character of source 1 and convert it to a bit.*/
|
|
625
|
+
// int ext = src1->type->flags.sign ? src1_data[width1-1] - '0' : 0;
|
|
626
|
+
int ext = bitstring_ext(src1);
|
|
627
|
+
|
|
628
|
+
/* Perform the and. */
|
|
629
|
+
unsigned long long count;
|
|
630
|
+
for(count = 0; count < width0; ++count) {
|
|
631
|
+
/* Performs the and. */
|
|
632
|
+
char d0 = src0_data[count] - '0'; /* Get and convert to bit. */
|
|
633
|
+
char res;
|
|
634
|
+
char d1;
|
|
635
|
+
if (count < width1) {
|
|
636
|
+
/* Still within source 1. */
|
|
637
|
+
d1 = src1_data[count] - '0';/* Get and convert to bit. */
|
|
638
|
+
} else {
|
|
639
|
+
/* Outside source 1, use the sign extension. */
|
|
640
|
+
d1 = ext;
|
|
641
|
+
}
|
|
642
|
+
if (d0 == (d0&1)) {
|
|
643
|
+
/* d0 is defined. */
|
|
644
|
+
if (d1 == (d1&1)) {
|
|
645
|
+
/* d1 is also defined. */
|
|
646
|
+
res = d0 & d1;
|
|
647
|
+
} else if (d0 == 0) {
|
|
648
|
+
/* d1 is not defined but d0 is 0. */
|
|
649
|
+
res = 0;
|
|
650
|
+
} else {
|
|
651
|
+
/* res is undefined. */
|
|
652
|
+
res = 'x'-'0';
|
|
653
|
+
}
|
|
654
|
+
} else {
|
|
655
|
+
/* d0 is undefined. */
|
|
656
|
+
if (d1 == 0) {
|
|
657
|
+
/* But d1 is 0. */
|
|
658
|
+
res = 0;
|
|
659
|
+
} else {
|
|
660
|
+
/* res is undefined. */
|
|
661
|
+
res = 'x'-'0';
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
dst_data[count] = res + '0';
|
|
665
|
+
}
|
|
666
|
+
/* Return the destination. */
|
|
667
|
+
return dst;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
/** Computes the or of two bitstring values.
|
|
672
|
+
* @param src0 the first source value of the and
|
|
673
|
+
* @param src1 the second source value of the and
|
|
674
|
+
* @param dst the destination value
|
|
675
|
+
* @return dst */
|
|
676
|
+
static Value or_value_bitstring(Value src0, Value src1, Value dst) {
|
|
677
|
+
/* Compute the width of sources in bits. */
|
|
678
|
+
unsigned long long width0 = type_width(src0->type);
|
|
679
|
+
unsigned long long width1 = type_width(src1->type);
|
|
680
|
+
|
|
681
|
+
/* Update the destination capacity if required. */
|
|
682
|
+
resize_value(dst,width0);
|
|
683
|
+
/* set the type and size of the destination the the type of the source. */
|
|
684
|
+
dst->type = src0->type;
|
|
685
|
+
dst->numeric = 0;
|
|
686
|
+
|
|
687
|
+
/* Get access to the data of the sources. */
|
|
688
|
+
char *src0_data = src0->data_str;
|
|
689
|
+
char *src1_data = src1->data_str;
|
|
690
|
+
/* Get access to the data of the destination. */
|
|
691
|
+
char *dst_data = dst->data_str;
|
|
692
|
+
|
|
693
|
+
/* Get the sign extension character of source 1 and convert it to a bit.*/
|
|
694
|
+
// int ext = src1->type->flags.sign ? src1_data[width1-1] - '0' : 0;
|
|
695
|
+
int ext = bitstring_ext(src1);
|
|
696
|
+
|
|
697
|
+
/* Perform the or. */
|
|
698
|
+
unsigned long long count;
|
|
699
|
+
for(count = 0; count < width0; ++count) {
|
|
700
|
+
/* Performs the or. */
|
|
701
|
+
char d0 = src0_data[count] - '0'; /* Get and convert to bit. */
|
|
702
|
+
char res;
|
|
703
|
+
char d1;
|
|
704
|
+
if (count < width1) {
|
|
705
|
+
/* Still within source 1. */
|
|
706
|
+
d1 = src1_data[count] - '0';/* Get and convert to bit. */
|
|
707
|
+
} else {
|
|
708
|
+
/* Outside source 1, use the sign extension. */
|
|
709
|
+
d1 = ext;
|
|
710
|
+
}
|
|
711
|
+
if (d0 == (d0&1)) {
|
|
712
|
+
/* d0 is defined. */
|
|
713
|
+
if (d1 == (d1&1)) {
|
|
714
|
+
/* d1 is also defined. */
|
|
715
|
+
res = d0 | d1;
|
|
716
|
+
} else if (d0 == 1) {
|
|
717
|
+
/* d1 is not defined but d0 is 1. */
|
|
718
|
+
res = 1;
|
|
719
|
+
} else {
|
|
720
|
+
/* res is undefined. */
|
|
721
|
+
res = 'x'-'0';
|
|
722
|
+
}
|
|
723
|
+
} else {
|
|
724
|
+
/* d0 is undefined. */
|
|
725
|
+
if (d1 == 1) {
|
|
726
|
+
/* But d1 is 1. */
|
|
727
|
+
res = 1;
|
|
728
|
+
} else {
|
|
729
|
+
/* res is undefined. */
|
|
730
|
+
res = 'x'-'0';
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
dst_data[count] = res + '0';
|
|
734
|
+
}
|
|
735
|
+
/* Return the destination. */
|
|
736
|
+
return dst;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
/** Computes the xor of two bitstring values.
|
|
741
|
+
* @param src0 the first source value of the and
|
|
742
|
+
* @param src1 the second source value of the and
|
|
743
|
+
* @param dst the destination value
|
|
744
|
+
* @return dst */
|
|
745
|
+
static Value xor_value_bitstring(Value src0, Value src1, Value dst) {
|
|
746
|
+
/* Compute the width of sources in bits. */
|
|
747
|
+
unsigned long long width0 = type_width(src0->type);
|
|
748
|
+
unsigned long long width1 = type_width(src1->type);
|
|
749
|
+
|
|
750
|
+
/* Update the destination capacity if required. */
|
|
751
|
+
resize_value(dst,width0);
|
|
752
|
+
/* set the type and size of the destination the the type of the source. */
|
|
753
|
+
dst->type = src0->type;
|
|
754
|
+
dst->numeric = 0;
|
|
755
|
+
|
|
756
|
+
/* Get access to the data of the sources. */
|
|
757
|
+
char *src0_data = src0->data_str;
|
|
758
|
+
char *src1_data = src1->data_str;
|
|
759
|
+
/* Get access to the data of the destination. */
|
|
760
|
+
char *dst_data = dst->data_str;
|
|
761
|
+
|
|
762
|
+
/* Get the sign extension character of source 1 and convert it to a bit.*/
|
|
763
|
+
// int ext = src1->type->flags.sign ? src1_data[width1-1] - '0' : 0;
|
|
764
|
+
int ext = bitstring_ext(src1);
|
|
765
|
+
|
|
766
|
+
/* Perform the xor. */
|
|
767
|
+
unsigned long long count;
|
|
768
|
+
for(count = 0; count < width0; ++count) {
|
|
769
|
+
/* Performs the xor. */
|
|
770
|
+
char d0 = src0_data[count] - '0'; /* Get and convert to bit. */
|
|
771
|
+
char res;
|
|
772
|
+
char d1;
|
|
773
|
+
if (count < width1) {
|
|
774
|
+
/* Still within source 1. */
|
|
775
|
+
d1 = src1_data[count] - '0';/* Get and convert to bit. */
|
|
776
|
+
} else {
|
|
777
|
+
/* Outside source 1, use the sign extension. */
|
|
778
|
+
d1 = ext;
|
|
779
|
+
}
|
|
780
|
+
if (d0 == (d0&1)) {
|
|
781
|
+
/* d0 is defined. */
|
|
782
|
+
if (d1 == (d1&1)) {
|
|
783
|
+
/* d1 is also defined. */
|
|
784
|
+
res = d0 ^ d1;
|
|
785
|
+
} else {
|
|
786
|
+
/* res is undefined. */
|
|
787
|
+
res = 'x'-'0';
|
|
788
|
+
}
|
|
789
|
+
} else {
|
|
790
|
+
/* res is undefined. */
|
|
791
|
+
res = 'x'-'0';
|
|
792
|
+
}
|
|
793
|
+
dst_data[count] = res + '0';
|
|
794
|
+
}
|
|
795
|
+
/* Return the destination. */
|
|
796
|
+
return dst;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
/** Computes the left shift of a bitstring value by a numeric value.
|
|
801
|
+
* @param src0 the first source value of the addition
|
|
802
|
+
* @param src1 the second source value of the addition
|
|
803
|
+
* @param dst the destination
|
|
804
|
+
* @return dst */
|
|
805
|
+
static Value shift_left_value_bitstring_numeric(Value src0, Value src1, Value dst) {
|
|
806
|
+
unsigned long long count;
|
|
807
|
+
/* Get the widths of the first source. */
|
|
808
|
+
unsigned long long width0 = type_width(src0->type);
|
|
809
|
+
|
|
810
|
+
/* Update the destination capacity if required. */
|
|
811
|
+
resize_value(dst,width0);
|
|
812
|
+
/* set the type and size of the destination to the type first source. */
|
|
813
|
+
dst->type = src0->type;
|
|
814
|
+
dst->numeric = 0;
|
|
815
|
+
|
|
816
|
+
/* Get access to the data of the source. */
|
|
817
|
+
char *src0_data = src0->data_str;
|
|
818
|
+
/* Get access to the data of the destination. */
|
|
819
|
+
char *dst_data = dst->data_str;
|
|
820
|
+
|
|
821
|
+
/* Compute the amount of shift. */
|
|
822
|
+
// unsigned int ext = word_ext(src1);
|
|
823
|
+
long long sh = value2integer(src1);
|
|
824
|
+
// if (ext && (sh > 0)) sh = -sh; /* Ensure the shift sign is right. */
|
|
825
|
+
/* Cleans the destination for a clean shift result. */
|
|
826
|
+
for(count = 0; count < width0; ++count) {
|
|
827
|
+
dst_data[count] = '0';
|
|
828
|
+
}
|
|
829
|
+
/* Perform the bit-wise shift. */
|
|
830
|
+
for(count = 0; count < width0; ++count) {
|
|
831
|
+
/* Access the source bit. */
|
|
832
|
+
char d0 = src0_data[count];
|
|
833
|
+
/* Set it to the destination at the right place. */
|
|
834
|
+
unsigned long long pos = count + sh;
|
|
835
|
+
if ((pos>0) && (pos<width0)) {
|
|
836
|
+
dst_data[pos] = d0;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
/* Return the destination value. */
|
|
840
|
+
return dst;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
/** Computes the right shift of a bitstring value by a numeric value.
|
|
845
|
+
* @param src0 the first source value of the addition
|
|
846
|
+
* @param src1 the second source value of the addition
|
|
847
|
+
* @param dst the destination
|
|
848
|
+
* @return dst */
|
|
849
|
+
static Value shift_right_value_bitstring_numeric(Value src0, Value src1, Value dst) {
|
|
850
|
+
unsigned long long count;
|
|
851
|
+
/* Get the widths of the first source. */
|
|
852
|
+
unsigned long long width0 = type_width(src0->type);
|
|
853
|
+
|
|
854
|
+
/* Update the destination capacity if required. */
|
|
855
|
+
resize_value(dst,width0);
|
|
856
|
+
/* set the type and size of the destination to the type first source. */
|
|
857
|
+
dst->type = src0->type;
|
|
858
|
+
dst->numeric = 0;
|
|
859
|
+
|
|
860
|
+
/* Get access to the data of the source. */
|
|
861
|
+
char *src0_data = src0->data_str;
|
|
862
|
+
/* Get access to the data of the destination. */
|
|
863
|
+
char *dst_data = dst->data_str;
|
|
864
|
+
|
|
865
|
+
/* Compute the amount of shift. */
|
|
866
|
+
// unsigned int ext = word_ext(src1);
|
|
867
|
+
long long sh = -value2integer(src1);
|
|
868
|
+
// if (ext && (sh > 0)) sh = -sh; /* Ensure the shift sign is right. */
|
|
869
|
+
/* Cleans the destination for a clean shift result. */
|
|
870
|
+
for(count = 0; count < width0; ++count) {
|
|
871
|
+
dst_data[count] = '0';
|
|
872
|
+
}
|
|
873
|
+
/* Perform the bit-wise shift. */
|
|
874
|
+
for(count = 0; count < width0; ++count) {
|
|
875
|
+
/* Access the source bit. */
|
|
876
|
+
char d0 = src0_data[count];
|
|
877
|
+
/* Set it to the destination at the right place. */
|
|
878
|
+
unsigned long long pos = count + sh;
|
|
879
|
+
if ((pos>0) && (pos<width0)) {
|
|
880
|
+
dst_data[pos] = d0;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
/* Return the destination value. */
|
|
884
|
+
return dst;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
/** Computes the left shift of two bitstring values.
|
|
889
|
+
* @param src0 the first source value of the addition
|
|
890
|
+
* @param src1 the second source value of the addition
|
|
891
|
+
* @param dst the destination
|
|
892
|
+
* @return dst */
|
|
893
|
+
static Value shift_left_value_bitstring(Value src0, Value src1, Value dst) {
|
|
894
|
+
unsigned long long count;
|
|
895
|
+
/* Get the widths of the first source. */
|
|
896
|
+
unsigned long long width0 = type_width(src0->type);
|
|
897
|
+
|
|
898
|
+
/* Update the destination capacity if required. */
|
|
899
|
+
resize_value(dst,width0);
|
|
900
|
+
/* set the type and size of the destination to the type first source. */
|
|
901
|
+
dst->type = src0->type;
|
|
902
|
+
dst->numeric = 0;
|
|
903
|
+
|
|
904
|
+
/* Get access to the data of the destination. */
|
|
905
|
+
char *dst_data = dst->data_str;
|
|
906
|
+
|
|
907
|
+
/* Unknow shift, fills the destination with x. */
|
|
908
|
+
for(count = 0; count < width0; ++count) {
|
|
909
|
+
dst_data[count] = 'x';
|
|
910
|
+
}
|
|
911
|
+
/* Return the destination value. */
|
|
912
|
+
return dst;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
/** Computes the right shift of two bitstring values.
|
|
917
|
+
* @param src0 the first source value of the addition
|
|
918
|
+
* @param src1 the second source value of the addition
|
|
919
|
+
* @param dst the destination
|
|
920
|
+
* @return dst */
|
|
921
|
+
static Value shift_right_value_bitstring(Value src0, Value src1, Value dst) {
|
|
922
|
+
unsigned long long count;
|
|
923
|
+
/* Get the widths of the first source. */
|
|
924
|
+
unsigned long long width0 = type_width(src0->type);
|
|
925
|
+
|
|
926
|
+
/* Update the destination capacity if required. */
|
|
927
|
+
resize_value(dst,width0);
|
|
928
|
+
/* set the type and size of the destination to the type first source. */
|
|
929
|
+
dst->type = src0->type;
|
|
930
|
+
dst->numeric = 0;
|
|
931
|
+
|
|
932
|
+
/* Get access to the data of the destination. */
|
|
933
|
+
char *dst_data = dst->data_str;
|
|
934
|
+
|
|
935
|
+
/* Unknow shift, fills the destination with x. */
|
|
936
|
+
for(count = 0; count < width0; ++count) {
|
|
937
|
+
dst_data[count] = 'x';
|
|
938
|
+
}
|
|
939
|
+
/* Return the destination value. */
|
|
940
|
+
return dst;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
/** Computes the equal (!XOR) of two bitstring values.
|
|
945
|
+
* @param src0 the first source value of the and
|
|
946
|
+
* @param src1 the second source value of the and
|
|
947
|
+
* @param dst the destination value
|
|
948
|
+
* @return dst */
|
|
949
|
+
static Value equal_value_bitstring(Value src0, Value src1, Value dst) {
|
|
950
|
+
/* Compute the width of sources in bits. */
|
|
951
|
+
unsigned long long width0 = type_width(src0->type);
|
|
952
|
+
unsigned long long width1 = type_width(src1->type);
|
|
953
|
+
|
|
954
|
+
/* Update the destination capacity if required. */
|
|
955
|
+
resize_value(dst,width0);
|
|
956
|
+
/* set the type and size of the destination the the type of the source. */
|
|
957
|
+
dst->type = src0->type;
|
|
958
|
+
dst->numeric = 0;
|
|
959
|
+
|
|
960
|
+
/* Get access to the data of the sources. */
|
|
961
|
+
char *src0_data = src0->data_str;
|
|
962
|
+
char *src1_data = src1->data_str;
|
|
963
|
+
/* Get access to the data of the destination. */
|
|
964
|
+
char *dst_data = dst->data_str;
|
|
965
|
+
|
|
966
|
+
/* Get the sign extension character of source 1 and convert it to a bit.*/
|
|
967
|
+
int ext = bitstring_ext(src1);
|
|
968
|
+
|
|
969
|
+
/* Perform the !xor. */
|
|
970
|
+
unsigned long long count;
|
|
971
|
+
/* Check if values are the same. */
|
|
972
|
+
char same = '1';
|
|
973
|
+
for(count = 0; count < width0; ++count) {
|
|
974
|
+
char d0 = src0_data[count] - '0'; /* Get and convert to bit. */
|
|
975
|
+
char d1;
|
|
976
|
+
if (count < width1) {
|
|
977
|
+
/* Still within source 1. */
|
|
978
|
+
d1 = src1_data[count] - '0';/* Get and convert to bit. */
|
|
979
|
+
} else {
|
|
980
|
+
/* Outside source 1, use the sign extension. */
|
|
981
|
+
d1 = ext;
|
|
982
|
+
}
|
|
983
|
+
if (d0 == (d0&1)) {
|
|
984
|
+
/* d0 is defined. */
|
|
985
|
+
if (d1 == (d1&1)) {
|
|
986
|
+
/* d1 is also defined. */
|
|
987
|
+
if (d0 != d1) {
|
|
988
|
+
same = '0';
|
|
989
|
+
break;
|
|
990
|
+
}
|
|
991
|
+
} else {
|
|
992
|
+
/* Undefined. */
|
|
993
|
+
same = 'x';
|
|
994
|
+
break;
|
|
995
|
+
}
|
|
996
|
+
} else {
|
|
997
|
+
/* Undefined. */
|
|
998
|
+
same = 'x';
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
/* Set the destination to 0 or 1 depending of different. */
|
|
1003
|
+
dst_data[0] = same;
|
|
1004
|
+
for(count = 1; count < width0; ++count) {
|
|
1005
|
+
dst_data[count] = '0';
|
|
1006
|
+
}
|
|
1007
|
+
/* Return the destination. */
|
|
1008
|
+
return dst;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
/** Selects a value depending on a bitstring condition.
|
|
1013
|
+
* @param cond the condition to use for selecting a value
|
|
1014
|
+
* @param dst the destination value (used only if new value is created).
|
|
1015
|
+
* @param num the number of values for the selection
|
|
1016
|
+
* @return the selected value */
|
|
1017
|
+
static Value select_value_bitstring(Value cond, Value dst, unsigned int num,
|
|
1018
|
+
va_list args)
|
|
1019
|
+
{
|
|
1020
|
+
printf("select_value_bitstring with cond=%s\n",cond->data_str);
|
|
1021
|
+
/* Get the first alternative for sizing the result. */
|
|
1022
|
+
Value src = va_arg(args,Value);
|
|
1023
|
+
/* Compute the width of the result in bits. */
|
|
1024
|
+
unsigned long long width = type_width(src->type);
|
|
1025
|
+
// printf("select width=%llu\n",width);
|
|
1026
|
+
|
|
1027
|
+
/* Update the destination capacity if required. */
|
|
1028
|
+
resize_value(dst,width);
|
|
1029
|
+
/* set the type and size of the destination the the type of the source. */
|
|
1030
|
+
dst->type = src->type;
|
|
1031
|
+
dst->numeric = 0;
|
|
1032
|
+
char *dst_data = dst->data_str;
|
|
1033
|
+
|
|
1034
|
+
/* Sets the destination as undefined. */
|
|
1035
|
+
unsigned long long count;
|
|
1036
|
+
for(count = 0; count < width; ++count) {
|
|
1037
|
+
dst_data[count] = 'x';
|
|
1038
|
+
}
|
|
1039
|
+
/* Return the destination. */
|
|
1040
|
+
return dst;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
/** Concat multiple bitstring values to a single one.
|
|
1045
|
+
* @param num the number of values to concat
|
|
1046
|
+
* @param dir the direction of concatenation
|
|
1047
|
+
* @param dst the destination value
|
|
1048
|
+
* @param args the values to concat
|
|
1049
|
+
* @return dst */
|
|
1050
|
+
static Value concat_value_bitstring_array(int num, int dir,
|
|
1051
|
+
Value dst, Value* args) {
|
|
1052
|
+
unsigned long long pos = 0; /* Current position in the resulting value.*/
|
|
1053
|
+
unsigned long long i;
|
|
1054
|
+
// printf("concat_value_bitstring with dir=%d\n",dir);
|
|
1055
|
+
|
|
1056
|
+
/* Compute the size of the destination. */
|
|
1057
|
+
unsigned long long width = 0;
|
|
1058
|
+
for(i=0; i<num; ++i) {
|
|
1059
|
+
width += type_width(args[i]->type);
|
|
1060
|
+
}
|
|
1061
|
+
/* Resize the destination accordignly. */
|
|
1062
|
+
resize_value(dst,width);
|
|
1063
|
+
|
|
1064
|
+
/* Access the data of the destination. */
|
|
1065
|
+
char* dst_data = dst->data_str;
|
|
1066
|
+
|
|
1067
|
+
/* Fills the destination with each value. */
|
|
1068
|
+
for(i=0; i<num; ++i) {
|
|
1069
|
+
/* The access index denpend on the concat direction. */
|
|
1070
|
+
unsigned int idx = dir ? (num-i-1) : i;
|
|
1071
|
+
Value value = args[idx];
|
|
1072
|
+
unsigned long long cw = type_width(value->type);
|
|
1073
|
+
// printf("value=%s cw=%llu\n",value->data_str,cw);
|
|
1074
|
+
memcpy(dst_data+pos,value->data_str,cw);
|
|
1075
|
+
pos += cw;
|
|
1076
|
+
}
|
|
1077
|
+
// printf("Result=%s\n",dst->data_str);
|
|
1078
|
+
/* Sets the type of the resulting value: it is necesserily an
|
|
1079
|
+
* unsigned bit string. */
|
|
1080
|
+
dst->type = get_type_vector(get_type_bit(),pos);
|
|
1081
|
+
/* Return the destination value. */
|
|
1082
|
+
return dst;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
/** Casts a bitstring value to another type.
|
|
1087
|
+
* @param src the source value
|
|
1088
|
+
* @param type the type to cast to
|
|
1089
|
+
* @param dst the destination value
|
|
1090
|
+
* @return dst */
|
|
1091
|
+
static Value cast_value_bitstring(Value src, Type type, Value dst) {
|
|
1092
|
+
unsigned long long i;
|
|
1093
|
+
// printf("cast_value_bitstring with src=%s to width=%llu\n",src->data_str,type_width(type));
|
|
1094
|
+
/* Get the width of the source. */
|
|
1095
|
+
unsigned long long swidth = type_width(src->type);
|
|
1096
|
+
/* Get the size of the result from the target type. */
|
|
1097
|
+
unsigned long long width = type_width(type);
|
|
1098
|
+
|
|
1099
|
+
/* Update the destination capacity if required. */
|
|
1100
|
+
resize_value(dst,width);
|
|
1101
|
+
/* set the type and size of the destination the the type of the source. */
|
|
1102
|
+
dst->type = type;
|
|
1103
|
+
dst->numeric = 0;
|
|
1104
|
+
|
|
1105
|
+
/* Get access to the data of the source. */
|
|
1106
|
+
char *src_data = src->data_str;
|
|
1107
|
+
/* Get access to the data of the destination. */
|
|
1108
|
+
char *dst_data = dst->data_str;
|
|
1109
|
+
/* Get the sign extension. */
|
|
1110
|
+
unsigned int ext = bitstring_ext(src) + '0';
|
|
1111
|
+
|
|
1112
|
+
/* Copy the source to the destination as long as there is enough room. */
|
|
1113
|
+
for(i=0; i<width && i<swidth; ++i) {
|
|
1114
|
+
dst_data[i] = src_data[i];
|
|
1115
|
+
}
|
|
1116
|
+
/* Add the extension for the remaining bits. */
|
|
1117
|
+
for(;i<width; ++i) {
|
|
1118
|
+
dst_data[i] = ext;
|
|
1119
|
+
}
|
|
1120
|
+
/* Return the destination value. */
|
|
1121
|
+
return dst;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
/** Testing if two bitstring values have the same content (the type is not checked).
|
|
1126
|
+
* @param value0 the first value to compare
|
|
1127
|
+
* @param value1 the second value to compare
|
|
1128
|
+
* @return 1 if same content. */
|
|
1129
|
+
static unsigned int same_content_value_bitstring(Value value0, Value value1) {
|
|
1130
|
+
unsigned long long i;
|
|
1131
|
+
// unsigned long long width = type_width(value0->type);
|
|
1132
|
+
// printf("same_content_value_bitstring.\n");
|
|
1133
|
+
// print_value(value0); printf(" "); print_value(value1); printf("\n");
|
|
1134
|
+
// printf("width0=%llu width1=%llu\n",type_width(value0->type),
|
|
1135
|
+
// type_width(value1->type));
|
|
1136
|
+
// /* Compare the sizes. */
|
|
1137
|
+
// if (type_width(value1->type) != width) return 0;
|
|
1138
|
+
unsigned long long width = min2(type_width(value0->type),type_width(value1->type));
|
|
1139
|
+
/* Compare the data up to the widths. */
|
|
1140
|
+
char* data0 = value0->data_str;
|
|
1141
|
+
char* data1 = value1->data_str;
|
|
1142
|
+
for(i=0; i<width; ++i) {
|
|
1143
|
+
if (data0[i] != data1[i])
|
|
1144
|
+
/* The contents are different. */
|
|
1145
|
+
return 0;
|
|
1146
|
+
}
|
|
1147
|
+
/* The values have the same content. */
|
|
1148
|
+
return 1;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
/** Testing if two bitstring values have the same content (the type is not checked).
|
|
1153
|
+
* @param value0 the first value to compare
|
|
1154
|
+
* @param first the first index of the range
|
|
1155
|
+
* @param last the last index of the range
|
|
1156
|
+
* @param value1 the second value to compare
|
|
1157
|
+
* @return 1 if same content. */
|
|
1158
|
+
static int same_content_value_range_bitstring(Value value0,
|
|
1159
|
+
unsigned long long first, unsigned long long last, Value value1) {
|
|
1160
|
+
/* Ensure first is the smaller. */
|
|
1161
|
+
if (first > last) {
|
|
1162
|
+
long long tmp = last;
|
|
1163
|
+
last = first;
|
|
1164
|
+
first = tmp;
|
|
1165
|
+
}
|
|
1166
|
+
unsigned long long i;
|
|
1167
|
+
unsigned long long width0 = type_width(value0->type);
|
|
1168
|
+
unsigned long long width1 = type_width(value1->type);
|
|
1169
|
+
/* Get access to the data of both values. */
|
|
1170
|
+
char* data0 = value0->data_str;
|
|
1171
|
+
char* data1 = value1->data_str;
|
|
1172
|
+
/* Compare within the range. */
|
|
1173
|
+
for(i=first; i<=last; ++i) {
|
|
1174
|
+
if (i>=width0) {
|
|
1175
|
+
if (i>=width1) {
|
|
1176
|
+
/* Both values are out of range. */
|
|
1177
|
+
return 1;
|
|
1178
|
+
} else {
|
|
1179
|
+
/* Only value 0 is out of range. */
|
|
1180
|
+
return 0;
|
|
1181
|
+
}
|
|
1182
|
+
} else if (i>=width1) {
|
|
1183
|
+
/* Only value 1 is out of range. */
|
|
1184
|
+
return 0;
|
|
1185
|
+
} else {
|
|
1186
|
+
if (data0[i] != data1[i]) {
|
|
1187
|
+
/* Values are different within the range. */
|
|
1188
|
+
return 0;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
/* Values are identical in the range. */
|
|
1193
|
+
return 1;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
/** Reads a range from a bitstring value.
|
|
1199
|
+
* @param value the value to read
|
|
1200
|
+
* @param first the first index of the range
|
|
1201
|
+
* @param last the last index of the range
|
|
1202
|
+
* @param base the type of the elements
|
|
1203
|
+
* @param dst the destination value
|
|
1204
|
+
* @return dst */
|
|
1205
|
+
Value read_range_bitstring(Value src, long long first, long long last,
|
|
1206
|
+
Type base, Value dst) {
|
|
1207
|
+
// printf("read_range_bitstring with first=%lld last=%lld src=%s\n",first,last,src->data_str);
|
|
1208
|
+
/* Ensure first is the smaller. */
|
|
1209
|
+
if (first > last) {
|
|
1210
|
+
long long tmp = last;
|
|
1211
|
+
last = first;
|
|
1212
|
+
first = tmp;
|
|
1213
|
+
}
|
|
1214
|
+
/* Compute the number of elements to read. */
|
|
1215
|
+
long long length = last-first+1;
|
|
1216
|
+
/* Compute the elements size. */
|
|
1217
|
+
unsigned long long bw = type_width(base);
|
|
1218
|
+
/* Scale the range according to the base type. */
|
|
1219
|
+
first *= bw;
|
|
1220
|
+
length *= bw;
|
|
1221
|
+
|
|
1222
|
+
/* Update the destination capacity if required. */
|
|
1223
|
+
resize_value(dst,length);
|
|
1224
|
+
/* set the type and size of the destination the the type of the source. */
|
|
1225
|
+
dst->type = make_type_vector(get_type_bit(),length);
|
|
1226
|
+
dst->numeric = 0;
|
|
1227
|
+
|
|
1228
|
+
/* Performs the read. */
|
|
1229
|
+
memcpy(dst->data_str,src->data_str + first, length);
|
|
1230
|
+
|
|
1231
|
+
/* Return the destination. */
|
|
1232
|
+
return dst;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
/** Writes to a range within a bitstring value.
|
|
1237
|
+
* NOTE: the type of the destination is NOT changed!
|
|
1238
|
+
* @param src the source value
|
|
1239
|
+
* @param first the first index of the range
|
|
1240
|
+
* @param last the last index of the range
|
|
1241
|
+
* @param dst the destination value
|
|
1242
|
+
* @return dst */
|
|
1243
|
+
Value write_range_bitstring(Value src, long long first, long long last,
|
|
1244
|
+
Value dst) {
|
|
1245
|
+
unsigned long long i;
|
|
1246
|
+
/* Ensure first is the smaller. */
|
|
1247
|
+
if (first > last) {
|
|
1248
|
+
long long tmp = last;
|
|
1249
|
+
last = first;
|
|
1250
|
+
first = tmp;
|
|
1251
|
+
}
|
|
1252
|
+
/* Get the widths of the source and the desintation. */
|
|
1253
|
+
unsigned long long src_width = type_width(src->type);
|
|
1254
|
+
unsigned long long dst_width = type_width(dst->type);
|
|
1255
|
+
/* scale the range according to the base type. */
|
|
1256
|
+
unsigned long long bw = dst->type->base;
|
|
1257
|
+
first *= bw;
|
|
1258
|
+
last *= bw;
|
|
1259
|
+
/* Access the source and destination bitstring data. */
|
|
1260
|
+
char* dst_data = dst->data_str;
|
|
1261
|
+
char* src_data = src->data_str;
|
|
1262
|
+
/* Perform the copy. */
|
|
1263
|
+
for(i=0; (i+first<=last) && (i<src_width) && (i+first<dst_width); ++i) {
|
|
1264
|
+
dst_data[i+first] = src_data[i];
|
|
1265
|
+
}
|
|
1266
|
+
return dst;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
|
|
1270
|
+
/** Writes to a range within a bitstring value without overwritting with Z.
|
|
1271
|
+
* NOTE: the type of the destination is NOT changed!
|
|
1272
|
+
* @param src the source value
|
|
1273
|
+
* @param first the first index of the range
|
|
1274
|
+
* @param last the last index of the range
|
|
1275
|
+
* @param dst the destination value
|
|
1276
|
+
* @return dst */
|
|
1277
|
+
Value write_range_bitstring_no_z(Value src, long long first, long long last,
|
|
1278
|
+
Value dst) {
|
|
1279
|
+
unsigned long long i;
|
|
1280
|
+
/* Ensure first is the smaller. */
|
|
1281
|
+
if (first > last) {
|
|
1282
|
+
long long tmp = last;
|
|
1283
|
+
last = first;
|
|
1284
|
+
first = tmp;
|
|
1285
|
+
}
|
|
1286
|
+
/* Get the widths of the source and the desintation. */
|
|
1287
|
+
unsigned long long src_width = type_width(src->type);
|
|
1288
|
+
unsigned long long dst_width = type_width(dst->type);
|
|
1289
|
+
/* scale the range according to the base type. */
|
|
1290
|
+
unsigned long long bw = dst->type->base;
|
|
1291
|
+
first *= bw;
|
|
1292
|
+
last *= bw;
|
|
1293
|
+
/* Access the source and destination bitstring data. */
|
|
1294
|
+
char* dst_data = dst->data_str;
|
|
1295
|
+
char* src_data = src->data_str;
|
|
1296
|
+
/* Perform the copy. */
|
|
1297
|
+
for(i=0; (i+first<=last) && (i<src_width) && (i+first<dst_width); ++i) {
|
|
1298
|
+
char b = src_data[i];
|
|
1299
|
+
if (b != 'z')
|
|
1300
|
+
dst_data[i+first] = src_data[i];
|
|
1301
|
+
}
|
|
1302
|
+
return dst;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
/* ############# End of the computation of bitstring values. ############## */
|
|
1306
|
+
|
|
1307
|
+
/* ############# Start of the computation of numeric values. ############## */
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
/** Computes the neg of a numeric value.
|
|
1311
|
+
* @param src the source value of the not
|
|
1312
|
+
* @param dst the destination value
|
|
1313
|
+
* @return dst */
|
|
1314
|
+
static Value neg_value_numeric(Value src, Value dst) {
|
|
1315
|
+
/* Sets state of the destination using the source. */
|
|
1316
|
+
dst->type = src->type;
|
|
1317
|
+
dst->numeric = 1;
|
|
1318
|
+
|
|
1319
|
+
/* Perform the negation. */
|
|
1320
|
+
dst->data_int = -src->data_int;
|
|
1321
|
+
return dst;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
/** Computes the addition of two numeric values.
|
|
1326
|
+
* @param src0 the first source value of the addition
|
|
1327
|
+
* @param src1 the second source value of the addition
|
|
1328
|
+
* @param dst the destination value
|
|
1329
|
+
* @return dst */
|
|
1330
|
+
static Value add_value_numeric(Value src0, Value src1, Value dst) {
|
|
1331
|
+
/* Sets state of the destination using the first source. */
|
|
1332
|
+
dst->type = src0->type;
|
|
1333
|
+
dst->numeric = 1;
|
|
1334
|
+
|
|
1335
|
+
/* Perform the addition. */
|
|
1336
|
+
dst->data_int = src0->data_int + src1->data_int;
|
|
1337
|
+
return dst;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
/** Computes the subtrasction of two numeric values.
|
|
1342
|
+
* @param src0 the first source value of the addition
|
|
1343
|
+
* @param src1 the second source value of the addition
|
|
1344
|
+
* @param dst the destination value
|
|
1345
|
+
* @return dst */
|
|
1346
|
+
static Value sub_value_numeric(Value src0, Value src1, Value dst) {
|
|
1347
|
+
/* Sets state of the destination using the first source. */
|
|
1348
|
+
dst->type = src0->type;
|
|
1349
|
+
dst->numeric = 1;
|
|
1350
|
+
|
|
1351
|
+
/* Perform the subtraction. */
|
|
1352
|
+
dst->data_int = src0->data_int - src1->data_int;
|
|
1353
|
+
return dst;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
/** Computes the NOT of a numeric value.
|
|
1358
|
+
* @param src the source value of the not
|
|
1359
|
+
* @param dst the destination value
|
|
1360
|
+
* @return the destination value */
|
|
1361
|
+
static Value not_value_numeric(Value src, Value dst) {
|
|
1362
|
+
/* Sets state of the destination using the first source. */
|
|
1363
|
+
dst->type = src->type;
|
|
1364
|
+
dst->numeric = 1;
|
|
1365
|
+
|
|
1366
|
+
/* Perform the not. */
|
|
1367
|
+
dst->data_int = !src->data_int;
|
|
1368
|
+
return dst;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
/** Computes the AND of two numeric values.
|
|
1373
|
+
* @param src0 the first source value of the addition
|
|
1374
|
+
* @param src1 the second source value of the addition
|
|
1375
|
+
* @param dst the destination value
|
|
1376
|
+
* @return dst */
|
|
1377
|
+
static Value and_value_numeric(Value src0, Value src1, Value dst) {
|
|
1378
|
+
/* Sets state of the destination using the first source. */
|
|
1379
|
+
dst->type = src0->type;
|
|
1380
|
+
dst->numeric = 1;
|
|
1381
|
+
|
|
1382
|
+
/* Perform the AND. */
|
|
1383
|
+
dst->data_int = src0->data_int & src1->data_int;
|
|
1384
|
+
return dst;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
/** Computes the OR of two numeric values.
|
|
1389
|
+
* @param src0 the first source value of the addition
|
|
1390
|
+
* @param src1 the second source value of the addition
|
|
1391
|
+
* @param dst the destination
|
|
1392
|
+
* @return dst */
|
|
1393
|
+
static Value or_value_numeric(Value src0, Value src1, Value dst) {
|
|
1394
|
+
/* Sets state of the destination using the first source. */
|
|
1395
|
+
dst->type = src0->type;
|
|
1396
|
+
dst->numeric = 1;
|
|
1397
|
+
|
|
1398
|
+
/* Perform the OR. */
|
|
1399
|
+
dst->data_int = src0->data_int | src1->data_int;
|
|
1400
|
+
return dst;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
|
|
1404
|
+
/** Computes the XOR of two numeric values.
|
|
1405
|
+
* @param src0 the first source value of the addition
|
|
1406
|
+
* @param src1 the second source value of the addition
|
|
1407
|
+
* @param dst the destination
|
|
1408
|
+
* @return dst */
|
|
1409
|
+
static Value xor_value_numeric(Value src0, Value src1, Value dst) {
|
|
1410
|
+
/* Sets state of the destination using the first source. */
|
|
1411
|
+
dst->type = src0->type;
|
|
1412
|
+
dst->numeric = 1;
|
|
1413
|
+
|
|
1414
|
+
/* Perform the XOR. */
|
|
1415
|
+
dst->data_int = src0->data_int ^ src1->data_int;
|
|
1416
|
+
return dst;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
/** Computes the left shift of two numeric values.
|
|
1421
|
+
* @param src0 the first source value of the addition
|
|
1422
|
+
* @param src1 the second source value of the addition
|
|
1423
|
+
* @param dst the destination
|
|
1424
|
+
* @return dst */
|
|
1425
|
+
static Value shift_left_value_numeric(Value src0, Value src1, Value dst) {
|
|
1426
|
+
/* Sets state of the destination using the first source. */
|
|
1427
|
+
dst->type = src0->type;
|
|
1428
|
+
dst->numeric = 1;
|
|
1429
|
+
|
|
1430
|
+
/* Perform the left shift. */
|
|
1431
|
+
dst->data_int = src0->data_int << src1->data_int;
|
|
1432
|
+
return dst;
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
/** Computes the right shift of two numeric values.
|
|
1437
|
+
* @param src0 the first source value of the addition
|
|
1438
|
+
* @param src1 the second source value of the addition
|
|
1439
|
+
* @param dst the destination
|
|
1440
|
+
* @return dst */
|
|
1441
|
+
static Value shift_right_value_numeric(Value src0, Value src1, Value dst) {
|
|
1442
|
+
/* Sets state of the destination using the first source. */
|
|
1443
|
+
dst->type = src0->type;
|
|
1444
|
+
dst->numeric = 1;
|
|
1445
|
+
|
|
1446
|
+
/* Perform the right shift. */
|
|
1447
|
+
dst->data_int = src0->data_int >> src1->data_int;
|
|
1448
|
+
return dst;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
/** Computes the equal (!XOR) of two numeric values.
|
|
1453
|
+
* @param src0 the first source value of the addition
|
|
1454
|
+
* @param src1 the second source value of the addition
|
|
1455
|
+
* @param dst the destination value
|
|
1456
|
+
* @return the destination value */
|
|
1457
|
+
static Value equal_value_numeric(Value src0, Value src1, Value dst) {
|
|
1458
|
+
/* Sets state of the destination using the first source. */
|
|
1459
|
+
dst->type = src0->type;
|
|
1460
|
+
dst->numeric = 1;
|
|
1461
|
+
|
|
1462
|
+
/* Perform the !XOR. */
|
|
1463
|
+
dst->data_int = (src0->data_int == src1->data_int);
|
|
1464
|
+
return dst;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
/** Selects a value depending on a numeric condition.
|
|
1469
|
+
* @param cond the condition to use for selecting a value
|
|
1470
|
+
* @param dst the destination value (used only if new value is created).
|
|
1471
|
+
* @param num the number of values for the selection
|
|
1472
|
+
* @return the selected value */
|
|
1473
|
+
static Value select_value_numeric(Value cond, Value dst, unsigned int num,
|
|
1474
|
+
va_list args) {
|
|
1475
|
+
unsigned int i;
|
|
1476
|
+
/* Select the value corresponding to the condition and copy it to
|
|
1477
|
+
* the destination. */
|
|
1478
|
+
for(i = 0; i<num; ++i) {
|
|
1479
|
+
Value value = va_arg(args,Value);
|
|
1480
|
+
if (i == value2integer(cond)) {
|
|
1481
|
+
/* The right value is reached, copy it. */
|
|
1482
|
+
copy_value(value,dst);
|
|
1483
|
+
return dst;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
/* Should never be here. */
|
|
1487
|
+
return NULL;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
/** Concat multiple numeric values to a single one.
|
|
1491
|
+
* @param num the number of values to concat
|
|
1492
|
+
* @param dir the direction of the concatenation.
|
|
1493
|
+
* @param dst the destination value
|
|
1494
|
+
* @return dst */
|
|
1495
|
+
static Value concat_value_numeric_array(int num, int dir,
|
|
1496
|
+
Value dst, Value* args) {
|
|
1497
|
+
unsigned int i,pos;
|
|
1498
|
+
/* Compute the bit width of the destination. */
|
|
1499
|
+
unsigned int width = 0;
|
|
1500
|
+
// printf("concat_value_numeric with dir=%d\n",dir);
|
|
1501
|
+
for(i=0; i<num; ++i) width += type_width(args[i]->type);
|
|
1502
|
+
|
|
1503
|
+
/* Sets state of the destination using the bit width. */
|
|
1504
|
+
dst->type = make_type_vector(get_type_bit(),width);
|
|
1505
|
+
dst->numeric = 1;
|
|
1506
|
+
|
|
1507
|
+
/* Perform the concatenation. */
|
|
1508
|
+
dst->data_int = 0;
|
|
1509
|
+
pos = 0;
|
|
1510
|
+
for(i=0; i<num; ++i) {
|
|
1511
|
+
/* The access index depend on the concatenation direction. */
|
|
1512
|
+
unsigned int idx = dir ? (num-i-1) : i;
|
|
1513
|
+
/* Compute the read mask. */
|
|
1514
|
+
unsigned long long arg_width = type_width(args[idx]->type);
|
|
1515
|
+
unsigned long long read_mask = ~((-1LL) << arg_width);
|
|
1516
|
+
/* Read from the value to concatenate. */
|
|
1517
|
+
unsigned long long arg_data = args[idx]->data_int & read_mask;
|
|
1518
|
+
/* Write it. */
|
|
1519
|
+
dst->data_int |= arg_data << pos;
|
|
1520
|
+
/* Update the write position. */
|
|
1521
|
+
pos += arg_width;
|
|
1522
|
+
}
|
|
1523
|
+
/* Return the destination. */
|
|
1524
|
+
return dst;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
|
|
1528
|
+
/** Casts a numeric value to another type.
|
|
1529
|
+
* @param src the source value
|
|
1530
|
+
* @param type the type to cast to
|
|
1531
|
+
* @param dst the destination value
|
|
1532
|
+
* @return dst */
|
|
1533
|
+
static Value cast_value_numeric(Value src, Type type, Value dst) {
|
|
1534
|
+
/* Copy the source to the destination. */
|
|
1535
|
+
dst->data_int = src->data_int;
|
|
1536
|
+
/* Update the destination type to the cast. */
|
|
1537
|
+
dst->type = type;
|
|
1538
|
+
dst->numeric = 1;
|
|
1539
|
+
/* Return the destination. */
|
|
1540
|
+
return dst;
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
/** Testing if a numeric value is 0.
|
|
1545
|
+
* @param value the value to check
|
|
1546
|
+
* @return 1 if 0 and 0 otherwize */
|
|
1547
|
+
static int zero_value_numeric(Value value) {
|
|
1548
|
+
return value->data_int == 0;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
/** Testing if two numeric values have the same content (the type is not checked).
|
|
1554
|
+
* @param value0 the first value to compare
|
|
1555
|
+
* @param value1 the second value to compare
|
|
1556
|
+
* @return 1 if same content. */
|
|
1557
|
+
static unsigned int same_content_value_numeric(Value value0, Value value1) {
|
|
1558
|
+
return value0->data_int == value1->data_int;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
/** Testing if two numeric values have the same content in a given
|
|
1563
|
+
* range (the type is not checked).
|
|
1564
|
+
* @param value0 the first value to compare
|
|
1565
|
+
* @param first the first index of the range
|
|
1566
|
+
* @param last the last index of the range
|
|
1567
|
+
* @param value1 the second value to compare
|
|
1568
|
+
* @return 1 if same content. */
|
|
1569
|
+
static int same_content_value_range_numeric(Value value0,
|
|
1570
|
+
unsigned long long first, unsigned long long last, Value value1) {
|
|
1571
|
+
/* Ensure first is the smaller index. */
|
|
1572
|
+
if (first>last) {
|
|
1573
|
+
unsigned long long tmp = first;
|
|
1574
|
+
first = last;
|
|
1575
|
+
last = tmp;
|
|
1576
|
+
}
|
|
1577
|
+
/* Compute the mask from the range. */
|
|
1578
|
+
unsigned long long mask = ((-1LL) << first) & ~((-1LL) << last);
|
|
1579
|
+
/* Compare using the mask. */
|
|
1580
|
+
return (value0->data_int & mask) == (value1->data_int & mask);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
|
|
1584
|
+
/** Reads a range from a numeric value.
|
|
1585
|
+
* @param value the value to read
|
|
1586
|
+
* @param first the first index of the range
|
|
1587
|
+
* @param last the last index of the range
|
|
1588
|
+
* @param base the type of the elements
|
|
1589
|
+
* @param dst the destination value
|
|
1590
|
+
* @return dst */
|
|
1591
|
+
Value read_range_numeric(Value value, long long first, long long last,
|
|
1592
|
+
Type base, Value dst) {
|
|
1593
|
+
/* Ensure first is the smaller. */
|
|
1594
|
+
if (first > last) {
|
|
1595
|
+
long long tmp = last;
|
|
1596
|
+
last = first;
|
|
1597
|
+
first = tmp;
|
|
1598
|
+
}
|
|
1599
|
+
/* Compute the number of elements to read. */
|
|
1600
|
+
long long length = last-first+1;
|
|
1601
|
+
/* Compute the elements size. */
|
|
1602
|
+
unsigned long long bw = type_width(base);
|
|
1603
|
+
/* Scale the range according to the base type. */
|
|
1604
|
+
first *= bw;
|
|
1605
|
+
length *= bw;
|
|
1606
|
+
// printf("first=%lld last=%lld bw=%llu length=%lld\n",first,last,bw,length);
|
|
1607
|
+
|
|
1608
|
+
/* set the type and size of the destination the the type of the source. */
|
|
1609
|
+
dst->type = make_type_vector(get_type_bit(),length);
|
|
1610
|
+
dst->numeric = 1;
|
|
1611
|
+
|
|
1612
|
+
/* Compute the read mask. */
|
|
1613
|
+
unsigned long long mask = ((-1LL) << first) & (~((-1LL) << (last+1)));
|
|
1614
|
+
/* Performs the read. */
|
|
1615
|
+
unsigned long long data = (value->data_int & mask) >> first;
|
|
1616
|
+
/* Write it to the destination. */
|
|
1617
|
+
dst->data_int = data;
|
|
1618
|
+
|
|
1619
|
+
/* Return the destination. */
|
|
1620
|
+
return dst;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
/** Writes to a range within a numeric value.
|
|
1624
|
+
* NOTE: the type of the destination is NOT changed!
|
|
1625
|
+
* @param src the source value
|
|
1626
|
+
* @param first the first index of the range
|
|
1627
|
+
* @param last the last index of the range
|
|
1628
|
+
* @param dst the destination value
|
|
1629
|
+
* @return dst */
|
|
1630
|
+
Value write_range_numeric(Value src, long long first, long long last,
|
|
1631
|
+
Value dst) {
|
|
1632
|
+
/* Ensure first is the smaller. */
|
|
1633
|
+
if (first > last) {
|
|
1634
|
+
long long tmp = last;
|
|
1635
|
+
last = first;
|
|
1636
|
+
first = tmp;
|
|
1637
|
+
}
|
|
1638
|
+
/* Get the widths of the source and the desintation. */
|
|
1639
|
+
unsigned long long src_width = type_width(src->type);
|
|
1640
|
+
unsigned long long dst_width = type_width(dst->type);
|
|
1641
|
+
/* scale the range according to the base type of the destination. */
|
|
1642
|
+
unsigned long long bw = dst->type->base;
|
|
1643
|
+
first *= bw;
|
|
1644
|
+
last *= bw;
|
|
1645
|
+
/* If first is too large, end here. */
|
|
1646
|
+
if (first>dst_width) return dst;
|
|
1647
|
+
/* Adjust the last to fit the source and destination range. */
|
|
1648
|
+
if (last >= dst_width) last = dst_width-1;
|
|
1649
|
+
if (last-first >= src_width) last = src_width + first - 1;
|
|
1650
|
+
/* Copy from the source. */
|
|
1651
|
+
unsigned long long src_data = src->data_int & ~((-1LL) << (last-first));
|
|
1652
|
+
/* Cleans the destination where to place the data. */
|
|
1653
|
+
unsigned long long mask = ((-1LL) << first) & ~((-1LL) << last);
|
|
1654
|
+
unsigned long long dst_data = dst->data_int & mask;
|
|
1655
|
+
/* Write the data. */
|
|
1656
|
+
dst_data |= src_data << first;
|
|
1657
|
+
dst->data_int = dst_data;
|
|
1658
|
+
/* Return the destination. */
|
|
1659
|
+
return dst;
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
|
|
1663
|
+
/* ############# End of the computation of numeric values. ################ */
|
|
1664
|
+
|
|
1665
|
+
/* ############# Start of the computation of general values. ################ */
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
/** Computes the neg of a general value.
|
|
1669
|
+
* @param src the source value of the not
|
|
1670
|
+
* @param dst the destination value
|
|
1671
|
+
* @return dst */
|
|
1672
|
+
Value neg_value(Value src, Value dst) {
|
|
1673
|
+
if (src->numeric) {
|
|
1674
|
+
/* The source is numeric. */
|
|
1675
|
+
return neg_value_numeric(src,dst);
|
|
1676
|
+
} else {
|
|
1677
|
+
/* The source cannot be numeric, compute bitsitrings. */
|
|
1678
|
+
return neg_value_bitstring(src,dst);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
|
|
1683
|
+
/** Computes the addition of two general values.
|
|
1684
|
+
* @param src0 the first source value of the addition
|
|
1685
|
+
* @param src1 the second source value of the addition
|
|
1686
|
+
* @param dst the destination value
|
|
1687
|
+
* @return dst */
|
|
1688
|
+
Value add_value(Value src0, Value src1, Value dst) {
|
|
1689
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1690
|
+
unsigned int pos = get_value_pos();
|
|
1691
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1692
|
+
* computation. */
|
|
1693
|
+
if (src0->numeric) {
|
|
1694
|
+
if (src1->numeric) {
|
|
1695
|
+
/* Both sources are numeric. */
|
|
1696
|
+
return add_value_numeric(src0,src1,dst);
|
|
1697
|
+
} else {
|
|
1698
|
+
/* src1 is not numeric, convert src0 to bitstring. */
|
|
1699
|
+
src0 = set_bitstring_value(src0,get_value());
|
|
1700
|
+
}
|
|
1701
|
+
} else {
|
|
1702
|
+
/* src0 is not numeric, what about src1. */
|
|
1703
|
+
if (src1->numeric) {
|
|
1704
|
+
/* src1 is numeric, convert it to bitstring. */
|
|
1705
|
+
src1 = set_bitstring_value(src1,get_value());
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1709
|
+
dst = add_value_bitstring(src0,src1,dst);
|
|
1710
|
+
/* Restores the pool of values. */
|
|
1711
|
+
set_value_pos(pos);
|
|
1712
|
+
/* Return the destination. */
|
|
1713
|
+
return dst;
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
/** Computes the subtrasction of two general values.
|
|
1718
|
+
* @param src0 the first source value of the addition
|
|
1719
|
+
* @param src1 the second source value of the addition
|
|
1720
|
+
* @param dst the destination value
|
|
1721
|
+
* @return dst */
|
|
1722
|
+
Value sub_value(Value src0, Value src1, Value dst) {
|
|
1723
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1724
|
+
unsigned int pos = get_value_pos();
|
|
1725
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1726
|
+
* computation. */
|
|
1727
|
+
if (src0->numeric) {
|
|
1728
|
+
if (src1->numeric) {
|
|
1729
|
+
/* Both sources are numeric. */
|
|
1730
|
+
return sub_value_numeric(src0,src1,dst);
|
|
1731
|
+
} else {
|
|
1732
|
+
/* src1 is not numeric, convert src0 to bitstring. */
|
|
1733
|
+
src0 = set_bitstring_value(src0,get_value());
|
|
1734
|
+
}
|
|
1735
|
+
} else {
|
|
1736
|
+
/* src0 is not numeric, what about src1. */
|
|
1737
|
+
if (src1->numeric) {
|
|
1738
|
+
/* src1 is numeric, convert it to bitstring. */
|
|
1739
|
+
src1 = set_bitstring_value(src1,get_value());
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1743
|
+
dst = sub_value_bitstring(src0,src1,dst);
|
|
1744
|
+
/* Restores the pool of values. */
|
|
1745
|
+
set_value_pos(pos);
|
|
1746
|
+
/* Return the destination. */
|
|
1747
|
+
return dst;
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
/** Computes the NOT of a general value.
|
|
1752
|
+
* @param src the source value of the not
|
|
1753
|
+
* @param dst the destination value
|
|
1754
|
+
* @return the destination value */
|
|
1755
|
+
Value not_value(Value src, Value dst) {
|
|
1756
|
+
if (src->numeric) {
|
|
1757
|
+
/* The source is numeric. */
|
|
1758
|
+
return not_value_numeric(src,dst);
|
|
1759
|
+
} else {
|
|
1760
|
+
/* The source cannot be numeric, compute bitsitrings. */
|
|
1761
|
+
return not_value_bitstring(src,dst);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
/** Computes the AND of two general values.
|
|
1767
|
+
* @param src0 the first source value of the addition
|
|
1768
|
+
* @param src1 the second source value of the addition
|
|
1769
|
+
* @param dst the destination value
|
|
1770
|
+
* @return dst */
|
|
1771
|
+
Value and_value(Value src0, Value src1, Value dst) {
|
|
1772
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1773
|
+
unsigned int pos = get_value_pos();
|
|
1774
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1775
|
+
* computation. */
|
|
1776
|
+
if (src0->numeric) {
|
|
1777
|
+
if (src1->numeric) {
|
|
1778
|
+
/* Both sources are numeric. */
|
|
1779
|
+
return and_value_numeric(src0,src1,dst);
|
|
1780
|
+
} else {
|
|
1781
|
+
/* src1 is not numeric, convert src0 to bitstring. */
|
|
1782
|
+
src0 = set_bitstring_value(src0,get_value());
|
|
1783
|
+
}
|
|
1784
|
+
} else {
|
|
1785
|
+
/* src0 is not numeric, what about src1. */
|
|
1786
|
+
if (src1->numeric) {
|
|
1787
|
+
/* src1 is numeric, convert it to bitstring. */
|
|
1788
|
+
src1 = set_bitstring_value(src1,get_value());
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1792
|
+
dst = and_value_bitstring(src0,src1,dst);
|
|
1793
|
+
/* Restores the pool of values. */
|
|
1794
|
+
set_value_pos(pos);
|
|
1795
|
+
/* Return the destination. */
|
|
1796
|
+
return dst;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
/** Computes the OR of two general values.
|
|
1801
|
+
* @param src0 the first source value of the addition
|
|
1802
|
+
* @param src1 the second source value of the addition
|
|
1803
|
+
* @param dst the destination
|
|
1804
|
+
* @return dst */
|
|
1805
|
+
Value or_value(Value src0, Value src1, Value dst) {
|
|
1806
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1807
|
+
unsigned int pos = get_value_pos();
|
|
1808
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1809
|
+
* computation. */
|
|
1810
|
+
if (src0->numeric) {
|
|
1811
|
+
if (src1->numeric) {
|
|
1812
|
+
/* Both sources are numeric. */
|
|
1813
|
+
return or_value_numeric(src0,src1,dst);
|
|
1814
|
+
} else {
|
|
1815
|
+
/* src1 is not numeric, convert src0 to bitstring. */
|
|
1816
|
+
src0 = set_bitstring_value(src0,get_value());
|
|
1817
|
+
}
|
|
1818
|
+
} else {
|
|
1819
|
+
/* src0 is not numeric, what about src1. */
|
|
1820
|
+
if (src1->numeric) {
|
|
1821
|
+
/* src1 is numeric, convert it to bitstring. */
|
|
1822
|
+
src1 = set_bitstring_value(src1,get_value());
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1826
|
+
dst = or_value_bitstring(src0,src1,dst);
|
|
1827
|
+
/* Restores the pool of values. */
|
|
1828
|
+
set_value_pos(pos);
|
|
1829
|
+
/* Return the destination. */
|
|
1830
|
+
return dst;
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
|
|
1834
|
+
/** Computes the XOR of two general values.
|
|
1835
|
+
* @param src0 the first source value of the addition
|
|
1836
|
+
* @param src1 the second source value of the addition
|
|
1837
|
+
* @param dst the destination
|
|
1838
|
+
* @return dst */
|
|
1839
|
+
Value xor_value(Value src0, Value src1, Value dst) {
|
|
1840
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1841
|
+
unsigned int pos = get_value_pos();
|
|
1842
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1843
|
+
* computation. */
|
|
1844
|
+
if (src0->numeric) {
|
|
1845
|
+
if (src1->numeric) {
|
|
1846
|
+
/* Both sources are numeric. */
|
|
1847
|
+
return xor_value_numeric(src0,src1,dst);
|
|
1848
|
+
} else {
|
|
1849
|
+
/* src1 is not numeric, convert src0 to bitstring. */
|
|
1850
|
+
src0 = set_bitstring_value(src0,get_value());
|
|
1851
|
+
}
|
|
1852
|
+
} else {
|
|
1853
|
+
/* src0 is not numeric, what about src1. */
|
|
1854
|
+
if (src1->numeric) {
|
|
1855
|
+
/* src1 is numeric, convert it to bitstring. */
|
|
1856
|
+
src1 = set_bitstring_value(src1,get_value());
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1860
|
+
dst = xor_value_bitstring(src0,src1,dst);
|
|
1861
|
+
/* Restores the pool of values. */
|
|
1862
|
+
set_value_pos(pos);
|
|
1863
|
+
/* Return the destination. */
|
|
1864
|
+
return dst;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
/** Computes the left shift of two general values.
|
|
1869
|
+
* @param src0 the first source value of the addition
|
|
1870
|
+
* @param src1 the second source value of the addition
|
|
1871
|
+
* @param dst the destination
|
|
1872
|
+
* @return dst */
|
|
1873
|
+
Value shift_left_value(Value src0, Value src1, Value dst) {
|
|
1874
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1875
|
+
unsigned int pos = get_value_pos();
|
|
1876
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1877
|
+
* computation. */
|
|
1878
|
+
if (src0->numeric) {
|
|
1879
|
+
if (src1->numeric) {
|
|
1880
|
+
/* Both sources are numeric. */
|
|
1881
|
+
return shift_left_value_numeric(src0,src1,dst);
|
|
1882
|
+
} else {
|
|
1883
|
+
/* src0 is numeric, convert it to bitstring. */
|
|
1884
|
+
src0 = set_bitstring_value(src1,get_value());
|
|
1885
|
+
}
|
|
1886
|
+
} else {
|
|
1887
|
+
/* src0 is not numeric, what about src1. */
|
|
1888
|
+
if (src1->numeric) {
|
|
1889
|
+
/* src0 is not numeric, but src1. */
|
|
1890
|
+
return shift_left_value_bitstring_numeric(src0,src1,dst);
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1894
|
+
dst = shift_left_value_bitstring(src0,src1,dst);
|
|
1895
|
+
/* Restores the pool of values. */
|
|
1896
|
+
set_value_pos(pos);
|
|
1897
|
+
/* Return the destination. */
|
|
1898
|
+
return dst;
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
|
|
1902
|
+
/** Computes the right shift of two general values.
|
|
1903
|
+
* @param src0 the first source value of the addition
|
|
1904
|
+
* @param src1 the second source value of the addition
|
|
1905
|
+
* @param dst the destination
|
|
1906
|
+
* @return dst */
|
|
1907
|
+
Value shift_right_value(Value src0, Value src1, Value dst) {
|
|
1908
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1909
|
+
unsigned int pos = get_value_pos();
|
|
1910
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1911
|
+
* computation. */
|
|
1912
|
+
if (src0->numeric) {
|
|
1913
|
+
if (src1->numeric) {
|
|
1914
|
+
/* Both sources are numeric. */
|
|
1915
|
+
return shift_right_value_numeric(src0,src1,dst);
|
|
1916
|
+
} else {
|
|
1917
|
+
/* src0 is numeric, convert it to bitstring. */
|
|
1918
|
+
src0 = set_bitstring_value(src1,get_value());
|
|
1919
|
+
}
|
|
1920
|
+
} else {
|
|
1921
|
+
/* src0 is not numeric, what about src1. */
|
|
1922
|
+
if (src1->numeric) {
|
|
1923
|
+
/* src0 is not numeric, but src1. */
|
|
1924
|
+
return shift_right_value_bitstring_numeric(src0,src1,dst);
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1928
|
+
dst = shift_right_value_bitstring(src0,src1,dst);
|
|
1929
|
+
/* Restores the pool of values. */
|
|
1930
|
+
set_value_pos(pos);
|
|
1931
|
+
/* Return the destination. */
|
|
1932
|
+
return dst;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
/** Computes the equal (!XOR) of two general values.
|
|
1937
|
+
* @param src0 the first source value of the addition
|
|
1938
|
+
* @param src1 the second source value of the addition
|
|
1939
|
+
* @param dst the destination value
|
|
1940
|
+
* @return the destination value */
|
|
1941
|
+
Value equal_value(Value src0, Value src1, Value dst) {
|
|
1942
|
+
/* Might allocate a new value so save the current pool state. */
|
|
1943
|
+
unsigned int pos = get_value_pos();
|
|
1944
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
|
1945
|
+
* computation. */
|
|
1946
|
+
if (src0->numeric) {
|
|
1947
|
+
if (src1->numeric) {
|
|
1948
|
+
/* Both sources are numeric. */
|
|
1949
|
+
return equal_value_numeric(src0,src1,dst);
|
|
1950
|
+
} else {
|
|
1951
|
+
/* src1 is not numeric, convert src0 to bitstring. */
|
|
1952
|
+
src0 = set_bitstring_value(src0,get_value());
|
|
1953
|
+
}
|
|
1954
|
+
} else {
|
|
1955
|
+
/* src0 is not numeric, what about src1. */
|
|
1956
|
+
if (src1->numeric) {
|
|
1957
|
+
/* src1 is numeric, convert it to bitstring. */
|
|
1958
|
+
src1 = set_bitstring_value(src1,get_value());
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1962
|
+
dst = equal_value_bitstring(src0,src1,dst);
|
|
1963
|
+
/* Restores the pool of values. */
|
|
1964
|
+
set_value_pos(pos);
|
|
1965
|
+
/* Return the destination. */
|
|
1966
|
+
return dst;
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
|
|
1970
|
+
/** Selects a value depending on a general condition.
|
|
1971
|
+
* @param cond the condition to use for selecting a value
|
|
1972
|
+
* @param dst the destination value (used only if new value is created).
|
|
1973
|
+
* @param num the number of values for the selection
|
|
1974
|
+
* @return the selected value */
|
|
1975
|
+
Value select_value(Value cond, Value dst, unsigned int num, ...) {
|
|
1976
|
+
va_list args;
|
|
1977
|
+
va_start(args,num);
|
|
1978
|
+
if (is_defined_value(cond)) {
|
|
1979
|
+
/* The condition can be made numeric. */
|
|
1980
|
+
dst = select_value_numeric(cond,dst,num,args);
|
|
1981
|
+
} else {
|
|
1982
|
+
/* The sources cannot be numeric, compute bitsitrings. */
|
|
1983
|
+
dst = select_value_bitstring(cond,dst,num,args);
|
|
1984
|
+
}
|
|
1985
|
+
va_end(args);
|
|
1986
|
+
return dst;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
/** Concat multiple general values to a single one.
|
|
1990
|
+
* @param dir the direction of the concatenation.
|
|
1991
|
+
* @param num the number of values to concat
|
|
1992
|
+
* @param dst the destination value
|
|
1993
|
+
* @return dst */
|
|
1994
|
+
Value concat_value(int num, int dir, Value dst, ...) {
|
|
1995
|
+
unsigned long long width = 0;
|
|
1996
|
+
int numeric = 1, i;
|
|
1997
|
+
va_list args;
|
|
1998
|
+
Value* values = alloca(num*sizeof(Value)); /* The values to concatenate. */
|
|
1999
|
+
va_start(args,dst);
|
|
2000
|
+
/* Copy the arguments to values for easier processing. */
|
|
2001
|
+
for(i=0; i<num; ++i) {
|
|
2002
|
+
values[i] = va_arg(args,Value);
|
|
2003
|
+
}
|
|
2004
|
+
/* check if all the sub values are numeric. */
|
|
2005
|
+
for(i=0; i<num; ++i) {
|
|
2006
|
+
if (!values[i]->numeric) {
|
|
2007
|
+
numeric = 0;
|
|
2008
|
+
break;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
/* Compute the resulting width to see if it first in a numeric. */
|
|
2012
|
+
if (numeric) {
|
|
2013
|
+
for(i = 0; i<num; ++i) {
|
|
2014
|
+
width += type_width(values[i]->type);
|
|
2015
|
+
}
|
|
2016
|
+
if (width > LONG_LONG_BIT) { numeric = 0; }
|
|
2017
|
+
}
|
|
2018
|
+
/* Reinitialize the access to the variadic arguments for further
|
|
2019
|
+
* accesses. */
|
|
2020
|
+
if (numeric) {
|
|
2021
|
+
/* The sub values are all numeric. */
|
|
2022
|
+
concat_value_numeric_array(num,dir,dst,values);
|
|
2023
|
+
} else {
|
|
2024
|
+
/* Cannot perfrom a numeric concatenation, do it for bitstrings. */
|
|
2025
|
+
/* First convert the numeric values to bitstrings. */
|
|
2026
|
+
for(i=0;i<num; ++i) {
|
|
2027
|
+
if (values[i]->numeric) {
|
|
2028
|
+
values[i] = set_bitstring_value(values[i],get_value());
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
/* The sub values are now all bitstrings. */
|
|
2033
|
+
concat_value_bitstring_array(num,dir,dst,values);
|
|
2034
|
+
}
|
|
2035
|
+
va_end(args);
|
|
2036
|
+
return dst;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
|
|
2040
|
+
/** Casts a value to another type.
|
|
2041
|
+
* @param src the source value
|
|
2042
|
+
* @param type the type to cast to
|
|
2043
|
+
* @param dst the destination value
|
|
2044
|
+
* @return dst */
|
|
2045
|
+
Value cast_value(Value src, Type type, Value dst) {
|
|
2046
|
+
if (src->numeric) {
|
|
2047
|
+
/* The source is numeric. */
|
|
2048
|
+
return cast_value_numeric(src,type,dst);
|
|
2049
|
+
} else {
|
|
2050
|
+
/* The source cannot be numeric, compute bitsitrings. */
|
|
2051
|
+
return cast_value_bitstring(src,type,dst);
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
|
|
2056
|
+
/** Testing if a general value is 0.
|
|
2057
|
+
* @param value the value to check
|
|
2058
|
+
* @return 1 if 0 and 0 otherwize */
|
|
2059
|
+
int zero_value(Value value) {
|
|
2060
|
+
if (value->numeric) {
|
|
2061
|
+
/* The value is numeric. */
|
|
2062
|
+
return zero_value_numeric(value);
|
|
2063
|
+
} else {
|
|
2064
|
+
/* The value cannot be reduced to numeric: cannot be 0. */
|
|
2065
|
+
return 0;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
|
|
2070
|
+
/** Testing if a value is defined or not.
|
|
2071
|
+
* @param value the value to check
|
|
2072
|
+
* @return 1 if defined and 0 otherwize */
|
|
2073
|
+
int is_defined_value(Value value) {
|
|
2074
|
+
if (value->numeric) {
|
|
2075
|
+
/* Numeric values are defined by definition. */
|
|
2076
|
+
return 1;
|
|
2077
|
+
} else {
|
|
2078
|
+
/* Ensures the value contains only '0' and '1'. */
|
|
2079
|
+
unsigned long long width = type_width(value->type);
|
|
2080
|
+
unsigned long long i;
|
|
2081
|
+
char* data = value->data_str;
|
|
2082
|
+
for(i=0; i<width; ++i) {
|
|
2083
|
+
char bit = data[i];
|
|
2084
|
+
if ((bit != '0') && (bit != '1')) {
|
|
2085
|
+
/* Not defined. */
|
|
2086
|
+
return 0;
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
/* Defined. */
|
|
2090
|
+
return 1;
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
|
|
2095
|
+
/** Testing if two general values have the same content (the type is not checked).
|
|
2096
|
+
* @param value0 the first value to compare
|
|
2097
|
+
* @param value1 the second value to compare
|
|
2098
|
+
* @return 1 if same content. */
|
|
2099
|
+
int same_content_value(Value value0, Value value1) {
|
|
2100
|
+
// printf("same_content_value with value0=%p value1=%p\n",value0,value1);
|
|
2101
|
+
// print_value(value0); printf(" "); print_value(value1); printf("\n");
|
|
2102
|
+
if (value0->numeric) {
|
|
2103
|
+
if (value1->numeric) {
|
|
2104
|
+
/* Both values are numeric. */
|
|
2105
|
+
return same_content_value_numeric(value0,value1);
|
|
2106
|
+
} else {
|
|
2107
|
+
/* One value is numeric, the othert is not, different. */
|
|
2108
|
+
return 0;
|
|
2109
|
+
}
|
|
2110
|
+
} else if (value1->numeric) {
|
|
2111
|
+
/* One value is numeric, the othert is not, different. */
|
|
2112
|
+
return 0;
|
|
2113
|
+
} else {
|
|
2114
|
+
/* Both values are bitstring. */
|
|
2115
|
+
return same_content_value_bitstring(value0,value1);
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
|
|
2120
|
+
/** Testing if two general values have the same content (the type is not checked).
|
|
2121
|
+
* @param value0 the first value to compare
|
|
2122
|
+
* @param first the first index of the range
|
|
2123
|
+
* @param last the last index of the range
|
|
2124
|
+
* @param value1 the second value to compare
|
|
2125
|
+
* @return 1 if same content. */
|
|
2126
|
+
int same_content_value_range(Value value0,
|
|
2127
|
+
unsigned long long first, unsigned long long last, Value value1) {
|
|
2128
|
+
if (value0->numeric) {
|
|
2129
|
+
if (value1->numeric) {
|
|
2130
|
+
/* Both values are numeric. */
|
|
2131
|
+
return same_content_value_range_numeric(value0,first,last,value1);
|
|
2132
|
+
} else {
|
|
2133
|
+
/* One value is numeric the other is not, different. */
|
|
2134
|
+
return 0;
|
|
2135
|
+
}
|
|
2136
|
+
} else if (value1->numeric) {
|
|
2137
|
+
/* One value is numeric, the other is not, different. */
|
|
2138
|
+
return 0;
|
|
2139
|
+
} else {
|
|
2140
|
+
/* Both values are bitstring. */
|
|
2141
|
+
return same_content_value_range_bitstring(value0,first,last,value1);
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
|
|
2146
|
+
/* ############# End of the computation of general values. ################ */
|
|
2147
|
+
|
|
2148
|
+
|
|
2149
|
+
|
|
2150
|
+
|
|
2151
|
+
|
|
2152
|
+
/** Creates a reference to a range inside a signal.
|
|
2153
|
+
* @param signal the signal to refer
|
|
2154
|
+
* @param first the start index of the range
|
|
2155
|
+
* @param last the end index of the range
|
|
2156
|
+
* @return the resulting reference */
|
|
2157
|
+
RefRangeS make_ref_rangeS(SignalI signal, unsigned long long first,
|
|
2158
|
+
unsigned long long last) {
|
|
2159
|
+
RefRangeS result = { signal, first, last };
|
|
2160
|
+
return result;
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
|
|
2164
|
+
|
|
2165
|
+
|
|
2166
|
+
|
|
2167
|
+
|
|
2168
|
+
/* Access and conversion functions. */
|
|
2169
|
+
|
|
2170
|
+
// /** Read and convert to 8-bit a value.
|
|
2171
|
+
// * @param value the value to read
|
|
2172
|
+
// * @return the resulting 8-bit value */
|
|
2173
|
+
// char read8(Value value) {
|
|
2174
|
+
// return value->data[0] & 0xFF;
|
|
2175
|
+
// }
|
|
2176
|
+
//
|
|
2177
|
+
// /** Read and convert to 16-bit a value.
|
|
2178
|
+
// * @param value the value to read
|
|
2179
|
+
// * @return the resulting 16-bit value */
|
|
2180
|
+
// short read16(Value value) {
|
|
2181
|
+
// return value->data[0] & 0xFFFF;
|
|
2182
|
+
// }
|
|
2183
|
+
//
|
|
2184
|
+
// /** Read and convert to 32-bit a value.
|
|
2185
|
+
// * @param value the value to read
|
|
2186
|
+
// * @return the resulting 32-bit value */
|
|
2187
|
+
// int read32(Value value) {
|
|
2188
|
+
// return value->data[0] & 0xFFFFFFFF;
|
|
2189
|
+
// }
|
|
2190
|
+
//
|
|
2191
|
+
// /** Read and convert to 64-bit a value.
|
|
2192
|
+
// * @param value the value to read
|
|
2193
|
+
// * @return the resulting 64-bit value */
|
|
2194
|
+
// long long read64(Value value) {
|
|
2195
|
+
// return value->data[0];
|
|
2196
|
+
// }
|
|
2197
|
+
|
|
2198
|
+
/** Converts a value to a long long int.
|
|
2199
|
+
* @param value the value to convert
|
|
2200
|
+
* @return the resulting int. */
|
|
2201
|
+
unsigned long long value2integer(Value value) {
|
|
2202
|
+
/* If the value is numeric, just return its data as is. */
|
|
2203
|
+
if (value->numeric) {
|
|
2204
|
+
return value->data_int;
|
|
2205
|
+
}
|
|
2206
|
+
/* Otherwise convert the bitstring to an integer if possible,
|
|
2207
|
+
* but return 0 in case of failure. */
|
|
2208
|
+
/* Gets the width of the value. */
|
|
2209
|
+
unsigned long long width = type_width(value->type);
|
|
2210
|
+
unsigned long long res = 0;
|
|
2211
|
+
unsigned long long i;
|
|
2212
|
+
char bit;
|
|
2213
|
+
/* Access the bitstring data. */
|
|
2214
|
+
char* data_str = value->data_str;
|
|
2215
|
+
/* Copy the bits. */
|
|
2216
|
+
for (i=0; i<width && i<LONG_LONG_BIT; ++i) {
|
|
2217
|
+
/* Get the bit. */
|
|
2218
|
+
bit = data_str[width-i-1]-'0';
|
|
2219
|
+
if ((bit != 0) && (bit != 1)) {
|
|
2220
|
+
/* Cannot convert, return 0. */
|
|
2221
|
+
return 0;
|
|
2222
|
+
}
|
|
2223
|
+
/* Write the bit. */
|
|
2224
|
+
res = (res << 1) | bit;
|
|
2225
|
+
}
|
|
2226
|
+
/* Perform the sign extension if required. */
|
|
2227
|
+
if (i>=width && value->type->flags.sign) {
|
|
2228
|
+
for(; i<LONG_LONG_BIT; ++i) {
|
|
2229
|
+
res = (res << 1) | bit;
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
return res;
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
/** Reads a range from a value.
|
|
2236
|
+
* @param value the value to read
|
|
2237
|
+
* @param first the first index of the range
|
|
2238
|
+
* @param last the last index of the range
|
|
2239
|
+
* @param base the type of the elements
|
|
2240
|
+
* @param dst the destination value
|
|
2241
|
+
* @return dst */
|
|
2242
|
+
Value read_range(Value value, long long first, long long last, Type base,
|
|
2243
|
+
Value dst) {
|
|
2244
|
+
/* Is the value numeric? */
|
|
2245
|
+
if (value->numeric) {
|
|
2246
|
+
/* Yes, do a numeric range read. */
|
|
2247
|
+
return read_range_numeric(value,first,last,base,dst);
|
|
2248
|
+
} else {
|
|
2249
|
+
/* No, do a bitstring range read. */
|
|
2250
|
+
return read_range_bitstring(value,first,last,base,dst);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
|
|
2255
|
+
// /** Writes 8 bits to a value
|
|
2256
|
+
// * @param data the data to write
|
|
2257
|
+
// * @param value the target value */
|
|
2258
|
+
// void write8(char data, Value value) {
|
|
2259
|
+
// /* Get the actual target value from: it should be the future value
|
|
2260
|
+
// * (f_value) is case it is a signal value. */
|
|
2261
|
+
// SignalI signal = value->signal;
|
|
2262
|
+
// if (signal) value = signal->f_value;
|
|
2263
|
+
// /* Sets the value. */
|
|
2264
|
+
// value->data[0] = (value->data[0] & 0xFFFFFFFFFFFFFF00ULL) | data;
|
|
2265
|
+
// /* Touch the corresponding signal (if any). */
|
|
2266
|
+
// if (signal) touch_signal(signal);
|
|
2267
|
+
// }
|
|
2268
|
+
//
|
|
2269
|
+
// /** Writes 16 bits to a value
|
|
2270
|
+
// * @param data the data to write
|
|
2271
|
+
// * @param value the target value */
|
|
2272
|
+
// void write16(short data, Value value) {
|
|
2273
|
+
// /* Get the actual target value from: it should be the future value
|
|
2274
|
+
// * (f_value) is case it is a signal value. */
|
|
2275
|
+
// SignalI signal = value->signal;
|
|
2276
|
+
// if (signal) value = signal->f_value;
|
|
2277
|
+
// /* Sets the value. */
|
|
2278
|
+
// value->data[0] = (value->data[0] & 0xFFFFFFFFFFFF0000ULL) | data;
|
|
2279
|
+
// /* Touch the corresponding signal (if any). */
|
|
2280
|
+
// if (signal) touch_signal(signal);
|
|
2281
|
+
// }
|
|
2282
|
+
//
|
|
2283
|
+
// /** Writes 32 bits to a value
|
|
2284
|
+
// * @param data the data to write
|
|
2285
|
+
// * @param value the target value */
|
|
2286
|
+
// void write32(int data, Value value) {
|
|
2287
|
+
// /* Get the actual target value from: it should be the future value
|
|
2288
|
+
// * (f_value) is case it is a signal value. */
|
|
2289
|
+
// SignalI signal = value->signal;
|
|
2290
|
+
// if (signal) value = signal->f_value;
|
|
2291
|
+
// /* Sets the value. */
|
|
2292
|
+
// value->data[0] = (value->data[0] & 0xFFFFFFFF00000000ULL) | data;
|
|
2293
|
+
// /* Touch the corresponding signal (if any). */
|
|
2294
|
+
// if (signal) touch_signal(signal);
|
|
2295
|
+
// }
|
|
2296
|
+
//
|
|
2297
|
+
// /** Writes 64 bits to a value
|
|
2298
|
+
// * @param data the data to write
|
|
2299
|
+
// * @param value the target value */
|
|
2300
|
+
// void write64(long long data, Value value) {
|
|
2301
|
+
// /* Get the actual target value from: it should be the future value
|
|
2302
|
+
// * (f_value) is case it is a signal value. */
|
|
2303
|
+
// SignalI signal = value->signal;
|
|
2304
|
+
// if (signal) value = signal->f_value;
|
|
2305
|
+
// /* Sets the value. */
|
|
2306
|
+
// value->data[0] = data;
|
|
2307
|
+
// /* Touch the corresponding signal (if any). */
|
|
2308
|
+
// if (signal) touch_signal(signal);
|
|
2309
|
+
// }
|
|
2310
|
+
|
|
2311
|
+
/** Writes to a range within a value.
|
|
2312
|
+
* NOTE: the type of the destination is NOT changed!
|
|
2313
|
+
* @param src the source value
|
|
2314
|
+
* @param first the first index of the range
|
|
2315
|
+
* @param last the last index of the range
|
|
2316
|
+
* @param dst the destination value
|
|
2317
|
+
* @return dst */
|
|
2318
|
+
Value write_range(Value src, long long first, long long last, Value dst) {
|
|
2319
|
+
/* Is the value numeric? */
|
|
2320
|
+
if ((src->numeric) && (dst->numeric)) {
|
|
2321
|
+
/* Yes, do a numeric range read. */
|
|
2322
|
+
return write_range_numeric(src,first,last,dst);
|
|
2323
|
+
} else {
|
|
2324
|
+
/* No, do a bitstring range read. */
|
|
2325
|
+
if (dst->numeric) {
|
|
2326
|
+
/* Need to convert the destination to a bitstring. */
|
|
2327
|
+
dst = set_bitstring_value(dst,get_value());
|
|
2328
|
+
} else if (src->numeric) {
|
|
2329
|
+
/* Need to convert the source to a bitstring. */
|
|
2330
|
+
src = set_bitstring_value(src,get_value());
|
|
2331
|
+
}
|
|
2332
|
+
return write_range_bitstring(src,first,last,dst);
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
/** Writes to a range within a value without overwriting with Z.
|
|
2337
|
+
* NOTE: the type of the destination is NOT changed!
|
|
2338
|
+
* @param src the source value
|
|
2339
|
+
* @param first the first index of the range
|
|
2340
|
+
* @param last the last index of the range
|
|
2341
|
+
* @param dst the destination value
|
|
2342
|
+
* @return dst */
|
|
2343
|
+
Value write_range_no_z(Value src, long long first, long long last, Value dst) {
|
|
2344
|
+
/* Is the value numeric? */
|
|
2345
|
+
if ((src->numeric) && (dst->numeric)) {
|
|
2346
|
+
/* Yes, do a numeric range read. */
|
|
2347
|
+
return write_range_numeric(src,first,last,dst);
|
|
2348
|
+
} else {
|
|
2349
|
+
/* No, do a bitstring range read. */
|
|
2350
|
+
if (dst->numeric) {
|
|
2351
|
+
/* Need to convert the destination to a bitstring. */
|
|
2352
|
+
dst = set_bitstring_value(dst,get_value());
|
|
2353
|
+
} else if (src->numeric) {
|
|
2354
|
+
/* Need to convert the source to a bitstring. */
|
|
2355
|
+
src = set_bitstring_value(src,get_value());
|
|
2356
|
+
}
|
|
2357
|
+
return write_range_bitstring_no_z(src,first,last,dst);
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
|
|
2362
|
+
|