// i386-generate.ccg -- code generator support for Intel	-*- C++ -*-
//
// Author: Ian.Piumarta@INRIA.Fr
//         marcus@ira.uka.de
//
// Last edited: 12/21/2000 by mdenker on cologne.rd.wdi.disney.com
// 

#include "archdep.h"

#include "generate.h"
#include "machine.h"
#include "optimise.h"
#include "primitive.h"

#define _ASM_LOCALPC /* #localpc */
#include "ccg/asm-i386.h" /* #cpu i386 */
/* #escape ! */
/* #comment ; */

#include "Frame.h"

#include ARCHDEP(emit.h)

extern int reg[], tmp[];

extern "C" {
  int fetchClassOf(int);
};


insn *gen_linkTo(insn *senderIP, insn *methodEntry, unsigned arg)
{
  assert(methodEntry != 0);
  PRINTF(("linkTo arg == %08x\n", arg));
  insn *sendSite= senderIP - 10;
  PRINTF(("relink: %p -> %p\n", sendSite, methodEntry));
  asm_pc= sendSite;
  emit_initcall(methodEntry);
     _ASM_APP_1 
	MOVLir	(arg, (reg[1])); 
  _ASM_NOAPP_1;
  emit_execcall(methodEntry);
  iflush(sendSite, asm_pc);
  assert(asm_pc == senderIP);
  // must rerun send (link register is no longer valid)
  return sendSite;
}


insn *gen_linkDeferredTo(insn *senderIP, insn *methodEntry, unsigned arg)
{
  assert(methodEntry != 0);
  PRINTF(("linkDeferredTo arg == %08x\n", arg));
  insn *sendSite= senderIP - 10;
  PRINTF(("relink: %p -> %p\n", sendSite, methodEntry));
  asm_pc= sendSite;
  emit_initcall(methodEntry);
    _ASM_APP_1 
	MOVLir	(arg, (reg[1])); 
  _ASM_NOAPP_1;
  emit_execjmp(methodEntry);
  iflush(sendSite, asm_pc);
  assert(asm_pc == senderIP);
  // must rerun send (link register is no longer valid)
  return sendSite;
}

///
/// METHOD PROLOGUE GENERATORS
///

void gen_relink(NativeMethod *nMeth)
{
  // we arrive here with reg[1] holding the supered/deferred flags,
  // reg[2] holding the patch site if deferred, and the sender's PC
  // still in the link register.
  // 
  // NOTE: if the cache is indirect then we arrive here with the address
  //	   of the cache line in r10

    _ASM_APP_1 
	POPLm	(f_pc_off,(FP),0,0); 
	MOVLrm	((SP), f_stackp_off,(FP),0,0); 
	PUSHLm	(((int)&tmpr2),0,0,0); 
	PUSHLr	((reg[1])); 
	PUSHLr	((reg[2])); 
	PUSHLi	(((int)nMeth)); 
	PUSHLr	((FP)); 
	CALLm	(c_relink,0,0,0); 
	ADDLir	(20, _ESP); 
	MOVLmr	(f_stackp_off,(FP),0,0, (SP)); 
	PUSHLm	(f_pc_off,(FP),0,0); 
	JMPm	(0,_EAX,0,0); 
  _ASM_NOAPP_1;
}

