void Value::assign_register() { if (in_register()) { return; } #if ENABLE_ARM_VFP if (stack_type() == T_FLOAT) { set_register(RegisterAllocator::allocate_float_register()); } else if (stack_type() == T_DOUBLE) { set_vfp_double_register(RegisterAllocator::allocate_double_register()); } else #endif { if (!is_two_word()) { set_register(RegisterAllocator::allocate()); } else { // NOTE: avoid doing this: set_registers(allocate(), allocate()); // The order of parameter list evaluation is undefined in C, and // on linux/i386 and solaris/sparc the orders are opposite. The following // code forces the same order, so AOT generator will generate exact // same code on both Linux and Solaris hosts. Assembler::Register hi = RegisterAllocator::allocate(); Assembler::Register low = RegisterAllocator::allocate(); set_registers(low, hi); } } }
//mark the location is not first time access if the location is assigned //same register. This is called when do set_is_not_first_time_access in //VirtualStackFrame::set_is_not_first_time_access(). bool set_is_not_first_time_access(Assembler::Register reg ) { if (!is_flushed() && in_register() && uses_register(reg) ) { _flags |= Value::F_IS_NOT_FIRST_TIME_ACCESS; return true; } return false; }
void Value::force_to_byte_register() { GUARANTEE(in_register(), "must be in register"); if (!Assembler::is_valid_byte_register(lo_register())) { Assembler::Register byte_register = RegisterAllocator::allocate_byte_register(); Compiler::code_generator()->movl(byte_register, lo_register()); set_register(byte_register); } }
void Value::destroy() { if (in_register()) { RegisterAllocator::dereference(lo_register()); if (use_two_registers()) { RegisterAllocator::dereference(hi_register()); } } set_where(T_NOWHERE); }
static void in_sdl_probe(const in_drv_t *drv) { const struct in_sdl_pdata *pdata = drv->pdata; struct in_sdl_state *state; SDL_Joystick *joy; int i, joycount; char name[256]; state = calloc(1, sizeof(*state)); if (state == NULL) { fprintf(stderr, "in_sdl: OOM\n"); return; } state->drv = drv; in_register(IN_SDL_PREFIX "keys", -1, state, SDLK_LAST, pdata->key_names, 0); /* joysticks go here too */ SDL_InitSubSystem(SDL_INIT_JOYSTICK); joycount = SDL_NumJoysticks(); for (i = 0; i < joycount; i++) { joy = SDL_JoystickOpen(i); if (joy == NULL) continue; state = calloc(1, sizeof(*state)); if (state == NULL) { fprintf(stderr, "in_sdl: OOM\n"); break; } state->joy = joy; state->joy_id = i; state->drv = drv; snprintf(name, sizeof(name), IN_SDL_PREFIX "%s", SDL_JoystickName(i)); in_register(name, -1, state, SDLK_LAST, pdata->key_names, 0); } if (joycount > 0) SDL_JoystickEventState(SDL_ENABLE); }
static void in_tsbutton_probe(void) { struct tsdev *dev = tsdev; if (dev == NULL) { fprintf(stderr, "in_tsbutton_probe: missing tsdev\n"); return; } in_register(IN_TSBUTTON_PREFIX "touchscreen as buttons", pl_gun_ts_get_fd(dev), NULL, IN_TSBUTTON_COUNT, in_tsbutton_keys, 0); }
void Value::copy(Value& result) { GUARANTEE(in_register(), "value must be in register"); if (use_two_registers()) { result.set_registers(lo_register(), hi_register()); RegisterAllocator::reference(lo_register()); RegisterAllocator::reference(hi_register()); //cse RegisterAllocator::wipe_notation_of(lo_register()); RegisterAllocator::wipe_notation_of(hi_register()); } else { result.set_register(lo_register()); RegisterAllocator::reference(lo_register()); //cse RegisterAllocator::wipe_notation_of(lo_register()); } }
void RawLocation::change_register(Assembler::Register dst, Assembler::Register src) { GUARANTEE(!is_flushed() && in_register(), "Sanity"); GUARANTEE(this->value() == src || (is_two_word() && next_location()->value() == src), "Only called if necessary"); if (this->value() == src) { this->set_value(dst); } if (is_two_word()) { RawLocation *next = next_location(); if (next->value() == src) { next->set_value(dst); } } }
bool RawLocation::is_register_identical_to(int my_index, RawLocation* other, int other_index) { GUARANTEE(in_register(), "must be in register"); // if the the other location isn't in a register we're not identical if (!other->in_register()) { return false; } // make sure the types match GUARANTEE(stack_type() == other->stack_type(), "types must match"); const Value this_value (this, my_index); const Value other_value(other, other_index); return this_value.lo_register() == other_value.lo_register() && (!this_value.use_two_registers() || this_value.hi_register() == other_value.hi_register() ); }
static void in_gp2x_probe(const in_drv_t *drv) { switch (gp2x_dev_id) { case GP2X_DEV_GP2X: in_gp2x_get_bits = in_gp2x_get_mmsp2_bits; break; case GP2X_DEV_WIZ: gpiodev = open("/dev/GPIO", O_RDONLY); if (gpiodev < 0) { perror("in_gp2x: couldn't open /dev/GPIO"); return; } in_gp2x_get_bits = in_gp2x_get_wiz_bits; break; // we'll use evdev for Caanoo default: return; } in_register(IN_GP2X_PREFIX "GP2X pad", -1, NULL, IN_GP2X_NBUTTONS, in_gp2x_keys, 1); }
void Value::writable_copy(Value& result) { GUARANTEE(in_register(), "value must be in register"); VirtualStackFrame* frame = Compiler::current()->frame(); if (use_two_registers()) { if ((RegisterAllocator::references(lo_register()) == 1) && (RegisterAllocator::references(hi_register()) == 1)) { // use this value as the writable copy. RegisterAllocator::spill(hi_register()); RegisterAllocator::spill(lo_register()); frame->dirtify(hi_register()); frame->dirtify(lo_register()); result.set_registers(lo_register(), hi_register()); // make sure we increment the reference counters RegisterAllocator::reference(lo_register()); RegisterAllocator::reference(hi_register()); } else { // allocate two new registers and copy the value of these registers into it. result.set_registers(RegisterAllocator::allocate(), RegisterAllocator::allocate()); Compiler::code_generator()->move(result, *this); } } else { if (RegisterAllocator::references(lo_register()) == 1) { // use this value as the writable copy. RegisterAllocator::spill(lo_register()); frame->dirtify(lo_register()); result.set_register(lo_register()); // make sure we increment the reference counter RegisterAllocator::reference(lo_register()); } else { // allocate a new register and copy the value of this register into it. result.assign_register(); Compiler::code_generator()->move(result, *this); } } }
void Value::assign_register() { if (in_register()) return; switch(stack_type()) { case T_OBJECT : // fall through case T_ARRAY : // fall through case T_INT : set_register(RegisterAllocator::allocate()); break; case T_LONG : set_registers(RegisterAllocator::allocate(), RegisterAllocator::allocate()); break; #if ENABLE_ARM_VFP case T_FLOAT : set_register(RegisterAllocator::allocate_float_register()); break; case T_DOUBLE : set_vfp_double_register(RegisterAllocator::allocate_double_register()); break; #else // !ENABLE_ARM_VFP case T_FLOAT : // fall through case T_DOUBLE : set_register(RegisterAllocator::allocate_float_register()); break; #endif // ENABLE_ARM_VFP default : SHOULD_NOT_REACH_HERE(); break; } }
bool RawLocation::has_register_conflict_with(int my_index, VirtualStackFrame *other_frame, RawLocation* other_loc, int other_index) { // locations not in registers cannot cause register conflicts if (!in_register()) { return false; } // compute the merge action const int actions = merge_actions(other_loc); if (actions & (REG_STORE | LOC_STORE)) { const Value this_value(this, my_index); if( is_used_in(other_frame, this_value) && ( (actions & LOC_STORE) || !is_register_identical_to(my_index, other_loc, other_index) ) ) { return true; } } // no conflict return false; }
Assembler::Register msw_register( void ) const { GUARANTEE(in_register() && type() == T_LONG, "check"); return (Assembler::Register)(TARGET_MSW_FIRST_FOR_LONG ? _low : _high); }
void write_changes(const Assembler::Register reg, const int index) { if (is_changed() && in_register() && uses_register(reg)) { write_changes(index); } }
// get registers Assembler::Register lo_register( void ) const { GUARANTEE(in_register(), "value must be in a register"); return (Assembler::Register)_low; }
// spill a specific register into this location if it mapped by it void spill_register(const Assembler::Register reg, const int index) { if (!is_flushed() && in_register() && uses_register(reg)) { flush(index); } }