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

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

Issue 115816: Add immediate operands and arithmetic operations to the x64 assembler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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
« no previous file with comments | « src/x64/assembler-x64-inl.h ('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 21 matching lines...) Expand all
32 #include "macro-assembler.h" 32 #include "macro-assembler.h"
33 #include "factory.h" 33 #include "factory.h"
34 #include "platform.h" 34 #include "platform.h"
35 #include "serialize.h" 35 #include "serialize.h"
36 #include "cctest.h" 36 #include "cctest.h"
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::Label; 43 using v8::internal::Label;
43 using v8::internal::rax; 44 using v8::internal::rax;
44 using v8::internal::rsi; 45 using v8::internal::rsi;
45 using v8::internal::rdi; 46 using v8::internal::rdi;
46 using v8::internal::rbp; 47 using v8::internal::rbp;
47 using v8::internal::rsp; 48 using v8::internal::rsp;
48 using v8::internal::FUNCTION_CAST; 49 using v8::internal::FUNCTION_CAST;
49 using v8::internal::CodeDesc; 50 using v8::internal::CodeDesc;
51 using v8::internal::less_equal;
52 using v8::internal::not_equal;
53 using v8::internal::greater;
50 54
51 55
52 // Test the x64 assembler by compiling some simple functions into 56 // Test the x64 assembler by compiling some simple functions into
53 // a buffer and executing them. These tests do not initialize the 57 // a buffer and executing them. These tests do not initialize the
54 // V8 library, create a context, or use any V8 objects. 58 // V8 library, create a context, or use any V8 objects.
55 // The AMD64 calling convention is used, with the first five arguments 59 // The AMD64 calling convention is used, with the first five arguments
56 // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in 60 // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in
57 // the XMM registers. The return value is in RAX. 61 // the XMM registers. The return value is in RAX.
58 // This calling convention is used on Linux, with GCC, and on Mac OS, 62 // This calling convention is used on Linux, with GCC, and on Mac OS,
59 // with GCC. A different convention is used on 64-bit windows. 63 // with GCC. A different convention is used on 64-bit windows.
60 64
61 typedef int (*F0)(); 65 typedef int (*F0)();
62 typedef int (*F1)(int x); 66 typedef int (*F1)(int x);
63 typedef int (*F2)(int x, int y); 67 typedef int (*F2)(int x, int y);
64 68
65 #define __ assm. 69 #define __ assm.
66 70
67 71
68 TEST(AssemblerX64ReturnOperation) { 72 TEST(AssemblerX64ReturnOperation) {
69 // Allocate an executable page of memory. 73 // Allocate an executable page of memory.
70 size_t actual_size; 74 size_t actual_size;
71 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 75 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
72 &actual_size, 76 &actual_size,
73 true)); 77 true));
74 CHECK(buffer); 78 CHECK(buffer);
75 Assembler assm(buffer, actual_size); 79 Assembler assm(buffer, actual_size);
76 80
77 // Assemble a simple function that copies argument 2 and returns it. 81 // Assemble a simple function that copies argument 2 and returns it.
78 __ mov(rax, rsi); 82 __ movq(rax, rsi);
79 __ nop(); 83 __ nop();
80 __ ret(0); 84 __ ret(0);
81 85
82 CodeDesc desc; 86 CodeDesc desc;
83 assm.GetCode(&desc); 87 assm.GetCode(&desc);
84 // Call the function from C++. 88 // Call the function from C++.
85 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 89 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
86 CHECK_EQ(2, result); 90 CHECK_EQ(2, result);
87 } 91 }
88 92
89 TEST(AssemblerX64StackOperations) { 93 TEST(AssemblerX64StackOperations) {
90 // Allocate an executable page of memory. 94 // Allocate an executable page of memory.
91 size_t actual_size; 95 size_t actual_size;
92 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 96 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
93 &actual_size, 97 &actual_size,
94 true)); 98 true));
95 CHECK(buffer); 99 CHECK(buffer);
96 Assembler assm(buffer, actual_size); 100 Assembler assm(buffer, actual_size);
97 101
98 // Assemble a simple function that copies argument 2 and returns it. 102 // Assemble a simple function that copies argument 2 and returns it.
99 // We compile without stack frame pointers, so the gdb debugger shows 103 // We compile without stack frame pointers, so the gdb debugger shows
100 // incorrect stack frames when debugging this function (which has them). 104 // incorrect stack frames when debugging this function (which has them).
101 __ push(rbp); 105 __ push(rbp);
102 __ mov(rbp, rsp); 106 __ movq(rbp, rsp);
103 __ push(rsi); // Value at (rbp - 8) 107 __ push(rsi); // Value at (rbp - 8)
104 __ push(rsi); // Value at (rbp - 16) 108 __ push(rsi); // Value at (rbp - 16)
105 __ push(rdi); // Value at (rbp - 24) 109 __ push(rdi); // Value at (rbp - 24)
106 __ pop(rax); 110 __ pop(rax);
107 __ pop(rax); 111 __ pop(rax);
108 __ pop(rax); 112 __ pop(rax);
109 __ pop(rbp); 113 __ pop(rbp);
110 __ nop(); 114 __ nop();
111 __ ret(0); 115 __ ret(0);
112 116
113 CodeDesc desc; 117 CodeDesc desc;
114 assm.GetCode(&desc); 118 assm.GetCode(&desc);
115 // Call the function from C++. 119 // Call the function from C++.
116 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 120 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
117 CHECK_EQ(2, result); 121 CHECK_EQ(2, result);
118 } 122 }
119 123
120 TEST(AssemblerX64ArithmeticOperations) { 124 TEST(AssemblerX64ArithmeticOperations) {
121 // Allocate an executable page of memory. 125 // Allocate an executable page of memory.
122 size_t actual_size; 126 size_t actual_size;
123 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 127 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
124 &actual_size, 128 &actual_size,
125 true)); 129 true));
126 CHECK(buffer); 130 CHECK(buffer);
127 Assembler assm(buffer, actual_size); 131 Assembler assm(buffer, actual_size);
128 132
129 // Assemble a simple function that copies argument 2 and returns it. 133 // Assemble a simple function that copies argument 2 and returns it.
130 __ mov(rax, rsi); 134 __ movq(rax, rsi);
131 __ add(rax, rdi); 135 __ add(rax, rdi);
132 __ ret(0); 136 __ ret(0);
133 137
134 CodeDesc desc; 138 CodeDesc desc;
135 assm.GetCode(&desc); 139 assm.GetCode(&desc);
136 // Call the function from C++. 140 // Call the function from C++.
137 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 141 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
138 CHECK_EQ(5, result); 142 CHECK_EQ(5, result);
139 } 143 }
140 144
141 TEST(AssemblerX64MemoryOperands) { 145 TEST(AssemblerX64MemoryOperands) {
142 // Allocate an executable page of memory. 146 // Allocate an executable page of memory.
143 size_t actual_size; 147 size_t actual_size;
144 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 148 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
145 &actual_size, 149 &actual_size,
146 true)); 150 true));
147 CHECK(buffer); 151 CHECK(buffer);
148 Assembler assm(buffer, actual_size); 152 Assembler assm(buffer, actual_size);
149 153
150 // Assemble a simple function that copies argument 2 and returns it. 154 // Assemble a simple function that copies argument 2 and returns it.
151 __ push(rbp); 155 __ push(rbp);
152 __ mov(rbp, rsp); 156 __ movq(rbp, rsp);
153 __ push(rsi); // Value at (rbp - 8) 157 __ push(rsi); // Value at (rbp - 8)
154 __ push(rsi); // Value at (rbp - 16) 158 __ push(rsi); // Value at (rbp - 16)
155 __ push(rdi); // Value at (rbp - 24) 159 __ push(rdi); // Value at (rbp - 24)
156 const int kStackElementSize = 8; 160 const int kStackElementSize = 8;
157 __ mov(rax, Operand(rbp, -3 * kStackElementSize)); 161 __ movq(rax, Operand(rbp, -3 * kStackElementSize));
158 __ pop(rsi); 162 __ pop(rsi);
159 __ pop(rsi); 163 __ pop(rsi);
160 __ pop(rsi); 164 __ pop(rsi);
161 __ pop(rbp); 165 __ pop(rbp);
162 __ nop(); 166 __ nop();
163 __ ret(0); 167 __ ret(0);
164 168
165 CodeDesc desc; 169 CodeDesc desc;
166 assm.GetCode(&desc); 170 assm.GetCode(&desc);
167 // Call the function from C++. 171 // Call the function from C++.
168 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 172 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
169 CHECK_EQ(3, result); 173 CHECK_EQ(3, result);
170 } 174 }
171 175
172 TEST(AssemblerX64ControlFlow) { 176 TEST(AssemblerX64ControlFlow) {
173 // Allocate an executable page of memory. 177 // Allocate an executable page of memory.
174 size_t actual_size; 178 size_t actual_size;
175 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 179 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
176 &actual_size, 180 &actual_size,
177 true)); 181 true));
178 CHECK(buffer); 182 CHECK(buffer);
179 Assembler assm(buffer, actual_size); 183 Assembler assm(buffer, actual_size);
180 184
181 // Assemble a simple function that copies argument 2 and returns it. 185 // Assemble a simple function that copies argument 2 and returns it.
182 __ push(rbp); 186 __ push(rbp);
183 __ mov(rbp, rsp); 187 __ movq(rbp, rsp);
184 __ mov(rax, rdi); 188 __ movq(rax, rdi);
185 Label target; 189 Label target;
186 __ jmp(&target); 190 __ jmp(&target);
187 __ mov(rax, rsi); 191 __ movq(rax, rsi);
188 __ bind(&target); 192 __ bind(&target);
189 __ pop(rbp); 193 __ pop(rbp);
190 __ ret(0); 194 __ ret(0);
191 195
192 CodeDesc desc; 196 CodeDesc desc;
193 assm.GetCode(&desc); 197 assm.GetCode(&desc);
194 // Call the function from C++. 198 // Call the function from C++.
195 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 199 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
196 CHECK_EQ(3, result); 200 CHECK_EQ(3, result);
197 } 201 }
198 202
203 TEST(AssemblerX64LoopImmediates) {
204 // Allocate an executable page of memory.
205 size_t actual_size;
206 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
207 &actual_size,
208 true));
209 CHECK(buffer);
210 Assembler assm(buffer, actual_size);
211 // Assemble two loops using rax as counter, and verify the ending counts.
212 Label Fail;
213 __ movq(rax, Immediate(-3));
214 Label Loop1_test;
215 Label Loop1_body;
216 __ jmp(&Loop1_test);
217 __ bind(&Loop1_body);
218 __ add(rax, Immediate(7));
219 __ bind(&Loop1_test);
220 __ cmp(rax, Immediate(20));
221 __ j(less_equal, &Loop1_body);
222 // Did the loop terminate with the expected value?
223 __ cmp(rax, Immediate(25));
224 __ j(not_equal, &Fail);
225
226 Label Loop2_test;
227 Label Loop2_body;
228 __ movq(rax, Immediate(0x11FEED00));
229 __ jmp(&Loop2_test);
230 __ bind(&Loop2_body);
231 __ add(rax, Immediate(-0x1100));
232 __ bind(&Loop2_test);
233 __ cmp(rax, Immediate(0x11FE8000));
234 __ j(greater, &Loop2_body);
235 // Did the loop terminate with the expected value?
236 __ cmp(rax, Immediate(0x11FE7600));
237 __ j(not_equal, &Fail);
238
239 __ movq(rax, Immediate(1));
240 __ ret(0);
241 __ bind(&Fail);
242 __ movq(rax, Immediate(0));
243 __ ret(0);
244
245 CodeDesc desc;
246 assm.GetCode(&desc);
247 // Call the function from C++.
248 int result = FUNCTION_CAST<F0>(buffer)();
249 CHECK_EQ(1, result);
250 }
199 #undef __ 251 #undef __
OLDNEW
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698