/* This file is part of GNU epsilon, a functional language implementation

Copyright (C) 2003 Luca Saiu
Copyright (C) 2003 Matteo Golfarini

GNU epsilon is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.

GNU epsilon is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with epsilon; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */


/* Code for the s_pshf instruction */
word_t* new_environment;
integer_t i;

/* Allocate new environment:*/
ASSIGN_MY_MALLOC(new_environment, ((integer_t)PARAMETER_1) + 1);

/* Create the s-link: */
new_environment[0] = environment;

/* Fill with non-top operands: */
for(i = 0; i < (integer_t)PARAMETER_1 - 1; i++)
  new_environment[i + 1] = stack[undertop_stack_pointer + i - (integer_t)PARAMETER_1 + 2];

/* Fill with top operand, if top is an operand; else copy top to the stack,
   so that we don't lose it: */
if((integer_t)PARAMETER_1 != (integer_t)0)
  new_environment[(integer_t)PARAMETER_1] = top;
else
  stack[undertop_stack_pointer + 1] = top;

/* Enlarge stack if needed:
                (2003-07-29, positron: this is *never* needed) */
/*
int stack_size1 = stack_size;
ENLARGE_STACK(undertop_stack_pointer + instructions_no);
if(stack_size != stack_size1){
  fprintf(stderr, "--------------------------------------------------------\n");
  fprintf(stderr, "SP is       %i\n", undertop_stack_pointer + 1);
  fprintf(stderr, "old size is %i\n", stack_size1 + 1);
  fprintf(stderr, "new size is %i\n", stack_size + 1);
  fprintf(stderr, "s_pshf: We seem to really need ENLARGE_STACK() in s_pshf\n");
  fprintf(stderr, "--------------------------------------------------------\n");
}
*/

/* Delete all operands, and replace them with old_env and old_FP: */
undertop_stack_pointer -= ((integer_t)PARAMETER_1 - 2);
stack[undertop_stack_pointer] = environment;
top = (word_t)frame_pointer;

/* Update env and FP: */
environment = new_environment;
frame_pointer = undertop_stack_pointer;
