hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
changeset 38028 be8cc044b136
parent 37271 95774d8b3cc2
child 38051 d092550d625d
equal deleted inserted replaced
38027:8a5693d27400 38028:be8cc044b136
  2020     __ ret(lr);
  2020     __ ret(lr);
  2021 
  2021 
  2022     return start;
  2022     return start;
  2023   }
  2023   }
  2024 
  2024 
       
  2025   //
       
  2026   // Generate stub for array fill. If "aligned" is true, the
       
  2027   // "to" address is assumed to be heapword aligned.
       
  2028   //
       
  2029   // Arguments for generated stub:
       
  2030   //   to:    c_rarg0
       
  2031   //   value: c_rarg1
       
  2032   //   count: c_rarg2 treated as signed
       
  2033   //
       
  2034   address generate_fill(BasicType t, bool aligned, const char *name) {
       
  2035     __ align(CodeEntryAlignment);
       
  2036     StubCodeMark mark(this, "StubRoutines", name);
       
  2037     address start = __ pc();
       
  2038 
       
  2039     BLOCK_COMMENT("Entry:");
       
  2040 
       
  2041     const Register to        = c_rarg0;  // source array address
       
  2042     const Register value     = c_rarg1;  // value
       
  2043     const Register count     = c_rarg2;  // elements count
       
  2044     const Register cnt_words = c_rarg3; // temp register
       
  2045 
       
  2046     __ enter();
       
  2047 
       
  2048     Label L_fill_elements, L_exit1;
       
  2049 
       
  2050     int shift = -1;
       
  2051     switch (t) {
       
  2052       case T_BYTE:
       
  2053         shift = 0;
       
  2054         __ cmpw(count, 8 >> shift); // Short arrays (< 8 bytes) fill by element
       
  2055         __ bfi(value, value, 8, 8);   // 8 bit -> 16 bit
       
  2056         __ bfi(value, value, 16, 16); // 16 bit -> 32 bit
       
  2057         __ br(Assembler::LO, L_fill_elements);
       
  2058         break;
       
  2059       case T_SHORT:
       
  2060         shift = 1;
       
  2061         __ cmpw(count, 8 >> shift); // Short arrays (< 8 bytes) fill by element
       
  2062         __ bfi(value, value, 16, 16); // 16 bit -> 32 bit
       
  2063         __ br(Assembler::LO, L_fill_elements);
       
  2064         break;
       
  2065       case T_INT:
       
  2066         shift = 2;
       
  2067         __ cmpw(count, 8 >> shift); // Short arrays (< 8 bytes) fill by element
       
  2068         __ br(Assembler::LO, L_fill_elements);
       
  2069         break;
       
  2070       default: ShouldNotReachHere();
       
  2071     }
       
  2072 
       
  2073     // Align source address at 8 bytes address boundary.
       
  2074     Label L_skip_align1, L_skip_align2, L_skip_align4;
       
  2075     if (!aligned) {
       
  2076       switch (t) {
       
  2077         case T_BYTE:
       
  2078           // One byte misalignment happens only for byte arrays.
       
  2079           __ tbz(to, 0, L_skip_align1);
       
  2080           __ strb(value, Address(__ post(to, 1)));
       
  2081           __ subw(count, count, 1);
       
  2082           __ bind(L_skip_align1);
       
  2083           // Fallthrough
       
  2084         case T_SHORT:
       
  2085           // Two bytes misalignment happens only for byte and short (char) arrays.
       
  2086           __ tbz(to, 1, L_skip_align2);
       
  2087           __ strh(value, Address(__ post(to, 2)));
       
  2088           __ subw(count, count, 2 >> shift);
       
  2089           __ bind(L_skip_align2);
       
  2090           // Fallthrough
       
  2091         case T_INT:
       
  2092           // Align to 8 bytes, we know we are 4 byte aligned to start.
       
  2093           __ tbz(to, 2, L_skip_align4);
       
  2094           __ strw(value, Address(__ post(to, 4)));
       
  2095           __ subw(count, count, 4 >> shift);
       
  2096           __ bind(L_skip_align4);
       
  2097           break;
       
  2098         default: ShouldNotReachHere();
       
  2099       }
       
  2100     }
       
  2101 
       
  2102     //
       
  2103     //  Fill large chunks
       
  2104     //
       
  2105     __ lsrw(cnt_words, count, 3 - shift); // number of words
       
  2106     __ bfi(value, value, 32, 32);         // 32 bit -> 64 bit
       
  2107     __ subw(count, count, cnt_words, Assembler::LSL, 3 - shift);
       
  2108     __ fill_words(to, cnt_words, value);
       
  2109 
       
  2110     // Remaining count is less than 8 bytes. Fill it by a single store.
       
  2111     // Note that the total length is no less than 8 bytes.
       
  2112     if (t == T_BYTE || t == T_SHORT) {
       
  2113       Label L_exit1;
       
  2114       __ cbzw(count, L_exit1);
       
  2115       __ add(to, to, count, Assembler::LSL, shift); // points to the end
       
  2116       __ str(value, Address(to, -8));    // overwrite some elements
       
  2117       __ bind(L_exit1);
       
  2118       __ leave();
       
  2119       __ ret(lr);
       
  2120     }
       
  2121 
       
  2122     // Handle copies less than 8 bytes.
       
  2123     Label L_fill_2, L_fill_4, L_exit2;
       
  2124     __ bind(L_fill_elements);
       
  2125     switch (t) {
       
  2126       case T_BYTE:
       
  2127         __ tbz(count, 0, L_fill_2);
       
  2128         __ strb(value, Address(__ post(to, 1)));
       
  2129         __ bind(L_fill_2);
       
  2130         __ tbz(count, 1, L_fill_4);
       
  2131         __ strh(value, Address(__ post(to, 2)));
       
  2132         __ bind(L_fill_4);
       
  2133         __ tbz(count, 2, L_exit2);
       
  2134         __ strw(value, Address(to));
       
  2135         break;
       
  2136       case T_SHORT:
       
  2137         __ tbz(count, 0, L_fill_4);
       
  2138         __ strh(value, Address(__ post(to, 2)));
       
  2139         __ bind(L_fill_4);
       
  2140         __ tbz(count, 1, L_exit2);
       
  2141         __ strw(value, Address(to));
       
  2142         break;
       
  2143       case T_INT:
       
  2144         __ cbzw(count, L_exit2);
       
  2145         __ strw(value, Address(to));
       
  2146         break;
       
  2147       default: ShouldNotReachHere();
       
  2148     }
       
  2149     __ bind(L_exit2);
       
  2150     __ leave();
       
  2151     __ ret(lr);
       
  2152     return start;
       
  2153   }
       
  2154 
  2025   void generate_arraycopy_stubs() {
  2155   void generate_arraycopy_stubs() {
  2026     address entry;
  2156     address entry;
  2027     address entry_jbyte_arraycopy;
  2157     address entry_jbyte_arraycopy;
  2028     address entry_jshort_arraycopy;
  2158     address entry_jshort_arraycopy;
  2029     address entry_jint_arraycopy;
  2159     address entry_jint_arraycopy;
  2123                                                                entry_jint_arraycopy,
  2253                                                                entry_jint_arraycopy,
  2124                                                                entry_oop_arraycopy,
  2254                                                                entry_oop_arraycopy,
  2125                                                                entry_jlong_arraycopy,
  2255                                                                entry_jlong_arraycopy,
  2126                                                                entry_checkcast_arraycopy);
  2256                                                                entry_checkcast_arraycopy);
  2127 
  2257 
       
  2258     StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
       
  2259     StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
       
  2260     StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
       
  2261     StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
       
  2262     StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
       
  2263     StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
  2128   }
  2264   }
  2129 
  2265 
  2130   void generate_math_stubs() { Unimplemented(); }
  2266   void generate_math_stubs() { Unimplemented(); }
  2131 
  2267 
  2132   // Arguments:
  2268   // Arguments: