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:
asr, lsl, lsr, and
rot) may use the shift_cnt_op and set_shift_cnt_op
methods to access the operand that specifies the numbers of bits to
shift or rotate. The other source operand may be accessed with the
src_op and set_src methods.
str) and memory copy (memcpy) instructions may use
the dst_addr_op and set_dst_addr_op methods to access the
source operand that holds the destination address for the memory
reference.
lod) and memory copy (memcpy) instructions may use
the src_addr_op and set_src_addr_op methods to access the
operand that specifies the source address for the memory reference.
Note that the actual operand field that is used is different for these
two opcodes.
src_op and set_src methods without specifying whether the
first or second operand field is used. In addition, a store
(str) instruction may use these methods to refer to the operand
holding the value to be stored. They are also used by shift and rotate
instructions as described above.
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
void type.
lod
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
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
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
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
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
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
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
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
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
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
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
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
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
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
abs
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
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
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
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
nop instruction. All of the
operands for these instructions should be null, and the result type
should be the SUIF void type.