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 |