Exemplo n.º 1
0
void C1_MacroAssembler::verify_not_null_oop(Register r) {
  Label not_null;
  cmpdi(CCR0, r, 0);
  bne(CCR0, not_null);
  stop("non-null oop required");
  bind(not_null);
  if (!VerifyOops) return;
  verify_oop(r);
}
Exemplo n.º 2
0
static char * BNE2() {
    CPU *c = getCPU();
    uint16_t address = 0xFFFF;
    OP_CODE_INFO *o = getOP_CODE_INFO(0,address,modeImmediate);
    setFlag(c,Z,1);
    bne(c,o);
    mu_assert("BNE2 err, PC != 0", c->PC == 0);
    freeOP_CODE_INFO(o);
    free(c);
    return 0;
}
Exemplo n.º 3
0
void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Register Rscratch, Label& slow_case) {
  assert_different_registers(Rmark, Roop, Rbox, Rscratch);

  Label done, cas_failed, slow_int;

  // The following move must be the first instruction of emitted since debug
  // information may be generated for it.
  // Load object header.
  ld(Rmark, oopDesc::mark_offset_in_bytes(), Roop);

  verify_oop(Roop);

  // Save object being locked into the BasicObjectLock...
  std(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);

  if (UseBiasedLocking) {
    biased_locking_enter(CCR0, Roop, Rmark, Rscratch, R0, done, &slow_int);
  }

  // ... and mark it unlocked.
  ori(Rmark, Rmark, markOopDesc::unlocked_value);

  // Save unlocked object header into the displaced header location on the stack.
  std(Rmark, BasicLock::displaced_header_offset_in_bytes(), Rbox);

  // Compare object markOop with Rmark and if equal exchange Rscratch with object markOop.
  assert(oopDesc::mark_offset_in_bytes() == 0, "cas must take a zero displacement");
  cmpxchgd(/*flag=*/CCR0,
           /*current_value=*/Rscratch,
           /*compare_value=*/Rmark,
           /*exchange_value=*/Rbox,
           /*where=*/Roop/*+0==mark_offset_in_bytes*/,
           MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
           MacroAssembler::cmpxchgx_hint_acquire_lock(),
           noreg,
           &cas_failed,
           /*check without membar and ldarx first*/true);
  // If compare/exchange succeeded we found an unlocked object and we now have locked it
  // hence we are done.
  b(done);

  bind(slow_int);
  b(slow_case); // far

  bind(cas_failed);
  // We did not find an unlocked object so see if this is a recursive case.
  sub(Rscratch, Rscratch, R1_SP);
  load_const_optimized(R0, (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place));
  and_(R0/*==0?*/, Rscratch, R0);
  std(R0/*==0, perhaps*/, BasicLock::displaced_header_offset_in_bytes(), Rbox);
  bne(CCR0, slow_int);

  bind(done);
}
// Do an explicit null check if access to a+offset will not raise a SIGSEGV.
// Either issue a trap instruction that raises SIGTRAP, or do a compare that
// branches to exception_entry.
// No support for compressed oops (base page of heap). Does not distinguish
// loads and stores.
inline void MacroAssembler::null_check_throw(Register a, int offset, Register temp_reg,
                                             address exception_entry) {
  if (!ImplicitNullChecks || needs_explicit_null_check(offset) || !os::zero_page_read_protected()) {
    if (TrapBasedNullChecks) {
      assert(UseSIGTRAP, "sanity");
      trap_null_check(a);
    } else {
      Label ok;
      cmpdi(CCR0, a, 0);
      bne(CCR0, ok);
      load_const_optimized(temp_reg, exception_entry);
      mtctr(temp_reg);
      bctr();
      bind(ok);
    }
  }
}
address InterpreterGenerator::generate_empty_entry()
{
  if (!UseFastEmptyMethods)
    return NULL;

  Label& slow_path = fast_accessor_slow_entry_path;
  
  address start = __ pc();

  // Drop into the slow path if we need a safepoint check.
  __ load (r3, (intptr_t) SafepointSynchronize::address_of_state());
  __ load (r0, Address(r3, 0));
  __ compare (r0, SafepointSynchronize::_not_synchronized);
  __ bne (slow_path);

  // Ok, we're done :)
  __ blr ();

  return start;
}
void CppInterpreterGenerator::generate_compute_interpreter_state(bool native)
{
  StackFrame frame;

  const Address stack_words_addr(
    Rmethod, methodOopDesc::max_stack_offset());
  const Address access_flags_addr(
    Rmethod, methodOopDesc::access_flags_offset());

  Label not_synchronized_1, not_synchronized_2, not_synchronized_3;
  Label not_static, init_monitor;

  const int monitor_size = frame::interpreter_frame_monitor_size() * wordSize;

  // Calculate the access flags conditions
  const Register access_flags = r3;

  __ lwz (access_flags, access_flags_addr);
  __ andi_ (r0, access_flags, JVM_ACC_SYNCHRONIZED);
  __ compare (CRsync, r0, JVM_ACC_SYNCHRONIZED);
  __ andi_ (r0, access_flags, JVM_ACC_STATIC);
  __ compare (CRstatic, r0, JVM_ACC_STATIC);

  const int basic_frame_size =
    frame.unaligned_size() + sizeof(BytecodeInterpreter) + slop_factor;

  // Calculate the frame size
  const Register stack_size = r3;
  const Register frame_size = r4;
  const Register padding    = r5;

  if (native) {
    __ load (frame_size, basic_frame_size);
  }
  else {
    __ lhz (stack_size, stack_words_addr);
    __ shift_left (stack_size, stack_size, LogBytesPerWord);
    __ addi (frame_size, stack_size, basic_frame_size);
  }
  __ bne (CRsync, not_synchronized_1);
  __ addi (frame_size, frame_size, monitor_size);
  __ bind (not_synchronized_1);
  __ calc_padding_for_alignment (padding, frame_size, StackAlignmentInBytes);
  __ add (frame_size, frame_size, padding);

  // Save the link register and create the new frame
  __ mflr (r0);
  __ store (r0, Address(r1, StackFrame::lr_save_offset * wordSize));
  __ neg (r0, frame_size);
  __ store_update_indexed (r1, r1, r0);

  // Calculate everything's addresses
  const Register stack_limit  = r6;
  const Register stack        = r7;
  const Register stack_base   = Rmonitor;
  const Register monitor_base = r8;

  __ addi (stack_limit, r1, frame.start_of_locals() + slop_factor - wordSize);
  __ add (stack_limit, stack_limit, padding);
  if (native)
    __ mr (stack, stack_limit);
  else
    __ add (stack, stack_limit, stack_size);
  __ addi (stack_base, stack, wordSize);
  __ mr (monitor_base, stack_base);
  __ bne (CRsync, not_synchronized_2);
  __ addi (monitor_base, monitor_base, monitor_size);
  __ bind (not_synchronized_2);
  __ mr (r0, Rstate);
  __ mr (Rstate, monitor_base);

  // Initialise the interpreter state object
  __ store (Rlocals, STATE(_locals));
  __ store (Rmethod, STATE(_method));
  __ store (Rstate, STATE(_self_link));
  __ store (r0, STATE(_prev_link));
  __ store (stack_limit, STATE(_stack_limit));
  __ store (stack, STATE(_stack));
  __ store (stack_base, STATE(_stack_base));
  __ store (monitor_base, STATE(_monitor_base));
  __ store (Rthread, STATE(_thread));

#ifdef ASSERT
  {
    Label ok;
    __ load (r3, ThreadLocalStorage::thread_index());
    __ call (CAST_FROM_FN_PTR(address, pthread_getspecific));
    __ compare (Rthread, r3);
    __ beq (ok);
    __ should_not_reach_here (__FILE__, __LINE__);
    __ bind (ok);
  }
#endif

  if (!native) {
    __ load (r3, Address(Rmethod, methodOopDesc::const_offset()));
    __ addi (r3, r3, in_bytes(constMethodOopDesc::codes_offset()));
    __ store (r3, STATE(_bcp));
  }

  __ load (r3, Address(Rmethod, methodOopDesc::constants_offset()));
  __ load (r3, Address(r3, constantPoolOopDesc::cache_offset_in_bytes()));
  __ store (r3, STATE(_constants));

  __ load (r3, BytecodeInterpreter::method_entry);
  __ stw (r3, STATE(_msg)); 

  __ load (r3, 0);
  if (native)
    __ store (r3, STATE(_bcp));    
  __ store (r3, STATE(_oop_temp));
  __ store (r3, STATE(_mdx));
  __ store (r3, STATE(_result._to_call._callee));

  // Initialise the monitor if synchronized
  __ bne (CRsync, not_synchronized_3);
  __ bne (CRstatic, not_static);
  __ get_mirror_handle (r3);  
  __ b (init_monitor);
  __ bind (not_static);
  __ load (r3, Address(Rlocals, 0));
  __ bind (init_monitor);
  __ store (r3, Address(Rmonitor, BasicObjectLock::obj_offset_in_bytes()));
  __ bind (not_synchronized_3);
}
Exemplo n.º 7
0
void simulate_MainWindow::simulate()
{
    currInstr=instrList[PC/4];
    currBin=binList[PC/4];

    vector<string> result;
    string temp=currInstr.toStdString();
    string_split(temp,result);

    coutString="";
    RD=RS=RT=immediate=address=0;
    v0=v1=v2=v3="None";
    v0=result[0];
    v1=result[1];
    printf("v0=%s\nv1=%s\n",v0.c_str(),v1.c_str());
    if(v0=="jr"||v0=="j"||v0=="jal")  // 2 parametes
    {
        if(v0=="jr")
        {
            jr();
        }
        else if(v0=="j")
            j();
        else if(v0=="jal")
            jal();
    }
    else if(v0=="lui")    // 3 parameters
    {
        v2=result[2];
        lui();
    }
    else                 // 4 parameters
    {
        v2=result[2];
        v3=result[3];
        if(v0=="add")
            add();
        else if(v0=="addu")
            addu();
        else if(v0=="sub")
            sub();
        else if(v0=="subu")
            subu();
        else if(v0=="and")
            and_funct();
        else if(v0=="or")
            or_funct();
        else if(v0=="xor")
            xor_funct();
        else if(v0=="nor")
            nor();
        else if(v0=="slt")
            slt();
        else if(v0=="sltu")
            sltu();
        else if(v0=="sll")
            sll();
        else if(v0=="srl")
            srl();
        else if(v0=="sllv")
            sllv();
        else if(v0=="srlv")
            srlv();
        else if(v0=="srav")
            srav();
        else if(v0=="addi")
            addi();
        else if(v0=="addiu")
            addiu();
        else if(v0=="andi")
            andi();
        else if(v0=="ori")
            ori();
        else if(v0=="xori")
            xori();
        else if(v0=="sw")
            sw();
        else if(v0=="lw")
            lw();
        else if(v0=="beq")
            beq();
        else if(v0=="bne")
            bne();
        else if(v0=="slti")
            slti();
        else if(v0=="sltiu")
            sltiu();
    }
    display_all();
}
Exemplo n.º 8
0
Arquivo: m6805.c Projeto: dinkc64/mame
/* execute instructions on this CPU until icount expires */
void m6805_base_device::execute_run()
{
	UINT8 ireg;

	S = SP_ADJUST( S );     /* Taken from CPU_SET_CONTEXT when pointer'afying */

	do
	{
		if (m_pending_interrupts != 0)
		{
			interrupt();
		}

		debugger_instruction_hook(this, PC);

		ireg=M_RDOP(PC++);

		switch( ireg )
		{
			case 0x00: brset(0x01); break;
			case 0x01: brclr(0x01); break;
			case 0x02: brset(0x02); break;
			case 0x03: brclr(0x02); break;
			case 0x04: brset(0x04); break;
			case 0x05: brclr(0x04); break;
			case 0x06: brset(0x08); break;
			case 0x07: brclr(0x08); break;
			case 0x08: brset(0x10); break;
			case 0x09: brclr(0x10); break;
			case 0x0A: brset(0x20); break;
			case 0x0B: brclr(0x20); break;
			case 0x0C: brset(0x40); break;
			case 0x0D: brclr(0x40); break;
			case 0x0E: brset(0x80); break;
			case 0x0F: brclr(0x80); break;
			case 0x10: bset(0x01); break;
			case 0x11: bclr(0x01); break;
			case 0x12: bset(0x02); break;
			case 0x13: bclr(0x02); break;
			case 0x14: bset(0x04); break;
			case 0x15: bclr(0x04); break;
			case 0x16: bset(0x08); break;
			case 0x17: bclr(0x08); break;
			case 0x18: bset(0x10); break;
			case 0x19: bclr(0x10); break;
			case 0x1a: bset(0x20); break;
			case 0x1b: bclr(0x20); break;
			case 0x1c: bset(0x40); break;
			case 0x1d: bclr(0x40); break;
			case 0x1e: bset(0x80); break;
			case 0x1f: bclr(0x80); break;
			case 0x20: bra(); break;
			case 0x21: brn(); break;
			case 0x22: bhi(); break;
			case 0x23: bls(); break;
			case 0x24: bcc(); break;
			case 0x25: bcs(); break;
			case 0x26: bne(); break;
			case 0x27: beq(); break;
			case 0x28: bhcc(); break;
			case 0x29: bhcs(); break;
			case 0x2a: bpl(); break;
			case 0x2b: bmi(); break;
			case 0x2c: bmc(); break;
			case 0x2d: bms(); break;
			case 0x2e: bil(); break;
			case 0x2f: bih(); break;
			case 0x30: neg_di(); break;
			case 0x31: illegal(); break;
			case 0x32: illegal(); break;
			case 0x33: com_di(); break;
			case 0x34: lsr_di(); break;
			case 0x35: illegal(); break;
			case 0x36: ror_di(); break;
			case 0x37: asr_di(); break;
			case 0x38: lsl_di(); break;
			case 0x39: rol_di(); break;
			case 0x3a: dec_di(); break;
			case 0x3b: illegal(); break;
			case 0x3c: inc_di(); break;
			case 0x3d: tst_di(); break;
			case 0x3e: illegal(); break;
			case 0x3f: clr_di(); break;
			case 0x40: nega(); break;
			case 0x41: illegal(); break;
			case 0x42: illegal(); break;
			case 0x43: coma(); break;
			case 0x44: lsra(); break;
			case 0x45: illegal(); break;
			case 0x46: rora(); break;
			case 0x47: asra(); break;
			case 0x48: lsla(); break;
			case 0x49: rola(); break;
			case 0x4a: deca(); break;
			case 0x4b: illegal(); break;
			case 0x4c: inca(); break;
			case 0x4d: tsta(); break;
			case 0x4e: illegal(); break;
			case 0x4f: clra(); break;
			case 0x50: negx(); break;
			case 0x51: illegal(); break;
			case 0x52: illegal(); break;
			case 0x53: comx(); break;
			case 0x54: lsrx(); break;
			case 0x55: illegal(); break;
			case 0x56: rorx(); break;
			case 0x57: asrx(); break;
			case 0x58: aslx(); break;
			case 0x59: rolx(); break;
			case 0x5a: decx(); break;
			case 0x5b: illegal(); break;
			case 0x5c: incx(); break;
			case 0x5d: tstx(); break;
			case 0x5e: illegal(); break;
			case 0x5f: clrx(); break;
			case 0x60: neg_ix1(); break;
			case 0x61: illegal(); break;
			case 0x62: illegal(); break;
			case 0x63: com_ix1(); break;
			case 0x64: lsr_ix1(); break;
			case 0x65: illegal(); break;
			case 0x66: ror_ix1(); break;
			case 0x67: asr_ix1(); break;
			case 0x68: lsl_ix1(); break;
			case 0x69: rol_ix1(); break;
			case 0x6a: dec_ix1(); break;
			case 0x6b: illegal(); break;
			case 0x6c: inc_ix1(); break;
			case 0x6d: tst_ix1(); break;
			case 0x6e: illegal(); break;
			case 0x6f: clr_ix1(); break;
			case 0x70: neg_ix(); break;
			case 0x71: illegal(); break;
			case 0x72: illegal(); break;
			case 0x73: com_ix(); break;
			case 0x74: lsr_ix(); break;
			case 0x75: illegal(); break;
			case 0x76: ror_ix(); break;
			case 0x77: asr_ix(); break;
			case 0x78: lsl_ix(); break;
			case 0x79: rol_ix(); break;
			case 0x7a: dec_ix(); break;
			case 0x7b: illegal(); break;
			case 0x7c: inc_ix(); break;
			case 0x7d: tst_ix(); break;
			case 0x7e: illegal(); break;
			case 0x7f: clr_ix(); break;
			case 0x80: rti(); break;
			case 0x81: rts(); break;
			case 0x82: illegal(); break;
			case 0x83: swi(); break;
			case 0x84: illegal(); break;
			case 0x85: illegal(); break;
			case 0x86: illegal(); break;
			case 0x87: illegal(); break;
			case 0x88: illegal(); break;
			case 0x89: illegal(); break;
			case 0x8a: illegal(); break;
			case 0x8b: illegal(); break;
			case 0x8c: illegal(); break;
			case 0x8d: illegal(); break;
			case 0x8e: illegal(); break;
			case 0x8f: illegal(); break;
			case 0x90: illegal(); break;
			case 0x91: illegal(); break;
			case 0x92: illegal(); break;
			case 0x93: illegal(); break;
			case 0x94: illegal(); break;
			case 0x95: illegal(); break;
			case 0x96: illegal(); break;
			case 0x97: tax(); break;
			case 0x98: CLC; break;
			case 0x99: SEC; break;
#if IRQ_LEVEL_DETECT
			case 0x9a: CLI; if (m_irq_state != CLEAR_LINE) m_pending_interrupts |= 1 << M6805_IRQ_LINE; break;
#else
			case 0x9a: CLI; break;
#endif
			case 0x9b: SEI; break;
			case 0x9c: rsp(); break;
			case 0x9d: nop(); break;
			case 0x9e: illegal(); break;
			case 0x9f: txa(); break;
			case 0xa0: suba_im(); break;
			case 0xa1: cmpa_im(); break;
			case 0xa2: sbca_im(); break;
			case 0xa3: cpx_im(); break;
			case 0xa4: anda_im(); break;
			case 0xa5: bita_im(); break;
			case 0xa6: lda_im(); break;
			case 0xa7: illegal(); break;
			case 0xa8: eora_im(); break;
			case 0xa9: adca_im(); break;
			case 0xaa: ora_im(); break;
			case 0xab: adda_im(); break;
			case 0xac: illegal(); break;
			case 0xad: bsr(); break;
			case 0xae: ldx_im(); break;
			case 0xaf: illegal(); break;
			case 0xb0: suba_di(); break;
			case 0xb1: cmpa_di(); break;
			case 0xb2: sbca_di(); break;
			case 0xb3: cpx_di(); break;
			case 0xb4: anda_di(); break;
			case 0xb5: bita_di(); break;
			case 0xb6: lda_di(); break;
			case 0xb7: sta_di(); break;
			case 0xb8: eora_di(); break;
			case 0xb9: adca_di(); break;
			case 0xba: ora_di(); break;
			case 0xbb: adda_di(); break;
			case 0xbc: jmp_di(); break;
			case 0xbd: jsr_di(); break;
			case 0xbe: ldx_di(); break;
			case 0xbf: stx_di(); break;
			case 0xc0: suba_ex(); break;
			case 0xc1: cmpa_ex(); break;
			case 0xc2: sbca_ex(); break;
			case 0xc3: cpx_ex(); break;
			case 0xc4: anda_ex(); break;
			case 0xc5: bita_ex(); break;
			case 0xc6: lda_ex(); break;
			case 0xc7: sta_ex(); break;
			case 0xc8: eora_ex(); break;
			case 0xc9: adca_ex(); break;
			case 0xca: ora_ex(); break;
			case 0xcb: adda_ex(); break;
			case 0xcc: jmp_ex(); break;
			case 0xcd: jsr_ex(); break;
			case 0xce: ldx_ex(); break;
			case 0xcf: stx_ex(); break;
			case 0xd0: suba_ix2(); break;
			case 0xd1: cmpa_ix2(); break;
			case 0xd2: sbca_ix2(); break;
			case 0xd3: cpx_ix2(); break;
			case 0xd4: anda_ix2(); break;
			case 0xd5: bita_ix2(); break;
			case 0xd6: lda_ix2(); break;
			case 0xd7: sta_ix2(); break;
			case 0xd8: eora_ix2(); break;
			case 0xd9: adca_ix2(); break;
			case 0xda: ora_ix2(); break;
			case 0xdb: adda_ix2(); break;
			case 0xdc: jmp_ix2(); break;
			case 0xdd: jsr_ix2(); break;
			case 0xde: ldx_ix2(); break;
			case 0xdf: stx_ix2(); break;
			case 0xe0: suba_ix1(); break;
			case 0xe1: cmpa_ix1(); break;
			case 0xe2: sbca_ix1(); break;
			case 0xe3: cpx_ix1(); break;
			case 0xe4: anda_ix1(); break;
			case 0xe5: bita_ix1(); break;
			case 0xe6: lda_ix1(); break;
			case 0xe7: sta_ix1(); break;
			case 0xe8: eora_ix1(); break;
			case 0xe9: adca_ix1(); break;
			case 0xea: ora_ix1(); break;
			case 0xeb: adda_ix1(); break;
			case 0xec: jmp_ix1(); break;
			case 0xed: jsr_ix1(); break;
			case 0xee: ldx_ix1(); break;
			case 0xef: stx_ix1(); break;
			case 0xf0: suba_ix(); break;
			case 0xf1: cmpa_ix(); break;
			case 0xf2: sbca_ix(); break;
			case 0xf3: cpx_ix(); break;
			case 0xf4: anda_ix(); break;
			case 0xf5: bita_ix(); break;
			case 0xf6: lda_ix(); break;
			case 0xf7: sta_ix(); break;
			case 0xf8: eora_ix(); break;
			case 0xf9: adca_ix(); break;
			case 0xfa: ora_ix(); break;
			case 0xfb: adda_ix(); break;
			case 0xfc: jmp_ix(); break;
			case 0xfd: jsr_ix(); break;
			case 0xfe: ldx_ix(); break;
			case 0xff: stx_ix(); break;
		}
		m_icount -= m_cycles1[ireg];
	} while( m_icount > 0 );
}
Exemplo n.º 9
0
/** 
 * @brief emulate instruction 
 * @return returns false if something goes wrong (e.g. illegal instruction)
 *
 * Current limitations:
 * 
 * - Illegal instructions are not implemented
 * - Excess cycles due to page boundary crossing are not calculated
 * - Some known architectural bugs are not emulated
 */
bool Cpu::emulate()
{
  /* fetch instruction */
  uint8_t insn = fetch_op();
  bool retval = true;
  /* emulate instruction */
  switch(insn)
  {
  /* BRK */
  case 0x0: brk(); break;
  /* ORA (nn,X) */
  case 0x1: ora(load_byte(addr_indx()),6); break;
  /* ORA nn */
  case 0x5: ora(load_byte(addr_zero()),3); break;
  /* ASL nn */
  case 0x6: asl_mem(addr_zero(),5); break;
  /* PHP */
  case 0x8: php(); break;
  /* ORA #nn */
  case 0x9: ora(fetch_op(),2); break;
  /* ASL A */
  case 0xA: asl_a(); break;
  /* ORA nnnn */
  case 0xD: ora(load_byte(addr_abs()),4); break;
  /* ASL nnnn */
  case 0xE: asl_mem(addr_abs(),6); break; 
  /* BPL nn */
  case 0x10: bpl(); break;
  /* ORA (nn,Y) */
  case 0x11: ora(load_byte(addr_indy()),5); break;
  /* ORA nn,X */
  case 0x15: ora(load_byte(addr_zerox()),4); break;
  /* ASL nn,X */
  case 0x16: asl_mem(addr_zerox(),6); break;
  /* CLC */
  case 0x18: clc(); break;
  /* ORA nnnn,Y */
  case 0x19: ora(load_byte(addr_absy()),4); break;
  /* ORA nnnn,X */
  case 0x1D: ora(load_byte(addr_absx()),4); break;
  /* ASL nnnn,X */
  case 0x1E: asl_mem(addr_absx(),7); break;
  /* JSR */
  case 0x20: jsr(); break;
  /* AND (nn,X) */
  case 0x21: _and(load_byte(addr_indx()),6); break;
  /* BIT nn */
  case 0x24: bit(addr_zero(),3); break;
  /* AND nn */
  case 0x25: _and(load_byte(addr_zero()),3); break;
  /* ROL nn */
  case 0x26: rol_mem(addr_zero(),5); break;
  /* PLP */
  case 0x28: plp(); break;
  /* AND #nn */
  case 0x29: _and(fetch_op(),2); break;
  /* ROL A */
  case 0x2A: rol_a(); break;
  /* BIT nnnn */
  case 0x2C: bit(addr_abs(),4); break;
  /* AND nnnn */
  case 0x2D: _and(load_byte(addr_abs()),4); break;
  /* ROL nnnn */
  case 0x2E: rol_mem(addr_abs(),6); break;
  /* BMI nn */
  case 0x30: bmi(); break;
  /* AND (nn,Y) */
  case 0x31: _and(load_byte(addr_indy()),5); break;               
  /* AND nn,X */
  case 0x35: _and(load_byte(addr_zerox()),4); break;
  /* ROL nn,X */
  case 0x36: rol_mem(addr_zerox(),6); break;
  /* SEC */
  case 0x38: sec(); break;
  /* AND nnnn,Y */
  case 0x39: _and(load_byte(addr_absy()),4); break;
  /* AND nnnn,X */
  case 0x3D: _and(load_byte(addr_absx()),4); break;
  /* ROL nnnn,X */
  case 0x3E: rol_mem(addr_absx(),7); break;
  /* RTI */
  case 0x40: rti(); break;
  /* EOR (nn,X) */
  case 0x41: eor(load_byte(addr_indx()),6); break;
  /* EOR nn */
  case 0x45: eor(load_byte(addr_zero()),3); break;
  /* LSR nn */
  case 0x46: lsr_mem(addr_zero(),5); break;
  /* PHA */
  case 0x48: pha(); break;
  /* EOR #nn */
  case 0x49: eor(fetch_op(),2); break;
  /* BVC */
  case 0x50: bvc(); break;
  /* JMP nnnn */
  case 0x4C: jmp(); break;
  /* EOR nnnn */
  case 0x4D: eor(load_byte(addr_abs()),4); break;
  /* LSR A */
  case 0x4A: lsr_a(); break;
  /* LSR nnnn */
  case 0x4E: lsr_mem(addr_abs(),6); break;
  /* EOR (nn,Y) */
  case 0x51: eor(load_byte(addr_indy()),5); break;
  /* EOR nn,X */
  case 0x55: eor(load_byte(addr_zerox()),4); break;
  /* LSR nn,X */
  case 0x56: lsr_mem(addr_zerox(),6); break;
  /* CLI */
  case 0x58: cli(); break;
  /* EOR nnnn,Y */
  case 0x59: eor(load_byte(addr_absy()),4); break;
  /* EOR nnnn,X */
  case 0x5D: eor(load_byte(addr_absx()),4); break;
  /* LSR nnnn,X */
  case 0x5E: lsr_mem(addr_absx(),7); break;
  /* RTS */
  case 0x60: rts(); break;
  /* ADC (nn,X) */
  case 0x61: adc(load_byte(addr_indx()),6); break;
  /* ADC nn */
  case 0x65: adc(load_byte(addr_zero()),3); break;
  /* ROR nn */
  case 0x66: ror_mem(addr_zero(),5); break;
  /* PLA */
  case 0x68: pla(); break;
  /* ADC #nn */
  case 0x69: adc(fetch_op(),2); break;
  /* ROR A */
  case 0x6A: ror_a(); break;
  /* JMP (nnnn) */
  case 0x6C: jmp_ind(); break;
  /* ADC nnnn */
  case 0x6D: adc(load_byte(addr_abs()),4); break;
  /* ROR nnnn */
  case 0x6E: ror_mem(addr_abs(),6); break;
  /* BVS */
  case 0x70: bvs(); break;
  /* ADC (nn,Y) */
  case 0x71: adc(load_byte(addr_indy()),5); break;
  /* ADC nn,X */
  case 0x75: adc(load_byte(addr_zerox()),4); break;
  /* ROR nn,X */
  case 0x76: ror_mem(addr_zerox(),6); break;
  /* SEI */
  case 0x78: sei(); break;
  /* ADC nnnn,Y */
  case 0x79: adc(load_byte(addr_absy()),4); break;
  /* ADC nnnn,X */
  case 0x7D: adc(load_byte(addr_absx()),4); break;
  /* ROR nnnn,X */
  case 0x7E: ror_mem(addr_absx(),7); break;
  /* STA (nn,X) */
  case 0x81: sta(addr_indx(),6); break;
  /* STY nn */
  case 0x84: sty(addr_zero(),3); break;
  /* STA nn */
  case 0x85: sta(addr_zero(),3); break;
  /* STX nn */
  case 0x86: stx(addr_zero(),3); break;
  /* DEY */
  case 0x88: dey(); break;
  /* TXA */
  case 0x8A: txa(); break;
  /* STY nnnn */
  case 0x8C: sty(addr_abs(),4); break;
  /* STA nnnn */
  case 0x8D: sta(addr_abs(),4); break;
  /* STX nnnn */
  case 0x8E: stx(addr_abs(),4); break;
  /* BCC nn */
  case 0x90: bcc(); break;
  /* STA (nn,Y) */
  case 0x91: sta(addr_indy(),6); break;
  /* STY nn,X */
  case 0x94: sty(addr_zerox(),4); break;
  /* STA nn,X */
  case 0x95: sta(addr_zerox(),4); break;
  /* STX nn,Y */
  case 0x96: stx(addr_zeroy(),4); break;
  /* TYA */
  case 0x98: tya(); break;
  /* STA nnnn,Y */
  case 0x99: sta(addr_absy(),5); break;
  /* TXS */
  case 0x9A: txs(); break;
  /* STA nnnn,X */
  case 0x9D: sta(addr_absx(),5); break;
  /* LDY #nn */
  case 0xA0: ldy(fetch_op(),2); break; 
  /* LDA (nn,X) */
  case 0xA1: lda(load_byte(addr_indx()),6); break;
  /* LDX #nn */
  case 0xA2: ldx(fetch_op(),2); break;
  /* LDY nn */
  case 0xA4: ldy(load_byte(addr_zero()),3); break;
  /* LDA nn */
  case 0xA5: lda(load_byte(addr_zero()),3); break;
  /* LDX nn */
  case 0xA6: ldx(load_byte(addr_zero()),3); break;
  /* TAY */
  case 0xA8: tay(); break;
  /* LDA #nn */
  case 0xA9: lda(fetch_op(),2); break;
  /* TAX */
  case 0xAA: tax(); break;
  /* LDY nnnn */
  case 0xAC: ldy(load_byte(addr_abs()),4); break;
  /* LDA nnnn */
  case 0xAD: lda(load_byte(addr_abs()),4); break;
  /* LDX nnnn */
  case 0xAE: ldx(load_byte(addr_abs()),4); break;
  /* BCS nn */
  case 0xB0: bcs(); break;
  /* LDA (nn,Y) */
  case 0xB1: lda(load_byte(addr_indy()),5); break;
  /* LDY nn,X */
  case 0xB4: ldy(load_byte(addr_zerox()),3); break;
  /* LDA nn,X */
  case 0xB5: lda(load_byte(addr_zerox()),3); break;
  /* LDX nn,Y */
  case 0xB6: ldx(load_byte(addr_zeroy()),3); break;
  /* CLV */
  case 0xB8: clv(); break;
  /* LDA nnnn,Y */
  case 0xB9: lda(load_byte(addr_absy()),4); break;
  /* TSX */
  case 0xBA: tsx(); break;
  /* LDY nnnn,X */
  case 0xBC: ldy(load_byte(addr_absx()),4); break;
  /* LDA nnnn,X */
  case 0xBD: lda(load_byte(addr_absx()),4); break;
  /* LDX nnnn,Y */
  case 0xBE: ldx(load_byte(addr_absy()),4); break;
  /* CPY #nn */
  case 0xC0: cpy(fetch_op(),2); break;
  /* CMP (nn,X) */
  case 0xC1: cmp(load_byte(addr_indx()),6); break;
  /* CPY nn */
  case 0xC4: cpy(load_byte(addr_zero()),3); break;
  /* CMP nn */
  case 0xC5: cmp(load_byte(addr_zero()),3); break;
  /* DEC nn */
  case 0xC6: dec(addr_zero(),5); break;
  /* INY */
  case 0xC8: iny(); break;
  /* CMP #nn */
  case 0xC9: cmp(fetch_op(),2); break;
  /* DEX */
  case 0xCA: dex(); break;
  /* CPY nnnn */
  case 0xCC: cpy(load_byte(addr_abs()),4); break;
  /* CMP nnnn */
  case 0xCD: cmp(load_byte(addr_abs()),4); break;
  /* DEC nnnn */
  case 0xCE: dec(addr_abs(),6); break;
  /* BNE nn */
  case 0xD0: bne(); break;
  /* CMP (nn,Y) */
  case 0xD1: cmp(load_byte(addr_indy()),5); break;
  /* CMP nn,X */
  case 0xD5: cmp(load_byte(addr_zerox()),4); break;
  /* DEC nn,X */
  case 0xD6: dec(addr_zerox(),6); break;
  /* CLD */
  case 0xD8: cld(); break;
  /* CMP nnnn,Y */
  case 0xD9: cmp(load_byte(addr_absy()),4); break;
  /* CMP nnnn,X */
  case 0xDD: cmp(load_byte(addr_absx()),4); break;
  /* DEC nnnn,X */
  case 0xDE: dec(addr_absx(),7); break;
  /* CPX #nn */
  case 0xE0: cpx(fetch_op(),2); break;
  /* SBC (nn,X) */
  case 0xE1: sbc(load_byte(addr_indx()),6); break;
  /* CPX nn */
  case 0xE4: cpx(load_byte(addr_zero()),3); break;
  /* SBC nn */
  case 0xE5: sbc(load_byte(addr_zero()),3); break;
  /* INC nn */
  case 0xE6: inc(addr_zero(),5); break;
  /* INX */
  case 0xE8: inx(); break;
  /* SBC #nn */
  case 0xE9: sbc(fetch_op(),2); break;
  /* NOP */
  case 0xEA: nop(); break;
  /* CPX nnnn */
  case 0xEC: cpx(load_byte(addr_abs()),4); break;
  /* SBC nnnn */
  case 0xED: sbc(load_byte(addr_abs()),4); break;
  /* INC nnnn */
  case 0xEE: inc(addr_abs(),6); break;
  /* BEQ nn */
  case 0xF0: beq(); break;
  /* SBC (nn,Y) */
  case 0xF1: sbc(load_byte(addr_indy()),5); break;
  /* SBC nn,X */
  case 0xF5: sbc(load_byte(addr_zerox()),4); break;
  /* INC nn,X */
  case 0xF6: inc(addr_zerox(),6); break;
  /* SED */
  case 0xF8: sed(); break;
  /* SBC nnnn,Y */
  case 0xF9: sbc(load_byte(addr_absy()),4); break;
  /* SBC nnnn,X */
  case 0xFD: sbc(load_byte(addr_absx()),4); break;
  /* INC nnnn,X */
  case 0xFE: inc(addr_absx(),7); break;
  /* Unknown or illegal instruction */
  default:
    D("Unknown instruction: %X at %04x\n", insn,pc());
    retval = false;
  }
  return retval;
}
Exemplo n.º 10
0
  address generate_call_stub(address& return_address)
  {
    assert (!TaggedStackInterpreter, "not supported");
    
    StubCodeMark mark(this, "StubRoutines", "call_stub");
    address start = __ enter();

    const Register call_wrapper    = r3;
    const Register result          = r4;
    const Register result_type     = r5;
    const Register method          = r6;
    const Register entry_point     = r7;
    const Register parameters      = r8;
    const Register parameter_words = r9;
    const Register thread          = r10;

#ifdef ASSERT
    // Make sure we have no pending exceptions
    {
      StackFrame frame;
      Label label;

      __ load (r0, Address(thread, Thread::pending_exception_offset()));
      __ compare (r0, 0);
      __ beq (label);
      __ prolog (frame);
      __ should_not_reach_here (__FILE__, __LINE__);
      __ epilog (frame);
      __ blr ();
      __ bind (label);
    }
#endif // ASSERT

    // Calculate the frame size
    StackFrame frame;
    for (int i = 0; i < StackFrame::max_crfs; i++)
      frame.get_cr_field();
    for (int i = 0; i < StackFrame::max_gprs; i++)
      frame.get_register();
    StubRoutines::set_call_stub_base_size(frame.unaligned_size() + 3*wordSize);
    // the 3 extra words are for call_wrapper, result and result_type

    const Register parameter_bytes = parameter_words;

    __ shift_left (parameter_bytes, parameter_words, LogBytesPerWord);    

    const Register frame_size = r11;
    const Register padding    = r12;

    __ addi (frame_size, parameter_bytes, StubRoutines::call_stub_base_size());
    __ calc_padding_for_alignment (padding, frame_size, StackAlignmentInBytes);
    __ add (frame_size, frame_size, padding);

    // Save the link register and create the new frame
    __ mflr (r0);
    __ store (r0, Address(r1, StackFrame::lr_save_offset * wordSize));
    __ neg (r0, frame_size);
    __ store_update_indexed (r1, r1, r0);
#ifdef PPC64
    __ mfcr (r0);
    __ store (r0, Address(r1, StackFrame::cr_save_offset * wordSize));
#endif // PPC64

    // Calculate the address of the interpreter's local variables
    const Register locals = frame_size;

    __ addi (locals, r1, frame.start_of_locals() - wordSize);
    __ add (locals, locals, padding);
    __ add (locals, locals, parameter_bytes);

    // Store the call wrapper address and the result stuff
    const int initial_offset = 1;
    int offset = initial_offset;

    __ store (call_wrapper, Address(locals, offset++ * wordSize));
    __ store (result,       Address(locals, offset++ * wordSize));
    __ store (result_type,  Address(locals, offset++ * wordSize));

    // Store the registers
#ifdef PPC32
    __ mfcr (r0);
    __ store (r0, Address(locals, offset++ * wordSize));
#endif // PPC32
    for (int i = 14; i < 32; i++) {
      __ store (as_Register(i), Address(locals, offset++ * wordSize));
    }
    const int final_offset = offset;

    // Store the location of call_wrapper
    frame::set_call_wrapper_offset((final_offset - initial_offset) * wordSize);

#ifdef ASSERT
    // Check that we wrote all the way to the end of the frame.
    // The frame may have been resized when we return from the
    // interpreter, so the start of the frame may have moved
    // but the end will be where we left it and we rely on this
    // to find our stuff.
    {
      StackFrame frame;
      Label label;

      __ load (r3, Address(r1, 0));
      __ subi (r3, r3, final_offset * wordSize);
      __ compare (r3, locals);
      __ beq (label);
      __ prolog (frame);
      __ should_not_reach_here (__FILE__, __LINE__);
      __ epilog (frame);
      __ blr ();
      __ bind (label);
    }
#endif // ASSERT

    // Pass parameters if any
    {
      Label loop, done;

      __ compare (parameter_bytes, 0);
      __ ble (done);

      const Register src = parameters;
      const Register dst = padding;

      __ mr (dst, locals);
      __ shift_right (r0, parameter_bytes, LogBytesPerWord);      
      __ mtctr (r0);
      __ bind (loop);
      __ load (r0, Address(src, 0));
      __ store (r0, Address(dst, 0));
      __ addi (src, src, wordSize);
      __ subi (dst, dst, wordSize);
      __ bdnz (loop);

      __ bind (done);
    }

    // Make the call
    __ mr (Rmethod, method);
    __ mr (Rlocals, locals);
    __ mr (Rthread, thread);
    __ mtctr (entry_point);
    __ bctrl();

    // This is used to identify call_stub stack frames
    return_address = __ pc();

    // Figure out where our stuff is stored
    __ load (locals, Address(r1, 0));
    __ subi (locals, locals, final_offset * wordSize);

#ifdef ASSERT
    // Rlocals should contain the address we just calculated.
    {
      StackFrame frame;
      Label label;

      __ compare (Rlocals, locals);
      __ beq (label);
      __ prolog (frame);
      __ should_not_reach_here (__FILE__, __LINE__);
      __ epilog (frame);
      __ blr ();
      __ bind (label);
    }
#endif // ASSERT
 
    // Is an exception being thrown?
    Label exit;

    __ load (r0, Address(Rthread, Thread::pending_exception_offset()));
    __ compare (r0, 0);
    __ bne (exit);

    // Store result depending on type
    const Register result_addr = r6;

    Label is_int, is_long, is_object;

    offset = initial_offset + 1; // skip call_wrapper
    __ load (result_addr, Address(locals, offset++ * wordSize));
    __ load (result_type, Address(locals, offset++ * wordSize));
    __ compare (result_type, T_INT);
    __ beq (is_int);
    __ compare (result_type, T_LONG);
    __ beq (is_long);
    __ compare (result_type, T_OBJECT);
    __ beq (is_object);
    
    __ should_not_reach_here (__FILE__, __LINE__);

    __ bind (is_int);
    __ stw (r3, Address(result_addr, 0));
    __ b (exit);
    
    __ bind (is_long);
#ifdef PPC32
    __ store (r4, Address(result_addr, wordSize));
#endif
    __ store (r3, Address(result_addr, 0));
    __ b (exit);
    
    __ bind (is_object);
    __ store (r3, Address(result_addr, 0));
    //__ b (exit);

    // Restore the registers
    __ bind (exit);
#ifdef PPC32
    __ load (r0, Address(locals, offset++ * wordSize));
    __ mtcr (r0);
#endif // PPC32
    for (int i = 14; i < 32; i++) {
      __ load (as_Register(i), Address(locals, offset++ * wordSize));
    }
#ifdef PPC64
    __ load (r0, Address(r1, StackFrame::cr_save_offset * wordSize));
    __ mtcr (r0);
#endif // PPC64
    assert (offset == final_offset, "save and restore must match");

    // Unwind and return
    __ load (r1, Address(r1, StackFrame::back_chain_offset * wordSize));
    __ load (r0, Address(r1, StackFrame::lr_save_offset * wordSize));
    __ mtlr (r0);
    __ blr ();
    
    return start;
  }
