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()));
}
Пример #2
0
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);
	}
}
Пример #3
0
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);
    }
}
Пример #4
0
int main() {
	int i;
	input();
	addi(1,0);
	for (i = 0; i < min+1; i++) {
		printf("%d ",minValue[i]);
	}
	
}
Пример #5
0
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);
}
Пример #6
0
/* 
 * 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]);
  }

}
Пример #7
0
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();
}
Пример #8
0
// 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
Пример #9
0
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());
}
Пример #10
0
void simulate_MainWindow::simulate()
{
    currInstr=instrList[PC/4];
    currBin=binList[PC/4];

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

    coutString="";
    RD=RS=RT=immediate=address=0;
    v0=v1=v2=v3="None";
    v0=result[0];
    v1=result[1];
    printf("v0=%s\nv1=%s\n",v0.c_str(),v1.c_str());
    if(v0=="jr"||v0=="j"||v0=="jal")  // 2 parametes
    {
        if(v0=="jr")
        {
            jr();
        }
        else if(v0=="j")
            j();
        else if(v0=="jal")
            jal();
    }
    else if(v0=="lui")    // 3 parameters
    {
        v2=result[2];
        lui();
    }
    else                 // 4 parameters
    {
        v2=result[2];
        v3=result[3];
        if(v0=="add")
            add();
        else if(v0=="addu")
            addu();
        else if(v0=="sub")
            sub();
        else if(v0=="subu")
            subu();
        else if(v0=="and")
            and_funct();
        else if(v0=="or")
            or_funct();
        else if(v0=="xor")
            xor_funct();
        else if(v0=="nor")
            nor();
        else if(v0=="slt")
            slt();
        else if(v0=="sltu")
            sltu();
        else if(v0=="sll")
            sll();
        else if(v0=="srl")
            srl();
        else if(v0=="sllv")
            sllv();
        else if(v0=="srlv")
            srlv();
        else if(v0=="srav")
            srav();
        else if(v0=="addi")
            addi();
        else if(v0=="addiu")
            addiu();
        else if(v0=="andi")
            andi();
        else if(v0=="ori")
            ori();
        else if(v0=="xori")
            xori();
        else if(v0=="sw")
            sw();
        else if(v0=="lw")
            lw();
        else if(v0=="beq")
            beq();
        else if(v0=="bne")
            bne();
        else if(v0=="slti")
            slti();
        else if(v0=="sltiu")
            sltiu();
    }
    display_all();
}
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));
}
Пример #12
0
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);
  }
}
Пример #13
0
Vec2D& Vec2D::operator+=(Vec2D const& other)
{
  return addi(other);
}
Пример #14
0
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;
}
Пример #15
0
void PPCAssembler::li(RegGPR rd, S16 simm) { addi(rd, r0, simm); }
Пример #16
0
  address generate_call_stub(address& return_address)
  {
    assert (!TaggedStackInterpreter, "not supported");
    
    StubCodeMark mark(this, "StubRoutines", "call_stub");
    address start = __ enter();

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

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

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

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

    const Register parameter_bytes = parameter_words;

    __ shift_left (parameter_bytes, parameter_words, LogBytesPerWord);    

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      __ bind (done);
    }

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

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

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

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

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

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

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

    Label is_int, is_long, is_object;

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

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

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

    // Unwind and return
    __ load (r1, Address(r1, StackFrame::back_chain_offset * wordSize));
    __ load (r0, Address(r1, StackFrame::lr_save_offset * wordSize));
    __ mtlr (r0);
    __ blr ();
    
    return start;
  }
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;
}
Пример #18
0
Файл: simp.c Проект: DevenLu/lcc
/* 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);
}
Пример #19
0
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();
}
Пример #20
0
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
  // Slow_signature handler that respects the PPC C calling conventions.
  //
  // We get called by the native entry code with our output register
  // area == 8. First we call InterpreterRuntime::get_result_handler
  // to copy the pointer to the signature string temporarily to the
  // first C-argument and to return the result_handler in
  // R3_RET. Since native_entry will copy the jni-pointer to the
  // first C-argument slot later on, it is OK to occupy this slot
  // temporarilly. Then we copy the argument list on the java
  // expression stack into native varargs format on the native stack
  // and load arguments into argument registers. Integer arguments in
  // the varargs vector will be sign-extended to 8 bytes.
  //
  // On entry:
  //   R3_ARG1        - intptr_t*     Address of java argument list in memory.
  //   R15_prev_state - BytecodeInterpreter* Address of interpreter state for
  //     this method
  //   R19_method
  //
  // On exit (just before return instruction):
  //   R3_RET            - contains the address of the result_handler.
  //   R4_ARG2           - is not updated for static methods and contains "this" otherwise.
  //   R5_ARG3-R10_ARG8: - When the (i-2)th Java argument is not of type float or double,
  //                       ARGi contains this argument. Otherwise, ARGi is not updated.
  //   F1_ARG1-F13_ARG13 - contain the first 13 arguments of type float or double.

  const int LogSizeOfTwoInstructions = 3;

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

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

  address entry = __ function_entry();

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

  __ mr(arg_java, R3_ARG1);

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

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

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

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

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

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

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

  __ bind(loop_start);

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

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

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

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

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

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

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

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

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

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

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

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

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

  __ bind(do_dontreachhere);

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

  __ bind(do_array);

  {
    Label start_skip, end_skip;

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

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

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

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

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

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

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

  __ bind(loop_end);

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

  __ blr();

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

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

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

  return entry;
}
Пример #21
0
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);
}
Пример #23
0
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;
}
Пример #25
0
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);
}
Пример #26
0
int exe(FILE* program)  //program指向存有待执行程序机器码的文件
{

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

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

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


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

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


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

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

    case 0x00000039:
        numRs=instru<<6>>27;
        numFt=instru<<11>>27;
        RS2=myRegister+numRs;
        FS1=myFloatReg+numFt;
        lig=instru<<16>>16;
        //printf("/********\nS.S %u %u\n****************/\n",numFt,numRs);
        pc=swc1(pc);
        break;
    case 0x00000011:
        numFt=instru<<11>>27;
        numFs=instru<<16>>27;
        numFd=instru<<21>>27;
        FS1=myFloatReg+numFt;
        FS2=myFloatReg+numFs;
        FD=myFloatReg+numFd;
        numRs=instru<<6>>27;
        tmp_fuc=instru%64;
        //printf("%u %u\n",tmp_fuc,numRs);
        if(numRs==0)
        {
            switch(tmp_fuc)
            {
            case 0:
                pc=add_s(pc);
                break;
            case 1:
                pc=sub_s(pc);
                break;
            case 2:
                pc=mul_s(pc);
            case 3:
                pc=div_s(pc);
            default:
                break;
            }
        }
        else if(numRs==1)
        {
            switch(tmp_fuc)
            {
            case 0:
                pc=add_d(pc);
                //printf("/****************\nADD.D %u %u %u\n*****************/\n",numFd,numFt,numFs);
                break;
            case 1:
                pc=sub_d(pc);
                break;
            case 2:
                pc=mul_d(pc);
            case 3:
                pc=div_d(pc);
            default:
                break;
            }
        }
        default:break;
    }
    pcShort=pc%0x00010000;
    //printf("%u %u\n",pc,pcShort);
    //printf("%u %u\n",pcShort,programTail);
    }
    return 0;
}
Пример #27
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;
}