void CppInterpreterGenerator::generate_more_monitors() { StackFrame frame; const int frame_header_size = frame.unaligned_size() + slop_factor; const int monitor_size = frame::interpreter_frame_monitor_size() * wordSize; const Address stack_words_addr(Rmethod, methodOopDesc::max_stack_offset()); Label loop_start, loop_test; // Extend the frame if necessary const Register required_bytes = r3; const Register available_bytes = r4; __ load (required_bytes, frame_header_size + monitor_size); __ load (available_bytes, STATE(_stack_limit)); __ addi (available_bytes, available_bytes, wordSize); __ sub (available_bytes, available_bytes, r1); __ maybe_extend_frame (required_bytes, available_bytes); // Move the expression stack contents const Register src = r3; const Register end = r4; const Register dst = r5; __ load (src, STATE(_stack)); __ addi (src, src, wordSize); __ load (end, STATE(_stack_base)); __ subi (dst, src, monitor_size); __ b (loop_test); __ bind (loop_start); __ load (r0, Address(src, 0)); __ store (r0, Address(dst, 0)); __ addi (src, src, wordSize); __ addi (dst, dst, wordSize); __ bind (loop_test); __ compare (src, end); __ blt (loop_start); // Move the expression stack pointers const Register tmp = r3; __ load (tmp, STATE(_stack_limit)); __ subi (tmp, tmp, monitor_size); __ store (tmp, STATE(_stack_limit)); __ load (tmp, STATE(_stack)); __ subi (tmp, tmp, monitor_size); __ store (tmp, STATE(_stack)); __ load (tmp, STATE(_stack_base)); __ subi (tmp, tmp, monitor_size); __ store (tmp, STATE(_stack_base)); // Zero the new monitor so the interpreter can find it. // NB tmp at this point contains _stack_base, the address // of the word after the expression stack -- which just // happens to be the address of our new monitor. __ load (r0, 0); __ store (r0, Address(tmp, BasicObjectLock::obj_offset_in_bytes())); }
void addi(int temp,int depth) { int i, j; if (temp > num) { return; } if (temp == num) { if (depth < min) { min = depth; save[depth] = temp; for (i = 0; i <= depth; i++) { minValue[i] = save[i]; } return; } } save[depth] = temp; if (depth >= min) //Å°Æ÷ÀÎÆ® return; for (i = depth; i > -1; i--) { addi(save[depth] + save[i], depth + 1); } }
void alu_unit(int s, int t) { struct ins* i = CPU.pipeline[1]; int opc = i->opcode; short c = i->c; if(opc) { if(opc == _addi) addi(s, c); else if(opc == _halt) printf("encounter halt\n"); else if(is_load(opc) || is_store(opc)) load_store(s, c); else if(opc == _lui) lui(c); else if(opc == _andi) andi(s, c); else if(opc == _ori) ori(s, c); else if(opc == _nori) nori(s, c); else if(opc == _slti) slti(s, c); } else { int func = i->func; int shamt = i->shamt; if(func == _add) add(0, s, t); else if(func == _sub) add(1, s, t); else if(func == _and) and(0, s, t); else if(func == _or) or(0, s, t); else if(func == _xor) or(1, s, t); else if(func == _nor) or(2, s, t); else if(func == _nand) and(1, s, t); else if(func == _slt) slt(s, t); else if(func == _sll) sll(t, shamt); else if(func == _srl) sr(0, t, shamt); else if(func == _sra) sr(1, t, shamt); } }
int main() { int i; input(); addi(1,0); for (i = 0; i < min+1; i++) { printf("%d ",minValue[i]); } }
void C1_MacroAssembler::initialize_object( Register obj, // result: pointer to object after successful allocation Register klass, // object klass Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise int con_size_in_bytes, // object size in bytes if known at compile time Register t1, // temp register Register t2 // temp register ) { const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; initialize_header(obj, klass, noreg, t1, t2); #ifdef ASSERT { lwz(t1, in_bytes(Klass::layout_helper_offset()), klass); if (var_size_in_bytes != noreg) { cmpw(CCR0, t1, var_size_in_bytes); } else { cmpwi(CCR0, t1, con_size_in_bytes); } asm_assert_eq("bad size in initialize_object", 0x753); } #endif // Initialize body. if (var_size_in_bytes != noreg) { // Use a loop. addi(t1, obj, hdr_size_in_bytes); // Compute address of first element. addi(t2, var_size_in_bytes, -hdr_size_in_bytes); // Compute size of body. initialize_body(t1, t2); } else if (con_size_in_bytes > hdr_size_in_bytes) { // Use a loop. initialize_body(obj, t1, t2, con_size_in_bytes, hdr_size_in_bytes); } if (CURRENT_ENV->dtrace_alloc_probes()) { Unimplemented(); // assert(obj == O0, "must be"); // call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), // relocInfo::runtime_call_type); } verify_oop(obj); }
/* * Updates the fourier transform of a sample window of N samples. * Uses a sample cache to update the frequencies. */ void sdft(uint8_t new_sample, complex *freq, complex *coefficients) { uint8_t old = get_old_sample(); insert_sample(new_sample); int8_t delta = (int8_t)(new_sample - old); for (uint8_t i=0; i<N; i++) { freq[i] = mul(addi(freq[i], delta), coefficients[i]); } }
void emit_trampoline(struct compilation_unit *cu, void *target_addr, struct jit_trampoline *t) { struct buffer *b = t->objcode; jit_text_lock(); b->buf = jit_text_ptr(); /* Allocate memory on the stack */ emit(b, stwu(1, -16, 1)); /* Save LR on stack */ emit(b, mflr(0)); emit(b, stw(0, 0, 1)); /* Pass pointer to 'struct compilation_unit' as first argument */ emit(b, lis(3, ptr_high(cu))); emit(b, ori(3, 3, ptr_low(cu))); /* Then call 'target_addr' */ emit(b, lis(0, ptr_high(target_addr))); emit(b, ori(0, 0, ptr_low(target_addr))); emit(b, mtctr(0)); emit(b, bctrl()); /* Restore LR from stack */ emit(b, lwz(0, 0, 1)); emit(b, mtlr(0)); /* Free memory on stack */ emit(b, addi(1, 1, 16)); /* Finally jump to the compiled method */ emit(b, mtctr(3)); emit(b, bctr()); jit_text_reserve(buffer_offset(b)); jit_text_unlock(); }
// add method // Add two register values // r[RD] = r[RD] + r[RS] void VirtualMachine::add() { clock += 1; if ( binaryCode.f1.I == 0 ) { int sum = reg[binaryCode.f1.RD] + reg[binaryCode.f1.RS]; if ( reg[binaryCode.f1.RD] >= 0 && reg[binaryCode.f1.RS] >= 0 && sum < 0 ) setOverflow(); else if ( reg[binaryCode.f1.RD] < 0 && reg[binaryCode.f1.RS] < 0 && sum >= 0 ) setOverflow(); reg[binaryCode.f1.RD] = sum; setCarryBit(); } else addi(); } // end add method
void create() { seteuid(getuid(this_object())); set_light(1); set_short("Magical Mind Altering Altar"); set_long( "This room is clean and has almost brand new furniture in it. A strange\n"+ "tilted altar is in the middle of the room. Tables with wheels, which are\n"+ "covered with magical devices, have been pushed up against the walls.\n"); addi("furniture", "The furniture is all made of oak.\n"); addi("altar", "The altar is made out of wood and is tilted at a strange angle.\n"); addi("tables", "The tables are covered with various wands, rings, orbs, magical herbs, and\n"+ "some things you cannot even identify.\n"); addi("table", "Each table is made out of sturdy oak and can be wheeled around the room.\n"); addi("devices","The devices are very peculiar.\n"); addi("device", "One device catches your eye. It is squirting water down a drain.\n"); addi("water","The water looks cool and refreshing.\n"); addi("drain","The drain is on the floor.\n"); addi("floor","The floor is well swept granite.\n"); addi("walls","The stone walls are bare of decorations.\n"); addi("wall","All the walls are the same.\n"); addi("stone","All the stone in this room is granite.\n"); addi("granite","The granite is grey and rough.\n"); // new("/obj/mon/wizard")->move(this_object()); }
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(); }
inline void MacroAssembler::round_to(Register r, int modulus) { assert(is_power_of_2_long((jlong)modulus), "must be power of 2"); addi(r, r, modulus-1); clrrdi(r, r, log2_long((jlong)modulus)); }
void C1_MacroAssembler::initialize_body(Register obj, Register tmp1, Register tmp2, int obj_size_in_bytes, int hdr_size_in_bytes) { const int index = (obj_size_in_bytes - hdr_size_in_bytes) / HeapWordSize; const int cl_size = VM_Version::L1_data_cache_line_size(), cl_dwords = cl_size>>3, cl_dw_addr_bits = exact_log2(cl_dwords); const Register tmp = R0, base_ptr = tmp1, cnt_dwords = tmp2; if (index <= 6) { // Use explicit NULL stores. if (index > 0) { li(tmp, 0); } for (int i = 0; i < index; ++i) { std(tmp, hdr_size_in_bytes + i * HeapWordSize, obj); } } else if (index < (2<<cl_dw_addr_bits)-1) { // simple loop Label loop; li(cnt_dwords, index); addi(base_ptr, obj, hdr_size_in_bytes); // Compute address of first element. li(tmp, 0); mtctr(cnt_dwords); // Load counter. bind(loop); std(tmp, 0, base_ptr); // Clear 8byte aligned block. addi(base_ptr, base_ptr, 8); bdnz(loop); } else { // like clear_memory_doubleword Label startloop, fast, fastloop, restloop, done; addi(base_ptr, obj, hdr_size_in_bytes); // Compute address of first element. load_const_optimized(cnt_dwords, index); rldicl_(tmp, base_ptr, 64-3, 64-cl_dw_addr_bits); // Extract dword offset within first cache line. beq(CCR0, fast); // Already 128byte aligned. subfic(tmp, tmp, cl_dwords); mtctr(tmp); // Set ctr to hit 128byte boundary (0<ctr<cl_dwords). subf(cnt_dwords, tmp, cnt_dwords); // rest. li(tmp, 0); bind(startloop); // Clear at the beginning to reach 128byte boundary. std(tmp, 0, base_ptr); // Clear 8byte aligned block. addi(base_ptr, base_ptr, 8); bdnz(startloop); bind(fast); // Clear 128byte blocks. srdi(tmp, cnt_dwords, cl_dw_addr_bits); // Loop count for 128byte loop (>0). andi(cnt_dwords, cnt_dwords, cl_dwords-1); // Rest in dwords. mtctr(tmp); // Load counter. bind(fastloop); dcbz(base_ptr); // Clear 128byte aligned block. addi(base_ptr, base_ptr, cl_size); bdnz(fastloop); cmpdi(CCR0, cnt_dwords, 0); // size 0? beq(CCR0, done); // rest == 0 li(tmp, 0); mtctr(cnt_dwords); // Load counter. bind(restloop); // Clear rest. std(tmp, 0, base_ptr); // Clear 8byte aligned block. addi(base_ptr, base_ptr, 8); bdnz(restloop); bind(done); } }
Vec2D& Vec2D::operator+=(Vec2D const& other) { return addi(other); }
void execution(int index){ if(test==1) printf("enter EX, with index=%d\n",index); if(index==0 || index==34){ //NOP or HALT return; } /**R-type instructions**/ else if(index==1){ add(RS,RT,RD); } else if(index==2){ addu(RS,RT,RD); } else if(index==3){ sub(RS,RT,RD); } else if(index==4){ and(RS,RT,RD); } else if(index==5){ or(RS,RT,RD); } else if(index==6){ xor(RS,RT,RD); } else if(index==7){ nor(RS,RT,RD); } else if(index==8){ nand(RS,RT,RD); } else if(index==9){ slt(RS,RT,RD); } else if(index==10){ sll(RT,RD,SHAMT); } else if(index==11){ srl(RT,RD,SHAMT); } else if(index==12){ sra(RT,RD,SHAMT); } /**J-type instructions**/ /*else if(index==13){ jr(RS); } else if(index==14){ jj(C); } else if(index==15){ jal(C); }*/ /**I-type instructions**/ else if(index==16){ addi(RS,RT,C); } else if(index==17){ addiu(RS,RT,C); } else if(index==18){ lw(RS,RT,signedC); } else if(index==19){ lh(RS,RT,signedC); } else if(index==20){ lhu(RS,RT,C); } else if(index==21){ lb(RS,RT,signedC); } else if(index==22){ lbu(RS,RT,C); } else if(index==23){ sw(RS,RT,signedC); } else if(index==24){ sh(RS,RT,signedC); } else if(index==25){ sb(RS,RT,signedC); } else if(index==26){ lui(RT,C); } else if(index==27){ andi(RS,RT,C); } else if(index==28){ or(RS,RT,C); } else if(index==29){ nor(RS,RT,C); } else if(index==30){ slti(RS,RT,C); } /*else if(index==31){ beq(RS,RT,signedC); } else if(index==32){ bne(RS,RT,signedC); } else if(index==33){ bgtz(RS,signedC); }*/ else{ if(test==1) printf("this is error instruction or is done in ID\n"); } EX_prev=index; DM_index=index; }
void PPCAssembler::li(RegGPR rd, S16 simm) { addi(rd, r0, simm); }
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; }
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; }
/* sub[id] - return 1 if min <= x-y <= max, 0 otherwise */ static int subi(long x, long y, long min, long max, int needconst) { return addi(x, -y, min, max, needconst); }
void codegen(xJIT *xjit) { xOperand *pputc, *pgetc, *stack; char c; const void *code; int lstack[100], *lcur = lstack, lno = 0; pputc = rbx; pgetc = rbp; stack = r12; push(rbx); push(rbp); push(r12); mov(pputc, rdi); /* putchar */ mov(pgetc, rsi); /* getchar */ mov(stack, rdx); /* stack */ while (~(c = getchar())) { switch (c) { case '+': case '-': { int cnt; cnt = countc(c); if (cnt == 1) { c == '+' ? inc(dword(stack)) : dec(dword(stack)); } else { addi(dword(stack), c == '+' ? cnt : -cnt); } } break; case '>': case '<': { int cnt; cnt = countc(c); addi(stack, 4 * (c == '>' ? cnt : -cnt)); } break; case '.': { mov(rdi, dword(stack)); call(pputc,XJIT_CALL_OPERAND); } break; case ',': { call(pgetc,XJIT_CALL_OPERAND); mov(dword(stack), eax); } break; case '[': { L(numl(lno, 'B')); /* backward label */ mov(eax, dword(stack)); test(eax, eax); jz(numl(lno, 'F'), XJIT_LABEL_NEAR); *lcur++ = lno++; } break; case ']': { int no; no = *--lcur; jmp(numl(no, 'B'), XJIT_JMP_LABEL); L(numl(no, 'F')); /* forward label */ } break; default: break; } } pop(r12); pop(rbp); pop(rbx); ret(); }
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; }
int luaU_guess_locals(Proto* f, int main) { intArray blocklist; LocVarArray locallist; int regassign[MAXARG_A+1]; int regusage[MAXARG_A+1]; int regblock[MAXARG_A+1]; int lastfree; int i,i2,x,pc; int func_endpc = FUNC_BLOCK_END(f); if (f->lineinfo != NULL) { return 0; } if (f->sizelocvars > 0) { return 0; } intArray_Init(&blocklist, MAXARG_A+1); addi(blocklist, func_endpc); LocVarArray_Init(&locallist, MAXARG_A+1); lastfree = 0; for (i=0; i<f->maxstacksize; i++) { regassign[i] = 0; regusage[i] = 0; regblock[i] = 0; } // parameters for (i = 0; i < f->numparams; i++) { add(locallist,0,func_endpc); regassign[lastfree] = 0; regusage[lastfree] = 1; regblock[lastfree] = func_endpc; lastfree++; } // vararg if (NEED_ARG(f)) { add(locallist,0,func_endpc); lastfree++; regassign[lastfree] = 0; regusage[lastfree] = 1; regblock[lastfree] = func_endpc; lastfree++; } #if LUA_VERSION_NUM == 501 // nil optimizations { Instruction i = f->code[0]; OpCode o = GET_OPCODE(i); int a = GETARG_A(i); int b = GETARG_B(i); int c = GETARG_C(i); int ixx,num_nil = -1; switch (o) { // read Ra only case OP_SETGLOBAL: case OP_SETUPVAL: case OP_TESTSET: num_nil = a; break; // read Rb only case OP_MOVE: case OP_UNM: case OP_NOT: case OP_LEN: if (!ISK(b)) { num_nil = b; } break; // read Rb and Rc case OP_GETTABLE: case OP_SETTABLE: case OP_SELF: case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_POW: case OP_EQ: case OP_LT: case OP_LE: if (!ISK(b)) { num_nil = b; } if (!ISK(c)) { num_nil = MAX(num_nil, c); } break; case OP_RETURN: // read Ra to a+b-2 // only return 1 value // move before return multiple values num_nil = MAX(num_nil, a+b-2); break; } for (ixx = lastfree; ixx <= num_nil; ixx++) { if (ixx!=num_nil) { add(locallist,0,last(blocklist)); lastfree++; } regassign[lastfree] = 0; regusage[lastfree] = 1; regblock[lastfree] = last(blocklist); lastfree++; } } #endif // start code checking for (pc = 0; pc < f->sizecode; pc++) { Instruction instr = f->code[pc]; OpCode o = GET_OPCODE(instr); int a = GETARG_A(instr); int b = GETARG_B(instr); int c = GETARG_C(instr); int bc = GETARG_Bx(instr); int sbc = GETARG_sBx(instr); int dest = 0; int setreg = -1; int setregto = -1; int setreg2 = -1; int loadreg = -1; int loadreg2 = -1; int loadreg3 = -1; int loadregto = -1; int intlocfrom = -1; int intlocto = -1; if ((o==OP_JMP) || (o==OP_FORPREP)) { dest = pc + sbc + 2; } else if ((pc+1!=f->sizecode) && (GET_OPCODE(f->code[pc+1])==OP_JMP)) { dest = pc + 1 + GETARG_sBx(f->code[pc+1]) + 2; } // check which registers were read or written to. switch (o) { case OP_MOVE: setreg = a; if (b<=a) { intlocfrom = b; intlocto = b; } loadreg = b; break; case OP_UNM: case OP_NOT: case OP_LEN: setreg = a; loadreg = b; break; case OP_LOADNIL: setreg = a; setregto = b; break; case OP_LOADK: #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_LOADKX: #endif case OP_GETUPVAL: #if LUA_VERSION_NUM == 501 case OP_GETGLOBAL: #endif #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_GETTABUP: #endif case OP_LOADBOOL: case OP_NEWTABLE: case OP_CLOSURE: setreg = a; break; case OP_GETTABLE: setreg = a; loadreg = b; if (!ISK(c)) { loadreg2 = c; } break; #if LUA_VERSION_NUM == 501 case OP_SETGLOBAL: #endif case OP_SETUPVAL: loadreg = a; break; #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_SETTABUP: if (!ISK(b)) { loadreg2 = b; } if (!ISK(c)) { if (loadreg2==-1) { loadreg2 = c; } else { loadreg3 = c; } } break; #endif case OP_SETTABLE: loadreg = a; if (!ISK(b)) { loadreg2 = b; } if (!ISK(c)) { if (loadreg2==-1) { loadreg2 = c; } else { loadreg3 = c; } if ((a+1!=c) && (c>a)) { intlocto = c-1; } } intlocfrom = 0; if (a-1>=intlocto) { intlocto = a-1; } break; case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_POW: case OP_MOD: setreg = a; if (!ISK(b)) { loadreg = b; } if (!ISK(c)) { if (loadreg==-1) { loadreg = c; } else { loadreg2 = c; } } break; case OP_CONCAT: setreg = a; loadreg = b; loadregto = c; break; case OP_CALL: if (c==0) { setreg = a; setregto = f->maxstacksize; } else if (c>=2) { setreg = a; setregto = a+c-2; } else if (c==1) { intlocfrom = 0; intlocto = a-1; } if (b==0) { loadreg = a; loadregto = f->maxstacksize; } else { loadreg = a; loadregto = a+b-1; } break; case OP_RETURN: if (b==0) { loadreg = a; loadregto = f->maxstacksize; } else if (b>=2) { loadreg = a; loadregto = a+b-2; } break; case OP_TAILCALL: if (b==0) { loadreg = a; loadregto = f->maxstacksize; } else { loadreg = a; loadregto = a+b-1; } break; case OP_VARARG: if (b==0) { setreg = a; setregto = f->maxstacksize; } else { setreg = a; setregto = a+b-1; } break; case OP_SELF: setreg = a; setregto = a+1; loadreg = b; if (a>b) { intlocfrom = 0; intlocto = b; } if (!ISK(c)) { loadreg2 = c; } break; case OP_EQ: case OP_LT: case OP_LE: if (!ISK(b)) { loadreg = b; } if (!ISK(c)) { if (loadreg==-1) { loadreg = c; } else { loadreg2 = c; } } break; case OP_TEST: loadreg = a; break; case OP_TESTSET: setreg = a; loadreg = b; break; case OP_SETLIST: loadreg = a; if (b==0) { loadregto = f->maxstacksize; } else { loadregto = a+b; } break; case OP_FORLOOP: #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_TFORCALL: #endif case OP_TFORLOOP: break; case OP_FORPREP: loadreg = a; loadregto = a+2; setreg = a; setregto = a+3; intlocfrom = a; intlocto = a+3; regassign[a] = pc; regassign[a+1] = pc; regassign[a+2] = pc; regassign[a+3] = pc+1; regblock[a] = dest; regblock[a+1] = dest; regblock[a+2] = dest; regblock[a+3] = dest-1; addi(blocklist, dest-1); if (GET_OPCODE(f->code[dest-2])==OP_JMP) { last(blocklist)--; } break; case OP_JMP: if (GET_OPCODE(f->code[dest-1]) == LUADEC_TFORLOOP) { int a = GETARG_A(f->code[dest-1]); int c = GETARG_C(f->code[dest-1]); setreg = a; setregto = a+c+2; loadreg = a; loadregto = a+2; intlocfrom = a; intlocto = a+c+2; regassign[a] = pc; regassign[a+1] = pc; regassign[a+2] = pc; regblock[a] = dest+1; regblock[a+1] = dest+1; regblock[a+2] = dest+1; for (x=a+3;x<=a+c+2;x++) { regassign[x] = pc+1; regblock[x] = dest-1; } } if (dest>pc) { addi(blocklist, dest-1); if (GET_OPCODE(f->code[dest-2])==OP_JMP) { last(blocklist)--; } } break; #if LUA_VERSION_NUM == 501 case OP_CLOSE: #endif #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 case OP_EXTRAARG: #endif default: break; } for (i=1; i<blocklist.size; i++) { x = blocklist.values[i]; i2 = i-1; while ((i2>=0) && (blocklist.values[i2]<x)) { blocklist.values[i2+1] = blocklist.values[i2]; i2 = i2-1; } blocklist.values[i2+1] = x; } if (loadreg!=-1) { if (loadregto==-1) loadregto = loadreg; for (i=loadreg;i<=loadregto;i++) { regusage[i]--; } if (loadreg2!=-1) regusage[loadreg2]--; if (loadreg3!=-1) regusage[loadreg3]--; } if (setreg!=-1) { if (setregto==-1) setregto = setreg; for (i=setreg;i<=setregto;i++) { regusage[i]++; } if (setreg2!=-1) regusage[setreg2]++; } i2 = lastfree-1; for (i=lastfree; i<f->maxstacksize; i++) { if ((regusage[i]<0) || (regusage[i]>1)) { i2 = i; } if ((intlocfrom!=-1) && ((intlocfrom<=i) && (i<=intlocto))) { i2 = i; } } for (i=setreg; i<=setregto; i++) { if (i>i2) { regassign[i] = pc+1; regblock[i] = last(blocklist); } } for (i=lastfree; i<=i2; i++) { //fprintf(stderr,"%d %d %d %d\n",i,regassign[i],regblock[i],block); add(locallist,regassign[i],regblock[i]); lastfree++; } while (blocklist.size > 0 && last(blocklist) <= pc+1) { intArray_Pop(&blocklist); } if (blocklist.size == 0) { fprintf(stderr, "cannot find blockend > %d , pc = %d, f->sizecode = %d\n", pc+1, pc, f->sizecode); } while ((lastfree!=0) && (regblock[lastfree-1] <= pc+1)) { lastfree--; regusage[lastfree]=0; } } intArray_Clear(&blocklist); // print out information { int length = locallist.size; f->sizelocvars = length; if (f->sizelocvars>0) { f->locvars = luaM_newvector(glstate,f->sizelocvars,LocVar); for (i = 0; i < length; i++) { char names[10]; sprintf(names,"l_%d_%d",main,i); f->locvars[i].varname = luaS_new(glstate, names); f->locvars[i].startpc = locallist.values[i].startpc; f->locvars[i].endpc = locallist.values[i].endpc; } } } LocVarArray_Clear(&locallist); // run with all functions for (i=0; i<f->sizep; i++) { luaU_guess_locals(f->p[i],main+i+1); } return 1; }
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); }
int main() { //allocate memory for registers and program data byte reg[16]; byte mem[4096]; //unsigned int offset = (unsigned int)mem - 0x200; word I = 0x200; int i; //printf("Hello World!\n"); //printf("Char size: %u\n",CHAR_BIT); //printf("Char min: %u\n",CHAR_MIN); //printf("Char max: %u\n",UCHAR_MAX); //printf("mem start: %p\n",mem); //printf("mem + 1: %p\n",mem+1); //fill registers to make the string "Hello World", //print it with printf, save it to memory, then //load it again seti(reg+0x0,0x48); seti(reg+0x1,0x65); seti(reg+0x2,0x6C); seti(reg+0x3,0x6C); seti(reg+0x4,0x6F); seti(reg+0x5,0x20); seti(reg+0x6,0x57); seti(reg+0x7,0x6F); seti(reg+0x8,0x72); seti(reg+0x9,0x6C); seti(reg+0xA,0x64); seti(reg+0xB,0x0); //print string printf("%s\n",reg); printf("Register contents after setting\n"); printregs(stdout,reg); printf("Memory contents before doing anythong\n"); printmem(stdout,mem,0x200,0x20F); //printf("Store register contents in memory"); stor(reg,0xB,mem,&I); //printmem(stdout,mem,0x200,0x20F); //zero all the registers memset(reg,0,REG_COUNT); printf("Memory after saving\n"); printmem(stdout,mem,0x200,0x20F); printf("Read memory as a string, line below should read \"Hello World\"\n"); printf("%s\n",mem+0x200); printf("Registers should all be 0\n"); printregs(stdout,reg); printf("Registers should now hold just the 2nd word\n"); I = 0x206; load(reg,0x5,mem,&I); //should load "World" printregs(stdout,reg); printf("%s\n",reg); //test the other opcodes printf("Clear registers\n"); memset(reg,0,REG_COUNT); printregs(stdout,reg); seti(reg+0x0,0x1); printf("set V0 to 1\n"); printregs(stdout,reg); set(reg+0x1,reg+0x0); printf("Set V1 to V0 (1)\n"); printregs(stdout,reg); addi(reg+0x0,0x2); printf("Added 2 to V0,should now be 3\n"); printregs(stdout,reg); add(reg+0x0,reg+0x1,reg+0xF); printf("Add V0 and V1, store answer in V0\n"); printregs(stdout,reg); addi(reg+0x2,0xFF); add(reg+0x0,reg+0x2,reg+0xF); printf("Testing carry flag, add 255 to V2 and add V2 to V0 (sets CF)\n"); printregs(stdout,reg); subyx(reg+0x0,reg+0x2,reg+0xF); printf("V0 - V2, V0 should be 0xFC, VF = 0\n"); printregs(stdout,reg); subxy(reg+0x1,reg+0x2,reg+0xF); printf("V2 (0xFF) - V1 (0x1) -> V1 (0xFE),VF = 1\n"); printregs(stdout,reg); }
// 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; }
void C1_MacroAssembler::allocate_array( Register obj, // result: pointer to array after successful allocation Register len, // array length Register t1, // temp register Register t2, // temp register Register t3, // temp register int hdr_size, // object header size in words int elt_size, // element size in bytes Register klass, // object klass Label& slow_case // continuation point if fast allocation fails ) { assert_different_registers(obj, len, t1, t2, t3, klass); // Determine alignment mask. assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work"); int log2_elt_size = exact_log2(elt_size); // Check for negative or excessive length. size_t max_length = max_array_allocation_length >> log2_elt_size; if (UseTLAB) { size_t max_tlab = align_size_up(ThreadLocalAllocBuffer::max_size() >> log2_elt_size, 64*K); if (max_tlab < max_length) { max_length = max_tlab; } } load_const_optimized(t1, max_length); cmpld(CCR0, len, t1); bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CCR0, Assembler::greater), slow_case); // compute array size // note: If 0 <= len <= max_length, len*elt_size + header + alignment is // smaller or equal to the largest integer; also, since top is always // aligned, we can do the alignment here instead of at the end address // computation. const Register arr_size = t1; Register arr_len_in_bytes = len; if (elt_size != 1) { sldi(t1, len, log2_elt_size); arr_len_in_bytes = t1; } addi(arr_size, arr_len_in_bytes, hdr_size * wordSize + MinObjAlignmentInBytesMask); // Add space for header & alignment. clrrdi(arr_size, arr_size, LogMinObjAlignmentInBytes); // Align array size. // Allocate space & initialize header. if (UseTLAB) { tlab_allocate(obj, arr_size, 0, t2, slow_case); } else { eden_allocate(obj, arr_size, 0, t2, t3, slow_case); } initialize_header(obj, klass, len, t2, t3); // Initialize body. const Register base = t2; const Register index = t3; addi(base, obj, hdr_size * wordSize); // compute address of first element addi(index, arr_size, -(hdr_size * wordSize)); // compute index = number of bytes to clear initialize_body(base, index); if (CURRENT_ENV->dtrace_alloc_probes()) { Unimplemented(); //assert(obj == O0, "must be"); //call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), // relocInfo::runtime_call_type); } verify_oop(obj); }
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; }
int encode_op(char *opcode, char *op_data) { int rd,rs,rt,imm,funct,shaft,target; char tmp[256]; const char *fi = "%s %d"; const char *fg = "%s %%g%d"; const char *ff = "%s %%f%d"; const char *fl = "%s %s"; const char *fgi = "%s %%g%d, %d"; const char *fgl = "%s %%g%d, %s"; const char *fgg = "%s %%g%d, %%g%d"; const char *fggl = "%s %%g%d, %%g%d, %s"; const char *fggi = "%s %%g%d, %%g%d, %d"; const char *fggg = "%s %%g%d, %%g%d, %%g%d"; const char *fff = "%s %%f%d, %%f%d"; const char *fgf = "%s %%g%d, %%f%d"; const char *ffg = "%s %%f%d, %%g%d"; const char *fffl = "%s %%f%d, %%f%d, %s"; const char *ffff = "%s %%f%d, %%f%d, %%f%d"; const char *ffgi = "%s %%f%d, %%g%d, %d"; const char *ffgg = "%s %%f%d, %%g%d, %%g%d"; char lname[256]; shaft = funct = target = 0; if(strcmp(opcode, "mvhi") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return mvhi(rs,0,imm); } if(strcmp(opcode, "mvlo") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return mvlo(rs,0,imm); } if(strcmp(opcode, "add") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return add(rs,rt,rd,0); } if(strcmp(opcode, "nor") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return nor(rs,rt,rd,0); } if(strcmp(opcode, "sub") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return sub(rs,rt,rd,0); } if(strcmp(opcode, "mul") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return mul(rs,rt,rd,0); } if(strcmp(opcode, "addi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return addi(rs,rt,imm); } if(strcmp(opcode, "subi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return subi(rs,rt,imm); } if(strcmp(opcode, "muli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return muli(rs,rt,imm); } if(strcmp(opcode, "input") == 0){ if(sscanf(op_data, fg, tmp, &rd) == 2) return input(0,0,rd,0); } if(strcmp(opcode, "inputw") == 0){ if(sscanf(op_data, fg, tmp, &rd) == 2) return inputw(0,0,rd,0); } if(strcmp(opcode, "inputf") == 0){ if(sscanf(op_data, ff, tmp, &rd) == 2) return inputf(0,0,rd,0); } if(strcmp(opcode, "output") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return output(rs,0,0,0); } if(strcmp(opcode, "outputw") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return outputw(rs,0,0,0); } if(strcmp(opcode, "outputf") == 0){ if(sscanf(op_data, ff, tmp, &rs) == 2) return outputf(rs,0,0,0); } if(strcmp(opcode, "and") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return _and(rs,rt,rd,0); } if(strcmp(opcode, "or") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return _or(rs,rt,rd,0); } if(strcmp(opcode, "sll") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return sll(rs,rt,rd,0); } if(strcmp(opcode, "srl") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return srl(rs,rt,rd,0); } if(strcmp(opcode, "slli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return slli(rs,rt,imm); } if(strcmp(opcode, "srli") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return srli(rs,rt,imm); } if(strcmp(opcode, "b") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return b(rs,0,0,0); } if(strcmp(opcode, "jmp") == 0){ if(sscanf(op_data, fl, tmp, lname) == 2) { strcpy(label_name[label_cnt],lname); return jmp(label_cnt++); } } if(strcmp(opcode, "jeq") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jeq(rs,rt,label_cnt++); } } if(strcmp(opcode, "jne") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jne(rs,rt,label_cnt++); } } if(strcmp(opcode, "jlt") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jlt(rs,rt,label_cnt++); } } if(strcmp(opcode, "jle") == 0){ if(sscanf(op_data, fggl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return jle(rs,rt,label_cnt++); } } if(strcmp(opcode, "call") == 0){ if(sscanf(op_data, fl, tmp, lname) == 2) { strcpy(label_name[label_cnt],lname); return call(label_cnt++); } } if(strcmp(opcode, "callR") == 0){ if(sscanf(op_data, fg, tmp, &rs) == 2) return callr(rs,0,0,0); } if(strcmp(opcode, "return") == 0){ return _return(0); } if(strcmp(opcode, "ld") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return ld(rs,rt,rd,0); } if(strcmp(opcode, "ldi") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return ldi(rs,rt,imm); } if(strcmp(opcode, "ldlr") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return ldlr(rs,0,imm); } if(strcmp(opcode, "fld") == 0){ if(sscanf(op_data, ffgg, tmp, &rd, &rs,&rt) == 4) return fld(rs,rt,rd,0); } if(strcmp(opcode, "st") == 0){ if(sscanf(op_data, fggg, tmp, &rd, &rs,&rt) == 4) return st(rs,rt,rd,0); } if(strcmp(opcode, "sti") == 0){ if(sscanf(op_data, fggi, tmp, &rt, &rs, &imm) == 4) return sti(rs,rt,imm); } if(strcmp(opcode, "stlr") == 0){ if(sscanf(op_data, fgi, tmp, &rs, &imm) == 3) return stlr(rs,0,imm); } if(strcmp(opcode, "fst") == 0){ if(sscanf(op_data, ffgg, tmp, &rd, &rs,&rt) == 4) return fst(rs,rt,rd,0); } if(strcmp(opcode, "fadd") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fadd(rs,rt,rd,0); } if(strcmp(opcode, "fsub") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fsub(rs,rt,rd,0); } if(strcmp(opcode, "fmul") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fmul(rs,rt,rd,0); } if(strcmp(opcode, "fdiv") == 0){ if(sscanf(op_data, ffff, tmp, &rd, &rs, &rt) == 4) return fdiv(rs,rt,rd,0); } if(strcmp(opcode, "fsqrt") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fsqrt(rs,0,rd,0); } if(strcmp(opcode, "fabs") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return _fabs(rs,0,rd,0); } if(strcmp(opcode, "fmov") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fmov(rs,0,rd,0); } if(strcmp(opcode, "fneg") == 0){ if(sscanf(op_data, fff, tmp, &rd, &rs) == 3) return fneg(rs,0,rd,0); } if(strcmp(opcode, "fldi") == 0){ if(sscanf(op_data, ffgi, tmp, &rt, &rs, &imm) == 4) return fldi(rs,rt,imm); } if(strcmp(opcode, "fsti") == 0){ if(sscanf(op_data, ffgi, tmp, &rt, &rs, &imm) == 4) return fsti(rs,rt,imm); } if(strcmp(opcode, "fjeq") == 0){ if(sscanf(op_data, fffl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return fjeq(rs,rt,label_cnt++); } } if(strcmp(opcode, "fjlt") == 0){ if(sscanf(op_data, fffl, tmp, &rs, &rt, lname) == 4) { strcpy(label_name[label_cnt],lname); return fjlt(rs,rt,label_cnt++); } } if(strcmp(opcode, "halt") == 0){ return halt(0,0,0,0); } if(strcmp(opcode, "setL") == 0){ if(sscanf(op_data, fgl, tmp, &rd, lname) == 3) { strcpy(label_name[label_cnt],lname); return setl(0,rd,label_cnt++); } } if(strcmp(opcode, "padd") == 0){ if(sscanf(op_data, fgi, tmp, &rt, &imm) == 3) { return padd(0,rt,imm); } } if(strcmp(opcode, "link") == 0){ if(sscanf(op_data, fi, tmp, &imm) == 2) { return link(0,0,imm); } } if(strcmp(opcode, "movlr") == 0){ return movlr(0,0,0,0); } if(strcmp(opcode, "btmplr") == 0){ return btmplr(0,0,0,0); } /* if(strcmp(opcode, "padd") == 0){ if(sscanf(op_data, fgg, tmp, &rd, &rt) == 3) { return padd(0,rt,d,0); } } */ return -1; }