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); } } }
/* ** 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; }
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); }
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++; }
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)); }
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(®,&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(®,&byte_offset); break; case 0xc : /* labels, ENDs and a couple of leftovers */ inc_pc(®,&byte_offset); if(prog_byte<=0xcd) { /* It's a label or an end */ prog_byte=read_byte(®,&byte_offset); if(prog_byte&0x80) { /* high bit is set, it's a label */ /* skip key assignment */ inc_pc(®,&byte_offset); putchar(34); /* double quote */ for(i=0; i<(prog_byte&0xf)-1;i++) { print_char(read_byte(®,&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(®,&byte_offset); inc_pc(®,&byte_offset); break; case 0xf : /* strings */ for(i=0; i<(prog_byte&0xf); i++) { inc_pc(®,&byte_offset); } break; } } }
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; }