Add packaging files for Tizen
[profile/ivi/yasm.git] / libyasm / intnum.c
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
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
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
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
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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
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
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
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
631 yasm_intnum_zero(yasm_intnum *intn)
632 {
633     yasm_intnum_set_int(intn, 0);
634 }
635
636 void
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
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
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
690 yasm_intnum_is_zero(const yasm_intnum *intn)
691 {
692     return (intn->type == INTNUM_L && intn->val.l == 0);
693 }
694
695 int
696 yasm_intnum_is_pos1(const yasm_intnum *intn)
697 {
698     return (intn->type == INTNUM_L && intn->val.l == 1);
699 }
700
701 int
702 yasm_intnum_is_neg1(const yasm_intnum *intn)
703 {
704     return (intn->type == INTNUM_L && intn->val.l == -1);
705 }
706
707 int
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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 }