| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| |
| <html> |
| |
| <head> |
| <title>Bytecode for the Dalvik VM</title> |
| <link rel=stylesheet href="dalvik-bytecode.css"> |
| </head> |
| |
| <body> |
| |
| <h1>Bytecode for the Dalvik VM</h1> |
| <p>Copyright © 2007 The Android Open Source Project |
| |
| <h2>General Design</h2> |
| |
| <ul> |
| <li>The machine model and calling conventions are meant to approximately |
| imitate common real architectures and C-style calling conventions: |
| <ul> |
| <li>The VM is register-based, and frames are fixed in size upon creation. |
| Each frame consists of a particular number of registers (specified by |
| the method) as well as any adjunct data needed to execute the method, |
| such as (but not limited to) the program counter and a reference to the |
| <code>.dex</code> file that contains the method. |
| </li> |
| <li>When used for bit values (such as integers and floating point |
| numbers), registers are considered 32 bits wide. Adjacent register |
| pairs are used for 64-bit values. There is no alignment requirement |
| for register pairs. |
| </li> |
| <li>When used for object references, registers are considered wide enough |
| to hold exactly one such reference. |
| </li> |
| <li>In terms of bitwise representation, <code>(Object) null == (int) |
| 0</code>. |
| </li> |
| <li>The <i>N</i> arguments to a method land in the last <i>N</i> registers |
| of the method's invocation frame, in order. Wide arguments consume |
| two registers. Instance methods are passed a <code>this</code> reference |
| as their first argument. |
| </li> |
| </ul> |
| <li>The storage unit in the instruction stream is a 16-bit unsigned quantity. |
| Some bits in some instructions are ignored / must-be-zero. |
| </li> |
| <li>Instructions aren't gratuitously limited to a particular type. For |
| example, instructions that move 32-bit register values without interpretation |
| don't have to specify whether they are moving ints or floats. |
| </li> |
| <li>There are separately enumerated and indexed constant pools for |
| references to strings, types, fields, and methods. |
| </li> |
| <li>Bitwise literal data is represented in-line in the instruction stream.</li> |
| <li>Because, in practice, it is uncommon for a method to need more than |
| 16 registers, and because needing more than eight registers <i>is</i> |
| reasonably common, many instructions are limited to only addressing |
| the first 16 |
| registers. When reasonably possible, instructions allow references to |
| up to the first 256 registers. In addition, some instructions have variants |
| that allow for much larger register counts, including a pair of catch-all |
| <code>move</code> instructions that can address registers in the range |
| <code>v0</code> – <code>v65535</code>. |
| In cases where an instruction variant isn't |
| available to address a desired register, it is expected that the register |
| contents get moved from the original register to a low register (before the |
| operation) and/or moved from a low result register to a high register |
| (after the operation). |
| </li> |
| <li>There are several "pseudo-instructions" that are used to hold |
| variable-length data payloads, which are referred to by regular |
| instructions (for example, |
| <code>fill-array-data</code>). Such instructions must never be |
| encountered during the normal flow of execution. In addition, the |
| instructions must be located on even-numbered bytecode offsets (that is, |
| 4-byte aligned). In order to meet this requirement, dex generation tools |
| must emit an extra <code>nop</code> instruction as a spacer if such an |
| instruction would otherwise be unaligned. Finally, though not required, |
| it is expected that most tools will choose to emit these instructions at |
| the ends of methods, since otherwise it would likely be the case that |
| additional instructions would be needed to branch around them. |
| </li> |
| <li>When installed on a running system, some instructions may be altered, |
| changing their format, as an install-time static linking optimization. |
| This is to allow for faster execution once linkage is known. |
| See the associated |
| <a href="instruction-formats.html">instruction formats document</a> |
| for the suggested variants. The word "suggested" is used advisedly; |
| it is not mandatory to implement these. |
| </li> |
| <li>Human-syntax and mnemonics: |
| <ul> |
| <li>Dest-then-source ordering for arguments.</li> |
| <li>Some opcodes have a disambiguating name suffix to indicate the type(s) |
| they operate on: |
| <ul> |
| <li>Type-general 32-bit opcodes are unmarked.</li> |
| <li>Type-general 64-bit opcodes are suffixed with <code>-wide</code>.</li> |
| <li>Type-specific opcodes are suffixed with their type (or a |
| straightforward abbreviation), one of: <code>-boolean</code> |
| <code>-byte</code> <code>-char</code> <code>-short</code> |
| <code>-int</code> <code>-long</code> <code>-float</code> |
| <code>-double</code> <code>-object</code> <code>-string</code> |
| <code>-class</code> <code>-void</code>.</li> |
| </ul> |
| </li> |
| <li>Some opcodes have a disambiguating suffix to distinguish |
| otherwise-identical operations that have different instruction layouts |
| or options. These suffixes are separated from the main names with a slash |
| ("<code>/</code>") and mainly exist at all to make there be a one-to-one |
| mapping with static constants in the code that generates and interprets |
| executables (that is, to reduce ambiguity for humans). |
| </li> |
| <li>In the descriptions here, the width of a value (indicating, e.g., the |
| range of a constant or the number of registers possibly addressed) is |
| emphasized by the use of a character per four bits of width. |
| </li> |
| <li>For example, in the instruction |
| "<code>move-wide/from16 vAA, vBBBB</code>": |
| <ul> |
| <li>"<code>move</code>" is the base opcode, indicating the base operation |
| (move a register's value).</li> |
| <li>"<code>wide</code>" is the name suffix, indicating that it operates |
| on wide (64 bit) data.</li> |
| <li>"<code>from16</code>" is the opcode suffix, indicating a variant |
| that has a 16-bit register reference as a source.</li> |
| <li>"<code>vAA</code>" is the destination register (implied by the |
| operation; again, the rule is that destination arguments always come |
| first), which must be in the range <code>v0</code> – |
| <code>v255</code>.</li> |
| <li>"<code>vBBBB</code>" is the source register, which must be in the |
| range <code>v0</code> – <code>v65535</code>.</li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li>See the <a href="instruction-formats.html">instruction formats |
| document</a> for more details about the various instruction formats |
| (listed under "Op & Format") as well as details about the opcode |
| syntax. |
| </li> |
| <li>See the <a href="dex-format.html"><code>.dex</code> file format |
| document</a> for more details about where the bytecode fits into |
| the bigger picture. |
| </li> |
| </ul> |
| |
| <h2>Summary of Instruction Set</h2> |
| |
| <table class="instruc"> |
| <thead> |
| <tr> |
| <th>Op & Format</th> |
| <th>Mnemonic / Syntax</th> |
| <th>Arguments</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>00 10x</td> |
| <td>nop</td> |
| <td> </td> |
| <td>Waste cycles. |
| <p><b>Note:</b> |
| Data-bearing pseudo-instructions are tagged with this opcode, in which |
| case the high-order byte of the opcode unit indicates the nature of |
| the data. See "<code>packed-switch-payload</code> Format", |
| "<code>sparse-switch-payload</code> Format", and |
| "<code>fill-array-data-payload</code> Format" below.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>01 12x</td> |
| <td>move vA, vB</td> |
| <td><code>A:</code> destination register (4 bits)<br/> |
| <code>B:</code> source register (4 bits)</td> |
| <td>Move the contents of one non-object register to another.</td> |
| </tr> |
| <tr> |
| <td>02 22x</td> |
| <td>move/from16 vAA, vBBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> source register (16 bits)</td> |
| <td>Move the contents of one non-object register to another.</td> |
| </tr> |
| <tr> |
| <td>03 32x</td> |
| <td>move/16 vAAAA, vBBBB</td> |
| <td><code>A:</code> destination register (16 bits)<br/> |
| <code>B:</code> source register (16 bits)</td> |
| <td>Move the contents of one non-object register to another.</td> |
| </tr> |
| <tr> |
| <td>04 12x</td> |
| <td>move-wide vA, vB</td> |
| <td><code>A:</code> destination register pair (4 bits)<br/> |
| <code>B:</code> source register pair (4 bits)</td> |
| <td>Move the contents of one register-pair to another. |
| <p><b>Note:</b> |
| It is legal to move from <code>v<i>N</i></code> to either |
| <code>v<i>N-1</i></code> or <code>v<i>N+1</i></code>, so implementations |
| must arrange for both halves of a register pair to be read before |
| anything is written.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>05 22x</td> |
| <td>move-wide/from16 vAA, vBBBB</td> |
| <td><code>A:</code> destination register pair (8 bits)<br/> |
| <code>B:</code> source register pair (16 bits)</td> |
| <td>Move the contents of one register-pair to another. |
| <p><b>Note:</b> |
| Implementation considerations are the same as <code>move-wide</code>, |
| above.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>06 32x</td> |
| <td>move-wide/16 vAAAA, vBBBB</td> |
| <td><code>A:</code> destination register pair (16 bits)<br/> |
| <code>B:</code> source register pair (16 bits)</td> |
| <td>Move the contents of one register-pair to another. |
| <p><b>Note:</b> |
| Implementation considerations are the same as <code>move-wide</code>, |
| above.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>07 12x</td> |
| <td>move-object vA, vB</td> |
| <td><code>A:</code> destination register (4 bits)<br/> |
| <code>B:</code> source register (4 bits)</td> |
| <td>Move the contents of one object-bearing register to another.</td> |
| </tr> |
| <tr> |
| <td>08 22x</td> |
| <td>move-object/from16 vAA, vBBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> source register (16 bits)</td> |
| <td>Move the contents of one object-bearing register to another.</td> |
| </tr> |
| <tr> |
| <td>09 32x</td> |
| <td>move-object/16 vAAAA, vBBBB</td> |
| <td><code>A:</code> destination register (16 bits)<br/> |
| <code>B:</code> source register (16 bits)</td> |
| <td>Move the contents of one object-bearing register to another.</td> |
| </tr> |
| <tr> |
| <td>0a 11x</td> |
| <td>move-result vAA</td> |
| <td><code>A:</code> destination register (8 bits)</td> |
| <td>Move the single-word non-object result of the most recent |
| <code>invoke-<i>kind</i></code> into the indicated register. |
| This must be done as the instruction immediately after an |
| <code>invoke-<i>kind</i></code> whose (single-word, non-object) result |
| is not to be ignored; anywhere else is invalid.</td> |
| </tr> |
| <tr> |
| <td>0b 11x</td> |
| <td>move-result-wide vAA</td> |
| <td><code>A:</code> destination register pair (8 bits)</td> |
| <td>Move the double-word result of the most recent |
| <code>invoke-<i>kind</i></code> into the indicated register pair. |
| This must be done as the instruction immediately after an |
| <code>invoke-<i>kind</i></code> whose (double-word) result |
| is not to be ignored; anywhere else is invalid.</td> |
| </tr> |
| <tr> |
| <td>0c 11x</td> |
| <td>move-result-object vAA</td> |
| <td><code>A:</code> destination register (8 bits)</td> |
| <td>Move the object result of the most recent <code>invoke-<i>kind</i></code> |
| into the indicated register. This must be done as the instruction |
| immediately after an <code>invoke-<i>kind</i></code> or |
| <code>filled-new-array</code> |
| whose (object) result is not to be ignored; anywhere else is invalid.</td> |
| </tr> |
| <tr> |
| <td>0d 11x</td> |
| <td>move-exception vAA</td> |
| <td><code>A:</code> destination register (8 bits)</td> |
| <td>Save a just-caught exception into the given register. This must |
| be the first instruction of any exception handler whose caught |
| exception is not to be ignored, and this instruction must <i>only</i> |
| ever occur as the first instruction of an exception handler; anywhere |
| else is invalid.</td> |
| </tr> |
| <tr> |
| <td>0e 10x</td> |
| <td>return-void</td> |
| <td> </td> |
| <td>Return from a <code>void</code> method.</td> |
| </tr> |
| <tr> |
| <td>0f 11x</td> |
| <td>return vAA</td> |
| <td><code>A:</code> return value register (8 bits)</td> |
| <td>Return from a single-width (32-bit) non-object value-returning |
| method. |
| </td> |
| </tr> |
| <tr> |
| <td>10 11x</td> |
| <td>return-wide vAA</td> |
| <td><code>A:</code> return value register-pair (8 bits)</td> |
| <td>Return from a double-width (64-bit) value-returning method.</td> |
| </tr> |
| <tr> |
| <td>11 11x</td> |
| <td>return-object vAA</td> |
| <td><code>A:</code> return value register (8 bits)</td> |
| <td>Return from an object-returning method.</td> |
| </tr> |
| <tr> |
| <td>12 11n</td> |
| <td>const/4 vA, #+B</td> |
| <td><code>A:</code> destination register (4 bits)<br/> |
| <code>B:</code> signed int (4 bits)</td> |
| <td>Move the given literal value (sign-extended to 32 bits) into |
| the specified register.</td> |
| </tr> |
| <tr> |
| <td>13 21s</td> |
| <td>const/16 vAA, #+BBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> signed int (16 bits)</td> |
| <td>Move the given literal value (sign-extended to 32 bits) into |
| the specified register.</td> |
| </tr> |
| <tr> |
| <td>14 31i</td> |
| <td>const vAA, #+BBBBBBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> arbitrary 32-bit constant</td> |
| <td>Move the given literal value into the specified register.</td> |
| </tr> |
| <tr> |
| <td>15 21h</td> |
| <td>const/high16 vAA, #+BBBB0000</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> signed int (16 bits)</td> |
| <td>Move the given literal value (right-zero-extended to 32 bits) into |
| the specified register.</td> |
| </tr> |
| <tr> |
| <td>16 21s</td> |
| <td>const-wide/16 vAA, #+BBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> signed int (16 bits)</td> |
| <td>Move the given literal value (sign-extended to 64 bits) into |
| the specified register-pair.</td> |
| </tr> |
| <tr> |
| <td>17 31i</td> |
| <td>const-wide/32 vAA, #+BBBBBBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> signed int (32 bits)</td> |
| <td>Move the given literal value (sign-extended to 64 bits) into |
| the specified register-pair.</td> |
| </tr> |
| <tr> |
| <td>18 51l</td> |
| <td>const-wide vAA, #+BBBBBBBBBBBBBBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> arbitrary double-width (64-bit) constant</td> |
| <td>Move the given literal value into |
| the specified register-pair.</td> |
| </tr> |
| <tr> |
| <td>19 21h</td> |
| <td>const-wide/high16 vAA, #+BBBB000000000000</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> signed int (16 bits)</td> |
| <td>Move the given literal value (right-zero-extended to 64 bits) into |
| the specified register-pair.</td> |
| </tr> |
| <tr> |
| <td>1a 21c</td> |
| <td>const-string vAA, string@BBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> string index</td> |
| <td>Move a reference to the string specified by the given index into the |
| specified register.</td> |
| </tr> |
| <tr> |
| <td>1b 31c</td> |
| <td>const-string/jumbo vAA, string@BBBBBBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> string index</td> |
| <td>Move a reference to the string specified by the given index into the |
| specified register.</td> |
| </tr> |
| <tr> |
| <td>1c 21c</td> |
| <td>const-class vAA, type@BBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> type index</td> |
| <td>Move a reference to the class specified by the given index into the |
| specified register. In the case where the indicated type is primitive, |
| this will store a reference to the primitive type's degenerate |
| class.</td> |
| </tr> |
| <tr> |
| <td>1d 11x</td> |
| <td>monitor-enter vAA</td> |
| <td><code>A:</code> reference-bearing register (8 bits)</td> |
| <td>Acquire the monitor for the indicated object.</td> |
| </tr> |
| <tr> |
| <td>1e 11x</td> |
| <td>monitor-exit vAA</td> |
| <td><code>A:</code> reference-bearing register (8 bits)</td> |
| <td>Release the monitor for the indicated object. |
| <p><b>Note:</b> |
| If this instruction needs to throw an exception, it must do |
| so as if the pc has already advanced past the instruction. |
| It may be useful to think of this as the instruction successfully |
| executing (in a sense), and the exception getting thrown <i>after</i> |
| the instruction but <i>before</i> the next one gets a chance to |
| run. This definition makes it possible for a method to use |
| a monitor cleanup catch-all (e.g., <code>finally</code>) block as |
| the monitor cleanup for that block itself, as a way to handle the |
| arbitrary exceptions that might get thrown due to the historical |
| implementation of <code>Thread.stop()</code>, while still managing |
| to have proper monitor hygiene.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>1f 21c</td> |
| <td>check-cast vAA, type@BBBB</td> |
| <td><code>A:</code> reference-bearing register (8 bits)<br/> |
| <code>B:</code> type index (16 bits)</td> |
| <td>Throw a <code>ClassCastException</code> if the reference in the |
| given register cannot be cast to the indicated type. |
| <p><b>Note:</b> Since <code>A</code> must always be a reference |
| (and not a primitive value), this will necessarily fail at runtime |
| (that is, it will throw an exception) if <code>B</code> refers to a |
| primitive type.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>20 22c</td> |
| <td>instance-of vA, vB, type@CCCC</td> |
| <td><code>A:</code> destination register (4 bits)<br/> |
| <code>B:</code> reference-bearing register (4 bits)<br/> |
| <code>C:</code> type index (16 bits)</td> |
| <td>Store in the given destination register <code>1</code> |
| if the indicated reference is an instance of the given type, |
| or <code>0</code> if not. |
| <p><b>Note:</b> Since <code>B</code> must always be a reference |
| (and not a primitive value), this will always result |
| in <code>0</code> being stored if <code>C</code> refers to a primitive |
| type.</td> |
| </tr> |
| <tr> |
| <td>21 12x</td> |
| <td>array-length vA, vB</td> |
| <td><code>A:</code> destination register (4 bits)<br/> |
| <code>B:</code> array reference-bearing register (4 bits)</td> |
| <td>Store in the given destination register the length of the indicated |
| array, in entries</td> |
| </tr> |
| <tr> |
| <td>22 21c</td> |
| <td>new-instance vAA, type@BBBB</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> type index</td> |
| <td>Construct a new instance of the indicated type, storing a |
| reference to it in the destination. The type must refer to a |
| non-array class.</td> |
| </tr> |
| <tr> |
| <td>23 22c</td> |
| <td>new-array vA, vB, type@CCCC</td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> size register<br/> |
| <code>C:</code> type index</td> |
| <td>Construct a new array of the indicated type and size. The type |
| must be an array type.</td> |
| </tr> |
| <tr> |
| <td>24 35c</td> |
| <td>filled-new-array {vD, vE, vF, vG, vA}, type@CCCC</td> |
| <td><code>B:</code> array size and argument word count (4 bits)<br/> |
| <code>C:</code> type index (16 bits)<br/> |
| <code>D..G, A:</code> argument registers (4 bits each)</td> |
| <td>Construct an array of the given type and size, filling it with the |
| supplied contents. The type must be an array type. The array's |
| contents must be single-word (that is, |
| no arrays of <code>long</code> or <code>double</code>, but reference |
| types are acceptable). The constructed |
| instance is stored as a "result" in the same way that the method invocation |
| instructions store their results, so the constructed instance must |
| be moved to a register with an immediately subsequent |
| <code>move-result-object</code> instruction (if it is to be used).</td> |
| </tr> |
| <tr> |
| <td>25 3rc</td> |
| <td>filled-new-array/range {vCCCC .. vNNNN}, type@BBBB</td> |
| <td><code>A:</code> array size and argument word count (8 bits)<br/> |
| <code>B:</code> type index (16 bits)<br/> |
| <code>C:</code> first argument register (16 bits)<br/> |
| <code>N = A + C - 1</code></td> |
| <td>Construct an array of the given type and size, filling it with |
| the supplied contents. Clarifications and restrictions are the same |
| as <code>filled-new-array</code>, described above.</td> |
| </tr> |
| <tr> |
| <td>26 31t</td> |
| <td>fill-array-data vAA, +BBBBBBBB <i>(with supplemental data as specified |
| below in "<code>fill-array-data-payload</code> Format")</i></td> |
| <td><code>A:</code> array reference (8 bits)<br/> |
| <code>B:</code> signed "branch" offset to table data pseudo-instruction |
| (32 bits) |
| </td> |
| <td>Fill the given array with the indicated data. The reference must be |
| to an array of primitives, and the data table must match it in type and |
| must contain no more elements than will fit in the array. That is, |
| the array may be larger than the table, and if so, only the initial |
| elements of the array are set, leaving the remainder alone. |
| </td> |
| </tr> |
| <tr> |
| <td>27 11x</td> |
| <td>throw vAA</td> |
| <td><code>A:</code> exception-bearing register (8 bits)<br/></td> |
| <td>Throw the indicated exception.</td> |
| </tr> |
| <tr> |
| <td>28 10t</td> |
| <td>goto +AA</td> |
| <td><code>A:</code> signed branch offset (8 bits)</td> |
| <td>Unconditionally jump to the indicated instruction. |
| <p><b>Note:</b> |
| The branch offset must not be <code>0</code>. (A spin |
| loop may be legally constructed either with <code>goto/32</code> or |
| by including a <code>nop</code> as a target before the branch.)</p> |
| </td> |
| </tr> |
| <tr> |
| <td>29 20t</td> |
| <td>goto/16 +AAAA</td> |
| <td><code>A:</code> signed branch offset (16 bits)<br/></td> |
| <td>Unconditionally jump to the indicated instruction. |
| <p><b>Note:</b> |
| The branch offset must not be <code>0</code>. (A spin |
| loop may be legally constructed either with <code>goto/32</code> or |
| by including a <code>nop</code> as a target before the branch.)</p> |
| </td> |
| </tr> |
| <tr> |
| <td>2a 30t</td> |
| <td>goto/32 +AAAAAAAA</td> |
| <td><code>A:</code> signed branch offset (32 bits)<br/></td> |
| <td>Unconditionally jump to the indicated instruction.</td> |
| </tr> |
| <tr> |
| <td>2b 31t</td> |
| <td>packed-switch vAA, +BBBBBBBB <i>(with supplemental data as |
| specified below in "<code>packed-switch-payload</code> Format")</i></td> |
| <td><code>A:</code> register to test<br/> |
| <code>B:</code> signed "branch" offset to table data pseudo-instruction |
| (32 bits) |
| </td> |
| <td>Jump to a new instruction based on the value in the |
| given register, using a table of offsets corresponding to each value |
| in a particular integral range, or fall through to the next |
| instruction if there is no match. |
| </td> |
| </tr> |
| <tr> |
| <td>2c 31t</td> |
| <td>sparse-switch vAA, +BBBBBBBB <i>(with supplemental data as |
| specified below in "<code>sparse-switch-payload</code> Format")</i></td> |
| <td><code>A:</code> register to test<br/> |
| <code>B:</code> signed "branch" offset to table data pseudo-instruction |
| (32 bits) |
| </td> |
| <td>Jump to a new instruction based on the value in the given |
| register, using an ordered table of value-offset pairs, or fall |
| through to the next instruction if there is no match. |
| </td> |
| </tr> |
| <tr> |
| <td>2d..31 23x</td> |
| <td>cmp<i>kind</i> vAA, vBB, vCC<br/> |
| 2d: cmpl-float <i>(lt bias)</i><br/> |
| 2e: cmpg-float <i>(gt bias)</i><br/> |
| 2f: cmpl-double <i>(lt bias)</i><br/> |
| 30: cmpg-double <i>(gt bias)</i><br/> |
| 31: cmp-long |
| </td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> first source register or pair<br/> |
| <code>C:</code> second source register or pair</td> |
| <td>Perform the indicated floating point or <code>long</code> comparison, |
| storing <code>0</code> if the two arguments are equal, <code>1</code> |
| if the second argument is larger, or <code>-1</code> if the first |
| argument is larger. The "bias" listed for the floating point operations |
| indicates how <code>NaN</code> comparisons are treated: "Gt bias" |
| instructions return <code>1</code> for <code>NaN</code> comparisons, |
| and "lt bias" instructions return |
| <code>-1</code>. |
| <p>For example, to check to see if floating point |
| <code>a < b</code>, then it is advisable to use |
| <code>cmpg-float</code>; a result of <code>-1</code> indicates that |
| the test was true, and the other values indicate it was false either |
| due to a valid comparison or because one or the other values was |
| <code>NaN</code>.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>32..37 22t</td> |
| <td>if-<i>test</i> vA, vB, +CCCC<br/> |
| 32: if-eq<br/> |
| 33: if-ne<br/> |
| 34: if-lt<br/> |
| 35: if-ge<br/> |
| 36: if-gt<br/> |
| 37: if-le<br/> |
| </td> |
| <td><code>A:</code> first register to test (4 bits)<br/> |
| <code>B:</code> second register to test (4 bits)<br/> |
| <code>C:</code> signed branch offset (16 bits)</td> |
| <td>Branch to the given destination if the given two registers' values |
| compare as specified. |
| <p><b>Note:</b> |
| The branch offset must not be <code>0</code>. (A spin |
| loop may be legally constructed either by branching around a |
| backward <code>goto</code> or by including a <code>nop</code> as |
| a target before the branch.)</p> |
| </td> |
| </tr> |
| <tr> |
| <td>38..3d 21t</td> |
| <td>if-<i>test</i>z vAA, +BBBB<br/> |
| 38: if-eqz<br/> |
| 39: if-nez<br/> |
| 3a: if-ltz<br/> |
| 3b: if-gez<br/> |
| 3c: if-gtz<br/> |
| 3d: if-lez<br/> |
| </td> |
| <td><code>A:</code> register to test (8 bits)<br/> |
| <code>B:</code> signed branch offset (16 bits)</td> |
| <td>Branch to the given destination if the given register's value compares |
| with 0 as specified. |
| <p><b>Note:</b> |
| The branch offset must not be <code>0</code>. (A spin |
| loop may be legally constructed either by branching around a |
| backward <code>goto</code> or by including a <code>nop</code> as |
| a target before the branch.)</p> |
| </td> |
| </tr> |
| <tr> |
| <td>3e..43 10x</td> |
| <td><i>(unused)</i></td> |
| <td> </td> |
| <td><i>(unused)</i></td> |
| </tr> |
| <tr> |
| <td>44..51 23x</td> |
| <td><i>arrayop</i> vAA, vBB, vCC<br/> |
| 44: aget<br/> |
| 45: aget-wide<br/> |
| 46: aget-object<br/> |
| 47: aget-boolean<br/> |
| 48: aget-byte<br/> |
| 49: aget-char<br/> |
| 4a: aget-short<br/> |
| 4b: aput<br/> |
| 4c: aput-wide<br/> |
| 4d: aput-object<br/> |
| 4e: aput-boolean<br/> |
| 4f: aput-byte<br/> |
| 50: aput-char<br/> |
| 51: aput-short |
| </td> |
| <td><code>A:</code> value register or pair; may be source or dest |
| (8 bits)<br/> |
| <code>B:</code> array register (8 bits)<br/> |
| <code>C:</code> index register (8 bits)</td> |
| <td>Perform the identified array operation at the identified index of |
| the given array, loading or storing into the value register.</td> |
| </tr> |
| <tr> |
| <td>52..5f 22c</td> |
| <td>i<i>instanceop</i> vA, vB, field@CCCC<br/> |
| 52: iget<br/> |
| 53: iget-wide<br/> |
| 54: iget-object<br/> |
| 55: iget-boolean<br/> |
| 56: iget-byte<br/> |
| 57: iget-char<br/> |
| 58: iget-short<br/> |
| 59: iput<br/> |
| 5a: iput-wide<br/> |
| 5b: iput-object<br/> |
| 5c: iput-boolean<br/> |
| 5d: iput-byte<br/> |
| 5e: iput-char<br/> |
| 5f: iput-short |
| </td> |
| <td><code>A:</code> value register or pair; may be source or dest |
| (4 bits)<br/> |
| <code>B:</code> object register (4 bits)<br/> |
| <code>C:</code> instance field reference index (16 bits)</td> |
| <td>Perform the identified object instance field operation with |
| the identified field, loading or storing into the value register. |
| <p><b>Note:</b> These opcodes are reasonable candidates for static linking, |
| altering the field argument to be a more direct offset.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>60..6d 21c</td> |
| <td>s<i>staticop</i> vAA, field@BBBB<br/> |
| 60: sget<br/> |
| 61: sget-wide<br/> |
| 62: sget-object<br/> |
| 63: sget-boolean<br/> |
| 64: sget-byte<br/> |
| 65: sget-char<br/> |
| 66: sget-short<br/> |
| 67: sput<br/> |
| 68: sput-wide<br/> |
| 69: sput-object<br/> |
| 6a: sput-boolean<br/> |
| 6b: sput-byte<br/> |
| 6c: sput-char<br/> |
| 6d: sput-short |
| </td> |
| <td><code>A:</code> value register or pair; may be source or dest |
| (8 bits)<br/> |
| <code>B:</code> static field reference index (16 bits)</td> |
| <td>Perform the identified object static field operation with the identified |
| static field, loading or storing into the value register. |
| <p><b>Note:</b> These opcodes are reasonable candidates for static linking, |
| altering the field argument to be a more direct offset.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>6e..72 35c</td> |
| <td>invoke-<i>kind</i> {vD, vE, vF, vG, vA}, meth@CCCC<br/> |
| 6e: invoke-virtual<br/> |
| 6f: invoke-super<br/> |
| 70: invoke-direct<br/> |
| 71: invoke-static<br/> |
| 72: invoke-interface |
| </td> |
| <td><code>B:</code> argument word count (4 bits)<br/> |
| <code>C:</code> method reference index (16 bits)<br/> |
| <code>D..G, A:</code> argument registers (4 bits each)</td> |
| <td>Call the indicated method. The result (if any) may be stored |
| with an appropriate <code>move-result*</code> variant as the immediately |
| subsequent instruction. |
| <p><code>invoke-virtual</code> is used to invoke a normal virtual |
| method (a method that is not <code>private</code>, <code>static</code>, |
| or <code>final</code>, and is also not a constructor).</p> |
| <p><code>invoke-super</code> is used to invoke the closest superclass's |
| virtual method (as opposed to the one with the same <code>method_id</code> |
| in the calling class). The same method restrictions hold as for |
| <code>invoke-virtual</code>.</p> |
| <p><code>invoke-direct</code> is used to invoke a non-<code>static</code> |
| direct method (that is, an instance method that is by its nature |
| non-overridable, namely either a <code>private</code> instance method |
| or a constructor).</p> |
| <p><code>invoke-static</code> is used to invoke a <code>static</code> |
| method (which is always considered a direct method).</p> |
| <p><code>invoke-interface</code> is used to invoke an |
| <code>interface</code> method, that is, on an object whose concrete |
| class isn't known, using a <code>method_id</code> that refers to |
| an <code>interface</code>.</p> |
| <p><b>Note:</b> These opcodes are reasonable candidates for static linking, |
| altering the method argument to be a more direct offset |
| (or pair thereof).</p> |
| </td> |
| </tr> |
| <tr> |
| <td>73 10x</td> |
| <td><i>(unused)</i></td> |
| <td> </td> |
| <td><i>(unused)</i></td> |
| </tr> |
| <tr> |
| <td>74..78 3rc</td> |
| <td>invoke-<i>kind</i>/range {vCCCC .. vNNNN}, meth@BBBB<br/> |
| 74: invoke-virtual/range<br/> |
| 75: invoke-super/range<br/> |
| 76: invoke-direct/range<br/> |
| 77: invoke-static/range<br/> |
| 78: invoke-interface/range |
| </td> |
| <td><code>A:</code> argument word count (8 bits)<br/> |
| <code>B:</code> method reference index (16 bits)<br/> |
| <code>C:</code> first argument register (16 bits)<br/> |
| <code>N = A + C - 1</code></td> |
| <td>Call the indicated method. See first <code>invoke-<i>kind</i></code> |
| description above for details, caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>79..7a 10x</td> |
| <td><i>(unused)</i></td> |
| <td> </td> |
| <td><i>(unused)</i></td> |
| </tr> |
| <tr> |
| <td>7b..8f 12x</td> |
| <td><i>unop</i> vA, vB<br/> |
| 7b: neg-int<br/> |
| 7c: not-int<br/> |
| 7d: neg-long<br/> |
| 7e: not-long<br/> |
| 7f: neg-float<br/> |
| 80: neg-double<br/> |
| 81: int-to-long<br/> |
| 82: int-to-float<br/> |
| 83: int-to-double<br/> |
| 84: long-to-int<br/> |
| 85: long-to-float<br/> |
| 86: long-to-double<br/> |
| 87: float-to-int<br/> |
| 88: float-to-long<br/> |
| 89: float-to-double<br/> |
| 8a: double-to-int<br/> |
| 8b: double-to-long<br/> |
| 8c: double-to-float<br/> |
| 8d: int-to-byte<br/> |
| 8e: int-to-char<br/> |
| 8f: int-to-short |
| </td> |
| <td><code>A:</code> destination register or pair (4 bits)<br/> |
| <code>B:</code> source register or pair (4 bits)</td> |
| <td>Perform the identified unary operation on the source register, |
| storing the result in the destination register.</td> |
| </tr> |
| |
| <tr> |
| <td>90..af 23x</td> |
| <td><i>binop</i> vAA, vBB, vCC<br/> |
| 90: add-int<br/> |
| 91: sub-int<br/> |
| 92: mul-int<br/> |
| 93: div-int<br/> |
| 94: rem-int<br/> |
| 95: and-int<br/> |
| 96: or-int<br/> |
| 97: xor-int<br/> |
| 98: shl-int<br/> |
| 99: shr-int<br/> |
| 9a: ushr-int<br/> |
| 9b: add-long<br/> |
| 9c: sub-long<br/> |
| 9d: mul-long<br/> |
| 9e: div-long<br/> |
| 9f: rem-long<br/> |
| a0: and-long<br/> |
| a1: or-long<br/> |
| a2: xor-long<br/> |
| a3: shl-long<br/> |
| a4: shr-long<br/> |
| a5: ushr-long<br/> |
| a6: add-float<br/> |
| a7: sub-float<br/> |
| a8: mul-float<br/> |
| a9: div-float<br/> |
| aa: rem-float<br/> |
| ab: add-double<br/> |
| ac: sub-double<br/> |
| ad: mul-double<br/> |
| ae: div-double<br/> |
| af: rem-double |
| </td> |
| <td><code>A:</code> destination register or pair (8 bits)<br/> |
| <code>B:</code> first source register or pair (8 bits)<br/> |
| <code>C:</code> second source register or pair (8 bits)</td> |
| <td>Perform the identified binary operation on the two source registers, |
| storing the result in the first source register.</td> |
| </tr> |
| <tr> |
| <td>b0..cf 12x</td> |
| <td><i>binop</i>/2addr vA, vB<br/> |
| b0: add-int/2addr<br/> |
| b1: sub-int/2addr<br/> |
| b2: mul-int/2addr<br/> |
| b3: div-int/2addr<br/> |
| b4: rem-int/2addr<br/> |
| b5: and-int/2addr<br/> |
| b6: or-int/2addr<br/> |
| b7: xor-int/2addr<br/> |
| b8: shl-int/2addr<br/> |
| b9: shr-int/2addr<br/> |
| ba: ushr-int/2addr<br/> |
| bb: add-long/2addr<br/> |
| bc: sub-long/2addr<br/> |
| bd: mul-long/2addr<br/> |
| be: div-long/2addr<br/> |
| bf: rem-long/2addr<br/> |
| c0: and-long/2addr<br/> |
| c1: or-long/2addr<br/> |
| c2: xor-long/2addr<br/> |
| c3: shl-long/2addr<br/> |
| c4: shr-long/2addr<br/> |
| c5: ushr-long/2addr<br/> |
| c6: add-float/2addr<br/> |
| c7: sub-float/2addr<br/> |
| c8: mul-float/2addr<br/> |
| c9: div-float/2addr<br/> |
| ca: rem-float/2addr<br/> |
| cb: add-double/2addr<br/> |
| cc: sub-double/2addr<br/> |
| cd: mul-double/2addr<br/> |
| ce: div-double/2addr<br/> |
| cf: rem-double/2addr |
| </td> |
| <td><code>A:</code> destination and first source register or pair |
| (4 bits)<br/> |
| <code>B:</code> second source register or pair (4 bits)</td> |
| <td>Perform the identified binary operation on the two source registers, |
| storing the result in the first source register.</td> |
| </tr> |
| <tr> |
| <td>d0..d7 22s</td> |
| <td><i>binop</i>/lit16 vA, vB, #+CCCC<br/> |
| d0: add-int/lit16<br/> |
| d1: rsub-int (reverse subtract)<br/> |
| d2: mul-int/lit16<br/> |
| d3: div-int/lit16<br/> |
| d4: rem-int/lit16<br/> |
| d5: and-int/lit16<br/> |
| d6: or-int/lit16<br/> |
| d7: xor-int/lit16 |
| </td> |
| <td><code>A:</code> destination register (4 bits)<br/> |
| <code>B:</code> source register (4 bits)<br/> |
| <code>C:</code> signed int constant (16 bits)</td> |
| <td>Perform the indicated binary op on the indicated register (first |
| argument) and literal value (second argument), storing the result in |
| the destination register. |
| <p><b>Note:</b> |
| <code>rsub-int</code> does not have a suffix since this version is the |
| main opcode of its family. Also, see below for details on its semantics. |
| </p> |
| </td> |
| </tr> |
| <tr> |
| <td>d8..e2 22b</td> |
| <td><i>binop</i>/lit8 vAA, vBB, #+CC<br/> |
| d8: add-int/lit8<br/> |
| d9: rsub-int/lit8<br/> |
| da: mul-int/lit8<br/> |
| db: div-int/lit8<br/> |
| dc: rem-int/lit8<br/> |
| dd: and-int/lit8<br/> |
| de: or-int/lit8<br/> |
| df: xor-int/lit8<br/> |
| e0: shl-int/lit8<br/> |
| e1: shr-int/lit8<br/> |
| e2: ushr-int/lit8 |
| </td> |
| <td><code>A:</code> destination register (8 bits)<br/> |
| <code>B:</code> source register (8 bits)<br/> |
| <code>C:</code> signed int constant (8 bits)</td> |
| <td>Perform the indicated binary op on the indicated register (first |
| argument) and literal value (second argument), storing the result |
| in the destination register. |
| <p><b>Note:</b> See below for details on the semantics of |
| <code>rsub-int</code>.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>e3..fe 10x</td> |
| <td><i>(unused)</i></td> |
| <td> </td> |
| <td><i>(unused)</i></td> |
| </tr> |
| <tr> |
| <td>ff -</td> |
| <td><i>(expanded opcode)</i></td> |
| <td> </td> |
| <td>An <code>ff</code> in the primary opcode position indicates that there |
| is a secondary opcode in the high-order byte of the opcode code unit, |
| as opposed to an argument value. These expanded opcodes are detailed |
| immediately below. |
| </td> |
| </tr> |
| <tr> |
| <td>00ff 41c</td> |
| <td>const-class/jumbo vBBBB, type@AAAAAAAA</td> |
| <td><code>A:</code> type index (32 bits)<br/> |
| <code>B:</code> destination register (16 bits)</td> |
| <td>Move a reference to the class specified by the given index into the |
| specified register. See <code>const-class</code> description above |
| for details, caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>01ff 41c</td> |
| <td>check-cast/jumbo vBBBB, type@AAAAAAAA</td> |
| <td><code>A:</code> type index (32 bits)<br/> |
| <code>B:</code> reference-bearing register (16 bits) |
| </td> |
| <td>Throw a <code>ClassCastException</code> if the reference in the |
| given register cannot be cast to the indicated type. See |
| <code>check-cast</code> description above for details, |
| caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>02ff 52c</td> |
| <td>instance-of/jumbo vBBBB, vCCCC, type@AAAAAAAA</td> |
| <td><code>A:</code> type index (32 bits)<br/> |
| <code>B:</code> destination register (16 bits)<br/> |
| <code>C:</code> reference-bearing register (16 bits) |
| </td> |
| <td>Store in the given destination register <code>1</code> |
| if the indicated reference is an instance of the given type, |
| or <code>0</code> if not. See |
| <code>instance-of</code> description above for details, |
| caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>03ff 41c</td> |
| <td>new-instance/jumbo vBBBB, type@AAAAAAAA</td> |
| <td><code>A:</code> type index (32 bits)<br/> |
| <code>B:</code> destination register (16 bits) |
| </td> |
| <td>Construct a new instance of the indicated type. See |
| <code>new-instance</code> description above for details, |
| caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>04ff 52c</td> |
| <td>new-array/jumbo vBBBB, vCCCC, type@AAAAAAAA</td> |
| <td><code>A:</code> type index (32 bits)<br/> |
| <code>B:</code> destination register (16 bits)<br/> |
| <code>C:</code> size register (16 bits) |
| </td> |
| <td>Construct a new array of the indicated type and size. See |
| <code>new-array</code> description above for details, |
| caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>05ff 5rc</td> |
| <td>filled-new-array/jumbo {vCCCC .. vNNNN}, type@AAAAAAAA</td> |
| <td><code>A:</code> type index (32 bits)<br/> |
| <code>B:</code> array size and argument word count (16 bits)<br/> |
| <code>C:</code> first argument register (16 bits)<br/> |
| <code>N = B + C - 1</code> |
| </td> |
| <td>Construct an array of the given type and size, filling it with the |
| supplied contents. See first |
| <code>filled-new-array</code> description above for details, |
| caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>06ff..13ff 52c</td> |
| <td>i<i>instanceop</i>/jumbo vBBBB, vCCCC, field@AAAAAAAA<br/> |
| 06ff: iget/jumbo<br/> |
| 07ff: iget-wide/jumbo<br/> |
| 08ff: iget-object/jumbo<br/> |
| 09ff: iget-boolean/jumbo<br/> |
| 0aff: iget-byte/jumbo<br/> |
| 0bff: iget-char/jumbo<br/> |
| 0cff: iget-short/jumbo<br/> |
| 0dff: iput/jumbo<br/> |
| 0eff: iput-wide/jumbo<br/> |
| 0fff: iput-object/jumbo<br/> |
| 10ff: iput-boolean/jumbo<br/> |
| 11ff: iput-byte/jumbo<br/> |
| 12ff: iput-char/jumbo<br/> |
| 13ff: iput-short/jumbo |
| </td> |
| <td><code>A:</code> instance field reference index (32 bits)<br/> |
| <code>B:</code> value register or pair; may be source or dest |
| (16 bits)<br/> |
| <code>C:</code> object register (16 bits) |
| </td> |
| <td>Perform the identified object instance field operation. See |
| <code>i<i>instanceop</i></code> description above for details, |
| caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>14ff..21ff 41c</td> |
| <td>s<i>staticop</i>/jumbo vBBBB, field@AAAAAAAA<br/> |
| 14ff: sget/jumbo<br/> |
| 15ff: sget-wide/jumbo<br/> |
| 16ff: sget-object/jumbo<br/> |
| 17ff: sget-boolean/jumbo<br/> |
| 18ff: sget-byte/jumbo<br/> |
| 19ff: sget-char/jumbo<br/> |
| 1aff: sget-short/jumbo<br/> |
| 1bff: sput/jumbo<br/> |
| 1cff: sput-wide/jumbo<br/> |
| 1dff: sput-object/jumbo<br/> |
| 1eff: sput-boolean/jumbo<br/> |
| 1fff: sput-byte/jumbo<br/> |
| 20ff: sput-char/jumbo<br/> |
| 21ff: sput-short/jumbo |
| </td> |
| <td><code>A:</code> instance field reference index (32 bits)<br/> |
| <code>B:</code> value register or pair; may be source or dest |
| (16 bits) |
| </td> |
| <td>Perform the identified object static field operation. See |
| <code>s<i>staticop</i></code> description above for details, |
| caveats, and suggestions. |
| </td> |
| </tr> |
| <tr> |
| <td>22ff..26ff 5rc</td> |
| <td>invoke-<i>kind</i>/jumbo {vCCCC .. vNNNN}, meth@AAAAAAAA<br/> |
| 22ff: invoke-virtual/jumbo<br/> |
| 23ff: invoke-super/jumbo<br/> |
| 24ff: invoke-direct/jumbo<br/> |
| 25ff: invoke-static/jumbo<br/> |
| 26ff: invoke-interface/jumbo |
| </td> |
| <td><code>A:</code> method reference index (32 bits)<br/> |
| <code>B:</code> argument word count (16 bits)<br/> |
| <code>C:</code> first argument register (16 bits)<br/> |
| <code>N = B + C - 1</code> |
| </td> |
| <td>Call the indicated method. See first <code>invoke-<i>kind</i></code> |
| description above for details, caveats, and suggestions. |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <h2><code>packed-switch-payload</code> Format</h2> |
| |
| <table class="supplement"> |
| <thead> |
| <tr> |
| <th>Name</th> |
| <th>Format</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>ident</td> |
| <td>ushort = 0x0100</td> |
| <td>identifying pseudo-opcode</td> |
| </tr> |
| <tr> |
| <td>size</td> |
| <td>ushort</td> |
| <td>number of entries in the table</td> |
| </tr> |
| <tr> |
| <td>first_key</td> |
| <td>int</td> |
| <td>first (and lowest) switch case value</td> |
| </tr> |
| <tr> |
| <td>targets</td> |
| <td>int[]</td> |
| <td>list of <code>size</code> relative branch targets. The targets are |
| relative to the address of the switch opcode, not of this table. |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <p><b>Note:</b> The total number of code units for an instance of this |
| table is <code>(size * 2) + 4</code>.</p> |
| |
| <h2><code>sparse-switch-payload</code> Format</h2> |
| |
| <table class="supplement"> |
| <thead> |
| <tr> |
| <th>Name</th> |
| <th>Format</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>ident</td> |
| <td>ushort = 0x0200</td> |
| <td>identifying pseudo-opcode</td> |
| </tr> |
| <tr> |
| <td>size</td> |
| <td>ushort</td> |
| <td>number of entries in the table</td> |
| </tr> |
| <tr> |
| <td>keys</td> |
| <td>int[]</td> |
| <td>list of <code>size</code> key values, sorted low-to-high</td> |
| </tr> |
| <tr> |
| <td>targets</td> |
| <td>int[]</td> |
| <td>list of <code>size</code> relative branch targets, each corresponding |
| to the key value at the same index. The targets are |
| relative to the address of the switch opcode, not of this table. |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <p><b>Note:</b> The total number of code units for an instance of this |
| table is <code>(size * 4) + 2</code>.</p> |
| |
| <h2><code>fill-array-data-payload</code> Format</h2> |
| |
| <table class="supplement"> |
| <thead> |
| <tr> |
| <th>Name</th> |
| <th>Format</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>ident</td> |
| <td>ushort = 0x0300</td> |
| <td>identifying pseudo-opcode</td> |
| </tr> |
| <tr> |
| <td>element_width</td> |
| <td>ushort</td> |
| <td>number of bytes in each element</td> |
| </tr> |
| <tr> |
| <td>size</td> |
| <td>uint</td> |
| <td>number of elements in the table</td> |
| </tr> |
| <tr> |
| <td>data</td> |
| <td>ubyte[]</td> |
| <td>data values</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <p><b>Note:</b> The total number of code units for an instance of this |
| table is <code>(size * element_width + 1) / 2 + 4</code>.</p> |
| |
| |
| <h2>Mathematical Operation Details</h2> |
| |
| <p><b>Note:</b> Floating point operations must follow IEEE 754 rules, using |
| round-to-nearest and gradual underflow, except where stated otherwise.</p> |
| |
| <table class="math"> |
| <thead> |
| <tr> |
| <th>Opcode</th> |
| <th>C Semantics</th> |
| <th>Notes</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>neg-int</td> |
| <td>int32 a;<br/> |
| int32 result = -a; |
| </td> |
| <td>Unary twos-complement.</td> |
| </tr> |
| <tr> |
| <td>not-int</td> |
| <td>int32 a;<br/> |
| int32 result = ~a; |
| </td> |
| <td>Unary ones-complement.</td> |
| </tr> |
| <tr> |
| <td>neg-long</td> |
| <td>int64 a;<br/> |
| int64 result = -a; |
| </td> |
| <td>Unary twos-complement.</td> |
| </tr> |
| <tr> |
| <td>not-long</td> |
| <td>int64 a;<br/> |
| int64 result = ~a; |
| </td> |
| <td>Unary ones-complement.</td> |
| </tr> |
| <tr> |
| <td>neg-float</td> |
| <td>float a;<br/> |
| float result = -a; |
| </td> |
| <td>Floating point negation.</td> |
| </tr> |
| <tr> |
| <td>neg-double</td> |
| <td>double a;<br/> |
| double result = -a; |
| </td> |
| <td>Floating point negation.</td> |
| </tr> |
| <tr> |
| <td>int-to-long</td> |
| <td>int32 a;<br/> |
| int64 result = (int64) a; |
| </td> |
| <td>Sign extension of <code>int32</code> into <code>int64</code>.</td> |
| </tr> |
| <tr> |
| <td>int-to-float</td> |
| <td>int32 a;<br/> |
| float result = (float) a; |
| </td> |
| <td>Conversion of <code>int32</code> to <code>float</code>, using |
| round-to-nearest. This loses precision for some values. |
| </td> |
| </tr> |
| <tr> |
| <td>int-to-double</td> |
| <td>int32 a;<br/> |
| double result = (double) a; |
| </td> |
| <td>Conversion of <code>int32</code> to <code>double</code>.</td> |
| </tr> |
| <tr> |
| <td>long-to-int</td> |
| <td>int64 a;<br/> |
| int32 result = (int32) a; |
| </td> |
| <td>Truncation of <code>int64</code> into <code>int32</code>.</td> |
| </tr> |
| <tr> |
| <td>long-to-float</td> |
| <td>int64 a;<br/> |
| float result = (float) a; |
| </td> |
| <td>Conversion of <code>int64</code> to <code>float</code>, using |
| round-to-nearest. This loses precision for some values. |
| </td> |
| </tr> |
| <tr> |
| <td>long-to-double</td> |
| <td>int64 a;<br/> |
| double result = (double) a; |
| </td> |
| <td>Conversion of <code>int64</code> to <code>double</code>, using |
| round-to-nearest. This loses precision for some values. |
| </td> |
| </tr> |
| <tr> |
| <td>float-to-int</td> |
| <td>float a;<br/> |
| int32 result = (int32) a; |
| </td> |
| <td>Conversion of <code>float</code> to <code>int32</code>, using |
| round-toward-zero. <code>NaN</code> and <code>-0.0</code> (negative zero) |
| convert to the integer <code>0</code>. Infinities and values with |
| too large a magnitude to be represented get converted to either |
| <code>0x7fffffff</code> or <code>-0x80000000</code> depending on sign. |
| </td> |
| </tr> |
| <tr> |
| <td>float-to-long</td> |
| <td>float a;<br/> |
| int64 result = (int64) a; |
| </td> |
| <td>Conversion of <code>float</code> to <code>int64</code>, using |
| round-toward-zero. The same special case rules as for |
| <code>float-to-int</code> apply here, except that out-of-range values |
| get converted to either <code>0x7fffffffffffffff</code> or |
| <code>-0x8000000000000000</code> depending on sign. |
| </td> |
| </tr> |
| <tr> |
| <td>float-to-double</td> |
| <td>float a;<br/> |
| double result = (double) a; |
| </td> |
| <td>Conversion of <code>float</code> to <code>double</code>, preserving |
| the value exactly. |
| </td> |
| </tr> |
| <tr> |
| <td>double-to-int</td> |
| <td>double a;<br/> |
| int32 result = (int32) a; |
| </td> |
| <td>Conversion of <code>double</code> to <code>int32</code>, using |
| round-toward-zero. The same special case rules as for |
| <code>float-to-int</code> apply here. |
| </td> |
| </tr> |
| <tr> |
| <td>double-to-long</td> |
| <td>double a;<br/> |
| int64 result = (int64) a; |
| </td> |
| <td>Conversion of <code>double</code> to <code>int64</code>, using |
| round-toward-zero. The same special case rules as for |
| <code>float-to-long</code> apply here. |
| </td> |
| </tr> |
| <tr> |
| <td>double-to-float</td> |
| <td>double a;<br/> |
| float result = (float) a; |
| </td> |
| <td>Conversion of <code>double</code> to <code>float</code>, using |
| round-to-nearest. This loses precision for some values. |
| </td> |
| </tr> |
| <tr> |
| <td>int-to-byte</td> |
| <td>int32 a;<br/> |
| int32 result = (a << 24) >> 24; |
| </td> |
| <td>Truncation of <code>int32</code> to <code>int8</code>, sign |
| extending the result. |
| </td> |
| </tr> |
| <tr> |
| <td>int-to-char</td> |
| <td>int32 a;<br/> |
| int32 result = a & 0xffff; |
| </td> |
| <td>Truncation of <code>int32</code> to <code>uint16</code>, without |
| sign extension. |
| </td> |
| </tr> |
| <tr> |
| <td>int-to-short</td> |
| <td>int32 a;<br/> |
| int32 result = (a << 16) >> 16; |
| </td> |
| <td>Truncation of <code>int32</code> to <code>int16</code>, sign |
| extending the result. |
| </td> |
| </tr> |
| <tr> |
| <td>add-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a + b; |
| </td> |
| <td>Twos-complement addition.</td> |
| </tr> |
| <tr> |
| <td>sub-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a - b; |
| </td> |
| <td>Twos-complement subtraction.</td> |
| </tr> |
| <tr> |
| <td>rsub-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = b - a; |
| </td> |
| <td>Twos-complement reverse subtraction.</td> |
| </tr> |
| <tr> |
| <td>mul-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a * b; |
| </td> |
| <td>Twos-complement multiplication.</td> |
| </tr> |
| <tr> |
| <td>div-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a / b; |
| </td> |
| <td>Twos-complement division, rounded towards zero (that is, truncated to |
| integer). This throws <code>ArithmeticException</code> if |
| <code>b == 0</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>rem-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a % b; |
| </td> |
| <td>Twos-complement remainder after division. The sign of the result |
| is the same as that of <code>a</code>, and it is more precisely |
| defined as <code>result == a - (a / b) * b</code>. This throws |
| <code>ArithmeticException</code> if <code>b == 0</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>and-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a & b; |
| </td> |
| <td>Bitwise AND.</td> |
| </tr> |
| <tr> |
| <td>or-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a | b; |
| </td> |
| <td>Bitwise OR.</td> |
| </tr> |
| <tr> |
| <td>xor-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a ^ b; |
| </td> |
| <td>Bitwise XOR.</td> |
| </tr> |
| <tr> |
| <td>shl-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a << (b & 0x1f); |
| </td> |
| <td>Bitwise shift left (with masked argument).</td> |
| </tr> |
| <tr> |
| <td>shr-int</td> |
| <td>int32 a, b;<br/> |
| int32 result = a >> (b & 0x1f); |
| </td> |
| <td>Bitwise signed shift right (with masked argument).</td> |
| </tr> |
| <tr> |
| <td>ushr-int</td> |
| <td>uint32 a, b;<br/> |
| int32 result = a >> (b & 0x1f); |
| </td> |
| <td>Bitwise unsigned shift right (with masked argument).</td> |
| </tr> |
| <tr> |
| <td>add-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a + b; |
| </td> |
| <td>Twos-complement addition.</td> |
| </tr> |
| <tr> |
| <td>sub-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a - b; |
| </td> |
| <td>Twos-complement subtraction.</td> |
| </tr> |
| <tr> |
| <td>mul-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a * b; |
| </td> |
| <td>Twos-complement multiplication.</td> |
| </tr> |
| <tr> |
| <td>div-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a / b; |
| </td> |
| <td>Twos-complement division, rounded towards zero (that is, truncated to |
| integer). This throws <code>ArithmeticException</code> if |
| <code>b == 0</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>rem-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a % b; |
| </td> |
| <td>Twos-complement remainder after division. The sign of the result |
| is the same as that of <code>a</code>, and it is more precisely |
| defined as <code>result == a - (a / b) * b</code>. This throws |
| <code>ArithmeticException</code> if <code>b == 0</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>and-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a & b; |
| </td> |
| <td>Bitwise AND.</td> |
| </tr> |
| <tr> |
| <td>or-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a | b; |
| </td> |
| <td>Bitwise OR.</td> |
| </tr> |
| <tr> |
| <td>xor-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a ^ b; |
| </td> |
| <td>Bitwise XOR.</td> |
| </tr> |
| <tr> |
| <td>shl-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a << (b & 0x3f); |
| </td> |
| <td>Bitwise shift left (with masked argument).</td> |
| </tr> |
| <tr> |
| <td>shr-long</td> |
| <td>int64 a, b;<br/> |
| int64 result = a >> (b & 0x3f); |
| </td> |
| <td>Bitwise signed shift right (with masked argument).</td> |
| </tr> |
| <tr> |
| <td>ushr-long</td> |
| <td>uint64 a, b;<br/> |
| int64 result = a >> (b & 0x3f); |
| </td> |
| <td>Bitwise unsigned shift right (with masked argument).</td> |
| </tr> |
| <tr> |
| <td>add-float</td> |
| <td>float a, b;<br/> |
| float result = a + b; |
| </td> |
| <td>Floating point addition.</td> |
| </tr> |
| <tr> |
| <td>sub-float</td> |
| <td>float a, b;<br/> |
| float result = a - b; |
| </td> |
| <td>Floating point subtraction.</td> |
| </tr> |
| <tr> |
| <td>mul-float</td> |
| <td>float a, b;<br/> |
| float result = a * b; |
| </td> |
| <td>Floating point multiplication.</td> |
| </tr> |
| <tr> |
| <td>div-float</td> |
| <td>float a, b;<br/> |
| float result = a / b; |
| </td> |
| <td>Floating point division.</td> |
| </tr> |
| <tr> |
| <td>rem-float</td> |
| <td>float a, b;<br/> |
| float result = a % b; |
| </td> |
| <td>Floating point remainder after division. This function is different |
| than IEEE 754 remainder and is defined as |
| <code>result == a - roundTowardZero(a / b) * b</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>add-double</td> |
| <td>double a, b;<br/> |
| double result = a + b; |
| </td> |
| <td>Floating point addition.</td> |
| </tr> |
| <tr> |
| <td>sub-double</td> |
| <td>double a, b;<br/> |
| double result = a - b; |
| </td> |
| <td>Floating point subtraction.</td> |
| </tr> |
| <tr> |
| <td>mul-double</td> |
| <td>double a, b;<br/> |
| double result = a * b; |
| </td> |
| <td>Floating point multiplication.</td> |
| </tr> |
| <tr> |
| <td>div-double</td> |
| <td>double a, b;<br/> |
| double result = a / b; |
| </td> |
| <td>Floating point division.</td> |
| </tr> |
| <tr> |
| <td>rem-double</td> |
| <td>double a, b;<br/> |
| double result = a % b; |
| </td> |
| <td>Floating point remainder after division. This function is different |
| than IEEE 754 remainder and is defined as |
| <code>result == a - roundTowardZero(a / b) * b</code>. |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| </body> |
| </html> |