// $Id: Codegen.java,v 1.3 1999/12/09 18:44:16 golem Exp $

package IR2;

public interface Codegen {

  // This procedure is called during the LowIR -> DelocalizedIR
  // pass, unlike most of the others.  It generates whatever
  // DelocalizedIR instructions necessary for setting up a stack frame.
  // (This is perfectly OK because the DelocalizedIR is conceptually
  // part of the machine-dependent pass.)
  public void generate_delocalized_prologue(MethodDescriptor d, CFG output);


  // The procedure "r" is guaranteed to return a valid "scratch" register.
  // There is always guaranteed to be at least three valid scratch registers,
  // so c.r(0), c.r(1), and c.r(2) always ought to return valid
  // registers.  However, the values in the scratch registers are not
  // guaranteed to be preserved across function calls.
  public DelocalizedRegister r(int n);

  // This procedure returns a list of registers available for allocation.
  public DelocalizedRegister[] allocatable_registers();


  // Reserves space for n zeroed words at the start of the .data area.
  public void reserve_zeroed_data_area(int n);

  // Allocates global space for a string and returns the location.
  public int allocate_string(String value);


  // Move instruction (register to register).
  public void generate_move(DelocalizedRegister dest, DelocalizedRegister src);

  // LI instruction (immediate to register).
  public void generate_load_immediate(DelocalizedRegister dest, long value);

  // LA instruction (address to register).
  public void generate_load_address(DelocalizedRegister dest, long value);

  // **** XXXX These will need to be changed to include the correct
  //           types and numbers of arguments.

  // Throw a val into the appropriate return register
  public void generate_return(DelocalizedRValue val);

  // Put label in assem output
  public void generate_label(String label_name);

  // Prologue of a function (after label; precedes actual code of function)
  public void generate_prologue(String name, int stack_size);

  // Epilogue of function (prepares to return and does actual RET)
  public void generate_epilogue(String name, int stack_size);

  // Load and store codegen

  public void generate_array_fetch(DelocalizedRegister dest,
                                   int array_offset,
                                   DelocalizedRegister index);

  public void generate_array_store(int array_offset,
                                   DelocalizedRegister index,
                                   DelocalizedRegister src);

  public void generate_load_global(DelocalizedRegister r, int offset);

  public void generate_save_global(int offset, DelocalizedRegister r);

  public void generate_load_local(DelocalizedRegister r, int offset);

  public void generate_save_local(int offset, DelocalizedRegister r);

  public void generate_load_param(DelocalizedRegister r, int param_num);

  public void generate_save_param(int param_num, DelocalizedRegister r);

  // Arith codegen

  public void generate_add(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_mulo(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_shl(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_shr(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_sub(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  // Boolean math instructions

  public void generate_seq(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_sge(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_sgt(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_sle(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_slt(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  public void generate_sne(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2);

  // Arith codegen with immeds

  public void generate_add(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_mulo(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_shl(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_shr(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_sub(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  // Boolean math instructions with immeds

  public void generate_seq(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_sge(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_sgt(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_sle(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_slt(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);

  public void generate_sne(DelocalizedRegister Rdest,
                           DelocalizedRegister Rsrc1,
                           DelocalizedImmed Src2);



  // Branch instructions

  public void generate_b(DelocalizedLabelInstruction lbl);
  public void generate_b(String lbl);

  public void generate_beq(DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2,
                           DelocalizedLabelInstruction lbl);

  public void generate_bgt(DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2,
                           DelocalizedLabelInstruction lbl);

  public void generate_bgt(DelocalizedRegister Rsrc1,
                           DelocalizedLabelInstruction lbl);

  public void generate_bge(DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2,
                           DelocalizedLabelInstruction lbl);

  public void generate_blt(DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2,
                           DelocalizedLabelInstruction lbl);

  public void generate_ble(DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2,
                           DelocalizedLabelInstruction lbl);

  public void generate_bne(DelocalizedRegister Rsrc1,
                           DelocalizedRegister Src2,
                           DelocalizedLabelInstruction lbl);

  public void generate_bne(DelocalizedRegister Rsrc1,
                           DelocalizedLabelInstruction lbl);

  public void generate_j(DelocalizedLabelInstruction lbl);

  public void generate_jal(DelocalizedLabelInstruction lbl);

  public void generate_jal(DelocalizedRegister Rsrc1);
                          
  public void generate_jr(DelocalizedRegister Rsrc1);

  // Calling convention
  public void prep_for_callout(int count);
  public void prep_for_call(int count);
  public void generate_call_arg(DelocalizedRValue arg, int arg_num);
  public void generate_callout_arg(DelocalizedRValue arg, int arg_num);
  public void generate_call(DelocalizedLabelInstruction target);
  public void generate_callout(DelocalizedLabelInstruction target);

  // Where do the answers go?
  public DelocalizedRegister function_return_register();

  // Add comments to code
  public void comment(String s);

  // Actually output code to file.
  public void output_code() throws Exception;
  
}

