1212 {
1213 return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr
1214 }
1215
1216 int MachCallDynamicJavaNode::ret_addr_offset() const
1217 {
1218 return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal
1219 }
1220
1221 int MachCallRuntimeNode::ret_addr_offset() const {
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" %}
10965 // Call Runtime Instruction without safepoint and with vector arguments
10966
10967 instruct CallLeafDirectVector(method meth)
10968 %{
10969 match(CallLeafVector);
10970
10971 effect(USE meth);
10972
10973 ins_cost(BRANCH_COST);
10974
10975 format %{ "CALL, runtime leaf vector $meth" %}
10976
10977 ins_encode(riscv_enc_java_to_runtime(meth));
10978
10979 ins_pipe(pipe_class_call);
10980 ins_alignment(4);
10981 %}
10982
10983 // Call Runtime Instruction
10984
10985 instruct CallLeafNoFPDirect(method meth)
10986 %{
10987 match(CallLeafNoFP);
10988
10989 effect(USE meth);
10990
10991 ins_cost(BRANCH_COST);
10992
10993 format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %}
10994
10995 ins_encode(riscv_enc_java_to_runtime(meth));
10996
10997 ins_pipe(pipe_class_call);
10998 ins_alignment(4);
10999 %}
11000
11001 // ============================================================================
11002 // Partial Subtype Check
11003 //
11004 // superklass array for an instance of the superklass. Set a hidden
11005 // internal cache on a hit (cache is checked with exposed code in
11006 // gen_subtype_check()). Return zero for a hit. The encoding
11296
11297
11298 instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
11299 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11300 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11301 %{
11302 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11303 predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
11304 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result,
11305 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11306
11307 format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
11308 ins_encode %{
11309 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
11310 $result$$Register, $tmp1$$Register, $tmp2$$Register,
11311 $tmp3$$Register, $tmp4$$Register, true /* isL */);
11312 %}
11313 ins_pipe(pipe_class_memory);
11314 %}
11315
11316 // clearing of an array
11317 instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegP_R30 tmp1,
11318 iRegP_R31 tmp2, rFlagsReg cr, Universe dummy)
11319 %{
11320 // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11321 predicate(UseBlockZeroing || !UseRVV);
11322 match(Set dummy (ClearArray cnt base));
11323 effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11324
11325 ins_cost(4 * DEFAULT_COST);
11326 format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %}
11327
11328 ins_encode %{
11329 address tpc = __ zero_words($base$$Register, $cnt$$Register);
11330 if (tpc == nullptr) {
11331 ciEnv::current()->record_failure("CodeCache is full");
11332 return;
11333 }
11334 %}
11335
11336 ins_pipe(pipe_class_memory);
11337 %}
11338
11339 instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr)
11340 %{
11341 predicate(!UseRVV && (uint64_t)n->in(2)->get_long()
11342 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
11343 match(Set dummy (ClearArray cnt base));
11344 effect(USE_KILL base, KILL cr);
11345
11346 ins_cost(4 * DEFAULT_COST);
11347 format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %}
11348
11349 ins_encode %{
11350 __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
11351 %}
11352
11353 ins_pipe(pipe_class_memory);
11354 %}
11355
11356 instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
11357 iRegI_R10 result, rFlagsReg cr)
11358 %{
11359 predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11360 match(Set result (StrEquals (Binary str1 str2) cnt));
11361 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
11362
11363 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() const
1217 {
1218 return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal
1219 }
1220
1221 int MachCallRuntimeNode::ret_addr_offset() const {
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" %}
10974 // Call Runtime Instruction without safepoint and with vector arguments
10975
10976 instruct CallLeafDirectVector(method meth)
10977 %{
10978 match(CallLeafVector);
10979
10980 effect(USE meth);
10981
10982 ins_cost(BRANCH_COST);
10983
10984 format %{ "CALL, runtime leaf vector $meth" %}
10985
10986 ins_encode(riscv_enc_java_to_runtime(meth));
10987
10988 ins_pipe(pipe_class_call);
10989 ins_alignment(4);
10990 %}
10991
10992 // Call Runtime Instruction
10993
10994 // entry point is null, target holds the address to call
10995 instruct CallLeafNoFPIndirect(iRegP target)
10996 %{
10997 predicate(n->as_Call()->entry_point() == nullptr);
10998
10999 match(CallLeafNoFP target);
11000
11001 ins_cost(BRANCH_COST);
11002
11003 format %{ "CALL, runtime leaf nofp indirect $target" %}
11004
11005 ins_encode %{
11006 Assembler::IncompressibleScope scope(masm); // Fixed length: see ret_addr_offset
11007 __ jalr($target$$Register);
11008 __ post_call_nop();
11009 %}
11010
11011 ins_pipe(pipe_class_call);
11012 ins_alignment(4);
11013 %}
11014
11015 instruct CallLeafNoFPDirect(method meth)
11016 %{
11017 predicate(n->as_Call()->entry_point() != nullptr);
11018
11019 match(CallLeafNoFP);
11020
11021 effect(USE meth);
11022
11023 ins_cost(BRANCH_COST);
11024
11025 format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %}
11026
11027 ins_encode(riscv_enc_java_to_runtime(meth));
11028
11029 ins_pipe(pipe_class_call);
11030 ins_alignment(4);
11031 %}
11032
11033 // ============================================================================
11034 // Partial Subtype Check
11035 //
11036 // superklass array for an instance of the superklass. Set a hidden
11037 // internal cache on a hit (cache is checked with exposed code in
11038 // gen_subtype_check()). Return zero for a hit. The encoding
11328
11329
11330 instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch,
11331 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2,
11332 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
11333 %{
11334 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
11335 predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
11336 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result,
11337 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
11338
11339 format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %}
11340 ins_encode %{
11341 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
11342 $result$$Register, $tmp1$$Register, $tmp2$$Register,
11343 $tmp3$$Register, $tmp4$$Register, true /* isL */);
11344 %}
11345 ins_pipe(pipe_class_memory);
11346 %}
11347
11348 // ============================================================================
11349 // clearing of an array
11350
11351 instruct clearArray_reg_reg_immL0(iRegL_R29 cnt, iRegP_R28 base, immL0 zero,
11352 iRegP_R30 tmp1, iRegP_R31 tmp2, rFlagsReg cr,
11353 Universe dummy)
11354 %{
11355 // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11356 predicate(UseBlockZeroing || !UseRVV);
11357 match(Set dummy (ClearArray (Binary cnt base) zero));
11358 effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11359
11360 ins_cost(4 * DEFAULT_COST);
11361 format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg_immL0" %}
11362
11363 ins_encode %{
11364 address tpc = __ zero_words($base$$Register, $cnt$$Register);
11365 if (tpc == nullptr) {
11366 ciEnv::current()->record_failure("CodeCache is full");
11367 return;
11368 }
11369 %}
11370
11371 ins_pipe(pipe_class_memory);
11372 %}
11373
11374 instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegL val,
11375 iRegP_R30 tmp1, iRegP_R31 tmp2, rFlagsReg cr,
11376 Universe dummy)
11377 %{
11378 // temp registers must match the one used in StubGenerator::generate_zero_blocks()
11379 predicate(((ClearArrayNode*)n)->word_copy_only());
11380 match(Set dummy (ClearArray (Binary cnt base) val));
11381 effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);
11382
11383 ins_cost(4 * DEFAULT_COST);
11384 format %{ "ClearArray $cnt, $base, $val\t#@clearArray_reg_reg" %}
11385
11386 ins_encode %{
11387 __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
11388 %}
11389
11390 ins_pipe(pipe_class_memory);
11391 %}
11392
11393 instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, immL0 zero, Universe dummy, rFlagsReg cr)
11394 %{
11395 predicate(!UseRVV
11396 && (uint64_t)n->in(2)->in(1)->get_long()
11397 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)
11398 && !((ClearArrayNode*)n)->word_copy_only());
11399 match(Set dummy (ClearArray (Binary cnt base) zero));
11400 effect(USE_KILL base, KILL cr);
11401
11402 ins_cost(4 * DEFAULT_COST);
11403 format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %}
11404
11405 ins_encode %{
11406 __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
11407 %}
11408
11409 ins_pipe(pipe_class_memory);
11410 %}
11411
11412 instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt,
11413 iRegI_R10 result, rFlagsReg cr)
11414 %{
11415 predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
11416 match(Set result (StrEquals (Binary str1 str2) cnt));
11417 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
11418
11419 format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %}
|