| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 __ LoadHalfWordUnaligned(R1, R0, TMP); | 101 __ LoadHalfWordUnaligned(R1, R0, TMP); |
| 102 __ mov(R0, Operand(R1)); | 102 __ mov(R0, Operand(R1)); |
| 103 __ bx(LR); | 103 __ bx(LR); |
| 104 } | 104 } |
| 105 | 105 |
| 106 | 106 |
| 107 ASSEMBLER_TEST_RUN(LoadHalfWordUnaligned, test) { | 107 ASSEMBLER_TEST_RUN(LoadHalfWordUnaligned, test) { |
| 108 EXPECT(test != NULL); | 108 EXPECT(test != NULL); |
| 109 typedef intptr_t (*LoadHalfWordUnaligned)(intptr_t) DART_UNUSED; | 109 typedef intptr_t (*LoadHalfWordUnaligned)(intptr_t) DART_UNUSED; |
| 110 uint8_t buffer[4] = { | 110 uint8_t buffer[4] = { |
| 111 0x89, 0xAB, 0xCD, 0xEF, | 111 0x89, 0xAB, 0xCD, 0xEF, |
| 112 }; | 112 }; |
| 113 | 113 |
| 114 EXPECT_EQ(static_cast<int16_t>(static_cast<uint16_t>(0xAB89)), | 114 EXPECT_EQ( |
| 115 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 115 static_cast<int16_t>(static_cast<uint16_t>(0xAB89)), |
| 116 LoadHalfWordUnaligned, | 116 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadHalfWordUnaligned, test->entry(), |
| 117 test->entry(), | 117 reinterpret_cast<intptr_t>(&buffer[0]))); |
| 118 reinterpret_cast<intptr_t>(&buffer[0]))); | 118 EXPECT_EQ( |
| 119 EXPECT_EQ(static_cast<int16_t>(static_cast<uint16_t>(0xCDAB)), | 119 static_cast<int16_t>(static_cast<uint16_t>(0xCDAB)), |
| 120 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 120 EXECUTE_TEST_CODE_INTPTR_INTPTR(LoadHalfWordUnaligned, test->entry(), |
| 121 LoadHalfWordUnaligned, | 121 reinterpret_cast<intptr_t>(&buffer[1]))); |
| 122 test->entry(), | |
| 123 reinterpret_cast<intptr_t>(&buffer[1]))); | |
| 124 } | 122 } |
| 125 | 123 |
| 126 | 124 |
| 127 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnsignedUnaligned, assembler) { | 125 ASSEMBLER_TEST_GENERATE(LoadHalfWordUnsignedUnaligned, assembler) { |
| 128 __ LoadHalfWordUnsignedUnaligned(R1, R0, TMP); | 126 __ LoadHalfWordUnsignedUnaligned(R1, R0, TMP); |
| 129 __ mov(R0, Operand(R1)); | 127 __ mov(R0, Operand(R1)); |
| 130 __ bx(LR); | 128 __ bx(LR); |
| 131 } | 129 } |
| 132 | 130 |
| 133 | 131 |
| 134 ASSEMBLER_TEST_RUN(LoadHalfWordUnsignedUnaligned, test) { | 132 ASSEMBLER_TEST_RUN(LoadHalfWordUnsignedUnaligned, test) { |
| 135 EXPECT(test != NULL); | 133 EXPECT(test != NULL); |
| 136 typedef intptr_t (*LoadHalfWordUnsignedUnaligned)(intptr_t) DART_UNUSED; | 134 typedef intptr_t (*LoadHalfWordUnsignedUnaligned)(intptr_t) DART_UNUSED; |
| 137 uint8_t buffer[4] = { | 135 uint8_t buffer[4] = { |
| 138 0x89, 0xAB, 0xCD, 0xEF, | 136 0x89, 0xAB, 0xCD, 0xEF, |
| 139 }; | 137 }; |
| 140 | 138 |
| 141 EXPECT_EQ(0xAB89, | 139 EXPECT_EQ(0xAB89, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 142 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 140 LoadHalfWordUnsignedUnaligned, test->entry(), |
| 143 LoadHalfWordUnsignedUnaligned, | 141 reinterpret_cast<intptr_t>(&buffer[0]))); |
| 144 test->entry(), | 142 EXPECT_EQ(0xCDAB, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 145 reinterpret_cast<intptr_t>(&buffer[0]))); | 143 LoadHalfWordUnsignedUnaligned, test->entry(), |
| 146 EXPECT_EQ(0xCDAB, | 144 reinterpret_cast<intptr_t>(&buffer[1]))); |
| 147 EXECUTE_TEST_CODE_INTPTR_INTPTR( | |
| 148 LoadHalfWordUnsignedUnaligned, | |
| 149 test->entry(), | |
| 150 reinterpret_cast<intptr_t>(&buffer[1]))); | |
| 151 } | 145 } |
| 152 | 146 |
| 153 | 147 |
| 154 ASSEMBLER_TEST_GENERATE(StoreHalfWordUnaligned, assembler) { | 148 ASSEMBLER_TEST_GENERATE(StoreHalfWordUnaligned, assembler) { |
| 155 __ LoadImmediate(R1, 0xABCD); | 149 __ LoadImmediate(R1, 0xABCD); |
| 156 __ StoreWordUnaligned(R1, R0, TMP); | 150 __ StoreWordUnaligned(R1, R0, TMP); |
| 157 __ mov(R0, Operand(R1)); | 151 __ mov(R0, Operand(R1)); |
| 158 __ bx(LR); | 152 __ bx(LR); |
| 159 } | 153 } |
| 160 | 154 |
| 161 | 155 |
| 162 ASSEMBLER_TEST_RUN(StoreHalfWordUnaligned, test) { | 156 ASSEMBLER_TEST_RUN(StoreHalfWordUnaligned, test) { |
| 163 EXPECT(test != NULL); | 157 EXPECT(test != NULL); |
| 164 typedef intptr_t (*StoreHalfWordUnaligned)(intptr_t) DART_UNUSED; | 158 typedef intptr_t (*StoreHalfWordUnaligned)(intptr_t) DART_UNUSED; |
| 165 uint8_t buffer[4] = { | 159 uint8_t buffer[4] = { |
| 166 0, 0, 0, 0, | 160 0, 0, 0, 0, |
| 167 }; | 161 }; |
| 168 | 162 |
| 169 EXPECT_EQ(0xABCD, | 163 EXPECT_EQ(0xABCD, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 170 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 164 StoreHalfWordUnaligned, test->entry(), |
| 171 StoreHalfWordUnaligned, | 165 reinterpret_cast<intptr_t>(&buffer[0]))); |
| 172 test->entry(), | |
| 173 reinterpret_cast<intptr_t>(&buffer[0]))); | |
| 174 EXPECT_EQ(0xCD, buffer[0]); | 166 EXPECT_EQ(0xCD, buffer[0]); |
| 175 EXPECT_EQ(0xAB, buffer[1]); | 167 EXPECT_EQ(0xAB, buffer[1]); |
| 176 EXPECT_EQ(0, buffer[2]); | 168 EXPECT_EQ(0, buffer[2]); |
| 177 | 169 |
| 178 EXPECT_EQ(0xABCD, | 170 EXPECT_EQ(0xABCD, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 179 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 171 StoreHalfWordUnaligned, test->entry(), |
| 180 StoreHalfWordUnaligned, | 172 reinterpret_cast<intptr_t>(&buffer[1]))); |
| 181 test->entry(), | |
| 182 reinterpret_cast<intptr_t>(&buffer[1]))); | |
| 183 EXPECT_EQ(0xCD, buffer[1]); | 173 EXPECT_EQ(0xCD, buffer[1]); |
| 184 EXPECT_EQ(0xAB, buffer[2]); | 174 EXPECT_EQ(0xAB, buffer[2]); |
| 185 EXPECT_EQ(0, buffer[3]); | 175 EXPECT_EQ(0, buffer[3]); |
| 186 } | 176 } |
| 187 | 177 |
| 188 | 178 |
| 189 ASSEMBLER_TEST_GENERATE(LoadWordUnaligned, assembler) { | 179 ASSEMBLER_TEST_GENERATE(LoadWordUnaligned, assembler) { |
| 190 __ LoadWordUnaligned(R1, R0, TMP); | 180 __ LoadWordUnaligned(R1, R0, TMP); |
| 191 __ mov(R0, Operand(R1)); | 181 __ mov(R0, Operand(R1)); |
| 192 __ bx(LR); | 182 __ bx(LR); |
| 193 } | 183 } |
| 194 | 184 |
| 195 | 185 |
| 196 ASSEMBLER_TEST_RUN(LoadWordUnaligned, test) { | 186 ASSEMBLER_TEST_RUN(LoadWordUnaligned, test) { |
| 197 EXPECT(test != NULL); | 187 EXPECT(test != NULL); |
| 198 typedef intptr_t (*LoadWordUnaligned)(intptr_t) DART_UNUSED; | 188 typedef intptr_t (*LoadWordUnaligned)(intptr_t) DART_UNUSED; |
| 199 uint8_t buffer[8] = { | 189 uint8_t buffer[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; |
| 200 0x12, 0x34, 0x56, 0x78, | |
| 201 0x9A, 0xBC, 0xDE, 0xF0 | |
| 202 }; | |
| 203 | 190 |
| 204 EXPECT_EQ(0x78563412, | 191 EXPECT_EQ(0x78563412, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 205 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 192 LoadWordUnaligned, test->entry(), |
| 206 LoadWordUnaligned, | 193 reinterpret_cast<intptr_t>(&buffer[0]))); |
| 207 test->entry(), | 194 EXPECT_EQ(0x9A785634, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 208 reinterpret_cast<intptr_t>(&buffer[0]))); | 195 LoadWordUnaligned, test->entry(), |
| 209 EXPECT_EQ(0x9A785634, | 196 reinterpret_cast<intptr_t>(&buffer[1]))); |
| 210 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 197 EXPECT_EQ(0xBC9A7856, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 211 LoadWordUnaligned, | 198 LoadWordUnaligned, test->entry(), |
| 212 test->entry(), | 199 reinterpret_cast<intptr_t>(&buffer[2]))); |
| 213 reinterpret_cast<intptr_t>(&buffer[1]))); | 200 EXPECT_EQ(0xDEBC9A78, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 214 EXPECT_EQ(0xBC9A7856, | 201 LoadWordUnaligned, test->entry(), |
| 215 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 202 reinterpret_cast<intptr_t>(&buffer[3]))); |
| 216 LoadWordUnaligned, | |
| 217 test->entry(), | |
| 218 reinterpret_cast<intptr_t>(&buffer[2]))); | |
| 219 EXPECT_EQ(0xDEBC9A78, | |
| 220 EXECUTE_TEST_CODE_INTPTR_INTPTR( | |
| 221 LoadWordUnaligned, | |
| 222 test->entry(), | |
| 223 reinterpret_cast<intptr_t>(&buffer[3]))); | |
| 224 } | 203 } |
| 225 | 204 |
| 226 | 205 |
| 227 ASSEMBLER_TEST_GENERATE(StoreWordUnaligned, assembler) { | 206 ASSEMBLER_TEST_GENERATE(StoreWordUnaligned, assembler) { |
| 228 __ LoadImmediate(R1, 0x12345678); | 207 __ LoadImmediate(R1, 0x12345678); |
| 229 __ StoreWordUnaligned(R1, R0, TMP); | 208 __ StoreWordUnaligned(R1, R0, TMP); |
| 230 __ mov(R0, Operand(R1)); | 209 __ mov(R0, Operand(R1)); |
| 231 __ bx(LR); | 210 __ bx(LR); |
| 232 } | 211 } |
| 233 | 212 |
| 234 | 213 |
| 235 ASSEMBLER_TEST_RUN(StoreWordUnaligned, test) { | 214 ASSEMBLER_TEST_RUN(StoreWordUnaligned, test) { |
| 236 EXPECT(test != NULL); | 215 EXPECT(test != NULL); |
| 237 typedef intptr_t (*StoreWordUnaligned)(intptr_t) DART_UNUSED; | 216 typedef intptr_t (*StoreWordUnaligned)(intptr_t) DART_UNUSED; |
| 238 uint8_t buffer[8] = { | 217 uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
| 239 0, 0, 0, 0, | |
| 240 0, 0, 0, 0 | |
| 241 }; | |
| 242 | 218 |
| 243 EXPECT_EQ(0x12345678, | 219 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 244 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 220 StoreWordUnaligned, test->entry(), |
| 245 StoreWordUnaligned, | 221 reinterpret_cast<intptr_t>(&buffer[0]))); |
| 246 test->entry(), | |
| 247 reinterpret_cast<intptr_t>(&buffer[0]))); | |
| 248 EXPECT_EQ(0x78, buffer[0]); | 222 EXPECT_EQ(0x78, buffer[0]); |
| 249 EXPECT_EQ(0x56, buffer[1]); | 223 EXPECT_EQ(0x56, buffer[1]); |
| 250 EXPECT_EQ(0x34, buffer[2]); | 224 EXPECT_EQ(0x34, buffer[2]); |
| 251 EXPECT_EQ(0x12, buffer[3]); | 225 EXPECT_EQ(0x12, buffer[3]); |
| 252 | 226 |
| 253 EXPECT_EQ(0x12345678, | 227 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 254 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 228 StoreWordUnaligned, test->entry(), |
| 255 StoreWordUnaligned, | 229 reinterpret_cast<intptr_t>(&buffer[1]))); |
| 256 test->entry(), | |
| 257 reinterpret_cast<intptr_t>(&buffer[1]))); | |
| 258 EXPECT_EQ(0x78, buffer[1]); | 230 EXPECT_EQ(0x78, buffer[1]); |
| 259 EXPECT_EQ(0x56, buffer[2]); | 231 EXPECT_EQ(0x56, buffer[2]); |
| 260 EXPECT_EQ(0x34, buffer[3]); | 232 EXPECT_EQ(0x34, buffer[3]); |
| 261 EXPECT_EQ(0x12, buffer[4]); | 233 EXPECT_EQ(0x12, buffer[4]); |
| 262 | 234 |
| 263 EXPECT_EQ(0x12345678, | 235 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 264 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 236 StoreWordUnaligned, test->entry(), |
| 265 StoreWordUnaligned, | 237 reinterpret_cast<intptr_t>(&buffer[2]))); |
| 266 test->entry(), | |
| 267 reinterpret_cast<intptr_t>(&buffer[2]))); | |
| 268 EXPECT_EQ(0x78, buffer[2]); | 238 EXPECT_EQ(0x78, buffer[2]); |
| 269 EXPECT_EQ(0x56, buffer[3]); | 239 EXPECT_EQ(0x56, buffer[3]); |
| 270 EXPECT_EQ(0x34, buffer[4]); | 240 EXPECT_EQ(0x34, buffer[4]); |
| 271 EXPECT_EQ(0x12, buffer[5]); | 241 EXPECT_EQ(0x12, buffer[5]); |
| 272 | 242 |
| 273 EXPECT_EQ(0x12345678, | 243 EXPECT_EQ(0x12345678, EXECUTE_TEST_CODE_INTPTR_INTPTR( |
| 274 EXECUTE_TEST_CODE_INTPTR_INTPTR( | 244 StoreWordUnaligned, test->entry(), |
| 275 StoreWordUnaligned, | 245 reinterpret_cast<intptr_t>(&buffer[3]))); |
| 276 test->entry(), | |
| 277 reinterpret_cast<intptr_t>(&buffer[3]))); | |
| 278 EXPECT_EQ(0x78, buffer[3]); | 246 EXPECT_EQ(0x78, buffer[3]); |
| 279 EXPECT_EQ(0x56, buffer[4]); | 247 EXPECT_EQ(0x56, buffer[4]); |
| 280 EXPECT_EQ(0x34, buffer[5]); | 248 EXPECT_EQ(0x34, buffer[5]); |
| 281 EXPECT_EQ(0x12, buffer[6]); | 249 EXPECT_EQ(0x12, buffer[6]); |
| 282 } | 250 } |
| 283 | 251 |
| 284 | 252 |
| 285 ASSEMBLER_TEST_GENERATE(Vmov, assembler) { | 253 ASSEMBLER_TEST_GENERATE(Vmov, assembler) { |
| 286 if (TargetCPUFeatures::vfp_supported()) { | 254 if (TargetCPUFeatures::vfp_supported()) { |
| 287 __ mov(R3, Operand(43)); | 255 __ mov(R3, Operand(43)); |
| 288 __ mov(R1, Operand(41)); | 256 __ mov(R1, Operand(41)); |
| 289 __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43 | 257 __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43 |
| 290 __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41 | 258 __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41 |
| 291 __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41 | 259 __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41 |
| 292 __ vmovrs(R3, S5); // R3 = S5, R3 == 41 | 260 __ vmovrs(R3, S5); // R3 = S5, R3 == 41 |
| 293 __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41 | 261 __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41 |
| 294 __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41 | 262 __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41 |
| 295 __ vmovdr(D3, 1, R1); // D3[1] == S7 = R1, S6:S7 == 41:43 | 263 __ vmovdr(D3, 1, R1); // D3[1] == S7 = R1, S6:S7 == 41:43 |
| 296 __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43 | 264 __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43 |
| 297 __ sub(R0, R1, Operand(R0)); // 43-41 | 265 __ sub(R0, R1, Operand(R0)); // 43-41 |
| 298 } | 266 } |
| 299 __ bx(LR); | 267 __ bx(LR); |
| 300 } | 268 } |
| 301 | 269 |
| 302 | 270 |
| 303 ASSEMBLER_TEST_RUN(Vmov, test) { | 271 ASSEMBLER_TEST_RUN(Vmov, test) { |
| 304 EXPECT(test != NULL); | 272 EXPECT(test != NULL); |
| 305 if (TargetCPUFeatures::vfp_supported()) { | 273 if (TargetCPUFeatures::vfp_supported()) { |
| 306 typedef int (*Vmov)() DART_UNUSED; | 274 typedef int (*Vmov)() DART_UNUSED; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 321 } | 289 } |
| 322 __ bx(LR); | 290 __ bx(LR); |
| 323 } | 291 } |
| 324 | 292 |
| 325 | 293 |
| 326 ASSEMBLER_TEST_RUN(SingleVLoadStore, test) { | 294 ASSEMBLER_TEST_RUN(SingleVLoadStore, test) { |
| 327 EXPECT(test != NULL); | 295 EXPECT(test != NULL); |
| 328 if (TargetCPUFeatures::vfp_supported()) { | 296 if (TargetCPUFeatures::vfp_supported()) { |
| 329 typedef float (*SingleVLoadStore)() DART_UNUSED; | 297 typedef float (*SingleVLoadStore)() DART_UNUSED; |
| 330 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); | 298 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); |
| 331 EXPECT_FLOAT_EQ(2*12.3f, res, 0.001f); | 299 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f); |
| 332 } | 300 } |
| 333 } | 301 } |
| 334 | 302 |
| 335 | 303 |
| 336 ASSEMBLER_TEST_GENERATE(SingleVShiftLoadStore, assembler) { | 304 ASSEMBLER_TEST_GENERATE(SingleVShiftLoadStore, assembler) { |
| 337 if (TargetCPUFeatures::vfp_supported()) { | 305 if (TargetCPUFeatures::vfp_supported()) { |
| 338 __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f)); | 306 __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f)); |
| 339 __ mov(R2, Operand(SP)); | 307 __ mov(R2, Operand(SP)); |
| 340 // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex)); | 308 // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex)); |
| 341 // as: | 309 // as: |
| 342 __ mov(R1, Operand(kWordSize)); | 310 __ mov(R1, Operand(kWordSize)); |
| 343 __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex)); | 311 __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex)); |
| 344 __ vldrs(S0, Address(R2, (-kWordSize * 32))); | 312 __ vldrs(S0, Address(R2, (-kWordSize * 32))); |
| 345 __ vadds(S0, S0, S0); | 313 __ vadds(S0, S0, S0); |
| 346 __ vstrs(S0, Address(R2, (-kWordSize * 32))); | 314 __ vstrs(S0, Address(R2, (-kWordSize * 32))); |
| 347 // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex)); | 315 // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex)); |
| 348 // as: | 316 // as: |
| 349 __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex)); | 317 __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex)); |
| 350 } | 318 } |
| 351 __ bx(LR); | 319 __ bx(LR); |
| 352 } | 320 } |
| 353 | 321 |
| 354 | 322 |
| 355 ASSEMBLER_TEST_RUN(SingleVShiftLoadStore, test) { | 323 ASSEMBLER_TEST_RUN(SingleVShiftLoadStore, test) { |
| 356 EXPECT(test != NULL); | 324 EXPECT(test != NULL); |
| 357 if (TargetCPUFeatures::vfp_supported()) { | 325 if (TargetCPUFeatures::vfp_supported()) { |
| 358 typedef float (*SingleVLoadStore)() DART_UNUSED; | 326 typedef float (*SingleVLoadStore)() DART_UNUSED; |
| 359 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); | 327 float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry()); |
| 360 EXPECT_FLOAT_EQ(2*12.3f, res, 0.001f); | 328 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f); |
| 361 } | 329 } |
| 362 } | 330 } |
| 363 | 331 |
| 364 | 332 |
| 365 ASSEMBLER_TEST_GENERATE(DoubleVLoadStore, assembler) { | 333 ASSEMBLER_TEST_GENERATE(DoubleVLoadStore, assembler) { |
| 366 if (TargetCPUFeatures::vfp_supported()) { | 334 if (TargetCPUFeatures::vfp_supported()) { |
| 367 int64_t value = bit_cast<int64_t, double>(12.3); | 335 int64_t value = bit_cast<int64_t, double>(12.3); |
| 368 __ LoadImmediate(R0, Utils::Low32Bits(value)); | 336 __ LoadImmediate(R0, Utils::Low32Bits(value)); |
| 369 __ LoadImmediate(R1, Utils::High32Bits(value)); | 337 __ LoadImmediate(R1, Utils::High32Bits(value)); |
| 370 __ mov(R2, Operand(SP)); | 338 __ mov(R2, Operand(SP)); |
| 371 __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex)); | 339 __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex)); |
| 372 __ str(R1, Address(R2, (-kWordSize * 29))); | 340 __ str(R1, Address(R2, (-kWordSize * 29))); |
| 373 __ vldrd(D0, Address(R2, (-kWordSize * 30))); | 341 __ vldrd(D0, Address(R2, (-kWordSize * 30))); |
| 374 __ vaddd(D0, D0, D0); | 342 __ vaddd(D0, D0, D0); |
| 375 __ vstrd(D0, Address(R2, (-kWordSize * 30))); | 343 __ vstrd(D0, Address(R2, (-kWordSize * 30))); |
| 376 __ ldr(R1, Address(R2, (-kWordSize * 29))); | 344 __ ldr(R1, Address(R2, (-kWordSize * 29))); |
| 377 __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex)); | 345 __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex)); |
| 378 } | 346 } |
| 379 __ bx(LR); | 347 __ bx(LR); |
| 380 } | 348 } |
| 381 | 349 |
| 382 | 350 |
| 383 ASSEMBLER_TEST_RUN(DoubleVLoadStore, test) { | 351 ASSEMBLER_TEST_RUN(DoubleVLoadStore, test) { |
| 384 EXPECT(test != NULL); | 352 EXPECT(test != NULL); |
| 385 if (TargetCPUFeatures::vfp_supported()) { | 353 if (TargetCPUFeatures::vfp_supported()) { |
| 386 typedef double (*DoubleVLoadStore)() DART_UNUSED; | 354 typedef double (*DoubleVLoadStore)() DART_UNUSED; |
| 387 float res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry()); | 355 float res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry()); |
| 388 EXPECT_FLOAT_EQ(2*12.3f, res, 0.001f); | 356 EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f); |
| 389 } | 357 } |
| 390 } | 358 } |
| 391 | 359 |
| 392 | 360 |
| 393 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { | 361 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { |
| 394 if (TargetCPUFeatures::vfp_supported()) { | 362 if (TargetCPUFeatures::vfp_supported()) { |
| 395 __ LoadSImmediate(S0, 12.3f); | 363 __ LoadSImmediate(S0, 12.3f); |
| 396 __ LoadSImmediate(S1, 3.4f); | 364 __ LoadSImmediate(S1, 3.4f); |
| 397 __ vnegs(S0, S0); // -12.3f | 365 __ vnegs(S0, S0); // -12.3f |
| 398 __ vabss(S0, S0); // 12.3f | 366 __ vabss(S0, S0); // 12.3f |
| 399 __ vadds(S0, S0, S1); // 15.7f | 367 __ vadds(S0, S0, S1); // 15.7f |
| 400 __ vmuls(S0, S0, S1); // 53.38f | 368 __ vmuls(S0, S0, S1); // 53.38f |
| 401 __ vsubs(S0, S0, S1); // 49.98f | 369 __ vsubs(S0, S0, S1); // 49.98f |
| 402 __ vdivs(S0, S0, S1); // 14.7f | 370 __ vdivs(S0, S0, S1); // 14.7f |
| 403 __ vsqrts(S0, S0); // 3.8340579f | 371 __ vsqrts(S0, S0); // 3.8340579f |
| 404 } | 372 } |
| 405 __ bx(LR); | 373 __ bx(LR); |
| 406 } | 374 } |
| 407 | 375 |
| 408 | 376 |
| 409 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { | 377 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { |
| 410 EXPECT(test != NULL); | 378 EXPECT(test != NULL); |
| 411 if (TargetCPUFeatures::vfp_supported()) { | 379 if (TargetCPUFeatures::vfp_supported()) { |
| 412 typedef float (*SingleFPOperations)() DART_UNUSED; | 380 typedef float (*SingleFPOperations)() DART_UNUSED; |
| 413 float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry()); | 381 float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry()); |
| 414 EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f); | 382 EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f); |
| 415 } | 383 } |
| 416 } | 384 } |
| 417 | 385 |
| 418 | 386 |
| 419 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { | 387 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { |
| 420 if (TargetCPUFeatures::vfp_supported()) { | 388 if (TargetCPUFeatures::vfp_supported()) { |
| 421 __ LoadDImmediate(D0, 12.3, R0); | 389 __ LoadDImmediate(D0, 12.3, R0); |
| 422 __ LoadDImmediate(D1, 3.4, R0); | 390 __ LoadDImmediate(D1, 3.4, R0); |
| 423 __ vnegd(D0, D0); // -12.3 | 391 __ vnegd(D0, D0); // -12.3 |
| 424 __ vabsd(D0, D0); // 12.3 | 392 __ vabsd(D0, D0); // 12.3 |
| 425 __ vaddd(D0, D0, D1); // 15.7 | 393 __ vaddd(D0, D0, D1); // 15.7 |
| 426 __ vmuld(D0, D0, D1); // 53.38 | 394 __ vmuld(D0, D0, D1); // 53.38 |
| 427 __ vsubd(D0, D0, D1); // 49.98 | 395 __ vsubd(D0, D0, D1); // 49.98 |
| 428 __ vdivd(D0, D0, D1); // 14.7 | 396 __ vdivd(D0, D0, D1); // 14.7 |
| 429 __ vsqrtd(D0, D0); // 3.8340579 | 397 __ vsqrtd(D0, D0); // 3.8340579 |
| 430 } | 398 } |
| 431 __ bx(LR); | 399 __ bx(LR); |
| 432 } | 400 } |
| 433 | 401 |
| 434 | 402 |
| 435 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { | 403 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { |
| 436 EXPECT(test != NULL); | 404 EXPECT(test != NULL); |
| 437 if (TargetCPUFeatures::vfp_supported()) { | 405 if (TargetCPUFeatures::vfp_supported()) { |
| 438 typedef double (*DoubleFPOperations)() DART_UNUSED; | 406 typedef double (*DoubleFPOperations)() DART_UNUSED; |
| 439 double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry()); | 407 double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 __ vcvtdi(D0, S3); | 440 __ vcvtdi(D0, S3); |
| 473 } | 441 } |
| 474 __ bx(LR); | 442 __ bx(LR); |
| 475 } | 443 } |
| 476 | 444 |
| 477 | 445 |
| 478 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { | 446 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { |
| 479 EXPECT(test != NULL); | 447 EXPECT(test != NULL); |
| 480 if (TargetCPUFeatures::vfp_supported()) { | 448 if (TargetCPUFeatures::vfp_supported()) { |
| 481 typedef double (*IntToDoubleConversionCode)() DART_UNUSED; | 449 typedef double (*IntToDoubleConversionCode)() DART_UNUSED; |
| 482 double res = EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode, | 450 double res = |
| 483 test->entry()); | 451 EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode, test->entry()); |
| 484 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 452 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
| 485 } | 453 } |
| 486 } | 454 } |
| 487 | 455 |
| 488 | 456 |
| 489 ASSEMBLER_TEST_GENERATE(LongToDoubleConversion, assembler) { | 457 ASSEMBLER_TEST_GENERATE(LongToDoubleConversion, assembler) { |
| 490 if (TargetCPUFeatures::vfp_supported()) { | 458 if (TargetCPUFeatures::vfp_supported()) { |
| 491 int64_t value = 60000000000LL; | 459 int64_t value = 60000000000LL; |
| 492 __ LoadImmediate(R0, Utils::Low32Bits(value)); | 460 __ LoadImmediate(R0, Utils::Low32Bits(value)); |
| 493 __ LoadImmediate(R1, Utils::High32Bits(value)); | 461 __ LoadImmediate(R1, Utils::High32Bits(value)); |
| 494 __ vmovsr(S0, R0); | 462 __ vmovsr(S0, R0); |
| 495 __ vmovsr(S2, R1); | 463 __ vmovsr(S2, R1); |
| 496 __ vcvtdu(D0, S0); | 464 __ vcvtdu(D0, S0); |
| 497 __ vcvtdi(D1, S2); | 465 __ vcvtdi(D1, S2); |
| 498 __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0); | 466 __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0); |
| 499 __ vmlad(D0, D1, D2); | 467 __ vmlad(D0, D1, D2); |
| 500 } | 468 } |
| 501 __ bx(LR); | 469 __ bx(LR); |
| 502 } | 470 } |
| 503 | 471 |
| 504 | 472 |
| 505 ASSEMBLER_TEST_RUN(LongToDoubleConversion, test) { | 473 ASSEMBLER_TEST_RUN(LongToDoubleConversion, test) { |
| 506 EXPECT(test != NULL); | 474 EXPECT(test != NULL); |
| 507 if (TargetCPUFeatures::vfp_supported()) { | 475 if (TargetCPUFeatures::vfp_supported()) { |
| 508 typedef double (*LongToDoubleConversionCode)() DART_UNUSED; | 476 typedef double (*LongToDoubleConversionCode)() DART_UNUSED; |
| 509 double res = EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode, | 477 double res = |
| 510 test->entry()); | 478 EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode, test->entry()); |
| 511 EXPECT_FLOAT_EQ(60000000000.0, res, 0.001); | 479 EXPECT_FLOAT_EQ(60000000000.0, res, 0.001); |
| 512 } | 480 } |
| 513 } | 481 } |
| 514 | 482 |
| 515 | 483 |
| 516 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) { | 484 ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) { |
| 517 if (TargetCPUFeatures::vfp_supported()) { | 485 if (TargetCPUFeatures::vfp_supported()) { |
| 518 __ mov(R3, Operand(6)); | 486 __ mov(R3, Operand(6)); |
| 519 __ vmovsr(S3, R3); | 487 __ vmovsr(S3, R3); |
| 520 __ vcvtsi(S0, S3); | 488 __ vcvtsi(S0, S3); |
| 521 } | 489 } |
| 522 __ bx(LR); | 490 __ bx(LR); |
| 523 } | 491 } |
| 524 | 492 |
| 525 | 493 |
| 526 ASSEMBLER_TEST_RUN(IntToFloatConversion, test) { | 494 ASSEMBLER_TEST_RUN(IntToFloatConversion, test) { |
| 527 EXPECT(test != NULL); | 495 EXPECT(test != NULL); |
| 528 if (TargetCPUFeatures::vfp_supported()) { | 496 if (TargetCPUFeatures::vfp_supported()) { |
| 529 typedef float (*IntToFloatConversionCode)() DART_UNUSED; | 497 typedef float (*IntToFloatConversionCode)() DART_UNUSED; |
| 530 float res = EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, | 498 float res = |
| 531 test->entry()); | 499 EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, test->entry()); |
| 532 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 500 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
| 533 } | 501 } |
| 534 } | 502 } |
| 535 | 503 |
| 536 | 504 |
| 537 ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) { | 505 ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) { |
| 538 if (TargetCPUFeatures::vfp_supported()) { | 506 if (TargetCPUFeatures::vfp_supported()) { |
| 539 __ vcvtis(S1, S0); | 507 __ vcvtis(S1, S0); |
| 540 __ vmovrs(R0, S1); | 508 __ vmovrs(R0, S1); |
| 541 } | 509 } |
| 542 __ bx(LR); | 510 __ bx(LR); |
| 543 } | 511 } |
| 544 | 512 |
| 545 | 513 |
| 546 ASSEMBLER_TEST_RUN(FloatToIntConversion, test) { | 514 ASSEMBLER_TEST_RUN(FloatToIntConversion, test) { |
| 547 EXPECT(test != NULL); | 515 EXPECT(test != NULL); |
| 548 if (TargetCPUFeatures::vfp_supported()) { | 516 if (TargetCPUFeatures::vfp_supported()) { |
| 549 typedef int (*FloatToIntConversion)(float arg) DART_UNUSED; | 517 typedef int (*FloatToIntConversion)(float arg) DART_UNUSED; |
| 550 EXPECT_EQ(12, | 518 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), |
| 551 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), | 519 12.8f)); |
| 552 12.8f)); | 520 EXPECT_EQ(INT_MIN, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, |
| 553 EXPECT_EQ(INT_MIN, | 521 test->entry(), -FLT_MAX)); |
| 554 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), | 522 EXPECT_EQ(INT_MAX, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, |
| 555 -FLT_MAX)); | 523 test->entry(), FLT_MAX)); |
| 556 EXPECT_EQ(INT_MAX, | |
| 557 EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(), | |
| 558 FLT_MAX)); | |
| 559 } | 524 } |
| 560 } | 525 } |
| 561 | 526 |
| 562 | 527 |
| 563 ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) { | 528 ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) { |
| 564 if (TargetCPUFeatures::vfp_supported()) { | 529 if (TargetCPUFeatures::vfp_supported()) { |
| 565 __ vcvtid(S0, D0); | 530 __ vcvtid(S0, D0); |
| 566 __ vmovrs(R0, S0); | 531 __ vmovrs(R0, S0); |
| 567 } | 532 } |
| 568 __ bx(LR); | 533 __ bx(LR); |
| 569 } | 534 } |
| 570 | 535 |
| 571 | 536 |
| 572 ASSEMBLER_TEST_RUN(DoubleToIntConversion, test) { | 537 ASSEMBLER_TEST_RUN(DoubleToIntConversion, test) { |
| 573 if (TargetCPUFeatures::vfp_supported()) { | 538 if (TargetCPUFeatures::vfp_supported()) { |
| 574 typedef int (*DoubleToIntConversion)(double arg) DART_UNUSED; | 539 typedef int (*DoubleToIntConversion)(double arg) DART_UNUSED; |
| 575 EXPECT(test != NULL); | 540 EXPECT(test != NULL); |
| 576 EXPECT_EQ(12, | 541 EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, |
| 577 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), | 542 test->entry(), 12.8)); |
| 578 12.8)); | 543 EXPECT_EQ(INT_MIN, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, |
| 579 EXPECT_EQ(INT_MIN, | 544 test->entry(), -DBL_MAX)); |
| 580 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), | 545 EXPECT_EQ(INT_MAX, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, |
| 581 -DBL_MAX)); | 546 test->entry(), DBL_MAX)); |
| 582 EXPECT_EQ(INT_MAX, | |
| 583 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), | |
| 584 DBL_MAX)); | |
| 585 } | 547 } |
| 586 } | 548 } |
| 587 | 549 |
| 588 | 550 |
| 589 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { | 551 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { |
| 590 if (TargetCPUFeatures::vfp_supported()) { | 552 if (TargetCPUFeatures::vfp_supported()) { |
| 591 __ LoadSImmediate(S2, 12.8f); | 553 __ LoadSImmediate(S2, 12.8f); |
| 592 __ vcvtds(D0, S2); | 554 __ vcvtds(D0, S2); |
| 593 } | 555 } |
| 594 __ bx(LR); | 556 __ bx(LR); |
| 595 } | 557 } |
| 596 | 558 |
| 597 | 559 |
| 598 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { | 560 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { |
| 599 if (TargetCPUFeatures::vfp_supported()) { | 561 if (TargetCPUFeatures::vfp_supported()) { |
| 600 typedef double (*FloatToDoubleConversionCode)() DART_UNUSED; | 562 typedef double (*FloatToDoubleConversionCode)() DART_UNUSED; |
| 601 EXPECT(test != NULL); | 563 EXPECT(test != NULL); |
| 602 double res = EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, | 564 double res = |
| 603 test->entry()); | 565 EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, test->entry()); |
| 604 EXPECT_FLOAT_EQ(12.8, res, 0.001); | 566 EXPECT_FLOAT_EQ(12.8, res, 0.001); |
| 605 } | 567 } |
| 606 } | 568 } |
| 607 | 569 |
| 608 | 570 |
| 609 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { | 571 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { |
| 610 if (TargetCPUFeatures::vfp_supported()) { | 572 if (TargetCPUFeatures::vfp_supported()) { |
| 611 __ LoadDImmediate(D1, 12.8, R0); | 573 __ LoadDImmediate(D1, 12.8, R0); |
| 612 __ vcvtsd(S0, D1); | 574 __ vcvtsd(S0, D1); |
| 613 } | 575 } |
| 614 __ bx(LR); | 576 __ bx(LR); |
| 615 } | 577 } |
| 616 | 578 |
| 617 | 579 |
| 618 ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) { | 580 ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) { |
| 619 EXPECT(test != NULL); | 581 EXPECT(test != NULL); |
| 620 if (TargetCPUFeatures::vfp_supported()) { | 582 if (TargetCPUFeatures::vfp_supported()) { |
| 621 typedef float (*DoubleToFloatConversionCode)() DART_UNUSED; | 583 typedef float (*DoubleToFloatConversionCode)() DART_UNUSED; |
| 622 float res = EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode, | 584 float res = |
| 623 test->entry()); | 585 EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode, test->entry()); |
| 624 EXPECT_FLOAT_EQ(12.8, res, 0.001); | 586 EXPECT_FLOAT_EQ(12.8, res, 0.001); |
| 625 } | 587 } |
| 626 } | 588 } |
| 627 | 589 |
| 628 | 590 |
| 629 ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) { | 591 ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) { |
| 630 if (TargetCPUFeatures::vfp_supported()) { | 592 if (TargetCPUFeatures::vfp_supported()) { |
| 631 // Test 12.3f vs 12.5f. | 593 // Test 12.3f vs 12.5f. |
| 632 __ LoadSImmediate(S0, 12.3f); | 594 __ LoadSImmediate(S0, 12.3f); |
| 633 __ LoadSImmediate(S1, 12.5f); | 595 __ LoadSImmediate(S1, 12.5f); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 762 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
| 801 __ mov(R0, Operand(40)); | 763 __ mov(R0, Operand(40)); |
| 802 __ mov(R1, Operand(42)); | 764 __ mov(R1, Operand(42)); |
| 803 __ Push(R0); | 765 __ Push(R0); |
| 804 Label retry; | 766 Label retry; |
| 805 __ Bind(&retry); | 767 __ Bind(&retry); |
| 806 __ ldrex(R0, SP); | 768 __ ldrex(R0, SP); |
| 807 __ strex(IP, R1, SP); // IP == 0, success | 769 __ strex(IP, R1, SP); // IP == 0, success |
| 808 __ tst(IP, Operand(0)); | 770 __ tst(IP, Operand(0)); |
| 809 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex. | 771 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex. |
| 810 __ Pop(R0); // 42 | 772 __ Pop(R0); // 42 |
| 811 } | 773 } |
| 812 __ bx(LR); | 774 __ bx(LR); |
| 813 } | 775 } |
| 814 | 776 |
| 815 | 777 |
| 816 ASSEMBLER_TEST_RUN(Semaphore, test) { | 778 ASSEMBLER_TEST_RUN(Semaphore, test) { |
| 817 EXPECT(test != NULL); | 779 EXPECT(test != NULL); |
| 818 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 780 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
| 819 typedef int (*Semaphore)() DART_UNUSED; | 781 typedef int (*Semaphore)() DART_UNUSED; |
| 820 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Semaphore, test->entry())); | 782 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Semaphore, test->entry())); |
| 821 } | 783 } |
| 822 } | 784 } |
| 823 | 785 |
| 824 | 786 |
| 825 ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) { | 787 ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) { |
| 826 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 788 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
| 827 __ mov(R0, Operand(40)); | 789 __ mov(R0, Operand(40)); |
| 828 __ mov(R1, Operand(42)); | 790 __ mov(R1, Operand(42)); |
| 829 __ Push(R0); | 791 __ Push(R0); |
| 830 __ ldrex(R0, SP); | 792 __ ldrex(R0, SP); |
| 831 __ clrex(); // Simulate a context switch. | 793 __ clrex(); // Simulate a context switch. |
| 832 __ strex(IP, R1, SP); // IP == 1, failure | 794 __ strex(IP, R1, SP); // IP == 1, failure |
| 833 __ Pop(R0); // 40 | 795 __ Pop(R0); // 40 |
| 834 __ add(R0, R0, Operand(IP)); | 796 __ add(R0, R0, Operand(IP)); |
| 835 } | 797 } |
| 836 __ bx(LR); | 798 __ bx(LR); |
| 837 } | 799 } |
| 838 | 800 |
| 839 | 801 |
| 840 ASSEMBLER_TEST_RUN(FailedSemaphore, test) { | 802 ASSEMBLER_TEST_RUN(FailedSemaphore, test) { |
| 841 EXPECT(test != NULL); | 803 EXPECT(test != NULL); |
| 842 if (TargetCPUFeatures::arm_version() != ARMv5TE) { | 804 if (TargetCPUFeatures::arm_version() != ARMv5TE) { |
| 843 typedef int (*FailedSemaphore)() DART_UNUSED; | 805 typedef int (*FailedSemaphore)() DART_UNUSED; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarry, test->entry())); | 841 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarry, test->entry())); |
| 880 } | 842 } |
| 881 | 843 |
| 882 | 844 |
| 883 ASSEMBLER_TEST_GENERATE(AddCarryInOut, assembler) { | 845 ASSEMBLER_TEST_GENERATE(AddCarryInOut, assembler) { |
| 884 __ LoadImmediate(R2, 0xFFFFFFFF); | 846 __ LoadImmediate(R2, 0xFFFFFFFF); |
| 885 __ mov(R1, Operand(1)); | 847 __ mov(R1, Operand(1)); |
| 886 __ mov(R0, Operand(0)); | 848 __ mov(R0, Operand(0)); |
| 887 __ adds(IP, R2, Operand(R1)); // c_out = 1. | 849 __ adds(IP, R2, Operand(R1)); // c_out = 1. |
| 888 __ adcs(IP, R2, Operand(R0)); // c_in = 1, c_out = 1. | 850 __ adcs(IP, R2, Operand(R0)); // c_in = 1, c_out = 1. |
| 889 __ adc(R0, R0, Operand(R0)); // c_in = 1. | 851 __ adc(R0, R0, Operand(R0)); // c_in = 1. |
| 890 __ bx(LR); | 852 __ bx(LR); |
| 891 } | 853 } |
| 892 | 854 |
| 893 | 855 |
| 894 ASSEMBLER_TEST_RUN(AddCarryInOut, test) { | 856 ASSEMBLER_TEST_RUN(AddCarryInOut, test) { |
| 895 EXPECT(test != NULL); | 857 EXPECT(test != NULL); |
| 896 typedef int (*AddCarryInOut)() DART_UNUSED; | 858 typedef int (*AddCarryInOut)() DART_UNUSED; |
| 897 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarryInOut, test->entry())); | 859 EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(AddCarryInOut, test->entry())); |
| 898 } | 860 } |
| 899 | 861 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 913 typedef int (*SubCarry)() DART_UNUSED; | 875 typedef int (*SubCarry)() DART_UNUSED; |
| 914 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarry, test->entry())); | 876 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarry, test->entry())); |
| 915 } | 877 } |
| 916 | 878 |
| 917 | 879 |
| 918 ASSEMBLER_TEST_GENERATE(SubCarryInOut, assembler) { | 880 ASSEMBLER_TEST_GENERATE(SubCarryInOut, assembler) { |
| 919 __ mov(R1, Operand(1)); | 881 __ mov(R1, Operand(1)); |
| 920 __ mov(R0, Operand(0)); | 882 __ mov(R0, Operand(0)); |
| 921 __ subs(IP, R0, Operand(R1)); // c_out = 1. | 883 __ subs(IP, R0, Operand(R1)); // c_out = 1. |
| 922 __ sbcs(IP, R0, Operand(R0)); // c_in = 1, c_out = 1. | 884 __ sbcs(IP, R0, Operand(R0)); // c_in = 1, c_out = 1. |
| 923 __ sbc(R0, R0, Operand(R0)); // c_in = 1. | 885 __ sbc(R0, R0, Operand(R0)); // c_in = 1. |
| 924 __ bx(LR); | 886 __ bx(LR); |
| 925 } | 887 } |
| 926 | 888 |
| 927 | 889 |
| 928 ASSEMBLER_TEST_RUN(SubCarryInOut, test) { | 890 ASSEMBLER_TEST_RUN(SubCarryInOut, test) { |
| 929 EXPECT(test != NULL); | 891 EXPECT(test != NULL); |
| 930 typedef int (*SubCarryInOut)() DART_UNUSED; | 892 typedef int (*SubCarryInOut)() DART_UNUSED; |
| 931 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarryInOut, test->entry())); | 893 EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT32(SubCarryInOut, test->entry())); |
| 932 } | 894 } |
| 933 | 895 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 961 | 923 |
| 962 ASSEMBLER_TEST_RUN(AndOrr, test) { | 924 ASSEMBLER_TEST_RUN(AndOrr, test) { |
| 963 EXPECT(test != NULL); | 925 EXPECT(test != NULL); |
| 964 typedef int (*AndOrr)() DART_UNUSED; | 926 typedef int (*AndOrr)() DART_UNUSED; |
| 965 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AndOrr, test->entry())); | 927 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(AndOrr, test->entry())); |
| 966 } | 928 } |
| 967 | 929 |
| 968 | 930 |
| 969 ASSEMBLER_TEST_GENERATE(Orrs, assembler) { | 931 ASSEMBLER_TEST_GENERATE(Orrs, assembler) { |
| 970 __ mov(R0, Operand(0)); | 932 __ mov(R0, Operand(0)); |
| 971 __ tst(R0, Operand(R1)); // Set zero-flag. | 933 __ tst(R0, Operand(R1)); // Set zero-flag. |
| 972 __ orrs(R0, R0, Operand(1)); // Clear zero-flag. | 934 __ orrs(R0, R0, Operand(1)); // Clear zero-flag. |
| 973 __ bx(LR, EQ); | 935 __ bx(LR, EQ); |
| 974 __ mov(R0, Operand(42)); | 936 __ mov(R0, Operand(42)); |
| 975 __ bx(LR, NE); // Only this return should fire. | 937 __ bx(LR, NE); // Only this return should fire. |
| 976 __ mov(R0, Operand(2)); | 938 __ mov(R0, Operand(2)); |
| 977 __ bx(LR); | 939 __ bx(LR); |
| 978 } | 940 } |
| 979 | 941 |
| 980 | 942 |
| 981 ASSEMBLER_TEST_RUN(Orrs, test) { | 943 ASSEMBLER_TEST_RUN(Orrs, test) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1002 | 964 |
| 1003 | 965 |
| 1004 ASSEMBLER_TEST_GENERATE(QuotientRemainder, assembler) { | 966 ASSEMBLER_TEST_GENERATE(QuotientRemainder, assembler) { |
| 1005 if (TargetCPUFeatures::vfp_supported()) { | 967 if (TargetCPUFeatures::vfp_supported()) { |
| 1006 __ vmovsr(S2, R0); | 968 __ vmovsr(S2, R0); |
| 1007 __ vmovsr(S4, R2); | 969 __ vmovsr(S4, R2); |
| 1008 __ vcvtdi(D1, S2); | 970 __ vcvtdi(D1, S2); |
| 1009 __ vcvtdi(D2, S4); | 971 __ vcvtdi(D2, S4); |
| 1010 __ vdivd(D0, D1, D2); | 972 __ vdivd(D0, D1, D2); |
| 1011 __ vcvtid(S0, D0); | 973 __ vcvtid(S0, D0); |
| 1012 __ vmovrs(R1, S0); // r1 = r0/r2 | 974 __ vmovrs(R1, S0); // r1 = r0/r2 |
| 1013 __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2 | 975 __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2 |
| 1014 } | 976 } |
| 1015 __ bx(LR); | 977 __ bx(LR); |
| 1016 } | 978 } |
| 1017 | 979 |
| 1018 | 980 |
| 1019 ASSEMBLER_TEST_RUN(QuotientRemainder, test) { | 981 ASSEMBLER_TEST_RUN(QuotientRemainder, test) { |
| 1020 EXPECT(test != NULL); | 982 EXPECT(test != NULL); |
| 1021 if (TargetCPUFeatures::vfp_supported()) { | 983 if (TargetCPUFeatures::vfp_supported()) { |
| 1022 typedef int64_t (*QuotientRemainder) | 984 typedef int64_t (*QuotientRemainder)(int64_t dividend, int64_t divisor) |
| 1023 (int64_t dividend, int64_t divisor) DART_UNUSED; | 985 DART_UNUSED; |
| 1024 EXPECT_EQ(0x1000400000da8LL, | 986 EXPECT_EQ(0x1000400000da8LL, |
| 1025 EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(), | 987 EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(), |
| 1026 0x12345678, 0x1234)); | 988 0x12345678, 0x1234)); |
| 1027 } | 989 } |
| 1028 } | 990 } |
| 1029 | 991 |
| 1030 | 992 |
| 1031 ASSEMBLER_TEST_GENERATE(Multiply64To64, assembler) { | 993 ASSEMBLER_TEST_GENERATE(Multiply64To64, assembler) { |
| 1032 __ Push(R4); | 994 __ Push(R4); |
| 1033 __ mov(IP, Operand(R0)); | 995 __ mov(IP, Operand(R0)); |
| 1034 __ mul(R4, R2, R1); | 996 __ mul(R4, R2, R1); |
| 1035 __ umull(R0, R1, R2, IP); | 997 __ umull(R0, R1, R2, IP); |
| 1036 __ mla(R2, IP, R3, R4); | 998 __ mla(R2, IP, R3, R4); |
| 1037 __ add(R1, R2, Operand(R1)); | 999 __ add(R1, R2, Operand(R1)); |
| 1038 __ Pop(R4); | 1000 __ Pop(R4); |
| 1039 __ bx(LR); | 1001 __ bx(LR); |
| 1040 } | 1002 } |
| 1041 | 1003 |
| 1042 | 1004 |
| 1043 ASSEMBLER_TEST_RUN(Multiply64To64, test) { | 1005 ASSEMBLER_TEST_RUN(Multiply64To64, test) { |
| 1044 EXPECT(test != NULL); | 1006 EXPECT(test != NULL); |
| 1045 typedef int64_t (*Multiply64To64) | 1007 typedef int64_t (*Multiply64To64)(int64_t operand0, int64_t operand1) |
| 1046 (int64_t operand0, int64_t operand1) DART_UNUSED; | 1008 DART_UNUSED; |
| 1047 EXPECT_EQ(6, | 1009 EXPECT_EQ(6, |
| 1048 EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2)); | 1010 EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2)); |
| 1049 } | 1011 } |
| 1050 | 1012 |
| 1051 | 1013 |
| 1052 ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) { | 1014 ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) { |
| 1053 __ smull(R0, R1, R0, R2); | 1015 __ smull(R0, R1, R0, R2); |
| 1054 __ bx(LR); | 1016 __ bx(LR); |
| 1055 } | 1017 } |
| 1056 | 1018 |
| 1057 | 1019 |
| 1058 ASSEMBLER_TEST_RUN(Multiply32To64, test) { | 1020 ASSEMBLER_TEST_RUN(Multiply32To64, test) { |
| 1059 EXPECT(test != NULL); | 1021 EXPECT(test != NULL); |
| 1060 typedef int64_t (*Multiply32To64) | 1022 typedef int64_t (*Multiply32To64)(int64_t operand0, int64_t operand1) |
| 1061 (int64_t operand0, int64_t operand1) DART_UNUSED; | 1023 DART_UNUSED; |
| 1062 EXPECT_EQ(6, | 1024 EXPECT_EQ(6, |
| 1063 EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2)); | 1025 EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2)); |
| 1064 } | 1026 } |
| 1065 | 1027 |
| 1066 | 1028 |
| 1067 ASSEMBLER_TEST_GENERATE(MultiplyAccumAccum32To64, assembler) { | 1029 ASSEMBLER_TEST_GENERATE(MultiplyAccumAccum32To64, assembler) { |
| 1068 __ umaal(R0, R1, R2, R3); | 1030 __ umaal(R0, R1, R2, R3); |
| 1069 __ bx(LR); | 1031 __ bx(LR); |
| 1070 } | 1032 } |
| 1071 | 1033 |
| 1072 | 1034 |
| 1073 ASSEMBLER_TEST_RUN(MultiplyAccumAccum32To64, test) { | 1035 ASSEMBLER_TEST_RUN(MultiplyAccumAccum32To64, test) { |
| 1074 EXPECT(test != NULL); | 1036 EXPECT(test != NULL); |
| 1075 typedef int64_t (*MultiplyAccumAccum32To64) | 1037 typedef int64_t (*MultiplyAccumAccum32To64)(int64_t operand0, |
| 1076 (int64_t operand0, int64_t operand1) DART_UNUSED; | 1038 int64_t operand1) DART_UNUSED; |
| 1077 EXPECT_EQ(3 + 7 + 5 * 11, | 1039 EXPECT_EQ(3 + 7 + 5 * 11, |
| 1078 EXECUTE_TEST_CODE_INT64_LL(MultiplyAccumAccum32To64, test->entry(), | 1040 EXECUTE_TEST_CODE_INT64_LL(MultiplyAccumAccum32To64, test->entry(), |
| 1079 (3LL << 32) + 7, (5LL << 32) + 11)); | 1041 (3LL << 32) + 7, (5LL << 32) + 11)); |
| 1080 } | 1042 } |
| 1081 | 1043 |
| 1082 | 1044 |
| 1083 ASSEMBLER_TEST_GENERATE(Clz, assembler) { | 1045 ASSEMBLER_TEST_GENERATE(Clz, assembler) { |
| 1084 Label error; | 1046 Label error; |
| 1085 | 1047 |
| 1086 __ mov(R0, Operand(0)); | 1048 __ mov(R0, Operand(0)); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 | 1289 |
| 1328 ASSEMBLER_TEST_RUN(Ldrh1, test) { | 1290 ASSEMBLER_TEST_RUN(Ldrh1, test) { |
| 1329 EXPECT(test != NULL); | 1291 EXPECT(test != NULL); |
| 1330 typedef int (*Tst)() DART_UNUSED; | 1292 typedef int (*Tst)() DART_UNUSED; |
| 1331 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1293 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 1332 } | 1294 } |
| 1333 | 1295 |
| 1334 | 1296 |
| 1335 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) { | 1297 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) { |
| 1336 __ mov(IP, Operand(SP)); | 1298 __ mov(IP, Operand(SP)); |
| 1337 __ sub(SP, SP, Operand(kWordSize*30)); | 1299 __ sub(SP, SP, Operand(kWordSize * 30)); |
| 1338 __ strd(R2, R3, SP, 0); | 1300 __ strd(R2, R3, SP, 0); |
| 1339 __ strd(R0, R1, IP, (-kWordSize*28)); | 1301 __ strd(R0, R1, IP, (-kWordSize * 28)); |
| 1340 __ ldrd(R2, R3, IP, (-kWordSize*28)); | 1302 __ ldrd(R2, R3, IP, (-kWordSize * 28)); |
| 1341 __ ldrd(R0, R1, SP, 0); | 1303 __ ldrd(R0, R1, SP, 0); |
| 1342 __ add(SP, SP, Operand(kWordSize*30)); | 1304 __ add(SP, SP, Operand(kWordSize * 30)); |
| 1343 __ sub(R0, R0, Operand(R2)); | 1305 __ sub(R0, R0, Operand(R2)); |
| 1344 __ add(R1, R1, Operand(R3)); | 1306 __ add(R1, R1, Operand(R3)); |
| 1345 __ bx(LR); | 1307 __ bx(LR); |
| 1346 } | 1308 } |
| 1347 | 1309 |
| 1348 | 1310 |
| 1349 ASSEMBLER_TEST_RUN(Ldrd, test) { | 1311 ASSEMBLER_TEST_RUN(Ldrd, test) { |
| 1350 EXPECT(test != NULL); | 1312 EXPECT(test != NULL); |
| 1351 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3) DART_UNUSED; | 1313 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3) DART_UNUSED; |
| 1352 EXPECT_EQ(0x0000444400002222LL, EXECUTE_TEST_CODE_INT64_LL( | 1314 EXPECT_EQ(0x0000444400002222LL, |
| 1353 Tst, test->entry(), 0x0000111100000000LL, 0x0000333300002222LL)); | 1315 EXECUTE_TEST_CODE_INT64_LL(Tst, test->entry(), 0x0000111100000000LL, |
| 1316 0x0000333300002222LL)); |
| 1354 } | 1317 } |
| 1355 | 1318 |
| 1356 | 1319 |
| 1357 ASSEMBLER_TEST_GENERATE(Ldm_stm_da, assembler) { | 1320 ASSEMBLER_TEST_GENERATE(Ldm_stm_da, assembler) { |
| 1358 __ mov(R0, Operand(1)); | 1321 __ mov(R0, Operand(1)); |
| 1359 __ mov(R1, Operand(7)); | 1322 __ mov(R1, Operand(7)); |
| 1360 __ mov(R2, Operand(11)); | 1323 __ mov(R2, Operand(11)); |
| 1361 __ mov(R3, Operand(31)); | 1324 __ mov(R3, Operand(31)); |
| 1362 __ Push(R9); // We use R9 as accumulator. | 1325 __ Push(R9); // We use R9 as accumulator. |
| 1363 __ Push(R9); | 1326 __ Push(R9); |
| 1364 __ Push(R9); | 1327 __ Push(R9); |
| 1365 __ Push(R9); | 1328 __ Push(R9); |
| 1366 __ Push(R9); | 1329 __ Push(R9); |
| 1367 __ Push(R0); // Make room, so we can decrement after. | 1330 __ Push(R0); // Make room, so we can decrement after. |
| 1368 __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); | 1331 __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); |
| 1369 __ str(R2, Address(SP)); // Should be a free slot. | 1332 __ str(R2, Address(SP)); // Should be a free slot. |
| 1370 __ ldr(R9, Address(SP, 1 * kWordSize)); // R0. R9 = +1. | 1333 __ ldr(R9, Address(SP, 1 * kWordSize)); // R0. R9 = +1. |
| 1371 __ ldr(IP, Address(SP, 2 * kWordSize)); // R1. | 1334 __ ldr(IP, Address(SP, 2 * kWordSize)); // R1. |
| 1372 __ sub(R9, R9, Operand(IP)); // -R1. R9 = -6. | 1335 __ sub(R9, R9, Operand(IP)); // -R1. R9 = -6. |
| 1373 __ ldr(IP, Address(SP, 3 * kWordSize)); // R2. | 1336 __ ldr(IP, Address(SP, 3 * kWordSize)); // R2. |
| 1374 __ add(R9, R9, Operand(IP)); // +R2. R9 = +5. | 1337 __ add(R9, R9, Operand(IP)); // +R2. R9 = +5. |
| 1375 __ ldr(IP, Address(SP, 4 * kWordSize)); // R3. | 1338 __ ldr(IP, Address(SP, 4 * kWordSize)); // R3. |
| 1376 __ sub(R9, R9, Operand(IP)); // -R3. R9 = -26. | 1339 __ sub(R9, R9, Operand(IP)); // -R3. R9 = -26. |
| 1377 __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); | 1340 __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3)); |
| 1378 // Same operations again. But this time from the restore registers. | 1341 // Same operations again. But this time from the restore registers. |
| 1379 __ add(R9, R9, Operand(R0)); | 1342 __ add(R9, R9, Operand(R0)); |
| 1380 __ sub(R9, R9, Operand(R1)); | 1343 __ sub(R9, R9, Operand(R1)); |
| 1381 __ add(R9, R9, Operand(R2)); | 1344 __ add(R9, R9, Operand(R2)); |
| 1382 __ sub(R0, R9, Operand(R3)); // R0 = result = -52. | 1345 __ sub(R0, R9, Operand(R3)); // R0 = result = -52. |
| 1383 __ Pop(R1); // Remove storage slot. | 1346 __ Pop(R1); // Remove storage slot. |
| 1384 __ Pop(R9); // Restore R9. | 1347 __ Pop(R9); // Restore R9. |
| 1385 __ Pop(R9); // Restore R9. | 1348 __ Pop(R9); // Restore R9. |
| 1386 __ Pop(R9); // Restore R9. | 1349 __ Pop(R9); // Restore R9. |
| 1387 __ Pop(R9); // Restore R9. | 1350 __ Pop(R9); // Restore R9. |
| 1388 __ Pop(R9); // Restore R9. | 1351 __ Pop(R9); // Restore R9. |
| 1389 __ bx(LR); | 1352 __ bx(LR); |
| 1390 } | 1353 } |
| 1391 | 1354 |
| 1392 | 1355 |
| 1393 ASSEMBLER_TEST_RUN(Ldm_stm_da, test) { | 1356 ASSEMBLER_TEST_RUN(Ldm_stm_da, test) { |
| 1394 EXPECT(test != NULL); | 1357 EXPECT(test != NULL); |
| 1395 typedef int (*Tst)() DART_UNUSED; | 1358 typedef int (*Tst)() DART_UNUSED; |
| 1396 EXPECT_EQ(-52, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1359 EXPECT_EQ(-52, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 1397 } | 1360 } |
| 1398 | 1361 |
| (...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3157 if (TargetCPUFeatures::neon_supported()) { | 3120 if (TargetCPUFeatures::neon_supported()) { |
| 3158 typedef int (*Tst)() DART_UNUSED; | 3121 typedef int (*Tst)() DART_UNUSED; |
| 3159 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 3122 EXPECT_EQ(4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 3160 } | 3123 } |
| 3161 } | 3124 } |
| 3162 | 3125 |
| 3163 | 3126 |
| 3164 ASSEMBLER_TEST_GENERATE(Vmvnq, assembler) { | 3127 ASSEMBLER_TEST_GENERATE(Vmvnq, assembler) { |
| 3165 if (TargetCPUFeatures::neon_supported()) { | 3128 if (TargetCPUFeatures::neon_supported()) { |
| 3166 __ LoadImmediate(R1, 42); // R1 <- 42. | 3129 __ LoadImmediate(R1, 42); // R1 <- 42. |
| 3167 __ vmovsr(S2, R1); // S2 <- R1. | 3130 __ vmovsr(S2, R1); // S2 <- R1. |
| 3168 __ vmvnq(Q1, Q0); // Q1 <- ~Q0. | 3131 __ vmvnq(Q1, Q0); // Q1 <- ~Q0. |
| 3169 __ vmvnq(Q2, Q1); // Q2 <- ~Q1. | 3132 __ vmvnq(Q2, Q1); // Q2 <- ~Q1. |
| 3170 __ vmovrs(R0, S10); // Now R0 should be 42 again. | 3133 __ vmovrs(R0, S10); // Now R0 should be 42 again. |
| 3171 } | 3134 } |
| 3172 __ bx(LR); | 3135 __ bx(LR); |
| 3173 } | 3136 } |
| 3174 | 3137 |
| 3175 | 3138 |
| 3176 ASSEMBLER_TEST_RUN(Vmvnq, test) { | 3139 ASSEMBLER_TEST_RUN(Vmvnq, test) { |
| 3177 EXPECT(test != NULL); | 3140 EXPECT(test != NULL); |
| 3178 if (TargetCPUFeatures::neon_supported()) { | 3141 if (TargetCPUFeatures::neon_supported()) { |
| 3179 typedef int (*Tst)() DART_UNUSED; | 3142 typedef int (*Tst)() DART_UNUSED; |
| 3180 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 3143 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3695 if (TargetCPUFeatures::neon_supported()) { | 3658 if (TargetCPUFeatures::neon_supported()) { |
| 3696 typedef int (*Tst)() DART_UNUSED; | 3659 typedef int (*Tst)() DART_UNUSED; |
| 3697 EXPECT_EQ(14, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 3660 EXPECT_EQ(14, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
| 3698 } | 3661 } |
| 3699 } | 3662 } |
| 3700 | 3663 |
| 3701 | 3664 |
| 3702 // This is the same function as in the Simulator. | 3665 // This is the same function as in the Simulator. |
| 3703 static float arm_recip_estimate(float a) { | 3666 static float arm_recip_estimate(float a) { |
| 3704 // From the ARM Architecture Reference Manual A2-85. | 3667 // From the ARM Architecture Reference Manual A2-85. |
| 3705 if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0; | 3668 if (isinf(a) || (fabs(a) >= exp2f(126))) |
| 3706 else if (a == 0.0) return kPosInfinity; | 3669 return 0.0; |
| 3707 else if (isnan(a)) return a; | 3670 else if (a == 0.0) |
| 3671 return kPosInfinity; |
| 3672 else if (isnan(a)) |
| 3673 return a; |
| 3708 | 3674 |
| 3709 uint32_t a_bits = bit_cast<uint32_t, float>(a); | 3675 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
| 3710 // scaled = '0011 1111 1110' : a<22:0> : Zeros(29) | 3676 // scaled = '0011 1111 1110' : a<22:0> : Zeros(29) |
| 3711 uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) | | 3677 uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) | |
| 3712 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); | 3678 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); |
| 3713 // result_exp = 253 - UInt(a<30:23>) | 3679 // result_exp = 253 - UInt(a<30:23>) |
| 3714 int32_t result_exp = 253 - ((a_bits >> 23) & 0xff); | 3680 int32_t result_exp = 253 - ((a_bits >> 23) & 0xff); |
| 3715 ASSERT((result_exp >= 1) && (result_exp <= 252)); | 3681 ASSERT((result_exp >= 1) && (result_exp <= 252)); |
| 3716 | 3682 |
| 3717 double scaled_d = bit_cast<double, uint64_t>(scaled); | 3683 double scaled_d = bit_cast<double, uint64_t>(scaled); |
| 3718 ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0)); | 3684 ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0)); |
| 3719 | 3685 |
| 3720 // a in units of 1/512 rounded down. | 3686 // a in units of 1/512 rounded down. |
| 3721 int32_t q = static_cast<int32_t>(scaled_d * 512.0); | 3687 int32_t q = static_cast<int32_t>(scaled_d * 512.0); |
| 3722 // reciprocal r. | 3688 // reciprocal r. |
| 3723 double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0); | 3689 double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0); |
| 3724 // r in units of 1/256 rounded to nearest. | 3690 // r in units of 1/256 rounded to nearest. |
| 3725 int32_t s = static_cast<int32_t>(256.0 * r + 0.5); | 3691 int32_t s = static_cast<int32_t>(256.0 * r + 0.5); |
| 3726 double estimate = static_cast<double>(s) / 256.0; | 3692 double estimate = static_cast<double>(s) / 256.0; |
| 3727 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0))); | 3693 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); |
| 3728 | 3694 |
| 3729 // result = sign : result_exp<7:0> : estimate<51:29> | 3695 // result = sign : result_exp<7:0> : estimate<51:29> |
| 3730 int32_t result_bits = | 3696 int32_t result_bits = |
| 3731 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | | 3697 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | |
| 3732 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 3698 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
| 3733 return bit_cast<float, int32_t>(result_bits); | 3699 return bit_cast<float, int32_t>(result_bits); |
| 3734 } | 3700 } |
| 3735 | 3701 |
| 3736 | 3702 |
| 3737 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) { | 3703 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3801 } | 3767 } |
| 3802 __ bx(LR); | 3768 __ bx(LR); |
| 3803 } | 3769 } |
| 3804 | 3770 |
| 3805 | 3771 |
| 3806 ASSEMBLER_TEST_RUN(Reciprocal, test) { | 3772 ASSEMBLER_TEST_RUN(Reciprocal, test) { |
| 3807 EXPECT(test != NULL); | 3773 EXPECT(test != NULL); |
| 3808 if (TargetCPUFeatures::neon_supported()) { | 3774 if (TargetCPUFeatures::neon_supported()) { |
| 3809 typedef float (*Reciprocal)() DART_UNUSED; | 3775 typedef float (*Reciprocal)() DART_UNUSED; |
| 3810 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry()); | 3776 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry()); |
| 3811 EXPECT_FLOAT_EQ(1.0/147000.0, res, 0.0001f); | 3777 EXPECT_FLOAT_EQ(1.0 / 147000.0, res, 0.0001f); |
| 3812 } | 3778 } |
| 3813 } | 3779 } |
| 3814 | 3780 |
| 3815 | 3781 |
| 3816 static float arm_reciprocal_sqrt_estimate(float a) { | 3782 static float arm_reciprocal_sqrt_estimate(float a) { |
| 3817 // From the ARM Architecture Reference Manual A2-87. | 3783 // From the ARM Architecture Reference Manual A2-87. |
| 3818 if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0; | 3784 if (isinf(a) || (fabs(a) >= exp2f(126))) |
| 3819 else if (a == 0.0) return kPosInfinity; | 3785 return 0.0; |
| 3820 else if (isnan(a)) return a; | 3786 else if (a == 0.0) |
| 3787 return kPosInfinity; |
| 3788 else if (isnan(a)) |
| 3789 return a; |
| 3821 | 3790 |
| 3822 uint32_t a_bits = bit_cast<uint32_t, float>(a); | 3791 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
| 3823 uint64_t scaled; | 3792 uint64_t scaled; |
| 3824 if (((a_bits >> 23) & 1) != 0) { | 3793 if (((a_bits >> 23) & 1) != 0) { |
| 3825 // scaled = '0 01111111101' : operand<22:0> : Zeros(29) | 3794 // scaled = '0 01111111101' : operand<22:0> : Zeros(29) |
| 3826 scaled = (static_cast<uint64_t>(0x3fd) << 52) | | 3795 scaled = (static_cast<uint64_t>(0x3fd) << 52) | |
| 3827 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); | 3796 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); |
| 3828 } else { | 3797 } else { |
| 3829 // scaled = '0 01111111110' : operand<22:0> : Zeros(29) | 3798 // scaled = '0 01111111110' : operand<22:0> : Zeros(29) |
| 3830 scaled = (static_cast<uint64_t>(0x3fe) << 52) | | 3799 scaled = (static_cast<uint64_t>(0x3fe) << 52) | |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3848 // range 0.5 <= a < 1.0 | 3817 // range 0.5 <= a < 1.0 |
| 3849 | 3818 |
| 3850 // a in units of 1/256 rounded down. | 3819 // a in units of 1/256 rounded down. |
| 3851 int32_t q1 = static_cast<int32_t>(scaled_d * 256.0); | 3820 int32_t q1 = static_cast<int32_t>(scaled_d * 256.0); |
| 3852 // reciprocal root r. | 3821 // reciprocal root r. |
| 3853 r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0); | 3822 r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0); |
| 3854 } | 3823 } |
| 3855 // r in units of 1/256 rounded to nearest. | 3824 // r in units of 1/256 rounded to nearest. |
| 3856 int32_t s = static_cast<int>(256.0 * r + 0.5); | 3825 int32_t s = static_cast<int>(256.0 * r + 0.5); |
| 3857 double estimate = static_cast<double>(s) / 256.0; | 3826 double estimate = static_cast<double>(s) / 256.0; |
| 3858 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0))); | 3827 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); |
| 3859 | 3828 |
| 3860 // result = 0 : result_exp<7:0> : estimate<51:29> | 3829 // result = 0 : result_exp<7:0> : estimate<51:29> |
| 3861 int32_t result_bits = ((result_exp & 0xff) << 23) | | 3830 int32_t result_bits = |
| 3831 ((result_exp & 0xff) << 23) | |
| 3862 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 3832 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
| 3863 return bit_cast<float, int32_t>(result_bits); | 3833 return bit_cast<float, int32_t>(result_bits); |
| 3864 } | 3834 } |
| 3865 | 3835 |
| 3866 | 3836 |
| 3867 ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) { | 3837 ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) { |
| 3868 if (TargetCPUFeatures::neon_supported()) { | 3838 if (TargetCPUFeatures::neon_supported()) { |
| 3869 __ LoadSImmediate(S4, 147.0); | 3839 __ LoadSImmediate(S4, 147.0); |
| 3870 __ vmovs(S5, S4); | 3840 __ vmovs(S5, S4); |
| 3871 __ vmovs(S6, S4); | 3841 __ vmovs(S6, S4); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3903 } | 3873 } |
| 3904 __ bx(LR); | 3874 __ bx(LR); |
| 3905 } | 3875 } |
| 3906 | 3876 |
| 3907 | 3877 |
| 3908 ASSEMBLER_TEST_RUN(Vrsqrtsqs, test) { | 3878 ASSEMBLER_TEST_RUN(Vrsqrtsqs, test) { |
| 3909 EXPECT(test != NULL); | 3879 EXPECT(test != NULL); |
| 3910 if (TargetCPUFeatures::neon_supported()) { | 3880 if (TargetCPUFeatures::neon_supported()) { |
| 3911 typedef float (*Vrsqrtsqs)() DART_UNUSED; | 3881 typedef float (*Vrsqrtsqs)() DART_UNUSED; |
| 3912 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrtsqs, test->entry()); | 3882 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrtsqs, test->entry()); |
| 3913 EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0)/2.0, res, 0.0001f); | 3883 EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0) / 2.0, res, 0.0001f); |
| 3914 } | 3884 } |
| 3915 } | 3885 } |
| 3916 | 3886 |
| 3917 | 3887 |
| 3918 ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) { | 3888 ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) { |
| 3919 if (TargetCPUFeatures::neon_supported()) { | 3889 if (TargetCPUFeatures::neon_supported()) { |
| 3920 __ LoadSImmediate(S4, 147000.0); | 3890 __ LoadSImmediate(S4, 147000.0); |
| 3921 __ vmovs(S5, S4); | 3891 __ vmovs(S5, S4); |
| 3922 __ vmovs(S6, S4); | 3892 __ vmovs(S6, S4); |
| 3923 __ vmovs(S7, S4); | 3893 __ vmovs(S7, S4); |
| 3924 | 3894 |
| 3925 // Reciprocal square root estimate. | 3895 // Reciprocal square root estimate. |
| 3926 __ vrsqrteqs(Q0, Q1); | 3896 __ vrsqrteqs(Q0, Q1); |
| 3927 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3897 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
| 3928 // First step. | 3898 // First step. |
| 3929 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3899 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
| 3930 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3900 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
| 3931 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3901 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
| 3932 // Second step. | 3902 // Second step. |
| 3933 __ vmulqs(Q2, Q0, Q0); | 3903 __ vmulqs(Q2, Q0, Q0); |
| 3934 __ vrsqrtsqs(Q2, Q1, Q2); | 3904 __ vrsqrtsqs(Q2, Q1, Q2); |
| 3935 __ vmulqs(Q0, Q0, Q2); | 3905 __ vmulqs(Q0, Q0, Q2); |
| 3936 } | 3906 } |
| 3937 __ bx(LR); | 3907 __ bx(LR); |
| 3938 } | 3908 } |
| 3939 | 3909 |
| 3940 | 3910 |
| 3941 ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) { | 3911 ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) { |
| 3942 EXPECT(test != NULL); | 3912 EXPECT(test != NULL); |
| 3943 if (TargetCPUFeatures::neon_supported()) { | 3913 if (TargetCPUFeatures::neon_supported()) { |
| 3944 typedef float (*ReciprocalSqrt)() DART_UNUSED; | 3914 typedef float (*ReciprocalSqrt)() DART_UNUSED; |
| 3945 float res = EXECUTE_TEST_CODE_FLOAT(ReciprocalSqrt, test->entry()); | 3915 float res = EXECUTE_TEST_CODE_FLOAT(ReciprocalSqrt, test->entry()); |
| 3946 EXPECT_FLOAT_EQ(1.0/sqrt(147000.0), res, 0.0001f); | 3916 EXPECT_FLOAT_EQ(1.0 / sqrt(147000.0), res, 0.0001f); |
| 3947 } | 3917 } |
| 3948 } | 3918 } |
| 3949 | 3919 |
| 3950 | 3920 |
| 3951 ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) { | 3921 ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) { |
| 3952 if (TargetCPUFeatures::neon_supported()) { | 3922 if (TargetCPUFeatures::neon_supported()) { |
| 3953 __ LoadSImmediate(S4, 147000.0); | 3923 __ LoadSImmediate(S4, 147000.0); |
| 3954 __ vmovs(S5, S4); | 3924 __ vmovs(S5, S4); |
| 3955 __ vmovs(S6, S4); | 3925 __ vmovs(S6, S4); |
| 3956 __ vmovs(S7, S4); | 3926 __ vmovs(S7, S4); |
| 3957 | 3927 |
| 3958 // Reciprocal square root estimate. | 3928 // Reciprocal square root estimate. |
| 3959 __ vrsqrteqs(Q0, Q1); | 3929 __ vrsqrteqs(Q0, Q1); |
| 3960 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3930 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
| 3961 // First step. | 3931 // First step. |
| 3962 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3932 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
| 3963 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3933 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
| 3964 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3934 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
| 3965 // Second step. | 3935 // Second step. |
| 3966 __ vmulqs(Q2, Q0, Q0); | 3936 __ vmulqs(Q2, Q0, Q0); |
| 3967 __ vrsqrtsqs(Q2, Q1, Q2); | 3937 __ vrsqrtsqs(Q2, Q1, Q2); |
| 3968 __ vmulqs(Q0, Q0, Q2); | 3938 __ vmulqs(Q0, Q0, Q2); |
| 3969 | 3939 |
| 3970 // Reciprocal. | 3940 // Reciprocal. |
| 3971 __ vmovq(Q1, Q0); | 3941 __ vmovq(Q1, Q0); |
| 3972 // Reciprocal estimate. | 3942 // Reciprocal estimate. |
| 3973 __ vrecpeqs(Q0, Q1); | 3943 __ vrecpeqs(Q0, Q1); |
| 3974 // 2 Newton-Raphson steps. | 3944 // 2 Newton-Raphson steps. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3995 if (TargetCPUFeatures::neon_supported()) { | 3965 if (TargetCPUFeatures::neon_supported()) { |
| 3996 __ LoadSImmediate(S4, 1.0); | 3966 __ LoadSImmediate(S4, 1.0); |
| 3997 __ LoadSImmediate(S5, 4.0); | 3967 __ LoadSImmediate(S5, 4.0); |
| 3998 __ LoadSImmediate(S6, 9.0); | 3968 __ LoadSImmediate(S6, 9.0); |
| 3999 __ LoadSImmediate(S7, 16.0); | 3969 __ LoadSImmediate(S7, 16.0); |
| 4000 | 3970 |
| 4001 // Reciprocal square root estimate. | 3971 // Reciprocal square root estimate. |
| 4002 __ vrsqrteqs(Q0, Q1); | 3972 __ vrsqrteqs(Q0, Q1); |
| 4003 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3973 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
| 4004 // First step. | 3974 // First step. |
| 4005 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3975 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
| 4006 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3976 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
| 4007 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3977 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
| 4008 // Second step. | 3978 // Second step. |
| 4009 __ vmulqs(Q2, Q0, Q0); | 3979 __ vmulqs(Q2, Q0, Q0); |
| 4010 __ vrsqrtsqs(Q2, Q1, Q2); | 3980 __ vrsqrtsqs(Q2, Q1, Q2); |
| 4011 __ vmulqs(Q0, Q0, Q2); | 3981 __ vmulqs(Q0, Q0, Q2); |
| 4012 | 3982 |
| 4013 // Reciprocal. | 3983 // Reciprocal. |
| 4014 __ vmovq(Q1, Q0); | 3984 __ vmovq(Q1, Q0); |
| 4015 // Reciprocal estimate. | 3985 // Reciprocal estimate. |
| 4016 __ vrecpeqs(Q0, Q1); | 3986 __ vrecpeqs(Q0, Q1); |
| 4017 // 2 Newton-Raphson steps. | 3987 // 2 Newton-Raphson steps. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4132 | 4102 |
| 4133 | 4103 |
| 4134 // Called from assembler_test.cc. | 4104 // Called from assembler_test.cc. |
| 4135 // LR: return address. | 4105 // LR: return address. |
| 4136 // R0: value. | 4106 // R0: value. |
| 4137 // R1: growable array. | 4107 // R1: growable array. |
| 4138 // R2: current thread. | 4108 // R2: current thread. |
| 4139 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { | 4109 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { |
| 4140 __ PushList((1 << LR) | (1 << THR)); | 4110 __ PushList((1 << LR) | (1 << THR)); |
| 4141 __ mov(THR, Operand(R2)); | 4111 __ mov(THR, Operand(R2)); |
| 4142 __ StoreIntoObject(R1, | 4112 __ StoreIntoObject(R1, FieldAddress(R1, GrowableObjectArray::data_offset()), |
| 4143 FieldAddress(R1, GrowableObjectArray::data_offset()), | |
| 4144 R0); | 4113 R0); |
| 4145 __ PopList((1 << LR) | (1 << THR)); | 4114 __ PopList((1 << LR) | (1 << THR)); |
| 4146 __ Ret(); | 4115 __ Ret(); |
| 4147 } | 4116 } |
| 4148 | 4117 |
| 4149 } // namespace dart | 4118 } // namespace dart |
| 4150 | 4119 |
| 4151 #endif // defined TARGET_ARCH_ARM | 4120 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |