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.