pvbemu/expressions.html

706 lines
22 KiB
HTML

<!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, .op1 {
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">&bull; 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">&bull; 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">&bull; 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">&bull; Literal</td>
<td>Provided directly by the expression.</td>
</tr>
<tr>
<td class="nowrap">&bull; 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">&bull; Signed Word</td>
<td>
32-bit, two's complement integer.
</td>
</tr>
<tr>
<td class="nowrap">&bull; Unsigned Word</td>
<td>
32-bit, unsigned integer.
</td>
</tr>
<tr>
<td class="nowrap">&bull; Float</td>
<td>
32-bit floating short in IEEE-754 format.
</td>
</tr>
<tr>
<td class="nowrap">&bull; 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 distinguished 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 following
restrictions: if the value of any float literal or 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 value
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 or to be written 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.
</p>
<p>
Each operator considers the types of its operands in order to produce a new
value of the appropriate type. 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 selects the "greater" of the two
types, in the following order (higher is "greater"):
</p>
<table class="indent">
<tr><td class="center narrow">&uarr;</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">&darr;</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 converted to float before performing the operation.
</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 according to the order in
which they appear in the expression: right-to-left for unary operators,
left-to-right for binary operators.
</p>
<table class="indent bordered">
<tr>
<td rowSpan="18" class="middle">Unary</td>
<td class="mono open op1">~</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 rowSpan="20" class="middle">Binary</td>
<td class="mono open op1">/</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">&lt;&lt;</td>
<td class="open">Shift Left</td>
<td class="open">Cannot be used with float values.</td>
</tr>
<tr>
<td class="mono open">&gt;&gt;</td>
<td class="open">Shift Right Arithmetic</td>
<td class="open">Cannot be used with float values.</td>
</tr>
<tr>
<td class="mono">&gt;&gt;&gt;</td>
<td>Shift Right Logical</td>
<td>Cannot be used with float values.</td>
</tr>
<tr>
<td class="mono open">&gt;</td>
<td class="open">Greater</td>
<td class="open">Always produces a boolean.</td>
</tr>
<tr>
<td class="mono open">&gt;=</td>
<td class="open">Greater or Equal</td>
<td class="open">Always produces a boolean.</td>
</tr>
<tr>
<td class="mono open">&lt;</td>
<td class="open">Less</td>
<td class="open">Always produces a boolean.</td>
</tr>
<tr>
<td class="mono">&lt;=</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">&amp;</td>
<td>And Bitwise</td>
<td>Cannot be used with float values.</td>
</tr>
<tr>
<td class="mono">^</td>
<td>Exclusive Or Bitwise</td>
<td>Cannot be used with float values.</td>
</tr>
<tr>
<td class="mono">|</td>
<td>Or Bitwise</td>
<td>Cannot be used with float values.</td>
</tr>
<tr>
<td class="mono">&amp;&amp;</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">&bull; <code>float</code></td>
<td>Behaves like <code>xfloat</code> instead.</td>
</tr>
<tr>
<td class="nowrap">&bull; <code>s8</code>, <code>u8</code></td>
<td>Performs a byte read of the specified signedness.</td>
</tr>
<tr>
<td class="nowrap">&bull; <code>s16</code>, <code>u16</code></td>
<td>Performs a halfword read of the specified signedness.</td>
</tr>
</table>
<p>
Reads are subjected to the alginment restrictions of the Virtual Boy's CPU:
the lowest bit of the address is ignored for halfword reads, and the lowest
two bits of the address are ignored for word reads.
</p>
<h1>&nbsp;</h1>
</body>
</html>