| 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" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 return false; | 138 return false; |
| 139 } | 139 } |
| 140 __ movq(RAX, Address(RSP, + 2 * kWordSize)); | 140 __ movq(RAX, Address(RSP, + 2 * kWordSize)); |
| 141 __ movq(RBX, Address(RSP, + 1 * kWordSize)); | 141 __ movq(RBX, Address(RSP, + 1 * kWordSize)); |
| 142 __ movq(FieldAddress(RAX, GrowableObjectArray::data_offset()), RBX); | 142 __ movq(FieldAddress(RAX, GrowableObjectArray::data_offset()), RBX); |
| 143 __ ret(); | 143 __ ret(); |
| 144 return true; | 144 return true; |
| 145 } | 145 } |
| 146 | 146 |
| 147 | 147 |
| 148 bool Intrinsifier::ByteArrayBase_getLength(Assembler* assembler) { |
| 149 __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
| 150 __ movq(RAX, FieldAddress(RAX, ByteArray::length_offset())); |
| 151 __ ret(); |
| 152 // Generate enough code to satisfy patchability constraint. |
| 153 intptr_t offset = __ CodeSize(); |
| 154 __ nop(JumpPattern::InstructionLength() - offset); |
| 155 return true; |
| 156 } |
| 157 |
| 158 |
| 159 // Assumes the first argument is a byte array, tests if the second |
| 160 // argument is a smi, tests if the smi is within bounds of the array |
| 161 // length, and jumps to label fall_through if any test fails. Leaves |
| 162 // the second argument in RBX. |
| 163 void TestByteArrayIndex(Assembler* assembler, Label* fall_through) { |
| 164 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Array. |
| 165 __ movq(RBX, Address(RSP, + 2 * kWordSize)); // Index. |
| 166 __ testq(RBX, Immediate(kSmiTagMask)); |
| 167 __ j(NOT_ZERO, fall_through, Assembler::kNearJump); // Non-smi index. |
| 168 // Range check. |
| 169 __ cmpq(RBX, FieldAddress(RAX, ByteArray::length_offset())); |
| 170 // Runtime throws exception. |
| 171 __ j(ABOVE_EQUAL, fall_through, Assembler::kNearJump); |
| 172 } |
| 173 |
| 174 |
| 175 bool Intrinsifier::Int8Array_getIndexed(Assembler* assembler) { |
| 176 Label fall_through; |
| 177 TestByteArrayIndex(assembler, &fall_through); |
| 178 __ SmiUntag(RBX); |
| 179 __ movsxb(RAX, FieldAddress(RAX, |
| 180 RBX, |
| 181 TIMES_1, |
| 182 Int8Array::data_offset())); |
| 183 __ SmiTag(RAX); |
| 184 __ ret(); |
| 185 __ Bind(&fall_through); |
| 186 return false; |
| 187 } |
| 188 |
| 189 |
| 190 bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) { |
| 191 Label fall_through; |
| 192 TestByteArrayIndex(assembler, &fall_through); |
| 193 __ SmiUntag(RBX); |
| 194 __ movzxb(RAX, FieldAddress(RAX, |
| 195 RBX, |
| 196 TIMES_1, |
| 197 Uint8Array::data_offset())); |
| 198 __ SmiTag(RAX); |
| 199 __ ret(); |
| 200 __ Bind(&fall_through); |
| 201 return false; |
| 202 } |
| 203 |
| 204 |
| 205 bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) { |
| 206 Label fall_through; |
| 207 TestByteArrayIndex(assembler, &fall_through); |
| 208 __ movsxw(RAX, FieldAddress(RAX, |
| 209 RBX, |
| 210 TIMES_1, |
| 211 Int16Array::data_offset())); |
| 212 __ SmiTag(RAX); |
| 213 __ ret(); |
| 214 __ Bind(&fall_through); |
| 215 return false; |
| 216 } |
| 217 |
| 218 |
| 219 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) { |
| 220 Label fall_through; |
| 221 TestByteArrayIndex(assembler, &fall_through); |
| 222 __ movzxw(RAX, FieldAddress(RAX, |
| 223 RBX, |
| 224 TIMES_1, |
| 225 Uint16Array::data_offset())); |
| 226 __ SmiTag(RAX); |
| 227 __ ret(); |
| 228 __ Bind(&fall_through); |
| 229 return false; |
| 230 } |
| 231 |
| 232 |
| 233 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) { |
| 234 Label fall_through; |
| 235 TestByteArrayIndex(assembler, &fall_through); |
| 236 __ movsxl(RAX, FieldAddress(RAX, |
| 237 RBX, |
| 238 TIMES_2, |
| 239 Int32Array::data_offset())); |
| 240 __ SmiTag(RAX); |
| 241 __ ret(); |
| 242 __ Bind(&fall_through); |
| 243 return false; |
| 244 } |
| 245 |
| 246 |
| 247 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) { |
| 248 Label fall_through; |
| 249 TestByteArrayIndex(assembler, &fall_through); |
| 250 __ movl(RAX, FieldAddress(RAX, |
| 251 RBX, |
| 252 TIMES_2, |
| 253 Uint32Array::data_offset())); |
| 254 __ SmiTag(RAX); |
| 255 __ ret(); |
| 256 __ Bind(&fall_through); |
| 257 return false; |
| 258 } |
| 259 |
| 260 |
| 148 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) { | 261 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) { |
| 149 return false; | 262 return false; |
| 150 } | 263 } |
| 151 | 264 |
| 152 | 265 |
| 153 bool Intrinsifier::Integer_add(Assembler* assembler) { | 266 bool Intrinsifier::Integer_add(Assembler* assembler) { |
| 154 return false; | 267 return false; |
| 155 } | 268 } |
| 156 | 269 |
| 157 | 270 |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 | 517 |
| 405 bool Intrinsifier::String_isEmpty(Assembler* assembler) { | 518 bool Intrinsifier::String_isEmpty(Assembler* assembler) { |
| 406 return false; | 519 return false; |
| 407 } | 520 } |
| 408 | 521 |
| 409 #undef __ | 522 #undef __ |
| 410 | 523 |
| 411 } // namespace dart | 524 } // namespace dart |
| 412 | 525 |
| 413 #endif // defined TARGET_ARCH_X64 | 526 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |