예제 #1
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void opc_cmp_handler(char *opd1,char *opd2,char *offset,char *immi){
int ans;
int dec_opd2=bintodec(opd2);
if(immi[1]=='0'){
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
int val_opd2=get_reg_val(dec_opd2);
ans=val_opd2-get_reg_val(dec_opd1);
}
else{
int dec_im_opd1=bintodec(opd1);
ans=get_reg_val(dec_opd2)-dec_im_opd1;
}
}
else{
int dec_off=bintodec(offset);
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
ans=get_mem_val(dec_opd2+dec_off)-get_reg_val(dec_opd1);
}
else{
int dec_im_opd1=bintodec(opd1);
ans=get_mem_val(dec_opd2+dec_off)-dec_im_opd1;
}
}
if(ans==0){
set_reg_val(regfile+R_FLAGS,0);
}
else if(ans>0){
set_reg_val(regfile+R_FLAGS,1);
}
else{
set_reg_val(regfile+R_FLAGS,2);
}
}
예제 #2
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void init_regs(int k){
if(k==0){
int i;
for(i=0;i<32;i++){
set_reg_val(regfile+i,0);
}
set_reg_val(regfile+8,100);
}
}
예제 #3
0
파일: psim.c 프로젝트: kywe665/ECEn-324
/* May need to disable updating of memory & condition codes */
static void update_state(bool_t update_mem, bool_t update_cc)
{
    /* Writeback(s):
       If either register is REG_NONE, write will have no effect .
       Order of two writes determines semantics of
       popl %esp.  According to ISA, %esp will get popped value
    */

    if (wb_destE != REG_NONE) {
	sim_log("Writeback: Wrote 0x%x to register %s\n",
		wb_valE, reg_name(wb_destE));
	set_reg_val(reg, wb_destE, wb_valE);
    }
    if (wb_destM != REG_NONE) {
	sim_log("Writeback: Wrote 0x%x to register %s\n",
		wb_valM, reg_name(wb_destM));
	set_reg_val(reg, wb_destM, wb_valM);
    }

    /* Memory write */
    if (mem_write && !update_mem) {
	sim_log("Disabled write of 0x%x to address 0x%x\n", mem_data, mem_addr);
    }
    if (update_mem && mem_write) {
	if (!set_word_val(mem, mem_addr, mem_data)) {
	    sim_log("Couldn't write to address 0x%x\n", mem_addr);
	} else {
	    sim_log("Wrote 0x%x to address 0x%x\n", mem_data, mem_addr);

#ifdef HAS_GUI
	    if (gui_mode) {
		if (mem_addr % 4 != 0) {
		    /* Just did a misaligned write.
		       Need to display both words */
		    word_t align_addr = mem_addr & ~0x3;
		    word_t val;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		    align_addr+=4;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		} else {
		    set_memory(mem_addr, mem_data);
		}
	    }
#endif

	}
    }
    if (update_cc)
	cc = cc_in;
}
예제 #4
0
/* May need to disable updating of memory & condition codes */
static void update_state(bool_t update_mem, bool_t update_cc)
{
    /* Writeback(s):
       If either register is REG_NONE, write will have no effect .
       Order of two writes determines semantics of
       popl %esp.  According to ISA, %esp will get popped value
       */

    if (wb_destE != REG_NONE) {
        sim_log("\tWriteback: Wrote 0x%x to register %s\n",
                wb_valE, reg_name(wb_destE));
        set_reg_val(reg, wb_destE, wb_valE);
        //printf("set_reg_valE %d %d %d\n", PSIM_ID, wb_destE, wb_valE);
        //fflush(stdout);
    }
    if (wb_destM != REG_NONE && wb_testM == REG_NONE) {
        sim_log("\tWriteback: Wrote 0x%x to register %s\n",
                wb_valM, reg_name(wb_destM));
        set_reg_val(reg, wb_destM, wb_valM);
        //printf("set_reg_valM %d %d %d\n", PSIM_ID, wb_destM, wb_valM);
        //fflush(stdout);
    }

    /* Memory write */

    if(wb_testM != REG_NONE){
        set_reg_val(reg, wb_testM, wb_valM);
        printf("PSIM_ID %d test_result:  %d on %d\n", PSIM_ID, wb_valM, mem_test_address);
        //fflush(stdout);
    }

    if (mem_write && !update_mem) {
        sim_log("\tDisabled write of 0x%x to address 0x%x\n", mem_data, mem_addr);
    }
    if (update_mem && mem_write) {
//        printf("WRITE: %d %d\n", mem_addr, mem_data);
        if (!set_word_val(mem, mem_addr, mem_data)) {
            sim_log("\tCouldn't write to address 0x%x\n", mem_addr);
        } else {
            sim_log("\tWrote 0x%x to address 0x%x\n", mem_data, mem_addr);
        }
        /*
        int ans;
        printf("%d %d\n",mem_addr, mem_data);
        int b = get_word_val(mem, mem_addr, &ans);
        printf("%d\n", ans);
        */
    }
    if (update_cc)
        cc = cc_in;
}
예제 #5
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void execute(_decoder_output *decoded_instr){
instr_handlers[0]=opc_add_handler;
instr_handlers[1]=opc_sub_handler;
instr_handlers[2]=opc_mov_handler;
instr_handlers[3]=opc_and_handler;
instr_handlers[4]=opc_xor_handler;
instr_handlers[5]=opc_or_handler;
instr_handlers[6]=opc_cmp_handler;

instr_handlers[8]=opc_xchange_handler;
instr_handlers[9]=opc_push_handler;
instr_handlers[10]=opc_pop_handler;
instr_handlers[11]=opc_mul_handler;
instr_handlers[12]=opc_mul_handler;
instr_handlers[13]=opc_div_handler;
instr_handlers[14]=opc_div_handler;
instr_handlers[15]=opc_jmp_handler;
instr_handlers[16]=opc_je_handler;
instr_handlers[17]=opc_jne_handler;
instr_handlers[18]=opc_jg_handler;
instr_handlers[19]=opc_jge_handler;
instr_handlers[20]=opc_jl_handler;
instr_handlers[21]=opc_jle_handler;
instr_handlers[22]=opc_jmp_handler;
if(clock>2){
int dec_opc=bintodec(decoded_instr->opc);
if(dec_opc==63){
printf("\n\npc is %d\n",get_reg_val(15));
printf("\n\nregister file is\n");
print(regfile);
printf("\n\nmemory is\n");
print(mem);
printf("exiting");
exit(0);
}
instr_handlers[dec_opc](decoded_instr->opd1,decoded_instr->opd2,decoded_instr->offset,decoded_instr->immi);
}
switch(pending_bds){
case 2:
set_reg_val(regfile+REG_PC,get_reg_val(REG_PC)+1);
pending_bds--;
break;
case 1:
set_reg_val(regfile+REG_PC,get_reg_val(REG_NEXTPC)-2);
pending_bds--;
break;
case 0:
set_reg_val(regfile+REG_PC,get_reg_val(REG_PC)+1);
break;
}
}
예제 #6
0
파일: ssim.c 프로젝트: kywe665/ECEn-324
/* Update the processor state */
static exc_t update_state()
{
    exc_t status = EXC_NONE;
    if (plusmode) {
	prev_icode = prev_icode_in;
	prev_ifun  = prev_ifun_in;
	prev_valc  = prev_valc_in;
	prev_valm  = prev_valm_in;
	prev_valp  = prev_valp_in;
	prev_bcond = prev_bcond_in;
    } else {
	pc = pc_in;
    }
    cc = cc_in;
    /* Writeback */
    if (destE != REG_NONE)
	set_reg_val(reg, destE, vale);
    if (destM != REG_NONE)
	set_reg_val(reg, destM, valm);

    if (mem_write) {
	if (!set_word_val(mem, mem_addr, mem_data)) {
	    sim_log("Couldn't write to address 0x%x\n", mem_addr);
	    status = EXC_ADDR;
	} else {
	    sim_log("Wrote 0x%x to address 0x%x\n", mem_data, mem_addr);

#ifdef HAS_GUI
	    if (gui_mode) {
		if (mem_addr % 4 != 0) {
		    /* Just did a misaligned write.
		       Need to display both words */
		    word_t align_addr = mem_addr & ~0x3;
		    word_t val;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		    align_addr+=4;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		} else {
		    set_memory(mem_addr, mem_data);
		}
	    }
#endif// HAS_GUI

	}
    }
    return status;
}
예제 #7
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void opc_pop_handler(char *opd1,char *opd2,char *offset,char *immi){
int ans;
int dec_opd2=bintodec(opd2);
int val_esp=get_reg_val(8);
if(immi[1]=='0'){
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
int val_mem=get_mem_val(mem+val_esp);
ans=val_mem;
set_reg_val(regfile+dec_opd1,ans);
}
}
int new_esp=get_reg_val(8)+1;
set_reg_val(regfile+8,new_esp);
}
예제 #8
0
int execute_command(PVRDMADev *dev)
{
    int err = 0xFFFF;
    DSRInfo *dsr_info;

    dsr_info = &dev->dsr_info;

    pr_dbg("cmd=%d\n", dsr_info->req->hdr.cmd);
    if (dsr_info->req->hdr.cmd >= sizeof(cmd_handlers) /
                      sizeof(struct cmd_handler)) {
        pr_dbg("Unsupported command\n");
        goto out;
    }

    if (!cmd_handlers[dsr_info->req->hdr.cmd].exec) {
        pr_dbg("Unsupported command (not implemented yet)\n");
        goto out;
    }

    err = cmd_handlers[dsr_info->req->hdr.cmd].exec(dev, dsr_info->req,
                            dsr_info->rsp);
out:
    set_reg_val(dev, PVRDMA_REG_ERR, err);
    post_interrupt(dev, INTR_VEC_CMD_RING);

    return (err == 0) ? 0 : -EINVAL;
}
예제 #9
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
int load_program(char *fname){
FILE *ifp;
char ch;
int i=0,j=0;
ifp= fopen(fname,"r");
while((ch=fgetc(ifp))!=EOF){
if(ch=='\n' && j==0)
continue;
if(ch=='\n'){
j++;
ch='\0';
mem[i].data[j]=ch;
i++;
j=0;
}
else{
mem[i].data[j]=ch;
j++;
}
}
if(j!=0){
mem[i].data[j]='\0';
}
set_reg_val(mem+i,0);
fclose(ifp);
return 0;
}
예제 #10
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void init_memory(int k){
if(k==0){
int i;
for(i=0;i<216;i++){
set_reg_val(mem+i,0);
}
}
}
예제 #11
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void opc_jmp_handler(char *opd1,char *opd2,char *offset,char *immi){
int ans;
int dec_opd2=bintodec(opd2);
if(immi[1]=='0'){
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
ans=get_reg_val(dec_opd1)-1;
set_reg_val(regfile+16,ans);
}
else{
int dec_im_opd1=bintodec(opd1);
ans=dec_im_opd1-1;
set_reg_val(regfile+16,ans);
}
}
pending_bds=2;
}
예제 #12
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void opc_div_handler(char *opd1,char *opd2,char *offset,char *immi){
int ans;
int dec_opd2=bintodec(opd2);
if(immi[1]=='0'){
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
int val_eax=get_reg_val(0);
ans=val_eax/get_reg_val(dec_opd1);
set_reg_val(regfile+0,ans);
}
else{
int dec_im_opd1=bintodec(opd1);
ans=get_reg_val(0)/dec_im_opd1;
set_reg_val(regfile+0,ans);
}
}
}
예제 #13
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void start_cpu(void){
int RESET_VEC_ADDR=0;
set_reg_val(regfile+16,RESET_VEC_ADDR);     //NEXT_PC
set_reg_val(regfile+15,get_reg_val(REG_NEXTPC)-2);   //PC
pending_bds =0 ;
while(1){
if(no_of_ins-1>stop_ins){
printf("\n\npc is %d\n",get_reg_val(15));
printf("\n\nregister file is\n");
print(regfile);
printf("\n\nmemory is\n");
print(mem);
exit(0);
}
start_new_cycle();
exec_pipeline_stages();
}
}
예제 #14
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void opc_push_handler(char *opd1,char *opd2,char *offset,char *immi){
int ans;
int dec_opd2=bintodec(opd2);
int val_esp=get_reg_val(8);
if(immi[1]=='0'){
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
ans=get_reg_val(dec_opd1);
set_reg_val(mem+val_esp,ans);
}
else{
int dec_im_opd1=bintodec(opd1);
ans=dec_im_opd1;
set_reg_val(mem+val_esp,ans);
}
}
int new_esp=get_reg_val(8)-1;
set_reg_val(regfile+8,new_esp);
}
예제 #15
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void decode( char *instr, _decoder_output *out){
if(instr){
get_opcode(instr,out);
get_operands(instr,out);
}
else{
out->opc[0] = '\0';
}
set_reg_val(regfile+REG_NEXTPC,get_reg_val(REG_NEXTPC)+1);
}
예제 #16
0
int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
{
	int r = 0;
	union kvmppc_one_reg val;
	int size;

	size = one_reg_size(reg->id);
	if (size > sizeof(val))
		return -EINVAL;

	r = kvmppc_get_one_reg(vcpu, reg->id, &val);
	if (r == -EINVAL) {
		r = 0;
		switch (reg->id) {
#ifdef CONFIG_ALTIVEC
		case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
				r = -ENXIO;
				break;
			}
			vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
			break;
		case KVM_REG_PPC_VSCR:
			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
				r = -ENXIO;
				break;
			}
			vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val);
			break;
		case KVM_REG_PPC_VRSAVE:
			if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
				r = -ENXIO;
				break;
			}
			vcpu->arch.vrsave = set_reg_val(reg->id, val);
			break;
#endif /* CONFIG_ALTIVEC */
		default:
			r = -EINVAL;
			break;
		}
	}
예제 #17
0
파일: ssim.c 프로젝트: Azard/icslabs
/* Update the processor state */
static void update_state()
{
    if (plusmode) {
	prev_icode = prev_icode_in;
	prev_ifun  = prev_ifun_in;
	prev_valc  = prev_valc_in;
	prev_valm  = prev_valm_in;
	prev_valp  = prev_valp_in;
	prev_bcond = prev_bcond_in;
    } else {
	pc = pc_in;
    }
    cc = cc_in;
    /* Writeback */
    if (destE != REG_NONE)
	set_reg_val(reg, destE, vale);
    if (destM != REG_NONE)
	set_reg_val(reg, destM, valm);

    if (mem_write) {
      /* Should have already tested this address */
      set_word_val(mem, mem_addr, mem_data);
	sim_log("Wrote 0x%x to address 0x%x\n", mem_data, mem_addr);
#ifdef HAS_GUI
	    if (gui_mode) {
		if (mem_addr % 4 != 0) {
		    /* Just did a misaligned write.
		       Need to display both words */
		    word_t align_addr = mem_addr & ~0x3;
		    word_t val;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		    align_addr+=4;
		    get_word_val(mem, align_addr, &val);
		    set_memory(align_addr, val);
		} else {
		    set_memory(mem_addr, mem_data);
		}
	    }
#endif /* HAS_GUI */
    }
}
예제 #18
0
파일: HDER.C 프로젝트: venzhega/aokt
void main(void) {

	unsigned       hder = 0, new_hder = 0;
	unsigned       crt_address;
	BIOS_VAR _far  *bios_var_ptr;
	unsigned       i = 0;

	// Получаем указатель на область переменных видеофункций BIOS
	bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);

	// Определяем адрес порта индексного регистра контроллера ЭЛТ
	crt_address = bios_var_ptr->crt_address;

	disable_protection_mode(crt_address);

	// Читаем значение HDER
	hder = get_reg_val(crt_address, HDER);

    // Очищаем экран
	clrscr();

	printf("\nТекущее значение HDER регистра %d\n", hder);

	for (i = 0; i < hder; i++)
	{
	    printf("*");
	}
	
	printf("\nВведите длину отображаемой части горизонтальной развертки:");
	scanf("%d", &new_hder);
	
	// Устанавливаем новое значение
	set_reg_val(crt_address, HDER, new_hder);

	printf("\nДля завершения программы нажмите любую клавишу");

	getch();

	// Восстанавливаем значение по умолчанию
	set_reg_val(crt_address, HDER, hder);
}
예제 #19
0
파일: prog.c 프로젝트: dvrvrm/32-bit_ism
void opc_xchange_handler(char *opd1,char *opd2,char *offset,char *immi){
int ans1,ans2;
int dec_opd2=bintodec(opd2);
if(immi[1]=='0'){
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
int val_opd2=get_reg_val(dec_opd2);
ans1=get_reg_val(dec_opd1);
set_reg_val(regfile+dec_opd2,ans1);
ans2=get_reg_val(dec_opd2);
set_reg_val(regfile+dec_opd1,ans2);
}
}
else{
int dec_off=bintodec(offset);
if(immi[0]=='0'){
int dec_opd1=bintodec(opd1);
ans1=get_mem_val(dec_opd2+dec_off)+get_reg_val(dec_opd1);
set_reg_val(mem+dec_opd2+dec_off,ans1);
ans2=get_mem_val(dec_opd2+dec_off);
set_reg_val(regfile+dec_opd1,ans2);
}
}
}
예제 #20
0
/* Execute single instruction.  Return exception condition. */
exc_t step_state(state_ptr s, FILE *error_file)
{
    word_t argA, argB;
    byte_t byte0 = 0;
    byte_t byte1 = 0;
    itype_t hi0;
    alu_t  lo0;
    reg_id_t hi1 = REG_NONE;
    reg_id_t lo1 = REG_NONE;
    bool_t ok1 = TRUE;
    word_t cval;
    word_t okc = TRUE;
    word_t val, dval;
    bool_t need_regids;
    bool_t need_imm;

    word_t ftpc = s->pc;

    if (!get_byte_val(s->m, ftpc, &byte0)) {
	if (error_file)
	    fprintf(error_file,
		    "PC = 0x%x, Invalid instruction address\n", s->pc);
	return EXC_ADDR;
    }
    ftpc++;

    hi0 = HI4(byte0);
    lo0 = LO4(byte0);

    need_regids =
	(hi0 == I_RRMOVL || hi0 == I_ALU || hi0 == I_PUSHL ||
	 hi0 == I_POPL || hi0 == I_IRMOVL || hi0 == I_RMMOVL ||
	 hi0 == I_MRMOVL || hi0 == I_ALUI);

    if (need_regids) {
	ok1 = get_byte_val(s->m, ftpc, &byte1);
	ftpc++;
	hi1 = HI4(byte1);
	lo1 = LO4(byte1);
    }

    need_imm =
	(hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL ||
	 hi0 == I_JXX || hi0 == I_CALL || hi0 == I_ALUI);

    if (need_imm) {
	okc = get_word_val(s->m, ftpc, &cval);
	ftpc += 4;
    }

    switch (hi0) {
    case I_NOP:
	s->pc = ftpc;
	break;
    case I_HALT:
	s->pc = ftpc;
	return EXC_HALT;
	break;
    case I_RRMOVL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (hi1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return EXC_INSTR;
	}
	if (lo1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return EXC_INSTR;
	}
	val = get_reg_val(s->r, hi1);
	set_reg_val(s->r, lo1, val);
	s->pc = ftpc;
	break;

	#if 0
    case I_IRMOVL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return EXC_INSTR;
	}
	if (lo1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return EXC_INSTR;
	}
	set_reg_val(s->r, lo1, cval);
	s->pc = ftpc;
	break;
	#endif
	
    case I_RMMOVL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_INSTR;
	}
	if (hi1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return EXC_INSTR;
	}
	if (lo1 < 8) 
	    cval += get_reg_val(s->r, lo1);
	val = get_reg_val(s->r, hi1);
	if (!set_word_val(s->m, cval, val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid data address 0x%x\n",
			s->pc, cval);
	    return EXC_ADDR;
	}
	s->pc = ftpc;
	break;
    case I_MRMOVL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction addres\n", s->pc);
	    return EXC_INSTR;
	}
	if (hi1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return EXC_INSTR;
	}
	if (lo1 < 8) 
	    cval += get_reg_val(s->r, lo1);
	if (!get_word_val(s->m, cval, &val))
	    return EXC_ADDR;
	set_reg_val(s->r, hi1, val);
	s->pc = ftpc;
	break;
    case I_ALU:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	argA = get_reg_val(s->r, hi1);
	argB = get_reg_val(s->r, lo1);
	val = compute_alu(lo0, argA, argB);
	set_reg_val(s->r, lo1, val);
	s->cc = compute_cc(lo0, argA, argB);
	s->pc = ftpc;
	break;
    case I_JXX:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (take_branch(s->cc, lo0))
	    s->pc = cval;
	else
	    s->pc = ftpc;
	break;
    #if 0
    case I_CALL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	val = get_reg_val(s->r, REG_ESP) - 4;
	set_reg_val(s->r, REG_ESP, val);
	if (!set_word_val(s->m, val, ftpc)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n", s->pc, val);
	    return EXC_ADDR;
	}
	s->pc = cval;
	break;
    case I_RET:
	/* Return Instruction.  Pop address from stack */
	dval = get_reg_val(s->r, REG_ESP);
	if (!get_word_val(s->m, dval, &val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n",
			s->pc, dval);
	    return EXC_ADDR;
	}
	set_reg_val(s->r, REG_ESP, dval + 4);
	s->pc = val;
	break;
    #endif
    case I_PUSHL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (hi1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1);
	    return EXC_INSTR;
	}
	val = get_reg_val(s->r, hi1);
	dval = get_reg_val(s->r, REG_ESP) - 4;
	set_reg_val(s->r, REG_ESP, dval);
	if  (!set_word_val(s->m, dval, val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval);
	    return EXC_ADDR;
	}
	s->pc = ftpc;
	break;
    case I_POPL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (hi1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1);
	    return EXC_INSTR;
	}
	dval = get_reg_val(s->r, REG_ESP);
	set_reg_val(s->r, REG_ESP, dval+4);
	if (!get_word_val(s->m, dval, &val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n",
			s->pc, dval);
	    return EXC_ADDR;
	}
	set_reg_val(s->r, hi1, val);
	s->pc = ftpc;
	break;
    case I_LEAVE:
	dval = get_reg_val(s->r, REG_EBP);
	set_reg_val(s->r, REG_ESP, dval+4);
	if (!get_word_val(s->m, dval, &val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n",
			s->pc, dval);
	    return EXC_ADDR;
	}
	set_reg_val(s->r, REG_EBP, val);
	s->pc = ftpc;
	break;

	#if 0
    case I_ALUI:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return EXC_ADDR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return EXC_INSTR;
	}
	if (lo1 >= 8) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return EXC_INSTR;
	}
	argB = get_reg_val(s->r, lo1);
	val = argB + cval;
	set_reg_val(s->r, lo1, val);
	s->cc = compute_cc(A_ADD, cval, argB);
	s->pc = ftpc;
	break;
	#endif
	
    default:
	if (error_file)
	    fprintf(error_file,
		    "PC = 0x%x, Invalid instruction %.2x\n", s->pc, byte0);
	return EXC_INSTR;
    }
    return EXC_NONE;
}
예제 #21
0
파일: dbg.hpp 프로젝트: trietptm/usefulres
inline bool set_reg_val(const char *regname, ulonglong ival)
{
  regval_t regval;
  regval.ival = ival;
  return set_reg_val(regname, &regval);
}
예제 #22
0
파일: y86sim.c 프로젝트: Azard/icslabs
/* 
 * nexti: execute single instruction and return status.
 * args
 *     sim: the y86 image with PC, register and memory
 *
 * return
 *     STAT_AOK: continue
 *     STAT_HLT: halt
 *     STAT_ADR: invalid instruction address
 *     STAT_INS: invalid instruction, register id, data address, stack address, ...
 */
stat_t nexti(y86sim_t *sim)
{
    byte_t codefun = 0;
    itype_t icode;
    alu_t ifun;
    long_t next_pc = sim->pc;
	regid_t rA = REG_NONE;
	regid_t rB = REG_NONE;
	long_t im_value = 0;

    /* get code and function (1 byte) */
    if (!get_byte_val(sim->m, next_pc, &codefun)) {
        err_print("PC = 0x%x, Invalid instruction address", sim->pc);
        return STAT_ADR;
    }
    icode = GET_ICODE(codefun);
    ifun = GET_FUN(codefun);
    next_pc++;

    /* get registers if needed (1 byte) */
	byte_t reg = 0;
	switch (icode)
	{
		case I_RRMOVL:
		case I_IRMOVL:
		case I_RMMOVL:
		case I_MRMOVL:
		case I_ALU:
		case I_PUSHL:
		case I_POPL:
			if(!get_byte_val(sim->m, next_pc, &reg)) {
				err_print("PC = 0x%x, Invalid instruction address", sim->pc);
				return STAT_ADR;
			}
			rA = GET_REGA(reg);
			rB = GET_REGB(reg);
			next_pc++;

		case I_HALT:case I_NOP:case I_JMP:case I_CALL:case I_RET:default:
			break;
	}

    /* get immediate if needed (4 bytes) */
	switch(icode)
	{
		case I_IRMOVL:
		case I_RMMOVL:
		case I_MRMOVL:
		case I_JMP:
		case I_CALL:
			if(!get_long_val(sim->m, next_pc, &im_value)) {
				err_print("PC = 0x%x, Invalid instruction address", sim->pc);				return STAT_ADR;
			}
			next_pc += 4;

		case I_HALT:case I_NOP:case I_RRMOVL:case I_ALU:
		case I_RET:case I_PUSHL:case I_POPL:default:
			break;	
	}

    /* execute the instruction */
    switch (icode) {
      case I_HALT: /* 0:0 */
        return STAT_HLT;
        break;
      case I_NOP: /* 1:0 */
        sim->pc = next_pc;
        break;

      case I_RRMOVL:/* 2:x regA:regB */
		{
			long_t rr_temp = get_reg_val(sim->r, rA);
			if (cond_doit(sim->cc, ifun))	
				set_reg_val(sim->r, rB, rr_temp);
			sim->pc = next_pc;	
			break;
		}

      case I_IRMOVL: /* 3:0 F:regB imm */
		{
			set_reg_val(sim->r, rB, im_value);
			sim->pc = next_pc;
			break;
		}

      case I_RMMOVL: /* 4:0 regA:regB imm */
		{
			long_t rm_temp_rA = get_reg_val(sim->r, rA);
			long_t rm_temp_rB = get_reg_val(sim->r, rB);
			set_long_val(sim->m, im_value+rm_temp_rB, rm_temp_rA);
			sim->pc = next_pc;
			break;
		}

      case I_MRMOVL: /* 5:0 regB:regA imm */
		{ 
			long_t mr_temp_rB = get_reg_val(sim->r, rB);
			long_t temp_val = 0;
			if(!get_long_val(sim->m, im_value+mr_temp_rB, &temp_val))
			{
				err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, im_value+mr_temp_rB);
				return STAT_ADR;
			}
			set_reg_val(sim->r, rA, temp_val);
			sim->pc = next_pc;
			break;
		}

	  case I_ALU: /* 6:x regA:regB */
		{
			long_t rA_val = get_reg_val(sim->r, rA);
			long_t rB_val = get_reg_val(sim->r, rB);
			long_t alu_result = 0;
			switch (ifun)
			{
				case A_ADD:case A_SUB:case A_AND:case A_XOR:
					alu_result = compute_alu(ifun, rA_val, rB_val);
					set_reg_val(sim->r, rB, alu_result);
					break;
				case A_NONE:default:
					return STAT_INS;
			}
			sim->cc = compute_cc(ifun, rA_val, rB_val, alu_result);
			sim->pc = next_pc;
			break;
		}

      case I_JMP: /* 7:x imm */
		{
			if (cond_doit(sim->cc, ifun))
				sim->pc = im_value;
			else
				sim->pc=next_pc;
			break;

		}
      case I_CALL: /* 8:x imm */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			esp -= 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			set_long_val(sim->m, esp, next_pc);
			sim->pc = im_value;
			break;
		}

      case I_RET: /* 9:0 */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			long_t return_value = 0;
			if(!get_long_val(sim->m, esp, &return_value))
			{
				err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			esp += 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			sim->pc = return_value;
			break;
		}

      case I_PUSHL: /* A:0 regA:F */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			long_t rA_value  = get_reg_val(sim->r, rA);
			esp -= 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			set_long_val(sim->m, esp, rA_value);
			sim->pc = next_pc;
			break;
		}

      case I_POPL: /* B:0 regA:F */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			long_t temp_value = 0;
			if(!get_long_val(sim->m, esp, &temp_value))
			{
				err_print("PC = 0x%x, Invalid instruction address", esp);
				return STAT_ADR;
			}
			esp += 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			set_reg_val(sim->r, rA, temp_value);
			sim->pc = next_pc;
			break;
		}
		
		return STAT_INS; /* unsupported now, replace it with your implementation */
		break;
	  default:
        err_print("PC = 0x%x, Invalid instruction %.2x", sim->pc, codefun);
        return STAT_INS;
    }
    
    return STAT_AOK;
}
예제 #23
0
/* Execute single instruction.  Return status. */
stat_t step_state(state_ptr s, FILE *error_file)
{
    word_t argA, argB;
    byte_t byte0 = 0;
    byte_t byte1 = 0;
    itype_t hi0;
    alu_t  lo0;
    reg_id_t hi1 = REG_NONE;
    reg_id_t lo1 = REG_NONE;
    bool_t ok1 = TRUE;
    word_t cval = 0;
    word_t okc = TRUE;
    word_t val, dval;
    bool_t need_regids;
    bool_t need_imm;
    word_t ftpc = s->pc;  /* Fall-through PC */

    if (!get_byte_val(s->m, ftpc, &byte0)) {
	if (error_file)
	    fprintf(error_file,
		    "PC = 0x%x, Invalid instruction address\n", s->pc);
	return STAT_ADR;
    }
    ftpc++;

    hi0 = HI4(byte0);
    lo0 = LO4(byte0);

    need_regids =
	(hi0 == I_RRMOVL || hi0 == I_ALU || hi0 == I_PUSHL ||
	 hi0 == I_POPL || hi0 == I_IRMOVL || hi0 == I_RMMOVL ||
	 hi0 == I_MRMOVL || hi0 == I_IADDL || hi0 == I_ISUBL);

    if (need_regids) {
	ok1 = get_byte_val(s->m, ftpc, &byte1);
	ftpc++;
	hi1 = HI4(byte1);
	lo1 = LO4(byte1);
    }

    need_imm =
	(hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL ||
	 hi0 == I_JMP || hi0 == I_CALL || hi0 == I_IADDL || hi0 == I_ISUBL);

    if (need_imm) {
	okc = get_word_val(s->m, ftpc, &cval);
	ftpc += 4;
    }

    switch (hi0) {
    case I_NOP:
	s->pc = ftpc;
	break;
    case I_HALT:
	return STAT_HLT;
	break;
    case I_RRMOVL:  /* Both unconditional and conditional moves */
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	val = get_reg_val(s->r, hi1);
	if (cond_holds(s->cc, lo0))
	  set_reg_val(s->r, lo1, val);
	s->pc = ftpc;
	break;
    case I_IRMOVL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	set_reg_val(s->r, lo1, cval);
	s->pc = ftpc;
	break;
    case I_RMMOVL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return STAT_INS;
	}
	if (reg_valid(lo1)) 
	    cval += get_reg_val(s->r, lo1);
	val = get_reg_val(s->r, hi1);
	if (!set_word_val(s->m, cval, val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid data address 0x%x\n",
			s->pc, cval);
	    return STAT_ADR;
	}
	s->pc = ftpc;
	break;
    case I_MRMOVL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction addres\n", s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return STAT_INS;
	}
	if (reg_valid(lo1)) 
	    cval += get_reg_val(s->r, lo1);
	if (!get_word_val(s->m, cval, &val))
	    return STAT_ADR;
	set_reg_val(s->r, hi1, val);
	s->pc = ftpc;
	break;
    case I_ALU:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	argA = get_reg_val(s->r, hi1);
	argB = get_reg_val(s->r, lo1);
	val = compute_alu(lo0, argA, argB);
	set_reg_val(s->r, lo1, val);
	s->cc = compute_cc(lo0, argA, argB);
	s->pc = ftpc;
	break;
    case I_JMP:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (cond_holds(s->cc, lo0))
	    s->pc = cval;
	else
	    s->pc = ftpc;
	break;
    case I_CALL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	val = get_reg_val(s->r, REG_ESP) - 4;
	set_reg_val(s->r, REG_ESP, val);
	if (!set_word_val(s->m, val, ftpc)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n", s->pc, val);
	    return STAT_ADR;
	}
	s->pc = cval;
	break;
    case I_RET:
	/* Return Instruction.  Pop address from stack */
	dval = get_reg_val(s->r, REG_ESP);
	if (!get_word_val(s->m, dval, &val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n",
			s->pc, dval);
	    return STAT_ADR;
	}
	set_reg_val(s->r, REG_ESP, dval + 4);
	s->pc = val;
	break;
    case I_PUSHL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1);
	    return STAT_INS;
	}
	val = get_reg_val(s->r, hi1);
	dval = get_reg_val(s->r, REG_ESP) - 4;
	set_reg_val(s->r, REG_ESP, dval);
	if  (!set_word_val(s->m, dval, val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval);
	    return STAT_ADR;
	}
	s->pc = ftpc;
	break;
    case I_POPL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1);
	    return STAT_INS;
	}
	dval = get_reg_val(s->r, REG_ESP);
	set_reg_val(s->r, REG_ESP, dval+4);
	if (!get_word_val(s->m, dval, &val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n",
			s->pc, dval);
	    return STAT_ADR;
	}
	set_reg_val(s->r, hi1, val);
	s->pc = ftpc;
	break;
    case I_LEAVE:
	dval = get_reg_val(s->r, REG_EBP);
	set_reg_val(s->r, REG_ESP, dval+4);
	if (!get_word_val(s->m, dval, &val)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid stack address 0x%x\n",
			s->pc, dval);
	    return STAT_ADR;
	}
	set_reg_val(s->r, REG_EBP, val);
	s->pc = ftpc;
	break;
    case I_IADDL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	argB = get_reg_val(s->r, lo1);
	val = argB + cval;
	set_reg_val(s->r, lo1, val);
	s->cc = compute_cc(A_ADD, cval, argB);
	s->pc = ftpc;
	break;
     case I_ISUBL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	argB = get_reg_val(s->r, lo1);
	val = argB - cval;
	set_reg_val(s->r, lo1, val);
	s->cc = compute_cc(A_SUB, cval, argB);
	s->pc = ftpc;
	break;
    default:
	if (error_file)
	    fprintf(error_file,
		    "PC = 0x%x, Invalid instruction %.2x\n", s->pc, byte0);
	return STAT_INS;
    }
    return STAT_AOK;
}
예제 #24
0
void execute_program(UM_state um)
{
        int ra =0;
        int rb =0;
        int rc =0;         
        //uint32_t val= 0;
        bool proceed = true;
        int num_instructions = get_words_in_seg(um->memory, 0);
        int i = um->instr_ctr;

        while (i < num_instructions && proceed) {
                uint32_t word = get_word(um->memory, 0, i);
                uint32_t op_code = get_op_code(word);

                /*if (op_code == 13) {
                        int ra = get_reg_num(word, LOAD_RA_LSB);
                        proceed &= valid_reg(ra);

                        uint32_t val = get_val(word);
                        (void) val;
                }

                else {*/
                        ra = get_reg_num(word, RA_LSB);
                        rb = get_reg_num(word, RB_LSB);
                        rc = get_reg_num(word, RC_LSB);

                        proceed &= valid_reg(ra);
                        proceed &= valid_reg(rb);
                        proceed &= valid_reg(rc);
                //}

                if (!proceed) {
                        break;
                }
                        
                if (op_code == 0) {
                        /* Conditional move - op code 0 */

                        if (val_in_reg(um, rc) != 0) {
                                uint32_t val = val_in_reg(um, rb);
                                set_reg_val(um, ra, val);
                        }
                                        
                } else if (op_code == 1) {
                        /* Segmented load - op code 1 */
                        uint32_t val = get_word(um->memory, val_in_reg(um, rb),
                                       val_in_reg(um, rc));
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 2) {

                        /* Segmented store - op code 2 */

                        uint32_t ID = val_in_reg(um, ra);
                        uint32_t offset = val_in_reg(um, rb);
                        uint32_t val = val_in_reg(um, rc);

                        put_word(um->memory, ID, offset, val);
                                        
                } else if (op_code == 3) {

                        /* Add - op code 3 */
                        uint32_t val = (val_in_reg(um, rb) + val_in_reg(um, rc)) % UINT_MAX;
                        set_reg_val(um, ra, val);

                                        
                } else if (op_code == 4) {
                        /* Multiply - op code 4 */
                        uint32_t val = (val_in_reg(um, rb) * val_in_reg(um, rc)) % UINT_MAX;
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 5) {
                        /* Divide - op code 5 */

                        uint32_t val = val_in_reg(um, rb) / val_in_reg(um, rc);
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 6) {
                        /* Bitwise NAND - op code 6 */

                        uint32_t val = ~(val_in_reg(um, rb) & val_in_reg(um, rc));
                        set_reg_val(um, ra, val);
                                        
                } else if (op_code == 7) {
                        /* Halt */
                        proceed = false;
                                        
                } else if (op_code == 8) {
                        /* Map segment - op code 8 */

                        if (Stack_empty(um->unmapped_IDs)) {
                              
                                uint32_t num_words = val_in_reg(um, rc);

                                proceed &= create_segment(um->memory, num_words);             
                                set_reg_val(um, rb, (get_num_segs(um->memory) - 1));
                        }

                        else {
                                uint32_t ID = get_unmapped_ID(um);
                                uint32_t num_words = val_in_reg(um, rc);

                                proceed &= resize(um->memory, ID, num_words);

                                set_reg_val(um, rb, ID);
                        }

                } else if (op_code == 9) {
                        /* Unmap segment - op code 9 */
                        
                        uint32_t ID = val_in_reg(um, rc);
                        proceed &= clear_seg(um->memory, ID);
                        proceed &= add_unmapped_ID(um, ID);
                                        
                } else if (op_code == 10) {
                        /* Output - op code 10 */
                        uint32_t val = val_in_reg(um, rc);

                        if (val < 256) {
                                fprintf(stdout, "%c", (char) val);
                        } else {
                                proceed &= false;

                        }
                                        
                } else if (op_code == 11) {
                        /* Input - op code 11 */

                        uint32_t val = getc(stdin);

                        if ((int) val == EOF) {
                                val = ~0;

                        } else if (val > 255) {
                                proceed &= false;
                        }

                        set_reg_val(um, rc, val);
                                        
                } else if (op_code == 12) {
                        /* Load program - op code 12 */

                        uint32_t ID = val_in_reg(um, rb);

                        if (ID != 0) {
                                proceed &= clear_seg(um->memory, 0);

                                int num_words = get_words_in_seg(um->memory, ID);
                                
                                resize(um->memory, 0, num_words);

                                for (int i = 0; i < num_words; i++) {
                                        proceed &= put_word(um->memory, 0, i,
                                                               get_word(um->memory, ID, i));
                                }
                        }

                        um->instr_ctr = val_in_reg(um, rc);

                        num_instructions = 
                                get_words_in_seg(um->memory, 0);
                        i = um->instr_ctr;
                                        
                } else if (op_code == 13) {

                       /* Load value - op code 13 */
                        ra = get_reg_num(word, LOAD_RA_LSB);
                        proceed &= valid_reg(ra);

                        uint32_t val = get_val(word);
                        set_reg_val(um, ra, val);
                        
                } else {

                        fprintf(stderr, "op code doesn't exist\n");
                        proceed = false;
                }
                
                if (op_code != 12) {
                        i++;
                }
        }

        return;
}
예제 #25
0
파일: y86sim.c 프로젝트: tjgykhulj/ICS_Lab
/* 
 * nexti: execute single instruction and return status.
 * args
 *     sim: the y86 image with PC, register and memory
 *
 * return
 *     STAT_AOK: continue
 *     STAT_HLT: halt
 *     STAT_ADR: invalid instruction address, data address, stack address, ...
 *     STAT_INS: invalid instruction, register id, ...
 */
