(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(** Conditions (boolean-valued operators). *)

Inductive condition : Type :=
  | Ccomp: comparison -> condition      (**r signed integer comparison *)
  | Ccompu: comparison -> condition     (**r unsigned integer comparison *)
  | Ccompimm: comparison -> int -> condition (**r signed integer comparison with a constant *)
  | Ccompuimm: comparison -> int -> condition (**r unsigned integer comparison with a constant *)
  | Ccompf: comparison -> condition     (**r floating-point comparison *)
  | Cnotcompf: comparison -> condition  (**r negation of a floating-point comparison *)
  | Cmaskzero: int -> condition         (**r test [(arg & constant) == 0] *)
  | Cmasknotzero: int -> condition      (**r test [(arg & constant) != 0] *)
(*c PPC64 specific conditions: *)
  | Ccompl: comparison -> condition     (**r signed int64 comparison *)
  | Ccomplu: comparison -> condition    (**r unsigned int64 comparison *)
  | Ccomplimm: comparison -> int64 -> condition (**r signed int64 comparison with a constant *)
  | Ccompluimm: comparison -> int64 -> condition.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r unsigned int64 comparison with a constant *)

(** Arithmetic and logical operations.  In the descriptions, [rd] is the
  result of the operation and [r1], [r2], etc, are the arguments. *)

Inductive operation : Type :=
  | Omove: operation                    (**r [rd = r1] *)
  | Ointconst: int -> operation         (**r [rd] is set to the given integer constant *)
  | Ofloatconst: float -> operation     (**r [rd] is set to the given float constant *)
  | Osingleconst: float32 -> operation  (**r [rd] is set to the given float constant *)
  | Oaddrsymbol: ident -> ptrofs -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
  | Oaddrstack: ptrofs -> operation     (**r [rd] is set to the stack pointer plus the given offset *)
(*c Integer arithmetic: *)
  | Ocast8signed: operation             (**r [rd] is 8-bit sign extension of [r1] *)
  | Ocast16signed: operation            (**r [rd] is 16-bit sign extension of [r1] *)
  | Oadd: operation                     (**r [rd = r1 + r2] *)
  | Oaddimm: int -> operation           (**r [rd = r1 + n] *)
  | Oaddsymbol: ident -> ptrofs -> operation (**r [rd = addr(id + ofs) + r1] *)
  | Osub: operation                     (**r [rd = r1 - r2] *)
  | Osubimm: int -> operation           (**r [rd = n - r1] *)
  | Omul: operation                     (**r [rd = r1 * r2] *)
  | Omulimm: int -> operation           (**r [rd = r1 * n] *)
  | Omulhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omulhu: operation                   (**r [rd = high part of r1 * r2, unsigned] *)
  | Odiv: operation                     (**r [rd = r1 / r2] (signed) *)
  | Odivu: operation                    (**r [rd = r1 / r2] (unsigned) *)
  | Oand: operation                     (**r [rd = r1 & r2] *)
  | Oandimm: int -> operation           (**r [rd = r1 & n] *)
  | Oor: operation                      (**r [rd = r1 | r2] *)
  | Oorimm: int -> operation            (**r [rd = r1 | n] *)
  | Oxor: operation                     (**r [rd = r1 ^ r2] *)
  | Oxorimm: int -> operation           (**r [rd = r1 ^ n] *)
  | Onot: operation                     (**r [rd = ~r1] *)
  | Onand: operation                    (**r [rd = ~(r1 & r2)] *)
  | Onor: operation                     (**r [rd = ~(r1 | r2)] *)
  | Onxor: operation                    (**r [rd = ~(r1 ^ r2)] *)
  | Oandc: operation                    (**r [rd = r1 & ~r2] *)
  | Oorc: operation                     (**r [rd = r1 | ~r2] *)
  | Oshl: operation                     (**r [rd = r1 << r2] *)
  | Oshr: operation                     (**r [rd = r1 >> r2] (signed) *)
  | Oshrimm: int -> operation           (**r [rd = r1 >> n] (signed) *)
  | Oshrximm: int -> operation          (**r [rd = r1 / 2^n] (signed) *)
  | Oshru: operation                    (**r [rd = r1 >> r2] (unsigned) *)
  | Orolm: int -> int -> operation      (**r rotate left and mask *)
  | Oroli: int -> int -> operation      (**r rotate left and insert *)
