OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 | 1940 |
1941 ASSERT_EQUAL_64(1, x0); | 1941 ASSERT_EQUAL_64(1, x0); |
1942 ASSERT_EQUAL_64(0, x1); | 1942 ASSERT_EQUAL_64(0, x1); |
1943 ASSERT_EQUAL_64(1, x2); | 1943 ASSERT_EQUAL_64(1, x2); |
1944 ASSERT_EQUAL_64(0, x3); | 1944 ASSERT_EQUAL_64(0, x3); |
1945 | 1945 |
1946 TEARDOWN(); | 1946 TEARDOWN(); |
1947 } | 1947 } |
1948 | 1948 |
1949 | 1949 |
| 1950 TEST(far_branch_backward) { |
| 1951 INIT_V8(); |
| 1952 |
| 1953 // Test that the MacroAssembler correctly resolves backward branches to labels |
| 1954 // that are outside the immediate range of branch instructions. |
| 1955 int max_range = |
| 1956 std::max(Instruction::ImmBranchRange(TestBranchType), |
| 1957 std::max(Instruction::ImmBranchRange(CompareBranchType), |
| 1958 Instruction::ImmBranchRange(CondBranchType))); |
| 1959 |
| 1960 SETUP_SIZE(max_range + 1000 * kInstructionSize); |
| 1961 |
| 1962 START(); |
| 1963 |
| 1964 Label done, fail; |
| 1965 Label test_tbz, test_cbz, test_bcond; |
| 1966 Label success_tbz, success_cbz, success_bcond; |
| 1967 |
| 1968 __ Mov(x0, 0); |
| 1969 __ Mov(x1, 1); |
| 1970 __ Mov(x10, 0); |
| 1971 |
| 1972 __ B(&test_tbz); |
| 1973 __ Bind(&success_tbz); |
| 1974 __ Orr(x0, x0, 1 << 0); |
| 1975 __ B(&test_cbz); |
| 1976 __ Bind(&success_cbz); |
| 1977 __ Orr(x0, x0, 1 << 1); |
| 1978 __ B(&test_bcond); |
| 1979 __ Bind(&success_bcond); |
| 1980 __ Orr(x0, x0, 1 << 2); |
| 1981 |
| 1982 __ B(&done); |
| 1983 |
| 1984 // Generate enough code to overflow the immediate range of the three types of |
| 1985 // branches below. |
| 1986 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) { |
| 1987 if (i % 100 == 0) { |
| 1988 // If we do land in this code, we do not want to execute so many nops |
| 1989 // before reaching the end of test (especially if tracing is activated). |
| 1990 __ B(&fail); |
| 1991 } else { |
| 1992 __ Nop(); |
| 1993 } |
| 1994 } |
| 1995 __ B(&fail); |
| 1996 |
| 1997 __ Bind(&test_tbz); |
| 1998 __ Tbz(x10, 7, &success_tbz); |
| 1999 __ Bind(&test_cbz); |
| 2000 __ Cbz(x10, &success_cbz); |
| 2001 __ Bind(&test_bcond); |
| 2002 __ Cmp(x10, 0); |
| 2003 __ B(eq, &success_bcond); |
| 2004 |
| 2005 // For each out-of-range branch instructions, at least two instructions should |
| 2006 // have been generated. |
| 2007 CHECK_GE(7 * kInstructionSize, __ SizeOfCodeGeneratedSince(&test_tbz)); |
| 2008 |
| 2009 __ Bind(&fail); |
| 2010 __ Mov(x1, 0); |
| 2011 __ Bind(&done); |
| 2012 |
| 2013 END(); |
| 2014 |
| 2015 RUN(); |
| 2016 |
| 2017 ASSERT_EQUAL_64(0x7, x0); |
| 2018 ASSERT_EQUAL_64(0x1, x1); |
| 2019 |
| 2020 TEARDOWN(); |
| 2021 } |
| 2022 |
| 2023 |
| 2024 TEST(far_branch_simple_veneer) { |
| 2025 INIT_V8(); |
| 2026 |
| 2027 // Test that the MacroAssembler correctly emits veneers for forward branches |
| 2028 // to labels that are outside the immediate range of branch instructions. |
| 2029 int max_range = |
| 2030 std::max(Instruction::ImmBranchRange(TestBranchType), |
| 2031 std::max(Instruction::ImmBranchRange(CompareBranchType), |
| 2032 Instruction::ImmBranchRange(CondBranchType))); |
| 2033 |
| 2034 SETUP_SIZE(max_range + 1000 * kInstructionSize); |
| 2035 |
| 2036 START(); |
| 2037 |
| 2038 Label done, fail; |
| 2039 Label test_tbz, test_cbz, test_bcond; |
| 2040 Label success_tbz, success_cbz, success_bcond; |
| 2041 |
| 2042 __ Mov(x0, 0); |
| 2043 __ Mov(x1, 1); |
| 2044 __ Mov(x10, 0); |
| 2045 |
| 2046 __ Bind(&test_tbz); |
| 2047 __ Tbz(x10, 7, &success_tbz); |
| 2048 __ Bind(&test_cbz); |
| 2049 __ Cbz(x10, &success_cbz); |
| 2050 __ Bind(&test_bcond); |
| 2051 __ Cmp(x10, 0); |
| 2052 __ B(eq, &success_bcond); |
| 2053 |
| 2054 // Generate enough code to overflow the immediate range of the three types of |
| 2055 // branches below. |
| 2056 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) { |
| 2057 if (i % 100 == 0) { |
| 2058 // If we do land in this code, we do not want to execute so many nops |
| 2059 // before reaching the end of test (especially if tracing is activated). |
| 2060 // Also, the branches give the MacroAssembler the opportunity to emit the |
| 2061 // veneers. |
| 2062 __ B(&fail); |
| 2063 } else { |
| 2064 __ Nop(); |
| 2065 } |
| 2066 } |
| 2067 __ B(&fail); |
| 2068 |
| 2069 __ Bind(&success_tbz); |
| 2070 __ Orr(x0, x0, 1 << 0); |
| 2071 __ B(&test_cbz); |
| 2072 __ Bind(&success_cbz); |
| 2073 __ Orr(x0, x0, 1 << 1); |
| 2074 __ B(&test_bcond); |
| 2075 __ Bind(&success_bcond); |
| 2076 __ Orr(x0, x0, 1 << 2); |
| 2077 |
| 2078 __ B(&done); |
| 2079 __ Bind(&fail); |
| 2080 __ Mov(x1, 0); |
| 2081 __ Bind(&done); |
| 2082 |
| 2083 END(); |
| 2084 |
| 2085 RUN(); |
| 2086 |
| 2087 ASSERT_EQUAL_64(0x7, x0); |
| 2088 ASSERT_EQUAL_64(0x1, x1); |
| 2089 |
| 2090 TEARDOWN(); |
| 2091 } |
| 2092 |
| 2093 |
| 2094 TEST(far_branch_veneer_link_chain) { |
| 2095 INIT_V8(); |
| 2096 |
| 2097 // Test that the MacroAssembler correctly emits veneers for forward branches |
| 2098 // that target out-of-range labels and are part of multiple instructions |
| 2099 // jumping to that label. |
| 2100 // |
| 2101 // We test the three situations with the different types of instruction: |
| 2102 // (1)- When the branch is at the start of the chain with tbz. |
| 2103 // (2)- When the branch is in the middle of the chain with cbz. |
| 2104 // (3)- When the branch is at the end of the chain with bcond. |
| 2105 int max_range = |
| 2106 std::max(Instruction::ImmBranchRange(TestBranchType), |
| 2107 std::max(Instruction::ImmBranchRange(CompareBranchType), |
| 2108 Instruction::ImmBranchRange(CondBranchType))); |
| 2109 |
| 2110 SETUP_SIZE(max_range + 1000 * kInstructionSize); |
| 2111 |
| 2112 START(); |
| 2113 |
| 2114 Label skip, fail, done; |
| 2115 Label test_tbz, test_cbz, test_bcond; |
| 2116 Label success_tbz, success_cbz, success_bcond; |
| 2117 |
| 2118 __ Mov(x0, 0); |
| 2119 __ Mov(x1, 1); |
| 2120 __ Mov(x10, 0); |
| 2121 |
| 2122 __ B(&skip); |
| 2123 // Branches at the start of the chain for situations (2) and (3). |
| 2124 __ B(&success_cbz); |
| 2125 __ B(&success_bcond); |
| 2126 __ Nop(); |
| 2127 __ B(&success_bcond); |
| 2128 __ B(&success_cbz); |
| 2129 __ Bind(&skip); |
| 2130 |
| 2131 __ Bind(&test_tbz); |
| 2132 __ Tbz(x10, 7, &success_tbz); |
| 2133 __ Bind(&test_cbz); |
| 2134 __ Cbz(x10, &success_cbz); |
| 2135 __ Bind(&test_bcond); |
| 2136 __ Cmp(x10, 0); |
| 2137 __ B(eq, &success_bcond); |
| 2138 |
| 2139 skip.Unuse(); |
| 2140 __ B(&skip); |
| 2141 // Branches at the end of the chain for situations (1) and (2). |
| 2142 __ B(&success_cbz); |
| 2143 __ B(&success_tbz); |
| 2144 __ Nop(); |
| 2145 __ B(&success_tbz); |
| 2146 __ B(&success_cbz); |
| 2147 __ Bind(&skip); |
| 2148 |
| 2149 // Generate enough code to overflow the immediate range of the three types of |
| 2150 // branches below. |
| 2151 for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) { |
| 2152 if (i % 100 == 0) { |
| 2153 // If we do land in this code, we do not want to execute so many nops |
| 2154 // before reaching the end of test (especially if tracing is activated). |
| 2155 // Also, the branches give the MacroAssembler the opportunity to emit the |
| 2156 // veneers. |
| 2157 __ B(&fail); |
| 2158 } else { |
| 2159 __ Nop(); |
| 2160 } |
| 2161 } |
| 2162 __ B(&fail); |
| 2163 |
| 2164 __ Bind(&success_tbz); |
| 2165 __ Orr(x0, x0, 1 << 0); |
| 2166 __ B(&test_cbz); |
| 2167 __ Bind(&success_cbz); |
| 2168 __ Orr(x0, x0, 1 << 1); |
| 2169 __ B(&test_bcond); |
| 2170 __ Bind(&success_bcond); |
| 2171 __ Orr(x0, x0, 1 << 2); |
| 2172 |
| 2173 __ B(&done); |
| 2174 __ Bind(&fail); |
| 2175 __ Mov(x1, 0); |
| 2176 __ Bind(&done); |
| 2177 |
| 2178 END(); |
| 2179 |
| 2180 RUN(); |
| 2181 |
| 2182 ASSERT_EQUAL_64(0x7, x0); |
| 2183 ASSERT_EQUAL_64(0x1, x1); |
| 2184 |
| 2185 TEARDOWN(); |
| 2186 } |
| 2187 |
| 2188 |
| 2189 TEST(far_branch_veneer_broken_link_chain) { |
| 2190 INIT_V8(); |
| 2191 |
| 2192 // Check that the MacroAssembler correctly handles the situation when removing |
| 2193 // a branch from the link chain of a label and the two links on each side of |
| 2194 // the removed branch cannot be linked together (out of range). |
| 2195 // |
| 2196 // We test with tbz because it has a small range. |
| 2197 int max_range = Instruction::ImmBranchRange(TestBranchType); |
| 2198 int inter_range = max_range / 2 + max_range / 10; |
| 2199 |
| 2200 SETUP_SIZE(3 * inter_range + 1000 * kInstructionSize); |
| 2201 |
| 2202 START(); |
| 2203 |
| 2204 Label skip, fail, done; |
| 2205 Label test_1, test_2, test_3; |
| 2206 Label far_target; |
| 2207 |
| 2208 __ Mov(x0, 0); // Indicates the origin of the branch. |
| 2209 __ Mov(x1, 1); |
| 2210 __ Mov(x10, 0); |
| 2211 |
| 2212 // First instruction in the label chain. |
| 2213 __ Bind(&test_1); |
| 2214 __ Mov(x0, 1); |
| 2215 __ B(&far_target); |
| 2216 |
| 2217 for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) { |
| 2218 if (i % 100 == 0) { |
| 2219 // Do not allow generating veneers. They should not be needed. |
| 2220 __ b(&fail); |
| 2221 } else { |
| 2222 __ Nop(); |
| 2223 } |
| 2224 } |
| 2225 |
| 2226 // Will need a veneer to point to reach the target. |
| 2227 __ Bind(&test_2); |
| 2228 __ Mov(x0, 2); |
| 2229 __ Tbz(x10, 7, &far_target); |
| 2230 |
| 2231 for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) { |
| 2232 if (i % 100 == 0) { |
| 2233 // Do not allow generating veneers. They should not be needed. |
| 2234 __ b(&fail); |
| 2235 } else { |
| 2236 __ Nop(); |
| 2237 } |
| 2238 } |
| 2239 |
| 2240 // Does not need a veneer to reach the target, but the initial branch |
| 2241 // instruction is out of range. |
| 2242 __ Bind(&test_3); |
| 2243 __ Mov(x0, 3); |
| 2244 __ Tbz(x10, 7, &far_target); |
| 2245 |
| 2246 for (unsigned i = 0; i < inter_range / kInstructionSize; ++i) { |
| 2247 if (i % 100 == 0) { |
| 2248 // Allow generating veneers. |
| 2249 __ B(&fail); |
| 2250 } else { |
| 2251 __ Nop(); |
| 2252 } |
| 2253 } |
| 2254 |
| 2255 __ B(&fail); |
| 2256 |
| 2257 __ Bind(&far_target); |
| 2258 __ Cmp(x0, 1); |
| 2259 __ B(eq, &test_2); |
| 2260 __ Cmp(x0, 2); |
| 2261 __ B(eq, &test_3); |
| 2262 |
| 2263 __ B(&done); |
| 2264 __ Bind(&fail); |
| 2265 __ Mov(x1, 0); |
| 2266 __ Bind(&done); |
| 2267 |
| 2268 END(); |
| 2269 |
| 2270 RUN(); |
| 2271 |
| 2272 ASSERT_EQUAL_64(0x3, x0); |
| 2273 ASSERT_EQUAL_64(0x1, x1); |
| 2274 |
| 2275 TEARDOWN(); |
| 2276 } |
| 2277 |
| 2278 |
1950 TEST(ldr_str_offset) { | 2279 TEST(ldr_str_offset) { |
1951 INIT_V8(); | 2280 INIT_V8(); |
1952 SETUP(); | 2281 SETUP(); |
1953 | 2282 |
1954 uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL}; | 2283 uint64_t src[2] = {0xfedcba9876543210UL, 0x0123456789abcdefUL}; |
1955 uint64_t dst[5] = {0, 0, 0, 0, 0}; | 2284 uint64_t dst[5] = {0, 0, 0, 0, 0}; |
1956 uintptr_t src_base = reinterpret_cast<uintptr_t>(src); | 2285 uintptr_t src_base = reinterpret_cast<uintptr_t>(src); |
1957 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); | 2286 uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); |
1958 | 2287 |
1959 START(); | 2288 START(); |
(...skipping 7505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9465 AbsHelperX(-42); | 9794 AbsHelperX(-42); |
9466 AbsHelperX(kXMinInt); | 9795 AbsHelperX(kXMinInt); |
9467 AbsHelperX(kXMaxInt); | 9796 AbsHelperX(kXMaxInt); |
9468 | 9797 |
9469 AbsHelperW(0); | 9798 AbsHelperW(0); |
9470 AbsHelperW(42); | 9799 AbsHelperW(42); |
9471 AbsHelperW(-42); | 9800 AbsHelperW(-42); |
9472 AbsHelperW(kWMinInt); | 9801 AbsHelperW(kWMinInt); |
9473 AbsHelperW(kWMaxInt); | 9802 AbsHelperW(kWMaxInt); |
9474 } | 9803 } |
OLD | NEW |