Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Side by Side Diff: test/cctest/test-assembler-a64.cc

Issue 169893002: A64: Let the MacroAssembler resolve branches to distant targets. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Ulan's comments. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698