Beispiel #1
0
void		read_in_mem(t_vm *vm)
{
  t_proc	*proc;

  for (proc = vm->proc; proc; proc = proc->next)
    if (proc->cur_work == READING)
    {
      if (!proc->rw->size || (proc->rw->cur_pos < proc->rw->size))
      {
	read_mem_value(vm, proc);
	inc_pc(proc->pc);
	proc->rw->cur_pos++;
      }
      if (!(proc->rw->cur_pos < 2) && !proc->rw->size)
      {
        proc->rw->size = get_inst_size(proc->rw->inst);
        proc->rw->delay = get_inst_delay(proc->rw->inst) + 1;
      }
      if (proc->rw->size && proc->rw->cur_pos >= proc->rw->size)
      {
        proc->cur_work = WAITING;
	if (vm->flags & TRACE)
	  trace_mode(vm, proc);
      }
    }
}
Beispiel #2
0
/*
** jmp rx
** Effectue un saut relatif long et inconditionnel de rx quartets
** (PC = PC + rx).
** rx est signe et utilise en entier. Le fonctionnement est independant de P
** et n'affecte pas Z.
*/
int		jmp(t_func_arg *arg)
{
  int		rx, neg;
  int		i;

  if (!arg || !arg->proc)
    return 2;
  if (arg->rx < 1 || arg->rx > 16)
    return 1;
  rx = reg2int(arg->proc->reg[arg->rx - 1]);
  neg = 0;
  if (rx < 0)
    {
      neg = 1;
      rx = -rx;
    }
  for (i = 0; i < rx; i++)
    if (neg)
      dec_pc(arg->proc->pc);
    else
      inc_pc(arg->proc->pc);
  arg->proc->rw->delay = 0;
  arg->proc->cur_work = WAIT_AFTER;
  return 0;
}
Beispiel #3
0
unsigned char read_byte(int *reg, int *byte_offset)
/* Read next byte from program memory and increment the pointer */
  {
    unsigned char prog_byte;
    prog_byte=memory[(*reg)*7+(*byte_offset)];
    inc_pc(reg,byte_offset);
    return(prog_byte);
  }
Beispiel #4
0
void except::behavior(hw_thread_ptr & hardware_thread) {
#else
void except::behavior() {
    hw_thread_ptr hardware_thread = in.read();
#endif /* _NO_SYSTEMC_ */

    /* Check if the hardware thread is enabled */
    if (_is_not_valid_hwthread(hardware_thread)) {
        return;
    }
    /* Everytime an instruction goes through this stage, increase its
       cycle count to 6 */
    hardware_thread->cnt_cycles += 6;

    /* If fetch stage is stalled then just increment the cycle count
    and return. */
    if (hardware_thread->is_fetch_stalled()) {
        return;
    }

    debug(hardware_thread);

    /* If the current instruction is a double word then set a flag to
       note it */
    set_dword_state(hardware_thread);

    /* If deadline is causing a stall then let skip out of this stage */
    if (dead_stalled(hardware_thread)) {
        return;
    }

    /* If the instruction fetch caused a stall then skip out of this
       stage */
    if (fetch_stalled(hardware_thread)) {
        return;
    }
    /* If memory is causing a stall then skip out of this stage */
    if (mem_stalled(hardware_thread)) {
        return;
    }

    if (!hardware_thread->is_db_word_stalled()) {
        /* Increment the PC based */
        inc_pc(hardware_thread);
    }

    write_regs(hardware_thread);
    write_special_regs(hardware_thread);

    /* Increment the number of instructions executed */
    hardware_thread->cnt_instr++;

}
Beispiel #5
0
int		get_int(t_core *c, t_proc *p)
{
	char	nb[4];
	int		i;

	i = 0;
	while (i < 4)
	{
		nb[i] = c->mem[p->pc % MEM_SIZE];
		inc_pc(p, 1);
		i++;
	}
	return (int_swap(*(int *)nb));
}
Beispiel #6
0
void prog_labels(int curtain, int global_end)
/* Display the global labels and ENDs from program memory */
  {
    int reg, byte_offset; /* Program counter */
    unsigned char prog_byte; /* Current program byte */
    unsigned char global_flag=0; /* set when global END found */
    int i; /* loop counter */

    /* Initialise program counter */
    reg=curtain-1; byte_offset=0;

    /* Scan program memory */
    while((!global_flag) && (reg>=global_end))
      {
        /* look at the next byte of the program */
        switch((prog_byte=read_byte(&reg,&byte_offset))>>4)
          {
            /* Bytes 0x00-0x8f are single-byte instructions, so nothing to
               do. Alpha XEQ/GTO are treated as a single-byte follwed by 
               a string. */
            case 0x9 :
            case 0xa :
            case 0xb : /* 2 byte instructions, skip suffix */
                       inc_pc(&reg,&byte_offset);
                       break;
            case 0xc : /* labels, ENDs and a couple of leftovers */
                       inc_pc(&reg,&byte_offset);
                       if(prog_byte<=0xcd)
                         {
                           /* It's a label or an end */
                           prog_byte=read_byte(&reg,&byte_offset);
                           if(prog_byte&0x80)
                             {
                               /* high bit is set, it's a label */
                               /* skip key assignment */
                               inc_pc(&reg,&byte_offset); 
                               putchar(34); /* double quote */
                               for(i=0; i<(prog_byte&0xf)-1;i++)
                                 {
                                   print_char(read_byte(&reg,&byte_offset));
                                 }
                               putchar(34);
                               printf("\n");
                             }
                           else
                             {
                               /* It's an END */
                               if(prog_byte&0x20)
                                 {
                                   /* It's the global END */
                                   printf(".END.\n");
                                   global_flag=1;
                                 }
                               else
                                 {
                                   printf("END\n");
                                 }
                             }
                         }
                       break;
            case 0xd :
            case 0xe : /* 3 byte instructions, skip 2 more bytes */
                       inc_pc(&reg,&byte_offset);
                       inc_pc(&reg,&byte_offset);
                       break;
            case 0xf : /* strings */
                       for(i=0; i<(prog_byte&0xf); i++)
                         {
                           inc_pc(&reg,&byte_offset);
                         }
                       break;
          }
      }
  }
Beispiel #7
0
buzzvm_state buzzvm_step(buzzvm_t vm) {
   /* buzzvm_dump(vm); */
   /* Can't execute if not ready */
   if(vm->state != BUZZVM_STATE_READY) return vm->state;
   /* Execute GC */
   buzzheap_gc(vm);
   /* Fetch instruction and (potential) argument */
   uint8_t instr = vm->bcode[vm->pc];
   /* Execute instruction */
   switch(instr) {
      case BUZZVM_INSTR_NOP: {
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_DONE: {
         buzzvm_done(vm);
         break;
      }
      case BUZZVM_INSTR_PUSHNIL: {
         inc_pc();
         buzzvm_pushnil(vm);
         break;
      }
      case BUZZVM_INSTR_DUP: {
         inc_pc();
         buzzvm_dup(vm);
         break;
      }
      case BUZZVM_INSTR_POP: {
         if(buzzvm_pop(vm) != BUZZVM_STATE_READY) return vm->state;
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_RET0: {
         if(buzzvm_ret0(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_RET1: {
         if(buzzvm_ret1(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_ADD: {
         buzzvm_add(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_SUB: {
         buzzvm_sub(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_MUL: {
         buzzvm_mul(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_DIV: {
         buzzvm_div(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_MOD: {
         buzzvm_mod(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_POW: {
         buzzvm_pow(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_UNM: {
         buzzvm_unm(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_AND: {
         buzzvm_and(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_OR: {
         buzzvm_or(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_NOT: {
         buzzvm_not(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_EQ: {
         buzzvm_eq(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_NEQ: {
         buzzvm_neq(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_GT: {
         buzzvm_gt(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_GTE: {
         buzzvm_gte(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_LT: {
         buzzvm_lt(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_LTE: {
         buzzvm_lte(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_GLOAD: {
         inc_pc();
         buzzvm_gload(vm);
         break;
      }
      case BUZZVM_INSTR_GSTORE: {
         inc_pc();
         if(buzzvm_gstore(vm) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHT: {
         buzzvm_pusht(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_TPUT: {
         if(buzzvm_tput(vm) != BUZZVM_STATE_READY) return vm->state;
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_TGET: {
         if(buzzvm_tget(vm) != BUZZVM_STATE_READY) return vm->state;
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_CALLC: {
         inc_pc();
         if(buzzvm_callc(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_CALLS: {
         inc_pc();
         if(buzzvm_calls(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_PUSHF: {
         inc_pc();
         get_arg(float);
         if(buzzvm_pushf(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHI: {
         inc_pc();
         get_arg(int32_t);
         if(buzzvm_pushi(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHS: {
         inc_pc();
         get_arg(int32_t);
         if(buzzvm_pushs(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHCN: {
         inc_pc();
         get_arg(uint32_t);
         if(buzzvm_pushcn(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHCC: {
         inc_pc();
         get_arg(uint32_t);
         if(buzzvm_pushcc(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHL: {
         inc_pc();
         get_arg(uint32_t);
         if(buzzvm_pushl(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_LLOAD: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_lload(vm, arg);
         break;
      }
      case BUZZVM_INSTR_LSTORE: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_lstore(vm, arg);
         break;
      }
      case BUZZVM_INSTR_JUMP: {
         inc_pc();
         get_arg(uint32_t);
         vm->pc = arg;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_JUMPZ: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_stack_assert(vm, 1);
         if(buzzvm_stack_at(vm, 1)->o.type == BUZZTYPE_NIL ||
            (buzzvm_stack_at(vm, 1)->o.type == BUZZTYPE_INT &&
             buzzvm_stack_at(vm, 1)->i.value == 0)) {
            vm->pc = arg;
            assert_pc(vm->pc);
         }
         buzzvm_pop(vm);
         break;
      }
      case BUZZVM_INSTR_JUMPNZ: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_stack_assert(vm, 1);
         if(buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_NIL &&
            (buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_INT ||
             buzzvm_stack_at(vm, 1)->i.value != 0)) {
            vm->pc = arg;
            assert_pc(vm->pc);
         }
         buzzvm_pop(vm);
         break;
      }
      default:
         buzzvm_seterror(vm, BUZZVM_ERROR_INSTR, NULL);
         break;
   }
   return vm->state;
}