Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: src/arm/simulator-arm.cc

Issue 17858002: ARM: Implement memcpy using NEON. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove "unaligned accesses" from C++ code Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 901 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 } 912 }
913 913
914 914
915 void Simulator::set_dw_register(int dreg, const int* dbl) { 915 void Simulator::set_dw_register(int dreg, const int* dbl) {
916 ASSERT((dreg >= 0) && (dreg < num_d_registers)); 916 ASSERT((dreg >= 0) && (dreg < num_d_registers));
917 registers_[dreg] = dbl[0]; 917 registers_[dreg] = dbl[0];
918 registers_[dreg + 1] = dbl[1]; 918 registers_[dreg + 1] = dbl[1];
919 } 919 }
920 920
921 921
922 void Simulator::get_d_register(int dreg, uint64_t* value) {
923 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
924 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value));
925 }
926
927
928 void Simulator::set_d_register(int dreg, const uint64_t* value) {
929 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
930 memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value));
931 }
932
933
934 void Simulator::get_d_register(int dreg, uint32_t* value) {
935 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
936 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value) * 2);
937 }
938
939
940 void Simulator::set_d_register(int dreg, const uint32_t* value) {
941 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
942 memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value) * 2);
943 }
944
945
946 void Simulator::get_q_register(int qreg, uint64_t* value) {
947 ASSERT((qreg >= 0) && (qreg < num_q_registers));
948 memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 2);
949 }
950
951
952 void Simulator::set_q_register(int qreg, const uint64_t* value) {
953 ASSERT((qreg >= 0) && (qreg < num_q_registers));
954 memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 2);
955 }
956
957
958 void Simulator::get_q_register(int qreg, uint32_t* value) {
959 ASSERT((qreg >= 0) && (qreg < num_q_registers));
960 memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 4);
961 }
962
963
964 void Simulator::set_q_register(int qreg, const uint32_t* value) {
965 ASSERT((qreg >= 0) && (qreg < num_q_registers));
966 memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 4);
967 }
968
969
922 // Raw access to the PC register. 970 // Raw access to the PC register.
923 void Simulator::set_pc(int32_t value) { 971 void Simulator::set_pc(int32_t value) {
924 pc_modified_ = true; 972 pc_modified_ = true;
925 registers_[pc] = value; 973 registers_[pc] = value;
926 } 974 }
927 975
928 976
929 bool Simulator::has_bad_pc() const { 977 bool Simulator::has_bad_pc() const {
930 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc)); 978 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc));
931 } 979 }
(...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after
2589 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); 2637 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
2590 int32_t addr = 0; 2638 int32_t addr = 0;
2591 switch (instr->PUField()) { 2639 switch (instr->PUField()) {
2592 case da_x: { 2640 case da_x: {
2593 ASSERT(!instr->HasW()); 2641 ASSERT(!instr->HasW());
2594 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); 2642 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
2595 UNIMPLEMENTED(); 2643 UNIMPLEMENTED();
2596 break; 2644 break;
2597 } 2645 }
2598 case ia_x: { 2646 case ia_x: {
2599 if (instr->HasW()) { 2647 if (instr->Bit(4) == 0) {
2600 ASSERT(instr->Bits(5, 4) == 0x1); 2648 // Memop.
2601 2649 } else {
2602 if (instr->Bit(22) == 0x1) { // USAT. 2650 if (instr->Bit(5) == 0) {
2603 int32_t sat_pos = instr->Bits(20, 16); 2651 switch (instr->Bits(22, 21)) {
2604 int32_t sat_val = (1 << sat_pos) - 1; 2652 case 0:
2605 int32_t shift = instr->Bits(11, 7); 2653 if (instr->Bit(20) == 0) {
2606 int32_t shift_type = instr->Bit(6); 2654 if (instr->Bit(6) == 0) {
2607 int32_t rm_val = get_register(instr->RmValue()); 2655 // Pkhbt.
2608 if (shift_type == 0) { // LSL 2656 uint32_t rn_val = get_register(rn);
2609 rm_val <<= shift; 2657 uint32_t rm_val = get_register(instr->RmValue());
2610 } else { // ASR 2658 int32_t shift = instr->Bits(11, 7);
2611 rm_val >>= shift; 2659 rm_val <<= shift;
2660 set_register(rd, (rn_val & 0xFFFF) | (rm_val & 0xFFFF0000U));
2661 } else {
2662 // Pkhtb.
2663 uint32_t rn_val = get_register(rn);
2664 int32_t rm_val = get_register(instr->RmValue());
2665 int32_t shift = instr->Bits(11, 7);
2666 if (shift == 0) {
2667 shift = 32;
2668 }
2669 rm_val >>= shift;
2670 set_register(rd, (rn_val & 0xFFFF0000U) | (rm_val & 0xFFFF));
2671 }
2672 } else {
2673 UNIMPLEMENTED();
2674 }
2675 break;
2676 case 1:
2677 UNIMPLEMENTED();
2678 break;
2679 case 2:
2680 UNIMPLEMENTED();
2681 break;
2682 case 3: {
2683 // Usat.
2684 int32_t sat_pos = instr->Bits(20, 16);
2685 int32_t sat_val = (1 << sat_pos) - 1;
2686 int32_t shift = instr->Bits(11, 7);
2687 int32_t shift_type = instr->Bit(6);
2688 int32_t rm_val = get_register(instr->RmValue());
2689 if (shift_type == 0) { // LSL
2690 rm_val <<= shift;
2691 } else { // ASR
2692 rm_val >>= shift;
2693 }
2694 // If saturation occurs, the Q flag should be set in the CPSR.
2695 // There is no Q flag yet, and no instruction (MRS) to read the
2696 // CPSR directly.
2697 if (rm_val > sat_val) {
2698 rm_val = sat_val;
2699 } else if (rm_val < 0) {
2700 rm_val = 0;
2701 }
2702 set_register(rd, rm_val);
2703 break;
2704 }
2612 } 2705 }
2613 // If saturation occurs, the Q flag should be set in the CPSR. 2706 } else {
2614 // There is no Q flag yet, and no instruction (MRS) to read the 2707 switch (instr->Bits(22, 21)) {
2615 // CPSR directly. 2708 case 0:
2616 if (rm_val > sat_val) { 2709 UNIMPLEMENTED();
2617 rm_val = sat_val; 2710 break;
2618 } else if (rm_val < 0) { 2711 case 1:
2619 rm_val = 0; 2712 UNIMPLEMENTED();
2713 break;
2714 case 2:
2715 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
2716 if (instr->Bits(19, 16) == 0xF) {
2717 // Uxtb16.
2718 uint32_t rm_val = get_register(instr->RmValue());
2719 int32_t rotate = instr->Bits(11, 10);
2720 switch (rotate) {
2721 case 0:
2722 break;
2723 case 1:
2724 rm_val = (rm_val >> 8) | (rm_val << 24);
2725 break;
2726 case 2:
2727 rm_val = (rm_val >> 16) | (rm_val << 16);
2728 break;
2729 case 3:
2730 rm_val = (rm_val >> 24) | (rm_val << 8);
2731 break;
2732 }
2733 set_register(rd,
2734 (rm_val & 0xFF) | (rm_val & 0xFF0000));
2735 } else {
2736 UNIMPLEMENTED();
2737 }
2738 } else {
2739 UNIMPLEMENTED();
2740 }
2741 break;
2742 case 3:
2743 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
2744 if (instr->Bits(19, 16) == 0xF) {
2745 // Uxtb.
2746 uint32_t rm_val = get_register(instr->RmValue());
2747 int32_t rotate = instr->Bits(11, 10);
2748 switch (rotate) {
2749 case 0:
2750 break;
2751 case 1:
2752 rm_val = (rm_val >> 8) | (rm_val << 24);
2753 break;
2754 case 2:
2755 rm_val = (rm_val >> 16) | (rm_val << 16);
2756 break;
2757 case 3:
2758 rm_val = (rm_val >> 24) | (rm_val << 8);
2759 break;
2760 }
2761 set_register(rd, (rm_val & 0xFF));
2762 } else {
2763 // Uxtab.
2764 uint32_t rn_val = get_register(rn);
2765 uint32_t rm_val = get_register(instr->RmValue());
2766 int32_t rotate = instr->Bits(11, 10);
2767 switch (rotate) {
2768 case 0:
2769 break;
2770 case 1:
2771 rm_val = (rm_val >> 8) | (rm_val << 24);
2772 break;
2773 case 2:
2774 rm_val = (rm_val >> 16) | (rm_val << 16);
2775 break;
2776 case 3:
2777 rm_val = (rm_val >> 24) | (rm_val << 8);
2778 break;
2779 }
2780 set_register(rd, rn_val + (rm_val & 0xFF));
2781 }
2782 } else {
2783 UNIMPLEMENTED();
2784 }
2785 break;
2620 } 2786 }
2621 set_register(rd, rm_val);
2622 } else { // SSAT.
2623 UNIMPLEMENTED();
2624 } 2787 }
2625 return; 2788 return;
2626 } else {
2627 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
2628 UNIMPLEMENTED();
2629 } 2789 }
2630 break; 2790 break;
2631 } 2791 }
2632 case db_x: { 2792 case db_x: {
2633 if (FLAG_enable_sudiv) { 2793 if (FLAG_enable_sudiv) {
2634 if (!instr->HasW()) { 2794 if (!instr->HasW()) {
2635 if (instr->Bits(5, 4) == 0x1) { 2795 if (instr->Bits(5, 4) == 0x1) {
2636 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { 2796 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
2637 // sdiv (in V8 notation matching ARM ISA format) rn = rm/rs 2797 // sdiv (in V8 notation matching ARM ISA format) rn = rm/rs
2638 // Format(instr, "'sdiv'cond'b 'rn, 'rm, 'rs); 2798 // Format(instr, "'sdiv'cond'b 'rn, 'rm, 'rs);
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
3342 break; 3502 break;
3343 default: 3503 default:
3344 UNIMPLEMENTED(); // Not used by V8. 3504 UNIMPLEMENTED(); // Not used by V8.
3345 } 3505 }
3346 } else { 3506 } else {
3347 UNIMPLEMENTED(); // Not used by V8. 3507 UNIMPLEMENTED(); // Not used by V8.
3348 } 3508 }
3349 } 3509 }
3350 3510
3351 3511
3512 void Simulator::DecodeSpecialCondition(Instruction* instr) {
3513 switch (instr->SpecialValue()) {
3514 case 5:
3515 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
3516 (instr->Bit(4) == 1)) {
3517 // vmovl signed
3518 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
3519 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
3520 int imm3 = instr->Bits(21, 19);
3521 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
3522 int esize = 8 * imm3;
3523 int elements = 64 / esize;
3524 int8_t from[8];
3525 get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
3526 int16_t to[8];
3527 int e = 0;
3528 while (e < elements) {
3529 to[e] = from[e];
3530 e++;
3531 }
3532 set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
3533 } else {
3534 UNIMPLEMENTED();
3535 }
3536 break;
3537 case 7:
3538 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
3539 (instr->Bit(4) == 1)) {
3540 // vmovl unsigned
3541 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
3542 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
3543 int imm3 = instr->Bits(21, 19);
3544 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
3545 int esize = 8 * imm3;
3546 int elements = 64 / esize;
3547 uint8_t from[8];
3548 get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
3549 uint16_t to[8];
3550 int e = 0;
3551 while (e < elements) {
3552 to[e] = from[e];
3553 e++;
3554 }
3555 set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
3556 } else {
3557 UNIMPLEMENTED();
3558 }
3559 break;
3560 case 8:
3561 if (instr->Bits(21, 20) == 0) {
3562 // vst1
3563 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
3564 int Rn = instr->VnValue();
3565 int type = instr->Bits(11, 8);
3566 int Rm = instr->VmValue();
3567 int32_t address = get_register(Rn);
3568 int regs = 0;
3569 switch (type) {
3570 case nlt_1:
3571 regs = 1;
3572 break;
3573 case nlt_2:
3574 regs = 2;
3575 break;
3576 case nlt_3:
3577 regs = 3;
3578 break;
3579 case nlt_4:
3580 regs = 4;
3581 break;
3582 default:
3583 UNIMPLEMENTED();
3584 break;
3585 }
3586 int r = 0;
3587 while (r < regs) {
3588 uint32_t data[2];
3589 get_d_register(Vd + r, data);
3590 WriteW(address, data[0], instr);
3591 WriteW(address + 4, data[1], instr);
3592 address += 8;
3593 r++;
3594 }
3595 if (Rm != 15) {
3596 if (Rm == 13) {
3597 set_register(Rn, address);
3598 } else {
3599 set_register(Rn, get_register(Rn) + get_register(Rm));
3600 }
3601 }
3602 } else if (instr->Bits(21, 20) == 2) {
3603 // vld1
3604 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
3605 int Rn = instr->VnValue();
3606 int type = instr->Bits(11, 8);
3607 int Rm = instr->VmValue();
3608 int32_t address = get_register(Rn);
3609 int regs = 0;
3610 switch (type) {
3611 case nlt_1:
3612 regs = 1;
3613 break;
3614 case nlt_2:
3615 regs = 2;
3616 break;
3617 case nlt_3:
3618 regs = 3;
3619 break;
3620 case nlt_4:
3621 regs = 4;
3622 break;
3623 default:
3624 UNIMPLEMENTED();
3625 break;
3626 }
3627 int r = 0;
3628 while (r < regs) {
3629 uint32_t data[2];
3630 data[0] = ReadW(address, instr);
3631 data[1] = ReadW(address + 4, instr);
3632 set_d_register(Vd + r, data);
3633 address += 8;
3634 r++;
3635 }
3636 if (Rm != 15) {
3637 if (Rm == 13) {
3638 set_register(Rn, address);
3639 } else {
3640 set_register(Rn, get_register(Rn) + get_register(Rm));
3641 }
3642 }
3643 } else {
3644 UNIMPLEMENTED();
3645 }
3646 break;
3647 case 0xA:
3648 case 0xB:
3649 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
3650 // pld: ignore instruction.
3651 } else {
3652 UNIMPLEMENTED();
3653 }
3654 break;
3655 default:
3656 UNIMPLEMENTED();
3657 break;
3658 }
3659 }
3660
3661
3352 // Executes the current instruction. 3662 // Executes the current instruction.
3353 void Simulator::InstructionDecode(Instruction* instr) { 3663 void Simulator::InstructionDecode(Instruction* instr) {
3354 if (v8::internal::FLAG_check_icache) { 3664 if (v8::internal::FLAG_check_icache) {
3355 CheckICache(isolate_->simulator_i_cache(), instr); 3665 CheckICache(isolate_->simulator_i_cache(), instr);
3356 } 3666 }
3357 pc_modified_ = false; 3667 pc_modified_ = false;
3358 if (::v8::internal::FLAG_trace_sim) { 3668 if (::v8::internal::FLAG_trace_sim) {
3359 disasm::NameConverter converter; 3669 disasm::NameConverter converter;
3360 disasm::Disassembler dasm(converter); 3670 disasm::Disassembler dasm(converter);
3361 // use a reasonably large buffer 3671 // use a reasonably large buffer
3362 v8::internal::EmbeddedVector<char, 256> buffer; 3672 v8::internal::EmbeddedVector<char, 256> buffer;
3363 dasm.InstructionDecode(buffer, 3673 dasm.InstructionDecode(buffer,
3364 reinterpret_cast<byte*>(instr)); 3674 reinterpret_cast<byte*>(instr));
3365 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start()); 3675 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start());
3366 } 3676 }
3367 if (instr->ConditionField() == kSpecialCondition) { 3677 if (instr->ConditionField() == kSpecialCondition) {
3368 UNIMPLEMENTED(); 3678 DecodeSpecialCondition(instr);
3369 } else if (ConditionallyExecute(instr)) { 3679 } else if (ConditionallyExecute(instr)) {
3370 switch (instr->TypeValue()) { 3680 switch (instr->TypeValue()) {
3371 case 0: 3681 case 0:
3372 case 1: { 3682 case 1: {
3373 DecodeType01(instr); 3683 DecodeType01(instr);
3374 break; 3684 break;
3375 } 3685 }
3376 case 2: { 3686 case 2: {
3377 DecodeType2(instr); 3687 DecodeType2(instr);
3378 break; 3688 break;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
3577 uintptr_t address = *stack_slot; 3887 uintptr_t address = *stack_slot;
3578 set_register(sp, current_sp + sizeof(uintptr_t)); 3888 set_register(sp, current_sp + sizeof(uintptr_t));
3579 return address; 3889 return address;
3580 } 3890 }
3581 3891
3582 } } // namespace v8::internal 3892 } } // namespace v8::internal
3583 3893
3584 #endif // USE_SIMULATOR 3894 #endif // USE_SIMULATOR
3585 3895
3586 #endif // V8_TARGET_ARCH_ARM 3896 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698