(*c PPC64 64-bit integer arithmetic: *)
  | Olongconst: int64 -> operation      (**r [rd] is set to the given int64 constant *)
  | Ocast32signed: operation            (**r [rd] is 64-bit sign extension of [r1] *)
  | Ocast32unsigned: operation          (**r [rd] is 64-bit zero extension of [r1] *)
  | Oaddl: operation                    (**r [rd = r1 + r2] *)
  | Oaddlimm: int64 -> operation        (**r [rd = r1 + n] *)
  | Osubl: operation                    (**r [rd = r1 - r2] *)
  | Onegl: operation                    (**r [rd = - r1] *)
  | Omull: operation                    (**r [rd = r1 * r2] *)
  | Omullhs: operation                   (**r [rd = high part of r1 * r2, signed] *)
  | Omullhu: operation                  (**r [rd = high part of r1 * r2, unsigned] *)
  | Odivl: operation                    (**r [rd = r1 / r2] (signed) *)
  | Odivlu: operation                   (**r [rd = r1 / r2] (unsigned) *)
  | Oandl: operation                    (**r [rd = r1 & r2] *)
  | Oandlimm: int64 -> operation        (**r [rd = r1 & n] *)
  | Oorl: operation                     (**r [rd = r1 | r2] *)
  | Oorlimm: int64 -> operation         (**r [rd = r1 | n] *)
  | Oxorl: operation                    (**r [rd = r1 ^ r2] *)
  | Oxorlimm: int64 -> operation        (**r [rd = r1 ^ n] *)
  | Onotl: operation                    (**r [rd = ~r1] *)
  | Oshll: operation                    (**r [rd = r1 << r2] *)
  | Oshrl: operation                    (**r [rd = r1 >> r2] (signed) *)
  | Oshrlimm: int -> operation          (**r [rd = r1 >> n] (signed) *)
  | Oshrxlimm: int -> operation         (**r [rd = r1 / 2^n] (signed) *)
  | Oshrlu: operation                   (**r [rd = r1 >> r2] (unsigned) *)
  | Orolml: int -> int64 -> operation   (**r rotate left and mask *)
  | Olongoffloat: operation             (**r [rd = signed_int64_of_float(r1)] *)
  | Ofloatoflong: operation             (**r [rd = float_of_signed_int64(r1)] *)
(*c Floating-point arithmetic: *)
  | Onegf: operation                    (**r [rd = - r1] *)
  | Oabsf: operation                    (**r [rd = abs(r1)] *)
  | Oaddf: operation                    (**r [rd = r1 + r2] *)
  | Osubf: operation                    (**r [rd = r1 - r2] *)
  | Omulf: operation                    (**r [rd = r1 * r2] *)
  | Odivf: operation                    (**r [rd = r1 / r2] *)
  | Onegfs: operation                   (**r [rd = - r1] *)
  | Oabsfs: operation                   (**r [rd = abs(r1)] *)
  | Oaddfs: operation                   (**r [rd = r1 + r2] *)
  | Osubfs: operation                   (**r [rd = r1 - r2] *)
  | Omulfs: operation                   (**r [rd = r1 * r2] *)
  | Odivfs: operation                   (**r [rd = r1 / r2] *)
  | Osingleoffloat: operation           (**r [rd] is [r1] truncated to single-precision float *)
  | Ofloatofsingle: operation           (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
  | Ointoffloat: operation              (**r [rd = signed_int_of_float(r1)] *)
  | Ointuoffloat: operation             (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
  | Ofloatofint: operation              (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
  | Ofloatofintu: operation             (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
  | Ofloatofwords: operation            (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
  | Omakelong: operation                (**r [rd = r1 << 32 | r2] *)
  | Olowlong: operation                 (**r [rd = low-word(r1)] *)
  | Ohighlong: operation                (**r [rd = high-word(r1)] *)
(*c Boolean tests: *)
  | Ocmp: condition -> operation.(**r [rd = 1] if condition holds, [rd = 0] otherwise. *)


(** Addressing modes.  [r1], [r2], etc, are the arguments to the
  addressing. *)

Inductive addressing: Type :=
  | Aindexed: int -> addressing            (**r Address is [r1 + offset] *)
  | Aindexed2: addressing                  (**r Address is [r1 + r2] *)
  | Aglobal: ident -> ptrofs -> addressing (**r Address is [symbol + offset] *)
  | Abased: ident -> ptrofs -> addressing  (**r Address is [symbol + offset + r1] *)
  | Ainstack: ptrofs -> addressing.(**r [rd = 1] if condition holds, [rd = 0] otherwise. *)


(** Addressing modes.  [r1], [r2], etc, are the arguments to the
  addressing. *)

Inductive addressing: Type :=
  | Aindexed: int -> addressing            (**r Address is [r1 + offset] *)
  | Aindexed2: addressing                  (**r Address is [r1 + r2] *)
  | Aglobal: ident -> ptrofs -> addressing (**r Address is [symbol + offset] *)
  | Abased: ident -> ptrofs -> addressing  (**r Address is [symbol + offset + r1] *)
  | Ainstack: ptrofs -> addressing.(**r [rd = 1] if condition holds, [rd = 0] otherwise. *)


(** Addressing modes.  [r1], [r2], etc, are the arguments to the
  addressing. *)

Inductive addressing: Type :=
  | Aindexed: int -> addressing            (**r Address is [r1 + offset] *)
  | Aindexed2: addressing                  (**r Address is [r1 + r2] *)
  | Aglobal: ident -> ptrofs -> addressing (**r Address is [symbol + offset] *)
  | Abased: ident -> ptrofs -> addressing  (**r Address is [symbol + offset + r1] *)
  | Ainstack: ptrofs -> addressing.(**r [rd = 1] if condition holds, [rd = 0] otherwise. *)


(** Addressing modes.  [r1], [r2], etc, are the arguments to the
  addressing. *)

Inductive addressing: Type :=
  | Aindexed: int -> addressing            (**r Address is [r1 + offset] *)
  | Aindexed2: addressing                  (**r Address is [r1 + r2] *)
  | Aglobal: ident -> ptrofs -> addressing (**r Address is [symbol + offset] *)
  | Abased: ident -> ptrofs -> addressing  (**r Address is [symbol + offset + r1] *)
  | Ainstack: ptrofs -> addressing.(**r [rd = 1] if condition holds, [rd = 0] otherwise. *)


(** Addressing modes.  [r1], [r2], etc, are the arguments to the
  addressing. *)

Inductive addressing: Type :=
  | Aindexed: int -> addressing            (**r Address is [r1 + offset] *)
  | Aindexed2: addressing                  (**r Address is [r1 + r2] *)
  | Aglobal: ident -> ptrofs -> addressing (**r Address is [symbol + offset] *)
  | Abased: ident -> ptrofs -> addressing  (**r Address is [symbol + offset + r1] *)
  | Ainstack: ptrofs -> addressing.(**r [rd = 1] if condition holds, [rd = 0] otherwise. *)


(** Addressing modes.  [r1], [r2], etc, are the arguments to the
  addressing. *)

Inductive addressing: Type :=
  | Aindexed: int -> addressing            (**r Address is [r1 + offset] *)
  | Aindexed2: addressing                  (**r Address is [r1 + r2] *)
  | Aglobal: ident -> ptrofs -> addressing (**r Address is [symbol + offset] *)
  | Abased: ident -> ptrofs -> addressing  (**r Address is [symbol + offset + r1] *)
  | Ainstack: ptrofs -> addressing.(**r Address is [stack_pointer + offset] *)

(** Comparison functions (used in module [CSE]). *)

Definition eq_condition (x y: condition) : {x=y} + {x<>y}.Definition beq_operation: forall (x y: operation), bool.Definition eq_operation (x y: operation): {x=y} + {x<>y}.Definition eq_addressing (x y: addressing) : {x=y} + {x<>y}.(** * Evaluation functions *)

(** Evaluation of conditions, operators and addressing modes applied
  to lists of values.  Return [None] when the computation can trigger an
  error, e.g. integer division by zero.  [eval_condition] returns a boolean,
  [eval_operation] and [eval_addressing] return a value. *)

Definition eval_condition (cond: condition) (vl: list val) (m: mem): option bool :=
  match cond, vl with
  | Ccomp c, v1 :: v2 :: nil => Val.cmp_bool c v1 v2
  | Ccompu c, v1 :: v2 :: nil => Val.cmpu_bool (Mem.valid_pointer m) c v1 v2
  | Ccompimm c n, v1 :: nil => Val.cmp_bool c v1 (Vint n)
  | Ccompuimm c n, v1 :: nil => Val.cmpu_bool (Mem.valid_pointer m) c v1 (Vint n)
  | Ccompf c, v1 :: v2 :: nil => Val.cmpf_bool c v1 v2
  | Cnotcompf c, v1 :: v2 :: nil => option_map negb (Val.cmpf_bool c v1 v2)
  | Cmaskzero n, v1 :: nil => Val.maskzero_bool v1 n
  | Cmasknotzero n, v1 :: nil => option_map negb (Val.maskzero_bool v1 n)
  | Ccompl c, v1 :: v2 :: nil => Val.cmpl_bool c v1 v2
  | Ccomplu c, v1 :: v2 :: nil => Val.cmplu_bool (Mem.valid_pointer m) c v1 v2
  | Ccomplimm c n, v1 :: nil => Val.cmpl_bool c v1 (Vlong n)
  | Ccompluimm c n, v1 :: nil => Val.cmplu_bool (Mem.valid_pointer m) c v1 (Vlong n)
  | _, _ => None
  end.Definition eval_operation
             (F V: Type) (genv: Genv.t F V) (sp: val)
             (op: operation) (vl: list val) (m: mem): option val :=
  match op, vl with
  | Omove, v1::nil => Some v1
  | Ointconst n, nil => Some (Vint n)
  | Ofloatconst n, nil => Some (Vfloat n)
  | Osingleconst n, nil => Some (Vsingle n)
  | Oaddrsymbol s ofs, nil => Some (Genv.symbol_address genv s ofs)
  | Oaddrstack ofs, nil => Some (Val.offset_ptr sp ofs)
  | Ocast8signed, v1::nil => Some (Val.sign_ext 8 v1)
  | Ocast16signed, v1::nil => Some (Val.sign_ext 16 v1)
  | Oadd, v1::v2::nil => Some (Val.add v1 v2)
  | Oaddimm n, v1::nil => Some (Val.add v1 (Vint n))
  | Oaddsymbol s ofs, v1::nil => Some (Val.add (Genv.symbol_address genv s ofs) v1)
  | Osub, v1::v2::nil => Some (Val.sub v1 v2)
  | Osubimm n, v1::nil => Some (Val.sub (Vint n) v1)
  | Omul, v1::v2::nil => Some (Val.mul v1 v2)
  | Omulimm n, v1::nil => Some (Val.mul v1 (Vint n))
  | Omulhs, v1::v2::nil => Some (Val.mulhs v1 v2)
  | Omulhu, v1::v2::nil => Some (Val.mulhu v1 v2)
  | Odiv, v1::v2::nil => Val.divs v1 v2
  | Odivu, v1::v2::nil => Val.divu v1 v2
  | Oand, v1::v2::nil => Some(Val.and v1 v2)
  | Oandimm n, v1::nil => Some (Val.and v1 (Vint n))
  | Oor, v1::v2::nil => Some(Val.or v1 v2)
  | Oorimm n, v1::nil => Some (Val.or v1 (Vint n))
  | Oxor, v1::v2::nil => Some(Val.xor v1 v2)
  | Oxorimm n, v1::nil => Some (Val.xor v1 (Vint n))
  | Onot, v1::nil => Some(Val.notint v1)
  | Onand, v1::v2::nil => Some (Val.notint (Val.and v1 v2))
  | Onor, v1::v2::nil => Some (Val.notint (Val.or v1 v2))
  | Onxor, v1::v2::nil => Some (Val.notint (Val.xor v1 v2))
  | Oandc, v1::v2::nil => Some (Val.and v1 (Val.notint v2))
  | Oorc, v1::v2::nil => Some (Val.or v1 (Val.notint v2))
  | Oshl, v1::v2::nil => Some (Val.shl v1 v2)
  | Oshr, v1::v2::nil => Some (Val.shr v1 v2)
  | Oshrimm n, v1::nil => Some (Val.shr v1 (Vint n))
  | Oshrximm n, v1::nil => Val.shrx v1 (Vint n)
  | Oshru, v1::v2::nil => Some (Val.shru v1 v2)
  | Orolm amount mask, v1::nil => Some (Val.rolm v1 amount mask)
  | Oroli amount mask, v1::v2::nil =>
      Some(Val.or (Val.and v1 (Vint (Int.not mask))) (Val.rolm v2 amount mask))
  | Olongconst n, nil => Some (Vlong n)
  | Ocast32signed, v1::nil => Some (Val.longofint v1)
  | Ocast32unsigned, v1::nil => Some (Val.longofintu v1)
  | Oaddl, v1::v2::nil => Some (Val.addl v1 v2)
  | Oaddlimm n, v1::nil => Some (Val.addl v1 (Vlong n))
  | Osubl, v1::v2::nil => Some (Val.subl v1 v2)
  | Onegl, v1::nil => Some (Val.negl v1)
  | Omull, v1::v2::nil => Some (Val.mull v1 v2)
  | Omullhs, v1::v2::nil => Some (Val.mullhs v1 v2)
  | Omullhu, v1::v2::nil => Some (Val.mullhu v1 v2)
  | Odivl, v1::v2::nil => Val.divls v1 v2
  | Odivlu, v1::v2::nil => Val.divlu v1 v2
  | Oandl, v1::v2::nil => Some(Val.andl v1 v2)
  | Oandlimm n, v1::nil => Some (Val.andl v1 (Vlong n))
  | Oorl, v1::v2::nil => Some(Val.orl v1 v2)
  | Oorlimm n, v1::nil => Some (Val.orl v1 (Vlong n))
  | Oxorl, v1::v2::nil => Some(Val.xorl v1 v2)
  | Oxorlimm n, v1::nil => Some (Val.xorl v1 (Vlong n))
  | Onotl, v1::nil => Some(Val.notl v1)
  | Oshll, v1::v2::nil => Some (Val.shll v1 v2)
  | Oshrl, v1::v2::nil => Some (Val.shrl v1 v2)
  | Oshrlimm n, v1::nil => Some (Val.shrl v1 (Vint n))
  | Oshrxlimm n, v1::nil => Val.shrxl v1 (Vint n)
  | Oshrlu, v1::v2::nil => Some (Val.shrlu v1 v2)
  | Orolml amount mask, v1::nil => Some (Val.rolml v1 amount mask)
  | Olongoffloat, v1::nil => Val.longoffloat v1
  | Ofloatoflong, v1::nil => Val.floatoflong v1
  | Onegf, v1::nil => Some(Val.negf v1)
  | Oabsf, v1::nil => Some(Val.absf v1)
  | Oaddf, v1::v2::nil => Some(Val.addf v1 v2)
  | Osubf, v1::v2::nil => Some(Val.subf v1 v2)
  | Omulf, v1::v2::nil => Some(Val.mulf v1 v2)
  | Odivf, v1::v2::nil => Some(Val.divf v1 v2)
  | Onegfs, v1::nil => Some(Val.negfs v1)
  | Oabsfs, v1::nil => Some(Val.absfs v1)
  | Oaddfs, v1::v2::nil => Some(Val.addfs v1 v2)
  | Osubfs, v1::v2::nil => Some(Val.subfs v1 v2)
  | Omulfs, v1::v2::nil => Some(Val.mulfs v1 v2)
  | Odivfs, v1::v2::nil => Some(Val.divfs v1 v2)
  | Osingleoffloat, v1::nil => Some(Val.singleoffloat v1)
  | Ofloatofsingle, v1::nil => Some(Val.floatofsingle v1)
  | Ointoffloat, v1::nil => Val.intoffloat v1
  | Ointuoffloat, v1::nil => Val.intuoffloat v1
  | Ofloatofint, v1::nil => Val.floatofint v1
  | Ofloatofintu, v1::nil => Val.floatofintu v1
  | Ofloatofwords, v1::v2::nil => Some(Val.floatofwords v1 v2)
  | Omakelong, v1::v2::nil => Some(Val.longofwords v1 v2)
  | Olowlong, v1::nil => Some(Val.loword v1)
  | Ohighlong, v1::nil => Some(Val.hiword v1)
  | Ocmp c, _ => Some(Val.of_optbool (eval_condition c vl m))
  | _, _ => None
  end.Definition eval_addressing
    (F V: Type) (genv: Genv.t F V) (sp: val)
    (addr: addressing) (vl: list val) : option val :=
  match addr, vl with
  | Aindexed n, v1::nil => Some (Val.add v1 (Vint n))
  | Aindexed2, v1::v2::nil => Some (Val.add v1 v2)
  | Aglobal s ofs, nil => Some (Genv.symbol_address genv s ofs)
  | Abased s ofs, v1::nil => Some (Val.add (Genv.symbol_address genv s ofs) v1)
  | Ainstack ofs, nil => Some(Val.offset_ptr sp ofs)
  | _, _ => None
  end.Remark eval_addressing_Ainstack:
  forall (F V: Type) (genv: Genv.t F V) sp ofs,
  eval_addressing genv sp (Ainstack ofs) nil = Some (Val.offset_ptr sp ofs).Remark eval_addressing_Ainstack_inv:
  forall (F V: Type) (genv: Genv.t F V) sp ofs vl v,
  eval_addressing genv sp (Ainstack ofs) vl = Some v -> vl = nil /\ v = Val.offset_ptr sp ofs.Ltac FuncInv :=
  match goal with
  | H: (match ?x with nil => _ | _ :: _ => _ end = Some _) |- _ =>
      destruct x; simpl in H; try discriminate; FuncInv
  | H: (match ?v with Vundef => _ | Vint _ => _ | Vlong _ => _ | Vfloat _ => _ | Vptr _ _ => _ end = Some _) |- _ =>
      destruct v; simpl in H; try discriminate; FuncInv
  | H: (Some _ = Some _) |- _ =>
      injection H; intros; clear H; FuncInv
  | _ =>
      idtac
  end.(** * Static typing of conditions, operators and addressing modes. *)

Definition type_of_condition (c: condition) : list typ :=
  match c with
  | Ccomp _ => Tint :: Tint :: nil
  | Ccompu _ => Tint :: Tint :: nil
  | Ccompimm _ _ => Tint :: nil
  | Ccompuimm _ _ => Tint :: nil
  | Ccompf _ => Tfloat :: Tfloat :: nil
  | Cnotcompf _ => Tfloat :: Tfloat :: nil
  | Cmaskzero _ => Tint :: nil
  | Cmasknotzero _ => Tint :: nil
  | Ccompl _ => Tlong :: Tlong :: nil
  | Ccomplu _ => Tlong :: Tlong :: nil
  | Ccomplimm _ _ => Tlong :: nil
  | Ccompluimm _ _ => Tlong :: nil
  end.Definition type_of_operation (op: operation) : list typ * typ :=
  match op with
  | Omove => (nil, Tint)   (* treated specially *)
  | Ointconst _ => (nil, Tint)
  | Ofloatconst f => (nil, Tfloat)
  | Osingleconst f => (nil, Tsingle)
  | Oaddrsymbol _ _ => (nil, Tint)
  | Oaddrstack _ => (nil, Tint)
  | Ocast8signed => (Tint :: nil, Tint)
  | Ocast16signed => (Tint :: nil, Tint)
  | Oadd => (Tint :: Tint :: nil, Tint)
  | Oaddimm _ => (Tint :: nil, Tint)
  | Oaddsymbol _ _ => (Tint :: nil, Tint)
  | Osub => (Tint :: Tint :: nil, Tint)
  | Osubimm _ => (Tint :: nil, Tint)
  | Omul => (Tint :: Tint :: nil, Tint)
  | Omulimm _ => (Tint :: nil, Tint)
  | Omulhs => (Tint :: Tint :: nil, Tint)
  | Omulhu => (Tint :: Tint :: nil, Tint)
  | Odiv => (Tint :: Tint :: nil, Tint)
  | Odivu => (Tint :: Tint :: nil, Tint)
  | Oand => (Tint :: Tint :: nil, Tint)
  | Oandimm _ => (Tint :: nil, Tint)
  | Oor => (Tint :: Tint :: nil, Tint)
  | Oorimm _ => (Tint :: nil, Tint)
  | Oxor => (Tint :: Tint :: nil, Tint)
  | Oxorimm _ => (Tint :: nil, Tint)
  | Onot => (Tint :: nil, Tint)
  | Onand => (Tint :: Tint :: nil, Tint)
  | Onor => (Tint :: Tint :: nil, Tint)
  | Onxor => (Tint :: Tint :: nil, Tint)
  | Oandc => (Tint :: Tint :: nil, Tint)
  | Oorc => (Tint :: Tint :: nil, Tint)
  | Oshl => (Tint :: Tint :: nil, Tint)
  | Oshr => (Tint :: Tint :: nil, Tint)
  | Oshrimm _ => (Tint :: nil, Tint)
  | Oshrximm _ => (Tint :: nil, Tint)
  | Oshru => (Tint :: Tint :: nil, Tint)
  | Orolm _ _ => (Tint :: nil, Tint)
  | Oroli _ _ => (Tint :: Tint :: nil, Tint)
  | Olongconst _ => (nil, Tlong)
  | Ocast32signed => (Tint :: nil, Tlong)
  | Ocast32unsigned => (Tint :: nil, Tlong)
  | Oaddl => (Tlong :: Tlong :: nil, Tlong)
  | Oaddlimm _ => (Tlong :: nil, Tlong)
  | Osubl => (Tlong :: Tlong :: nil, Tlong)
  | Onegl => (Tlong :: nil, Tlong)
  | Omull => (Tlong :: Tlong :: nil, Tlong)
  | Omullhs => (Tlong :: Tlong :: nil, Tlong)
  | Omullhu => (Tlong :: Tlong :: nil, Tlong)
  | Odivl => (Tlong :: Tlong :: nil, Tlong)
  | Odivlu => (Tlong :: Tlong :: nil, Tlong)
  | Oandl => (Tlong :: Tlong :: nil, Tlong)
  | Oandlimm _ => (Tlong :: nil, Tlong)
  | Oorl => (Tlong :: Tlong :: nil, Tlong)
  | Oorlimm _ => (Tlong :: nil, Tlong)
  | Oxorl => (Tlong :: Tlong :: nil, Tlong)
  | Oxorlimm _ => (Tlong :: nil, Tlong)
  | Onotl => (Tlong :: nil, Tlong)
  | Oshll => (Tlong :: Tint :: nil, Tlong)
  | Oshrl => (Tlong :: Tint :: nil, Tlong)
  | Oshrlimm _ => (Tlong :: nil, Tlong)
  | Oshrxlimm _ => (Tlong :: nil, Tlong)
  | Oshrlu => (Tlong :: Tint :: nil, Tlong)
  | Orolml _ _ => (Tlong :: nil, Tlong)
  | Olongoffloat => (Tfloat :: nil, Tlong)
  | Ofloatoflong => (Tlong :: nil, Tfloat)
  | Onegf => (Tfloat :: nil, Tfloat)
  | Oabsf => (Tfloat :: nil, Tfloat)
  | Oaddf => (Tfloat :: Tfloat :: nil, Tfloat)
  | Osubf => (Tfloat :: Tfloat :: nil, Tfloat)
  | Omulf => (Tfloat :: Tfloat :: nil, Tfloat)
  | Odivf => (Tfloat :: Tfloat :: nil, Tfloat)
  | Onegfs => (Tsingle :: nil, Tsingle)
  | Oabsfs => (Tsingle :: nil, Tsingle)
  | Oaddfs => (Tsingle :: Tsingle :: nil, Tsingle)
  | Osubfs => (Tsingle :: Tsingle :: nil, Tsingle)
  | Omulfs => (Tsingle :: Tsingle :: nil, Tsingle)
  | Odivfs => (Tsingle :: Tsingle :: nil, Tsingle)
  | Osingleoffloat => (Tfloat :: nil, Tsingle)
  | Ofloatofsingle => (Tsingle :: nil, Tfloat)
  | Ointoffloat => (Tfloat :: nil, Tint)
  | Ointuoffloat => (Tfloat :: nil, Tint)
  | Ofloatofint => (Tint :: nil, Tfloat)
  | Ofloatofintu => (Tint :: nil, Tfloat)
  | Ofloatofwords => (Tint :: Tint :: nil, Tfloat)
  | Omakelong => (Tint :: Tint :: nil, Tlong)
  | Olowlong => (Tlong :: nil, Tint)
  | Ohighlong => (Tlong :: nil, Tint)
  | Ocmp c => (type_of_condition c, Tint)
  end.Definition type_of_addressing (addr: addressing) : list typ :=
  match addr with
  | Aindexed _ => Tint :: nil
  | Aindexed2 => Tint :: Tint :: nil
  | Aglobal _ _ => nil
  | Abased _ _ => Tint :: nil
  | Ainstack _ => nil
  end.

(* Specifications: *)
Lemma type_of_operation_sound: forall op vl sp v m, op <> Omove -> eval_operation genv sp op vl m = Some v -> Val.has_type v (snd (type_of_operation op)).