owned this note
owned this note
Published
Linked with GitHub
# ZKASM Feijoa Features
## SAVE, RESTORE
Feature to save and restore registers. The registers involved are B, C, D, E, RR, RCX, and RID. Also, the *op* was saved. The op saved is restored as FREE INPUT (\$). The RID register (Restore ID) is an internal register used to save and restore, avoid the use, or modify the RID register.
The syntax for SAVE is with registers SAVE(B,C,D,E,RR,RCX), but also you could use SAVE without specifying registers. In the case of RESTORE, it always was without specifying registers.
Register A isn't saved because it's usually used as a return value. It's possible to save register A (or others not included) using op:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">SAVE</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">D</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">RCX</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"></span><span style="color: #008000;">; some code</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RESTORE</span></div></div>
This feature introduce's a change on RETURN, now RETURN using next value of RR, means it's compatible something like:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; using next value of RR, it's value saved on tmpRR</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RETURN</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">tmpRR</span><span style="color: #3b3b3b;">)</span></div></div>
Since Register RR is saved, we don't worry about RR throwing CALLs that use save and restore. We write recursive functions (but we shouldn't use them). An example of a typical factorial recursive function:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #001080;">fact</span><span style="color: #3b3b3b;">: </span></div><div><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">SAVE</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">D</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">RCX</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; check if direct case (A == 1)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">1</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> $ :</span><span style="color: #0000ff;">EQ</span><span style="color: #3b3b3b;">,</span><span style="color: #af00db;">JMPC</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">fact_finish</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; store current value of A in C</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; call again to fact with A - 1</span></div><div><span style="color: #3b3b3b;"> $ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">SUB</span><span style="color: #3b3b3b;">,</span><span style="color: #af00db;">CALL</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">fact</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; A * fact(A - 1)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">C</span></div><div><span style="color: #3b3b3b;"> ${A * B} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH</span></div><br><div><span style="color: #001080;">fact_finish</span><span style="color: #3b3b3b;">: </span></div><div><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RESTORE</span><span style="color: #3b3b3b;">,</span><span style="color: #af00db;">RETURN</span></div></div>
SAVE and RESTORE are compatible with JMP, JMPx, CALL, and MSTORE. Also, SAVE is compatible with MLOAD. RESTORE is incompatible with restore registers assignations (dual assignation between restore and left assignation). For example:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;"> $ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RESTORE</span><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; ERROR: because B it's restored</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; cannot use B,C,D,E,RR,RCX,RID</span></div><br><div><span style="color: #3b3b3b;"> $ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RESTORE</span><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; OK: because A it isn't restored </span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; really it's restored op as freeinput</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">30</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">10</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">SAVE</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">15</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> $ </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RESTORE</span><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; OK: B isn't assigned, after RESTORE</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; A contains value of op when SAVE added</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; with value of B before restore</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; after RESTORE A = 25, B = 30</span></div></div>
Each save must be restored precisely once. At the end of the program, all saves without restoration must be cleaned because if not, **proof generation fails**. You would have non-restored saves, for example, if you use jmp (OOC) or similar.For this reason, this code must be called near the end of the program.
<div style="color: #3b3b3b;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #0000ff;">VAR</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">GLOBAL</span><span style="color: #3b3b3b;"> </span><span style="color: #001080;">lastRID</span></div><br><div><span style="color: #001080;">clearPedingRestores</span><span style="color: #3b3b3b;">:</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;"> </span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">SAVE</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">D</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">RCX</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RID</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">lastRID</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #001080;">clearPedingRestores_loop</span><span style="color: #3b3b3b;">:</span></div><div><span style="color: #3b3b3b;"> ${getPendingRID(mem.lastRID)} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RID</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPN</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">clearPedingRestores_end</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RESTORE</span><span style="color: #3b3b3b;">, </span><span style="color: #af00db;">JMP</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">clearPedingRestores_loop</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #001080;">clearPedingRestores_end</span><span style="color: #3b3b3b;">:</span></div><div><span style="color: #3b3b3b;"> $ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RID</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">lastRID</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RESTORE</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RID</span></div></div>
## Assume Free Input
When we use an operation with "single" FREE INPUT (\$), the executor fills the value because it knows how to calculate it. Still, after validating this non-trust calculation, use the op, not the FREE INPUT. This behavior doesn't make much sense, especially regarding memory operation.
With the internal assumeFree flag, we indicate to the processor that it has to verify the FREE INPUT, not the op. This behavior could be used with memory-style instructions like MLOAD and HASHx. In assembly, to indicate it, we use the prefix F_ on instructions, like F_MLOAD, F_HASHP, etc. For example:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; increment value of B with contents of var1</span></div><br><div><span style="color: #008000;">; using MLOAD (worse case) - 4 steps</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">tmpC</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">tmpC</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; using F_MLOAD - 1 step</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">F_MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">)</span></div></div>
We could use assumeFree with HASH, for example:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; increment value of B with contents of HASHP</span></div><br><div><span style="color: #008000;">; using HASHP1 (worse case)</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">tmpC</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHP1</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">tmpC</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; using F_HASHP1</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">F_HASHP1</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">)</span></div><br></div>
With this feature, sense introduces a sugar syntax for memory access, using the name of a variable without F_MLOAD or MSTORE. For example:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; equivalent lines</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">F_MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #001080;">var1</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><br><div><span style="color: #008000;">; equivalent lines (MSTORE because storing op)</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #001080;">var1</span></div><br><div><span style="color: #008000;">; ERROR: two memory access</span></div><div><span style="color: #001080;">var2</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #001080;">var1</span></div></div>
To access arrays it's better to use [] syntax. For example:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; equivalent lines</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">F_MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #000000;">+</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">5</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">F_MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">[</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">5</span><span style="color: #3b3b3b;">])</span></div><div><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">[</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">5</span><span style="color: #3b3b3b;">] </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><br><div><span style="color: #008000;">; equivalent lines</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #000000;">+</span><span style="color: #098658;">3</span><span style="color: #000000;">*</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #3b3b3b;"> :</span><span style="color: #001080;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">[</span><span style="color: #098658;">3</span><span style="color: #000000;">*</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">])</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #001080;">var1</span><span style="color: #3b3b3b;">[</span><span style="color: #098658;">3</span><span style="color: #000000;">*</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">]</span></div></div>
With this feature, has sense reorganizes the use of addrRel (the relative/dynamic part of address calculated on runtime using E and RR registers). One address has two parts: a static part and a dynamic/relative part. The idea is that each instruction/part (mload/mstore, jmpAddr, elseAddr) has its static part and a flag indicating if use dynamic/relative part. If two instructions/parts have the same relative part, they could share it. Also, change flags ind and indE, now they are multipliers (as described in pil). For example:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPNZ</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">label</span><span style="color: #000000;">+</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPNZ</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">label</span><span style="color: #000000;">+</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">labelZ</span><span style="color: #3b3b3b;">, @</span><span style="color: #001080;">labelNZ</span><span style="color: #000000;">+</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">) </span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">labelZ</span><span style="color: #000000;">+</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">, @</span><span style="color: #001080;">labelNZ</span><span style="color: #000000;">+</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; OK: addrRel is the same 2*E</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">labelZ</span><span style="color: #000000;">+</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">, @</span><span style="color: #001080;">labelNZ</span><span style="color: #000000;">+</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; ERROR: addrRel isn't the same 2*E vs E</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">labelZ</span><span style="color: #000000;">+</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">, @</span><span style="color: #001080;">labelNZ</span><span style="color: #000000;">+</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; ERROR: addrRel isn't the same E vs RR</span></div><br><div><span style="color: #008000;">; VALID options</span></div><div><span style="color: #3b3b3b;">$ :</span><span style="color: #0000ff;">HASHP</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">), </span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">data</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ :</span><span style="color: #0000ff;">HASHP</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #000000;">-</span><span style="color: #098658;">2</span><span style="color: #3b3b3b;">), </span><span style="color: #0000ff;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">data</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ :</span><span style="color: #0000ff;">HASHP</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">), </span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">data</span><span style="color: #3b3b3b;">), </span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">label</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">labelElse</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; addrRel=3*RR-2*E, offset=data+5, jmpAddr=@lIFZ+2 elseAddr=@lELSE</span></div><div><span style="color: #3b3b3b;">$ :</span><span style="color: #0000ff;">HASHP</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">5</span><span style="color: #3b3b3b;">), </span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">data</span><span style="color: #3b3b3b;">[</span><span style="color: #098658;">3</span><span style="color: #000000;">*</span><span style="color: #0000ff;">RR</span><span style="color: #000000;">-</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">5</span><span style="color: #3b3b3b;">]), </span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">lIFZ</span><span style="color: #000000;">+</span><span style="color: #098658;">3</span><span style="color: #000000;">*</span><span style="color: #0000ff;">RR</span><span style="color: #000000;">-</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">2</span><span style="color: #3b3b3b;">,@</span><span style="color: #001080;">lELSE</span><span style="color: #000000;">+</span><span style="color: #098658;">3</span><span style="color: #000000;">*</span><span style="color: #0000ff;">RR</span><span style="color: #000000;">-</span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">matriz_20x30</span><span style="color: #3b3b3b;">[</span><span style="color: #0000ff;">E</span><span style="color: #000000;">*</span><span style="color: #098658;">30</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">])</span></div></div>
In hash operations, a dynamic address is usually used. To allow using hash with these indirections, define that the hash address always uses E with an offset that could be zero. This means that now, we can't use RR or only constant for the hash address. Some examples:
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHK32</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">;OK</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHPDIGEST</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">3</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">;OK</span></div><br><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHK32</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">0</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">;ERROR: Always use E0</span></div><br><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHPDIGEST</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">3</span><span style="color: #3b3b3b;">),</span><span style="color: #0000ff;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">values</span><span style="color: #3b3b3b;">[</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">]) </span><span style="color: #008000;">;OK</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHPDIGEST</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">3</span><span style="color: #3b3b3b;">),</span><span style="color: #0000ff;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">values</span><span style="color: #3b3b3b;">[</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">]) </span><span style="color: #008000;">;OK</span></div><br><div><span style="color: #008000;">; addrRel=3*E, addr=values+3*E, hashAddr= E0+3</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHPDIGEST</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #000000;">+</span><span style="color: #098658;">3</span><span style="color: #3b3b3b;">),</span><span style="color: #0000ff;">MSTORE</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">values</span><span style="color: #3b3b3b;">[</span><span style="color: #098658;">3</span><span style="color: #000000;">*</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">])</span><span style="color: #008000;">;OK</span></div></div>
The difference between instruction CALL and JMP is that CALL stores zkPC + 1 in register RR, but the rest is the same. This version introduces the conditional calls to avoid the parts of ROM that appear legacy code that sets RR with zkPC. With conditional calls, always set register RR, independent of condition. Some examples:
<div style="color: #3b3b3b;margin-bottom: 10px;background-color: #f8f8f8;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; CALL if OP0 is zero</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_Z</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">label</span><span style="color: #000000;">+</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_NZ</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_Z</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">labelElse</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; CALL if carry</span></div><div><span style="color: #3b3b3b;">$ :</span><span style="color: #0000ff;">EQ</span><span style="color: #3b3b3b;">,</span><span style="color: #af00db;">CALL_C</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ :</span><span style="color: #0000ff;">EQ</span><span style="color: #3b3b3b;">,</span><span style="color: #af00db;">CALL_NC</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ :</span><span style="color: #0000ff;">EQ</span><span style="color: #3b3b3b;">,</span><span style="color: #af00db;">CALL_C</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">label</span><span style="color: #000000;">+</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">labelElse</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; CALL if OP0 is 32 bit negative </span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_N</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_N</span><span style="color: #3b3b3b;">(@</span><span style="color: #001080;">label</span><span style="color: #000000;">+</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">labelElse</span><span style="color: #3b3b3b;">)</span></div><br></div>
## HASH bytes
With this feature, there are two possibilities for specifying hash bytes: dynamically with the D0 register and statically with instruction. To use statically, you must call HASHXn, where n is the number of bytes (1-32). If you call HASHX without n, use the D0 register as the number of bytes.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; hash 3 bytes of A</span></div><div><span style="color: #098658;">3</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHK</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; hash 1 byte of A</span></div><div><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHK1</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; hash 3 bytes of A</span></div><div><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHK3</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; with hash-bytes also continue using dynamic number of bytes</span></div><div><span style="color: #098658;">4</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHK</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; hash 32 bytes of A</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">HASHK32</span><span style="color: #3b3b3b;">(</span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;">) </span></div><br></div>
## ASSERT Byte Free Input
This feature guarantees (assert) that FREE0 is a valid byte; if FREE0 has a nonvalid byte, the proof cannot be generated. For this reason, we must be sure that the value calculated in FREE input has a byte value (0-255).
The use is different than $0 because it does not check the free input; it only loads to op the FREE0, which is limited to a field element (less than 64 bits). FreeByte is similar to JMPN; you must be sure that the value is a valid 32-bit value. FreeByte avoids MAP (malicious prover), returning a bigger value. Some examples:
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; a MAP only could return a value from 0 to 255</span></div><div><span style="color: #008000;">; using to rebuild byte to byte for example</span></div><div><span style="color: #3b3b3b;">$BYTE{A & 0xFF} </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">*</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">256</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><br><div><span style="color: #008000;">; using to limited jmp tables</span></div><div><span style="color: #3b3b3b;">${A & 0xFF} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPN</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">assertFails</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #098658;">255</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">-</span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPN</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">assertFails</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">table</span><span style="color: #000000;">+</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">),</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">somethingToLoad</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #008000;">; using to limited jmp tables</span></div><div><span style="color: #3b3b3b;">$BYTE{A & 0xFF} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span></div><div><span style="color: #3b3b3b;">$ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">table</span><span style="color: #000000;">+</span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;">),</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">somethingToLoad</span><span style="color: #3b3b3b;">)</span></div></div>
FreeByte is incompatible with JMPN, because use same flags.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;">$BYTE{A & 0xFF} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">isZero</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">;OK, it isn't JMPN</span></div><br><div><span style="color: #3b3b3b;">$BYTE{A & 0xFF} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPN</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">isZero</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">;ERROR: use JMPN and FreeByte</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">;no sense, RR must be 0-255, JMPN never jumps.</span></div><br><div><span style="color: #3b3b3b;">$BYTE{A & 0xFF} </span><span style="color: #000000;">-</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">3</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">RR</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPN</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">isZero</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">;ERROR: use JMPN and FreeByte</span></div></div>
## MEM_ALIGN with variable length
One previous limitation of MEM_ALIGN was that it only worked with 32-byte values, and it wasn't useful to read bytes over 256-bit memory. For this reason, modify MEM_ALIGN to allow specifying the number of bytes. With this new PIL2 design compatible with PIL1, we could add free extra features, and the final solution is eight (8) columns cheaper than the precedent.
These extra features are alignment (left, right) and endian (little, big). To be compatible with the current ROM code by default right-alignment and big-endian. To avoid using more registers, all these parameters are coded in a mode; for compatibility, use C0 to specify this mode. The formula for this mode is:
```
mode = offset_bytes (0-64)
+ 128 * length (0-32, 0 for compatibility is equivalent to 32)
+ 8192 * left_alignment (0-1)
+ 16384 * little_endian (0-1)
```
At this point, it's better to review the features of mem_align. To read from memory, we need to read two consecutive addresses (M0, M1) and store them on registers A and B, respectively. Use C to store mode and OP to obtain bytes read.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; MEM_ALIGN_RD</span></div><div><span style="color: #008000;">; </span></div><div><span style="color: #008000;">; <───────────── 32 bytes ───────────> <───────────── 32 bytes ───────────></span></div><div><span style="color: #008000;">; ┌────────────────────────────────────┬────────────────────────────────────┐</span></div><div><span style="color: #008000;">; M0 (A) │ M0(A) ┆ │ M1 (B)┆ │</span></div><div><span style="color: #008000;">; └────────────────────────────────────┴────────────────────────────────────┘</span></div><div><span style="color: #008000;">; │ │ │ │ │ │ │ </span></div><div><span style="color: #008000;">; ▼ ▼ ▼ ▼ ▼ ▼ ▼ </span></div><div><span style="color: #008000;">; <── offset(bytes) ──>┌───────────────────────┐ </span></div><div><span style="color: #008000;">; │V(OP) │ </span></div><div><span style="color: #008000;">; └───────────────────────┘ </span></div><div><span style="color: #008000;">; <─── length (bytes) ──></span></div></div>
Another parameter of mem_align is its alignment, which defines how bytes read are stored inside the 32-byte register. If the length is 32, the left and right alignments are the same.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">;</span></div><div><span style="color: #008000;">; <───────────── 32 bytes ───────────></span></div><div><span style="color: #008000;">; ┌────────────┬───────────────────────┐</span></div><div><span style="color: #008000;">; RIGHT ALIGNMENT │ 000...000 │ V(OP) │</span></div><div><span style="color: #008000;">; (default) └────────────┴───────────────────────┘</span></div><div><span style="color: #008000;">; <─── length (bytes) ──></span></div><div><span style="color: #008000;">;</span></div><div><span style="color: #008000;">; <───────────── 32 bytes ───────────></span></div><div><span style="color: #008000;">; ┌───────── ─────────────┬───────────┐</span></div><div><span style="color: #008000;">; LEFT ALIGNMENT │ V(OP) │ 000...000 │</span></div><div><span style="color: #008000;">; └───────────────────────┴───────────┘</span></div><div><span style="color: #008000;">; <─── length (bytes) ──></span></div><div><span style="color: #008000;">;</span></div></div>
The last parameter of mem_align is its endian type, which defines how the ordered bytes are read. Big endian takes bytes as they are in memory, while little endian reverses them.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">;</span></div><div><span style="color: #008000;">; <───────────── 32 bytes ───────────> <───────────── 32 bytes ───────────></span></div><div><span style="color: #008000;">; ┌────────────────────────────────────┬────────────────────────────────────┐</span></div><div><span style="color: #008000;">; M0 (A) │ M0(A) A2 A1 A0 │ B31 B30 M1(B) │</span></div><div><span style="color: #008000;">; └────────────────────────────────────┴────────────────────────────────────┘</span></div><div><span style="color: #008000;">; │ │ │ │ │ </span></div><div><span style="color: #008000;">; ▼ ▼ ▼ ▼ ▼ </span></div><div><span style="color: #008000;">; ┌────────────────────────┐ </span></div><div><span style="color: #008000;">; BIG ENDIAN V(OP)| A2 A1 A0 B31 B30 │ </span></div><div><span style="color: #008000;">; (default) └────────────────────────┘ </span></div><div><span style="color: #008000;">;</span></div><div><span style="color: #008000;">; ┌────────────────────────┐ </span></div><div><span style="color: #008000;">; LITTLE ENDIAN V(OP)| B30 B31 A0 A1 A2 A3 │ </span></div><div><span style="color: #008000;">; └────────────────────────┘ </span></div><br></div>
Finally, operation MEM_ALIGN_WR, in this case, verifies D as W0 and E as W1, indicating how memory M0 and M1 were modified after "writing" n bytes of OP with offset. The extra parameters alignment and endian define how to take this byte from V (OP).
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; <───────────── 32 bytes ───────────> <───────────── 32 bytes ───────────></span></div><div><span style="color: #008000;">; ┌────────────────────────────────────┬────────────────────────────────────┐</span></div><div><span style="color: #008000;">; │ M0(A) │ M1 (B) │</span></div><div><span style="color: #008000;">; └────────────────────────────────────┴────────────────────────────────────┘</span></div><div><span style="color: #008000;">; │ │ │ │ │ │ │ │ │ </span></div><div><span style="color: #008000;">; │ │ │ │ <─── length (bytes) ──> │ │ │ │ │ </span></div><div><span style="color: #008000;">; <── offset(bytes) ──>┌───────────────────────┐ │ │ │ │ │ </span></div><div><span style="color: #008000;">; │ │ │ │ │V(OP) │ │ │ │ │ │ </span></div><div><span style="color: #008000;">; │ │ │ │ └───────────────────────┘ │ │ │ │ │ </span></div><div><span style="color: #008000;">; │ │ │ │ │ │ │ │ │ │ │ │ │ </span></div><div><span style="color: #008000;">; ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ </span></div><div><span style="color: #008000;">; ┌────────────────────────────────────┬────────────────────────────────────┐</span></div><div><span style="color: #008000;">; │ W0(D) ┆ │ W1 (E) ┆ │</span></div><div><span style="color: #008000;">; └────────────────────────────────────┴────────────────────────────────────┘</span></div></div>
Some examples for compatible cases:
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; #3168 w=[101376-101407]</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; ·---------·---------·---########################################</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; ########################--·---------·---------·---------·-------</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #0000ff;"> B</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">12n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #3b3b3b;"> $ </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MEM_ALIGN_RD</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3Bn</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ASSERT</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; #3172 w=[101504-101535]</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; ·---------·---------·---########################################</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x101112131415161718191A1B0E1E2E3E4E5E6E7E8E9EAEBECEDEEEEF0F1F2F3Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">12n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; ########################--·---------·---------·---------·-------</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x4F5F6F7F8F9FAFBFCFDFEFFF3C3D3E3F404142434445464748494A4B4C4D4E4Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">E</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x0E1E2E3E4E5E6E7E8E9EAEBECEDEEEEF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFFFn</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MEM_ALIGN_WR</span></div><br></div>
In this new version, MEM_ALIGN_WR8 does not exist because it's a particular case of MEM_ALIGN_WR with length = 1. The only inconvenience is that you need to set registers B and E to zero.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">12n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">*</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">%</span><span style="color: #001080;">MA_LEN_FACTOR</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; ·---------·---------·---##----·---------·---------·---------·---</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x101112131415161718191A1BFF1D1E1F202122232425262728292A2B2C2D2E2Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">E</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x00000000000000000000000000000000000000000000000000000000000000FFn</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MEM_ALIGN_WR</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; supports dirty bytes on write</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; ·---------·---------·---##----·---------·---------·---------·---</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x101112131415161718191A1BFF1D1E1F202122232425262728292A2B2C2D2E2Fn</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">12n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">+</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">*</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">%</span><span style="color: #001080;">MA_LEN_FACTOR</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;">,</span><span style="color: #0000ff;">E</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0x0E1E2E3E4E5E6E7E8E9EAEBECEDEEEEF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFFFn</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MEM_ALIGN_WR</span></div><br></div>
## ARITH_MOD (modular arithmetic)
Given registers `A,B,C,D,op`, it checks whether the linear operation `A*B + C` is equal to `op` modulo `D`, i.e.:
$$
A · B + C = \text{op} \pmod{D}
$$
It can be used to optimized division-related operations. For example, it could be used to safely verify the remainder of a division. Say you want to compute/verify $A \% D$, you could use the modular arithmetic as follows:
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; Compute A%D and return it on register C</span></div><div><span style="color: #001080;">checkRem</span><span style="color: #3b3b3b;">:</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; A·1 + 0 = op (mod D)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">1</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">0</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #3b3b3b;"> ${A % D} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RETURN</span></div></div>
As a second example, addition modulo a prime `p` pre-feijoa was done as follows:
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #001080;">addFpBN254</span><span style="color: #3b3b3b;">:</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; 1] Compute and check the sum over Z</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; A·[1] + C = [D]·2²⁵⁶ + [E]</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; A·1 + C = op (mod BN254_P)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">1</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> $${var _addFpBN254_AC = A + C}</span></div><div><span style="color: #3b3b3b;"> ${_addFpBN254_AC >> 256} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #3b3b3b;"> ${_addFpBN254_AC} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; 2] Check it over Fp, that is, it must be satisfied that:</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; [BN254_P]·[(A+C) / p] + [(A+C) % p] = D·2²⁵⁶ + E</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; where C < BN254_P</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #000000;">%</span><span style="color: #001080;">BN254_P</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #3b3b3b;"> ${_addFpBN254_AC / const.BN254_P} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; quotient (256 bits)</span></div><div><span style="color: #3b3b3b;"> ${_addFpBN254_AC % const.BN254_P} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; residue (256 bits)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; 3] Check that the result is lower than BN254_P</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">1</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">LT</span><span style="color: #3b3b3b;">, </span><span style="color: #af00db;">RETURN</span></div></div>
using 2 standard arithmetic (one for controlling the possible overflow and the other for ensuring that `a = q·b + r`) and one binary to check the result is alias-free.
With the modular arithmetic, this could be expressed as:
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #001080;">addFpBN254</span><span style="color: #3b3b3b;">:</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; A·1 + C = op (mod BN254_P)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">1</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #000000;">%</span><span style="color: #001080;">BN254_P</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #3b3b3b;"> ${(A + C) % D} </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">E</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">RETURN</span></div></div>
More examples:
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #008000;">; 1] 0·0 + 0 = 0 (mod 1)</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><br><div><span style="color: #008000;">; 2] 1·0 + 0 = 0 (mod 1)</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><br><div><span style="color: #008000;">; 3] 0·1 + 0 = 0 (mod 1)</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><br><div><span style="color: #008000;">; 4] 0·0 + 1 = 0 (mod 1)</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><br><div><span style="color: #008000;">; 5] x·y + z = 0 (mod 1)</span></div><div><span style="color: #098658;">82404511619898090395080044893130374032931121663279308706641192292251088604573n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #098658;">218016309922137699094797478333585171696794824697587846381595937510543687571n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #098658;">63787468536760849300814264976359137980835693562263609965507003207114627618515n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #098658;">1n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #098658;">0n</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><br><div><span style="color: #008000;">; 6] Small random test</span></div><div><span style="color: #098658;">17741</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #098658;">901868</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #098658;">536729</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #098658;">355064</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #098658;">327885</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><br><div><span style="color: #008000;">; 7] Big random test</span></div><div><span style="color: #098658;">19056371982582167475593876340225319134850470258276413387066558886464698322210n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span></div><div><span style="color: #098658;">20914269056602289532121456290808074920610800738424321255588157751277776260456n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">B</span></div><div><span style="color: #098658;">10634756649036098220049242607700175280465139227303175868315978071819374369450n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">C</span></div><div><span style="color: #098658;">10707315989258942200484412153631767731310293817155149881083576310392120779817n</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">=></span><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span></div><div><span style="color: #098658;">6920609207119167395959131992066380589796703421563779918050515844861464646812n</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">ARITH_MOD</span></div><br></div>
Since we ensure via lookups that $0 \leq \text{op} < D$, it cannot be used with $D = 0$. This is consistent with the definition because division by 0 is not well-defined.
It correctly works with $D = 1$, even tho the arithmetic check might be unoptimal for this particular case.
## Conditional Constant
This feature allows to define a more readable syntax for comparing values of op0. Internally, a constant value was added to op0 before comparison.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; without cond const feature</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span><span style="color: #3b3b3b;"> :</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">bytes</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">-</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">32</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMPZ</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">labelD32</span><span style="color: #3b3b3b;">)</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #008000;">; with cond const feature</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">D</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">32</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">labelD32</span><span style="color: #3b3b3b;">),</span><span style="color: #0000ff;">MLOAD</span><span style="color: #3b3b3b;">(</span><span style="color: #001080;">bytes</span><span style="color: #3b3b3b;">)</span></div></div>
This constant value is calculated in compilation time. It could contain constants, numbers, and more complex expressions, all of which must be resolved in compilation time.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #000000;">%</span><span style="color: #001080;">K1</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #000000;">+</span><span style="color: #098658;">10</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #000000;">%</span><span style="color: #001080;">K1</span><span style="color: #000000;">+</span><span style="color: #098658;">10</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">A</span><span style="color: #000000;">-</span><span style="color: #098658;">10</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">2</span><span style="color: #000000;">*%</span><span style="color: #001080;">K1</span><span style="color: #000000;">-</span><span style="color: #098658;">10</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #098658;">2</span><span style="color: #000000;">*</span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #000000;">%</span><span style="color: #001080;">K1</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">==</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">230</span><span style="color: #3b3b3b;"> </span><span style="color: #000000;">?</span><span style="color: #3b3b3b;"> </span><span style="color: #098658;">460</span><span style="color: #3b3b3b;"> : </span><span style="color: #098658;">2</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">)</span></div></div>
This feature has six (6) operations. EQ and NE use JMPZ internally, while LT, LE, GT, and GE use JMPN. For this reason, EQ and NE work with all finite fields, but LT, LE, GT, and GE work only with 32 bits (positive or negative), considering subtracting constants. Also, all these "instructions" are available with CALL.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; equal</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_NE</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; not equal</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_LT</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; less than (32 bits)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_LE</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; less or equal than (32 bits)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_GT</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; greater than (32 bits)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_GE</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; greater or equal than (32 bits)</span></div><br><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; equal</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_NE</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; not equal</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_LT</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; less than (32 bits)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_LE</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; less or equal than (32 bits)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_GT</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; greater than (32 bits)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_GE</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">) </span><span style="color: #008000;">; greater or equal than (32 bits)</span></div></div>
These instructions could define else-address when the condition is false.
<div style="color: #3b3b3b;background-color: #f8f8f8;margin-bottom: 10px;padding: 10px;font-family: 'Dejavu Sans Mono','Ubuntu Mono','Roboto Mono','Source Code Pro','JetBrains Mono','Droid Sans Mono', 'monospace', monospace, 'Droid Sans Mono', 'monospace', monospace;font-weight: normal;font-size: 13px;line-height: 18px;white-space: pre;"><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">JMP_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">elseLabel</span><span style="color: #3b3b3b;">)</span></div><div><span style="color: #3b3b3b;"> </span><span style="color: #0000ff;">A</span><span style="color: #3b3b3b;"> :</span><span style="color: #af00db;">CALL_EQ</span><span style="color: #3b3b3b;">(</span><span style="color: #098658;">230</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">label</span><span style="color: #3b3b3b;">, </span><span style="color: #001080;">elseLabel</span><span style="color: #3b3b3b;">)</span></div></div>
## 384-bit Arithmetic
Described [here](https://hackmd.io/5pZOs4Y1RKeRsFVr9ZQLfg).
# Open Points
- recover instruction F_MSTORE
- recover hash address as only constant
- free-feature to allow hash address no consecutive (distance max: 256k)
- use prefix \_\_ (or \_) for file scope labels and variables
# TBD for Next Release
- ARITH_DIV DIV(A,B)=\[OP,D\] D < B
- free_bits
- ASSERT_U32
- LOOP_RR or similar
- MINC(constant_32bits)
- MDEC(constant_32bits)
- MSET(fromAddr, toAddr, value)
- MCOPY(addr1, addr2) copy a word between positions