/* Compress a bitvector into intnum storage. * If saved as a bitvector, clones the passed bitvector. * Can modify the passed bitvector. */ static void intnum_frombv(/*@out@*/ yasm_intnum *intn, wordptr bv) { if (Set_Max(bv) < 31) { intn->type = INTNUM_L; intn->val.l = (long)BitVector_Chunk_Read(bv, 31, 0); } else if (BitVector_msb_(bv)) { /* Negative, negate and see if we'll fit into a long. */ unsigned long ul; BitVector_Negate(bv, bv); if (Set_Max(bv) >= 32 || ((ul = BitVector_Chunk_Read(bv, 32, 0)) & 0x80000000)) { /* too negative */ BitVector_Negate(bv, bv); intn->type = INTNUM_BV; intn->val.bv = BitVector_Clone(bv); } else { intn->type = INTNUM_L; intn->val.l = -((long)ul); } } else { intn->type = INTNUM_BV; intn->val.bv = BitVector_Clone(bv); } }
void yasm_intnum_set(yasm_intnum *intn, const yasm_intnum *val) { if (intn->type == val->type) { switch (val->type) { case INTNUM_L: intn->val.l = val->val.l; break; case INTNUM_BV: BitVector_Copy(intn->val.bv, val->val.bv); break; } } else { switch (val->type) { case INTNUM_L: BitVector_Destroy(intn->val.bv); intn->val.l = val->val.l; break; case INTNUM_BV: intn->val.bv = BitVector_Clone(val->val.bv); break; } intn->type = val->type; } }
yasm_floatnum * yasm_floatnum_copy(const yasm_floatnum *flt) { yasm_floatnum *f = yasm_xmalloc(sizeof(yasm_floatnum)); f->mantissa = BitVector_Clone(flt->mantissa); f->exponent = flt->exponent; f->sign = flt->sign; f->flags = flt->flags; return f; }
yasm_intnum * yasm_intnum_create_charconst_tasm(const char *str) { yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum)); size_t len = strlen(str); size_t i; if(len*8 > BITVECT_NATIVE_SIZE) yasm_error_set(YASM_ERROR_OVERFLOW, N_("Character constant too large for internal format")); /* be conservative in choosing bitvect in case MSB is set */ if (len > 3) { BitVector_Empty(conv_bv); intn->type = INTNUM_BV; } else { intn->val.l = 0; intn->type = INTNUM_L; } /* tasm uses big endian notation */ i = 0; switch (len) { case 3: intn->val.l |= ((unsigned long)str[i++]) & 0xff; intn->val.l <<= 8; /*@fallthrough@*/ case 2: intn->val.l |= ((unsigned long)str[i++]) & 0xff; intn->val.l <<= 8; /*@fallthrough@*/ case 1: intn->val.l |= ((unsigned long)str[i++]) & 0xff; case 0: break; default: /* >=32 bit conversion */ while (i < len) { BitVector_Chunk_Store(conv_bv, 8, (len-i-1)*8, ((unsigned long)str[i]) & 0xff); i++; } intn->val.bv = BitVector_Clone(conv_bv); } return intn; }
yasm_intnum * yasm_intnum_copy(const yasm_intnum *intn) { yasm_intnum *n = yasm_xmalloc(sizeof(yasm_intnum)); switch (intn->type) { case INTNUM_L: n->val.l = intn->val.l; break; case INTNUM_BV: n->val.bv = BitVector_Clone(intn->val.bv); break; } n->type = intn->type; return n; }