HDLRuby 2.0.8

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