Expression Evaluator

The expression evaluator is a module in the emulator that is capable of interpreting an expression entered by the user and evaluating it against the current emulation state. It is used by the Breakpoint window's Condition field and the CPU window's Goto prompt.

Types

During evaluation, values are tracked internally with one of three types:

Integer A 32-bit two's-complement integer.
Float A 32-bit floating-point "single" in IEEE-754 format.
Boolean A 1-bit value representing true or false.

Booleans cannot be expressed as literals. Float literals are specified by the presence of a decimal point.

Certain operations require particular types, and the values used will automatically be converted to the types needed.

If two different types are used in a binary operation, the value whose type has lower priority will be promoted to the other type. Boolean has lower priority than integer, which has lower priority than float. When a boolean is promoted, false becomes 0 and true becomes 1. For bitwise operations, float values are taken as their actual bits rather than their numeric value.

Floats are not allowed to store NaNs, indefinites or non-zero denormal values. If the result of any operation should produce such a result, it will automatically be converted to zero. The result of float operations will never produce a negative zero.

Integers and floats may be used in logical contexts. A value of false is implicit if the value is zero, or a value of true is implicit otherwise.

The Breakpoint window's Condition field accepts any type as the result of evaluation, and will activate the breakpoint if the result is "true".

The CPU window's Goto prompt requires the results of evaluations to be integer.

Operators

The following operators are available for use in expressions:

Operator Name Type Input type Output type Description
() Precedence Group Any Same as input Operations inside the group will be evaluated before operations outside the group.
[] Read Group Integer Integer Same as (), but the resulting value inside the group is interpreted as an integer then used as the bus address for a 32-bit read operation on the emulation state.
~ Bitwise Not Unary Bits Integer Inverts the bits in the value.
! Logical Not Unary Boolean Boolean Produces the opposite value.
- Negate Unary Integer, Float Same as input Produces the negative of the value.
float Cast to Float Unary Integer, Float Float Converts the value to float.
int Cast to Integer Unary Integer, Float Integer Converts the value to integer by rounding to nearest.
xfloat Reinterpret as Float Unary Integer, Float Float Reinterprets the bits of the value as the corresponding float value, correcting for invalid values.
xint Reinterpret as Integer Unary Integer, Float Integer Reinterprets the bits of the value as the corresponding integer value.
fix Remove Fraction Unary Integer, Float Same as input Determines only the whole number part of the value.
floor Round Down Unary Integer, Float Same as input Rounds down to the next lower whole number value.
round Round Nearest Unary Integer, Float Same as input Rounds to the nearest whole number value.
ceil Round Up Unary Integer, Float Same as input Rounds up to the next higher whole number value.
/ Divide Binary Integer, Float Same as input Divides the left value by the right value. If the right value is zero, the result is zero.
* Multiply Binary Integer, Float Same as input Multiplies the two values.
% Remainder Binary Integer, Float Same as input Divides the left value by the right value and determines the remainder. If the right value is zero, the result is zero.
+ Add Binary Integer, Float Same as input Adds the two values.
- Subtract Binary Integer, Float Same as input Subtracts the right value from the left value.
<< Shift Left Binary Bits Integer Shifts the left value left the amount specified by the lowest 5 bits of the right value.
>> Shift Right Arithmetic Binary Bits Integer Shifts the left value right the amount specified by the lowest 5 bits of the right value. The result propagates the sign bit.
>>> Shift Right Logical Binary Bits Integer Shifts the left value right the amount specified by the lowest 5 bits of the right value. The result fills zeroes in on the left.
> Greater Than Signed Binary Integer, Float Boolean True if the left value is greater than the right value, or false otherwise.
>= Greater Than or Equal Signed Binary Integer, Float Boolean True if the left value is greater than or equal to the right value, or false otherwise.
< Less Than Signed Binary Integer, Float Boolean True if the left value is less than the right value, or false otherwise.
<= Less Than or Equal Signed Binary Integer, Float Boolean True if the left value is less than or equal to the right value, or false otherwise.
>_ Greater Than Unsigned Binary Integer, Float Boolean True if the left value is greater than the right value, or false otherwise. Floats are compared as signed.
>=_ Greater Than or Equal Unsigned Binary Integer, Float Boolean True if the left value is greater than or equal to the right value, or false otherwise. Floats are compared as signed.
<_ Less Than Unsigned Binary Integer, Float Boolean True if the left value is less than the right value, or false otherwise. Floats are compared as signed.
<=_ Less Than or Equal Unsigned Binary Integer, Float Boolean True if the left value is less than or equal to the right value, or false otherwise. Floats are compared as signed.
== Equal Binary Any Boolean True if the values are equal, false otherwise.
!= Not Equal Binary Any Boolean False if the values are equal, true otherwise.
& Bitwise And Binary Bits Integer AND's the corresponding bits of both values.
^ Bitwise Exclusive Or Binary Bits Integer XOR's the corresponding bits of both values.
| Bitwise Or Binary Bits Integer OR's the corresponding bits of both values.
&& Logical And Binary Any Same as input The right value if the left value is "true", or false otherwise.
^^ Logical Exclusive Or Binary Any Same as input If both values are true or both are false, gives zero. Otherwise, gives the "true" value.
|| Logical Or Binary Any Same as input The left value if the left value is "true", or the right value otherwise.

