| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 | 100 |
| 101 | 101 |
| 102 ASSEMBLER_TEST_RUN(AddressingModes, test) { | 102 ASSEMBLER_TEST_RUN(AddressingModes, test) { |
| 103 // Avoid running the code since it is constructed to lead to crashes. | 103 // Avoid running the code since it is constructed to lead to crashes. |
| 104 } | 104 } |
| 105 | 105 |
| 106 | 106 |
| 107 ASSEMBLER_TEST_GENERATE(JumpAroundCrash, assembler) { | 107 ASSEMBLER_TEST_GENERATE(JumpAroundCrash, assembler) { |
| 108 Label done; | 108 Label done; |
| 109 // Make sure all the condition jumps work. | 109 // Make sure all the condition jumps work. |
| 110 for (Condition condition = OVERFLOW; | 110 for (Condition condition = OVERFLOW; condition <= GREATER; |
| 111 condition <= GREATER; | |
| 112 condition = static_cast<Condition>(condition + 1)) { | 111 condition = static_cast<Condition>(condition + 1)) { |
| 113 __ j(condition, &done); | 112 __ j(condition, &done); |
| 114 } | 113 } |
| 115 // This isn't strictly necessary, but we do an unconditional | 114 // This isn't strictly necessary, but we do an unconditional |
| 116 // jump around the crashing code anyway. | 115 // jump around the crashing code anyway. |
| 117 __ jmp(&done); | 116 __ jmp(&done); |
| 118 | 117 |
| 119 // Be sure to skip this crashing code. | 118 // Be sure to skip this crashing code. |
| 120 __ movl(EAX, Immediate(0)); | 119 __ movl(EAX, Immediate(0)); |
| 121 __ movl(Address(EAX, 0), EAX); | 120 __ movl(Address(EAX, 0), EAX); |
| 122 | 121 |
| 123 __ Bind(&done); | 122 __ Bind(&done); |
| 124 __ ret(); | 123 __ ret(); |
| 125 } | 124 } |
| 126 | 125 |
| 127 | 126 |
| 128 ASSEMBLER_TEST_RUN(JumpAroundCrash, test) { | 127 ASSEMBLER_TEST_RUN(JumpAroundCrash, test) { |
| 129 Instr* instr = Instr::At(test->entry()); | 128 Instr* instr = Instr::At(test->entry()); |
| 130 EXPECT(!instr->IsBreakPoint()); | 129 EXPECT(!instr->IsBreakPoint()); |
| 131 typedef void (*JumpAroundCrashCode)(); | 130 typedef void (*JumpAroundCrashCode)(); |
| 132 reinterpret_cast<JumpAroundCrashCode>(test->entry())(); | 131 reinterpret_cast<JumpAroundCrashCode>(test->entry())(); |
| 133 } | 132 } |
| 134 | 133 |
| 135 | 134 |
| 136 ASSEMBLER_TEST_GENERATE(NearJumpAroundCrash, assembler) { | 135 ASSEMBLER_TEST_GENERATE(NearJumpAroundCrash, assembler) { |
| 137 Label done; | 136 Label done; |
| 138 // Make sure all the condition jumps work. | 137 // Make sure all the condition jumps work. |
| 139 for (Condition condition = OVERFLOW; | 138 for (Condition condition = OVERFLOW; condition <= GREATER; |
| 140 condition <= GREATER; | |
| 141 condition = static_cast<Condition>(condition + 1)) { | 139 condition = static_cast<Condition>(condition + 1)) { |
| 142 __ j(condition, &done, Assembler::kNearJump); | 140 __ j(condition, &done, Assembler::kNearJump); |
| 143 } | 141 } |
| 144 // This isn't strictly necessary, but we do an unconditional | 142 // This isn't strictly necessary, but we do an unconditional |
| 145 // jump around the crashing code anyway. | 143 // jump around the crashing code anyway. |
| 146 __ jmp(&done, Assembler::kNearJump); | 144 __ jmp(&done, Assembler::kNearJump); |
| 147 | 145 |
| 148 // Be sure to skip this crashing code. | 146 // Be sure to skip this crashing code. |
| 149 __ movl(EAX, Immediate(0)); | 147 __ movl(EAX, Immediate(0)); |
| 150 __ movl(Address(EAX, 0), EAX); | 148 __ movl(Address(EAX, 0), EAX); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 EXPECT_EQ(1, call(3)); | 350 EXPECT_EQ(1, call(3)); |
| 353 EXPECT_EQ(2, call(4)); | 351 EXPECT_EQ(2, call(4)); |
| 354 EXPECT_EQ(5, call(42)); | 352 EXPECT_EQ(5, call(42)); |
| 355 EXPECT_EQ(31, call(-1)); | 353 EXPECT_EQ(31, call(-1)); |
| 356 } | 354 } |
| 357 | 355 |
| 358 | 356 |
| 359 ASSEMBLER_TEST_GENERATE(MoveExtend, assembler) { | 357 ASSEMBLER_TEST_GENERATE(MoveExtend, assembler) { |
| 360 __ pushl(EBX); // preserve EBX. | 358 __ pushl(EBX); // preserve EBX. |
| 361 __ movl(EDX, Immediate(0x1234ffff)); | 359 __ movl(EDX, Immediate(0x1234ffff)); |
| 362 __ movzxb(EAX, DL); // EAX = 0xff | 360 __ movzxb(EAX, DL); // EAX = 0xff |
| 363 __ movsxw(EBX, EDX); // EBX = -1 | 361 __ movsxw(EBX, EDX); // EBX = -1 |
| 364 __ movzxw(ECX, EDX); // ECX = 0xffff | 362 __ movzxw(ECX, EDX); // ECX = 0xffff |
| 365 __ addl(EBX, ECX); | 363 __ addl(EBX, ECX); |
| 366 __ addl(EAX, EBX); | 364 __ addl(EAX, EBX); |
| 367 __ popl(EBX); // restore EBX. | 365 __ popl(EBX); // restore EBX. |
| 368 __ ret(); | 366 __ ret(); |
| 369 } | 367 } |
| 370 | 368 |
| 371 | 369 |
| 372 ASSEMBLER_TEST_RUN(MoveExtend, test) { | 370 ASSEMBLER_TEST_RUN(MoveExtend, test) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 402 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { | 400 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { |
| 403 __ movl(ECX, Immediate(42)); | 401 __ movl(ECX, Immediate(42)); |
| 404 __ xorl(ECX, ECX); | 402 __ xorl(ECX, ECX); |
| 405 __ orl(ECX, Immediate(0x100)); | 403 __ orl(ECX, Immediate(0x100)); |
| 406 __ movl(EAX, Immediate(0x648)); | 404 __ movl(EAX, Immediate(0x648)); |
| 407 __ orl(ECX, EAX); // 0x748. | 405 __ orl(ECX, EAX); // 0x748. |
| 408 __ movl(EAX, Immediate(0xfff0)); | 406 __ movl(EAX, Immediate(0xfff0)); |
| 409 __ andl(ECX, EAX); // 0x740. | 407 __ andl(ECX, EAX); // 0x740. |
| 410 __ pushl(Immediate(0xF6FF)); | 408 __ pushl(Immediate(0xF6FF)); |
| 411 __ andl(ECX, Address(ESP, 0)); // 0x640. | 409 __ andl(ECX, Address(ESP, 0)); // 0x640. |
| 412 __ popl(EAX); // Discard. | 410 __ popl(EAX); // Discard. |
| 413 __ movl(EAX, Immediate(1)); | 411 __ movl(EAX, Immediate(1)); |
| 414 __ orl(ECX, EAX); // 0x641. | 412 __ orl(ECX, EAX); // 0x641. |
| 415 __ pushl(Immediate(0x7)); | 413 __ pushl(Immediate(0x7)); |
| 416 __ orl(ECX, Address(ESP, 0)); // 0x647. | 414 __ orl(ECX, Address(ESP, 0)); // 0x647. |
| 417 __ popl(EAX); // Discard. | 415 __ popl(EAX); // Discard. |
| 418 __ xorl(ECX, Immediate(0)); // 0x647. | 416 __ xorl(ECX, Immediate(0)); // 0x647. |
| 419 __ pushl(Immediate(0x1C)); | 417 __ pushl(Immediate(0x1C)); |
| 420 __ xorl(ECX, Address(ESP, 0)); // 0x65B. | 418 __ xorl(ECX, Address(ESP, 0)); // 0x65B. |
| 421 __ popl(EAX); // Discard. | 419 __ popl(EAX); // Discard. |
| 422 __ movl(EAX, Address(ESP, kWordSize)); | 420 __ movl(EAX, Address(ESP, kWordSize)); |
| 423 __ movl(EDX, Immediate(0xB0)); | 421 __ movl(EDX, Immediate(0xB0)); |
| 424 __ orl(Address(EAX, 0), EDX); | 422 __ orl(Address(EAX, 0), EDX); |
| 425 __ movl(EAX, ECX); | 423 __ movl(EAX, ECX); |
| 426 __ ret(); | 424 __ ret(); |
| 427 } | 425 } |
| 428 | 426 |
| 429 | 427 |
| 430 ASSEMBLER_TEST_RUN(Bitwise, test) { | 428 ASSEMBLER_TEST_RUN(Bitwise, test) { |
| 431 typedef int (*Bitwise)(int* value); | 429 typedef int (*Bitwise)(int* value); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 | 767 |
| 770 | 768 |
| 771 ASSEMBLER_TEST_RUN(Exchange, test) { | 769 ASSEMBLER_TEST_RUN(Exchange, test) { |
| 772 typedef int (*Exchange)(); | 770 typedef int (*Exchange)(); |
| 773 EXPECT_EQ(987654321 - 123456789, reinterpret_cast<Exchange>(test->entry())()); | 771 EXPECT_EQ(987654321 - 123456789, reinterpret_cast<Exchange>(test->entry())()); |
| 774 } | 772 } |
| 775 | 773 |
| 776 | 774 |
| 777 static int ComputeStackSpaceReservation(int needed, int fixed) { | 775 static int ComputeStackSpaceReservation(int needed, int fixed) { |
| 778 return (OS::ActivationFrameAlignment() > 1) | 776 return (OS::ActivationFrameAlignment() > 1) |
| 779 ? Utils::RoundUp(needed + fixed, OS::ActivationFrameAlignment()) - fixed | 777 ? Utils::RoundUp(needed + fixed, OS::ActivationFrameAlignment()) - |
| 780 : needed; | 778 fixed |
| 779 : needed; |
| 781 } | 780 } |
| 782 | 781 |
| 783 | 782 |
| 784 static int LeafReturn42() { | 783 static int LeafReturn42() { |
| 785 return 42; | 784 return 42; |
| 786 } | 785 } |
| 787 | 786 |
| 788 | 787 |
| 789 static int LeafReturnArgument(int x) { | 788 static int LeafReturnArgument(int x) { |
| 790 return x + 87; | 789 return x + 87; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 } | 872 } |
| 874 | 873 |
| 875 | 874 |
| 876 ASSEMBLER_TEST_RUN(SingleFPMoves, test) { | 875 ASSEMBLER_TEST_RUN(SingleFPMoves, test) { |
| 877 typedef float (*SingleFPMovesCode)(); | 876 typedef float (*SingleFPMovesCode)(); |
| 878 float res = reinterpret_cast<SingleFPMovesCode>(test->entry())(); | 877 float res = reinterpret_cast<SingleFPMovesCode>(test->entry())(); |
| 879 EXPECT_EQ(234.0f, res); | 878 EXPECT_EQ(234.0f, res); |
| 880 } | 879 } |
| 881 | 880 |
| 882 | 881 |
| 883 | |
| 884 ASSEMBLER_TEST_GENERATE(SingleFPMoves2, assembler) { | 882 ASSEMBLER_TEST_GENERATE(SingleFPMoves2, assembler) { |
| 885 __ pushl(EBX); // preserve EBX. | 883 __ pushl(EBX); // preserve EBX. |
| 886 __ pushl(ECX); // preserve ECX. | 884 __ pushl(ECX); // preserve ECX. |
| 887 __ movl(EBX, Immediate(bit_cast<int32_t, float>(234.0f))); | 885 __ movl(EBX, Immediate(bit_cast<int32_t, float>(234.0f))); |
| 888 __ movd(XMM0, EBX); | 886 __ movd(XMM0, EBX); |
| 889 __ movss(XMM1, XMM0); | 887 __ movss(XMM1, XMM0); |
| 890 __ movd(ECX, XMM1); | 888 __ movd(ECX, XMM1); |
| 891 __ pushl(ECX); | 889 __ pushl(ECX); |
| 892 __ flds(Address(ESP, 0)); | 890 __ flds(Address(ESP, 0)); |
| 893 __ popl(EAX); | 891 __ popl(EAX); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 } | 946 } |
| 949 | 947 |
| 950 | 948 |
| 951 ASSEMBLER_TEST_GENERATE(PackedFPOperations, assembler) { | 949 ASSEMBLER_TEST_GENERATE(PackedFPOperations, assembler) { |
| 952 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 950 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 953 __ movd(XMM0, EAX); | 951 __ movd(XMM0, EAX); |
| 954 __ shufps(XMM0, XMM0, Immediate(0x0)); | 952 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 955 __ movl(EAX, Immediate(bit_cast<int32_t, float>(3.4f))); | 953 __ movl(EAX, Immediate(bit_cast<int32_t, float>(3.4f))); |
| 956 __ movd(XMM1, EAX); | 954 __ movd(XMM1, EAX); |
| 957 __ shufps(XMM1, XMM1, Immediate(0x0)); | 955 __ shufps(XMM1, XMM1, Immediate(0x0)); |
| 958 __ addps(XMM0, XMM1); // 15.7f | 956 __ addps(XMM0, XMM1); // 15.7f |
| 959 __ mulps(XMM0, XMM1); // 53.38f | 957 __ mulps(XMM0, XMM1); // 53.38f |
| 960 __ subps(XMM0, XMM1); // 49.98f | 958 __ subps(XMM0, XMM1); // 49.98f |
| 961 __ divps(XMM0, XMM1); // 14.7f | 959 __ divps(XMM0, XMM1); // 14.7f |
| 962 __ shufps(XMM0, XMM0, Immediate(0x55)); // Copy second lane into all 4 lanes. | 960 __ shufps(XMM0, XMM0, Immediate(0x55)); // Copy second lane into all 4 lanes. |
| 963 __ pushl(EAX); | 961 __ pushl(EAX); |
| 964 // Copy the low lane at ESP. | 962 // Copy the low lane at ESP. |
| 965 __ movss(Address(ESP, 0), XMM0); | 963 __ movss(Address(ESP, 0), XMM0); |
| 966 __ flds(Address(ESP, 0)); | 964 __ flds(Address(ESP, 0)); |
| 967 __ popl(EAX); | 965 __ popl(EAX); |
| 968 __ ret(); | 966 __ ret(); |
| 969 } | 967 } |
| 970 | 968 |
| 971 | 969 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 999 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); | 997 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); |
| 1000 EXPECT_EQ(static_cast<uword>(0x5), res); | 998 EXPECT_EQ(static_cast<uword>(0x5), res); |
| 1001 } | 999 } |
| 1002 | 1000 |
| 1003 | 1001 |
| 1004 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) { | 1002 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) { |
| 1005 __ movl(EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 1003 __ movl(EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1006 __ movd(XMM0, EAX); | 1004 __ movd(XMM0, EAX); |
| 1007 __ shufps(XMM0, XMM0, Immediate(0x0)); | 1005 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 1008 | 1006 |
| 1009 __ movaps(XMM1, XMM0); // Copy XMM0 | 1007 __ movaps(XMM1, XMM0); // Copy XMM0 |
| 1010 __ reciprocalps(XMM1); // 0.25 | 1008 __ reciprocalps(XMM1); // 0.25 |
| 1011 __ sqrtps(XMM1); // 0.5 | 1009 __ sqrtps(XMM1); // 0.5 |
| 1012 __ rsqrtps(XMM0); // ~0.5 | 1010 __ rsqrtps(XMM0); // ~0.5 |
| 1013 __ subps(XMM0, XMM1); // ~0.0 | 1011 __ subps(XMM0, XMM1); // ~0.0 |
| 1014 __ shufps(XMM0, XMM0, Immediate(0x00)); // Copy second lane into all 4 lanes. | 1012 __ shufps(XMM0, XMM0, Immediate(0x00)); // Copy second lane into all 4 lanes. |
| 1015 __ pushl(EAX); | 1013 __ pushl(EAX); |
| 1016 // Copy the low lane at ESP. | 1014 // Copy the low lane at ESP. |
| 1017 __ movss(Address(ESP, 0), XMM0); | 1015 __ movss(Address(ESP, 0), XMM0); |
| 1018 __ flds(Address(ESP, 0)); | 1016 __ flds(Address(ESP, 0)); |
| 1019 __ popl(EAX); | 1017 __ popl(EAX); |
| 1020 __ ret(); | 1018 __ ret(); |
| 1021 } | 1019 } |
| 1022 | 1020 |
| 1023 | 1021 |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 EXPECT_FLOAT_EQ(4.0f, res, 0.001f); | 1249 EXPECT_FLOAT_EQ(4.0f, res, 0.001f); |
| 1252 } | 1250 } |
| 1253 | 1251 |
| 1254 | 1252 |
| 1255 ASSEMBLER_TEST_GENERATE(PackedLogicalOr, assembler) { | 1253 ASSEMBLER_TEST_GENERATE(PackedLogicalOr, assembler) { |
| 1256 static const struct ALIGN16 { | 1254 static const struct ALIGN16 { |
| 1257 uint32_t a; | 1255 uint32_t a; |
| 1258 uint32_t b; | 1256 uint32_t b; |
| 1259 uint32_t c; | 1257 uint32_t c; |
| 1260 uint32_t d; | 1258 uint32_t d; |
| 1261 } constant1 = | 1259 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; |
| 1262 { 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0 }; | |
| 1263 static const struct ALIGN16 { | 1260 static const struct ALIGN16 { |
| 1264 uint32_t a; | 1261 uint32_t a; |
| 1265 uint32_t b; | 1262 uint32_t b; |
| 1266 uint32_t c; | 1263 uint32_t c; |
| 1267 uint32_t d; | 1264 uint32_t d; |
| 1268 } constant2 = | 1265 } constant2 = {0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; |
| 1269 { 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F }; | |
| 1270 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1266 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1271 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant2))); | 1267 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant2))); |
| 1272 __ orps(XMM0, XMM1); | 1268 __ orps(XMM0, XMM1); |
| 1273 // Copy the low lane at ESP. | 1269 // Copy the low lane at ESP. |
| 1274 __ pushl(EAX); | 1270 __ pushl(EAX); |
| 1275 __ movss(Address(ESP, 0), XMM0); | 1271 __ movss(Address(ESP, 0), XMM0); |
| 1276 __ flds(Address(ESP, 0)); | 1272 __ flds(Address(ESP, 0)); |
| 1277 __ popl(EAX); | 1273 __ popl(EAX); |
| 1278 __ ret(); | 1274 __ ret(); |
| 1279 } | 1275 } |
| 1280 | 1276 |
| 1281 | 1277 |
| 1282 ASSEMBLER_TEST_RUN(PackedLogicalOr, test) { | 1278 ASSEMBLER_TEST_RUN(PackedLogicalOr, test) { |
| 1283 typedef uint32_t (*PackedLogicalOrCode)(); | 1279 typedef uint32_t (*PackedLogicalOrCode)(); |
| 1284 uint32_t res = reinterpret_cast<PackedLogicalOrCode>(test->entry())(); | 1280 uint32_t res = reinterpret_cast<PackedLogicalOrCode>(test->entry())(); |
| 1285 EXPECT_EQ(0xFFFFFFFF, res); | 1281 EXPECT_EQ(0xFFFFFFFF, res); |
| 1286 } | 1282 } |
| 1287 | 1283 |
| 1288 | 1284 |
| 1289 ASSEMBLER_TEST_GENERATE(PackedLogicalAnd, assembler) { | 1285 ASSEMBLER_TEST_GENERATE(PackedLogicalAnd, assembler) { |
| 1290 static const struct ALIGN16 { | 1286 static const struct ALIGN16 { |
| 1291 uint32_t a; | 1287 uint32_t a; |
| 1292 uint32_t b; | 1288 uint32_t b; |
| 1293 uint32_t c; | 1289 uint32_t c; |
| 1294 uint32_t d; | 1290 uint32_t d; |
| 1295 } constant1 = | 1291 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; |
| 1296 { 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0 }; | |
| 1297 static const struct ALIGN16 { | 1292 static const struct ALIGN16 { |
| 1298 uint32_t a; | 1293 uint32_t a; |
| 1299 uint32_t b; | 1294 uint32_t b; |
| 1300 uint32_t c; | 1295 uint32_t c; |
| 1301 uint32_t d; | 1296 uint32_t d; |
| 1302 } constant2 = | 1297 } constant2 = {0x0F0FFF0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; |
| 1303 { 0x0F0FFF0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F }; | |
| 1304 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1298 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1305 __ andps(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant2))); | 1299 __ andps(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant2))); |
| 1306 // Copy the low lane at ESP. | 1300 // Copy the low lane at ESP. |
| 1307 __ pushl(EAX); | 1301 __ pushl(EAX); |
| 1308 __ movss(Address(ESP, 0), XMM0); | 1302 __ movss(Address(ESP, 0), XMM0); |
| 1309 __ flds(Address(ESP, 0)); | 1303 __ flds(Address(ESP, 0)); |
| 1310 __ popl(EAX); | 1304 __ popl(EAX); |
| 1311 __ ret(); | 1305 __ ret(); |
| 1312 } | 1306 } |
| 1313 | 1307 |
| 1314 | 1308 |
| 1315 ASSEMBLER_TEST_RUN(PackedLogicalAnd, test) { | 1309 ASSEMBLER_TEST_RUN(PackedLogicalAnd, test) { |
| 1316 typedef uint32_t (*PackedLogicalAndCode)(); | 1310 typedef uint32_t (*PackedLogicalAndCode)(); |
| 1317 uint32_t res = reinterpret_cast<PackedLogicalAndCode>(test->entry())(); | 1311 uint32_t res = reinterpret_cast<PackedLogicalAndCode>(test->entry())(); |
| 1318 EXPECT_EQ(static_cast<uword>(0x0000F000), res); | 1312 EXPECT_EQ(static_cast<uword>(0x0000F000), res); |
| 1319 } | 1313 } |
| 1320 | 1314 |
| 1321 | 1315 |
| 1322 ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) { | 1316 ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) { |
| 1323 static const struct ALIGN16 { | 1317 static const struct ALIGN16 { |
| 1324 uint32_t a; | 1318 uint32_t a; |
| 1325 uint32_t b; | 1319 uint32_t b; |
| 1326 uint32_t c; | 1320 uint32_t c; |
| 1327 uint32_t d; | 1321 uint32_t d; |
| 1328 } constant1 = | 1322 } constant1 = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; |
| 1329 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; | |
| 1330 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1323 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1331 __ notps(XMM0); | 1324 __ notps(XMM0); |
| 1332 // Copy the low lane at ESP. | 1325 // Copy the low lane at ESP. |
| 1333 __ pushl(EAX); | 1326 __ pushl(EAX); |
| 1334 __ movss(Address(ESP, 0), XMM0); | 1327 __ movss(Address(ESP, 0), XMM0); |
| 1335 __ flds(Address(ESP, 0)); | 1328 __ flds(Address(ESP, 0)); |
| 1336 __ popl(EAX); | 1329 __ popl(EAX); |
| 1337 __ ret(); | 1330 __ ret(); |
| 1338 } | 1331 } |
| 1339 | 1332 |
| 1340 | 1333 |
| 1341 ASSEMBLER_TEST_RUN(PackedLogicalNot, test) { | 1334 ASSEMBLER_TEST_RUN(PackedLogicalNot, test) { |
| 1342 typedef uint32_t (*PackedLogicalNotCode)(); | 1335 typedef uint32_t (*PackedLogicalNotCode)(); |
| 1343 uint32_t res = reinterpret_cast<PackedLogicalNotCode>(test->entry())(); | 1336 uint32_t res = reinterpret_cast<PackedLogicalNotCode>(test->entry())(); |
| 1344 EXPECT_EQ(static_cast<uword>(0x0), res); | 1337 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1345 } | 1338 } |
| 1346 | 1339 |
| 1347 | 1340 |
| 1348 ASSEMBLER_TEST_GENERATE(PackedMoveHighLow, assembler) { | 1341 ASSEMBLER_TEST_GENERATE(PackedMoveHighLow, assembler) { |
| 1349 static const struct ALIGN16 { | 1342 static const struct ALIGN16 { |
| 1350 float a; | 1343 float a; |
| 1351 float b; | 1344 float b; |
| 1352 float c; | 1345 float c; |
| 1353 float d; | 1346 float d; |
| 1354 } constant0 = { 1.0, 2.0, 3.0, 4.0 }; | 1347 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1355 static const struct ALIGN16 { | 1348 static const struct ALIGN16 { |
| 1356 float a; | 1349 float a; |
| 1357 float b; | 1350 float b; |
| 1358 float c; | 1351 float c; |
| 1359 float d; | 1352 float d; |
| 1360 } constant1 = { 5.0, 6.0, 7.0, 8.0 }; | 1353 } constant1 = {5.0, 6.0, 7.0, 8.0}; |
| 1361 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. | 1354 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. |
| 1362 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1355 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1363 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. | 1356 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. |
| 1364 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1357 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1365 // XMM0 = 7.0f, 8.0f, 3.0f, 4.0f. | 1358 // XMM0 = 7.0f, 8.0f, 3.0f, 4.0f. |
| 1366 __ movhlps(XMM0, XMM1); | 1359 __ movhlps(XMM0, XMM1); |
| 1367 __ xorps(XMM1, XMM1); | 1360 __ xorps(XMM1, XMM1); |
| 1368 // XMM1 = 7.0f, 8.0f, 3.0f, 4.0f. | 1361 // XMM1 = 7.0f, 8.0f, 3.0f, 4.0f. |
| 1369 __ movaps(XMM1, XMM0); | 1362 __ movaps(XMM1, XMM0); |
| 1370 __ shufps(XMM0, XMM0, Immediate(0x00)); // 7.0f. | 1363 __ shufps(XMM0, XMM0, Immediate(0x00)); // 7.0f. |
| 1371 __ shufps(XMM1, XMM1, Immediate(0x55)); // 8.0f. | 1364 __ shufps(XMM1, XMM1, Immediate(0x55)); // 8.0f. |
| 1372 __ addss(XMM0, XMM1); // 15.0f. | 1365 __ addss(XMM0, XMM1); // 15.0f. |
| 1373 __ pushl(EAX); | 1366 __ pushl(EAX); |
| 1374 __ movss(Address(ESP, 0), XMM0); | 1367 __ movss(Address(ESP, 0), XMM0); |
| 1375 __ flds(Address(ESP, 0)); | 1368 __ flds(Address(ESP, 0)); |
| 1376 __ popl(EAX); | 1369 __ popl(EAX); |
| 1377 __ ret(); | 1370 __ ret(); |
| 1378 } | 1371 } |
| 1379 | 1372 |
| 1380 | 1373 |
| 1381 ASSEMBLER_TEST_RUN(PackedMoveHighLow, test) { | 1374 ASSEMBLER_TEST_RUN(PackedMoveHighLow, test) { |
| 1382 typedef float (*PackedMoveHighLow)(); | 1375 typedef float (*PackedMoveHighLow)(); |
| 1383 float res = reinterpret_cast<PackedMoveHighLow>(test->entry())(); | 1376 float res = reinterpret_cast<PackedMoveHighLow>(test->entry())(); |
| 1384 EXPECT_FLOAT_EQ(15.0f, res, 0.001f); | 1377 EXPECT_FLOAT_EQ(15.0f, res, 0.001f); |
| 1385 } | 1378 } |
| 1386 | 1379 |
| 1387 | 1380 |
| 1388 ASSEMBLER_TEST_GENERATE(PackedMoveLowHigh, assembler) { | 1381 ASSEMBLER_TEST_GENERATE(PackedMoveLowHigh, assembler) { |
| 1389 static const struct ALIGN16 { | 1382 static const struct ALIGN16 { |
| 1390 float a; | 1383 float a; |
| 1391 float b; | 1384 float b; |
| 1392 float c; | 1385 float c; |
| 1393 float d; | 1386 float d; |
| 1394 } constant0 = { 1.0, 2.0, 3.0, 4.0 }; | 1387 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1395 static const struct ALIGN16 { | 1388 static const struct ALIGN16 { |
| 1396 float a; | 1389 float a; |
| 1397 float b; | 1390 float b; |
| 1398 float c; | 1391 float c; |
| 1399 float d; | 1392 float d; |
| 1400 } constant1 = { 5.0, 6.0, 7.0, 8.0 }; | 1393 } constant1 = {5.0, 6.0, 7.0, 8.0}; |
| 1401 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. | 1394 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. |
| 1402 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1395 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1403 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. | 1396 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. |
| 1404 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1397 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1405 // XMM0 = 1.0f, 2.0f, 5.0f, 6.0f | 1398 // XMM0 = 1.0f, 2.0f, 5.0f, 6.0f |
| 1406 __ movlhps(XMM0, XMM1); | 1399 __ movlhps(XMM0, XMM1); |
| 1407 __ xorps(XMM1, XMM1); | 1400 __ xorps(XMM1, XMM1); |
| 1408 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f | 1401 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f |
| 1409 __ movaps(XMM1, XMM0); | 1402 __ movaps(XMM1, XMM0); |
| 1410 __ shufps(XMM0, XMM0, Immediate(0xAA)); // 5.0f. | 1403 __ shufps(XMM0, XMM0, Immediate(0xAA)); // 5.0f. |
| 1411 __ shufps(XMM1, XMM1, Immediate(0xFF)); // 6.0f. | 1404 __ shufps(XMM1, XMM1, Immediate(0xFF)); // 6.0f. |
| 1412 __ addss(XMM0, XMM1); // 11.0f. | 1405 __ addss(XMM0, XMM1); // 11.0f. |
| 1413 __ pushl(EAX); | 1406 __ pushl(EAX); |
| 1414 __ movss(Address(ESP, 0), XMM0); | 1407 __ movss(Address(ESP, 0), XMM0); |
| 1415 __ flds(Address(ESP, 0)); | 1408 __ flds(Address(ESP, 0)); |
| 1416 __ popl(EAX); | 1409 __ popl(EAX); |
| 1417 __ ret(); | 1410 __ ret(); |
| 1418 } | 1411 } |
| 1419 | 1412 |
| 1420 | 1413 |
| 1421 ASSEMBLER_TEST_RUN(PackedMoveLowHigh, test) { | 1414 ASSEMBLER_TEST_RUN(PackedMoveLowHigh, test) { |
| 1422 typedef float (*PackedMoveLowHigh)(); | 1415 typedef float (*PackedMoveLowHigh)(); |
| 1423 float res = reinterpret_cast<PackedMoveLowHigh>(test->entry())(); | 1416 float res = reinterpret_cast<PackedMoveLowHigh>(test->entry())(); |
| 1424 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); | 1417 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); |
| 1425 } | 1418 } |
| 1426 | 1419 |
| 1427 | 1420 |
| 1428 ASSEMBLER_TEST_GENERATE(PackedUnpackLow, assembler) { | 1421 ASSEMBLER_TEST_GENERATE(PackedUnpackLow, assembler) { |
| 1429 static const struct ALIGN16 { | 1422 static const struct ALIGN16 { |
| 1430 float a; | 1423 float a; |
| 1431 float b; | 1424 float b; |
| 1432 float c; | 1425 float c; |
| 1433 float d; | 1426 float d; |
| 1434 } constant0 = { 1.0, 2.0, 3.0, 4.0 }; | 1427 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1435 static const struct ALIGN16 { | 1428 static const struct ALIGN16 { |
| 1436 float a; | 1429 float a; |
| 1437 float b; | 1430 float b; |
| 1438 float c; | 1431 float c; |
| 1439 float d; | 1432 float d; |
| 1440 } constant1 = { 5.0, 6.0, 7.0, 8.0 }; | 1433 } constant1 = {5.0, 6.0, 7.0, 8.0}; |
| 1441 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. | 1434 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. |
| 1442 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1435 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1443 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. | 1436 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. |
| 1444 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1437 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1445 // XMM0 = 1.0f, 5.0f, 2.0f, 6.0f. | 1438 // XMM0 = 1.0f, 5.0f, 2.0f, 6.0f. |
| 1446 __ unpcklps(XMM0, XMM1); | 1439 __ unpcklps(XMM0, XMM1); |
| 1447 // XMM1 = 1.0f, 5.0f, 2.0f, 6.0f. | 1440 // XMM1 = 1.0f, 5.0f, 2.0f, 6.0f. |
| 1448 __ movaps(XMM1, XMM0); | 1441 __ movaps(XMM1, XMM0); |
| 1449 __ shufps(XMM0, XMM0, Immediate(0x55)); | 1442 __ shufps(XMM0, XMM0, Immediate(0x55)); |
| 1450 __ shufps(XMM1, XMM1, Immediate(0xFF)); | 1443 __ shufps(XMM1, XMM1, Immediate(0xFF)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1463 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); | 1456 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); |
| 1464 } | 1457 } |
| 1465 | 1458 |
| 1466 | 1459 |
| 1467 ASSEMBLER_TEST_GENERATE(PackedUnpackHigh, assembler) { | 1460 ASSEMBLER_TEST_GENERATE(PackedUnpackHigh, assembler) { |
| 1468 static const struct ALIGN16 { | 1461 static const struct ALIGN16 { |
| 1469 float a; | 1462 float a; |
| 1470 float b; | 1463 float b; |
| 1471 float c; | 1464 float c; |
| 1472 float d; | 1465 float d; |
| 1473 } constant0 = { 1.0, 2.0, 3.0, 4.0 }; | 1466 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1474 static const struct ALIGN16 { | 1467 static const struct ALIGN16 { |
| 1475 float a; | 1468 float a; |
| 1476 float b; | 1469 float b; |
| 1477 float c; | 1470 float c; |
| 1478 float d; | 1471 float d; |
| 1479 } constant1 = { 5.0, 6.0, 7.0, 8.0 }; | 1472 } constant1 = {5.0, 6.0, 7.0, 8.0}; |
| 1480 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. | 1473 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. |
| 1481 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1474 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1482 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. | 1475 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. |
| 1483 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1476 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1484 // XMM0 = 3.0f, 7.0f, 4.0f, 8.0f. | 1477 // XMM0 = 3.0f, 7.0f, 4.0f, 8.0f. |
| 1485 __ unpckhps(XMM0, XMM1); | 1478 __ unpckhps(XMM0, XMM1); |
| 1486 // XMM1 = 3.0f, 7.0f, 4.0f, 8.0f. | 1479 // XMM1 = 3.0f, 7.0f, 4.0f, 8.0f. |
| 1487 __ movaps(XMM1, XMM0); | 1480 __ movaps(XMM1, XMM0); |
| 1488 __ shufps(XMM0, XMM0, Immediate(0x00)); | 1481 __ shufps(XMM0, XMM0, Immediate(0x00)); |
| 1489 __ shufps(XMM1, XMM1, Immediate(0xAA)); | 1482 __ shufps(XMM1, XMM1, Immediate(0xAA)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1502 EXPECT_FLOAT_EQ(7.0f, res, 0.001f); | 1495 EXPECT_FLOAT_EQ(7.0f, res, 0.001f); |
| 1503 } | 1496 } |
| 1504 | 1497 |
| 1505 | 1498 |
| 1506 ASSEMBLER_TEST_GENERATE(PackedUnpackLowPair, assembler) { | 1499 ASSEMBLER_TEST_GENERATE(PackedUnpackLowPair, assembler) { |
| 1507 static const struct ALIGN16 { | 1500 static const struct ALIGN16 { |
| 1508 float a; | 1501 float a; |
| 1509 float b; | 1502 float b; |
| 1510 float c; | 1503 float c; |
| 1511 float d; | 1504 float d; |
| 1512 } constant0 = { 1.0, 2.0, 3.0, 4.0 }; | 1505 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1513 static const struct ALIGN16 { | 1506 static const struct ALIGN16 { |
| 1514 float a; | 1507 float a; |
| 1515 float b; | 1508 float b; |
| 1516 float c; | 1509 float c; |
| 1517 float d; | 1510 float d; |
| 1518 } constant1 = { 5.0, 6.0, 7.0, 8.0 }; | 1511 } constant1 = {5.0, 6.0, 7.0, 8.0}; |
| 1519 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. | 1512 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. |
| 1520 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1513 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1521 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. | 1514 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. |
| 1522 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1515 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1523 // XMM0 = 1.0f, 2.0f, 5.0f, 6.0f. | 1516 // XMM0 = 1.0f, 2.0f, 5.0f, 6.0f. |
| 1524 __ unpcklpd(XMM0, XMM1); | 1517 __ unpcklpd(XMM0, XMM1); |
| 1525 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f. | 1518 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f. |
| 1526 __ movaps(XMM1, XMM0); | 1519 __ movaps(XMM1, XMM0); |
| 1527 __ shufps(XMM0, XMM0, Immediate(0x00)); | 1520 __ shufps(XMM0, XMM0, Immediate(0x00)); |
| 1528 __ shufps(XMM1, XMM1, Immediate(0xAA)); | 1521 __ shufps(XMM1, XMM1, Immediate(0xAA)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1541 EXPECT_FLOAT_EQ(6.0f, res, 0.001f); | 1534 EXPECT_FLOAT_EQ(6.0f, res, 0.001f); |
| 1542 } | 1535 } |
| 1543 | 1536 |
| 1544 | 1537 |
| 1545 ASSEMBLER_TEST_GENERATE(PackedUnpackHighPair, assembler) { | 1538 ASSEMBLER_TEST_GENERATE(PackedUnpackHighPair, assembler) { |
| 1546 static const struct ALIGN16 { | 1539 static const struct ALIGN16 { |
| 1547 float a; | 1540 float a; |
| 1548 float b; | 1541 float b; |
| 1549 float c; | 1542 float c; |
| 1550 float d; | 1543 float d; |
| 1551 } constant0 = { 1.0, 2.0, 3.0, 4.0 }; | 1544 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1552 static const struct ALIGN16 { | 1545 static const struct ALIGN16 { |
| 1553 float a; | 1546 float a; |
| 1554 float b; | 1547 float b; |
| 1555 float c; | 1548 float c; |
| 1556 float d; | 1549 float d; |
| 1557 } constant1 = { 5.0, 6.0, 7.0, 8.0 }; | 1550 } constant1 = {5.0, 6.0, 7.0, 8.0}; |
| 1558 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. | 1551 // XMM0 = 1.0f, 2.0f, 3.0f, 4.0f. |
| 1559 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1552 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1560 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. | 1553 // XMM1 = 5.0f, 6.0f, 7.0f, 8.0f. |
| 1561 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1554 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1562 // XMM0 = 3.0f, 4.0f, 7.0f, 8.0f. | 1555 // XMM0 = 3.0f, 4.0f, 7.0f, 8.0f. |
| 1563 __ unpckhpd(XMM0, XMM1); | 1556 __ unpckhpd(XMM0, XMM1); |
| 1564 // XMM1 = 3.0f, 4.0f, 7.0f, 8.0f. | 1557 // XMM1 = 3.0f, 4.0f, 7.0f, 8.0f. |
| 1565 __ movaps(XMM1, XMM0); | 1558 __ movaps(XMM1, XMM0); |
| 1566 __ shufps(XMM0, XMM0, Immediate(0x55)); | 1559 __ shufps(XMM0, XMM0, Immediate(0x55)); |
| 1567 __ shufps(XMM1, XMM1, Immediate(0xFF)); | 1560 __ shufps(XMM1, XMM1, Immediate(0xFF)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1578 typedef float (*PackedUnpackHighPair)(); | 1571 typedef float (*PackedUnpackHighPair)(); |
| 1579 float res = reinterpret_cast<PackedUnpackHighPair>(test->entry())(); | 1572 float res = reinterpret_cast<PackedUnpackHighPair>(test->entry())(); |
| 1580 EXPECT_FLOAT_EQ(12.0f, res, 0.001f); | 1573 EXPECT_FLOAT_EQ(12.0f, res, 0.001f); |
| 1581 } | 1574 } |
| 1582 | 1575 |
| 1583 | 1576 |
| 1584 ASSEMBLER_TEST_GENERATE(PackedDoubleAdd, assembler) { | 1577 ASSEMBLER_TEST_GENERATE(PackedDoubleAdd, assembler) { |
| 1585 static const struct ALIGN16 { | 1578 static const struct ALIGN16 { |
| 1586 double a; | 1579 double a; |
| 1587 double b; | 1580 double b; |
| 1588 } constant0 = { 1.0, 2.0 }; | 1581 } constant0 = {1.0, 2.0}; |
| 1589 static const struct ALIGN16 { | 1582 static const struct ALIGN16 { |
| 1590 double a; | 1583 double a; |
| 1591 double b; | 1584 double b; |
| 1592 } constant1 = { 3.0, 4.0 }; | 1585 } constant1 = {3.0, 4.0}; |
| 1593 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1586 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1594 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1587 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1595 __ addpd(XMM0, XMM1); | 1588 __ addpd(XMM0, XMM1); |
| 1596 __ pushl(EAX); | 1589 __ pushl(EAX); |
| 1597 __ pushl(EAX); | 1590 __ pushl(EAX); |
| 1598 __ movsd(Address(ESP, 0), XMM0); | 1591 __ movsd(Address(ESP, 0), XMM0); |
| 1599 __ fldl(Address(ESP, 0)); | 1592 __ fldl(Address(ESP, 0)); |
| 1600 __ popl(EAX); | 1593 __ popl(EAX); |
| 1601 __ popl(EAX); | 1594 __ popl(EAX); |
| 1602 __ ret(); | 1595 __ ret(); |
| 1603 } | 1596 } |
| 1604 | 1597 |
| 1605 | 1598 |
| 1606 ASSEMBLER_TEST_RUN(PackedDoubleAdd, test) { | 1599 ASSEMBLER_TEST_RUN(PackedDoubleAdd, test) { |
| 1607 typedef double (*PackedDoubleAdd)(); | 1600 typedef double (*PackedDoubleAdd)(); |
| 1608 double res = reinterpret_cast<PackedDoubleAdd>(test->entry())(); | 1601 double res = reinterpret_cast<PackedDoubleAdd>(test->entry())(); |
| 1609 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); | 1602 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); |
| 1610 } | 1603 } |
| 1611 | 1604 |
| 1612 | 1605 |
| 1613 ASSEMBLER_TEST_GENERATE(PackedDoubleSub, assembler) { | 1606 ASSEMBLER_TEST_GENERATE(PackedDoubleSub, assembler) { |
| 1614 static const struct ALIGN16 { | 1607 static const struct ALIGN16 { |
| 1615 double a; | 1608 double a; |
| 1616 double b; | 1609 double b; |
| 1617 } constant0 = { 1.0, 2.0 }; | 1610 } constant0 = {1.0, 2.0}; |
| 1618 static const struct ALIGN16 { | 1611 static const struct ALIGN16 { |
| 1619 double a; | 1612 double a; |
| 1620 double b; | 1613 double b; |
| 1621 } constant1 = { 3.0, 4.0 }; | 1614 } constant1 = {3.0, 4.0}; |
| 1622 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1615 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1623 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1616 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1624 __ subpd(XMM0, XMM1); | 1617 __ subpd(XMM0, XMM1); |
| 1625 __ pushl(EAX); | 1618 __ pushl(EAX); |
| 1626 __ pushl(EAX); | 1619 __ pushl(EAX); |
| 1627 __ movsd(Address(ESP, 0), XMM0); | 1620 __ movsd(Address(ESP, 0), XMM0); |
| 1628 __ fldl(Address(ESP, 0)); | 1621 __ fldl(Address(ESP, 0)); |
| 1629 __ popl(EAX); | 1622 __ popl(EAX); |
| 1630 __ popl(EAX); | 1623 __ popl(EAX); |
| 1631 __ ret(); | 1624 __ ret(); |
| 1632 } | 1625 } |
| 1633 | 1626 |
| 1634 | 1627 |
| 1635 ASSEMBLER_TEST_RUN(PackedDoubleSub, test) { | 1628 ASSEMBLER_TEST_RUN(PackedDoubleSub, test) { |
| 1636 typedef double (*PackedDoubleSub)(); | 1629 typedef double (*PackedDoubleSub)(); |
| 1637 double res = reinterpret_cast<PackedDoubleSub>(test->entry())(); | 1630 double res = reinterpret_cast<PackedDoubleSub>(test->entry())(); |
| 1638 EXPECT_FLOAT_EQ(-2.0, res, 0.000001f); | 1631 EXPECT_FLOAT_EQ(-2.0, res, 0.000001f); |
| 1639 } | 1632 } |
| 1640 | 1633 |
| 1641 | 1634 |
| 1642 ASSEMBLER_TEST_GENERATE(PackedDoubleNegate, assembler) { | 1635 ASSEMBLER_TEST_GENERATE(PackedDoubleNegate, assembler) { |
| 1643 static const struct ALIGN16 { | 1636 static const struct ALIGN16 { |
| 1644 double a; | 1637 double a; |
| 1645 double b; | 1638 double b; |
| 1646 } constant0 = { 1.0, 2.0 }; | 1639 } constant0 = {1.0, 2.0}; |
| 1647 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1640 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1648 __ negatepd(XMM0); | 1641 __ negatepd(XMM0); |
| 1649 __ pushl(EAX); | 1642 __ pushl(EAX); |
| 1650 __ pushl(EAX); | 1643 __ pushl(EAX); |
| 1651 __ movsd(Address(ESP, 0), XMM0); | 1644 __ movsd(Address(ESP, 0), XMM0); |
| 1652 __ fldl(Address(ESP, 0)); | 1645 __ fldl(Address(ESP, 0)); |
| 1653 __ popl(EAX); | 1646 __ popl(EAX); |
| 1654 __ popl(EAX); | 1647 __ popl(EAX); |
| 1655 __ ret(); | 1648 __ ret(); |
| 1656 } | 1649 } |
| 1657 | 1650 |
| 1658 | 1651 |
| 1659 ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) { | 1652 ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) { |
| 1660 typedef double (*PackedDoubleNegate)(); | 1653 typedef double (*PackedDoubleNegate)(); |
| 1661 double res = reinterpret_cast<PackedDoubleNegate>(test->entry())(); | 1654 double res = reinterpret_cast<PackedDoubleNegate>(test->entry())(); |
| 1662 EXPECT_FLOAT_EQ(-1.0, res, 0.000001f); | 1655 EXPECT_FLOAT_EQ(-1.0, res, 0.000001f); |
| 1663 } | 1656 } |
| 1664 | 1657 |
| 1665 | 1658 |
| 1666 ASSEMBLER_TEST_GENERATE(PackedDoubleAbsolute, assembler) { | 1659 ASSEMBLER_TEST_GENERATE(PackedDoubleAbsolute, assembler) { |
| 1667 static const struct ALIGN16 { | 1660 static const struct ALIGN16 { |
| 1668 double a; | 1661 double a; |
| 1669 double b; | 1662 double b; |
| 1670 } constant0 = { -1.0, 2.0 }; | 1663 } constant0 = {-1.0, 2.0}; |
| 1671 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1664 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1672 __ abspd(XMM0); | 1665 __ abspd(XMM0); |
| 1673 __ pushl(EAX); | 1666 __ pushl(EAX); |
| 1674 __ pushl(EAX); | 1667 __ pushl(EAX); |
| 1675 __ movsd(Address(ESP, 0), XMM0); | 1668 __ movsd(Address(ESP, 0), XMM0); |
| 1676 __ fldl(Address(ESP, 0)); | 1669 __ fldl(Address(ESP, 0)); |
| 1677 __ popl(EAX); | 1670 __ popl(EAX); |
| 1678 __ popl(EAX); | 1671 __ popl(EAX); |
| 1679 __ ret(); | 1672 __ ret(); |
| 1680 } | 1673 } |
| 1681 | 1674 |
| 1682 | 1675 |
| 1683 ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) { | 1676 ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) { |
| 1684 typedef double (*PackedDoubleAbsolute)(); | 1677 typedef double (*PackedDoubleAbsolute)(); |
| 1685 double res = reinterpret_cast<PackedDoubleAbsolute>(test->entry())(); | 1678 double res = reinterpret_cast<PackedDoubleAbsolute>(test->entry())(); |
| 1686 EXPECT_FLOAT_EQ(1.0, res, 0.000001f); | 1679 EXPECT_FLOAT_EQ(1.0, res, 0.000001f); |
| 1687 } | 1680 } |
| 1688 | 1681 |
| 1689 | 1682 |
| 1690 ASSEMBLER_TEST_GENERATE(PackedDoubleMul, assembler) { | 1683 ASSEMBLER_TEST_GENERATE(PackedDoubleMul, assembler) { |
| 1691 static const struct ALIGN16 { | 1684 static const struct ALIGN16 { |
| 1692 double a; | 1685 double a; |
| 1693 double b; | 1686 double b; |
| 1694 } constant0 = { 3.0, 2.0 }; | 1687 } constant0 = {3.0, 2.0}; |
| 1695 static const struct ALIGN16 { | 1688 static const struct ALIGN16 { |
| 1696 double a; | 1689 double a; |
| 1697 double b; | 1690 double b; |
| 1698 } constant1 = { 3.0, 4.0 }; | 1691 } constant1 = {3.0, 4.0}; |
| 1699 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1692 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1700 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1693 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1701 __ mulpd(XMM0, XMM1); | 1694 __ mulpd(XMM0, XMM1); |
| 1702 __ pushl(EAX); | 1695 __ pushl(EAX); |
| 1703 __ pushl(EAX); | 1696 __ pushl(EAX); |
| 1704 __ movsd(Address(ESP, 0), XMM0); | 1697 __ movsd(Address(ESP, 0), XMM0); |
| 1705 __ fldl(Address(ESP, 0)); | 1698 __ fldl(Address(ESP, 0)); |
| 1706 __ popl(EAX); | 1699 __ popl(EAX); |
| 1707 __ popl(EAX); | 1700 __ popl(EAX); |
| 1708 __ ret(); | 1701 __ ret(); |
| 1709 } | 1702 } |
| 1710 | 1703 |
| 1711 | 1704 |
| 1712 ASSEMBLER_TEST_RUN(PackedDoubleMul, test) { | 1705 ASSEMBLER_TEST_RUN(PackedDoubleMul, test) { |
| 1713 typedef double (*PackedDoubleMul)(); | 1706 typedef double (*PackedDoubleMul)(); |
| 1714 double res = reinterpret_cast<PackedDoubleMul>(test->entry())(); | 1707 double res = reinterpret_cast<PackedDoubleMul>(test->entry())(); |
| 1715 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 1708 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
| 1716 } | 1709 } |
| 1717 | 1710 |
| 1718 | 1711 |
| 1719 ASSEMBLER_TEST_GENERATE(PackedDoubleDiv, assembler) { | 1712 ASSEMBLER_TEST_GENERATE(PackedDoubleDiv, assembler) { |
| 1720 static const struct ALIGN16 { | 1713 static const struct ALIGN16 { |
| 1721 double a; | 1714 double a; |
| 1722 double b; | 1715 double b; |
| 1723 } constant0 = { 9.0, 2.0 }; | 1716 } constant0 = {9.0, 2.0}; |
| 1724 static const struct ALIGN16 { | 1717 static const struct ALIGN16 { |
| 1725 double a; | 1718 double a; |
| 1726 double b; | 1719 double b; |
| 1727 } constant1 = { 3.0, 4.0 }; | 1720 } constant1 = {3.0, 4.0}; |
| 1728 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1721 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1729 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1722 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1730 __ divpd(XMM0, XMM1); | 1723 __ divpd(XMM0, XMM1); |
| 1731 __ pushl(EAX); | 1724 __ pushl(EAX); |
| 1732 __ pushl(EAX); | 1725 __ pushl(EAX); |
| 1733 __ movsd(Address(ESP, 0), XMM0); | 1726 __ movsd(Address(ESP, 0), XMM0); |
| 1734 __ fldl(Address(ESP, 0)); | 1727 __ fldl(Address(ESP, 0)); |
| 1735 __ popl(EAX); | 1728 __ popl(EAX); |
| 1736 __ popl(EAX); | 1729 __ popl(EAX); |
| 1737 __ ret(); | 1730 __ ret(); |
| 1738 } | 1731 } |
| 1739 | 1732 |
| 1740 | 1733 |
| 1741 ASSEMBLER_TEST_RUN(PackedDoubleDiv, test) { | 1734 ASSEMBLER_TEST_RUN(PackedDoubleDiv, test) { |
| 1742 typedef double (*PackedDoubleDiv)(); | 1735 typedef double (*PackedDoubleDiv)(); |
| 1743 double res = reinterpret_cast<PackedDoubleDiv>(test->entry())(); | 1736 double res = reinterpret_cast<PackedDoubleDiv>(test->entry())(); |
| 1744 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); | 1737 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); |
| 1745 } | 1738 } |
| 1746 | 1739 |
| 1747 | 1740 |
| 1748 ASSEMBLER_TEST_GENERATE(PackedDoubleSqrt, assembler) { | 1741 ASSEMBLER_TEST_GENERATE(PackedDoubleSqrt, assembler) { |
| 1749 static const struct ALIGN16 { | 1742 static const struct ALIGN16 { |
| 1750 double a; | 1743 double a; |
| 1751 double b; | 1744 double b; |
| 1752 } constant0 = { 16.0, 2.0 }; | 1745 } constant0 = {16.0, 2.0}; |
| 1753 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1746 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1754 __ sqrtpd(XMM0); | 1747 __ sqrtpd(XMM0); |
| 1755 __ pushl(EAX); | 1748 __ pushl(EAX); |
| 1756 __ pushl(EAX); | 1749 __ pushl(EAX); |
| 1757 __ movsd(Address(ESP, 0), XMM0); | 1750 __ movsd(Address(ESP, 0), XMM0); |
| 1758 __ fldl(Address(ESP, 0)); | 1751 __ fldl(Address(ESP, 0)); |
| 1759 __ popl(EAX); | 1752 __ popl(EAX); |
| 1760 __ popl(EAX); | 1753 __ popl(EAX); |
| 1761 __ ret(); | 1754 __ ret(); |
| 1762 } | 1755 } |
| 1763 | 1756 |
| 1764 | 1757 |
| 1765 ASSEMBLER_TEST_RUN(PackedDoubleSqrt, test) { | 1758 ASSEMBLER_TEST_RUN(PackedDoubleSqrt, test) { |
| 1766 typedef double (*PackedDoubleSqrt)(); | 1759 typedef double (*PackedDoubleSqrt)(); |
| 1767 double res = reinterpret_cast<PackedDoubleSqrt>(test->entry())(); | 1760 double res = reinterpret_cast<PackedDoubleSqrt>(test->entry())(); |
| 1768 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); | 1761 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); |
| 1769 } | 1762 } |
| 1770 | 1763 |
| 1771 | 1764 |
| 1772 ASSEMBLER_TEST_GENERATE(PackedDoubleMin, assembler) { | 1765 ASSEMBLER_TEST_GENERATE(PackedDoubleMin, assembler) { |
| 1773 static const struct ALIGN16 { | 1766 static const struct ALIGN16 { |
| 1774 double a; | 1767 double a; |
| 1775 double b; | 1768 double b; |
| 1776 } constant0 = { 9.0, 2.0 }; | 1769 } constant0 = {9.0, 2.0}; |
| 1777 static const struct ALIGN16 { | 1770 static const struct ALIGN16 { |
| 1778 double a; | 1771 double a; |
| 1779 double b; | 1772 double b; |
| 1780 } constant1 = { 3.0, 4.0 }; | 1773 } constant1 = {3.0, 4.0}; |
| 1781 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1774 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1782 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1775 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1783 __ minpd(XMM0, XMM1); | 1776 __ minpd(XMM0, XMM1); |
| 1784 __ pushl(EAX); | 1777 __ pushl(EAX); |
| 1785 __ pushl(EAX); | 1778 __ pushl(EAX); |
| 1786 __ movsd(Address(ESP, 0), XMM0); | 1779 __ movsd(Address(ESP, 0), XMM0); |
| 1787 __ fldl(Address(ESP, 0)); | 1780 __ fldl(Address(ESP, 0)); |
| 1788 __ popl(EAX); | 1781 __ popl(EAX); |
| 1789 __ popl(EAX); | 1782 __ popl(EAX); |
| 1790 __ ret(); | 1783 __ ret(); |
| 1791 } | 1784 } |
| 1792 | 1785 |
| 1793 | 1786 |
| 1794 ASSEMBLER_TEST_RUN(PackedDoubleMin, test) { | 1787 ASSEMBLER_TEST_RUN(PackedDoubleMin, test) { |
| 1795 typedef double (*PackedDoubleMin)(); | 1788 typedef double (*PackedDoubleMin)(); |
| 1796 double res = reinterpret_cast<PackedDoubleMin>(test->entry())(); | 1789 double res = reinterpret_cast<PackedDoubleMin>(test->entry())(); |
| 1797 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); | 1790 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); |
| 1798 } | 1791 } |
| 1799 | 1792 |
| 1800 | 1793 |
| 1801 ASSEMBLER_TEST_GENERATE(PackedDoubleMax, assembler) { | 1794 ASSEMBLER_TEST_GENERATE(PackedDoubleMax, assembler) { |
| 1802 static const struct ALIGN16 { | 1795 static const struct ALIGN16 { |
| 1803 double a; | 1796 double a; |
| 1804 double b; | 1797 double b; |
| 1805 } constant0 = { 9.0, 2.0 }; | 1798 } constant0 = {9.0, 2.0}; |
| 1806 static const struct ALIGN16 { | 1799 static const struct ALIGN16 { |
| 1807 double a; | 1800 double a; |
| 1808 double b; | 1801 double b; |
| 1809 } constant1 = { 3.0, 4.0 }; | 1802 } constant1 = {3.0, 4.0}; |
| 1810 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1803 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1811 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1804 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1812 __ maxpd(XMM0, XMM1); | 1805 __ maxpd(XMM0, XMM1); |
| 1813 __ pushl(EAX); | 1806 __ pushl(EAX); |
| 1814 __ pushl(EAX); | 1807 __ pushl(EAX); |
| 1815 __ movsd(Address(ESP, 0), XMM0); | 1808 __ movsd(Address(ESP, 0), XMM0); |
| 1816 __ fldl(Address(ESP, 0)); | 1809 __ fldl(Address(ESP, 0)); |
| 1817 __ popl(EAX); | 1810 __ popl(EAX); |
| 1818 __ popl(EAX); | 1811 __ popl(EAX); |
| 1819 __ ret(); | 1812 __ ret(); |
| 1820 } | 1813 } |
| 1821 | 1814 |
| 1822 | 1815 |
| 1823 ASSEMBLER_TEST_RUN(PackedDoubleMax, test) { | 1816 ASSEMBLER_TEST_RUN(PackedDoubleMax, test) { |
| 1824 typedef double (*PackedDoubleMax)(); | 1817 typedef double (*PackedDoubleMax)(); |
| 1825 double res = reinterpret_cast<PackedDoubleMax>(test->entry())(); | 1818 double res = reinterpret_cast<PackedDoubleMax>(test->entry())(); |
| 1826 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 1819 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
| 1827 } | 1820 } |
| 1828 | 1821 |
| 1829 | 1822 |
| 1830 ASSEMBLER_TEST_GENERATE(PackedDoubleShuffle, assembler) { | 1823 ASSEMBLER_TEST_GENERATE(PackedDoubleShuffle, assembler) { |
| 1831 static const struct ALIGN16 { | 1824 static const struct ALIGN16 { |
| 1832 double a; | 1825 double a; |
| 1833 double b; | 1826 double b; |
| 1834 } constant0 = { 2.0, 9.0 }; | 1827 } constant0 = {2.0, 9.0}; |
| 1835 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1828 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1836 // Splat Y across all lanes. | 1829 // Splat Y across all lanes. |
| 1837 __ shufpd(XMM0, XMM0, Immediate(0x33)); | 1830 __ shufpd(XMM0, XMM0, Immediate(0x33)); |
| 1838 // Splat X across all lanes. | 1831 // Splat X across all lanes. |
| 1839 __ shufpd(XMM0, XMM0, Immediate(0x0)); | 1832 __ shufpd(XMM0, XMM0, Immediate(0x0)); |
| 1840 // Set return value. | 1833 // Set return value. |
| 1841 __ pushl(EAX); | 1834 __ pushl(EAX); |
| 1842 __ pushl(EAX); | 1835 __ pushl(EAX); |
| 1843 __ movsd(Address(ESP, 0), XMM0); | 1836 __ movsd(Address(ESP, 0), XMM0); |
| 1844 __ fldl(Address(ESP, 0)); | 1837 __ fldl(Address(ESP, 0)); |
| 1845 __ popl(EAX); | 1838 __ popl(EAX); |
| 1846 __ popl(EAX); | 1839 __ popl(EAX); |
| 1847 __ ret(); | 1840 __ ret(); |
| 1848 } | 1841 } |
| 1849 | 1842 |
| 1850 | 1843 |
| 1851 ASSEMBLER_TEST_RUN(PackedDoubleShuffle, test) { | 1844 ASSEMBLER_TEST_RUN(PackedDoubleShuffle, test) { |
| 1852 typedef double (*PackedDoubleShuffle)(); | 1845 typedef double (*PackedDoubleShuffle)(); |
| 1853 double res = reinterpret_cast<PackedDoubleShuffle>(test->entry())(); | 1846 double res = reinterpret_cast<PackedDoubleShuffle>(test->entry())(); |
| 1854 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 1847 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
| 1855 } | 1848 } |
| 1856 | 1849 |
| 1857 | 1850 |
| 1858 ASSEMBLER_TEST_GENERATE(PackedDoubleToSingle, assembler) { | 1851 ASSEMBLER_TEST_GENERATE(PackedDoubleToSingle, assembler) { |
| 1859 static const struct ALIGN16 { | 1852 static const struct ALIGN16 { |
| 1860 double a; | 1853 double a; |
| 1861 double b; | 1854 double b; |
| 1862 } constant0 = { 9.0, 2.0 }; | 1855 } constant0 = {9.0, 2.0}; |
| 1863 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1856 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1864 __ cvtpd2ps(XMM0, XMM1); | 1857 __ cvtpd2ps(XMM0, XMM1); |
| 1865 __ pushl(EAX); | 1858 __ pushl(EAX); |
| 1866 __ movss(Address(ESP, 0), XMM0); | 1859 __ movss(Address(ESP, 0), XMM0); |
| 1867 __ flds(Address(ESP, 0)); | 1860 __ flds(Address(ESP, 0)); |
| 1868 __ popl(EAX); | 1861 __ popl(EAX); |
| 1869 __ ret(); | 1862 __ ret(); |
| 1870 } | 1863 } |
| 1871 | 1864 |
| 1872 | 1865 |
| 1873 ASSEMBLER_TEST_RUN(PackedDoubleToSingle, test) { | 1866 ASSEMBLER_TEST_RUN(PackedDoubleToSingle, test) { |
| 1874 typedef float (*PackedDoubleToSingle)(); | 1867 typedef float (*PackedDoubleToSingle)(); |
| 1875 float res = reinterpret_cast<PackedDoubleToSingle>(test->entry())(); | 1868 float res = reinterpret_cast<PackedDoubleToSingle>(test->entry())(); |
| 1876 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); | 1869 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); |
| 1877 } | 1870 } |
| 1878 | 1871 |
| 1879 | 1872 |
| 1880 ASSEMBLER_TEST_GENERATE(PackedSingleToDouble, assembler) { | 1873 ASSEMBLER_TEST_GENERATE(PackedSingleToDouble, assembler) { |
| 1881 static const struct ALIGN16 { | 1874 static const struct ALIGN16 { |
| 1882 float a; | 1875 float a; |
| 1883 float b; | 1876 float b; |
| 1884 float c; | 1877 float c; |
| 1885 float d; | 1878 float d; |
| 1886 } constant0 = { 9.0f, 2.0f, 3.0f, 4.0f }; | 1879 } constant0 = {9.0f, 2.0f, 3.0f, 4.0f}; |
| 1887 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1880 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1888 __ cvtps2pd(XMM0, XMM1); | 1881 __ cvtps2pd(XMM0, XMM1); |
| 1889 __ pushl(EAX); | 1882 __ pushl(EAX); |
| 1890 __ pushl(EAX); | 1883 __ pushl(EAX); |
| 1891 __ movsd(Address(ESP, 0), XMM0); | 1884 __ movsd(Address(ESP, 0), XMM0); |
| 1892 __ fldl(Address(ESP, 0)); | 1885 __ fldl(Address(ESP, 0)); |
| 1893 __ popl(EAX); | 1886 __ popl(EAX); |
| 1894 __ popl(EAX); | 1887 __ popl(EAX); |
| 1895 __ ret(); | 1888 __ ret(); |
| 1896 } | 1889 } |
| (...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2628 ASSEMBLER_TEST_RUN(LongUnsignedMulReg, test) { | 2621 ASSEMBLER_TEST_RUN(LongUnsignedMulReg, test) { |
| 2629 typedef uint64_t (*LongUnsignedMulRegCode)(uint32_t a, uint32_t b); | 2622 typedef uint64_t (*LongUnsignedMulRegCode)(uint32_t a, uint32_t b); |
| 2630 uint32_t a = 3; | 2623 uint32_t a = 3; |
| 2631 uint32_t b = 13; | 2624 uint32_t b = 13; |
| 2632 uint64_t mul_res = a * b; | 2625 uint64_t mul_res = a * b; |
| 2633 uint64_t res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); | 2626 uint64_t res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); |
| 2634 EXPECT_EQ(mul_res, res); | 2627 EXPECT_EQ(mul_res, res); |
| 2635 a = 4021288948u; | 2628 a = 4021288948u; |
| 2636 b = 13; | 2629 b = 13; |
| 2637 res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); | 2630 res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); |
| 2638 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); | 2631 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); |
| 2639 EXPECT_EQ(mul_res, res); | 2632 EXPECT_EQ(mul_res, res); |
| 2640 } | 2633 } |
| 2641 | 2634 |
| 2642 | 2635 |
| 2643 ASSEMBLER_TEST_GENERATE(LongUnsignedMulAddress, assembler) { | 2636 ASSEMBLER_TEST_GENERATE(LongUnsignedMulAddress, assembler) { |
| 2644 __ movl(EAX, Address(ESP, 2 * kWordSize)); | 2637 __ movl(EAX, Address(ESP, 2 * kWordSize)); |
| 2645 __ mull(Address(ESP, kWordSize)); | 2638 __ mull(Address(ESP, kWordSize)); |
| 2646 __ ret(); | 2639 __ ret(); |
| 2647 } | 2640 } |
| 2648 | 2641 |
| 2649 | 2642 |
| 2650 ASSEMBLER_TEST_RUN(LongUnsignedMulAddress, test) { | 2643 ASSEMBLER_TEST_RUN(LongUnsignedMulAddress, test) { |
| 2651 typedef uint64_t (*LongUnsignedMulAddressCode)(uint32_t a, uint32_t b); | 2644 typedef uint64_t (*LongUnsignedMulAddressCode)(uint32_t a, uint32_t b); |
| 2652 uint32_t a = 12; | 2645 uint32_t a = 12; |
| 2653 uint32_t b = 13; | 2646 uint32_t b = 13; |
| 2654 uint64_t mul_res = a * b; | 2647 uint64_t mul_res = a * b; |
| 2655 uint64_t res = | 2648 uint64_t res = |
| 2656 reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); | 2649 reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); |
| 2657 EXPECT_EQ(mul_res, res); | 2650 EXPECT_EQ(mul_res, res); |
| 2658 a = 4294967284u; | 2651 a = 4294967284u; |
| 2659 b = 13; | 2652 b = 13; |
| 2660 res = reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); | 2653 res = reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); |
| 2661 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); | 2654 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); |
| 2662 EXPECT_EQ(mul_res, res); | 2655 EXPECT_EQ(mul_res, res); |
| 2663 } | 2656 } |
| 2664 | 2657 |
| 2665 | 2658 |
| 2666 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) { | 2659 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) { |
| 2667 // Preserve clobbered callee-saved register (EBX). | 2660 // Preserve clobbered callee-saved register (EBX). |
| 2668 __ pushl(EBX); | 2661 __ pushl(EBX); |
| 2669 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. | 2662 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. |
| 2670 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. | 2663 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. |
| 2671 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. | 2664 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3077 __ fldl(Address(ESP, 0)); | 3070 __ fldl(Address(ESP, 0)); |
| 3078 __ popl(EAX); | 3071 __ popl(EAX); |
| 3079 __ popl(EAX); | 3072 __ popl(EAX); |
| 3080 __ ret(); | 3073 __ ret(); |
| 3081 } | 3074 } |
| 3082 | 3075 |
| 3083 | 3076 |
| 3084 ASSEMBLER_TEST_RUN(DoubleAbs, test) { | 3077 ASSEMBLER_TEST_RUN(DoubleAbs, test) { |
| 3085 typedef double (*DoubleAbsCode)(double d); | 3078 typedef double (*DoubleAbsCode)(double d); |
| 3086 double val = -12.45; | 3079 double val = -12.45; |
| 3087 double res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); | 3080 double res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); |
| 3088 EXPECT_FLOAT_EQ(-val, res, 0.001); | 3081 EXPECT_FLOAT_EQ(-val, res, 0.001); |
| 3089 val = 12.45; | 3082 val = 12.45; |
| 3090 res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); | 3083 res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); |
| 3091 EXPECT_FLOAT_EQ(val, res, 0.001); | 3084 EXPECT_FLOAT_EQ(val, res, 0.001); |
| 3092 } | 3085 } |
| 3093 | 3086 |
| 3094 | 3087 |
| 3095 ASSEMBLER_TEST_GENERATE(ExtractSignBits, assembler) { | 3088 ASSEMBLER_TEST_GENERATE(ExtractSignBits, assembler) { |
| 3096 __ movsd(XMM0, Address(ESP, kWordSize)); | 3089 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 3097 __ movmskpd(EAX, XMM0); | 3090 __ movmskpd(EAX, XMM0); |
| 3098 __ andl(EAX, Immediate(0x1)); | 3091 __ andl(EAX, Immediate(0x1)); |
| 3099 __ ret(); | 3092 __ ret(); |
| 3100 } | 3093 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 __ addl(EDX, Address(ESP, 2 * kWordSize)); | 3139 __ addl(EDX, Address(ESP, 2 * kWordSize)); |
| 3147 __ movl(EAX, Immediate(1)); | 3140 __ movl(EAX, Immediate(1)); |
| 3148 __ movl(ECX, Immediate(0)); | 3141 __ movl(ECX, Immediate(0)); |
| 3149 __ cmovno(EAX, ECX); | 3142 __ cmovno(EAX, ECX); |
| 3150 __ ret(); | 3143 __ ret(); |
| 3151 } | 3144 } |
| 3152 | 3145 |
| 3153 | 3146 |
| 3154 ASSEMBLER_TEST_RUN(ConditionalMovesNoOverflow, test) { | 3147 ASSEMBLER_TEST_RUN(ConditionalMovesNoOverflow, test) { |
| 3155 typedef int (*ConditionalMovesNoOverflowCode)(int i, int j); | 3148 typedef int (*ConditionalMovesNoOverflowCode)(int i, int j); |
| 3156 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>( | 3149 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())( |
| 3157 test->entry())(0x7fffffff, 2); | 3150 0x7fffffff, 2); |
| 3158 EXPECT_EQ(1, res); | 3151 EXPECT_EQ(1, res); |
| 3159 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); | 3152 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); |
| 3160 EXPECT_EQ(0, res); | 3153 EXPECT_EQ(0, res); |
| 3161 } | 3154 } |
| 3162 | 3155 |
| 3163 | 3156 |
| 3164 // Return 1 if equal, 0 if not equal. | 3157 // Return 1 if equal, 0 if not equal. |
| 3165 ASSEMBLER_TEST_GENERATE(ConditionalMovesEqual, assembler) { | 3158 ASSEMBLER_TEST_GENERATE(ConditionalMovesEqual, assembler) { |
| 3166 __ xorl(EAX, EAX); | 3159 __ xorl(EAX, EAX); |
| 3167 __ movl(ECX, Immediate(1)); | 3160 __ movl(ECX, Immediate(1)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3195 ASSEMBLER_TEST_RUN(ConditionalMovesNotEqual, test) { | 3188 ASSEMBLER_TEST_RUN(ConditionalMovesNotEqual, test) { |
| 3196 typedef int (*ConditionalMovesNotEqualCode)(int i); | 3189 typedef int (*ConditionalMovesNotEqualCode)(int i); |
| 3197 int res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(785); | 3190 int res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(785); |
| 3198 EXPECT_EQ(0, res); | 3191 EXPECT_EQ(0, res); |
| 3199 res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(-12); | 3192 res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(-12); |
| 3200 EXPECT_EQ(1, res); | 3193 EXPECT_EQ(1, res); |
| 3201 } | 3194 } |
| 3202 | 3195 |
| 3203 | 3196 |
| 3204 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { | 3197 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { |
| 3205 __ movl(EDX, Immediate(1)); // Greater equal. | 3198 __ movl(EDX, Immediate(1)); // Greater equal. |
| 3206 __ movl(ECX, Immediate(-1)); // Less | 3199 __ movl(ECX, Immediate(-1)); // Less |
| 3207 __ movl(EAX, Address(ESP, 1 * kWordSize)); | 3200 __ movl(EAX, Address(ESP, 1 * kWordSize)); |
| 3208 __ cmpl(EAX, Address(ESP, 2 * kWordSize)); | 3201 __ cmpl(EAX, Address(ESP, 2 * kWordSize)); |
| 3209 __ cmovlessl(EAX, ECX); | 3202 __ cmovlessl(EAX, ECX); |
| 3210 __ cmovgel(EAX, EDX); | 3203 __ cmovgel(EAX, EDX); |
| 3211 __ ret(); | 3204 __ ret(); |
| 3212 } | 3205 } |
| 3213 | 3206 |
| 3214 | 3207 |
| 3215 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { | 3208 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3380 | 3373 |
| 3381 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { | 3374 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { |
| 3382 const char* from = "0123456789"; | 3375 const char* from = "0123456789"; |
| 3383 const char* to = new char[10]; | 3376 const char* to = new char[10]; |
| 3384 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); | 3377 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); |
| 3385 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); | 3378 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); |
| 3386 EXPECT_EQ(to[0], '0'); | 3379 EXPECT_EQ(to[0], '0'); |
| 3387 for (int i = 0; i < 10; i++) { | 3380 for (int i = 0; i < 10; i++) { |
| 3388 EXPECT_EQ(from[i], to[i]); | 3381 EXPECT_EQ(from[i], to[i]); |
| 3389 } | 3382 } |
| 3390 delete [] to; | 3383 delete[] to; |
| 3391 } | 3384 } |
| 3392 | 3385 |
| 3393 | 3386 |
| 3394 // Called from assembler_test.cc. | 3387 // Called from assembler_test.cc. |
| 3395 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { | 3388 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { |
| 3396 __ pushl(THR); | 3389 __ pushl(THR); |
| 3397 __ movl(EAX, Address(ESP, 2 * kWordSize)); | 3390 __ movl(EAX, Address(ESP, 2 * kWordSize)); |
| 3398 __ movl(ECX, Address(ESP, 3 * kWordSize)); | 3391 __ movl(ECX, Address(ESP, 3 * kWordSize)); |
| 3399 __ movl(THR, Address(ESP, 4 * kWordSize)); | 3392 __ movl(THR, Address(ESP, 4 * kWordSize)); |
| 3400 __ pushl(EAX); | 3393 __ pushl(EAX); |
| 3401 __ StoreIntoObject(ECX, | 3394 __ StoreIntoObject(ECX, FieldAddress(ECX, GrowableObjectArray::data_offset()), |
| 3402 FieldAddress(ECX, GrowableObjectArray::data_offset()), | |
| 3403 EAX); | 3395 EAX); |
| 3404 __ popl(EAX); | 3396 __ popl(EAX); |
| 3405 __ popl(THR); | 3397 __ popl(THR); |
| 3406 __ ret(); | 3398 __ ret(); |
| 3407 } | 3399 } |
| 3408 | 3400 |
| 3409 | 3401 |
| 3410 ASSEMBLER_TEST_GENERATE(BitTest, assembler) { | 3402 ASSEMBLER_TEST_GENERATE(BitTest, assembler) { |
| 3411 __ movl(EAX, Immediate(4)); | 3403 __ movl(EAX, Immediate(4)); |
| 3412 __ movl(ECX, Immediate(2)); | 3404 __ movl(ECX, Immediate(2)); |
| 3413 __ bt(EAX, ECX); | 3405 __ bt(EAX, ECX); |
| 3414 Label ok; | 3406 Label ok; |
| 3415 __ j(CARRY, &ok); | 3407 __ j(CARRY, &ok); |
| 3416 __ int3(); | 3408 __ int3(); |
| 3417 __ Bind(&ok); | 3409 __ Bind(&ok); |
| 3418 __ movl(EAX, Immediate(1)); | 3410 __ movl(EAX, Immediate(1)); |
| 3419 __ ret(); | 3411 __ ret(); |
| 3420 } | 3412 } |
| 3421 | 3413 |
| 3422 | 3414 |
| 3423 ASSEMBLER_TEST_RUN(BitTest, test) { | 3415 ASSEMBLER_TEST_RUN(BitTest, test) { |
| 3424 typedef int (*BitTest)(); | 3416 typedef int (*BitTest)(); |
| 3425 EXPECT_EQ(1, reinterpret_cast<BitTest>(test->entry())()); | 3417 EXPECT_EQ(1, reinterpret_cast<BitTest>(test->entry())()); |
| 3426 } | 3418 } |
| 3427 | 3419 |
| 3428 } // namespace dart | 3420 } // namespace dart |
| 3429 | 3421 |
| 3430 #endif // defined TARGET_ARCH_IA32 | 3422 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |