void InterpreterStubs::generate_interpreter_timer_tick() {
  comment_section("Interpreter call timer_tick");
  entry("interpreter_timer_tick");
  interpreter_call_vm(Constant("timer_tick"), T_VOID);
  dispatch_next();
  entry_end(); // interpreter_timer_tick

#if ENABLE_PAGE_PROTECTION
  stop_code_segment();
  start_data_segment();
  if (GenerateGNUCode || GenerateInlineAsm) {
    align(PROTECTED_PAGE_SIZE);
    define_array_begin("unsigned char", "_protected_page");
    for (int i = 0; i < PROTECTED_PAGE_SIZE; i++) {
      define_byte_element(Constant(0));
    }
    define_array_end();
  } else {
    // MASM doesn't allow 4096-byte alignment,
    // so surround the protected area with 4K padding.
    // This will certainly add 8K of static footprint,
    // but who cares about the size of win32_i386 binary!
    define_byte(Constant(0), PROTECTED_PAGE_SIZE);
    define_long(Constant(0), PROTECTED_PAGE_SIZE / BytesPerWord,
                "_protected_page");
    define_byte(Constant(0), PROTECTED_PAGE_SIZE);
  }
  stop_data_segment();
  start_code_segment();
#endif
}
示例#2
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

}
void GPTableGenerator::generate_protected_page() {
  if (!GenerateGPTableOnly && ENABLE_PAGE_PROTECTION) {
    GUARANTEE(!ENABLE_THUMB_GP_TABLE, "Not supported");
    align(PROTECTED_PAGE_SIZE);
    bind("_protected_page");
    // Fill the page with pointers to gp_base_label to allow ldr gp, [gp, -##]
    Label gp_base_label("gp_base_label");
    for (int i = 0; i < PROTECTED_PAGE_SIZE; i += BytesPerWord) {
      define_long(gp_base_label);
    }
  }
}
示例#4
0
void SourceAssembler::define_call_info() {
#if ENABLE_EMBEDDED_CALLINFO
  CallInfo ci = CallInfo::interpreter();
  define_long(ci.raw());
#endif
}
// Bytecode dispatch table for ARM Interpreter/Thumb Compiler
void
GPTableGenerator::generate_thumb_bytecode_dispatch_table()
{
  int i;
  define_long(0);                           // 256 or 263
  define_long(0);                           // 255 or 262

  if (ENABLE_DISPATCH_TABLE_PADDING) {
    SHOULD_NOT_REACH_HERE();
    // This is a bit bogus -- padded dispatch tables must be ascending,
    // so it won't work with Thumb compiler!
    define_long("bytecode_dispatch_0x105");
    define_long("bytecode_dispatch_0x104");
    define_long("bytecode_dispatch_0x103");
    define_long("bytecode_dispatch_0x102");
    define_long("bytecode_dispatch_0x101");
    define_long("bytecode_dispatch_0x100");
    define_long("bytecode_dispatch_0x0FF");
    define_long("bytecode_dispatch_0x0FE");
  }

  for (i = 253; i > 0; i--) {
    Bytecodes::Code bc = (Bytecodes::Code) i;
    if (Bytecodes::is_defined(bc) && !GenerateGPTableOnly) {
      char buffer[256];
      if (GenerateGNUCode) {
        jvm_sprintf(buffer, "bc_impl_%-30s /* 0x%x */", Bytecodes::name(bc),
                    (int)bc);
      } else {
        jvm_sprintf(buffer, "bc_impl_%-30s ; 0x%x", Bytecodes::name(bc), \
                    (int)bc);
      }
      define_long(buffer);
    } else {
      define_long(0);
    }
  }

  bind("gp_base_label");
  set_current_commented_offset(0);
  set_use_offset_comments(true);

  if (!GenerateGPTableOnly) {
    // Define nop at offset 0 from base_label
    // the rest would be at -ve offset
    char buffer[256];
    if (GenerateGNUCode) {
      jvm_sprintf(buffer, "bc_impl_%-30s /* 0x%x */",
                  Bytecodes::name((Bytecodes::Code)0), 0);
    } else {
      jvm_sprintf(buffer, "bc_impl_%-30s ; 0x%x",
                  Bytecodes::name((Bytecodes::Code)0), 0);
    }
    define_long(buffer);
  } else {
    define_long(0);
  }
}
// Bytecode dispatch table for ARM Interpreter/Compiler
void GPTableGenerator::generate_arm_bytecode_dispatch_table()
{
  int i;
  bind("gp_base_label");
  set_current_commented_offset(0);
  set_use_offset_comments(true);

  for (i = 0; i <= 253; i++) {
    Bytecodes::Code bc = (Bytecodes::Code) i;
    if (Bytecodes::is_defined(bc) && !GenerateGPTableOnly) {
      char buffer[256];
      if (GenerateGNUCode) {
        jvm_sprintf(buffer, "bc_impl_%-30s /* 0x%x */", Bytecodes::name(bc),
                    (int)bc);
      } else {
        jvm_sprintf(buffer, "bc_impl_%-30s ; 0x%x", Bytecodes::name(bc), 
                    (int)bc);
      }
      define_long(buffer);
    } else {
      eol_comment("undefined bytecode 0x%x", bc);
      define_long(0);
    }
  }

  if (ENABLE_DISPATCH_TABLE_PADDING) {
    define_long("bytecode_dispatch_0x0FE");
    define_long("bytecode_dispatch_0x0FF");
    define_long("bytecode_dispatch_0x100");
    define_long("bytecode_dispatch_0x101");
    define_long("bytecode_dispatch_0x102");
    define_long("bytecode_dispatch_0x103");
    define_long("bytecode_dispatch_0x104");
    define_long("bytecode_dispatch_0x105");
  }
  define_long(0);                           // 255 or 262
  define_long(0);                           // 256 or 263
}
void GPTableGenerator::generate_constants_table() {
  int i;

  bind("gp_constants");

  static const GPTemplate gp_templates[] = {
    GP_SYMBOLS_DO(DEFINE_GP_POINTER, DEFINE_GP_VALUE)
    {NULL, 0, 0, 0}
  };

  for (const GPTemplate* tmpl = gp_templates; tmpl->name; tmpl++) {
    if (tmpl->is_pointer) {
      char buff[120];
      jvm_sprintf(buff, "gp_%s_ptr", tmpl->name);
      bind(buff);

      Label L(tmpl->name);
      if (!tmpl->is_asm) {
        import(L);
      }
      define_long(L);
    } else {
      if (jvm_strcmp(tmpl->name, "current_thread") == 0) {
         bind("jvm_fast_globals");
      }
      char buff[120];
      jvm_sprintf(buff, "_%s", tmpl->name);
      bind(buff);
      if (jvm_strcmp(tmpl->name, "bit_selector") == 0) {
        // IMPL_NOTE: create a common framework to define initial values
        define_long(0x80808080);
      } else {
        define_zeros(tmpl->size);
      }
    }
  }

  if (!GenerateGPTableOnly) {
    // Some constants to check we've linked with the right ROM
    Label L1(XSTR(_ROM_LINKCHECK_HLE));
    import(L1);
    define_long(L1);

    Label L2(XSTR(_ROM_LINKCHECK_MFFD));
    import(L2);
    define_long(L2);

    Label L3(XSTR(_ROM_LINKCHECK_MFFL));
    import(L3);
    define_long(L3);
  }

  if (ENABLE_THUMB_GP_TABLE && GenerateGPTableOnly) {
    // These symbols are necessary to link romgen.
    // We define a long for each entry, since they 
    // should be bound to different addresses.
    bind("jvm_ladd");
    define_long(0);
    bind("jvm_lsub");
    define_long(0);
    bind("jvm_land");
    define_long(0);
    bind("jvm_lor");
    define_long(0);
    bind("jvm_lxor");
    define_long(0);
    bind("jvm_lcmp");
    define_long(0);
    bind("jvm_lmin");
    define_long(0);
    bind("jvm_lmax");
    define_long(0);
    bind("jvm_lmul");
    define_long(0);
    bind("jvm_lshl");
    define_long(0);
    bind("jvm_lshr");
    define_long(0);
    bind("jvm_lushr");
    define_long(0);
  }

  bind("gp_constants_end");
}