Chromium Code Reviews| 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 __ SmiUntag(RBX); | |
|
srdjan
2012/06/06 23:30:00
ditto
cshapiro
2012/06/06 23:43:07
Done.
| |
| 209 __ movsxw(RAX, FieldAddress(RAX, | |
| 210 RBX, | |
| 211 TIMES_2, | |
| 212 Int16Array::data_offset())); | |
| 213 __ SmiTag(RAX); | |
| 214 __ ret(); | |
| 215 __ Bind(&fall_through); | |
| 216 return false; | |
| 217 } | |
| 218 | |
| 219 | |
| 220 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) { | |
| 221 Label fall_through; | |
| 222 TestByteArrayIndex(assembler, &fall_through); | |
| 223 __ SmiUntag(RBX); | |
|
srdjan
2012/06/06 23:30:00
ditto
| |
| 224 __ movzxw(RAX, FieldAddress(RAX, | |
| 225 RBX, | |
| 226 TIMES_2, | |
| 227 Uint16Array::data_offset())); | |
| 228 __ SmiTag(RAX); | |
| 229 __ ret(); | |
| 230 __ Bind(&fall_through); | |
| 231 return false; | |
| 232 } | |
| 233 | |
| 234 | |
| 235 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) { | |
| 236 Label fall_through; | |
| 237 TestByteArrayIndex(assembler, &fall_through); | |
| 238 __ SmiUntag(RBX); | |
|
srdjan
2012/06/06 23:30:00
Skip untagging, use TIMES_2.
cshapiro
2012/06/06 23:43:07
Done.
| |
| 239 __ movsxl(RAX, FieldAddress(RAX, | |
| 240 RBX, | |
| 241 TIMES_4, | |
| 242 Int32Array::data_offset())); | |
| 243 __ SmiTag(RAX); | |
| 244 __ ret(); | |
| 245 __ Bind(&fall_through); | |
| 246 return false; | |
| 247 } | |
| 248 | |
| 249 | |
| 250 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) { | |
| 251 Label fall_through; | |
| 252 TestByteArrayIndex(assembler, &fall_through); | |
| 253 __ SmiUntag(RBX); | |
|
srdjan
2012/06/06 23:30:00
ditto
cshapiro
2012/06/06 23:43:07
Done.
| |
| 254 __ movl(RAX, FieldAddress(RAX, | |
| 255 RBX, | |
| 256 TIMES_4, | |
| 257 Uint32Array::data_offset())); | |
| 258 __ SmiTag(RAX); | |
| 259 __ ret(); | |
| 260 __ Bind(&fall_through); | |
| 261 return false; | |
| 262 } | |
| 263 | |
| 264 | |
| 148 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) { | 265 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) { |
| 149 return false; | 266 return false; |
| 150 } | 267 } |
| 151 | 268 |
| 152 | 269 |
| 153 bool Intrinsifier::Integer_add(Assembler* assembler) { | 270 bool Intrinsifier::Integer_add(Assembler* assembler) { |
| 154 return false; | 271 return false; |
| 155 } | 272 } |
| 156 | 273 |
| 157 | 274 |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 | 521 |
| 405 bool Intrinsifier::String_isEmpty(Assembler* assembler) { | 522 bool Intrinsifier::String_isEmpty(Assembler* assembler) { |
| 406 return false; | 523 return false; |
| 407 } | 524 } |
| 408 | 525 |
| 409 #undef __ | 526 #undef __ |
| 410 | 527 |
| 411 } // namespace dart | 528 } // namespace dart |
| 412 | 529 |
| 413 #endif // defined TARGET_ARCH_X64 | 530 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |