// genObject.cc -- Object method prologue generation		-*- C++ -*-
// 
// Author: Ian.Piumarta@INRIA.Fr
//
// Last edited: Thu Jan 13 03:45:32 2000 by piumarta (Ian Piumarta) on pingu

#include "Object.h"

#include "machine.h"
#include "emit.h"

#include "genObject.h"


void genEquivalent(NativeMethod *nMeth, insn *fail)
{
  declareLabel(same);
  twoPass({
    emit_move_S_r(0, reg[1]);
    emit_cmp_r_r(reg[0], reg[1]);
    emit_beq(same);
    emit_move_0_r(reg[0]);
    emit_move_r_popS(reg[0], 1);
    emit_resume();
    defineLabel(same);
    emit_move_1_r(reg[0]);
    emit_move_r_popS(reg[0], 1);
    emit_resume();
  });
}


void genNew(NativeMethod *nMeth, insn *fail)
{
  emit_move_i_r(0, reg[1]);
  emit_savepc();
  emit_extern();
  emit_gcprotect();
  emit_mkcargs2();
  emit_ccall(instantiateClassindexableSize);	// regs/tmps trashed!
  emit_killcargs2();
#     ifndef NDEBUG
  emit_gcunprotect();
#     endif
  emit_restorepc();
  emit_move_r_S(reg[0], 0);
  emit_resume();
}


void genNewWithArg(NativeMethod *nMeth, insn *fail)
{
  emit_move_S_r(0, reg[1]);
  emit_tagck_r_t(reg[1], fail);
  emit_untaggeck_r_t(reg[1], fail);
  emit_savepc();
  emit_extern();
  emit_gcprotect();
  emit_mkcargs2();
  emit_ccall(instantiateClassindexableSize);	// regs/tmps trashed!
  emit_killcargs2();
#     ifndef NDEBUG
  emit_gcunprotect();
#     endif
  emit_restorepc();
  emit_move_r_popS(reg[0], 1);
  emit_resume();
}


void genAsOop(NativeMethod *nMeth, insn *fail)
{
  declareLabel(fixnum);
  twoPass({
    emit_notagck_r_t(reg[0], fail);
    emit_get_i_r_r(0, reg[0], reg[0]);		// base header
    emit_bfextshl_i_i_i_r(17, 12, 1, reg[0]);	// hash bits
    emit_or_i_r(1, reg[0]);			// entag
    emit_move_r_S(reg[0], 0);
    defineLabel(fixnum);
    emit_resume();
  });
}


void genNoop(NativeMethod *nMeth, insn *fail)
{
  emit_resume();
}
