Ejemplo n.º 1
0
/*
 * clock source
 */
static u64 sched_clock_read(void)
{
	return (u64)mfcr(PTIM_CCVR);
}
Ejemplo n.º 2
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;
  }
Ejemplo n.º 3
0
static u64 clksrc_read(struct clocksource *c)
{
	return (u64)mfcr(PTIM_CCVR);
}