1 /* pk-val.c - poke values. */
2
3 /* Copyright (C) 2020, 2021 Jose E. Marchesi */
4
5 /* This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <config.h>
20
21 #include "pvm.h"
22 #include "pvm-val.h"
23 #include "libpoke.h"
24
25 pk_val
pk_make_int(int64_t value,int size)26 pk_make_int (int64_t value, int size)
27 {
28 pk_val new;
29
30 /* At the moment poke integers are limited to a maximum number of
31 bits. */
32 if (size > 64)
33 return PK_NULL;
34
35 if (size <= 32)
36 new = pvm_make_int (value, size);
37 else
38 new = pvm_make_long (value, size);
39
40 return new;
41 }
42
43 int64_t
pk_int_value(pk_val val)44 pk_int_value (pk_val val)
45 {
46 if (PVM_IS_INT (val))
47 return PVM_VAL_INT (val);
48 else
49 return PVM_VAL_LONG (val);
50 }
51
52 int
pk_int_size(pk_val val)53 pk_int_size (pk_val val)
54 {
55 if (PVM_IS_INT (val))
56 return PVM_VAL_INT_SIZE (val);
57 else
58 return PVM_VAL_LONG_SIZE (val);
59 }
60
61 pk_val
pk_make_uint(uint64_t value,int size)62 pk_make_uint (uint64_t value, int size)
63 {
64 pk_val new;
65
66 /* At the moment poke integers are limited to a maximum number of
67 bits. */
68 if (size > 64)
69 return PK_NULL;
70
71 if (size <= 32)
72 new = pvm_make_uint (value, size);
73 else
74 new = pvm_make_ulong (value, size);
75
76 return new;
77 }
78
79 uint64_t
pk_uint_value(pk_val val)80 pk_uint_value (pk_val val)
81 {
82 if (PVM_IS_UINT (val))
83 return PVM_VAL_UINT (val);
84 else
85 return PVM_VAL_ULONG (val);
86 }
87
88 int
pk_uint_size(pk_val val)89 pk_uint_size (pk_val val)
90 {
91 if (PVM_IS_UINT (val))
92 return PVM_VAL_UINT_SIZE (val);
93 else
94 return PVM_VAL_ULONG_SIZE (val);
95 }
96
97 pk_val
pk_make_string(const char * str)98 pk_make_string (const char *str)
99 {
100 return pvm_make_string (str);
101 }
102
103 const char *
pk_string_str(pk_val val)104 pk_string_str (pk_val val)
105 {
106 return PVM_VAL_STR (val);
107 }
108
109 pk_val
pk_make_offset(pk_val magnitude,pk_val unit)110 pk_make_offset (pk_val magnitude, pk_val unit)
111 {
112 if (!PVM_IS_INTEGRAL (magnitude)
113 || !PVM_IS_ULONG (unit)
114 || PVM_VAL_ULONG (unit) == 0
115 || PVM_VAL_ULONG_SIZE (unit) != 64)
116 return PK_NULL;
117 else
118 return pvm_make_offset (magnitude, unit);
119 }
120
121 pk_val
pk_offset_magnitude(pk_val val)122 pk_offset_magnitude (pk_val val)
123 {
124 return PVM_VAL_OFF_MAGNITUDE (val);
125 }
126
127 pk_val
pk_offset_unit(pk_val val)128 pk_offset_unit (pk_val val)
129 {
130 return PVM_VAL_OFF_UNIT (val);
131 }
132
133 int
pk_val_mapped_p(pk_val val)134 pk_val_mapped_p (pk_val val)
135 {
136 return PVM_VAL_MAPPED_P (val);
137 }
138
139 pk_val
pk_val_ios(pk_val val)140 pk_val_ios (pk_val val)
141 {
142 return PVM_VAL_IOS (val);
143 }
144
145 pk_val
pk_val_offset(pk_val val)146 pk_val_offset (pk_val val)
147 {
148 /* The offset in the PVM value is a bit-offset. Convert to a proper
149 offset. */
150 uint64_t bit_offset = PVM_VAL_ULONG (PVM_VAL_OFFSET (val));
151
152 /* XXX "upunit" properly so we get a nice unit, not just bytes or
153 bits. */
154 if (bit_offset % 8 == 0)
155 return pvm_make_offset (pvm_make_ulong (bit_offset / 8, 64),
156 pvm_make_ulong (8, 32));
157 else
158 return pvm_make_offset (PVM_VAL_OFFSET (val),
159 pvm_make_ulong (1, 32));
160 }
161
162 int
pk_type_code(pk_val val)163 pk_type_code (pk_val val)
164 {
165 switch (PVM_VAL_TYP_CODE (val))
166 {
167 case PVM_TYPE_INTEGRAL:
168 if ((pk_int_value (pk_integral_type_signed_p (val))))
169 return PK_INT;
170 else
171 return PK_UINT;
172 case PVM_TYPE_STRING:
173 return PK_STRING;
174 case PVM_TYPE_ARRAY:
175 return PK_ARRAY;
176 case PVM_TYPE_STRUCT:
177 return PK_STRUCT;
178 case PVM_TYPE_OFFSET:
179 return PK_OFFSET;
180 case PVM_TYPE_CLOSURE:
181 return PK_CLOSURE;
182 case PVM_TYPE_ANY:
183 return PK_ANY;
184 default:
185 return PK_UNKNOWN;
186 }
187 }
188
189 int
pk_val_equal_p(pk_val val1,pk_val val2)190 pk_val_equal_p (pk_val val1, pk_val val2)
191 {
192 return pvm_val_equal_p (val1, val2);
193 }
194
195 pk_val
pk_make_struct(pk_val nfields,pk_val type)196 pk_make_struct (pk_val nfields, pk_val type)
197 {
198 return pvm_make_struct (nfields, pvm_make_ulong (0, 64), type);
199 }
200
201 pk_val
pk_struct_nfields(pk_val sct)202 pk_struct_nfields (pk_val sct)
203 {
204 return PVM_VAL_SCT_NFIELDS (sct);
205 }
206
pk_struct_field_boffset(pk_val sct,uint64_t idx)207 pk_val pk_struct_field_boffset (pk_val sct, uint64_t idx)
208 {
209 if (idx < pk_uint_value (pk_struct_nfields (sct)))
210 return PVM_VAL_SCT_FIELD_OFFSET (sct, idx);
211 else
212 return PK_NULL;
213 }
214
pk_struct_set_field_boffset(pk_val sct,uint64_t idx,pk_val boffset)215 void pk_struct_set_field_boffset (pk_val sct, uint64_t idx, pk_val boffset)
216 {
217 if (idx < pk_uint_value (pk_struct_nfields (sct)))
218 PVM_VAL_SCT_FIELD_OFFSET (sct, idx) = boffset;
219 }
220
pk_struct_field_name(pk_val sct,uint64_t idx)221 pk_val pk_struct_field_name (pk_val sct, uint64_t idx)
222 {
223 if (idx < pk_uint_value (pk_struct_nfields (sct)))
224 return PVM_VAL_SCT_FIELD_NAME (sct, idx);
225 else
226 return PK_NULL;
227 }
228
pk_struct_set_field_name(pk_val sct,uint64_t idx,pk_val name)229 void pk_struct_set_field_name (pk_val sct, uint64_t idx, pk_val name)
230 {
231 if (idx < pk_uint_value (pk_struct_nfields (sct)))
232 PVM_VAL_SCT_FIELD_NAME (sct, idx) = name;
233 }
234
pk_struct_field_value(pk_val sct,uint64_t idx)235 pk_val pk_struct_field_value (pk_val sct, uint64_t idx)
236 {
237 if (idx < pk_uint_value (pk_struct_nfields (sct)))
238 return PVM_VAL_SCT_FIELD_VALUE (sct, idx);
239 else
240 return PK_NULL;
241 }
242
pk_struct_set_field_value(pk_val sct,uint64_t idx,pk_val value)243 void pk_struct_set_field_value (pk_val sct, uint64_t idx, pk_val value)
244 {
245 if (idx < pk_uint_value (pk_struct_nfields (sct)))
246 PVM_VAL_SCT_FIELD_VALUE (sct, idx) = value;
247 }
248
249 pk_val
pk_make_array(pk_val nelem,pk_val array_type)250 pk_make_array (pk_val nelem, pk_val array_type)
251 {
252 return pvm_make_array (nelem, array_type);
253 }
254
255 pk_val
pk_make_integral_type(pk_val size,pk_val signed_p)256 pk_make_integral_type (pk_val size, pk_val signed_p)
257 {
258 return pvm_make_integral_type (size, signed_p);
259 }
260
261 pk_val
pk_integral_type_size(pk_val type)262 pk_integral_type_size (pk_val type)
263 {
264 return PVM_VAL_TYP_I_SIZE (type);
265 }
266
267 pk_val
pk_integral_type_signed_p(pk_val type)268 pk_integral_type_signed_p (pk_val type)
269 {
270 return PVM_VAL_TYP_I_SIGNED_P (type);
271 }
272
273 pk_val
pk_make_string_type(void)274 pk_make_string_type (void)
275 {
276 return pvm_make_string_type ();
277 }
278
279 pk_val
pk_make_offset_type(pk_val base_type,pk_val unit)280 pk_make_offset_type (pk_val base_type, pk_val unit)
281 {
282 return pvm_make_offset_type (base_type, unit);
283 }
284
285 pk_val
pk_offset_type_base_type(pk_val type)286 pk_offset_type_base_type (pk_val type)
287 {
288 return PVM_VAL_TYP_O_BASE_TYPE (type);
289 }
290
291 pk_val
pk_offset_type_unit(pk_val type)292 pk_offset_type_unit (pk_val type)
293 {
294 return PVM_VAL_TYP_O_UNIT (type);
295 }
296
297 pk_val
pk_make_any_type(void)298 pk_make_any_type (void)
299 {
300 return pvm_make_any_type ();
301 }
302
303 pk_val
pk_make_struct_type(pk_val nfields,pk_val name,pk_val * fnames,pk_val * ftypes)304 pk_make_struct_type (pk_val nfields, pk_val name, pk_val *fnames, pk_val *ftypes)
305 {
306 return pvm_make_struct_type (nfields, name, fnames, ftypes);
307 }
308
309 pk_val
pk_struct_type(pk_val sct)310 pk_struct_type (pk_val sct)
311 {
312 return PVM_VAL_SCT_TYPE (sct);
313 }
314
315 void
pk_allocate_struct_attrs(pk_val nfields,pk_val ** fnames,pk_val ** ftypes)316 pk_allocate_struct_attrs (pk_val nfields, pk_val **fnames, pk_val **ftypes)
317 {
318 pvm_allocate_struct_attrs (nfields, fnames, ftypes);
319 }
320
321 pk_val
pk_struct_type_name(pk_val type)322 pk_struct_type_name (pk_val type)
323 {
324 return PVM_VAL_TYP_S_NAME (type);
325 }
326
327 pk_val
pk_struct_type_nfields(pk_val type)328 pk_struct_type_nfields (pk_val type)
329 {
330 return PVM_VAL_TYP_S_NFIELDS (type);
331 }
332
333 pk_val
pk_struct_type_fname(pk_val type,uint64_t idx)334 pk_struct_type_fname (pk_val type, uint64_t idx)
335 {
336 if (idx < pk_uint_value (pk_struct_type_nfields (type)))
337 return PVM_VAL_TYP_S_FNAME (type, idx);
338 else
339 return PK_NULL;
340 }
341
342 void
pk_struct_type_set_fname(pk_val type,uint64_t idx,pk_val field_name)343 pk_struct_type_set_fname (pk_val type, uint64_t idx, pk_val field_name)
344 {
345 if (idx < pk_uint_value (pk_struct_type_nfields (type)))
346 PVM_VAL_TYP_S_FNAME (type, idx) = field_name;
347 }
348
349 pk_val
pk_struct_type_ftype(pk_val type,uint64_t idx)350 pk_struct_type_ftype (pk_val type, uint64_t idx)
351 {
352 if (idx < pk_uint_value (pk_struct_type_nfields (type)))
353 return PVM_VAL_TYP_S_FTYPE (type, idx);
354 else
355 return PK_NULL;
356 }
357
358 void
pk_struct_type_set_ftype(pk_val type,uint64_t idx,pk_val field_type)359 pk_struct_type_set_ftype (pk_val type, uint64_t idx, pk_val field_type)
360 {
361 if (idx < pk_uint_value (pk_struct_type_nfields (type)))
362 PVM_VAL_TYP_S_FTYPE (type, idx) = field_type;
363 }
364
365 pk_val
pk_make_array_type(pk_val etype,pk_val bound)366 pk_make_array_type (pk_val etype, pk_val bound)
367 {
368 return pvm_make_array_type (etype, bound);
369 }
370
371 pk_val
pk_array_type_etype(pk_val type)372 pk_array_type_etype (pk_val type)
373 {
374 return PVM_VAL_TYP_A_ETYPE (type);
375 }
376
377 pk_val
pk_array_type_bound(pk_val type)378 pk_array_type_bound (pk_val type)
379 {
380 return PVM_VAL_TYP_A_BOUND (type);
381 }
382
383 pk_val
pk_typeof(pk_val val)384 pk_typeof (pk_val val)
385 {
386 return pvm_typeof (val);
387 }
388
389 pk_val
pk_array_nelem(pk_val array)390 pk_array_nelem (pk_val array)
391 {
392 return PVM_VAL_ARR_NELEM (array);
393 }
394
395 pk_val
pk_array_elem_val(pk_val array,uint64_t idx)396 pk_array_elem_val (pk_val array, uint64_t idx)
397 {
398 if (idx < pk_uint_value (pk_array_nelem (array)))
399 return PVM_VAL_ARR_ELEM_VALUE (array, idx);
400 else
401 return PK_NULL;
402 }
403
404 void
pk_array_insert_elem(pk_val array,uint64_t idx,pk_val val)405 pk_array_insert_elem (pk_val array, uint64_t idx, pk_val val)
406 {
407 (void) pvm_array_insert (array, pvm_make_ulong (idx, 64), val);
408 }
409
410 void
pk_array_set_elem(pk_val array,uint64_t idx,pk_val val)411 pk_array_set_elem (pk_val array, uint64_t idx, pk_val val)
412 {
413 (void) pvm_array_set (array, pvm_make_ulong (idx, 64), val);
414 }
415
416 pk_val
pk_array_elem_boffset(pk_val array,uint64_t idx)417 pk_array_elem_boffset (pk_val array, uint64_t idx)
418 {
419 if (idx < pk_uint_value (pk_array_nelem (array)))
420 return PVM_VAL_ARR_ELEM_OFFSET (array, idx);
421 else
422 return PK_NULL;
423 }
424
425 void
pk_array_set_elem_boffset(pk_val array,uint64_t idx,pk_val boffset)426 pk_array_set_elem_boffset (pk_val array, uint64_t idx, pk_val boffset)
427 {
428 if (idx < pk_uint_value (pk_array_nelem (array)))
429 PVM_VAL_ARR_ELEM_OFFSET (array, idx) = boffset;
430 }
431