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

import dspl.intermediate.variable.Variable;

/**
 * An immediate operand is a constant 
 * 
 * @author David
 */
public class X86ImmediateOperand extends X86Operand {
	private Variable var; 
	
	/**
	 * 
	 * @param var Variable which is constant and atomic 
	 */
	public X86ImmediateOperand(Variable var) { 
		if (var.isArray()) {
			throw new Error("array cannot be operand to an x86 instruction"); 
		}
		if (!var.isConstant()) {
			throw new Error("immediate operand variables must be constants"); 
		}
		/*
		else if (var.getDataType()==Variable.DATA_TYPE_STRING) {
			throw new Error("string cannot be an immediate operand"); 
		}
		*/ 
		else if (var.getDataType()==Variable.DATA_TYPE_COMPLEX) { 
			throw new Error("complex cannot be an immediate operand"); 
		}
		this.var = var; 
	}
	
	/**
	 * Specifically intended for doing instructions like "mov $iC, %edx" where iC is begining of an array, and is ok to treat as a 4byte pointer constant
	 * @param var
	 * @param treatArrayAsConst
	 */
	public X86ImmediateOperand(Variable var, boolean treatArrayAsConst) { 
		if (!treatArrayAsConst) { 
			throw new Error("only implemented for use when treatArrayAsConst IS true... "); 
		}
		if (var==null) { 
			throw new Error("var null"); 
		}
		this.var = var; 
	}
	
	/* (non-Javadoc)
	 * @see dspl.backend.x86.operands.X86Operand#freeOperand()
	 */
	public void freeOperand() {
		//do nothing since immediate variables do not require any registers
	}

	/* (non-Javadoc)
	 * @see dspl.backend.x86.operands.X86Operand#getOperandType()
	 */
	public int getOperandType() {
		return X86Operand.OPERAND_TYPE_IMMEDIATE; 
	}
	
	/* (non-Javadoc)
	 * @see dspl.backend.x86.operands.X86Operand#toString()
	 */
	public String toString() {
		if (var.isNaturalNum() || var.getDataType()==Variable.DATA_TYPE_STRING || var.isArray()) { //if its an array, we always want to print the name of the array, this is specifically required else the below with float will break, as it tires to pritn the value (undefined) of an float_array
			return "$" + var.getIdentifier();
		}
		else if (var.getDataType()==Variable.DATA_TYPE_FLOAT) {
			Float f = (Float) var.getValue();
			//return Float.toHexString(f.floatValue()); //doesn't work
			return new String("$0x" + Integer.toHexString(Float.floatToIntBits(f.floatValue()))); 
		}
		throw new Error("not supported"); 
	}

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