|
22 | 22 | - [`MUL`: Multiply](#mul-multiply) |
23 | 23 | - [`MULI`: Multiply immediate](#muli-multiply-immediate) |
24 | 24 | - [`MLDV`: Fused multiply-divide](#mldv-fused-multiply-divide) |
| 25 | + - [`NIOP`: Narrow integer operation](#niop-narrow-integer-operation) |
25 | 26 | - [`NOOP`: No operation](#noop-no-operation) |
26 | 27 | - [`NOT`: Invert](#not-invert) |
27 | 28 | - [`OR`: OR](#or-or) |
|
32 | 33 | - [`SRLI`: Shift right logical immediate](#srli-shift-right-logical-immediate) |
33 | 34 | - [`SUB`: Subtract](#sub-subtract) |
34 | 35 | - [`SUBI`: Subtract immediate](#subi-subtract-immediate) |
35 | | - - [`SUBI`: Subtract immediate](#subi-subtract-immediate) |
36 | 36 | - [`WDCM`: 128-bit integer comparison](#wdcm-128-bit-integer-comparison) |
37 | 37 | - [`WQCM`: 256-bit integer comparison](#wqcm-256-bit-integer-comparison) |
38 | 38 | - [`WDOP`: Misc 128-bit integer operations](#wdop-misc-128-bit-integer-operations) |
|
69 | 69 | - [`CFS`: Shrink call frame](#cfs-shrink-call-frame) |
70 | 70 | - [`CFSI`: Shrink call frame immediate](#cfsi-shrink-call-frame-immediate) |
71 | 71 | - [`LB`: Load byte](#lb-load-byte) |
| 72 | + - [`LQW`: Load quarter word](#lqw-load-quarter-word) |
| 73 | + - [`LHW`: Load half word](#lhw-load-half-word) |
72 | 74 | - [`LW`: Load word](#lw-load-word) |
73 | 75 | - [`MCL`: Memory clear](#mcl-memory-clear) |
74 | 76 | - [`MCLI`: Memory clear immediate](#mcli-memory-clear-immediate) |
|
80 | 82 | - [`PSHH`: Push a set of high registers to stack](#pshh-push-a-set-of-high-registers-to-stack) |
81 | 83 | - [`PSHL`: Push a set of low registers to stack](#pshl-push-a-set-of-low-registers-to-stack) |
82 | 84 | - [`SB`: Store byte](#sb-store-byte) |
| 85 | + - [`SQW`: Store quarter word](#sqw-store-quarter-word) |
| 86 | + - [`SHW`: Store half word](#shw-store-half-word) |
83 | 87 | - [`SW`: Store word](#sw-store-word) |
84 | 88 | - [Contract Instructions](#contract-instructions) |
85 | 89 | - [`BAL`: Balance of contract ID](#bal-balance-of-contract-id) |
@@ -537,6 +541,55 @@ If the result of after the division doesn't fit into a register, `$of` is assign |
537 | 541 |
|
538 | 542 | `$err` is cleared. |
539 | 543 |
|
| 544 | +### `NIOP`: Narrow integer operation |
| 545 | + |
| 546 | +| | | |
| 547 | +|-------------|-------------------------------------------------------------------------------------| |
| 548 | +| Description | Perform an ALU operation with overflow handing for 8, 16 or 32 bit integers | |
| 549 | +| Operation | `$rA = op($rB,$rC);` | |
| 550 | +| Syntax | `niop $rA, $rB, $rC, imm` | |
| 551 | +| Encoding | `0x00 rA rB rC i` | |
| 552 | +| Notes | Operations that would be identical with their 64-bit counterparts are not available | |
| 553 | + |
| 554 | +The six-bit immediate value is used to select operating mode, as follows: |
| 555 | + |
| 556 | +Bits | Short name | Description |
| 557 | +---------|------------|------------------------------------- |
| 558 | +`..XXXX` | `op` | Operation selection, see below |
| 559 | +`XX....` | `width` | Operation width, see below |
| 560 | + |
| 561 | +Then the actual operation that's performed: |
| 562 | + |
| 563 | +`op` | Name | Description |
| 564 | +-----|-------|--------------------------- |
| 565 | +0 | `add` | Add (`a = b + c`) |
| 566 | +1 | `mul` | Multiply (`a = b * c`) |
| 567 | +2 | `exp` | Exponentiate (`a = b ** c`) |
| 568 | +3 | `sll` | Bit shift left (logical) (`a = b << c`) |
| 569 | +4 | `xnor`| Bitwise xnor (`a = b ^ (!c)`). |
| 570 | +other| - | Reserved and must not be used |
| 571 | + |
| 572 | +And operation width: |
| 573 | + |
| 574 | +`width`| Bits |
| 575 | +-------|------ |
| 576 | +0 | 8 |
| 577 | +1 | 16 |
| 578 | +2 | 32 |
| 579 | +3 | Reserved and must not be used |
| 580 | + |
| 581 | +All operations first truncate their operands to the given bit width, |
| 582 | +then perform the operation with overflow checking on that size. The |
| 583 | +result always fits within the bit width of the operation. |
| 584 | + |
| 585 | +Operations set `$of` and `$err` similarly to their 64-bit counterparts. |
| 586 | +`XNOR` has no counterpart, and it always clears both `$of` and `$err`. |
| 587 | + |
| 588 | +Panic if: |
| 589 | + |
| 590 | +- Reserved bits of the immediate are set |
| 591 | +- `$rA` is a [reserved register](./index.md#semantics) |
| 592 | + |
540 | 593 | ### `NOOP`: No operation |
541 | 594 |
|
542 | 595 | | | | |
@@ -1383,6 +1436,36 @@ Panic if: |
1383 | 1436 | - `$rA` is a [reserved register](./index.md#semantics) |
1384 | 1437 | - `$rB + imm + 1` overflows or `> VM_MAX_RAM` |
1385 | 1438 |
|
| 1439 | +### `LQW`: Load quarter word |
| 1440 | + |
| 1441 | +| | | |
| 1442 | +|-------------|----------------------------------------------------------------------| |
| 1443 | +| Description | A quarter word is loaded from the specified address offset by `imm`. | |
| 1444 | +| Operation | ```$rA = MEM[$rB + (imm * 2), 2];``` | |
| 1445 | +| Syntax | `lqw $rA, $rB, imm` | |
| 1446 | +| Encoding | `0x00 rA rB i i` | |
| 1447 | +| Notes | | |
| 1448 | + |
| 1449 | +Panic if: |
| 1450 | + |
| 1451 | +- `$rA` is a [reserved register](./index.md#semantics) |
| 1452 | +- `$rB + (imm * 2) + 2` overflows or `> VM_MAX_RAM` |
| 1453 | + |
| 1454 | +### `LHW`: Load half word |
| 1455 | + |
| 1456 | +| | | |
| 1457 | +|-------------|----------------------------------------------------------------------| |
| 1458 | +| Description | A half word is loaded from the specified address offset by `imm`. | |
| 1459 | +| Operation | ```$rA = MEM[$rB + (imm * 4), 4];``` | |
| 1460 | +| Syntax | `lhw $rA, $rB, imm` | |
| 1461 | +| Encoding | `0x00 rA rB i i` | |
| 1462 | +| Notes | | |
| 1463 | + |
| 1464 | +Panic if: |
| 1465 | + |
| 1466 | +- `$rA` is a [reserved register](./index.md#semantics) |
| 1467 | +- `$rB + (imm * 4) + 4` overflows or `> VM_MAX_RAM` |
| 1468 | + |
1386 | 1469 | ### `LW`: Load word |
1387 | 1470 |
|
1388 | 1471 | | | | |
@@ -1565,6 +1648,31 @@ Panic if: |
1565 | 1648 | - `$rA + imm + 1` overflows or `> VM_MAX_RAM` |
1566 | 1649 | - The memory range `MEM[$rA + imm, 1]` does not pass [ownership check](./index.md#ownership) |
1567 | 1650 |
|
| 1651 | +### `SQW`: Store quarter word |
| 1652 | + |
| 1653 | +| | | |
| 1654 | +|-------------|-----------------------------------------------------------------------------------------------| |
| 1655 | +| Description | The two least significant bytes of of `$rB` is stored at the address `$rA` offset by `imm`. | |
| 1656 | +| Operation | ```MEM[$rA + (imm * 2), 2] = $rB;``` | |
| 1657 | +| Syntax | `sqw $rA, $rB, imm` | |
| 1658 | +| Encoding | `0x00 rA rB i i` | |
| 1659 | +| Notes | | |
| 1660 | + |
| 1661 | +### `SHW`: Store half word |
| 1662 | + |
| 1663 | +| | | |
| 1664 | +|-------------|-----------------------------------------------------------------------------------------------| |
| 1665 | +| Description | The four least significant bytes of of `$rB` is stored at the address `$rA` offset by `imm`. | |
| 1666 | +| Operation | ```MEM[$rA + (imm * 4), 4] = $rB;``` | |
| 1667 | +| Syntax | `shw $rA, $rB, imm` | |
| 1668 | +| Encoding | `0x00 rA rB i i` | |
| 1669 | +| Notes | | |
| 1670 | + |
| 1671 | +Panic if: |
| 1672 | + |
| 1673 | +- `$rA + (imm * 4) + 4` overflows or `> VM_MAX_RAM` |
| 1674 | +- The memory range `MEM[$rA + (imm * 4), 4]` does not pass [ownership check](./index.md#ownership) |
| 1675 | + |
1568 | 1676 | ### `SW`: Store word |
1569 | 1677 |
|
1570 | 1678 | | | | |
|
0 commit comments