Пример #1
1
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  // conditional-branch offset bits
  int offbits = 0;
  int twoscompl = 0;
  unsigned int abs_offbits = 0;
  
  // number of bits changed in a GPR
  int bits_changed;
  
  int dst_reg; // destination register in part 3

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

	// initialize all the arrays
	init_arrays();
	
		
  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
		  dst_reg = O1;					\
		  if(dst_reg > 0 && dst_reg < NUM_REGS) prev_val[dst_reg] = regs.regs_R[dst_reg]; \
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}
	
	
	// for registers 0-31 determine the new value written to dst_reg
	if(dst_reg > 0 && dst_reg < NUM_REGS){
		
		bits_changed = func_bits_chng(prev_val[dst_reg], regs.regs_R[dst_reg]);
		reg_contents[dst_reg] += bits_changed;
		num_inst_chng_bits++;
		
	}
	
	
	  if(MD_OP_FLAGS(op) & F_COND)
	{
		g_total_cond_branches++;
		
		// increment histogram index with corresp. offset bits
		offbits = (regs.regs_TPC - regs.regs_PC)/8;
		
		// absolute value representation of the offbits
		abs_offbits = abs(regs.regs_TPC - regs.regs_PC)/8;
				
		if(offbits < 0){
			// if offset is negative, simply add one bit (the signed bit) to its absolute value
			// this is equivalent to offbits = ceil(log10(-1*offbits)/log10(2) + 1); (trust me, I've tried it)
			offbits = floor(log10(abs_offbits)/log10(2) + 2) + 1; 
		}else{
			offbits = floor(log10(abs_offbits)/log10(2) + 2);
		}
		
		
		histogram[offbits]++;

	}
	
	  if(MD_OP_FLAGS(op) & F_DIRJMP)
	{
		g_total_uncond_branches++;
		
	}
	
	  if((MD_OP_FLAGS(op) & F_FCOMP) || (MD_OP_FLAGS(op) & F_FPCOND))
	{
		g_total_fp_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_STORE)
	{
		g_total_store_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_LOAD)
	{
		g_total_ld_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_IMM)
	{
		g_total_imm_inst++;
	}
	
      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

	

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts){
			
			return;
		}
    }
}
Пример #2
0
void print_list(insn_struct* queue, char* text, int limit)
{
  int i = 0;

	printf("--------%s STARTING",text);
	printf("-------------\n\n");

	insn_struct* temp = queue;

  while (temp != NULL && i < limit)
  {
    md_print_insn(temp->insn->inst, temp->insn->pc, stdout);
    myfprintf(stdout, "\t%d\t%d\t%d\t%d\n", 
	    temp->insn->tom_dispatch_cycle,
	    temp->insn->tom_issue_cycle,
	    temp->insn->tom_execute_cycle,
	    temp->insn->tom_cdb_cycle);
   	i++;
		temp =  temp->next;
  }

	printf("--------%s ENDING",text);
	printf("-------------\n\n");
}
Пример #3
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  /* ECE552 Assignment 2 - BEGIN CODE */
  
  int i, j;
 
  /* Initialization of tables */

  for (i = 0; i < 4096; i++)
  {
    two_bit_table[i] = n;
  }
   
  for (i = 0; i < 8; i++)
  {
    for (j = 0; j < 64; j++)
    {
	PHT[i][j] = n;
    }
  }

  for (i = 0; i < 32; i++)
  {
    for (j = 0; j < 1024; j++)
    {
	GPHT[i][j] = n;
    }
  }

 /* ECE552 Assignment 2 - END CODE */

  fprintf(stderr, "sim: ** starting functional simulation **\n");
  
  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;
	  
      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      /* ECE552 Assignment 2 - BEGIN CODE */

      if (MD_OP_FLAGS(op) & F_COND)
      {
	int index = (regs.regs_PC >> 3) & 0xfff;
	int bht_index = (regs.regs_PC >> 6) & 0x1ff;
	int pht_index = (regs.regs_PC >> 3) & 0x7;
	int pht_row_index = BHT[bht_index];
	int gap_pht_index = (regs.regs_PC >> 3) & 0x1f;
	int g_pht_row_index = GHR;
 	

	if (regs.regs_NPC == regs.regs_PC + sizeof(md_inst_t))
	{
          br_taken = 0;
	  sim_num_mispred_static++;
        }
        else
        {
	  br_taken = 1;
        }

	/* two bit saturation branch predictor */

        switch(two_bit_table[index])
        {
	  case N:
	    if (br_taken)
	    {
	      two_bit_table[index] = n;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      two_bit_table[index] = t;
	      sim_num_mispred_2bitsat++;
	    }
	    else
	    {
	      two_bit_table[index] = N;
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      two_bit_table[index] = T;
	    }
	    else
	    {
	      two_bit_table[index] = n;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
	  case T:
	    if (!br_taken)
	    {
	      two_bit_table[index] = t;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
        }

	/* two level adaptive branch predictor */

	switch(PHT[pht_index][pht_row_index])
        {
	  case N:
	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = n;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f) | 0x1;
	      sim_num_mispred_2level++;
	    }
	    else
	    {
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = t;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	      sim_num_mispred_2level++;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = N;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = T;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = n;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	      sim_num_mispred_2level++;
	    }
	    break;
	  case T:
	    if (br_taken)
	    {
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = t;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	      sim_num_mispred_2level++;
	    }
	    break;
        }

	/* open ended branch predictor */

	switch(GPHT[gap_pht_index][g_pht_row_index])
        {
	  case N:
	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = n;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	      sim_num_mispred_openend++;
	    }
	    else
	    {
	      GHR = ((GHR << 1) & 0x3ff);
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = t;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	      sim_num_mispred_openend++;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = N;
	      GHR = ((GHR << 1) & 0x3ff);
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = T;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = n;
	      GHR = ((GHR << 1) & 0x3ff);
	      sim_num_mispred_openend++;
	    }
	    break;
	  case T:
	    if (br_taken)
	    {
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = t;
	      GHR = ((GHR << 1) & 0x3ff);
	      sim_num_mispred_openend++;
	    }
	    break;
        }
	
        sim_num_br++;
      }

      /* ECE552 Assignment 2 - END CODE */

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
Пример #4
0
/* read an X event */
void ReadXServer (void)
{
  static XEvent event;
  int old_cursor = 0, keypress;
  Item *item, *old_item;
  KeySym ks;
  char *sp, *dp;
  static unsigned char buf[10];         /* unsigned for international */
  static int n;

  while (FEventsQueued(dpy, QueuedAfterReading)) {
    FNextEvent(dpy, &event);
    if (event.xany.window == CF.frame) {
      switch (event.type) {
      case ClientMessage:
      {
	      if(event.xclient.format == 32 &&
		 event.xclient.data.l[0] == wm_del_win)
	      {
		      exit(0);
	      }
      }
      break;
      case ConfigureNotify:             /* has window be reconfigured */
      {
	      XEvent tmpe;

	      while (FCheckTypedWindowEvent(
		      dpy, CF.frame, ConfigureNotify, &tmpe))
	      {
		      if (!tmpe.xconfigure.send_event)
			      continue;
		      event.xconfigure.x = tmpe.xconfigure.x;
		      event.xconfigure.y = tmpe.xconfigure.y;
		      event.xconfigure.send_event = True;
	      }
	      if (CF.max_width != event.xconfigure.width ||
		  CF.total_height != event.xconfigure.height)
	      {
		      /* adjust yourself... do noting */
		      ResizeFrame();
		      CF.max_width = event.xconfigure.width;
		      CF.total_height = event.xconfigure.height;
		      UpdateRootTransapency(False, True);
		      if (!CSET_IS_TRANSPARENT(colorset))
		      {
			  RedrawFrame(NULL);
		      }
	      }
	      else if (event.xconfigure.send_event)
	      {
		      UpdateRootTransapency(False, True);
	      }
      }
      break;
#if 0
      case SelectionClear:
	 selection_clear ();
	break;
      case SelectionNotify:
	selection_paste ();
	break;
      case SelectionRequest:
	 selection_send ();
	break;
#endif
      case Expose:
      {
	      int ex = event.xexpose.x;
	      int ey = event.xexpose.y;
	      int ex2 = event.xexpose.x + event.xexpose.width;
	      int ey2 = event.xexpose.y + event.xexpose.height;
	      while (FCheckTypedWindowEvent(dpy, CF.frame, Expose, &event))
	      {
		      ex = min(ex, event.xexpose.x);
		      ey = min(ey, event.xexpose.y);
		      ex2 = max(ex2, event.xexpose.x + event.xexpose.width);
		      ey2 = max(ey2 , event.xexpose.y + event.xexpose.height);
	      }
	      event.xexpose.x = ex;
	      event.xexpose.y = ey;
	      event.xexpose.width = ex2 - ex;
	      event.xexpose.height = ey2 - ey;
	      RedrawFrame(&event);
	      if (CF.grab_server && !CF.server_grabbed)
	      {
		      if (GrabSuccess ==
			  XGrabPointer(dpy, CF.frame, True, 0,
				       GrabModeAsync, GrabModeAsync,
				       None, None, CurrentTime))
			      CF.server_grabbed = 1;
	      }
      }
      break;
      case VisibilityNotify:
	if (CF.server_grabbed &&
	    event.xvisibility.state != VisibilityUnobscured)
	{
	  /* raise our window to the top */
	  XRaiseWindow(dpy, CF.frame);
	  XSync(dpy, 0);
	}
	break;
      case KeyPress:  /* we do text input here */
	n = XLookupString(&event.xkey, (char *)buf, sizeof(buf), &ks, NULL);
	keypress = buf[0];
	myfprintf((stderr, "Keypress [%s]\n", buf));
	if (n == 0) {  /* not a regular key, translate it into one */
	  switch (ks) {
	  case XK_Home:
	  case XK_Begin:
	    buf[0] = '\001';  /* ^A */
	    break;
	  case XK_End:
	    buf[0] = '\005';  /* ^E */
	    break;
	  case XK_Left:
	    buf[0] = '\002';  /* ^B */
	    break;
	  case XK_Right:
	    buf[0] = '\006';  /* ^F */
	    break;
	  case XK_Up:
	    buf[0] = '\020';            /* ^P */
	    break;
	  case XK_Down:
	    buf[0] = '\016';  /* ^N */
	    break;
	  default:
	    if (ks >= XK_F1 && ks <= XK_F35) {
	      buf[0] = '\0';
	      keypress = 257 + ks - XK_F1;
	    } else
	      goto no_redraw;  /* no action for this event */
	  }
	}
	switch (ks) {                   /* regular key, may need adjustment */
	case XK_Tab:
#ifdef XK_XKB_KEYS
	case XK_ISO_Left_Tab:
#endif
	  if (event.xkey.state & ShiftMask) { /* shifted key */
	    buf[0] = '\020';          /* chg shift tab to ^P */
	  }
	  break;
	case '>':
	  if (event.xkey.state & Mod1Mask) { /* Meta, shift > */
	    process_history(1);
	    goto redraw_newcursor;
	  }
	  break;
	case '<':
	  if (event.xkey.state & Mod1Mask) { /* Meta, shift < */
	    process_history(-1);
	    goto redraw_newcursor;
	  }
	  break;
	}
	if (!CF.cur_input) {  /* no text input fields */
	  for (item = root_item_ptr; item != 0;
	       item = item->header.next) {/* all items */
	    if (item->type == I_BUTTON && item->button.keypress == keypress) {
	      RedrawItem(item, 1, NULL);
	      usleep(MICRO_S_FOR_10MS);
	      RedrawItem(item, 0, NULL);
	      DoCommand(item);
	      goto no_redraw;
	    }
	  }
	  break;
	} else if (CF.cur_input == CF.cur_input->input.next_input) {
	  /* 1 ip field */
	  switch (buf[0]) {
	  case '\020':                  /* ^P previous field */
	    process_history(-1);
	    goto redraw_newcursor;
	    break;
	  case '\016':                  /* ^N  next field */
	    process_history(1);
	    goto redraw_newcursor;
	    break;
	  } /* end switch */
	} /* end one input field */
	switch (buf[0]) {
	case '\001':  /* ^A */
	  old_cursor = CF.abs_cursor;
	  CF.rel_cursor = 0;
	  CF.abs_cursor = 0;
	  CF.cur_input->input.left = 0;
	  goto redraw_newcursor;
	  break;
	case '\005':  /* ^E */
	  old_cursor = CF.abs_cursor;
	  CF.rel_cursor = CF.cur_input->input.n;
	  if ((CF.cur_input->input.left =
	       CF.rel_cursor - CF.cur_input->input.size) < 0)
	    CF.cur_input->input.left = 0;
	  CF.abs_cursor = CF.rel_cursor - CF.cur_input->input.left;
	  goto redraw_newcursor;
	  break;
	case '\002':  /* ^B */
	  old_cursor = CF.abs_cursor;
	  if (CF.rel_cursor > 0) {
	    CF.rel_cursor--;
	    CF.abs_cursor--;
	    if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) {
	      CF.abs_cursor++;
	      CF.cur_input->input.left--;
	    }
	  }
	  goto redraw_newcursor;
	  break;
	case '\006':  /* ^F */
	  old_cursor = CF.abs_cursor;
	  if (CF.rel_cursor < CF.cur_input->input.n) {
	    CF.rel_cursor++;
	    CF.abs_cursor++;
	    if (CF.abs_cursor >= CF.cur_input->input.size &&
		CF.rel_cursor < CF.cur_input->input.n) {
	      CF.abs_cursor--;
	      CF.cur_input->input.left++;
	    }
	  }
	  goto redraw_newcursor;
	  break;
	case '\010':  /* ^H */
	  old_cursor = CF.abs_cursor;
	  if (CF.rel_cursor > 0) {
	    sp = CF.cur_input->input.value + CF.rel_cursor;
	    dp = sp - 1;
	    for (; *dp = *sp, *sp != '\0'; dp++, sp++);
	    CF.cur_input->input.n--;
	    CF.rel_cursor--;
	    if (CF.rel_cursor < CF.abs_cursor) {
	      CF.abs_cursor--;
	      if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) {
		CF.abs_cursor++;
		CF.cur_input->input.left--;
	      }
	    } else
	      CF.cur_input->input.left--;
	  }
	  goto redraw_newcursor;
	  break;
	case '\177':  /* DEL */
	case '\004':  /* ^D */
	  if (CF.rel_cursor < CF.cur_input->input.n) {
	    sp = CF.cur_input->input.value + CF.rel_cursor + 1;
	    dp = sp - 1;
	    for (; *dp = *sp, *sp != '\0'; dp++, sp++);
	    CF.cur_input->input.n--;
	    goto redraw_newcursor;
	  }
	  break;
	case '\013':  /* ^K */
	  CF.cur_input->input.value[CF.rel_cursor] = '\0';
	  CF.cur_input->input.n = CF.rel_cursor;
	  goto redraw_newcursor;
	case '\025':  /* ^U */
	  CF.cur_input->input.value[0] = '\0';
	  CF.cur_input->input.n = CF.cur_input->input.left = 0;
	  CF.rel_cursor = CF.abs_cursor = 0;
	  goto redraw_newcursor;
	case '\020':                    /* ^P previous field */
	  old_item = CF.cur_input;
	  CF.cur_input = old_item->input.prev_input; /* new current input fld */
	  RedrawItem(old_item, 1, NULL);
	  CF.rel_cursor = CF.abs_cursor = 0; /* home cursor in new input field */
	  goto redraw;
	  break;
	case '\t':
	case '\n':
	case '\015':
	case '\016':  /* LINEFEED, TAB, RETURN, ^N, jump to the next field */
	  switch (process_tabtypes(&buf[0])) {
	    case 0: goto no_redraw;break;
	    case 1: goto redraw;break;
	  }
	  break;
	default:
	  old_cursor = CF.abs_cursor;
	  if((buf[0] >= ' ' &&
	      buf[0] < '\177') ||
	     (buf[0] >= 160)) {         /* regular or intl char */
	    process_regular_char_input(&buf[0]); /* insert into input field */
	    goto redraw_newcursor;
	  }
	  /* unrecognized key press, check for buttons */
	  for (item = root_item_ptr; item != 0; item = item->header.next)
	  {
	    /* all items */
	    myfprintf((stderr, "Button: keypress==%d\n",
		    item->button.keypress));
	    if (item->type == I_BUTTON && item->button.keypress == keypress) {
	      RedrawItem(item, 1, NULL);
	      usleep(MICRO_S_FOR_10MS);  /* .1 seconds */
	      RedrawItem(item, 0, NULL);
	      DoCommand(item);
	      goto no_redraw;
	    }
	  }
	  break;
	}
      redraw_newcursor:
	{
	  XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC,
			 CF.cur_input->header.dt_ptr->dt_colors[c_item_bg]);
	  /* Since DrawString is being used, I changed this to clear the
	     entire input field.  dje 10/24/99. */
	  XClearArea(dpy, CF.cur_input->header.win,
		     BOX_SPC + TEXT_SPC - 1, BOX_SPC,
		     CF.cur_input->header.size_x
		     - (2 * BOX_SPC) - 2 - TEXT_SPC,
		     (CF.cur_input->header.size_y - 1)
		     - 2 * BOX_SPC + 1, False);
	}
      redraw:
	{
	  int len, x, dy;
	  len = CF.cur_input->input.n - CF.cur_input->input.left;
	  XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC,
			 CF.cur_input->header.dt_ptr->dt_colors[c_item_fg]);
	  if (len > CF.cur_input->input.size)
	    len = CF.cur_input->input.size;
	  CF.cur_input->header.dt_ptr->dt_Fstr->win = CF.cur_input->header.win;
	  CF.cur_input->header.dt_ptr->dt_Fstr->gc  =
	    CF.cur_input->header.dt_ptr->dt_item_GC;
	  CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = False;
	  if (itemcolorset >= 0)
	  {
	    CF.cur_input->header.dt_ptr->dt_Fstr->colorset =
		    &Colorset[itemcolorset];
	    CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = True;
	  }
	  CF.cur_input->header.dt_ptr->dt_Fstr->str = CF.cur_input->input.value;
	  CF.cur_input->header.dt_ptr->dt_Fstr->x   = BOX_SPC + TEXT_SPC;
	  CF.cur_input->header.dt_ptr->dt_Fstr->y   = BOX_SPC + TEXT_SPC
	    + CF.cur_input->header.dt_ptr->dt_Ffont->ascent;
	  CF.cur_input->header.dt_ptr->dt_Fstr->len = len;
	  FlocaleDrawString(dpy,
			    CF.cur_input->header.dt_ptr->dt_Ffont,
			    CF.cur_input->header.dt_ptr->dt_Fstr,
			    FWS_HAVE_LENGTH);
	  x = BOX_SPC + TEXT_SPC +
		  FlocaleTextWidth(CF.cur_input->header.dt_ptr->dt_Ffont,
				   CF.cur_input->input.value,CF.abs_cursor)
		  - 1;
	  dy = CF.cur_input->header.size_y - 1;
	  XDrawLine(dpy, CF.cur_input->header.win,
		    CF.cur_input->header.dt_ptr->dt_item_GC,
		    x, BOX_SPC, x, dy - BOX_SPC);
	  myfprintf((stderr,"Line %d/%d - %d/%d (char)\n",
		     x, BOX_SPC, x, dy - BOX_SPC));
	}
      no_redraw:
	break;  /* end of case KeyPress */
      }  /* end of switch (event.type) */
      continue;
    }  /* end of if (event.xany.window == CF.frame) */
    for (item = root_item_ptr; item != 0;
	 item = item->header.next) {    /* all items */
      if (event.xany.window == item->header.win) {
	switch (event.type) {
	case Expose:
	{
		int ex = event.xexpose.x;
		int ey = event.xexpose.y;
		int ex2 = event.xexpose.x + event.xexpose.width;
		int ey2 = event.xexpose.y + event.xexpose.height;
		while (FCheckTypedWindowEvent(
			dpy, item->header.win, Expose, &event))
		{
			ex = min(ex, event.xexpose.x);
			ey = min(ey, event.xexpose.y);
			ex2 = max(ex2, event.xexpose.x + event.xexpose.width);
			ey2 = max(ey2 , event.xexpose.y + event.xexpose.height);
		}
		event.xexpose.x = ex;
		event.xexpose.y = ey;
		event.xexpose.width = ex2 - ex;
		event.xexpose.height = ey2 - ey;
		RedrawItem(item, 0, &event);
	}
	break;
	case ButtonPress:
	  if (item->type == I_INPUT) {
	    old_item = CF.cur_input;
	    CF.cur_input = item;
	    RedrawItem(old_item, 1, NULL);
	    {
	      Bool done = False;

	      CF.abs_cursor = 0;
	      while(CF.abs_cursor <= item->input.size && !done)
	      {
		if (FlocaleTextWidth(item->header.dt_ptr->dt_Ffont,
				     item->input.value,
				     CF.abs_cursor) >=
		    event.xbutton.x - BOX_SPC - TEXT_SPC)
		{
		  done = True;
		  CF.abs_cursor--;
		}
		else
		{
		  CF.abs_cursor++;
		}
	      }
	    }
	    if (CF.abs_cursor < 0)
	      CF.abs_cursor = 0;
	    if (CF.abs_cursor > item->input.size)
	      CF.abs_cursor = item->input.size;
	    CF.rel_cursor = CF.abs_cursor + item->input.left;
	    if (CF.rel_cursor < 0)
	      CF.rel_cursor = 0;
	    if (CF.rel_cursor > item->input.n)
	      CF.rel_cursor = item->input.n;
	    if (CF.rel_cursor > 0 && CF.rel_cursor == item->input.left)
	      item->input.left--;
	    if (CF.rel_cursor < item->input.n &&
		CF.rel_cursor == item->input.left + item->input.size)
	      item->input.left++;
	    CF.abs_cursor = CF.rel_cursor - item->input.left;
	    if (event.xbutton.button == Button2) { /* if paste request */
	      process_paste_request (&event, item);
	    }
	    RedrawItem(item, 0, NULL);
	  }
	  if (item->type == I_CHOICE)
	    ToggleChoice(item);
	  if (item->type == I_BUTTON) {
	    RedrawItem(item, 1, NULL);    /* push button in */
	    if (CF.activate_on_press) {
	      usleep(MICRO_S_FOR_10MS);   /* make sure its visible */
	      RedrawItem(item, 0, NULL);  /* pop button out */
	      DoCommand(item);            /* execute the button command */
	    } else {
	      XGrabPointer(dpy, item->header.win,
			   False,         /* owner of events */
			   ButtonReleaseMask, /* events to report */
			   GrabModeAsync, /* keyboard mode */
			   GrabModeAsync, /* pointer mode */
			   None,          /* confine to */
			   /* I sort of like this, the hand points in
			      the other direction and the color is
			      reversed. I don't know what other GUIs do,
			      Java doesn't do anything, neither does anything
			      else I can find...dje */
			   CF.pointer[button_in_pointer],   /* cursor */
			   CurrentTime);
	    } /* end activate on press */
	  }
	  break;
	case ButtonRelease:
	  if (!CF.activate_on_press) {
	    RedrawItem(item, 0, NULL);
	    if (CF.grab_server && CF.server_grabbed) {
	      /* You have to regrab the pointer, or focus
		 can go to another window.
		 grab...
	      */
	      XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync,
			   None, None, CurrentTime);
	      XFlush(dpy);
	    } else {
	      XUngrabPointer(dpy, CurrentTime);
	      XFlush(dpy);
	    }
	    if (event.xbutton.x >= 0 &&
		event.xbutton.x < item->header.size_x &&
		event.xbutton.y >= 0 &&
		event.xbutton.y < item->header.size_y) {
	      DoCommand(item);
	    }
	  }
	  break;
	}
      }
    }  /* end of for (i = 0) */
  }  /* while loop */
}
Пример #5
0
/* load program text and initialized data into simulated virtual memory
   space and initialize program segment range variables */
