Go to the previous, next section.

Three Operand Instructions

The vast majority of SUIF instructions are represented by the in_rrr class which includes fields for two source operands. Not all of the operands have to be used. For example, nop instructions don't use any operands at all.

The src1_op and src2_op methods retrieve the source operands, and the set_src1 and set_src2 methods assign new operands. Besides the methods to directly access the two source operands, other methods are provided to refer to these sources according to their uses with specific opcodes:

Using these opcode-specific methods with the wrong opcodes will cause errors.

For your convenience, the in_rrr class provides a method, is_unary, to determine if an instruction produces a result value using only one of the source operands. It does not consider return (ret) instructions to be unary because they do not produce result values. Although load (lod) instructions fit the pattern, they are a special case and are not considered to be unary.

The is_commutative method checks the opcode of an instruction to determine if it is a commutative operation. If so, the two source operands should be interchangeable.

Some of the arithmetic instructions may generate run-time exceptions if the appropriate class of exceptions is enabled (see section Miscellaneous Annotations). If the exceptions are not enabled, the rules for ANSI C are used to determine the result.

The following table lists all of the three operand SUIF instructions. Each entry describes the operands used with that opcode and includes any restrictions on the operand and result types.

nop
Do nothing at all. All of the operands for these instructions should be null, and the result type should be the SUIF void type.

lod
Load the value at the address contained in the src1 operand and put it in the dst operand. The result type indicates the type of the value being loaded and may be any type, subject to the usual restrictions on a result type (see section Result Types). The type of the expression in src1 must be a pointer to the result type. The src2 operand is not used.

str
Store the value in the src2 operand at the address contained in the src1 operand. Both operands must be specified. There is no special restriction on the type of the src2 operand, though the restrictions on instruction result types (see section Result Types) and variables (see section Variable Symbols) guarantee it will have a known, non-zero size. The src1 operand should contain an expression that is a pointer to the type of the operand being stored. The dst operand is not used.

memcpy
Memory to memory copy. Load the value from the address in the src2 operand and store it at the address in the src1 operand. The type of the object to be copied is subject to the same conditions as the result type of an instruction (see section Result Types), so it must have known, non-zero size. Both of the source operands must be pointers to this object type. The dst operand is not used.

cpy
Copy the src1 operand to the dst operand. The src2 operand is not used. The result type must be the same as the type of the source operand. The restrictions on instruction result types (see section Result Types) guarantee that the object being copied has known, non-zero size.

cvt
Convert the src1 operand to the result type and put it in the dst operand. The src2 operand is not used. Nothing can can be converted to or from a struct, union, array, or void type. Pointer types can only be converted to and from integer types and other pointer types.

neg
Negation. Change the sign of the value in the src1 operand and put the result in the dst operand. The src2 operand is unused. The result type and the type of the operand must be the same signed integer or floating-point type.

add
Add the values in the src1 and src2 operands and put the result in the dst operand. Except for pointer additions, the result type and the types of the operands must be the same integer or floating-point types. Pointer addition is a special case. One of the source operands may have a pointer type, as long as the other source operand has signed or unsigned integer type of any size; the result type must also be a pointer type, but need not be the same as the source pointer type.

sub
Subtract the value in the src2 operand from the value in the src1 operand and put the result in the dst operand. Except for pointer subtractions, the result type and the types of the operands must be the same integer or floating-point types. There are two special cases for pointer subtractions. In either case, the src1 operand must have a pointer type. First, the src2 operand may have any integer type, in which case the result type may be any pointer type, not necessarily the same as the source pointer type. Second, the src2 operand's type may be another pointer, in which case the result type must be type_ptr_diff.

mul
div
Multiply or divide the value in the src1 operand by the value in the src2 operand and put the result in the dst operand. The result type and the types of the operands must be the same integer or floating-point type. Integer multiplication and division are defined according to the rules for ANSI C.

rem
mod
Remainder and modulus. These two instructions are very similar. Both divide the value in the src1 operand by the value in the src2 operand to find the remainder or modulus. The rem instruction is identical to the modulus operator in ANSI C. That is, if either source operand is negative, the sign of the result is undefined and depends on the semantics of integer division. The mod instruction is the same except that its result is always guaranteed to be positive. The result type and the types of the destination and source operands must be the same integer type.

not
Bit-wise inversion. Compute the one's complement negation of the value in the src1 operand and put the result in the dst operand. The src2 operand is not used. The result type and the types of the operand must be the same unsigned integer type.

and
ior
xor
Compute the bit-wise AND, inclusive OR, or exclusive OR of the values in the src1 and src2 operands and put the result in the dst operand. The result type and the type of the operands must be the same unsigned integer type.

asr
lsr
lsl
Shift the value in the src1 operand right or left by the amount specified in the src2 operand. The variable in the src2 operand must always have an unsigned integer type. The asr instruction performs sign extension and requires that the result type and the type src1 operand be the same signed integer type. The lsr instructions does not perform sign extension and requires that the result type and type of the src1 operand be the same unsigned integer type. Sign extension is not an issue for left shifts, so the lsl instruction only requires that the result type and the type of the src1 operand be the same integer type.

divfloor
divceil
Division combined with floor and ceiling operations. The divfloor opcode means take the rational quotient of the src1 operand by the src2 operand and apply the floor operation (i.e. round to the nearest integer less than or equal to the quotient). The divceil opcode means take the rational quotient of the src1 operand by the src2 operand and apply the ceiling operation (i.e. round to the nearest integer greater than or equal to the quotient). The result type and the operand types must be the same integer type.

min
max
Minimum and maximum. The result value is the minimum or maximum, respectively, of the two source operands. The result type and the operand types must be the same integer or floating-point types.

abs
Absolute value. Compute the absolute value of the src1 operand. The src2 operand is unused. The result type and the source operand type must be the same integer or floating-point type.

rot
Rotate the value in the src1 operand left or right by the amount specified in the src2 operand. The variable in the src2 operand must always have a signed integer type. If the shift amount is positive, the value is rotated to the left (toward the most-significant bit); if it is negative, the value is rotated to the right. The result type and the type of the src1 operand must be the same integer type.

seq
sne
sl
sle
Comparison instructions. If the src1 operand is equal, not equal, less than, or less than or equal, respectively, to the src2 operand, assign the integer value one to the dst operand. Otherwise, set the dst operand to zero. The result type must always be a signed integer type. The source operands must be either the same integer or floating point type, or two (possibly different) pointer types.

ret
Return from a procedure. Only the src1 operand is used and it is optional. If specified, it is the return value and may contain an operand of any type except array or function types. If the procedure's function type has void return type, the operand must be null; otherwise the operand must not be null and must have the same type as the return type of the procedure.

mrk
This pseudo-instruction only marks a position in the program and is used to hold miscellaneous annotations such as line numbers. It is functionally equivalent to a nop instruction. All of the operands for these instructions should be null, and the result type should be the SUIF void type.

Go to the previous, next section.