// $Id: DelocalizedStoreInstruction.java,v 1.6 1999/12/10 13:36:25 mpp Exp $

package IR2;

import java.util.*;

public class DelocalizedStoreInstruction
  extends DelocalizedInstruction
  implements CopyInstruction {

  private DelocalizedLValue dest;
  private DelocalizedRValue src;

  public DelocalizedStoreInstruction(DelocalizedLValue d,
                                     DelocalizedRValue s) {
    dest = d; src = s;
  }

  public DelocalizedLValue destination() {
    return dest;
  }

  public Enumeration lsources() {
    if (src instanceof DelocalizedLValue) {
      return new ShortEnumeration(src);
    } else {
      return new ShortEnumeration();
    }
  }

  public void generate_code(Codegen c){
    DelocalizedLValue pdest = dest.lproxy();
    DelocalizedRValue psrc = src.rproxy();

    if (psrc instanceof DelocalizedRegister) {
      pdest.store_from_reg(c, (DelocalizedRegister) psrc);
    } else {
      if (pdest instanceof DelocalizedRegister) {
        psrc.load_into_reg(c, (DelocalizedRegister) pdest);
      } else {
        psrc.load_into_reg(c, c.r(0));
        pdest.store_from_reg(c, c.r(0));
      }
    }
  }

  // Substitution. For swapping in a symbolic register
  public void substitute_lvalue(DelocalizedLValue oldlval, 
                                DelocalizedLValue newlval) {
    if (dest.lproxy() == oldlval) dest = newlval; 
  }

  public void substitute_rvalue(DelocalizedLValue oldlval, 
                                DelocalizedLValue newlval) {
    if (src.rproxy() == oldlval) src = (DelocalizedRValue)newlval;
  }

  /* CopyInstruction */
  public DelocalizedLValue copy_destination() { return dest; }
  public DelocalizedRValue copy_source()      { return src; }

  /* Copy propagation */
  public boolean kills_copy(CopyInstruction copy) {
    return dest.equals(copy.copy_source())
      || dest.equals(copy.copy_destination());
  }
  public void substitute_copies(Hashtable map) {
    if (map.containsKey(src))
      src = (DelocalizedRValue) map.get(src);
  }


  public String toString() { return "DelocStoreInsn: " + dest + " <- " + src; }
}
