187 // calls out to InterpreterRuntime::resolve_get_put to do |
187 // calls out to InterpreterRuntime::resolve_get_put to do |
188 // additional, required work. |
188 // additional, required work. |
189 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); |
189 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); |
190 assert(load_bc_into_bc_reg, "we use bc_reg as temp"); |
190 assert(load_bc_into_bc_reg, "we use bc_reg as temp"); |
191 __ get_cache_and_index_at_bcp(Rtemp /* dst = cache */, 1); |
191 __ get_cache_and_index_at_bcp(Rtemp /* dst = cache */, 1); |
192 // Big Endian: ((*(cache+indices))>>((1+byte_no)*8))&0xFF |
192 // ((*(cache+indices))>>((1+byte_no)*8))&0xFF: |
|
193 #if defined(VM_LITTLE_ENDIAN) |
|
194 __ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 1 + byte_no, Rtemp); |
|
195 #else |
193 __ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (1 + byte_no), Rtemp); |
196 __ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (1 + byte_no), Rtemp); |
|
197 #endif |
194 __ cmpwi(CCR0, Rnew_bc, 0); |
198 __ cmpwi(CCR0, Rnew_bc, 0); |
195 __ li(Rnew_bc, (unsigned int)(unsigned char)new_bc); |
199 __ li(Rnew_bc, (unsigned int)(unsigned char)new_bc); |
196 __ beq(CCR0, L_patch_done); |
200 __ beq(CCR0, L_patch_done); |
197 // __ isync(); // acquire not needed |
201 // __ isync(); // acquire not needed |
198 break; |
202 break; |
1837 // Align bcp. |
1841 // Align bcp. |
1838 __ addi(Rdef_offset_addr, R14_bcp, BytesPerInt); |
1842 __ addi(Rdef_offset_addr, R14_bcp, BytesPerInt); |
1839 __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt)); |
1843 __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt)); |
1840 |
1844 |
1841 // Load lo & hi. |
1845 // Load lo & hi. |
1842 __ lwz(Rlow_byte, BytesPerInt, Rdef_offset_addr); |
1846 __ get_u4(Rlow_byte, Rdef_offset_addr, BytesPerInt, InterpreterMacroAssembler::Unsigned); |
1843 __ lwz(Rhigh_byte, BytesPerInt * 2, Rdef_offset_addr); |
1847 __ get_u4(Rhigh_byte, Rdef_offset_addr, 2 *BytesPerInt, InterpreterMacroAssembler::Unsigned); |
1844 |
1848 |
1845 // Check for default case (=index outside [low,high]). |
1849 // Check for default case (=index outside [low,high]). |
1846 __ cmpw(CCR0, R17_tos, Rlow_byte); |
1850 __ cmpw(CCR0, R17_tos, Rlow_byte); |
1847 __ cmpw(CCR1, R17_tos, Rhigh_byte); |
1851 __ cmpw(CCR1, R17_tos, Rhigh_byte); |
1848 __ blt(CCR0, Ldefault_case); |
1852 __ blt(CCR0, Ldefault_case); |
1852 __ sub(Rindex, R17_tos, Rlow_byte); |
1856 __ sub(Rindex, R17_tos, Rlow_byte); |
1853 __ extsw(Rindex, Rindex); |
1857 __ extsw(Rindex, Rindex); |
1854 __ profile_switch_case(Rindex, Rhigh_byte /* scratch */, Rscratch1, Rscratch2); |
1858 __ profile_switch_case(Rindex, Rhigh_byte /* scratch */, Rscratch1, Rscratch2); |
1855 __ sldi(Rindex, Rindex, LogBytesPerInt); |
1859 __ sldi(Rindex, Rindex, LogBytesPerInt); |
1856 __ addi(Rindex, Rindex, 3 * BytesPerInt); |
1860 __ addi(Rindex, Rindex, 3 * BytesPerInt); |
|
1861 #if defined(VM_LITTLE_ENDIAN) |
|
1862 __ lwbrx(Roffset, Rdef_offset_addr, Rindex); |
|
1863 __ extsw(Roffset, Roffset); |
|
1864 #else |
1857 __ lwax(Roffset, Rdef_offset_addr, Rindex); |
1865 __ lwax(Roffset, Rdef_offset_addr, Rindex); |
|
1866 #endif |
1858 __ b(Ldispatch); |
1867 __ b(Ldispatch); |
1859 |
1868 |
1860 __ bind(Ldefault_case); |
1869 __ bind(Ldefault_case); |
1861 __ profile_switch_default(Rhigh_byte, Rscratch1); |
1870 __ profile_switch_default(Rhigh_byte, Rscratch1); |
1862 __ lwa(Roffset, 0, Rdef_offset_addr); |
1871 __ get_u4(Roffset, Rdef_offset_addr, 0, InterpreterMacroAssembler::Signed); |
1863 |
1872 |
1864 __ bind(Ldispatch); |
1873 __ bind(Ldispatch); |
1865 |
1874 |
1866 __ add(R14_bcp, Roffset, R14_bcp); |
1875 __ add(R14_bcp, Roffset, R14_bcp); |
1867 __ dispatch_next(vtos); |
1876 __ dispatch_next(vtos); |
1873 } |
1882 } |
1874 |
1883 |
1875 // Table switch using linear search through cases. |
1884 // Table switch using linear search through cases. |
1876 // Bytecode stream format: |
1885 // Bytecode stream format: |
1877 // Bytecode (1) | 4-byte padding | default offset (4) | count (4) | value/offset pair1 (8) | value/offset pair2 (8) | ... |
1886 // Bytecode (1) | 4-byte padding | default offset (4) | count (4) | value/offset pair1 (8) | value/offset pair2 (8) | ... |
1878 // Note: Everything is big-endian format here. So on little endian machines, we have to revers offset and count and cmp value. |
1887 // Note: Everything is big-endian format here. |
1879 void TemplateTable::fast_linearswitch() { |
1888 void TemplateTable::fast_linearswitch() { |
1880 transition(itos, vtos); |
1889 transition(itos, vtos); |
1881 |
1890 |
1882 Label Lloop_entry, Lsearch_loop, Lfound, Lcontinue_execution, Ldefault_case; |
1891 Label Lloop_entry, Lsearch_loop, Lcontinue_execution, Ldefault_case; |
1883 |
|
1884 Register Rcount = R3_ARG1, |
1892 Register Rcount = R3_ARG1, |
1885 Rcurrent_pair = R4_ARG2, |
1893 Rcurrent_pair = R4_ARG2, |
1886 Rdef_offset_addr = R5_ARG3, // Is going to contain address of default offset. |
1894 Rdef_offset_addr = R5_ARG3, // Is going to contain address of default offset. |
1887 Roffset = R31, // Might need to survive C call. |
1895 Roffset = R31, // Might need to survive C call. |
1888 Rvalue = R12_scratch2, |
1896 Rvalue = R12_scratch2, |
1892 // Align bcp. |
1900 // Align bcp. |
1893 __ addi(Rdef_offset_addr, R14_bcp, BytesPerInt); |
1901 __ addi(Rdef_offset_addr, R14_bcp, BytesPerInt); |
1894 __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt)); |
1902 __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt)); |
1895 |
1903 |
1896 // Setup loop counter and limit. |
1904 // Setup loop counter and limit. |
1897 __ lwz(Rcount, BytesPerInt, Rdef_offset_addr); // Load count. |
1905 __ get_u4(Rcount, Rdef_offset_addr, BytesPerInt, InterpreterMacroAssembler::Unsigned); |
1898 __ addi(Rcurrent_pair, Rdef_offset_addr, 2 * BytesPerInt); // Rcurrent_pair now points to first pair. |
1906 __ addi(Rcurrent_pair, Rdef_offset_addr, 2 * BytesPerInt); // Rcurrent_pair now points to first pair. |
1899 |
1907 |
1900 // Set up search loop. |
1908 __ mtctr(Rcount); |
1901 __ cmpwi(CCR0, Rcount, 0); |
1909 __ cmpwi(CCR0, Rcount, 0); |
1902 __ beq(CCR0, Ldefault_case); |
1910 __ bne(CCR0, Lloop_entry); |
1903 |
1911 |
1904 __ mtctr(Rcount); |
1912 // Default case |
1905 |
|
1906 // linear table search |
|
1907 __ bind(Lsearch_loop); |
|
1908 |
|
1909 __ lwz(Rvalue, 0, Rcurrent_pair); |
|
1910 __ lwa(Roffset, 1 * BytesPerInt, Rcurrent_pair); |
|
1911 |
|
1912 __ cmpw(CCR0, Rvalue, Rcmp_value); |
|
1913 __ beq(CCR0, Lfound); |
|
1914 |
|
1915 __ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt); |
|
1916 __ bdnz(Lsearch_loop); |
|
1917 |
|
1918 // default case |
|
1919 __ bind(Ldefault_case); |
1913 __ bind(Ldefault_case); |
1920 |
1914 __ get_u4(Roffset, Rdef_offset_addr, 0, InterpreterMacroAssembler::Signed); |
1921 __ lwa(Roffset, 0, Rdef_offset_addr); |
|
1922 if (ProfileInterpreter) { |
1915 if (ProfileInterpreter) { |
1923 __ profile_switch_default(Rdef_offset_addr, Rcount/* scratch */); |
1916 __ profile_switch_default(Rdef_offset_addr, Rcount/* scratch */); |
1924 __ b(Lcontinue_execution); |
1917 } |
1925 } |
1918 __ b(Lcontinue_execution); |
1926 |
1919 |
1927 // Entry found, skip Roffset bytecodes and continue. |
1920 // Next iteration |
1928 __ bind(Lfound); |
1921 __ bind(Lsearch_loop); |
|
1922 __ bdz(Ldefault_case); |
|
1923 __ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt); |
|
1924 __ bind(Lloop_entry); |
|
1925 __ get_u4(Rvalue, Rcurrent_pair, 0, InterpreterMacroAssembler::Unsigned); |
|
1926 __ cmpw(CCR0, Rvalue, Rcmp_value); |
|
1927 __ bne(CCR0, Lsearch_loop); |
|
1928 |
|
1929 // Found, load offset. |
|
1930 __ get_u4(Roffset, Rcurrent_pair, BytesPerInt, InterpreterMacroAssembler::Signed); |
|
1931 // Calculate case index and profile |
|
1932 __ mfctr(Rcurrent_pair); |
1929 if (ProfileInterpreter) { |
1933 if (ProfileInterpreter) { |
1930 // Calc the num of the pair we hit. Careful, Rcurrent_pair points 2 ints |
1934 __ sub(Rcurrent_pair, Rcount, Rcurrent_pair); |
1931 // beyond the actual current pair due to the auto update load above! |
|
1932 __ sub(Rcurrent_pair, Rcurrent_pair, Rdef_offset_addr); |
|
1933 __ addi(Rcurrent_pair, Rcurrent_pair, - 2 * BytesPerInt); |
|
1934 __ srdi(Rcurrent_pair, Rcurrent_pair, LogBytesPerInt + 1); |
|
1935 __ profile_switch_case(Rcurrent_pair, Rcount /*scratch*/, Rdef_offset_addr/*scratch*/, Rscratch); |
1935 __ profile_switch_case(Rcurrent_pair, Rcount /*scratch*/, Rdef_offset_addr/*scratch*/, Rscratch); |
1936 __ bind(Lcontinue_execution); |
1936 } |
1937 } |
1937 |
|
1938 __ bind(Lcontinue_execution); |
1938 __ add(R14_bcp, Roffset, R14_bcp); |
1939 __ add(R14_bcp, Roffset, R14_bcp); |
1939 __ dispatch_next(vtos); |
1940 __ dispatch_next(vtos); |
1940 } |
1941 } |
1941 |
1942 |
1942 // Table switch using binary search (value/offset pairs are ordered). |
1943 // Table switch using binary search (value/offset pairs are ordered). |
2037 __ mr(Rh, Ri); // Save index in i for profiling. |
2042 __ mr(Rh, Ri); // Save index in i for profiling. |
2038 } |
2043 } |
2039 // Ri = value offset |
2044 // Ri = value offset |
2040 __ sldi(Ri, Ri, log_entry_size); |
2045 __ sldi(Ri, Ri, log_entry_size); |
2041 __ add(Ri, Ri, Rarray); |
2046 __ add(Ri, Ri, Rarray); |
2042 __ lwz(Rscratch, 0, Ri); |
2047 __ get_u4(Rscratch, Ri, 0, InterpreterMacroAssembler::Unsigned); |
2043 |
2048 |
2044 Label not_found; |
2049 Label not_found; |
2045 // Ri = offset offset |
2050 // Ri = offset offset |
2046 __ cmpw(CCR0, Rkey, Rscratch); |
2051 __ cmpw(CCR0, Rkey, Rscratch); |
2047 __ beq(CCR0, not_found); |
2052 __ beq(CCR0, not_found); |
2048 // entry not found -> j = default offset |
2053 // entry not found -> j = default offset |
2049 __ lwz(Rj, -2 * BytesPerInt, Rarray); |
2054 __ get_u4(Rj, Rarray, -2 * BytesPerInt, InterpreterMacroAssembler::Unsigned); |
2050 __ b(default_case); |
2055 __ b(default_case); |
2051 |
2056 |
2052 __ bind(not_found); |
2057 __ bind(not_found); |
2053 // entry found -> j = offset |
2058 // entry found -> j = offset |
2054 __ profile_switch_case(Rh, Rj, Rscratch, Rkey); |
2059 __ profile_switch_case(Rh, Rj, Rscratch, Rkey); |
2055 __ lwz(Rj, BytesPerInt, Ri); |
2060 __ get_u4(Rj, Ri, BytesPerInt, InterpreterMacroAssembler::Unsigned); |
2056 |
2061 |
2057 if (ProfileInterpreter) { |
2062 if (ProfileInterpreter) { |
2058 __ b(continue_execution); |
2063 __ b(continue_execution); |
2059 } |
2064 } |
2060 |
2065 |
2145 __ get_cache_and_index_at_bcp(Rcache, 1, index_size); |
2150 __ get_cache_and_index_at_bcp(Rcache, 1, index_size); |
2146 Label Lresolved, Ldone; |
2151 Label Lresolved, Ldone; |
2147 |
2152 |
2148 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); |
2153 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); |
2149 // We are resolved if the indices offset contains the current bytecode. |
2154 // We are resolved if the indices offset contains the current bytecode. |
2150 // Big Endian: |
2155 #if defined(VM_LITTLE_ENDIAN) |
|
2156 __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + byte_no + 1, Rcache); |
|
2157 #else |
2151 __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (byte_no + 1), Rcache); |
2158 __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (byte_no + 1), Rcache); |
|
2159 #endif |
2152 // Acquire by cmp-br-isync (see below). |
2160 // Acquire by cmp-br-isync (see below). |
2153 __ cmpdi(CCR0, Rscratch, (int)bytecode()); |
2161 __ cmpdi(CCR0, Rscratch, (int)bytecode()); |
2154 __ beq(CCR0, Lresolved); |
2162 __ beq(CCR0, Lresolved); |
2155 |
2163 |
2156 address entry = NULL; |
2164 address entry = NULL; |