void
ld_load_prog(char *fname,		/* program to load */
	     int argc, char **argv,	/* simulated program cmd line args */
	     char **envp,		/* simulated program environment */
	     struct regs_t *regs,	/* registers to initialize for load */
	     struct mem_t *mem,		/* memory space to load prog into */
	     int zero_bss_segs)		/* zero uninit data segment? */
{
  int i;
  qword_t temp;
  md_addr_t sp, data_break = 0, null_ptr = 0, argv_addr, envp_addr;

  if (eio_valid(fname))
    {
      if (argc != 1)
	{
	  fprintf(stderr, "error: EIO file has arguments\n");
	  exit(1);
	}

      fprintf(stderr, "sim: loading EIO file: %s\n", fname);

      sim_eio_fname = mystrdup(fname);

      /* open the EIO file stream */
      sim_eio_fd = eio_open(fname);

      /* load initial state checkpoint */
      if (eio_read_chkpt(regs, mem, sim_eio_fd) != -1)
	fatal("bad initial checkpoint in EIO file");

      /* load checkpoint? */
      if (sim_chkpt_fname != NULL)
	{
	  counter_t restore_icnt;

	  FILE *chkpt_fd;

	  fprintf(stderr, "sim: loading checkpoint file: %s\n",
		  sim_chkpt_fname);

	  if (!eio_valid(sim_chkpt_fname))
	    fatal("file `%s' does not appear to be a checkpoint file",
		  sim_chkpt_fname);

	  /* open the checkpoint file */
	  chkpt_fd = eio_open(sim_chkpt_fname);

	  /* load the state image */
	  restore_icnt = eio_read_chkpt(regs, mem, chkpt_fd);

	  /* fast forward the baseline EIO trace to checkpoint location */
	  myfprintf(stderr, "sim: fast forwarding to instruction %n\n",
		    restore_icnt);
	  eio_fast_forward(sim_eio_fd, restore_icnt);
	}

      /* computed state... */
      ld_environ_base = regs->regs_R[MD_REG_SP];
      ld_prog_entry = regs->regs_PC;

      /* fini... */
      return;
    }
#ifdef MD_CROSS_ENDIAN
  else
    {
      warn("endian of `%s' does not match host", fname);
      warn("running with experimental cross-endian execution support");
      warn("****************************************");
      warn("**>> please check results carefully <<**");
      warn("****************************************");
#if 0
      fatal("SimpleScalar/Alpha only supports binary execution on\n"
	    "       little-endian hosts, use EIO files on big-endian hosts");
#endif
    }
#endif /* MD_CROSS_ENDIAN */

  if (sim_chkpt_fname != NULL)
    fatal("checkpoints only supported while EIO tracing");

#ifdef BFD_LOADER

  {
    bfd *abfd;
    asection *sect;

    /* set up a local stack pointer, this is where the argv and envp
       data is written into program memory */
    ld_stack_base = MD_STACK_BASE;
    sp = ROUND_DOWN(MD_STACK_BASE - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE));
    ld_stack_size = ld_stack_base - sp;
    printf("Thread 0 stack size (3)%d\n",  current->ld_stack_size);

    /* initial stack pointer value */
    ld_environ_base = sp;

    /* load the program into memory, try both endians */
    if (!(abfd = bfd_openr(argv[0], "ss-coff-big")))
      if (!(abfd = bfd_openr(argv[0], "ss-coff-little")))
	fatal("cannot open executable `%s'", argv[0]);

    /* this call is mainly for its side effect of reading in the sections.
       we follow the traditional behavior of `strings' in that we don't
       complain if we don't recognize a file to be an object file.  */
    if (!bfd_check_format(abfd, bfd_object))
      {
	bfd_close(abfd);
	fatal("cannot open executable `%s'", argv[0]);
      }

    /* record profile file name */
    ld_prog_fname = argv[0];

    /* record endian of target */
    ld_target_big_endian = abfd->xvec->byteorder_big_p;

    debug("processing %d sections in `%s'...",
	  bfd_count_sections(abfd), argv[0]);

    /* read all sections in file */
    for (sect=abfd->sections; sect; sect=sect->next)
      {
	char *p;

	debug("processing section `%s', %d bytes @ 0x%08x...",
	      bfd_section_name(abfd, sect), bfd_section_size(abfd, sect),
	      bfd_section_vma(abfd, sect));

	/* read the section data, if allocated and loadable and non-NULL */
	if ((bfd_get_section_flags(abfd, sect) & SEC_ALLOC)
	    && (bfd_get_section_flags(abfd, sect) & SEC_LOAD)
	    && bfd_section_vma(abfd, sect)
	    && bfd_section_size(abfd, sect))
	  {
	    /* allocate a section buffer */
	    p = calloc(bfd_section_size(abfd, sect), sizeof(char));
	    if (!p)
	      fatal("cannot allocate %d bytes for section `%s'",
		    bfd_section_size(abfd, sect),
		    bfd_section_name(abfd, sect));

	    if (!bfd_get_section_contents(abfd, sect, p, (file_ptr)0,
					  bfd_section_size(abfd, sect)))
	      fatal("could not read entire `%s' section from executable",
		    bfd_section_name(abfd, sect));

	    /* copy program section it into simulator target memory */
	    mem_bcopy(mem_fn, Write, bfd_section_vma(abfd, sect),
		      p, bfd_section_size(abfd, sect));

	    /* release the section buffer */
	    free(p);
	  }
	/* zero out the section if it is loadable but not allocated in exec */
	else if (zero_bss_segs
		 && (bfd_get_section_flags(abfd, sect) & SEC_LOAD)
		 && bfd_section_vma(abfd, sect)
		 && bfd_section_size(abfd, sect))
	  {
	    /* zero out the section region */
	    mem_bzero(mem_fn,
		      bfd_section_vma(abfd, sect),
		      bfd_section_size(abfd, sect));
	  }
	else
	  {
	    /* else do nothing with this section, it's probably debug data */
	    debug("ignoring section `%s' during load...",
		  bfd_section_name(abfd, sect));
	  }

	/* expected text section */
	if (!strcmp(bfd_section_name(abfd, sect), ".text"))
	  {
	    /* .text section processing */
	    ld_text_size =
	      ((bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect))
	       - MD_TEXT_BASE)
		+ /* for speculative fetches/decodes */TEXT_TAIL_PADDING;

	    /* create tail padding and copy into simulator target memory */
#if 0
	    mem_bzero(mem_fn,
		      bfd_section_vma(abfd, sect)
		      + bfd_section_size(abfd, sect),
		      TEXT_TAIL_PADDING);
#endif
	  }
	/* expected data sections */
	else if (!strcmp(bfd_section_name(abfd, sect), ".rdata")
		 || !strcmp(bfd_section_name(abfd, sect), ".data")
		 || !strcmp(bfd_section_name(abfd, sect), ".sdata")
		 || !strcmp(bfd_section_name(abfd, sect), ".bss")
		 || !strcmp(bfd_section_name(abfd, sect), ".sbss"))
	  {
	    /* data section processing */
	    if (bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect) >
		data_break)
	      data_break = (bfd_section_vma(abfd, sect) +
			    bfd_section_size(abfd, sect));
	  }
	else
	  {
	    /* what is this section??? */
	    fatal("encountered unknown section `%s', %d bytes @ 0x%08x",
		  bfd_section_name(abfd, sect), bfd_section_size(abfd, sect),
		  bfd_section_vma(abfd, sect));
	  }
      }

    /* compute data segment size from data break point */
    ld_text_base = MD_TEXT_BASE;
    ld_data_base = MD_DATA_BASE;
    ld_prog_entry = bfd_get_start_address(abfd);
    ld_data_size = data_break - ld_data_base;

    /* done with the executable, close it */
    if (!bfd_close(abfd))
      fatal("could not close executable `%s'", argv[0]);
  }

#else /* !BFD_LOADER, i.e., standalone loader */

  {
    FILE *fobj;
    long floc;
    struct ecoff_filehdr fhdr;
    struct ecoff_aouthdr ahdr;
    struct ecoff_scnhdr shdr;

    /* record profile file name */
    ld_prog_fname = argv[0];

    /* load the program into memory, try both endians */
#if defined(__CYGWIN32__) || defined(_MSC_VER)
    fobj = fopen(argv[0], "rb");
#else
    fobj = fopen(argv[0], "r");
#endif
    if (!fobj)
      fatal("cannot open executable `%s'", argv[0]);

    if (fread(&fhdr, sizeof(struct ecoff_filehdr), 1, fobj) < 1)
      fatal("cannot read header from executable `%s'", argv[0]);

    /* record endian of target */
    if (fhdr.f_magic == MD_SWAPH(ECOFF_ALPHAMAGIC))
      ld_target_big_endian = FALSE;
    else if (fhdr.f_magic == MD_SWAPH(ECOFF_EB_MAGIC)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EL_MAGIC)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EB_OTHER)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EL_OTHER))
      fatal("Alpha simulator cannot run PISA binary `%s'", argv[0]);
    else
      fatal("bad magic number in executable `%s' (not an executable)",
	    argv[0]);

    if (fread(&ahdr, sizeof(struct ecoff_aouthdr), 1, fobj) < 1)
      fatal("cannot read AOUT header from executable `%s'", argv[0]);

    ld_text_base = MD_SWAPQ(ahdr.text_start);
    ld_text_size = MD_SWAPQ(ahdr.tsize);
    ld_prog_entry = MD_SWAPQ(ahdr.entry);
    ld_data_base = MD_SWAPQ(ahdr.data_start);
    ld_data_size = MD_SWAPQ(ahdr.dsize) + MD_SWAPQ(ahdr.bsize);
    regs->regs_R[MD_REG_GP] = MD_SWAPQ(ahdr.gp_value);

    /* compute data segment size from data break point */
    data_break = ld_data_base + ld_data_size;

    /* seek to the beginning of the first section header, the file header comes
       first, followed by the optional header (this is the aouthdr), the size
       of the aouthdr is given in Fdhr.f_opthdr */
    fseek(fobj, sizeof(struct ecoff_filehdr) + MD_SWAPH(fhdr.f_opthdr), 0);

    debug("processing %d sections in `%s'...",
	  MD_SWAPH(fhdr.f_nscns), argv[0]);

    /* loop through the section headers */
    floc = ftell(fobj);
    for (i = 0; i < MD_SWAPH(fhdr.f_nscns); i++)
      {
	char *p;

	if (fseek(fobj, floc, 0) == -1)
	  fatal("could not reset location in executable");
	if (fread(&shdr, sizeof(struct ecoff_scnhdr), 1, fobj) < 1)
	  fatal("could not read section %d from executable", i);
	floc = ftell(fobj);

	switch (MD_SWAPW(shdr.s_flags))
	  {
	  case ECOFF_STYP_TEXT:
	    p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
	    if (!p)
	      fatal("out of virtual memory");

	    if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
	      fatal("could not read `.text' from executable", i);
	    if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
	      fatal("could not read text section from executable");

	    /* copy program section into simulator target memory */
	    mem_bcopy(mem_access, mem, Write,
		      MD_SWAPQ(shdr.s_vaddr), p, MD_SWAPQ(shdr.s_size));

#if 0
	    /* create tail padding and copy into simulator target memory */
	    mem_bzero(mem_access, mem,
		      MD_SWAPQ(shdr.s_vaddr) + MD_SWAPQ(shdr.s_size),
		      TEXT_TAIL_PADDING);
#endif

	    /* release the section buffer */
	    free(p);

#if 0
	    Text_seek = MD_SWAPQ(shdr.s_scnptr);
	    Text_start = MD_SWAPQ(shdr.s_vaddr);
	    Text_size = MD_SWAPQ(shdr.s_size) / 4;
	    /* there is a null routine after the supposed end of text */
	    Text_size += 10;
	    Text_end = Text_start + Text_size * 4;
	    /* create_text_reloc(shdr.s_relptr, shdr.s_nreloc); */
#endif
	    break;

	  case ECOFF_STYP_INIT:
	  case ECOFF_STYP_FINI:
	    if (MD_SWAPQ(shdr.s_size) > 0)
	      {
		p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
		if (!p)
		  fatal("out of virtual memory");

		if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
		  fatal("could not read `.text' from executable", i);
		if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
		  fatal("could not read text section from executable");
		
		/* copy program section into simulator target memory */
		mem_bcopy(mem_access, mem,
			  Write, MD_SWAPQ(shdr.s_vaddr),
			  p, MD_SWAPQ(shdr.s_size));

		/* release the section buffer */
		free(p);
	      }
	    else
	      warn("section `%s' is empty...", shdr.s_name);
	    break;

	  case ECOFF_STYP_LITA:
	  case ECOFF_STYP_LIT8:
	  case ECOFF_STYP_LIT4:
	  case ECOFF_STYP_XDATA:
	  case ECOFF_STYP_PDATA:
	  case ECOFF_STYP_RCONST:
	    /* fall through */

	  case ECOFF_STYP_RDATA:
	    /* The .rdata section is sometimes placed before the text
	     * section instead of being contiguous with the .data section.
	     */
#if 0
	    Rdata_start = MD_SWAPQ(shdr.s_vaddr);
	    Rdata_size = MD_SWAPQ(shdr.s_size);
	    Rdata_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    /* fall through */
	  case ECOFF_STYP_DATA:
#if 0
	    Data_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    /* fall through */
	  case ECOFF_STYP_SDATA:
#if 0
	    Sdata_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    if (MD_SWAPQ(shdr.s_size) > 0)
	      {
		p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
		if (!p)
		  fatal("out of virtual memory");

		if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
		  fatal("could not read `.text' from executable", i);
		if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
		  fatal("could not read text section from executable");

		/* copy program section it into simulator target memory */
		mem_bcopy(mem_access, mem,
			  Write, MD_SWAPQ(shdr.s_vaddr),
			  p, MD_SWAPQ(shdr.s_size));

		/* release the section buffer */
		free(p);
	      }
	    else
	      warn("section `%s' is empty...", shdr.s_name);
	  break;

	  case ECOFF_STYP_BSS:
	  case ECOFF_STYP_SBSS:
	    /* no data to read... */
	    break;

	  default:
	    warn("section `%s' ignored...", shdr.s_name);
	  }
      }

    /* done with the executable, close it */
    if (fclose(fobj))
      fatal("could not close executable `%s'", argv[0]);
  }

#endif /* BFD_LOADER */

  /* perform sanity checks on segment ranges */
  if (!ld_text_base || !ld_text_size)
    fatal("executable is missing a `.text' section");
  if (!ld_data_base || !ld_data_size)
    fatal("executable is missing a `.data' section");
  if (!ld_prog_entry)
    fatal("program entry point not specified");

  /* determine byte/words swapping required to execute on this host */
  sim_swap_bytes = (endian_host_byte_order() != endian_target_byte_order());
  if (sim_swap_bytes)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping bytes to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }
  sim_swap_words = (endian_host_word_order() != endian_target_word_order());
  if (sim_swap_words)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping words to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }

  /* set up a local stack pointer, this is where the argv and envp
     data is written into program memory */
  ld_stack_base = ld_text_base - (409600+4096);
#if 0
  sp = ROUND_DOWN(ld_stack_base - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE));
#endif
  sp = ld_stack_base - MD_MAX_ENVIRON;
  ld_stack_size = ld_stack_base - sp;
    printf("Thread 0 stack size (4)%d\n",  current->ld_stack_size);

  /* initial stack pointer value */
  ld_environ_base = sp;

  /* write [argc] to stack */
  temp = MD_SWAPQ(argc);
  mem_access(mem, Write, sp, &temp, sizeof(qword_t));
  regs->regs_R[MD_REG_A0] = temp;
  sp += sizeof(qword_t);

  /* skip past argv array and NULL */
  argv_addr = sp;
  regs->regs_R[MD_REG_A1] = argv_addr;
  sp = sp + (argc + 1) * sizeof(md_addr_t);

  /* save space for envp array and NULL */
  envp_addr = sp;
  for (i=0; envp[i]; i++)
    sp += sizeof(md_addr_t);
  sp += sizeof(md_addr_t);

  /* fill in the argv pointer array and data */
  for (i=0; i<argc; i++)
    {
      /* write the argv pointer array entry */
      temp = MD_SWAPQ(sp);
      mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, argv[i]);
      sp += strlen(argv[i])+1;
    }
  /* terminate argv array with a NULL */
  mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* write envp pointer array and data to stack */
  for (i = 0; envp[i]; i++)
    {
      /* write the envp pointer array entry */
      temp = MD_SWAPQ(sp);
      mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, envp[i]);
      sp += strlen(envp[i]) + 1;
    }
  /* terminate the envp array with a NULL */
  mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* did we tromp off the stop of the stack? */
  if (sp > ld_stack_base)
    {
      /* we did, indicate to the user that MD_MAX_ENVIRON must be increased,
	 alternatively, you can use a smaller environment, or fewer
	 command line arguments */
      fatal("environment overflow, increase MD_MAX_ENVIRON in alpha.h");
    }

  /* initialize the bottom of heap to top of data segment */
  ld_brk_point = ROUND_UP(ld_data_base + ld_data_size, MD_PAGE_SIZE);

  /* set initial minimum stack pointer value to initial stack value */
  ld_stack_min = regs->regs_R[MD_REG_SP];

  regs->regs_R[MD_REG_SP] = ld_environ_base;
  regs->regs_PC = ld_prog_entry;

  printf("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  printf("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  printf("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  printf("ld_prog_entry: 0x%08x", ld_prog_entry);

  debug("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  debug("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  debug("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  debug("ld_prog_entry: 0x%08x", ld_prog_entry);
}
Пример #6
0
/* disassemble an Alpha instruction */
void
md_print_insn(md_inst_t inst,		/* instruction to disassemble */
	      md_addr_t pc,		/* addr of inst, used for PC-rels */
	      FILE *stream)		/* output stream */
{
  enum md_opcode op;

  /* use stderr as default output stream */
  if (!stream)
    stream = stderr;

  /* decode the instruction, assumes predecoded text segment */
  MD_SET_OPCODE(op, inst);

  /* disassemble the instruction */
  if (op <= OP_NA || op >= OP_MAX)
    {
      /* bogus instruction */
      fprintf(stream, "<invalid inst: 0x%08x>", inst);
    }
  else
    {
      char *s;

      fprintf(stream, "%-10s", MD_OP_NAME(op));

      s = MD_OP_FORMAT(op);
      while (*s) {
	switch (*s) {
	case 'a':
	  fprintf(stream, "r%d", RA);
	  break;
	case 'b':
	  fprintf(stream, "r%d", RB);
	  break;
	case 'c':
	  fprintf(stream, "r%d", RC);
	  break;
	case 'A':
	  fprintf(stream, "f%d", RA);
	  break;
	case 'B':
	  fprintf(stream, "f%d", RB);
	  break;
	case 'C':
	  fprintf(stream, "f%d", RC);
	  break;
	case 'o':
	  fprintf(stream, "%d", (sword_t)SEXT(OFS));
	  break;
	case 'j':
	  myfprintf(stream, "0x%p", pc + (SEXT(OFS) << 2) + 4);
	  break;
	case 'J':
	  myfprintf(stream, "0x%p", pc + (SEXT21(TARG) << 2) + 4);
	  break;
	case 'i':
	  fprintf(stream, "%d", (word_t)IMM);
	  break;
	default:
	  /* anything unrecognized, e.g., '.' is just passed through */
	  fputc(*s, stream);
	}
	s++;
      }
    }
}
Пример #7
0
/* print integer REG(S) to STREAM */
void
md_print_ireg(md_gpr_t regs, int reg, FILE *stream)
{
  myfprintf(stream, "%4s: %16ld/0x%012lx",
	    md_reg_name(rt_gpr, reg), regs[reg], regs[reg]);
}
Пример #8
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  int i;
  md_inst_t inst;
  register md_addr_t addr;
  register int is_write;
  enum md_opcode op;
  unsigned int flags;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      mem_access(mem, Read, regs.regs_PC, &inst, sizeof(md_inst_t));

      if (verbose)
	{
	  myfprintf(stderr, "%10n @ 0x%08p: ", sim_num_insn, regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /*
       * profile this instruction
       */
      flags = MD_OP_FLAGS(op);

      if (prof_ic)
	{
	  enum inst_class_t ic;

	  /* compute instruction class */
	  if (flags & F_LOAD)
	    ic = ic_load;
	  else if (flags & F_STORE)
	    ic = ic_store;
	  else if (flags & F_UNCOND)
	    ic = ic_uncond;
	  else if (flags & F_COND)
	    ic = ic_cond;      
	  else if (flags & F_ICOMP)
	    ic = ic_icomp;
	  else if (flags & F_FCOMP)
	    ic = ic_fcomp;
	  else if (flags & F_TRAP)
	    ic = ic_trap;
	  else
	    panic("instruction has no class");

	  /* update instruction class profile */
	  stat_add_sample(ic_prof, (int)ic);
	}

      if (prof_inst)
	{
	  /* update instruction profile */
	  stat_add_sample(inst_prof, (int)op - /* skip NA */1);
	}

      if (prof_bc)
	{
	  enum branch_class_t bc;

	  /* compute instruction class */
	  if (flags & F_CTRL)
	    {
	      if ((flags & (F_CALL|F_DIRJMP)) == (F_CALL|F_DIRJMP))
		bc = bc_call_dir;
	      else if ((flags & (F_CALL|F_INDIRJMP)) == (F_CALL|F_INDIRJMP))
		bc = bc_call_indir;
	      else if ((flags & (F_UNCOND|F_DIRJMP)) == (F_UNCOND|F_DIRJMP))
		bc = bc_uncond_dir;
	      else if ((flags & (F_UNCOND|F_INDIRJMP))== (F_UNCOND|F_INDIRJMP))
		bc = bc_uncond_indir;
	      else if ((flags & (F_COND|F_DIRJMP)) == (F_COND|F_DIRJMP))
		bc = bc_cond_dir;
	      else if ((flags & (F_COND|F_INDIRJMP)) == (F_COND|F_INDIRJMP))
		bc = bc_cond_indir;
	      else
		panic("branch has no class");

	      /* update instruction class profile */
	      stat_add_sample(bc_prof, (int)bc);
	    }
	}

      if (prof_am)
	{
	  enum md_amode_type am;

	  /* update addressing mode pre-probe FSM */
	  MD_AMODE_PREPROBE(op, fsm);

	  /* compute addressing mode */
	  if (flags & F_MEM)
	    {
	      /* compute addressing mode */
	      MD_AMODE_PROBE(am, op, fsm);

	      /* update the addressing mode profile */
	      stat_add_sample(am_prof, (int)am);

	      /* addressing mode pre-probe FSM, after all loads and stores */
	      MD_AMODE_POSTPROBE(fsm);
	    }
	}

      if (prof_seg)
	{
	  if (flags & F_MEM)
	    {
	      /* update instruction profile */
	      stat_add_sample(seg_prof, (int)bind_to_seg(addr));
	    }
	}

      if (prof_tsyms)
	{
	  int tindex;

	  /* attempt to bind inst address to a text segment symbol */
	  sym_bind_addr(regs.regs_PC, &tindex, /* !exact */FALSE, sdb_text);

	  if (tindex >= 0)
	    {
	      if (tindex > sym_ntextsyms)
		panic("bogus text symbol index");

	      stat_add_sample(tsym_prof, tindex);
	    }
	  /* else, could not bind to a symbol */
	}

      if (prof_dsyms)
	{
	  int dindex;

	  if (flags & F_MEM)
	    {
	      /* attempt to bind inst address to a text segment symbol */
	      sym_bind_addr(addr, &dindex, /* !exact */FALSE, sdb_data);

	      if (dindex >= 0)
		{
		  if (dindex > sym_ndatasyms)
		    panic("bogus data symbol index");

		  stat_add_sample(dsym_prof, dindex);
		}
	      /* else, could not bind to a symbol */
	    }
	}

      if (prof_taddr)
	{
	  /* add regs_PC exec event to text address profile */
	  stat_add_sample(taddr_prof, regs.regs_PC);
	}

      /* update any stats tracked by PC */
      for (i=0; i<pcstat_nelt; i++)
	{
	  counter_t newval;
	  int delta;

	  /* check if any tracked stats changed */
	  newval = STATVAL(pcstat_stats[i]);
	  delta = newval - pcstat_lastvals[i];
	  if (delta != 0)
	    {
	      stat_add_samples(pcstat_sdists[i], regs.regs_PC, delta);
	      pcstat_lastvals[i] = newval;
	    }

	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Пример #9
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register bool_t is_write;
  enum md_fault_type fault;

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  /* fast forward simulator loop, performs functional simulation for
     FASTFWD_COUNT insts, then turns on performance (timing) simulation */
  if (fastfwd_count > 0)
    {
      int icount;

      fprintf(stderr, "sim: ** fast forwarding %d insts **\n", fastfwd_count);

      fastfwding = TRUE;
      for (icount=0; icount < fastfwd_count; icount++)
	{
	  /* maintain $r0 semantics */
	  regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
	  regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

	  /* get the next instruction to execute */
	  MD_FETCH_INST(inst, mem, regs.regs_PC);

	  /* set default reference address */
	  addr = 0; is_write = FALSE;

	  /* set default fault - none */
	  fault = md_fault_none;

	  /* decode the instruction */
	  MD_SET_OPCODE(op, inst);

	  /* execute the instruction */
	  switch (op)
	    {
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	    case OP:							\
	      SYMCAT(OP,_IMPL);						\
	      break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
	    case OP:							\
	      panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#undef DECLARE_FAULT
#define DECLARE_FAULT(FAULT)						\
	      { fault = (FAULT); break; }
#include "machine.def"
	    default:
	      panic("attempted to execute a bogus opcode");
	    }

	  if (fault != md_fault_none)
	    fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

	  /* update memory access stats */
	  if (MD_OP_FLAGS(op) & F_MEM)
	    {
	      if (MD_OP_FLAGS(op) & F_STORE)
		is_write = TRUE;
	    }

	  /* check for DLite debugger entry condition */
	  if (dlite_check_break(regs.regs_NPC,
				is_write ? ACCESS_WRITE : ACCESS_READ,
				addr, sim_num_insn, sim_num_insn))
	    dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

	  /* go to the next instruction */
	  regs.regs_PC = regs.regs_NPC;
	  regs.regs_NPC += sizeof(md_inst_t);
	}
    }
  fastfwding = FALSE;

  if (trace_fd != NULL)
    {
      fprintf(stderr, "sim: writing EIO file initial checkpoint...\n");
      if (eio_write_chkpt(&regs, mem, trace_fd) != -1)
	panic("checkpoint code is broken");
    }

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* check if checkpoint should be generated here... */
      if (chkpt_kind == one_shot_chkpt
	  && !range_cmp_range1(&chkpt_range, regs.regs_NPC,
			       sim_num_insn, sim_num_insn))
	{
	  myfprintf(stderr, "sim: writing checkpoint file `%s' @ inst %n...\n",
		  chkpt_fname, sim_num_insn);

	  /* write the checkpoint file */
	  eio_write_chkpt(&regs, mem, chkpt_fd);

	  /* close the checkpoint file */
	  eio_close(chkpt_fd);

	  /* exit jumps to the target set in main() */
	  longjmp(sim_exit_buf, /* exitcode + fudge */0+1);
	}
      else if (chkpt_kind == periodic_chkpt
	       && sim_num_insn == next_chkpt_cycle)
	{
	  char this_chkpt_fname[256];

	  /* 'chkpt_fname' should be a printf format string */
	  sprintf(this_chkpt_fname, chkpt_fname, chkpt_num);
	  chkpt_fd = eio_create(this_chkpt_fname);

	  myfprintf(stderr, "sim: writing checkpoint file `%s' @ inst %n...\n",
		  this_chkpt_fname, sim_num_insn);

	  /* write the checkpoint file */
	  eio_write_chkpt(&regs, mem, chkpt_fd);

	  /* close the checkpoint file */
	  eio_close(chkpt_fd);

	  chkpt_num++;
	  next_chkpt_cycle += per_chkpt_interval;
	}

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Пример #10
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr, target_PC;
  enum md_opcode op;
  register int is_write;
  int stack_idx;
  enum md_fault_type fault;

  int out1, out2, in1, in2, in3;	  /* register names */
  int v_out1, v_out2, v_in1, v_in2, v_in3;/* register values */
  int vl_out1, vl_out2, vl_in1, vl_in2, vl_in3;
  md_addr_t addr_dispatch;              /* access_address */
  int m_size;                           /* access_size */
  FILE *stream;
  md_addr_t predicted_PC;

  fprintf(stderr, "sim: ** starting functional simulation w/ predictors **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      mem_access(mem, Read, regs.regs_PC, &inst, sizeof(md_inst_t));

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,CLASS,O1,O2,I1,I2,I3,            \
                VO1,LO1,VO2,LO2,ADDR,VI1,LI1,VI2,LI2,VI3,LI3,M_Size)    \
	case OP:							\
	  in1 = I1; in2 = I2; in3 = I3;					\
	  v_in1 = VI1; v_in2 = VI2; v_in3 = VI3;			\
	  vl_in1 = LI1; vl_in2 = LI2; vl_in3 = LI3;			\
          SYMCAT(OP,_IMPL);						\
	  out1 = O1; out2 = O2;						\
	  v_out1 = VO1; v_out2 = VO2;					\
	  vl_out1 = LO1; vl_out2 = LO2;					\
	  addr_dispatch = ADDR;						\
	  m_size = M_Size;						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "operand.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      if (MD_OP_FLAGS(op) & F_CTRL)
	{
	  md_addr_t pred_PC;
	  struct bpred_update_t update_rec;

	  sim_num_branches++;

	  if (pred)
	    {
	      /* get the next predicted fetch address */
	      pred_PC = bpred_lookup(pred,
				     /* branch addr */regs.regs_PC,
				     /* target */target_PC,
				     /* inst opcode */op,
				     /* call? */MD_IS_CALL(op),
				     /* return? */MD_IS_RETURN(op),
				     /* stash an update ptr */&update_rec,
				     /* stash return stack ptr */&stack_idx);

	      /* valid address returned from branch predictor? */
	      if (!pred_PC)
		{
		  /* no predicted taken target, attempt not taken target */
		  pred_PC = regs.regs_PC + sizeof(md_inst_t);
		}

	      bpred_update(pred,
			   /* branch addr */regs.regs_PC,
			   /* resolved branch target */regs.regs_NPC,
			   /* taken? */regs.regs_NPC != (regs.regs_PC +
							 sizeof(md_inst_t)),
			   /* pred taken? */pred_PC != (regs.regs_PC +
							sizeof(md_inst_t)),
			   /* correct pred? */pred_PC == regs.regs_NPC,
			   /* opcode */op,
			   /* predictor update pointer */&update_rec);
	    }
	  predicted_PC = pred_PC;
	}

      /*   ここから下を見ればどの変数に何が入っているか分かるはず。 */
      stream = stdout;
      fprintf(stream, "############################################################ \n");
      fprintf(stream, " --- trace count(%d) \n", (int)sim_num_insn);
      fprintf(sim_fd, "%s, inst: `",
      fprintf(stream, "       opcode: %s, inst: `",
	      MD_OP_NAME(op));
      md_print_insn(inst, regs.regs_PC, stream);
      fprintf(stream, "'\n");
      myfprintf(stream, "         PC: 0x%08p, NPC: 0x%08p",
		regs.regs_PC, regs.regs_NPC);
      if(pred)
	myfprintf(stream, " (pred_PC: 0x%08p)\n",
		  regs.regs_PC, regs.regs_NPC, predicted_PC);
      else
	myfprintf(stream, "\n");
      fprintf(stream," |  in(r%02d,r%02d,r%02d),out(r%02d,r%02d),\n",
	      in1, in2, in3, out1, out2);
      fprintf(stream," |  IN(%8x,%8x,%8x),OUT(%8x,%8x)addr(%8x)|\n",
	      v_in1, v_in2, v_in3, v_out1, v_out2, addr_dispatch);
      /* ダブルワードだった場合,この変数がセットされる */
      fprintf(stream," |  in(%8x,%8x,%8x),out(%8x,%8x)         |\n",
	      vl_in1, vl_in2, vl_in3, vl_out1, vl_out2);

      /* machine.h をみるとopから命令の種類を判別する方法が分かる。以下は例 */
      if (op == MD_NOP_OP)
	{
	  fprintf(stream, "   NOP instruction \n");
	}
      else if (MD_OP_FLAGS(op) & F_MEM)
	{
	  fprintf(stream, "   MEMORY instruction \n");
	  if (MD_OP_FLAGS(op) & F_STORE)
	    fprintf(stream, "        store instruction \n");
	  else if (MD_OP_FLAGS(op) & F_LOAD)
	    fprintf(stream, "        load instruction \n");
	  fprintf(stream, "          ld/st address is %010x\n",
		  addr_dispatch);
	  fprintf(stream, "          ld/st size is %2d\n",
		  m_size);
	  /* ロードストアがバイト単位なのか,ワード単位なのか,
	     ハーフワード単位なのかは,opを見て判断できる。
	     例えば, md_op2name[op] が "sh"ならハーフワードである。
	     しかし、これだと面倒なのでoperand.defを改良した方が良い
	     かも知れない。これはおまかせ。
	     */
	  
	  /* ロードストアの詳細に関しては,machine.def を参照。
	     例えば,store halfの場合,(machine.def をエディタで開いて
	     "sh"と言う文字列をサーチすれば該当箇所が見つかる)
	     以下のようにかかれている。*/
	  /*
                #define SH_IMPL                                     
                  {                                                 
                    half_t _src;                                    
                    enum md_fault_type _fault;                      
                    _src = (half_t)(word_t)GPR(RT);                 
                    WRITE_HALF(_src, GPR(BS) + OFS, _fault);        
                    if (_fault != md_fault_none)                    
                      DECLARE_FAULT(_fault);                        
                   }
		   */
	  /*ここで、GPR(BS)はBS番レジスタの値 OFS はオフセットを示す。
	    そして,GPR(RT)はRT番レジスタの値を示す。
	    そしてWRITE_HALF(_src, GPR(BS) + OFS, _fault);は
	    値 _src をアドレス GPR(BS) + OFS に書き込む事を意味する。
	    書き込みのサイズは,halfワードである。*/
	}
      else if (MD_OP_FLAGS(op) & F_CTRL)
	{
	  fprintf(stream, "   BRANCH instruction \n");
	  if (MD_IS_CALL(op))
	    fprintf(stream, "        function call \n");
	  else if (MD_IS_RETURN(op))
	    fprintf(stream, "        function return \n");
	  else if (MD_IS_INDIR(op))
	    fprintf(stream, "        indirect jump \n");
	  else if ((MD_OP_FLAGS(op) & (F_CTRL|F_DIRJMP)) == (F_CTRL|F_DIRJMP))
	    fprintf(stream, "        direct jump \n");
	}
      else
	{
	  fprintf(stream, "   other instruction \n");
	}
      /* この応用として,いきなりopからstoreを判別するには,以下のようにすれば良い*/
      if ((MD_OP_FLAGS(op) & (F_MEM|F_STORE)) == (F_MEM|F_STORE))
	{
	  /*fprintf(stream, "   store instruction \n");*/
	}
      else if ((MD_OP_FLAGS(op) & (F_MEM|F_LOAD)) == (F_MEM|F_LOAD))
	{
	  /*fprintf(stream, "   load instruction \n");*/
	}

      /* ここまで */


      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Пример #11
0
/* start simulation, program loaded, processor precise state initialized */
bool_t
sim_sample(unsigned int n_insn)
{
  md_inst_t inst;
  enum md_fault_t fault;
  struct predec_insn_t *pdi;
  counter_t sim_num_insn_begin = sim_num_insn;
  bool_t fdumpinsn;

  while (n_insn == 0 || sim_num_insn < sim_num_insn_begin + n_insn)
    {
      /* maintain $r0 semantics */
      regs.regs[MD_REG_ZERO].q = 0;
      regs.regs[MD_FREG_ZERO].d = 0.0;

      /* get the next instruction to execute */
      if (itlb)
	cache_access(itlb, mc_READ, regs.PC, sizeof(md_inst_t), 0, NULL, tlb_miss_handler);
      if (cache_il1)
	cache_access(cache_il1, mc_READ, regs.PC, sizeof(md_inst_t), 0, NULL, l1_miss_handler);

      mem_access(mem, mc_READ, regs.PC, &inst, sizeof(md_inst_t));

      /* set default reference address and access mode */
      regs.addr = 0; regs.dsize = 0;

      /* set default fault - none */
      fault = md_fault_none;

      /* get the next instruction to execute */
      pdi = predec_lookup(regs.PC);
      if (!pdi)
	{
	  mem_access(mem, mc_READ, regs.PC, &inst, sizeof(md_inst_t));
	  pdi = predec_enter(regs.PC, inst);
	}

      /* keep an instruction count */
      if (pdi->iclass != ic_nop)
	{
	  sim_num_insn++;
	  sim_sample_insn++;
	  sim_sample_insn_split[pdi->iclass]++;
	}

      fdumpinsn = fdump && sim_num_insn >= insn_dumpbegin && sim_num_insn < insn_dumpend; 
      inst = pdi->inst;
      
      /* execute the instruction */
      switch (pdi->poi.op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
          panic("attempted to execute a bogus opcode");
	}

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.PC);

      if (pdi->iclass == ic_load || pdi->iclass == ic_store || pdi->iclass == ic_prefetch)
	{
	  enum mem_cmd_t dl1_cmd = pdi->iclass == ic_store ? mc_WRITE : (pdi->iclass == ic_load ? mc_READ : mc_PREFETCH);
	  enum mem_cmd_t dtlb_cmd = (pdi->iclass == ic_store || pdi->iclass == ic_load) ? mc_READ : mc_PREFETCH;
	  bool_t miss_info[ct_NUM] = {FALSE, FALSE, FALSE, FALSE};

	  if (cache_dl1)
	    cache_access(cache_dl1, dl1_cmd, regs.addr, regs.dsize, 0, miss_info, l1_miss_handler);

	  if (dtlb)
	    cache_access(dtlb, dtlb_cmd, regs.addr, regs.dsize, 0, NULL, tlb_miss_handler);
	}


      /* go to the next instruction */
      regs.PC = regs.NPC;
      regs.NPC += sizeof(md_inst_t);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.PC);
	  md_print_insn(inst, regs.PC, stderr);
	  if (MD_OP_HASFLAGS(pdi->poi.op, F_MEM))
	    myfprintf(stderr, "  mem: 0x%08p", regs.addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}
	  
      if (fdumpinsn)
	{
	  fprintf(fdump, "%-9u: 0x%08x ", (word_t)sim_num_insn, (word_t)regs.PC);
	  if (LREG_ISDEP(pdi->lregnums[DEP_O1]))
	    myfprintf(fdump, " O1: %016p", regs_value(pdi->lregnums[DEP_O1]));
	  fprintf(fdump, "\n");
	}

      if (fdump && sim_num_insn == insn_dumpend)
	{
	  fflush(fdump);
	  fclose(fdump);
	}

      /* finish early? */
      if (insn_limit && sim_sample_insn >= insn_limit)
	{
	  myfprintf(stderr, "Reached instruction limit: %u\n", insn_limit);
	  return FALSE;
	}
      
      if (insn_progress && sim_sample_insn >= insn_progress)
	{
	  sim_print_stats(stderr);
	  fflush(stderr);
	  while (sim_sample_insn >= insn_progress)
	    insn_progress += insn_progress_update;
	}
    }

  return (sim_num_insn - sim_num_insn_begin == n_insn); 
}
Пример #12
0
int lsPlaylists(FILE * fp, char * utf8path) {
	DIR * dir;
	struct stat st;
	struct dirent * ent;
	char * dup;
	char * utf8;
	char s[MAXPATHLEN+1];
	List * list = NULL;
	ListNode * node = NULL;
	char * path = strdup(utf8ToFsCharset(utf8path));
	char * actualPath = rpp2app(path);
	int actlen = strlen(actualPath)+1;
	int maxlen = MAXPATHLEN-actlen;
	int suflen = strlen(PLAYLIST_FILE_SUFFIX)+1;
	int suff;

	if(actlen>MAXPATHLEN-1 || (dir = opendir(actualPath))==NULL) {
		free(path);
		return 0;
	}

	s[MAXPATHLEN] = '\0';
	/* this is safe, notice actlen > MAXPATHLEN-1 above */
	strcpy(s,actualPath);
	strcat(s,"/");

	while((ent = readdir(dir))) {
		dup = ent->d_name;
		if(dup[0]!='.' && 
				(suff=strlen(dup)-suflen)>0 && 
				dup[suff]=='.' &&
				strcmp(dup+suff+1,PLAYLIST_FILE_SUFFIX)==0) 
		{
			strncpy(s+actlen,ent->d_name,maxlen);
			if(stat(s,&st)==0) {
				if(S_ISREG(st.st_mode)) {
					if(list==NULL) list = makeList(NULL, 1);
					dup = strdup(ent->d_name);
					dup[suff] = '\0';
					if((utf8 = fsCharsetToUtf8(dup))) {
						insertInList(list,utf8,NULL);
					}
					free(dup);
				}
			}
		}
	}
	
	closedir(dir);
	free(path);

	if(list) {
		int i;
		sortList(list);

		dup = malloc(strlen(utf8path)+2);
		strcpy(dup,utf8path);
		for(i = strlen(dup)-1; i >= 0 && dup[i]=='/'; i--) {
			dup[i] = '\0';
		}
		if(strlen(dup)) strcat(dup,"/");

		node = list->firstNode;
		while(node!=NULL) {
                        if(!strchr(node->key, '\n')) {
			        myfprintf(fp,"playlist: %s%s\n",dup,node->key);
                        }
			node = node->nextNode;
		}

		freeList(list);
		free(dup);
	}

	return 0;
}
Пример #13
0
int
main (int argc, char **argv ) 
{
  UINT4 line=0, i;
UINT8  id=0;
  UINT4 start = 0;
  ResultIn trigger;
  REAL4 tau0, tau3, tau0I, tau3I, psi0, psi3, phaseI, coaTime;
  FILE *input1, *input2, *bank;
  FILE *output;      
  SnglInspiralTable     *inputData = NULL;
  INT4 numFileTriggers = 0;

  MetadataTable         templateBank;




  char sbuf[512];
  
  if (argc>1) {
    if (strcmp(argv[1], "--help")==0) {
      BEAscii2XmlHelp();
    }  
    if (strcmp(argv[1], "-h")==0) { 
      BEAscii2XmlHelp();
    }  
  }
  /* Main program starts here */
  /* First we open the file containing the ascii results */
  fprintf(stderr,"opening the xml output data file -- %s", BEASCII2XML_OUTPUT);
  output = fopen(BEASCII2XML_OUTPUT,"w");
  fprintf(stderr,"done\n");

  fprintf(stderr,"opening the xml input data file -- %s", BEASCII2XML_INPUT1);
  if  ( (input1  = fopen(BEASCII2XML_INPUT1,"r"))==NULL) {
    fprintf(stderr,"error while opening input file %s\n",BEASCII2XML_INPUT1);
    exit(0);
  }
  fprintf(stderr,"done\n");

  fprintf(stderr,"opening the xml prototype (argument of BankEfficiency code) -- ");
  if  ( (input2  = fopen(BEASCII2XML_INPUT2,"r"))==NULL)
    {
      fprintf(stderr,"error while opening input file %s\n",BEASCII2XML_INPUT2);
      fprintf(stderr,"the xml file will not contains parameters information\n");
      PRINT_LIGOLW_XML_HEADER(output);
      fprintf(stderr,"creating the header file -- done\n");
    }
  else 
    {
      /* read prototype and save in outputfile */
      fprintf(stderr,"parsing the prototype  -- ");
      while(fgets(sbuf,1024,input2) !=NULL)
	fputs(sbuf, output);
      fprintf(stderr," done\n");

      
    }
  

  /* insert the template bank here */
  if  ( (bank  = fopen(BEASCII2XML_BANK,"r"))==NULL)
    {
      fprintf(stderr,"error while opening input file %s\n",BEASCII2XML_BANK);
      fprintf(stderr,"the xml file will not contains the bank table\n");
    }
  else 
    {
      /* read prototype and save in outputfile */
      fprintf(stderr,"parsing the bank  -- ");
      fprintf( stdout, "reading triggers from file: %s\n", BEASCII2XML_BANK );
      numFileTriggers = 
        LALSnglInspiralTableFromLIGOLw( &inputData,BEASCII2XML_BANK , 0, -1 );
      fprintf(stderr," done %d\n", numFileTriggers);      
       myfprintf(output, LIGOLW_XML_SNGL_INSPIRAL );
       while(inputData)
	{
	  /*	  id = inputData->event_id->id;*/
	  
	  fprintf(output, SNGL_INSPIRAL_ROW, 
		  inputData->ifo,
		  inputData->search,
		  inputData->channel,
		  inputData->end_time.gpsSeconds,
		  inputData->end_time.gpsNanoSeconds,
		  inputData->end_time_gmst,
		  inputData->impulse_time.gpsSeconds,
		  inputData->impulse_time.gpsNanoSeconds,
		  inputData->template_duration,
		  inputData->event_duration,
		  inputData->amplitude,
		  inputData->eff_distance,
		  inputData->coa_phase,
		  inputData->mass1,
		  inputData->mass2,
		  inputData->mchirp,
		  inputData->mtotal,
		  inputData->eta,
		  inputData->tau0,
		  inputData->tau2,
		  inputData->tau3,
		  inputData->tau4,
		  inputData->tau5,
		  inputData->ttotal,
		  inputData->psi0,
		  inputData->psi3,
		  inputData->alpha,
		  inputData->alpha1,
		  inputData->alpha2,
		  inputData->alpha3,
		  inputData->alpha4,
		  inputData->alpha5,
		  inputData->alpha6,
		  inputData->beta,
		  inputData->f_final,
		  inputData->snr,
		  inputData->chisq,
		  inputData->chisq_dof,
		  inputData->sigmasq,
		  id);
	  inputData = inputData->next;
	  fprintf(output, "\n");

	}
       myfprintf(output, LIGOLW_XML_TABLE_FOOTER );

    }



  PRINT_LIGOLW_XML_BANKEFFICIENCY(output);
  fprintf(stderr,"done\n");
  /* read ascii input and save in xml format */
  fprintf(stderr,"reading the ascii file -- and saving xml file");
  do  
    {
      fscanf(input1,BANKEFFICIENCY_PARAMS_ROW_SPACE,
	     &trigger.psi0_triggerU,
	     &trigger.psi3_triggerU,
	     &trigger.psi0_trigger,
	     &trigger.psi3_trigger,
	     &psi0, 
	     &psi3,
	     &tau0, 
	     &tau3, 
	     &tau0I, 
	     &tau3I,
	     &trigger.fend_triggerU, 
	     &trigger.fend_trigger, 
	     &trigger.fend_inject,
	     &trigger.mass1_inject,
	     &trigger.mass2_inject,
	     &trigger.rho_finalU,
	     &trigger.phaseU,
	     &phaseI,
	     &trigger.alphaFU, 
	     &trigger.layerU,
	     &trigger.binU,
	     &trigger.rho_final,
	     &trigger.snrAtCoaTime, 
	     &phaseI,
	     &trigger.phase,
	     &trigger.alphaF, 
	     &trigger.layer,
	     &trigger.bin, 
	     &coaTime);

     if (start==0){
	      start+=1;
      }
      else 
      {
	      fprintf(output,",\n");
      }
      fprintf(output, BANKEFFICIENCY_PARAMS_ROW,
	      trigger.psi0_triggerU,
	      trigger.psi3_triggerU,
	      trigger.psi0_trigger,
	      trigger.psi3_trigger,
	      psi0, 
	      psi3,
	      tau0,
	      tau3,
	      tau0I,
	      tau3I,
	      trigger.fend_triggerU, 
	      trigger.fend_trigger, 
	      trigger.fend_inject,
	      trigger.mass1_inject,
	      trigger.mass2_inject,
	      trigger.rho_finalU,
	      phaseI,
	      trigger.phaseU,
	      trigger.alphaFU, 
	      trigger.layerU,
	      trigger.binU,
	      trigger.rho_final,
	      trigger.snrAtCoaTime,
	      phaseI,
	      trigger.phase,
	      trigger.alphaF, 
	      trigger.layer,
	      trigger.bin, 
	      coaTime);
         line++;
    }
   while(!feof(input1));

    fprintf(stderr,"read %d lines...done\n", line);
  PRINT_LIGOLW_XML_TABLE_FOOTER(output);
  PRINT_LIGOLW_XML_FOOTER(output);

  fclose(output);
    fprintf(stderr,"closing xml file\n");

  return 0;
}
Пример #14
0
int printDirectoryInDirectory(FILE * fp, Directory * directory, void * data) {
        if(directory->path) {
		myfprintf(fp,"directory: %s\n", getDirectoryPath(directory));
	}
        return 0;
}
Пример #15
0
Файл: glue.c Проект: aosm/dyld
// called by libuwind code before aborting
size_t fwrite(const void* ptr, size_t size, size_t nitme, FILE* stream)
{
	return myfprintf(stream, "%s", (char*)ptr); 
}
Пример #16
0
int mnewt(int ntrial, FTYPE x[], int n, FTYPE tolx, FTYPE tolf)
{
  int i = 0, j = 0, k = 0;
  FTYPE errx=1E30, errf=1E30, d;
  FTYPE lasterrx,lasterrf;
  FTYPE dampfactor,dampfactorchange;
  static int firstc = 1;
  static int *indx;
  static FTYPE **fjac, *fvec, *pp,*xold;
  // debug stuff
  static long count = 0;
  static long lastnstep = 0;
  static long calls = 0;
  // debug stuff
  static FTYPE *startx,*startfvec;
  int usrfunreturn;
  struct of_geom geom;
  int lowtol[2]={0,0}; // 0=errx, 1=errf
  FTYPE X[NDIM],r,th;
#if(DEBUG==2)
  FTYPE trialvalue[MAXTRIAL][NPR];
  FTYPE trialerr[MAXTRIAL][2];
  FILE  * out;
#endif
  int truetrialnum=0;
  int donesincechange;
  static int DODAMP;
  FTYPE abstol=(NUMEPSILON*50.0); // near machine precision
  int allownewdamp,numstabletot,countstable,numdampedtot,countdamped;
  int dampdeath;
  long int mnewtstepfail;
  int mnewtifail,mnewtjfail,mnewtpartialstepfail;
  FTYPE tolfallowed,tolxallowed,tolfreport,tolxreport;
  FTYPE normf;
#if(DEBUG)
  calls++;
#endif

  tolfallowed=tolxallowed=1E-4;
  tolfreport=tolxreport=tolf*1.E3;

  // for debug purposes
  mnewtstepfail=9198;
  mnewtifail=0;
  mnewtjfail=63;
  mnewtpartialstepfail=0;

  // settings
  DODAMP=2;
  dampfactor=1.0;
  dampfactorchange=0.5;
  donesincechange=0;
  dampdeath=0;
  // for DODAMP==2
  allownewdamp=0; // start fresh
  numstabletot=5;
  numdampedtot=5;
  countstable=0;
  countdamped=0;

#if(DEBUGPOINT)
  if((myid==2)&&(icurr+startpos[1]==mnewtifail)&&(jcurr+startpos[2]==mnewtjfail)&&(realnstep==mnewtstepfail)&&(partialstep==mnewtpartialstepfail)){
    
    DODAMP=2;
    
    // testing, works well, turn on the if just inside the ntrial loop
    //        DODAMP=1;
  }
#endif

  if (firstc) {
    firstc = 0;

    indx = ivector(1, n);
    pp = dvector(1, n);
    xold = dvector(1, n);
    startx = dvector(1, n);
    startfvec = dvector(1, n);
    fvec = dvector(1, n);
    fjac = dmatrix(1, n, 1, n);
  }


  // save guess for debugging
#if(DEBUG)
  for (i = 1; i <= n; i++){
    startx[i]=x[i];
#if(DEBUG==2)
    trialvalue[truetrialnum][i-1]=x[i];
#endif
  }
#endif
  
  // initially
  for (i = 1; i <= n; i++) xold[i]=x[i];

  for (k = 1; k <= ntrial; k++) {
    truetrialnum++;
    nstroke++;

    // determine error in f, conserved quantities
    usrfunreturn=usrfun(x, n, fvec, fjac,&normf);
#if(DEBUG)
    for(i=1;i<=n;i++){ startfvec[i]=fvec[i]; }
#endif

    if (usrfunreturn>=1){
            
      // fix up the damping if we get a psychotic solution
      errf=1.E30;
      errx=1.E30;
      failed=0; // force no failure condition
    }
    else{ // estimate error normally
      errf = 0.0;
      for (i = 1; i <= n; i++)	errf += fabs(fvec[i]);
      errf/=normf; // renormalize since truly U (conserved quantity) has no better significance than this error

      if (errf <= abstol) lowtol[1]=2;
      else if (errf <= tolf) lowtol[1]=1;
      else lowtol[1]=0;
    }

    // now fix x (primitive variables)

    if(((DODAMP==1)||(DODAMP==2)&&(allownewdamp))&&(k>1)&&(lasterrf<errf)){ // only consider if damped failed when using damping odd/even trial
      // if we are here, the error actually increased
      // if increased, lower damp factor and back up
      countdamped++; // coming here counts as a general damped run
      if(countdamped>=numdampedtot){ allownewdamp=0; countdamped=0; countstable=0;}
      donesincechange=0;
      dampfactor*=dampfactorchange;

      dampdeath=0;
      // how hard do we want to make the code try for the highest precision (damping)?
      if((dampfactor<1E-5)&&(errf<tolf*100.0)){
	// then we'll assume this is good enough and any smaller dampfactor won't get us much less error
	dampdeath=1;
      }
      else if(dampfactor<1E-7){
	if(debugfail>=1){
	  dualfprintf(fail_file,"mnewt: ok, we really need something better\n: dampfactor: %g errf: %g\n",dampfactor,errf);	
	}
	dampdeath=1; // let the bottom non-convergence criterea handle things
      }
      if(dampdeath==0){
	for (i = 1; i <= n; i++)	x[i]=xold[i];
	k--; // want absolute number of trials to be fixed
      }
    }
    else{
      // then error is decreasing or first trial, good!  So let's continue changing x
      //if(donesincechange==5) dampfactor/=dampfactorchange;
      donesincechange++;
      if(allownewdamp==0) countstable++;
      if(allownewdamp) countdamped++; // coming here counts as a general damped run
      //else       countstable++; // then counts as stable run

      if(countstable>=numstabletot){ allownewdamp=1; countdamped=0; countstable=0;}
      if(countdamped>=numdampedtot){ allownewdamp=0; countdamped=0; countstable=0;}
      lasterrf=errf;
      // save old x to go back to it
      for (i = 1; i <= n; i++) xold[i]=x[i]; 
      
      for (i = 1; i <= n; i++)	pp[i] = -fvec[i];
      ludcmp(fjac, n, indx, &d);
      lubksb(fjac, n, indx, pp);
      // DAMP (faster to damp every other one)
      // 
      if(DODAMP) for (i = 1; i <= n; i++)	pp[i] = dampfactor*pp[i];

      ///////
      // evaluate x error (already properly normalized since directly what we seek)
      ///////
      errx = 0.0;
      for (i = 1; i <= n; i++) {
	errx += fabs(pp[i]);
	x[i] += pp[i];
      }

      if (errx <= abstol) lowtol[0]=2;
      else if (errx <= tolx) lowtol[0]=1;
      else lowtol[0]=0;

    }// else if error decreased
#if(DEBUGPOINT)
    //if((myid==2)&&(icurr+startpos[1]==mnewtifail)&&(jcurr+startpos[2]==mnewtjfail)&&(realnstep==mnewtstepfail)&&(partialstep==mnewtpartialstepfail)){
      //	if (errf <=1E-20){
      //for (i = 1; i <= n; i++) dualfprintf(fail_file,"wtf: true=%d k=%d errx=%21.15g pp[%d]=%25.17g\n",truetrialnum, k, errx,i,pp[i]);
      //	}
    //}

#endif
#if(DEBUG==2)
    // some debug stuff, done every trial type
    for (i = 1; i <= n; i++) {
      trialvalue[truetrialnum][i-1]=x[i];
    }
    if(truetrialnum>MAXTRIAL){ dualfprintf(fail_file,"oops! %d %d\n",truetrialnum,MAXTRIAL); fflush(fail_file); myexit(1);}
    trialerr[truetrialnum-1][0]=errf;
    trialerr[truetrialnum-1][1]=errx;
#endif

    if(dampdeath) break; // problem with damping, too strong, etc.
    // tolerance conditions
    if((lowtol[0]==2)||(lowtol[1]==2)) break; // end immediately since we are unable to go further anyways below machine precision
    else if((lowtol[0]==1)&&(lowtol[1]==1)) break; // then exactly what we wanted      
    // if 0 0 or 1 0 or 0 1, then continue to try to find better solution

  }// over trials


  ///////////////////////////////
  //
  // done with MNEWT, now debug stuff comes
  //
  ///////////////////////////////

  // see what's going on
#if(DEBUGPOINT)
  if((myid==2)&&(icurr+startpos[1]==mnewtifail)&&(jcurr+startpos[2]==mnewtjfail)&&(realnstep==mnewtstepfail)&&(partialstep==mnewtpartialstepfail)){
    dualfprintf(fail_file,"trueerrx=%25.17g trueerrf=%25.17g\n",errx,errf);
    errf=1E30; errx=1E30; lowtol[1]=0; lowtol[0]=0; // pretend    
  }
#endif
  // some counting on this run of mnewt, failed or not
#if(DEBUG)
  if (lastnstep < nstep) {
    fprintf(log_file,"#1 count/zone: %g calls: %g\n",
	    ((FTYPE) count) / ((FTYPE) (N1 * N2)),
	    ((FTYPE)calls) / ((FTYPE)(N1 * N2))); fflush(log_file);
    fprintf(log_file,"count: %ld zones: %d calls: %d\n",
	    count,N1 * N2,calls); fflush(log_file);
    mpildsum0(&count,0);
    mpildsum0(&calls,0);
    /*
      myfprintf(stderr,"count: %ld zones: %d calls: %d\n",
      count,totalzones,calls); fflush(log_file);
    */
    myfprintf(logfull_file,"#1 count/zone: %g calls: %g\n",
	      ((FTYPE) count) / ((FTYPE) (totalzones)),((FTYPE)
							calls) / ((FTYPE)(totalzones)));
    myfprintf(stderr,"#1 count/zone: %g calls: %g\n",
	      ((FTYPE) count) / ((FTYPE) (totalzones)),((FTYPE)
							calls) / ((FTYPE)(totalzones)));
    count = (long)(k - 1);
    lastnstep = nstep;
    calls = 0;
  } else {
    count += (long)(k - 1);
  }
#endif


  // determine if can leave or not
  if((lowtol[0]>=1)&&(lowtol[1]>=1)) return(0);
  // otherwise we didn't reach tolerances we wanted note that both
  // tolerances are asked for, not just one or the other, since one
  // variable may have low error but the other high error, and that's
  // not what we want.  We want both to be low.



  ////////////////////////////////////
  //
  // rest of this is error analysis (i.e. failure, or acceptable failure)
  //
  //


  // if we got here, we never converged to desired tolerance in the specified maximum number of trials

  // only report if pseudo-bad convergence i.e. not near limits since that produces too much data
  if ((errf >= tolfreport)||(errx >= tolxreport)) {
    if(debugfail>=2){
      dualfprintf(fail_file,"proc: %d, t=%25.17g realnstep=%ld\nmnewt didn't converge (k=%d true=%d): i=%d j=%d, errf: %g errx: %g dampfactor: %g\n",myid,t,realnstep, k, truetrialnum, startpos[1]+icurr,startpos[2]+jcurr,errf,errx,dampfactor);
    }
  }
  // assume won't fail if not too bad convergence if <=1E-4
  if ((errf <= tolfallowed)&&(errx<=tolxallowed)) {
    return (0); // for now
  }
  else{ // if >1E-4, then something is wrong
#if(DEBUG)
    if(debugfail>=1){
      dualfprintf(fail_file, "mnewt: (k=%d truetrialnum=%d) failure\n", k,truetrialnum);
    }
    if(debugfail>=2){
      // COMMENT
      // if failed, probably went outside allowed solution given constraints
      // placed on p.  How can this occur when U and p are related?  Is U somehow
      // more flexible?
      coord(icurr,jcurr,CENT,X);
      bl_coord(X,&r,&th);
      get_geometry(icurr,jcurr,CENT,&geom);
      dualfprintf(fail_file,"i=%d j=%d \nx1=%25.17g x2=%25.17g \nr=%25.17g th=%25.17g \ng=%25.17g\n",startpos[1]+icurr,startpos[2]+jcurr,X[1],X[2],r,th,geom.g);
      dualfprintf(fail_file,"x->%25.17g``20, y->%25.17g``20\n",X[1],X[2]);
      for(i=1;i<=n;i++) { dualfprintf(fail_file, "startfvec[%d]=%25.17g startx[%d]=%25.17g x[%d]=%25.17g\n",i,startfvec[i],i,startx[i],i,x[i]); }
      for(i=1;i<=n;i++){
	for(j=1;j<=n;j++){
	  dualfprintf(fail_file, "fjac[%d][%d]=%25.17g ",i,j,fjac[i][j]);
	}
	dualfprintf(fail_file,"\n");
      }
#endif      
#if(DEBUG==2)
#if(0)
      dualfprintf(fail_file,"mnewt={");
      for(i=0;i<n;i++){ // seperately for each primitive variable
	dualfprintf(fail_file,"{");
	for(j=0;j<truetrialnum+1;j++){	  
	  dualfprintf(fail_file,"%25.17g``20 ",trialvalue[j][i]);
	  if(j<truetrialnum-1) 	    dualfprintf(fail_file,",");	    
	}
	dualfprintf(fail_file,"}\n");
	if(i<n-1) 	    dualfprintf(fail_file,",");	    
      }
      dualfprintf(fail_file,"};\n");
      dualfprintf(fail_file,"mnewterr={");
      for(i=0;i<=1;i++){ // seperately for each primitive variable
	dualfprintf(fail_file,"{");
	for(j=0;j<truetrialnum;j++){	  
	  dualfprintf(fail_file,"%25.17g``20 ",trialerr[j][i]);
	  if(j<truetrialnum-1) 	    dualfprintf(fail_file,",");	    
	}
	dualfprintf(fail_file,"}\n");
	if(i<1) 	    dualfprintf(fail_file,",");	    
      }
      dualfprintf(fail_file,"};\n");
#else
      out=fopen("mnewtvaluelist.txt","wt");
      if(out==NULL){ fprintf(stderr,"cannot open mnewtvaluelist.txt\n"); exit(1);}
      for(j=0;j<truetrialnum+1;j++){
	for(i=0;i<n;i++) {
	  fprintf(out,"%25.17g ",trialvalue[j][i]);
	}
	fprintf(out,"\n");
      }
      fclose(out);

      out=fopen("mnewterrlist.txt","wt");
      if(out==NULL){ fprintf(stderr,"cannot open mnewterrlist.txt\n"); exit(1);}
      for(j=0;j<truetrialnum;j++){
	for(i=0;i<2;i++) {
	  fprintf(out,"%25.17g ",trialerr[j][i]);
	}
	fprintf(out,"\n");
      }
      fclose(out);
#endif      
#endif
      //failed = 3;		// source of failure (nonconvergence)
    }
    FAILSTATEMENT("mnewt.c", "convergence", 1);
  }
}
Пример #17
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_PC = ld_text_base;
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
#ifndef TARGET_ARM
      regs.regs_R[MD_REG_ZERO] = 0;
#endif
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      if (regs.regs_PC >= ld_text_bound)
	{
	  info("all instructions decoded...");
	  exit(0);
	}

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

#if 0
      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3,I4)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);
#endif

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  myfprintf(stderr, "           op: %d, inst: 0x%08x\n", op, inst);
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Пример #18
0
void savePlaylistState() {
	if(playlist_stateFile) {
		FILE * fp;
		char tmp[MAXPATHLEN+1];

		snprintf(tmp,MAXPATHLEN,"%s.%05d.%ld",playlist_stateFile,
				getpid(),time(NULL));

		while(!(fp = fopen(tmp,"w")) && errno==EINTR);
		if(!fp) {
			ERROR("problems opening state file \"%s\" for "
				"writing\n",playlist_stateFile);
			return;
		}

		myfprintf(fp,"%s",PLAYLIST_STATE_FILE_STATE);
		switch(playlist_state) {
		case PLAYLIST_STATE_PLAY:
			switch(getPlayerState()) {
			case PLAYER_STATE_PAUSE:
				myfprintf(fp,"%s\n",
					PLAYLIST_STATE_FILE_STATE_PAUSE);
				break;
			default:
				myfprintf(fp,"%s\n",
					PLAYLIST_STATE_FILE_STATE_PLAY);
			}
			myfprintf(fp,"%s%i\n",PLAYLIST_STATE_FILE_CURRENT,
				playlist.order[playlist.current]);
			myfprintf(fp,"%s%i\n",PLAYLIST_STATE_FILE_TIME,
				getPlayerElapsedTime());
			break;
		default:
			myfprintf(fp,"%s\n",PLAYLIST_STATE_FILE_STATE_STOP);
			break;
		}
		myfprintf(fp,"%s%i\n",PLAYLIST_STATE_FILE_RANDOM,
				playlist.random);
		myfprintf(fp,"%s%i\n",PLAYLIST_STATE_FILE_REPEAT,
				playlist.repeat);
		myfprintf(fp,"%s%i\n",PLAYLIST_STATE_FILE_CROSSFADE,
				(int)(getPlayerCrossFade()));
		myfprintf(fp,"%s\n",PLAYLIST_STATE_FILE_PLAYLIST_BEGIN);
		showPlaylist(fp);
		myfprintf(fp,"%s\n",PLAYLIST_STATE_FILE_PLAYLIST_END);

		while(fclose(fp) && errno==EINTR);

		rename(tmp,playlist_stateFile);
	}
}
Пример #19
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* ECE552 Pre-Assignment - BEGIN CODE*/
  int r_out[2], r_in[3];
  /* ECE552 Pre-Assignment - END CODE*/

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {

      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */

      switch (op)
      {
	      /* ECE552 Pre-Assignment - BEGIN CODE*/
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \
	      case OP: \
		       r_out[0] = (O1); r_out[1] = (O2); \
	      r_in[0] = (I1); r_in[1] = (I2); r_in[2] = (I3); \
	      SYMCAT(OP,_IMPL); \
	      break;
	      /* ECE552 Pre-Assignment - END CODE*/
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      /* ECE552 Pre-Assignment - BEGIN CODE*/
      if ( (MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD) ) {
	      sim_num_loads++;
      }
      {
	      int i;
	      for (i = 0; i < 3; i++) {
		      if (r_in[i] != DNA && reg_ready [r_in [i]] > sim_num_insn) {
			      if ((i == 0) && (MD_OP_FLAGS(op) & F_MEM) &&
					      (MD_OP_FLAGS(op) & F_STORE)) {
				      continue;
			      }
			      sim_num_lduh++;
			      break;
		      }
	      }
      }
      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD)) {
	      if (r_out[0] != DNA)
		      reg_ready[r_out[0]] = sim_num_insn + 2;
	      if (r_out[1] != DNA)
		      reg_ready[r_out[1]] = sim_num_insn + 2;
      }
      /* ECE552 Pre-Assignment - END CODE*/

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Пример #20
0
void printPlaylistSongInfo(FILE * fp, int song) {
	printSongInfo(fp, playlist.songs[song]);
	myfprintf(fp, "Pos: %i\n", song);
	myfprintf(fp, "Id: %i\n", playlist.positionToId[song]);
}
Пример #21
0
void decode(void)
{
    md_inst_t inst;
    register md_addr_t addr;
    enum md_opcode op;
    register int is_write;
    enum md_fault_type fault;
    int i;
    int i1, i2, i3, o1, o2;

    inst_t *pI = g_piperegister[IF_ID_REGISTER];

    if( g_piperegister[ID_EX_REGISTER] != NULL )
        return; // stall
    if( pI == NULL )
        return; // bubble

    if( !pI->stalled ) {
        // BEGIN FUNCTIONAL EXECUTION -->
        assert( pI->pc == regs.regs_PC );

        /* maintain $r0 semantics */
        regs.regs_R[MD_REG_ZERO] = 0;
        inst = pI->inst;

        /* keep an instruction count */
        sim_num_insn++;

        /* set default reference address and access mode */
        addr = 0; is_write = FALSE;

        /* set default fault - none */
        fault = md_fault_none;

        /* decode the instruction */
        MD_SET_OPCODE(op, inst);
        pI->op = op;

        /* execute the instruction */
        switch (op)
        {
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)    \
        case OP:                                                    \
              i1 = I1; i2 = I2; i3 = I3; o1 = O1; o2 = O2;          \
              SYMCAT(OP,_IMPL);                                     \
              break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)                         \
            case OP:                                                \
              panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)                                    \
          { fault = (FAULT); break; }
#include "machine.def"
        default:
          panic("attempted to execute a bogus opcode");
        }

        if (fault != md_fault_none)
            fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

        if (verbose) {
            myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
            sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
            md_print_insn(inst, regs.regs_PC, stderr);
            if (MD_OP_FLAGS(op) & F_MEM)
            myfprintf(stderr, "  mem: 0x%08p", addr);
            fprintf(stderr, "\n");
            /* fflush(stderr); */
        }

        if (MD_OP_FLAGS(op) & F_MEM) {
          sim_num_refs++;
          if (MD_OP_FLAGS(op) & F_STORE)
            is_write = TRUE;
        }

        /* go to the next instruction */
        regs.regs_PC = regs.regs_NPC;
        regs.regs_NPC += sizeof(md_inst_t);

        // <---  END FUNCTIONAL EXECUTION

	// record correct next instruction address (use for branches/jumps)
	pI->next_pc = regs.regs_PC;

        // record dependencies on instructions already in the pipeline 
        pI->src[0] = g_raw[i1];
        pI->src[1] = g_raw[i2];
        pI->src[2] = g_raw[i3];

        // record which register(s) this instruction writes to
        if( o1 != DNA ) g_raw[o1] = pI;
        if( o2 != DNA ) g_raw[o2] = pI;
        pI->dst[0] = o1;
        pI->dst[1] = o2;

        // determine instruction type
        if( MD_OP_FLAGS(op) & F_CTRL ) 
            pI->taken = (regs.regs_PC != (pI->pc+sizeof(md_inst_t)));
    }

    // check for RAW hazard
    for ( i=0; i < 3; ++i ) { // for each potential source operand...
        if ( pI->src[i] != NULL ) {
            if( pI->src[i]->donecycle > sim_cycle ) {
                // src[i] has not written to register file this cycle or earlier
		pI->stalled = 1;
                return;
            }
        }
    }

    if( pI->taken ) {
        g_fetch_redirected = 1;
        g_target_pc = pI->next_pc;
    }

    // move instruction from IF/ID to ID/EX register...
    pI->stalled = 0;
    pI->status = DECODED;
    g_piperegister[ID_EX_REGISTER] = pI; // move to ID/EX register
    g_piperegister[IF_ID_REGISTER] = NULL;
}
Пример #22
0
/*
 *
 *  Procedure:
 *      main - start of module
 *
 */
int
main(int argc, char **argv)
{
	/* The struct holding the module info */
	static ModuleArgs* module;
	char *enter_fn="Silent Raise";        /* default */
	char *leave_fn=NULL;
	char *buf;
	int len;
	unsigned long m_mask;
	unsigned long mx_mask;
	unsigned long last_win = 0;   /* last window handled */
	unsigned long focus_win = 0;  /* current focus */
	unsigned long raised_win = 0;
	fd_set_size_t fd_width;
	int fd[2];
	int timeout;
	int sec = 0;
	int usec = 0;
	int n;
	struct timeval value;
	struct timeval *delay;
	fd_set in_fdset;
	Bool do_pass_id = False;
	Bool use_enter_mode = False;
	Bool use_leave_mode = False;
#ifdef DEBUG
	int count = 0;
#endif

#ifdef DEBUGTOFILE
	freopen(".FvwmAutoDebug","w",stderr);
#endif

	module = ParseModuleArgs(argc,argv,0); /* no alias in this module */
	if (module==NULL)
	{
		fprintf(stderr,"FvwmAuto Version "VERSION" should only be executed by fvwm!\n");
		exit(1);
	}


	if (module->user_argc < 1 || module->user_argc > 5)
	{
		fprintf(stderr,"FvwmAuto can use one to five arguments.\n");
		exit(1);
	}

	/* Dead pipes mean fvwm died */
#ifdef HAVE_SIGACTION
	{
		struct sigaction  sigact;

		sigemptyset(&sigact.sa_mask);
		sigaddset(&sigact.sa_mask, SIGPIPE);
		sigaddset(&sigact.sa_mask, SIGINT);
		sigaddset(&sigact.sa_mask, SIGHUP);
		sigaddset(&sigact.sa_mask, SIGQUIT);
		sigaddset(&sigact.sa_mask, SIGTERM);
#ifdef SA_RESTART
		sigact.sa_flags = SA_RESTART;
# else
		sigact.sa_flags = 0;
#endif
		sigact.sa_handler = TerminateHandler;

		sigaction(SIGPIPE, &sigact, NULL);
		sigaction(SIGINT,  &sigact, NULL);
		sigaction(SIGHUP,  &sigact, NULL);
		sigaction(SIGQUIT, &sigact, NULL);
		sigaction(SIGTERM, &sigact, NULL);
	}
#else
	/* We don't have sigaction(), so fall back to less robust methods.  */
#ifdef USE_BSD_SIGNALS
	fvwmSetSignalMask( sigmask(SIGPIPE) |
			   sigmask(SIGINT)  |
			   sigmask(SIGHUP)  |
			   sigmask(SIGQUIT) |
			   sigmask(SIGTERM) );
#endif

	signal(SIGPIPE, TerminateHandler);
	signal(SIGINT,  TerminateHandler);
	signal(SIGHUP,  TerminateHandler);
	signal(SIGQUIT, TerminateHandler);
	signal(SIGTERM, TerminateHandler);
#ifdef HAVE_SIGINTERRUPT
	siginterrupt(SIGPIPE, 0);
	siginterrupt(SIGINT, 0);
	siginterrupt(SIGHUP, 0);
	siginterrupt(SIGQUIT, 0);
	siginterrupt(SIGTERM, 0);
#endif
#endif

	fd[0] = module->to_fvwm;
	fd[1] = module->from_fvwm;

	if ((timeout = atoi(module->user_argv[0]) ))
	{
		sec = timeout / 1000;
		usec = (timeout % 1000) * 1000;
	}
	else
	{
		sec = 0;
		usec = 1000;
	}
	delay = &value;

	n = 1;
	if (n < module->user_argc && module->user_argv[n])
	{
		char *token;

		/* -passid option */
		if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-passid"))
		{
			do_pass_id = True;
			n++;
		}
		if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menterleave"))
		{
			/* enterleave mode */
			use_leave_mode = True;
			use_enter_mode = True;
			n++;
		}
		else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menter"))
		{
			/* enter mode */
			use_leave_mode = False;
			use_enter_mode = True;
			n++;
		}
		else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-mfocus"))
		{
			/* focus mode */
			use_leave_mode = False;
			use_enter_mode = False;
			n++;
		}
		/*** enter command ***/
		if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "Nop"))
		{
			/* nop */
			enter_fn = NULL;
			n++;
		}
		else if (n < module->user_argc)
		{
			/* override default */
			enter_fn = module->user_argv[n];
			n++;
		}
		/* This is a hack to prevent user interaction with old configs.
		 */
		if (enter_fn)
		{
			token = PeekToken(enter_fn, NULL);
			if (!StrEquals(token, "Silent"))
			{
				enter_fn = safestrdup(
					CatString2("Silent ", enter_fn));
			}
		}
		/*** leave command ***/
		if (n < module->user_argc && module->user_argv[n] && *module->user_argv[n] &&
		    StrEquals(module->user_argv[n], "Nop"))
		{
			/* nop */
			leave_fn = NULL;
			n++;
		}
		else if (n < module->user_argc)
		{
			/* leave function specified */
			leave_fn=module->user_argv[n];
			n++;
		}
		if (leave_fn)
		{
			token = PeekToken(leave_fn, NULL);
			if (!StrEquals(token, "Silent"))
			{
				leave_fn = safestrdup(
					CatString2("Silent ", leave_fn));
			}
		}
	}

	/* Exit if nothing to do. */
	if (!enter_fn && !leave_fn)
	{
		return -1;
	}

	if (use_enter_mode)
	{
		m_mask = 0;
		mx_mask = MX_ENTER_WINDOW | MX_LEAVE_WINDOW | M_EXTENDED_MSG;
	}
	else
	{
		mx_mask = M_EXTENDED_MSG;
		m_mask = M_FOCUS_CHANGE;
	}
	/* Disable special raise/lower support on general actions. *
	 * This works as expected in most of cases. */
	if (matchWildcards("*Raise*", CatString2(enter_fn, leave_fn)) ||
	    matchWildcards("*Lower*", CatString2(enter_fn, leave_fn)))
	{
		m_mask |= M_RAISE_WINDOW | M_LOWER_WINDOW;
	}

	/* migo (04/May/2000): It is simply incorrect to listen to raise/lower
	 * packets and change the state if the action itself has no raise/lower.
	 * Detecting whether to listen or not by the action name is good enough.
	 m_mask = M_FOCUS_CHANGE | M_RAISE_WINDOW | M_LOWER_WINDOW;
	*/

	SetMessageMask(fd, m_mask);
	SetMessageMask(fd, mx_mask);
	/* tell fvwm we're running */
	SendFinishedStartupNotification(fd);
	/* tell fvwm that we want to be lock on send */
	SetSyncMask(fd, m_mask);
	SetSyncMask(fd, mx_mask);

	fd_width = fd[1] + 1;
	FD_ZERO(&in_fdset);

	/* create the command buffer */
	len = 0;
	if (enter_fn != 0)
	{
		len = strlen(enter_fn);
	}
	if (leave_fn != NULL)
	{
		len = max(len, strlen(leave_fn));
	}
	if (do_pass_id)
	{
		len += 32;
	}
	buf = safemalloc(len);

	while (!isTerminated)
	{
		char raise_window_now;
		static char have_new_window = 0;

		FD_SET(fd[1], &in_fdset);

		myfprintf(
			(stderr, "\nstart %d (hnw = %d, usec = %d)\n", count++,
			 have_new_window, usec));
		/* fill in struct - modified by select() */
		delay->tv_sec = sec;
		delay->tv_usec = usec;
#ifdef DEBUG
		{
			char tmp[32];

			sprintf(tmp, "%d usecs", (delay) ?
				(int)delay->tv_usec : -1);
			myfprintf((stderr, "select: delay = %s\n",
				   (have_new_window) ? tmp : "infinite" ));
		}
#endif
		if (fvwmSelect(fd_width, &in_fdset, NULL, NULL,
			       (have_new_window) ? delay : NULL) == -1)
		{
			myfprintf(
				(stderr, "select: error! (%s)\n",
				 strerror(errno)));
			break;
		}

		raise_window_now = 0;
		if (FD_ISSET(fd[1], &in_fdset))
		{
			FvwmPacket *packet = ReadFvwmPacket(fd[1]);

			if (packet == NULL)
			{
				myfprintf(
					(stderr,
					 "Leaving because of null packet\n"));
				break;
			}

			myfprintf(
				(stderr,
				 "pw = 0x%x, fw=0x%x, rw = 0x%x, lw=0x%x\n",
				 (int)packet->body[0], (int)focus_win,
				 (int)raised_win, (int)last_win));

			switch (packet->type)
			{
			case MX_ENTER_WINDOW:
				focus_win = packet->body[0];
				if (focus_win != raised_win)
				{
					myfprintf((stderr,
						   "entered new window\n"));
					have_new_window = 1;
					raise_window_now = 0;
				}
				else if (focus_win == last_win)
				{
					have_new_window = 0;
				}
				else
				{
					myfprintf((stderr,
						   "entered other window\n"));
				}
				break;

			case MX_LEAVE_WINDOW:
				if (use_leave_mode)
				{
					if (focus_win == raised_win)
					{
						focus_win = 0;
					}
					myfprintf((stderr,
						   "left raised window\n"));
					have_new_window = 1;
					raise_window_now = 0;
				}
				break;

			case M_FOCUS_CHANGE:
				/* it's a focus package */
				focus_win = packet->body[0];
				if (focus_win != raised_win)
				{
					myfprintf((stderr,
						   "focus on new window\n"));
					have_new_window = 1;
					raise_window_now = 0;
				}
				else
				{
					myfprintf((stderr,
						   "focus on old window\n"));
				}
				break;

			case M_RAISE_WINDOW:
				myfprintf(
					(stderr, "raise packet 0x%x\n",
					 (int)packet->body[0]));
				raised_win = packet->body[0];
				if (have_new_window && focus_win == raised_win)
				{
					myfprintf(
						(stderr, "its the old window:"
						 " don't raise\n"));
					have_new_window = 0;
				}
				break;

			case M_LOWER_WINDOW:
				myfprintf(
					(stderr, "lower packet 0x%x\n",
					 (int)packet->body[0]));
				if (have_new_window &&
				    focus_win == packet->body[0])
				{
					myfprintf(
						(stderr,
						 "window was explicitly"
						 " lowered, don't raise it"
						 " again\n"));
					have_new_window = 0;
				}
				break;
			} /* switch */
			SendUnlockNotification(fd);
		}
		else
		{
			if (have_new_window)
			{
				myfprintf((stderr, "must raise now\n"));
				raise_window_now = 1;
			}
		}

		if (raise_window_now)
		{
			myfprintf((stderr, "raising 0x%x\n", (int)focus_win));

			if (leave_fn &&
			    ((last_win && !use_leave_mode) ||
			     (raised_win && use_enter_mode)))
			{
				/* if focus_win isn't the root */
				if (do_pass_id)
				{
					sprintf(buf, "%s 0x%x\n", leave_fn,
						(int)last_win);
				}
				else
				{
					sprintf(buf, "%s\n", leave_fn);
				}
				SendInfo(fd, buf, last_win);
				if (use_enter_mode)
				{
					raised_win = 0;
				}
			}

			if (focus_win && enter_fn)
			{
				/* if focus_win isn't the root */
				if (do_pass_id)
				{
					sprintf(buf, "%s 0x%x\n", enter_fn,
						(int)focus_win);
				}
				else
				{
					sprintf(buf, "%s\n", enter_fn);
				}
				SendInfo(fd, buf, focus_win);
				raised_win = focus_win;
			}
			else if (focus_win && enter_fn == NULL)
			{
				raised_win = focus_win;
			}
			/* force fvwm to synchronise on slow X connections to
			 * avoid a race condition.  Still possible, but much
			 * less likely. */
			SendInfo(fd, "XSync", focus_win);

			/* switch to wait mode again */
			last_win = focus_win;
			have_new_window = 0;
		}
	} /* while */

	return 0;
}
Пример #23
0
/* print floating point REGS to STREAM */
void
md_print_fpreg(md_fpr_t regs, int reg, FILE *stream)
{
  myfprintf(stream, "%4s: %16ld/0x%012lx/%f",
	    md_reg_name(rt_fpr, reg), regs.q[reg], regs.q[reg], regs.d[reg]);
}
Пример #24
0
/* check point current architected state to stream FD, returns
   EIO transaction count (an EIO file pointer) */