void gen_activate(NativeMethod *nMeth)
{
  size_t nArgs= nMeth->argumentCount;
  size_t nTemps= nMeth->temporaryCount;

# ifdef STACK_GROWS_DOWN
    _ASM_APP_1 
	POPLm	(f_pc_off,(FP),0,0); 
	MOVLrm	((FP), (-sizeof(Frame)),(FP),0,0); 
	LEALmr	((-sizeof(Frame)),(FP),0,0, (FP)); 
	LEALmr	(((nArgs+1)*4),(SP),0,0, (tmp[0])); 
	MOVLrm	((tmp[0]), (sizeof(Frame)+f_stackp_off),(FP),0,0); 
	MOVLmr	(-4,(tmp[0]),0,0, (reg[0])); 
	MOVLrm	((reg[0]), (f_receiver_off),(FP),0,0); 
	LEALmr	((f_stack_off+(LargeFrame*4)),(FP),0,0, (SP)); 
	MOVLrr	((FP), _ESP); 
 if (nTemps > 0) {
#   ifdef USE_GLOBAL_PTR
	MOVLmr	(gp_nilObj_off,(GP),0,0, (tmp[1])); 
#   else
	MOVLmr	(_nilObj,0,0,0, (tmp[1])); 
#   endif
    }
	MOVLim	(((int)nMeth), f_nmeth_off,(FP),0,0); 
   for (size_t i= 0; i < nArgs; ++i) {
	MOVLmr	((-8-i*4),(tmp[0]),0,0, (reg[0])); 
	ADDLir	((-4), (SP)); 
	MOVLrm	((reg[0]), 0,(SP),0,0); 
  }
      while (nTemps--) {
	ADDLir	((-4), (SP)); 
	MOVLrm	((tmp[1]), 0,(SP),0,0); 
    }
  _ASM_NOAPP_1;

# else  //!STACK_GROWS_DOWN

    _ASM_APP_1 
	POPLm	(f_pc_off,(FP),0,0); 
	MOVLrm	((FP), (-sizeof(Frame)),(FP),0,0); 
	LEALmr	((-sizeof(Frame)),(FP),0,0, (FP)); 
	LEALmr	((-((nArgs+1)*4)),(SP),0,0, (tmp[0])); 
	MOVLrm	((tmp[0]), (sizeof(Frame)+f_stackp_off),(FP),0,0); 
	MOVLmr	(4,(tmp[0]),0,0, (reg[0])); 
	MOVLrm	((reg[0]), (f_receiver_off),(FP),0,0); 
	LEALmr	((f_stack_off-4),(FP),0,0, (SP)); 
	MOVLrr	((FP), _ESP); 
 if (nTemps > 0) {
#   ifdef USE_GLOBAL_PTR
	MOVLmr	(gp_nilObj_off,(GP),0,0, (tmp[1])); 
#   else
	MOVLmr	(_nilObj,0,0,0, (tmp[1])); 
#   endif
    }
	MOVLim	(((int)nMeth), f_nmeth_off,(FP),0,0); 
	MOVLim	(0, f_pcx_off,(FP),0,0); 
   for (size_t i= 0; i < nArgs; ++i) {
	MOVLmr	((8+i*4),(tmp[0]),0,0, (reg[0])); 
	ADDLir	(4, (SP)); 
	MOVLrm	((reg[0]), 0,(SP),0,0); 
  }
      while (nTemps--) {
	ADDLir	(4, (SP)); 
	MOVLrm	((tmp[1]), 0,(SP),0,0); 
    }
  _ASM_NOAPP_1;
# endif
}

// we arrive here with reg[0] holding the receiver (a BlockClosure)

void gen_blockActivate(NativeMethod *nMeth, size_t nArgs)
{
#ifdef STACK_GROWS_DOWN
    _ASM_APP_1 
	POPLm	(f_pc_off,(FP),0,0); 
	MOVLmr	((4*nArgs),(SP),0,0, (reg[0])); 
	MOVLrm	((FP), (-sizeof(Frame)),(FP),0,0); 
	LEALmr	((-sizeof(Frame)),(FP),0,0, (FP)); 
	LEALmr	((((nArgs+1)*4)),(SP),0,0, (tmp[0])); 
	MOVLrm	((tmp[0]), (sizeof(Frame)+f_stackp_off),(FP),0,0); 
	MOVLrm	((reg[0]), f_pcx_off,(FP),0,0); 
	MOVLmr	(bx_home_off,(reg[0]),0,0, (reg[0])); 
	MOVLrm	((reg[0]), f_receiver_off,(FP),0,0); 
	LEALmr	((f_stack_off+(LargeFrame*4)),(FP),0,0, (SP)); 
	MOVLrr	((FP), _ESP); 
    for (size_t i= 0; i < nArgs; ++i) {
	MOVLmr	((-8-i*4),(tmp[0]),0,0, (reg[0])); 
	ADDLir	((-4), (SP)); 
	MOVLrm	((reg[0]), 0,(SP),0,0); 
  }
#ifdef BLOCK_CLOSURES
	MOVLim	(((int)nMeth|2), f_nmeth_off,(FP),0,0); 
#else
	MOVLmr	(((int)&t_cxFault),0,0,0, (tmp[0])); 
	MOVLrm	((tmp[0]), (sizeof(Frame)+f_pc_off),(FP),0,0); 
#endif
  _ASM_NOAPP_1;

#else

    _ASM_APP_1 
	POPLm	(f_pc_off,(FP),0,0); 
	MOVLmr	((-4*nArgs),(SP),0,0, (reg[0])); 
	MOVLrm	((FP), (-sizeof(Frame)),(FP),0,0); 
	LEALmr	((-sizeof(Frame)),(FP),0,0, (FP)); 
	LEALmr	((-((nArgs+1)*4)),(SP),0,0, (tmp[0])); 
	MOVLrm	((tmp[0]), (sizeof(Frame)+f_stackp_off),(FP),0,0); 
	MOVLrm	((reg[0]), f_pcx_off,(FP),0,0); 
	MOVLmr	(bx_home_off,(reg[0]),0,0, (reg[0])); 
	MOVLrm	((reg[0]), f_receiver_off,(FP),0,0); 
	LEALmr	((f_stack_off-4),(FP),0,0, (SP)); 
	MOVLrr	((FP), _ESP); 
    for (size_t i= 0; i < nArgs; ++i) {
	MOVLmr	((8+i*4),(tmp[0]),0,0, (reg[0])); 
	ADDLir	(4, (SP)); 
	MOVLrm	((reg[0]), 0,(SP),0,0); 
  }
#ifdef BLOCK_CLOSURES
	MOVLim	(((int)nMeth|2), f_nmeth_off,(FP),0,0); 
#else
	MOVLmr	(((int)&t_cxFault),0,0,0, (tmp[0])); 
	MOVLrm	((tmp[0]), (sizeof(Frame)+f_pc_off),(FP),0,0); 
#endif
  _ASM_NOAPP_1;
#endif
}


