OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 using v8::internal::rdx; | 54 using v8::internal::rdx; |
55 using v8::internal::rbp; | 55 using v8::internal::rbp; |
56 using v8::internal::rsp; | 56 using v8::internal::rsp; |
57 using v8::internal::r8; | 57 using v8::internal::r8; |
58 using v8::internal::r9; | 58 using v8::internal::r9; |
59 using v8::internal::r11; | 59 using v8::internal::r11; |
60 using v8::internal::r12; // Remember: r12..r15 are callee save! | 60 using v8::internal::r12; // Remember: r12..r15 are callee save! |
61 using v8::internal::r13; | 61 using v8::internal::r13; |
62 using v8::internal::r14; | 62 using v8::internal::r14; |
63 using v8::internal::r15; | 63 using v8::internal::r15; |
| 64 using v8::internal::times_pointer_size; |
64 using v8::internal::FUNCTION_CAST; | 65 using v8::internal::FUNCTION_CAST; |
65 using v8::internal::CodeDesc; | 66 using v8::internal::CodeDesc; |
66 using v8::internal::less_equal; | 67 using v8::internal::less_equal; |
67 using v8::internal::not_equal; | 68 using v8::internal::not_equal; |
68 using v8::internal::not_zero; | 69 using v8::internal::not_zero; |
69 using v8::internal::greater; | 70 using v8::internal::greater; |
70 using v8::internal::greater_equal; | 71 using v8::internal::greater_equal; |
71 using v8::internal::carry; | 72 using v8::internal::carry; |
72 using v8::internal::not_carry; | 73 using v8::internal::not_carry; |
73 using v8::internal::negative; | 74 using v8::internal::negative; |
74 using v8::internal::positive; | 75 using v8::internal::positive; |
75 using v8::internal::Smi; | 76 using v8::internal::Smi; |
76 using v8::internal::kSmiTagMask; | 77 using v8::internal::kSmiTagMask; |
77 using v8::internal::kSmiValueSize; | 78 using v8::internal::kSmiValueSize; |
| 79 using v8::internal::kPointerSize; |
| 80 using v8::internal::kIntSize; |
78 | 81 |
79 // Test the x64 assembler by compiling some simple functions into | 82 // Test the x64 assembler by compiling some simple functions into |
80 // a buffer and executing them. These tests do not initialize the | 83 // a buffer and executing them. These tests do not initialize the |
81 // V8 library, create a context, or use any V8 objects. | 84 // V8 library, create a context, or use any V8 objects. |
82 // The AMD64 calling convention is used, with the first five arguments | 85 // The AMD64 calling convention is used, with the first five arguments |
83 // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in | 86 // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in |
84 // the XMM registers. The return value is in RAX. | 87 // the XMM registers. The return value is in RAX. |
85 // This calling convention is used on Linux, with GCC, and on Mac OS, | 88 // This calling convention is used on Linux, with GCC, and on Mac OS, |
86 // with GCC. A different convention is used on 64-bit windows. | 89 // with GCC. A different convention is used on 64-bit windows. |
87 | 90 |
(...skipping 1958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2046 __ ret(0); | 2049 __ ret(0); |
2047 | 2050 |
2048 CodeDesc desc; | 2051 CodeDesc desc; |
2049 masm->GetCode(&desc); | 2052 masm->GetCode(&desc); |
2050 // Call the function from C++. | 2053 // Call the function from C++. |
2051 int result = FUNCTION_CAST<F0>(buffer)(); | 2054 int result = FUNCTION_CAST<F0>(buffer)(); |
2052 CHECK_EQ(0, result); | 2055 CHECK_EQ(0, result); |
2053 } | 2056 } |
2054 | 2057 |
2055 | 2058 |
| 2059 TEST(OperandOffset) { |
| 2060 int data[256]; |
| 2061 for (int i = 0; i < 256; i++) { data[i] = i * 0x01010101; } |
| 2062 |
| 2063 // Allocate an executable page of memory. |
| 2064 size_t actual_size; |
| 2065 byte* buffer = |
| 2066 static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, |
| 2067 &actual_size, |
| 2068 true)); |
| 2069 CHECK(buffer); |
| 2070 HandleScope handles; |
| 2071 MacroAssembler assembler(buffer, static_cast<int>(actual_size)); |
| 2072 |
| 2073 MacroAssembler* masm = &assembler; |
| 2074 masm->set_allow_stub_calls(false); |
| 2075 Label exit; |
| 2076 |
| 2077 __ push(r12); |
| 2078 __ push(r13); |
| 2079 __ push(rbx); |
| 2080 __ push(rbp); |
| 2081 __ push(Immediate(0x100)); // <-- rbp |
| 2082 __ movq(rbp, rsp); |
| 2083 __ push(Immediate(0x101)); |
| 2084 __ push(Immediate(0x102)); |
| 2085 __ push(Immediate(0x103)); |
| 2086 __ push(Immediate(0x104)); |
| 2087 __ push(Immediate(0x105)); // <-- rbx |
| 2088 __ push(Immediate(0x106)); |
| 2089 __ push(Immediate(0x107)); |
| 2090 __ push(Immediate(0x108)); |
| 2091 __ push(Immediate(0x109)); // <-- rsp |
| 2092 // rbp = rsp[9] |
| 2093 // r12 = rsp[3] |
| 2094 // rbx = rsp[5] |
| 2095 // r13 = rsp[7] |
| 2096 __ lea(r12, Operand(rsp, 3 * kPointerSize)); |
| 2097 __ lea(r13, Operand(rbp, -3 * kPointerSize)); |
| 2098 __ lea(rbx, Operand(rbp, -5 * kPointerSize)); |
| 2099 __ movl(rcx, Immediate(2)); |
| 2100 __ movq(r8, reinterpret_cast<uintptr_t>(&data[128]), RelocInfo::NONE); |
| 2101 __ movl(rax, Immediate(1)); |
| 2102 |
| 2103 Operand sp0 = Operand(rsp, 0); |
| 2104 |
| 2105 // Test 1. |
| 2106 __ movl(rdx, sp0); // Sanity check. |
| 2107 __ cmpl(rdx, Immediate(0x109)); |
| 2108 __ j(not_equal, &exit); |
| 2109 __ incq(rax); |
| 2110 |
| 2111 // Test 2. |
| 2112 // Zero to non-zero displacement. |
| 2113 __ movl(rdx, Operand(sp0, 2 * kPointerSize)); |
| 2114 __ cmpl(rdx, Immediate(0x107)); |
| 2115 __ j(not_equal, &exit); |
| 2116 __ incq(rax); |
| 2117 |
| 2118 Operand sp2 = Operand(rsp, 2 * kPointerSize); |
| 2119 |
| 2120 // Test 3. |
| 2121 __ movl(rdx, sp2); // Sanity check. |
| 2122 __ cmpl(rdx, Immediate(0x107)); |
| 2123 __ j(not_equal, &exit); |
| 2124 __ incq(rax); |
| 2125 |
| 2126 __ movl(rdx, Operand(sp2, 2 * kPointerSize)); |
| 2127 __ cmpl(rdx, Immediate(0x105)); |
| 2128 __ j(not_equal, &exit); |
| 2129 __ incq(rax); |
| 2130 |
| 2131 // Non-zero to zero displacement. |
| 2132 __ movl(rdx, Operand(sp2, -2 * kPointerSize)); |
| 2133 __ cmpl(rdx, Immediate(0x109)); |
| 2134 __ j(not_equal, &exit); |
| 2135 __ incq(rax); |
| 2136 |
| 2137 Operand sp2c2 = Operand(rsp, rcx, times_pointer_size, 2 * kPointerSize); |
| 2138 |
| 2139 // Test 6. |
| 2140 __ movl(rdx, sp2c2); // Sanity check. |
| 2141 __ cmpl(rdx, Immediate(0x105)); |
| 2142 __ j(not_equal, &exit); |
| 2143 __ incq(rax); |
| 2144 |
| 2145 __ movl(rdx, Operand(sp2c2, 2 * kPointerSize)); |
| 2146 __ cmpl(rdx, Immediate(0x103)); |
| 2147 __ j(not_equal, &exit); |
| 2148 __ incq(rax); |
| 2149 |
| 2150 // Non-zero to zero displacement. |
| 2151 __ movl(rdx, Operand(sp2c2, -2 * kPointerSize)); |
| 2152 __ cmpl(rdx, Immediate(0x107)); |
| 2153 __ j(not_equal, &exit); |
| 2154 __ incq(rax); |
| 2155 |
| 2156 |
| 2157 Operand bp0 = Operand(rbp, 0); |
| 2158 |
| 2159 // Test 9. |
| 2160 __ movl(rdx, bp0); // Sanity check. |
| 2161 __ cmpl(rdx, Immediate(0x100)); |
| 2162 __ j(not_equal, &exit); |
| 2163 __ incq(rax); |
| 2164 |
| 2165 // Zero to non-zero displacement. |
| 2166 __ movl(rdx, Operand(bp0, -2 * kPointerSize)); |
| 2167 __ cmpl(rdx, Immediate(0x102)); |
| 2168 __ j(not_equal, &exit); |
| 2169 __ incq(rax); |
| 2170 |
| 2171 Operand bp2 = Operand(rbp, -2 * kPointerSize); |
| 2172 |
| 2173 // Test 11. |
| 2174 __ movl(rdx, bp2); // Sanity check. |
| 2175 __ cmpl(rdx, Immediate(0x102)); |
| 2176 __ j(not_equal, &exit); |
| 2177 __ incq(rax); |
| 2178 |
| 2179 // Non-zero to zero displacement. |
| 2180 __ movl(rdx, Operand(bp2, 2 * kPointerSize)); |
| 2181 __ cmpl(rdx, Immediate(0x100)); |
| 2182 __ j(not_equal, &exit); |
| 2183 __ incq(rax); |
| 2184 |
| 2185 __ movl(rdx, Operand(bp2, -2 * kPointerSize)); |
| 2186 __ cmpl(rdx, Immediate(0x104)); |
| 2187 __ j(not_equal, &exit); |
| 2188 __ incq(rax); |
| 2189 |
| 2190 Operand bp2c4 = Operand(rbp, rcx, times_pointer_size, -4 * kPointerSize); |
| 2191 |
| 2192 // Test 14: |
| 2193 __ movl(rdx, bp2c4); // Sanity check. |
| 2194 __ cmpl(rdx, Immediate(0x102)); |
| 2195 __ j(not_equal, &exit); |
| 2196 __ incq(rax); |
| 2197 |
| 2198 __ movl(rdx, Operand(bp2c4, 2 * kPointerSize)); |
| 2199 __ cmpl(rdx, Immediate(0x100)); |
| 2200 __ j(not_equal, &exit); |
| 2201 __ incq(rax); |
| 2202 |
| 2203 __ movl(rdx, Operand(bp2c4, -2 * kPointerSize)); |
| 2204 __ cmpl(rdx, Immediate(0x104)); |
| 2205 __ j(not_equal, &exit); |
| 2206 __ incq(rax); |
| 2207 |
| 2208 Operand bx0 = Operand(rbx, 0); |
| 2209 |
| 2210 // Test 17. |
| 2211 __ movl(rdx, bx0); // Sanity check. |
| 2212 __ cmpl(rdx, Immediate(0x105)); |
| 2213 __ j(not_equal, &exit); |
| 2214 __ incq(rax); |
| 2215 |
| 2216 __ movl(rdx, Operand(bx0, 5 * kPointerSize)); |
| 2217 __ cmpl(rdx, Immediate(0x100)); |
| 2218 __ j(not_equal, &exit); |
| 2219 __ incq(rax); |
| 2220 |
| 2221 __ movl(rdx, Operand(bx0, -4 * kPointerSize)); |
| 2222 __ cmpl(rdx, Immediate(0x109)); |
| 2223 __ j(not_equal, &exit); |
| 2224 __ incq(rax); |
| 2225 |
| 2226 Operand bx2 = Operand(rbx, 2 * kPointerSize); |
| 2227 |
| 2228 // Test 20. |
| 2229 __ movl(rdx, bx2); // Sanity check. |
| 2230 __ cmpl(rdx, Immediate(0x103)); |
| 2231 __ j(not_equal, &exit); |
| 2232 __ incq(rax); |
| 2233 |
| 2234 __ movl(rdx, Operand(bx2, 2 * kPointerSize)); |
| 2235 __ cmpl(rdx, Immediate(0x101)); |
| 2236 __ j(not_equal, &exit); |
| 2237 __ incq(rax); |
| 2238 |
| 2239 // Non-zero to zero displacement. |
| 2240 __ movl(rdx, Operand(bx2, -2 * kPointerSize)); |
| 2241 __ cmpl(rdx, Immediate(0x105)); |
| 2242 __ j(not_equal, &exit); |
| 2243 __ incq(rax); |
| 2244 |
| 2245 Operand bx2c2 = Operand(rbx, rcx, times_pointer_size, -2 * kPointerSize); |
| 2246 |
| 2247 // Test 23. |
| 2248 __ movl(rdx, bx2c2); // Sanity check. |
| 2249 __ cmpl(rdx, Immediate(0x105)); |
| 2250 __ j(not_equal, &exit); |
| 2251 __ incq(rax); |
| 2252 |
| 2253 __ movl(rdx, Operand(bx2c2, 2 * kPointerSize)); |
| 2254 __ cmpl(rdx, Immediate(0x103)); |
| 2255 __ j(not_equal, &exit); |
| 2256 __ incq(rax); |
| 2257 |
| 2258 __ movl(rdx, Operand(bx2c2, -2 * kPointerSize)); |
| 2259 __ cmpl(rdx, Immediate(0x107)); |
| 2260 __ j(not_equal, &exit); |
| 2261 __ incq(rax); |
| 2262 |
| 2263 Operand r80 = Operand(r8, 0); |
| 2264 |
| 2265 // Test 26. |
| 2266 __ movl(rdx, r80); // Sanity check. |
| 2267 __ cmpl(rdx, Immediate(0x80808080)); |
| 2268 __ j(not_equal, &exit); |
| 2269 __ incq(rax); |
| 2270 |
| 2271 __ movl(rdx, Operand(r80, -8 * kIntSize)); |
| 2272 __ cmpl(rdx, Immediate(0x78787878)); |
| 2273 __ j(not_equal, &exit); |
| 2274 __ incq(rax); |
| 2275 |
| 2276 __ movl(rdx, Operand(r80, 8 * kIntSize)); |
| 2277 __ cmpl(rdx, Immediate(0x88888888)); |
| 2278 __ j(not_equal, &exit); |
| 2279 __ incq(rax); |
| 2280 |
| 2281 __ movl(rdx, Operand(r80, -64 * kIntSize)); |
| 2282 __ cmpl(rdx, Immediate(0x40404040)); |
| 2283 __ j(not_equal, &exit); |
| 2284 __ incq(rax); |
| 2285 |
| 2286 __ movl(rdx, Operand(r80, 64 * kIntSize)); |
| 2287 __ cmpl(rdx, Immediate(0xC0C0C0C0)); |
| 2288 __ j(not_equal, &exit); |
| 2289 __ incq(rax); |
| 2290 |
| 2291 Operand r88 = Operand(r8, 8 * kIntSize); |
| 2292 |
| 2293 // Test 31. |
| 2294 __ movl(rdx, r88); // Sanity check. |
| 2295 __ cmpl(rdx, Immediate(0x88888888)); |
| 2296 __ j(not_equal, &exit); |
| 2297 __ incq(rax); |
| 2298 |
| 2299 __ movl(rdx, Operand(r88, -8 * kIntSize)); |
| 2300 __ cmpl(rdx, Immediate(0x80808080)); |
| 2301 __ j(not_equal, &exit); |
| 2302 __ incq(rax); |
| 2303 |
| 2304 __ movl(rdx, Operand(r88, 8 * kIntSize)); |
| 2305 __ cmpl(rdx, Immediate(0x90909090)); |
| 2306 __ j(not_equal, &exit); |
| 2307 __ incq(rax); |
| 2308 |
| 2309 __ movl(rdx, Operand(r88, -64 * kIntSize)); |
| 2310 __ cmpl(rdx, Immediate(0x48484848)); |
| 2311 __ j(not_equal, &exit); |
| 2312 __ incq(rax); |
| 2313 |
| 2314 __ movl(rdx, Operand(r88, 64 * kIntSize)); |
| 2315 __ cmpl(rdx, Immediate(0xC8C8C8C8)); |
| 2316 __ j(not_equal, &exit); |
| 2317 __ incq(rax); |
| 2318 |
| 2319 |
| 2320 Operand r864 = Operand(r8, 64 * kIntSize); |
| 2321 |
| 2322 // Test 36. |
| 2323 __ movl(rdx, r864); // Sanity check. |
| 2324 __ cmpl(rdx, Immediate(0xC0C0C0C0)); |
| 2325 __ j(not_equal, &exit); |
| 2326 __ incq(rax); |
| 2327 |
| 2328 __ movl(rdx, Operand(r864, -8 * kIntSize)); |
| 2329 __ cmpl(rdx, Immediate(0xB8B8B8B8)); |
| 2330 __ j(not_equal, &exit); |
| 2331 __ incq(rax); |
| 2332 |
| 2333 __ movl(rdx, Operand(r864, 8 * kIntSize)); |
| 2334 __ cmpl(rdx, Immediate(0xC8C8C8C8)); |
| 2335 __ j(not_equal, &exit); |
| 2336 __ incq(rax); |
| 2337 |
| 2338 __ movl(rdx, Operand(r864, -64 * kIntSize)); |
| 2339 __ cmpl(rdx, Immediate(0x80808080)); |
| 2340 __ j(not_equal, &exit); |
| 2341 __ incq(rax); |
| 2342 |
| 2343 __ movl(rdx, Operand(r864, 32 * kIntSize)); |
| 2344 __ cmpl(rdx, Immediate(0xE0E0E0E0)); |
| 2345 __ j(not_equal, &exit); |
| 2346 __ incq(rax); |
| 2347 |
| 2348 // 32-bit offset to 8-bit offset. |
| 2349 __ movl(rdx, Operand(r864, -60 * kIntSize)); |
| 2350 __ cmpl(rdx, Immediate(0x84848484)); |
| 2351 __ j(not_equal, &exit); |
| 2352 __ incq(rax); |
| 2353 |
| 2354 __ movl(rdx, Operand(r864, 60 * kIntSize)); |
| 2355 __ cmpl(rdx, Immediate(0xFCFCFCFC)); |
| 2356 __ j(not_equal, &exit); |
| 2357 __ incq(rax); |
| 2358 |
| 2359 // Test unaligned offsets. |
| 2360 |
| 2361 // Test 43. |
| 2362 __ movl(rdx, Operand(r80, 2)); |
| 2363 __ cmpl(rdx, Immediate(0x81818080)); |
| 2364 __ j(not_equal, &exit); |
| 2365 __ incq(rax); |
| 2366 |
| 2367 __ movl(rdx, Operand(r80, -2)); |
| 2368 __ cmpl(rdx, Immediate(0x80807F7F)); |
| 2369 __ j(not_equal, &exit); |
| 2370 __ incq(rax); |
| 2371 |
| 2372 __ movl(rdx, Operand(r80, 126)); |
| 2373 __ cmpl(rdx, Immediate(0xA0A09F9F)); |
| 2374 __ j(not_equal, &exit); |
| 2375 __ incq(rax); |
| 2376 |
| 2377 __ movl(rdx, Operand(r80, -126)); |
| 2378 __ cmpl(rdx, Immediate(0x61616060)); |
| 2379 __ j(not_equal, &exit); |
| 2380 __ incq(rax); |
| 2381 |
| 2382 __ movl(rdx, Operand(r80, 254)); |
| 2383 __ cmpl(rdx, Immediate(0xC0C0BFBF)); |
| 2384 __ j(not_equal, &exit); |
| 2385 __ incq(rax); |
| 2386 |
| 2387 __ movl(rdx, Operand(r80, -254)); |
| 2388 __ cmpl(rdx, Immediate(0x41414040)); |
| 2389 __ j(not_equal, &exit); |
| 2390 __ incq(rax); |
| 2391 |
| 2392 // Success. |
| 2393 |
| 2394 __ movl(rax, Immediate(0)); |
| 2395 __ bind(&exit); |
| 2396 __ lea(rsp, Operand(rbp, kPointerSize)); |
| 2397 __ pop(rbp); |
| 2398 __ pop(rbx); |
| 2399 __ pop(r13); |
| 2400 __ pop(r12); |
| 2401 __ ret(0); |
| 2402 |
| 2403 |
| 2404 CodeDesc desc; |
| 2405 masm->GetCode(&desc); |
| 2406 // Call the function from C++. |
| 2407 int result = FUNCTION_CAST<F0>(buffer)(); |
| 2408 CHECK_EQ(0, result); |
| 2409 } |
| 2410 |
| 2411 |
| 2412 |
2056 #undef __ | 2413 #undef __ |
OLD | NEW |