counter_t
eio_write_chkpt(struct regs_t *regs,		/* regs to dump */
		struct mem_t *mem,		/* memory to dump */
		FILE *fd)			/* stream to write to */
{
  int i;
  struct exo_term_t *exo;
  struct mem_pte_t *pte;

  myfprintf(fd, "/* ** start checkpoint @ %n... */\n\n", eio_trans_icnt);

  myfprintf(fd, "/* EIO file pointer: %n... */\n", eio_trans_icnt);
  exo = exo_new(ec_integer, (exo_integer_t)eio_trans_icnt);
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  /* dump misc regs: icnt, PC, NPC, etc... */
  fprintf(fd, "/* misc regs icnt, PC, NPC, etc... */\n");
  exo = MD_MISC_REGS_TO_EXO(regs);
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  /* dump integer registers */
  fprintf(fd, "/* integer regs */\n");
  exo = exo_new(ec_list, NULL);
  for (i=0; i < MD_NUM_IREGS; i++)
    exo->as_list.head = exo_chain(exo->as_list.head, MD_IREG_TO_EXO(regs, i));
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  /* dump FP registers */
  fprintf(fd, "/* FP regs (integer format) */\n");
  exo = exo_new(ec_list, NULL);
  for (i=0; i < MD_NUM_FREGS; i++)
    exo->as_list.head = exo_chain(exo->as_list.head, MD_FREG_TO_EXO(regs, i));
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  fprintf(fd, "/* writing `%d' memory pages... */\n", (int)mem->page_count);
  exo = exo_new(ec_list,
		exo_new(ec_integer, (exo_integer_t)mem->page_count),
		exo_new(ec_address, (exo_integer_t)ld_brk_point),
		exo_new(ec_address, (exo_integer_t)ld_stack_min),
		NULL);
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  fprintf(fd, "/* text segment specifiers (base & size) */\n");
  exo = exo_new(ec_list,
		exo_new(ec_address, (exo_integer_t)ld_text_base),
		exo_new(ec_integer, (exo_integer_t)ld_text_size),
		NULL);
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  fprintf(fd, "/* data segment specifiers (base & size) */\n");
  exo = exo_new(ec_list,
		exo_new(ec_address, (exo_integer_t)ld_data_base),
		exo_new(ec_integer, (exo_integer_t)ld_data_size),
		NULL);
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  fprintf(fd, "/* stack segment specifiers (base & size) */\n");
  exo = exo_new(ec_list,
		exo_new(ec_address, (exo_integer_t)ld_stack_base),
		exo_new(ec_integer, (exo_integer_t)ld_stack_size),
		NULL);
  exo_print(exo, fd);
  fprintf(fd, "\n\n");
  exo_delete(exo);

  /* visit all active memory pages, and dump them to the checkpoint file */
  MEM_FORALL(mem, i, pte)
    {
      /* dump this page... */
      exo = exo_new(ec_list,
		    exo_new(ec_address, (exo_integer_t)MEM_PTE_ADDR(pte, i)),
		    exo_new(ec_blob, MD_PAGE_SIZE, pte->page),
		    NULL);
      exo_print(exo, fd);
      fprintf(fd, "\n\n");
      exo_delete(exo);
    }
Пример #25
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  /* ECE552 Assignment 1 - BEGIN CODE */

  int r_in[3], r_out[2];

  /* ECE552 Assignment 1 - END CODE */

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {

      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */

      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
	  r_out[0] = (O1); r_out[1] = (O2);				\
	  r_in[0] = (I1); r_in[1] = (I2); r_in[2] = (I3);		\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }
      
      /* ECE552 Assignment 1 - BEGIN CODE */

      /* ECE552 Part 1 */

      int i, counter_q1 = 0, counter_q2 = 0, counter_q3 = 0;

      for (i = 0;  i < 3; i++)
      {
	if (r_in[i] != DNA && reg_ready_q1[r_in[i]] > sim_num_insn)
	{
	  int cycle = reg_ready_q1[r_in[i]] - sim_num_insn;
	  
	  if (cycle ==  1)
	  {
  	    counter_q1++;
	  }
	  else if (cycle == 2)
	  {
	    counter_q1 =  counter_q1 + 2;
	  }

	  //reset the register
	  reg_ready_q1[r_in[i]] = DNA;
	}
      }

      if (counter_q1 == 1)
      {
        sim_num_one_cycle_hazard_q1++;
      }
      else if (counter_q1 >= 2)
      {
	 sim_num_two_cycle_hazard_q1++;
      }	

      if (r_out[0] != DNA)
      {
	reg_ready_q1[r_out[0]] = sim_num_insn + 3;
      }

      if (r_out[1] != DNA)
      {
	reg_ready_q1[r_out[1]] = sim_num_insn + 3;
      }
    
      sim_num_RAW_hazard_q1 = sim_num_one_cycle_hazard_q1 + sim_num_two_cycle_hazard_q1; 

      /* ECE552 Part 2*/

      for (i = 0;  i < 3; i++)
      {
	if (r_in[i] != DNA && reg_ready_q2[r_in[i]] > sim_num_insn)
	{
	  if ((i == 0) && (MD_OP_FLAGS(op) & F_MEM) &&
	      (MD_OP_FLAGS(op) & F_STORE))
	  {
	      continue;
	  }
          
	  int cycle = reg_ready_q2[r_in[i]] - sim_num_insn;

	  if (cycle == 1)
	  {
	    counter_q2++;
	  }
	  else if (cycle == 2)
	  {
		counter_q2 = counter_q2 + 2;
	  }

          //reset the register
	  reg_ready_q2[r_in[i]] = DNA;
	}
      }
      
      if (counter_q2 == 1)
      {
	sim_num_one_cycle_hazard_q2++;
      }
      else if (counter_q2 >= 2)
      {
	sim_num_two_cycle_hazard_q2++;
      }

      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
        if (r_out[0] != DNA)
        {
	  reg_ready_q2[r_out[0]] = sim_num_insn + 3;
        }

        if (r_out[1] != DNA)
        {
	  reg_ready_q2[r_out[1]] = sim_num_insn + 3;
        }
      }
      else if (!(MD_OP_FLAGS(op) & F_MEM))
      {
        if (r_out[0] != DNA)
        {
	  reg_ready_q2[r_out[0]] = sim_num_insn + 2;
        }

        if (r_out[1] != DNA)
        {
	  reg_ready_q2[r_out[1]] = sim_num_insn + 2;
        }
      }

      sim_num_RAW_hazard_q2 = sim_num_one_cycle_hazard_q2 + sim_num_two_cycle_hazard_q2;

      /* ECE552 Part 3 */


      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
	is_current_load = true;
      }
      else if (!(MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
	is_previous_load = false;
      }
 
      if (!(MD_OP_FLAGS(op) & F_LOAD))
      {
		
        for (i = 0;  i < 2; i++)
        {
	  if (r_out[i] != DNA && reg_ready_q3[r_out[i]] > sim_num_insn)
	  {
   	    int cycle = reg_ready_q3[r_out[i]] - sim_num_insn;
	  
	    if (cycle == 1)
	    {
	      //two cycle stall for non mem instruction
	      if (is_current_load == true && is_current_load == true)
	      {
		 sim_num_two_cycle_hazard_q3++;
	      }
	      else
	      {
		sim_num_one_cycle_hazard_q3++;	
	      }
	  }
   	  else if (cycle == 2)
	  {
	    sim_num_two_cycle_hazard_q3++;
	  }

 	  reg_ready_q3[r_out[i]] = DNA;
          counter_q3 = 1;
        }
      } 

	if(counter_q3 == 0 && (r_out[0] != DNA || r_out[1] != DNA))
	{
	  if(is_current_load && is_previous_load && write_back_ready == sim_num_insn + 1)
          {
		sim_num_structural_hazard_q3 = sim_num_structural_hazard_q3 + 2;
          }
	  else if(write_back_ready == sim_num_insn)
	  {
	    sim_num_structural_hazard_q3++;
	  }
	}
    }
      
     if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
     {
       if (r_out[0] != DNA)
       {
	 reg_ready_q3[r_out[0]] = sim_num_insn + 3;
       }

       if (r_out[1] != DNA)
       {
	 reg_ready_q3[r_out[1]] = sim_num_insn + 3;
       }

       write_back_ready = sim_num_insn + 2;
       is_previous_load = true;
     }
     else if (!(MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
     {
	is_previous_load = false;
     }

     sim_num_WAW_hazard_q3  = sim_num_one_cycle_hazard_q3 + sim_num_two_cycle_hazard_q3;

     /* ECE552 Assignment 1 - END CODE */

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Пример #26
0
/* print a sparse array distribution */
static void
print_sdist(struct stat_stat_t *stat,	/* stat variable */
	    FILE *fd)			/* output stream */
{
  unsigned int i, bcount;
  md_addr_t imax, imin;
  double btotal, bsum, bvar, bavg, bsqsum;
  struct bucket_t *bucket;
  int pf = stat->variant.for_sdist.pf;

  /* count and sum entries */
  bcount = 0; btotal = 0.0; bvar = 0.0; bsqsum = 0.0;
  imax = 0; imin = UINT_MAX;
  for (i=0; i<HTAB_SZ; i++)
    {
      for (bucket = stat->variant.for_sdist.sarr[i];
	   bucket != NULL;
	   bucket = bucket->next)
	{
	  bcount++;
	  btotal += bucket->count;
	  /* on-line variance computation, tres cool, no!?! */
	  bsqsum += ((double)bucket->count * (double)bucket->count);
	  bavg = btotal / (double)bcount;
	  bvar = (bsqsum - ((double)bcount * bavg * bavg)) / 
	    (double)(((bcount - 1) > 0) ? (bcount - 1) : 1);
	  if (bucket->index < imin)
	    imin = bucket->index;
	  if (bucket->index > imax)
	    imax = bucket->index;
	}
    }

  /* print header */
  fprintf(fd, "\n");
  fprintf(fd, "%-22s # %s\n", stat->name, stat->desc);
  fprintf(fd, "%s.count = %u\n", stat->name, bcount);
  fprintf(fd, "%s.total = %.0f\n", stat->name, btotal);
  if (bcount > 0)
    {
      myfprintf(fd, "%s.imin = 0x%p\n", stat->name, imin);
      myfprintf(fd, "%s.imax = 0x%p\n", stat->name, imax);
    }
  else
    {
      fprintf(fd, "%s.imin = %d\n", stat->name, -1);
      fprintf(fd, "%s.imax = %d\n", stat->name, -1);
    }
  fprintf(fd, "%s.average = %8.4f\n", stat->name, btotal/bcount);
  fprintf(fd, "%s.std_dev = %8.4f\n", stat->name, sqrt(bvar));
  fprintf(fd, "%s.overflows = 0\n", stat->name);

  fprintf(fd, "# pdf == prob dist fn, cdf == cumulative dist fn\n");
  fprintf(fd, "# %14s ", "index");
  if (pf & PF_COUNT)
    fprintf(fd, "%10s ", "count");
  if (pf & PF_PDF)
    fprintf(fd, "%6s ", "pdf");
  if (pf & PF_CDF)
    fprintf(fd, "%6s ", "cdf");
  fprintf(fd, "\n");

  fprintf(fd, "%s.start_dist\n", stat->name);

  if (bcount > 0)
    {
      unsigned int bindex;
      struct bucket_t **barr;

      /* collect all buckets */
      barr = (struct bucket_t **)calloc(bcount, sizeof(struct bucket_t *));
      if (!barr)
	fatal("out of virtual memory");
      for (bindex=0,i=0; i<HTAB_SZ; i++)
	{
	  for (bucket = stat->variant.for_sdist.sarr[i];
	       bucket != NULL;
	       bucket = bucket->next)
	    {
	      barr[bindex++] = bucket;
	    }
	}

      /* sort the array by index */
      qsort(barr, bcount, sizeof(struct bucket_t *), (void *)compare_fn);

      /* print the array */
      bsum = 0.0;
      for (i=0; i<bcount; i++)
	{
	  bsum += (double)barr[i]->count;
	  if (stat->variant.for_sdist.print_fn)
	    {
	      stat->variant.for_sdist.print_fn(stat,
					       barr[i]->index,
					       barr[i]->count,
					       bsum,
					       btotal);
	    }
	  else
	    {
	      if (stat->format == NULL)
		{
		  myfprintf(fd, "0x%p ", barr[i]->index);
		  if (pf & PF_COUNT)
		    fprintf(fd, "%10u ", barr[i]->count);
		  if (pf & PF_PDF)
		    fprintf(fd, "%6.2f ",
			    (double)barr[i]->count/MAX(btotal, 1.0) * 100.0);
		  if (pf & PF_CDF)
		    fprintf(fd, "%6.2f ", bsum/MAX(btotal, 1.0) * 100.0);
		}
	      else
		{
		  if (pf == (PF_COUNT|PF_PDF|PF_CDF))
		    {
		      myfprintf(fd, stat->format,
				barr[i]->index, barr[i]->count,
				(double)barr[i]->count/MAX(btotal, 1.0)*100.0,
				bsum/MAX(btotal, 1.0) * 100.0);
		    }
		  else if (pf == (PF_COUNT|PF_PDF))
		    {
		      myfprintf(fd, stat->format,
				barr[i]->index, barr[i]->count,
				(double)barr[i]->count/MAX(btotal, 1.0)*100.0);
		    }
		  else if (pf == PF_COUNT)
		    {
		      myfprintf(fd, stat->format,
				barr[i]->index, barr[i]->count);
		    }
		  else
		    fatal("distribution format not yet implemented");
		}
	      fprintf(fd, "\n");
	    }
	}

      /* all done, release bucket pointer array */
      free(barr);
    }

  fprintf(fd, "%s.end_dist\n", stat->name);
}
Пример #27
0
/* print the value of stat variable STAT */
void
stat_print_stat(struct stat_sdb_t *sdb,	/* stat database */
		struct stat_stat_t *stat,/* stat variable */
		FILE *fd)		/* output stream */
{
  struct eval_value_t val;

  switch (stat->sc)
    {
    case sc_int:
      fprintf(fd, "%-22s ", stat->name);
      myfprintf(fd, stat->format, *stat->variant.for_int.var);
      fprintf(fd, " # %s", stat->desc);
      break;
    case sc_uint:
      fprintf(fd, "%-22s ", stat->name);
      myfprintf(fd, stat->format, *stat->variant.for_uint.var);
      fprintf(fd, " # %s", stat->desc);
      break;
#ifdef HOST_HAS_QWORD
    case sc_qword:
      {
	char buf[128];

	fprintf(fd, "%-22s ", stat->name);
	mysprintf(buf, stat->format, *stat->variant.for_qword.var);
	fprintf(fd, "%s # %s", buf, stat->desc);
      }
      break;
    case sc_sqword:
      {
	char buf[128];

	fprintf(fd, "%-22s ", stat->name);
	mysprintf(buf, stat->format, *stat->variant.for_sqword.var);
	fprintf(fd, "%s # %s", buf, stat->desc);
      }
      break;
#endif /* HOST_HAS_QWORD */
    case sc_float:
      fprintf(fd, "%-22s ", stat->name);
      myfprintf(fd, stat->format, (double)*stat->variant.for_float.var);
      fprintf(fd, " # %s", stat->desc);
      break;
    case sc_double:
      fprintf(fd, "%-22s ", stat->name);
      myfprintf(fd, stat->format, *stat->variant.for_double.var);
      fprintf(fd, " # %s", stat->desc);
      break;
    case sc_dist:
      print_dist(stat, fd);
      break;
    case sc_sdist:
      print_sdist(stat, fd);
      break;
    case sc_formula:
      {
	/* instantiate a new evaluator to avoid recursion problems */
	struct eval_state_t *es = eval_new(stat_eval_ident, sdb);
	char *endp;

	fprintf(fd, "%-22s ", stat->name);
	val = eval_expr(es, stat->variant.for_formula.formula, &endp);
	if (eval_error != ERR_NOERR || *endp != '\0')
	  fprintf(fd, "<error: %s>", eval_err_str[eval_error]);
	else
	  myfprintf(fd, stat->format, eval_as_double(val));
	fprintf(fd, " # %s", stat->desc);

	/* done with the evaluator */
	eval_delete(es);
      }
      break;
    default:
      panic("bogus stat class");
    }
  fprintf(fd, "\n");
}
Пример #28
0
/* print an EXO term */
void
exo_print(struct exo_term_t *exo, FILE *stream)
{
  if (!stream)
    stream = stderr;

  switch (exo->ec)
    {
    case ec_integer:
      if (sizeof(exo_integer_t) == 4)
	myfprintf(stream, "%u", exo->as_integer.val);
      else
	myfprintf(stream, "%lu", exo->as_integer.val);
      break;

    case ec_address:
      if (sizeof(exo_address_t) == 4)
	myfprintf(stream, "0x%x", exo->as_integer.val);
      else
	myfprintf(stream, "0x%lx", exo->as_integer.val);
      break;

    case ec_float:
      fprintf(stream, "%f", exo->as_float.val);
      break;

    case ec_char:
      fprintf(stream, "'");
      print_char(exo->as_char.val, stream);
      fprintf(stream, "'");
      break;

    case ec_string:
      fprintf(stream, "\"");
      print_string(exo->as_string.str, stream);
      fprintf(stream, "\"");
      break;

    case ec_list:
      {
	struct exo_term_t *ent;

	fprintf(stream, "(");
	for (ent=exo->as_list.head; ent != NULL; ent=ent->next)
	  {
	    exo_print(ent, stream);
	    if (ent->next)
	      fprintf(stream, ", ");
	  }
	fprintf(stream, ")");
      }
      break;

    case ec_array:
      {
	int i, last;

	/* search for last first non-NULL entry */
	for (last=exo->as_array.size-1; last >= 0; last--)
	  {
	    if (EXO_ARR(exo, last) != NULL)
	      break;
	  }
	/* LAST == index of last non-NULL array entry */

	fprintf(stream, "{%d}[", exo->as_array.size);
	for (i=0; i<exo->as_array.size && i <= last; i++)
	  {
	    if (exo->as_array.array[i] != NULL)
	      exo_print(exo->as_array.array[i], stream);
	    else
	      fprintf(stream, " ");
	    if (i != exo->as_array.size-1 && i != last)
	      fprintf(stream, ", ");
	  }
	fprintf(stream, "]");
      }
      break;

    case ec_token:
      fprintf(stream, "%s", exo->as_token.ent->str);
      break;

    case ec_blob:
      {
	int i, cr;

	fprintf(stream, "{%d}<\n", exo->as_blob.size);
	for (i=0; i < exo->as_blob.size; i++)
	  {
	    cr = FALSE;
	    if (i != 0 && (i % 38) == 0)
	      {
		fprintf(stream, "\n");
		cr = TRUE;
	      }
	    fprintf(stream, "%02x", exo->as_blob.data[i]);
	  }
	if (!cr)
	  fprintf(stream, "\n");
	fprintf(stream, ">");
      }
      break;

    default:
      panic("bogus EXO class");
    }
}
Пример #29
0
/* load program text and initialized data into simulated virtual memory
   space and initialize program segment range variables */
void
ld_load_prog(char *fname,		/* program to load */
	     int argc, char **argv,	/* simulated program cmd line args */
	     char **envp,		/* simulated program environment */
	     struct regs_t *regs,	/* registers to initialize for load */
	     struct mem_t *mem,		/* memory space to load prog into */
	     int zero_bss_segs)		/* zero uninit data segment? */
{
  int i;
  word_t temp;
  md_addr_t sp, data_break = 0, null_ptr = 0, argv_addr, envp_addr;
  FILE *fobj;
  struct elf_filehdr fhdr;
  struct elf_scnhdr shdr;
  byte_t *strtab, *buffer;

  if (eio_valid(fname))
    {
      if (argc != 1)
	{
	  fprintf(stderr, "error: EIO file has arguments\n");
	  exit(1);
	}

      fprintf(stderr, "sim: loading EIO file: %s\n", fname);

      sim_eio_fname = mystrdup(fname);

      /* open the EIO file stream */
      sim_eio_fd = eio_open(fname);

      /* load initial state checkpoint */
      if (eio_read_chkpt(regs, mem, sim_eio_fd) != -1)
	fatal("bad initial checkpoint in EIO file");

      /* load checkpoint? */
      if (sim_chkpt_fname != NULL)
	{
	  counter_t restore_icnt;

	  FILE *chkpt_fd;

	  fprintf(stderr, "sim: loading checkpoint file: %s\n",
		  sim_chkpt_fname);

	  if (!eio_valid(sim_chkpt_fname))
	    fatal("file `%s' does not appear to be a checkpoint file",
		  sim_chkpt_fname);

	  /* open the checkpoint file */
	  chkpt_fd = eio_open(sim_chkpt_fname);

	  /* load the state image */
	  restore_icnt = eio_read_chkpt(regs, mem, chkpt_fd);

	  /* fast forward the baseline EIO trace to checkpoint location */
	  myfprintf(stderr, "sim: fast forwarding to instruction %n\n",
		    restore_icnt);
	  eio_fast_forward(sim_eio_fd, restore_icnt);
	}

      /* computed state... */
      ld_environ_base = regs->regs_R[MD_REG_SP];
      ld_prog_entry = regs->regs_PC;

      /* fini... */
      return;
    }
#ifdef MD_CROSS_ENDIAN
  else
    {
      warn("endian of `%s' does not match host", fname);
      warn("running with experimental cross-endian execution support");
      warn("****************************************");
      warn("**>> please check results carefully <<**");
      warn("****************************************");
#if 0
      fatal("SimpleScalar/ARM only supports binary execution on\n"
	    "       little-endian hosts, use EIO files on big-endian hosts");
#endif
    }
#endif /* MD_CROSS_ENDIAN */

  if (sim_chkpt_fname != NULL)
    fatal("checkpoints only supported while EIO tracing");

  /* record profile file name */
  ld_prog_fname = argv[0];

  /* load the program into memory, try both endians */
#if defined(__CYGWIN32__) || defined(_MSC_VER)
  fobj = fopen(argv[0], "rb");
#else
  fobj = fopen(argv[0], "r");
#endif
  if (!fobj)
    fatal("cannot open executable `%s'", argv[0]);

  if (fread(&fhdr, sizeof(struct elf_filehdr), 1, fobj) < 1)
    fatal("cannot read header from executable `%s'", argv[0]);

  /* check if it is a valid ELF file */
  if (!(fhdr.e_ident[EI_MAG0] == 0x7f &&
	fhdr.e_ident[EI_MAG1] == 'E' &&
	fhdr.e_ident[EI_MAG2] == 'L' &&
	fhdr.e_ident[EI_MAG3] == 'F'))
    fatal("bad magic number in executable `%s' (not an executable)", argv[0]);

  /* check if the file is executable */
  if (fhdr.e_type != ET_EXEC)
    fatal("object file `%s' is not executable", argv[0]);

  /* check if the file is for ARM architecture */
  if (fhdr.e_machine != EM_ARM)
    fatal("executable file `%s' is not for the ARM architecture", argv[0]);

  ld_prog_entry = fhdr.e_entry;

  debug("number of sections in executable = %d\n", fhdr.e_shnum);
  debug("offset to section header table = %d", fhdr.e_shoff);

  /* seek to the beginning of the first section header, the file header comes
     first, followed by the optional header (this is the aouthdr), the size
     of the aouthdr is given in Fdhr.f_opthdr */
  fseek(fobj, fhdr.e_shoff + (fhdr.e_shstrndx * fhdr.e_shentsize), SEEK_SET);
  if (fread(&shdr, sizeof(struct elf_scnhdr), 1, fobj) < 1)
    fatal("error reading string section header from `%s'", argv[0]);

  /* allocate space for string table */
  strtab = (char *)calloc(shdr.sh_size, sizeof(char));
  if (!strtab)
    fatal("out of virtual memory");

  /* read the string table */
  if (fseek(fobj, shdr.sh_offset, SEEK_SET) < 0)
    fatal("cannot seek to string table section");
  if (fread(strtab, shdr.sh_size, 1, fobj) < 0)
    fatal("cannot read string table section");

  debug("size of string table = %d", shdr.sh_size);
  debug("type of section = %d", shdr.sh_type);
  debug("offset of string table in file = %d", shdr.sh_offset);

  debug("processing %d sections in `%s'...", fhdr.e_shnum, argv[0]);

  /* loop through the section headers */
  for (i=0; i < fhdr.e_shnum; i++)
    {
      buffer = NULL;

      if (fseek(fobj, fhdr.e_shoff + (i * fhdr.e_shentsize), SEEK_SET) < 0)
	fatal("could not reset location in executable");
      if (fread(&shdr, sizeof(struct elf_scnhdr), 1, fobj) < 1)
	fatal("could not read section %d from executable", i);

      /* make sure the file is static */
      if (shdr.sh_type == SHT_DYNAMIC || shdr.sh_type == SHT_DYNSYM)
	fatal("file is dynamically linked, compile with `-static'");

      debug("processing section `%s'...", &strtab[shdr.sh_name]);
      debug("  section flags = 0x%08x", shdr.sh_flags);	
      debug("  section type = %d", shdr.sh_type);
      debug("  section address = 0x%08x", shdr.sh_addr);
      debug("  section offset = %d", shdr.sh_offset);
      debug("  section size = %d", shdr.sh_size);
      debug("  section link = %d", shdr.sh_link);
      debug("  section extra info = %d", shdr.sh_info);
      debug("  section entry size = %d", shdr.sh_entsize);

      if (shdr.sh_addr != 0
	  && shdr.sh_size != 0
	  && (shdr.sh_type == SHT_PROGBITS || shdr.sh_type == SHT_NOBITS))
	{
	  /* if the ELF format designates an address for the section then
	     load it into memory */
	  debug("  processing section `%s'...", &strtab[shdr.sh_name]);

	  if ((shdr.sh_flags & SHF_ALLOC) != 0 && shdr.sh_type != SHT_NOBITS)
	    {
	      debug("  loading section `%s'...", &strtab[shdr.sh_name]);
	      /* go to the offset in file where section is located */
	      if (fseek(fobj, shdr.sh_offset, SEEK_SET) < 0)
		fatal("cannot file pointer");

	      /* allocate memory for the section contents */
	      buffer = (char *)calloc(shdr.sh_size, sizeof(byte_t));
	      if (!buffer)
		fatal("out of virtual memory");

	      /* read section into buffer */	
	      if (fread(buffer, shdr.sh_size, 1, fobj) < 1)
		fatal("could not read all the contents of section");

	      /* copy the section contents into simulator target memory */
	      mem_bcopy(mem_access, mem, Write, shdr.sh_addr,
			buffer, shdr.sh_size);
	    }

	  /* update program space limits */
	  if ((shdr.sh_flags & SHF_EXECINSTR) != 0)
	    {
	      debug("updating text size...");
	      if (shdr.sh_addr < ld_text_base)
		ld_text_base = shdr.sh_addr;
	      if ((shdr.sh_addr + shdr.sh_size) > ld_text_bound)
		ld_text_bound = shdr.sh_addr + shdr.sh_size;
	    }
	  else
	    {
	      debug("updating data size...");
	      if (shdr.sh_addr < ld_data_base)
		ld_data_base = shdr.sh_addr;
	      if ((shdr.sh_addr + shdr.sh_size) > ld_data_bound)
		ld_data_bound = shdr.sh_addr + shdr.sh_size;
	    }
	  ld_text_size = ld_text_bound - ld_text_base;
	  ld_data_size = ld_data_bound - ld_data_base;

	  /* release buffer storage */
	  if (buffer != NULL)
	    free(buffer);	
	}
    }

  /* release string table storage */
  free(strtab);

  /* perform sanity checks on segment ranges */
  if (!ld_text_base || !ld_text_size)
    fatal("executable is missing a `.text' section");
  if (!ld_data_base || !ld_data_size)
    fatal("executable is missing a `.data' section");
  if (!ld_prog_entry)
    fatal("program entry point not specified");

  /* determine byte/words swapping required to execute on this host */
  sim_swap_bytes = (endian_host_byte_order() != endian_target_byte_order());
  if (sim_swap_bytes)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping bytes to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }
  sim_swap_words = (endian_host_word_order() != endian_target_word_order());
  if (sim_swap_words)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping words to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }

  /* set up a local stack pointer, this is where the argv and envp
     data is written into program memory */
  /* ld_stack_base = ld_text_base - (409600+4096); */

  ld_stack_base = 0xc0000000;
#if 0
  sp = ROUND_DOWN(ld_stack_base - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE));
#endif
  sp = ld_stack_base - MD_MAX_ENVIRON;
  ld_stack_size = ld_stack_base - sp;

  /* initial stack pointer value */
  ld_environ_base = sp;

  /* write [argc] to stack */
  temp = argc;
  mem_access(mem, Write, sp, &temp, sizeof(word_t));
  regs->regs_R[MD_REG_R1] = temp;
  sp += sizeof(word_t);

  /* skip past argv array and NULL */
  argv_addr = sp;
  regs->regs_R[MD_REG_R2] = argv_addr;
  sp = sp + (argc + 1) * sizeof(md_addr_t);

  /* save space for envp array and NULL */
  envp_addr = sp;
  for (i=0; envp[i]; i++)
    sp += sizeof(md_addr_t);
  sp += sizeof(md_addr_t);

  /* fill in the argv pointer array and data */
  for (i=0; i<argc; i++)
    {
      /* write the argv pointer array entry */
      temp = sp;
      mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, argv[i]);
      sp += strlen(argv[i])+1;
    }
  /* terminate argv array with a NULL */
  mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* write envp pointer array and data to stack */
  for (i = 0; envp[i]; i++)
    {
      /* write the envp pointer array entry */
      temp = sp;
      mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, envp[i]);
      sp += strlen(envp[i]) + 1;
    }
  /* terminate the envp array with a NULL */
  mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* did we tromp off the stop of the stack? */
  if (sp > ld_stack_base)
    {
      /* we did, indicate to the user that MD_MAX_ENVIRON must be increased,
	 alternatively, you can use a smaller environment, or fewer
	 command line arguments */
      fatal("environment overflow, increase MD_MAX_ENVIRON in arm.h");
    }

  /* initialize the bottom of heap to top of data segment */
  ld_brk_point = ROUND_UP(ld_data_base + ld_data_size, MD_PAGE_SIZE);

  /* set initial minimum stack pointer value to initial stack value */
  ld_stack_min = regs->regs_R[MD_REG_SP];

  regs->regs_R[MD_REG_SP] = ld_environ_base;
  regs->regs_PC = ld_prog_entry;

  debug("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  debug("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  debug("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  debug("ld_prog_entry: 0x%08x", ld_prog_entry);
}
Пример #30
0
/* print the value of an option */
void
opt_print_option(struct opt_opt_t *opt,/* option variable */
		 FILE *fd)		/* output stream */
{
  int i, nelt;

  switch (opt->oc)
    {
    case oc_int:
      if (opt->nelt)
	nelt = *(opt->nelt);
      else
	nelt = 1;
      for (i=0; i<nelt; i++)
	{
	  fprintf(fd, opt->format, opt->variant.for_int.var[i]);
	  fprintf(fd, " ");
	}
      break;
    case oc_uint:
      if (opt->nelt)
	nelt = *(opt->nelt);
      else
	nelt = 1;
      for (i=0; i<nelt; i++)
	{
	  fprintf(fd, opt->format, opt->variant.for_uint.var[i]);
	  fprintf(fd, " ");
	}
      break;
    case oc_ulonglong:
      if (opt->nelt)
        nelt = *(opt->nelt);
      else
        nelt = 1;
      for (i=0; i<nelt; i++)
        {
          myfprintf(fd, opt->format, opt->variant.for_ulonglong.var[i]);
          fprintf(fd, " ");
        }
      break;
    case oc_float:
      if (opt->nelt)
	nelt = *(opt->nelt);
      else
	nelt = 1;
      for (i=0; i<nelt; i++)
	{
	  fprintf(fd, opt->format, (double)opt->variant.for_float.var[i]);
	  fprintf(fd, " ");
	}
      break;
    case oc_double:
      if (opt->nelt)
	nelt = *(opt->nelt);
      else
	nelt = 1;
      for (i=0; i<nelt; i++)
	{
	  fprintf(fd, opt->format, opt->variant.for_double.var[i]);
	  fprintf(fd, " ");
	}
      break;
    case oc_enum:
      if (opt->nelt)
	nelt = *(opt->nelt);
      else
	nelt = 1;
      for (i=0; i<nelt; i++)
	{
	  char *estr = bind_to_str(opt->variant.for_enum.var[i],
				   opt->variant.for_enum.emap,
				   opt->variant.for_enum.eval,
				   opt->variant.for_enum.emap_sz);
	  if (!estr)
	    panic("could not bind enum `%d' for option `%s'",
		  opt->variant.for_enum.var[i], opt->name);

	  fprintf(fd, opt->format, estr);
	  fprintf(fd, " ");
	}
      break;
    case oc_flag:
      if (opt->nelt)
	nelt = *(opt->nelt);
      else
	nelt = 1;
      for (i=0; i<nelt; i++)
	{
	  char *estr = bind_to_str(opt->variant.for_enum.var[i],
				   opt->variant.for_enum.emap,
				   opt->variant.for_enum.eval,
				   opt->variant.for_enum.emap_sz);
	  if (!estr)
	    panic("could not bind boolean `%d' for option `%s'",
		  opt->variant.for_enum.var[i], opt->name);
	  
	  fprintf(fd, opt->format, estr);
	  fprintf(fd, " ");
	}
      break;
    case oc_string:
      if (!opt->nvars)
	{
	  fprintf(fd, "%12s ", "<null>");
	  break;
	}
      if (opt->nelt)
	nelt = *(opt->nelt);
      else
	nelt = 1;
      if (nelt == 0)
	{
	  fprintf(fd, "%12s ", "<null>");
	  break;
	}
      else
	{
	  for (i=0; i<nelt; i++)
	    {
	      fprintf(fd, opt->format,
		      (opt->variant.for_string.var[i]
		       ? opt->variant.for_string.var[i]
		       : "<null>"));
	      fprintf(fd, " ");
	    }
	}
      break;
    default:
      panic("bogus option class");
    }
}