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.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. 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
+