size_t gen_codeSize(size_t nBytecodes)
{
  // FIXME (250)
  // prologue is at most 50 words
  // largest opcode: LdLit = 8 insns
  return (1500 + 24 * nBytecodes + 100*nBytecodes) * sizeof(insn);
}


void gen_release(void)
{
  fatal("gen_release");
}

void gen_flush(insn *first, insn *last)
{
  iflush(first, last);
}

insn *g_end = 0; 
insn *xfer2 = 0;
insn *xfer21 = 0;

void gen_initialise(void)
{


  insn *glue= asm_pc= (insn *)codeCache->reserve(4096);

  // cglue: callout to C, resume in active frame

# define _CGLUEm(dst,b,i,s)   _ASM_APP_1 \
	POPLm	(f_pc_off,(FP),0,0); \
	PUSHLr	((reg[1])); \
	PUSHLr	((FP)); \
	MOVLrm	((SP), f_stackp_off,(FP),0,0); \
	CALLm	(dst,0,0,0); \
	ADDLir	(8, _ESP); \
	MOVLmr	(f_pc_off,(FP),0,0, (reg[1])); \
	MOVLmr	(f_stackp_off,(FP),0,0, (SP)); \
	JMPm	(0,(reg[1]),0,0); \
  _ASM_NOAPP_1;

  // Jump glue: callout(destAddr), jump to new PC

# define _JGLUEm(dst,b,i,s)   _ASM_APP_1 \
	POPLm	(f_pc_off,(FP),0,0); \
	PUSHLr	((reg[1])); \
	PUSHLr	((FP)); \
	MOVLrm	((SP), f_stackp_off,(FP),0,0); \
	CALLm	(dst,0,0,0); \
	ADDLir	(8, _ESP); \
	MOVLmr	(f_stackp_off,(FP),0,0, (SP)); \
	JMPm	(0,_EAX,0,0); \
  _ASM_NOAPP_1;


  // send glue: callout(), jump to new PC iff !0 preserving senderIP

# define _SGLUEm(dst,b,i,s)   _ASM_APP_2 \
  _ASM_LBL(xfer);\
	POPLm	(f_pc_off,(FP),0,0); \
	PUSHLr	((reg[1])); \
	PUSHLr	((FP)); \
	MOVLrm	((SP), f_stackp_off,(FP),0,0); \
	CALLm	(dst,0,0,0); \
	ADDLir	(8, _ESP); \
	PUSHLm	(f_pc_off,(FP),0,0); \
	MOVLmr	(f_stackp_off,(FP),0,0, (SP)); \
	TESTLrr	(_EAX, _EAX); \
	JNESm	(xfer,0,0,0); \
	RET	(); \
  _ASM_DEF(xfer);\
	JMPm	(0,_EAX,0,0); \
  _ASM_NOAPP_2;

  // frame glue: alloc temp frame, callout(), reload from new frame

# define _FGLUEm(dst,b,i,s)   _ASM_APP_1 \
	POPLm	(f_pc_off,(FP),0,0); \
	MOVLrm	((SP), f_stackp_off,(FP),0,0); \
	MOVLrr	((FP), (reg[1])); \
	LEALmr	((-sizeof(Frame)),(FP),0,0, _ESP); \
	MOVLrm	((FP), 0,_ESP,0,0); \
	MOVLrr	(_ESP, (FP)); \
	PUSHLr	((reg[1])); \
	CALLm	(dst,0,0,0); \
	ADDLir	(4, _ESP); \
	MOVLrr	(_EAX, (FP)); \
	MOVLmr	(f_pc_off,(FP),0,0, _EAX); \
	MOVLmr	(f_stackp_off,(FP),0,0, (SP)); \
	MOVLrr	((FP), _ESP); \
	JMPm	(0,_EAX,0,0); \
  _ASM_NOAPP_1;

# define _FAULTGLUEm(dst,b,i,s)   _ASM_APP_1 \
	MOVLrm	((SP), f_stackp_off,(FP),0,0); \
	MOVLrr	((FP), (reg[1])); \
	LEALmr	((-sizeof(Frame)),(FP),0,0, _ESP); \
	MOVLrm	((FP), 0,_ESP,0,0); \
	MOVLrr	(_ESP, (FP)); \
	PUSHLr	((reg[1])); \
	CALLm	(dst,0,0,0); \
	ADDLir	(4, _ESP); \
	MOVLrr	(_EAX, (FP)); \
	MOVLmr	(f_pc_off,(FP),0,0, _EAX); \
	MOVLmr	(f_stackp_off,(FP),0,0, (SP)); \
	MOVLrr	((FP), _ESP); \
	JMPm	(0,_EAX,0,0); \
  _ASM_NOAPP_1;


  _ASM_APP_1 
  _ASM_DEF(t_cxFault);	_FAULTGLUEm	(c_cxFault,0,0,0); 
  _ASM_DEF(t_mxFault);	_FAULTGLUEm	(c_mxFault,0,0,0); 

  _ASM_DEF(g_Pop);	_CGLUEm	(c_Pop,0,0,0); 
  _ASM_DEF(g_Dup);	_CGLUEm	(c_Dup,0,0,0); 
  _ASM_DEF(g_LdSelf);	_CGLUEm	(c_LdSelf,0,0,0); 
  _ASM_DEF(g_bLdSelf);	_CGLUEm	(c_bLdSelf,0,0,0); 
  _ASM_DEF(g_LdTrue);	_CGLUEm	(c_LdTrue,0,0,0); 
  _ASM_DEF(g_LdFalse);	_CGLUEm	(c_LdFalse,0,0,0); 
  _ASM_DEF(g_LdNil);	_CGLUEm	(c_LdNil,0,0,0); 
  _ASM_DEF(g_LdInt);	_CGLUEm	(c_LdInt,0,0,0); 
  _ASM_DEF(g_LdThisContext);	_CGLUEm	(c_LdThisContext,0,0,0); 
  _ASM_DEF(g_LdLit);	_CGLUEm	(c_LdLit,0,0,0); 
  _ASM_DEF(g_bLdLit);	_CGLUEm	(c_bLdLit,0,0,0); 
  _ASM_DEF(g_LdInst);	_CGLUEm	(c_LdInst,0,0,0); 
  _ASM_DEF(g_bLdInst);	_CGLUEm	(c_bLdInst,0,0,0); 
  _ASM_DEF(g_pLdInst);	_CGLUEm	(c_pLdInst,0,0,0); 
  _ASM_DEF(g_bpLdInst);	_CGLUEm	(c_bpLdInst,0,0,0); 
  _ASM_DEF(g_StInst);	_CGLUEm	(c_StInst,0,0,0); 
  _ASM_DEF(g_bStInst);	_CGLUEm	(c_bStInst,0,0,0); 
  _ASM_DEF(g_pStInst);	_CGLUEm	(c_pStInst,0,0,0); 
  _ASM_DEF(g_bpStInst);	_CGLUEm	(c_bpStInst,0,0,0); 
  _ASM_DEF(g_PopInst);	_CGLUEm	(c_PopInst,0,0,0); 
  _ASM_DEF(g_bPopInst);	_CGLUEm	(c_bPopInst,0,0,0); 
  _ASM_DEF(g_pPopInst);	_CGLUEm	(c_pPopInst,0,0,0); 
  _ASM_DEF(g_bpPopInst);	_CGLUEm	(c_bpPopInst,0,0,0); 

  _ASM_DEF(g_LdTemp);	_CGLUEm	(c_LdTemp,0,0,0); 
  _ASM_DEF(g_bLdTemp);	_CGLUEm	(c_bLdTemp,0,0,0); 
  _ASM_DEF(g_StTemp);	_CGLUEm	(c_StTemp,0,0,0); 
  _ASM_DEF(g_bStTemp);	_CGLUEm	(c_bStTemp,0,0,0); 
  _ASM_DEF(g_LdLitInd);	_CGLUEm	(c_LdLitInd,0,0,0); 
  _ASM_DEF(g_bLdLitInd);	_CGLUEm	(c_bLdLitInd,0,0,0); 
  _ASM_DEF(g_StLitInd);	_CGLUEm	(c_StLitInd,0,0,0); 
  _ASM_DEF(g_bStLitInd);	_CGLUEm	(c_bStLitInd,0,0,0); 

  _ASM_DEF(g_Jmp);	_JGLUEm	(c_Jmp,0,0,0); 
  _ASM_DEF(g_JmpF);	_SGLUEm	(c_JmpF,0,0,0); 
  _ASM_DEF(g_JmpT);	_SGLUEm	(c_JmpT,0,0,0); 

  _ASM_DEF(g_SuperUnlinked);	_SGLUEm	(c_SuperUnlinked,0,0,0); 
  _ASM_DEF(g_SendUnlinked);	_SGLUEm	(c_SendUnlinked,0,0,0); 
  _ASM_DEF(g_SpecialUnlinked);	_SGLUEm	(c_SpecialUnlinked,0,0,0); 
  _ASM_DEF(g_SpecialDeferred);	_SGLUEm	(c_SpecialDeferred,0,0,0); 

  _ASM_DEF(g_LocalRetTop);	_FGLUEm	(c_LocalRetTop,0,0,0); 
  _ASM_DEF(g_RemoteRetTop);	_FGLUEm	(c_RemoteRetTop,0,0,0); 

  _ASM_DEF(g_Add);	_SGLUEm	(c_Add,0,0,0); 
  _ASM_DEF(g_Subtract);	_SGLUEm	(c_Subtract,0,0,0); 
  _ASM_DEF(g_LessThan);	_SGLUEm	(c_LessThan,0,0,0); 
  _ASM_DEF(g_GreaterThan);	_SGLUEm	(c_GreaterThan,0,0,0); 
  _ASM_DEF(g_LessOrEqual);	_SGLUEm	(c_LessOrEqual,0,0,0); 
  _ASM_DEF(g_GreaterOrEqual);	_SGLUEm	(c_GreaterOrEqual,0,0,0); 
  _ASM_DEF(g_Equal);	_SGLUEm	(c_Equal,0,0,0); 
  _ASM_DEF(g_NotEqual);	_SGLUEm	(c_NotEqual,0,0,0); 
  _ASM_DEF(g_Multiply);	_SGLUEm	(c_Multiply,0,0,0); 
  _ASM_DEF(g_Divide);	_SGLUEm	(c_Divide,0,0,0); 
  _ASM_DEF(g_Mod);	_SGLUEm	(c_Mod,0,0,0); 
  _ASM_DEF(g_MakePoint);	_SGLUEm	(c_MakePoint,0,0,0); 
  _ASM_DEF(g_BitShift);	_SGLUEm	(c_BitShift,0,0,0); 
  _ASM_DEF(g_Div);	_SGLUEm	(c_Div,0,0,0); 
  _ASM_DEF(g_BitAnd);	_SGLUEm	(c_BitAnd,0,0,0); 
  _ASM_DEF(g_BitOr);	_SGLUEm	(c_BitOr,0,0,0); 
  _ASM_DEF(g_Equivalent);	_CGLUEm	(c_Equivalent,0,0,0); 
  _ASM_DEF(g_Class);	_CGLUEm	(c_Class,0,0,0); 
  _ASM_DEF(g_BlockCopy);	_SGLUEm	(c_BlockCopy,0,0,0); 
  _ASM_DEF(g_bBlockCopy);	_SGLUEm	(c_bBlockCopy,0,0,0); 

  _ASM_DEF(g_Lambda);	_CGLUEm	(c_Lambda,0,0,0); 
  _ASM_DEF(g_bLambda);	_CGLUEm	(c_bLambda,0,0,0); 






  _ASM_DEF(g_sendLinkedIndirect);
	PUSHLr	((tmp[0])); 
	MOVLmr	(0,(reg[1]),0,0, (tmp[0])); 
	MOVLrm	((tmp[0]), ((int)&tmpr1),0,0,0); 
	MOVLrm	((reg[1]), ((int)&tmpr2),0,0,0); 
	MOVLmr	(4,(reg[1]),0,0, (reg[1])); 
	POPLr	((tmp[0])); 
	JMPm	(tmpr1,0,0,0); 








  _ASM_DEF(xfer21);	RET	(); 

  _ASM_DEF(xfer2);
	POPLr	((reg[0])); 
	RET	(); 

  _ASM_DEF(g_storeCheck);
	TESTLir	(1, (tmp[1])); 
	JNZm	(xfer21,0,0,0); 
	CMPLmr	(((int)&youngStart),0,0,0, (tmp[0])); 
	JGEm	(xfer21,0,0,0); 
	CMPLmr	(((int)&youngStart),0,0,0, (tmp[1])); 
	JLm	(xfer21,0,0,0); 
	TESTLim	((Object::RootBit), 0,(tmp[0]),0,0); 
	JNZm	(xfer21,0,0,0); 

	PUSHLr	((reg[0])); 
	CMPLim	(((int)RootTableSize), ((int)&rootTableCount),0,0,0); 
	JGEm	(xfer2,0,0,0); 
	INCLm	(((int)&rootTableCount),0,0,0); 
	MOVLmr	(((int)&rootTableCount),0,0,0, (reg[0])); 
	SHLLir	(2, (reg[0])); 
	ADDLir	(((int)rootTable), (reg[0])); 
	MOVLrm	((tmp[0]), 0,(reg[0]),0,0); 
	ORLim	((Object::RootBit), 0,(tmp[0]),0,0); 
	JMPm	(xfer2,0,0,0); 




  _ASM_DEF(g_beRoot);
	PUSHLr	((reg[0])); 
	PUSHLr	((reg[1])); 
	TESTLim	((Object::RootBit), 0,(tmp[0]),0,0); 
	JNZm	(xfer2,0,0,0); 
	MOVLir	(((int)&youngStart), (reg[0])); 
	CMPLmr	(0,(reg[0]),0,0, (tmp[0])); 
	JGEm	(xfer2,0,0,0); 

	MOVLir	(((int)&rootTableCount), (reg[0])); 
	MOVLmr	(0,(reg[0]),0,0, (reg[1])); 
	CMPLir	(((int)RootTableSize), (reg[1])); 
	JGEm	(xfer2,0,0,0); 
	ADDLir	(1, (reg[1])); 
	MOVLrm	((reg[1]), ((int)&rootTableCount),0,0,0); 
	MOVLir	(((int)rootTable), (reg[0])); 
	MOVLrm	((tmp[0]), 0,(reg[0]),(reg[1]),4); 
	ORLim	((Object::RootBit), 0,(tmp[0]),0,0); 
	JMPm	(xfer2,0,0,0); 

  _ASM_DEF(g_end);

  _ASM_NOAPP_1;

  codeCache->allocate((int)asm_pc - (int)glue);
  iflush(glue, asm_pc);
  PRINTF(("glue generated at %p + %d bytes\n", glue, (int)asm_pc - (int)glue));
}

void gen_profile(size_t expected, float elapsed)
{
  /*  size_t gtotal= Profiler::total(g_start, g_end);

  printf("\nglue profiles...\n");
  printf("\n%20s %7s %6s", "glue", "time", "contrib");
  printf("\n%20s %7s %6s\n", "----", "----", "-------");

  profile("cglue", cglue, jglue, expected, elapsed);
  profile("jglue", jglue, sglue, expected, elapsed);
  profile("sglue", sglue, fglue, expected, elapsed);
  profile("fglue", fglue, t_cxFault, expected, elapsed);

  profile("g_sendLinkedIndirect", g_sendLinkedIndirect, g_storeCheck, expected, elapsed);
  profile("g_storeCheck", g_storeCheck, g_beRoot, expected, elapsed);
  profile("g_beRoot", g_beRoot, g_end, expected, elapsed);

  printf("\n"); */
}
















