1 /*
  2  * Copyright (c) 2000, 2026, 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   void move(LIR_Opr src, LIR_Opr dst);
116 public:
117 
118   void emit_cmove(LIR_Op4* op);
119 
120   void store_parameter(Register r, int offset_from_rsp_in_words);
121   void store_parameter(jint c, int offset_from_rsp_in_words);
122 
123 #endif // CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP