< prev index next >

src/hotspot/cpu/riscv/riscv.ad

Print this page

 1211 {
 1212   return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr
 1213 }
 1214 
 1215 int MachCallDynamicJavaNode::ret_addr_offset()
 1216 {
 1217   return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal
 1218 }
 1219 
 1220 int MachCallRuntimeNode::ret_addr_offset() {
 1221   // For address inside the code cache the call will be:
 1222   //   auipc + jalr
 1223   // For real runtime callouts it will be 8 instructions
 1224   // see riscv_enc_java_to_runtime
 1225   //   la(t0, retaddr)                                             ->  auipc + addi
 1226   //   sd(t0, Address(xthread, JavaThread::last_Java_pc_offset())) ->  sd
 1227   //   movptr(t1, addr, offset, t0)                                ->  lui + lui + slli + add
 1228   //   jalr(t1, offset)                                            ->  jalr
 1229   if (CodeCache::contains(_entry_point)) {
 1230     return 2 * NativeInstruction::instruction_size;



 1231   } else {
 1232     return 8 * NativeInstruction::instruction_size;
 1233   }
 1234 }
 1235 
 1236 //
 1237 // Compute padding required for nodes which need alignment
 1238 //
 1239 
 1240 // With RVC a call instruction may get 2-byte aligned.
 1241 // The address of the call instruction needs to be 4-byte aligned to
 1242 // ensure that it does not span a cache line so that it can be patched.
 1243 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
 1244 {
 1245   // to make sure the address of jal 4-byte aligned.
 1246   return align_up(current_offset, alignment_required()) - current_offset;
 1247 }
 1248 
 1249 // With RVC a call instruction may get 2-byte aligned.
 1250 // The address of the call instruction needs to be 4-byte aligned to

 1258   current_offset += NativeMovConstReg::movptr2_instruction_size;
 1259   // to make sure the address of jal 4-byte aligned.
 1260   return align_up(current_offset, alignment_required()) - current_offset;
 1261 }
 1262 
 1263 int CallRuntimeDirectNode::compute_padding(int current_offset) const
 1264 {
 1265   return align_up(current_offset, alignment_required()) - current_offset;
 1266 }
 1267 
 1268 int CallLeafDirectNode::compute_padding(int current_offset) const
 1269 {
 1270   return align_up(current_offset, alignment_required()) - current_offset;
 1271 }
 1272 
 1273 int CallLeafDirectVectorNode::compute_padding(int current_offset) const
 1274 {
 1275   return align_up(current_offset, alignment_required()) - current_offset;
 1276 }
 1277 





 1278 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const
 1279 {
 1280   return align_up(current_offset, alignment_required()) - current_offset;
 1281 }
 1282 
 1283 //=============================================================================
 1284 
 1285 #ifndef PRODUCT
 1286 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1287   assert_cond(st != nullptr);
 1288   st->print("BREAKPOINT");
 1289 }
 1290 #endif
 1291 
 1292 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1293   __ ebreak();
 1294 }
 1295 
 1296 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
 1297   return MachNode::size(ra_);

 1364     st->print("sd  t2, [sp, #%d]\n\t", framesize - 3 * wordSize);
 1365   }
 1366 
 1367   if (C->stub_function() == nullptr) {
 1368     st->print("ld  t0, [guard]\n\t");
 1369     st->print("membar LoadLoad\n\t");
 1370     st->print("ld  t1, [xthread, #thread_disarmed_guard_value_offset]\n\t");
 1371     st->print("beq t0, t1, skip\n\t");
 1372     st->print("jalr #nmethod_entry_barrier_stub\n\t");
 1373     st->print("j skip\n\t");
 1374     st->print("guard: int\n\t");
 1375     st->print("skip:\n\t");
 1376   }
 1377 }
 1378 #endif
 1379 
 1380 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1381   assert_cond(ra_ != nullptr);
 1382   Compile* C = ra_->C;
 1383 
 1384   // n.b. frame size includes space for return pc and fp
 1385   const int framesize = C->output()->frame_size_in_bytes();
 1386 
 1387   assert_cond(C != nullptr);
 1388 
 1389   if (C->clinit_barrier_on_entry()) {
 1390     assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
 1391 
 1392     Label L_skip_barrier;
 1393 
 1394     __ mov_metadata(t1, C->method()->holder()->constant_encoding());
 1395     __ clinit_barrier(t1, t0, &L_skip_barrier);
 1396     __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
 1397     __ bind(L_skip_barrier);
 1398   }
 1399 
 1400   int bangsize = C->output()->bang_size_in_bytes();
 1401   if (C->output()->need_stack_bang(bangsize)) {
 1402     __ generate_stack_overflow_check(bangsize);
 1403   }
 1404 
 1405   __ build_frame(framesize);
 1406 
 1407   if (VerifyStackAtCalls) {


 1408     __ mv(t2, MAJIK_DWORD);
 1409     __ sd(t2, Address(sp, framesize - 3 * wordSize));
 1410   }
 1411 
 1412   if (C->stub_function() == nullptr) {
 1413     BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
 1414     // Dummy labels for just measuring the code size
 1415     Label dummy_slow_path;
 1416     Label dummy_continuation;
 1417     Label dummy_guard;
 1418     Label* slow_path = &dummy_slow_path;
 1419     Label* continuation = &dummy_continuation;
 1420     Label* guard = &dummy_guard;
 1421     if (!Compile::current()->output()->in_scratch_emit_size()) {
 1422       // Use real labels from actual stub when not emitting code for purpose of measuring its size
 1423       C2EntryBarrierStub* stub = new (Compile::current()->comp_arena()) C2EntryBarrierStub();
 1424       Compile::current()->output()->add_stub(stub);
 1425       slow_path = &stub->entry();
 1426       continuation = &stub->continuation();
 1427       guard = &stub->guard();
 1428     }
 1429     // In the C2 code, we move the non-hot part of nmethod entry barriers out-of-line to a stub.
 1430     bs->nmethod_entry_barrier(masm, slow_path, continuation, guard);
 1431   }
 1432 
 1433   C->output()->set_frame_complete(__ offset());
 1434 
 1435   if (C->has_mach_constant_base_node()) {
 1436     // NOTE: We set the table base offset here because users might be
 1437     // emitted before MachConstantBaseNode.
 1438     ConstantTable& constant_table = C->output()->constant_table();
 1439     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
 1440   }
 1441 }
 1442 
 1443 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
 1444 {
 1445   assert_cond(ra_ != nullptr);
 1446   return MachNode::size(ra_); // too many variables; just compute it
 1447                               // the hard way
 1448 }
 1449 
 1450 int MachPrologNode::reloc() const
 1451 {
 1452   return 0;
 1453 }
 1454 
 1455 //=============================================================================
 1456 
 1457 #ifndef PRODUCT
 1458 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1459   assert_cond(st != nullptr && ra_ != nullptr);
 1460   Compile* C = ra_->C;
 1461   assert_cond(C != nullptr);
 1462   int framesize = C->output()->frame_size_in_bytes();
 1463 
 1464   st->print("# pop frame %d\n\t", framesize);
 1465 
 1466   if (framesize == 0) {
 1467     st->print("ld  ra, [sp,#%d]\n\t", (2 * wordSize));
 1468     st->print("ld  fp, [sp,#%d]\n\t", (3 * wordSize));
 1469     st->print("add sp, sp, #%d\n\t", (2 * wordSize));

 1489 
 1490   __ remove_frame(framesize);
 1491 
 1492   if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
 1493     __ reserved_stack_check();
 1494   }
 1495 
 1496   if (do_polling() && C->is_method_compilation()) {
 1497     Label dummy_label;
 1498     Label* code_stub = &dummy_label;
 1499     if (!C->output()->in_scratch_emit_size()) {
 1500       C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
 1501       C->output()->add_stub(stub);
 1502       code_stub = &stub->entry();
 1503     }
 1504     __ relocate(relocInfo::poll_return_type);
 1505     __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */);
 1506   }
 1507 }
 1508 
 1509 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
 1510   assert_cond(ra_ != nullptr);
 1511   // Variable size. Determine dynamically.
 1512   return MachNode::size(ra_);
 1513 }
 1514 
 1515 int MachEpilogNode::reloc() const {
 1516   // Return number of relocatable values contained in this instruction.
 1517   return 1; // 1 for polling page.
 1518 }
 1519 const Pipeline * MachEpilogNode::pipeline() const {
 1520   return MachNode::pipeline_class();
 1521 }
 1522 
 1523 //=============================================================================
 1524 
 1525 // Figure out which register class each belongs in: rc_int, rc_float or
 1526 // rc_stack.
 1527 enum RC { rc_bad, rc_int, rc_float, rc_vector, rc_stack };
 1528 
 1529 static enum RC rc_class(OptoReg::Name reg) {
 1530 
 1531   if (reg == OptoReg::Bad) {
 1532     return rc_bad;
 1533   }
 1534 

 1773     __ addi(as_Register(reg), sp, offset);
 1774   } else {
 1775     __ li32(t0, offset);
 1776     __ add(as_Register(reg), sp, t0);
 1777   }
 1778 }
 1779 
 1780 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
 1781   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
 1782   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 1783 
 1784   if (Assembler::is_simm12(offset)) {
 1785     return NativeInstruction::instruction_size;
 1786   } else {
 1787     return 3 * NativeInstruction::instruction_size; // lui + addiw + add;
 1788   }
 1789 }
 1790 
 1791 //=============================================================================
 1792 














 1793 #ifndef PRODUCT
 1794 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
 1795 {
 1796   assert_cond(st != nullptr);
 1797   st->print_cr("# MachUEPNode");
 1798   st->print_cr("\tlwu t1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
 1799   st->print_cr("\tlwu t2, [t0      + CompiledICData::speculated_klass_offset()]\t# compressed klass");
 1800   st->print_cr("\tbeq t1, t2, ic_hit");
 1801   st->print_cr("\tj, SharedRuntime::_ic_miss_stub\t # Inline cache check");
 1802   st->print_cr("\tic_hit:");
 1803 }
 1804 #endif
 1805 
 1806 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const
 1807 {
 1808   // This is the unverified entry point.
 1809   __ ic_check(CodeEntryAlignment);
 1810 
 1811   // ic_check() aligns to CodeEntryAlignment >= InteriorEntryAlignment(min 16) > NativeInstruction::instruction_size(4).
 1812   assert(((__ offset()) % CodeEntryAlignment) == 0, "Misaligned verified entry point");
 1813 }
 1814 
 1815 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
 1816 {
 1817   assert_cond(ra_ != nullptr);
 1818   return MachNode::size(ra_);
 1819 }
 1820 
 1821 // REQUIRED EMIT CODE
 1822 
 1823 //=============================================================================
 1824 
 1825 // Emit deopt handler code.
 1826 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
 1827 {
 1828   address base = __ start_a_stub(size_deopt_handler());
 1829   if (base == nullptr) {
 1830     ciEnv::current()->record_failure("CodeCache is full");
 1831     return 0;  // CodeBuffer::expand failed
 1832   }
 1833   int offset = __ offset();
 1834 
 1835   Label start;
 1836   __ bind(start);
 1837 
 1838   __ far_call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
 1839 
 1840   int entry_offset = __ offset();

 2665 
 2666 // Unsigned Integer Immediate:  6-bit int, greater than 32
 2667 operand uimmI6_ge32() %{
 2668   predicate(((unsigned int)(n->get_int()) < 64) && (n->get_int() >= 32));
 2669   match(ConI);
 2670   op_cost(0);
 2671   format %{ %}
 2672   interface(CONST_INTER);
 2673 %}
 2674 
 2675 operand immI_le_4()
 2676 %{
 2677   predicate(n->get_int() <= 4);
 2678   match(ConI);
 2679 
 2680   op_cost(0);
 2681   format %{ %}
 2682   interface(CONST_INTER);
 2683 %}
 2684 










 2685 operand immI_16()
 2686 %{
 2687   predicate(n->get_int() == 16);
 2688   match(ConI);
 2689   op_cost(0);
 2690   format %{ %}
 2691   interface(CONST_INTER);
 2692 %}
 2693 
 2694 operand immI_24()
 2695 %{
 2696   predicate(n->get_int() == 24);
 2697   match(ConI);
 2698   op_cost(0);
 2699   format %{ %}
 2700   interface(CONST_INTER);
 2701 %}
 2702 
 2703 operand immI_31()
 2704 %{

 8328   ins_pipe(pipe_serial);
 8329 %}
 8330 
 8331 instruct spin_wait() %{
 8332   predicate(UseZihintpause);
 8333   match(OnSpinWait);
 8334   ins_cost(CACHE_MISS_COST);
 8335 
 8336   format %{ "spin_wait" %}
 8337 
 8338   ins_encode %{
 8339     __ pause();
 8340   %}
 8341 
 8342   ins_pipe(pipe_serial);
 8343 %}
 8344 
 8345 // ============================================================================
 8346 // Cast Instructions (Java-level type cast)
 8347 




























 8348 instruct castX2P(iRegPNoSp dst, iRegL src) %{
 8349   match(Set dst (CastX2P src));
 8350 
 8351   ins_cost(ALU_COST);
 8352   format %{ "mv  $dst, $src\t# long -> ptr, #@castX2P" %}
 8353 
 8354   ins_encode %{
 8355     if ($dst$$reg != $src$$reg) {
 8356       __ mv(as_Register($dst$$reg), as_Register($src$$reg));
 8357     }
 8358   %}
 8359 
 8360   ins_pipe(ialu_reg);
 8361 %}
 8362 
 8363 instruct castP2X(iRegLNoSp dst, iRegP src) %{
 8364   match(Set dst (CastP2X src));
 8365 
 8366   ins_cost(ALU_COST);
 8367   format %{ "mv  $dst, $src\t# ptr -> long, #@castP2X" %}

10865 // Call Runtime Instruction without safepoint and with vector arguments
10866 
10867 instruct CallLeafDirectVector(method meth)
10868 %{
10869   match(CallLeafVector);
10870 
10871   effect(USE meth);
10872 
10873   ins_cost(BRANCH_COST);
10874 
10875   format %{ "CALL, runtime leaf vector $meth" %}
10876 
10877   ins_encode(riscv_enc_java_to_runtime(meth));
10878 
10879   ins_pipe(pipe_class_call);
10880   ins_alignment(4);
10881 %}
10882 
10883 // Call Runtime Instruction
10884 





















10885 instruct CallLeafNoFPDirect(method meth)
10886 %{


10887   match(CallLeafNoFP);
10888 
10889   effect(USE meth);
10890 
10891   ins_cost(BRANCH_COST);
10892 
10893   format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %}
10894 
10895   ins_encode(riscv_enc_java_to_runtime(meth));
10896 
10897   ins_pipe(pipe_class_call);
10898   ins_alignment(4);
10899 %}
10900 
10901 // ============================================================================
10902 // Partial Subtype Check
10903 //
10904 // superklass array for an instance of the superklass.  Set a hidden
10905 // internal cache on a hit (cache is checked with exposed code in
10906 // gen_subtype_check()).  Return zero for a hit.  The encoding

11196 
11197 
11198 instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
11199                               iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11200                               iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11201 %{
11202   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11203   predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
11204   effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result,
11205          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11206 
11207   format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
11208   ins_encode %{
11209     __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
11210                            $result$$Register, $tmp1$$Register, $tmp2$$Register,
11211                            $tmp3$$Register, $tmp4$$Register, true /* isL */);
11212   %}
11213   ins_pipe(pipe_class_memory);
11214 %}
11215 

11216 // clearing of an array
11217 instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegP_R30 tmp1,
11218                             iRegP_R31 tmp2, rFlagsReg cr, Universe dummy)


