< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page

2029   int push_slots = count + (odd ? 1 : 0);
2030 
2031   if (odd) {
2032     ldrq(as_FloatRegister(regs[count - 1]), Address(stack, (count - 1) * wordSize * 2));
2033     words_pushed++;
2034   }
2035 
2036   for (int i = 2; i + 1 < count; i += 2) {
2037     ldpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
2038     words_pushed += 2;
2039   }
2040 
2041   ldpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(post(stack, push_slots * wordSize * 2)));
2042   words_pushed += 2;
2043 
2044   assert(words_pushed == count, "oops, pushed(%d) != count(%d)", words_pushed, count);
2045 
2046   return count * 2;
2047 }
2048 












































































2049 #ifdef ASSERT
2050 void MacroAssembler::verify_heapbase(const char* msg) {
2051 #if 0
2052   assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
2053   assert (Universe::heap() != NULL, "java heap should be initialized");
2054   if (!UseCompressedOops || Universe::ptr_base() == NULL) {
2055     // rheapbase is allocated as general register
2056     return;
2057   }
2058   if (CheckCompressedOops) {
2059     Label ok;
2060     push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1
2061     cmpptr(rheapbase, ExternalAddress((address)CompressedOops::ptrs_base_addr()));
2062     br(Assembler::EQ, ok);
2063     stop(msg);
2064     bind(ok);
2065     pop(1 << rscratch1->encoding(), sp);
2066   }
2067 #endif
2068 }

2487       st1(as_FloatRegister(i-3), as_FloatRegister(i-2), as_FloatRegister(i-1),
2488           as_FloatRegister(i), T1D, Address(post(sp, rscratch1)));
2489   }
2490   st1(as_FloatRegister(0), as_FloatRegister(1), as_FloatRegister(2),
2491       as_FloatRegister(3), T1D, Address(sp));
2492 }
2493 
2494 void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
2495   for (int i = 0; i < 32; i += 4) {
2496     if (i <= v7->encoding() || i >= v16->encoding())
2497       ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
2498           as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize)));
2499   }
2500 
2501   reinitialize_ptrue();
2502 
2503   pop(call_clobbered_registers() - exclude, sp);
2504 }
2505 
2506 void MacroAssembler::push_CPU_state(bool save_vectors, bool use_sve,
2507                                     int sve_vector_size_in_bytes) {
2508   push(0x3fffffff, sp);         // integer registers except lr & sp
2509   if (save_vectors && use_sve && sve_vector_size_in_bytes > 16) {
2510     sub(sp, sp, sve_vector_size_in_bytes * FloatRegisterImpl::number_of_registers);
2511     for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
2512       sve_str(as_FloatRegister(i), Address(sp, i));
2513     }
2514   } else {
2515     int step = (save_vectors ? 8 : 4) * wordSize;
2516     mov(rscratch1, -step);
2517     sub(sp, sp, step);
2518     for (int i = 28; i >= 4; i -= 4) {
2519       st1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
2520           as_FloatRegister(i+3), save_vectors ? T2D : T1D, Address(post(sp, rscratch1)));
2521     }
2522     st1(v0, v1, v2, v3, save_vectors ? T2D : T1D, sp);
2523   }






2524 }
2525 
2526 void MacroAssembler::pop_CPU_state(bool restore_vectors, bool use_sve,
2527                                    int sve_vector_size_in_bytes) {






2528   if (restore_vectors && use_sve && sve_vector_size_in_bytes > 16) {
2529     for (int i = FloatRegisterImpl::number_of_registers - 1; i >= 0; i--) {
2530       sve_ldr(as_FloatRegister(i), Address(sp, i));
2531     }
2532     add(sp, sp, sve_vector_size_in_bytes * FloatRegisterImpl::number_of_registers);
2533   } else {
2534     int step = (restore_vectors ? 8 : 4) * wordSize;
2535     for (int i = 0; i <= 28; i += 4)
2536       ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
2537           as_FloatRegister(i+3), restore_vectors ? T2D : T1D, Address(post(sp, step)));
2538   }
2539 
2540   // We may use predicate registers and rely on ptrue with SVE,
2541   // regardless of wide vector (> 8 bytes) used or not.
2542   if (use_sve) {
2543     reinitialize_ptrue();
2544   }
2545 
2546   pop(0x3fffffff, sp);         // integer registers except lr & sp
2547 }

2029   int push_slots = count + (odd ? 1 : 0);
2030 
2031   if (odd) {
2032     ldrq(as_FloatRegister(regs[count - 1]), Address(stack, (count - 1) * wordSize * 2));
2033     words_pushed++;
2034   }
2035 
2036   for (int i = 2; i + 1 < count; i += 2) {
2037     ldpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
2038     words_pushed += 2;
2039   }
2040 
2041   ldpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(post(stack, push_slots * wordSize * 2)));
2042   words_pushed += 2;
2043 
2044   assert(words_pushed == count, "oops, pushed(%d) != count(%d)", words_pushed, count);
2045 
2046   return count * 2;
2047 }
2048 
2049 // Return the number of dwords pushed
2050 int MacroAssembler::push_p(unsigned int bitset, Register stack) {
2051   bool use_sve = false;
2052   int sve_predicate_size_in_slots = 0;
2053 
2054 #ifdef COMPILER2
2055   use_sve = Matcher::supports_scalable_vector();
2056   if (use_sve) {
2057     sve_predicate_size_in_slots = Matcher::scalable_predicate_reg_slots();
2058   }
2059 #endif
2060 
2061   if (!use_sve) {
2062     return 0;
2063   }
2064 
2065   const int num_of_regs = PRegisterImpl::number_of_saved_registers;
2066   unsigned char regs[num_of_regs];
2067   int count = 0;
2068   for (int reg = 0; reg < num_of_regs; reg++) {
2069     if (1 & bitset)
2070       regs[count++] = reg;
2071     bitset >>= 1;
2072   }
2073 
2074   if (count == 0) {
2075     return 0;
2076   }
2077 
2078   int total_push_bytes = align_up(sve_predicate_size_in_slots *
2079                                   VMRegImpl::stack_slot_size * count, 16);
2080   sub(stack, stack, total_push_bytes);
2081   for (int i = 0; i < count; i++) {
2082     sve_str(as_PRegister(regs[i]), Address(stack, i));
2083   }
2084   return total_push_bytes / 8;
2085 }
2086 
2087 // Return the number of dwords poped
2088 int MacroAssembler::pop_p(unsigned int bitset, Register stack) {
2089   bool use_sve = false;
2090   int sve_predicate_size_in_slots = 0;
2091 
2092 #ifdef COMPILER2
2093   use_sve = Matcher::supports_scalable_vector();
2094   if (use_sve) {
2095     sve_predicate_size_in_slots = Matcher::scalable_predicate_reg_slots();
2096   }
2097 #endif
2098 
2099   if (!use_sve) {
2100     return 0;
2101   }
2102 
2103   const int num_of_regs = PRegisterImpl::number_of_saved_registers;
2104   unsigned char regs[num_of_regs];
2105   int count = 0;
2106   for (int reg = 0; reg < num_of_regs; reg++) {
2107     if (1 & bitset)
2108       regs[count++] = reg;
2109     bitset >>= 1;
2110   }
2111 
2112   if (count == 0) {
2113     return 0;
2114   }
2115 
2116   int total_pop_bytes = align_up(sve_predicate_size_in_slots *
2117                                  VMRegImpl::stack_slot_size * count, 16);
2118   for (int i = count - 1; i >= 0; i--) {
2119     sve_ldr(as_PRegister(regs[i]), Address(stack, i));
2120   }
2121   add(stack, stack, total_pop_bytes);
2122   return total_pop_bytes / 8;
2123 }
2124 
2125 #ifdef ASSERT
2126 void MacroAssembler::verify_heapbase(const char* msg) {
2127 #if 0
2128   assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
2129   assert (Universe::heap() != NULL, "java heap should be initialized");
2130   if (!UseCompressedOops || Universe::ptr_base() == NULL) {
2131     // rheapbase is allocated as general register
2132     return;
2133   }
2134   if (CheckCompressedOops) {
2135     Label ok;
2136     push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1
2137     cmpptr(rheapbase, ExternalAddress((address)CompressedOops::ptrs_base_addr()));
2138     br(Assembler::EQ, ok);
2139     stop(msg);
2140     bind(ok);
2141     pop(1 << rscratch1->encoding(), sp);
2142   }
2143 #endif
2144 }

2563       st1(as_FloatRegister(i-3), as_FloatRegister(i-2), as_FloatRegister(i-1),
2564           as_FloatRegister(i), T1D, Address(post(sp, rscratch1)));
2565   }
2566   st1(as_FloatRegister(0), as_FloatRegister(1), as_FloatRegister(2),
2567       as_FloatRegister(3), T1D, Address(sp));
2568 }
2569 
2570 void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
2571   for (int i = 0; i < 32; i += 4) {
2572     if (i <= v7->encoding() || i >= v16->encoding())
2573       ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
2574           as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize)));
2575   }
2576 
2577   reinitialize_ptrue();
2578 
2579   pop(call_clobbered_registers() - exclude, sp);
2580 }
2581 
2582 void MacroAssembler::push_CPU_state(bool save_vectors, bool use_sve,
2583                                     int sve_vector_size_in_bytes, int total_predicate_in_bytes) {
2584   push(0x3fffffff, sp);         // integer registers except lr & sp
2585   if (save_vectors && use_sve && sve_vector_size_in_bytes > 16) {
2586     sub(sp, sp, sve_vector_size_in_bytes * FloatRegisterImpl::number_of_registers);
2587     for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
2588       sve_str(as_FloatRegister(i), Address(sp, i));
2589     }
2590   } else {
2591     int step = (save_vectors ? 8 : 4) * wordSize;
2592     mov(rscratch1, -step);
2593     sub(sp, sp, step);
2594     for (int i = 28; i >= 4; i -= 4) {
2595       st1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
2596           as_FloatRegister(i+3), save_vectors ? T2D : T1D, Address(post(sp, rscratch1)));
2597     }
2598     st1(v0, v1, v2, v3, save_vectors ? T2D : T1D, sp);
2599   }
2600   if (save_vectors && use_sve && total_predicate_in_bytes > 0) {
2601     sub(sp, sp, total_predicate_in_bytes);
2602     for (int i = 0; i < PRegisterImpl::number_of_saved_registers; i++) {
2603       sve_str(as_PRegister(i), Address(sp, i));
2604     }
2605   }
2606 }
2607 
2608 void MacroAssembler::pop_CPU_state(bool restore_vectors, bool use_sve,
2609                                    int sve_vector_size_in_bytes, int total_predicate_in_bytes) {
2610   if (restore_vectors && use_sve && total_predicate_in_bytes > 0) {
2611     for (int i = PRegisterImpl::number_of_saved_registers - 1; i >= 0; i--) {
2612       sve_ldr(as_PRegister(i), Address(sp, i));
2613     }
2614     add(sp, sp, total_predicate_in_bytes);
2615   }
2616   if (restore_vectors && use_sve && sve_vector_size_in_bytes > 16) {
2617     for (int i = FloatRegisterImpl::number_of_registers - 1; i >= 0; i--) {
2618       sve_ldr(as_FloatRegister(i), Address(sp, i));
2619     }
2620     add(sp, sp, sve_vector_size_in_bytes * FloatRegisterImpl::number_of_registers);
2621   } else {
2622     int step = (restore_vectors ? 8 : 4) * wordSize;
2623     for (int i = 0; i <= 28; i += 4)
2624       ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
2625           as_FloatRegister(i+3), restore_vectors ? T2D : T1D, Address(post(sp, step)));
2626   }
2627 
2628   // We may use predicate registers and rely on ptrue with SVE,
2629   // regardless of wide vector (> 8 bytes) used or not.
2630   if (use_sve) {
2631     reinitialize_ptrue();
2632   }
2633 
2634   pop(0x3fffffff, sp);         // integer registers except lr & sp
2635 }
< prev index next >