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