Home | History | Annotate | Download | only in libyasm
      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 }
   1097