/**
 * 
 */
package dspl.backend.x86.operands;

/**
 * Base Class representing an operand to an X86 instruction<br>
 * See IA32 Manual 1: 3.7 Operand Addressing
 * <ul>Operand types:
 * <li>Immediate</li>
 * <li>Register</li>
 * <li>Memory</li>
 * </ul>
 * 
 * @author David
 *
 */
public abstract class X86Operand {
	//note all OPERAND_TYPEs must be powers of two to allow for bit flag operations
	
	public final static int OPERAND_TYPE_IMMEDIATE = 1; 
	public final static int OPERAND_TYPE_MEMORY = 2; 
	public final static int OPERAND_TYPE_INDEXED_MEMORY = 4; 
	public final static int OPERAND_TYPE_REGISTER = 8; 
	
	
	/**
	 * Class of operands that can be on the destination end of an operation (so called lvalue becuase they can appear on the left of a "dest = arg" expressioN)
	 */
	public final static int OPERAND_CLASS_LVALUE = OPERAND_TYPE_MEMORY | OPERAND_TYPE_INDEXED_MEMORY | OPERAND_TYPE_REGISTER; 
	
	public final static int OPERAND_CLASS_ANY = OPERAND_TYPE_MEMORY | OPERAND_TYPE_INDEXED_MEMORY | OPERAND_TYPE_REGISTER | OPERAND_TYPE_IMMEDIATE; 
	
	/**
	 * Returns whether the Operand contains a memory-based type (either OPERAND_TYPE_MEMORY or OPERAND_TYPE_INDEXED_MEMORY)
	 * @return true if operand is a memory-based operand
	 */
	public boolean isMemoryType() { 
		int type = getOperandType(); //only make call once
		return (type==OPERAND_TYPE_MEMORY || type == OPERAND_TYPE_INDEXED_MEMORY); 
	}
	
	/**
	 * Frees any resources (registers) that have been allocated
	 * for the operand
	 *
	 */
	public abstract void freeOperand(); 
	
	/**
	 * Returns the X86Operand type, must be one of X86Operand.OPERAND_TYPE_xxx
	 * @return
	 */
	public abstract int getOperandType(); 
	
	/**
	 * Returns the operand's byte size, should be either 1, 2, or 4
	 * @return
	 */
	public abstract int getOperandSize(); 
	
	/**
	 * @return gnu assembler-friendly representation of the operand
	 */
	public abstract String toString(); 
}
