OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 int32_t disp, | 255 int32_t disp, |
256 RelocInfo::Mode rmode) { | 256 RelocInfo::Mode rmode) { |
257 ASSERT(!index.is(esp)); // illegal addressing mode | 257 ASSERT(!index.is(esp)); // illegal addressing mode |
258 // [index*scale + disp/r] | 258 // [index*scale + disp/r] |
259 set_modrm(0, esp); | 259 set_modrm(0, esp); |
260 set_sib(scale, index, ebp); | 260 set_sib(scale, index, ebp); |
261 set_dispr(disp, rmode); | 261 set_dispr(disp, rmode); |
262 } | 262 } |
263 | 263 |
264 | 264 |
| 265 Operand::Operand(const Operand& operand, int32_t offset) { |
| 266 ASSERT(operand.len_ >= 1); |
| 267 // Operand encodes REX ModR/M [SIB] [Disp]. |
| 268 byte modrm = operand.buf_[0]; |
| 269 ASSERT(modrm < 0xC0); // Disallow mode 3 (register target). |
| 270 bool has_sib = ((modrm & 0x07) == 0x04); |
| 271 byte mode = modrm & 0xC0; |
| 272 int disp_offset = has_sib ? 2 : 1; |
| 273 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07; |
| 274 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit |
| 275 // displacement. |
| 276 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base. |
| 277 int32_t disp_value = 0; |
| 278 if (mode == 0x80 || is_baseless) { |
| 279 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement. |
| 280 disp_value = *BitCast<const int32_t*>(&operand.buf_[disp_offset]); |
| 281 } else if (mode == 0x40) { |
| 282 // Mode 1: Byte displacement. |
| 283 disp_value = static_cast<signed char>(operand.buf_[disp_offset]); |
| 284 } |
| 285 |
| 286 // Write new operand with same registers, but with modified displacement. |
| 287 ASSERT(offset >= 0 ? disp_value + offset >= disp_value |
| 288 : disp_value + offset < disp_value); // No overflow. |
| 289 disp_value += offset; |
| 290 if (!is_int8(disp_value) || is_baseless) { |
| 291 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13. |
| 292 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80); |
| 293 len_ = disp_offset + 4; |
| 294 Memory::int32_at(&buf_[disp_offset]) = disp_value; |
| 295 } else if (disp_value != 0 || (base_reg == 0x05)) { |
| 296 // Need 8 bits of displacement. |
| 297 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1. |
| 298 len_ = disp_offset + 1; |
| 299 buf_[disp_offset] = static_cast<byte>(disp_value); |
| 300 } else { |
| 301 // Need no displacement. |
| 302 buf_[0] = (modrm & 0x3f); // Mode 0. |
| 303 len_ = disp_offset; |
| 304 } |
| 305 if (has_sib) { |
| 306 buf_[1] = operand.buf_[1]; |
| 307 } |
| 308 } |
| 309 |
| 310 |
265 bool Operand::is_reg(Register reg) const { | 311 bool Operand::is_reg(Register reg) const { |
266 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. | 312 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. |
267 && ((buf_[0] & 0x07) == reg.code()); // register codes match. | 313 && ((buf_[0] & 0x07) == reg.code()); // register codes match. |
268 } | 314 } |
269 | 315 |
270 | 316 |
271 bool Operand::is_reg_only() const { | 317 bool Operand::is_reg_only() const { |
272 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. | 318 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. |
273 } | 319 } |
274 | 320 |
(...skipping 2224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2499 EnsureSpace ensure_space(this); | 2545 EnsureSpace ensure_space(this); |
2500 EMIT(0x66); | 2546 EMIT(0x66); |
2501 EMIT(0x0F); | 2547 EMIT(0x0F); |
2502 EMIT(0x3A); | 2548 EMIT(0x3A); |
2503 EMIT(0x22); | 2549 EMIT(0x22); |
2504 emit_sse_operand(dst, src); | 2550 emit_sse_operand(dst, src); |
2505 EMIT(offset); | 2551 EMIT(offset); |
2506 } | 2552 } |
2507 | 2553 |
2508 | 2554 |
| 2555 void Assembler::movups(XMMRegister dst, const Operand& src) { |
| 2556 ASSERT(IsEnabled(SSE2)); |
| 2557 EnsureSpace ensure_space(this); |
| 2558 EMIT(0x0F); |
| 2559 EMIT(0x10); |
| 2560 emit_sse_operand(dst, src); |
| 2561 } |
| 2562 |
| 2563 |
| 2564 void Assembler::movups(const Operand& dst, XMMRegister src) { |
| 2565 ASSERT(IsEnabled(SSE2)); |
| 2566 EnsureSpace ensure_space(this); |
| 2567 EMIT(0x0F); |
| 2568 EMIT(0x11); |
| 2569 emit_sse_operand(src, dst); |
| 2570 } |
| 2571 |
| 2572 |
| 2573 void Assembler::minps(XMMRegister dst, const Operand& src) { |
| 2574 ASSERT(IsEnabled(SSE2)); |
| 2575 EnsureSpace ensure_space(this); |
| 2576 EMIT(0x0F); |
| 2577 EMIT(0x5D); |
| 2578 emit_sse_operand(dst, src); |
| 2579 } |
| 2580 |
| 2581 |
| 2582 void Assembler::maxps(XMMRegister dst, const Operand& src) { |
| 2583 ASSERT(IsEnabled(SSE2)); |
| 2584 EnsureSpace ensure_space(this); |
| 2585 EMIT(0x0F); |
| 2586 EMIT(0x5F); |
| 2587 emit_sse_operand(dst, src); |
| 2588 } |
| 2589 |
| 2590 |
| 2591 void Assembler::rcpps(XMMRegister dst, const Operand& src) { |
| 2592 ASSERT(IsEnabled(SSE2)); |
| 2593 EnsureSpace ensure_space(this); |
| 2594 EMIT(0x0F); |
| 2595 EMIT(0x53); |
| 2596 emit_sse_operand(dst, src); |
| 2597 } |
| 2598 |
| 2599 |
| 2600 void Assembler::rsqrtps(XMMRegister dst, const Operand& src) { |
| 2601 ASSERT(IsEnabled(SSE2)); |
| 2602 EnsureSpace ensure_space(this); |
| 2603 EMIT(0x0F); |
| 2604 EMIT(0x52); |
| 2605 emit_sse_operand(dst, src); |
| 2606 } |
| 2607 |
| 2608 |
| 2609 void Assembler::sqrtps(XMMRegister dst, const Operand& src) { |
| 2610 ASSERT(IsEnabled(SSE2)); |
| 2611 EnsureSpace ensure_space(this); |
| 2612 EMIT(0x0F); |
| 2613 EMIT(0x51); |
| 2614 emit_sse_operand(dst, src); |
| 2615 } |
| 2616 |
| 2617 |
| 2618 void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) { |
| 2619 ASSERT(IsEnabled(SSE2)); |
| 2620 EnsureSpace ensure_space(this); |
| 2621 EMIT(0x0F); |
| 2622 EMIT(0x5B); |
| 2623 emit_sse_operand(dst, src); |
| 2624 } |
| 2625 |
| 2626 |
| 2627 void Assembler::paddd(XMMRegister dst, const Operand& src) { |
| 2628 ASSERT(IsEnabled(SSE2)); |
| 2629 EnsureSpace ensure_space(this); |
| 2630 EMIT(0x66); |
| 2631 EMIT(0x0F); |
| 2632 EMIT(0xFE); |
| 2633 emit_sse_operand(dst, src); |
| 2634 } |
| 2635 |
| 2636 |
| 2637 void Assembler::psubd(XMMRegister dst, const Operand& src) { |
| 2638 ASSERT(IsEnabled(SSE2)); |
| 2639 EnsureSpace ensure_space(this); |
| 2640 EMIT(0x66); |
| 2641 EMIT(0x0F); |
| 2642 EMIT(0xFA); |
| 2643 emit_sse_operand(dst, src); |
| 2644 } |
| 2645 |
| 2646 |
| 2647 void Assembler::pmulld(XMMRegister dst, const Operand& src) { |
| 2648 ASSERT(IsEnabled(SSE4_1)); |
| 2649 EnsureSpace ensure_space(this); |
| 2650 EMIT(0x66); |
| 2651 EMIT(0x0F); |
| 2652 EMIT(0x38); |
| 2653 EMIT(0x40); |
| 2654 emit_sse_operand(dst, src); |
| 2655 } |
| 2656 |
| 2657 |
| 2658 void Assembler::pmuludq(XMMRegister dst, const Operand& src) { |
| 2659 ASSERT(IsEnabled(SSE2)); |
| 2660 EnsureSpace ensure_space(this); |
| 2661 EMIT(0x66); |
| 2662 EMIT(0x0F); |
| 2663 EMIT(0xF4); |
| 2664 emit_sse_operand(dst, src); |
| 2665 } |
| 2666 |
| 2667 |
| 2668 void Assembler::punpackldq(XMMRegister dst, const Operand& src) { |
| 2669 ASSERT(IsEnabled(SSE2)); |
| 2670 EnsureSpace ensure_space(this); |
| 2671 EMIT(0x66); |
| 2672 EMIT(0x0F); |
| 2673 EMIT(0x62); |
| 2674 emit_sse_operand(dst, src); |
| 2675 } |
| 2676 |
| 2677 |
| 2678 void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) { |
| 2679 ASSERT(IsEnabled(SSE2)); |
| 2680 EnsureSpace ensure_space(this); |
| 2681 EMIT(0x66); |
| 2682 EMIT(0x0F); |
| 2683 EMIT(0x5B); |
| 2684 emit_sse_operand(dst, src); |
| 2685 } |
| 2686 |
| 2687 |
| 2688 void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) { |
| 2689 ASSERT(IsEnabled(SSE2)); |
| 2690 EnsureSpace ensure_space(this); |
| 2691 EMIT(0x0F); |
| 2692 EMIT(0xC2); |
| 2693 emit_sse_operand(dst, src); |
| 2694 EMIT(cmp); |
| 2695 } |
| 2696 |
| 2697 |
| 2698 void Assembler::cmpeqps(XMMRegister dst, XMMRegister src) { |
| 2699 cmpps(dst, src, 0x0); |
| 2700 } |
| 2701 |
| 2702 |
| 2703 void Assembler::cmpltps(XMMRegister dst, XMMRegister src) { |
| 2704 cmpps(dst, src, 0x1); |
| 2705 } |
| 2706 |
| 2707 |
| 2708 void Assembler::cmpleps(XMMRegister dst, XMMRegister src) { |
| 2709 cmpps(dst, src, 0x2); |
| 2710 } |
| 2711 |
| 2712 |
| 2713 void Assembler::cmpneqps(XMMRegister dst, XMMRegister src) { |
| 2714 cmpps(dst, src, 0x4); |
| 2715 } |
| 2716 |
| 2717 |
| 2718 void Assembler::cmpnltps(XMMRegister dst, XMMRegister src) { |
| 2719 cmpps(dst, src, 0x5); |
| 2720 } |
| 2721 |
| 2722 |
| 2723 void Assembler::cmpnleps(XMMRegister dst, XMMRegister src) { |
| 2724 cmpps(dst, src, 0x6); |
| 2725 } |
| 2726 |
| 2727 |
| 2728 void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) { |
| 2729 ASSERT(CpuFeatures::IsSupported(SSE4_1)); |
| 2730 ASSERT(is_uint8(imm8)); |
| 2731 EnsureSpace ensure_space(this); |
| 2732 EMIT(0x66); |
| 2733 EMIT(0x0F); |
| 2734 EMIT(0x3A); |
| 2735 EMIT(0x21); |
| 2736 emit_sse_operand(dst, src); |
| 2737 EMIT(imm8); |
| 2738 } |
| 2739 |
| 2740 |
2509 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { | 2741 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { |
2510 Register ireg = { reg.code() }; | 2742 Register ireg = { reg.code() }; |
2511 emit_operand(ireg, adr); | 2743 emit_operand(ireg, adr); |
2512 } | 2744 } |
2513 | 2745 |
2514 | 2746 |
2515 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { | 2747 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { |
2516 EMIT(0xC0 | dst.code() << 3 | src.code()); | 2748 EMIT(0xC0 | dst.code() << 3 | src.code()); |
2517 } | 2749 } |
2518 | 2750 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2725 fprintf(coverage_log, "%s\n", file_line); | 2957 fprintf(coverage_log, "%s\n", file_line); |
2726 fflush(coverage_log); | 2958 fflush(coverage_log); |
2727 } | 2959 } |
2728 } | 2960 } |
2729 | 2961 |
2730 #endif | 2962 #endif |
2731 | 2963 |
2732 } } // namespace v8::internal | 2964 } } // namespace v8::internal |
2733 | 2965 |
2734 #endif // V8_TARGET_ARCH_IA32 | 2966 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |