963
1077
p->freason = BADARITH;
964
1078
return THE_NON_VALUE;
966
ires = BIG_NEED_SIZE(MAX(big_size(arg1), big_size(arg2)) + 1);
967
hp = ArithAlloc(p, ires);
1080
need = BIG_NEED_SIZE(MAX(big_size(arg1), big_size(arg2)) + 1);
1081
hp = ArithAlloc(p, need);
968
1082
arg1 = big_bxor(arg1, arg2, hp);
1083
ASSERT(is_not_nil(arg1));
1084
maybe_shrink(p, hp, arg1, need);
970
ASSERT(is_not_nil(arg1));
1089
Eterm erts_bnot(Process* p, Eterm arg)
1094
Uint need = BIG_NEED_SIZE(big_size(arg)+1);
1095
Eterm* bigp = ArithAlloc(p, need);
1097
ret = big_bnot(arg, bigp);
1098
maybe_shrink(p, bigp, ret, need);
1100
p->freason = SYSTEM_LIMIT;
1105
p->freason = BADARITH;
1111
#if defined(HEAP_FRAG_ELIM_TEST)
1112
#define ERTS_ARITH_FORCE_GC 0
1114
#define ERTS_NEED_GC(p, need) \
1115
(ERTS_ARITH_FORCE_GC || (HEAP_LIMIT((p)) - HEAP_TOP((p))) <= (need))
1117
static ERTS_INLINE void
1118
trim_heap(Process* p, Eterm* hp, Eterm res)
1120
ASSERT(p->heap <= hp && hp <= p->htop);
1121
if (is_immed(res)) {
1124
ASSERT(is_big(res));
1125
p->htop = hp + bignum_header_arity(*hp) + 1;
1130
* The following are not allowed to be used here
1132
#define erts_arith_shrink horrible error
1133
#define maybe_shrink horrible error
1136
#define ArithAlloc horrible error
1137
#define ArithCheck horrible error
1141
erts_gc_mixed_plus(Process* p, Eterm* reg, Uint live)
1150
dsize_t sz1, sz2, sz;
1157
ERTS_FP_CHECK_INIT(p);
1158
switch (arg1 & _TAG_PRIMARY_MASK) {
1159
case TAG_PRIMARY_IMMED1:
1160
switch ((arg1 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1161
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1162
switch (arg2 & _TAG_PRIMARY_MASK) {
1163
case TAG_PRIMARY_IMMED1:
1164
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1165
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1166
ires = signed_val(arg1) + signed_val(arg2);
1167
ASSERT(MY_IS_SSMALL(ires) == IS_SSMALL(ires));
1168
if (MY_IS_SSMALL(ires)) {
1169
return make_small(ires);
1171
if (ERTS_NEED_GC(p, 2)) {
1172
erts_garbage_collect(p, 2, reg, live);
1176
res = small_to_big(ires, hp);
1181
p->freason = BADARITH;
1182
return THE_NON_VALUE;
1184
case TAG_PRIMARY_BOXED:
1185
hdr = *boxed_val(arg2);
1186
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1187
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1188
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1189
if (arg1 == SMALL_ZERO) {
1192
arg1 = small_to_big(signed_val(arg1), tmp_big1);
1194
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1195
f1.fd = signed_val(arg1);
1196
GET_DOUBLE(arg2, f2);
1205
case TAG_PRIMARY_BOXED:
1206
hdr = *boxed_val(arg1);
1207
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1208
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1209
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1210
switch (arg2 & _TAG_PRIMARY_MASK) {
1211
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1212
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1213
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1214
if (arg2 == SMALL_ZERO) {
1217
arg2 = small_to_big(signed_val(arg2), tmp_big2);
1222
case TAG_PRIMARY_BOXED:
1223
hdr = *boxed_val(arg2);
1224
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1225
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1226
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1228
sz1 = big_size(arg1);
1229
sz2 = big_size(arg2);
1230
sz = MAX(sz1, sz2)+1;
1231
need_heap = BIG_NEED_SIZE(sz);
1232
if (ERTS_NEED_GC(p, need_heap)) {
1233
erts_garbage_collect(p, 2, reg, live+2);
1234
if (arg1 != make_big(tmp_big1)) {
1237
if (arg2 != make_big(tmp_big2)) {
1242
p->htop += need_heap;
1243
res = big_plus(arg1, arg2, hp);
1244
trim_heap(p, hp, res);
1246
p->freason = SYSTEM_LIMIT;
1247
return THE_NON_VALUE;
1250
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1251
if (big_to_double(arg1, &f1.fd) < 0) {
1254
GET_DOUBLE(arg2, f2);
1260
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1261
switch (arg2 & _TAG_PRIMARY_MASK) {
1262
case TAG_PRIMARY_IMMED1:
1263
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1264
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1265
GET_DOUBLE(arg1, f1);
1266
f2.fd = signed_val(arg2);
1271
case TAG_PRIMARY_BOXED:
1272
hdr = *boxed_val(arg2);
1273
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1274
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1275
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1276
GET_DOUBLE(arg1, f1);
1277
if (big_to_double(arg2, &f2.fd) < 0) {
1281
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1282
GET_DOUBLE(arg1, f1);
1283
GET_DOUBLE(arg2, f2);
1286
f1.fd = f1.fd + f2.fd;
1287
ERTS_FP_ERROR(p, f1.fd, goto badarith);
1288
if (ERTS_NEED_GC(p, FLOAT_SIZE_OBJECT)) {
1289
erts_garbage_collect(p, FLOAT_SIZE_OBJECT, reg, live);
1292
p->htop += FLOAT_SIZE_OBJECT;
1293
res = make_float(hp);
1309
erts_gc_mixed_minus(Process* p, Eterm* reg, Uint live)
1318
dsize_t sz1, sz2, sz;
1325
ERTS_FP_CHECK_INIT(p);
1326
switch (arg1 & _TAG_PRIMARY_MASK) {
1327
case TAG_PRIMARY_IMMED1:
1328
switch ((arg1 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1329
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1330
switch (arg2 & _TAG_PRIMARY_MASK) {
1331
case TAG_PRIMARY_IMMED1:
1332
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1333
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1334
ires = signed_val(arg1) - signed_val(arg2);
1335
ASSERT(MY_IS_SSMALL(ires) == IS_SSMALL(ires));
1336
if (MY_IS_SSMALL(ires)) {
1337
return make_small(ires);
1339
if (ERTS_NEED_GC(p, 2)) {
1340
erts_garbage_collect(p, 2, reg, live);
1344
res = small_to_big(ires, hp);
1349
p->freason = BADARITH;
1350
return THE_NON_VALUE;
1352
case TAG_PRIMARY_BOXED:
1353
hdr = *boxed_val(arg2);
1354
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1355
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1356
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1357
arg1 = small_to_big(signed_val(arg1), tmp_big1);
1359
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1360
f1.fd = signed_val(arg1);
1361
GET_DOUBLE(arg2, f2);
1370
case TAG_PRIMARY_BOXED:
1371
hdr = *boxed_val(arg1);
1372
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1373
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1374
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1375
switch (arg2 & _TAG_PRIMARY_MASK) {
1376
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1377
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1378
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1379
if (arg2 == SMALL_ZERO) {
1382
arg2 = small_to_big(signed_val(arg2), tmp_big2);
1385
sz1 = big_size(arg1);
1386
sz2 = big_size(arg2);
1387
sz = MAX(sz1, sz2)+1;
1388
need_heap = BIG_NEED_SIZE(sz);
1389
if (ERTS_NEED_GC(p, need_heap)) {
1390
erts_garbage_collect(p, need_heap, reg, live+2);
1391
if (arg1 != make_big(tmp_big1)) {
1394
if (arg2 != make_big(tmp_big2)) {
1399
p->htop += need_heap;
1400
res = big_minus(arg1, arg2, hp);
1401
trim_heap(p, hp, res);
1403
p->freason = SYSTEM_LIMIT;
1404
return THE_NON_VALUE;
1410
case TAG_PRIMARY_BOXED:
1411
hdr = *boxed_val(arg2);
1412
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1413
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1414
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1416
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1417
if (big_to_double(arg1, &f1.fd) < 0) {
1420
GET_DOUBLE(arg2, f2);
1426
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1427
switch (arg2 & _TAG_PRIMARY_MASK) {
1428
case TAG_PRIMARY_IMMED1:
1429
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1430
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1431
GET_DOUBLE(arg1, f1);
1432
f2.fd = signed_val(arg2);
1437
case TAG_PRIMARY_BOXED:
1438
hdr = *boxed_val(arg2);
1439
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1440
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1441
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1442
GET_DOUBLE(arg1, f1);
1443
if (big_to_double(arg2, &f2.fd) < 0) {
1447
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1448
GET_DOUBLE(arg1, f1);
1449
GET_DOUBLE(arg2, f2);
1452
f1.fd = f1.fd - f2.fd;
1453
ERTS_FP_ERROR(p, f1.fd, goto badarith);
1454
if (ERTS_NEED_GC(p, FLOAT_SIZE_OBJECT)) {
1455
erts_garbage_collect(p, FLOAT_SIZE_OBJECT, reg, live);
1458
p->htop += FLOAT_SIZE_OBJECT;
1459
res = make_float(hp);
1475
erts_gc_mixed_times(Process* p, Eterm* reg, Uint live)
1484
dsize_t sz1, sz2, sz;
1490
ERTS_FP_CHECK_INIT(p);
1491
switch (arg1 & _TAG_PRIMARY_MASK) {
1492
case TAG_PRIMARY_IMMED1:
1493
switch ((arg1 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1494
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1495
switch (arg2 & _TAG_PRIMARY_MASK) {
1496
case TAG_PRIMARY_IMMED1:
1497
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1498
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1499
if ((arg1 == SMALL_ZERO) || (arg2 == SMALL_ZERO)) {
1501
} else if (arg1 == SMALL_ONE) {
1503
} else if (arg2 == SMALL_ONE) {
1509
* The following code is optimized for the case that
1510
* result is small (which should be the most common case
1513
arg1 = small_to_big(signed_val(arg1), tmp_big1);
1514
arg2 = small_to_big(signed_val(arg2), tmp_big2);
1515
res = big_times(arg1, arg2, big_res);
1516
if (is_small(res)) {
1520
* The result is a a big number.
1521
* Allocate a heap fragment and copy the result.
1522
* Be careful to allocate exactly what we need
1523
* to not leave any holes.
1528
ASSERT(is_big(res));
1530
arity = bignum_header_arity(hdr);
1531
ASSERT(arity == 1 || arity == 2);
1533
if (ERTS_NEED_GC(p, need)) {
1534
erts_garbage_collect(p, need, reg, live);
1549
p->freason = BADARITH;
1550
return THE_NON_VALUE;
1552
case TAG_PRIMARY_BOXED:
1553
hdr = *boxed_val(arg2);
1554
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1555
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1556
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1557
if (arg1 == SMALL_ZERO)
1559
if (arg1 == SMALL_ONE)
1561
arg1 = small_to_big(signed_val(arg1), tmp_big1);
1562
sz = 2 + big_size(arg2);
1564
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1565
f1.fd = signed_val(arg1);
1566
GET_DOUBLE(arg2, f2);
1575
case TAG_PRIMARY_BOXED:
1576
hdr = *boxed_val(arg1);
1577
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1578
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1579
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1580
switch (arg2 & _TAG_PRIMARY_MASK) {
1581
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1582
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1583
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1584
if (arg2 == SMALL_ZERO)
1586
if (arg2 == SMALL_ONE)
1588
arg2 = small_to_big(signed_val(arg2), tmp_big2);
1589
sz = 2 + big_size(arg1);
1594
case TAG_PRIMARY_BOXED:
1595
hdr = *boxed_val(arg2);
1596
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1597
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1598
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1599
sz1 = big_size(arg1);
1600
sz2 = big_size(arg2);
1604
need_heap = BIG_NEED_SIZE(sz);
1605
if (ERTS_NEED_GC(p, need_heap)) {
1606
erts_garbage_collect(p, need_heap, reg, live+2);
1607
if (arg1 != make_big(tmp_big1)) {
1610
if (arg2 != make_big(tmp_big2)) {
1615
p->htop += need_heap;
1616
res = big_times(arg1, arg2, hp);
1617
trim_heap(p, hp, res);
1620
* Note that the result must be big in this case, since
1621
* at least one operand was big to begin with, and
1622
* the absolute value of the other is > 1.
1626
p->freason = SYSTEM_LIMIT;
1627
return THE_NON_VALUE;
1630
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1631
if (big_to_double(arg1, &f1.fd) < 0) {
1634
GET_DOUBLE(arg2, f2);
1640
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1641
switch (arg2 & _TAG_PRIMARY_MASK) {
1642
case TAG_PRIMARY_IMMED1:
1643
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1644
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1645
GET_DOUBLE(arg1, f1);
1646
f2.fd = signed_val(arg2);
1651
case TAG_PRIMARY_BOXED:
1652
hdr = *boxed_val(arg2);
1653
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1654
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1655
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1656
GET_DOUBLE(arg1, f1);
1657
if (big_to_double(arg2, &f2.fd) < 0) {
1661
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1662
GET_DOUBLE(arg1, f1);
1663
GET_DOUBLE(arg2, f2);
1666
f1.fd = f1.fd * f2.fd;
1667
ERTS_FP_ERROR(p, f1.fd, goto badarith);
1668
if (ERTS_NEED_GC(p, FLOAT_SIZE_OBJECT)) {
1669
erts_garbage_collect(p, FLOAT_SIZE_OBJECT, reg, live);
1672
p->htop += FLOAT_SIZE_OBJECT;
1673
res = make_float(hp);
1689
erts_gc_mixed_div(Process* p, Eterm* reg, Uint live)
1699
ERTS_FP_CHECK_INIT(p);
1700
switch (arg1 & _TAG_PRIMARY_MASK) {
1701
case TAG_PRIMARY_IMMED1:
1702
switch ((arg1 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1703
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1704
switch (arg2 & _TAG_PRIMARY_MASK) {
1705
case TAG_PRIMARY_IMMED1:
1706
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1707
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1708
f1.fd = signed_val(arg1);
1709
f2.fd = signed_val(arg2);
1713
p->freason = BADARITH;
1714
return THE_NON_VALUE;
1716
case TAG_PRIMARY_BOXED:
1717
hdr = *boxed_val(arg2);
1718
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1719
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1720
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1721
f1.fd = signed_val(arg1);
1722
if (big_to_double(arg2, &f2.fd) < 0) {
1726
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1727
f1.fd = signed_val(arg1);
1728
GET_DOUBLE(arg2, f2);
1737
case TAG_PRIMARY_BOXED:
1738
hdr = *boxed_val(arg1);
1739
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1740
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1741
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1742
switch (arg2 & _TAG_PRIMARY_MASK) {
1743
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1744
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1745
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1746
if (big_to_double(arg1, &f1.fd) < 0) {
1749
f2.fd = signed_val(arg2);
1754
case TAG_PRIMARY_BOXED:
1755
hdr = *boxed_val(arg2);
1756
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1757
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1758
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1759
if (big_to_double(arg1, &f1.fd) < 0 ||
1760
big_to_double(arg2, &f2.fd) < 0) {
1764
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1765
if (big_to_double(arg1, &f1.fd) < 0) {
1768
GET_DOUBLE(arg2, f2);
1774
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1775
switch (arg2 & _TAG_PRIMARY_MASK) {
1776
case TAG_PRIMARY_IMMED1:
1777
switch ((arg2 & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {
1778
case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):
1779
GET_DOUBLE(arg1, f1);
1780
f2.fd = signed_val(arg2);
1785
case TAG_PRIMARY_BOXED:
1786
hdr = *boxed_val(arg2);
1787
switch ((hdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
1788
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
1789
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
1790
GET_DOUBLE(arg1, f1);
1791
if (big_to_double(arg2, &f2.fd) < 0) {
1795
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
1796
GET_DOUBLE(arg1, f1);
1797
GET_DOUBLE(arg2, f2);
1800
f1.fd = f1.fd / f2.fd;
1801
ERTS_FP_ERROR(p, f1.fd, goto badarith);
1802
if (ERTS_NEED_GC(p, FLOAT_SIZE_OBJECT)) {
1803
erts_garbage_collect(p, FLOAT_SIZE_OBJECT, reg, live);
1806
p->htop += FLOAT_SIZE_OBJECT;
1808
return make_float(hp);
1822
erts_gc_int_div(Process* p, Eterm* reg, Uint live)
1832
switch (NUMBER_CODE(arg1, arg2)) {
1834
/* This case occurs if the most negative fixnum is divided by -1. */
1835
ASSERT(arg2 == make_small(-1));
1836
arg1 = small_to_big(signed_val(arg1), tmp_big1);
1839
arg2 = small_to_big(signed_val(arg2), tmp_big2);
1842
if (arg1 != make_small(MIN_SMALL)) {
1845
arg1 = small_to_big(signed_val(arg1), tmp_big1);
1849
ires = big_ucomp(arg1, arg2);
1852
} else if (ires == 0) {
1853
arg1 = (big_sign(arg1) == big_sign(arg2)) ?
1854
SMALL_ONE : SMALL_MINUS_ONE;
1857
int i = big_size(arg1);
1860
ires = big_size(arg2);
1861
need = BIG_NEED_SIZE(i-ires+1) + BIG_NEED_SIZE(i);
1862
if (ERTS_NEED_GC(p, need)) {
1863
erts_garbage_collect(p, need, reg, live+2);
1864
if (arg1 != make_big(tmp_big1)) {
1867
if (arg2 != make_big(tmp_big2)) {
1873
arg1 = big_div(arg1, arg2, hp);
1874
trim_heap(p, hp, arg1);
1876
p->freason = SYSTEM_LIMIT;
1877
return THE_NON_VALUE;
1882
p->freason = BADARITH;
1883
return THE_NON_VALUE;
1888
erts_gc_int_rem(Process* p, Eterm* reg, Uint live)
1898
switch (NUMBER_CODE(arg1, arg2)) {
1900
arg2 = small_to_big(signed_val(arg2), tmp_big2);
1903
if (arg1 != make_small(MIN_SMALL)) {
1906
arg1 = small_to_big(signed_val(arg1), tmp_big1);
1910
ires = big_ucomp(arg1, arg2);
1913
} else if (ires > 0) {
1915
Uint need = BIG_NEED_SIZE(big_size(arg1));
1917
if (ERTS_NEED_GC(p, need)) {
1918
erts_garbage_collect(p, need, reg, live+2);
1919
if (arg1 != make_big(tmp_big1)) {
1922
if (arg2 != make_big(tmp_big2)) {
1928
arg1 = big_rem(arg1, arg2, hp);
1929
trim_heap(p, hp, arg1);
1931
p->freason = SYSTEM_LIMIT;
1932
return THE_NON_VALUE;
1937
p->freason = BADARITH;
1938
return THE_NON_VALUE;
1942
#define DEFINE_GC_LOGIC_FUNC(func) \
1943
Eterm erts_gc_##func(Process* p, Eterm* reg, Uint live) \
1947
Eterm tmp_big1[2]; \
1948
Eterm tmp_big2[2]; \
1953
arg2 = reg[live+1]; \
1954
switch (NUMBER_CODE(arg1, arg2)) { \
1956
arg1 = small_to_big(signed_val(arg1), tmp_big1); \
1957
need = BIG_NEED_SIZE(big_size(arg2) + 1); \
1958
if (ERTS_NEED_GC(p, need)) { \
1959
erts_garbage_collect(p, need, reg, live+2); \
1960
arg2 = reg[live+1]; \
1964
arg2 = small_to_big(signed_val(arg2), tmp_big2); \
1965
need = BIG_NEED_SIZE(big_size(arg1) + 1); \
1966
if (ERTS_NEED_GC(p, need)) { \
1967
erts_garbage_collect(p, need, reg, live+2); \
1972
need = BIG_NEED_SIZE(MAX(big_size(arg1), big_size(arg2)) + 1); \
1973
if (ERTS_NEED_GC(p, need)) { \
1974
erts_garbage_collect(p, need, reg, live+2); \
1976
arg2 = reg[live+1]; \
1980
p->freason = BADARITH; \
1981
return THE_NON_VALUE; \
1985
arg1 = big_##func(arg1, arg2, hp); \
1986
trim_heap(p, hp, arg1); \
1990
DEFINE_GC_LOGIC_FUNC(band)
1991
DEFINE_GC_LOGIC_FUNC(bor)
1992
DEFINE_GC_LOGIC_FUNC(bxor)
1994
Eterm erts_gc_bnot(Process* p, Eterm* reg, Uint live)
2002
if (is_not_big(arg)) {
2003
p->freason = BADARITH;
2006
need = BIG_NEED_SIZE(big_size(arg)+1);
2007
if (ERTS_NEED_GC(p, need)) {
2008
erts_garbage_collect(p, need, reg, live+1);
2013
result = big_bnot(arg, bigp);
2014
trim_heap(p, bigp, result);
2015
if (is_nil(result)) {
2016
p->freason = SYSTEM_LIMIT;