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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // The AMD64 calling convention is used, with the first six arguments | 44 // The AMD64 calling convention is used, with the first six arguments |
45 // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in | 45 // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in |
46 // the XMM registers. The return value is in RAX. | 46 // the XMM registers. The return value is in RAX. |
47 // This calling convention is used on Linux, with GCC, and on Mac OS, | 47 // This calling convention is used on Linux, with GCC, and on Mac OS, |
48 // with GCC. A different convention is used on 64-bit windows, | 48 // with GCC. A different convention is used on 64-bit windows, |
49 // where the first four integer arguments are passed in RCX, RDX, R8 and R9. | 49 // where the first four integer arguments are passed in RCX, RDX, R8 and R9. |
50 | 50 |
51 typedef int (*F0)(); | 51 typedef int (*F0)(); |
52 typedef int (*F1)(int64_t x); | 52 typedef int (*F1)(int64_t x); |
53 typedef int (*F2)(int64_t x, int64_t y); | 53 typedef int (*F2)(int64_t x, int64_t y); |
54 typedef unsigned (*F3)(double x); | 54 typedef int (*F3)(double x); |
55 typedef uint64_t (*F4)(uint64_t* x, uint64_t* y); | 55 typedef int64_t (*F4)(int64_t* x, int64_t* y); |
56 typedef uint64_t (*F5)(uint64_t x); | 56 typedef int64_t (*F5)(int64_t x); |
57 | 57 |
58 #ifdef _WIN64 | 58 #ifdef _WIN64 |
59 static const Register arg1 = rcx; | 59 static const Register arg1 = rcx; |
60 static const Register arg2 = rdx; | 60 static const Register arg2 = rdx; |
61 #else | 61 #else |
62 static const Register arg1 = rdi; | 62 static const Register arg1 = rdi; |
63 static const Register arg2 = rsi; | 63 static const Register arg2 = rsi; |
64 #endif | 64 #endif |
65 | 65 |
66 #define __ assm. | 66 #define __ assm. |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 __ movq(rax, Operand(arg1, 0)); | 213 __ movq(rax, Operand(arg1, 0)); |
214 __ movq(r11, Operand(arg2, 0)); | 214 __ movq(r11, Operand(arg2, 0)); |
215 __ xchgl(rax, r11); | 215 __ xchgl(rax, r11); |
216 __ movq(Operand(arg1, 0), rax); | 216 __ movq(Operand(arg1, 0), rax); |
217 __ movq(Operand(arg2, 0), r11); | 217 __ movq(Operand(arg2, 0), r11); |
218 __ ret(0); | 218 __ ret(0); |
219 | 219 |
220 CodeDesc desc; | 220 CodeDesc desc; |
221 assm.GetCode(&desc); | 221 assm.GetCode(&desc); |
222 // Call the function from C++. | 222 // Call the function from C++. |
223 uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 223 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
224 uint64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); | 224 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); |
225 uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 225 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
226 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left); | 226 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left); |
227 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right); | 227 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right); |
228 USE(result); | 228 USE(result); |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 TEST(AssemblerX64OrlOperations) { | 232 TEST(AssemblerX64OrlOperations) { |
233 CcTest::InitializeVM(); | 233 CcTest::InitializeVM(); |
234 // Allocate an executable page of memory. | 234 // Allocate an executable page of memory. |
235 size_t actual_size; | 235 size_t actual_size; |
236 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( | 236 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
237 Assembler::kMinimalBufferSize, &actual_size, true)); | 237 Assembler::kMinimalBufferSize, &actual_size, true)); |
238 CHECK(buffer); | 238 CHECK(buffer); |
239 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 239 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
240 | 240 |
241 __ movq(rax, Operand(arg2, 0)); | 241 __ movq(rax, Operand(arg2, 0)); |
242 __ orl(Operand(arg1, 0), rax); | 242 __ orl(Operand(arg1, 0), rax); |
243 __ ret(0); | 243 __ ret(0); |
244 | 244 |
245 CodeDesc desc; | 245 CodeDesc desc; |
246 assm.GetCode(&desc); | 246 assm.GetCode(&desc); |
247 // Call the function from C++. | 247 // Call the function from C++. |
248 uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 248 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
249 uint64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); | 249 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); |
250 uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 250 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
251 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left); | 251 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left); |
252 USE(result); | 252 USE(result); |
253 } | 253 } |
254 | 254 |
255 | 255 |
256 TEST(AssemblerX64RollOperations) { | 256 TEST(AssemblerX64RollOperations) { |
257 CcTest::InitializeVM(); | 257 CcTest::InitializeVM(); |
258 // Allocate an executable page of memory. | 258 // Allocate an executable page of memory. |
259 size_t actual_size; | 259 size_t actual_size; |
260 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( | 260 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
261 Assembler::kMinimalBufferSize, &actual_size, true)); | 261 Assembler::kMinimalBufferSize, &actual_size, true)); |
262 CHECK(buffer); | 262 CHECK(buffer); |
263 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 263 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
264 | 264 |
265 __ movq(rax, arg1); | 265 __ movq(rax, arg1); |
266 __ roll(rax, Immediate(1)); | 266 __ roll(rax, Immediate(1)); |
267 __ ret(0); | 267 __ ret(0); |
268 | 268 |
269 CodeDesc desc; | 269 CodeDesc desc; |
270 assm.GetCode(&desc); | 270 assm.GetCode(&desc); |
271 // Call the function from C++. | 271 // Call the function from C++. |
272 uint64_t src = V8_2PART_UINT64_C(0x10000000, C0000000); | 272 int64_t src = V8_2PART_UINT64_C(0x10000000, C0000000); |
273 uint64_t result = FUNCTION_CAST<F5>(buffer)(src); | 273 int64_t result = FUNCTION_CAST<F5>(buffer)(src); |
274 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result); | 274 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result); |
275 } | 275 } |
276 | 276 |
277 | 277 |
278 TEST(AssemblerX64SublOperations) { | 278 TEST(AssemblerX64SublOperations) { |
279 CcTest::InitializeVM(); | 279 CcTest::InitializeVM(); |
280 // Allocate an executable page of memory. | 280 // Allocate an executable page of memory. |
281 size_t actual_size; | 281 size_t actual_size; |
282 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( | 282 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
283 Assembler::kMinimalBufferSize, &actual_size, true)); | 283 Assembler::kMinimalBufferSize, &actual_size, true)); |
284 CHECK(buffer); | 284 CHECK(buffer); |
285 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 285 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
286 | 286 |
287 __ movq(rax, Operand(arg2, 0)); | 287 __ movq(rax, Operand(arg2, 0)); |
288 __ subl(Operand(arg1, 0), rax); | 288 __ subl(Operand(arg1, 0), rax); |
289 __ ret(0); | 289 __ ret(0); |
290 | 290 |
291 CodeDesc desc; | 291 CodeDesc desc; |
292 assm.GetCode(&desc); | 292 assm.GetCode(&desc); |
293 // Call the function from C++. | 293 // Call the function from C++. |
294 uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 294 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
295 uint64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); | 295 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); |
296 uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 296 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
297 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left); | 297 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left); |
298 USE(result); | 298 USE(result); |
299 } | 299 } |
300 | 300 |
301 | 301 |
302 TEST(AssemblerX64TestlOperations) { | 302 TEST(AssemblerX64TestlOperations) { |
303 CcTest::InitializeVM(); | 303 CcTest::InitializeVM(); |
304 // Allocate an executable page of memory. | 304 // Allocate an executable page of memory. |
305 size_t actual_size; | 305 size_t actual_size; |
306 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( | 306 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
307 Assembler::kMinimalBufferSize, &actual_size, true)); | 307 Assembler::kMinimalBufferSize, &actual_size, true)); |
308 CHECK(buffer); | 308 CHECK(buffer); |
309 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 309 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
310 | 310 |
311 // Set rax with the ZF flag of the testl instruction. | 311 // Set rax with the ZF flag of the testl instruction. |
312 Label done; | 312 Label done; |
313 __ movq(rax, Immediate(1)); | 313 __ movq(rax, Immediate(1)); |
314 __ movq(r11, Operand(arg2, 0)); | 314 __ movq(r11, Operand(arg2, 0)); |
315 __ testl(Operand(arg1, 0), r11); | 315 __ testl(Operand(arg1, 0), r11); |
316 __ j(zero, &done, Label::kNear); | 316 __ j(zero, &done, Label::kNear); |
317 __ movq(rax, Immediate(0)); | 317 __ movq(rax, Immediate(0)); |
318 __ bind(&done); | 318 __ bind(&done); |
319 __ ret(0); | 319 __ ret(0); |
320 | 320 |
321 CodeDesc desc; | 321 CodeDesc desc; |
322 assm.GetCode(&desc); | 322 assm.GetCode(&desc); |
323 // Call the function from C++. | 323 // Call the function from C++. |
324 uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 324 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
325 uint64_t right = V8_2PART_UINT64_C(0x30000000, 00000000); | 325 int64_t right = V8_2PART_UINT64_C(0x30000000, 00000000); |
326 uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 326 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
327 CHECK_EQ(1u, result); | 327 CHECK_EQ(static_cast<int64_t>(1), result); |
328 } | 328 } |
329 | 329 |
330 | 330 |
331 TEST(AssemblerX64XorlOperations) { | 331 TEST(AssemblerX64XorlOperations) { |
332 CcTest::InitializeVM(); | 332 CcTest::InitializeVM(); |
333 // Allocate an executable page of memory. | 333 // Allocate an executable page of memory. |
334 size_t actual_size; | 334 size_t actual_size; |
335 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( | 335 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
336 Assembler::kMinimalBufferSize, &actual_size, true)); | 336 Assembler::kMinimalBufferSize, &actual_size, true)); |
337 CHECK(buffer); | 337 CHECK(buffer); |
338 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 338 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
339 | 339 |
340 __ movq(rax, Operand(arg2, 0)); | 340 __ movq(rax, Operand(arg2, 0)); |
341 __ xorl(Operand(arg1, 0), rax); | 341 __ xorl(Operand(arg1, 0), rax); |
342 __ ret(0); | 342 __ ret(0); |
343 | 343 |
344 CodeDesc desc; | 344 CodeDesc desc; |
345 assm.GetCode(&desc); | 345 assm.GetCode(&desc); |
346 // Call the function from C++. | 346 // Call the function from C++. |
347 uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 347 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
348 uint64_t right = V8_2PART_UINT64_C(0x30000000, 60000000); | 348 int64_t right = V8_2PART_UINT64_C(0x30000000, 60000000); |
349 uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 349 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
350 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left); | 350 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left); |
351 USE(result); | 351 USE(result); |
352 } | 352 } |
353 | 353 |
354 | 354 |
355 TEST(AssemblerX64MemoryOperands) { | 355 TEST(AssemblerX64MemoryOperands) { |
356 CcTest::InitializeVM(); | 356 CcTest::InitializeVM(); |
357 // Allocate an executable page of memory. | 357 // Allocate an executable page of memory. |
358 size_t actual_size; | 358 size_t actual_size; |
359 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( | 359 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 Handle<Code> code = isolate->factory()->NewCode( | 579 Handle<Code> code = isolate->factory()->NewCode( |
580 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 580 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
581 | 581 |
582 F0 f = FUNCTION_CAST<F0>(code->entry()); | 582 F0 f = FUNCTION_CAST<F0>(code->entry()); |
583 int res = f(); | 583 int res = f(); |
584 CHECK_EQ(42, res); | 584 CHECK_EQ(42, res); |
585 } | 585 } |
586 | 586 |
587 | 587 |
588 #ifdef __GNUC__ | 588 #ifdef __GNUC__ |
589 #define ELEMENT_COUNT 4u | 589 #define ELEMENT_COUNT 4 |
590 | 590 |
591 void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { | 591 void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { |
592 v8::HandleScope scope(CcTest::isolate()); | 592 v8::HandleScope scope(CcTest::isolate()); |
593 byte buffer[1024]; | 593 byte buffer[1024]; |
594 | 594 |
595 CHECK(args[0]->IsArray()); | 595 CHECK(args[0]->IsArray()); |
596 v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); | 596 v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); |
597 CHECK_EQ(ELEMENT_COUNT, vec->Length()); | 597 CHECK_EQ(ELEMENT_COUNT, vec->Length()); |
598 | 598 |
599 Isolate* isolate = CcTest::i_isolate(); | 599 Isolate* isolate = CcTest::i_isolate(); |
600 Assembler assm(isolate, buffer, sizeof(buffer)); | 600 Assembler assm(isolate, buffer, sizeof(buffer)); |
601 | 601 |
602 // Remove return address from the stack for fix stack frame alignment. | 602 // Remove return address from the stack for fix stack frame alignment. |
603 __ popq(rcx); | 603 __ popq(rcx); |
604 | 604 |
605 // Store input vector on the stack. | 605 // Store input vector on the stack. |
606 for (unsigned i = 0; i < ELEMENT_COUNT; i++) { | 606 for (int i = 0; i < ELEMENT_COUNT; i++) { |
607 __ movl(rax, Immediate(vec->Get(i)->Int32Value())); | 607 __ movl(rax, Immediate(vec->Get(i)->Int32Value())); |
608 __ shlq(rax, Immediate(0x20)); | 608 __ shlq(rax, Immediate(0x20)); |
609 __ orq(rax, Immediate(vec->Get(++i)->Int32Value())); | 609 __ orq(rax, Immediate(vec->Get(++i)->Int32Value())); |
610 __ pushq(rax); | 610 __ pushq(rax); |
611 } | 611 } |
612 | 612 |
613 // Read vector into a xmm register. | 613 // Read vector into a xmm register. |
614 __ xorps(xmm0, xmm0); | 614 __ xorps(xmm0, xmm0); |
615 __ movdqa(xmm0, Operand(rsp, 0)); | 615 __ movdqa(xmm0, Operand(rsp, 0)); |
616 // Create mask and store it in the return register. | 616 // Create mask and store it in the return register. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 "function foo(vec) {" | 650 "function foo(vec) {" |
651 " return do_sse2(vec);" | 651 " return do_sse2(vec);" |
652 "}"); | 652 "}"); |
653 | 653 |
654 v8::Local<v8::Object> global_object = env->Global(); | 654 v8::Local<v8::Object> global_object = env->Global(); |
655 v8::Local<v8::Function> foo = | 655 v8::Local<v8::Function> foo = |
656 v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); | 656 v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); |
657 | 657 |
658 int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; | 658 int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; |
659 v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); | 659 v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); |
660 for (unsigned i = 0; i < ELEMENT_COUNT; i++) { | 660 for (int i = 0; i < ELEMENT_COUNT; i++) { |
661 v8_vec->Set(i, v8_num(vec[i])); | 661 v8_vec->Set(i, v8_num(vec[i])); |
662 } | 662 } |
663 | 663 |
664 v8::Local<v8::Value> args[] = { v8_vec }; | 664 v8::Local<v8::Value> args[] = { v8_vec }; |
665 v8::Local<v8::Value> result = foo->Call(global_object, 1, args); | 665 v8::Local<v8::Value> result = foo->Call(global_object, 1, args); |
666 | 666 |
667 // The mask should be 0b1000. | 667 // The mask should be 0b1000. |
668 CHECK_EQ(8, result->Int32Value()); | 668 CHECK_EQ(8, result->Int32Value()); |
669 } | 669 } |
670 | 670 |
(...skipping 18 matching lines...) Expand all Loading... |
689 assm.GetCode(&desc); | 689 assm.GetCode(&desc); |
690 Handle<Code> code = isolate->factory()->NewCode( | 690 Handle<Code> code = isolate->factory()->NewCode( |
691 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 691 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
692 #ifdef OBJECT_PRINT | 692 #ifdef OBJECT_PRINT |
693 OFStream os(stdout); | 693 OFStream os(stdout); |
694 code->Print(os); | 694 code->Print(os); |
695 #endif | 695 #endif |
696 | 696 |
697 F3 f = FUNCTION_CAST<F3>(code->entry()); | 697 F3 f = FUNCTION_CAST<F3>(code->entry()); |
698 uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321); | 698 uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321); |
699 CHECK_EQ(0x12345678u, f(uint64_to_double(value1))); | 699 CHECK_EQ(0x12345678, f(uint64_to_double(value1))); |
700 uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678); | 700 uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678); |
701 CHECK_EQ(0x87654321u, f(uint64_to_double(value2))); | 701 CHECK_EQ(0x87654321, f(uint64_to_double(value2))); |
702 } | 702 } |
703 | 703 |
704 | 704 |
705 typedef int (*F6)(float x, float y); | 705 typedef int (*F6)(float x, float y); |
706 TEST(AssemblerX64SSE) { | 706 TEST(AssemblerX64SSE) { |
707 CcTest::InitializeVM(); | 707 CcTest::InitializeVM(); |
708 | 708 |
709 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); | 709 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); |
710 HandleScope scope(isolate); | 710 HandleScope scope(isolate); |
711 v8::internal::byte buffer[256]; | 711 v8::internal::byte buffer[256]; |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 1180 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
1181 #ifdef OBJECT_PRINT | 1181 #ifdef OBJECT_PRINT |
1182 OFStream os(stdout); | 1182 OFStream os(stdout); |
1183 code->Print(os); | 1183 code->Print(os); |
1184 #endif | 1184 #endif |
1185 | 1185 |
1186 F8 f = FUNCTION_CAST<F8>(code->entry()); | 1186 F8 f = FUNCTION_CAST<F8>(code->entry()); |
1187 CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f)); | 1187 CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f)); |
1188 } | 1188 } |
1189 #undef __ | 1189 #undef __ |
OLD | NEW |