Пример #1
0
void Ppc405Iss::op_b()
{
	uint32_t base = m_ins.i.aa ? 0 : r_pc;
    if ( m_ins.i.lk )
        r_lr = r_pc + 4;
    m_next_pc = base + sign_ext(m_ins.i.li<<2, 26);
}
Пример #2
0
void EMips::decode(ULONG inst)
{
  switch(opFormat) {
    case EMIPS_FORMAT_NONE:
      break;
    case EMIPS_FORMAT_CONST:
      imm=(op&0x03ffffff)<<2;
      ea=imm+(pc&0xf0000000);
      break;
    case EMIPS_FORMAT_REG_REG_CONST:
      rt=(op>>16)&0x1f;
      rs=(op>>21)&0x1f;
      imm=sign_ext(op&0xffff,16);
      break;
    case EMIPS_FORMAT_REG_REG_REG:
      sa=(op>>6)&0x1f;
      rd=(op>>11)&0x1f;
      rt=(op>>16)&0x1f;
      rs=(op>>21)&0x1f;
      break;
    case EMIPS_FORMAT_VARIOUS:
      if(!disFlag) {
        disFlag=true;
        disVarious();
        disFlag=false;
      }
      else debugger("Caught in disVarious loop in decode!\n");
      break;
    default:
      DEBUG_OUT<<"decode: opFormat is "<<opFormat<<"!\n";
      DEBUG_OUT<<"decode: top was "<<top<<" bop was "<<bop<<"\n";
      debugger("Bad opFormat in decode()!\n");
      break;
  }
}
Пример #3
0
/* Basic integer 3-address imm16 format:
 *   mnemonic #imm16,%rs2,%rd  */
static void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn)
{
	/* Sign extend the 16-bit immediate.
	   Print as hex for the bitwise operations.  */
	int upper_6bits = (insn >> 26) & 0x3f;
	if (upper_6bits >= 0x30 && upper_6bits <= 0x3f)
		util::stream_format(stream, "%s\t0x%04x,%%r%d,%%r%d", mnemonic,
			(uint32_t)(get_imm16 (insn)), get_isrc2 (insn), get_idest (insn));
	else
		util::stream_format(stream, "%s\t%d,%%r%d,%%r%d", mnemonic,
			sign_ext(get_imm16 (insn), 16), get_isrc2 (insn), get_idest (insn));
}
Пример #4
0
/* Basic integer 3-address imm16 format:
 *   mnemonic #imm16,%rs2,%rd  */
static void int_i2d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn)
{
	/* Sign extend the 16-bit immediate.
       Print as hex for the bitwise operations.  */
	int upper_6bits = (insn >> 26) & 0x3f;
	if (upper_6bits >= 0x30 && upper_6bits <= 0x3f)
		sprintf(buf, "%s\t0x%04x,%%r%d,%%r%d", mnemonic,
			(UINT32)(get_imm16 (insn)), get_isrc2 (insn), get_idest (insn));
	else
		sprintf(buf, "%s\t%d,%%r%d,%%r%d", mnemonic,
			sign_ext(get_imm16 (insn), 16), get_isrc2 (insn), get_idest (insn));
}
Пример #5
0
// CLASS METHOD: Interpreter::exec_load_store_instr()
// PURPOSE:      Load/store instructions move data between memory and the
//               general registers.  They are all encoded as "I-Type"
//               instructions, and the only addressing mode implemented is base
//               register plus signed, immediate offset.  This directly enables
//               the use of three distinct addressing modes: register plus
//               offset; register direct; and immediate.
//
// ARGUMENTS: None.
// RETURNS:   None.
void
Interpreter::exec_load_store_instr(void)
{
    Word vaddr, paddr;

    switch (op(curr_instr))
    {
        // LB -- Load Byte
        // 
        // Sign-extend 16-bit `offset` and add to contents of register `base` to
        // form address.  Sign-extend contents of addressed byte and load into
        // `rt`.
        case LB:
            vaddr = gpr[base(curr_instr)] + sign_ext(curr_instr);
            paddr = translate_address(align(vaddr));

            do_load(LOADREG, rt(curr_instr), sign_ext_byte(mem->read(vaddr, paddr), bytepos(vaddr)));
            break;

        // LBU -- Load Byte Unsigned
        //
        // Sign-extend 16-bit `offse` and add to contents of register `base` to
        // form address.  Zero-extend contents of addressed byte and load into
        // `rt`.
        case LBU:
            vaddr = gpr[base(curr_instr)] + sign_ext(curr_instr);
            paddr = translate_address(align(vaddr));

            do_load(LOADREG, rt(curr_instr), zero_ext_byte(mem->read(vaddr, paddr), bytepos(vaddr)));
            break;

        // LH -- Load Halfword
        //
        // Sign-extend 16-bit `offset` and add to contents of register `base` to
        // form address.  Sign-extend contents of addressed byte and load into
        // `rt`.
        case LH:
            vaddr = gpr[base(curr_instr)] + sign_ext(curr_instr);
            paddr = translate_address(align(vaddr));

            do_load(LOADREG, rt(curr_instr), sign_ext_hword(mem->read(vaddr, paddr), hwordpos(vaddr)));
            break;

        // LHU -- Load Halfword Unsigned
        //
        // Sign-extend 16-bit `offset` and add to contents of register `base` to
        // form address.  Zero-extend contents of addressed byte and load into
        // `rt`.
        case LHU:
            vaddr = gpr[base(curr_instr)] + sign_ext(curr_instr);
            paddr = translate_address(align(vaddr));

            do_load(LOADREG, rt(curr_instr), zero_ext_hword(mem->read(vaddr, paddr), hwordpos(vaddr)));
            break;

        // LW -- Load Word
        //
        // Sign-extend 16-bit `offset` and add to contents of register `base` to
        // form address.  Load contents of addressed word into register `rt`.
        case LW:
            vaddr = gpr[base(curr_instr)] + sign_ext(curr_instr);
            paddr = translate_address(align(vaddr));

            do_load(LOADREG, rt(curr_instr), mem->read(vaddr, paddr));
            break;

        // LWL -- Load Word Left
        //
        // Sign-extend 16-bit `offset` and add to contents of register `base` to
        // form address.  Shift addressed word left so that addressed byte is
        // leftmost byte of a word.  Merge bytes from memory with contents of
        // register `rt` and load result into register `rt`.
        case LWL:
            vaddr = gpr[base(curr_instr)] + sign_ext(curr_instr);
            paddr = translate_address(align(vaddr));

            do_load(LOADREG, rt(curr_instr), merge(gpr[rt(curr_instr)], mem->read(vaddr, paddr), bytepos(vaddr), true));
            break;

        // LWR -- Load Word Right
        //
        // Sign-extend 16-bit `offset` and add to contents of register `base` to
        // form address.  Shfit addressed word right so that addressed byte is
        // rightmost byte of a word.  Merge bytes from memory with contents of
        // register `rt` and load result into register `rt`.
        case LWR:
            vaddr = gpr[base(curr_instr)] + sign_ext(curr_instr);
            paddr = translate_address(align(vaddr));

            do_load(LOADREG, rt(curr_instr), merge(gpr[rt(curr_instr)], mem->read(vaddr, paddr), bytepos(vaddr), false));
            break;

        // SB -- Store Byte
        //
        // Sign-extend 16-bit `offset` and add to contents of register `base` to
        // form address.  Store least significant byte of register `rt` at
        // addressed location.
    }
}
srcdest
decode_bit (int destcode)
{
  srcdest sd;
  int addr = 0;
  static const char *dc_names[] = { "r0", "r1", "r2", "r3",
    "a0", "a1", "[a0]", "[a1]",
    "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
    "disp16[a0]", "disp16[a1]", "disp16[sb]", "abs16"
  };

  if (trace)
    {
      const char *the_bits = bits (destcode, 4);
      printf ("decode: %s : %s\n", the_bits, dc_names[destcode]);
    }

  switch (destcode)
    {
    case 0:
      sd.u.reg = r0;
      break;
    case 1:
      sd.u.reg = r1;
      break;
    case 2:
      sd.u.reg = r2;
      break;
    case 3:
      sd.u.reg = r3;
      break;
    case 4:
      sd.u.reg = a0;
      break;
    case 5:
      sd.u.reg = a1;
      break;
    case 6:
      addr = get_reg (a0);
      break;
    case 7:
      addr = get_reg (a1);
      break;
    case 8:
      addr = get_reg (a0) + disp8 ();
      break;
    case 9:
      addr = get_reg (a1) + disp8 ();
      break;
    case 10:
      addr = get_reg (sb) * 8 + disp8 ();
      break;
    case 11:
      addr = get_reg (fb) * 8 + sign_ext (disp8 (), 8);
      break;
    case 12:
      addr = get_reg (a0) + disp16 ();
      break;
    case 13:
      addr = get_reg (a1) + disp16 ();
      break;
    case 14:
      addr = get_reg (sb) + disp16 ();
      break;
    case 15:
      addr = disp16 ();
      break;
    }

  if (destcode < 6)
    {
      int d = disp8 ();
      sd.mem = 0;
      sd.mask = 1 << (d & 0x0f);
    }
  else
    {
      addr &= addr_mask;
      sd.mem = 1;
      sd.mask = 1 << (addr & 7);
      sd.u.addr = addr >> 3;
    }
  return sd;
}
static srcdest
decode_sd23 (int bbb, int bb, int bytes, int ind, int add)
{
  srcdest sd;
  int code = (bbb << 2) | bb;

  if (code >= sizeof (modes23) / sizeof (modes23[0]))
    abort ();

  if (trace)
    {
      char *b1 = "";
      char *b2 = "";
      char ad[30];
      if (ind)
	{
	  b1 = "[";
	  b2 = "]";
	}
      if (add)
	sprintf (ad, "%+d", add);
      else
	ad[0] = 0;
      if (!the_bits)
	the_bits = bits (code, 4);
      printf ("decode: %s (%d) : %s%s%s%s\n", the_bits, code, b1,
	      modes23[code].name, ad, b2);
      the_bits = 0;
    }

  sd.bytes = bytes;
  sd.mem = modes23[code].is_memory;
  if (sd.mem)
    {
      if (modes23[code].w_regno == mem)
	sd.u.addr = 0;
      else
	sd.u.addr = get_reg (modes23[code].w_regno);
      switch (modes23[code].disp_bytes)
	{
	case 1:
	  sd.u.addr += disp8 ();
	  break;
	case 2:
	  sd.u.addr += disp16 ();
	  break;
	case -1:
	  sd.u.addr += sign_ext (disp8 (), 8);
	  break;
	case -2:
	  sd.u.addr += sign_ext (disp16 (), 16);
	  break;
	case 3:
	  sd.u.addr += disp24 ();
	  break;
	default:
	  break;
	}
      if (add)
	sd.u.addr += add;
      if (ind)
	sd.u.addr = mem_get_si (sd.u.addr & membus_mask);
      sd.u.addr &= membus_mask;
    }
  else
    {
      sd.u.reg = (bytes > 1) ? modes23[code].w_regno : modes23[code].b_regno;
      if (bytes == 3 || bytes == 4)
	{
	  switch (sd.u.reg)
	    {
	    case r0:
	      sd.u.reg = r2r0;
	      break;
	    case r1:
	      sd.u.reg = r3r1;
	      break;
	    case r2:
	      abort ();
	    case r3:
	      abort ();
	    default:;
	    }
	}

    }
  return sd;
}
srcdest
decode_jumpdest (int destcode, int w)
{
  srcdest sd;
  sd.bytes = w ? 2 : 3;
  sd.mem = (destcode >= 6) ? 1 : 0;
  static const char *dc_wnames[16] = { "r0", "r1", "r2", "r3",
    "a0", "a1", "[a0]", "[a1]",
    "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
    "disp20[a0]", "disp20[a1]", "disp16[sb]", "abs16"
  };
  static const char *dc_anames[4] = { "r0l", "r0h", "r1l", "r1h" };

  if (trace)
    {
      const char *n = dc_wnames[destcode];
      if (w == 0 && destcode <= 3)
	n = dc_anames[destcode];
      if (!the_bits)
	the_bits = bits (destcode, 4);
      printf ("decode: %s : %s\n", the_bits, n);
      the_bits = 0;
    }

  switch (destcode)
    {
    case 0x0:
      sd.u.reg = w ? r0 : r2r0;
      break;
    case 0x1:
      sd.u.reg = w ? r1 : r2r0;
      break;
    case 0x2:
      sd.u.reg = w ? r2 : r3r1;
      break;
    case 0x3:
      sd.u.reg = w ? r3 : r3r1;
      break;
    case 0x4:
      sd.u.reg = w ? a0 : a1a0;
      break;
    case 0x5:
      sd.u.reg = w ? a1 : a1a0;
      break;
    case 0x6:
      sd.u.addr = get_reg (a0);
      break;
    case 0x7:
      sd.u.addr = get_reg (a1);
      break;
    case 0x8:
      sd.u.addr = get_reg (a0) + disp8 ();
      break;
    case 0x9:
      sd.u.addr = get_reg (a1) + disp8 ();
      break;
    case 0xa:
      sd.u.addr = get_reg (sb) + disp8 ();
      break;
    case 0xb:
      sd.u.addr = get_reg (fb) + sign_ext (disp8 (), 8);
      break;
    case 0xc:
      sd.u.addr = get_reg (a0) + disp20 ();
      break;
    case 0xd:
      sd.u.addr = get_reg (a1) + disp20 ();
      break;
    case 0xe:
      sd.u.addr = get_reg (sb) + disp16 ();
      break;
    case 0xf:
      sd.u.addr = disp16 ();
      break;
    default:
      abort ();
    }
  if (sd.mem)
    sd.u.addr &= addr_mask;
  return sd;
}
Пример #9
0
void EArm::decode()
{
  willExecute=false;
  cond=(opcode>>28)&0xf;
  op1.init();  op2.init();  op3.init();
  unsigned int rn,rd,rs,rm,imm;
  switch(mode) {
    case EARM_NONE:
      break;
    case EARM_SPECIAL:
      decode_special();
      break;
    case EARM_ILLEGAL:
      debugger("illegal mode in decode!");
      break;
    case EARM_REG_IMM:
      rn=(opcode>>16)&0xf;
      rd=(opcode>>12)&0xf;
      rs=(opcode>>8)&0xf;
      opcode2=(opcode>>4)&0xf;
      imm=opcode&0xf;
      op1.mode=EARM_REG;  op1.reg=rd;
      op2.mode=EARM_IMM;  op2.val=imm;
      break;
    case EARM_REG_IMM2:
      rn=(opcode>>16)&0xf;
      rd=(opcode>>12)&0xf;
      rs=(opcode>>8)&0xf;
      opcode2=(opcode>>4)&0xf;
      imm=opcode&0xf;
      op1.mode=EARM_REG;  op1.reg=rn;
      op2.mode=EARM_IMM;  op2.val=imm;
      break;
    case EARM_REG_REG:
      rn=(opcode>>16)&0xf;
      rd=(opcode>>12)&0xf;
      rs=(opcode>>8)&0xf;
      opcode2=(opcode>>4)&0xf;
      rm=opcode&0xf;
      op1.mode=EARM_REG;  op1.reg=rd;
      op2.mode=EARM_REG;  op2.reg=rm;
      break;
    case EARM_REG_REG2:
      rn=(opcode>>16)&0xf;
      rd=(opcode>>12)&0xf;
      rs=(opcode>>8)&0xf;
      opcode2=(opcode>>4)&0xf;
      rm=opcode&0xf;
      op1.mode=EARM_REG;  op1.reg=rn;
      op2.mode=EARM_REG;  op2.reg=rm;
      break;
    case EARM_REG_REG_REG:
      rn=(opcode>>16)&0xf;
      rd=(opcode>>12)&0xf;
      rs=(opcode>>8)&0xf;
      opcode2=(opcode>>4)&0xf;
      rm=opcode&0xf;
      op1.mode=EARM_REG;  op1.reg=rd;
      op2.mode=EARM_REG;  op2.reg=rn;
      op3.mode=EARM_REG;  op3.reg=rm;
      break;
    case EARM_REG_REG_IMM:
      rn=(opcode>>16)&0xf;
      rd=(opcode>>12)&0xf;
      rs=(opcode>>8)&0xf;
      opcode2=(opcode>>4)&0xf;
      imm=opcode&0xf;
      op1.mode=EARM_REG;  op1.reg=rd;
      op2.mode=EARM_REG;  op2.reg=rn;
      op3.mode=EARM_IMM;  op3.val=imm;
      break;
    case EARM_DISP:
      imm=sign_ext(opcode&0xffffff,24);
      op1.mode=EARM_DISP;  op1.val=imm*4;
      break;
    case EARM_REG_ADDR:
      rn=(opcode>>16)&0xf;
      rd=(opcode>>12)&0xf;
      imm=opcode&0xfff;
      op1.mode=EARM_REG;  op1.reg=rd;
      op2.mode=EARM_INDREG;  op2.reg=rn;  op2.val=-imm;
      break;
    case EARM_MULTREG:
      rn=(opcode>>16)&0xf;
      imm=opcode&0xffff;
      op1.mode=EARM_REG;  op1.reg=rn;
      op2.mode=EARM_MULTREG;  op2.val=imm;
      break;
    default:
      DEBUG_OUT<<"Mode was "<<mode<<"\n";
      debugger("unknown mode in decode!");
      break;
  }
  if(cond==EARM_CC_NEVER) {
    decode_special();
  }
  else {
    if(cond==EARM_CC_ALWAYS) willExecute=true;
    else {
      // TODO: Check cond code, set willExecute to true if necessary
    }
  }
}
Пример #10
0
void Ppc405Iss::op_bc()
{
    int32_t base = m_ins.b.aa ? 0 : r_pc;
    branch_cond( base + sign_ext(m_ins.i.li<<2, 16) );
}
Пример #11
0
void Ppc405Iss::op_addic_()
{
    uint32_t tmp = do_addi( r_gp[m_ins.d.ra], sign_ext(m_ins.d.imm, 16), 0, true );
    crSetSigned( 0, tmp, 0 );
}
Пример #12
0
void Ppc405Iss::op_addic()
{
    do_addi( r_gp[m_ins.d.ra], sign_ext(m_ins.d.imm, 16), 0, true );
}
Пример #13
0
void Ppc405Iss::op_addi()
{
    uint32_t base = m_ins.d.ra ? r_gp[m_ins.d.ra] : 0;
    do_addi( base, sign_ext(m_ins.d.imm, 16), 0, false );
}