11219 %{
11220   // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11221   predicate(UseBlockZeroing || !UseRVV);
11222   match(Set dummy (ClearArray cnt base));
11223   effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11224 
11225   ins_cost(4 * DEFAULT_COST);
11226   format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %}
11227 
11228   ins_encode %{
11229     address tpc = __ zero_words($base$$Register, $cnt$$Register);
11230     if (tpc == nullptr) {
11231       ciEnv::current()->record_failure("CodeCache is full");
11232       return;
11233     }
11234   %}
11235 
11236   ins_pipe(pipe_class_memory);
11237 %}
11238 
11239 instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr)



















11240 %{
11241   predicate(!UseRVV && (uint64_t)n->in(2)->get_long()
11242             < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
11243   match(Set dummy (ClearArray cnt base));


11244   effect(USE_KILL base, KILL cr);
11245 
11246   ins_cost(4 * DEFAULT_COST);
11247   format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %}
11248 
11249   ins_encode %{
11250     __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
11251   %}
11252 
11253   ins_pipe(pipe_class_memory);
11254 %}
11255 
11256 instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
11257                         iRegI_R10 result, rFlagsReg cr)
11258 %{
11259   predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11260   match(Set result (StrEquals (Binary str1 str2) cnt));
11261   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
11262 
11263   format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %}

 1211 {
 1212   return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr
 1213 }
 1214 
 1215 int MachCallDynamicJavaNode::ret_addr_offset()
 1216 {
 1217   return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal
 1218 }
 1219 
 1220 int MachCallRuntimeNode::ret_addr_offset() {
 1221   // For address inside the code cache the call will be:
 1222   //   auipc + jalr
 1223   // For real runtime callouts it will be 8 instructions
 1224   // see riscv_enc_java_to_runtime
 1225   //   la(t0, retaddr)                                             ->  auipc + addi
 1226   //   sd(t0, Address(xthread, JavaThread::last_Java_pc_offset())) ->  sd
 1227   //   movptr(t1, addr, offset, t0)                                ->  lui + lui + slli + add
 1228   //   jalr(t1, offset)                                            ->  jalr
 1229   if (CodeCache::contains(_entry_point)) {
 1230     return 2 * NativeInstruction::instruction_size;
 1231   } else if (_entry_point == nullptr) {
 1232     // See CallLeafNoFPIndirect
 1233     return 1 * NativeInstruction::instruction_size;
 1234   } else {
 1235     return 8 * NativeInstruction::instruction_size;
 1236   }
 1237 }
 1238 
 1239 //
 1240 // Compute padding required for nodes which need alignment
 1241 //
 1242 
 1243 // With RVC a call instruction may get 2-byte aligned.
 1244 // The address of the call instruction needs to be 4-byte aligned to
 1245 // ensure that it does not span a cache line so that it can be patched.
 1246 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
 1247 {
 1248   // to make sure the address of jal 4-byte aligned.
 1249   return align_up(current_offset, alignment_required()) - current_offset;
 1250 }
 1251 
 1252 // With RVC a call instruction may get 2-byte aligned.
 1253 // The address of the call instruction needs to be 4-byte aligned to

 1261   current_offset += NativeMovConstReg::movptr2_instruction_size;
 1262   // to make sure the address of jal 4-byte aligned.
 1263   return align_up(current_offset, alignment_required()) - current_offset;
 1264 }
 1265 
 1266 int CallRuntimeDirectNode::compute_padding(int current_offset) const
 1267 {
 1268   return align_up(current_offset, alignment_required()) - current_offset;
 1269 }
 1270 
 1271 int CallLeafDirectNode::compute_padding(int current_offset) const
 1272 {
 1273   return align_up(current_offset, alignment_required()) - current_offset;
 1274 }
 1275 
 1276 int CallLeafDirectVectorNode::compute_padding(int current_offset) const
 1277 {
 1278   return align_up(current_offset, alignment_required()) - current_offset;
 1279 }
 1280 
 1281 int CallLeafNoFPIndirectNode::compute_padding(int current_offset) const
 1282 {
 1283   return align_up(current_offset, alignment_required()) - current_offset;
 1284 }
 1285 
 1286 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const
 1287 {
 1288   return align_up(current_offset, alignment_required()) - current_offset;
 1289 }
 1290 
 1291 //=============================================================================
 1292 
 1293 #ifndef PRODUCT
 1294 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1295   assert_cond(st != nullptr);
 1296   st->print("BREAKPOINT");
 1297 }
 1298 #endif
 1299 
 1300 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1301   __ ebreak();
 1302 }
 1303 
 1304 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
 1305   return MachNode::size(ra_);

 1372     st->print("sd  t2, [sp, #%d]\n\t", framesize - 3 * wordSize);
 1373   }
 1374 
 1375   if (C->stub_function() == nullptr) {
 1376     st->print("ld  t0, [guard]\n\t");
 1377     st->print("membar LoadLoad\n\t");
 1378     st->print("ld  t1, [xthread, #thread_disarmed_guard_value_offset]\n\t");
 1379     st->print("beq t0, t1, skip\n\t");
 1380     st->print("jalr #nmethod_entry_barrier_stub\n\t");
 1381     st->print("j skip\n\t");
 1382     st->print("guard: int\n\t");
 1383     st->print("skip:\n\t");
 1384   }
 1385 }
 1386 #endif
 1387 
 1388 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
 1389   assert_cond(ra_ != nullptr);
 1390   Compile* C = ra_->C;
 1391 
 1392   __ verified_entry(C, 0);





















 1393 
 1394   if (VerifyStackAtCalls) {
 1395     // n.b. frame size includes space for return pc and fp
 1396     const long framesize = C->output()->frame_size_in_bytes();
 1397     __ mv(t2, MAJIK_DWORD);
 1398     __ sd(t2, Address(sp, framesize - 3 * wordSize));
 1399   }
 1400 
 1401   if (C->stub_function() == nullptr) {
 1402     __ entry_barrier();
 1403   }
 1404 
 1405   if (!Compile::current()->output()->in_scratch_emit_size()) {
 1406     __ bind(*_verified_entry);













 1407   }
 1408 
 1409   C->output()->set_frame_complete(__ offset());
 1410 
 1411   if (C->has_mach_constant_base_node()) {
 1412     // NOTE: We set the table base offset here because users might be
 1413     // emitted before MachConstantBaseNode.
 1414     ConstantTable& constant_table = C->output()->constant_table();
 1415     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
 1416   }
 1417 }
 1418 







 1419 int MachPrologNode::reloc() const
 1420 {
 1421   return 0;
 1422 }
 1423 
 1424 //=============================================================================
 1425 
 1426 #ifndef PRODUCT
 1427 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 1428   assert_cond(st != nullptr && ra_ != nullptr);
 1429   Compile* C = ra_->C;
 1430   assert_cond(C != nullptr);
 1431   int framesize = C->output()->frame_size_in_bytes();
 1432 
 1433   st->print("# pop frame %d\n\t", framesize);
 1434 
 1435   if (framesize == 0) {
 1436     st->print("ld  ra, [sp,#%d]\n\t", (2 * wordSize));
 1437     st->print("ld  fp, [sp,#%d]\n\t", (3 * wordSize));
 1438     st->print("add sp, sp, #%d\n\t", (2 * wordSize));

 1458 
 1459   __ remove_frame(framesize);
 1460 
 1461   if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
 1462     __ reserved_stack_check();
 1463   }
 1464 
 1465   if (do_polling() && C->is_method_compilation()) {
 1466     Label dummy_label;
 1467     Label* code_stub = &dummy_label;
 1468     if (!C->output()->in_scratch_emit_size()) {
 1469       C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
 1470       C->output()->add_stub(stub);
 1471       code_stub = &stub->entry();
 1472     }
 1473     __ relocate(relocInfo::poll_return_type);
 1474     __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */);
 1475   }
 1476 }
 1477 






 1478 int MachEpilogNode::reloc() const {
 1479   // Return number of relocatable values contained in this instruction.
 1480   return 1; // 1 for polling page.
 1481 }
 1482 const Pipeline * MachEpilogNode::pipeline() const {
 1483   return MachNode::pipeline_class();
 1484 }
 1485 
 1486 //=============================================================================
 1487 
 1488 // Figure out which register class each belongs in: rc_int, rc_float or
 1489 // rc_stack.
 1490 enum RC { rc_bad, rc_int, rc_float, rc_vector, rc_stack };
 1491 
 1492 static enum RC rc_class(OptoReg::Name reg) {
 1493 
 1494   if (reg == OptoReg::Bad) {
 1495     return rc_bad;
 1496   }
 1497 

 1736     __ addi(as_Register(reg), sp, offset);
 1737   } else {
 1738     __ li32(t0, offset);
 1739     __ add(as_Register(reg), sp, t0);
 1740   }
 1741 }
 1742 
 1743 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
 1744   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
 1745   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
 1746 
 1747   if (Assembler::is_simm12(offset)) {
 1748     return NativeInstruction::instruction_size;
 1749   } else {
 1750     return 3 * NativeInstruction::instruction_size; // lui + addiw + add;
 1751   }
 1752 }
 1753 
 1754 //=============================================================================
 1755 
 1756 #ifndef PRODUCT
 1757 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
 1758 {
 1759   Unimplemented();
 1760 }
 1761 #endif
 1762 
 1763 void MachVEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc* ra_) const
 1764 {
 1765   Unimplemented();
 1766 }
 1767 
 1768 //=============================================================================
 1769 
 1770 #ifndef PRODUCT
 1771 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
 1772 {
 1773   assert_cond(st != nullptr);
 1774   st->print_cr("# MachUEPNode");
 1775   st->print_cr("\tlwu t1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
 1776   st->print_cr("\tlwu t2, [t0      + CompiledICData::speculated_klass_offset()]\t# compressed klass");
 1777   st->print_cr("\tbeq t1, t2, ic_hit");
 1778   st->print_cr("\tj, SharedRuntime::_ic_miss_stub\t # Inline cache check");
 1779   st->print_cr("\tic_hit:");
 1780 }
 1781 #endif
 1782 
 1783 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const
 1784 {
 1785   // This is the unverified entry point.
 1786   __ ic_check(CodeEntryAlignment);
 1787 
 1788   // ic_check() aligns to CodeEntryAlignment >= InteriorEntryAlignment(min 16) > NativeInstruction::instruction_size(4).
 1789   assert(((__ offset()) % CodeEntryAlignment) == 0, "Misaligned verified entry point");
 1790 }
 1791 






 1792 // REQUIRED EMIT CODE
 1793 
 1794 //=============================================================================
 1795 
 1796 // Emit deopt handler code.
 1797 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
 1798 {
 1799   address base = __ start_a_stub(size_deopt_handler());
 1800   if (base == nullptr) {
 1801     ciEnv::current()->record_failure("CodeCache is full");
 1802     return 0;  // CodeBuffer::expand failed
 1803   }
 1804   int offset = __ offset();
 1805 
 1806   Label start;
 1807   __ bind(start);
 1808 
 1809   __ far_call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
 1810 
 1811   int entry_offset = __ offset();

 2636 
 2637 // Unsigned Integer Immediate:  6-bit int, greater than 32
 2638 operand uimmI6_ge32() %{
 2639   predicate(((unsigned int)(n->get_int()) < 64) && (n->get_int() >= 32));
 2640   match(ConI);
 2641   op_cost(0);
 2642   format %{ %}
 2643   interface(CONST_INTER);
 2644 %}
 2645 
 2646 operand immI_le_4()
 2647 %{
 2648   predicate(n->get_int() <= 4);
 2649   match(ConI);
 2650 
 2651   op_cost(0);
 2652   format %{ %}
 2653   interface(CONST_INTER);
 2654 %}
 2655 
 2656 operand immI_4()
 2657 %{
 2658   predicate(n->get_int() == 4);
 2659   match(ConI);
 2660 
 2661   op_cost(0);
 2662   format %{ %}
 2663   interface(CONST_INTER);
 2664 %}
 2665 
 2666 operand immI_16()
 2667 %{
 2668   predicate(n->get_int() == 16);
 2669   match(ConI);
 2670   op_cost(0);
 2671   format %{ %}
 2672   interface(CONST_INTER);
 2673 %}
 2674 
 2675 operand immI_24()
 2676 %{
 2677   predicate(n->get_int() == 24);
 2678   match(ConI);
 2679   op_cost(0);
 2680   format %{ %}
 2681   interface(CONST_INTER);
 2682 %}
 2683 
 2684 operand immI_31()
 2685 %{

 8309   ins_pipe(pipe_serial);
 8310 %}
 8311 
 8312 instruct spin_wait() %{
 8313   predicate(UseZihintpause);
 8314   match(OnSpinWait);
 8315   ins_cost(CACHE_MISS_COST);
 8316 
 8317   format %{ "spin_wait" %}
 8318 
 8319   ins_encode %{
 8320     __ pause();
 8321   %}
 8322 
 8323   ins_pipe(pipe_serial);
 8324 %}
 8325 
 8326 // ============================================================================
 8327 // Cast Instructions (Java-level type cast)
 8328 
 8329 instruct castI2N(iRegNNoSp dst, iRegI src) %{
 8330   match(Set dst (CastI2N src));
 8331 
 8332   ins_cost(ALU_COST);
 8333   format %{ "zext $dst, $src, 32\t# int -> narrow ptr" %}
 8334 
 8335   ins_encode %{
 8336     __ zext(as_Register($dst$$reg), as_Register($src$$reg), 32);
 8337   %}
 8338 
 8339   ins_pipe(ialu_reg);
 8340 %}
 8341 
 8342 instruct castN2X(iRegLNoSp dst, iRegN src) %{
 8343   match(Set dst (CastP2X src));
 8344 
 8345   ins_cost(ALU_COST);
 8346   format %{ "mv $dst, $src\t# ptr -> long" %}
 8347 
 8348   ins_encode %{
 8349     if ($dst$$reg != $src$$reg) {
 8350       __ mv(as_Register($dst$$reg), as_Register($src$$reg));
 8351     }
 8352   %}
 8353 
 8354   ins_pipe(ialu_reg);
 8355 %}
 8356 
 8357 instruct castX2P(iRegPNoSp dst, iRegL src) %{
 8358   match(Set dst (CastX2P src));
 8359 
 8360   ins_cost(ALU_COST);
 8361   format %{ "mv  $dst, $src\t# long -> ptr, #@castX2P" %}
 8362 
 8363   ins_encode %{
 8364     if ($dst$$reg != $src$$reg) {
 8365       __ mv(as_Register($dst$$reg), as_Register($src$$reg));
 8366     }
 8367   %}
 8368 
 8369   ins_pipe(ialu_reg);
 8370 %}
 8371 
 8372 instruct castP2X(iRegLNoSp dst, iRegP src) %{
 8373   match(Set dst (CastP2X src));
 8374 
 8375   ins_cost(ALU_COST);
 8376   format %{ "mv  $dst, $src\t# ptr -> long, #@castP2X" %}

10874 // Call Runtime Instruction without safepoint and with vector arguments
10875 
10876 instruct CallLeafDirectVector(method meth)
10877 %{
10878   match(CallLeafVector);
10879 
10880   effect(USE meth);
10881 
10882   ins_cost(BRANCH_COST);
10883 
10884   format %{ "CALL, runtime leaf vector $meth" %}
10885 
10886   ins_encode(riscv_enc_java_to_runtime(meth));
10887 
10888   ins_pipe(pipe_class_call);
10889   ins_alignment(4);
10890 %}
10891 
10892 // Call Runtime Instruction
10893 
10894 // entry point is null, target holds the address to call
10895 instruct CallLeafNoFPIndirect(iRegP target)
10896 %{
10897   predicate(n->as_Call()->entry_point() == nullptr);
10898 
10899   match(CallLeafNoFP target);
10900 
10901   ins_cost(BRANCH_COST);
10902 
10903   format %{ "CALL, runtime leaf nofp indirect $target" %}
10904 
10905   ins_encode %{
10906     Assembler::IncompressibleScope scope(masm); // Fixed length: see ret_addr_offset
10907     __ jalr($target$$Register);
10908     __ post_call_nop();
10909   %}
10910 
10911   ins_pipe(pipe_class_call);
10912   ins_alignment(4);
10913 %}
10914 
10915 instruct CallLeafNoFPDirect(method meth)
10916 %{
10917   predicate(n->as_Call()->entry_point() != nullptr);
10918 
10919   match(CallLeafNoFP);
10920 
10921   effect(USE meth);
10922 
10923   ins_cost(BRANCH_COST);
10924 
10925   format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %}
10926 
10927   ins_encode(riscv_enc_java_to_runtime(meth));
10928 
10929   ins_pipe(pipe_class_call);
10930   ins_alignment(4);
10931 %}
10932 
10933 // ============================================================================
10934 // Partial Subtype Check
10935 //
10936 // superklass array for an instance of the superklass.  Set a hidden
10937 // internal cache on a hit (cache is checked with exposed code in
10938 // gen_subtype_check()).  Return zero for a hit.  The encoding

11228 
11229 
11230 instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
11231                               iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11232                               iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11233 %{
11234   match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11235   predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
11236   effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result,
11237          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11238 
11239   format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
11240   ins_encode %{
11241     __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
11242                            $result$$Register, $tmp1$$Register, $tmp2$$Register,
11243                            $tmp3$$Register, $tmp4$$Register, true /* isL */);
11244   %}
11245   ins_pipe(pipe_class_memory);
11246 %}
11247 
11248 // ============================================================================
11249 // clearing of an array
11250 
11251 instruct clearArray_reg_reg_immL0(iRegL_R29 cnt, iRegP_R28 base, immL0 zero,
11252                                   iRegP_R30 tmp1, iRegP_R31 tmp2, rFlagsReg cr,
11253                                   Universe dummy)
11254 %{
11255   // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11256   predicate(UseBlockZeroing || !UseRVV);
11257   match(Set dummy (ClearArray (Binary cnt base) zero));
11258   effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11259 
11260   ins_cost(4 * DEFAULT_COST);
11261   format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg_immL0" %}
11262 
11263   ins_encode %{
11264     address tpc = __ zero_words($base$$Register, $cnt$$Register);
11265     if (tpc == nullptr) {
11266       ciEnv::current()->record_failure("CodeCache is full");
11267       return;
11268     }
11269   %}
11270 
11271   ins_pipe(pipe_class_memory);
11272 %}
11273 
11274 instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegL val,
11275                             iRegP_R30 tmp1, iRegP_R31 tmp2, rFlagsReg cr,
11276                             Universe dummy)
11277 %{
11278   // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11279   predicate(((ClearArrayNode*)n)->word_copy_only());
11280   match(Set dummy (ClearArray (Binary cnt base) val));
11281   effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11282 
11283   ins_cost(4 * DEFAULT_COST);
11284   format %{ "ClearArray $cnt, $base, $val\t#@clearArray_reg_reg" %}
11285 
11286   ins_encode %{
11287     __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
11288   %}
11289 
11290   ins_pipe(pipe_class_memory);
11291 %}
11292 
11293 instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, immL0 zero, Universe dummy, rFlagsReg cr)
11294 %{
11295   predicate(!UseRVV
11296             && (uint64_t)n->in(2)->in(1)->get_long()
11297                < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)
11298             && !((ClearArrayNode*)n)->word_copy_only());
11299   match(Set dummy (ClearArray (Binary cnt base) zero));
11300   effect(USE_KILL base, KILL cr);
11301 
11302   ins_cost(4 * DEFAULT_COST);
11303   format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %}
11304 
11305   ins_encode %{
11306     __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
11307   %}
11308 
11309   ins_pipe(pipe_class_memory);
11310 %}
11311 
11312 instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
11313                         iRegI_R10 result, rFlagsReg cr)
11314 %{
11315   predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11316   match(Set result (StrEquals (Binary str1 str2) cnt));
11317   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
11318 
11319   format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %}
< prev index next >