1 /*
2 * Integer number functions.
3 *
4 * Copyright (C) 2001-2007 Peter Johnson
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include "util.h"
28
29 #include <ctype.h>
30 #include <limits.h>
31
32 #include "coretype.h"
33 #include "bitvect.h"
34 #include "file.h"
35
36 #include "errwarn.h"
37 #include "intnum.h"
38
39
40 /* "Native" "word" size for intnum calculations. */
41 #define BITVECT_NATIVE_SIZE 256
42
43 struct yasm_intnum {
44 union val {
45 long l; /* integer value (for integers <32 bits) */
46 wordptr bv; /* bit vector (for integers >=32 bits) */
47 } val;
48 enum { INTNUM_L, INTNUM_BV } type;
49 };
50
51 /* static bitvect used for conversions */
52 static /*@only@*/ wordptr conv_bv;
53
54 /* static bitvects used for computation */
55 static /*@only@*/ wordptr result, spare, op1static, op2static;
56
57 static /*@only@*/ BitVector_from_Dec_static_data *from_dec_data;
58
59
60 void
yasm_intnum_initialize(void)61 yasm_intnum_initialize(void)
62 {
63 conv_bv = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
64 result = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
65 spare = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
66 op1static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
67 op2static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
68 from_dec_data = BitVector_from_Dec_static_Boot(BITVECT_NATIVE_SIZE);
69 }
70
71 void
yasm_intnum_cleanup(void)72 yasm_intnum_cleanup(void)
73 {
74 BitVector_from_Dec_static_Shutdown(from_dec_data);
75 BitVector_Destroy(op2static);
76 BitVector_Destroy(op1static);
77 BitVector_Destroy(spare);
78 BitVector_Destroy(result);
79 BitVector_Destroy(conv_bv);
80 }
81
82 /* Compress a bitvector into intnum storage.
83 * If saved as a bitvector, clones the passed bitvector.
84 * Can modify the passed bitvector.
85 */
86 static void
intnum_frombv(yasm_intnum * intn,wordptr bv)87 intnum_frombv(/*@out@*/ yasm_intnum *intn, wordptr bv)
88 {
89 if (Set_Max(bv) < 31) {
90 intn->type = INTNUM_L;
91 intn->val.l = (long)BitVector_Chunk_Read(bv, 31, 0);
92 } else if (BitVector_msb_(bv)) {
93 /* Negative, negate and see if we'll fit into a long. */
94 unsigned long ul;
95 BitVector_Negate(bv, bv);
96 if (Set_Max(bv) >= 32 ||
97 ((ul = BitVector_Chunk_Read(bv, 32, 0)) & 0x80000000)) {
98 /* too negative */
99 BitVector_Negate(bv, bv);
100 intn->type = INTNUM_BV;
101 intn->val.bv = BitVector_Clone(bv);
102 } else {
103 intn->type = INTNUM_L;
104 intn->val.l = -((long)ul);
105 }
106 } else {
107 intn->type = INTNUM_BV;
108 intn->val.bv = BitVector_Clone(bv);
109 }
110 }
111
112 /* If intnum is a BV, returns its bitvector directly.
113 * If not, converts into passed bv and returns that instead.
114 */
115 static wordptr
intnum_tobv(wordptr bv,const yasm_intnum * intn)116 intnum_tobv(/*@returned@*/ wordptr bv, const yasm_intnum *intn)
117 {
118 if (intn->type == INTNUM_BV)
119 return intn->val.bv;
120
121 BitVector_Empty(bv);
122 if (intn->val.l >= 0)
123 BitVector_Chunk_Store(bv, 32, 0, (unsigned long)intn->val.l);
124 else {
125 BitVector_Chunk_Store(bv, 32, 0, (unsigned long)-intn->val.l);
126 BitVector_Negate(bv, bv);
127 }
128 return bv;
129 }
130
131 yasm_intnum *
yasm_intnum_create_dec(char * str)132 yasm_intnum_create_dec(char *str)
133 {
134 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
135
136 switch (BitVector_from_Dec_static(from_dec_data, conv_bv,
137 (unsigned char *)str)) {
138 case ErrCode_Pars:
139 yasm_error_set(YASM_ERROR_VALUE, N_("invalid decimal literal"));
140 break;
141 case ErrCode_Ovfl:
142 yasm_error_set(YASM_ERROR_OVERFLOW,
143 N_("Numeric constant too large for internal format"));
144 break;
145 default:
146 break;
147 }
148 intnum_frombv(intn, conv_bv);
149 return intn;
150 }
151
152 yasm_intnum *
yasm_intnum_create_bin(char * str)153 yasm_intnum_create_bin(char *str)
154 {
155 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
156
157 switch (BitVector_from_Bin(conv_bv, (unsigned char *)str)) {
158 case ErrCode_Pars:
159 yasm_error_set(YASM_ERROR_VALUE, N_("invalid binary literal"));
160 break;
161 case ErrCode_Ovfl:
162 yasm_error_set(YASM_ERROR_OVERFLOW,
163 N_("Numeric constant too large for internal format"));
164 break;
165 default:
166 break;
167 }
168 intnum_frombv(intn, conv_bv);
169 return intn;
170 }
171
172 yasm_intnum *
yasm_intnum_create_oct(char * str)173 yasm_intnum_create_oct(char *str)
174 {
175 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
176
177 switch (BitVector_from_Oct(conv_bv, (unsigned char *)str)) {
178 case ErrCode_Pars:
179 yasm_error_set(YASM_ERROR_VALUE, N_("invalid octal literal"));
180 break;
181 case ErrCode_Ovfl:
182 yasm_error_set(YASM_ERROR_OVERFLOW,
183 N_("Numeric constant too large for internal format"));
184 break;
185 default:
186 break;
187 }
188 intnum_frombv(intn, conv_bv);
189 return intn;
190 }
191
192 yasm_intnum *
yasm_intnum_create_hex(char * str)193 yasm_intnum_create_hex(char *str)
194 {
195 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
196
197 switch (BitVector_from_Hex(conv_bv, (unsigned char *)str)) {
198 case ErrCode_Pars:
199 yasm_error_set(YASM_ERROR_VALUE, N_("invalid hex literal"));
200 break;
201 case ErrCode_Ovfl:
202 yasm_error_set(YASM_ERROR_OVERFLOW,
203 N_("Numeric constant too large for internal format"));
204 break;
205 default:
206 break;
207 }
208 intnum_frombv(intn, conv_bv);
209 return intn;
210 }
211
212 /*@-usedef -compdef -uniondef@*/
213 yasm_intnum *
yasm_intnum_create_charconst_nasm(const char * str)214 yasm_intnum_create_charconst_nasm(const char *str)
215 {
216 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
217 size_t len = strlen(str);
218
219 if(len*8 > BITVECT_NATIVE_SIZE)
220 yasm_error_set(YASM_ERROR_OVERFLOW,
221 N_("Character constant too large for internal format"));
222
223 /* be conservative in choosing bitvect in case MSB is set */
224 if (len > 3) {
225 BitVector_Empty(conv_bv);
226 intn->type = INTNUM_BV;
227 } else {
228 intn->val.l = 0;
229 intn->type = INTNUM_L;
230 }
231
232 switch (len) {
233 case 3:
234 intn->val.l |= ((unsigned long)str[2]) & 0xff;
235 intn->val.l <<= 8;
236 /*@fallthrough@*/
237 case 2:
238 intn->val.l |= ((unsigned long)str[1]) & 0xff;
239 intn->val.l <<= 8;
240 /*@fallthrough@*/
241 case 1:
242 intn->val.l |= ((unsigned long)str[0]) & 0xff;
243 case 0:
244 break;
245 default:
246 /* >=32 bit conversion */
247 while (len) {
248 BitVector_Move_Left(conv_bv, 8);
249 BitVector_Chunk_Store(conv_bv, 8, 0,
250 ((unsigned long)str[--len]) & 0xff);
251 }
252 intn->val.bv = BitVector_Clone(conv_bv);
253 }
254
255 return intn;
256 }
257
258 yasm_intnum *
yasm_intnum_create_charconst_tasm(const char * str)259 yasm_intnum_create_charconst_tasm(const char *str)
260 {
261 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
262 size_t len = strlen(str);
263 size_t i;
264
265 if(len*8 > BITVECT_NATIVE_SIZE)
266 yasm_error_set(YASM_ERROR_OVERFLOW,
267 N_("Character constant too large for internal format"));
268
269 /* be conservative in choosing bitvect in case MSB is set */
270 if (len > 3) {
271 BitVector_Empty(conv_bv);
272 intn->type = INTNUM_BV;
273 } else {
274 intn->val.l = 0;
275 intn->type = INTNUM_L;
276 }
277
278 /* tasm uses big endian notation */
279 i = 0;
280 switch (len) {
281 case 3:
282 intn->val.l |= ((unsigned long)str[i++]) & 0xff;
283 intn->val.l <<= 8;
284 /*@fallthrough@*/
285 case 2:
286 intn->val.l |= ((unsigned long)str[i++]) & 0xff;
287 intn->val.l <<= 8;
288 /*@fallthrough@*/
289 case 1:
290 intn->val.l |= ((unsigned long)str[i++]) & 0xff;
291 case 0:
292 break;
293 default:
294 /* >=32 bit conversion */
295 while (i < len) {
296 BitVector_Chunk_Store(conv_bv, 8, (len-i-1)*8,
297 ((unsigned long)str[i]) & 0xff);
298 i++;
299 }
300 intn->val.bv = BitVector_Clone(conv_bv);
301 }
302
303 return intn;
304 }
305 /*@=usedef =compdef =uniondef@*/
306
307 yasm_intnum *
yasm_intnum_create_uint(unsigned long i)308 yasm_intnum_create_uint(unsigned long i)
309 {
310 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
311
312 if (i > LONG_MAX) {
313 /* Too big, store as bitvector */
314 intn->val.bv = BitVector_Create(BITVECT_NATIVE_SIZE, TRUE);
315 intn->type = INTNUM_BV;
316 BitVector_Chunk_Store(intn->val.bv, 32, 0, i);
317 } else {
318 intn->val.l = (long)i;
319 intn->type = INTNUM_L;
320 }
321
322 return intn;
323 }
324
325 yasm_intnum *
yasm_intnum_create_int(long i)326 yasm_intnum_create_int(long i)
327 {
328 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
329
330 intn->val.l = i;
331 intn->type = INTNUM_L;
332
333 return intn;
334 }
335
336 yasm_intnum *
yasm_intnum_create_leb128(const unsigned char * ptr,int sign,unsigned long * size)337 yasm_intnum_create_leb128(const unsigned char *ptr, int sign,
338 unsigned long *size)
339 {
340 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
341 const unsigned char *ptr_orig = ptr;
342 unsigned long i = 0;
343
344 BitVector_Empty(conv_bv);
345 for (;;) {
346 BitVector_Chunk_Store(conv_bv, 7, i, *ptr);
347 i += 7;
348 if ((*ptr & 0x80) != 0x80)
349 break;
350 ptr++;
351 }
352
353 *size = (unsigned long)(ptr-ptr_orig)+1;
354
355 if(i > BITVECT_NATIVE_SIZE)
356 yasm_error_set(YASM_ERROR_OVERFLOW,
357 N_("Numeric constant too large for internal format"));
358 else if (sign && (*ptr & 0x40) == 0x40)
359 BitVector_Interval_Fill(conv_bv, i, BITVECT_NATIVE_SIZE-1);
360
361 intnum_frombv(intn, conv_bv);
362 return intn;
363 }
364
365 yasm_intnum *
yasm_intnum_create_sized(unsigned char * ptr,int sign,size_t srcsize,int bigendian)366 yasm_intnum_create_sized(unsigned char *ptr, int sign, size_t srcsize,
367 int bigendian)
368 {
369 yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
370 unsigned long i = 0;
371
372 if (srcsize*8 > BITVECT_NATIVE_SIZE)
373 yasm_error_set(YASM_ERROR_OVERFLOW,
374 N_("Numeric constant too large for internal format"));
375
376 /* Read the buffer into a bitvect */
377 BitVector_Empty(conv_bv);
378 if (bigendian) {
379 /* TODO */
380 yasm_internal_error(N_("big endian not implemented"));
381 } else {
382 for (i = 0; i < srcsize; i++)
383 BitVector_Chunk_Store(conv_bv, 8, i*8, ptr[i]);
384 }
385
386 /* Sign extend if needed */
387 if (srcsize*8 < BITVECT_NATIVE_SIZE && sign && (ptr[i-1] & 0x80) == 0x80)
388 BitVector_Interval_Fill(conv_bv, i*8, BITVECT_NATIVE_SIZE-1);
389
390 intnum_frombv(intn, conv_bv);
391 return intn;
392 }
393
394 yasm_intnum *
yasm_intnum_copy(const yasm_intnum * intn)395 yasm_intnum_copy(const yasm_intnum *intn)
396 {
397 yasm_intnum *n = yasm_xmalloc(sizeof(yasm_intnum));
398
399 switch (intn->type) {
400 case INTNUM_L:
401 n->val.l = intn->val.l;
402 break;
403 case INTNUM_BV:
404 n->val.bv = BitVector_Clone(intn->val.bv);
405 break;
406 }
407 n->type = intn->type;
408
409 return n;
410 }
411
412 void
yasm_intnum_destroy(yasm_intnum * intn)413 yasm_intnum_destroy(yasm_intnum *intn)
414 {
415 if (intn->type == INTNUM_BV)
416 BitVector_Destroy(intn->val.bv);
417 yasm_xfree(intn);
418 }
419
420 /*@-nullderef -nullpass -branchstate@*/
421 int
yasm_intnum_calc(yasm_intnum * acc,yasm_expr_op op,yasm_intnum * operand)422 yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand)
423 {
424 boolean carry = 0;
425 wordptr op1, op2 = NULL;
426 N_int count;
427
428 /* Always do computations with in full bit vector.
429 * Bit vector results must be calculated through intermediate storage.
430 */
431 op1 = intnum_tobv(op1static, acc);
432 if (operand)
433 op2 = intnum_tobv(op2static, operand);
434
435 if (!operand && op != YASM_EXPR_NEG && op != YASM_EXPR_NOT &&
436 op != YASM_EXPR_LNOT) {
437 yasm_error_set(YASM_ERROR_ARITHMETIC,
438 N_("operation needs an operand"));
439 BitVector_Empty(result);
440 return 1;
441 }
442
443 /* A operation does a bitvector computation if result is allocated. */
444 switch (op) {
445 case YASM_EXPR_ADD:
446 BitVector_add(result, op1, op2, &carry);
447 break;
448 case YASM_EXPR_SUB:
449 BitVector_sub(result, op1, op2, &carry);
450 break;
451 case YASM_EXPR_MUL:
452 BitVector_Multiply(result, op1, op2);
453 break;
454 case YASM_EXPR_DIV:
455 /* TODO: make sure op1 and op2 are unsigned */
456 if (BitVector_is_empty(op2)) {
457 yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
458 BitVector_Empty(result);
459 return 1;
460 } else
461 BitVector_Divide(result, op1, op2, spare);
462 break;
463 case YASM_EXPR_SIGNDIV:
464 if (BitVector_is_empty(op2)) {
465 yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
466 BitVector_Empty(result);
467 return 1;
468 } else
469 BitVector_Divide(result, op1, op2, spare);
470 break;
471 case YASM_EXPR_MOD:
472 /* TODO: make sure op1 and op2 are unsigned */
473 if (BitVector_is_empty(op2)) {
474 yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
475 BitVector_Empty(result);
476 return 1;
477 } else
478 BitVector_Divide(spare, op1, op2, result);
479 break;
480 case YASM_EXPR_SIGNMOD:
481 if (BitVector_is_empty(op2)) {
482 yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
483 BitVector_Empty(result);
484 return 1;
485 } else
486 BitVector_Divide(spare, op1, op2, result);
487 break;
488 case YASM_EXPR_NEG:
489 BitVector_Negate(result, op1);
490 break;
491 case YASM_EXPR_NOT:
492 Set_Complement(result, op1);
493 break;
494 case YASM_EXPR_OR:
495 Set_Union(result, op1, op2);
496 break;
497 case YASM_EXPR_AND:
498 Set_Intersection(result, op1, op2);
499 break;
500 case YASM_EXPR_XOR:
501 Set_ExclusiveOr(result, op1, op2);
502 break;
503 case YASM_EXPR_XNOR:
504 Set_ExclusiveOr(result, op1, op2);
505 Set_Complement(result, result);
506 break;
507 case YASM_EXPR_NOR:
508 Set_Union(result, op1, op2);
509 Set_Complement(result, result);
510 break;
511 case YASM_EXPR_SHL:
512 if (operand->type == INTNUM_L && operand->val.l >= 0) {
513 BitVector_Copy(result, op1);
514 BitVector_Move_Left(result, (N_int)operand->val.l);
515 } else /* don't even bother, just zero result */
516 BitVector_Empty(result);
517 break;
518 case YASM_EXPR_SHR:
519 if (operand->type == INTNUM_L && operand->val.l >= 0) {
520 BitVector_Copy(result, op1);
521 carry = BitVector_msb_(op1);
522 count = (N_int)operand->val.l;
523 while (count-- > 0)
524 BitVector_shift_right(result, carry);
525 } else /* don't even bother, just zero result */
526 BitVector_Empty(result);
527 break;
528 case YASM_EXPR_LOR:
529 BitVector_Empty(result);
530 BitVector_LSB(result, !BitVector_is_empty(op1) ||
531 !BitVector_is_empty(op2));
532 break;
533 case YASM_EXPR_LAND:
534 BitVector_Empty(result);
535 BitVector_LSB(result, !BitVector_is_empty(op1) &&
536 !BitVector_is_empty(op2));
537 break;
538 case YASM_EXPR_LNOT:
539 BitVector_Empty(result);
540 BitVector_LSB(result, BitVector_is_empty(op1));
541 break;
542 case YASM_EXPR_LXOR:
543 BitVector_Empty(result);
544 BitVector_LSB(result, !BitVector_is_empty(op1) ^
545 !BitVector_is_empty(op2));
546 break;
547 case YASM_EXPR_LXNOR:
548 BitVector_Empty(result);
549 BitVector_LSB(result, !(!BitVector_is_empty(op1) ^
550 !BitVector_is_empty(op2)));
551 break;
552 case YASM_EXPR_LNOR:
553 BitVector_Empty(result);
554 BitVector_LSB(result, !(!BitVector_is_empty(op1) ||
555 !BitVector_is_empty(op2)));
556 break;
557 case YASM_EXPR_EQ:
558 BitVector_Empty(result);
559 BitVector_LSB(result, BitVector_equal(op1, op2));
560 break;
561 case YASM_EXPR_LT:
562 BitVector_Empty(result);
563 BitVector_LSB(result, BitVector_Compare(op1, op2) < 0);
564 break;
565 case YASM_EXPR_GT:
566 BitVector_Empty(result);
567 BitVector_LSB(result, BitVector_Compare(op1, op2) > 0);
568 break;
569 case YASM_EXPR_LE:
570 BitVector_Empty(result);
571 BitVector_LSB(result, BitVector_Compare(op1, op2) <= 0);
572 break;
573 case YASM_EXPR_GE:
574 BitVector_Empty(result);
575 BitVector_LSB(result, BitVector_Compare(op1, op2) >= 0);
576 break;
577 case YASM_EXPR_NE:
578 BitVector_Empty(result);
579 BitVector_LSB(result, !BitVector_equal(op1, op2));
580 break;
581 case YASM_EXPR_SEG:
582 yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
583 "SEG");
584 break;
585 case YASM_EXPR_WRT:
586 yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
587 "WRT");
588 break;
589 case YASM_EXPR_SEGOFF:
590 yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
591 ":");
592 break;
593 case YASM_EXPR_IDENT:
594 if (result)
595 BitVector_Copy(result, op1);
596 break;
597 default:
598 yasm_error_set(YASM_ERROR_ARITHMETIC,
599 N_("invalid operation in intnum calculation"));
600 BitVector_Empty(result);
601 return 1;
602 }
603
604 /* Try to fit the result into 32 bits if possible */
605 if (acc->type == INTNUM_BV)
606 BitVector_Destroy(acc->val.bv);
607 intnum_frombv(acc, result);
608 return 0;
609 }
610 /*@=nullderef =nullpass =branchstate@*/
611
612 int
yasm_intnum_compare(const yasm_intnum * intn1,const yasm_intnum * intn2)613 yasm_intnum_compare(const yasm_intnum *intn1, const yasm_intnum *intn2)
614 {
615 wordptr op1, op2;
616
617 if (intn1->type == INTNUM_L && intn2->type == INTNUM_L) {
618 if (intn1->val.l < intn2->val.l)
619 return -1;
620 if (intn1->val.l > intn2->val.l)
621 return 1;
622 return 0;
623 }
624
625 op1 = intnum_tobv(op1static, intn1);
626 op2 = intnum_tobv(op2static, intn2);
627 return BitVector_Compare(op1, op2);
628 }
629
630 void
yasm_intnum_zero(yasm_intnum * intn)631 yasm_intnum_zero(yasm_intnum *intn)
632 {
633 yasm_intnum_set_int(intn, 0);
634 }
635
636 void
yasm_intnum_set(yasm_intnum * intn,const yasm_intnum * val)637 yasm_intnum_set(yasm_intnum *intn, const yasm_intnum *val)
638 {
639 if (intn->type == val->type) {
640 switch (val->type) {
641 case INTNUM_L:
642 intn->val.l = val->val.l;
643 break;
644 case INTNUM_BV:
645 BitVector_Copy(intn->val.bv, val->val.bv);
646 break;
647 }
648 } else {
649 switch (val->type) {
650 case INTNUM_L:
651 BitVector_Destroy(intn->val.bv);
652 intn->val.l = val->val.l;
653 break;
654 case INTNUM_BV:
655 intn->val.bv = BitVector_Clone(val->val.bv);
656 break;
657 }
658 intn->type = val->type;
659 }
660 }
661
662 void
yasm_intnum_set_uint(yasm_intnum * intn,unsigned long val)663 yasm_intnum_set_uint(yasm_intnum *intn, unsigned long val)
664 {
665 if (val > LONG_MAX) {
666 if (intn->type != INTNUM_BV) {
667 intn->val.bv = BitVector_Create(BITVECT_NATIVE_SIZE, TRUE);
668 intn->type = INTNUM_BV;
669 }
670 BitVector_Chunk_Store(intn->val.bv, 32, 0, val);
671 } else {
672 if (intn->type == INTNUM_BV) {
673 BitVector_Destroy(intn->val.bv);
674 intn->type = INTNUM_L;
675 }
676 intn->val.l = (long)val;
677 }
678 }
679
680 void
yasm_intnum_set_int(yasm_intnum * intn,long val)681 yasm_intnum_set_int(yasm_intnum *intn, long val)
682 {
683 if (intn->type == INTNUM_BV)
684 BitVector_Destroy(intn->val.bv);
685 intn->type = INTNUM_L;
686 intn->val.l = val;
687 }
688
689 int
yasm_intnum_is_zero(const yasm_intnum * intn)690 yasm_intnum_is_zero(const yasm_intnum *intn)
691 {
692 return (intn->type == INTNUM_L && intn->val.l == 0);
693 }
694
695 int
yasm_intnum_is_pos1(const yasm_intnum * intn)696 yasm_intnum_is_pos1(const yasm_intnum *intn)
697 {
698 return (intn->type == INTNUM_L && intn->val.l == 1);
699 }
700
701 int
yasm_intnum_is_neg1(const yasm_intnum * intn)702 yasm_intnum_is_neg1(const yasm_intnum *intn)
703 {
704 return (intn->type == INTNUM_L && intn->val.l == -1);
705 }
706
707 int
yasm_intnum_sign(const yasm_intnum * intn)708 yasm_intnum_sign(const yasm_intnum *intn)
709 {
710 if (intn->type == INTNUM_L) {
711 if (intn->val.l == 0)
712 return 0;
713 else if (intn->val.l < 0)
714 return -1;
715 else
716 return 1;
717 } else
718 return BitVector_Sign(intn->val.bv);
719 }
720
721 unsigned long
yasm_intnum_get_uint(const yasm_intnum * intn)722 yasm_intnum_get_uint(const yasm_intnum *intn)
723 {
724 switch (intn->type) {
725 case INTNUM_L:
726 if (intn->val.l < 0)
727 return 0;
728 return (unsigned long)intn->val.l;
729 case INTNUM_BV:
730 if (BitVector_msb_(intn->val.bv))
731 return 0;
732 if (Set_Max(intn->val.bv) > 32)
733 return ULONG_MAX;
734 return BitVector_Chunk_Read(intn->val.bv, 32, 0);
735 default:
736 yasm_internal_error(N_("unknown intnum type"));
737 /*@notreached@*/
738 return 0;
739 }
740 }
741
742 long
yasm_intnum_get_int(const yasm_intnum * intn)743 yasm_intnum_get_int(const yasm_intnum *intn)
744 {
745 switch (intn->type) {
746 case INTNUM_L:
747 return intn->val.l;
748 case INTNUM_BV:
749 if (BitVector_msb_(intn->val.bv)) {
750 /* it's negative: negate the bitvector to get a positive
751 * number, then negate the positive number.
752 */
753 unsigned long ul;
754
755 BitVector_Negate(conv_bv, intn->val.bv);
756 if (Set_Max(conv_bv) >= 32) {
757 /* too negative */
758 return LONG_MIN;
759 }
760 ul = BitVector_Chunk_Read(conv_bv, 32, 0);
761 /* check for too negative */
762 return (ul & 0x80000000) ? LONG_MIN : -((long)ul);
763 }
764
765 /* it's positive, and since it's a BV, it must be >0x7FFFFFFF */
766 return LONG_MAX;
767 default:
768 yasm_internal_error(N_("unknown intnum type"));
769 /*@notreached@*/
770 return 0;
771 }
772 }
773
774 void
yasm_intnum_get_sized(const yasm_intnum * intn,unsigned char * ptr,size_t destsize,size_t valsize,int shift,int bigendian,int warn)775 yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
776 size_t destsize, size_t valsize, int shift,
777 int bigendian, int warn)
778 {
779 wordptr op1 = op1static, op2;
780 unsigned char *buf;
781 unsigned int len;
782 size_t rshift = shift < 0 ? (size_t)(-shift) : 0;
783 int carry_in;
784
785 /* Currently don't support destinations larger than our native size */
786 if (destsize*8 > BITVECT_NATIVE_SIZE)
787 yasm_internal_error(N_("destination too large"));
788
789 /* General size warnings */
790 if (warn<0 && !yasm_intnum_check_size(intn, valsize, rshift, 1))
791 yasm_warn_set(YASM_WARN_GENERAL,
792 N_("value does not fit in signed %d bit field"),
793 valsize);
794 if (warn>0 && !yasm_intnum_check_size(intn, valsize, rshift, 2))
795 yasm_warn_set(YASM_WARN_GENERAL,
796 N_("value does not fit in %d bit field"), valsize);
797
798 /* Read the original data into a bitvect */
799 if (bigendian) {
800 /* TODO */
801 yasm_internal_error(N_("big endian not implemented"));
802 } else
803 BitVector_Block_Store(op1, ptr, (N_int)destsize);
804
805 /* If not already a bitvect, convert value to be written to a bitvect */
806 op2 = intnum_tobv(op2static, intn);
807
808 /* Check low bits if right shifting and warnings enabled */
809 if (warn && rshift > 0) {
810 BitVector_Copy(conv_bv, op2);
811 BitVector_Move_Left(conv_bv, (N_int)(BITVECT_NATIVE_SIZE-rshift));
812 if (!BitVector_is_empty(conv_bv))
813 yasm_warn_set(YASM_WARN_GENERAL,
814 N_("misaligned value, truncating to boundary"));
815 }
816
817 /* Shift right if needed */
818 if (rshift > 0) {
819 carry_in = BitVector_msb_(op2);
820 while (rshift-- > 0)
821 BitVector_shift_right(op2, carry_in);
822 shift = 0;
823 }
824
825 /* Write the new value into the destination bitvect */
826 BitVector_Interval_Copy(op1, op2, (unsigned int)shift, 0, (N_int)valsize);
827
828 /* Write out the new data */
829 buf = BitVector_Block_Read(op1, &len);
830 if (bigendian) {
831 /* TODO */
832 yasm_internal_error(N_("big endian not implemented"));
833 } else
834 memcpy(ptr, buf, destsize);
835 yasm_xfree(buf);
836 }
837
838 /* Return 1 if okay size, 0 if not */
839 int
yasm_intnum_check_size(const yasm_intnum * intn,size_t size,size_t rshift,int rangetype)840 yasm_intnum_check_size(const yasm_intnum *intn, size_t size, size_t rshift,
841 int rangetype)
842 {
843 wordptr val;
844
845 /* If not already a bitvect, convert value to a bitvect */
846 if (intn->type == INTNUM_BV) {
847 if (rshift > 0) {
848 val = conv_bv;
849 BitVector_Copy(val, intn->val.bv);
850 } else
851 val = intn->val.bv;
852 } else
853 val = intnum_tobv(conv_bv, intn);
854
855 if (size >= BITVECT_NATIVE_SIZE)
856 return 1;
857
858 if (rshift > 0) {
859 int carry_in = BitVector_msb_(val);
860 while (rshift-- > 0)
861 BitVector_shift_right(val, carry_in);
862 }
863
864 if (rangetype > 0) {
865 if (BitVector_msb_(val)) {
866 /* it's negative */
867 int retval;
868
869 BitVector_Negate(conv_bv, val);
870 BitVector_dec(conv_bv, conv_bv);
871 retval = Set_Max(conv_bv) < (long)size-1;
872
873 return retval;
874 }
875
876 if (rangetype == 1)
877 size--;
878 }
879 return (Set_Max(val) < (long)size);
880 }
881
882 int
yasm_intnum_in_range(const yasm_intnum * intn,long low,long high)883 yasm_intnum_in_range(const yasm_intnum *intn, long low, long high)
884 {
885 wordptr val = intnum_tobv(result, intn);
886 wordptr lval = op1static;
887 wordptr hval = op2static;
888
889 /* Convert high and low to bitvects */
890 BitVector_Empty(lval);
891 if (low >= 0)
892 BitVector_Chunk_Store(lval, 32, 0, (unsigned long)low);
893 else {
894 BitVector_Chunk_Store(lval, 32, 0, (unsigned long)(-low));
895 BitVector_Negate(lval, lval);
896 }
897
898 BitVector_Empty(hval);
899 if (high >= 0)
900 BitVector_Chunk_Store(hval, 32, 0, (unsigned long)high);
901 else {
902 BitVector_Chunk_Store(hval, 32, 0, (unsigned long)(-high));
903 BitVector_Negate(hval, hval);
904 }
905
906 /* Compare! */
907 return (BitVector_Compare(val, lval) >= 0
908 && BitVector_Compare(val, hval) <= 0);
909 }
910
911 static unsigned long
get_leb128(wordptr val,unsigned char * ptr,int sign)912 get_leb128(wordptr val, unsigned char *ptr, int sign)
913 {
914 unsigned long i, size;
915 unsigned char *ptr_orig = ptr;
916
917 if (sign) {
918 /* Signed mode */
919 if (BitVector_msb_(val)) {
920 /* Negative */
921 BitVector_Negate(conv_bv, val);
922 size = Set_Max(conv_bv)+2;
923 } else {
924 /* Positive */
925 size = Set_Max(val)+2;
926 }
927 } else {
928 /* Unsigned mode */
929 size = Set_Max(val)+1;
930 }
931
932 /* Positive/Unsigned write */
933 for (i=0; i<size; i += 7) {
934 *ptr = (unsigned char)BitVector_Chunk_Read(val, 7, i);
935 *ptr |= 0x80;
936 ptr++;
937 }
938 *(ptr-1) &= 0x7F; /* Clear MSB of last byte */
939 return (unsigned long)(ptr-ptr_orig);
940 }
941
942 static unsigned long
size_leb128(wordptr val,int sign)943 size_leb128(wordptr val, int sign)
944 {
945 if (sign) {
946 /* Signed mode */
947 if (BitVector_msb_(val)) {
948 /* Negative */
949 BitVector_Negate(conv_bv, val);
950 return (Set_Max(conv_bv)+8)/7;
951 } else {
952 /* Positive */
953 return (Set_Max(val)+8)/7;
954 }
955 } else {
956 /* Unsigned mode */
957 return (Set_Max(val)+7)/7;
958 }
959 }
960
961 unsigned long
yasm_intnum_get_leb128(const yasm_intnum * intn,unsigned char * ptr,int sign)962 yasm_intnum_get_leb128(const yasm_intnum *intn, unsigned char *ptr, int sign)
963 {
964 wordptr val;
965
966 /* Shortcut 0 */
967 if (intn->type == INTNUM_L && intn->val.l == 0) {
968 *ptr = 0;
969 return 1;
970 }
971
972 /* If not already a bitvect, convert value to be written to a bitvect */
973 val = intnum_tobv(op1static, intn);
974
975 return get_leb128(val, ptr, sign);
976 }
977
978 unsigned long
yasm_intnum_size_leb128(const yasm_intnum * intn,int sign)979 yasm_intnum_size_leb128(const yasm_intnum *intn, int sign)
980 {
981 wordptr val;
982
983 /* Shortcut 0 */
984 if (intn->type == INTNUM_L && intn->val.l == 0) {
985 return 1;
986 }
987
988 /* If not already a bitvect, convert value to a bitvect */
989 val = intnum_tobv(op1static, intn);
990
991 return size_leb128(val, sign);
992 }
993
994 unsigned long
yasm_get_sleb128(long v,unsigned char * ptr)995 yasm_get_sleb128(long v, unsigned char *ptr)
996 {
997 wordptr val = op1static;
998
999 /* Shortcut 0 */
1000 if (v == 0) {
1001 *ptr = 0;
1002 return 1;
1003 }
1004
1005 BitVector_Empty(val);
1006 if (v >= 0)
1007 BitVector_Chunk_Store(val, 32, 0, (unsigned long)v);
1008 else {
1009 BitVector_Chunk_Store(val, 32, 0, (unsigned long)(-v));
1010 BitVector_Negate(val, val);
1011 }
1012 return get_leb128(val, ptr, 1);
1013 }
1014
1015 unsigned long
yasm_size_sleb128(long v)1016 yasm_size_sleb128(long v)
1017 {
1018 wordptr val = op1static;
1019
1020 if (v == 0)
1021 return 1;
1022
1023 BitVector_Empty(val);
1024 if (v >= 0)
1025 BitVector_Chunk_Store(val, 32, 0, (unsigned long)v);
1026 else {
1027 BitVector_Chunk_Store(val, 32, 0, (unsigned long)(-v));
1028 BitVector_Negate(val, val);
1029 }
1030 return size_leb128(val, 1);
1031 }
1032
1033 unsigned long
yasm_get_uleb128(unsigned long v,unsigned char * ptr)1034 yasm_get_uleb128(unsigned long v, unsigned char *ptr)
1035 {
1036 wordptr val = op1static;
1037
1038 /* Shortcut 0 */
1039 if (v == 0) {
1040 *ptr = 0;
1041 return 1;
1042 }
1043
1044 BitVector_Empty(val);
1045 BitVector_Chunk_Store(val, 32, 0, v);
1046 return get_leb128(val, ptr, 0);
1047 }
1048
1049 unsigned long
yasm_size_uleb128(unsigned long v)1050 yasm_size_uleb128(unsigned long v)
1051 {
1052 wordptr val = op1static;
1053
1054 if (v == 0)
1055 return 1;
1056
1057 BitVector_Empty(val);
1058 BitVector_Chunk_Store(val, 32, 0, v);
1059 return size_leb128(val, 0);
1060 }
1061
1062 char *
yasm_intnum_get_str(const yasm_intnum * intn)1063 yasm_intnum_get_str(const yasm_intnum *intn)
1064 {
1065 unsigned char *s;
1066
1067 switch (intn->type) {
1068 case INTNUM_L:
1069 s = yasm_xmalloc(16);
1070 sprintf((char *)s, "%ld", intn->val.l);
1071 return (char *)s;
1072 break;
1073 case INTNUM_BV:
1074 return (char *)BitVector_to_Dec(intn->val.bv);
1075 break;
1076 }
1077 /*@notreached@*/
1078 return NULL;
1079 }
1080
1081 void
yasm_intnum_print(const yasm_intnum * intn,FILE * f)1082 yasm_intnum_print(const yasm_intnum *intn, FILE *f)
1083 {
1084 unsigned char *s;
1085
1086 switch (intn->type) {
1087 case INTNUM_L:
1088 fprintf(f, "0x%lx", intn->val.l);
1089 break;
1090 case INTNUM_BV:
1091 s = BitVector_to_Hex(intn->val.bv);
1092 fprintf(f, "0x%s", (char *)s);
1093 yasm_xfree(s);
1094 break;
1095 }
1096 }
1097