Exemple #1
0
static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
  assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
         "mismatch in calculation");
  __ save_frame_c1(frame_size_in_bytes);

  // Record volatile registers as callee-save values in an OopMap so their save locations will be
  // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
  // deoptimization; see compiledVFrame::create_stack_value).  The caller's I, L and O registers
  // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
  // (as the stub's I's) when the runtime routine called by the stub creates its frame.
  // OopMap frame sizes are in c2 stack slot sizes (sizeof(jint))

  int i;
  for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
    Register r = as_Register(i);
    if (r == G1 || r == G3 || r == G4 || r == G5) {
      int sp_offset = cpu_reg_save_offsets[i];
      __ st_ptr(r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
    }
  }

  if (save_fpu_registers) {
    for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
      FloatRegister r = as_FloatRegister(i);
      int sp_offset = fpu_reg_save_offsets[i];
      __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
    }
  }

  return generate_oop_map(sasm, save_fpu_registers);
}
Exemple #2
0
static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
  assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
         "mismatch in calculation");
  sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
  int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
  OopMap* oop_map = new OopMap(frame_size_in_slots, 0);

  int i;
  for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
    Register r = as_Register(i);
    if (r == G1 || r == G3 || r == G4 || r == G5) {
      int sp_offset = cpu_reg_save_offsets[i];
      oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
                                r->as_VMReg());
    }
  }

  if (save_fpu_registers) {
    for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
      FloatRegister r = as_FloatRegister(i);
      int sp_offset = fpu_reg_save_offsets[i];
      oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
                                r->as_VMReg());
    }
  }
  return oop_map;
}
Exemple #3
0
// Reg2 unused.
LIR_Opr LIR_OprFact::double_fpu(int reg1, int reg2) {
  assert(as_FloatRegister(reg2) == fnoreg, "Not used on this platform");
  return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) |
                             (reg1 << LIR_OprDesc::reg2_shift) |
                             LIR_OprDesc::double_type          |
                             LIR_OprDesc::fpu_register         |
                             LIR_OprDesc::double_size);
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_double()
{
  const Address src(from(), -(offset() + 1) * wordSize);

#ifdef _WIN64
  if (_num_args < Argument::n_float_register_parameters-1) {
    __ movlpd(as_FloatRegister(++_num_args), src);
  } else {
    __ movq(rax, src);
    __ movq(Address(to(), _stack_offset), rax);
    _stack_offset += wordSize;
  }
#else
  if (_num_fp_args < 8) {
    __ movlpd(as_FloatRegister(_num_fp_args++), src);
  } else {
    __ movq(rax, src);
    __ movq(Address(to(), _stack_offset), rax);
    _stack_offset += wordSize;
  }
#endif
}
Exemple #5
0
static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
  for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
    Register r = as_Register(i);
    if (r == G1 || r == G3 || r == G4 || r == G5) {
      __ ld_ptr(SP, (cpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
    }
  }

  if (restore_fpu_registers) {
    for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
      FloatRegister r = as_FloatRegister(i);
      __ ldf(FloatRegisterImpl::S, SP, (fpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
    }
  }
}
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
  // JVMCI Registers are numbered as follows:
  //   0..31: Thirty-two General Purpose registers (CPU Registers)
  //   32..63: Thirty-two single precision float registers
  //   64..95: Thirty-two double precision float registers
  //   96..111: Sixteen quad precision float registers
  if (jvmci_reg < 32) {
    return as_Register(jvmci_reg)->as_VMReg();
  } else {
    jint floatRegisterNumber;
    if(jvmci_reg < 64) { // Single precision
      floatRegisterNumber = jvmci_reg - 32;
    } else if(jvmci_reg < 96) {
      floatRegisterNumber = 2 * (jvmci_reg - 64);
    } else if(jvmci_reg < 112) {
      floatRegisterNumber = 4 * (jvmci_reg - 96);
    } else {
      JVMCI_ERROR_NULL("invalid register number: %d", jvmci_reg);
    }
    return as_FloatRegister(floatRegisterNumber)->as_VMReg();
  }
}
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
  address entry = __ pc();

  __ andr(esp, esp, -16);
  __ mov(c_rarg3, esp);
  // rmethod
  // rlocals
  // c_rarg3: first stack arg - wordSize

  // adjust sp
  __ sub(sp, c_rarg3, 18 * wordSize);
  __ str(lr, Address(__ pre(sp, -2 * wordSize)));
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address,
                              InterpreterRuntime::slow_signature_handler),
             rmethod, rlocals, c_rarg3);

  // r0: result handler

  // Stack layout:
  // rsp: return address           <- sp
  //      1 garbage
  //      8 integer args (if static first is unused)
  //      1 float/double identifiers
  //      8 double args
  //        stack args              <- esp
  //        garbage
  //        expression stack bottom
  //        bcp (NULL)
  //        ...

  // Restore LR
  __ ldr(lr, Address(__ post(sp, 2 * wordSize)));

  // Do FP first so we can use c_rarg3 as temp
  __ ldrw(c_rarg3, Address(sp, 9 * wordSize)); // float/double identifiers

  for (int i = 0; i < Argument::n_float_register_parameters_c; i++) {
    const FloatRegister r = as_FloatRegister(i);

    Label d, done;

    __ tbnz(c_rarg3, i, d);
    __ ldrs(r, Address(sp, (10 + i) * wordSize));
    __ b(done);
    __ bind(d);
    __ ldrd(r, Address(sp, (10 + i) * wordSize));
    __ bind(done);
  }

  // c_rarg0 contains the result from the call of
  // InterpreterRuntime::slow_signature_handler so we don't touch it
  // here.  It will be loaded with the JNIEnv* later.
  __ ldr(c_rarg1, Address(sp, 1 * wordSize));
  for (int i = c_rarg2->encoding(); i <= c_rarg7->encoding(); i += 2) {
    Register rm = as_Register(i), rn = as_Register(i+1);
    __ ldp(rm, rn, Address(sp, i * wordSize));
  }

  __ add(sp, sp, 18 * wordSize);
  __ ret(lr);

  return entry;
}
 // derived registers, offsets, and addresses
 FloatRegister successor() const
 {
   return as_FloatRegister(encoding() + 1);
 }
void InterpreterRuntime::SignatureHandlerGenerator::pass_prev(int slot_offset) {
  Argument      jni_arg(_prev_jni_offset);
  Argument::Sig sig = _prev_sig;

  if (sig == Argument::no_sig) {
    return;
  }

  slot_offset += BytesPerWord;

  if (Argument::is_integral(sig)) {
    // Integral argument

    // Load either the output register or a very-local temp from the java stack
    // Bump java stack offset address if requested.
    const Register tmp = jni_arg.is_register() ? jni_arg.as_register() : GR2_SCRATCH;

    if (slot_offset == 0) {
      __ ld8(tmp, GR_I0);
    } else {
      __ ld8(tmp, GR_I0, -slot_offset);
    }

    if (Argument::is_4byte(sig)) {
      __ sxt4(tmp, tmp);
    }

    if (Argument::is_obj(sig)) {
      // Object, box if not null
      const PredicateRegister box = PR15_SCRATCH;

      __ cmp(box, PR0, 0, tmp, Assembler::notEqual);
      __ add(box, tmp, GR_I0, slot_offset);
    }

    if (!jni_arg.is_register()) {
      // Store into native memory parameter list
      __ add(GR3_SCRATCH, SP, jni_arg.jni_offset_in_frame());
      __ st8(GR3_SCRATCH, tmp);
    }

  } else {
    // Floating point argument
    const FloatRegister tmp = jni_arg.is_register() ? as_FloatRegister(FR_I0->encoding() + _prev_float_reg_offset) : FR6;

    if (jni_arg.is_register()) {
      if (Argument::is_4byte(sig)) {
	// Single precision float
	if (slot_offset == 0) {
	  __ ldfs(tmp, GR_I0);
	} else {
	  __ ldfs(tmp, GR_I0, -slot_offset);
	}
      } else {
	// Double precision float
	if (slot_offset == 0) {
	  __ ldfd(tmp, GR_I0);
	} else {
	  __ ldfd(tmp, GR_I0, -slot_offset);
	}
      }
    } else {
      if (slot_offset == 0) {
	__ ld8(GR2_SCRATCH, GR_I0);
      } else {
	__ ld8(GR2_SCRATCH, GR_I0, -slot_offset);
      }
      __ add(GR3_SCRATCH, SP, jni_arg.jni_offset_in_frame());
      __ st8(GR3_SCRATCH, GR2_SCRATCH);
    }
  }
}
Exemple #10
0
VMReg FrameMap::fpu_regname (int n) {
  // Return the OptoReg name for the fpu stack slot "n"
  // A spilled fpu stack slot comprises to two single-word OptoReg's.
  return as_FloatRegister(n)->as_VMReg();
}