コード例 #1
0
void InterpreterStubs::generate_current_thread_to_primordial() {
  Segment seg(this, code_segment, "Current thread to primordial");
  bind_global("current_thread_to_primordial");
  
  comment("Set up global pointer, as we can be called from C code");
  ldr_gp_base(gp);
  
  bind_global("current_thread_to_primordial_fast");

  // We're never going to return to this thread, so it doesn't matter if
  // it doesn't look like a stopped Java thread anymore.
  get_primordial_sp(sp);
  comment("restore permanent registers (including return address)");
  ldr(lr, imm_index(sp, BytesPerWord, post_indexed));
  ldmfd(sp, range(r3, r11), writeback);
  jmpx(lr);

  if (GenerateDebugAssembly) {
    bind_local("interpreter_bkpt");
    get_gp_bytecode_counter(tmp3);
    add(tmp3, tmp3, imm(1));
    set_gp_bytecode_counter(tmp3);
    mov(pc, reg(tmp0));
  }

#if ENABLE_XSCALE_WMMX_TIMER_TICK && !ENABLE_TIMER_THREAD
  // set timer_tick from WMMX wCASF register
  comment("wmmx_set_timer_tick to set timer_tick from WMMX register");
  bind_global("wmmx_set_timer_tick");
  // tmrc(r2, wCASF);
  define_long(0xEE132110);
  mvn(r3, imm(4) );
  andr(r2, r2, reg(r3) );
  // tmcr(wCASF, r2);
  define_long(0xEE032110);
  jmpx(lr);
  // clear timer_tick from WMMX wCASF register
  comment("wmmx_set_timer_tick to clear timer_tick from WMMX register");
  bind_global("wmmx_clear_timer_tick");
  define_long(0xEE100060); 
//  wcmpgtub(wR0, wR0, wR0);
  jmpx(lr);
#endif // ENABLE_XSCALE_WMMX_TIMER_TICK && !ENABLE_TIMER_THREAD

}
コード例 #2
0
void InterpreterStubs::generate_primordial_to_current_thread() {
  Segment seg(this, code_segment, "Primordial to current thread");

bind_global("primordial_to_current_thread");
  comment("save permanent registers (including return address)");
  stmfd(sp, range(r3, r11), writeback);
  str(lr, imm_index(sp, -BytesPerWord, pre_indexed));

  comment("Set up global pointer");
  ldr_gp_base(gp);

  comment("Get current thread");
  get_thread(r1);

  comment("Save primordial stack pointer");
  set_primordial_sp(sp);

  comment("Get new stack pointer");
  ldr(jsp, imm_index(r1, Thread::stack_pointer_offset()));
  
  comment("Go to code");
  ldr(lr, imm_index(jsp, -JavaStackDirection * BytesPerWord));
  ldr(fp, imm_index(jsp, -JavaStackDirection * 2 * BytesPerWord, post_indexed));
  jmpx(lr);

bind_global("start_lightweight_thread_asm");
  Label testing_compiler; 
  const int SignedBytesPerWord = JavaStackDirection * BytesPerWord;

  comment("Set up global pointer");
  ldr_gp_base(gp);
  // jsp       => Thread::lightweight_thread_exit
  // jsp +- 4   => Thread::lightweight_thread_uncaught_exception
  // jsp +- 8   => Thread::finish
  // jsp +- 12  => force_terminated
  // jsp +- 16  => TestCompiler

  comment("Invoke pending entries unless the thread is being terminated");
  get_thread(r0);
  comment("r1 = THREAD->status();");
  ldr(r1, imm_index(r0, Thread::status_offset()));
  mov(r2, zero);
  comment("if ((r1 & THREAD_TERMINATING) != 0) {");
  tst(r1, imm(THREAD_TERMINATING));
  comment("  THREAD->pending_entries = NULL;");
  str(r2, imm_index(r0, Thread::pending_entries_offset()), ne);
  comment("} else {");
  comment("  invoke_pending_entries(THREAD)");
  bl("invoke_pending_entries", eq);
  comment("}");

  comment("if (!TestCompiler) {");
  ldr(r0, imm_index(jsp, -4 * SignedBytesPerWord));
  get_current_pending_exception(r1);
  cmp(r0, zero);
  b(testing_compiler, ne);

  comment("  if (Thread::current_has_pending_exception()) {");
  comment("    call_on_primordial_stack(lightweight_thread_uncaught_exception);");
  comment("  }");
  cmp(r1, zero);
  ldr(r0, imm_index(jsp, -1 * SignedBytesPerWord), ne);
  bl("call_on_primordial_stack",                   ne); 

  comment("  call_on_primordial_stack(finish);");
  ldr(r0, imm_index(jsp, -2 * SignedBytesPerWord));
  bl("call_on_primordial_stack");   

  comment("  invoke_pending_entries(THREAD);");
  get_thread(r0);
  bl("invoke_pending_entries");

  comment("  force_terminated()");
  ldr(r0, imm_index(jsp, -3 * SignedBytesPerWord));  
  bl("call_on_primordial_stack");
  comment("}");  
#if ENABLE_ISOLATES
  comment("Terminate the task if no other threads on it");
  ldr_label(r0, "thread_task_cleanup");
  bl("call_on_primordial_stack");   
  comment("  invoke_pending_entries(THREAD);");
  get_thread(r0);
  bl("invoke_pending_entries");
#endif

bind_global(testing_compiler);
  comment("call_on_primordial_stack(lightweight_thread_exit);");
  ldr(r0, imm_index(jsp));
  bl("call_on_primordial_stack");

  comment("GUARANTEE(Scheduler::_next_runnable_thread == NULL");

  ldr_label(r0, "_next_runnable_thread");
  ldr(r0, imm_index(r0));
  cmp(r0, zero);
  breakpoint(ne);

  comment("current_thread_to_primordial();");
  bl("current_thread_to_primordial_fast");
  breakpoint();
}
コード例 #3
0
ファイル: SourceAssembler_arm.cpp プロジェクト: sfsy1989/j2me
void SourceAssembler::str_using_gp(Register reg, const char *name, 
                                   Condition cond) {
  int offset = find_gp_offset(name);
  str(reg, imm_index(gp, offset), cond);
}