Skip to content

Commit

Permalink
8294100: RISC-V: Move rt_call and xxx_move from SharedRuntime to Macr…
Browse files Browse the repository at this point in the history
…oAssembler

Reviewed-by: shade, fyang
  • Loading branch information
feilongjiang authored and RealFYang committed Sep 22, 2022
1 parent 2283c32 commit 742bc04
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 212 deletions.
203 changes: 203 additions & 0 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3957,3 +3957,206 @@ void MacroAssembler::cmp_l2i(Register dst, Register src1, Register src2, Registe
neg(dst, dst);
bind(done);
}

// The java_calling_convention describes stack locations as ideal slots on
// a frame with no abi restrictions. Since we must observe abi restrictions
// (like the placement of the register window) the slots must be biased by
// the following value.
static int reg2offset_in(VMReg r) {
// Account for saved fp and ra
// This should really be in_preserve_stack_slots
return r->reg2stack() * VMRegImpl::stack_slot_size;
}

static int reg2offset_out(VMReg r) {
return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
}

// On 64 bit we will store integer like items to the stack as
// 64 bits items (riscv64 abi) even though java would only store
// 32bits for a parameter. On 32bit it will simply be 32 bits
// So this routine will do 32->32 on 32bit and 32->64 on 64bit
void MacroAssembler::move32_64(VMRegPair src, VMRegPair dst, Register tmp) {
if (src.first()->is_stack()) {
if (dst.first()->is_stack()) {
// stack to stack
ld(tmp, Address(fp, reg2offset_in(src.first())));
sd(tmp, Address(sp, reg2offset_out(dst.first())));
} else {
// stack to reg
lw(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first())));
}
} else if (dst.first()->is_stack()) {
// reg to stack
sd(src.first()->as_Register(), Address(sp, reg2offset_out(dst.first())));
} else {
if (dst.first() != src.first()) {
// 32bits extend sign
addw(dst.first()->as_Register(), src.first()->as_Register(), zr);
}
}
}

// An oop arg. Must pass a handle not the oop itself
void MacroAssembler::object_move(OopMap* map,
int oop_handle_offset,
int framesize_in_slots,
VMRegPair src,
VMRegPair dst,
bool is_receiver,
int* receiver_offset) {
assert_cond(map != NULL && receiver_offset != NULL);
// must pass a handle. First figure out the location we use as a handle
Register rHandle = dst.first()->is_stack() ? t1 : dst.first()->as_Register();

// See if oop is NULL if it is we need no handle

if (src.first()->is_stack()) {
// Oop is already on the stack as an argument
int offset_in_older_frame = src.first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots));
if (is_receiver) {
*receiver_offset = (offset_in_older_frame + framesize_in_slots) * VMRegImpl::stack_slot_size;
}

ld(t0, Address(fp, reg2offset_in(src.first())));
la(rHandle, Address(fp, reg2offset_in(src.first())));
// conditionally move a NULL
Label notZero1;
bnez(t0, notZero1);
mv(rHandle, zr);
bind(notZero1);
} else {

// Oop is in a register we must store it to the space we reserve
// on the stack for oop_handles and pass a handle if oop is non-NULL

const Register rOop = src.first()->as_Register();
int oop_slot = -1;
if (rOop == j_rarg0) {
oop_slot = 0;
} else if (rOop == j_rarg1) {
oop_slot = 1;
} else if (rOop == j_rarg2) {
oop_slot = 2;
} else if (rOop == j_rarg3) {
oop_slot = 3;
} else if (rOop == j_rarg4) {
oop_slot = 4;
} else if (rOop == j_rarg5) {
oop_slot = 5;
} else if (rOop == j_rarg6) {
oop_slot = 6;
} else {
assert(rOop == j_rarg7, "wrong register");
oop_slot = 7;
}

oop_slot = oop_slot * VMRegImpl::slots_per_word + oop_handle_offset;
int offset = oop_slot * VMRegImpl::stack_slot_size;

map->set_oop(VMRegImpl::stack2reg(oop_slot));
// Store oop in handle area, may be NULL
sd(rOop, Address(sp, offset));
if (is_receiver) {
*receiver_offset = offset;
}

//rOop maybe the same as rHandle
if (rOop == rHandle) {
Label isZero;
beqz(rOop, isZero);
la(rHandle, Address(sp, offset));
bind(isZero);
} else {
Label notZero2;
la(rHandle, Address(sp, offset));
bnez(rOop, notZero2);
mv(rHandle, zr);
bind(notZero2);
}
}

// If arg is on the stack then place it otherwise it is already in correct reg.
if (dst.first()->is_stack()) {
sd(rHandle, Address(sp, reg2offset_out(dst.first())));
}
}

// A float arg may have to do float reg int reg conversion
void MacroAssembler::float_move(VMRegPair src, VMRegPair dst, Register tmp) {
assert(src.first()->is_stack() && dst.first()->is_stack() ||
src.first()->is_reg() && dst.first()->is_reg() ||
src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
if (src.first()->is_stack()) {
if (dst.first()->is_stack()) {
lwu(tmp, Address(fp, reg2offset_in(src.first())));
sw(tmp, Address(sp, reg2offset_out(dst.first())));
} else if (dst.first()->is_Register()) {
lwu(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first())));
} else {
ShouldNotReachHere();
}
} else if (src.first() != dst.first()) {
if (src.is_single_phys_reg() && dst.is_single_phys_reg()) {
fmv_s(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
} else {
ShouldNotReachHere();
}
}
}

// A long move
void MacroAssembler::long_move(VMRegPair src, VMRegPair dst, Register tmp) {
if (src.first()->is_stack()) {
if (dst.first()->is_stack()) {
// stack to stack
ld(tmp, Address(fp, reg2offset_in(src.first())));
sd(tmp, Address(sp, reg2offset_out(dst.first())));
} else {
// stack to reg
ld(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first())));
}
} else if (dst.first()->is_stack()) {
// reg to stack
sd(src.first()->as_Register(), Address(sp, reg2offset_out(dst.first())));
} else {
if (dst.first() != src.first()) {
mv(dst.first()->as_Register(), src.first()->as_Register());
}
}
}

// A double move
void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) {
assert(src.first()->is_stack() && dst.first()->is_stack() ||
src.first()->is_reg() && dst.first()->is_reg() ||
src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
if (src.first()->is_stack()) {
if (dst.first()->is_stack()) {
ld(tmp, Address(fp, reg2offset_in(src.first())));
sd(tmp, Address(sp, reg2offset_out(dst.first())));
} else if (dst.first()-> is_Register()) {
ld(dst.first()->as_Register(), Address(fp, reg2offset_in(src.first())));
} else {
ShouldNotReachHere();
}
} else if (src.first() != dst.first()) {
if (src.is_single_phys_reg() && dst.is_single_phys_reg()) {
fmv_d(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
} else {
ShouldNotReachHere();
}
}
}

void MacroAssembler::rt_call(address dest, Register tmp) {
CodeBlob *cb = CodeCache::find_blob(dest);
if (cb) {
far_call(RuntimeAddress(dest));
} else {
int32_t offset = 0;
la_patchable(tmp, RuntimeAddress(dest), offset);
jalr(x1, tmp, offset);
}
}
17 changes: 17 additions & 0 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define CPU_RISCV_MACROASSEMBLER_RISCV_HPP

#include "asm/assembler.hpp"
#include "code/vmreg.hpp"
#include "metaprogramming/enableIf.hpp"
#include "oops/compressedOops.hpp"
#include "utilities/powerOfTwo.hpp"
Expand Down Expand Up @@ -869,6 +870,22 @@ class MacroAssembler: public Assembler {
void vncvt_x_x_w(VectorRegister vd, VectorRegister vs, VectorMask vm = unmasked);
void vfneg_v(VectorRegister vd, VectorRegister vs);


// support for argument shuffling
void move32_64(VMRegPair src, VMRegPair dst, Register tmp = t0);
void float_move(VMRegPair src, VMRegPair dst, Register tmp = t0);
void long_move(VMRegPair src, VMRegPair dst, Register tmp = t0);
void double_move(VMRegPair src, VMRegPair dst, Register tmp = t0);
void object_move(OopMap* map,
int oop_handle_offset,
int framesize_in_slots,
VMRegPair src,
VMRegPair dst,
bool is_receiver,
int* receiver_offset);

void rt_call(address dest, Register tmp = t0);

private:

#ifdef ASSERT
Expand Down

1 comment on commit 742bc04

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.