| 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" |
| 11 #include "vm/unit_test.h" | 11 #include "vm/unit_test.h" |
| 12 #include "vm/virtual_memory.h" | 12 #include "vm/virtual_memory.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 #define __ assembler-> | 16 #define __ assembler-> |
| 17 | 17 |
| 18 | |
| 19 ASSEMBLER_TEST_GENERATE(Simple, assembler) { | 18 ASSEMBLER_TEST_GENERATE(Simple, assembler) { |
| 20 __ movl(EAX, Immediate(42)); | 19 __ movl(EAX, Immediate(42)); |
| 21 __ ret(); | 20 __ ret(); |
| 22 } | 21 } |
| 23 | 22 |
| 24 | |
| 25 ASSEMBLER_TEST_RUN(Simple, test) { | 23 ASSEMBLER_TEST_RUN(Simple, test) { |
| 26 typedef int (*SimpleCode)(); | 24 typedef int (*SimpleCode)(); |
| 27 EXPECT_EQ(42, reinterpret_cast<SimpleCode>(test->entry())()); | 25 EXPECT_EQ(42, reinterpret_cast<SimpleCode>(test->entry())()); |
| 28 } | 26 } |
| 29 | 27 |
| 30 | |
| 31 ASSEMBLER_TEST_GENERATE(ReadArgument, assembler) { | 28 ASSEMBLER_TEST_GENERATE(ReadArgument, assembler) { |
| 32 __ movl(EAX, Address(ESP, kWordSize)); | 29 __ movl(EAX, Address(ESP, kWordSize)); |
| 33 __ ret(); | 30 __ ret(); |
| 34 } | 31 } |
| 35 | 32 |
| 36 | |
| 37 ASSEMBLER_TEST_RUN(ReadArgument, test) { | 33 ASSEMBLER_TEST_RUN(ReadArgument, test) { |
| 38 typedef int (*ReadArgumentCode)(int n); | 34 typedef int (*ReadArgumentCode)(int n); |
| 39 EXPECT_EQ(42, reinterpret_cast<ReadArgumentCode>(test->entry())(42)); | 35 EXPECT_EQ(42, reinterpret_cast<ReadArgumentCode>(test->entry())(42)); |
| 40 EXPECT_EQ(87, reinterpret_cast<ReadArgumentCode>(test->entry())(87)); | 36 EXPECT_EQ(87, reinterpret_cast<ReadArgumentCode>(test->entry())(87)); |
| 41 } | 37 } |
| 42 | 38 |
| 43 | |
| 44 ASSEMBLER_TEST_GENERATE(AddressingModes, assembler) { | 39 ASSEMBLER_TEST_GENERATE(AddressingModes, assembler) { |
| 45 __ movl(EAX, Address(ESP, 0)); | 40 __ movl(EAX, Address(ESP, 0)); |
| 46 __ movl(EAX, Address(EBP, 0)); | 41 __ movl(EAX, Address(EBP, 0)); |
| 47 __ movl(EAX, Address(EAX, 0)); | 42 __ movl(EAX, Address(EAX, 0)); |
| 48 | 43 |
| 49 __ movl(EAX, Address(ESP, kWordSize)); | 44 __ movl(EAX, Address(ESP, kWordSize)); |
| 50 __ movl(EAX, Address(EBP, kWordSize)); | 45 __ movl(EAX, Address(EBP, kWordSize)); |
| 51 __ movl(EAX, Address(EAX, kWordSize)); | 46 __ movl(EAX, Address(EAX, kWordSize)); |
| 52 | 47 |
| 53 __ movl(EAX, Address(ESP, -kWordSize)); | 48 __ movl(EAX, Address(ESP, -kWordSize)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); | 86 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); |
| 92 | 87 |
| 93 __ movl(EAX, Address(EAX, EBP, TIMES_2, 256 * kWordSize)); | 88 __ movl(EAX, Address(EAX, EBP, TIMES_2, 256 * kWordSize)); |
| 94 __ movl(EAX, Address(EAX, EAX, TIMES_2, 256 * kWordSize)); | 89 __ movl(EAX, Address(EAX, EAX, TIMES_2, 256 * kWordSize)); |
| 95 __ movl(EAX, Address(EBP, EBP, TIMES_2, 256 * kWordSize)); | 90 __ movl(EAX, Address(EBP, EBP, TIMES_2, 256 * kWordSize)); |
| 96 __ movl(EAX, Address(EBP, EAX, TIMES_2, 256 * kWordSize)); | 91 __ movl(EAX, Address(EBP, EAX, TIMES_2, 256 * kWordSize)); |
| 97 __ movl(EAX, Address(ESP, EBP, TIMES_2, 256 * kWordSize)); | 92 __ movl(EAX, Address(ESP, EBP, TIMES_2, 256 * kWordSize)); |
| 98 __ movl(EAX, Address(ESP, EAX, TIMES_2, 256 * kWordSize)); | 93 __ movl(EAX, Address(ESP, EAX, TIMES_2, 256 * kWordSize)); |
| 99 } | 94 } |
| 100 | 95 |
| 101 | |
| 102 ASSEMBLER_TEST_RUN(AddressingModes, test) { | 96 ASSEMBLER_TEST_RUN(AddressingModes, test) { |
| 103 // Avoid running the code since it is constructed to lead to crashes. | 97 // Avoid running the code since it is constructed to lead to crashes. |
| 104 } | 98 } |
| 105 | 99 |
| 106 | |
| 107 ASSEMBLER_TEST_GENERATE(JumpAroundCrash, assembler) { | 100 ASSEMBLER_TEST_GENERATE(JumpAroundCrash, assembler) { |
| 108 Label done; | 101 Label done; |
| 109 // Make sure all the condition jumps work. | 102 // Make sure all the condition jumps work. |
| 110 for (Condition condition = OVERFLOW; condition <= GREATER; | 103 for (Condition condition = OVERFLOW; condition <= GREATER; |
| 111 condition = static_cast<Condition>(condition + 1)) { | 104 condition = static_cast<Condition>(condition + 1)) { |
| 112 __ j(condition, &done); | 105 __ j(condition, &done); |
| 113 } | 106 } |
| 114 // This isn't strictly necessary, but we do an unconditional | 107 // This isn't strictly necessary, but we do an unconditional |
| 115 // jump around the crashing code anyway. | 108 // jump around the crashing code anyway. |
| 116 __ jmp(&done); | 109 __ jmp(&done); |
| 117 | 110 |
| 118 // Be sure to skip this crashing code. | 111 // Be sure to skip this crashing code. |
| 119 __ movl(EAX, Immediate(0)); | 112 __ movl(EAX, Immediate(0)); |
| 120 __ movl(Address(EAX, 0), EAX); | 113 __ movl(Address(EAX, 0), EAX); |
| 121 | 114 |
| 122 __ Bind(&done); | 115 __ Bind(&done); |
| 123 __ ret(); | 116 __ ret(); |
| 124 } | 117 } |
| 125 | 118 |
| 126 | |
| 127 ASSEMBLER_TEST_RUN(JumpAroundCrash, test) { | 119 ASSEMBLER_TEST_RUN(JumpAroundCrash, test) { |
| 128 Instr* instr = Instr::At(test->entry()); | 120 Instr* instr = Instr::At(test->entry()); |
| 129 EXPECT(!instr->IsBreakPoint()); | 121 EXPECT(!instr->IsBreakPoint()); |
| 130 typedef void (*JumpAroundCrashCode)(); | 122 typedef void (*JumpAroundCrashCode)(); |
| 131 reinterpret_cast<JumpAroundCrashCode>(test->entry())(); | 123 reinterpret_cast<JumpAroundCrashCode>(test->entry())(); |
| 132 } | 124 } |
| 133 | 125 |
| 134 | |
| 135 ASSEMBLER_TEST_GENERATE(NearJumpAroundCrash, assembler) { | 126 ASSEMBLER_TEST_GENERATE(NearJumpAroundCrash, assembler) { |
| 136 Label done; | 127 Label done; |
| 137 // Make sure all the condition jumps work. | 128 // Make sure all the condition jumps work. |
| 138 for (Condition condition = OVERFLOW; condition <= GREATER; | 129 for (Condition condition = OVERFLOW; condition <= GREATER; |
| 139 condition = static_cast<Condition>(condition + 1)) { | 130 condition = static_cast<Condition>(condition + 1)) { |
| 140 __ j(condition, &done, Assembler::kNearJump); | 131 __ j(condition, &done, Assembler::kNearJump); |
| 141 } | 132 } |
| 142 // This isn't strictly necessary, but we do an unconditional | 133 // This isn't strictly necessary, but we do an unconditional |
| 143 // jump around the crashing code anyway. | 134 // jump around the crashing code anyway. |
| 144 __ jmp(&done, Assembler::kNearJump); | 135 __ jmp(&done, Assembler::kNearJump); |
| 145 | 136 |
| 146 // Be sure to skip this crashing code. | 137 // Be sure to skip this crashing code. |
| 147 __ movl(EAX, Immediate(0)); | 138 __ movl(EAX, Immediate(0)); |
| 148 __ movl(Address(EAX, 0), EAX); | 139 __ movl(Address(EAX, 0), EAX); |
| 149 | 140 |
| 150 __ Bind(&done); | 141 __ Bind(&done); |
| 151 __ ret(); | 142 __ ret(); |
| 152 } | 143 } |
| 153 | 144 |
| 154 | |
| 155 ASSEMBLER_TEST_RUN(NearJumpAroundCrash, test) { | 145 ASSEMBLER_TEST_RUN(NearJumpAroundCrash, test) { |
| 156 typedef void (*NearJumpAroundCrashCode)(); | 146 typedef void (*NearJumpAroundCrashCode)(); |
| 157 reinterpret_cast<NearJumpAroundCrashCode>(test->entry())(); | 147 reinterpret_cast<NearJumpAroundCrashCode>(test->entry())(); |
| 158 } | 148 } |
| 159 | 149 |
| 160 | |
| 161 ASSEMBLER_TEST_GENERATE(SimpleLoop, assembler) { | 150 ASSEMBLER_TEST_GENERATE(SimpleLoop, assembler) { |
| 162 __ movl(EAX, Immediate(0)); | 151 __ movl(EAX, Immediate(0)); |
| 163 __ movl(ECX, Immediate(0)); | 152 __ movl(ECX, Immediate(0)); |
| 164 Label loop; | 153 Label loop; |
| 165 __ Bind(&loop); | 154 __ Bind(&loop); |
| 166 __ addl(EAX, Immediate(2)); | 155 __ addl(EAX, Immediate(2)); |
| 167 __ incl(ECX); | 156 __ incl(ECX); |
| 168 __ cmpl(ECX, Immediate(87)); | 157 __ cmpl(ECX, Immediate(87)); |
| 169 __ j(LESS, &loop); | 158 __ j(LESS, &loop); |
| 170 __ ret(); | 159 __ ret(); |
| 171 } | 160 } |
| 172 | 161 |
| 173 | |
| 174 ASSEMBLER_TEST_RUN(SimpleLoop, test) { | 162 ASSEMBLER_TEST_RUN(SimpleLoop, test) { |
| 175 typedef int (*SimpleLoopCode)(); | 163 typedef int (*SimpleLoopCode)(); |
| 176 EXPECT_EQ(2 * 87, reinterpret_cast<SimpleLoopCode>(test->entry())()); | 164 EXPECT_EQ(2 * 87, reinterpret_cast<SimpleLoopCode>(test->entry())()); |
| 177 } | 165 } |
| 178 | 166 |
| 179 | |
| 180 ASSEMBLER_TEST_GENERATE(Cmpb, assembler) { | 167 ASSEMBLER_TEST_GENERATE(Cmpb, assembler) { |
| 181 Label done; | 168 Label done; |
| 182 __ movl(EAX, Immediate(1)); | 169 __ movl(EAX, Immediate(1)); |
| 183 __ pushl(Immediate(0xffffff11)); | 170 __ pushl(Immediate(0xffffff11)); |
| 184 __ cmpb(Address(ESP, 0), Immediate(0x11)); | 171 __ cmpb(Address(ESP, 0), Immediate(0x11)); |
| 185 __ j(EQUAL, &done, Assembler::kNearJump); | 172 __ j(EQUAL, &done, Assembler::kNearJump); |
| 186 __ movl(EAX, Immediate(0)); | 173 __ movl(EAX, Immediate(0)); |
| 187 __ Bind(&done); | 174 __ Bind(&done); |
| 188 __ popl(ECX); | 175 __ popl(ECX); |
| 189 __ ret(); | 176 __ ret(); |
| 190 } | 177 } |
| 191 | 178 |
| 192 | |
| 193 ASSEMBLER_TEST_RUN(Cmpb, test) { | 179 ASSEMBLER_TEST_RUN(Cmpb, test) { |
| 194 typedef int (*CmpbCode)(); | 180 typedef int (*CmpbCode)(); |
| 195 EXPECT_EQ(1, reinterpret_cast<CmpbCode>(test->entry())()); | 181 EXPECT_EQ(1, reinterpret_cast<CmpbCode>(test->entry())()); |
| 196 } | 182 } |
| 197 | 183 |
| 198 | |
| 199 ASSEMBLER_TEST_GENERATE(Testb, assembler) { | 184 ASSEMBLER_TEST_GENERATE(Testb, assembler) { |
| 200 __ movl(EAX, Immediate(1)); | 185 __ movl(EAX, Immediate(1)); |
| 201 __ movl(ECX, Immediate(0)); | 186 __ movl(ECX, Immediate(0)); |
| 202 __ pushl(Immediate(0xffffff11)); | 187 __ pushl(Immediate(0xffffff11)); |
| 203 __ testb(Address(ESP, 0), Immediate(0x10)); | 188 __ testb(Address(ESP, 0), Immediate(0x10)); |
| 204 // Fail if zero flag set. | 189 // Fail if zero flag set. |
| 205 __ cmove(EAX, ECX); | 190 __ cmove(EAX, ECX); |
| 206 __ testb(Address(ESP, 0), Immediate(0x20)); | 191 __ testb(Address(ESP, 0), Immediate(0x20)); |
| 207 // Fail if zero flag not set. | 192 // Fail if zero flag not set. |
| 208 __ cmovne(EAX, ECX); | 193 __ cmovne(EAX, ECX); |
| 209 __ popl(ECX); | 194 __ popl(ECX); |
| 210 __ ret(); | 195 __ ret(); |
| 211 } | 196 } |
| 212 | 197 |
| 213 | |
| 214 ASSEMBLER_TEST_RUN(Testb, test) { | 198 ASSEMBLER_TEST_RUN(Testb, test) { |
| 215 typedef int (*TestbCode)(); | 199 typedef int (*TestbCode)(); |
| 216 EXPECT_EQ(1, reinterpret_cast<TestbCode>(test->entry())()); | 200 EXPECT_EQ(1, reinterpret_cast<TestbCode>(test->entry())()); |
| 217 } | 201 } |
| 218 | 202 |
| 219 | |
| 220 ASSEMBLER_TEST_GENERATE(Increment, assembler) { | 203 ASSEMBLER_TEST_GENERATE(Increment, assembler) { |
| 221 __ movl(EAX, Immediate(0)); | 204 __ movl(EAX, Immediate(0)); |
| 222 __ pushl(EAX); | 205 __ pushl(EAX); |
| 223 __ incl(Address(ESP, 0)); | 206 __ incl(Address(ESP, 0)); |
| 224 __ movl(ECX, Address(ESP, 0)); | 207 __ movl(ECX, Address(ESP, 0)); |
| 225 __ incl(ECX); | 208 __ incl(ECX); |
| 226 __ popl(EAX); | 209 __ popl(EAX); |
| 227 __ movl(EAX, ECX); | 210 __ movl(EAX, ECX); |
| 228 __ ret(); | 211 __ ret(); |
| 229 } | 212 } |
| 230 | 213 |
| 231 | |
| 232 ASSEMBLER_TEST_RUN(Increment, test) { | 214 ASSEMBLER_TEST_RUN(Increment, test) { |
| 233 typedef int (*IncrementCode)(); | 215 typedef int (*IncrementCode)(); |
| 234 EXPECT_EQ(2, reinterpret_cast<IncrementCode>(test->entry())()); | 216 EXPECT_EQ(2, reinterpret_cast<IncrementCode>(test->entry())()); |
| 235 } | 217 } |
| 236 | 218 |
| 237 | |
| 238 ASSEMBLER_TEST_GENERATE(Decrement, assembler) { | 219 ASSEMBLER_TEST_GENERATE(Decrement, assembler) { |
| 239 __ movl(EAX, Immediate(2)); | 220 __ movl(EAX, Immediate(2)); |
| 240 __ pushl(EAX); | 221 __ pushl(EAX); |
| 241 __ decl(Address(ESP, 0)); | 222 __ decl(Address(ESP, 0)); |
| 242 __ movl(ECX, Address(ESP, 0)); | 223 __ movl(ECX, Address(ESP, 0)); |
| 243 __ decl(ECX); | 224 __ decl(ECX); |
| 244 __ popl(EAX); | 225 __ popl(EAX); |
| 245 __ movl(EAX, ECX); | 226 __ movl(EAX, ECX); |
| 246 __ ret(); | 227 __ ret(); |
| 247 } | 228 } |
| 248 | 229 |
| 249 | |
| 250 ASSEMBLER_TEST_RUN(Decrement, test) { | 230 ASSEMBLER_TEST_RUN(Decrement, test) { |
| 251 typedef int (*DecrementCode)(); | 231 typedef int (*DecrementCode)(); |
| 252 EXPECT_EQ(0, reinterpret_cast<DecrementCode>(test->entry())()); | 232 EXPECT_EQ(0, reinterpret_cast<DecrementCode>(test->entry())()); |
| 253 } | 233 } |
| 254 | 234 |
| 255 | |
| 256 ASSEMBLER_TEST_GENERATE(AddressBinOp, assembler) { | 235 ASSEMBLER_TEST_GENERATE(AddressBinOp, assembler) { |
| 257 __ movl(EAX, Address(ESP, kWordSize)); | 236 __ movl(EAX, Address(ESP, kWordSize)); |
| 258 __ addl(EAX, Address(ESP, kWordSize)); | 237 __ addl(EAX, Address(ESP, kWordSize)); |
| 259 __ incl(EAX); | 238 __ incl(EAX); |
| 260 __ subl(EAX, Address(ESP, kWordSize)); | 239 __ subl(EAX, Address(ESP, kWordSize)); |
| 261 __ imull(EAX, Address(ESP, kWordSize)); | 240 __ imull(EAX, Address(ESP, kWordSize)); |
| 262 __ ret(); | 241 __ ret(); |
| 263 } | 242 } |
| 264 | 243 |
| 265 | |
| 266 ASSEMBLER_TEST_RUN(AddressBinOp, test) { | 244 ASSEMBLER_TEST_RUN(AddressBinOp, test) { |
| 267 typedef int (*AddressBinOpCode)(int a); | 245 typedef int (*AddressBinOpCode)(int a); |
| 268 EXPECT_EQ((2 + 2 + 1 - 2) * 2, | 246 EXPECT_EQ((2 + 2 + 1 - 2) * 2, |
| 269 reinterpret_cast<AddressBinOpCode>(test->entry())(2)); | 247 reinterpret_cast<AddressBinOpCode>(test->entry())(2)); |
| 270 } | 248 } |
| 271 | 249 |
| 272 | |
| 273 ASSEMBLER_TEST_GENERATE(SignedMultiply, assembler) { | 250 ASSEMBLER_TEST_GENERATE(SignedMultiply, assembler) { |
| 274 __ movl(EAX, Immediate(2)); | 251 __ movl(EAX, Immediate(2)); |
| 275 __ movl(ECX, Immediate(4)); | 252 __ movl(ECX, Immediate(4)); |
| 276 __ imull(EAX, ECX); | 253 __ imull(EAX, ECX); |
| 277 __ imull(EAX, Immediate(1000)); | 254 __ imull(EAX, Immediate(1000)); |
| 278 __ ret(); | 255 __ ret(); |
| 279 } | 256 } |
| 280 | 257 |
| 281 | |
| 282 ASSEMBLER_TEST_RUN(SignedMultiply, test) { | 258 ASSEMBLER_TEST_RUN(SignedMultiply, test) { |
| 283 typedef int (*SignedMultiply)(); | 259 typedef int (*SignedMultiply)(); |
| 284 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply>(test->entry())()); | 260 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply>(test->entry())()); |
| 285 } | 261 } |
| 286 | 262 |
| 287 | |
| 288 ASSEMBLER_TEST_GENERATE(OverflowSignedMultiply, assembler) { | 263 ASSEMBLER_TEST_GENERATE(OverflowSignedMultiply, assembler) { |
| 289 __ movl(EDX, Immediate(0)); | 264 __ movl(EDX, Immediate(0)); |
| 290 __ movl(EAX, Immediate(0x0fffffff)); | 265 __ movl(EAX, Immediate(0x0fffffff)); |
| 291 __ movl(ECX, Immediate(0x0fffffff)); | 266 __ movl(ECX, Immediate(0x0fffffff)); |
| 292 __ imull(EAX, ECX); | 267 __ imull(EAX, ECX); |
| 293 __ imull(EAX, EDX); | 268 __ imull(EAX, EDX); |
| 294 __ ret(); | 269 __ ret(); |
| 295 } | 270 } |
| 296 | 271 |
| 297 | |
| 298 ASSEMBLER_TEST_RUN(OverflowSignedMultiply, test) { | 272 ASSEMBLER_TEST_RUN(OverflowSignedMultiply, test) { |
| 299 typedef int (*OverflowSignedMultiply)(); | 273 typedef int (*OverflowSignedMultiply)(); |
| 300 EXPECT_EQ(0, reinterpret_cast<OverflowSignedMultiply>(test->entry())()); | 274 EXPECT_EQ(0, reinterpret_cast<OverflowSignedMultiply>(test->entry())()); |
| 301 } | 275 } |
| 302 | 276 |
| 303 | |
| 304 ASSEMBLER_TEST_GENERATE(SignedMultiply1, assembler) { | 277 ASSEMBLER_TEST_GENERATE(SignedMultiply1, assembler) { |
| 305 __ pushl(EBX); // preserve EBX. | 278 __ pushl(EBX); // preserve EBX. |
| 306 __ movl(EBX, Immediate(2)); | 279 __ movl(EBX, Immediate(2)); |
| 307 __ movl(ECX, Immediate(4)); | 280 __ movl(ECX, Immediate(4)); |
| 308 __ imull(EBX, ECX); | 281 __ imull(EBX, ECX); |
| 309 __ imull(EBX, Immediate(1000)); | 282 __ imull(EBX, Immediate(1000)); |
| 310 __ movl(EAX, EBX); | 283 __ movl(EAX, EBX); |
| 311 __ popl(EBX); // restore EBX. | 284 __ popl(EBX); // restore EBX. |
| 312 __ ret(); | 285 __ ret(); |
| 313 } | 286 } |
| 314 | 287 |
| 315 | |
| 316 ASSEMBLER_TEST_RUN(SignedMultiply1, test) { | 288 ASSEMBLER_TEST_RUN(SignedMultiply1, test) { |
| 317 typedef int (*SignedMultiply1)(); | 289 typedef int (*SignedMultiply1)(); |
| 318 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply1>(test->entry())()); | 290 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply1>(test->entry())()); |
| 319 } | 291 } |
| 320 | 292 |
| 321 | |
| 322 ASSEMBLER_TEST_GENERATE(Negate, assembler) { | 293 ASSEMBLER_TEST_GENERATE(Negate, assembler) { |
| 323 __ movl(ECX, Immediate(42)); | 294 __ movl(ECX, Immediate(42)); |
| 324 __ negl(ECX); | 295 __ negl(ECX); |
| 325 __ movl(EAX, ECX); | 296 __ movl(EAX, ECX); |
| 326 __ ret(); | 297 __ ret(); |
| 327 } | 298 } |
| 328 | 299 |
| 329 | |
| 330 ASSEMBLER_TEST_RUN(Negate, test) { | 300 ASSEMBLER_TEST_RUN(Negate, test) { |
| 331 typedef int (*Negate)(); | 301 typedef int (*Negate)(); |
| 332 EXPECT_EQ(-42, reinterpret_cast<Negate>(test->entry())()); | 302 EXPECT_EQ(-42, reinterpret_cast<Negate>(test->entry())()); |
| 333 } | 303 } |
| 334 | 304 |
| 335 | |
| 336 ASSEMBLER_TEST_GENERATE(BitScanReverse, assembler) { | 305 ASSEMBLER_TEST_GENERATE(BitScanReverse, assembler) { |
| 337 __ movl(ECX, Address(ESP, kWordSize)); | 306 __ movl(ECX, Address(ESP, kWordSize)); |
| 338 __ movl(EAX, Immediate(666)); // Marker for conditional write. | 307 __ movl(EAX, Immediate(666)); // Marker for conditional write. |
| 339 __ bsrl(EAX, ECX); | 308 __ bsrl(EAX, ECX); |
| 340 __ ret(); | 309 __ ret(); |
| 341 } | 310 } |
| 342 | 311 |
| 343 | |
| 344 ASSEMBLER_TEST_RUN(BitScanReverse, test) { | 312 ASSEMBLER_TEST_RUN(BitScanReverse, test) { |
| 345 typedef int (*Bsr)(int input); | 313 typedef int (*Bsr)(int input); |
| 346 Bsr call = reinterpret_cast<Bsr>(test->entry()); | 314 Bsr call = reinterpret_cast<Bsr>(test->entry()); |
| 347 EXPECT_EQ(666, call(0)); | 315 EXPECT_EQ(666, call(0)); |
| 348 EXPECT_EQ(0, call(1)); | 316 EXPECT_EQ(0, call(1)); |
| 349 EXPECT_EQ(1, call(2)); | 317 EXPECT_EQ(1, call(2)); |
| 350 EXPECT_EQ(1, call(3)); | 318 EXPECT_EQ(1, call(3)); |
| 351 EXPECT_EQ(2, call(4)); | 319 EXPECT_EQ(2, call(4)); |
| 352 EXPECT_EQ(5, call(42)); | 320 EXPECT_EQ(5, call(42)); |
| 353 EXPECT_EQ(31, call(-1)); | 321 EXPECT_EQ(31, call(-1)); |
| 354 } | 322 } |
| 355 | 323 |
| 356 | |
| 357 ASSEMBLER_TEST_GENERATE(MoveExtend, assembler) { | 324 ASSEMBLER_TEST_GENERATE(MoveExtend, assembler) { |
| 358 __ pushl(EBX); // preserve EBX. | 325 __ pushl(EBX); // preserve EBX. |
| 359 __ movl(EDX, Immediate(0x1234ffff)); | 326 __ movl(EDX, Immediate(0x1234ffff)); |
| 360 __ movzxb(EAX, DL); // EAX = 0xff | 327 __ movzxb(EAX, DL); // EAX = 0xff |
| 361 __ movsxw(EBX, EDX); // EBX = -1 | 328 __ movsxw(EBX, EDX); // EBX = -1 |
| 362 __ movzxw(ECX, EDX); // ECX = 0xffff | 329 __ movzxw(ECX, EDX); // ECX = 0xffff |
| 363 __ addl(EBX, ECX); | 330 __ addl(EBX, ECX); |
| 364 __ addl(EAX, EBX); | 331 __ addl(EAX, EBX); |
| 365 __ popl(EBX); // restore EBX. | 332 __ popl(EBX); // restore EBX. |
| 366 __ ret(); | 333 __ ret(); |
| 367 } | 334 } |
| 368 | 335 |
| 369 | |
| 370 ASSEMBLER_TEST_RUN(MoveExtend, test) { | 336 ASSEMBLER_TEST_RUN(MoveExtend, test) { |
| 371 typedef int (*MoveExtend)(); | 337 typedef int (*MoveExtend)(); |
| 372 EXPECT_EQ(0xff - 1 + 0xffff, reinterpret_cast<MoveExtend>(test->entry())()); | 338 EXPECT_EQ(0xff - 1 + 0xffff, reinterpret_cast<MoveExtend>(test->entry())()); |
| 373 } | 339 } |
| 374 | 340 |
| 375 | |
| 376 ASSEMBLER_TEST_GENERATE(MoveExtendMemory, assembler) { | 341 ASSEMBLER_TEST_GENERATE(MoveExtendMemory, assembler) { |
| 377 __ pushl(EBX); // preserve EBX. | 342 __ pushl(EBX); // preserve EBX. |
| 378 __ movl(EDX, Immediate(0x1234ffff)); | 343 __ movl(EDX, Immediate(0x1234ffff)); |
| 379 | 344 |
| 380 __ pushl(EDX); | 345 __ pushl(EDX); |
| 381 __ movzxb(EAX, Address(ESP, 0)); // EAX = 0xff | 346 __ movzxb(EAX, Address(ESP, 0)); // EAX = 0xff |
| 382 __ movsxw(EBX, Address(ESP, 0)); // EBX = -1 | 347 __ movsxw(EBX, Address(ESP, 0)); // EBX = -1 |
| 383 __ movzxw(ECX, Address(ESP, 0)); // ECX = 0xffff | 348 __ movzxw(ECX, Address(ESP, 0)); // ECX = 0xffff |
| 384 __ addl(ESP, Immediate(kWordSize)); | 349 __ addl(ESP, Immediate(kWordSize)); |
| 385 | 350 |
| 386 __ addl(EBX, ECX); | 351 __ addl(EBX, ECX); |
| 387 __ addl(EAX, EBX); | 352 __ addl(EAX, EBX); |
| 388 __ popl(EBX); // restore EBX. | 353 __ popl(EBX); // restore EBX. |
| 389 __ ret(); | 354 __ ret(); |
| 390 } | 355 } |
| 391 | 356 |
| 392 | |
| 393 ASSEMBLER_TEST_RUN(MoveExtendMemory, test) { | 357 ASSEMBLER_TEST_RUN(MoveExtendMemory, test) { |
| 394 typedef int (*MoveExtendMemory)(); | 358 typedef int (*MoveExtendMemory)(); |
| 395 EXPECT_EQ(0xff - 1 + 0xffff, | 359 EXPECT_EQ(0xff - 1 + 0xffff, |
| 396 reinterpret_cast<MoveExtendMemory>(test->entry())()); | 360 reinterpret_cast<MoveExtendMemory>(test->entry())()); |
| 397 } | 361 } |
| 398 | 362 |
| 399 | |
| 400 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { | 363 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { |
| 401 __ movl(ECX, Immediate(42)); | 364 __ movl(ECX, Immediate(42)); |
| 402 __ xorl(ECX, ECX); | 365 __ xorl(ECX, ECX); |
| 403 __ orl(ECX, Immediate(0x100)); | 366 __ orl(ECX, Immediate(0x100)); |
| 404 __ movl(EAX, Immediate(0x648)); | 367 __ movl(EAX, Immediate(0x648)); |
| 405 __ orl(ECX, EAX); // 0x748. | 368 __ orl(ECX, EAX); // 0x748. |
| 406 __ movl(EAX, Immediate(0xfff0)); | 369 __ movl(EAX, Immediate(0xfff0)); |
| 407 __ andl(ECX, EAX); // 0x740. | 370 __ andl(ECX, EAX); // 0x740. |
| 408 __ pushl(Immediate(0xF6FF)); | 371 __ pushl(Immediate(0xF6FF)); |
| 409 __ andl(ECX, Address(ESP, 0)); // 0x640. | 372 __ andl(ECX, Address(ESP, 0)); // 0x640. |
| 410 __ popl(EAX); // Discard. | 373 __ popl(EAX); // Discard. |
| 411 __ movl(EAX, Immediate(1)); | 374 __ movl(EAX, Immediate(1)); |
| 412 __ orl(ECX, EAX); // 0x641. | 375 __ orl(ECX, EAX); // 0x641. |
| 413 __ pushl(Immediate(0x7)); | 376 __ pushl(Immediate(0x7)); |
| 414 __ orl(ECX, Address(ESP, 0)); // 0x647. | 377 __ orl(ECX, Address(ESP, 0)); // 0x647. |
| 415 __ popl(EAX); // Discard. | 378 __ popl(EAX); // Discard. |
| 416 __ xorl(ECX, Immediate(0)); // 0x647. | 379 __ xorl(ECX, Immediate(0)); // 0x647. |
| 417 __ pushl(Immediate(0x1C)); | 380 __ pushl(Immediate(0x1C)); |
| 418 __ xorl(ECX, Address(ESP, 0)); // 0x65B. | 381 __ xorl(ECX, Address(ESP, 0)); // 0x65B. |
| 419 __ popl(EAX); // Discard. | 382 __ popl(EAX); // Discard. |
| 420 __ movl(EAX, Address(ESP, kWordSize)); | 383 __ movl(EAX, Address(ESP, kWordSize)); |
| 421 __ movl(EDX, Immediate(0xB0)); | 384 __ movl(EDX, Immediate(0xB0)); |
| 422 __ orl(Address(EAX, 0), EDX); | 385 __ orl(Address(EAX, 0), EDX); |
| 423 __ movl(EAX, ECX); | 386 __ movl(EAX, ECX); |
| 424 __ ret(); | 387 __ ret(); |
| 425 } | 388 } |
| 426 | 389 |
| 427 | |
| 428 ASSEMBLER_TEST_RUN(Bitwise, test) { | 390 ASSEMBLER_TEST_RUN(Bitwise, test) { |
| 429 typedef int (*Bitwise)(int* value); | 391 typedef int (*Bitwise)(int* value); |
| 430 int value = 0xA; | 392 int value = 0xA; |
| 431 const int result = reinterpret_cast<Bitwise>(test->entry())(&value); | 393 const int result = reinterpret_cast<Bitwise>(test->entry())(&value); |
| 432 EXPECT_EQ(0x65B, result); | 394 EXPECT_EQ(0x65B, result); |
| 433 EXPECT_EQ(0xBA, value); | 395 EXPECT_EQ(0xBA, value); |
| 434 } | 396 } |
| 435 | 397 |
| 436 | |
| 437 ASSEMBLER_TEST_GENERATE(LogicalOps, assembler) { | 398 ASSEMBLER_TEST_GENERATE(LogicalOps, assembler) { |
| 438 Label donetest1; | 399 Label donetest1; |
| 439 __ movl(EAX, Immediate(4)); | 400 __ movl(EAX, Immediate(4)); |
| 440 __ andl(EAX, Immediate(2)); | 401 __ andl(EAX, Immediate(2)); |
| 441 __ cmpl(EAX, Immediate(0)); | 402 __ cmpl(EAX, Immediate(0)); |
| 442 __ j(EQUAL, &donetest1); | 403 __ j(EQUAL, &donetest1); |
| 443 // Be sure to skip this crashing code. | 404 // Be sure to skip this crashing code. |
| 444 __ movl(EAX, Immediate(0)); | 405 __ movl(EAX, Immediate(0)); |
| 445 __ movl(Address(EAX, 0), EAX); | 406 __ movl(Address(EAX, 0), EAX); |
| 446 __ Bind(&donetest1); | 407 __ Bind(&donetest1); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 __ shldl(EDX, EAX, Immediate(2)); | 576 __ shldl(EDX, EAX, Immediate(2)); |
| 616 __ cmpl(EDX, Immediate(0xF0000003)); | 577 __ cmpl(EDX, Immediate(0xF0000003)); |
| 617 __ j(EQUAL, &donetest17); | 578 __ j(EQUAL, &donetest17); |
| 618 __ int3(); | 579 __ int3(); |
| 619 __ Bind(&donetest17); | 580 __ Bind(&donetest17); |
| 620 | 581 |
| 621 __ movl(EAX, Immediate(0)); | 582 __ movl(EAX, Immediate(0)); |
| 622 __ ret(); | 583 __ ret(); |
| 623 } | 584 } |
| 624 | 585 |
| 625 | |
| 626 ASSEMBLER_TEST_RUN(LogicalOps, test) { | 586 ASSEMBLER_TEST_RUN(LogicalOps, test) { |
| 627 typedef int (*LogicalOpsCode)(); | 587 typedef int (*LogicalOpsCode)(); |
| 628 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); | 588 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); |
| 629 } | 589 } |
| 630 | 590 |
| 631 | |
| 632 ASSEMBLER_TEST_GENERATE(LogicalTest, assembler) { | 591 ASSEMBLER_TEST_GENERATE(LogicalTest, assembler) { |
| 633 __ pushl(EBX); // save EBX. | 592 __ pushl(EBX); // save EBX. |
| 634 Label donetest1; | 593 Label donetest1; |
| 635 __ movl(EAX, Immediate(4)); | 594 __ movl(EAX, Immediate(4)); |
| 636 __ movl(ECX, Immediate(2)); | 595 __ movl(ECX, Immediate(2)); |
| 637 __ testl(EAX, ECX); | 596 __ testl(EAX, ECX); |
| 638 __ j(EQUAL, &donetest1); | 597 __ j(EQUAL, &donetest1); |
| 639 // Be sure to skip this crashing code. | 598 // Be sure to skip this crashing code. |
| 640 __ movl(EAX, Immediate(0)); | 599 __ movl(EAX, Immediate(0)); |
| 641 __ movl(Address(EAX, 0), EAX); | 600 __ movl(Address(EAX, 0), EAX); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 // Be sure to skip this crashing code. | 635 // Be sure to skip this crashing code. |
| 677 __ movl(EAX, Immediate(0)); | 636 __ movl(EAX, Immediate(0)); |
| 678 __ movl(Address(EAX, 0), EAX); | 637 __ movl(Address(EAX, 0), EAX); |
| 679 __ Bind(&donetest5); | 638 __ Bind(&donetest5); |
| 680 | 639 |
| 681 __ movl(EAX, Immediate(0)); | 640 __ movl(EAX, Immediate(0)); |
| 682 __ popl(EBX); // restore EBX. | 641 __ popl(EBX); // restore EBX. |
| 683 __ ret(); | 642 __ ret(); |
| 684 } | 643 } |
| 685 | 644 |
| 686 | |
| 687 ASSEMBLER_TEST_RUN(LogicalTest, test) { | 645 ASSEMBLER_TEST_RUN(LogicalTest, test) { |
| 688 typedef int (*LogicalTestCode)(); | 646 typedef int (*LogicalTestCode)(); |
| 689 EXPECT_EQ(0, reinterpret_cast<LogicalTestCode>(test->entry())()); | 647 EXPECT_EQ(0, reinterpret_cast<LogicalTestCode>(test->entry())()); |
| 690 } | 648 } |
| 691 | 649 |
| 692 | |
| 693 ASSEMBLER_TEST_GENERATE(CompareSwapEQ, assembler) { | 650 ASSEMBLER_TEST_GENERATE(CompareSwapEQ, assembler) { |
| 694 __ movl(EAX, Immediate(0)); | 651 __ movl(EAX, Immediate(0)); |
| 695 __ pushl(EAX); | 652 __ pushl(EAX); |
| 696 __ movl(EAX, Immediate(4)); | 653 __ movl(EAX, Immediate(4)); |
| 697 __ movl(ECX, Immediate(0)); | 654 __ movl(ECX, Immediate(0)); |
| 698 __ movl(Address(ESP, 0), EAX); | 655 __ movl(Address(ESP, 0), EAX); |
| 699 __ LockCmpxchgl(Address(ESP, 0), ECX); | 656 __ LockCmpxchgl(Address(ESP, 0), ECX); |
| 700 __ popl(EAX); | 657 __ popl(EAX); |
| 701 __ ret(); | 658 __ ret(); |
| 702 } | 659 } |
| 703 | 660 |
| 704 | |
| 705 ASSEMBLER_TEST_RUN(CompareSwapEQ, test) { | 661 ASSEMBLER_TEST_RUN(CompareSwapEQ, test) { |
| 706 typedef int (*CompareSwapEQCode)(); | 662 typedef int (*CompareSwapEQCode)(); |
| 707 EXPECT_EQ(0, reinterpret_cast<CompareSwapEQCode>(test->entry())()); | 663 EXPECT_EQ(0, reinterpret_cast<CompareSwapEQCode>(test->entry())()); |
| 708 } | 664 } |
| 709 | 665 |
| 710 | |
| 711 ASSEMBLER_TEST_GENERATE(CompareSwapNEQ, assembler) { | 666 ASSEMBLER_TEST_GENERATE(CompareSwapNEQ, assembler) { |
| 712 __ movl(EAX, Immediate(0)); | 667 __ movl(EAX, Immediate(0)); |
| 713 __ pushl(EAX); | 668 __ pushl(EAX); |
| 714 __ movl(EAX, Immediate(2)); | 669 __ movl(EAX, Immediate(2)); |
| 715 __ movl(ECX, Immediate(4)); | 670 __ movl(ECX, Immediate(4)); |
| 716 __ movl(Address(ESP, 0), ECX); | 671 __ movl(Address(ESP, 0), ECX); |
| 717 __ LockCmpxchgl(Address(ESP, 0), ECX); | 672 __ LockCmpxchgl(Address(ESP, 0), ECX); |
| 718 __ popl(EAX); | 673 __ popl(EAX); |
| 719 __ ret(); | 674 __ ret(); |
| 720 } | 675 } |
| 721 | 676 |
| 722 | |
| 723 ASSEMBLER_TEST_RUN(CompareSwapNEQ, test) { | 677 ASSEMBLER_TEST_RUN(CompareSwapNEQ, test) { |
| 724 typedef int (*CompareSwapNEQCode)(); | 678 typedef int (*CompareSwapNEQCode)(); |
| 725 EXPECT_EQ(4, reinterpret_cast<CompareSwapNEQCode>(test->entry())()); | 679 EXPECT_EQ(4, reinterpret_cast<CompareSwapNEQCode>(test->entry())()); |
| 726 } | 680 } |
| 727 | 681 |
| 728 | |
| 729 ASSEMBLER_TEST_GENERATE(SignedDivide, assembler) { | 682 ASSEMBLER_TEST_GENERATE(SignedDivide, assembler) { |
| 730 __ movl(EAX, Immediate(-87)); | 683 __ movl(EAX, Immediate(-87)); |
| 731 __ movl(EDX, Immediate(123)); | 684 __ movl(EDX, Immediate(123)); |
| 732 __ cdq(); | 685 __ cdq(); |
| 733 __ movl(ECX, Immediate(42)); | 686 __ movl(ECX, Immediate(42)); |
| 734 __ idivl(ECX); | 687 __ idivl(ECX); |
| 735 __ ret(); | 688 __ ret(); |
| 736 } | 689 } |
| 737 | 690 |
| 738 | |
| 739 ASSEMBLER_TEST_RUN(SignedDivide, test) { | 691 ASSEMBLER_TEST_RUN(SignedDivide, test) { |
| 740 typedef int (*SignedDivide)(); | 692 typedef int (*SignedDivide)(); |
| 741 EXPECT_EQ(-87 / 42, reinterpret_cast<SignedDivide>(test->entry())()); | 693 EXPECT_EQ(-87 / 42, reinterpret_cast<SignedDivide>(test->entry())()); |
| 742 } | 694 } |
| 743 | 695 |
| 744 | |
| 745 ASSEMBLER_TEST_GENERATE(UnsignedDivide, assembler) { | 696 ASSEMBLER_TEST_GENERATE(UnsignedDivide, assembler) { |
| 746 __ movl(EAX, Immediate(0xffffffbe)); | 697 __ movl(EAX, Immediate(0xffffffbe)); |
| 747 __ movl(EDX, Immediate(0x41)); | 698 __ movl(EDX, Immediate(0x41)); |
| 748 __ movl(ECX, Immediate(-1)); | 699 __ movl(ECX, Immediate(-1)); |
| 749 __ divl(ECX); | 700 __ divl(ECX); |
| 750 __ ret(); | 701 __ ret(); |
| 751 } | 702 } |
| 752 | 703 |
| 753 | |
| 754 ASSEMBLER_TEST_RUN(UnsignedDivide, test) { | 704 ASSEMBLER_TEST_RUN(UnsignedDivide, test) { |
| 755 typedef int (*UnsignedDivide)(); | 705 typedef int (*UnsignedDivide)(); |
| 756 EXPECT_EQ(0x42, reinterpret_cast<UnsignedDivide>(test->entry())()); | 706 EXPECT_EQ(0x42, reinterpret_cast<UnsignedDivide>(test->entry())()); |
| 757 } | 707 } |
| 758 | 708 |
| 759 | |
| 760 ASSEMBLER_TEST_GENERATE(Exchange, assembler) { | 709 ASSEMBLER_TEST_GENERATE(Exchange, assembler) { |
| 761 __ movl(EAX, Immediate(123456789)); | 710 __ movl(EAX, Immediate(123456789)); |
| 762 __ movl(EDX, Immediate(987654321)); | 711 __ movl(EDX, Immediate(987654321)); |
| 763 __ xchgl(EAX, EDX); | 712 __ xchgl(EAX, EDX); |
| 764 __ subl(EAX, EDX); | 713 __ subl(EAX, EDX); |
| 765 __ ret(); | 714 __ ret(); |
| 766 } | 715 } |
| 767 | 716 |
| 768 | |
| 769 ASSEMBLER_TEST_RUN(Exchange, test) { | 717 ASSEMBLER_TEST_RUN(Exchange, test) { |
| 770 typedef int (*Exchange)(); | 718 typedef int (*Exchange)(); |
| 771 EXPECT_EQ(987654321 - 123456789, reinterpret_cast<Exchange>(test->entry())()); | 719 EXPECT_EQ(987654321 - 123456789, reinterpret_cast<Exchange>(test->entry())()); |
| 772 } | 720 } |
| 773 | 721 |
| 774 | |
| 775 static int ComputeStackSpaceReservation(int needed, int fixed) { | 722 static int ComputeStackSpaceReservation(int needed, int fixed) { |
| 776 return (OS::ActivationFrameAlignment() > 1) | 723 return (OS::ActivationFrameAlignment() > 1) |
| 777 ? Utils::RoundUp(needed + fixed, OS::ActivationFrameAlignment()) - | 724 ? Utils::RoundUp(needed + fixed, OS::ActivationFrameAlignment()) - |
| 778 fixed | 725 fixed |
| 779 : needed; | 726 : needed; |
| 780 } | 727 } |
| 781 | 728 |
| 782 | |
| 783 static int LeafReturn42() { | 729 static int LeafReturn42() { |
| 784 return 42; | 730 return 42; |
| 785 } | 731 } |
| 786 | 732 |
| 787 | |
| 788 static int LeafReturnArgument(int x) { | 733 static int LeafReturnArgument(int x) { |
| 789 return x + 87; | 734 return x + 87; |
| 790 } | 735 } |
| 791 | 736 |
| 792 | |
| 793 ASSEMBLER_TEST_GENERATE(CallSimpleLeaf, assembler) { | 737 ASSEMBLER_TEST_GENERATE(CallSimpleLeaf, assembler) { |
| 794 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); | 738 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); |
| 795 ExternalLabel call2(reinterpret_cast<uword>(LeafReturnArgument)); | 739 ExternalLabel call2(reinterpret_cast<uword>(LeafReturnArgument)); |
| 796 int space = ComputeStackSpaceReservation(0, 4); | 740 int space = ComputeStackSpaceReservation(0, 4); |
| 797 __ AddImmediate(ESP, Immediate(-space)); | 741 __ AddImmediate(ESP, Immediate(-space)); |
| 798 __ call(&call1); | 742 __ call(&call1); |
| 799 __ AddImmediate(ESP, Immediate(space)); | 743 __ AddImmediate(ESP, Immediate(space)); |
| 800 space = ComputeStackSpaceReservation(4, 4); | 744 space = ComputeStackSpaceReservation(4, 4); |
| 801 __ AddImmediate(ESP, Immediate(-space)); | 745 __ AddImmediate(ESP, Immediate(-space)); |
| 802 __ movl(Address(ESP, 0), EAX); | 746 __ movl(Address(ESP, 0), EAX); |
| 803 __ call(&call2); | 747 __ call(&call2); |
| 804 __ AddImmediate(ESP, Immediate(space)); | 748 __ AddImmediate(ESP, Immediate(space)); |
| 805 __ ret(); | 749 __ ret(); |
| 806 } | 750 } |
| 807 | 751 |
| 808 | |
| 809 ASSEMBLER_TEST_RUN(CallSimpleLeaf, test) { | 752 ASSEMBLER_TEST_RUN(CallSimpleLeaf, test) { |
| 810 typedef int (*CallSimpleLeafCode)(); | 753 typedef int (*CallSimpleLeafCode)(); |
| 811 EXPECT_EQ(42 + 87, reinterpret_cast<CallSimpleLeafCode>(test->entry())()); | 754 EXPECT_EQ(42 + 87, reinterpret_cast<CallSimpleLeafCode>(test->entry())()); |
| 812 } | 755 } |
| 813 | 756 |
| 814 | |
| 815 ASSEMBLER_TEST_GENERATE(JumpSimpleLeaf, assembler) { | 757 ASSEMBLER_TEST_GENERATE(JumpSimpleLeaf, assembler) { |
| 816 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); | 758 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); |
| 817 Label L; | 759 Label L; |
| 818 int space = ComputeStackSpaceReservation(0, 4); | 760 int space = ComputeStackSpaceReservation(0, 4); |
| 819 __ AddImmediate(ESP, Immediate(-space)); | 761 __ AddImmediate(ESP, Immediate(-space)); |
| 820 __ call(&L); | 762 __ call(&L); |
| 821 __ AddImmediate(ESP, Immediate(space)); | 763 __ AddImmediate(ESP, Immediate(space)); |
| 822 __ ret(); | 764 __ ret(); |
| 823 __ Bind(&L); | 765 __ Bind(&L); |
| 824 __ jmp(&call1); | 766 __ jmp(&call1); |
| 825 } | 767 } |
| 826 | 768 |
| 827 | |
| 828 ASSEMBLER_TEST_RUN(JumpSimpleLeaf, test) { | 769 ASSEMBLER_TEST_RUN(JumpSimpleLeaf, test) { |
| 829 typedef int (*JumpSimpleLeafCode)(); | 770 typedef int (*JumpSimpleLeafCode)(); |
| 830 EXPECT_EQ(42, reinterpret_cast<JumpSimpleLeafCode>(test->entry())()); | 771 EXPECT_EQ(42, reinterpret_cast<JumpSimpleLeafCode>(test->entry())()); |
| 831 } | 772 } |
| 832 | 773 |
| 833 | |
| 834 ASSEMBLER_TEST_GENERATE(JumpConditionalSimpleLeaf, assembler) { | 774 ASSEMBLER_TEST_GENERATE(JumpConditionalSimpleLeaf, assembler) { |
| 835 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); | 775 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); |
| 836 Label L; | 776 Label L; |
| 837 int space = ComputeStackSpaceReservation(0, 4); | 777 int space = ComputeStackSpaceReservation(0, 4); |
| 838 __ AddImmediate(ESP, Immediate(-space)); | 778 __ AddImmediate(ESP, Immediate(-space)); |
| 839 __ call(&L); | 779 __ call(&L); |
| 840 __ AddImmediate(ESP, Immediate(space)); | 780 __ AddImmediate(ESP, Immediate(space)); |
| 841 __ ret(); | 781 __ ret(); |
| 842 __ Bind(&L); | 782 __ Bind(&L); |
| 843 __ cmpl(EAX, EAX); | 783 __ cmpl(EAX, EAX); |
| 844 __ j(EQUAL, &call1); | 784 __ j(EQUAL, &call1); |
| 845 __ int3(); | 785 __ int3(); |
| 846 } | 786 } |
| 847 | 787 |
| 848 | |
| 849 ASSEMBLER_TEST_RUN(JumpConditionalSimpleLeaf, test) { | 788 ASSEMBLER_TEST_RUN(JumpConditionalSimpleLeaf, test) { |
| 850 typedef int (*JumpConditionalSimpleLeafCode)(); | 789 typedef int (*JumpConditionalSimpleLeafCode)(); |
| 851 EXPECT_EQ(42, | 790 EXPECT_EQ(42, |
| 852 reinterpret_cast<JumpConditionalSimpleLeafCode>(test->entry())()); | 791 reinterpret_cast<JumpConditionalSimpleLeafCode>(test->entry())()); |
| 853 } | 792 } |
| 854 | 793 |
| 855 | |
| 856 ASSEMBLER_TEST_GENERATE(SingleFPMoves, assembler) { | 794 ASSEMBLER_TEST_GENERATE(SingleFPMoves, assembler) { |
| 857 __ movl(EAX, Immediate(bit_cast<int32_t, float>(234.0f))); | 795 __ movl(EAX, Immediate(bit_cast<int32_t, float>(234.0f))); |
| 858 __ movd(XMM0, EAX); | 796 __ movd(XMM0, EAX); |
| 859 __ movss(XMM1, XMM0); | 797 __ movss(XMM1, XMM0); |
| 860 __ movss(XMM2, XMM1); | 798 __ movss(XMM2, XMM1); |
| 861 __ movss(XMM3, XMM2); | 799 __ movss(XMM3, XMM2); |
| 862 __ movss(XMM4, XMM3); | 800 __ movss(XMM4, XMM3); |
| 863 __ movss(XMM5, XMM4); | 801 __ movss(XMM5, XMM4); |
| 864 __ movss(XMM6, XMM5); | 802 __ movss(XMM6, XMM5); |
| 865 __ movss(XMM7, XMM6); | 803 __ movss(XMM7, XMM6); |
| 866 __ pushl(EAX); | 804 __ pushl(EAX); |
| 867 __ movl(Address(ESP, 0), Immediate(0)); | 805 __ movl(Address(ESP, 0), Immediate(0)); |
| 868 __ movss(Address(ESP, 0), XMM7); | 806 __ movss(Address(ESP, 0), XMM7); |
| 869 __ flds(Address(ESP, 0)); | 807 __ flds(Address(ESP, 0)); |
| 870 __ popl(EAX); | 808 __ popl(EAX); |
| 871 __ ret(); | 809 __ ret(); |
| 872 } | 810 } |
| 873 | 811 |
| 874 | |
| 875 ASSEMBLER_TEST_RUN(SingleFPMoves, test) { | 812 ASSEMBLER_TEST_RUN(SingleFPMoves, test) { |
| 876 typedef float (*SingleFPMovesCode)(); | 813 typedef float (*SingleFPMovesCode)(); |
| 877 float res = reinterpret_cast<SingleFPMovesCode>(test->entry())(); | 814 float res = reinterpret_cast<SingleFPMovesCode>(test->entry())(); |
| 878 EXPECT_EQ(234.0f, res); | 815 EXPECT_EQ(234.0f, res); |
| 879 } | 816 } |
| 880 | 817 |
| 881 | |
| 882 ASSEMBLER_TEST_GENERATE(SingleFPMoves2, assembler) { | 818 ASSEMBLER_TEST_GENERATE(SingleFPMoves2, assembler) { |
| 883 __ pushl(EBX); // preserve EBX. | 819 __ pushl(EBX); // preserve EBX. |
| 884 __ pushl(ECX); // preserve ECX. | 820 __ pushl(ECX); // preserve ECX. |
| 885 __ movl(EBX, Immediate(bit_cast<int32_t, float>(234.0f))); | 821 __ movl(EBX, Immediate(bit_cast<int32_t, float>(234.0f))); |
| 886 __ movd(XMM0, EBX); | 822 __ movd(XMM0, EBX); |
| 887 __ movss(XMM1, XMM0); | 823 __ movss(XMM1, XMM0); |
| 888 __ movd(ECX, XMM1); | 824 __ movd(ECX, XMM1); |
| 889 __ pushl(ECX); | 825 __ pushl(ECX); |
| 890 __ flds(Address(ESP, 0)); | 826 __ flds(Address(ESP, 0)); |
| 891 __ popl(EAX); | 827 __ popl(EAX); |
| 892 __ popl(ECX); | 828 __ popl(ECX); |
| 893 __ popl(EBX); | 829 __ popl(EBX); |
| 894 __ ret(); | 830 __ ret(); |
| 895 } | 831 } |
| 896 | 832 |
| 897 | |
| 898 ASSEMBLER_TEST_RUN(SingleFPMoves2, test) { | 833 ASSEMBLER_TEST_RUN(SingleFPMoves2, test) { |
| 899 typedef float (*SingleFPMoves2Code)(); | 834 typedef float (*SingleFPMoves2Code)(); |
| 900 float res = reinterpret_cast<SingleFPMoves2Code>(test->entry())(); | 835 float res = reinterpret_cast<SingleFPMoves2Code>(test->entry())(); |
| 901 EXPECT_EQ(234.0f, res); | 836 EXPECT_EQ(234.0f, res); |
| 902 } | 837 } |
| 903 | 838 |
| 904 | |
| 905 ASSEMBLER_TEST_GENERATE(SingleFPUStackMoves, assembler) { | 839 ASSEMBLER_TEST_GENERATE(SingleFPUStackMoves, assembler) { |
| 906 __ movl(EAX, Immediate(1131020288)); // 234.0f | 840 __ movl(EAX, Immediate(1131020288)); // 234.0f |
| 907 __ pushl(EAX); | 841 __ pushl(EAX); |
| 908 __ flds(Address(ESP, 0)); | 842 __ flds(Address(ESP, 0)); |
| 909 __ xorl(ECX, ECX); | 843 __ xorl(ECX, ECX); |
| 910 __ pushl(ECX); | 844 __ pushl(ECX); |
| 911 __ fstps(Address(ESP, 0)); | 845 __ fstps(Address(ESP, 0)); |
| 912 __ popl(EAX); | 846 __ popl(EAX); |
| 913 __ popl(ECX); | 847 __ popl(ECX); |
| 914 __ ret(); | 848 __ ret(); |
| 915 } | 849 } |
| 916 | 850 |
| 917 | |
| 918 ASSEMBLER_TEST_RUN(SingleFPUStackMoves, test) { | 851 ASSEMBLER_TEST_RUN(SingleFPUStackMoves, test) { |
| 919 typedef int (*SingleFPUStackMovesCode)(); | 852 typedef int (*SingleFPUStackMovesCode)(); |
| 920 int res = reinterpret_cast<SingleFPUStackMovesCode>(test->entry())(); | 853 int res = reinterpret_cast<SingleFPUStackMovesCode>(test->entry())(); |
| 921 EXPECT_EQ(234.0f, (bit_cast<float, int>(res))); | 854 EXPECT_EQ(234.0f, (bit_cast<float, int>(res))); |
| 922 } | 855 } |
| 923 | 856 |
| 924 | |
| 925 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { | 857 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { |
| 926 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 858 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 927 __ movd(XMM0, EAX); | 859 __ movd(XMM0, EAX); |
| 928 __ movl(EAX, Immediate(bit_cast<int32_t, float>(3.4f))); | 860 __ movl(EAX, Immediate(bit_cast<int32_t, float>(3.4f))); |
| 929 __ movd(XMM1, EAX); | 861 __ movd(XMM1, EAX); |
| 930 __ addss(XMM0, XMM1); // 15.7f | 862 __ addss(XMM0, XMM1); // 15.7f |
| 931 __ mulss(XMM0, XMM1); // 53.38f | 863 __ mulss(XMM0, XMM1); // 53.38f |
| 932 __ subss(XMM0, XMM1); // 49.98f | 864 __ subss(XMM0, XMM1); // 49.98f |
| 933 __ divss(XMM0, XMM1); // 14.7f | 865 __ divss(XMM0, XMM1); // 14.7f |
| 934 __ pushl(EAX); | 866 __ pushl(EAX); |
| 935 __ movss(Address(ESP, 0), XMM0); | 867 __ movss(Address(ESP, 0), XMM0); |
| 936 __ flds(Address(ESP, 0)); | 868 __ flds(Address(ESP, 0)); |
| 937 __ popl(EAX); | 869 __ popl(EAX); |
| 938 __ ret(); | 870 __ ret(); |
| 939 } | 871 } |
| 940 | 872 |
| 941 | |
| 942 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { | 873 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { |
| 943 typedef float (*SingleFPOperationsCode)(); | 874 typedef float (*SingleFPOperationsCode)(); |
| 944 float res = reinterpret_cast<SingleFPOperationsCode>(test->entry())(); | 875 float res = reinterpret_cast<SingleFPOperationsCode>(test->entry())(); |
| 945 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); | 876 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); |
| 946 } | 877 } |
| 947 | 878 |
| 948 | |
| 949 ASSEMBLER_TEST_GENERATE(PackedFPOperations, assembler) { | 879 ASSEMBLER_TEST_GENERATE(PackedFPOperations, assembler) { |
| 950 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 880 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 951 __ movd(XMM0, EAX); | 881 __ movd(XMM0, EAX); |
| 952 __ shufps(XMM0, XMM0, Immediate(0x0)); | 882 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 953 __ movl(EAX, Immediate(bit_cast<int32_t, float>(3.4f))); | 883 __ movl(EAX, Immediate(bit_cast<int32_t, float>(3.4f))); |
| 954 __ movd(XMM1, EAX); | 884 __ movd(XMM1, EAX); |
| 955 __ shufps(XMM1, XMM1, Immediate(0x0)); | 885 __ shufps(XMM1, XMM1, Immediate(0x0)); |
| 956 __ addps(XMM0, XMM1); // 15.7f | 886 __ addps(XMM0, XMM1); // 15.7f |
| 957 __ mulps(XMM0, XMM1); // 53.38f | 887 __ mulps(XMM0, XMM1); // 53.38f |
| 958 __ subps(XMM0, XMM1); // 49.98f | 888 __ subps(XMM0, XMM1); // 49.98f |
| 959 __ divps(XMM0, XMM1); // 14.7f | 889 __ divps(XMM0, XMM1); // 14.7f |
| 960 __ shufps(XMM0, XMM0, Immediate(0x55)); // Copy second lane into all 4 lanes. | 890 __ shufps(XMM0, XMM0, Immediate(0x55)); // Copy second lane into all 4 lanes. |
| 961 __ pushl(EAX); | 891 __ pushl(EAX); |
| 962 // Copy the low lane at ESP. | 892 // Copy the low lane at ESP. |
| 963 __ movss(Address(ESP, 0), XMM0); | 893 __ movss(Address(ESP, 0), XMM0); |
| 964 __ flds(Address(ESP, 0)); | 894 __ flds(Address(ESP, 0)); |
| 965 __ popl(EAX); | 895 __ popl(EAX); |
| 966 __ ret(); | 896 __ ret(); |
| 967 } | 897 } |
| 968 | 898 |
| 969 | |
| 970 ASSEMBLER_TEST_RUN(PackedFPOperations, test) { | 899 ASSEMBLER_TEST_RUN(PackedFPOperations, test) { |
| 971 typedef float (*PackedFPOperationsCode)(); | 900 typedef float (*PackedFPOperationsCode)(); |
| 972 float res = reinterpret_cast<PackedFPOperationsCode>(test->entry())(); | 901 float res = reinterpret_cast<PackedFPOperationsCode>(test->entry())(); |
| 973 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); | 902 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); |
| 974 } | 903 } |
| 975 | 904 |
| 976 | |
| 977 ASSEMBLER_TEST_GENERATE(PackedIntOperations, assembler) { | 905 ASSEMBLER_TEST_GENERATE(PackedIntOperations, assembler) { |
| 978 __ movl(EAX, Immediate(0x2)); | 906 __ movl(EAX, Immediate(0x2)); |
| 979 __ movd(XMM0, EAX); | 907 __ movd(XMM0, EAX); |
| 980 __ shufps(XMM0, XMM0, Immediate(0x0)); | 908 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 981 __ movl(EAX, Immediate(0x1)); | 909 __ movl(EAX, Immediate(0x1)); |
| 982 __ movd(XMM1, EAX); | 910 __ movd(XMM1, EAX); |
| 983 __ shufps(XMM1, XMM1, Immediate(0x0)); | 911 __ shufps(XMM1, XMM1, Immediate(0x0)); |
| 984 __ addpl(XMM0, XMM1); // 0x3 | 912 __ addpl(XMM0, XMM1); // 0x3 |
| 985 __ addpl(XMM0, XMM0); // 0x6 | 913 __ addpl(XMM0, XMM0); // 0x6 |
| 986 __ subpl(XMM0, XMM1); // 0x5 | 914 __ subpl(XMM0, XMM1); // 0x5 |
| 987 // Copy the low lane at ESP. | 915 // Copy the low lane at ESP. |
| 988 __ pushl(EAX); | 916 __ pushl(EAX); |
| 989 __ movss(Address(ESP, 0), XMM0); | 917 __ movss(Address(ESP, 0), XMM0); |
| 990 __ popl(EAX); | 918 __ popl(EAX); |
| 991 __ ret(); | 919 __ ret(); |
| 992 } | 920 } |
| 993 | 921 |
| 994 | |
| 995 ASSEMBLER_TEST_RUN(PackedIntOperations, test) { | 922 ASSEMBLER_TEST_RUN(PackedIntOperations, test) { |
| 996 typedef uint32_t (*PackedIntOperationsCode)(); | 923 typedef uint32_t (*PackedIntOperationsCode)(); |
| 997 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); | 924 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); |
| 998 EXPECT_EQ(static_cast<uword>(0x5), res); | 925 EXPECT_EQ(static_cast<uword>(0x5), res); |
| 999 } | 926 } |
| 1000 | 927 |
| 1001 | |
| 1002 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) { | 928 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) { |
| 1003 __ movl(EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 929 __ movl(EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1004 __ movd(XMM0, EAX); | 930 __ movd(XMM0, EAX); |
| 1005 __ shufps(XMM0, XMM0, Immediate(0x0)); | 931 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 1006 | 932 |
| 1007 __ movaps(XMM1, XMM0); // Copy XMM0 | 933 __ movaps(XMM1, XMM0); // Copy XMM0 |
| 1008 __ reciprocalps(XMM1); // 0.25 | 934 __ reciprocalps(XMM1); // 0.25 |
| 1009 __ sqrtps(XMM1); // 0.5 | 935 __ sqrtps(XMM1); // 0.5 |
| 1010 __ rsqrtps(XMM0); // ~0.5 | 936 __ rsqrtps(XMM0); // ~0.5 |
| 1011 __ subps(XMM0, XMM1); // ~0.0 | 937 __ subps(XMM0, XMM1); // ~0.0 |
| 1012 __ shufps(XMM0, XMM0, Immediate(0x00)); // Copy second lane into all 4 lanes. | 938 __ shufps(XMM0, XMM0, Immediate(0x00)); // Copy second lane into all 4 lanes. |
| 1013 __ pushl(EAX); | 939 __ pushl(EAX); |
| 1014 // Copy the low lane at ESP. | 940 // Copy the low lane at ESP. |
| 1015 __ movss(Address(ESP, 0), XMM0); | 941 __ movss(Address(ESP, 0), XMM0); |
| 1016 __ flds(Address(ESP, 0)); | 942 __ flds(Address(ESP, 0)); |
| 1017 __ popl(EAX); | 943 __ popl(EAX); |
| 1018 __ ret(); | 944 __ ret(); |
| 1019 } | 945 } |
| 1020 | 946 |
| 1021 | |
| 1022 ASSEMBLER_TEST_RUN(PackedFPOperations2, test) { | 947 ASSEMBLER_TEST_RUN(PackedFPOperations2, test) { |
| 1023 typedef float (*PackedFPOperations2Code)(); | 948 typedef float (*PackedFPOperations2Code)(); |
| 1024 float res = reinterpret_cast<PackedFPOperations2Code>(test->entry())(); | 949 float res = reinterpret_cast<PackedFPOperations2Code>(test->entry())(); |
| 1025 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); | 950 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
| 1026 } | 951 } |
| 1027 | 952 |
| 1028 | |
| 1029 ASSEMBLER_TEST_GENERATE(PackedCompareEQ, assembler) { | 953 ASSEMBLER_TEST_GENERATE(PackedCompareEQ, assembler) { |
| 1030 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 954 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1031 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 955 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1032 __ cmppseq(XMM0, XMM1); | 956 __ cmppseq(XMM0, XMM1); |
| 1033 // Copy the low lane at ESP. | 957 // Copy the low lane at ESP. |
| 1034 __ pushl(EAX); | 958 __ pushl(EAX); |
| 1035 __ movss(Address(ESP, 0), XMM0); | 959 __ movss(Address(ESP, 0), XMM0); |
| 1036 __ flds(Address(ESP, 0)); | 960 __ flds(Address(ESP, 0)); |
| 1037 __ popl(EAX); | 961 __ popl(EAX); |
| 1038 __ ret(); | 962 __ ret(); |
| 1039 } | 963 } |
| 1040 | 964 |
| 1041 | |
| 1042 ASSEMBLER_TEST_RUN(PackedCompareEQ, test) { | 965 ASSEMBLER_TEST_RUN(PackedCompareEQ, test) { |
| 1043 typedef uint32_t (*PackedCompareEQCode)(); | 966 typedef uint32_t (*PackedCompareEQCode)(); |
| 1044 uint32_t res = reinterpret_cast<PackedCompareEQCode>(test->entry())(); | 967 uint32_t res = reinterpret_cast<PackedCompareEQCode>(test->entry())(); |
| 1045 EXPECT_EQ(static_cast<uword>(0x0), res); | 968 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1046 } | 969 } |
| 1047 | 970 |
| 1048 | |
| 1049 ASSEMBLER_TEST_GENERATE(PackedCompareNEQ, assembler) { | 971 ASSEMBLER_TEST_GENERATE(PackedCompareNEQ, assembler) { |
| 1050 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 972 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1051 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 973 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1052 __ cmppsneq(XMM0, XMM1); | 974 __ cmppsneq(XMM0, XMM1); |
| 1053 // Copy the low lane at ESP. | 975 // Copy the low lane at ESP. |
| 1054 __ pushl(EAX); | 976 __ pushl(EAX); |
| 1055 __ movss(Address(ESP, 0), XMM0); | 977 __ movss(Address(ESP, 0), XMM0); |
| 1056 __ flds(Address(ESP, 0)); | 978 __ flds(Address(ESP, 0)); |
| 1057 __ popl(EAX); | 979 __ popl(EAX); |
| 1058 __ ret(); | 980 __ ret(); |
| 1059 } | 981 } |
| 1060 | 982 |
| 1061 | |
| 1062 ASSEMBLER_TEST_RUN(PackedCompareNEQ, test) { | 983 ASSEMBLER_TEST_RUN(PackedCompareNEQ, test) { |
| 1063 typedef uint32_t (*PackedCompareNEQCode)(); | 984 typedef uint32_t (*PackedCompareNEQCode)(); |
| 1064 uint32_t res = reinterpret_cast<PackedCompareNEQCode>(test->entry())(); | 985 uint32_t res = reinterpret_cast<PackedCompareNEQCode>(test->entry())(); |
| 1065 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); | 986 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
| 1066 } | 987 } |
| 1067 | 988 |
| 1068 | |
| 1069 ASSEMBLER_TEST_GENERATE(PackedCompareLT, assembler) { | 989 ASSEMBLER_TEST_GENERATE(PackedCompareLT, assembler) { |
| 1070 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 990 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1071 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 991 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1072 __ cmppslt(XMM0, XMM1); | 992 __ cmppslt(XMM0, XMM1); |
| 1073 // Copy the low lane at ESP. | 993 // Copy the low lane at ESP. |
| 1074 __ pushl(EAX); | 994 __ pushl(EAX); |
| 1075 __ movss(Address(ESP, 0), XMM0); | 995 __ movss(Address(ESP, 0), XMM0); |
| 1076 __ flds(Address(ESP, 0)); | 996 __ flds(Address(ESP, 0)); |
| 1077 __ popl(EAX); | 997 __ popl(EAX); |
| 1078 __ ret(); | 998 __ ret(); |
| 1079 } | 999 } |
| 1080 | 1000 |
| 1081 | |
| 1082 ASSEMBLER_TEST_RUN(PackedCompareLT, test) { | 1001 ASSEMBLER_TEST_RUN(PackedCompareLT, test) { |
| 1083 typedef uint32_t (*PackedCompareLTCode)(); | 1002 typedef uint32_t (*PackedCompareLTCode)(); |
| 1084 uint32_t res = reinterpret_cast<PackedCompareLTCode>(test->entry())(); | 1003 uint32_t res = reinterpret_cast<PackedCompareLTCode>(test->entry())(); |
| 1085 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); | 1004 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
| 1086 } | 1005 } |
| 1087 | 1006 |
| 1088 | |
| 1089 ASSEMBLER_TEST_GENERATE(PackedCompareLE, assembler) { | 1007 ASSEMBLER_TEST_GENERATE(PackedCompareLE, assembler) { |
| 1090 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 1008 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1091 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 1009 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1092 __ cmppsle(XMM0, XMM1); | 1010 __ cmppsle(XMM0, XMM1); |
| 1093 // Copy the low lane at ESP. | 1011 // Copy the low lane at ESP. |
| 1094 __ pushl(EAX); | 1012 __ pushl(EAX); |
| 1095 __ movss(Address(ESP, 0), XMM0); | 1013 __ movss(Address(ESP, 0), XMM0); |
| 1096 __ flds(Address(ESP, 0)); | 1014 __ flds(Address(ESP, 0)); |
| 1097 __ popl(EAX); | 1015 __ popl(EAX); |
| 1098 __ ret(); | 1016 __ ret(); |
| 1099 } | 1017 } |
| 1100 | 1018 |
| 1101 | |
| 1102 ASSEMBLER_TEST_RUN(PackedCompareLE, test) { | 1019 ASSEMBLER_TEST_RUN(PackedCompareLE, test) { |
| 1103 typedef uint32_t (*PackedCompareLECode)(); | 1020 typedef uint32_t (*PackedCompareLECode)(); |
| 1104 uint32_t res = reinterpret_cast<PackedCompareLECode>(test->entry())(); | 1021 uint32_t res = reinterpret_cast<PackedCompareLECode>(test->entry())(); |
| 1105 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); | 1022 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
| 1106 } | 1023 } |
| 1107 | 1024 |
| 1108 | |
| 1109 ASSEMBLER_TEST_GENERATE(PackedCompareNLT, assembler) { | 1025 ASSEMBLER_TEST_GENERATE(PackedCompareNLT, assembler) { |
| 1110 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 1026 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1111 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 1027 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1112 __ cmppsnlt(XMM0, XMM1); | 1028 __ cmppsnlt(XMM0, XMM1); |
| 1113 // Copy the low lane at ESP. | 1029 // Copy the low lane at ESP. |
| 1114 __ pushl(EAX); | 1030 __ pushl(EAX); |
| 1115 __ movss(Address(ESP, 0), XMM0); | 1031 __ movss(Address(ESP, 0), XMM0); |
| 1116 __ flds(Address(ESP, 0)); | 1032 __ flds(Address(ESP, 0)); |
| 1117 __ popl(EAX); | 1033 __ popl(EAX); |
| 1118 __ ret(); | 1034 __ ret(); |
| 1119 } | 1035 } |
| 1120 | 1036 |
| 1121 | |
| 1122 ASSEMBLER_TEST_RUN(PackedCompareNLT, test) { | 1037 ASSEMBLER_TEST_RUN(PackedCompareNLT, test) { |
| 1123 typedef uint32_t (*PackedCompareNLTCode)(); | 1038 typedef uint32_t (*PackedCompareNLTCode)(); |
| 1124 uint32_t res = reinterpret_cast<PackedCompareNLTCode>(test->entry())(); | 1039 uint32_t res = reinterpret_cast<PackedCompareNLTCode>(test->entry())(); |
| 1125 EXPECT_EQ(static_cast<uword>(0x0), res); | 1040 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1126 } | 1041 } |
| 1127 | 1042 |
| 1128 | |
| 1129 ASSEMBLER_TEST_GENERATE(PackedCompareNLE, assembler) { | 1043 ASSEMBLER_TEST_GENERATE(PackedCompareNLE, assembler) { |
| 1130 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 1044 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1131 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 1045 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1132 __ cmppsnle(XMM0, XMM1); | 1046 __ cmppsnle(XMM0, XMM1); |
| 1133 // Copy the low lane at ESP. | 1047 // Copy the low lane at ESP. |
| 1134 __ pushl(EAX); | 1048 __ pushl(EAX); |
| 1135 __ movss(Address(ESP, 0), XMM0); | 1049 __ movss(Address(ESP, 0), XMM0); |
| 1136 __ flds(Address(ESP, 0)); | 1050 __ flds(Address(ESP, 0)); |
| 1137 __ popl(EAX); | 1051 __ popl(EAX); |
| 1138 __ ret(); | 1052 __ ret(); |
| 1139 } | 1053 } |
| 1140 | 1054 |
| 1141 | |
| 1142 ASSEMBLER_TEST_RUN(PackedCompareNLE, test) { | 1055 ASSEMBLER_TEST_RUN(PackedCompareNLE, test) { |
| 1143 typedef uint32_t (*PackedCompareNLECode)(); | 1056 typedef uint32_t (*PackedCompareNLECode)(); |
| 1144 uint32_t res = reinterpret_cast<PackedCompareNLECode>(test->entry())(); | 1057 uint32_t res = reinterpret_cast<PackedCompareNLECode>(test->entry())(); |
| 1145 EXPECT_EQ(static_cast<uword>(0x0), res); | 1058 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1146 } | 1059 } |
| 1147 | 1060 |
| 1148 | |
| 1149 ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) { | 1061 ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) { |
| 1150 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 1062 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 1151 __ movd(XMM0, EAX); | 1063 __ movd(XMM0, EAX); |
| 1152 __ shufps(XMM0, XMM0, Immediate(0x0)); | 1064 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 1153 __ negateps(XMM0); | 1065 __ negateps(XMM0); |
| 1154 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. | 1066 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. |
| 1155 __ pushl(EAX); | 1067 __ pushl(EAX); |
| 1156 // Copy the low lane at ESP. | 1068 // Copy the low lane at ESP. |
| 1157 __ movss(Address(ESP, 0), XMM0); | 1069 __ movss(Address(ESP, 0), XMM0); |
| 1158 __ flds(Address(ESP, 0)); | 1070 __ flds(Address(ESP, 0)); |
| 1159 __ popl(EAX); | 1071 __ popl(EAX); |
| 1160 __ ret(); | 1072 __ ret(); |
| 1161 } | 1073 } |
| 1162 | 1074 |
| 1163 | |
| 1164 ASSEMBLER_TEST_RUN(PackedNegate, test) { | 1075 ASSEMBLER_TEST_RUN(PackedNegate, test) { |
| 1165 typedef float (*PackedNegateCode)(); | 1076 typedef float (*PackedNegateCode)(); |
| 1166 float res = reinterpret_cast<PackedNegateCode>(test->entry())(); | 1077 float res = reinterpret_cast<PackedNegateCode>(test->entry())(); |
| 1167 EXPECT_FLOAT_EQ(-12.3f, res, 0.001f); | 1078 EXPECT_FLOAT_EQ(-12.3f, res, 0.001f); |
| 1168 } | 1079 } |
| 1169 | 1080 |
| 1170 | |
| 1171 ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) { | 1081 ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) { |
| 1172 __ movl(EAX, Immediate(bit_cast<int32_t, float>(-15.3f))); | 1082 __ movl(EAX, Immediate(bit_cast<int32_t, float>(-15.3f))); |
| 1173 __ movd(XMM0, EAX); | 1083 __ movd(XMM0, EAX); |
| 1174 __ shufps(XMM0, XMM0, Immediate(0x0)); | 1084 __ shufps(XMM0, XMM0, Immediate(0x0)); |
| 1175 __ absps(XMM0); | 1085 __ absps(XMM0); |
| 1176 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. | 1086 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. |
| 1177 // Copy the low lane at ESP. | 1087 // Copy the low lane at ESP. |
| 1178 __ pushl(EAX); | 1088 __ pushl(EAX); |
| 1179 __ movss(Address(ESP, 0), XMM0); | 1089 __ movss(Address(ESP, 0), XMM0); |
| 1180 __ flds(Address(ESP, 0)); | 1090 __ flds(Address(ESP, 0)); |
| 1181 __ popl(EAX); | 1091 __ popl(EAX); |
| 1182 __ ret(); | 1092 __ ret(); |
| 1183 } | 1093 } |
| 1184 | 1094 |
| 1185 | |
| 1186 ASSEMBLER_TEST_RUN(PackedAbsolute, test) { | 1095 ASSEMBLER_TEST_RUN(PackedAbsolute, test) { |
| 1187 typedef float (*PackedAbsoluteCode)(); | 1096 typedef float (*PackedAbsoluteCode)(); |
| 1188 float res = reinterpret_cast<PackedAbsoluteCode>(test->entry())(); | 1097 float res = reinterpret_cast<PackedAbsoluteCode>(test->entry())(); |
| 1189 EXPECT_FLOAT_EQ(15.3f, res, 0.001f); | 1098 EXPECT_FLOAT_EQ(15.3f, res, 0.001f); |
| 1190 } | 1099 } |
| 1191 | 1100 |
| 1192 | |
| 1193 ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) { | 1101 ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) { |
| 1194 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 1102 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 1195 __ zerowps(XMM0); | 1103 __ zerowps(XMM0); |
| 1196 __ shufps(XMM0, XMM0, Immediate(0xFF)); // Copy the W lane which is now 0.0. | 1104 __ shufps(XMM0, XMM0, Immediate(0xFF)); // Copy the W lane which is now 0.0. |
| 1197 // Copy the low lane at ESP. | 1105 // Copy the low lane at ESP. |
| 1198 __ pushl(EAX); | 1106 __ pushl(EAX); |
| 1199 __ movss(Address(ESP, 0), XMM0); | 1107 __ movss(Address(ESP, 0), XMM0); |
| 1200 __ flds(Address(ESP, 0)); | 1108 __ flds(Address(ESP, 0)); |
| 1201 __ popl(EAX); | 1109 __ popl(EAX); |
| 1202 __ ret(); | 1110 __ ret(); |
| 1203 } | 1111 } |
| 1204 | 1112 |
| 1205 | |
| 1206 ASSEMBLER_TEST_RUN(PackedSetWZero, test) { | 1113 ASSEMBLER_TEST_RUN(PackedSetWZero, test) { |
| 1207 typedef float (*PackedSetWZeroCode)(); | 1114 typedef float (*PackedSetWZeroCode)(); |
| 1208 float res = reinterpret_cast<PackedSetWZeroCode>(test->entry())(); | 1115 float res = reinterpret_cast<PackedSetWZeroCode>(test->entry())(); |
| 1209 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); | 1116 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
| 1210 } | 1117 } |
| 1211 | 1118 |
| 1212 | |
| 1213 ASSEMBLER_TEST_GENERATE(PackedMin, assembler) { | 1119 ASSEMBLER_TEST_GENERATE(PackedMin, assembler) { |
| 1214 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 1120 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1215 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 1121 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1216 __ minps(XMM0, XMM1); | 1122 __ minps(XMM0, XMM1); |
| 1217 // Copy the low lane at ESP. | 1123 // Copy the low lane at ESP. |
| 1218 __ pushl(EAX); | 1124 __ pushl(EAX); |
| 1219 __ movss(Address(ESP, 0), XMM0); | 1125 __ movss(Address(ESP, 0), XMM0); |
| 1220 __ flds(Address(ESP, 0)); | 1126 __ flds(Address(ESP, 0)); |
| 1221 __ popl(EAX); | 1127 __ popl(EAX); |
| 1222 __ ret(); | 1128 __ ret(); |
| 1223 } | 1129 } |
| 1224 | 1130 |
| 1225 | |
| 1226 ASSEMBLER_TEST_RUN(PackedMin, test) { | 1131 ASSEMBLER_TEST_RUN(PackedMin, test) { |
| 1227 typedef float (*PackedMinCode)(); | 1132 typedef float (*PackedMinCode)(); |
| 1228 float res = reinterpret_cast<PackedMinCode>(test->entry())(); | 1133 float res = reinterpret_cast<PackedMinCode>(test->entry())(); |
| 1229 EXPECT_FLOAT_EQ(2.0f, res, 0.001f); | 1134 EXPECT_FLOAT_EQ(2.0f, res, 0.001f); |
| 1230 } | 1135 } |
| 1231 | 1136 |
| 1232 | |
| 1233 ASSEMBLER_TEST_GENERATE(PackedMax, assembler) { | 1137 ASSEMBLER_TEST_GENERATE(PackedMax, assembler) { |
| 1234 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 1138 __ set1ps(XMM0, EAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
| 1235 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 1139 __ set1ps(XMM1, EAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
| 1236 __ maxps(XMM0, XMM1); | 1140 __ maxps(XMM0, XMM1); |
| 1237 // Copy the low lane at ESP. | 1141 // Copy the low lane at ESP. |
| 1238 __ pushl(EAX); | 1142 __ pushl(EAX); |
| 1239 __ movss(Address(ESP, 0), XMM0); | 1143 __ movss(Address(ESP, 0), XMM0); |
| 1240 __ flds(Address(ESP, 0)); | 1144 __ flds(Address(ESP, 0)); |
| 1241 __ popl(EAX); | 1145 __ popl(EAX); |
| 1242 __ ret(); | 1146 __ ret(); |
| 1243 } | 1147 } |
| 1244 | 1148 |
| 1245 | |
| 1246 ASSEMBLER_TEST_RUN(PackedMax, test) { | 1149 ASSEMBLER_TEST_RUN(PackedMax, test) { |
| 1247 typedef float (*PackedMaxCode)(); | 1150 typedef float (*PackedMaxCode)(); |
| 1248 float res = reinterpret_cast<PackedMaxCode>(test->entry())(); | 1151 float res = reinterpret_cast<PackedMaxCode>(test->entry())(); |
| 1249 EXPECT_FLOAT_EQ(4.0f, res, 0.001f); | 1152 EXPECT_FLOAT_EQ(4.0f, res, 0.001f); |
| 1250 } | 1153 } |
| 1251 | 1154 |
| 1252 | |
| 1253 ASSEMBLER_TEST_GENERATE(PackedLogicalOr, assembler) { | 1155 ASSEMBLER_TEST_GENERATE(PackedLogicalOr, assembler) { |
| 1254 static const struct ALIGN16 { | 1156 static const struct ALIGN16 { |
| 1255 uint32_t a; | 1157 uint32_t a; |
| 1256 uint32_t b; | 1158 uint32_t b; |
| 1257 uint32_t c; | 1159 uint32_t c; |
| 1258 uint32_t d; | 1160 uint32_t d; |
| 1259 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; | 1161 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; |
| 1260 static const struct ALIGN16 { | 1162 static const struct ALIGN16 { |
| 1261 uint32_t a; | 1163 uint32_t a; |
| 1262 uint32_t b; | 1164 uint32_t b; |
| 1263 uint32_t c; | 1165 uint32_t c; |
| 1264 uint32_t d; | 1166 uint32_t d; |
| 1265 } constant2 = {0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; | 1167 } constant2 = {0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; |
| 1266 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1168 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1267 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant2))); | 1169 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant2))); |
| 1268 __ orps(XMM0, XMM1); | 1170 __ orps(XMM0, XMM1); |
| 1269 // Copy the low lane at ESP. | 1171 // Copy the low lane at ESP. |
| 1270 __ pushl(EAX); | 1172 __ pushl(EAX); |
| 1271 __ movss(Address(ESP, 0), XMM0); | 1173 __ movss(Address(ESP, 0), XMM0); |
| 1272 __ flds(Address(ESP, 0)); | 1174 __ flds(Address(ESP, 0)); |
| 1273 __ popl(EAX); | 1175 __ popl(EAX); |
| 1274 __ ret(); | 1176 __ ret(); |
| 1275 } | 1177 } |
| 1276 | 1178 |
| 1277 | |
| 1278 ASSEMBLER_TEST_RUN(PackedLogicalOr, test) { | 1179 ASSEMBLER_TEST_RUN(PackedLogicalOr, test) { |
| 1279 typedef uint32_t (*PackedLogicalOrCode)(); | 1180 typedef uint32_t (*PackedLogicalOrCode)(); |
| 1280 uint32_t res = reinterpret_cast<PackedLogicalOrCode>(test->entry())(); | 1181 uint32_t res = reinterpret_cast<PackedLogicalOrCode>(test->entry())(); |
| 1281 EXPECT_EQ(0xFFFFFFFF, res); | 1182 EXPECT_EQ(0xFFFFFFFF, res); |
| 1282 } | 1183 } |
| 1283 | 1184 |
| 1284 | |
| 1285 ASSEMBLER_TEST_GENERATE(PackedLogicalAnd, assembler) { | 1185 ASSEMBLER_TEST_GENERATE(PackedLogicalAnd, assembler) { |
| 1286 static const struct ALIGN16 { | 1186 static const struct ALIGN16 { |
| 1287 uint32_t a; | 1187 uint32_t a; |
| 1288 uint32_t b; | 1188 uint32_t b; |
| 1289 uint32_t c; | 1189 uint32_t c; |
| 1290 uint32_t d; | 1190 uint32_t d; |
| 1291 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; | 1191 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; |
| 1292 static const struct ALIGN16 { | 1192 static const struct ALIGN16 { |
| 1293 uint32_t a; | 1193 uint32_t a; |
| 1294 uint32_t b; | 1194 uint32_t b; |
| 1295 uint32_t c; | 1195 uint32_t c; |
| 1296 uint32_t d; | 1196 uint32_t d; |
| 1297 } constant2 = {0x0F0FFF0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; | 1197 } constant2 = {0x0F0FFF0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; |
| 1298 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1198 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1299 __ andps(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant2))); | 1199 __ andps(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant2))); |
| 1300 // Copy the low lane at ESP. | 1200 // Copy the low lane at ESP. |
| 1301 __ pushl(EAX); | 1201 __ pushl(EAX); |
| 1302 __ movss(Address(ESP, 0), XMM0); | 1202 __ movss(Address(ESP, 0), XMM0); |
| 1303 __ flds(Address(ESP, 0)); | 1203 __ flds(Address(ESP, 0)); |
| 1304 __ popl(EAX); | 1204 __ popl(EAX); |
| 1305 __ ret(); | 1205 __ ret(); |
| 1306 } | 1206 } |
| 1307 | 1207 |
| 1308 | |
| 1309 ASSEMBLER_TEST_RUN(PackedLogicalAnd, test) { | 1208 ASSEMBLER_TEST_RUN(PackedLogicalAnd, test) { |
| 1310 typedef uint32_t (*PackedLogicalAndCode)(); | 1209 typedef uint32_t (*PackedLogicalAndCode)(); |
| 1311 uint32_t res = reinterpret_cast<PackedLogicalAndCode>(test->entry())(); | 1210 uint32_t res = reinterpret_cast<PackedLogicalAndCode>(test->entry())(); |
| 1312 EXPECT_EQ(static_cast<uword>(0x0000F000), res); | 1211 EXPECT_EQ(static_cast<uword>(0x0000F000), res); |
| 1313 } | 1212 } |
| 1314 | 1213 |
| 1315 | |
| 1316 ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) { | 1214 ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) { |
| 1317 static const struct ALIGN16 { | 1215 static const struct ALIGN16 { |
| 1318 uint32_t a; | 1216 uint32_t a; |
| 1319 uint32_t b; | 1217 uint32_t b; |
| 1320 uint32_t c; | 1218 uint32_t c; |
| 1321 uint32_t d; | 1219 uint32_t d; |
| 1322 } constant1 = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; | 1220 } constant1 = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; |
| 1323 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1221 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1324 __ notps(XMM0); | 1222 __ notps(XMM0); |
| 1325 // Copy the low lane at ESP. | 1223 // Copy the low lane at ESP. |
| 1326 __ pushl(EAX); | 1224 __ pushl(EAX); |
| 1327 __ movss(Address(ESP, 0), XMM0); | 1225 __ movss(Address(ESP, 0), XMM0); |
| 1328 __ flds(Address(ESP, 0)); | 1226 __ flds(Address(ESP, 0)); |
| 1329 __ popl(EAX); | 1227 __ popl(EAX); |
| 1330 __ ret(); | 1228 __ ret(); |
| 1331 } | 1229 } |
| 1332 | 1230 |
| 1333 | |
| 1334 ASSEMBLER_TEST_RUN(PackedLogicalNot, test) { | 1231 ASSEMBLER_TEST_RUN(PackedLogicalNot, test) { |
| 1335 typedef uint32_t (*PackedLogicalNotCode)(); | 1232 typedef uint32_t (*PackedLogicalNotCode)(); |
| 1336 uint32_t res = reinterpret_cast<PackedLogicalNotCode>(test->entry())(); | 1233 uint32_t res = reinterpret_cast<PackedLogicalNotCode>(test->entry())(); |
| 1337 EXPECT_EQ(static_cast<uword>(0x0), res); | 1234 EXPECT_EQ(static_cast<uword>(0x0), res); |
| 1338 } | 1235 } |
| 1339 | 1236 |
| 1340 | |
| 1341 ASSEMBLER_TEST_GENERATE(PackedMoveHighLow, assembler) { | 1237 ASSEMBLER_TEST_GENERATE(PackedMoveHighLow, assembler) { |
| 1342 static const struct ALIGN16 { | 1238 static const struct ALIGN16 { |
| 1343 float a; | 1239 float a; |
| 1344 float b; | 1240 float b; |
| 1345 float c; | 1241 float c; |
| 1346 float d; | 1242 float d; |
| 1347 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 1243 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1348 static const struct ALIGN16 { | 1244 static const struct ALIGN16 { |
| 1349 float a; | 1245 float a; |
| 1350 float b; | 1246 float b; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1363 __ shufps(XMM0, XMM0, Immediate(0x00)); // 7.0f. | 1259 __ shufps(XMM0, XMM0, Immediate(0x00)); // 7.0f. |
| 1364 __ shufps(XMM1, XMM1, Immediate(0x55)); // 8.0f. | 1260 __ shufps(XMM1, XMM1, Immediate(0x55)); // 8.0f. |
| 1365 __ addss(XMM0, XMM1); // 15.0f. | 1261 __ addss(XMM0, XMM1); // 15.0f. |
| 1366 __ pushl(EAX); | 1262 __ pushl(EAX); |
| 1367 __ movss(Address(ESP, 0), XMM0); | 1263 __ movss(Address(ESP, 0), XMM0); |
| 1368 __ flds(Address(ESP, 0)); | 1264 __ flds(Address(ESP, 0)); |
| 1369 __ popl(EAX); | 1265 __ popl(EAX); |
| 1370 __ ret(); | 1266 __ ret(); |
| 1371 } | 1267 } |
| 1372 | 1268 |
| 1373 | |
| 1374 ASSEMBLER_TEST_RUN(PackedMoveHighLow, test) { | 1269 ASSEMBLER_TEST_RUN(PackedMoveHighLow, test) { |
| 1375 typedef float (*PackedMoveHighLow)(); | 1270 typedef float (*PackedMoveHighLow)(); |
| 1376 float res = reinterpret_cast<PackedMoveHighLow>(test->entry())(); | 1271 float res = reinterpret_cast<PackedMoveHighLow>(test->entry())(); |
| 1377 EXPECT_FLOAT_EQ(15.0f, res, 0.001f); | 1272 EXPECT_FLOAT_EQ(15.0f, res, 0.001f); |
| 1378 } | 1273 } |
| 1379 | 1274 |
| 1380 | |
| 1381 ASSEMBLER_TEST_GENERATE(PackedMoveLowHigh, assembler) { | 1275 ASSEMBLER_TEST_GENERATE(PackedMoveLowHigh, assembler) { |
| 1382 static const struct ALIGN16 { | 1276 static const struct ALIGN16 { |
| 1383 float a; | 1277 float a; |
| 1384 float b; | 1278 float b; |
| 1385 float c; | 1279 float c; |
| 1386 float d; | 1280 float d; |
| 1387 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 1281 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1388 static const struct ALIGN16 { | 1282 static const struct ALIGN16 { |
| 1389 float a; | 1283 float a; |
| 1390 float b; | 1284 float b; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1403 __ shufps(XMM0, XMM0, Immediate(0xAA)); // 5.0f. | 1297 __ shufps(XMM0, XMM0, Immediate(0xAA)); // 5.0f. |
| 1404 __ shufps(XMM1, XMM1, Immediate(0xFF)); // 6.0f. | 1298 __ shufps(XMM1, XMM1, Immediate(0xFF)); // 6.0f. |
| 1405 __ addss(XMM0, XMM1); // 11.0f. | 1299 __ addss(XMM0, XMM1); // 11.0f. |
| 1406 __ pushl(EAX); | 1300 __ pushl(EAX); |
| 1407 __ movss(Address(ESP, 0), XMM0); | 1301 __ movss(Address(ESP, 0), XMM0); |
| 1408 __ flds(Address(ESP, 0)); | 1302 __ flds(Address(ESP, 0)); |
| 1409 __ popl(EAX); | 1303 __ popl(EAX); |
| 1410 __ ret(); | 1304 __ ret(); |
| 1411 } | 1305 } |
| 1412 | 1306 |
| 1413 | |
| 1414 ASSEMBLER_TEST_RUN(PackedMoveLowHigh, test) { | 1307 ASSEMBLER_TEST_RUN(PackedMoveLowHigh, test) { |
| 1415 typedef float (*PackedMoveLowHigh)(); | 1308 typedef float (*PackedMoveLowHigh)(); |
| 1416 float res = reinterpret_cast<PackedMoveLowHigh>(test->entry())(); | 1309 float res = reinterpret_cast<PackedMoveLowHigh>(test->entry())(); |
| 1417 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); | 1310 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); |
| 1418 } | 1311 } |
| 1419 | 1312 |
| 1420 | |
| 1421 ASSEMBLER_TEST_GENERATE(PackedUnpackLow, assembler) { | 1313 ASSEMBLER_TEST_GENERATE(PackedUnpackLow, assembler) { |
| 1422 static const struct ALIGN16 { | 1314 static const struct ALIGN16 { |
| 1423 float a; | 1315 float a; |
| 1424 float b; | 1316 float b; |
| 1425 float c; | 1317 float c; |
| 1426 float d; | 1318 float d; |
| 1427 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 1319 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1428 static const struct ALIGN16 { | 1320 static const struct ALIGN16 { |
| 1429 float a; | 1321 float a; |
| 1430 float b; | 1322 float b; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1442 __ shufps(XMM0, XMM0, Immediate(0x55)); | 1334 __ shufps(XMM0, XMM0, Immediate(0x55)); |
| 1443 __ shufps(XMM1, XMM1, Immediate(0xFF)); | 1335 __ shufps(XMM1, XMM1, Immediate(0xFF)); |
| 1444 __ addss(XMM0, XMM1); // 11.0f. | 1336 __ addss(XMM0, XMM1); // 11.0f. |
| 1445 __ pushl(EAX); | 1337 __ pushl(EAX); |
| 1446 __ movss(Address(ESP, 0), XMM0); | 1338 __ movss(Address(ESP, 0), XMM0); |
| 1447 __ flds(Address(ESP, 0)); | 1339 __ flds(Address(ESP, 0)); |
| 1448 __ popl(EAX); | 1340 __ popl(EAX); |
| 1449 __ ret(); | 1341 __ ret(); |
| 1450 } | 1342 } |
| 1451 | 1343 |
| 1452 | |
| 1453 ASSEMBLER_TEST_RUN(PackedUnpackLow, test) { | 1344 ASSEMBLER_TEST_RUN(PackedUnpackLow, test) { |
| 1454 typedef float (*PackedUnpackLow)(); | 1345 typedef float (*PackedUnpackLow)(); |
| 1455 float res = reinterpret_cast<PackedUnpackLow>(test->entry())(); | 1346 float res = reinterpret_cast<PackedUnpackLow>(test->entry())(); |
| 1456 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); | 1347 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); |
| 1457 } | 1348 } |
| 1458 | 1349 |
| 1459 | |
| 1460 ASSEMBLER_TEST_GENERATE(PackedUnpackHigh, assembler) { | 1350 ASSEMBLER_TEST_GENERATE(PackedUnpackHigh, assembler) { |
| 1461 static const struct ALIGN16 { | 1351 static const struct ALIGN16 { |
| 1462 float a; | 1352 float a; |
| 1463 float b; | 1353 float b; |
| 1464 float c; | 1354 float c; |
| 1465 float d; | 1355 float d; |
| 1466 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 1356 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1467 static const struct ALIGN16 { | 1357 static const struct ALIGN16 { |
| 1468 float a; | 1358 float a; |
| 1469 float b; | 1359 float b; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1481 __ shufps(XMM0, XMM0, Immediate(0x00)); | 1371 __ shufps(XMM0, XMM0, Immediate(0x00)); |
| 1482 __ shufps(XMM1, XMM1, Immediate(0xAA)); | 1372 __ shufps(XMM1, XMM1, Immediate(0xAA)); |
| 1483 __ addss(XMM0, XMM1); // 7.0f. | 1373 __ addss(XMM0, XMM1); // 7.0f. |
| 1484 __ pushl(EAX); | 1374 __ pushl(EAX); |
| 1485 __ movss(Address(ESP, 0), XMM0); | 1375 __ movss(Address(ESP, 0), XMM0); |
| 1486 __ flds(Address(ESP, 0)); | 1376 __ flds(Address(ESP, 0)); |
| 1487 __ popl(EAX); | 1377 __ popl(EAX); |
| 1488 __ ret(); | 1378 __ ret(); |
| 1489 } | 1379 } |
| 1490 | 1380 |
| 1491 | |
| 1492 ASSEMBLER_TEST_RUN(PackedUnpackHigh, test) { | 1381 ASSEMBLER_TEST_RUN(PackedUnpackHigh, test) { |
| 1493 typedef float (*PackedUnpackHigh)(); | 1382 typedef float (*PackedUnpackHigh)(); |
| 1494 float res = reinterpret_cast<PackedUnpackHigh>(test->entry())(); | 1383 float res = reinterpret_cast<PackedUnpackHigh>(test->entry())(); |
| 1495 EXPECT_FLOAT_EQ(7.0f, res, 0.001f); | 1384 EXPECT_FLOAT_EQ(7.0f, res, 0.001f); |
| 1496 } | 1385 } |
| 1497 | 1386 |
| 1498 | |
| 1499 ASSEMBLER_TEST_GENERATE(PackedUnpackLowPair, assembler) { | 1387 ASSEMBLER_TEST_GENERATE(PackedUnpackLowPair, assembler) { |
| 1500 static const struct ALIGN16 { | 1388 static const struct ALIGN16 { |
| 1501 float a; | 1389 float a; |
| 1502 float b; | 1390 float b; |
| 1503 float c; | 1391 float c; |
| 1504 float d; | 1392 float d; |
| 1505 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 1393 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1506 static const struct ALIGN16 { | 1394 static const struct ALIGN16 { |
| 1507 float a; | 1395 float a; |
| 1508 float b; | 1396 float b; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1520 __ shufps(XMM0, XMM0, Immediate(0x00)); | 1408 __ shufps(XMM0, XMM0, Immediate(0x00)); |
| 1521 __ shufps(XMM1, XMM1, Immediate(0xAA)); | 1409 __ shufps(XMM1, XMM1, Immediate(0xAA)); |
| 1522 __ addss(XMM0, XMM1); // 6.0f. | 1410 __ addss(XMM0, XMM1); // 6.0f. |
| 1523 __ pushl(EAX); | 1411 __ pushl(EAX); |
| 1524 __ movss(Address(ESP, 0), XMM0); | 1412 __ movss(Address(ESP, 0), XMM0); |
| 1525 __ flds(Address(ESP, 0)); | 1413 __ flds(Address(ESP, 0)); |
| 1526 __ popl(EAX); | 1414 __ popl(EAX); |
| 1527 __ ret(); | 1415 __ ret(); |
| 1528 } | 1416 } |
| 1529 | 1417 |
| 1530 | |
| 1531 ASSEMBLER_TEST_RUN(PackedUnpackLowPair, test) { | 1418 ASSEMBLER_TEST_RUN(PackedUnpackLowPair, test) { |
| 1532 typedef float (*PackedUnpackLowPair)(); | 1419 typedef float (*PackedUnpackLowPair)(); |
| 1533 float res = reinterpret_cast<PackedUnpackLowPair>(test->entry())(); | 1420 float res = reinterpret_cast<PackedUnpackLowPair>(test->entry())(); |
| 1534 EXPECT_FLOAT_EQ(6.0f, res, 0.001f); | 1421 EXPECT_FLOAT_EQ(6.0f, res, 0.001f); |
| 1535 } | 1422 } |
| 1536 | 1423 |
| 1537 | |
| 1538 ASSEMBLER_TEST_GENERATE(PackedUnpackHighPair, assembler) { | 1424 ASSEMBLER_TEST_GENERATE(PackedUnpackHighPair, assembler) { |
| 1539 static const struct ALIGN16 { | 1425 static const struct ALIGN16 { |
| 1540 float a; | 1426 float a; |
| 1541 float b; | 1427 float b; |
| 1542 float c; | 1428 float c; |
| 1543 float d; | 1429 float d; |
| 1544 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 1430 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
| 1545 static const struct ALIGN16 { | 1431 static const struct ALIGN16 { |
| 1546 float a; | 1432 float a; |
| 1547 float b; | 1433 float b; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1559 __ shufps(XMM0, XMM0, Immediate(0x55)); | 1445 __ shufps(XMM0, XMM0, Immediate(0x55)); |
| 1560 __ shufps(XMM1, XMM1, Immediate(0xFF)); | 1446 __ shufps(XMM1, XMM1, Immediate(0xFF)); |
| 1561 __ addss(XMM0, XMM1); // 12.0f. | 1447 __ addss(XMM0, XMM1); // 12.0f. |
| 1562 __ pushl(EAX); | 1448 __ pushl(EAX); |
| 1563 __ movss(Address(ESP, 0), XMM0); | 1449 __ movss(Address(ESP, 0), XMM0); |
| 1564 __ flds(Address(ESP, 0)); | 1450 __ flds(Address(ESP, 0)); |
| 1565 __ popl(EAX); | 1451 __ popl(EAX); |
| 1566 __ ret(); | 1452 __ ret(); |
| 1567 } | 1453 } |
| 1568 | 1454 |
| 1569 | |
| 1570 ASSEMBLER_TEST_RUN(PackedUnpackHighPair, test) { | 1455 ASSEMBLER_TEST_RUN(PackedUnpackHighPair, test) { |
| 1571 typedef float (*PackedUnpackHighPair)(); | 1456 typedef float (*PackedUnpackHighPair)(); |
| 1572 float res = reinterpret_cast<PackedUnpackHighPair>(test->entry())(); | 1457 float res = reinterpret_cast<PackedUnpackHighPair>(test->entry())(); |
| 1573 EXPECT_FLOAT_EQ(12.0f, res, 0.001f); | 1458 EXPECT_FLOAT_EQ(12.0f, res, 0.001f); |
| 1574 } | 1459 } |
| 1575 | 1460 |
| 1576 | |
| 1577 ASSEMBLER_TEST_GENERATE(PackedDoubleAdd, assembler) { | 1461 ASSEMBLER_TEST_GENERATE(PackedDoubleAdd, assembler) { |
| 1578 static const struct ALIGN16 { | 1462 static const struct ALIGN16 { |
| 1579 double a; | 1463 double a; |
| 1580 double b; | 1464 double b; |
| 1581 } constant0 = {1.0, 2.0}; | 1465 } constant0 = {1.0, 2.0}; |
| 1582 static const struct ALIGN16 { | 1466 static const struct ALIGN16 { |
| 1583 double a; | 1467 double a; |
| 1584 double b; | 1468 double b; |
| 1585 } constant1 = {3.0, 4.0}; | 1469 } constant1 = {3.0, 4.0}; |
| 1586 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1470 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1587 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1471 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1588 __ addpd(XMM0, XMM1); | 1472 __ addpd(XMM0, XMM1); |
| 1589 __ pushl(EAX); | 1473 __ pushl(EAX); |
| 1590 __ pushl(EAX); | 1474 __ pushl(EAX); |
| 1591 __ movsd(Address(ESP, 0), XMM0); | 1475 __ movsd(Address(ESP, 0), XMM0); |
| 1592 __ fldl(Address(ESP, 0)); | 1476 __ fldl(Address(ESP, 0)); |
| 1593 __ popl(EAX); | 1477 __ popl(EAX); |
| 1594 __ popl(EAX); | 1478 __ popl(EAX); |
| 1595 __ ret(); | 1479 __ ret(); |
| 1596 } | 1480 } |
| 1597 | 1481 |
| 1598 | |
| 1599 ASSEMBLER_TEST_RUN(PackedDoubleAdd, test) { | 1482 ASSEMBLER_TEST_RUN(PackedDoubleAdd, test) { |
| 1600 typedef double (*PackedDoubleAdd)(); | 1483 typedef double (*PackedDoubleAdd)(); |
| 1601 double res = reinterpret_cast<PackedDoubleAdd>(test->entry())(); | 1484 double res = reinterpret_cast<PackedDoubleAdd>(test->entry())(); |
| 1602 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); | 1485 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); |
| 1603 } | 1486 } |
| 1604 | 1487 |
| 1605 | |
| 1606 ASSEMBLER_TEST_GENERATE(PackedDoubleSub, assembler) { | 1488 ASSEMBLER_TEST_GENERATE(PackedDoubleSub, assembler) { |
| 1607 static const struct ALIGN16 { | 1489 static const struct ALIGN16 { |
| 1608 double a; | 1490 double a; |
| 1609 double b; | 1491 double b; |
| 1610 } constant0 = {1.0, 2.0}; | 1492 } constant0 = {1.0, 2.0}; |
| 1611 static const struct ALIGN16 { | 1493 static const struct ALIGN16 { |
| 1612 double a; | 1494 double a; |
| 1613 double b; | 1495 double b; |
| 1614 } constant1 = {3.0, 4.0}; | 1496 } constant1 = {3.0, 4.0}; |
| 1615 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1497 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1616 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1498 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1617 __ subpd(XMM0, XMM1); | 1499 __ subpd(XMM0, XMM1); |
| 1618 __ pushl(EAX); | 1500 __ pushl(EAX); |
| 1619 __ pushl(EAX); | 1501 __ pushl(EAX); |
| 1620 __ movsd(Address(ESP, 0), XMM0); | 1502 __ movsd(Address(ESP, 0), XMM0); |
| 1621 __ fldl(Address(ESP, 0)); | 1503 __ fldl(Address(ESP, 0)); |
| 1622 __ popl(EAX); | 1504 __ popl(EAX); |
| 1623 __ popl(EAX); | 1505 __ popl(EAX); |
| 1624 __ ret(); | 1506 __ ret(); |
| 1625 } | 1507 } |
| 1626 | 1508 |
| 1627 | |
| 1628 ASSEMBLER_TEST_RUN(PackedDoubleSub, test) { | 1509 ASSEMBLER_TEST_RUN(PackedDoubleSub, test) { |
| 1629 typedef double (*PackedDoubleSub)(); | 1510 typedef double (*PackedDoubleSub)(); |
| 1630 double res = reinterpret_cast<PackedDoubleSub>(test->entry())(); | 1511 double res = reinterpret_cast<PackedDoubleSub>(test->entry())(); |
| 1631 EXPECT_FLOAT_EQ(-2.0, res, 0.000001f); | 1512 EXPECT_FLOAT_EQ(-2.0, res, 0.000001f); |
| 1632 } | 1513 } |
| 1633 | 1514 |
| 1634 | |
| 1635 ASSEMBLER_TEST_GENERATE(PackedDoubleNegate, assembler) { | 1515 ASSEMBLER_TEST_GENERATE(PackedDoubleNegate, assembler) { |
| 1636 static const struct ALIGN16 { | 1516 static const struct ALIGN16 { |
| 1637 double a; | 1517 double a; |
| 1638 double b; | 1518 double b; |
| 1639 } constant0 = {1.0, 2.0}; | 1519 } constant0 = {1.0, 2.0}; |
| 1640 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1520 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1641 __ negatepd(XMM0); | 1521 __ negatepd(XMM0); |
| 1642 __ pushl(EAX); | 1522 __ pushl(EAX); |
| 1643 __ pushl(EAX); | 1523 __ pushl(EAX); |
| 1644 __ movsd(Address(ESP, 0), XMM0); | 1524 __ movsd(Address(ESP, 0), XMM0); |
| 1645 __ fldl(Address(ESP, 0)); | 1525 __ fldl(Address(ESP, 0)); |
| 1646 __ popl(EAX); | 1526 __ popl(EAX); |
| 1647 __ popl(EAX); | 1527 __ popl(EAX); |
| 1648 __ ret(); | 1528 __ ret(); |
| 1649 } | 1529 } |
| 1650 | 1530 |
| 1651 | |
| 1652 ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) { | 1531 ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) { |
| 1653 typedef double (*PackedDoubleNegate)(); | 1532 typedef double (*PackedDoubleNegate)(); |
| 1654 double res = reinterpret_cast<PackedDoubleNegate>(test->entry())(); | 1533 double res = reinterpret_cast<PackedDoubleNegate>(test->entry())(); |
| 1655 EXPECT_FLOAT_EQ(-1.0, res, 0.000001f); | 1534 EXPECT_FLOAT_EQ(-1.0, res, 0.000001f); |
| 1656 } | 1535 } |
| 1657 | 1536 |
| 1658 | |
| 1659 ASSEMBLER_TEST_GENERATE(PackedDoubleAbsolute, assembler) { | 1537 ASSEMBLER_TEST_GENERATE(PackedDoubleAbsolute, assembler) { |
| 1660 static const struct ALIGN16 { | 1538 static const struct ALIGN16 { |
| 1661 double a; | 1539 double a; |
| 1662 double b; | 1540 double b; |
| 1663 } constant0 = {-1.0, 2.0}; | 1541 } constant0 = {-1.0, 2.0}; |
| 1664 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1542 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1665 __ abspd(XMM0); | 1543 __ abspd(XMM0); |
| 1666 __ pushl(EAX); | 1544 __ pushl(EAX); |
| 1667 __ pushl(EAX); | 1545 __ pushl(EAX); |
| 1668 __ movsd(Address(ESP, 0), XMM0); | 1546 __ movsd(Address(ESP, 0), XMM0); |
| 1669 __ fldl(Address(ESP, 0)); | 1547 __ fldl(Address(ESP, 0)); |
| 1670 __ popl(EAX); | 1548 __ popl(EAX); |
| 1671 __ popl(EAX); | 1549 __ popl(EAX); |
| 1672 __ ret(); | 1550 __ ret(); |
| 1673 } | 1551 } |
| 1674 | 1552 |
| 1675 | |
| 1676 ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) { | 1553 ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) { |
| 1677 typedef double (*PackedDoubleAbsolute)(); | 1554 typedef double (*PackedDoubleAbsolute)(); |
| 1678 double res = reinterpret_cast<PackedDoubleAbsolute>(test->entry())(); | 1555 double res = reinterpret_cast<PackedDoubleAbsolute>(test->entry())(); |
| 1679 EXPECT_FLOAT_EQ(1.0, res, 0.000001f); | 1556 EXPECT_FLOAT_EQ(1.0, res, 0.000001f); |
| 1680 } | 1557 } |
| 1681 | 1558 |
| 1682 | |
| 1683 ASSEMBLER_TEST_GENERATE(PackedDoubleMul, assembler) { | 1559 ASSEMBLER_TEST_GENERATE(PackedDoubleMul, assembler) { |
| 1684 static const struct ALIGN16 { | 1560 static const struct ALIGN16 { |
| 1685 double a; | 1561 double a; |
| 1686 double b; | 1562 double b; |
| 1687 } constant0 = {3.0, 2.0}; | 1563 } constant0 = {3.0, 2.0}; |
| 1688 static const struct ALIGN16 { | 1564 static const struct ALIGN16 { |
| 1689 double a; | 1565 double a; |
| 1690 double b; | 1566 double b; |
| 1691 } constant1 = {3.0, 4.0}; | 1567 } constant1 = {3.0, 4.0}; |
| 1692 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1568 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1693 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1569 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1694 __ mulpd(XMM0, XMM1); | 1570 __ mulpd(XMM0, XMM1); |
| 1695 __ pushl(EAX); | 1571 __ pushl(EAX); |
| 1696 __ pushl(EAX); | 1572 __ pushl(EAX); |
| 1697 __ movsd(Address(ESP, 0), XMM0); | 1573 __ movsd(Address(ESP, 0), XMM0); |
| 1698 __ fldl(Address(ESP, 0)); | 1574 __ fldl(Address(ESP, 0)); |
| 1699 __ popl(EAX); | 1575 __ popl(EAX); |
| 1700 __ popl(EAX); | 1576 __ popl(EAX); |
| 1701 __ ret(); | 1577 __ ret(); |
| 1702 } | 1578 } |
| 1703 | 1579 |
| 1704 | |
| 1705 ASSEMBLER_TEST_RUN(PackedDoubleMul, test) { | 1580 ASSEMBLER_TEST_RUN(PackedDoubleMul, test) { |
| 1706 typedef double (*PackedDoubleMul)(); | 1581 typedef double (*PackedDoubleMul)(); |
| 1707 double res = reinterpret_cast<PackedDoubleMul>(test->entry())(); | 1582 double res = reinterpret_cast<PackedDoubleMul>(test->entry())(); |
| 1708 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 1583 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
| 1709 } | 1584 } |
| 1710 | 1585 |
| 1711 | |
| 1712 ASSEMBLER_TEST_GENERATE(PackedDoubleDiv, assembler) { | 1586 ASSEMBLER_TEST_GENERATE(PackedDoubleDiv, assembler) { |
| 1713 static const struct ALIGN16 { | 1587 static const struct ALIGN16 { |
| 1714 double a; | 1588 double a; |
| 1715 double b; | 1589 double b; |
| 1716 } constant0 = {9.0, 2.0}; | 1590 } constant0 = {9.0, 2.0}; |
| 1717 static const struct ALIGN16 { | 1591 static const struct ALIGN16 { |
| 1718 double a; | 1592 double a; |
| 1719 double b; | 1593 double b; |
| 1720 } constant1 = {3.0, 4.0}; | 1594 } constant1 = {3.0, 4.0}; |
| 1721 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1595 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1722 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1596 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1723 __ divpd(XMM0, XMM1); | 1597 __ divpd(XMM0, XMM1); |
| 1724 __ pushl(EAX); | 1598 __ pushl(EAX); |
| 1725 __ pushl(EAX); | 1599 __ pushl(EAX); |
| 1726 __ movsd(Address(ESP, 0), XMM0); | 1600 __ movsd(Address(ESP, 0), XMM0); |
| 1727 __ fldl(Address(ESP, 0)); | 1601 __ fldl(Address(ESP, 0)); |
| 1728 __ popl(EAX); | 1602 __ popl(EAX); |
| 1729 __ popl(EAX); | 1603 __ popl(EAX); |
| 1730 __ ret(); | 1604 __ ret(); |
| 1731 } | 1605 } |
| 1732 | 1606 |
| 1733 | |
| 1734 ASSEMBLER_TEST_RUN(PackedDoubleDiv, test) { | 1607 ASSEMBLER_TEST_RUN(PackedDoubleDiv, test) { |
| 1735 typedef double (*PackedDoubleDiv)(); | 1608 typedef double (*PackedDoubleDiv)(); |
| 1736 double res = reinterpret_cast<PackedDoubleDiv>(test->entry())(); | 1609 double res = reinterpret_cast<PackedDoubleDiv>(test->entry())(); |
| 1737 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); | 1610 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); |
| 1738 } | 1611 } |
| 1739 | 1612 |
| 1740 | |
| 1741 ASSEMBLER_TEST_GENERATE(PackedDoubleSqrt, assembler) { | 1613 ASSEMBLER_TEST_GENERATE(PackedDoubleSqrt, assembler) { |
| 1742 static const struct ALIGN16 { | 1614 static const struct ALIGN16 { |
| 1743 double a; | 1615 double a; |
| 1744 double b; | 1616 double b; |
| 1745 } constant0 = {16.0, 2.0}; | 1617 } constant0 = {16.0, 2.0}; |
| 1746 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1618 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1747 __ sqrtpd(XMM0); | 1619 __ sqrtpd(XMM0); |
| 1748 __ pushl(EAX); | 1620 __ pushl(EAX); |
| 1749 __ pushl(EAX); | 1621 __ pushl(EAX); |
| 1750 __ movsd(Address(ESP, 0), XMM0); | 1622 __ movsd(Address(ESP, 0), XMM0); |
| 1751 __ fldl(Address(ESP, 0)); | 1623 __ fldl(Address(ESP, 0)); |
| 1752 __ popl(EAX); | 1624 __ popl(EAX); |
| 1753 __ popl(EAX); | 1625 __ popl(EAX); |
| 1754 __ ret(); | 1626 __ ret(); |
| 1755 } | 1627 } |
| 1756 | 1628 |
| 1757 | |
| 1758 ASSEMBLER_TEST_RUN(PackedDoubleSqrt, test) { | 1629 ASSEMBLER_TEST_RUN(PackedDoubleSqrt, test) { |
| 1759 typedef double (*PackedDoubleSqrt)(); | 1630 typedef double (*PackedDoubleSqrt)(); |
| 1760 double res = reinterpret_cast<PackedDoubleSqrt>(test->entry())(); | 1631 double res = reinterpret_cast<PackedDoubleSqrt>(test->entry())(); |
| 1761 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); | 1632 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); |
| 1762 } | 1633 } |
| 1763 | 1634 |
| 1764 | |
| 1765 ASSEMBLER_TEST_GENERATE(PackedDoubleMin, assembler) { | 1635 ASSEMBLER_TEST_GENERATE(PackedDoubleMin, assembler) { |
| 1766 static const struct ALIGN16 { | 1636 static const struct ALIGN16 { |
| 1767 double a; | 1637 double a; |
| 1768 double b; | 1638 double b; |
| 1769 } constant0 = {9.0, 2.0}; | 1639 } constant0 = {9.0, 2.0}; |
| 1770 static const struct ALIGN16 { | 1640 static const struct ALIGN16 { |
| 1771 double a; | 1641 double a; |
| 1772 double b; | 1642 double b; |
| 1773 } constant1 = {3.0, 4.0}; | 1643 } constant1 = {3.0, 4.0}; |
| 1774 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1644 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1775 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1645 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1776 __ minpd(XMM0, XMM1); | 1646 __ minpd(XMM0, XMM1); |
| 1777 __ pushl(EAX); | 1647 __ pushl(EAX); |
| 1778 __ pushl(EAX); | 1648 __ pushl(EAX); |
| 1779 __ movsd(Address(ESP, 0), XMM0); | 1649 __ movsd(Address(ESP, 0), XMM0); |
| 1780 __ fldl(Address(ESP, 0)); | 1650 __ fldl(Address(ESP, 0)); |
| 1781 __ popl(EAX); | 1651 __ popl(EAX); |
| 1782 __ popl(EAX); | 1652 __ popl(EAX); |
| 1783 __ ret(); | 1653 __ ret(); |
| 1784 } | 1654 } |
| 1785 | 1655 |
| 1786 | |
| 1787 ASSEMBLER_TEST_RUN(PackedDoubleMin, test) { | 1656 ASSEMBLER_TEST_RUN(PackedDoubleMin, test) { |
| 1788 typedef double (*PackedDoubleMin)(); | 1657 typedef double (*PackedDoubleMin)(); |
| 1789 double res = reinterpret_cast<PackedDoubleMin>(test->entry())(); | 1658 double res = reinterpret_cast<PackedDoubleMin>(test->entry())(); |
| 1790 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); | 1659 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); |
| 1791 } | 1660 } |
| 1792 | 1661 |
| 1793 | |
| 1794 ASSEMBLER_TEST_GENERATE(PackedDoubleMax, assembler) { | 1662 ASSEMBLER_TEST_GENERATE(PackedDoubleMax, assembler) { |
| 1795 static const struct ALIGN16 { | 1663 static const struct ALIGN16 { |
| 1796 double a; | 1664 double a; |
| 1797 double b; | 1665 double b; |
| 1798 } constant0 = {9.0, 2.0}; | 1666 } constant0 = {9.0, 2.0}; |
| 1799 static const struct ALIGN16 { | 1667 static const struct ALIGN16 { |
| 1800 double a; | 1668 double a; |
| 1801 double b; | 1669 double b; |
| 1802 } constant1 = {3.0, 4.0}; | 1670 } constant1 = {3.0, 4.0}; |
| 1803 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1671 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1804 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); | 1672 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant1))); |
| 1805 __ maxpd(XMM0, XMM1); | 1673 __ maxpd(XMM0, XMM1); |
| 1806 __ pushl(EAX); | 1674 __ pushl(EAX); |
| 1807 __ pushl(EAX); | 1675 __ pushl(EAX); |
| 1808 __ movsd(Address(ESP, 0), XMM0); | 1676 __ movsd(Address(ESP, 0), XMM0); |
| 1809 __ fldl(Address(ESP, 0)); | 1677 __ fldl(Address(ESP, 0)); |
| 1810 __ popl(EAX); | 1678 __ popl(EAX); |
| 1811 __ popl(EAX); | 1679 __ popl(EAX); |
| 1812 __ ret(); | 1680 __ ret(); |
| 1813 } | 1681 } |
| 1814 | 1682 |
| 1815 | |
| 1816 ASSEMBLER_TEST_RUN(PackedDoubleMax, test) { | 1683 ASSEMBLER_TEST_RUN(PackedDoubleMax, test) { |
| 1817 typedef double (*PackedDoubleMax)(); | 1684 typedef double (*PackedDoubleMax)(); |
| 1818 double res = reinterpret_cast<PackedDoubleMax>(test->entry())(); | 1685 double res = reinterpret_cast<PackedDoubleMax>(test->entry())(); |
| 1819 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 1686 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
| 1820 } | 1687 } |
| 1821 | 1688 |
| 1822 | |
| 1823 ASSEMBLER_TEST_GENERATE(PackedDoubleShuffle, assembler) { | 1689 ASSEMBLER_TEST_GENERATE(PackedDoubleShuffle, assembler) { |
| 1824 static const struct ALIGN16 { | 1690 static const struct ALIGN16 { |
| 1825 double a; | 1691 double a; |
| 1826 double b; | 1692 double b; |
| 1827 } constant0 = {2.0, 9.0}; | 1693 } constant0 = {2.0, 9.0}; |
| 1828 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1694 __ movups(XMM0, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1829 // Splat Y across all lanes. | 1695 // Splat Y across all lanes. |
| 1830 __ shufpd(XMM0, XMM0, Immediate(0x33)); | 1696 __ shufpd(XMM0, XMM0, Immediate(0x33)); |
| 1831 // Splat X across all lanes. | 1697 // Splat X across all lanes. |
| 1832 __ shufpd(XMM0, XMM0, Immediate(0x0)); | 1698 __ shufpd(XMM0, XMM0, Immediate(0x0)); |
| 1833 // Set return value. | 1699 // Set return value. |
| 1834 __ pushl(EAX); | 1700 __ pushl(EAX); |
| 1835 __ pushl(EAX); | 1701 __ pushl(EAX); |
| 1836 __ movsd(Address(ESP, 0), XMM0); | 1702 __ movsd(Address(ESP, 0), XMM0); |
| 1837 __ fldl(Address(ESP, 0)); | 1703 __ fldl(Address(ESP, 0)); |
| 1838 __ popl(EAX); | 1704 __ popl(EAX); |
| 1839 __ popl(EAX); | 1705 __ popl(EAX); |
| 1840 __ ret(); | 1706 __ ret(); |
| 1841 } | 1707 } |
| 1842 | 1708 |
| 1843 | |
| 1844 ASSEMBLER_TEST_RUN(PackedDoubleShuffle, test) { | 1709 ASSEMBLER_TEST_RUN(PackedDoubleShuffle, test) { |
| 1845 typedef double (*PackedDoubleShuffle)(); | 1710 typedef double (*PackedDoubleShuffle)(); |
| 1846 double res = reinterpret_cast<PackedDoubleShuffle>(test->entry())(); | 1711 double res = reinterpret_cast<PackedDoubleShuffle>(test->entry())(); |
| 1847 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 1712 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
| 1848 } | 1713 } |
| 1849 | 1714 |
| 1850 | |
| 1851 ASSEMBLER_TEST_GENERATE(PackedDoubleToSingle, assembler) { | 1715 ASSEMBLER_TEST_GENERATE(PackedDoubleToSingle, assembler) { |
| 1852 static const struct ALIGN16 { | 1716 static const struct ALIGN16 { |
| 1853 double a; | 1717 double a; |
| 1854 double b; | 1718 double b; |
| 1855 } constant0 = {9.0, 2.0}; | 1719 } constant0 = {9.0, 2.0}; |
| 1856 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1720 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1857 __ cvtpd2ps(XMM0, XMM1); | 1721 __ cvtpd2ps(XMM0, XMM1); |
| 1858 __ pushl(EAX); | 1722 __ pushl(EAX); |
| 1859 __ movss(Address(ESP, 0), XMM0); | 1723 __ movss(Address(ESP, 0), XMM0); |
| 1860 __ flds(Address(ESP, 0)); | 1724 __ flds(Address(ESP, 0)); |
| 1861 __ popl(EAX); | 1725 __ popl(EAX); |
| 1862 __ ret(); | 1726 __ ret(); |
| 1863 } | 1727 } |
| 1864 | 1728 |
| 1865 | |
| 1866 ASSEMBLER_TEST_RUN(PackedDoubleToSingle, test) { | 1729 ASSEMBLER_TEST_RUN(PackedDoubleToSingle, test) { |
| 1867 typedef float (*PackedDoubleToSingle)(); | 1730 typedef float (*PackedDoubleToSingle)(); |
| 1868 float res = reinterpret_cast<PackedDoubleToSingle>(test->entry())(); | 1731 float res = reinterpret_cast<PackedDoubleToSingle>(test->entry())(); |
| 1869 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); | 1732 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); |
| 1870 } | 1733 } |
| 1871 | 1734 |
| 1872 | |
| 1873 ASSEMBLER_TEST_GENERATE(PackedSingleToDouble, assembler) { | 1735 ASSEMBLER_TEST_GENERATE(PackedSingleToDouble, assembler) { |
| 1874 static const struct ALIGN16 { | 1736 static const struct ALIGN16 { |
| 1875 float a; | 1737 float a; |
| 1876 float b; | 1738 float b; |
| 1877 float c; | 1739 float c; |
| 1878 float d; | 1740 float d; |
| 1879 } constant0 = {9.0f, 2.0f, 3.0f, 4.0f}; | 1741 } constant0 = {9.0f, 2.0f, 3.0f, 4.0f}; |
| 1880 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); | 1742 __ movups(XMM1, Address::Absolute(reinterpret_cast<uword>(&constant0))); |
| 1881 __ cvtps2pd(XMM0, XMM1); | 1743 __ cvtps2pd(XMM0, XMM1); |
| 1882 __ pushl(EAX); | 1744 __ pushl(EAX); |
| 1883 __ pushl(EAX); | 1745 __ pushl(EAX); |
| 1884 __ movsd(Address(ESP, 0), XMM0); | 1746 __ movsd(Address(ESP, 0), XMM0); |
| 1885 __ fldl(Address(ESP, 0)); | 1747 __ fldl(Address(ESP, 0)); |
| 1886 __ popl(EAX); | 1748 __ popl(EAX); |
| 1887 __ popl(EAX); | 1749 __ popl(EAX); |
| 1888 __ ret(); | 1750 __ ret(); |
| 1889 } | 1751 } |
| 1890 | 1752 |
| 1891 | |
| 1892 ASSEMBLER_TEST_RUN(PackedSingleToDouble, test) { | 1753 ASSEMBLER_TEST_RUN(PackedSingleToDouble, test) { |
| 1893 typedef double (*PackedSingleToDouble)(); | 1754 typedef double (*PackedSingleToDouble)(); |
| 1894 double res = reinterpret_cast<PackedSingleToDouble>(test->entry())(); | 1755 double res = reinterpret_cast<PackedSingleToDouble>(test->entry())(); |
| 1895 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); | 1756 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); |
| 1896 } | 1757 } |
| 1897 | 1758 |
| 1898 | |
| 1899 ASSEMBLER_TEST_GENERATE(SingleFPOperationsStack, assembler) { | 1759 ASSEMBLER_TEST_GENERATE(SingleFPOperationsStack, assembler) { |
| 1900 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 1760 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 1901 __ movd(XMM0, EAX); | 1761 __ movd(XMM0, EAX); |
| 1902 __ addss(XMM0, Address(ESP, kWordSize)); // 15.7f | 1762 __ addss(XMM0, Address(ESP, kWordSize)); // 15.7f |
| 1903 __ mulss(XMM0, Address(ESP, kWordSize)); // 53.38f | 1763 __ mulss(XMM0, Address(ESP, kWordSize)); // 53.38f |
| 1904 __ subss(XMM0, Address(ESP, kWordSize)); // 49.98f | 1764 __ subss(XMM0, Address(ESP, kWordSize)); // 49.98f |
| 1905 __ divss(XMM0, Address(ESP, kWordSize)); // 14.7f | 1765 __ divss(XMM0, Address(ESP, kWordSize)); // 14.7f |
| 1906 __ pushl(EAX); | 1766 __ pushl(EAX); |
| 1907 __ movss(Address(ESP, 0), XMM0); | 1767 __ movss(Address(ESP, 0), XMM0); |
| 1908 __ flds(Address(ESP, 0)); | 1768 __ flds(Address(ESP, 0)); |
| 1909 __ popl(EAX); | 1769 __ popl(EAX); |
| 1910 __ ret(); | 1770 __ ret(); |
| 1911 } | 1771 } |
| 1912 | 1772 |
| 1913 | |
| 1914 ASSEMBLER_TEST_RUN(SingleFPOperationsStack, test) { | 1773 ASSEMBLER_TEST_RUN(SingleFPOperationsStack, test) { |
| 1915 typedef float (*SingleFPOperationsStackCode)(float f); | 1774 typedef float (*SingleFPOperationsStackCode)(float f); |
| 1916 float res = reinterpret_cast<SingleFPOperationsStackCode>(test->entry())(3.4); | 1775 float res = reinterpret_cast<SingleFPOperationsStackCode>(test->entry())(3.4); |
| 1917 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); | 1776 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); |
| 1918 } | 1777 } |
| 1919 | 1778 |
| 1920 | |
| 1921 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { | 1779 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { |
| 1922 int64_t l = bit_cast<int64_t, double>(1024.67); | 1780 int64_t l = bit_cast<int64_t, double>(1024.67); |
| 1923 __ movl(EAX, Immediate(Utils::High32Bits(l))); | 1781 __ movl(EAX, Immediate(Utils::High32Bits(l))); |
| 1924 __ pushl(EAX); | 1782 __ pushl(EAX); |
| 1925 __ movl(EAX, Immediate(Utils::Low32Bits(l))); | 1783 __ movl(EAX, Immediate(Utils::Low32Bits(l))); |
| 1926 __ pushl(EAX); | 1784 __ pushl(EAX); |
| 1927 __ movsd(XMM0, Address(ESP, 0)); | 1785 __ movsd(XMM0, Address(ESP, 0)); |
| 1928 __ movsd(XMM1, XMM0); | 1786 __ movsd(XMM1, XMM0); |
| 1929 __ movsd(XMM2, XMM1); | 1787 __ movsd(XMM2, XMM1); |
| 1930 __ movsd(XMM3, XMM2); | 1788 __ movsd(XMM3, XMM2); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1946 __ movaps(XMM0, XMM1); | 1804 __ movaps(XMM0, XMM1); |
| 1947 __ movl(Address(ESP, 0), Immediate(0)); | 1805 __ movl(Address(ESP, 0), Immediate(0)); |
| 1948 __ movl(Address(ESP, kWordSize), Immediate(0)); | 1806 __ movl(Address(ESP, kWordSize), Immediate(0)); |
| 1949 __ movsd(Address(ESP, 0), XMM0); | 1807 __ movsd(Address(ESP, 0), XMM0); |
| 1950 __ fldl(Address(ESP, 0)); | 1808 __ fldl(Address(ESP, 0)); |
| 1951 __ popl(EAX); | 1809 __ popl(EAX); |
| 1952 __ popl(EAX); | 1810 __ popl(EAX); |
| 1953 __ ret(); | 1811 __ ret(); |
| 1954 } | 1812 } |
| 1955 | 1813 |
| 1956 | |
| 1957 ASSEMBLER_TEST_RUN(DoubleFPMoves, test) { | 1814 ASSEMBLER_TEST_RUN(DoubleFPMoves, test) { |
| 1958 typedef double (*DoubleFPMovesCode)(); | 1815 typedef double (*DoubleFPMovesCode)(); |
| 1959 double res = reinterpret_cast<DoubleFPMovesCode>(test->entry())(); | 1816 double res = reinterpret_cast<DoubleFPMovesCode>(test->entry())(); |
| 1960 EXPECT_FLOAT_EQ(1024.67, res, 0.0001); | 1817 EXPECT_FLOAT_EQ(1024.67, res, 0.0001); |
| 1961 } | 1818 } |
| 1962 | 1819 |
| 1963 ASSEMBLER_TEST_GENERATE(DoubleFPUStackMoves, assembler) { | 1820 ASSEMBLER_TEST_GENERATE(DoubleFPUStackMoves, assembler) { |
| 1964 int64_t l = bit_cast<int64_t, double>(1024.67); | 1821 int64_t l = bit_cast<int64_t, double>(1024.67); |
| 1965 __ movl(EAX, Immediate(Utils::High32Bits(l))); | 1822 __ movl(EAX, Immediate(Utils::High32Bits(l))); |
| 1966 __ pushl(EAX); | 1823 __ pushl(EAX); |
| 1967 __ movl(EAX, Immediate(Utils::Low32Bits(l))); | 1824 __ movl(EAX, Immediate(Utils::Low32Bits(l))); |
| 1968 __ pushl(EAX); | 1825 __ pushl(EAX); |
| 1969 __ fldl(Address(ESP, 0)); | 1826 __ fldl(Address(ESP, 0)); |
| 1970 __ movl(Address(ESP, 0), Immediate(0)); | 1827 __ movl(Address(ESP, 0), Immediate(0)); |
| 1971 __ movl(Address(ESP, kWordSize), Immediate(0)); | 1828 __ movl(Address(ESP, kWordSize), Immediate(0)); |
| 1972 __ fstpl(Address(ESP, 0)); | 1829 __ fstpl(Address(ESP, 0)); |
| 1973 __ popl(EAX); | 1830 __ popl(EAX); |
| 1974 __ popl(EDX); | 1831 __ popl(EDX); |
| 1975 __ ret(); | 1832 __ ret(); |
| 1976 } | 1833 } |
| 1977 | 1834 |
| 1978 | |
| 1979 ASSEMBLER_TEST_RUN(DoubleFPUStackMoves, test) { | 1835 ASSEMBLER_TEST_RUN(DoubleFPUStackMoves, test) { |
| 1980 typedef int64_t (*DoubleFPUStackMovesCode)(); | 1836 typedef int64_t (*DoubleFPUStackMovesCode)(); |
| 1981 int64_t res = reinterpret_cast<DoubleFPUStackMovesCode>(test->entry())(); | 1837 int64_t res = reinterpret_cast<DoubleFPUStackMovesCode>(test->entry())(); |
| 1982 EXPECT_FLOAT_EQ(1024.67, (bit_cast<double, int64_t>(res)), 0.001); | 1838 EXPECT_FLOAT_EQ(1024.67, (bit_cast<double, int64_t>(res)), 0.001); |
| 1983 } | 1839 } |
| 1984 | 1840 |
| 1985 | |
| 1986 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { | 1841 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { |
| 1987 int64_t l = bit_cast<int64_t, double>(12.3); | 1842 int64_t l = bit_cast<int64_t, double>(12.3); |
| 1988 __ movl(EAX, Immediate(Utils::High32Bits(l))); | 1843 __ movl(EAX, Immediate(Utils::High32Bits(l))); |
| 1989 __ pushl(EAX); | 1844 __ pushl(EAX); |
| 1990 __ movl(EAX, Immediate(Utils::Low32Bits(l))); | 1845 __ movl(EAX, Immediate(Utils::Low32Bits(l))); |
| 1991 __ pushl(EAX); | 1846 __ pushl(EAX); |
| 1992 __ movsd(XMM0, Address(ESP, 0)); | 1847 __ movsd(XMM0, Address(ESP, 0)); |
| 1993 __ popl(EAX); | 1848 __ popl(EAX); |
| 1994 __ popl(EAX); | 1849 __ popl(EAX); |
| 1995 l = bit_cast<int64_t, double>(3.4); | 1850 l = bit_cast<int64_t, double>(3.4); |
| 1996 __ movl(EAX, Immediate(Utils::High32Bits(l))); | 1851 __ movl(EAX, Immediate(Utils::High32Bits(l))); |
| 1997 __ pushl(EAX); | 1852 __ pushl(EAX); |
| 1998 __ movl(EAX, Immediate(Utils::Low32Bits(l))); | 1853 __ movl(EAX, Immediate(Utils::Low32Bits(l))); |
| 1999 __ pushl(EAX); | 1854 __ pushl(EAX); |
| 2000 __ movsd(XMM1, Address(ESP, 0)); | 1855 __ movsd(XMM1, Address(ESP, 0)); |
| 2001 __ addsd(XMM0, XMM1); // 15.7 | 1856 __ addsd(XMM0, XMM1); // 15.7 |
| 2002 __ mulsd(XMM0, XMM1); // 53.38 | 1857 __ mulsd(XMM0, XMM1); // 53.38 |
| 2003 __ subsd(XMM0, XMM1); // 49.98 | 1858 __ subsd(XMM0, XMM1); // 49.98 |
| 2004 __ divsd(XMM0, XMM1); // 14.7 | 1859 __ divsd(XMM0, XMM1); // 14.7 |
| 2005 __ movsd(Address(ESP, 0), XMM0); | 1860 __ movsd(Address(ESP, 0), XMM0); |
| 2006 __ fldl(Address(ESP, 0)); | 1861 __ fldl(Address(ESP, 0)); |
| 2007 __ popl(EAX); | 1862 __ popl(EAX); |
| 2008 __ popl(EAX); | 1863 __ popl(EAX); |
| 2009 __ ret(); | 1864 __ ret(); |
| 2010 } | 1865 } |
| 2011 | 1866 |
| 2012 | |
| 2013 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { | 1867 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { |
| 2014 typedef double (*DoubleFPOperationsCode)(); | 1868 typedef double (*DoubleFPOperationsCode)(); |
| 2015 double res = reinterpret_cast<DoubleFPOperationsCode>(test->entry())(); | 1869 double res = reinterpret_cast<DoubleFPOperationsCode>(test->entry())(); |
| 2016 EXPECT_FLOAT_EQ(14.7, res, 0.001); | 1870 EXPECT_FLOAT_EQ(14.7, res, 0.001); |
| 2017 } | 1871 } |
| 2018 | 1872 |
| 2019 | |
| 2020 ASSEMBLER_TEST_GENERATE(DoubleFPOperationsStack, assembler) { | 1873 ASSEMBLER_TEST_GENERATE(DoubleFPOperationsStack, assembler) { |
| 2021 int64_t l = bit_cast<int64_t, double>(12.3); | 1874 int64_t l = bit_cast<int64_t, double>(12.3); |
| 2022 __ movl(EAX, Immediate(Utils::High32Bits(l))); | 1875 __ movl(EAX, Immediate(Utils::High32Bits(l))); |
| 2023 __ pushl(EAX); | 1876 __ pushl(EAX); |
| 2024 __ movl(EAX, Immediate(Utils::Low32Bits(l))); | 1877 __ movl(EAX, Immediate(Utils::Low32Bits(l))); |
| 2025 __ pushl(EAX); | 1878 __ pushl(EAX); |
| 2026 __ movsd(XMM0, Address(ESP, 0)); | 1879 __ movsd(XMM0, Address(ESP, 0)); |
| 2027 __ popl(EAX); | 1880 __ popl(EAX); |
| 2028 __ popl(EAX); | 1881 __ popl(EAX); |
| 2029 | 1882 |
| 2030 __ addsd(XMM0, Address(ESP, kWordSize)); // 15.7 | 1883 __ addsd(XMM0, Address(ESP, kWordSize)); // 15.7 |
| 2031 __ mulsd(XMM0, Address(ESP, kWordSize)); // 53.38 | 1884 __ mulsd(XMM0, Address(ESP, kWordSize)); // 53.38 |
| 2032 __ subsd(XMM0, Address(ESP, kWordSize)); // 49.98 | 1885 __ subsd(XMM0, Address(ESP, kWordSize)); // 49.98 |
| 2033 __ divsd(XMM0, Address(ESP, kWordSize)); // 14.7 | 1886 __ divsd(XMM0, Address(ESP, kWordSize)); // 14.7 |
| 2034 | 1887 |
| 2035 __ pushl(EAX); | 1888 __ pushl(EAX); |
| 2036 __ pushl(EAX); | 1889 __ pushl(EAX); |
| 2037 __ movsd(Address(ESP, 0), XMM0); | 1890 __ movsd(Address(ESP, 0), XMM0); |
| 2038 __ fldl(Address(ESP, 0)); | 1891 __ fldl(Address(ESP, 0)); |
| 2039 __ popl(EAX); | 1892 __ popl(EAX); |
| 2040 __ popl(EAX); | 1893 __ popl(EAX); |
| 2041 __ ret(); | 1894 __ ret(); |
| 2042 } | 1895 } |
| 2043 | 1896 |
| 2044 | |
| 2045 ASSEMBLER_TEST_RUN(DoubleFPOperationsStack, test) { | 1897 ASSEMBLER_TEST_RUN(DoubleFPOperationsStack, test) { |
| 2046 typedef double (*DoubleFPOperationsStackCode)(double d); | 1898 typedef double (*DoubleFPOperationsStackCode)(double d); |
| 2047 double res = | 1899 double res = |
| 2048 reinterpret_cast<DoubleFPOperationsStackCode>(test->entry())(3.4); | 1900 reinterpret_cast<DoubleFPOperationsStackCode>(test->entry())(3.4); |
| 2049 EXPECT_FLOAT_EQ(14.7, res, 0.001); | 1901 EXPECT_FLOAT_EQ(14.7, res, 0.001); |
| 2050 } | 1902 } |
| 2051 | 1903 |
| 2052 | |
| 2053 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) { | 1904 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) { |
| 2054 __ movl(EDX, Immediate(6)); | 1905 __ movl(EDX, Immediate(6)); |
| 2055 __ cvtsi2sd(XMM1, EDX); | 1906 __ cvtsi2sd(XMM1, EDX); |
| 2056 __ pushl(EAX); | 1907 __ pushl(EAX); |
| 2057 __ pushl(EAX); | 1908 __ pushl(EAX); |
| 2058 __ movsd(Address(ESP, 0), XMM1); | 1909 __ movsd(Address(ESP, 0), XMM1); |
| 2059 __ fldl(Address(ESP, 0)); | 1910 __ fldl(Address(ESP, 0)); |
| 2060 __ popl(EAX); | 1911 __ popl(EAX); |
| 2061 __ popl(EAX); | 1912 __ popl(EAX); |
| 2062 __ ret(); | 1913 __ ret(); |
| 2063 } | 1914 } |
| 2064 | 1915 |
| 2065 | |
| 2066 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { | 1916 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { |
| 2067 typedef double (*IntToDoubleConversionCode)(); | 1917 typedef double (*IntToDoubleConversionCode)(); |
| 2068 double res = reinterpret_cast<IntToDoubleConversionCode>(test->entry())(); | 1918 double res = reinterpret_cast<IntToDoubleConversionCode>(test->entry())(); |
| 2069 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 1919 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
| 2070 } | 1920 } |
| 2071 | 1921 |
| 2072 | |
| 2073 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion2, assembler) { | 1922 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion2, assembler) { |
| 2074 __ filds(Address(ESP, kWordSize)); | 1923 __ filds(Address(ESP, kWordSize)); |
| 2075 __ ret(); | 1924 __ ret(); |
| 2076 } | 1925 } |
| 2077 | 1926 |
| 2078 | |
| 2079 ASSEMBLER_TEST_RUN(IntToDoubleConversion2, test) { | 1927 ASSEMBLER_TEST_RUN(IntToDoubleConversion2, test) { |
| 2080 typedef double (*IntToDoubleConversion2Code)(int i); | 1928 typedef double (*IntToDoubleConversion2Code)(int i); |
| 2081 double res = reinterpret_cast<IntToDoubleConversion2Code>(test->entry())(3); | 1929 double res = reinterpret_cast<IntToDoubleConversion2Code>(test->entry())(3); |
| 2082 EXPECT_FLOAT_EQ(3.0, res, 0.001); | 1930 EXPECT_FLOAT_EQ(3.0, res, 0.001); |
| 2083 } | 1931 } |
| 2084 | 1932 |
| 2085 | |
| 2086 ASSEMBLER_TEST_GENERATE(Int64ToDoubleConversion, assembler) { | 1933 ASSEMBLER_TEST_GENERATE(Int64ToDoubleConversion, assembler) { |
| 2087 __ movl(EAX, Immediate(0)); | 1934 __ movl(EAX, Immediate(0)); |
| 2088 __ movl(EDX, Immediate(6)); | 1935 __ movl(EDX, Immediate(6)); |
| 2089 __ pushl(EAX); | 1936 __ pushl(EAX); |
| 2090 __ pushl(EDX); | 1937 __ pushl(EDX); |
| 2091 __ fildl(Address(ESP, 0)); | 1938 __ fildl(Address(ESP, 0)); |
| 2092 __ popl(EAX); | 1939 __ popl(EAX); |
| 2093 __ popl(EAX); | 1940 __ popl(EAX); |
| 2094 __ ret(); | 1941 __ ret(); |
| 2095 } | 1942 } |
| 2096 | 1943 |
| 2097 | |
| 2098 ASSEMBLER_TEST_RUN(Int64ToDoubleConversion, test) { | 1944 ASSEMBLER_TEST_RUN(Int64ToDoubleConversion, test) { |
| 2099 typedef double (*Int64ToDoubleConversionCode)(); | 1945 typedef double (*Int64ToDoubleConversionCode)(); |
| 2100 double res = reinterpret_cast<Int64ToDoubleConversionCode>(test->entry())(); | 1946 double res = reinterpret_cast<Int64ToDoubleConversionCode>(test->entry())(); |
| 2101 EXPECT_EQ(6.0, res); | 1947 EXPECT_EQ(6.0, res); |
| 2102 } | 1948 } |
| 2103 | 1949 |
| 2104 | |
| 2105 ASSEMBLER_TEST_GENERATE(NegativeInt64ToDoubleConversion, assembler) { | 1950 ASSEMBLER_TEST_GENERATE(NegativeInt64ToDoubleConversion, assembler) { |
| 2106 __ movl(EAX, Immediate(0xFFFFFFFF)); | 1951 __ movl(EAX, Immediate(0xFFFFFFFF)); |
| 2107 __ movl(EDX, Immediate(0xFFFFFFFA)); | 1952 __ movl(EDX, Immediate(0xFFFFFFFA)); |
| 2108 __ pushl(EAX); | 1953 __ pushl(EAX); |
| 2109 __ pushl(EDX); | 1954 __ pushl(EDX); |
| 2110 __ fildl(Address(ESP, 0)); | 1955 __ fildl(Address(ESP, 0)); |
| 2111 __ popl(EAX); | 1956 __ popl(EAX); |
| 2112 __ popl(EAX); | 1957 __ popl(EAX); |
| 2113 __ ret(); | 1958 __ ret(); |
| 2114 } | 1959 } |
| 2115 | 1960 |
| 2116 | |
| 2117 ASSEMBLER_TEST_RUN(NegativeInt64ToDoubleConversion, test) { | 1961 ASSEMBLER_TEST_RUN(NegativeInt64ToDoubleConversion, test) { |
| 2118 typedef double (*NegativeInt64ToDoubleConversionCode)(); | 1962 typedef double (*NegativeInt64ToDoubleConversionCode)(); |
| 2119 double res = | 1963 double res = |
| 2120 reinterpret_cast<NegativeInt64ToDoubleConversionCode>(test->entry())(); | 1964 reinterpret_cast<NegativeInt64ToDoubleConversionCode>(test->entry())(); |
| 2121 EXPECT_EQ(-6.0, res); | 1965 EXPECT_EQ(-6.0, res); |
| 2122 } | 1966 } |
| 2123 | 1967 |
| 2124 | |
| 2125 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) { | 1968 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) { |
| 2126 __ movl(EDX, Immediate(6)); | 1969 __ movl(EDX, Immediate(6)); |
| 2127 __ cvtsi2ss(XMM1, EDX); | 1970 __ cvtsi2ss(XMM1, EDX); |
| 2128 __ pushl(EAX); | 1971 __ pushl(EAX); |
| 2129 __ movss(Address(ESP, 0), XMM1); | 1972 __ movss(Address(ESP, 0), XMM1); |
| 2130 __ flds(Address(ESP, 0)); | 1973 __ flds(Address(ESP, 0)); |
| 2131 __ popl(EAX); | 1974 __ popl(EAX); |
| 2132 __ ret(); | 1975 __ ret(); |
| 2133 } | 1976 } |
| 2134 | 1977 |
| 2135 | |
| 2136 ASSEMBLER_TEST_RUN(IntToFloatConversion, test) { | 1978 ASSEMBLER_TEST_RUN(IntToFloatConversion, test) { |
| 2137 typedef float (*IntToFloatConversionCode)(); | 1979 typedef float (*IntToFloatConversionCode)(); |
| 2138 float res = reinterpret_cast<IntToFloatConversionCode>(test->entry())(); | 1980 float res = reinterpret_cast<IntToFloatConversionCode>(test->entry())(); |
| 2139 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 1981 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
| 2140 } | 1982 } |
| 2141 | 1983 |
| 2142 | |
| 2143 ASSEMBLER_TEST_GENERATE(FloatToIntConversionRound, assembler) { | 1984 ASSEMBLER_TEST_GENERATE(FloatToIntConversionRound, assembler) { |
| 2144 __ movsd(XMM1, Address(ESP, kWordSize)); | 1985 __ movsd(XMM1, Address(ESP, kWordSize)); |
| 2145 __ cvtss2si(EDX, XMM1); | 1986 __ cvtss2si(EDX, XMM1); |
| 2146 __ movl(EAX, EDX); | 1987 __ movl(EAX, EDX); |
| 2147 __ ret(); | 1988 __ ret(); |
| 2148 } | 1989 } |
| 2149 | 1990 |
| 2150 | |
| 2151 ASSEMBLER_TEST_RUN(FloatToIntConversionRound, test) { | 1991 ASSEMBLER_TEST_RUN(FloatToIntConversionRound, test) { |
| 2152 typedef int (*FloatToIntConversionRoundCode)(float f); | 1992 typedef int (*FloatToIntConversionRoundCode)(float f); |
| 2153 int res = | 1993 int res = |
| 2154 reinterpret_cast<FloatToIntConversionRoundCode>(test->entry())(12.3); | 1994 reinterpret_cast<FloatToIntConversionRoundCode>(test->entry())(12.3); |
| 2155 EXPECT_EQ(12, res); | 1995 EXPECT_EQ(12, res); |
| 2156 res = reinterpret_cast<FloatToIntConversionRoundCode>(test->entry())(12.8); | 1996 res = reinterpret_cast<FloatToIntConversionRoundCode>(test->entry())(12.8); |
| 2157 EXPECT_EQ(13, res); | 1997 EXPECT_EQ(13, res); |
| 2158 } | 1998 } |
| 2159 | 1999 |
| 2160 | |
| 2161 ASSEMBLER_TEST_GENERATE(FloatToIntConversionTrunc, assembler) { | 2000 ASSEMBLER_TEST_GENERATE(FloatToIntConversionTrunc, assembler) { |
| 2162 __ movsd(XMM1, Address(ESP, kWordSize)); | 2001 __ movsd(XMM1, Address(ESP, kWordSize)); |
| 2163 __ cvttss2si(EDX, XMM1); | 2002 __ cvttss2si(EDX, XMM1); |
| 2164 __ movl(EAX, EDX); | 2003 __ movl(EAX, EDX); |
| 2165 __ ret(); | 2004 __ ret(); |
| 2166 } | 2005 } |
| 2167 | 2006 |
| 2168 | |
| 2169 ASSEMBLER_TEST_RUN(FloatToIntConversionTrunc, test) { | 2007 ASSEMBLER_TEST_RUN(FloatToIntConversionTrunc, test) { |
| 2170 typedef int (*FloatToIntConversionTruncCode)(float f); | 2008 typedef int (*FloatToIntConversionTruncCode)(float f); |
| 2171 int res = | 2009 int res = |
| 2172 reinterpret_cast<FloatToIntConversionTruncCode>(test->entry())(12.3); | 2010 reinterpret_cast<FloatToIntConversionTruncCode>(test->entry())(12.3); |
| 2173 EXPECT_EQ(12, res); | 2011 EXPECT_EQ(12, res); |
| 2174 res = reinterpret_cast<FloatToIntConversionTruncCode>(test->entry())(12.8); | 2012 res = reinterpret_cast<FloatToIntConversionTruncCode>(test->entry())(12.8); |
| 2175 EXPECT_EQ(12, res); | 2013 EXPECT_EQ(12, res); |
| 2176 } | 2014 } |
| 2177 | 2015 |
| 2178 | |
| 2179 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { | 2016 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { |
| 2180 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 2017 __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 2181 __ movd(XMM1, EAX); | 2018 __ movd(XMM1, EAX); |
| 2182 __ xorl(EAX, EAX); | 2019 __ xorl(EAX, EAX); |
| 2183 __ cvtss2sd(XMM2, XMM1); | 2020 __ cvtss2sd(XMM2, XMM1); |
| 2184 __ pushl(EAX); | 2021 __ pushl(EAX); |
| 2185 __ pushl(EAX); | 2022 __ pushl(EAX); |
| 2186 __ movsd(Address(ESP, 0), XMM2); | 2023 __ movsd(Address(ESP, 0), XMM2); |
| 2187 __ fldl(Address(ESP, 0)); | 2024 __ fldl(Address(ESP, 0)); |
| 2188 __ popl(EAX); | 2025 __ popl(EAX); |
| 2189 __ popl(EAX); | 2026 __ popl(EAX); |
| 2190 __ ret(); | 2027 __ ret(); |
| 2191 } | 2028 } |
| 2192 | 2029 |
| 2193 | |
| 2194 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { | 2030 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { |
| 2195 typedef double (*FloatToDoubleConversionCode)(); | 2031 typedef double (*FloatToDoubleConversionCode)(); |
| 2196 double res = reinterpret_cast<FloatToDoubleConversionCode>(test->entry())(); | 2032 double res = reinterpret_cast<FloatToDoubleConversionCode>(test->entry())(); |
| 2197 EXPECT_FLOAT_EQ(12.3, res, 0.001); | 2033 EXPECT_FLOAT_EQ(12.3, res, 0.001); |
| 2198 } | 2034 } |
| 2199 | 2035 |
| 2200 | |
| 2201 ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) { | 2036 ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) { |
| 2202 // Count errors in EAX. EAX is zero if no errors found. | 2037 // Count errors in EAX. EAX is zero if no errors found. |
| 2203 Label is_nan, is_above, is_ok, cont_1, cont_2; | 2038 Label is_nan, is_above, is_ok, cont_1, cont_2; |
| 2204 // Test 12.3f vs 12.5f. | 2039 // Test 12.3f vs 12.5f. |
| 2205 __ xorl(EAX, EAX); | 2040 __ xorl(EAX, EAX); |
| 2206 __ movl(EDX, Immediate(bit_cast<int32_t, float>(12.3f))); | 2041 __ movl(EDX, Immediate(bit_cast<int32_t, float>(12.3f))); |
| 2207 __ movd(XMM0, EDX); | 2042 __ movd(XMM0, EDX); |
| 2208 __ movl(EDX, Immediate(bit_cast<int32_t, float>(12.5f))); | 2043 __ movl(EDX, Immediate(bit_cast<int32_t, float>(12.5f))); |
| 2209 __ movd(XMM1, EDX); | 2044 __ movd(XMM1, EDX); |
| 2210 __ comiss(XMM0, XMM1); | 2045 __ comiss(XMM0, XMM1); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2232 | 2067 |
| 2233 __ Bind(&is_nan); | 2068 __ Bind(&is_nan); |
| 2234 __ incl(EAX); | 2069 __ incl(EAX); |
| 2235 __ jmp(&cont_1); | 2070 __ jmp(&cont_1); |
| 2236 | 2071 |
| 2237 __ Bind(&is_above); | 2072 __ Bind(&is_above); |
| 2238 __ incl(EAX); | 2073 __ incl(EAX); |
| 2239 __ jmp(&cont_2); | 2074 __ jmp(&cont_2); |
| 2240 } | 2075 } |
| 2241 | 2076 |
| 2242 | |
| 2243 ASSEMBLER_TEST_RUN(FloatCompare, test) { | 2077 ASSEMBLER_TEST_RUN(FloatCompare, test) { |
| 2244 typedef int (*FloatCompareCode)(); | 2078 typedef int (*FloatCompareCode)(); |
| 2245 int res = reinterpret_cast<FloatCompareCode>(test->entry())(); | 2079 int res = reinterpret_cast<FloatCompareCode>(test->entry())(); |
| 2246 EXPECT_EQ(0, res); | 2080 EXPECT_EQ(0, res); |
| 2247 } | 2081 } |
| 2248 | 2082 |
| 2249 | |
| 2250 ASSEMBLER_TEST_GENERATE(DoubleCompare, assembler) { | 2083 ASSEMBLER_TEST_GENERATE(DoubleCompare, assembler) { |
| 2251 int64_t a = bit_cast<int64_t, double>(12.3); | 2084 int64_t a = bit_cast<int64_t, double>(12.3); |
| 2252 int64_t b = bit_cast<int64_t, double>(12.5); | 2085 int64_t b = bit_cast<int64_t, double>(12.5); |
| 2253 | 2086 |
| 2254 __ movl(EDX, Immediate(Utils::High32Bits(a))); | 2087 __ movl(EDX, Immediate(Utils::High32Bits(a))); |
| 2255 __ pushl(EDX); | 2088 __ pushl(EDX); |
| 2256 __ movl(EDX, Immediate(Utils::Low32Bits(a))); | 2089 __ movl(EDX, Immediate(Utils::Low32Bits(a))); |
| 2257 __ pushl(EDX); | 2090 __ pushl(EDX); |
| 2258 __ movsd(XMM0, Address(ESP, 0)); | 2091 __ movsd(XMM0, Address(ESP, 0)); |
| 2259 __ popl(EDX); | 2092 __ popl(EDX); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2303 | 2136 |
| 2304 __ Bind(&is_nan); | 2137 __ Bind(&is_nan); |
| 2305 __ incl(EAX); | 2138 __ incl(EAX); |
| 2306 __ jmp(&cont_1); | 2139 __ jmp(&cont_1); |
| 2307 | 2140 |
| 2308 __ Bind(&is_above); | 2141 __ Bind(&is_above); |
| 2309 __ incl(EAX); | 2142 __ incl(EAX); |
| 2310 __ jmp(&cont_2); | 2143 __ jmp(&cont_2); |
| 2311 } | 2144 } |
| 2312 | 2145 |
| 2313 | |
| 2314 ASSEMBLER_TEST_RUN(DoubleCompare, test) { | 2146 ASSEMBLER_TEST_RUN(DoubleCompare, test) { |
| 2315 typedef int (*DoubleCompareCode)(); | 2147 typedef int (*DoubleCompareCode)(); |
| 2316 int res = reinterpret_cast<DoubleCompareCode>(test->entry())(); | 2148 int res = reinterpret_cast<DoubleCompareCode>(test->entry())(); |
| 2317 EXPECT_EQ(0, res); | 2149 EXPECT_EQ(0, res); |
| 2318 } | 2150 } |
| 2319 | 2151 |
| 2320 | |
| 2321 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { | 2152 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { |
| 2322 int64_t l = bit_cast<int64_t, double>(12.3); | 2153 int64_t l = bit_cast<int64_t, double>(12.3); |
| 2323 __ movl(EAX, Immediate(Utils::High32Bits(l))); | 2154 __ movl(EAX, Immediate(Utils::High32Bits(l))); |
| 2324 __ pushl(EAX); | 2155 __ pushl(EAX); |
| 2325 __ movl(EAX, Immediate(Utils::Low32Bits(l))); | 2156 __ movl(EAX, Immediate(Utils::Low32Bits(l))); |
| 2326 __ pushl(EAX); | 2157 __ pushl(EAX); |
| 2327 __ movsd(XMM0, Address(ESP, 0)); | 2158 __ movsd(XMM0, Address(ESP, 0)); |
| 2328 __ cvtsd2ss(XMM1, XMM0); | 2159 __ cvtsd2ss(XMM1, XMM0); |
| 2329 __ movss(Address(ESP, 0), XMM1); | 2160 __ movss(Address(ESP, 0), XMM1); |
| 2330 __ flds(Address(ESP, 0)); | 2161 __ flds(Address(ESP, 0)); |
| 2331 __ popl(EAX); | 2162 __ popl(EAX); |
| 2332 __ popl(EAX); | 2163 __ popl(EAX); |
| 2333 __ ret(); | 2164 __ ret(); |
| 2334 } | 2165 } |
| 2335 | 2166 |
| 2336 | |
| 2337 ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) { | 2167 ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) { |
| 2338 typedef float (*DoubleToFloatConversionCode)(); | 2168 typedef float (*DoubleToFloatConversionCode)(); |
| 2339 float res = reinterpret_cast<DoubleToFloatConversionCode>(test->entry())(); | 2169 float res = reinterpret_cast<DoubleToFloatConversionCode>(test->entry())(); |
| 2340 EXPECT_FLOAT_EQ(12.3f, res, 0.001); | 2170 EXPECT_FLOAT_EQ(12.3f, res, 0.001); |
| 2341 } | 2171 } |
| 2342 | 2172 |
| 2343 | |
| 2344 ASSEMBLER_TEST_GENERATE(DoubleToIntConversionRound, assembler) { | 2173 ASSEMBLER_TEST_GENERATE(DoubleToIntConversionRound, assembler) { |
| 2345 __ movsd(XMM3, Address(ESP, kWordSize)); | 2174 __ movsd(XMM3, Address(ESP, kWordSize)); |
| 2346 __ cvtsd2si(EAX, XMM3); | 2175 __ cvtsd2si(EAX, XMM3); |
| 2347 __ ret(); | 2176 __ ret(); |
| 2348 } | 2177 } |
| 2349 | 2178 |
| 2350 | |
| 2351 ASSEMBLER_TEST_RUN(DoubleToIntConversionRound, test) { | 2179 ASSEMBLER_TEST_RUN(DoubleToIntConversionRound, test) { |
| 2352 typedef int (*DoubleToIntConversionRoundCode)(double d); | 2180 typedef int (*DoubleToIntConversionRoundCode)(double d); |
| 2353 int res = | 2181 int res = |
| 2354 reinterpret_cast<DoubleToIntConversionRoundCode>(test->entry())(12.3); | 2182 reinterpret_cast<DoubleToIntConversionRoundCode>(test->entry())(12.3); |
| 2355 EXPECT_EQ(12, res); | 2183 EXPECT_EQ(12, res); |
| 2356 res = reinterpret_cast<DoubleToIntConversionRoundCode>(test->entry())(12.8); | 2184 res = reinterpret_cast<DoubleToIntConversionRoundCode>(test->entry())(12.8); |
| 2357 EXPECT_EQ(13, res); | 2185 EXPECT_EQ(13, res); |
| 2358 } | 2186 } |
| 2359 | 2187 |
| 2360 | |
| 2361 ASSEMBLER_TEST_GENERATE(DoubleToIntConversionTrunc, assembler) { | 2188 ASSEMBLER_TEST_GENERATE(DoubleToIntConversionTrunc, assembler) { |
| 2362 __ movsd(XMM3, Address(ESP, kWordSize)); | 2189 __ movsd(XMM3, Address(ESP, kWordSize)); |
| 2363 __ cvttsd2si(EAX, XMM3); | 2190 __ cvttsd2si(EAX, XMM3); |
| 2364 __ ret(); | 2191 __ ret(); |
| 2365 } | 2192 } |
| 2366 | 2193 |
| 2367 | |
| 2368 ASSEMBLER_TEST_RUN(DoubleToIntConversionTrunc, test) { | 2194 ASSEMBLER_TEST_RUN(DoubleToIntConversionTrunc, test) { |
| 2369 typedef int (*DoubleToIntConversionTruncCode)(double d); | 2195 typedef int (*DoubleToIntConversionTruncCode)(double d); |
| 2370 int res = | 2196 int res = |
| 2371 reinterpret_cast<DoubleToIntConversionTruncCode>(test->entry())(12.3); | 2197 reinterpret_cast<DoubleToIntConversionTruncCode>(test->entry())(12.3); |
| 2372 EXPECT_EQ(12, res); | 2198 EXPECT_EQ(12, res); |
| 2373 res = reinterpret_cast<DoubleToIntConversionTruncCode>(test->entry())(12.8); | 2199 res = reinterpret_cast<DoubleToIntConversionTruncCode>(test->entry())(12.8); |
| 2374 EXPECT_EQ(12, res); | 2200 EXPECT_EQ(12, res); |
| 2375 } | 2201 } |
| 2376 | 2202 |
| 2377 | |
| 2378 ASSEMBLER_TEST_GENERATE(DoubleToDoubleTrunc, assembler) { | 2203 ASSEMBLER_TEST_GENERATE(DoubleToDoubleTrunc, assembler) { |
| 2379 __ movsd(XMM3, Address(ESP, kWordSize)); | 2204 __ movsd(XMM3, Address(ESP, kWordSize)); |
| 2380 __ roundsd(XMM2, XMM3, Assembler::kRoundToZero); | 2205 __ roundsd(XMM2, XMM3, Assembler::kRoundToZero); |
| 2381 __ pushl(EAX); | 2206 __ pushl(EAX); |
| 2382 __ pushl(EAX); | 2207 __ pushl(EAX); |
| 2383 __ movsd(Address(ESP, 0), XMM2); | 2208 __ movsd(Address(ESP, 0), XMM2); |
| 2384 __ fldl(Address(ESP, 0)); | 2209 __ fldl(Address(ESP, 0)); |
| 2385 __ popl(EAX); | 2210 __ popl(EAX); |
| 2386 __ popl(EAX); | 2211 __ popl(EAX); |
| 2387 __ ret(); | 2212 __ ret(); |
| 2388 } | 2213 } |
| 2389 | 2214 |
| 2390 | |
| 2391 ASSEMBLER_TEST_RUN(DoubleToDoubleTrunc, test) { | 2215 ASSEMBLER_TEST_RUN(DoubleToDoubleTrunc, test) { |
| 2392 typedef double (*DoubleToDoubleTruncCode)(double d); | 2216 typedef double (*DoubleToDoubleTruncCode)(double d); |
| 2393 double res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.3); | 2217 double res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.3); |
| 2394 EXPECT_EQ(12.0, res); | 2218 EXPECT_EQ(12.0, res); |
| 2395 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.8); | 2219 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.8); |
| 2396 EXPECT_EQ(12.0, res); | 2220 EXPECT_EQ(12.0, res); |
| 2397 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.3); | 2221 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.3); |
| 2398 EXPECT_EQ(-12.0, res); | 2222 EXPECT_EQ(-12.0, res); |
| 2399 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.8); | 2223 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.8); |
| 2400 EXPECT_EQ(-12.0, res); | 2224 EXPECT_EQ(-12.0, res); |
| 2401 } | 2225 } |
| 2402 | 2226 |
| 2403 | |
| 2404 static const double kDoubleConst = 3.226; | 2227 static const double kDoubleConst = 3.226; |
| 2405 | 2228 |
| 2406 ASSEMBLER_TEST_GENERATE(GlobalAddress, assembler) { | 2229 ASSEMBLER_TEST_GENERATE(GlobalAddress, assembler) { |
| 2407 __ movsd(XMM0, Address::Absolute(reinterpret_cast<uword>(&kDoubleConst))); | 2230 __ movsd(XMM0, Address::Absolute(reinterpret_cast<uword>(&kDoubleConst))); |
| 2408 __ pushl(EAX); | 2231 __ pushl(EAX); |
| 2409 __ pushl(EAX); | 2232 __ pushl(EAX); |
| 2410 __ movsd(Address(ESP, 0), XMM0); | 2233 __ movsd(Address(ESP, 0), XMM0); |
| 2411 __ fldl(Address(ESP, 0)); | 2234 __ fldl(Address(ESP, 0)); |
| 2412 __ popl(EAX); | 2235 __ popl(EAX); |
| 2413 __ popl(EAX); | 2236 __ popl(EAX); |
| 2414 __ ret(); | 2237 __ ret(); |
| 2415 } | 2238 } |
| 2416 | 2239 |
| 2417 | |
| 2418 ASSEMBLER_TEST_RUN(GlobalAddress, test) { | 2240 ASSEMBLER_TEST_RUN(GlobalAddress, test) { |
| 2419 typedef double (*GlobalAddressCode)(); | 2241 typedef double (*GlobalAddressCode)(); |
| 2420 double res = reinterpret_cast<GlobalAddressCode>(test->entry())(); | 2242 double res = reinterpret_cast<GlobalAddressCode>(test->entry())(); |
| 2421 EXPECT_FLOAT_EQ(kDoubleConst, res, 0.000001); | 2243 EXPECT_FLOAT_EQ(kDoubleConst, res, 0.000001); |
| 2422 } | 2244 } |
| 2423 | 2245 |
| 2424 | |
| 2425 ASSEMBLER_TEST_GENERATE(Sine, assembler) { | 2246 ASSEMBLER_TEST_GENERATE(Sine, assembler) { |
| 2426 __ flds(Address(ESP, kWordSize)); | 2247 __ flds(Address(ESP, kWordSize)); |
| 2427 __ fsin(); | 2248 __ fsin(); |
| 2428 __ ret(); | 2249 __ ret(); |
| 2429 } | 2250 } |
| 2430 | 2251 |
| 2431 | |
| 2432 ASSEMBLER_TEST_RUN(Sine, test) { | 2252 ASSEMBLER_TEST_RUN(Sine, test) { |
| 2433 typedef float (*SineCode)(float f); | 2253 typedef float (*SineCode)(float f); |
| 2434 const float kFloatConst = 0.7; | 2254 const float kFloatConst = 0.7; |
| 2435 float res = reinterpret_cast<SineCode>(test->entry())(kFloatConst); | 2255 float res = reinterpret_cast<SineCode>(test->entry())(kFloatConst); |
| 2436 EXPECT_FLOAT_EQ(sin(kFloatConst), res, 0.0001); | 2256 EXPECT_FLOAT_EQ(sin(kFloatConst), res, 0.0001); |
| 2437 } | 2257 } |
| 2438 | 2258 |
| 2439 | |
| 2440 ASSEMBLER_TEST_GENERATE(Cosine, assembler) { | 2259 ASSEMBLER_TEST_GENERATE(Cosine, assembler) { |
| 2441 __ flds(Address(ESP, kWordSize)); | 2260 __ flds(Address(ESP, kWordSize)); |
| 2442 __ fcos(); | 2261 __ fcos(); |
| 2443 __ ret(); | 2262 __ ret(); |
| 2444 } | 2263 } |
| 2445 | 2264 |
| 2446 | |
| 2447 ASSEMBLER_TEST_RUN(Cosine, test) { | 2265 ASSEMBLER_TEST_RUN(Cosine, test) { |
| 2448 typedef float (*CosineCode)(float f); | 2266 typedef float (*CosineCode)(float f); |
| 2449 const float kFloatConst = 0.7; | 2267 const float kFloatConst = 0.7; |
| 2450 float res = reinterpret_cast<CosineCode>(test->entry())(kFloatConst); | 2268 float res = reinterpret_cast<CosineCode>(test->entry())(kFloatConst); |
| 2451 EXPECT_FLOAT_EQ(cos(kFloatConst), res, 0.0001); | 2269 EXPECT_FLOAT_EQ(cos(kFloatConst), res, 0.0001); |
| 2452 } | 2270 } |
| 2453 | 2271 |
| 2454 | |
| 2455 ASSEMBLER_TEST_GENERATE(SinCos, assembler) { | 2272 ASSEMBLER_TEST_GENERATE(SinCos, assembler) { |
| 2456 __ fldl(Address(ESP, kWordSize)); | 2273 __ fldl(Address(ESP, kWordSize)); |
| 2457 __ fsincos(); | 2274 __ fsincos(); |
| 2458 __ subl(ESP, Immediate(2 * kWordSize)); | 2275 __ subl(ESP, Immediate(2 * kWordSize)); |
| 2459 __ fstpl(Address(ESP, 0)); // cos result. | 2276 __ fstpl(Address(ESP, 0)); // cos result. |
| 2460 __ movsd(XMM0, Address(ESP, 0)); | 2277 __ movsd(XMM0, Address(ESP, 0)); |
| 2461 __ fstpl(Address(ESP, 0)); // sin result. | 2278 __ fstpl(Address(ESP, 0)); // sin result. |
| 2462 __ movsd(XMM1, Address(ESP, 0)); | 2279 __ movsd(XMM1, Address(ESP, 0)); |
| 2463 __ subsd(XMM1, XMM0); // sin - cos. | 2280 __ subsd(XMM1, XMM0); // sin - cos. |
| 2464 __ movsd(Address(ESP, 0), XMM1); | 2281 __ movsd(Address(ESP, 0), XMM1); |
| 2465 __ fldl(Address(ESP, 0)); | 2282 __ fldl(Address(ESP, 0)); |
| 2466 __ addl(ESP, Immediate(2 * kWordSize)); | 2283 __ addl(ESP, Immediate(2 * kWordSize)); |
| 2467 __ ret(); | 2284 __ ret(); |
| 2468 } | 2285 } |
| 2469 | 2286 |
| 2470 | |
| 2471 ASSEMBLER_TEST_RUN(SinCos, test) { | 2287 ASSEMBLER_TEST_RUN(SinCos, test) { |
| 2472 typedef double (*SinCosCode)(double d); | 2288 typedef double (*SinCosCode)(double d); |
| 2473 const double arg = 1.2345; | 2289 const double arg = 1.2345; |
| 2474 const double expected = sin(arg) - cos(arg); | 2290 const double expected = sin(arg) - cos(arg); |
| 2475 double res = reinterpret_cast<SinCosCode>(test->entry())(arg); | 2291 double res = reinterpret_cast<SinCosCode>(test->entry())(arg); |
| 2476 EXPECT_FLOAT_EQ(expected, res, 0.000001); | 2292 EXPECT_FLOAT_EQ(expected, res, 0.000001); |
| 2477 } | 2293 } |
| 2478 | 2294 |
| 2479 | |
| 2480 ASSEMBLER_TEST_GENERATE(Tangent, assembler) { | 2295 ASSEMBLER_TEST_GENERATE(Tangent, assembler) { |
| 2481 __ fldl(Address(ESP, kWordSize)); | 2296 __ fldl(Address(ESP, kWordSize)); |
| 2482 __ fptan(); | 2297 __ fptan(); |
| 2483 __ ffree(0); | 2298 __ ffree(0); |
| 2484 __ fincstp(); | 2299 __ fincstp(); |
| 2485 __ ret(); | 2300 __ ret(); |
| 2486 } | 2301 } |
| 2487 | 2302 |
| 2488 | |
| 2489 ASSEMBLER_TEST_RUN(Tangent, test) { | 2303 ASSEMBLER_TEST_RUN(Tangent, test) { |
| 2490 typedef double (*TangentCode)(double d); | 2304 typedef double (*TangentCode)(double d); |
| 2491 const double kDoubleConst = 0.6108652375000001; | 2305 const double kDoubleConst = 0.6108652375000001; |
| 2492 double res = reinterpret_cast<TangentCode>(test->entry())(kDoubleConst); | 2306 double res = reinterpret_cast<TangentCode>(test->entry())(kDoubleConst); |
| 2493 EXPECT_FLOAT_EQ(tan(kDoubleConst), res, 0.0001); | 2307 EXPECT_FLOAT_EQ(tan(kDoubleConst), res, 0.0001); |
| 2494 } | 2308 } |
| 2495 | 2309 |
| 2496 | |
| 2497 ASSEMBLER_TEST_GENERATE(SquareRootFloat, assembler) { | 2310 ASSEMBLER_TEST_GENERATE(SquareRootFloat, assembler) { |
| 2498 __ movss(XMM0, Address(ESP, kWordSize)); | 2311 __ movss(XMM0, Address(ESP, kWordSize)); |
| 2499 __ sqrtss(XMM1, XMM0); | 2312 __ sqrtss(XMM1, XMM0); |
| 2500 __ pushl(EAX); | 2313 __ pushl(EAX); |
| 2501 __ movss(Address(ESP, 0), XMM1); | 2314 __ movss(Address(ESP, 0), XMM1); |
| 2502 __ flds(Address(ESP, 0)); | 2315 __ flds(Address(ESP, 0)); |
| 2503 __ popl(EAX); | 2316 __ popl(EAX); |
| 2504 __ ret(); | 2317 __ ret(); |
| 2505 } | 2318 } |
| 2506 | 2319 |
| 2507 | |
| 2508 ASSEMBLER_TEST_RUN(SquareRootFloat, test) { | 2320 ASSEMBLER_TEST_RUN(SquareRootFloat, test) { |
| 2509 typedef float (*SquareRootFloatCode)(float f); | 2321 typedef float (*SquareRootFloatCode)(float f); |
| 2510 const float kFloatConst = 0.7; | 2322 const float kFloatConst = 0.7; |
| 2511 float res = reinterpret_cast<SquareRootFloatCode>(test->entry())(kFloatConst); | 2323 float res = reinterpret_cast<SquareRootFloatCode>(test->entry())(kFloatConst); |
| 2512 EXPECT_FLOAT_EQ(sqrt(kFloatConst), res, 0.0001); | 2324 EXPECT_FLOAT_EQ(sqrt(kFloatConst), res, 0.0001); |
| 2513 } | 2325 } |
| 2514 | 2326 |
| 2515 | |
| 2516 ASSEMBLER_TEST_GENERATE(SquareRootDouble, assembler) { | 2327 ASSEMBLER_TEST_GENERATE(SquareRootDouble, assembler) { |
| 2517 __ movsd(XMM0, Address(ESP, kWordSize)); | 2328 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2518 __ sqrtsd(XMM1, XMM0); | 2329 __ sqrtsd(XMM1, XMM0); |
| 2519 __ pushl(EAX); | 2330 __ pushl(EAX); |
| 2520 __ pushl(EAX); | 2331 __ pushl(EAX); |
| 2521 __ movsd(Address(ESP, 0), XMM1); | 2332 __ movsd(Address(ESP, 0), XMM1); |
| 2522 __ fldl(Address(ESP, 0)); | 2333 __ fldl(Address(ESP, 0)); |
| 2523 __ popl(EAX); | 2334 __ popl(EAX); |
| 2524 __ popl(EAX); | 2335 __ popl(EAX); |
| 2525 __ ret(); | 2336 __ ret(); |
| 2526 } | 2337 } |
| 2527 | 2338 |
| 2528 | |
| 2529 ASSEMBLER_TEST_RUN(SquareRootDouble, test) { | 2339 ASSEMBLER_TEST_RUN(SquareRootDouble, test) { |
| 2530 typedef double (*SquareRootDoubleCode)(double d); | 2340 typedef double (*SquareRootDoubleCode)(double d); |
| 2531 const double kDoubleConst = .7; | 2341 const double kDoubleConst = .7; |
| 2532 double res = | 2342 double res = |
| 2533 reinterpret_cast<SquareRootDoubleCode>(test->entry())(kDoubleConst); | 2343 reinterpret_cast<SquareRootDoubleCode>(test->entry())(kDoubleConst); |
| 2534 EXPECT_FLOAT_EQ(sqrt(kDoubleConst), res, 0.0001); | 2344 EXPECT_FLOAT_EQ(sqrt(kDoubleConst), res, 0.0001); |
| 2535 } | 2345 } |
| 2536 | 2346 |
| 2537 | |
| 2538 ASSEMBLER_TEST_GENERATE(FloatNegate, assembler) { | 2347 ASSEMBLER_TEST_GENERATE(FloatNegate, assembler) { |
| 2539 __ movss(XMM0, Address(ESP, kWordSize)); | 2348 __ movss(XMM0, Address(ESP, kWordSize)); |
| 2540 __ FloatNegate(XMM0); | 2349 __ FloatNegate(XMM0); |
| 2541 __ pushl(EAX); | 2350 __ pushl(EAX); |
| 2542 __ movss(Address(ESP, 0), XMM0); | 2351 __ movss(Address(ESP, 0), XMM0); |
| 2543 __ flds(Address(ESP, 0)); | 2352 __ flds(Address(ESP, 0)); |
| 2544 __ popl(EAX); | 2353 __ popl(EAX); |
| 2545 __ ret(); | 2354 __ ret(); |
| 2546 } | 2355 } |
| 2547 | 2356 |
| 2548 | |
| 2549 ASSEMBLER_TEST_RUN(FloatNegate, test) { | 2357 ASSEMBLER_TEST_RUN(FloatNegate, test) { |
| 2550 typedef float (*FloatNegateCode)(float f); | 2358 typedef float (*FloatNegateCode)(float f); |
| 2551 const float kFloatConst = 12.345; | 2359 const float kFloatConst = 12.345; |
| 2552 float res = reinterpret_cast<FloatNegateCode>(test->entry())(kFloatConst); | 2360 float res = reinterpret_cast<FloatNegateCode>(test->entry())(kFloatConst); |
| 2553 EXPECT_FLOAT_EQ(-kFloatConst, res, 0.0001); | 2361 EXPECT_FLOAT_EQ(-kFloatConst, res, 0.0001); |
| 2554 } | 2362 } |
| 2555 | 2363 |
| 2556 | |
| 2557 ASSEMBLER_TEST_GENERATE(DoubleNegate, assembler) { | 2364 ASSEMBLER_TEST_GENERATE(DoubleNegate, assembler) { |
| 2558 __ movsd(XMM0, Address(ESP, kWordSize)); | 2365 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2559 __ DoubleNegate(XMM0); | 2366 __ DoubleNegate(XMM0); |
| 2560 __ pushl(EAX); | 2367 __ pushl(EAX); |
| 2561 __ pushl(EAX); | 2368 __ pushl(EAX); |
| 2562 __ movsd(Address(ESP, 0), XMM0); | 2369 __ movsd(Address(ESP, 0), XMM0); |
| 2563 __ fldl(Address(ESP, 0)); | 2370 __ fldl(Address(ESP, 0)); |
| 2564 __ popl(EAX); | 2371 __ popl(EAX); |
| 2565 __ popl(EAX); | 2372 __ popl(EAX); |
| 2566 __ ret(); | 2373 __ ret(); |
| 2567 } | 2374 } |
| 2568 | 2375 |
| 2569 | |
| 2570 ASSEMBLER_TEST_RUN(DoubleNegate, test) { | 2376 ASSEMBLER_TEST_RUN(DoubleNegate, test) { |
| 2571 typedef double (*DoubleNegateCode)(double f); | 2377 typedef double (*DoubleNegateCode)(double f); |
| 2572 const double kDoubleConst = 12.345; | 2378 const double kDoubleConst = 12.345; |
| 2573 double res = reinterpret_cast<DoubleNegateCode>(test->entry())(kDoubleConst); | 2379 double res = reinterpret_cast<DoubleNegateCode>(test->entry())(kDoubleConst); |
| 2574 EXPECT_FLOAT_EQ(-kDoubleConst, res, 0.0001); | 2380 EXPECT_FLOAT_EQ(-kDoubleConst, res, 0.0001); |
| 2575 } | 2381 } |
| 2576 | 2382 |
| 2577 | |
| 2578 ASSEMBLER_TEST_GENERATE(LongMulReg, assembler) { | 2383 ASSEMBLER_TEST_GENERATE(LongMulReg, assembler) { |
| 2579 __ movl(ECX, Address(ESP, kWordSize)); | 2384 __ movl(ECX, Address(ESP, kWordSize)); |
| 2580 __ movl(EAX, Address(ESP, 2 * kWordSize)); | 2385 __ movl(EAX, Address(ESP, 2 * kWordSize)); |
| 2581 __ imull(ECX); | 2386 __ imull(ECX); |
| 2582 __ ret(); | 2387 __ ret(); |
| 2583 } | 2388 } |
| 2584 | 2389 |
| 2585 | |
| 2586 ASSEMBLER_TEST_RUN(LongMulReg, test) { | 2390 ASSEMBLER_TEST_RUN(LongMulReg, test) { |
| 2587 typedef int64_t (*LongMulRegCode)(int a, int b); | 2391 typedef int64_t (*LongMulRegCode)(int a, int b); |
| 2588 const int a = -12; | 2392 const int a = -12; |
| 2589 const int b = 13; | 2393 const int b = 13; |
| 2590 const int64_t mul_res = a * b; | 2394 const int64_t mul_res = a * b; |
| 2591 int64_t res = reinterpret_cast<LongMulRegCode>(test->entry())(a, b); | 2395 int64_t res = reinterpret_cast<LongMulRegCode>(test->entry())(a, b); |
| 2592 EXPECT_EQ(mul_res, res); | 2396 EXPECT_EQ(mul_res, res); |
| 2593 } | 2397 } |
| 2594 | 2398 |
| 2595 | |
| 2596 ASSEMBLER_TEST_GENERATE(LongMulAddress, assembler) { | 2399 ASSEMBLER_TEST_GENERATE(LongMulAddress, assembler) { |
| 2597 __ movl(EAX, Address(ESP, 2 * kWordSize)); | 2400 __ movl(EAX, Address(ESP, 2 * kWordSize)); |
| 2598 __ imull(Address(ESP, kWordSize)); | 2401 __ imull(Address(ESP, kWordSize)); |
| 2599 __ ret(); | 2402 __ ret(); |
| 2600 } | 2403 } |
| 2601 | 2404 |
| 2602 | |
| 2603 ASSEMBLER_TEST_RUN(LongMulAddress, test) { | 2405 ASSEMBLER_TEST_RUN(LongMulAddress, test) { |
| 2604 typedef int64_t (*LongMulAddressCode)(int a, int b); | 2406 typedef int64_t (*LongMulAddressCode)(int a, int b); |
| 2605 const int a = -12; | 2407 const int a = -12; |
| 2606 const int b = 13; | 2408 const int b = 13; |
| 2607 const int64_t mul_res = a * b; | 2409 const int64_t mul_res = a * b; |
| 2608 int64_t res = reinterpret_cast<LongMulAddressCode>(test->entry())(a, b); | 2410 int64_t res = reinterpret_cast<LongMulAddressCode>(test->entry())(a, b); |
| 2609 EXPECT_EQ(mul_res, res); | 2411 EXPECT_EQ(mul_res, res); |
| 2610 } | 2412 } |
| 2611 | 2413 |
| 2612 | |
| 2613 ASSEMBLER_TEST_GENERATE(LongUnsignedMulReg, assembler) { | 2414 ASSEMBLER_TEST_GENERATE(LongUnsignedMulReg, assembler) { |
| 2614 __ movl(ECX, Address(ESP, kWordSize)); | 2415 __ movl(ECX, Address(ESP, kWordSize)); |
| 2615 __ movl(EAX, Address(ESP, 2 * kWordSize)); | 2416 __ movl(EAX, Address(ESP, 2 * kWordSize)); |
| 2616 __ mull(ECX); | 2417 __ mull(ECX); |
| 2617 __ ret(); | 2418 __ ret(); |
| 2618 } | 2419 } |
| 2619 | 2420 |
| 2620 | |
| 2621 ASSEMBLER_TEST_RUN(LongUnsignedMulReg, test) { | 2421 ASSEMBLER_TEST_RUN(LongUnsignedMulReg, test) { |
| 2622 typedef uint64_t (*LongUnsignedMulRegCode)(uint32_t a, uint32_t b); | 2422 typedef uint64_t (*LongUnsignedMulRegCode)(uint32_t a, uint32_t b); |
| 2623 uint32_t a = 3; | 2423 uint32_t a = 3; |
| 2624 uint32_t b = 13; | 2424 uint32_t b = 13; |
| 2625 uint64_t mul_res = a * b; | 2425 uint64_t mul_res = a * b; |
| 2626 uint64_t res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); | 2426 uint64_t res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); |
| 2627 EXPECT_EQ(mul_res, res); | 2427 EXPECT_EQ(mul_res, res); |
| 2628 a = 4021288948u; | 2428 a = 4021288948u; |
| 2629 b = 13; | 2429 b = 13; |
| 2630 res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); | 2430 res = reinterpret_cast<LongUnsignedMulRegCode>(test->entry())(a, b); |
| 2631 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); | 2431 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); |
| 2632 EXPECT_EQ(mul_res, res); | 2432 EXPECT_EQ(mul_res, res); |
| 2633 } | 2433 } |
| 2634 | 2434 |
| 2635 | |
| 2636 ASSEMBLER_TEST_GENERATE(LongUnsignedMulAddress, assembler) { | 2435 ASSEMBLER_TEST_GENERATE(LongUnsignedMulAddress, assembler) { |
| 2637 __ movl(EAX, Address(ESP, 2 * kWordSize)); | 2436 __ movl(EAX, Address(ESP, 2 * kWordSize)); |
| 2638 __ mull(Address(ESP, kWordSize)); | 2437 __ mull(Address(ESP, kWordSize)); |
| 2639 __ ret(); | 2438 __ ret(); |
| 2640 } | 2439 } |
| 2641 | 2440 |
| 2642 | |
| 2643 ASSEMBLER_TEST_RUN(LongUnsignedMulAddress, test) { | 2441 ASSEMBLER_TEST_RUN(LongUnsignedMulAddress, test) { |
| 2644 typedef uint64_t (*LongUnsignedMulAddressCode)(uint32_t a, uint32_t b); | 2442 typedef uint64_t (*LongUnsignedMulAddressCode)(uint32_t a, uint32_t b); |
| 2645 uint32_t a = 12; | 2443 uint32_t a = 12; |
| 2646 uint32_t b = 13; | 2444 uint32_t b = 13; |
| 2647 uint64_t mul_res = a * b; | 2445 uint64_t mul_res = a * b; |
| 2648 uint64_t res = | 2446 uint64_t res = |
| 2649 reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); | 2447 reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); |
| 2650 EXPECT_EQ(mul_res, res); | 2448 EXPECT_EQ(mul_res, res); |
| 2651 a = 4294967284u; | 2449 a = 4294967284u; |
| 2652 b = 13; | 2450 b = 13; |
| 2653 res = reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); | 2451 res = reinterpret_cast<LongUnsignedMulAddressCode>(test->entry())(a, b); |
| 2654 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); | 2452 mul_res = static_cast<uint64_t>(a) * static_cast<uint64_t>(b); |
| 2655 EXPECT_EQ(mul_res, res); | 2453 EXPECT_EQ(mul_res, res); |
| 2656 } | 2454 } |
| 2657 | 2455 |
| 2658 | |
| 2659 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) { | 2456 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) { |
| 2660 // Preserve clobbered callee-saved register (EBX). | 2457 // Preserve clobbered callee-saved register (EBX). |
| 2661 __ pushl(EBX); | 2458 __ pushl(EBX); |
| 2662 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. | 2459 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. |
| 2663 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. | 2460 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. |
| 2664 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. | 2461 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. |
| 2665 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high | 2462 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high |
| 2666 __ addl(EAX, ECX); | 2463 __ addl(EAX, ECX); |
| 2667 __ adcl(EDX, EBX); | 2464 __ adcl(EDX, EBX); |
| 2668 __ popl(EBX); | 2465 __ popl(EBX); |
| 2669 // Result is in EAX/EDX. | 2466 // Result is in EAX/EDX. |
| 2670 __ ret(); | 2467 __ ret(); |
| 2671 } | 2468 } |
| 2672 | 2469 |
| 2673 | |
| 2674 ASSEMBLER_TEST_RUN(LongAddReg, test) { | 2470 ASSEMBLER_TEST_RUN(LongAddReg, test) { |
| 2675 typedef int64_t (*LongAddRegCode)(int64_t a, int64_t b); | 2471 typedef int64_t (*LongAddRegCode)(int64_t a, int64_t b); |
| 2676 int64_t a = 12; | 2472 int64_t a = 12; |
| 2677 int64_t b = 14; | 2473 int64_t b = 14; |
| 2678 int64_t res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); | 2474 int64_t res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
| 2679 EXPECT_EQ((a + b), res); | 2475 EXPECT_EQ((a + b), res); |
| 2680 a = 2147483647; | 2476 a = 2147483647; |
| 2681 b = 600000; | 2477 b = 600000; |
| 2682 res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); | 2478 res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
| 2683 EXPECT_EQ((a + b), res); | 2479 EXPECT_EQ((a + b), res); |
| 2684 } | 2480 } |
| 2685 | 2481 |
| 2686 | |
| 2687 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { | 2482 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { |
| 2688 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. | 2483 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. |
| 2689 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. | 2484 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. |
| 2690 __ addl(EAX, Address(ESP, 3 * kWordSize)); // low. | 2485 __ addl(EAX, Address(ESP, 3 * kWordSize)); // low. |
| 2691 __ adcl(EDX, Address(ESP, 4 * kWordSize)); // high. | 2486 __ adcl(EDX, Address(ESP, 4 * kWordSize)); // high. |
| 2692 // Result is in EAX/EDX. | 2487 // Result is in EAX/EDX. |
| 2693 __ ret(); | 2488 __ ret(); |
| 2694 } | 2489 } |
| 2695 | 2490 |
| 2696 | |
| 2697 ASSEMBLER_TEST_RUN(LongAddAddress, test) { | 2491 ASSEMBLER_TEST_RUN(LongAddAddress, test) { |
| 2698 typedef int64_t (*LongAddAddressCode)(int64_t a, int64_t b); | 2492 typedef int64_t (*LongAddAddressCode)(int64_t a, int64_t b); |
| 2699 int64_t a = 12; | 2493 int64_t a = 12; |
| 2700 int64_t b = 14; | 2494 int64_t b = 14; |
| 2701 int64_t res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); | 2495 int64_t res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); |
| 2702 EXPECT_EQ((a + b), res); | 2496 EXPECT_EQ((a + b), res); |
| 2703 a = 2147483647; | 2497 a = 2147483647; |
| 2704 b = 600000; | 2498 b = 600000; |
| 2705 res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); | 2499 res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); |
| 2706 EXPECT_EQ((a + b), res); | 2500 EXPECT_EQ((a + b), res); |
| 2707 } | 2501 } |
| 2708 | 2502 |
| 2709 | |
| 2710 ASSEMBLER_TEST_GENERATE(LongSubReg, assembler) { | 2503 ASSEMBLER_TEST_GENERATE(LongSubReg, assembler) { |
| 2711 // Preserve clobbered callee-saved register (EBX). | 2504 // Preserve clobbered callee-saved register (EBX). |
| 2712 __ pushl(EBX); | 2505 __ pushl(EBX); |
| 2713 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. | 2506 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. |
| 2714 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. | 2507 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. |
| 2715 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. | 2508 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. |
| 2716 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high | 2509 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high |
| 2717 __ subl(EAX, ECX); | 2510 __ subl(EAX, ECX); |
| 2718 __ sbbl(EDX, EBX); | 2511 __ sbbl(EDX, EBX); |
| 2719 __ popl(EBX); | 2512 __ popl(EBX); |
| 2720 // Result is in EAX/EDX. | 2513 // Result is in EAX/EDX. |
| 2721 __ ret(); | 2514 __ ret(); |
| 2722 } | 2515 } |
| 2723 | 2516 |
| 2724 | |
| 2725 ASSEMBLER_TEST_RUN(LongSubReg, test) { | 2517 ASSEMBLER_TEST_RUN(LongSubReg, test) { |
| 2726 typedef int64_t (*LongSubRegCode)(int64_t a, int64_t b); | 2518 typedef int64_t (*LongSubRegCode)(int64_t a, int64_t b); |
| 2727 int64_t a = 12; | 2519 int64_t a = 12; |
| 2728 int64_t b = 14; | 2520 int64_t b = 14; |
| 2729 int64_t res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); | 2521 int64_t res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
| 2730 EXPECT_EQ((a - b), res); | 2522 EXPECT_EQ((a - b), res); |
| 2731 a = 600000; | 2523 a = 600000; |
| 2732 b = 2147483647; | 2524 b = 2147483647; |
| 2733 res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); | 2525 res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
| 2734 EXPECT_EQ((a - b), res); | 2526 EXPECT_EQ((a - b), res); |
| 2735 } | 2527 } |
| 2736 | 2528 |
| 2737 | |
| 2738 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { | 2529 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { |
| 2739 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. | 2530 __ movl(EAX, Address(ESP, 1 * kWordSize)); // left low. |
| 2740 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. | 2531 __ movl(EDX, Address(ESP, 2 * kWordSize)); // left high. |
| 2741 __ subl(EAX, Address(ESP, 3 * kWordSize)); // low. | 2532 __ subl(EAX, Address(ESP, 3 * kWordSize)); // low. |
| 2742 __ sbbl(EDX, Address(ESP, 4 * kWordSize)); // high. | 2533 __ sbbl(EDX, Address(ESP, 4 * kWordSize)); // high. |
| 2743 // Result is in EAX/EDX. | 2534 // Result is in EAX/EDX. |
| 2744 __ ret(); | 2535 __ ret(); |
| 2745 } | 2536 } |
| 2746 | 2537 |
| 2747 | |
| 2748 ASSEMBLER_TEST_RUN(LongSubAddress, test) { | 2538 ASSEMBLER_TEST_RUN(LongSubAddress, test) { |
| 2749 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); | 2539 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); |
| 2750 int64_t a = 12; | 2540 int64_t a = 12; |
| 2751 int64_t b = 14; | 2541 int64_t b = 14; |
| 2752 int64_t res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); | 2542 int64_t res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
| 2753 EXPECT_EQ((a - b), res); | 2543 EXPECT_EQ((a - b), res); |
| 2754 a = 600000; | 2544 a = 600000; |
| 2755 b = 2147483647; | 2545 b = 2147483647; |
| 2756 res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); | 2546 res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
| 2757 EXPECT_EQ((a - b), res); | 2547 EXPECT_EQ((a - b), res); |
| 2758 } | 2548 } |
| 2759 | 2549 |
| 2760 | |
| 2761 ASSEMBLER_TEST_GENERATE(LongSubAddress2, assembler) { | 2550 ASSEMBLER_TEST_GENERATE(LongSubAddress2, assembler) { |
| 2762 // Preserve clobbered callee-saved register (EBX). | 2551 // Preserve clobbered callee-saved register (EBX). |
| 2763 __ pushl(EBX); | 2552 __ pushl(EBX); |
| 2764 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. | 2553 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. |
| 2765 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. | 2554 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. |
| 2766 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. | 2555 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. |
| 2767 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high | 2556 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high |
| 2768 __ subl(ESP, Immediate(2 * kWordSize)); | 2557 __ subl(ESP, Immediate(2 * kWordSize)); |
| 2769 __ movl(Address(ESP, 0 * kWordSize), EAX); // left low. | 2558 __ movl(Address(ESP, 0 * kWordSize), EAX); // left low. |
| 2770 __ movl(Address(ESP, 1 * kWordSize), EDX); // left high. | 2559 __ movl(Address(ESP, 1 * kWordSize), EDX); // left high. |
| 2771 __ subl(Address(ESP, 0 * kWordSize), ECX); | 2560 __ subl(Address(ESP, 0 * kWordSize), ECX); |
| 2772 __ sbbl(Address(ESP, 1 * kWordSize), EBX); | 2561 __ sbbl(Address(ESP, 1 * kWordSize), EBX); |
| 2773 __ movl(EAX, Address(ESP, 0 * kWordSize)); | 2562 __ movl(EAX, Address(ESP, 0 * kWordSize)); |
| 2774 __ movl(EDX, Address(ESP, 1 * kWordSize)); | 2563 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 2775 __ addl(ESP, Immediate(2 * kWordSize)); | 2564 __ addl(ESP, Immediate(2 * kWordSize)); |
| 2776 __ popl(EBX); | 2565 __ popl(EBX); |
| 2777 // Result is in EAX/EDX. | 2566 // Result is in EAX/EDX. |
| 2778 __ ret(); | 2567 __ ret(); |
| 2779 } | 2568 } |
| 2780 | 2569 |
| 2781 | |
| 2782 ASSEMBLER_TEST_RUN(LongSubAddress2, test) { | 2570 ASSEMBLER_TEST_RUN(LongSubAddress2, test) { |
| 2783 typedef int64_t (*LongSubAddress2Code)(int64_t a, int64_t b); | 2571 typedef int64_t (*LongSubAddress2Code)(int64_t a, int64_t b); |
| 2784 int64_t a = 12; | 2572 int64_t a = 12; |
| 2785 int64_t b = 14; | 2573 int64_t b = 14; |
| 2786 int64_t res = reinterpret_cast<LongSubAddress2Code>(test->entry())(a, b); | 2574 int64_t res = reinterpret_cast<LongSubAddress2Code>(test->entry())(a, b); |
| 2787 EXPECT_EQ((a - b), res); | 2575 EXPECT_EQ((a - b), res); |
| 2788 a = 600000; | 2576 a = 600000; |
| 2789 b = 2147483647; | 2577 b = 2147483647; |
| 2790 res = reinterpret_cast<LongSubAddress2Code>(test->entry())(a, b); | 2578 res = reinterpret_cast<LongSubAddress2Code>(test->entry())(a, b); |
| 2791 EXPECT_EQ((a - b), res); | 2579 EXPECT_EQ((a - b), res); |
| 2792 } | 2580 } |
| 2793 | 2581 |
| 2794 | |
| 2795 ASSEMBLER_TEST_GENERATE(LongAddAddress2, assembler) { | 2582 ASSEMBLER_TEST_GENERATE(LongAddAddress2, assembler) { |
| 2796 // Preserve clobbered callee-saved register (EBX). | 2583 // Preserve clobbered callee-saved register (EBX). |
| 2797 __ pushl(EBX); | 2584 __ pushl(EBX); |
| 2798 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. | 2585 __ movl(EAX, Address(ESP, 2 * kWordSize)); // left low. |
| 2799 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. | 2586 __ movl(EDX, Address(ESP, 3 * kWordSize)); // left high. |
| 2800 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. | 2587 __ movl(ECX, Address(ESP, 4 * kWordSize)); // right low. |
| 2801 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high | 2588 __ movl(EBX, Address(ESP, 5 * kWordSize)); // right high |
| 2802 __ subl(ESP, Immediate(2 * kWordSize)); | 2589 __ subl(ESP, Immediate(2 * kWordSize)); |
| 2803 __ movl(Address(ESP, 0 * kWordSize), EAX); // left low. | 2590 __ movl(Address(ESP, 0 * kWordSize), EAX); // left low. |
| 2804 __ movl(Address(ESP, 1 * kWordSize), EDX); // left high. | 2591 __ movl(Address(ESP, 1 * kWordSize), EDX); // left high. |
| 2805 __ addl(Address(ESP, 0 * kWordSize), ECX); | 2592 __ addl(Address(ESP, 0 * kWordSize), ECX); |
| 2806 __ adcl(Address(ESP, 1 * kWordSize), EBX); | 2593 __ adcl(Address(ESP, 1 * kWordSize), EBX); |
| 2807 __ movl(EAX, Address(ESP, 0 * kWordSize)); | 2594 __ movl(EAX, Address(ESP, 0 * kWordSize)); |
| 2808 __ movl(EDX, Address(ESP, 1 * kWordSize)); | 2595 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 2809 __ addl(ESP, Immediate(2 * kWordSize)); | 2596 __ addl(ESP, Immediate(2 * kWordSize)); |
| 2810 __ popl(EBX); | 2597 __ popl(EBX); |
| 2811 // Result is in EAX/EDX. | 2598 // Result is in EAX/EDX. |
| 2812 __ ret(); | 2599 __ ret(); |
| 2813 } | 2600 } |
| 2814 | 2601 |
| 2815 | |
| 2816 ASSEMBLER_TEST_RUN(LongAddAddress2, test) { | 2602 ASSEMBLER_TEST_RUN(LongAddAddress2, test) { |
| 2817 typedef int64_t (*LongAddAddress2Code)(int64_t a, int64_t b); | 2603 typedef int64_t (*LongAddAddress2Code)(int64_t a, int64_t b); |
| 2818 int64_t a = 12; | 2604 int64_t a = 12; |
| 2819 int64_t b = 14; | 2605 int64_t b = 14; |
| 2820 int64_t res = reinterpret_cast<LongAddAddress2Code>(test->entry())(a, b); | 2606 int64_t res = reinterpret_cast<LongAddAddress2Code>(test->entry())(a, b); |
| 2821 EXPECT_EQ((a + b), res); | 2607 EXPECT_EQ((a + b), res); |
| 2822 a = 600000; | 2608 a = 600000; |
| 2823 b = 2147483647; | 2609 b = 2147483647; |
| 2824 res = reinterpret_cast<LongAddAddress2Code>(test->entry())(a, b); | 2610 res = reinterpret_cast<LongAddAddress2Code>(test->entry())(a, b); |
| 2825 EXPECT_EQ((a + b), res); | 2611 EXPECT_EQ((a + b), res); |
| 2826 } | 2612 } |
| 2827 | 2613 |
| 2828 | |
| 2829 // Testing only the lower 64-bit value of 'cvtdq2pd'. | 2614 // Testing only the lower 64-bit value of 'cvtdq2pd'. |
| 2830 ASSEMBLER_TEST_GENERATE(IntegerToDoubleConversion, assembler) { | 2615 ASSEMBLER_TEST_GENERATE(IntegerToDoubleConversion, assembler) { |
| 2831 __ movsd(XMM1, Address(ESP, kWordSize)); | 2616 __ movsd(XMM1, Address(ESP, kWordSize)); |
| 2832 __ cvtdq2pd(XMM2, XMM1); | 2617 __ cvtdq2pd(XMM2, XMM1); |
| 2833 __ pushl(EAX); | 2618 __ pushl(EAX); |
| 2834 __ pushl(EAX); | 2619 __ pushl(EAX); |
| 2835 __ movsd(Address(ESP, 0), XMM2); | 2620 __ movsd(Address(ESP, 0), XMM2); |
| 2836 __ fldl(Address(ESP, 0)); | 2621 __ fldl(Address(ESP, 0)); |
| 2837 __ popl(EAX); | 2622 __ popl(EAX); |
| 2838 __ popl(EAX); | 2623 __ popl(EAX); |
| 2839 __ ret(); | 2624 __ ret(); |
| 2840 } | 2625 } |
| 2841 | 2626 |
| 2842 | |
| 2843 ASSEMBLER_TEST_RUN(IntegerToDoubleConversion, test) { | 2627 ASSEMBLER_TEST_RUN(IntegerToDoubleConversion, test) { |
| 2844 typedef double (*IntegerToDoubleConversionCode)(int32_t); | 2628 typedef double (*IntegerToDoubleConversionCode)(int32_t); |
| 2845 const int32_t val = -12; | 2629 const int32_t val = -12; |
| 2846 double res = | 2630 double res = |
| 2847 reinterpret_cast<IntegerToDoubleConversionCode>(test->entry())(val); | 2631 reinterpret_cast<IntegerToDoubleConversionCode>(test->entry())(val); |
| 2848 EXPECT_FLOAT_EQ(static_cast<double>(val), res, 0.001); | 2632 EXPECT_FLOAT_EQ(static_cast<double>(val), res, 0.001); |
| 2849 } | 2633 } |
| 2850 | 2634 |
| 2851 | |
| 2852 // Implement with truncation. | 2635 // Implement with truncation. |
| 2853 ASSEMBLER_TEST_GENERATE(FPUStoreLong, assembler) { | 2636 ASSEMBLER_TEST_GENERATE(FPUStoreLong, assembler) { |
| 2854 __ fldl(Address(ESP, kWordSize)); | 2637 __ fldl(Address(ESP, kWordSize)); |
| 2855 __ pushl(EAX); | 2638 __ pushl(EAX); |
| 2856 __ pushl(EAX); | 2639 __ pushl(EAX); |
| 2857 __ fnstcw(Address(ESP, 0)); | 2640 __ fnstcw(Address(ESP, 0)); |
| 2858 __ movzxw(EAX, Address(ESP, 0)); | 2641 __ movzxw(EAX, Address(ESP, 0)); |
| 2859 __ orl(EAX, Immediate(0x0c00)); | 2642 __ orl(EAX, Immediate(0x0c00)); |
| 2860 __ movw(Address(ESP, kWordSize), EAX); | 2643 __ movw(Address(ESP, kWordSize), EAX); |
| 2861 __ fldcw(Address(ESP, kWordSize)); | 2644 __ fldcw(Address(ESP, kWordSize)); |
| 2862 __ pushl(EAX); | 2645 __ pushl(EAX); |
| 2863 __ pushl(EAX); | 2646 __ pushl(EAX); |
| 2864 __ fistpl(Address(ESP, 0)); | 2647 __ fistpl(Address(ESP, 0)); |
| 2865 __ popl(EAX); | 2648 __ popl(EAX); |
| 2866 __ popl(EDX); | 2649 __ popl(EDX); |
| 2867 __ fldcw(Address(ESP, 0)); | 2650 __ fldcw(Address(ESP, 0)); |
| 2868 __ addl(ESP, Immediate(kWordSize * 2)); | 2651 __ addl(ESP, Immediate(kWordSize * 2)); |
| 2869 __ ret(); | 2652 __ ret(); |
| 2870 } | 2653 } |
| 2871 | 2654 |
| 2872 | |
| 2873 ASSEMBLER_TEST_RUN(FPUStoreLong, test) { | 2655 ASSEMBLER_TEST_RUN(FPUStoreLong, test) { |
| 2874 typedef int64_t (*FPUStoreLongCode)(double d); | 2656 typedef int64_t (*FPUStoreLongCode)(double d); |
| 2875 double val = 12.2; | 2657 double val = 12.2; |
| 2876 int64_t res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); | 2658 int64_t res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); |
| 2877 EXPECT_EQ(static_cast<int64_t>(val), res); | 2659 EXPECT_EQ(static_cast<int64_t>(val), res); |
| 2878 val = -12.2; | 2660 val = -12.2; |
| 2879 res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); | 2661 res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); |
| 2880 EXPECT_EQ(static_cast<int64_t>(val), res); | 2662 EXPECT_EQ(static_cast<int64_t>(val), res); |
| 2881 val = 12.8; | 2663 val = 12.8; |
| 2882 res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); | 2664 res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); |
| 2883 EXPECT_EQ(static_cast<int64_t>(val), res); | 2665 EXPECT_EQ(static_cast<int64_t>(val), res); |
| 2884 val = -12.8; | 2666 val = -12.8; |
| 2885 res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); | 2667 res = reinterpret_cast<FPUStoreLongCode>(test->entry())(val); |
| 2886 EXPECT_EQ(static_cast<int64_t>(val), res); | 2668 EXPECT_EQ(static_cast<int64_t>(val), res); |
| 2887 } | 2669 } |
| 2888 | 2670 |
| 2889 | |
| 2890 ASSEMBLER_TEST_GENERATE(XorpdZeroing, assembler) { | 2671 ASSEMBLER_TEST_GENERATE(XorpdZeroing, assembler) { |
| 2891 __ movsd(XMM0, Address(ESP, kWordSize)); | 2672 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2892 __ xorpd(XMM0, XMM0); | 2673 __ xorpd(XMM0, XMM0); |
| 2893 __ pushl(EAX); | 2674 __ pushl(EAX); |
| 2894 __ pushl(EAX); | 2675 __ pushl(EAX); |
| 2895 __ movsd(Address(ESP, 0), XMM0); | 2676 __ movsd(Address(ESP, 0), XMM0); |
| 2896 __ fldl(Address(ESP, 0)); | 2677 __ fldl(Address(ESP, 0)); |
| 2897 __ popl(EAX); | 2678 __ popl(EAX); |
| 2898 __ popl(EAX); | 2679 __ popl(EAX); |
| 2899 __ ret(); | 2680 __ ret(); |
| 2900 } | 2681 } |
| 2901 | 2682 |
| 2902 | |
| 2903 ASSEMBLER_TEST_RUN(XorpdZeroing, test) { | 2683 ASSEMBLER_TEST_RUN(XorpdZeroing, test) { |
| 2904 typedef double (*XorpdZeroingCode)(double d); | 2684 typedef double (*XorpdZeroingCode)(double d); |
| 2905 double res = reinterpret_cast<XorpdZeroingCode>(test->entry())(12.56e3); | 2685 double res = reinterpret_cast<XorpdZeroingCode>(test->entry())(12.56e3); |
| 2906 EXPECT_FLOAT_EQ(0.0, res, 0.0001); | 2686 EXPECT_FLOAT_EQ(0.0, res, 0.0001); |
| 2907 } | 2687 } |
| 2908 | 2688 |
| 2909 | |
| 2910 ASSEMBLER_TEST_GENERATE(Pxor, assembler) { | 2689 ASSEMBLER_TEST_GENERATE(Pxor, assembler) { |
| 2911 __ movsd(XMM0, Address(ESP, kWordSize)); | 2690 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2912 __ pxor(XMM0, XMM0); | 2691 __ pxor(XMM0, XMM0); |
| 2913 __ pushl(EAX); | 2692 __ pushl(EAX); |
| 2914 __ pushl(EAX); | 2693 __ pushl(EAX); |
| 2915 __ movsd(Address(ESP, 0), XMM0); | 2694 __ movsd(Address(ESP, 0), XMM0); |
| 2916 __ fldl(Address(ESP, 0)); | 2695 __ fldl(Address(ESP, 0)); |
| 2917 __ popl(EAX); | 2696 __ popl(EAX); |
| 2918 __ popl(EAX); | 2697 __ popl(EAX); |
| 2919 __ ret(); | 2698 __ ret(); |
| 2920 } | 2699 } |
| 2921 | 2700 |
| 2922 | |
| 2923 ASSEMBLER_TEST_RUN(Pxor, test) { | 2701 ASSEMBLER_TEST_RUN(Pxor, test) { |
| 2924 typedef double (*PxorCode)(double d); | 2702 typedef double (*PxorCode)(double d); |
| 2925 double res = reinterpret_cast<PxorCode>(test->entry())(12.3456e3); | 2703 double res = reinterpret_cast<PxorCode>(test->entry())(12.3456e3); |
| 2926 EXPECT_FLOAT_EQ(0.0, res, 0.0); | 2704 EXPECT_FLOAT_EQ(0.0, res, 0.0); |
| 2927 } | 2705 } |
| 2928 | 2706 |
| 2929 | |
| 2930 ASSEMBLER_TEST_GENERATE(Orpd, assembler) { | 2707 ASSEMBLER_TEST_GENERATE(Orpd, assembler) { |
| 2931 __ movsd(XMM0, Address(ESP, kWordSize)); | 2708 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2932 __ xorpd(XMM1, XMM1); | 2709 __ xorpd(XMM1, XMM1); |
| 2933 __ DoubleNegate(XMM1); | 2710 __ DoubleNegate(XMM1); |
| 2934 __ orpd(XMM0, XMM1); | 2711 __ orpd(XMM0, XMM1); |
| 2935 __ pushl(EAX); | 2712 __ pushl(EAX); |
| 2936 __ pushl(EAX); | 2713 __ pushl(EAX); |
| 2937 __ movsd(Address(ESP, 0), XMM0); | 2714 __ movsd(Address(ESP, 0), XMM0); |
| 2938 __ fldl(Address(ESP, 0)); | 2715 __ fldl(Address(ESP, 0)); |
| 2939 __ popl(EAX); | 2716 __ popl(EAX); |
| 2940 __ popl(EAX); | 2717 __ popl(EAX); |
| 2941 __ ret(); | 2718 __ ret(); |
| 2942 } | 2719 } |
| 2943 | 2720 |
| 2944 | |
| 2945 ASSEMBLER_TEST_RUN(Orpd, test) { | 2721 ASSEMBLER_TEST_RUN(Orpd, test) { |
| 2946 typedef double (*OrpdCode)(double d); | 2722 typedef double (*OrpdCode)(double d); |
| 2947 double res = reinterpret_cast<OrpdCode>(test->entry())(12.56e3); | 2723 double res = reinterpret_cast<OrpdCode>(test->entry())(12.56e3); |
| 2948 EXPECT_FLOAT_EQ(-12.56e3, res, 0.0); | 2724 EXPECT_FLOAT_EQ(-12.56e3, res, 0.0); |
| 2949 } | 2725 } |
| 2950 | 2726 |
| 2951 | |
| 2952 ASSEMBLER_TEST_GENERATE(Pextrd0, assembler) { | 2727 ASSEMBLER_TEST_GENERATE(Pextrd0, assembler) { |
| 2953 if (TargetCPUFeatures::sse4_1_supported()) { | 2728 if (TargetCPUFeatures::sse4_1_supported()) { |
| 2954 __ movsd(XMM0, Address(ESP, kWordSize)); | 2729 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2955 __ pextrd(EAX, XMM0, Immediate(0)); | 2730 __ pextrd(EAX, XMM0, Immediate(0)); |
| 2956 } | 2731 } |
| 2957 __ ret(); | 2732 __ ret(); |
| 2958 } | 2733 } |
| 2959 | 2734 |
| 2960 | |
| 2961 ASSEMBLER_TEST_RUN(Pextrd0, test) { | 2735 ASSEMBLER_TEST_RUN(Pextrd0, test) { |
| 2962 if (TargetCPUFeatures::sse4_1_supported()) { | 2736 if (TargetCPUFeatures::sse4_1_supported()) { |
| 2963 typedef int32_t (*PextrdCode0)(double d); | 2737 typedef int32_t (*PextrdCode0)(double d); |
| 2964 int32_t res = reinterpret_cast<PextrdCode0>(test->entry())(123456789); | 2738 int32_t res = reinterpret_cast<PextrdCode0>(test->entry())(123456789); |
| 2965 EXPECT_EQ(0x54000000, res); | 2739 EXPECT_EQ(0x54000000, res); |
| 2966 } | 2740 } |
| 2967 } | 2741 } |
| 2968 | 2742 |
| 2969 | |
| 2970 ASSEMBLER_TEST_GENERATE(Pextrd1, assembler) { | 2743 ASSEMBLER_TEST_GENERATE(Pextrd1, assembler) { |
| 2971 if (TargetCPUFeatures::sse4_1_supported()) { | 2744 if (TargetCPUFeatures::sse4_1_supported()) { |
| 2972 __ movsd(XMM0, Address(ESP, kWordSize)); | 2745 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2973 __ pextrd(EAX, XMM0, Immediate(1)); | 2746 __ pextrd(EAX, XMM0, Immediate(1)); |
| 2974 } | 2747 } |
| 2975 __ ret(); | 2748 __ ret(); |
| 2976 } | 2749 } |
| 2977 | 2750 |
| 2978 | |
| 2979 ASSEMBLER_TEST_RUN(Pextrd1, test) { | 2751 ASSEMBLER_TEST_RUN(Pextrd1, test) { |
| 2980 if (TargetCPUFeatures::sse4_1_supported()) { | 2752 if (TargetCPUFeatures::sse4_1_supported()) { |
| 2981 typedef int32_t (*PextrdCode1)(double d); | 2753 typedef int32_t (*PextrdCode1)(double d); |
| 2982 int32_t res = reinterpret_cast<PextrdCode1>(test->entry())(123456789); | 2754 int32_t res = reinterpret_cast<PextrdCode1>(test->entry())(123456789); |
| 2983 EXPECT_EQ(0x419d6f34, res); | 2755 EXPECT_EQ(0x419d6f34, res); |
| 2984 } | 2756 } |
| 2985 } | 2757 } |
| 2986 | 2758 |
| 2987 | |
| 2988 ASSEMBLER_TEST_GENERATE(Pmovsxdq, assembler) { | 2759 ASSEMBLER_TEST_GENERATE(Pmovsxdq, assembler) { |
| 2989 if (TargetCPUFeatures::sse4_1_supported()) { | 2760 if (TargetCPUFeatures::sse4_1_supported()) { |
| 2990 __ movsd(XMM0, Address(ESP, kWordSize)); | 2761 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 2991 __ pmovsxdq(XMM0, XMM0); | 2762 __ pmovsxdq(XMM0, XMM0); |
| 2992 __ pextrd(EAX, XMM0, Immediate(1)); | 2763 __ pextrd(EAX, XMM0, Immediate(1)); |
| 2993 } | 2764 } |
| 2994 __ ret(); | 2765 __ ret(); |
| 2995 } | 2766 } |
| 2996 | 2767 |
| 2997 | |
| 2998 ASSEMBLER_TEST_RUN(Pmovsxdq, test) { | 2768 ASSEMBLER_TEST_RUN(Pmovsxdq, test) { |
| 2999 if (TargetCPUFeatures::sse4_1_supported()) { | 2769 if (TargetCPUFeatures::sse4_1_supported()) { |
| 3000 typedef int32_t (*PmovsxdqCode)(double d); | 2770 typedef int32_t (*PmovsxdqCode)(double d); |
| 3001 int32_t res = reinterpret_cast<PmovsxdqCode>(test->entry())(123456789); | 2771 int32_t res = reinterpret_cast<PmovsxdqCode>(test->entry())(123456789); |
| 3002 EXPECT_EQ(0, res); | 2772 EXPECT_EQ(0, res); |
| 3003 } | 2773 } |
| 3004 } | 2774 } |
| 3005 | 2775 |
| 3006 | |
| 3007 ASSEMBLER_TEST_GENERATE(Pcmpeqq, assembler) { | 2776 ASSEMBLER_TEST_GENERATE(Pcmpeqq, assembler) { |
| 3008 if (TargetCPUFeatures::sse4_1_supported()) { | 2777 if (TargetCPUFeatures::sse4_1_supported()) { |
| 3009 __ movsd(XMM0, Address(ESP, kWordSize)); | 2778 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 3010 __ xorpd(XMM1, XMM1); | 2779 __ xorpd(XMM1, XMM1); |
| 3011 __ pcmpeqq(XMM0, XMM1); | 2780 __ pcmpeqq(XMM0, XMM1); |
| 3012 __ movd(EAX, XMM0); | 2781 __ movd(EAX, XMM0); |
| 3013 } | 2782 } |
| 3014 __ ret(); | 2783 __ ret(); |
| 3015 } | 2784 } |
| 3016 | 2785 |
| 3017 | |
| 3018 ASSEMBLER_TEST_RUN(Pcmpeqq, test) { | 2786 ASSEMBLER_TEST_RUN(Pcmpeqq, test) { |
| 3019 if (TargetCPUFeatures::sse4_1_supported()) { | 2787 if (TargetCPUFeatures::sse4_1_supported()) { |
| 3020 typedef int32_t (*PcmpeqqCode)(double d); | 2788 typedef int32_t (*PcmpeqqCode)(double d); |
| 3021 int32_t res = reinterpret_cast<PcmpeqqCode>(test->entry())(0); | 2789 int32_t res = reinterpret_cast<PcmpeqqCode>(test->entry())(0); |
| 3022 EXPECT_EQ(-1, res); | 2790 EXPECT_EQ(-1, res); |
| 3023 } | 2791 } |
| 3024 } | 2792 } |
| 3025 | 2793 |
| 3026 | |
| 3027 ASSEMBLER_TEST_GENERATE(AndPd, assembler) { | 2794 ASSEMBLER_TEST_GENERATE(AndPd, assembler) { |
| 3028 __ movsd(XMM0, Address(ESP, kWordSize)); | 2795 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 3029 __ andpd(XMM0, XMM0); | 2796 __ andpd(XMM0, XMM0); |
| 3030 __ pushl(EAX); | 2797 __ pushl(EAX); |
| 3031 __ pushl(EAX); | 2798 __ pushl(EAX); |
| 3032 __ movsd(Address(ESP, 0), XMM0); | 2799 __ movsd(Address(ESP, 0), XMM0); |
| 3033 __ fldl(Address(ESP, 0)); | 2800 __ fldl(Address(ESP, 0)); |
| 3034 __ popl(EAX); | 2801 __ popl(EAX); |
| 3035 __ popl(EAX); | 2802 __ popl(EAX); |
| 3036 __ ret(); | 2803 __ ret(); |
| 3037 } | 2804 } |
| 3038 | 2805 |
| 3039 | |
| 3040 ASSEMBLER_TEST_RUN(AndPd, test) { | 2806 ASSEMBLER_TEST_RUN(AndPd, test) { |
| 3041 typedef double (*AndpdCode)(double d); | 2807 typedef double (*AndpdCode)(double d); |
| 3042 double res = reinterpret_cast<AndpdCode>(test->entry())(12.56e3); | 2808 double res = reinterpret_cast<AndpdCode>(test->entry())(12.56e3); |
| 3043 EXPECT_FLOAT_EQ(12.56e3, res, 0.0); | 2809 EXPECT_FLOAT_EQ(12.56e3, res, 0.0); |
| 3044 } | 2810 } |
| 3045 | 2811 |
| 3046 | |
| 3047 ASSEMBLER_TEST_GENERATE(Movq, assembler) { | 2812 ASSEMBLER_TEST_GENERATE(Movq, assembler) { |
| 3048 __ movq(XMM0, Address(ESP, kWordSize)); | 2813 __ movq(XMM0, Address(ESP, kWordSize)); |
| 3049 __ subl(ESP, Immediate(kDoubleSize)); | 2814 __ subl(ESP, Immediate(kDoubleSize)); |
| 3050 __ movq(Address(ESP, 0), XMM0); | 2815 __ movq(Address(ESP, 0), XMM0); |
| 3051 __ fldl(Address(ESP, 0)); | 2816 __ fldl(Address(ESP, 0)); |
| 3052 __ addl(ESP, Immediate(kDoubleSize)); | 2817 __ addl(ESP, Immediate(kDoubleSize)); |
| 3053 __ ret(); | 2818 __ ret(); |
| 3054 } | 2819 } |
| 3055 | 2820 |
| 3056 | |
| 3057 ASSEMBLER_TEST_RUN(Movq, test) { | 2821 ASSEMBLER_TEST_RUN(Movq, test) { |
| 3058 typedef double (*MovqCode)(double d); | 2822 typedef double (*MovqCode)(double d); |
| 3059 double res = reinterpret_cast<MovqCode>(test->entry())(12.34e5); | 2823 double res = reinterpret_cast<MovqCode>(test->entry())(12.34e5); |
| 3060 EXPECT_FLOAT_EQ(12.34e5, res, 0.0); | 2824 EXPECT_FLOAT_EQ(12.34e5, res, 0.0); |
| 3061 } | 2825 } |
| 3062 | 2826 |
| 3063 | |
| 3064 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) { | 2827 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) { |
| 3065 __ movsd(XMM0, Address(ESP, kWordSize)); | 2828 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 3066 __ DoubleAbs(XMM0); | 2829 __ DoubleAbs(XMM0); |
| 3067 __ pushl(EAX); | 2830 __ pushl(EAX); |
| 3068 __ pushl(EAX); | 2831 __ pushl(EAX); |
| 3069 __ movsd(Address(ESP, 0), XMM0); | 2832 __ movsd(Address(ESP, 0), XMM0); |
| 3070 __ fldl(Address(ESP, 0)); | 2833 __ fldl(Address(ESP, 0)); |
| 3071 __ popl(EAX); | 2834 __ popl(EAX); |
| 3072 __ popl(EAX); | 2835 __ popl(EAX); |
| 3073 __ ret(); | 2836 __ ret(); |
| 3074 } | 2837 } |
| 3075 | 2838 |
| 3076 | |
| 3077 ASSEMBLER_TEST_RUN(DoubleAbs, test) { | 2839 ASSEMBLER_TEST_RUN(DoubleAbs, test) { |
| 3078 typedef double (*DoubleAbsCode)(double d); | 2840 typedef double (*DoubleAbsCode)(double d); |
| 3079 double val = -12.45; | 2841 double val = -12.45; |
| 3080 double res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); | 2842 double res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); |
| 3081 EXPECT_FLOAT_EQ(-val, res, 0.001); | 2843 EXPECT_FLOAT_EQ(-val, res, 0.001); |
| 3082 val = 12.45; | 2844 val = 12.45; |
| 3083 res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); | 2845 res = reinterpret_cast<DoubleAbsCode>(test->entry())(val); |
| 3084 EXPECT_FLOAT_EQ(val, res, 0.001); | 2846 EXPECT_FLOAT_EQ(val, res, 0.001); |
| 3085 } | 2847 } |
| 3086 | 2848 |
| 3087 | |
| 3088 ASSEMBLER_TEST_GENERATE(ExtractSignBits, assembler) { | 2849 ASSEMBLER_TEST_GENERATE(ExtractSignBits, assembler) { |
| 3089 __ movsd(XMM0, Address(ESP, kWordSize)); | 2850 __ movsd(XMM0, Address(ESP, kWordSize)); |
| 3090 __ movmskpd(EAX, XMM0); | 2851 __ movmskpd(EAX, XMM0); |
| 3091 __ andl(EAX, Immediate(0x1)); | 2852 __ andl(EAX, Immediate(0x1)); |
| 3092 __ ret(); | 2853 __ ret(); |
| 3093 } | 2854 } |
| 3094 | 2855 |
| 3095 | |
| 3096 ASSEMBLER_TEST_RUN(ExtractSignBits, test) { | 2856 ASSEMBLER_TEST_RUN(ExtractSignBits, test) { |
| 3097 typedef int (*ExtractSignBits)(double d); | 2857 typedef int (*ExtractSignBits)(double d); |
| 3098 int res = reinterpret_cast<ExtractSignBits>(test->entry())(1.0); | 2858 int res = reinterpret_cast<ExtractSignBits>(test->entry())(1.0); |
| 3099 EXPECT_EQ(0, res); | 2859 EXPECT_EQ(0, res); |
| 3100 res = reinterpret_cast<ExtractSignBits>(test->entry())(-1.0); | 2860 res = reinterpret_cast<ExtractSignBits>(test->entry())(-1.0); |
| 3101 EXPECT_EQ(1, res); | 2861 EXPECT_EQ(1, res); |
| 3102 res = reinterpret_cast<ExtractSignBits>(test->entry())(-0.0); | 2862 res = reinterpret_cast<ExtractSignBits>(test->entry())(-0.0); |
| 3103 EXPECT_EQ(1, res); | 2863 EXPECT_EQ(1, res); |
| 3104 } | 2864 } |
| 3105 | 2865 |
| 3106 | |
| 3107 // Return -1 if signed, 1 if not signed and 0 otherwise. | 2866 // Return -1 if signed, 1 if not signed and 0 otherwise. |
| 3108 ASSEMBLER_TEST_GENERATE(ConditionalMovesSign, assembler) { | 2867 ASSEMBLER_TEST_GENERATE(ConditionalMovesSign, assembler) { |
| 3109 // Preserve clobbered callee-saved register (EBX). | 2868 // Preserve clobbered callee-saved register (EBX). |
| 3110 __ pushl(EBX); | 2869 __ pushl(EBX); |
| 3111 | 2870 |
| 3112 __ movl(EDX, Address(ESP, 2 * kWordSize)); | 2871 __ movl(EDX, Address(ESP, 2 * kWordSize)); |
| 3113 __ xorl(EAX, EAX); | 2872 __ xorl(EAX, EAX); |
| 3114 __ movl(EBX, Immediate(1)); | 2873 __ movl(EBX, Immediate(1)); |
| 3115 __ movl(ECX, Immediate(-1)); | 2874 __ movl(ECX, Immediate(-1)); |
| 3116 __ testl(EDX, EDX); | 2875 __ testl(EDX, EDX); |
| 3117 __ cmovs(EAX, ECX); // return -1. | 2876 __ cmovs(EAX, ECX); // return -1. |
| 3118 __ testl(EDX, EDX); | 2877 __ testl(EDX, EDX); |
| 3119 __ cmovns(EAX, EBX); // return 1. | 2878 __ cmovns(EAX, EBX); // return 1. |
| 3120 | 2879 |
| 3121 // Restore callee-saved register (EBX) and return. | 2880 // Restore callee-saved register (EBX) and return. |
| 3122 __ popl(EBX); | 2881 __ popl(EBX); |
| 3123 __ ret(); | 2882 __ ret(); |
| 3124 } | 2883 } |
| 3125 | 2884 |
| 3126 | |
| 3127 ASSEMBLER_TEST_RUN(ConditionalMovesSign, test) { | 2885 ASSEMBLER_TEST_RUN(ConditionalMovesSign, test) { |
| 3128 typedef int (*ConditionalMovesSignCode)(int i); | 2886 typedef int (*ConditionalMovesSignCode)(int i); |
| 3129 int res = reinterpret_cast<ConditionalMovesSignCode>(test->entry())(785); | 2887 int res = reinterpret_cast<ConditionalMovesSignCode>(test->entry())(785); |
| 3130 EXPECT_EQ(1, res); | 2888 EXPECT_EQ(1, res); |
| 3131 res = reinterpret_cast<ConditionalMovesSignCode>(test->entry())(-12); | 2889 res = reinterpret_cast<ConditionalMovesSignCode>(test->entry())(-12); |
| 3132 EXPECT_EQ(-1, res); | 2890 EXPECT_EQ(-1, res); |
| 3133 } | 2891 } |
| 3134 | 2892 |
| 3135 | |
| 3136 // Return 1 if overflow, 0 if no overflow. | 2893 // Return 1 if overflow, 0 if no overflow. |
| 3137 ASSEMBLER_TEST_GENERATE(ConditionalMovesNoOverflow, assembler) { | 2894 ASSEMBLER_TEST_GENERATE(ConditionalMovesNoOverflow, assembler) { |
| 3138 __ movl(EDX, Address(ESP, 1 * kWordSize)); | 2895 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 3139 __ addl(EDX, Address(ESP, 2 * kWordSize)); | 2896 __ addl(EDX, Address(ESP, 2 * kWordSize)); |
| 3140 __ movl(EAX, Immediate(1)); | 2897 __ movl(EAX, Immediate(1)); |
| 3141 __ movl(ECX, Immediate(0)); | 2898 __ movl(ECX, Immediate(0)); |
| 3142 __ cmovno(EAX, ECX); | 2899 __ cmovno(EAX, ECX); |
| 3143 __ ret(); | 2900 __ ret(); |
| 3144 } | 2901 } |
| 3145 | 2902 |
| 3146 | |
| 3147 ASSEMBLER_TEST_RUN(ConditionalMovesNoOverflow, test) { | 2903 ASSEMBLER_TEST_RUN(ConditionalMovesNoOverflow, test) { |
| 3148 typedef int (*ConditionalMovesNoOverflowCode)(int i, int j); | 2904 typedef int (*ConditionalMovesNoOverflowCode)(int i, int j); |
| 3149 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())( | 2905 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())( |
| 3150 0x7fffffff, 2); | 2906 0x7fffffff, 2); |
| 3151 EXPECT_EQ(1, res); | 2907 EXPECT_EQ(1, res); |
| 3152 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); | 2908 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); |
| 3153 EXPECT_EQ(0, res); | 2909 EXPECT_EQ(0, res); |
| 3154 } | 2910 } |
| 3155 | 2911 |
| 3156 | |
| 3157 // Return 1 if equal, 0 if not equal. | 2912 // Return 1 if equal, 0 if not equal. |
| 3158 ASSEMBLER_TEST_GENERATE(ConditionalMovesEqual, assembler) { | 2913 ASSEMBLER_TEST_GENERATE(ConditionalMovesEqual, assembler) { |
| 3159 __ xorl(EAX, EAX); | 2914 __ xorl(EAX, EAX); |
| 3160 __ movl(ECX, Immediate(1)); | 2915 __ movl(ECX, Immediate(1)); |
| 3161 __ movl(EDX, Address(ESP, 1 * kWordSize)); | 2916 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 3162 __ cmpl(EDX, Immediate(785)); | 2917 __ cmpl(EDX, Immediate(785)); |
| 3163 __ cmove(EAX, ECX); | 2918 __ cmove(EAX, ECX); |
| 3164 __ ret(); | 2919 __ ret(); |
| 3165 } | 2920 } |
| 3166 | 2921 |
| 3167 | |
| 3168 ASSEMBLER_TEST_RUN(ConditionalMovesEqual, test) { | 2922 ASSEMBLER_TEST_RUN(ConditionalMovesEqual, test) { |
| 3169 typedef int (*ConditionalMovesEqualCode)(int i); | 2923 typedef int (*ConditionalMovesEqualCode)(int i); |
| 3170 int res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(785); | 2924 int res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(785); |
| 3171 EXPECT_EQ(1, res); | 2925 EXPECT_EQ(1, res); |
| 3172 res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(-12); | 2926 res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(-12); |
| 3173 EXPECT_EQ(0, res); | 2927 EXPECT_EQ(0, res); |
| 3174 } | 2928 } |
| 3175 | 2929 |
| 3176 | |
| 3177 // Return 1 if not equal, 0 if equal. | 2930 // Return 1 if not equal, 0 if equal. |
| 3178 ASSEMBLER_TEST_GENERATE(ConditionalMovesNotEqual, assembler) { | 2931 ASSEMBLER_TEST_GENERATE(ConditionalMovesNotEqual, assembler) { |
| 3179 __ xorl(EAX, EAX); | 2932 __ xorl(EAX, EAX); |
| 3180 __ movl(ECX, Immediate(1)); | 2933 __ movl(ECX, Immediate(1)); |
| 3181 __ movl(EDX, Address(ESP, 1 * kWordSize)); | 2934 __ movl(EDX, Address(ESP, 1 * kWordSize)); |
| 3182 __ cmpl(EDX, Immediate(785)); | 2935 __ cmpl(EDX, Immediate(785)); |
| 3183 __ cmovne(EAX, ECX); | 2936 __ cmovne(EAX, ECX); |
| 3184 __ ret(); | 2937 __ ret(); |
| 3185 } | 2938 } |
| 3186 | 2939 |
| 3187 | |
| 3188 ASSEMBLER_TEST_RUN(ConditionalMovesNotEqual, test) { | 2940 ASSEMBLER_TEST_RUN(ConditionalMovesNotEqual, test) { |
| 3189 typedef int (*ConditionalMovesNotEqualCode)(int i); | 2941 typedef int (*ConditionalMovesNotEqualCode)(int i); |
| 3190 int res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(785); | 2942 int res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(785); |
| 3191 EXPECT_EQ(0, res); | 2943 EXPECT_EQ(0, res); |
| 3192 res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(-12); | 2944 res = reinterpret_cast<ConditionalMovesNotEqualCode>(test->entry())(-12); |
| 3193 EXPECT_EQ(1, res); | 2945 EXPECT_EQ(1, res); |
| 3194 } | 2946 } |
| 3195 | 2947 |
| 3196 | |
| 3197 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { | 2948 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { |
| 3198 __ movl(EDX, Immediate(1)); // Greater equal. | 2949 __ movl(EDX, Immediate(1)); // Greater equal. |
| 3199 __ movl(ECX, Immediate(-1)); // Less | 2950 __ movl(ECX, Immediate(-1)); // Less |
| 3200 __ movl(EAX, Address(ESP, 1 * kWordSize)); | 2951 __ movl(EAX, Address(ESP, 1 * kWordSize)); |
| 3201 __ cmpl(EAX, Address(ESP, 2 * kWordSize)); | 2952 __ cmpl(EAX, Address(ESP, 2 * kWordSize)); |
| 3202 __ cmovlessl(EAX, ECX); | 2953 __ cmovlessl(EAX, ECX); |
| 3203 __ cmovgel(EAX, EDX); | 2954 __ cmovgel(EAX, EDX); |
| 3204 __ ret(); | 2955 __ ret(); |
| 3205 } | 2956 } |
| 3206 | 2957 |
| 3207 | |
| 3208 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { | 2958 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { |
| 3209 typedef int (*ConditionalMovesCompareCode)(int i, int j); | 2959 typedef int (*ConditionalMovesCompareCode)(int i, int j); |
| 3210 int res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(10, 5); | 2960 int res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(10, 5); |
| 3211 EXPECT_EQ(1, res); // Greater equal. | 2961 EXPECT_EQ(1, res); // Greater equal. |
| 3212 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(5, 5); | 2962 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(5, 5); |
| 3213 EXPECT_EQ(1, res); // Greater equal. | 2963 EXPECT_EQ(1, res); // Greater equal. |
| 3214 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(2, 5); | 2964 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(2, 5); |
| 3215 EXPECT_EQ(-1, res); // Less. | 2965 EXPECT_EQ(-1, res); // Less. |
| 3216 } | 2966 } |
| 3217 | 2967 |
| 3218 | |
| 3219 ASSEMBLER_TEST_GENERATE(TestLoadDoubleConstant, assembler) { | 2968 ASSEMBLER_TEST_GENERATE(TestLoadDoubleConstant, assembler) { |
| 3220 __ LoadDoubleConstant(XMM3, -12.34); | 2969 __ LoadDoubleConstant(XMM3, -12.34); |
| 3221 __ pushl(EAX); | 2970 __ pushl(EAX); |
| 3222 __ pushl(EAX); | 2971 __ pushl(EAX); |
| 3223 __ movsd(Address(ESP, 0), XMM3); | 2972 __ movsd(Address(ESP, 0), XMM3); |
| 3224 __ fldl(Address(ESP, 0)); | 2973 __ fldl(Address(ESP, 0)); |
| 3225 __ popl(EAX); | 2974 __ popl(EAX); |
| 3226 __ popl(EAX); | 2975 __ popl(EAX); |
| 3227 __ ret(); | 2976 __ ret(); |
| 3228 } | 2977 } |
| 3229 | 2978 |
| 3230 | |
| 3231 ASSEMBLER_TEST_RUN(TestLoadDoubleConstant, test) { | 2979 ASSEMBLER_TEST_RUN(TestLoadDoubleConstant, test) { |
| 3232 typedef double (*TestLoadDoubleConstantCode)(); | 2980 typedef double (*TestLoadDoubleConstantCode)(); |
| 3233 double res = reinterpret_cast<TestLoadDoubleConstantCode>(test->entry())(); | 2981 double res = reinterpret_cast<TestLoadDoubleConstantCode>(test->entry())(); |
| 3234 EXPECT_FLOAT_EQ(-12.34, res, 0.0001); | 2982 EXPECT_FLOAT_EQ(-12.34, res, 0.0001); |
| 3235 } | 2983 } |
| 3236 | 2984 |
| 3237 | |
| 3238 ASSEMBLER_TEST_GENERATE(TestObjectCompare, assembler) { | 2985 ASSEMBLER_TEST_GENERATE(TestObjectCompare, assembler) { |
| 3239 ObjectStore* object_store = Isolate::Current()->object_store(); | 2986 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 3240 const Object& obj = Object::ZoneHandle(object_store->smi_class()); | 2987 const Object& obj = Object::ZoneHandle(object_store->smi_class()); |
| 3241 Label fail; | 2988 Label fail; |
| 3242 __ LoadObject(EAX, obj); | 2989 __ LoadObject(EAX, obj); |
| 3243 __ CompareObject(EAX, obj); | 2990 __ CompareObject(EAX, obj); |
| 3244 __ j(NOT_EQUAL, &fail); | 2991 __ j(NOT_EQUAL, &fail); |
| 3245 __ LoadObject(ECX, obj); | 2992 __ LoadObject(ECX, obj); |
| 3246 __ CompareObject(ECX, obj); | 2993 __ CompareObject(ECX, obj); |
| 3247 __ j(NOT_EQUAL, &fail); | 2994 __ j(NOT_EQUAL, &fail); |
| 3248 __ movl(EAX, Immediate(1)); // OK | 2995 __ movl(EAX, Immediate(1)); // OK |
| 3249 __ ret(); | 2996 __ ret(); |
| 3250 __ Bind(&fail); | 2997 __ Bind(&fail); |
| 3251 __ movl(EAX, Immediate(0)); // Fail. | 2998 __ movl(EAX, Immediate(0)); // Fail. |
| 3252 __ ret(); | 2999 __ ret(); |
| 3253 } | 3000 } |
| 3254 | 3001 |
| 3255 | |
| 3256 ASSEMBLER_TEST_RUN(TestObjectCompare, test) { | 3002 ASSEMBLER_TEST_RUN(TestObjectCompare, test) { |
| 3257 typedef bool (*TestObjectCompare)(); | 3003 typedef bool (*TestObjectCompare)(); |
| 3258 bool res = reinterpret_cast<TestObjectCompare>(test->entry())(); | 3004 bool res = reinterpret_cast<TestObjectCompare>(test->entry())(); |
| 3259 EXPECT_EQ(true, res); | 3005 EXPECT_EQ(true, res); |
| 3260 } | 3006 } |
| 3261 | 3007 |
| 3262 | |
| 3263 ASSEMBLER_TEST_GENERATE(TestSetCC, assembler) { | 3008 ASSEMBLER_TEST_GENERATE(TestSetCC, assembler) { |
| 3264 __ movl(EAX, Immediate(0xFFFFFFFF)); | 3009 __ movl(EAX, Immediate(0xFFFFFFFF)); |
| 3265 __ cmpl(EAX, EAX); | 3010 __ cmpl(EAX, EAX); |
| 3266 __ setcc(NOT_EQUAL, AL); | 3011 __ setcc(NOT_EQUAL, AL); |
| 3267 __ ret(); | 3012 __ ret(); |
| 3268 } | 3013 } |
| 3269 | 3014 |
| 3270 | |
| 3271 ASSEMBLER_TEST_RUN(TestSetCC, test) { | 3015 ASSEMBLER_TEST_RUN(TestSetCC, test) { |
| 3272 typedef uword (*TestSetCC)(); | 3016 typedef uword (*TestSetCC)(); |
| 3273 uword res = reinterpret_cast<TestSetCC>(test->entry())(); | 3017 uword res = reinterpret_cast<TestSetCC>(test->entry())(); |
| 3274 EXPECT_EQ(0xFFFFFF00, res); | 3018 EXPECT_EQ(0xFFFFFF00, res); |
| 3275 } | 3019 } |
| 3276 | 3020 |
| 3277 | |
| 3278 ASSEMBLER_TEST_GENERATE(TestNop, assembler) { | 3021 ASSEMBLER_TEST_GENERATE(TestNop, assembler) { |
| 3279 __ nop(1); | 3022 __ nop(1); |
| 3280 __ nop(2); | 3023 __ nop(2); |
| 3281 __ nop(3); | 3024 __ nop(3); |
| 3282 __ nop(4); | 3025 __ nop(4); |
| 3283 __ nop(5); | 3026 __ nop(5); |
| 3284 __ nop(6); | 3027 __ nop(6); |
| 3285 __ nop(7); | 3028 __ nop(7); |
| 3286 __ nop(8); | 3029 __ nop(8); |
| 3287 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. | 3030 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. |
| 3288 __ ret(); | 3031 __ ret(); |
| 3289 } | 3032 } |
| 3290 | 3033 |
| 3291 | |
| 3292 ASSEMBLER_TEST_RUN(TestNop, test) { | 3034 ASSEMBLER_TEST_RUN(TestNop, test) { |
| 3293 typedef int (*TestNop)(); | 3035 typedef int (*TestNop)(); |
| 3294 int res = reinterpret_cast<TestNop>(test->entry())(); | 3036 int res = reinterpret_cast<TestNop>(test->entry())(); |
| 3295 EXPECT_EQ(36, res); // 36 nop bytes emitted. | 3037 EXPECT_EQ(36, res); // 36 nop bytes emitted. |
| 3296 } | 3038 } |
| 3297 | 3039 |
| 3298 | |
| 3299 ASSEMBLER_TEST_GENERATE(TestAlign0, assembler) { | 3040 ASSEMBLER_TEST_GENERATE(TestAlign0, assembler) { |
| 3300 __ Align(4, 0); | 3041 __ Align(4, 0); |
| 3301 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. | 3042 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. |
| 3302 __ ret(); | 3043 __ ret(); |
| 3303 } | 3044 } |
| 3304 | 3045 |
| 3305 | |
| 3306 ASSEMBLER_TEST_RUN(TestAlign0, test) { | 3046 ASSEMBLER_TEST_RUN(TestAlign0, test) { |
| 3307 typedef int (*TestAlign0)(); | 3047 typedef int (*TestAlign0)(); |
| 3308 int res = reinterpret_cast<TestAlign0>(test->entry())(); | 3048 int res = reinterpret_cast<TestAlign0>(test->entry())(); |
| 3309 EXPECT_EQ(0, res); // 0 bytes emitted. | 3049 EXPECT_EQ(0, res); // 0 bytes emitted. |
| 3310 } | 3050 } |
| 3311 | 3051 |
| 3312 | |
| 3313 ASSEMBLER_TEST_GENERATE(TestAlign1, assembler) { | 3052 ASSEMBLER_TEST_GENERATE(TestAlign1, assembler) { |
| 3314 __ nop(1); | 3053 __ nop(1); |
| 3315 __ Align(4, 0); | 3054 __ Align(4, 0); |
| 3316 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. | 3055 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. |
| 3317 __ ret(); | 3056 __ ret(); |
| 3318 } | 3057 } |
| 3319 | 3058 |
| 3320 | |
| 3321 ASSEMBLER_TEST_RUN(TestAlign1, test) { | 3059 ASSEMBLER_TEST_RUN(TestAlign1, test) { |
| 3322 typedef int (*TestAlign1)(); | 3060 typedef int (*TestAlign1)(); |
| 3323 int res = reinterpret_cast<TestAlign1>(test->entry())(); | 3061 int res = reinterpret_cast<TestAlign1>(test->entry())(); |
| 3324 EXPECT_EQ(4, res); // 4 bytes emitted. | 3062 EXPECT_EQ(4, res); // 4 bytes emitted. |
| 3325 } | 3063 } |
| 3326 | 3064 |
| 3327 | |
| 3328 ASSEMBLER_TEST_GENERATE(TestAlign1Offset1, assembler) { | 3065 ASSEMBLER_TEST_GENERATE(TestAlign1Offset1, assembler) { |
| 3329 __ nop(1); | 3066 __ nop(1); |
| 3330 __ Align(4, 1); | 3067 __ Align(4, 1); |
| 3331 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. | 3068 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. |
| 3332 __ ret(); | 3069 __ ret(); |
| 3333 } | 3070 } |
| 3334 | 3071 |
| 3335 | |
| 3336 ASSEMBLER_TEST_RUN(TestAlign1Offset1, test) { | 3072 ASSEMBLER_TEST_RUN(TestAlign1Offset1, test) { |
| 3337 typedef int (*TestAlign1Offset1)(); | 3073 typedef int (*TestAlign1Offset1)(); |
| 3338 int res = reinterpret_cast<TestAlign1Offset1>(test->entry())(); | 3074 int res = reinterpret_cast<TestAlign1Offset1>(test->entry())(); |
| 3339 EXPECT_EQ(3, res); // 3 bytes emitted. | 3075 EXPECT_EQ(3, res); // 3 bytes emitted. |
| 3340 } | 3076 } |
| 3341 | 3077 |
| 3342 | |
| 3343 ASSEMBLER_TEST_GENERATE(TestAlignLarge, assembler) { | 3078 ASSEMBLER_TEST_GENERATE(TestAlignLarge, assembler) { |
| 3344 __ nop(1); | 3079 __ nop(1); |
| 3345 __ Align(16, 0); | 3080 __ Align(16, 0); |
| 3346 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. | 3081 __ movl(EAX, Immediate(assembler->CodeSize())); // Return code size. |
| 3347 __ ret(); | 3082 __ ret(); |
| 3348 } | 3083 } |
| 3349 | 3084 |
| 3350 | |
| 3351 ASSEMBLER_TEST_RUN(TestAlignLarge, test) { | 3085 ASSEMBLER_TEST_RUN(TestAlignLarge, test) { |
| 3352 typedef int (*TestAlignLarge)(); | 3086 typedef int (*TestAlignLarge)(); |
| 3353 int res = reinterpret_cast<TestAlignLarge>(test->entry())(); | 3087 int res = reinterpret_cast<TestAlignLarge>(test->entry())(); |
| 3354 EXPECT_EQ(16, res); // 16 bytes emitted. | 3088 EXPECT_EQ(16, res); // 16 bytes emitted. |
| 3355 } | 3089 } |
| 3356 | 3090 |
| 3357 | |
| 3358 ASSEMBLER_TEST_GENERATE(TestRepMovsBytes, assembler) { | 3091 ASSEMBLER_TEST_GENERATE(TestRepMovsBytes, assembler) { |
| 3359 // Preserve registers. | 3092 // Preserve registers. |
| 3360 __ pushl(ESI); | 3093 __ pushl(ESI); |
| 3361 __ pushl(EDI); | 3094 __ pushl(EDI); |
| 3362 __ pushl(ECX); | 3095 __ pushl(ECX); |
| 3363 __ movl(ESI, Address(ESP, 4 * kWordSize)); // from. | 3096 __ movl(ESI, Address(ESP, 4 * kWordSize)); // from. |
| 3364 __ movl(EDI, Address(ESP, 5 * kWordSize)); // to. | 3097 __ movl(EDI, Address(ESP, 5 * kWordSize)); // to. |
| 3365 __ movl(ECX, Address(ESP, 6 * kWordSize)); // count. | 3098 __ movl(ECX, Address(ESP, 6 * kWordSize)); // count. |
| 3366 __ rep_movsb(); | 3099 __ rep_movsb(); |
| 3367 __ popl(ECX); | 3100 __ popl(ECX); |
| 3368 __ popl(EDI); | 3101 __ popl(EDI); |
| 3369 __ popl(ESI); | 3102 __ popl(ESI); |
| 3370 __ ret(); | 3103 __ ret(); |
| 3371 } | 3104 } |
| 3372 | 3105 |
| 3373 | |
| 3374 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { | 3106 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { |
| 3375 const char* from = "0123456789"; | 3107 const char* from = "0123456789"; |
| 3376 const char* to = new char[10]; | 3108 const char* to = new char[10]; |
| 3377 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); | 3109 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); |
| 3378 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); | 3110 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); |
| 3379 EXPECT_EQ(to[0], '0'); | 3111 EXPECT_EQ(to[0], '0'); |
| 3380 for (int i = 0; i < 10; i++) { | 3112 for (int i = 0; i < 10; i++) { |
| 3381 EXPECT_EQ(from[i], to[i]); | 3113 EXPECT_EQ(from[i], to[i]); |
| 3382 } | 3114 } |
| 3383 delete[] to; | 3115 delete[] to; |
| 3384 } | 3116 } |
| 3385 | 3117 |
| 3386 | |
| 3387 // Called from assembler_test.cc. | 3118 // Called from assembler_test.cc. |
| 3388 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { | 3119 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { |
| 3389 __ pushl(THR); | 3120 __ pushl(THR); |
| 3390 __ movl(EAX, Address(ESP, 2 * kWordSize)); | 3121 __ movl(EAX, Address(ESP, 2 * kWordSize)); |
| 3391 __ movl(ECX, Address(ESP, 3 * kWordSize)); | 3122 __ movl(ECX, Address(ESP, 3 * kWordSize)); |
| 3392 __ movl(THR, Address(ESP, 4 * kWordSize)); | 3123 __ movl(THR, Address(ESP, 4 * kWordSize)); |
| 3393 __ pushl(EAX); | 3124 __ pushl(EAX); |
| 3394 __ StoreIntoObject(ECX, FieldAddress(ECX, GrowableObjectArray::data_offset()), | 3125 __ StoreIntoObject(ECX, FieldAddress(ECX, GrowableObjectArray::data_offset()), |
| 3395 EAX); | 3126 EAX); |
| 3396 __ popl(EAX); | 3127 __ popl(EAX); |
| 3397 __ popl(THR); | 3128 __ popl(THR); |
| 3398 __ ret(); | 3129 __ ret(); |
| 3399 } | 3130 } |
| 3400 | 3131 |
| 3401 | |
| 3402 ASSEMBLER_TEST_GENERATE(BitTest, assembler) { | 3132 ASSEMBLER_TEST_GENERATE(BitTest, assembler) { |
| 3403 __ movl(EAX, Immediate(4)); | 3133 __ movl(EAX, Immediate(4)); |
| 3404 __ movl(ECX, Immediate(2)); | 3134 __ movl(ECX, Immediate(2)); |
| 3405 __ bt(EAX, ECX); | 3135 __ bt(EAX, ECX); |
| 3406 Label ok; | 3136 Label ok; |
| 3407 __ j(CARRY, &ok); | 3137 __ j(CARRY, &ok); |
| 3408 __ int3(); | 3138 __ int3(); |
| 3409 __ Bind(&ok); | 3139 __ Bind(&ok); |
| 3410 __ movl(EAX, Immediate(1)); | 3140 __ movl(EAX, Immediate(1)); |
| 3411 __ ret(); | 3141 __ ret(); |
| 3412 } | 3142 } |
| 3413 | 3143 |
| 3414 | |
| 3415 ASSEMBLER_TEST_RUN(BitTest, test) { | 3144 ASSEMBLER_TEST_RUN(BitTest, test) { |
| 3416 typedef int (*BitTest)(); | 3145 typedef int (*BitTest)(); |
| 3417 EXPECT_EQ(1, reinterpret_cast<BitTest>(test->entry())()); | 3146 EXPECT_EQ(1, reinterpret_cast<BitTest>(test->entry())()); |
| 3418 } | 3147 } |
| 3419 | 3148 |
| 3420 } // namespace dart | 3149 } // namespace dart |
| 3421 | 3150 |
| 3422 #endif // defined TARGET_ARCH_IA32 | 3151 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |