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); }
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; }
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); }
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(); }
/* 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 ); }
/** * @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; }
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; }
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; }
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; }
// 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; }
/* 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 */ }
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; }
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; }
/* 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; }
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; }
/* 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; }
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; }
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"); }