This chart organizes operators into groups. Groups listed earlier in the chart have higher precedence than, and are processed before, groups listed later in the list.

Symbolic Names

In addition to literals and operators, symbolic names can be used in expressions as values:

The current value of the program counter can be used with "pc".
The current value of a program register can be used with "rn", where n is the program register's index. Additionally, aliases gp, hp, lp, sp and tp may be used.
The current value of a system register can be used with its register name: adtre, chcw, ecr, eipc, eipsw, fepc, fepsw, pir, psw, tkcw, and special names for undocumented system registers: sr29, sr30 and sr31.
The exception code for exception breakpoints can be used with code. For other breakpoints, this symbol gives zero.

Operands of the current instruction are available. Any instruction not listed below will give zero for the corresponding operand name:

address The effective/target address for Bcond, JAL, JR, JMP, RETI, TRAP and all format VI instructions.
cond The condition code for Bcond and SETF.
disp The displacement offset for all format III, IV and VI instructions.
format The instruction's format, from 1 to 7.
imm The immediate value for all format II and V instructions except bit string, LDSR, SETF, STSR and TRAP.
inst The internal instruction ID for the instruction. See below for a list of symbolic instruction IDs.
opcode The instruction's opcode. Bcond is given as 0x10.
reg1 The source/address register for all format I, V, VI and VII instructions.
reg2 The destination/data register for all format I, II, V, VI and VII instructions.
regid The system register ID for LDSR and STSR.
size The size in bytes of the instruction.
subopcode The sub-opcode for bit string and floating-point/Nintendo instructions.
vector The vector for TRAP.

When checking the instruction's internal ID with inst, the following symbolic instruction ID names should be used: illegal, add_imm, add_reg, addf.s, addi, and, andbsu, andi, andnbsu, bcond, caxi, cli, cmp_imm, cmp_reg, cmpf.s, cvt.sw, cvt.ws, div, divf.s, divu, halt, in.b, in.h, in.w, jal, jmp, jr, ld.b, ld.h, ld.w, ldsr, mov_imm, mov_reg, movbsu, movea, movhi, mpyhw, mul, mulf.s, mulu, not, or, orbsu, ori, ornbsu, out.b, out.h, out.w, reti, rev, sar_imm, sar_reg, sch0bsd, sch0bsu, sch1bsd, sch1bsu, sei, setf, shl_imm, shl_reg, shr_imm, shr_reg, st.b, st.h, st.w, stsr, sub, subf.s, trap, trnc.sw, xb, xh, xor, xorbsu, xori and xornbsu.