Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 } | 182 } |
| 183 | 183 |
| 184 void Assembler::RecordPosition(int a) { | 184 void Assembler::RecordPosition(int a) { |
| 185 UNIMPLEMENTED(); | 185 UNIMPLEMENTED(); |
| 186 } | 186 } |
| 187 | 187 |
| 188 void Assembler::RecordStatementPosition(int a) { | 188 void Assembler::RecordStatementPosition(int a) { |
| 189 UNIMPLEMENTED(); | 189 UNIMPLEMENTED(); |
| 190 } | 190 } |
| 191 | 191 |
| 192 void Assembler::bind(Label* a) { | 192 |
| 193 UNIMPLEMENTED(); | 193 void Assembler::bind_to(Label* L, int pos) { |
| 194 ASSERT(!L->is_bound()); // Label may only be bound once. | |
| 195 last_pc_ = NULL; | |
| 196 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. | |
| 197 if (L->is_linked()) { | |
| 198 int current = L->pos(); | |
| 199 int next = long_at(current); | |
| 200 while (next != current) { | |
| 201 // relative address, relative to point after address | |
| 202 int imm32 = pos - (current + sizeof(int32_t)); | |
| 203 long_at_put(current, imm32); | |
| 204 current = next; | |
| 205 next = long_at(next); | |
| 206 } | |
| 207 // Fix up last fixup on linked list. | |
| 208 int last_imm32 = pos - (current + sizeof(int32_t)); | |
| 209 long_at_put(current, last_imm32); | |
| 210 } | |
| 211 L->bind_to(pos); | |
| 194 } | 212 } |
| 195 | 213 |
| 214 | |
| 215 void Assembler::bind(Label* L) { | |
| 216 bind_to(L, pc_offset()); | |
| 217 } | |
| 218 | |
| 219 | |
| 196 void Assembler::GrowBuffer() { | 220 void Assembler::GrowBuffer() { |
| 197 ASSERT(overflow()); // should not call this otherwise | 221 ASSERT(overflow()); // should not call this otherwise |
| 198 if (!own_buffer_) FATAL("external code buffer is too small"); | 222 if (!own_buffer_) FATAL("external code buffer is too small"); |
| 199 | 223 |
| 200 // compute new buffer size | 224 // compute new buffer size |
| 201 CodeDesc desc; // the new buffer | 225 CodeDesc desc; // the new buffer |
| 202 if (buffer_size_ < 4*KB) { | 226 if (buffer_size_ < 4*KB) { |
| 203 desc.buffer_size = 4*KB; | 227 desc.buffer_size = 4*KB; |
| 204 } else { | 228 } else { |
| 205 desc.buffer_size = 2*buffer_size_; | 229 desc.buffer_size = 2*buffer_size_; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 268 | 292 |
| 269 // Emit updated ModRM byte containing the given register. | 293 // Emit updated ModRM byte containing the given register. |
| 270 pc_[0] = (adr.buf_[0] & ~0x38) | ((reg.code() && 0x7) << 3); | 294 pc_[0] = (adr.buf_[0] & ~0x38) | ((reg.code() && 0x7) << 3); |
| 271 | 295 |
| 272 // Emit the rest of the encoded operand. | 296 // Emit the rest of the encoded operand. |
| 273 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; | 297 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; |
| 274 pc_ += length; | 298 pc_ += length; |
| 275 } | 299 } |
| 276 | 300 |
| 277 | 301 |
| 302 // Assembler Instruction implementations | |
| 303 | |
| 278 void Assembler::add(Register dst, const Operand& src) { | 304 void Assembler::add(Register dst, const Operand& src) { |
| 279 EnsureSpace ensure_space(this); | 305 EnsureSpace ensure_space(this); |
| 280 last_pc_ = pc_; | 306 last_pc_ = pc_; |
| 281 emit_rex_64(dst, src); | 307 emit_rex_64(dst, src); |
| 282 EMIT(0x03); | 308 EMIT(0x03); |
| 283 emit_operand(dst, src); | 309 emit_operand(dst, src); |
| 284 } | 310 } |
| 285 | 311 |
| 286 | 312 |
| 287 void Assembler::add(Register dst, Register src) { | 313 void Assembler::add(Register dst, Register src) { |
| 288 EnsureSpace ensure_space(this); | 314 EnsureSpace ensure_space(this); |
| 289 last_pc_ = pc_; | 315 last_pc_ = pc_; |
| 290 emit_rex_64(dst, src); | 316 emit_rex_64(dst, src); |
| 291 EMIT(0x03); | 317 EMIT(0x03); |
| 292 EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7)); | 318 EMIT(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); |
|
Lasse Reichstein
2009/05/26 12:14:41
Was this incorrect before?
William Hesse
2009/05/26 15:15:32
Yes it was. Cases with two register operands shou
| |
| 319 } | |
| 320 | |
| 321 | |
| 322 void Assembler::call(Label* L) { | |
| 323 EnsureSpace ensure_space(this); | |
| 324 last_pc_ = pc_; | |
| 325 // 1110 1000 #32-bit disp | |
| 326 EMIT(0xE8); | |
| 327 if (L->is_bound()) { | |
| 328 int offset = L->pos() - pc_offset() - sizeof(int32_t); | |
| 329 ASSERT(offset <= 0); | |
| 330 emit(offset); | |
| 331 } else if (L->is_linked()) { | |
| 332 emit(L->pos()); | |
| 333 L->link_to(pc_offset() - sizeof(int32_t)); | |
| 334 } else { | |
| 335 ASSERT(L->is_unused()); | |
| 336 int32_t current = pc_offset(); | |
| 337 emit(current); | |
| 338 L->link_to(current); | |
| 339 } | |
| 293 } | 340 } |
| 294 | 341 |
| 295 | 342 |
| 296 void Assembler::dec(Register dst) { | 343 void Assembler::dec(Register dst) { |
| 297 EnsureSpace ensure_space(this); | 344 EnsureSpace ensure_space(this); |
| 298 last_pc_ = pc_; | 345 last_pc_ = pc_; |
| 299 emit_rex_64(rcx, dst); | 346 emit_rex_64(rcx, dst); |
| 300 EMIT(0xFF); | 347 EMIT(0xFF); |
| 301 EMIT(0xC8 | (dst.code() & 0x7)); | 348 EMIT(0xC8 | (dst.code() & 0x7)); |
| 302 } | 349 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 } | 383 } |
| 337 | 384 |
| 338 | 385 |
| 339 void Assembler::int3() { | 386 void Assembler::int3() { |
| 340 EnsureSpace ensure_space(this); | 387 EnsureSpace ensure_space(this); |
| 341 last_pc_ = pc_; | 388 last_pc_ = pc_; |
| 342 EMIT(0xCC); | 389 EMIT(0xCC); |
| 343 } | 390 } |
| 344 | 391 |
| 345 | 392 |
| 393 void Assembler::j(Condition cc, Label* L) { | |
| 394 EnsureSpace ensure_space(this); | |
| 395 last_pc_ = pc_; | |
| 396 ASSERT(0 <= cc && cc < 16); | |
| 397 if (L->is_bound()) { | |
| 398 const int short_size = 2; | |
| 399 const int long_size = 6; | |
| 400 int offs = L->pos() - pc_offset(); | |
| 401 ASSERT(offs <= 0); | |
| 402 if (is_int8(offs - short_size)) { | |
| 403 // 0111 tttn #8-bit disp | |
| 404 EMIT(0x70 | cc); | |
| 405 EMIT((offs - short_size) & 0xFF); | |
| 406 } else { | |
| 407 // 0000 1111 1000 tttn #32-bit disp | |
| 408 EMIT(0x0F); | |
| 409 EMIT(0x80 | cc); | |
| 410 emit(offs - long_size); | |
| 411 } | |
| 412 } else if (L->is_linked()) { | |
| 413 // 0000 1111 1000 tttn #32-bit disp | |
| 414 EMIT(0x0F); | |
| 415 EMIT(0x80 | cc); | |
| 416 emit(L->pos()); | |
| 417 L->link_to(pc_offset() - sizeof(int32_t)); | |
| 418 } else { | |
| 419 ASSERT(L->is_unused()); | |
| 420 EMIT(0x0F); | |
| 421 EMIT(0x80 | cc); | |
| 422 int32_t current = pc_offset(); | |
| 423 emit(current); | |
| 424 L->link_to(current); | |
| 425 } | |
| 426 } | |
| 427 | |
| 428 | |
| 429 void Assembler::jmp(Label* L) { | |
| 430 EnsureSpace ensure_space(this); | |
| 431 last_pc_ = pc_; | |
| 432 if (L->is_bound()) { | |
| 433 int offs = L->pos() - pc_offset() - 1; | |
| 434 ASSERT(offs <= 0); | |
| 435 if (is_int8(offs - sizeof(int8_t))) { | |
| 436 // 1110 1011 #8-bit disp | |
| 437 EMIT(0xEB); | |
| 438 EMIT((offs - sizeof(int8_t)) & 0xFF); | |
| 439 } else { | |
| 440 // 1110 1001 #32-bit disp | |
| 441 EMIT(0xE9); | |
| 442 emit(offs - sizeof(int32_t)); | |
| 443 } | |
| 444 } else if (L->is_linked()) { | |
| 445 // 1110 1001 #32-bit disp | |
| 446 EMIT(0xE9); | |
| 447 emit(L->pos()); | |
| 448 L->link_to(pc_offset() - sizeof(int32_t)); | |
| 449 } else { | |
| 450 // 1110 1001 #32-bit disp | |
| 451 ASSERT(L->is_unused()); | |
| 452 EMIT(0xE9); | |
| 453 int32_t current = pc_offset(); | |
| 454 emit(current); | |
| 455 L->link_to(current); | |
| 456 } | |
| 457 } | |
| 458 | |
| 459 | |
| 346 void Assembler::mov(Register dst, const Operand& src) { | 460 void Assembler::mov(Register dst, const Operand& src) { |
| 347 EnsureSpace ensure_space(this); | 461 EnsureSpace ensure_space(this); |
| 348 last_pc_ = pc_; | 462 last_pc_ = pc_; |
| 349 emit_rex_64(dst, src); | 463 emit_rex_64(dst, src); |
| 350 EMIT(0x8B); | 464 EMIT(0x8B); |
| 351 emit_operand(dst, src); | 465 emit_operand(dst, src); |
| 352 } | 466 } |
| 353 | 467 |
| 354 | 468 |
| 355 void Assembler::mov(Register dst, Register src) { | 469 void Assembler::mov(Register dst, Register src) { |
| 356 EnsureSpace ensure_space(this); | 470 EnsureSpace ensure_space(this); |
| 357 last_pc_ = pc_; | 471 last_pc_ = pc_; |
| 358 emit_rex_64(dst, src); | 472 emit_rex_64(dst, src); |
| 359 EMIT(0x89); | 473 EMIT(0x8B); |
| 360 EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7)); | 474 EMIT(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); |
| 361 } | 475 } |
| 362 | 476 |
| 363 | 477 |
| 364 void Assembler::nop() { | 478 void Assembler::nop() { |
| 365 EnsureSpace ensure_space(this); | 479 EnsureSpace ensure_space(this); |
| 366 last_pc_ = pc_; | 480 last_pc_ = pc_; |
| 367 EMIT(0x90); | 481 EMIT(0x90); |
| 368 } | 482 } |
| 369 | 483 |
| 370 void Assembler::pop(Register dst) { | 484 void Assembler::pop(Register dst) { |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 UNIMPLEMENTED(); | 816 UNIMPLEMENTED(); |
| 703 return NULL; | 817 return NULL; |
| 704 } | 818 } |
| 705 | 819 |
| 706 byte* JavaScriptFrame::GetCallerStackPointer() const { | 820 byte* JavaScriptFrame::GetCallerStackPointer() const { |
| 707 UNIMPLEMENTED(); | 821 UNIMPLEMENTED(); |
| 708 return NULL; | 822 return NULL; |
| 709 } | 823 } |
| 710 | 824 |
| 711 } } // namespace v8::internal | 825 } } // namespace v8::internal |
| OLD | NEW |