//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MCOperandInfo and MCInstrDesc classes, which
// are used to describe target instructions and their operands.
//
//===----------------------------------------------------------------------===//

/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */

#ifndef CS_LLVM_MC_MCINSTRDESC_H
#define CS_LLVM_MC_MCINSTRDESC_H

#include "capstone/platform.h"

//===----------------------------------------------------------------------===//
// Machine Operand Flags and Description
//===----------------------------------------------------------------------===//

// Operand constraints
enum MCOI_OperandConstraint {
	MCOI_TIED_TO = 0,    // Must be allocated the same register as.
	MCOI_EARLY_CLOBBER   // Operand is an early clobber register operand
};

/// OperandFlags - These are flags set on operands, but should be considered
/// private, all access should go through the MCOperandInfo accessors.
/// See the accessors for a description of what these are.
enum MCOI_OperandFlags {
	MCOI_LookupPtrRegClass = 0,
	MCOI_Predicate,
	MCOI_OptionalDef
};

/// Operand Type - Operands are tagged with one of the values of this enum.
enum MCOI_OperandType {
	MCOI_OPERAND_UNKNOWN,
	MCOI_OPERAND_IMMEDIATE,
	MCOI_OPERAND_REGISTER,
	MCOI_OPERAND_MEMORY,
	MCOI_OPERAND_PCREL
};


/// MCOperandInfo - This holds information about one operand of a machine
/// instruction, indicating the register class for register operands, etc.
///
typedef struct MCOperandInfo {
	/// RegClass - This specifies the register class enumeration of the operand
	/// if the operand is a register.  If isLookupPtrRegClass is set, then this is
	/// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
	/// get a dynamic register class.
	int16_t RegClass;

	/// Flags - These are flags from the MCOI::OperandFlags enum.
	uint8_t Flags;

	/// OperandType - Information about the type of the operand.
	uint8_t OperandType;

	/// Lower 16 bits are used to specify which constraints are set. The higher 16
	/// bits are used to specify the value of constraints (4 bits each).
	uint32_t Constraints;
	/// Currently no other information.
} MCOperandInfo;


//===----------------------------------------------------------------------===//
// Machine Instruction Flags and Description
//===----------------------------------------------------------------------===//

/// MCInstrDesc flags - These should be considered private to the
/// implementation of the MCInstrDesc class.  Clients should use the predicate
/// methods on MCInstrDesc, not use these directly.  These all correspond to
/// bitfields in the MCInstrDesc::Flags field.
enum {
	MCID_Variadic = 0,
	MCID_HasOptionalDef,
	MCID_Pseudo,
	MCID_Return,
	MCID_Call,
	MCID_Barrier,
	MCID_Terminator,
	MCID_Branch,
	MCID_IndirectBranch,
	MCID_Compare,
	MCID_MoveImm,
	MCID_Bitcast,
	MCID_Select,
	MCID_DelaySlot,
	MCID_FoldableAsLoad,
	MCID_MayLoad,
	MCID_MayStore,
	MCID_Predicable,
	MCID_NotDuplicable,
	MCID_UnmodeledSideEffects,
	MCID_Commutable,
	MCID_ConvertibleTo3Addr,
	MCID_UsesCustomInserter,
	MCID_HasPostISelHook,
	MCID_Rematerializable,
	MCID_CheapAsAMove,
	MCID_ExtraSrcRegAllocReq,
	MCID_ExtraDefRegAllocReq,
	MCID_RegSequence,
	MCID_ExtractSubreg,
	MCID_InsertSubreg
};

/// MCInstrDesc - Describe properties that are true of each instruction in the
/// target description file.  This captures information about side effects,
/// register use and many other things.  There is one instance of this struct
/// for each target instruction class, and the MachineInstr class points to
/// this struct directly to describe itself.
typedef struct MCInstrDesc {
	unsigned short  Opcode;        // The opcode number
	unsigned char  NumOperands;   // Num of args (may be more if variable_ops)
	unsigned char  NumDefs;       // Num of args that are definitions
	unsigned short  SchedClass;    // enum identifying instr sched class
	unsigned char  Size;          // Number of bytes in encoding.
	unsigned        Flags;         // Flags identifying machine instr class
	uint64_t        TSFlags;       // Target Specific Flag values
	char ImplicitUses;  // Registers implicitly read by this instr
	char ImplicitDefs;  // Registers implicitly defined by this instr
	const MCOperandInfo *OpInfo;   // 'NumOperands' entries about operands
	uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any     
	// A complex method to determine is a certain is deprecated or not, and return        
	// the reason for deprecation.
	//bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);           
	unsigned char ComplexDeprecationInfo;	// dummy field, just to satisfy initializer
} MCInstrDesc;

bool MCOperandInfo_isPredicate(const MCOperandInfo *m);

bool MCOperandInfo_isOptionalDef(const MCOperandInfo *m);

#endif
