<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Expression Evaluator</title> <style> :root { font-family: Arial, sans-serif; font-size : 16px; text-align : justify; -webkit-text-size-adjust: none; } a { text-decoration : underline; } a.ext { text-decoration-style: dotted; } body { margin : 8px; } circle, path, rect { fill : none; paint-order : markers fill stroke; stroke-width: 1.5; } code, pre, .mono { font-family: Consolas, monospace; } h1 { border-radius: 8px; font-size : 20px; font-weight : normal; padding : 4px 8px; } h1.top { font-weight: bold; font-size : 24px; text-align : center; } h1.bottom { font-size : 16px; padding : 6px 8px; text-align: right; } h2 { font-size : 18px; font-weight: bold; margin-top : 32px; } sup, .small { font-size: 10px; } table { border : none; border-spacing: 0px; } td, th { padding-right : 12px; } tr { vertical-align: top; } .b { border-style: solid; border-width: 0; font-size : 1px; height : 4px; padding : 0; width : 16px; } .bb { border-bottom-width: 1px; } .bc, .bd, .be { font-size : 12px; height : 32px; position : relative; text-align: center; } .bd { height: 48px; } .be { height: 72px; } .bh { font-size : 10px; padding : 2px 0; text-align: center; } .bl { border-left-width : 1px; } .br { border-right-width : 1px; } .bs, .by, .bz { box-sizing : border-box; height : 17px; left : 17px; line-height : 17px; margin-left : -1px; position : absolute; text-align : center; top : -4px; transform : rotate(90deg); transform-origin: 0 0; white-space : nowrap; width : 41px; } .by { font-size: 10px; width : 82px; } .bz { font-size: 10px; width : 57px; } .bt { border-top-width : 1px; } .center { text-align : center; } .ednote { border-radius: 8px; border-style : solid; border-width : 1px; font-style : italic; margin-left : 16px; margin-right : 16px; padding : 4px 8px; } .indent { margin-left : 16px; } .middle { vertical-align: middle; } .minor { font-size : 14px; } .nowrap { white-space : nowrap; } .narrow { width : 1px; } .outdent { margin-left : -16px; } .right { text-align : right; } :root { color : #000000; } a { color : #0099ff; } a.ext { color : #00bb66; } a.redlink { color : #ff3366; } body { background : #ffffff; } h1, .shade { background : #d4d4d4; } .b { border-color: #666666; } .ednote { border-color: #999999; color: #666666; } .fill { fill : #ffffff; } .stroke { stroke : #666666; } .bordered { border-style: solid; border-color: #999999; border-width: 1px 0 0 1px; } .bordered td { border-style: solid; border-color: #999999; border-width: 0 1px 1px 0; } .bordered tr > :first-child { padding: 1px 12px 1px 12px; text-align: center; } .bordered td.open { border-bottom: none; } </style> </head> <body> <h1 class="top">Expression Evaluator</h1> <p> The emulator is capable of evaluating expressions within breakpoint conditions and Go To prompts. These expressions inspect the current emulation state and can be used to dynamically process registers, variables and other data elements that may change from one invocation to the next. </p> <p> Expressions are organized into series of tokens with three main modes of significance: </p> <table class="indent"> <tr> <td class="narrow nowrap">• Value</td> <td> Numeric value that can be used in computation. This may take the form of a literal number provided directly in the expression, or one of the named symbols that represent things in the CPU state, current instruction and/or current memory access. </td> </tr> <tr> <td class="narrow nowrap">• Operator</td> <td> Modifies one or two values through a given operation. Unary operators modify only the value on their right, while binary operators consider the values on their left and right and produce a new value as the result. </td> </tr> <tr> <td class="nowrap">• Group</td> <td> Operand groups, mainly through the use of parentheses <code>()</code>, override the default order of operations. Anything enclosed in a group is processed before any operations adjacent to that group. </td> </tr> </table> <p> Expressions are case-insensitive. </p> <h2>Values</h2> <p> Values come in two forms: </p> <table class="indent"> <tr> <td class="narrow nowrap">• Literal</td> <td>Provided directly by the expression.</td> </tr> <tr> <td class="nowrap">• Symbol</td> <td>Refers to something in the current emulation state.</td> </tr> </table> <p> Values may be one of four data types: </p> <table class="indent"> <tr> <td class="narrow nowrap">• Signed Word</td> <td> 32-bit, two's complement integer. </td> </tr> <tr> <td class="nowrap">• Unsigned Word</td> <td> 32-bit, unsigned integer. </td> </tr> <tr> <td class="nowrap">• Float</td> <td> 32-bit floating short in IEEE-754 format. </td> </tr> <tr> <td class="nowrap">• Boolean</td> <td> 1-bit value representing whether a condition is true or false. </td> </tr> </table> <p> Signed word and unsigned word are represented as sequences of character digits. A numeric token that begins with the characters <code>0x</code> will be interpreted as hexadecimal, allowing letters <code>A</code> through <code>F</code> to be used as digits as well. If the given value can be represented in the signed word data type, the token is a signed word. Otherwise, if it can be represented in the unsigned word data type, the token is an unsigned word. If the value cannot be represented in either data type, a parsing error occurs. </p> <p> Floats, like words, are represented as sequences of character digits. They are differentiated from words by the presence of a dot <code>.</code> character somewhere within the sequence. Only one dot may be present in a float literal, and dots cannot be used in hexadecimal literals. If the given value cannot be represented in the float data type, a parsing error occurs. Float values in the expression evaluator are subjected to the same restrictions as on the Virtual Boy's CPU: if the result of any float operation is NaN, an infinity, a denormal number or negative zero, it will be changed to positive zero. </p> <p> Booleans are mechanically identical to signed words, but the semantics are slightly different. When used in a numeric operation, a boolean will use the value <code>0</code> if false or the value <code>1</code> if true. Boolean literals are specified with the named values <code>true</code> and <code>false</code> within the expression. In a boolean operation, any result that is zero is considered false, and any non-zero value is considered true. </p> <p> Operators exist for converting between data types (see Operators below). A Go To expression will only be valid if its final data type is signed word or unsigned word. </p> <p> The following symbols may be used for accessing information about the current instruction being executed: </p> <table class="indent"> <tr> <td class="mono narrow">address</td> <td>Current memory access's address.</td> </tr> <tr> <td class="mono">break</td> <td> Identifies what type of break scenario is being considered. See below for a list of identifiers. </td> </tr> <tr> <td class="mono">code</td> <td>Current exception's exception code.</td> </tr> <tr> <td class="mono">cond</td> <td> Condition code for <code>Bcond</code> and <code>SETF</code> instructions. See below for a list of conditions. </td> </tr> <tr> <td class="mono">disp</td> <td>Displacement offset for jumps and memory accesses.</td> </tr> <tr> <td class="mono">fetch</td> <td> Data unit index during a fetch operation, or <code>-1</code> if the read operation is not a fetch. </td> </tr> <tr> <td class="mono">format</td> <td>Current instruction's encoding format.</td> </tr> <tr> <td class="mono">id</td> <td> Identifies which specific instruction is being executed, considering <code>opcode</code> and, where applicable, <code>subopcode</code>. See below for a list of identifiers. </td> </tr> <tr> <td class="mono">imm</td> <td>Immediate operand.</td> </tr> <tr> <td class="mono">opcode</td> <td>Current instruction's top-level opcode.</td> </tr> <tr> <td class="mono">reg1</td> <td>Source register index.</td> </tr> <tr> <td class="mono">reg2</td> <td>Destination register index.</td> </tr> <tr> <td class="mono">regid</td> <td> System register index in <code>LDSR</code> and <code>STSR</code> instructions. </td> </tr> <tr> <td class="mono">size</td> <td>Number of bytes occupied by the current instruction.</td> </tr> <tr> <td class="mono">subopcode</td> <td>Current instruction's secondary opcode.</td> </tr> <tr> <td class="mono">type</td> <td>Data type of the current memory access.</td> </tr> <tr> <td class="mono">value</td> <td>Value read by the current memory access.</td> </tr> <tr> <td class="mono">vector</td> <td>Vector for <code>TRAP</code> instructions.</td> </tr> </table> <p> The following symbols may be used in conjunction with the <code>break</code> symbol: </p> <div class="indent mono" style="column-width: 75px;"> <div>exception</div><div>execute</div><div>read</div><div>write</div> </div> <p> The following symbols may be used in conjunction with the <code>cond</code> symbol: </p> <div class="indent mono" style="column-width: 75px;"> <div>c </div><div>e </div><div>f </div><div>ge</div><div>gt</div> <div>h </div><div>l </div><div>le</div><div>lt</div><div>n </div> <div>nc</div><div>ne</div><div>nh</div><div>nl</div><div>nv</div> <div>nz</div><div>p </div><div>t </div><div>v </div><div>z </div> </div> <p> The following symbols may be used in conjunction with the <code>id</code> symbol: </p> <div class="indent mono" style="column-width: 75px;"> <div>illegal</div><div>add_imm</div><div>add_reg</div><div>addf.s </div> <div>addi </div><div>and </div><div>andbsu </div><div>andi </div> <div>andnbsu</div><div>bcond </div><div>caxi </div><div>cli </div> <div>cmp_imm</div><div>cmp_reg</div><div>cmpf.s </div><div>cvt.sw </div> <div>cvt.ws </div><div>div </div><div>divf.s </div><div>divu </div> <div>halt </div><div>in.b </div><div>in.h </div><div>in.w </div> <div>jal </div><div>jmp </div><div>jr </div><div>ld.b </div> <div>ld.h </div><div>ld.w </div><div>ldsr </div><div>mov_imm</div> <div>mov_reg</div><div>movbsu </div><div>movea </div><div>movhi </div> <div>mpyhw </div><div>mul </div><div>mulf.s </div><div>mulu </div> <div>not </div><div>notbsu </div><div>or </div><div>orbsu </div> <div>ori </div><div>ornbsu </div><div>out.b </div><div>out.h </div> <div>out.w </div><div>reti </div><div>rev </div><div>sar_imm</div> <div>sar_reg</div><div>sch0bsd</div><div>sch0bsu</div><div>sch1bsd</div> <div>sch1bsu</div><div>sei </div><div>setf </div><div>shl_imm</div> <div>shl_reg</div><div>shr_imm</div><div>shr_reg</div><div>st.b </div> <div>st.h </div><div>st.w </div><div>stsr </div><div>sub </div> <div>subf.s </div><div>trap </div><div>trnc.sw</div><div>xb </div> <div>xh </div><div>xor </div><div>xorbsu </div><div>xori </div> <div>xornbsu</div> </div> <p> The following symbols may be used to retrieve the contents of a CPU program register: </p> <div class="indent mono" style="column-width: 75px;"> <div>r0 </div><div>r1 </div><div>r2 </div><div>r3 </div><div>r4 </div> <div>r5 </div><div>r6 </div><div>r7 </div><div>r8 </div><div>r9 </div> <div>r10</div><div>r11</div><div>r12</div><div>r13</div><div>r14</div> <div>r15</div><div>r16</div><div>r17</div><div>r18</div><div>r19</div> <div>r20</div><div>r21</div><div>r22</div><div>r23</div><div>r24</div> <div>r25</div><div>r26</div><div>r27</div><div>r28</div><div>r29</div> <div>r30</div><div>r31</div><div>gp </div><div>hp </div><div>lp </div> <div>sp </div><div>tp </div> </div> <p> The following symbols may be used to retrieve the contents of a CPU system register: </p> <div class="indent mono" style="column-width: 75px;"> <div>adtre</div><div>chcw </div><div>ecr </div><div>eipc</div> <div>eipsw</div><div>fepc </div><div>fepsw</div><div>pc </div> <div>pir </div><div>psw </div><div>tkcw </div><div>sr29</div> <div>sr30 </div><div>sr31 </div> </div> <h2>Operators</h2> <p> Operators may apply to one (unary) or two (binary) values. All unary operators appear to the left of the value they modify (or another unary operator). Binary operators appear between the values they modify. Each operator considers the types of its operands in order to produce a new value of the appropriate type. </p> <p> If the operands of a binary operator have different types, one of the values will be converted to the other type before performing the operation. The conversion depends on the "greater" of the two types, in the following order (higher is "greater"): </p> <table class="indent"> <tr><td class="center narrow">↑</td><td>Float</td></tr> <tr><td class="center"></td><td>Unsigned word</td></tr> <tr><td class="center"></td><td>Signed word</td></tr> <tr><td class="center">↓</td><td>Boolean</td></tr> </table> <p> For example, if an operation contains both a signed word and a float, the signed word value is first converted to float. </p> <p> Operators have assigned precedence that specifies the order of operations. For example, in the expression <code>1 + 2 * 3</code>, the multiplication happens before the addition because it has higher precedence. Parentheses <code>()</code> may be used to encapsulate operations and guarantee that they are evaluated first regardless of the relative precedence of the adjacent operators. For example, in the expression <code>(1 + 2) * 3</code>, the addition happens before the multiplication because it is enclosed in parentheses. </p> <p> The following operators may be used in expressions. Groups listed higher have higher precedence and happen before groups listed lower. Operators within groups have the same precedence and are processed in the order they appear in the expression from left to right. </p> <table class="indent bordered"> <tr> <td class="mono open">~</td> <td class="open">Not Bitwise</td> <td class="open">Cannot be used with a float value.</td> </tr> <tr> <td class="mono open">!</td> <td class="open">Not Logical</td> <td class="open">Always produces a boolean.</td> </tr> <tr> <td class="mono open">-</td> <td class="open">Negate</td> <td class="open">Cannot be used with an unsigned word value.</td> </tr> <tr> <td class="mono open">bool</td> <td class="open">Cast to Boolean</td> <td class="open"></td> </tr> <tr> <td class="mono open">ceil</td> <td class="open">Round Up</td> <td class="open"></td> </tr> <tr> <td class="mono open">float</td> <td class="open">Cast to Float</td> <td class="open"></td> </tr> <tr> <td class="mono open">floor</td> <td class="open">Round Down</td> <td class="open"></td> </tr> <tr> <td class="mono open">round</td> <td class="open">Round to Nearest</td> <td class="open"></td> </tr> <tr> <td class="open"><code>s8</code>, <code>byte</code></td> <td class="open">Cast to Signed Byte</td> <td class="open">Result is of type signed word.</td> </tr> <tr> <td class="open"><code>s16</code>, <code>halfword</code></td> <td class="open">Cast to Signed Halfword</td> <td class="open">Result is of type signed word.</td> </tr> <tr> <td class="open"><code>s32</code>, <code>word</code></td> <td class="open">Cast to Signed Word</td> <td class="open"></td> </tr> <tr> <td class="mono open">trunc</td> <td class="open">Truncate</td> <td class="open">Removes any fraction.</td> </tr> <tr> <td class="open"><code><code>u8</code>, ubyte</code></td> <td class="open">Cast to Unsigned Byte</td> <td class="open">Result is of type unsigned word.</td> </tr> <tr> <td class="open"><code>u16</code>, <code>uhalfword</code></td> <td class="open">Cast to Unsigned Halfword</td> <td class="open">Result is of type unsigned word.</td> </tr> <tr> <td class="open"><code>u32</code>, <code>uword</code></td> <td class="open">Cast to Unsigned Word</td> <td class="open"></td> </tr> <tr> <td class="mono open">xfloat</td> <td class="open">Reinterpret as Float</td> <td class="open">The binary value is not modified.</td> </tr> <tr> <td class="open"><code>xs32</code>, <code>xword</code></td> <td class="open">Reinterpret as Signed Word</td> <td class="open">The binary value is not modified.</td> </tr> <tr> <td><code>xu32</code>, <code>xuword</code></td> <td>Reinterpret as Unsgned Word</td> <td>The binary value is not modified.</td> </tr> <tr> <td class="mono open">/</td> <td class="open">Divide</td> <td class="open">Zero divisor yields zero as result.</td> </tr> <tr> <td class="mono open">*</td> <td class="open">Multiply</td> <td class="open"></td> </tr> <tr> <td class="mono">%</td> <td>Remainder</td> <td>Zero divisor yields zero as result.</td> </tr> <tr> <td class="mono open">+</td> <td class="open">Add</td> <td class="open"></td> </tr> <tr> <td class="mono">-</td> <td>Subtract</td> <td></td> </tr> <tr> <td class="mono open"><<</td> <td class="open">Shift Left</td> <td class="open">Cannot be used with a float value.</td> </tr> <tr> <td class="mono open">>></td> <td class="open">Shift Right Arithmetic</td> <td class="open">Cannot be used with a float value.</td> </tr> <tr> <td class="mono">>>></td> <td>Shift Right Logical</td> <td>Cannot be used with a float value.</td> </tr> <tr> <td class="mono open">></td> <td class="open">Greater</td> <td class="open">Always produces a boolean.</td> </tr> <tr> <td class="mono open">>=</td> <td class="open">Greater or Equal</td> <td class="open">Always produces a boolean.</td> </tr> <tr> <td class="mono open"><</td> <td class="open">Less</td> <td class="open">Always produces a boolean.</td> </tr> <tr> <td class="mono"><=</td> <td>Less or Equal</td> <td>Always produces a boolean.</td> </tr> <tr> <td class="mono open">==</td> <td class="open">Equal</td> <td class="open">Always produces a boolean.</td> </tr> <tr> <td class="mono">!=</td> <td>Not Equal</td> <td>Always produces a boolean.</td> </tr> <tr> <td class="mono">&</td> <td>And Bitwise</td> <td>Cannot be used with a float value.</td> </tr> <tr> <td class="mono">^</td> <td>Exclusive Or Bitwise</td> <td>Cannot be used with a float value.</td> </tr> <tr> <td class="mono">|</td> <td>Or Bitwise</td> <td>Cannot be used with a float value.</td> </tr> <tr> <td class="mono">&&</td> <td>And Logical</td> <td>If left is true, returns right; else returns left.</td> </tr> <tr> <td class="mono">^^</td> <td>Exclusive Or Logical</td> <td>If only one operand is true, returns the truthy value.</td> </tr> <tr> <td class="mono">||</td> <td>Or Logical</td> <td>If left is true, returns left; else returns right.</td> </tr> </table> <h2>Memory Read</h2> <p> A value can be read from the memory bus of the emulation state. This is done by enclosing the part of the expression that represents the address in square brackets <code>[]</code>. This functions in an identical manner to parentheses <code>()</code>, but will additionally perform the read operation. </p> <p> Under most circumstances, a signed word read is performed. Certain operators can be placed in front of the group to alter how the read is performed: </p> <table class="indent"> <tr> <td class="narrow nowrap">• <code>float</code></td> <td>Behaves like <code>xfloat</code> instead.</td> </tr> <tr> <td class="nowrap">• <code>s8</code>, <code>u8</code></td> <td>Performs a byte read of the specified signedness.</td> </tr> <tr> <td class="nowrap">• <code>s16</code>, <code>u16</code></td> <td>Performs a halfword read of the specified signedness.</td> </tr> </table> </body> </html>