package dspl.backend.x86.operands;

import dspl.intermediate.variable.Variable;

/**
 * X86MemoryOperand represents a direct access into a memory location<p>
 * For example: movl %eax, someVar (where someVar is a memory location)
 *
 * @author David
 */
public class X86MemoryOperand extends X86Operand {
	public Variable var; 
	
	public X86MemoryOperand(Variable var) { 
		if (var.isArray()) {
			throw new Error("Cannot use an array as argument to assembly instruction"); 
		}
		if (var.isConstant()) { 
			throw new Error("Cannot return memory operand for constant variable"); 
		}
		
		this.var = var; 
	}
	
	/**
	 * Checks to make sure that the variable can be a memory operand<br>
	 * Intended to be called before calling new X86MemoryOperand, specificall in X86VariableManager, within prepareVariables,
	 * if one needs to get an Immediate into an lvalue, then prepareVariable will first try to put it into memory before trying
	 * to put it into a reg, this check will allowing skipping the memory operand if it cannot do it. 
	 * @param var
	 * @return
	 */
	public static boolean canBeMemoryOperand(Variable var) { 
		if (var.isArray() || var.isConstant()) {
			return false; 
		}
		return true; 
	}
	
	/* (non-Javadoc)
	 * @see dspl.backend.x86.operands.X86Operand#freeOperand()
	 */
	public void freeOperand() {
		//not needed, memory operand does not utilize any registers
	}
	
	/* (non-Javadoc)
	 * @see dspl.backend.x86.operands.X86Operand#getOperandType()
	 */
	public int getOperandType() {
		return X86Operand.OPERAND_TYPE_MEMORY; 
	}

	/* (non-Javadoc)
	 * @see dspl.backend.x86.operands.X86Operand#toString()
	 */
	public String toString() {
		//TODO: (David) check toString on X86MemoryOperand should perhaps have $ in front of it 
		return var.getIdentifier(); 
	}

	public int getOperandSize() {
		return var.getDataTypeByteSize(); 
	}
}
