1 /*
2 * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2014, Red Hat Inc. All rights reserved.
4 * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 */
26
27 #ifndef CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP
28 #define CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP
29
30 // ArrayCopyStub needs access to bailout
31 friend class ArrayCopyStub;
32
33 private:
34
35 #include "c1_LIRAssembler_arith_riscv.hpp"
36 #include "c1_LIRAssembler_arraycopy_riscv.hpp"
37
38 int array_element_size(BasicType type) const;
39
40 static Register as_reg(LIR_Opr op) {
41 return op->is_double_cpu() ? op->as_register_lo() : op->as_register();
42 }
43
44 Address as_Address(LIR_Address* addr, Register tmp);
45
46 // helper functions which checks for overflow and sets bailout if it
47 // occurs. Always returns a valid embeddable pointer but in the
48 // bailout case the pointer won't be to unique storage.
49 address float_constant(float f);
50 address double_constant(double d);
51 address int_constant(jlong n);
52
53 // Ensure we have a valid Address (base + offset) to a stack-slot.
54 Address stack_slot_address(int index, uint shift, int adjust = 0);
55
56 // Record the type of the receiver in ReceiverTypeData
57 void type_profile_helper(Register mdo, ciMethodData *md,
58 ciProfileData *data, Register recv);
59
60 void casw(Register addr, Register newval, Register cmpval);
61 void caswu(Register addr, Register newval, Register cmpval);
62 void casl(Register addr, Register newval, Register cmpval);
63
64 void deoptimize_trap(CodeEmitInfo *info);
65
66 enum {
67 // call stub: CompiledDirectCall::to_interp_stub_size() +
68 // CompiledDirectCall::to_trampoline_stub_size()
69 _call_stub_size = 11 * MacroAssembler::instruction_size +
70 1 * MacroAssembler::instruction_size + wordSize,
71 // See emit_exception_handler for detail
72 _exception_handler_size = DEBUG_ONLY(256) NOT_DEBUG(32), // or smaller
73 // See emit_deopt_handler for detail
74 // far_call (2) + j (1)
75 _deopt_handler_size = 1 * MacroAssembler::instruction_size +
76 2 * MacroAssembler::instruction_size
77 };
78
79 void check_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp,
80 Label &next, Label &none, Address mdo_addr);
81 void check_no_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp, Address mdo_addr, Label &next);
82
83 void check_exact_klass(Register tmp, ciKlass* exact_klass);
84
85 void check_null(Register tmp, Label &update, intptr_t current_klass, Address mdo_addr, bool do_update, Label &next);
86
87 void (MacroAssembler::*add)(Register prev, RegisterOrConstant incr, Register addr);
88 void (MacroAssembler::*xchg)(Register prev, Register newv, Register addr);
89
90 void get_op(BasicType type);
91
92 // emit_typecheck_helper sub functions
93 void data_check(LIR_OpTypeCheck *op, ciMethodData **md, ciProfileData **data);
94 void typecheck_helper_slowcheck(ciKlass* k, Register obj, Register Rtmp1,
95 Register k_RInfo, Register klass_RInfo,
96 Label* failure_target, Label* success_target);
97 void profile_object(ciMethodData* md, ciProfileData* data, Register obj,
98 Register k_RInfo, Register klass_RInfo, Label* obj_is_null);
99 void typecheck_loaded(LIR_OpTypeCheck* op, ciKlass* k, Register k_RInfo);
100
101 // emit_opTypeCheck sub functions
102 void typecheck_lir_store(LIR_OpTypeCheck* op, bool should_profile);
103
104 void lir_store_slowcheck(Register k_RInfo, Register klass_RInfo, Register Rtmp1,
105 Label* success_target, Label* failure_target);
106
107 void const2reg_helper(LIR_Opr src);
108
109 void emit_branch(LIR_Condition cmp_flag, LIR_Opr cmp1, LIR_Opr cmp2, Label& label, bool is_far, bool is_unordered);
110
111 void logic_op_reg32(Register dst, Register left, Register right, LIR_Code code);
112 void logic_op_reg(Register dst, Register left, Register right, LIR_Code code);
113 void logic_op_imm(Register dst, Register left, int right, LIR_Code code);
114
115 public:
116
117 void emit_cmove(LIR_Op4* op);
118
119 void store_parameter(Register r, int offset_from_rsp_in_words);
120 void store_parameter(jint c, int offset_from_rsp_in_words);
121
122 #endif // CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP