blob: 73fceea38051e70cf4c799704e38175b2084c2c4 [file] [edit]
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP
#define CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP
// C2_MacroAssembler contains high-level macros for C2
private:
// Return true if the phase output is in the scratch emit size mode.
virtual bool in_scratch_emit_size() override;
void element_compare(Register r1, Register r2,
Register result, Register cnt,
Register tmp1, Register tmp2,
VectorRegister vr1, VectorRegister vr2,
VectorRegister vrs,
bool is_latin, Label& DONE, Assembler::LMUL lmul);
void string_compare_long_same_encoding(Register result, Register str1, Register str2,
const bool isLL, Register cnt1, Register cnt2,
Register tmp1, Register tmp2, Register tmp3,
const int STUB_THRESHOLD, Label *STUB, Label *SHORT_STRING, Label *DONE);
void string_compare_long_different_encoding(Register result, Register str1, Register str2,
bool isLU, Register cnt1, Register cnt2,
Register tmp1, Register tmp2, Register tmp3,
const int STUB_THRESHOLD, Label *STUB, Label *DONE);
public:
// Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file.
void fast_lock(Register object, Register box,
Register tmp1, Register tmp2, Register tmp3, Register tmp4);
void fast_unlock(Register object, Register box, Register tmp1, Register tmp2);
// Code used by cmpFastLockLightweight and cmpFastUnlockLightweight mach instructions in .ad file.
void fast_lock_lightweight(Register object, Register box,
Register tmp1, Register tmp2, Register tmp3, Register tmp4);
void fast_unlock_lightweight(Register object, Register box,
Register tmp1, Register tmp2, Register tmp3);
void string_compare(Register str1, Register str2,
Register cnt1, Register cnt2, Register result,
Register tmp1, Register tmp2, Register tmp3,
int ae);
void string_indexof_char_short(Register str1, Register cnt1,
Register ch, Register result,
bool isL);
void string_indexof_char(Register str1, Register cnt1,
Register ch, Register result,
Register tmp1, Register tmp2,
Register tmp3, Register tmp4,
bool isL);
void string_indexof(Register str1, Register str2,
Register cnt1, Register cnt2,
Register tmp1, Register tmp2,
Register tmp3, Register tmp4,
Register tmp5, Register tmp6,
Register result, int ae);
void string_indexof_linearscan(Register haystack, Register needle,
Register haystack_len, Register needle_len,
Register tmp1, Register tmp2,
Register tmp3, Register tmp4,
int needle_con_cnt, Register result, int ae);
void arrays_equals(Register r1, Register r2,
Register tmp1, Register tmp2, Register tmp3,
Register result, int elem_size);
void arrays_hashcode(Register ary, Register cnt, Register result,
Register tmp1, Register tmp2,
Register tmp3, Register tmp4,
Register tmp5, Register tmp6,
BasicType eltype);
// helper function for arrays_hashcode
int arrays_hashcode_elsize(BasicType eltype);
void arrays_hashcode_elload(Register dst, Address src, BasicType eltype);
void string_equals(Register r1, Register r2,
Register result, Register cnt1);
// refer to conditional_branches and float_conditional_branches
static const int bool_test_bits = 3;
static const int unsigned_branch_mask = 1 << bool_test_bits;
static const int double_branch_mask = 1 << bool_test_bits;
// cmp
void cmp_branch(int cmpFlag,
Register op1, Register op2,
Label& label, bool is_far = false);
void float_cmp_branch(int cmpFlag,
FloatRegister op1, FloatRegister op2,
Label& label, bool is_far = false);
void enc_cmpUEqNeLeGt_imm0_branch(int cmpFlag, Register op,
Label& L, bool is_far = false);
void enc_cmpEqNe_imm0_branch(int cmpFlag, Register op,
Label& L, bool is_far = false);
void enc_cmove(int cmpFlag,
Register op1, Register op2,
Register dst, Register src);
void enc_cmove_cmp_fp(int cmpFlag,
FloatRegister op1, FloatRegister op2,
Register dst, Register src, bool is_single);
void spill(Register r, bool is64, int offset) {
is64 ? sd(r, Address(sp, offset))
: sw(r, Address(sp, offset));
}
void spill(FloatRegister f, bool is64, int offset) {
is64 ? fsd(f, Address(sp, offset))
: fsw(f, Address(sp, offset));
}
void spill(VectorRegister v, int offset) {
add(t0, sp, offset);
vs1r_v(v, t0);
}
void unspill(Register r, bool is64, int offset) {
is64 ? ld(r, Address(sp, offset))
: lw(r, Address(sp, offset));
}
void unspillu(Register r, bool is64, int offset) {
is64 ? ld(r, Address(sp, offset))
: lwu(r, Address(sp, offset));
}
void unspill(FloatRegister f, bool is64, int offset) {
is64 ? fld(f, Address(sp, offset))
: flw(f, Address(sp, offset));
}
void unspill(VectorRegister v, int offset) {
add(t0, sp, offset);
vl1r_v(v, t0);
}
void spill_copy_vector_stack_to_stack(int src_offset, int dst_offset, uint vector_length_in_bytes) {
assert(vector_length_in_bytes % 16 == 0, "unexpected vector reg size");
for (int i = 0; i < (int)vector_length_in_bytes / 8; i++) {
unspill(t0, true, src_offset + (i * 8));
spill(t0, true, dst_offset + (i * 8));
}
}
enum class FLOAT_TYPE {
half_precision,
single_precision,
double_precision
};
void minmax_fp(FloatRegister dst,
FloatRegister src1, FloatRegister src2,
FLOAT_TYPE ft, bool is_min);
void round_double_mode(FloatRegister dst, FloatRegister src, int round_mode,
Register tmp1, Register tmp2, Register tmp3);
void signum_fp(FloatRegister dst, FloatRegister one, bool is_double);
void float16_to_float(FloatRegister dst, Register src, Register tmp);
void float_to_float16(Register dst, FloatRegister src, FloatRegister ftmp, Register xtmp);
void signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen);
// intrinsic methods implemented by rvv instructions
void java_round_float_v(VectorRegister dst, VectorRegister src, FloatRegister ftmp, BasicType bt, uint vector_length);
void java_round_double_v(VectorRegister dst, VectorRegister src, FloatRegister ftmp, BasicType bt, uint vector_length);
void float16_to_float_v(VectorRegister dst, VectorRegister src, uint vector_length);
void float_to_float16_v(VectorRegister dst, VectorRegister src, VectorRegister vtmp, Register tmp, uint vector_length);
void string_equals_v(Register r1, Register r2,
Register result, Register cnt1);
void arrays_equals_v(Register r1, Register r2,
Register result, Register cnt1,
int elem_size);
void string_compare_v(Register str1, Register str2,
Register cnt1, Register cnt2,
Register result,
Register tmp1, Register tmp2,
int encForm);
void clear_array_v(Register base, Register cnt);
void byte_array_inflate_v(Register src, Register dst,
Register len, Register tmp);
void char_array_compress_v(Register src, Register dst,
Register len, Register result,
Register tmp);
void encode_iso_array_v(Register src, Register dst,
Register len, Register result,
Register tmp, bool ascii);
void count_positives_v(Register ary, Register len,
Register result, Register tmp);
void string_indexof_char_v(Register str1, Register cnt1,
Register ch, Register result,
Register tmp1, Register tmp2,
bool isL);
void minmax_fp_v(VectorRegister dst,
VectorRegister src1, VectorRegister src2,
BasicType bt, bool is_min, uint vector_length);
void minmax_fp_masked_v(VectorRegister dst, VectorRegister src1, VectorRegister src2,
VectorRegister vmask, VectorRegister tmp1, VectorRegister tmp2,
BasicType bt, bool is_min, uint vector_length);
void reduce_minmax_fp_v(FloatRegister dst,
FloatRegister src1, VectorRegister src2,
VectorRegister tmp1, VectorRegister tmp2,
bool is_double, bool is_min, uint vector_length,
VectorMask vm = Assembler::unmasked);
void reduce_integral_v(Register dst, Register src1,
VectorRegister src2, VectorRegister tmp,
int opc, BasicType bt, uint vector_length,
VectorMask vm = Assembler::unmasked);
void reduce_mul_integral_v(Register dst, Register src1, VectorRegister src2,
VectorRegister vtmp1, VectorRegister vtmp2, BasicType bt,
uint vector_length, VectorMask vm = Assembler::unmasked);
void vsetvli_helper(BasicType bt, uint vector_length, LMUL vlmul = Assembler::m1, Register tmp = t0);
void compare_integral_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, int cond,
BasicType bt, uint vector_length, VectorMask vm = Assembler::unmasked);
void compare_fp_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, int cond,
BasicType bt, uint vector_length, VectorMask vm = Assembler::unmasked);
void spill_vmask(VectorRegister v, int offset);
void unspill_vmask(VectorRegister v, int offset);
void spill_copy_vmask_stack_to_stack(int src_offset, int dst_offset, uint vector_length_in_bytes) {
assert(vector_length_in_bytes % 4 == 0, "unexpected vector mask reg size");
for (int i = 0; i < (int)vector_length_in_bytes / 4; i++) {
unspill(t0, false, src_offset + (i * 4));
spill(t0, false, dst_offset + (i * 4));
}
}
void integer_extend_v(VectorRegister dst, BasicType dst_bt, uint vector_length,
VectorRegister src, BasicType src_bt, bool is_signed);
void integer_narrow_v(VectorRegister dst, BasicType dst_bt, uint vector_length,
VectorRegister src, BasicType src_bt);
void vfcvt_rtz_x_f_v_safe(VectorRegister dst, VectorRegister src);
void extract_v(Register dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp);
void extract_fp_v(FloatRegister dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp);
#endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP