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

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

Issue 264047: X64: Fix bugs affecting Win64. (Closed)
Patch Set: Addressed review comments Created 11 years, 2 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
« no previous file with comments | « test/cctest/test-api.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 26 matching lines...) Expand all
37 37
38 using v8::internal::byte; 38 using v8::internal::byte;
39 using v8::internal::OS; 39 using v8::internal::OS;
40 using v8::internal::Assembler; 40 using v8::internal::Assembler;
41 using v8::internal::Operand; 41 using v8::internal::Operand;
42 using v8::internal::Immediate; 42 using v8::internal::Immediate;
43 using v8::internal::Label; 43 using v8::internal::Label;
44 using v8::internal::rax; 44 using v8::internal::rax;
45 using v8::internal::rsi; 45 using v8::internal::rsi;
46 using v8::internal::rdi; 46 using v8::internal::rdi;
47 using v8::internal::rcx;
47 using v8::internal::rdx; 48 using v8::internal::rdx;
48 using v8::internal::rbp; 49 using v8::internal::rbp;
49 using v8::internal::rsp; 50 using v8::internal::rsp;
50 using v8::internal::FUNCTION_CAST; 51 using v8::internal::FUNCTION_CAST;
51 using v8::internal::CodeDesc; 52 using v8::internal::CodeDesc;
52 using v8::internal::less_equal; 53 using v8::internal::less_equal;
53 using v8::internal::not_equal; 54 using v8::internal::not_equal;
54 using v8::internal::greater; 55 using v8::internal::greater;
55 56
56
57 // Test the x64 assembler by compiling some simple functions into 57 // Test the x64 assembler by compiling some simple functions into
58 // a buffer and executing them. These tests do not initialize the 58 // a buffer and executing them. These tests do not initialize the
59 // V8 library, create a context, or use any V8 objects. 59 // V8 library, create a context, or use any V8 objects.
60 // The AMD64 calling convention is used, with the first five arguments 60 // The AMD64 calling convention is used, with the first six arguments
61 // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in 61 // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in
62 // the XMM registers. The return value is in RAX. 62 // the XMM registers. The return value is in RAX.
63 // This calling convention is used on Linux, with GCC, and on Mac OS, 63 // This calling convention is used on Linux, with GCC, and on Mac OS,
64 // with GCC. A different convention is used on 64-bit windows. 64 // with GCC. A different convention is used on 64-bit windows,
65 // where the first four integer arguments are passed in RCX, RDX, R8 and R9.
65 66
66 typedef int (*F0)(); 67 typedef int (*F0)();
67 typedef int (*F1)(int64_t x); 68 typedef int (*F1)(int64_t x);
68 typedef int (*F2)(int64_t x, int64_t y); 69 typedef int (*F2)(int64_t x, int64_t y);
69 70
71 #ifdef _WIN64
72 static const v8::internal::Register arg1 = rcx;
73 static const v8::internal::Register arg2 = rdx;
74 #else
75 static const v8::internal::Register arg1 = rdi;
76 static const v8::internal::Register arg2 = rsi;
77 #endif
78
70 #define __ assm. 79 #define __ assm.
71 80
72 81
73 TEST(AssemblerX64ReturnOperation) { 82 TEST(AssemblerX64ReturnOperation) {
74 // Allocate an executable page of memory. 83 // Allocate an executable page of memory.
75 size_t actual_size; 84 size_t actual_size;
76 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 85 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
77 &actual_size, 86 &actual_size,
78 true)); 87 true));
79 CHECK(buffer); 88 CHECK(buffer);
80 Assembler assm(buffer, actual_size); 89 Assembler assm(buffer, actual_size);
81 90
82 // Assemble a simple function that copies argument 2 and returns it. 91 // Assemble a simple function that copies argument 2 and returns it.
83 __ movq(rax, rsi); 92 __ movq(rax, arg2);
84 __ nop(); 93 __ nop();
85 __ ret(0); 94 __ ret(0);
86 95
87 CodeDesc desc; 96 CodeDesc desc;
88 assm.GetCode(&desc); 97 assm.GetCode(&desc);
89 // Call the function from C++. 98 // Call the function from C++.
90 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 99 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
91 CHECK_EQ(2, result); 100 CHECK_EQ(2, result);
92 } 101 }
93 102
94 TEST(AssemblerX64StackOperations) { 103 TEST(AssemblerX64StackOperations) {
95 // Allocate an executable page of memory. 104 // Allocate an executable page of memory.
96 size_t actual_size; 105 size_t actual_size;
97 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 106 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
98 &actual_size, 107 &actual_size,
99 true)); 108 true));
100 CHECK(buffer); 109 CHECK(buffer);
101 Assembler assm(buffer, actual_size); 110 Assembler assm(buffer, actual_size);
102 111
103 // Assemble a simple function that copies argument 2 and returns it. 112 // Assemble a simple function that copies argument 2 and returns it.
104 // We compile without stack frame pointers, so the gdb debugger shows 113 // We compile without stack frame pointers, so the gdb debugger shows
105 // incorrect stack frames when debugging this function (which has them). 114 // incorrect stack frames when debugging this function (which has them).
106 __ push(rbp); 115 __ push(rbp);
107 __ movq(rbp, rsp); 116 __ movq(rbp, rsp);
117 #ifdef _WIN64
118 __ push(rdx); // Value at (rbp - 8)
119 __ push(rdx); // Value at (rbp - 16)
120 __ push(rcx); // Value at (rbp - 24)
121 #else
108 __ push(rsi); // Value at (rbp - 8) 122 __ push(rsi); // Value at (rbp - 8)
109 __ push(rsi); // Value at (rbp - 16) 123 __ push(rsi); // Value at (rbp - 16)
110 __ push(rdi); // Value at (rbp - 24) 124 __ push(rdi); // Value at (rbp - 24)
125 #endif
111 __ pop(rax); 126 __ pop(rax);
112 __ pop(rax); 127 __ pop(rax);
113 __ pop(rax); 128 __ pop(rax);
114 __ pop(rbp); 129 __ pop(rbp);
115 __ nop(); 130 __ nop();
116 __ ret(0); 131 __ ret(0);
117 132
118 CodeDesc desc; 133 CodeDesc desc;
119 assm.GetCode(&desc); 134 assm.GetCode(&desc);
120 // Call the function from C++. 135 // Call the function from C++.
121 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 136 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
122 CHECK_EQ(2, result); 137 CHECK_EQ(2, result);
123 } 138 }
124 139
125 TEST(AssemblerX64ArithmeticOperations) { 140 TEST(AssemblerX64ArithmeticOperations) {
126 // Allocate an executable page of memory. 141 // Allocate an executable page of memory.
127 size_t actual_size; 142 size_t actual_size;
128 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 143 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
129 &actual_size, 144 &actual_size,
130 true)); 145 true));
131 CHECK(buffer); 146 CHECK(buffer);
132 Assembler assm(buffer, actual_size); 147 Assembler assm(buffer, actual_size);
133 148
134 // Assemble a simple function that adds arguments returning the sum. 149 // Assemble a simple function that adds arguments returning the sum.
135 __ movq(rax, rsi); 150 __ movq(rax, arg2);
136 __ addq(rax, rdi); 151 __ addq(rax, arg1);
137 __ ret(0); 152 __ ret(0);
138 153
139 CodeDesc desc; 154 CodeDesc desc;
140 assm.GetCode(&desc); 155 assm.GetCode(&desc);
141 // Call the function from C++. 156 // Call the function from C++.
142 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 157 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
143 CHECK_EQ(5, result); 158 CHECK_EQ(5, result);
144 } 159 }
145 160
146 TEST(AssemblerX64ImulOperation) { 161 TEST(AssemblerX64ImulOperation) {
147 // Allocate an executable page of memory. 162 // Allocate an executable page of memory.
148 size_t actual_size; 163 size_t actual_size;
149 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 164 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
150 &actual_size, 165 &actual_size,
151 true)); 166 true));
152 CHECK(buffer); 167 CHECK(buffer);
153 Assembler assm(buffer, actual_size); 168 Assembler assm(buffer, actual_size);
154 169
155 // Assemble a simple function that multiplies arguments returning the high 170 // Assemble a simple function that multiplies arguments returning the high
156 // word. 171 // word.
157 __ movq(rax, rsi); 172 __ movq(rax, arg2);
158 __ imul(rdi); 173 __ imul(arg1);
159 __ movq(rax, rdx); 174 __ movq(rax, rdx);
160 __ ret(0); 175 __ ret(0);
161 176
162 CodeDesc desc; 177 CodeDesc desc;
163 assm.GetCode(&desc); 178 assm.GetCode(&desc);
164 // Call the function from C++. 179 // Call the function from C++.
165 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 180 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
166 CHECK_EQ(0, result); 181 CHECK_EQ(0, result);
167 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); 182 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l);
168 CHECK_EQ(1, result); 183 CHECK_EQ(1, result);
169 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); 184 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l);
170 CHECK_EQ(-1, result); 185 CHECK_EQ(-1, result);
171 } 186 }
172 187
173 TEST(AssemblerX64MemoryOperands) { 188 TEST(AssemblerX64MemoryOperands) {
174 // Allocate an executable page of memory. 189 // Allocate an executable page of memory.
175 size_t actual_size; 190 size_t actual_size;
176 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 191 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
177 &actual_size, 192 &actual_size,
178 true)); 193 true));
179 CHECK(buffer); 194 CHECK(buffer);
180 Assembler assm(buffer, actual_size); 195 Assembler assm(buffer, actual_size);
181 196
182 // Assemble a simple function that copies argument 2 and returns it. 197 // Assemble a simple function that copies argument 2 and returns it.
183 __ push(rbp); 198 __ push(rbp);
184 __ movq(rbp, rsp); 199 __ movq(rbp, rsp);
185 __ push(rsi); // Value at (rbp - 8) 200
186 __ push(rsi); // Value at (rbp - 16) 201 __ push(arg2); // Value at (rbp - 8)
187 __ push(rdi); // Value at (rbp - 24) 202 __ push(arg2); // Value at (rbp - 16)
203 __ push(arg1); // Value at (rbp - 24)
204
188 const int kStackElementSize = 8; 205 const int kStackElementSize = 8;
189 __ movq(rax, Operand(rbp, -3 * kStackElementSize)); 206 __ movq(rax, Operand(rbp, -3 * kStackElementSize));
190 __ pop(rsi); 207 __ pop(arg2);
191 __ pop(rsi); 208 __ pop(arg2);
192 __ pop(rsi); 209 __ pop(arg2);
193 __ pop(rbp); 210 __ pop(rbp);
194 __ nop(); 211 __ nop();
195 __ ret(0); 212 __ ret(0);
196 213
197 CodeDesc desc; 214 CodeDesc desc;
198 assm.GetCode(&desc); 215 assm.GetCode(&desc);
199 // Call the function from C++. 216 // Call the function from C++.
200 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 217 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
201 CHECK_EQ(3, result); 218 CHECK_EQ(3, result);
202 } 219 }
203 220
204 TEST(AssemblerX64ControlFlow) { 221 TEST(AssemblerX64ControlFlow) {
205 // Allocate an executable page of memory. 222 // Allocate an executable page of memory.
206 size_t actual_size; 223 size_t actual_size;
207 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 224 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
208 &actual_size, 225 &actual_size,
209 true)); 226 true));
210 CHECK(buffer); 227 CHECK(buffer);
211 Assembler assm(buffer, actual_size); 228 Assembler assm(buffer, actual_size);
212 229
213 // Assemble a simple function that copies argument 2 and returns it. 230 // Assemble a simple function that copies argument 1 and returns it.
214 __ push(rbp); 231 __ push(rbp);
232
215 __ movq(rbp, rsp); 233 __ movq(rbp, rsp);
216 __ movq(rax, rdi); 234 __ movq(rax, arg1);
217 Label target; 235 Label target;
218 __ jmp(&target); 236 __ jmp(&target);
219 __ movq(rax, rsi); 237 __ movq(rax, arg2);
220 __ bind(&target); 238 __ bind(&target);
221 __ pop(rbp); 239 __ pop(rbp);
222 __ ret(0); 240 __ ret(0);
223 241
224 CodeDesc desc; 242 CodeDesc desc;
225 assm.GetCode(&desc); 243 assm.GetCode(&desc);
226 // Call the function from C++. 244 // Call the function from C++.
227 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 245 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
228 CHECK_EQ(3, result); 246 CHECK_EQ(3, result);
229 } 247 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 __ ret(0); 289 __ ret(0);
272 290
273 CodeDesc desc; 291 CodeDesc desc;
274 assm.GetCode(&desc); 292 assm.GetCode(&desc);
275 // Call the function from C++. 293 // Call the function from C++.
276 int result = FUNCTION_CAST<F0>(buffer)(); 294 int result = FUNCTION_CAST<F0>(buffer)();
277 CHECK_EQ(1, result); 295 CHECK_EQ(1, result);
278 } 296 }
279 297
280 #undef __ 298 #undef __
OLDNEW
« no previous file with comments | « test/cctest/test-api.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698