1 /*
  2  * Copyright (c) 2000, 2019, 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,
 58                            ciMethodData *md, ciProfileData *data,
 59                            Register recv, Label* update_done);
 60 
 61   void casw(Register addr, Register newval, Register cmpval);
 62   void caswu(Register addr, Register newval, Register cmpval);
 63   void casl(Register addr, Register newval, Register cmpval);
 64 
 65   void poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info = NULL);
 66 
 67   void deoptimize_trap(CodeEmitInfo *info);
 68 
 69   enum {
 70     // See emit_static_call_stub for detail
 71     // CompiledStaticCall::to_interp_stub_size() (14) + CompiledStaticCall::to_trampoline_stub_size() (1 + 3 + address)
 72     _call_stub_size = 14 * NativeInstruction::instruction_size +
 73                       (NativeInstruction::instruction_size + NativeCallTrampolineStub::instruction_size),
 74     // See emit_exception_handler for detail
 75     // verify_not_null_oop + far_call + should_not_reach_here + invalidate_registers(DEBUG_ONLY)
 76     _exception_handler_size = DEBUG_ONLY(584) NOT_DEBUG(548), // or smaller
 77     // See emit_deopt_handler for detail
 78     // auipc (1) + far_jump (6 or 2)
 79     _deopt_handler_size = 1 * NativeInstruction::instruction_size +
 80                           6 * NativeInstruction::instruction_size // or smaller
 81   };
 82 
 83   void check_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp,
 84                       Label &next, Label &none, Address mdo_addr);
 85   void check_no_conflict(ciKlass* exact_klass, intptr_t current_klass, Register tmp, Address mdo_addr, Label &next);
 86 
 87   void check_exact_klass(Register tmp, ciKlass* exact_klass);
 88 
 89   void check_null(Register tmp, Label &update, intptr_t current_klass, Address mdo_addr, bool do_update, Label &next);
 90 
 91   void (MacroAssembler::*add)(Register prev, RegisterOrConstant incr, Register addr);
 92   void (MacroAssembler::*xchg)(Register prev, Register newv, Register addr);
 93 
 94   void get_op(BasicType type);
 95 
 96   // emit_typecheck_helper sub functions
 97   void data_check(LIR_OpTypeCheck *op, ciMethodData **md, ciProfileData **data);
 98   void typecheck_helper_slowcheck(ciKlass* k, Register obj, Register Rtmp1,
 99                                   Register k_RInfo, Register klass_RInfo,
100                                   Label* failure_target, Label* success_target);
101   void profile_object(ciMethodData* md, ciProfileData* data, Register obj,
102                       Register klass_RInfo, Label* obj_is_null);
103   void typecheck_loaded(LIR_OpTypeCheck* op, ciKlass* k, Register k_RInfo);
104 
105   // emit_opTypeCheck sub functions
106   void typecheck_lir_store(LIR_OpTypeCheck* op, bool should_profile);
107 
108   void type_profile(Register obj, ciMethodData* md, Register klass_RInfo, Register k_RInfo,
109                     ciProfileData* data, Label* success, Label* failure,
110                     Label& profile_cast_success, Label& profile_cast_failure);
111 
112   void lir_store_slowcheck(Register k_RInfo, Register klass_RInfo, Register Rtmp1,
113                            Label* success_target, Label* failure_target);
114 
115   void const2reg_helper(LIR_Opr src);
116 
117   void emit_branch(LIR_Condition cmp_flag, LIR_Opr cmp1, LIR_Opr cmp2, Label& label, bool is_far, bool is_unordered);
118 
119   void logic_op_reg32(Register dst, Register left, Register right, LIR_Code code);
120   void logic_op_reg(Register dst, Register left, Register right, LIR_Code code);
121   void logic_op_imm(Register dst, Register left, int right, LIR_Code code);
122 
123 public:
124 
125   void emit_cmove(LIR_Op4* op);
126 
127   void store_parameter(Register r, int offset_from_rsp_in_words);
128   void store_parameter(jint c, int offset_from_rsp_in_words);
129 
130 #endif // CPU_RISCV_C1_LIRASSEMBLER_RISCV_HPP