stat_t nexti(y86sim_t *sim)
{
    byte_t codefun = 0;
    itype_t icode;
    alu_t ifun;
    long_t valP = sim->pc;

    /* get code and function (1 byte) */
    if (!get_byte_val(sim->m, valP, &codefun)) {
        err_print("PC = 0x%x, Invalid instruction address", sim->pc);
        return STAT_ADR;
    }
    icode = GET_ICODE(codefun);
    ifun = GET_FUN(codefun);
    valP++;

    /* get registers if needed (1 byte) */

    byte_t  byte;
    long_t  valA, valB, valC, val;
    regid_t  regA, regB;

    if ((icode>1 && icode<7) || icode==I_PUSHL || icode==I_POPL)
    {
	if (!get_byte_val(sim->m, valP, &byte)) {
	  err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC);
	  return STAT_ADR;
	}
	valP++;
	regA = HIGH(byte);
	regB = LOW(byte);
    }

    /* get immediate if needed (4 bytes) */
    if (icode>=3 && icode<=8 && icode!=I_ALU) {
	if (!get_long_val(sim->m, valP, &valC)) {
	  err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC);
	  return STAT_ADR;
	}
	valP+=4;
    }

    /* execute the instruction */
    switch (icode) {
      case I_HALT: /* 0:0 */
        return STAT_HLT;
        break;
      case I_NOP: /* 1:0 */
        sim->pc = valP;
        break;

      case I_RRMOVL:
	sim->pc = valP;
	if (!cond_doit(sim->cc,ifun)) 
	    break;
	val = get_reg_val(sim->r, regA);
	set_reg_val(sim->r, regB, val);
	break;
	/* 2:x regA:regB */
      case I_IRMOVL:
	set_reg_val(sim->r, regB, valC);
	sim->pc = valP;
	break;
	/* 3:0 F:regB imm */
      case I_RMMOVL:
	valC += get_reg_val(sim->r, regB);
	val = get_reg_val(sim->r, regA);
	set_long_val(sim->m, valC, val);
	sim->pc = valP;
	break;
	/* 4:0 regA:regB imm */
      case I_MRMOVL:
	valC += get_reg_val(sim->r, regB);
	if (!get_long_val(sim->m, valC, &val)) {
	  err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC);
	  return STAT_ADR;
	}
	set_reg_val(sim->r, regA, val);
	sim->pc = valP;
	break;
	/* 5:0 regB:regA imm */
      case I_ALU:
	valA = get_reg_val(sim->r,regA);
	valB = get_reg_val(sim->r,regB);
	val = compute_alu(ifun, valA, valB);
	set_reg_val(sim->r, regB, val);
	sim->cc = compute_cc(ifun, valA, valB, val);
	sim->pc = valP;
	break;
	/* 6:x regA:regB */
      case I_JMP:
	sim->pc = (cond_doit(sim->cc,ifun))?valC:valP;
	break;
	/* 7:x imm */
      case I_CALL:
	val = get_reg_val(sim->r, REG_ESP) - 4;
	set_reg_val(sim->r, REG_ESP, val);
	if (!set_long_val(sim->m, val, valP)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, val);
	  return STAT_ADR;
	}
	sim->pc = valC;
	break;
	/* 8:x imm */
      case I_RET: 
	valA = get_reg_val(sim->r, REG_ESP);
	if (!get_long_val(sim->m, valA, &valB)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, valA);
	  return STAT_ADR;
	}
	set_reg_val(sim->r, REG_ESP, valA+4);
	sim->pc = valB;
	break;
	/* 9:0 */
      case I_PUSHL:
	valA = get_reg_val(sim->r, regA);
	val = get_reg_val(sim->r, REG_ESP) - 4;
	set_reg_val(sim->r, REG_ESP, val);
	if (!set_long_val(sim->m, val, valA)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, val);
	  return STAT_ADR;
	}
	sim->pc = valP;
	break;
	/* A:0 regA:F */
      case I_POPL: 
	valA = get_reg_val(sim->r, REG_ESP);
	set_reg_val(sim->r, REG_ESP, valA+4);
	if (!get_long_val(sim->m, valA, &valB)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, valA);
	  return STAT_ADR;
	}
	set_reg_val(sim->r, regA, valB);
	sim->pc = valP;
	break;
	/* B:0 regA:F */
      default:
        err_print("PC = 0x%x, Invalid instruction %.2x", sim->pc, codefun);
        return STAT_INS;
    }
    
    return STAT_AOK;
}
예제 #26
0
/* 
 * nexti: execute single instruction and return status.
 * args
 *     sim: the y64 image with PC, register and memory
 *
 * return
 *     STAT_AOK: continue
 *     STAT_HLT: halt
 *     STAT_ADR: invalid instruction address
 *     STAT_INS: invalid instruction, register id, data address, stack address, ...
 */
stat_t nexti(y64sim_t *sim)
{
    byte_t codefun = 0; /* 1 byte */
    itype_t icode;
    alu_t ifun;
    long_t next_pc = sim->pc;
    
    /* get code and function (1 byte) */
    if (!get_byte_val(sim->m, next_pc, &codefun)) {
        err_print("PC = 0x%lx, Invalid instruction address", sim->pc);
        return STAT_ADR;
    }
    icode = GET_ICODE(codefun);
    ifun = GET_FUN(codefun);
    next_pc++;
	
    /* get registers if needed (1 byte) */
  	byte_t rArB = 0; 
	regid_t rA = REG_ERR, rB = REG_ERR;
	if((icode == I_RRMOVQ) || (icode == I_ALU) || (icode == I_RMMOVQ) || 
					(icode == I_PUSHQ) || (icode == I_POPQ) ||
					(icode == I_IRMOVQ) || (icode == I_MRMOVQ) ){
   		get_byte_val(sim->m, next_pc, &rArB);
		rA = GET_REGA(rArB);
		rB = GET_REGB(rArB);
		next_pc++;
	}

    /* get immediate if needed (8 bytes) */
    long_t valC;
	if(icode == I_IRMOVQ || icode == I_RMMOVQ ||icode == I_MRMOVQ ||
				   	icode == I_JMP || icode == I_CALL){
		get_long_val(sim->m,next_pc,&valC);
		next_pc += 8;
	}

    /* execute the instruction*/
    long_t valA,valB,valE,valM;
   	switch (icode) {
      case I_HALT: /* 0:0 */
	    return STAT_HLT;
	    break;
      case I_NOP: /* 1:0 */
    	sim->pc = next_pc;
    	break;
      case I_RRMOVQ:  /* 2:x regA:regB */
	  	if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
			
	  	valA = get_reg_val(sim->r,rA);
		
		valE = valA + 0;
		if(cond_doit(sim->cc, ifun))
			set_reg_val(sim->r, rB, valE);
		sim->pc = next_pc;
		break;
      case I_IRMOVQ: /* 3:0 F:regB imm */
		
		if(!NORM_REG(rB) || !NONE_REG(rA)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);
		valE = 0 + valC;
		set_reg_val(sim->r, rB, valE);
		sim->pc = next_pc;
		break;
      case I_RMMOVQ: /* 4:0 regA:regB imm */
		
		if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);
		valE = valB + valC;
		if(!set_long_val(sim->m, valE, valA)){
			err_print("PC = 0x%lx, Invalid data address 0x%.8lx", sim->pc, valE);
			return STAT_ADR;
		}
		sim->pc = next_pc;
		break;
      case I_MRMOVQ: /* 5:0 regB:regA imm */
		
		if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);
		valE = valB + valC;
		if(!get_long_val(sim->m, valE, &valM)){
			err_print("PC = 0x%lx, Invalid data address 0x%.8lx", sim->pc, valE);
			return STAT_ADR;
		}
		set_reg_val(sim->r, rA, valM);
		sim->pc = next_pc;
		break;
      case I_ALU: /* 6:x regA:regB */
		if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);	
		valE = compute_alu(ifun, valA, valB);
		sim->cc = compute_cc(ifun, valA, valB, valE);
		set_reg_val(sim->r, rB, valE);
		sim->pc = next_pc;
		break;
      case I_JMP: /* 7:x imm */
		if(ifun > 6){
			err_print("PC = 0x%lx, Invalid instruction %.2x", sim->pc, codefun);
    		return STAT_INS;
		}
		sim->pc = cond_doit(sim->cc,ifun)? valC : next_pc;
		break;
      case I_CALL: /* 8:x imm */
		valB = get_reg_val(sim->r, REG_RSP); 
		valE = valB + (-8);
		
		set_reg_val(sim->r, REG_RSP, valE);
		if(!set_long_val(sim->m, valE, next_pc)){
			err_print("PC = 0x%lx, Invalid stack address 0x%.8lx", sim->pc, valE);
    		return STAT_ADR;	
		}
		sim->pc = valC;
		break;
      case I_RET: /* 9:0 */
		valA = get_reg_val(sim->r, REG_RSP);
		valB = valA;
		
		valE = valB + 8;

		get_long_val(sim->m, valA, &valM);
		set_reg_val(sim->r, REG_RSP, valE);
		sim->pc = valM;
		break;
      case I_PUSHQ: /* A:0 regA:F */
		if(!NORM_REG(rA)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
    		return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, REG_RSP);
		
		valE = valB + (-8);
		
		set_reg_val(sim->r, REG_RSP, valE);
		if(!set_long_val(sim->m, valE, valA)){
			err_print("PC = 0x%lx, Invalid stack address 0x%.8lx", sim->pc, valE);
    		return STAT_ADR;
		}
		sim->pc = next_pc;
		break;
      case I_POPQ: /* B:0 regA:F */
		if(!NORM_REG(rA)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
    		return STAT_INS;
		}
		valA = get_reg_val(sim->r, REG_RSP);
		valB = valA;

		valE = valB + 8;
		
		get_long_val(sim->m, valA, &valM);
		set_reg_val(sim->r, REG_RSP, valE);
		set_reg_val(sim->r, rA, valM);
		sim->pc = next_pc;
		break;

    //	return STAT_INS; /* unsupported now, replace it with your implementation */
      default:
    	err_print("PC = 0x%lx, Invalid instruction %.2x", sim->pc, codefun);
    	return STAT_INS;
    }
    
    return STAT_AOK;
}