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