// i386-tramp.ccg -- Intel trampolines				-*- C++ -*-
//
// Author: Ian.Piumarta@INRIA.Fr
// 
// Last edited: Fri Dec  3 18:57:49 1999 by piumarta (Ian Piumarta) on pingu

#include "Cache.h"

#include "archdep.h"
#include "tramp.h"

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

#include "i386-defs.h"

#include "Frame.h"


static Frame *c_fp= 0;	// C frame pointer, saved during transfer to Smalltalk stack
static Frame *st_fp= 0;	// Smalltalk frame pointer, saved during transfer to C stack

#define _c_fp	((int)&c_fp)
#define _st_fp	((int)&st_fp)


void tramp_initialise(void)
{
  insn *st_init_fp= 0;
  insn *st_resume= 0;
  insn *st_callOnCStack= 0;

  insn *tramp= asm_pc= (insn *)codeCache->reserve(4096);
    _ASM_APP_1 
  _ASM_DEF(st_init_fp);

	PUSHLr	(_EBP); 
	MOVLrr	(_ESP, _EBP); 
	MOVLrm	(_EBP, _c_fp,0,0,0); 
	LEAVE	(); 
	RET	(); 

  _ASM_DEF(st_resume);

	POPLr	(_EAX); 
	POPLr	((FP)); 
	MOVLrr	((FP), _ESP); 
	MOVLmr	(f_pc_off,(FP),0,0, _EAX); 
	MOVLmr	(f_stackp_off,(FP),0,0, (SP)); 
	JMPm	(0,_EAX,0,0); 

  _ASM_DEF(st_callOnCStack);

	PUSHLr	(_EBP); 
	MOVLrr	(_ESP, _EBP); 

	PUSHLr	((FP)); 
	PUSHLr	((SP)); 
	MOVLrm	(_ESP, _st_fp,0,0,0); 

	MOVLmr	(_c_fp,0,0,0, _ESP); 

	PUSHLm	(20,_EBP,0,0); 
	PUSHLm	(16,_EBP,0,0); 
	PUSHLm	(12,_EBP,0,0); 
	MOVLmr	(8,_EBP,0,0, _EAX); 
	CALLm	(0,_EAX,0,0); 
	CALLm	(abort,0,0,0); 

	MOVLmr	(_st_fp,0,0,0, _ESP); 
	POPLr	((SP)); 
	POPLr	((FP)); 
	LEAVE	(); 
	RET	(); 

  _ASM_NOAPP_1;

  codeCache->allocate((int)asm_pc - (int)tramp);
  iflush(tramp, asm_pc);

  tramp_resume= (void (*)(Frame *))st_resume;
  tramp_callOnCStack= (int (*)(void *, int a, int b, int c)) st_callOnCStack;

  PRINTF(("trampolines generated at %p + %d bytes\n", tramp, (int)asm_pc - (int)tramp));

  ((void (*)(void))st_init_fp)();	// save C stack FP

  PRINTF(("saved C FP is %p\n", c_fp)); 
}