Exemplo n.º 11
0
address InterpreterGenerator::generate_native_entry(bool synchronized)
{
  const Register handler  = r14;
  const Register function = r15;

  assert_different_registers(Rmethod, Rlocals, Rthread, Rstate, Rmonitor,
			     handler, function);

  // We use the same code for synchronized and not
  if (native_entry)
    return native_entry;

  address start = __ pc();

  // Allocate and initialize our stack frame.
  __ load (Rstate, 0);
  generate_compute_interpreter_state(true);

  // Make sure method is native and not abstract
#ifdef ASSERT
  {
    Label ok;
    __ lwz (r0, Address(Rmethod, methodOopDesc::access_flags_offset()));
    __ andi_ (r0, r0, JVM_ACC_NATIVE | JVM_ACC_ABSTRACT);
    __ compare (r0, JVM_ACC_NATIVE);
    __ beq (ok);
    __ should_not_reach_here (__FILE__, __LINE__);
    __ bind (ok);
  }
#endif

  // Lock if necessary
  Label not_synchronized_1;
  
  __ bne (CRsync, not_synchronized_1);
  __ lock_object (Rmonitor);
  __ bind (not_synchronized_1);
  
  // Get signature handler
  const Address signature_handler_addr(
    Rmethod, methodOopDesc::signature_handler_offset());

  Label return_to_caller, got_signature_handler;

  __ load (handler, signature_handler_addr);
  __ compare (handler, 0);
  __ bne (got_signature_handler);
  __ call_VM (noreg,
              CAST_FROM_FN_PTR(address,
                               InterpreterRuntime::prepare_native_call),
              Rmethod,
              CALL_VM_NO_EXCEPTION_CHECKS);
  __ load (r0, Address(Rthread, Thread::pending_exception_offset()));
  __ compare (r0, 0);
  __ bne (return_to_caller);
  __ load (handler, signature_handler_addr);
  __ bind (got_signature_handler); 

  // Get the native function entry point
  const Address native_function_addr(
    Rmethod, methodOopDesc::native_function_offset());

  Label got_function;

  __ load (function, native_function_addr);
#ifdef ASSERT
  {
    // InterpreterRuntime::prepare_native_call() sets the mirror
    // handle and native function address first and the signature
    // handler last, so function should always be set here.
    Label ok;
    __ compare (function, 0);
    __ bne (ok);
    __ should_not_reach_here (__FILE__, __LINE__);
    __ bind (ok);
  }
#endif

  // Call signature handler
  __ mtctr (handler);
  __ bctrl ();
  __ mr (handler, r0);

  // Pass JNIEnv
  __ la (r3, Address(Rthread, JavaThread::jni_environment_offset()));

  // Pass mirror handle if static
  const Address oop_temp_addr = STATE(_oop_temp);

  Label not_static;

  __ bne (CRstatic, not_static);
  __ get_mirror_handle (r4);
  __ store (r4, oop_temp_addr);
  __ la (r4, oop_temp_addr);
  __ bind (not_static);

  // Set up the Java frame anchor
  __ set_last_Java_frame ();

  // Change the thread state to native
  const Address thread_state_addr(Rthread, JavaThread::thread_state_offset());
#ifdef ASSERT
  {
    Label ok;
    __ lwz (r0, thread_state_addr);
    __ compare (r0, _thread_in_Java);
    __ beq (ok);
    __ should_not_reach_here (__FILE__, __LINE__);
    __ bind (ok);
  }
#endif
  __ load (r0, _thread_in_native);
  __ stw (r0, thread_state_addr);

  // Make the call
  __ call (function);
  __ fixup_after_potential_safepoint ();

  // The result will be in r3 (and maybe r4 on 32-bit) or f1.
  // Wherever it is, we need to store it before calling anything
  const Register r3_save      = r16;
#ifdef PPC32
  const Register r4_save      = r17;
#endif
  const FloatRegister f1_save = f14;

  __ mr (r3_save, r3);
#ifdef PPC32
  __ mr (r4_save, r4);
#endif
  __ fmr (f1_save, f1);

  // Switch thread to "native transition" state before reading the
  // synchronization state.  This additional state is necessary
  // because reading and testing the synchronization state is not
  // atomic with respect to garbage collection.
  __ load (r0, _thread_in_native_trans);
  __ stw (r0, thread_state_addr);

  // Ensure the new state is visible to the VM thread.
  if(os::is_MP()) {
    if (UseMembar)
      __ sync ();
    else
      __ serialize_memory (r3, r4);
  }

  // Check for safepoint operation in progress and/or pending
  // suspend requests.  We use a leaf call in order to leave
  // the last_Java_frame setup undisturbed.
  Label block, no_block;

  __ load (r3, (intptr_t) SafepointSynchronize::address_of_state());
  __ lwz (r0, Address(r3, 0));
  __ compare (r0, SafepointSynchronize::_not_synchronized);
  __ bne (block);
  __ lwz (r0, Address(Rthread, JavaThread::suspend_flags_offset()));
  __ compare (r0, 0);
  __ beq (no_block);
  __ bind (block);
  __ call_VM_leaf (
       CAST_FROM_FN_PTR(address, 
                        JavaThread::check_special_condition_for_native_trans));
  __ fixup_after_potential_safepoint ();
  __ bind (no_block);

  // Change the thread state
  __ load (r0, _thread_in_Java);
  __ stw (r0, thread_state_addr);

  // Reset the frame anchor  
  __ reset_last_Java_frame ();

  // If the result was an OOP then unbox it and store it in the frame
  // (where it will be safe from garbage collection) before we release
  // the handle it might be protected by
  Label non_oop, store_oop;
  
  __ load (r0, (intptr_t) AbstractInterpreter::result_handler(T_OBJECT));
  __ compare (r0, handler);
  __ bne (non_oop);
  __ compare (r3_save, 0);
  __ beq (store_oop);
  __ load (r3_save, Address(r3_save, 0));
  __ bind (store_oop);
  __ store (r3_save, STATE(_oop_temp));
  __ bind (non_oop);

  // Reset handle block
  __ load (r3, Address(Rthread, JavaThread::active_handles_offset()));
  __ load (r0, 0);
  __ stw (r0, Address(r3, JNIHandleBlock::top_offset_in_bytes()));

  // If there is an exception we skip the result handler and return.
  // Note that this also skips unlocking which seems totally wrong,
  // but apparently this is what the asm interpreter does so we do
  // too.
  __ load (r0, Address(Rthread, Thread::pending_exception_offset()));
  __ compare (r0, 0);
  __ bne (return_to_caller);
  
  // Unlock if necessary
  Label not_synchronized_2;
  
  __ bne (CRsync, not_synchronized_2);
  __ unlock_object (Rmonitor);
  __ bind (not_synchronized_2);

  // Restore saved result and call the result handler
  __ mr (r3, r3_save);
#ifdef PPC32
  __ mr (r4, r4_save);
#endif
  __ fmr (f1, f1_save);
  __ mtctr (handler);
  __ bctrl ();
  
  // Unwind the current activation and return
  __ bind (return_to_caller);

  generate_unwind_interpreter_state();
  __ blr ();

  native_entry = start;
  return start;
}
Exemplo n.º 12
0
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
  // Slow_signature handler that respects the PPC C calling conventions.
  //
  // We get called by the native entry code with our output register
  // area == 8. First we call InterpreterRuntime::get_result_handler
  // to copy the pointer to the signature string temporarily to the
  // first C-argument and to return the result_handler in
  // R3_RET. Since native_entry will copy the jni-pointer to the
  // first C-argument slot later on, it is OK to occupy this slot
  // temporarilly. Then we copy the argument list on the java
  // expression stack into native varargs format on the native stack
  // and load arguments into argument registers. Integer arguments in
  // the varargs vector will be sign-extended to 8 bytes.
  //
  // On entry:
  //   R3_ARG1        - intptr_t*     Address of java argument list in memory.
  //   R15_prev_state - BytecodeInterpreter* Address of interpreter state for
  //     this method
  //   R19_method
  //
  // On exit (just before return instruction):
  //   R3_RET            - contains the address of the result_handler.
  //   R4_ARG2           - is not updated for static methods and contains "this" otherwise.
  //   R5_ARG3-R10_ARG8: - When the (i-2)th Java argument is not of type float or double,
  //                       ARGi contains this argument. Otherwise, ARGi is not updated.
  //   F1_ARG1-F13_ARG13 - contain the first 13 arguments of type float or double.

  const int LogSizeOfTwoInstructions = 3;

  // FIXME: use Argument:: GL: Argument names different numbers!
  const int max_fp_register_arguments  = 13;
  const int max_int_register_arguments = 6;  // first 2 are reserved

  const Register arg_java       = R21_tmp1;
  const Register arg_c          = R22_tmp2;
  const Register signature      = R23_tmp3;  // is string
  const Register sig_byte       = R24_tmp4;
  const Register fpcnt          = R25_tmp5;
  const Register argcnt         = R26_tmp6;
  const Register intSlot        = R27_tmp7;
  const Register target_sp      = R28_tmp8;
  const FloatRegister floatSlot = F0;

  address entry = __ function_entry();

  __ save_LR_CR(R0);
  __ save_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));
  // We use target_sp for storing arguments in the C frame.
  __ mr(target_sp, R1_SP);
  __ push_frame_reg_args_nonvolatiles(0, R11_scratch1);

  __ mr(arg_java, R3_ARG1);

  __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_signature), R16_thread, R19_method);

  // Signature is in R3_RET. Signature is callee saved.
  __ mr(signature, R3_RET);

  // Get the result handler.
  __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method);

  {
    Label L;
    // test if static
    // _access_flags._flags must be at offset 0.
    // TODO PPC port: requires change in shared code.
    //assert(in_bytes(AccessFlags::flags_offset()) == 0,
    //       "MethodDesc._access_flags == MethodDesc._access_flags._flags");
    // _access_flags must be a 32 bit value.
    assert(sizeof(AccessFlags) == 4, "wrong size");
    __ lwa(R11_scratch1/*access_flags*/, method_(access_flags));
    // testbit with condition register.
    __ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT);
    __ btrue(CCR0, L);
    // For non-static functions, pass "this" in R4_ARG2 and copy it
    // to 2nd C-arg slot.
    // We need to box the Java object here, so we use arg_java
    // (address of current Java stack slot) as argument and don't
    // dereference it as in case of ints, floats, etc.
    __ mr(R4_ARG2, arg_java);
    __ addi(arg_java, arg_java, -BytesPerWord);
    __ std(R4_ARG2, _abi(carg_2), target_sp);
    __ bind(L);
  }

  // Will be incremented directly after loop_start. argcnt=0
  // corresponds to 3rd C argument.
  __ li(argcnt, -1);
  // arg_c points to 3rd C argument
  __ addi(arg_c, target_sp, _abi(carg_3));
  // no floating-point args parsed so far
  __ li(fpcnt, 0);

  Label move_intSlot_to_ARG, move_floatSlot_to_FARG;
  Label loop_start, loop_end;
  Label do_int, do_long, do_float, do_double, do_dontreachhere, do_object, do_array, do_boxed;

  // signature points to '(' at entry
