Exemple #1
0
long_t get_reg_val(mem_t *r, regid_t id)
{
    long_t val = 0;
    if (id >= REG_NONE)
        return 0;
    get_long_val(r, id*4, &val);
    return val;
}
Exemple #2
0
bool_t diff_mem(mem_t *oldm, mem_t *newm, FILE *outfile)
{
    long_t pos;
    int len = oldm->len;
    bool_t diff = FALSE;
    
    if (newm->len < len)
	    len = newm->len;
    
    for (pos = 0; (!diff || outfile) && pos < len; pos += 4) {
        long_t ov = 0;  long_t nv = 0;
        get_long_val(oldm, pos, &ov);
        get_long_val(newm, pos, &nv);
        if (nv != ov) {
            diff = TRUE;
            if (outfile)
                fprintf(outfile, "0x%.4x:\t0x%.8x\t0x%.8x\n", pos, ov, nv);
        }
    }
    return diff;
}
Exemple #3
0
bool_t diff_reg(mem_t *oldr, mem_t *newr, FILE *outfile)
{
    long_t pos;
    int len = oldr->len;
    bool_t diff = FALSE;
    
    if (newr->len < len)
	    len = newr->len;
    
    for (pos = 0; (!diff || outfile) && pos < len; pos += 4) {
        long_t ov = 0;
        long_t nv = 0;
        get_long_val(oldr, pos, &ov);
        get_long_val(newr, pos, &nv);
        if (nv != ov) {
            diff = TRUE;
            if (outfile)
                fprintf(outfile, "%s:\t0x%.8x\t0x%.8x\n",
                        reg_table[pos/4].name, ov, nv);
        }
    }
    return diff;
}
Exemple #4
0
/* 
 * 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;
}
Exemple #5
0
int 
eval_options (int argc, char **argv, struct target_opts* defaults, 
              const char** exe_opts)
{
    const char opt_timeout[]  = "-t";
    const char opt_data_dir[] = "-d";
    const char opt_t_flags[]  = "-x";
    const char opt_compat[]   = "--compat";
    const char opt_exit[]     = "--exit";
    const char opt_help[]     = "--help";
    const char opt_ignore[]   = "--ignore";
    const char opt_nocompat[] = "--nocompat";
    const char opt_signal[]   = "--signal";
    const char opt_sleep[]    = "--sleep";
    const char opt_ulimit[]   = "--ulimit";
    const char opt_verbose[]  = "--verbose";
    const char opt_warn[]     = "--warn";

    int i;

    assert (0 != argv);
    assert (0 != defaults);

    memset (defaults, 0, sizeof (target_opts));

    /* The chain of preprocesor logic below initializes the defaults->c_warn 
       and defaults->l_warn values.
    */
#ifdef __GNUG__
    parse_warn_opts ("Gcc", defaults);
#elif defined (__HP_aCC)
    parse_warn_opts ("Acc", defaults);
#elif defined (__IBMCPP__)
    parse_warn_opts ("Xlc", defaults);
#elif defined (__SUNPRO_CC)
    parse_warn_opts ("Sunpro", defaults);
#elif defined (SNI)
    parse_warn_opts ("Cds", defaults);
#elif defined (__APOGEE__) /* EDG variant that doesn't define __EDG__. */
    parse_warn_opts ("Como", defaults);

/* The following are EDG variants, that define __EDG__ */
#elif defined (__DECCXX)
    parse_warn_opts ("Cxx", defaults);
#elif defined (_SGI_COMPILER_VERSION)
    parse_warn_opts ("Mipspro", defaults);
#elif defined (__INTEL_COMPILER)
    parse_warn_opts ("Icc", defaults);

/* So we need to check for __EDG__ after we check for them. */
#elif defined (__EDG__)
    parse_warn_opts ("Eccp", defaults);
#endif

    if (1 == argc || '-' != argv [1][0])
        return 1;

    for (i = 1; i < argc && '-' == argv [i][0]; ++i) {

        /* the name of the option being processed */
        const char* optname = argv [i];

        /* the option's argument, if any */
        const char* optarg  = 0;

        char* end = 0;

        switch (argv [i][1]) {
        case '?':   /* display help and exit with status of 0 */
        case 'h':
            show_usage (0);

        case 'r':
            ++i; /* Ignore -r option (makefile compat) */
            break;

        case 't':   /* executable timeout in seconds */
            optname = opt_timeout;
            optarg  = get_short_val (argv, &i);
            if (optarg) {
                if (!isdigit (*optarg))
                    bad_value (optname, optarg);

                errno = 0;
                defaults->timeout = strtol (optarg, &end, 10);
                if (*end || errno)
                    bad_value (optname, optarg);
            }
            else
                missing_value (optname);

            break;

        case 'd':   /* directory containing example reference files */
            optname = opt_data_dir;
            defaults->data_dir = get_short_val (argv, &i);
            if (!defaults->data_dir)
                missing_value (optname);
            break;

        case 'v':   /* enable verbose mode */
            optname = opt_verbose;
            ++defaults->verbose;
            break;

        case 'x':   /* command line options to pass to targets */
            optname  = opt_t_flags;
            *exe_opts = get_short_val (argv, &i);
            if (!*exe_opts)
                missing_value (optname);
            break;

        case '-':   /* long options */
        {
            const size_t arglen = strlen (argv [i]);

            /* abort processing on --, eat token */
            if ('\0' == argv [i][2])
                return i+1;

            if (   sizeof opt_compat - 1 == arglen
                && !memcmp (opt_compat, argv [i], sizeof opt_compat)) {
                /* enter compatibility mode */
                defaults->compat = 1;
                break;
            }
            else if (   sizeof opt_nocompat - 1 == arglen
                     && !memcmp (opt_nocompat, argv [i], sizeof opt_nocompat)) {
                /* exit compatibility mode */
                defaults->compat = 0;
                break;
            }
            else if (   sizeof opt_exit - 1 <= arglen
                     && !memcmp (opt_exit, argv [i], sizeof opt_exit - 1)) {
                /* exit immediately with the specified status */
                optname = opt_exit;
                optarg  = get_long_val (argv, &i, sizeof opt_exit - 1);
                if (optarg && *optarg) {
                    if (!isdigit (*optarg))
                        bad_value (optname, optarg);

                    errno = 0;
                    const long code = strtol (optarg, &end, 10);
                    if ('\0' == *end && !errno)
                        exit (code);
                }
            }
            else if (   sizeof opt_help - 1 == arglen
                     && !memcmp (opt_help, argv [i], sizeof opt_help - 1)) {
                /* display help and exit with status of 0 */
                optname = opt_help;
                show_usage (0);
                break;
            }
            else if (   sizeof opt_sleep - 1 <= arglen
                     && !memcmp (opt_sleep, argv [i], sizeof opt_sleep - 1)) {
                /* sleep for the specified number of seconds */ 
                optname = opt_sleep;
                optarg  = get_long_val (argv, &i, sizeof opt_sleep - 1);
                if (optarg && *optarg) {
                    if (!isdigit (*optarg))
                        bad_value (optname, optarg);

                    errno = 0;
                    const long nsec = strtol (optarg, &end, 10);
                    if ('\0' == *end && 0 <= nsec && !errno) {
                        rw_sleep (nsec);
                        break;
                    }
                }
            }
            else if (   sizeof opt_signal - 1 <= arglen
                     && !memcmp (opt_signal, argv [i], sizeof opt_signal - 1)) {
                /* send ourselves the specified signal */
                optname = opt_signal;
                optarg  = get_long_val (argv, &i, sizeof opt_signal - 1);
                if (optarg && *optarg) {
                    const int signo = get_signo (optarg);
                    if (0 <= signo) {
                        if (0 > raise (signo))
                            terminate (1, "raise(%s) failed: %s\n",
                                       get_signame (signo), strerror (errno));
                        break;
                    }
                }
            }
            else if (   sizeof opt_ignore - 1 <= arglen
                     && !memcmp (opt_ignore, argv [i], sizeof opt_ignore - 1)) {
                /* ignore the specified signal */
                optname = opt_ignore;
                optarg  = get_long_val (argv, &i, sizeof opt_ignore - 1);
                if (optarg && *optarg) {
                    const int signo = get_signo (optarg);
                    if (0 <= signo) {
                        if (rw_signal (signo, 0 /* SIG_IGN */))
                            terminate (1, "rw_signal(%s, ...) failed: %s\n",
                                       get_signame (signo), strerror (errno));
                        break;
                    }
                }
            }
            else if (   sizeof opt_ulimit - 1 <= arglen
                     && !memcmp (opt_ulimit, argv [i], sizeof opt_ulimit - 1)) {
                /* set child process resource utilization limits */
                optname = opt_ulimit;
                optarg  = get_long_val (argv, &i, sizeof opt_ulimit - 1);
                if (optarg && *optarg) {
                    if (!parse_limit_opts (optarg, defaults)) {
                        break;
                    }
                }
            }
            else if (   sizeof opt_warn - 1 <= arglen
                     && !memcmp (opt_warn, argv [i], sizeof opt_warn - 1)) {
                /* set compiler warning mode */
                optname = opt_warn;
                optarg  = get_long_val (argv, &i, sizeof opt_warn - 1);
                if (optarg && *optarg) {
                    if (!parse_warn_opts (optarg, defaults)) {
                        break;
                    }
                }
            }
            /* fall through */
        }
        default:
            if (optarg) {
                if (*optarg)
                    bad_value (optname, optarg);
                else
                    missing_value (optname);
            }

            if (argv [i])
                bad_option (argv [i]);
            else
                missing_value (optname);
        }
    }

    return i;
}
Exemple #6
0
/* 
 * 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;
}
/* 
 * 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;
}