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

Side by Side Diff: test/cctest/test-macro-assembler-arm.cc

Issue 2546933002: [Turbofan] Add ARM NEON instructions for implementing SIMD. (Closed)
Patch Set: Review comments. Created 4 years 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
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 24 matching lines...) Expand all
35 #include "src/arm/macro-assembler-arm.h" 35 #include "src/arm/macro-assembler-arm.h"
36 #include "src/arm/simulator-arm.h" 36 #include "src/arm/simulator-arm.h"
37 37
38 38
39 using namespace v8::internal; 39 using namespace v8::internal;
40 40
41 typedef void* (*F)(int x, int y, int p2, int p3, int p4); 41 typedef void* (*F)(int x, int y, int p2, int p3, int p4);
42 42
43 #define __ masm-> 43 #define __ masm->
44 44
45 typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
45 typedef int (*F5)(void*, void*, void*, void*, void*); 46 typedef int (*F5)(void*, void*, void*, void*, void*);
46 47
47 48
48 TEST(LoadAndStoreWithRepresentation) { 49 TEST(LoadAndStoreWithRepresentation) {
49 // Allocate an executable page of memory. 50 // Allocate an executable page of memory.
50 size_t actual_size; 51 size_t actual_size;
51 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 52 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
52 Assembler::kMinimalBufferSize, &actual_size, true)); 53 Assembler::kMinimalBufferSize, &actual_size, true));
53 CHECK(buffer); 54 CHECK(buffer);
54 Isolate* isolate = CcTest::i_isolate(); 55 Isolate* isolate = CcTest::i_isolate();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 CodeDesc desc; 128 CodeDesc desc;
128 masm->GetCode(&desc); 129 masm->GetCode(&desc);
129 Handle<Code> code = isolate->factory()->NewCode( 130 Handle<Code> code = isolate->factory()->NewCode(
130 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 131 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
131 132
132 // Call the function from C++. 133 // Call the function from C++.
133 F5 f = FUNCTION_CAST<F5>(code->entry()); 134 F5 f = FUNCTION_CAST<F5>(code->entry());
134 CHECK(!CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); 135 CHECK(!CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
135 } 136 }
136 137
138 TEST(ExtractLane) {
139 if (!CpuFeatures::IsSupported(NEON)) return;
140
141 // Allocate an executable page of memory.
142 size_t actual_size;
143 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
144 Assembler::kMinimalBufferSize, &actual_size, true));
145 CHECK(buffer);
146 Isolate* isolate = CcTest::i_isolate();
147 HandleScope handles(isolate);
148 MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
149 v8::internal::CodeObjectRequired::kYes);
150 MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
151
152 typedef struct {
153 int32_t i32x4_low[4];
154 int32_t i32x4_high[4];
155 int32_t i16x8_low[8];
156 int32_t i16x8_high[8];
157 int32_t i8x16_low[16];
158 int32_t i8x16_high[16];
159 int32_t f32x4_low[4];
160 int32_t f32x4_high[4];
161 } T;
162 T t;
163
164 __ stm(db_w, sp, r4.bit() | r5.bit() | lr.bit());
165
166 for (int i = 0; i < 4; i++) {
167 __ mov(r4, Operand(i));
168 __ vdup(q1, r4, Neon32);
169 __ ExtractLane(r5, q1, NeonS32, i);
170 __ str(r5, MemOperand(r0, offsetof(T, i32x4_low) + 4 * i));
171 SwVfpRegister si = SwVfpRegister::from_code(i);
172 __ ExtractLane(si, q1, r4, i);
173 __ vstr(si, r0, offsetof(T, f32x4_low) + 4 * i);
174 }
175
176 for (int i = 0; i < 8; i++) {
177 __ mov(r4, Operand(i));
178 __ vdup(q1, r4, Neon16);
179 __ ExtractLane(r5, q1, NeonS16, i);
180 __ str(r5, MemOperand(r0, offsetof(T, i16x8_low) + 4 * i));
181 }
182
183 for (int i = 0; i < 16; i++) {
184 __ mov(r4, Operand(i));
185 __ vdup(q1, r4, Neon8);
186 __ ExtractLane(r5, q1, NeonS8, i);
187 __ str(r5, MemOperand(r0, offsetof(T, i8x16_low) + 4 * i));
188 }
189
190 if (CpuFeatures::IsSupported(VFP32DREGS)) {
191 for (int i = 0; i < 4; i++) {
192 __ mov(r4, Operand(-i));
193 __ vdup(q15, r4, Neon32);
194 __ ExtractLane(r5, q15, NeonS32, i);
195 __ str(r5, MemOperand(r0, offsetof(T, i32x4_high) + 4 * i));
196 SwVfpRegister si = SwVfpRegister::from_code(i);
197 __ ExtractLane(si, q15, r4, i);
198 __ vstr(si, r0, offsetof(T, f32x4_high) + 4 * i);
199 }
200
201 for (int i = 0; i < 8; i++) {
202 __ mov(r4, Operand(-i));
203 __ vdup(q15, r4, Neon16);
204 __ ExtractLane(r5, q15, NeonS16, i);
205 __ str(r5, MemOperand(r0, offsetof(T, i16x8_high) + 4 * i));
206 }
207
208 for (int i = 0; i < 16; i++) {
209 __ mov(r4, Operand(-i));
210 __ vdup(q15, r4, Neon8);
211 __ ExtractLane(r5, q15, NeonS8, i);
212 __ str(r5, MemOperand(r0, offsetof(T, i8x16_high) + 4 * i));
213 }
214 }
215
216 __ ldm(ia_w, sp, r4.bit() | r5.bit() | pc.bit());
217 __ bx(lr);
Rodolph Perfetta (ARM) 2016/12/08 18:08:28 nit: this is not necessary, the line above loaded
bbudge 2016/12/10 21:33:05 Done.
218
219 CodeDesc desc;
220 masm->GetCode(&desc);
221 Handle<Code> code = isolate->factory()->NewCode(
222 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
223 #ifdef DEBUG
224 OFStream os(stdout);
225 code->Print(os);
226 #endif
227 F3 f = FUNCTION_CAST<F3>(code->entry());
228 Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
229 USE(dummy);
230 for (int i = 0; i < 4; i++) {
231 CHECK_EQ(i, t.i32x4_low[i]);
232 CHECK_EQ(i, t.f32x4_low[i]);
233 }
234 for (int i = 0; i < 8; i++) {
235 CHECK_EQ(i, t.i16x8_low[i]);
236 }
237 for (int i = 0; i < 16; i++) {
238 CHECK_EQ(i, t.i8x16_low[i]);
239 }
240 if (CpuFeatures::IsSupported(VFP32DREGS)) {
241 for (int i = 0; i < 4; i++) {
242 CHECK_EQ(-i, t.i32x4_high[i]);
243 CHECK_EQ(-i, t.f32x4_high[i]);
244 }
245 for (int i = 0; i < 8; i++) {
246 CHECK_EQ(-i, t.i16x8_high[i]);
247 }
248 for (int i = 0; i < 16; i++) {
249 CHECK_EQ(-i, t.i8x16_high[i]);
250 }
251 }
252 }
253
254 TEST(ReplaceLane) {
255 if (!CpuFeatures::IsSupported(NEON)) return;
256
257 // Allocate an executable page of memory.
258 size_t actual_size;
259 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
260 Assembler::kMinimalBufferSize, &actual_size, true));
261 CHECK(buffer);
262 Isolate* isolate = CcTest::i_isolate();
263 HandleScope handles(isolate);
264 MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
265 v8::internal::CodeObjectRequired::kYes);
266 MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
267
268 typedef struct {
269 int32_t i32x4_low[4];
270 int32_t i32x4_high[4];
271 int16_t i16x8_low[8];
272 int16_t i16x8_high[8];
273 int8_t i8x16_low[16];
274 int8_t i8x16_high[16];
275 int32_t f32x4_low[4];
276 int32_t f32x4_high[4];
277 } T;
278 T t;
279
280 __ stm(db_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | lr.bit());
281
282 const Register kScratch = r5;
283
284 __ veor(q0, q0, q0); // Zero
285 __ veor(q1, q1, q1); // Zero
286 for (int i = 0; i < 4; i++) {
287 __ mov(r4, Operand(i));
288 __ ReplaceLane(q0, q0, r4, kScratch, NeonS32, i);
289 SwVfpRegister si = SwVfpRegister::from_code(i);
290 __ vmov(si, r4);
291 __ ReplaceLane(q1, q1, si, kScratch, i);
292 }
293 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i32x4_low))));
294 __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
295 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, f32x4_low))));
296 __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
297
298 __ veor(q0, q0, q0); // Zero
299 for (int i = 0; i < 8; i++) {
300 __ mov(r4, Operand(i));
301 __ ReplaceLane(q0, q0, r4, kScratch, NeonS16, i);
302 }
303 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i16x8_low))));
304 __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
305
306 __ veor(q0, q0, q0); // Zero
307 for (int i = 0; i < 16; i++) {
308 __ mov(r4, Operand(i));
309 __ ReplaceLane(q0, q0, r4, kScratch, NeonS8, i);
310 }
311 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i8x16_low))));
312 __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
313
314 if (CpuFeatures::IsSupported(VFP32DREGS)) {
315 __ veor(q14, q14, q14); // Zero
316 __ veor(q15, q15, q15); // Zero
317 for (int i = 0; i < 4; i++) {
318 __ mov(r4, Operand(-i));
319 __ ReplaceLane(q14, q14, r4, kScratch, NeonS32, i);
320 SwVfpRegister si = SwVfpRegister::from_code(i);
321 __ vmov(si, r4);
322 __ ReplaceLane(q15, q15, si, kScratch, i);
323 }
324 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i32x4_high))));
325 __ vst1(Neon8, NeonListOperand(q14), NeonMemOperand(r4));
326 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, f32x4_high))));
327 __ vst1(Neon8, NeonListOperand(q15), NeonMemOperand(r4));
328
329 __ veor(q14, q14, q14); // Zero
330 for (int i = 0; i < 8; i++) {
331 __ mov(r4, Operand(-i));
332 __ ReplaceLane(q14, q14, r4, kScratch, NeonS16, i);
333 }
334 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i16x8_high))));
335 __ vst1(Neon8, NeonListOperand(q14), NeonMemOperand(r4));
336
337 __ veor(q14, q14, q14); // Zero
338 for (int i = 0; i < 16; i++) {
339 __ mov(r4, Operand(-i));
340 __ ReplaceLane(q14, q14, r4, kScratch, NeonS8, i);
341 }
342 __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i8x16_high))));
343 __ vst1(Neon8, NeonListOperand(q14), NeonMemOperand(r4));
344 }
345
346 __ ldm(ia_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | pc.bit());
347 __ bx(lr);
bbudge 2016/12/10 21:33:04 And here.
348
349 CodeDesc desc;
350 masm->GetCode(&desc);
351 Handle<Code> code = isolate->factory()->NewCode(
352 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
353 #ifdef DEBUG
354 OFStream os(stdout);
355 code->Print(os);
356 #endif
357 F3 f = FUNCTION_CAST<F3>(code->entry());
358 Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
359 USE(dummy);
360 for (int i = 0; i < 4; i++) {
361 CHECK_EQ(i, t.i32x4_low[i]);
362 CHECK_EQ(i, t.f32x4_low[i]);
363 }
364 for (int i = 0; i < 8; i++) {
365 CHECK_EQ(i, t.i16x8_low[i]);
366 }
367 for (int i = 0; i < 16; i++) {
368 CHECK_EQ(i, t.i8x16_low[i]);
369 }
370 if (CpuFeatures::IsSupported(VFP32DREGS)) {
371 for (int i = 0; i < 4; i++) {
372 CHECK_EQ(-i, t.i32x4_high[i]);
373 CHECK_EQ(-i, t.f32x4_high[i]);
374 }
375 for (int i = 0; i < 8; i++) {
376 CHECK_EQ(-i, t.i16x8_high[i]);
377 }
378 for (int i = 0; i < 16; i++) {
379 CHECK_EQ(-i, t.i8x16_high[i]);
380 }
381 }
382 }
383
137 #undef __ 384 #undef __
OLDNEW
« test/cctest/test-disasm-arm.cc ('K') | « test/cctest/test-disasm-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698