< prev index next >

src/hotspot/cpu/riscv/riscv.ad

Print this page

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



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

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





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

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


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

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

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














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

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










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

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




























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

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





















10886 instruct CallLeafNoFPDirect(method meth)
10887 %{


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

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

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


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



















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


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

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

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

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





















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













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







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

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






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

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






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

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

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

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

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