--- /dev/null	Mon Nov 18 13:18:35 2019
+++ new/usr/src/tools/smatch/src/Documentation/IR.rst	Mon Nov 18 13:18:35 2019
@@ -0,0 +1,427 @@
+.. default-domain:: ir
+
+Sparse's Intermediate Representation
+====================================
+
+Instructions
+~~~~~~~~~~~~
+
+This document briefly describes which field of struct instruction is
+used by which operation.
+
+Some of those fields are used by almost all instructions,
+some others are specific to only one or a few instructions.
+The common ones are:
+
+* .src1, .src2, .src3: (pseudo_t) operands of binops or ternary ops.
+* .src: (pseudo_t) operand of unary ops (alias for .src1).
+* .target: (pseudo_t) result of unary, binary & ternary ops, is
+  sometimes used otherwise by some others instructions.
+* .cond: (pseudo_t) input operands for condition (alias .src/.src1)
+* .type: (symbol*) usually the type of .result, sometimes of the operands
+
+Terminators
+-----------
+.. op:: OP_RET
+	Return from subroutine.
+
+	* .src : returned value (NULL if void)
+	* .type: type of .src
+
+.. op:: OP_BR
+	Unconditional branch
+
+	* .bb_true: destination basic block
+
+.. op:: OP_CBR
+	Conditional branch
+
+	* .cond: condition
+	* .type: type of .cond, must be an integral type
+	* .bb_true, .bb_false: destination basic blocks
+
+.. op:: OP_SWITCH
+	Switch / multi-branch
+
+	* .cond: condition
+	* .type: type of .cond, must be an integral type
+	* .multijmp_list: pairs of case-value - destination basic block
+
+.. op:: OP_COMPUTEDGOTO
+	Computed goto / branch to register
+
+	* .src: address to branch to (void*)
+	* .multijmp_list: list of possible destination basic blocks
+
+Arithmetic binops
+-----------------
+They all follow the same signature:
+	* .src1, .src1: operands (types must be compatible with .target)
+	* .target: result of the operation (must be an integral type)
+	* .type: type of .target
+
+.. op:: OP_ADD
+	Integer addition.
+
+.. op:: OP_SUB
+	Integer subtraction.
+
+.. op:: OP_MUL
+	Integer multiplication.
+
+.. op:: OP_DIVU
+	Integer unsigned division.
+
+.. op:: OP_DIVS
+	Integer signed division.
+
+.. op:: OP_MODU
+	Integer unsigned remainder.
+
+.. op:: OP_MODS
+	Integer signed remainder.
+
+.. op:: OP_SHL
+	Shift left (integer only)
+
+.. op:: OP_LSR
+	Logical Shift right (integer only)
+
+.. op:: OP_ASR
+	Arithmetic Shift right (integer only)
+
+Floating-point binops
+---------------------
+They all follow the same signature:
+	* .src1, .src1: operands (types must be compatible with .target)
+	* .target: result of the operation (must be a floating-point type)
+	* .type: type of .target
+
+.. op:: OP_FADD
+	Floating-point addition.
+
+.. op:: OP_FSUB
+	Floating-point subtraction.
+
+.. op:: OP_FMUL
+	Floating-point multiplication.
+
+.. op:: OP_FDIV
+	Floating-point division.
+
+Logical ops
+-----------
+They all follow the same signature:
+	* .src1, .src2: operands (types must be compatible with .target)
+	* .target: result of the operation
+	* .type: type of .target, must be an integral type
+
+.. op:: OP_AND
+	Logical AND
+
+.. op:: OP_OR
+	Logical OR
+
+.. op:: OP_XOR
+	Logical XOR
+
+Integer compares
+----------------
+They all have the following signature:
+	* .src1, .src2: operands (types must be compatible)
+	* .target: result of the operation (0/1 valued integer)
+	* .type: type of .target, must be an integral type
+
+.. op:: OP_SET_EQ
+	Compare equal.
+
+.. op:: OP_SET_NE
+	Compare not-equal.
+
+.. op:: OP_SET_LE
+	Compare less-than-or-equal (signed).
+
+.. op:: OP_SET_GE
+	Compare greater-than-or-equal (signed).
+
+.. op:: OP_SET_LT
+	Compare less-than (signed).
+
+.. op:: OP_SET_GT
+	Compare greater-than (signed).
+
+.. op:: OP_SET_B
+	Compare less-than (unsigned).
+
+.. op:: OP_SET_A
+	Compare greater-than (unsigned).
+
+.. op:: OP_SET_BE
+	Compare less-than-or-equal (unsigned).
+
+.. op:: OP_SET_AE
+	Compare greater-than-or-equal (unsigned).
+
+Floating-point compares
+-----------------------
+They all have the same signature as the integer compares.
+
+The usual 6 operations exist in two versions: 'ordered' and
+'unordered'. These operations first check if any operand is a
+NaN and if it is the case the ordered compares return false
+and then unordered return true, otherwise the result of the
+comparison, now guaranteed to be done on non-NaNs, is returned.
+
+.. op:: OP_FCMP_OEQ
+	Floating-point compare ordered equal
+
+.. op:: OP_FCMP_ONE
+	Floating-point compare ordered not-equal
+
+.. op:: OP_FCMP_OLE
+	Floating-point compare ordered less-than-or-equal
+
+.. op:: OP_FCMP_OGE
+	Floating-point compare ordered greater-or-equal
+
+.. op:: OP_FCMP_OLT
+	Floating-point compare ordered less-than
+
+.. op:: OP_FCMP_OGT
+	Floating-point compare ordered greater-than
+
+
+.. op:: OP_FCMP_UEQ
+	Floating-point compare unordered equal
+
+.. op:: OP_FCMP_UNE
+	Floating-point compare unordered not-equal
+
+.. op:: OP_FCMP_ULE
+	Floating-point compare unordered less-than-or-equal
+
+.. op:: OP_FCMP_UGE
+	Floating-point compare unordered greater-or-equal
+
+.. op:: OP_FCMP_ULT
+	Floating-point compare unordered less-than
+
+.. op:: OP_FCMP_UGT
+	Floating-point compare unordered greater-than
+
+
+.. op:: OP_FCMP_ORD
+	Floating-point compare ordered: return true if both operands are ordered
+	(none of the operands are a NaN) and false otherwise.
+
+.. op:: OP_FCMP_UNO
+	Floating-point compare unordered: return false if no operands is ordered
+	and true otherwise.
+
+Unary ops
+---------
+.. op:: OP_NOT
+	Logical not.
+
+	* .src: operand (type must be compatible with .target)
+	* .target: result of the operation
+	* .type: type of .target, must be an integral type
+
+.. op:: OP_NEG
+	Integer negation.
+
+	* .src: operand (type must be compatible with .target)
+	* .target: result of the operation (must be an integral type)
+	* .type: type of .target
+
+.. op:: OP_FNEG
+	Floating-point negation.
+
+	* .src: operand (type must be compatible with .target)
+	* .target: result of the operation (must be a floating-point type)
+	* .type: type of .target
+
+.. op:: OP_SYMADDR
+	Create a pseudo corresponding to the address of a symbol.
+
+	* .src: input symbol (must be a PSEUDO_SYM)
+	* .target: symbol's address
+
+.. op:: OP_COPY
+	Copy (only needed after out-of-SSA).
+
+	* .src: operand (type must be compatible with .target)
+	* .target: result of the operation
+	* .type: type of .target
+
+Type conversions
+----------------
+They all have the following signature:
+	* .src: source value
+	* .orig_type: type of .src
+	* .target: result value
+	* .type: type of .target
+
+Currently, a cast to a void pointer is treated like a cast to
+an unsigned integer of the same size.
+
+.. op:: OP_TRUNC
+	Cast from integer to an integer of a smaller size.
+
+.. op:: OP_SEXT
+	Cast from integer to an integer of a bigger size with sign extension.
+
+.. op:: OP_ZEXT
+	Cast from integer to an integer of a bigger size with zero extension.
+
+.. op:: OP_UTPTR
+	Cast from pointer-sized unsigned integer to pointer type.
+
+.. op:: OP_PTRTU
+	Cast from pointer type to pointer-sized unsigned integer.
+
+.. op:: OP_PTRCAST
+	Cast between pointers.
+
+.. op:: OP_FCVTU
+	Conversion from float type to unsigned integer.
+
+.. op:: OP_FCVTS
+	Conversion from float type to signed integer.
+
+.. op:: OP_UCVTF
+	Conversion from unsigned integer to float type.
+
+.. op:: OP_SCVTF
+	Conversion from signed integer to float type.
+
+.. op:: OP_FCVTF
+	Conversion between float types.
+
+Ternary ops
+-----------
+.. op:: OP_SEL
+	* .src1: condition, must be of integral type
+	* .src2, .src3: operands (types must be compatible with .target)
+	* .target: result of the operation
+	* .type: type of .target
+
+.. op:: OP_RANGE
+	Range/bounds checking (only used for an unused sparse extension).
+
+	* .src1: value to be checked
+	* .src2, src3: bound of the value (must be constants?)
+	* .type: type of .src[123]?
+
+Memory ops
+----------
+.. op:: OP_LOAD
+	Load.
+
+	* .src: base address to load from
+	* .offset: address offset
+	* .target: loaded value
+	* .type: type of .target
+
+.. op:: OP_STORE
+	Store.
+
+	* .src: base address to store to
+	* .offset: address offset
+	* .target: value to be stored
+	* .type: type of .target
+
+Others
+------
+.. op:: OP_SETFVAL
+	Create a pseudo corresponding to a floating-point literal.
+
+	* .fvalue: the literal's value (long double)
+	* .target: the corresponding pseudo
+	* .type: type of the literal & .target
+
+.. op:: OP_SETVAL
+	Create a pseudo corresponding to a string literal or a label-as-value.
+	The value is given as an expression EXPR_STRING or EXPR_LABEL.
+
+	* .val: (expression) input expression
+	* .target: the resulting value
+	* .type: type of .target, the value
+
+.. op:: OP_PHI
+	Phi-node (for SSA form).
+
+	* .phi_list: phi-operands (type must be compatible with .target)
+	* .target: "result"
+	* .type: type of .target
+
+.. op:: OP_PHISOURCE
+	Phi-node source.
+	Like OP_COPY but exclusively used to give a defining instructions
+	(and thus also a type) to *all* OP_PHI operands.
+
+	* .phi_src: operand (type must be compatible with .target, alias .src)
+	* .target: the "result" PSEUDO_PHI
+	* .type: type of .target
+	* .phi_users: list of phi instructions using the target pseudo
+
+.. op:: OP_CALL
+	Function call.
+
+	* .func: (pseudo_t) the function (can be a symbol or a "register",
+	  alias .src))
+	* .arguments: (pseudo_list) list of the associated arguments
+	* .target: function return value (if any)
+	* .type: type of .target
+	* .fntypes: (symbol_list) list of the function's types: the first
+	  entry is the full function type, the next ones are the type of
+	  each arguments
+
+.. op:: OP_INLINED_CALL
+	Only used as an annotation to show that the instructions just above
+	correspond to a function that have been inlined.
+
+	* .func: (pseudo_t) the function (must be a symbol, alias .src))
+	* .arguments: list of pseudos that where the function's arguments
+	* .target: function return value (if any)
+	* .type: type of .target
+
+.. op:: OP_SLICE
+	Extract a "slice" from an aggregate.
+
+	* .base: (pseudo_t) aggregate (alias .src)
+	* .from, .len: offet & size of the "slice" within the aggregate
+	* .target: result
+	* .type: type of .target
+
+.. op:: OP_ASM
+	Inlined assembly code.
+
+	* .string: asm template
+	* .asm_rules: asm constraints, rules
+
+Sparse tagging (line numbers, context, whatever)
+------------------------------------------------
+.. op:: OP_CONTEXT
+	Currently only used for lock/unlock tracking.
+
+	* .context_expr: unused
+	* .increment: (1 for locking, -1 for unlocking)
+	* .check: (ignore the instruction if 0)
+
+Misc ops
+--------
+.. op:: OP_ENTRY
+	Function entry point (no associated semantic).
+
+.. op:: OP_BADOP
+	Invalid operation (should never be generated).
+
+.. op:: OP_NOP
+	No-op (should never be generated).
+
+.. op:: OP_DEATHNOTE
+	Annotation telling the pseudo will be death after the next
+	instruction (other than some other annotation, that is).
+
+.. # vim: tabstop=4