#ifdef ASSERT
  __ lbz(sig_byte, 0, signature);
  __ cmplwi(CCR0, sig_byte, '(');
  __ bne(CCR0, do_dontreachhere);
#endif

  __ bind(loop_start);

  __ addi(argcnt, argcnt, 1);
  __ lbzu(sig_byte, 1, signature);

  __ cmplwi(CCR0, sig_byte, ')'); // end of signature
  __ beq(CCR0, loop_end);

  __ cmplwi(CCR0, sig_byte, 'B'); // byte
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'C'); // char
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'D'); // double
  __ beq(CCR0, do_double);

  __ cmplwi(CCR0, sig_byte, 'F'); // float
  __ beq(CCR0, do_float);

  __ cmplwi(CCR0, sig_byte, 'I'); // int
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'J'); // long
  __ beq(CCR0, do_long);

  __ cmplwi(CCR0, sig_byte, 'S'); // short
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'Z'); // boolean
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'L'); // object
  __ beq(CCR0, do_object);

  __ cmplwi(CCR0, sig_byte, '['); // array
  __ beq(CCR0, do_array);

  //  __ cmplwi(CCR0, sig_byte, 'V'); // void cannot appear since we do not parse the return type
  //  __ beq(CCR0, do_void);

  __ bind(do_dontreachhere);

  __ unimplemented("ShouldNotReachHere in slow_signature_handler", 120);

  __ bind(do_array);

  {
    Label start_skip, end_skip;

    __ bind(start_skip);
    __ lbzu(sig_byte, 1, signature);
    __ cmplwi(CCR0, sig_byte, '[');
    __ beq(CCR0, start_skip); // skip further brackets
    __ cmplwi(CCR0, sig_byte, '9');
    __ bgt(CCR0, end_skip);   // no optional size
    __ cmplwi(CCR0, sig_byte, '0');
    __ bge(CCR0, start_skip); // skip optional size
    __ bind(end_skip);

    __ cmplwi(CCR0, sig_byte, 'L');
    __ beq(CCR0, do_object);  // for arrays of objects, the name of the object must be skipped
    __ b(do_boxed);          // otherwise, go directly to do_boxed
  }

  __ bind(do_object);
  {
    Label L;
    __ bind(L);
    __ lbzu(sig_byte, 1, signature);
    __ cmplwi(CCR0, sig_byte, ';');
    __ bne(CCR0, L);
   }
  // Need to box the Java object here, so we use arg_java (address of
  // current Java stack slot) as argument and don't dereference it as
  // in case of ints, floats, etc.
  Label do_null;
  __ bind(do_boxed);
  __ ld(R0,0, arg_java);
  __ cmpdi(CCR0, R0, 0);
  __ li(intSlot,0);
  __ beq(CCR0, do_null);
  __ mr(intSlot, arg_java);
  __ bind(do_null);
  __ std(intSlot, 0, arg_c);
  __ addi(arg_java, arg_java, -BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
  __ blt(CCR0, move_intSlot_to_ARG);
  __ b(loop_start);

  __ bind(do_int);
  __ lwa(intSlot, 0, arg_java);
  __ std(intSlot, 0, arg_c);
  __ addi(arg_java, arg_java, -BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
  __ blt(CCR0, move_intSlot_to_ARG);
  __ b(loop_start);

  __ bind(do_long);
  __ ld(intSlot, -BytesPerWord, arg_java);
  __ std(intSlot, 0, arg_c);
  __ addi(arg_java, arg_java, - 2 * BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
  __ blt(CCR0, move_intSlot_to_ARG);
  __ b(loop_start);

  __ bind(do_float);
  __ lfs(floatSlot, 0, arg_java);
#if defined(LINUX)
  // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float
  // in the least significant word of an argument slot.
#if defined(VM_LITTLE_ENDIAN)
  __ stfs(floatSlot, 0, arg_c);
#else
  __ stfs(floatSlot, 4, arg_c);
#endif
#elif defined(AIX)
  // Although AIX runs on big endian CPU, float is in most significant
  // word of an argument slot.
  __ stfs(floatSlot, 0, arg_c);
#else
#error "unknown OS"
#endif
  __ addi(arg_java, arg_java, -BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, fpcnt, max_fp_register_arguments);
  __ blt(CCR0, move_floatSlot_to_FARG);
  __ b(loop_start);

  __ bind(do_double);
  __ lfd(floatSlot, - BytesPerWord, arg_java);
  __ stfd(floatSlot, 0, arg_c);
  __ addi(arg_java, arg_java, - 2 * BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, fpcnt, max_fp_register_arguments);
  __ blt(CCR0, move_floatSlot_to_FARG);
  __ b(loop_start);

  __ bind(loop_end);

  __ pop_frame();
  __ restore_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));
  __ restore_LR_CR(R0);

  __ blr();

  Label move_int_arg, move_float_arg;
  __ bind(move_int_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)
  __ mr(R5_ARG3, intSlot);  __ b(loop_start);
  __ mr(R6_ARG4, intSlot);  __ b(loop_start);
  __ mr(R7_ARG5, intSlot);  __ b(loop_start);
  __ mr(R8_ARG6, intSlot);  __ b(loop_start);
  __ mr(R9_ARG7, intSlot);  __ b(loop_start);
  __ mr(R10_ARG8, intSlot); __ b(loop_start);

  __ bind(move_float_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)
  __ fmr(F1_ARG1, floatSlot);   __ b(loop_start);
  __ fmr(F2_ARG2, floatSlot);   __ b(loop_start);
  __ fmr(F3_ARG3, floatSlot);   __ b(loop_start);
  __ fmr(F4_ARG4, floatSlot);   __ b(loop_start);
  __ fmr(F5_ARG5, floatSlot);   __ b(loop_start);
  __ fmr(F6_ARG6, floatSlot);   __ b(loop_start);
  __ fmr(F7_ARG7, floatSlot);   __ b(loop_start);
  __ fmr(F8_ARG8, floatSlot);   __ b(loop_start);
  __ fmr(F9_ARG9, floatSlot);   __ b(loop_start);
  __ fmr(F10_ARG10, floatSlot); __ b(loop_start);
  __ fmr(F11_ARG11, floatSlot); __ b(loop_start);
  __ fmr(F12_ARG12, floatSlot); __ b(loop_start);
  __ fmr(F13_ARG13, floatSlot); __ b(loop_start);

  __ bind(move_intSlot_to_ARG);
  __ sldi(R0, argcnt, LogSizeOfTwoInstructions);
  __ load_const(R11_scratch1, move_int_arg); // Label must be bound here.
  __ add(R11_scratch1, R0, R11_scratch1);
  __ mtctr(R11_scratch1/*branch_target*/);
  __ bctr();
  __ bind(move_floatSlot_to_FARG);
  __ sldi(R0, fpcnt, LogSizeOfTwoInstructions);
  __ addi(fpcnt, fpcnt, 1);
  __ load_const(R11_scratch1, move_float_arg); // Label must be bound here.
  __ add(R11_scratch1, R0, R11_scratch1);
  __ mtctr(R11_scratch1/*branch_target*/);
  __ bctr();

  return entry;
}
Exemplo n.º 13
0
// Call an accessor method (assuming it is resolved, otherwise drop into
// vanilla (slow path) entry.
address InterpreterGenerator::generate_accessor_entry(void) {
  if (!UseFastAccessorMethods && (!FLAG_IS_ERGO(UseFastAccessorMethods))) {
    return NULL;
  }

  Label Lslow_path, Lacquire;

  const Register
         Rclass_or_obj = R3_ARG1,
         Rconst_method = R4_ARG2,
         Rcodes        = Rconst_method,
         Rcpool_cache  = R5_ARG3,
         Rscratch      = R11_scratch1,
         Rjvmti_mode   = Rscratch,
         Roffset       = R12_scratch2,
         Rflags        = R6_ARG4,
         Rbtable       = R7_ARG5;

  static address branch_table[number_of_states];

  address entry = __ pc();

  // Check for safepoint:
  // Ditch this, real man don't need safepoint checks.

  // Also check for JVMTI mode
  // Check for null obj, take slow path if so.
  __ ld(Rclass_or_obj, Interpreter::stackElementSize, CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp));
  __ lwz(Rjvmti_mode, thread_(interp_only_mode));
  __ cmpdi(CCR1, Rclass_or_obj, 0);
  __ cmpwi(CCR0, Rjvmti_mode, 0);
  __ crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2);
  __ beq(CCR0, Lslow_path); // this==null or jvmti_mode!=0

  // Do 2 things in parallel:
  // 1. Load the index out of the first instruction word, which looks like this:
  //    <0x2a><0xb4><index (2 byte, native endianess)>.
  // 2. Load constant pool cache base.
  __ ld(Rconst_method, in_bytes(Method::const_offset()), R19_method);
  __ ld(Rcpool_cache, in_bytes(ConstMethod::constants_offset()), Rconst_method);

  __ lhz(Rcodes, in_bytes(ConstMethod::codes_offset()) + 2, Rconst_method); // Lower half of 32 bit field.
  __ ld(Rcpool_cache, ConstantPool::cache_offset_in_bytes(), Rcpool_cache);

  // Get the const pool entry by means of <index>.
  const int codes_shift = exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord);
  __ slwi(Rscratch, Rcodes, codes_shift); // (codes&0xFFFF)<<codes_shift
  __ add(Rcpool_cache, Rscratch, Rcpool_cache);

  // Check if cpool cache entry is resolved.
  // We are resolved if the indices offset contains the current bytecode.
  ByteSize cp_base_offset = ConstantPoolCache::base_offset();
  // Big Endian:
  __ lbz(Rscratch, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::indices_offset()) + 7 - 2, Rcpool_cache);
  __ cmpwi(CCR0, Rscratch, Bytecodes::_getfield);
  __ bne(CCR0, Lslow_path);
  __ isync(); // Order succeeding loads wrt. load of _indices field from cpool_cache.

  // Finally, start loading the value: Get cp cache entry into regs.
  __ ld(Rflags, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::flags_offset()), Rcpool_cache);
  __ ld(Roffset, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::f2_offset()), Rcpool_cache);

  // Following code is from templateTable::getfield_or_static
  // Load pointer to branch table
  __ load_const_optimized(Rbtable, (address)branch_table, Rscratch);

  // Get volatile flag
  __ rldicl(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // extract volatile bit
  // note: sync is needed before volatile load on PPC64

  // Check field type
  __ rldicl(Rflags, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);

#ifdef ASSERT
  Label LFlagInvalid;
  __ cmpldi(CCR0, Rflags, number_of_states);
  __ bge(CCR0, LFlagInvalid);

  __ ld(R9_ARG7, 0, R1_SP);
  __ ld(R10_ARG8, 0, R21_sender_SP);
  __ cmpd(CCR0, R9_ARG7, R10_ARG8);
  __ asm_assert_eq("backlink", 0x543);
#endif // ASSERT
  __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.

  // Load from branch table and dispatch (volatile case: one instruction ahead)
  __ sldi(Rflags, Rflags, LogBytesPerWord);
  __ cmpwi(CCR6, Rscratch, 1); // volatile?
  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
    __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0
  }
  __ ldx(Rbtable, Rbtable, Rflags);

  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
    __ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point
  }
  __ mtctr(Rbtable);
  __ bctr();

#ifdef ASSERT
  __ bind(LFlagInvalid);
  __ stop("got invalid flag", 0x6541);

  bool all_uninitialized = true,
       all_initialized   = true;
  for (int i = 0; i<number_of_states; ++i) {
    all_uninitialized = all_uninitialized && (branch_table[i] == NULL);
    all_initialized   = all_initialized   && (branch_table[i] != NULL);
  }
  assert(all_uninitialized != all_initialized, "consistency"); // either or

  __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
  if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point
  if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point
  if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point
  __ stop("unexpected type", 0x6551);
#endif

  if (branch_table[itos] == 0) { // generate only once
    __ align(32, 28, 28); // align load
    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
    branch_table[itos] = __ pc(); // non-volatile_entry point
    __ lwax(R3_RET, Rclass_or_obj, Roffset);
    __ beq(CCR6, Lacquire);
    __ blr();
  }

  if (branch_table[ltos] == 0) { // generate only once
    __ align(32, 28, 28); // align load
    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
    branch_table[ltos] = __ pc(); // non-volatile_entry point
    __ ldx(R3_RET, Rclass_or_obj, Roffset);
    __ beq(CCR6, Lacquire);
    __ blr();
  }

  if (branch_table[btos] == 0) { // generate only once
    __ align(32, 28, 28); // align load
    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
    branch_table[btos] = __ pc(); // non-volatile_entry point
    __ lbzx(R3_RET, Rclass_or_obj, Roffset);
    __ extsb(R3_RET, R3_RET);
    __ beq(CCR6, Lacquire);
    __ blr();
  }

  if (branch_table[ctos] == 0) { // generate only once
    __ align(32, 28, 28); // align load
    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
    branch_table[ctos] = __ pc(); // non-volatile_entry point
    __ lhzx(R3_RET, Rclass_or_obj, Roffset);
    __ beq(CCR6, Lacquire);
    __ blr();
  }

  if (branch_table[stos] == 0) { // generate only once
    __ align(32, 28, 28); // align load
    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
    branch_table[stos] = __ pc(); // non-volatile_entry point
    __ lhax(R3_RET, Rclass_or_obj, Roffset);
    __ beq(CCR6, Lacquire);
    __ blr();
  }

  if (branch_table[atos] == 0) { // generate only once
    __ align(32, 28, 28); // align load
    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
    branch_table[atos] = __ pc(); // non-volatile_entry point
    __ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj);
    __ verify_oop(R3_RET);
    //__ dcbt(R3_RET); // prefetch
    __ beq(CCR6, Lacquire);
    __ blr();
  }

  __ align(32, 12);
  __ bind(Lacquire);
  __ twi_0(R3_RET);
  __ isync(); // acquire
  __ blr();

#ifdef ASSERT
  for (int i = 0; i<number_of_states; ++i) {
    assert(branch_table[i], "accessor_entry initialization");
    //tty->print_cr("accessor_entry: branch_table[%d] = 0x%llx (opcode 0x%llx)", i, branch_table[i], *((unsigned int*)branch_table[i]));
  }
#endif

  __ bind(Lslow_path);
  __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), Rscratch);
  __ flush();

  return entry;
}
Exemplo n.º 14
0
/* execute instructions on this CPU until icount expires */
static CPU_EXECUTE( m6809 )	/* NS 970908 */
{
	m68_state_t *m68_state = get_safe_token(device);

    m68_state->icount = cycles - m68_state->extra_cycles;
	m68_state->extra_cycles = 0;

	check_irq_lines(m68_state);

	if (m68_state->int_state & (M6809_CWAI | M6809_SYNC))
	{
		debugger_instruction_hook(device, PCD);
		m68_state->icount = 0;
	}
	else
	{
		do
		{
			pPPC = pPC;

			debugger_instruction_hook(device, PCD);

			m68_state->ireg = ROP(PCD);
			PC++;
#if BIG_SWITCH
            switch( m68_state->ireg )
			{
			case 0x00: neg_di(m68_state);    break;
			case 0x01: neg_di(m68_state);    break;	/* undocumented */
			case 0x02: IIError(m68_state);   break;
			case 0x03: com_di(m68_state);    break;
			case 0x04: lsr_di(m68_state);    break;
			case 0x05: IIError(m68_state);   break;
			case 0x06: ror_di(m68_state);    break;
			case 0x07: asr_di(m68_state);    break;
			case 0x08: asl_di(m68_state);    break;
			case 0x09: rol_di(m68_state);    break;
			case 0x0a: dec_di(m68_state);    break;
			case 0x0b: IIError(m68_state);   break;
			case 0x0c: inc_di(m68_state);    break;
			case 0x0d: tst_di(m68_state);    break;
			case 0x0e: jmp_di(m68_state);    break;
			case 0x0f: clr_di(m68_state);    break;
			case 0x10: pref10(m68_state);					 break;
			case 0x11: pref11(m68_state);					 break;
			case 0x12: nop(m68_state);	    break;
			case 0x13: sync(m68_state);	    break;
			case 0x14: IIError(m68_state);   break;
			case 0x15: IIError(m68_state);   break;
			case 0x16: lbra(m68_state);	    break;
			case 0x17: lbsr(m68_state);	    break;
			case 0x18: IIError(m68_state);   break;
			case 0x19: daa(m68_state);	    break;
			case 0x1a: orcc(m68_state);	    break;
			case 0x1b: IIError(m68_state);   break;
			case 0x1c: andcc(m68_state);     break;
			case 0x1d: sex(m68_state);	    break;
			case 0x1e: exg(m68_state);	    break;
			case 0x1f: tfr(m68_state);	    break;
			case 0x20: bra(m68_state);	    break;
			case 0x21: brn(m68_state);	    break;
			case 0x22: bhi(m68_state);	    break;
			case 0x23: bls(m68_state);	    break;
			case 0x24: bcc(m68_state);	    break;
			case 0x25: bcs(m68_state);	    break;
			case 0x26: bne(m68_state);	    break;
			case 0x27: beq(m68_state);	    break;
			case 0x28: bvc(m68_state);	    break;
			case 0x29: bvs(m68_state);	    break;
			case 0x2a: bpl(m68_state);	    break;
			case 0x2b: bmi(m68_state);	    break;
			case 0x2c: bge(m68_state);	    break;
			case 0x2d: blt(m68_state);	    break;
			case 0x2e: bgt(m68_state);	    break;
			case 0x2f: ble(m68_state);	    break;
			case 0x30: leax(m68_state);	    break;
			case 0x31: leay(m68_state);	    break;
			case 0x32: leas(m68_state);	    break;
			case 0x33: leau(m68_state);	    break;
			case 0x34: pshs(m68_state);	    break;
			case 0x35: puls(m68_state);	    break;
			case 0x36: pshu(m68_state);	    break;
			case 0x37: pulu(m68_state);	    break;
			case 0x38: IIError(m68_state);   break;
			case 0x39: rts(m68_state);	    break;
			case 0x3a: abx(m68_state);	    break;
			case 0x3b: rti(m68_state);	    break;
			case 0x3c: cwai(m68_state);	    break;
			case 0x3d: mul(m68_state);	    break;
			case 0x3e: IIError(m68_state);   break;
			case 0x3f: swi(m68_state);	    break;
			case 0x40: nega(m68_state);	    break;
			case 0x41: IIError(m68_state);   break;
			case 0x42: IIError(m68_state);   break;
			case 0x43: coma(m68_state);	    break;
			case 0x44: lsra(m68_state);	    break;
			case 0x45: IIError(m68_state);   break;
			case 0x46: rora(m68_state);	    break;
			case 0x47: asra(m68_state);	    break;
			case 0x48: asla(m68_state);	    break;
			case 0x49: rola(m68_state);	    break;
			case 0x4a: deca(m68_state);	    break;
			case 0x4b: IIError(m68_state);   break;
			case 0x4c: inca(m68_state);	    break;
			case 0x4d: tsta(m68_state);	    break;
			case 0x4e: IIError(m68_state);   break;
			case 0x4f: clra(m68_state);	    break;
			case 0x50: negb(m68_state);	    break;
			case 0x51: IIError(m68_state);   break;
			case 0x52: IIError(m68_state);   break;
			case 0x53: comb(m68_state);	    break;
			case 0x54: lsrb(m68_state);	    break;
			case 0x55: IIError(m68_state);   break;
			case 0x56: rorb(m68_state);	    break;
			case 0x57: asrb(m68_state);	    break;
			case 0x58: aslb(m68_state);	    break;
			case 0x59: rolb(m68_state);	    break;
			case 0x5a: decb(m68_state);	    break;
			case 0x5b: IIError(m68_state);   break;
			case 0x5c: incb(m68_state);	    break;
			case 0x5d: tstb(m68_state);	    break;
			case 0x5e: IIError(m68_state);   break;
			case 0x5f: clrb(m68_state);	    break;
			case 0x60: neg_ix(m68_state);    break;
			case 0x61: IIError(m68_state);   break;
			case 0x62: IIError(m68_state);   break;
			case 0x63: com_ix(m68_state);    break;
			case 0x64: lsr_ix(m68_state);    break;
			case 0x65: IIError(m68_state);   break;
			case 0x66: ror_ix(m68_state);    break;
			case 0x67: asr_ix(m68_state);    break;
			case 0x68: asl_ix(m68_state);    break;
			case 0x69: rol_ix(m68_state);    break;
			case 0x6a: dec_ix(m68_state);    break;
			case 0x6b: IIError(m68_state);   break;
			case 0x6c: inc_ix(m68_state);    break;
			case 0x6d: tst_ix(m68_state);    break;
			case 0x6e: jmp_ix(m68_state);    break;
			case 0x6f: clr_ix(m68_state);    break;
			case 0x70: neg_ex(m68_state);    break;
			case 0x71: IIError(m68_state);   break;
			case 0x72: IIError(m68_state);   break;
			case 0x73: com_ex(m68_state);    break;
			case 0x74: lsr_ex(m68_state);    break;
			case 0x75: IIError(m68_state);   break;
			case 0x76: ror_ex(m68_state);    break;
			case 0x77: asr_ex(m68_state);    break;
			case 0x78: asl_ex(m68_state);    break;
			case 0x79: rol_ex(m68_state);    break;
			case 0x7a: dec_ex(m68_state);    break;
			case 0x7b: IIError(m68_state);   break;
			case 0x7c: inc_ex(m68_state);    break;
			case 0x7d: tst_ex(m68_state);    break;
			case 0x7e: jmp_ex(m68_state);    break;
			case 0x7f: clr_ex(m68_state);    break;
			case 0x80: suba_im(m68_state);   break;
			case 0x81: cmpa_im(m68_state);   break;
			case 0x82: sbca_im(m68_state);   break;
			case 0x83: subd_im(m68_state);   break;
			case 0x84: anda_im(m68_state);   break;
			case 0x85: bita_im(m68_state);   break;
			case 0x86: lda_im(m68_state);    break;
			case 0x87: sta_im(m68_state);    break;
			case 0x88: eora_im(m68_state);   break;
			case 0x89: adca_im(m68_state);   break;
			case 0x8a: ora_im(m68_state);    break;
			case 0x8b: adda_im(m68_state);   break;
			case 0x8c: cmpx_im(m68_state);   break;
			case 0x8d: bsr(m68_state);	    break;
			case 0x8e: ldx_im(m68_state);    break;
			case 0x8f: stx_im(m68_state);    break;
			case 0x90: suba_di(m68_state);   break;
			case 0x91: cmpa_di(m68_state);   break;
			case 0x92: sbca_di(m68_state);   break;
			case 0x93: subd_di(m68_state);   break;
			case 0x94: anda_di(m68_state);   break;
			case 0x95: bita_di(m68_state);   break;
			case 0x96: lda_di(m68_state);    break;
			case 0x97: sta_di(m68_state);    break;
			case 0x98: eora_di(m68_state);   break;
			case 0x99: adca_di(m68_state);   break;
			case 0x9a: ora_di(m68_state);    break;
			case 0x9b: adda_di(m68_state);   break;
			case 0x9c: cmpx_di(m68_state);   break;
			case 0x9d: jsr_di(m68_state);    break;
			case 0x9e: ldx_di(m68_state);    break;
			case 0x9f: stx_di(m68_state);    break;
			case 0xa0: suba_ix(m68_state);   break;
			case 0xa1: cmpa_ix(m68_state);   break;
			case 0xa2: sbca_ix(m68_state);   break;
			case 0xa3: subd_ix(m68_state);   break;
			case 0xa4: anda_ix(m68_state);   break;
			case 0xa5: bita_ix(m68_state);   break;
			case 0xa6: lda_ix(m68_state);    break;
			case 0xa7: sta_ix(m68_state);    break;
			case 0xa8: eora_ix(m68_state);   break;
			case 0xa9: adca_ix(m68_state);   break;
			case 0xaa: ora_ix(m68_state);    break;
			case 0xab: adda_ix(m68_state);   break;
			case 0xac: cmpx_ix(m68_state);   break;
			case 0xad: jsr_ix(m68_state);    break;
			case 0xae: ldx_ix(m68_state);    break;
			case 0xaf: stx_ix(m68_state);    break;
			case 0xb0: suba_ex(m68_state);   break;
			case 0xb1: cmpa_ex(m68_state);   break;
			case 0xb2: sbca_ex(m68_state);   break;
			case 0xb3: subd_ex(m68_state);   break;
			case 0xb4: anda_ex(m68_state);   break;
			case 0xb5: bita_ex(m68_state);   break;
			case 0xb6: lda_ex(m68_state);    break;
			case 0xb7: sta_ex(m68_state);    break;
			case 0xb8: eora_ex(m68_state);   break;
			case 0xb9: adca_ex(m68_state);   break;
			case 0xba: ora_ex(m68_state);    break;
			case 0xbb: adda_ex(m68_state);   break;
			case 0xbc: cmpx_ex(m68_state);   break;
			case 0xbd: jsr_ex(m68_state);    break;
			case 0xbe: ldx_ex(m68_state);    break;
			case 0xbf: stx_ex(m68_state);    break;
			case 0xc0: subb_im(m68_state);   break;
			case 0xc1: cmpb_im(m68_state);   break;
			case 0xc2: sbcb_im(m68_state);   break;
			case 0xc3: addd_im(m68_state);   break;
			case 0xc4: andb_im(m68_state);   break;
			case 0xc5: bitb_im(m68_state);   break;
			case 0xc6: ldb_im(m68_state);    break;
			case 0xc7: stb_im(m68_state);    break;
			case 0xc8: eorb_im(m68_state);   break;
			case 0xc9: adcb_im(m68_state);   break;
			case 0xca: orb_im(m68_state);    break;
			case 0xcb: addb_im(m68_state);   break;
			case 0xcc: ldd_im(m68_state);    break;
			case 0xcd: std_im(m68_state);    break;
			case 0xce: ldu_im(m68_state);    break;
			case 0xcf: stu_im(m68_state);    break;
			case 0xd0: subb_di(m68_state);   break;
			case 0xd1: cmpb_di(m68_state);   break;
			case 0xd2: sbcb_di(m68_state);   break;
			case 0xd3: addd_di(m68_state);   break;
			case 0xd4: andb_di(m68_state);   break;
			case 0xd5: bitb_di(m68_state);   break;
			case 0xd6: ldb_di(m68_state);    break;
			case 0xd7: stb_di(m68_state);    break;
			case 0xd8: eorb_di(m68_state);   break;
			case 0xd9: adcb_di(m68_state);   break;
			case 0xda: orb_di(m68_state);    break;
			case 0xdb: addb_di(m68_state);   break;
			case 0xdc: ldd_di(m68_state);    break;
			case 0xdd: std_di(m68_state);    break;
			case 0xde: ldu_di(m68_state);    break;
			case 0xdf: stu_di(m68_state);    break;
			case 0xe0: subb_ix(m68_state);   break;
			case 0xe1: cmpb_ix(m68_state);   break;
			case 0xe2: sbcb_ix(m68_state);   break;
			case 0xe3: addd_ix(m68_state);   break;
			case 0xe4: andb_ix(m68_state);   break;
			case 0xe5: bitb_ix(m68_state);   break;
			case 0xe6: ldb_ix(m68_state);    break;
			case 0xe7: stb_ix(m68_state);    break;
			case 0xe8: eorb_ix(m68_state);   break;
			case 0xe9: adcb_ix(m68_state);   break;
			case 0xea: orb_ix(m68_state);    break;
			case 0xeb: addb_ix(m68_state);   break;
			case 0xec: ldd_ix(m68_state);    break;
			case 0xed: std_ix(m68_state);    break;
			case 0xee: ldu_ix(m68_state);    break;
			case 0xef: stu_ix(m68_state);    break;
			case 0xf0: subb_ex(m68_state);   break;
			case 0xf1: cmpb_ex(m68_state);   break;
			case 0xf2: sbcb_ex(m68_state);   break;
			case 0xf3: addd_ex(m68_state);   break;
			case 0xf4: andb_ex(m68_state);   break;
			case 0xf5: bitb_ex(m68_state);   break;
			case 0xf6: ldb_ex(m68_state);    break;
			case 0xf7: stb_ex(m68_state);    break;
			case 0xf8: eorb_ex(m68_state);   break;
			case 0xf9: adcb_ex(m68_state);   break;
			case 0xfa: orb_ex(m68_state);    break;
			case 0xfb: addb_ex(m68_state);   break;
			case 0xfc: ldd_ex(m68_state);    break;
			case 0xfd: std_ex(m68_state);    break;
			case 0xfe: ldu_ex(m68_state);    break;
			case 0xff: stu_ex(m68_state);    break;
			}
#else
            		(*m6809_main[m68_state->ireg])(m68_state);
#endif    /* BIG_SWITCH */
        		m68_state->icount -= cycles1[m68_state->ireg];

		} while( m68_state->icount > 0 );

        m68_state->icount -= m68_state->extra_cycles;
		m68_state->extra_cycles = 0;
    }

    return cycles - m68_state->icount;   /* NS 970908 */
}
Exemplo n.º 15
0
void instruction_decode(int index){
    if(test==1) printf("enter ID, with index=%d\n",index);

    if(index==0 || index==34){ //NOP or HALT
        return;
    }

    /**stall detect**/
    if(index>=1&&index<=9){
        if(DM_dest_reg==RS || DM_dest_reg==RT){
            if(dest_reg!=RS && dest_reg!=RT){
                stall=1;
            }
        }
    }
    else if(index>=10&&index<=12){
        if(DM_dest_reg==RT){
            if(dest_reg!=RT){
                stall=1;
            }
        }
    }
    else if(index==13){
        if(dest_reg==RS){
            stall=1;
        }
    }
    else if(index>=16&&index<=22 || index>=27&&index<=30){
        if(DM_dest_reg==RS){
            if(dest_reg!=RS){
                stall=1;
            }
        }
    }
    else if(index>=23&&index<=25){
        if(DM_dest_reg==RS || DM_dest_reg==RT){
            if(dest_reg!=RS && dest_reg!=RT){
                stall=1;
            }
        }
    }
    else if(index>=31&&index<=33){
        if(dest_reg==RS || dest_reg==RT){
            stall=1;
        }
        if(DM_dest_reg==RS || DM_dest_reg==RT){
            if(EX_index>=18&&EX_index<=22){
                stall=1;
            }
        }
    }

    /**flush detect**/
    if(index==13){
        jr(RS);
        flush=1;
    }
    else if(index==14){
        jj(C);
        flush=1;
    }
    else if(index==15){
        jal(C);
        flush=1;
    }
    else if(index==31){
        beq(RS,RT,signedC);
        flush=1;
    }
    else if(index==32){
        bne(RS,RT,signedC);
        flush=1;
    }
    else if(index==33){
        bgtz(RS,signedC);
        flush=1;
    }
    ID_prev=index;
    EX_index=index;

}
Exemplo n.º 16
0
address InterpreterGenerator::generate_accessor_entry()
{
  if (!UseFastAccessorMethods)
    return NULL;

  Label& slow_path = fast_accessor_slow_entry_path;
  
  address start = __ pc();

  // Drop into the slow path if we need a safepoint check.
  __ load (r3, (intptr_t) SafepointSynchronize::address_of_state());
  __ load (r0, Address(r3, 0));
  __ compare (r0, SafepointSynchronize::_not_synchronized);
  __ bne (slow_path);
  
  // Load the object pointer and drop into the slow path
  // if we have a NullPointerException.
  const Register object = r4;

  __ load (object, Address(Rlocals, 0));
  __ compare (object, 0);
  __ beq (slow_path);

  // Read the field index from the bytecode, which looks like this:
  //  0:  0x2a:    aload_0
  //  1:  0xb4:    getfield
  //  2:             index (high byte)
  //  3:             index (low byte)
  //  4:  0xac/b0: ireturn/areturn
  const Register index = r5;
  
  __ load (index, Address(Rmethod, methodOopDesc::const_offset()));
  __ lwz (index, Address(index, constMethodOopDesc::codes_offset()));
#ifdef ASSERT
  {
    Label ok;
    __ shift_right (r0, index, 16);
    __ compare (r0, (Bytecodes::_aload_0 << 8) | Bytecodes::_getfield);
    __ beq (ok);
    __ should_not_reach_here (__FILE__, __LINE__);
    __ bind (ok);
  }
#endif
  __ andi_ (index, index, 0xffff);

  // Locate the entry in the constant pool cache
  const Register entry = r6;
  
  __ load (entry, Address(Rmethod, methodOopDesc::constants_offset()));
  __ load (entry, Address(entry,constantPoolOopDesc::cache_offset_in_bytes()));
  __ la (entry, Address(entry, constantPoolCacheOopDesc::base_offset()));
  __ shift_left(r0, index,
       exact_log2(in_words(ConstantPoolCacheEntry::size())) + LogBytesPerWord);
  __ add (entry, entry, r0);

  // Check the validity of the cache entry by testing whether the
  // _indices field contains Bytecode::_getfield in b1 byte.
  __ load (r0, Address(entry, ConstantPoolCacheEntry::indices_offset()));
  __ shift_right (r0, r0, 16);
  __ andi_ (r0, r0, 0xff);
  __ compare (r0, Bytecodes::_getfield);
  __ bne (slow_path);

  // Calculate the type and offset of the field
  const Register offset = r7;
  const Register type   = r8;

  __ load (offset, Address(entry, ConstantPoolCacheEntry::f2_offset()));
  __ load (type, Address(entry, ConstantPoolCacheEntry::flags_offset()));
  ConstantPoolCacheEntry::verify_tosBits();
  __ shift_right (type, type, ConstantPoolCacheEntry::tosBits);

  // Load the value
  Label is_object, is_int, is_byte, is_short, is_char;

  __ compare (type, atos);
  __ beq (is_object);
  __ compare (type, itos);
  __ beq (is_int);
  __ compare (type, btos);
  __ beq (is_byte);
  __ compare (type, stos);
  __ beq (is_short);
  __ compare (type, ctos);
  __ beq (is_char);

  __ load (r3, (intptr_t) "error: unknown type: %d\n");
  __ mr (r4, type);
  __ call (CAST_FROM_FN_PTR(address, printf));
  __ should_not_reach_here (__FILE__, __LINE__);

  __ bind (is_object);
  __ load_indexed (r3, object, offset);
  __ blr ();

  __ bind (is_int);
  __ lwax (r3, object, offset);
  __ blr ();

  __ bind (is_byte);
  __ lbax (r3, object, offset);
  __ blr ();

  __ bind (is_short);
  __ lhax (r3, object, offset);
  __ blr ();

  __ bind (is_char);
  __ lhzx (r3, object, offset);
  __ blr ();

  return start;  
}
Exemplo n.º 17
0
/* Generate interrupts */
static void Interrupt(void)
{
	/* the 6805 latches interrupt requests internally, so we don't clear */
	/* pending_interrupts until the interrupt is taken, no matter what the */
	/* external IRQ pin does. */

#if (1) //HAS_HD63705)
	if( (m6805.pending_interrupts & (1<<HD63705_INT_NMI)) != 0)
	{
		PUSHWORD(m6805.pc);
		PUSHBYTE(m6805.x);
		PUSHBYTE(m6805.a);
		PUSHBYTE(m6805.cc);
        SEI;
		/* no vectors supported, just do the callback to clear irq_state if needed */
		if (m6805.irq_callback)
			(*m6805.irq_callback)(0);

		RM16( 0x1ffc, &pPC);
		change_pc(PC);
		m6805.pending_interrupts &= ~(1<<HD63705_INT_NMI);

		m6805_ICount -= 11;

	}
	else if( (m6805.pending_interrupts & ((1<<M6805_IRQ_LINE)|HD63705_INT_MASK)) != 0 ) {
		if ( (CC & IFLAG) == 0 ) {
#else
	if( (m6805.pending_interrupts & (1<<M6805_IRQ_LINE)) != 0 ) {
		if ( (CC & IFLAG) == 0 ) {
#endif
	{
        /* standard IRQ */
//#if (HAS_HD63705)
//      if(SUBTYPE!=SUBTYPE_HD63705)
//#endif
//          PC |= ~AMASK;
		PUSHWORD(m6805.pc);
		PUSHBYTE(m6805.x);
		PUSHBYTE(m6805.a);
		PUSHBYTE(m6805.cc);
        SEI;
		/* no vectors supported, just do the callback to clear irq_state if needed */
		if (m6805.irq_callback)
			(*m6805.irq_callback)(0);


//#if (HAS_HD63705)
		if(SUBTYPE==SUBTYPE_HD63705)
		{
			/* Need to add emulation of other interrupt sources here KW-2/4/99 */
			/* This is just a quick patch for Namco System 2 operation         */

			if((m6805.pending_interrupts&(1<<HD63705_INT_IRQ1))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_IRQ1);
				RM16( 0x1ff8, &pPC);
				change_pc(PC);
			}
			else if((m6805.pending_interrupts&(1<<HD63705_INT_IRQ2))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_IRQ2);
				RM16( 0x1fec, &pPC);
				change_pc(PC);
			}
			else if((m6805.pending_interrupts&(1<<HD63705_INT_ADCONV))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_ADCONV);
				RM16( 0x1fea, &pPC);
				change_pc(PC);
			}
			else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER1))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER1);
				RM16( 0x1ff6, &pPC);
				change_pc(PC);
			}
			else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER2))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER2);
				RM16( 0x1ff4, &pPC);
				change_pc(PC);
			}
			else if((m6805.pending_interrupts&(1<<HD63705_INT_TIMER3))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_TIMER3);
				RM16( 0x1ff2, &pPC);
				change_pc(PC);
			}
			else if((m6805.pending_interrupts&(1<<HD63705_INT_PCI))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_PCI);
				RM16( 0x1ff0, &pPC);
				change_pc(PC);
			}
			else if((m6805.pending_interrupts&(1<<HD63705_INT_SCI))!=0)
			{
				m6805.pending_interrupts &= ~(1<<HD63705_INT_SCI);
				RM16( 0x1fee, &pPC);
				change_pc(PC);
			}
		}
		else
//#endif
		{
			RM16( 0xffff - 5, &pPC );
			change_pc(PC);
		}

		}	// CC & IFLAG
			m6805.pending_interrupts &= ~(1<<M6805_IRQ_LINE);
		}
		m6805_ICount -= 11;
	}
}

static void m6805_reset()
{
	int (*save_irqcallback)(int) = m6805.irq_callback;
	memset(&m6805, 0, sizeof(m6805));
	m6805.irq_callback = save_irqcallback;
	/* Force CPU sub-type and relevant masks */
	m6805.subtype	= SUBTYPE_M6805;
	SP_MASK = 0x07f;
	SP_LOW	= 0x060;
	/* Initial stack pointer */
	S = SP_MASK;
	/* IRQ disabled */
    SEI;
	RM16( 0xfffe , &pPC );
	change_pc(PC);
}

void m6805Reset() {
	m6805_reset();
}

//static void m6805_init(int ) //int (*irqcallback)(int))
//{
//	m6805.irq_callback = irqcallback;
//}

//static void m6805_exit(void)
//{
//	/* nothing to do */
//}


void m6805SetIrqLine(int , int state)
{
	/* Basic 6805 only has one IRQ line */
	/* See HD63705 specific version     */
	if (m6805.irq_state[0] == state) return;

	m6805.irq_state[0] = state;
	if (state != CLEAR_LINE)
		m6805.pending_interrupts |= 1<<M6805_IRQ_LINE;
}


#include "6805ops.c"


/* execute instructions on this CPU until icount expires */
int m6805Run(int cycles)
{
	UINT8 ireg;
	m6805_ICount = cycles;

	do
	{
		if (m6805.pending_interrupts != 0)
		{
			if (SUBTYPE==SUBTYPE_M68705)
			{
				m68705_Interrupt();
			}
			else
			{
				Interrupt();
			}
		}

		ireg=M_RDOP(PC++);

		switch( ireg )
		{
			case 0x00: brset(0x01); break;
			case 0x01: brclr(0x01); break;
			case 0x02: brset(0x02); break;
			case 0x03: brclr(0x02); break;
			case 0x04: brset(0x04); break;
			case 0x05: brclr(0x04); break;
			case 0x06: brset(0x08); break;
			case 0x07: brclr(0x08); break;
			case 0x08: brset(0x10); break;
			case 0x09: brclr(0x10); break;
			case 0x0A: brset(0x20); break;
			case 0x0B: brclr(0x20); break;
			case 0x0C: brset(0x40); break;
			case 0x0D: brclr(0x40); break;
			case 0x0E: brset(0x80); break;
			case 0x0F: brclr(0x80); break;
			case 0x10: bset(0x01); break;
			case 0x11: bclr(0x01); break;
			case 0x12: bset(0x02); break;
			case 0x13: bclr(0x02); break;
			case 0x14: bset(0x04); break;
			case 0x15: bclr(0x04); break;
			case 0x16: bset(0x08); break;
			case 0x17: bclr(0x08); break;
			case 0x18: bset(0x10); break;
			case 0x19: bclr(0x10); break;
			case 0x1a: bset(0x20); break;
			case 0x1b: bclr(0x20); break;
			case 0x1c: bset(0x40); break;
			case 0x1d: bclr(0x40); break;
			case 0x1e: bset(0x80); break;
			case 0x1f: bclr(0x80); break;
			case 0x20: bra(); break;
			case 0x21: brn(); break;
			case 0x22: bhi(); break;
			case 0x23: bls(); break;
			case 0x24: bcc(); break;
			case 0x25: bcs(); break;
			case 0x26: bne(); break;
			case 0x27: beq(); break;
			case 0x28: bhcc(); break;
			case 0x29: bhcs(); break;
			case 0x2a: bpl(); break;
			case 0x2b: bmi(); break;
			case 0x2c: bmc(); break;
			case 0x2d: bms(); break;
			case 0x2e: bil(); break;
			case 0x2f: bih(); break;
			case 0x30: neg_di(); break;
			case 0x31: illegal(); break;
			case 0x32: illegal(); break;
			case 0x33: com_di(); break;
			case 0x34: lsr_di(); break;
			case 0x35: illegal(); break;
			case 0x36: ror_di(); break;
			case 0x37: asr_di(); break;
			case 0x38: lsl_di(); break;
			case 0x39: rol_di(); break;
			case 0x3a: dec_di(); break;
			case 0x3b: illegal(); break;
			case 0x3c: inc_di(); break;
			case 0x3d: tst_di(); break;
			case 0x3e: illegal(); break;
			case 0x3f: clr_di(); break;
			case 0x40: nega(); break;
			case 0x41: illegal(); break;
			case 0x42: illegal(); break;
			case 0x43: coma(); break;
			case 0x44: lsra(); break;
			case 0x45: illegal(); break;
			case 0x46: rora(); break;
			case 0x47: asra(); break;
			case 0x48: lsla(); break;
			case 0x49: rola(); break;
			case 0x4a: deca(); break;
			case 0x4b: illegal(); break;
			case 0x4c: inca(); break;
			case 0x4d: tsta(); break;
			case 0x4e: illegal(); break;
			case 0x4f: clra(); break;
			case 0x50: negx(); break;
			case 0x51: illegal(); break;
			case 0x52: illegal(); break;
			case 0x53: comx(); break;
			case 0x54: lsrx(); break;
			case 0x55: illegal(); break;
			case 0x56: rorx(); break;
			case 0x57: asrx(); break;
			case 0x58: aslx(); break;
			case 0x59: rolx(); break;
			case 0x5a: decx(); break;
			case 0x5b: illegal(); break;
			case 0x5c: incx(); break;
			case 0x5d: tstx(); break;
			case 0x5e: illegal(); break;
			case 0x5f: clrx(); break;
			case 0x60: neg_ix1(); break;
			case 0x61: illegal(); break;
			case 0x62: illegal(); break;
			case 0x63: com_ix1(); break;
			case 0x64: lsr_ix1(); break;
			case 0x65: illegal(); break;
			case 0x66: ror_ix1(); break;
			case 0x67: asr_ix1(); break;
			case 0x68: lsl_ix1(); break;
			case 0x69: rol_ix1(); break;
			case 0x6a: dec_ix1(); break;
			case 0x6b: illegal(); break;
			case 0x6c: inc_ix1(); break;
			case 0x6d: tst_ix1(); break;
			case 0x6e: illegal(); break;
			case 0x6f: clr_ix1(); break;
			case 0x70: neg_ix(); break;
			case 0x71: illegal(); break;
			case 0x72: illegal(); break;
			case 0x73: com_ix(); break;
			case 0x74: lsr_ix(); break;
			case 0x75: illegal(); break;
			case 0x76: ror_ix(); break;
			case 0x77: asr_ix(); break;
			case 0x78: lsl_ix(); break;
			case 0x79: rol_ix(); break;
			case 0x7a: dec_ix(); break;
			case 0x7b: illegal(); break;
			case 0x7c: inc_ix(); break;
			case 0x7d: tst_ix(); break;
			case 0x7e: illegal(); break;
			case 0x7f: clr_ix(); break;
			case 0x80: rti(); break;
			case 0x81: rts(); break;
			case 0x82: illegal(); break;
			case 0x83: swi(); break;
			case 0x84: illegal(); break;
			case 0x85: illegal(); break;
			case 0x86: illegal(); break;
			case 0x87: illegal(); break;
			case 0x88: illegal(); break;
			case 0x89: illegal(); break;
			case 0x8a: illegal(); break;
			case 0x8b: illegal(); break;
			case 0x8c: illegal(); break;
			case 0x8d: illegal(); break;
			case 0x8e: illegal(); break;
			case 0x8f: illegal(); break;
			case 0x90: illegal(); break;
			case 0x91: illegal(); break;
			case 0x92: illegal(); break;
			case 0x93: illegal(); break;
			case 0x94: illegal(); break;
			case 0x95: illegal(); break;
			case 0x96: illegal(); break;
			case 0x97: tax(); break;
			case 0x98: CLC; break;
			case 0x99: SEC; break;
#if IRQ_LEVEL_DETECT
			case 0x9a: CLI; if (m6805.irq_state != CLEAR_LINE) m6805.pending_interrupts |= 1<<M6805_IRQ_LINE; break;
#else
			case 0x9a: CLI; break;
#endif
			case 0x9b: SEI; break;
			case 0x9c: rsp(); break;
			case 0x9d: nop(); break;
			case 0x9e: illegal(); break;
			case 0x9f: txa(); break;
			case 0xa0: suba_im(); break;
			case 0xa1: cmpa_im(); break;
			case 0xa2: sbca_im(); break;
			case 0xa3: cpx_im(); break;
			case 0xa4: anda_im(); break;
			case 0xa5: bita_im(); break;
			case 0xa6: lda_im(); break;
			case 0xa7: illegal(); break;
			case 0xa8: eora_im(); break;
			case 0xa9: adca_im(); break;
			case 0xaa: ora_im(); break;
			case 0xab: adda_im(); break;
			case 0xac: illegal(); break;
			case 0xad: bsr(); break;
			case 0xae: ldx_im(); break;
			case 0xaf: illegal(); break;
			case 0xb0: suba_di(); break;
			case 0xb1: cmpa_di(); break;
			case 0xb2: sbca_di(); break;
			case 0xb3: cpx_di(); break;
			case 0xb4: anda_di(); break;
			case 0xb5: bita_di(); break;
			case 0xb6: lda_di(); break;
			case 0xb7: sta_di(); break;
			case 0xb8: eora_di(); break;
			case 0xb9: adca_di(); break;
			case 0xba: ora_di(); break;
			case 0xbb: adda_di(); break;
			case 0xbc: jmp_di(); break;
			case 0xbd: jsr_di(); break;
			case 0xbe: ldx_di(); break;
			case 0xbf: stx_di(); break;
			case 0xc0: suba_ex(); break;
			case 0xc1: cmpa_ex(); break;
			case 0xc2: sbca_ex(); break;
			case 0xc3: cpx_ex(); break;
			case 0xc4: anda_ex(); break;
			case 0xc5: bita_ex(); break;
			case 0xc6: lda_ex(); break;
			case 0xc7: sta_ex(); break;
			case 0xc8: eora_ex(); break;
			case 0xc9: adca_ex(); break;
			case 0xca: ora_ex(); break;
			case 0xcb: adda_ex(); break;
			case 0xcc: jmp_ex(); break;
			case 0xcd: jsr_ex(); break;
			case 0xce: ldx_ex(); break;
			case 0xcf: stx_ex(); break;
			case 0xd0: suba_ix2(); break;
			case 0xd1: cmpa_ix2(); break;
			case 0xd2: sbca_ix2(); break;
			case 0xd3: cpx_ix2(); break;
			case 0xd4: anda_ix2(); break;
			case 0xd5: bita_ix2(); break;
			case 0xd6: lda_ix2(); break;
			case 0xd7: sta_ix2(); break;
			case 0xd8: eora_ix2(); break;
			case 0xd9: adca_ix2(); break;
			case 0xda: ora_ix2(); break;
			case 0xdb: adda_ix2(); break;
			case 0xdc: jmp_ix2(); break;
			case 0xdd: jsr_ix2(); break;
			case 0xde: ldx_ix2(); break;
			case 0xdf: stx_ix2(); break;
			case 0xe0: suba_ix1(); break;
			case 0xe1: cmpa_ix1(); break;
			case 0xe2: sbca_ix1(); break;
			case 0xe3: cpx_ix1(); break;
			case 0xe4: anda_ix1(); break;
			case 0xe5: bita_ix1(); break;
			case 0xe6: lda_ix1(); break;
			case 0xe7: sta_ix1(); break;
			case 0xe8: eora_ix1(); break;
			case 0xe9: adca_ix1(); break;
			case 0xea: ora_ix1(); break;
			case 0xeb: adda_ix1(); break;
			case 0xec: jmp_ix1(); break;
			case 0xed: jsr_ix1(); break;
			case 0xee: ldx_ix1(); break;
			case 0xef: stx_ix1(); break;
			case 0xf0: suba_ix(); break;
			case 0xf1: cmpa_ix(); break;
			case 0xf2: sbca_ix(); break;
			case 0xf3: cpx_ix(); break;
			case 0xf4: anda_ix(); break;
			case 0xf5: bita_ix(); break;
			case 0xf6: lda_ix(); break;
			case 0xf7: sta_ix(); break;
			case 0xf8: eora_ix(); break;
			case 0xf9: adca_ix(); break;
			case 0xfa: ora_ix(); break;
			case 0xfb: adda_ix(); break;
			case 0xfc: jmp_ix(); break;
			case 0xfd: jsr_ix(); break;
			case 0xfe: ldx_ix(); break;
			case 0xff: stx_ix(); break;
		}
		m6805_ICount -= cycles1[ireg];
		m6805.nTotalCycles += cycles1[ireg];
	} while( m6805_ICount > 0 );

	return cycles - m6805_ICount;
}
Exemplo n.º 18
0
address InterpreterGenerator::generate_normal_entry(bool synchronized)
{
  assert_different_registers(Rmethod, Rlocals, Rthread, Rstate, Rmonitor);
  
  Label re_dispatch;
  Label call_interpreter;
  Label call_method;
  Label call_non_interpreted_method;
  Label return_with_exception;
  Label return_from_method;
  Label resume_interpreter;
  Label return_to_initial_caller;
  Label more_monitors;
  Label throwing_exception;

  // We use the same code for synchronized and not
  if (normal_entry)
    return normal_entry;

  address start = __ pc();

  // There are two ways in which we can arrive at this entry.
  // There is the special case where a normal interpreted method
  // calls another normal interpreted method, and there is the
  // general case of when we enter from somewhere else: from
  // call_stub, from C1 or C2, or from a fast accessor which
  // deferred. In the special case we're already in frame manager
  // code: we arrive at re_dispatch with Rstate containing the
  // previous interpreter state.  In the general case we arrive
  // at start with no previous interpreter state so we set Rstate
  // to NULL to indicate this.
  __ bind (fast_accessor_slow_entry_path);
  __ load (Rstate, 0);
  __ bind (re_dispatch);

  // Adjust the caller's stack frame to accomodate any additional
  // local variables we have contiguously with our parameters.
  generate_adjust_callers_stack();

  // Allocate and initialize our stack frame.
  generate_compute_interpreter_state(false);

  // Call the interpreter ==============================================
  __ bind (call_interpreter);

  // We can setup the frame anchor with everything we want at
  // this point as we are thread_in_Java and no safepoints can
  // occur until we go to vm mode. We do have to clear flags
  // on return from vm but that is it
  __ set_last_Java_frame ();

  // Call interpreter
  address interpreter = JvmtiExport::can_post_interpreter_events() ?
    CAST_FROM_FN_PTR(address, BytecodeInterpreter::runWithChecks) :
    CAST_FROM_FN_PTR(address, BytecodeInterpreter::run);    

  __ mr (r3, Rstate);
  __ call (interpreter);
  __ fixup_after_potential_safepoint ();

  // Clear the frame anchor
  __ reset_last_Java_frame ();

  // Examine the message from the interpreter to decide what to do
  __ lwz (r4, STATE(_msg));
  __ compare (r4, BytecodeInterpreter::call_method);
  __ beq (call_method);
  __ compare (r4, BytecodeInterpreter::return_from_method);
  __ beq (return_from_method);
  __ compare (r4, BytecodeInterpreter::more_monitors);
  __ beq (more_monitors);
  __ compare (r4, BytecodeInterpreter::throwing_exception);
  __ beq (throwing_exception);

  __ load (r3, (intptr_t) "error: bad message from interpreter: %d\n");
  __ call (CAST_FROM_FN_PTR(address, printf));
  __ should_not_reach_here (__FILE__, __LINE__);

  // Handle a call_method message ======================================
  __ bind (call_method);

  __ load (Rmethod, STATE(_result._to_call._callee));
  __ verify_oop(Rmethod);
  __ load (Rlocals, STATE(_stack));
  __ lhz (r0, Address(Rmethod, methodOopDesc::size_of_parameters_offset()));
  __ shift_left (r0, r0, LogBytesPerWord);
  __ add (Rlocals, Rlocals, r0);

  __ load (r0, STATE(_result._to_call._callee_entry_point));
  __ load (r3, (intptr_t) start);
  __ compare (r0, r3);
  __ bne (call_non_interpreted_method);

  // Interpreted methods are intercepted and re-dispatched -----------
  __ load (r0, CAST_FROM_FN_PTR(intptr_t, RecursiveInterpreterActivation));
  __ mtlr (r0);
  __ b (re_dispatch);

  // Non-interpreted methods are dispatched normally -----------------
  __ bind (call_non_interpreted_method);
  __ mtctr (r0);
  __ bctrl ();

  // Restore Rstate
  __ load (Rstate, Address(r1, StackFrame::back_chain_offset * wordSize));
  __ subi (Rstate, Rstate, sizeof(BytecodeInterpreter));

  // Check for pending exceptions
  __ load (r0, Address(Rthread, Thread::pending_exception_offset()));
  __ compare (r0, 0);
  __ bne (return_with_exception);

  // Convert the result and resume
  generate_convert_result(CppInterpreter::_tosca_to_stack);
  __ b (resume_interpreter);

  // Handle a return_from_method message ===============================
  __ bind (return_from_method);

  __ load (r0, STATE(_prev_link));
  __ compare (r0, 0);
  __ beq (return_to_initial_caller);

  // "Return" from a re-dispatch -------------------------------------

  generate_convert_result(CppInterpreter::_stack_to_stack);
  generate_unwind_interpreter_state();

  // Resume the interpreter
  __ bind (resume_interpreter);

  __ store (Rlocals, STATE(_stack));
  __ load (Rlocals, STATE(_locals));
  __ load (Rmethod, STATE(_method));
  __ verify_oop(Rmethod);
  __ load (r0, BytecodeInterpreter::method_resume);
  __ stw (r0, STATE(_msg));
  __ b (call_interpreter);

  // Return to the initial caller (call_stub etc) --------------------
  __ bind (return_to_initial_caller);

  generate_convert_result(CppInterpreter::_stack_to_native_abi);
  generate_unwind_interpreter_state();
  __ blr ();

  // Handle a more_monitors message ====================================
  __ bind (more_monitors);

  generate_more_monitors();

  __ load (r0, BytecodeInterpreter::got_monitors);
  __ stw (r0, STATE(_msg));
  __ b (call_interpreter);

  // Handle a throwing_exception message ===============================
  __ bind (throwing_exception);

  // Check we actually have an exception
#ifdef ASSERT
  {
    Label ok;
    __ load (r0, Address(Rthread, Thread::pending_exception_offset()));
    __ compare (r0, 0);
    __ bne (ok);
    __ should_not_reach_here (__FILE__, __LINE__);
    __ bind (ok);
  }
#endif

  // Return to wherever
  generate_unwind_interpreter_state();
  __ bind (return_with_exception);
  __ compare (Rstate, 0);
  __ bne (resume_interpreter);
  __ blr ();

  normal_entry = start;
  return start;
}
VtableStub* VtableStubs::create_itable_stub(int itable_index) {
  // PPC port: use fixed size.
  const int code_length = VtableStub::pd_code_size_limit(false);
  VtableStub* s = new (code_length) VtableStub(false, itable_index);

  // Can be NULL if there is no free space in the code cache.
  if (s == NULL) {
    return NULL;
  }

  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);
  address start_pc;

#ifndef PRODUCT
  if (CountCompiledCalls) {
    int offs = __ load_const_optimized(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr(), R12_scratch2, true);
    __ lwz(R12_scratch2, offs, R11_scratch1);
    __ addi(R12_scratch2, R12_scratch2, 1);
    __ stw(R12_scratch2, offs, R11_scratch1);
  }
#endif

  assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1");

  // Entry arguments:
  //  R19_method: Interface
  //  R3_ARG1:    Receiver

  Label L_no_such_interface;
  const Register rcvr_klass = R11_scratch1,
                 interface  = R12_scratch2,
                 tmp1       = R21_tmp1,
                 tmp2       = R22_tmp2;

  address npe_addr = __ pc(); // npe = null pointer exception
  __ load_klass_with_trap_null_check(rcvr_klass, R3_ARG1);

  // Receiver subtype check against REFC.
  __ ld(interface, CompiledICHolder::holder_klass_offset(), R19_method);
  __ lookup_interface_method(rcvr_klass, interface, noreg,
                             R0, tmp1, tmp2,
                             L_no_such_interface, /*return_method=*/ false);

  // Get Method* and entrypoint for compiler
  __ ld(interface, CompiledICHolder::holder_metadata_offset(), R19_method);
  __ lookup_interface_method(rcvr_klass, interface, itable_index,
                             R19_method, tmp1, tmp2,
                             L_no_such_interface, /*return_method=*/ true);

#ifndef PRODUCT
  if (DebugVtables) {
    Label ok;
    __ cmpd(CCR0, R19_method, 0);
    __ bne(CCR0, ok);
    __ stop("method is null", 103);
    __ bind(ok);
  }
#endif

  // If the vtable entry is null, the method is abstract.
  address ame_addr = __ pc(); // ame = abstract method error

  // Must do an explicit check if implicit checks are disabled.
  assert(!MacroAssembler::needs_explicit_null_check(in_bytes(Method::from_compiled_offset())), "sanity");
  if (!ImplicitNullChecks || !os::zero_page_read_protected()) {
    if (TrapBasedNullChecks) {
      __ trap_null_check(R19_method);
    } else {
      __ cmpdi(CCR0, R19_method, 0);
      __ beq(CCR0, L_no_such_interface);
    }
  }
  __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method);
  __ mtctr(R12_scratch2);
  __ bctr();

  // Handle IncompatibleClassChangeError in itable stubs.
  // More detailed error message.
  // We force resolving of the call site by jumping to the "handle
  // wrong method" stub, and so let the interpreter runtime do all the
  // dirty work.
  __ bind(L_no_such_interface);
  __ load_const_optimized(R11_scratch1, SharedRuntime::get_handle_wrong_method_stub(), R12_scratch2);
  __ mtctr(R11_scratch1);
  __ bctr();

  masm->flush();

  guarantee(__ pc() <= s->code_end(), "overflowed buffer");

  s->set_exception_points(npe_addr, ame_addr);
  return s;
}
Exemplo n.º 20
0
/* execute instructions on this CPU until icount expires */
static int hd6309_execute(int cycles)	/* NS 970908 */
{
	hd6309_ICount = cycles - hd6309.extra_cycles;
	hd6309.extra_cycles = 0;

	if (hd6309.int_state & (HD6309_CWAI | HD6309_SYNC))
	{
		CALL_MAME_DEBUG;
		hd6309_ICount = 0;
	}
	else
	{
		do
		{
			pPPC = pPC;

			CALL_MAME_DEBUG;

			hd6309.ireg = ROP(PCD);
			PC++;

#ifdef BIG_SWITCH
			switch( hd6309.ireg )
			{
			case 0x00: neg_di();   				break;
			case 0x01: oim_di();   				break;
			case 0x02: aim_di();   				break;
			case 0x03: com_di();   				break;
			case 0x04: lsr_di();   				break;
			case 0x05: eim_di();   				break;
			case 0x06: ror_di();   				break;
			case 0x07: asr_di();   				break;
			case 0x08: asl_di();   				break;
			case 0x09: rol_di();   				break;
			case 0x0a: dec_di();   				break;
			case 0x0b: tim_di();   				break;
			case 0x0c: inc_di();   				break;
			case 0x0d: tst_di();   				break;
			case 0x0e: jmp_di();   				break;
			case 0x0f: clr_di();   				break;
			case 0x10: pref10();				break;
			case 0x11: pref11();				break;
			case 0x12: nop();	   				break;
			case 0x13: sync();	   				break;
			case 0x14: sexw();	   				break;
			case 0x15: IIError();				break;
			case 0x16: lbra();	   				break;
			case 0x17: lbsr();	   				break;
			case 0x18: IIError();				break;
			case 0x19: daa();	   				break;
			case 0x1a: orcc();	   				break;
			case 0x1b: IIError();				break;
			case 0x1c: andcc();    				break;
			case 0x1d: sex();	   				break;
			case 0x1e: exg();	   				break;
			case 0x1f: tfr();	   				break;
			case 0x20: bra();	   				break;
			case 0x21: brn();	   				break;
			case 0x22: bhi();	   				break;
			case 0x23: bls();	   				break;
			case 0x24: bcc();	   				break;
			case 0x25: bcs();	   				break;
			case 0x26: bne();	   				break;
			case 0x27: beq();	   				break;
			case 0x28: bvc();	   				break;
			case 0x29: bvs();	   				break;
			case 0x2a: bpl();	   				break;
			case 0x2b: bmi();	   				break;
			case 0x2c: bge();	   				break;
			case 0x2d: blt();	   				break;
			case 0x2e: bgt();	   				break;
			case 0x2f: ble();	   				break;
			case 0x30: leax();	   				break;
			case 0x31: leay();	   				break;
			case 0x32: leas();	   				break;
			case 0x33: leau();	   				break;
			case 0x34: pshs();	   				break;
			case 0x35: puls();	   				break;
			case 0x36: pshu();	   				break;
			case 0x37: pulu();	   				break;
			case 0x38: IIError();				break;
			case 0x39: rts();	   				break;
			case 0x3a: abx();	   				break;
			case 0x3b: rti();	   				break;
			case 0x3c: cwai();					break;
			case 0x3d: mul();					break;
			case 0x3e: IIError();				break;
			case 0x3f: swi();					break;
			case 0x40: nega();	   				break;
			case 0x41: IIError();				break;
			case 0x42: IIError();				break;
			case 0x43: coma();	   				break;
			case 0x44: lsra();	   				break;
			case 0x45: IIError();				break;
			case 0x46: rora();	   				break;
			case 0x47: asra();	   				break;
			case 0x48: asla();	   				break;
			case 0x49: rola();	   				break;
			case 0x4a: deca();	   				break;
			case 0x4b: IIError();				break;
			case 0x4c: inca();	   				break;
			case 0x4d: tsta();	   				break;
			case 0x4e: IIError();				break;
			case 0x4f: clra();	   				break;
			case 0x50: negb();	   				break;
			case 0x51: IIError();				break;
			case 0x52: IIError();				break;
			case 0x53: comb();	   				break;
			case 0x54: lsrb();	   				break;
			case 0x55: IIError();				break;
			case 0x56: rorb();	   				break;
			case 0x57: asrb();	   				break;
			case 0x58: aslb();	   				break;
			case 0x59: rolb();	   				break;
			case 0x5a: decb();	   				break;
			case 0x5b: IIError();				break;
			case 0x5c: incb();	   				break;
			case 0x5d: tstb();	   				break;
			case 0x5e: IIError();				break;
			case 0x5f: clrb();	   				break;
			case 0x60: neg_ix();   				break;
			case 0x61: oim_ix();   				break;
			case 0x62: aim_ix();   				break;
			case 0x63: com_ix();   				break;
			case 0x64: lsr_ix();   				break;
			case 0x65: eim_ix();   				break;
			case 0x66: ror_ix();   				break;
			case 0x67: asr_ix();   				break;
			case 0x68: asl_ix();   				break;
			case 0x69: rol_ix();   				break;
			case 0x6a: dec_ix();   				break;
			case 0x6b: tim_ix();   				break;
			case 0x6c: inc_ix();   				break;
			case 0x6d: tst_ix();   				break;
			case 0x6e: jmp_ix();   				break;
			case 0x6f: clr_ix();   				break;
			case 0x70: neg_ex();   				break;
			case 0x71: oim_ex();   				break;
			case 0x72: aim_ex();   				break;
			case 0x73: com_ex();   				break;
			case 0x74: lsr_ex();   				break;
			case 0x75: eim_ex();   				break;
			case 0x76: ror_ex();   				break;
			case 0x77: asr_ex();   				break;
			case 0x78: asl_ex();   				break;
			case 0x79: rol_ex();   				break;
			case 0x7a: dec_ex();   				break;
			case 0x7b: tim_ex();   				break;
			case 0x7c: inc_ex();   				break;
			case 0x7d: tst_ex();   				break;
			case 0x7e: jmp_ex();   				break;
			case 0x7f: clr_ex();   				break;
			case 0x80: suba_im();  				break;
			case 0x81: cmpa_im();  				break;
			case 0x82: sbca_im();  				break;
			case 0x83: subd_im();  				break;
			case 0x84: anda_im();  				break;
			case 0x85: bita_im();  				break;
			case 0x86: lda_im();   				break;
			case 0x87: IIError(); 				break;
			case 0x88: eora_im();  				break;
			case 0x89: adca_im();  				break;
			case 0x8a: ora_im();   				break;
			case 0x8b: adda_im();  				break;
			case 0x8c: cmpx_im();  				break;
			case 0x8d: bsr();	   				break;
			case 0x8e: ldx_im();   				break;
			case 0x8f: IIError();  				break;
			case 0x90: suba_di();  				break;
			case 0x91: cmpa_di();  				break;
			case 0x92: sbca_di();  				break;
			case 0x93: subd_di();  				break;
			case 0x94: anda_di();  				break;
			case 0x95: bita_di();  				break;
			case 0x96: lda_di();   				break;
			case 0x97: sta_di();   				break;
			case 0x98: eora_di();  				break;
			case 0x99: adca_di();  				break;
			case 0x9a: ora_di();   				break;
			case 0x9b: adda_di();  				break;
			case 0x9c: cmpx_di();  				break;
			case 0x9d: jsr_di();   				break;
			case 0x9e: ldx_di();   				break;
			case 0x9f: stx_di();   				break;
			case 0xa0: suba_ix();  				break;
			case 0xa1: cmpa_ix();  				break;
			case 0xa2: sbca_ix();  				break;
			case 0xa3: subd_ix();  				break;
			case 0xa4: anda_ix();  				break;
			case 0xa5: bita_ix();  				break;
			case 0xa6: lda_ix();   				break;
			case 0xa7: sta_ix();   				break;
			case 0xa8: eora_ix();  				break;
			case 0xa9: adca_ix();  				break;
			case 0xaa: ora_ix();   				break;
			case 0xab: adda_ix();  				break;
			case 0xac: cmpx_ix();  				break;
			case 0xad: jsr_ix();   				break;
			case 0xae: ldx_ix();   				break;
			case 0xaf: stx_ix();   				break;
			case 0xb0: suba_ex();  				break;
			case 0xb1: cmpa_ex();  				break;
			case 0xb2: sbca_ex();  				break;
			case 0xb3: subd_ex();  				break;
			case 0xb4: anda_ex();  				break;
			case 0xb5: bita_ex();  				break;
			case 0xb6: lda_ex();   				break;
			case 0xb7: sta_ex();   				break;
			case 0xb8: eora_ex();  				break;
			case 0xb9: adca_ex();  				break;
			case 0xba: ora_ex();   				break;
			case 0xbb: adda_ex();  				break;
			case 0xbc: cmpx_ex();  				break;
			case 0xbd: jsr_ex();   				break;
			case 0xbe: ldx_ex();   				break;
			case 0xbf: stx_ex();   				break;
			case 0xc0: subb_im();  				break;
			case 0xc1: cmpb_im();  				break;
			case 0xc2: sbcb_im();  				break;
			case 0xc3: addd_im();  				break;
			case 0xc4: andb_im();  				break;
			case 0xc5: bitb_im();  				break;
			case 0xc6: ldb_im();   				break;
			case 0xc7: IIError(); 				break;
			case 0xc8: eorb_im();  				break;
			case 0xc9: adcb_im();  				break;
			case 0xca: orb_im();   				break;
			case 0xcb: addb_im();  				break;
			case 0xcc: ldd_im();   				break;
			case 0xcd: ldq_im();   				break; /* in m6809 was std_im */
			case 0xce: ldu_im();   				break;
			case 0xcf: IIError();  				break;
			case 0xd0: subb_di();  				break;
			case 0xd1: cmpb_di();  				break;
			case 0xd2: sbcb_di();  				break;
			case 0xd3: addd_di();  				break;
			case 0xd4: andb_di();  				break;
			case 0xd5: bitb_di();  				break;
			case 0xd6: ldb_di();   				break;
			case 0xd7: stb_di();   				break;
			case 0xd8: eorb_di();  				break;
			case 0xd9: adcb_di();  				break;
			case 0xda: orb_di();   				break;
			case 0xdb: addb_di();  				break;
			case 0xdc: ldd_di();   				break;
			case 0xdd: std_di();   				break;
			case 0xde: ldu_di();   				break;
			case 0xdf: stu_di();   				break;
			case 0xe0: subb_ix();  				break;
			case 0xe1: cmpb_ix();  				break;
			case 0xe2: sbcb_ix();  				break;
			case 0xe3: addd_ix();  				break;
			case 0xe4: andb_ix();  				break;
			case 0xe5: bitb_ix();  				break;
			case 0xe6: ldb_ix();   				break;
			case 0xe7: stb_ix();   				break;
			case 0xe8: eorb_ix();  				break;
			case 0xe9: adcb_ix();  				break;
			case 0xea: orb_ix();   				break;
			case 0xeb: addb_ix();  				break;
			case 0xec: ldd_ix();   				break;
			case 0xed: std_ix();   				break;
			case 0xee: ldu_ix();   				break;
			case 0xef: stu_ix();   				break;
			case 0xf0: subb_ex();  				break;
			case 0xf1: cmpb_ex();  				break;
			case 0xf2: sbcb_ex();  				break;
			case 0xf3: addd_ex();  				break;
			case 0xf4: andb_ex();  				break;
			case 0xf5: bitb_ex();  				break;
			case 0xf6: ldb_ex();   				break;
			case 0xf7: stb_ex();   				break;
			case 0xf8: eorb_ex();  				break;
			case 0xf9: adcb_ex();  				break;
			case 0xfa: orb_ex();   				break;
			case 0xfb: addb_ex();  				break;
			case 0xfc: ldd_ex();   				break;
			case 0xfd: std_ex();   				break;
			case 0xfe: ldu_ex();   				break;
			case 0xff: stu_ex();   				break;
			}
#else
			(*hd6309_main[hd6309.ireg])();
#endif    /* BIG_SWITCH */

			hd6309_ICount -= cycle_counts_page0[hd6309.ireg];

		} while( hd6309_ICount > 0 );

		hd6309_ICount -= hd6309.extra_cycles;
		hd6309.extra_cycles = 0;
	}

	return cycles - hd6309_ICount;	 /* NS 970908 */
}
// Used by compiler only; may use only caller saved, non-argument
// registers.
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
  // PPC port: use fixed size.
  const int code_length = VtableStub::pd_code_size_limit(true);
  VtableStub* s = new (code_length) VtableStub(true, vtable_index);

  // Can be NULL if there is no free space in the code cache.
  if (s == NULL) {
    return NULL;
  }

  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);

#ifndef PRODUCT
  if (CountCompiledCalls) {
    int offs = __ load_const_optimized(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr(), R12_scratch2, true);
    __ lwz(R12_scratch2, offs, R11_scratch1);
    __ addi(R12_scratch2, R12_scratch2, 1);
    __ stw(R12_scratch2, offs, R11_scratch1);
  }
#endif

  assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1");

  // Get receiver klass.
  const Register rcvr_klass = R11_scratch1;

  // We might implicit NULL fault here.
  address npe_addr = __ pc(); // npe = null pointer exception
  __ load_klass_with_trap_null_check(rcvr_klass, R3);

 // Set method (in case of interpreted method), and destination address.
  int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();

#ifndef PRODUCT
  if (DebugVtables) {
    Label L;
    // Check offset vs vtable length.
    const Register vtable_len = R12_scratch2;
    __ lwz(vtable_len, InstanceKlass::vtable_length_offset()*wordSize, rcvr_klass);
    __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size());
    __ bge(CCR0, L);
    __ li(R12_scratch2, vtable_index);
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), R3_ARG1, R12_scratch2, false);
    __ bind(L);
  }
#endif

  int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();

  __ ld(R19_method, v_off, rcvr_klass);

#ifndef PRODUCT
  if (DebugVtables) {
    Label L;
    __ cmpdi(CCR0, R19_method, 0);
    __ bne(CCR0, L);
    __ stop("Vtable entry is ZERO", 102);
    __ bind(L);
  }
#endif

  // If the vtable entry is null, the method is abstract.
  address ame_addr = __ pc(); // ame = abstract method error

  __ load_with_trap_null_check(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method);
  __ mtctr(R12_scratch2);
  __ bctr();

  masm->flush();

  guarantee(__ pc() <= s->code_end(), "overflowed buffer");

  s->set_exception_points(npe_addr, ame_addr);

  return s;
}
Exemplo n.º 22
0
int exe(FILE* program)  //program指向存有待执行程序机器码的文件
{

     char* tmp_instru=(char*)malloc(33*sizeof(char)); //读机器码
     programTail=programHead;
     while(fscanf(program,"%s",tmp_instru)!=EOF)
     {
         instru=0;
         int i=0;
         unsigned j=1;
         for(i=31;i>=0;i--)
         {
            if(tmp_instru[i]=='1')
            {
                instru+=j;
                j*=2;
            }
            else
            {
                j*=2;
            }
         }//将机器码转为unsi
         unsigned char* tmp_R=&instru;
         for(i=0;i<4;i++)
         {
             writeMymemory(programTail+i,tmp_R+i);//装载指令
         }
         programTail+=4;//最后一条指令的下一条指令的地址,用来判断程序是否执行完
     }
     pcShort=programHead;
     pc=pcShort;
     while(pcShort!=programTail)
    {
        instru=0;   //指令寄存器清零
    unsigned char* tmp_R=&instru;
    unsigned short addr=addrToMyAddr(pc);
    int i;
    for(i=0;i<4;i++)
    {
        readMymemory(addr+i,tmp_R+i);//取指令
    }
    unsigned tmp=instru>>26;//得到指令op

    //printf("the op is :  %u\n",tmp);

    unsigned numRs=0,numRt=0,numRd=0,numFs=0,numFt=0,numFd=0,tmp_fuc=0;
    switch(tmp)
    {
    case 0x00000023:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=lw(pc);
        break;
    case 0x0000002B:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=sw(pc);
        break;
    case 0x00000008:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=addi(pc);
        break;
    case 0x00000009:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=addiu(pc);
        break;
    case 0x0000000A:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=slti(pc);
        break;
    case 0x0000000B:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=sltiu(pc);
        break;
    case 0x0000000C:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=andi(pc);
        break;
    case 0x0000000D:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=ori(pc);
        break;
    case 0x0000000E:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=xori(pc);
        break;
    case 0x00000024:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=lbu(pc);
        break;
    case 0x00000020:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=lb(pc);
        break;
    case 0x00000028:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=sb(pc);
        break;
    case 0x0000000F:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=lui(pc);
        break;
    case 0x00000004:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=beq(pc);
        break;
    case 0x00000005:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        //printf("%u,%u,%u,%u\n",numRt,numRs,*RS1,*RS2);
        lig=instru<<16>>16;
       // printf("%u\n",lig);
        pc=bne(pc);
        break;
    case 0x00000006:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=blez(pc);
        break;
    case 0x00000007:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=bgtz(pc);
        break;
    case 0x00000001:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        lig=instru<<16>>16;
        pc=bltz(pc);
        break;
    case 0x00000002:
        pc=j(pc);
        break;
    case 0x00000003:
        pc=jal(pc);
        break;
    case 0x00000000:
        numRs=instru<<6>>27;
        numRt=instru<<11>>27;
        numRd=instru<<16>>27;
        RS1=myRegister+numRt;
        RS2=myRegister+numRs;
        RD=myRegister+numRd;
        tmp_fuc=instru%64;
        switch(tmp_fuc)
        {
        case 32:
            pc=add(pc);
            break;
        case 33:
            pc=addu(pc);
            break;
        case 34:
            pc=sub(pc);
            break;
        case 35:
            pc=subu(pc);
            break;
        case 24:
            pc=mul(pc);
            break;
        case 25:
            pc=mulu(pc);
            break;
        case 26:
            pc=myDiv(pc);
            break;
        case 27:
            pc=divu(pc);
            break;
        case 42:
            pc=slt(pc);
            break;
        case 43:
            pc=sltu(pc);
            break;
        case 36:
            pc=myAnd(pc);
            break;
        case 37:
            pc=myOr(pc);
            break;
        case 39:
            pc=nor(pc);
            break;
        case 40:
            pc=myXor(pc);
            break;
        case 8:
            pc=jr(pc);
            break;
        case 9:
            pc=jalr(pc);
            break;
        case 0:
            pc=nop(pc);
            break;
        case 16:
            pc=mfhi(pc);
            break;
        case 18:
            pc=mflo(pc);
            break;
        default:
            break;
        }
        break;
    case 0x00000010:
        numRt=instru<<11>>27;
        numRd=instru<<16>>27;
        RS1=myRegister+numRt;
        if(numRd==14)
        {
            pc=mfepc(pc);
        }
        else if(numRd==13)
        {
            pc=mfco(pc);
        }
        else return -1;
        break;
    case 0x00000031:
        numRs=instru<<6>>27;
        numFt=instru<<11>>27;
        RS2=myRegister+numRs;
        FS1=myFloatReg+numFt;
        lig=instru<<16>>16;
        pc=lwc1(pc);


            //printf("/********\nL.S %u %u\n****************/\n",numFt,numRs);

        break;
    case 0x0000001F:
        numRs=instru<<6>>27;
        numFt=instru<<11>>27;
        RS2=myRegister+numRs;
        FS1=myFloatReg+numFt;
        lig=instru<<16>>16;
        pc=S_D(pc);


            //printf("/********\nL.D %u %u\n****************/\n",numFt,numRs);

        break;
    case 0x0000001E:
        numRs=instru<<6>>27;
        numFt=instru<<11>>27;
        RS2=myRegister+numRs;
        FS1=myFloatReg+numFt;
        lig=instru<<16>>16;
        //printf("/********\nS.D %u %u\n****************/\n",numFt,numRs);
        pc=S_D(pc);
        break;

    case 0x00000039:
        numRs=instru<<6>>27;
        numFt=instru<<11>>27;
        RS2=myRegister+numRs;
        FS1=myFloatReg+numFt;
        lig=instru<<16>>16;
        //printf("/********\nS.S %u %u\n****************/\n",numFt,numRs);
        pc=swc1(pc);
        break;
    case 0x00000011:
        numFt=instru<<11>>27;
        numFs=instru<<16>>27;
        numFd=instru<<21>>27;
        FS1=myFloatReg+numFt;
        FS2=myFloatReg+numFs;
        FD=myFloatReg+numFd;
        numRs=instru<<6>>27;
        tmp_fuc=instru%64;
        //printf("%u %u\n",tmp_fuc,numRs);
        if(numRs==0)
        {
            switch(tmp_fuc)
            {
            case 0:
                pc=add_s(pc);
                break;
            case 1:
                pc=sub_s(pc);
                break;
            case 2:
                pc=mul_s(pc);
            case 3:
                pc=div_s(pc);
            default:
                break;
            }
        }
        else if(numRs==1)
        {
            switch(tmp_fuc)
            {
            case 0:
                pc=add_d(pc);
                //printf("/****************\nADD.D %u %u %u\n*****************/\n",numFd,numFt,numFs);
                break;
            case 1:
                pc=sub_d(pc);
                break;
            case 2:
                pc=mul_d(pc);
            case 3:
                pc=div_d(pc);
            default:
                break;
            }
        }
        default:break;
    }
    pcShort=pc%0x00010000;
    //printf("%u %u\n",pc,pcShort);
    //printf("%u %u\n",pcShort,programTail);
    }
    return 0;
}
Exemplo n.º 23
0
void read_file(char * filename)
{
	fp = fopen(filename, "r");

    char * line = malloc(sizeof(char) * 255);
   	while (fgets(line,255,fp) != NULL) 
  	{

      char * buf[] = {" "," "," "," "};
      char * check = strtok(line, " ");
      int i = 0;
      while (check != NULL)
      {

        if (check != NULL)
        {
          buf[i] = malloc(strlen(check) + 1);
          strcpy(buf[i],check);
        }
        check = strtok(NULL, " ");
        i++;
      } 


  		if(strcmp(buf[0],"addu") == 0)
  		{
  			addu(trim(buf[2], ','),trim(buf[3], ','),trim(buf[1], '\n'));
  		} 
  		else if (strcmp(buf[0],"subu") == 0)
  		{
  			subu(trim(buf[2], ','),trim(buf[3], ','),trim(buf[1], '\n'));
  		}
  		else if(strcmp(buf[0],"slt") ==0)
  		{
  			slt(trim(buf[2], ','),trim(buf[3], ','),trim(buf[1], '\n'));
  		}
  		else if(strcmp(buf[0],"and") == 0)
  		{
  			and(trim(buf[2], ','),trim(buf[3], ','),trim(buf[1], '\n'));
  		}
  		else if(strcmp(buf[0],"or") == 0)
  		{
  			or(trim(buf[2], ','),trim(buf[3], ','),trim(buf[1], '\n'));
  		}
  		else if(strcmp(buf[0],"lw") == 0)
  		{
  			lw(rs_I(buf[2]), trim(buf[1], ','), trim(buf[2], '('));
  		}
  		else if (strcmp(buf[0],"sw") == 0)
  		{
  			sw(rs_I(buf[2]), trim(buf[1], ','), trim(buf[2], '('));
  		}
  		else if(strcmp(buf[0],"bne") == 0)
  		{
  			bne(trim(buf[2], ','),trim(buf[1], ','),trim(buf[3], 'j'));
  		}
  		else if(strcmp(buf[0],"j")== 0)
  		{
  			j(trim(buf[1], 'j'));
  		}

  		
  	}
    fclose(fp);
  	printf("End Scan\n");
}