| OLD | NEW | 
|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/crankshaft/ppc/lithium-codegen-ppc.h" | 5 #include "src/crankshaft/ppc/lithium-codegen-ppc.h" | 
| 6 | 6 | 
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" | 
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" | 
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" | 
| 10 #include "src/crankshaft/hydrogen-osr.h" | 10 #include "src/crankshaft/hydrogen-osr.h" | 
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 706     Translation translation(&translations_, frame_count, jsframe_count, zone()); | 706     Translation translation(&translations_, frame_count, jsframe_count, zone()); | 
| 707     WriteTranslation(environment, &translation); | 707     WriteTranslation(environment, &translation); | 
| 708     int deoptimization_index = deoptimizations_.length(); | 708     int deoptimization_index = deoptimizations_.length(); | 
| 709     int pc_offset = masm()->pc_offset(); | 709     int pc_offset = masm()->pc_offset(); | 
| 710     environment->Register(deoptimization_index, translation.index(), | 710     environment->Register(deoptimization_index, translation.index(), | 
| 711                           (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); | 711                           (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); | 
| 712     deoptimizations_.Add(environment, zone()); | 712     deoptimizations_.Add(environment, zone()); | 
| 713   } | 713   } | 
| 714 } | 714 } | 
| 715 | 715 | 
| 716 |  | 
| 717 void LCodeGen::DeoptimizeIf(Condition cond, LInstruction* instr, | 716 void LCodeGen::DeoptimizeIf(Condition cond, LInstruction* instr, | 
| 718                             Deoptimizer::DeoptReason deopt_reason, | 717                             DeoptimizeReason deopt_reason, | 
| 719                             Deoptimizer::BailoutType bailout_type, | 718                             Deoptimizer::BailoutType bailout_type, | 
| 720                             CRegister cr) { | 719                             CRegister cr) { | 
| 721   LEnvironment* environment = instr->environment(); | 720   LEnvironment* environment = instr->environment(); | 
| 722   RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 721   RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 
| 723   DCHECK(environment->HasBeenRegistered()); | 722   DCHECK(environment->HasBeenRegistered()); | 
| 724   int id = environment->deoptimization_index(); | 723   int id = environment->deoptimization_index(); | 
| 725   Address entry = | 724   Address entry = | 
| 726       Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 725       Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 
| 727   if (entry == NULL) { | 726   if (entry == NULL) { | 
| 728     Abort(kBailoutWasNotPrepared); | 727     Abort(kBailoutWasNotPrepared); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 770     // jump entry if this is the case. | 769     // jump entry if this is the case. | 
| 771     if (FLAG_trace_deopt || isolate()->is_profiling() || | 770     if (FLAG_trace_deopt || isolate()->is_profiling() || | 
| 772         jump_table_.is_empty() || | 771         jump_table_.is_empty() || | 
| 773         !table_entry.IsEquivalentTo(jump_table_.last())) { | 772         !table_entry.IsEquivalentTo(jump_table_.last())) { | 
| 774       jump_table_.Add(table_entry, zone()); | 773       jump_table_.Add(table_entry, zone()); | 
| 775     } | 774     } | 
| 776     __ b(cond, &jump_table_.last().label, cr); | 775     __ b(cond, &jump_table_.last().label, cr); | 
| 777   } | 776   } | 
| 778 } | 777 } | 
| 779 | 778 | 
| 780 |  | 
| 781 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, | 779 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, | 
| 782                             Deoptimizer::DeoptReason deopt_reason, | 780                             DeoptimizeReason deopt_reason, CRegister cr) { | 
| 783                             CRegister cr) { |  | 
| 784   Deoptimizer::BailoutType bailout_type = | 781   Deoptimizer::BailoutType bailout_type = | 
| 785       info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; | 782       info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; | 
| 786   DeoptimizeIf(condition, instr, deopt_reason, bailout_type, cr); | 783   DeoptimizeIf(condition, instr, deopt_reason, bailout_type, cr); | 
| 787 } | 784 } | 
| 788 | 785 | 
| 789 | 786 | 
| 790 void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr, | 787 void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr, | 
| 791                                             SafepointMode safepoint_mode) { | 788                                             SafepointMode safepoint_mode) { | 
| 792   if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { | 789   if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { | 
| 793     RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); | 790     RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 895   Label dividend_is_not_negative, done; | 892   Label dividend_is_not_negative, done; | 
| 896   if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { | 893   if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { | 
| 897     __ cmpwi(dividend, Operand::Zero()); | 894     __ cmpwi(dividend, Operand::Zero()); | 
| 898     __ bge(÷nd_is_not_negative); | 895     __ bge(÷nd_is_not_negative); | 
| 899     if (shift) { | 896     if (shift) { | 
| 900       // Note that this is correct even for kMinInt operands. | 897       // Note that this is correct even for kMinInt operands. | 
| 901       __ neg(dividend, dividend); | 898       __ neg(dividend, dividend); | 
| 902       __ ExtractBitRange(dividend, dividend, shift - 1, 0); | 899       __ ExtractBitRange(dividend, dividend, shift - 1, 0); | 
| 903       __ neg(dividend, dividend, LeaveOE, SetRC); | 900       __ neg(dividend, dividend, LeaveOE, SetRC); | 
| 904       if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 901       if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 905         DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, cr0); | 902         DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, cr0); | 
| 906       } | 903       } | 
| 907     } else if (!hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 904     } else if (!hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 908       __ li(dividend, Operand::Zero()); | 905       __ li(dividend, Operand::Zero()); | 
| 909     } else { | 906     } else { | 
| 910       DeoptimizeIf(al, instr, Deoptimizer::kMinusZero); | 907       DeoptimizeIf(al, instr, DeoptimizeReason::kMinusZero); | 
| 911     } | 908     } | 
| 912     __ b(&done); | 909     __ b(&done); | 
| 913   } | 910   } | 
| 914 | 911 | 
| 915   __ bind(÷nd_is_not_negative); | 912   __ bind(÷nd_is_not_negative); | 
| 916   if (shift) { | 913   if (shift) { | 
| 917     __ ExtractBitRange(dividend, dividend, shift - 1, 0); | 914     __ ExtractBitRange(dividend, dividend, shift - 1, 0); | 
| 918   } else { | 915   } else { | 
| 919     __ li(dividend, Operand::Zero()); | 916     __ li(dividend, Operand::Zero()); | 
| 920   } | 917   } | 
| 921   __ bind(&done); | 918   __ bind(&done); | 
| 922 } | 919 } | 
| 923 | 920 | 
| 924 | 921 | 
| 925 void LCodeGen::DoModByConstI(LModByConstI* instr) { | 922 void LCodeGen::DoModByConstI(LModByConstI* instr) { | 
| 926   Register dividend = ToRegister(instr->dividend()); | 923   Register dividend = ToRegister(instr->dividend()); | 
| 927   int32_t divisor = instr->divisor(); | 924   int32_t divisor = instr->divisor(); | 
| 928   Register result = ToRegister(instr->result()); | 925   Register result = ToRegister(instr->result()); | 
| 929   DCHECK(!dividend.is(result)); | 926   DCHECK(!dividend.is(result)); | 
| 930 | 927 | 
| 931   if (divisor == 0) { | 928   if (divisor == 0) { | 
| 932     DeoptimizeIf(al, instr, Deoptimizer::kDivisionByZero); | 929     DeoptimizeIf(al, instr, DeoptimizeReason::kDivisionByZero); | 
| 933     return; | 930     return; | 
| 934   } | 931   } | 
| 935 | 932 | 
| 936   __ TruncatingDiv(result, dividend, Abs(divisor)); | 933   __ TruncatingDiv(result, dividend, Abs(divisor)); | 
| 937   __ mov(ip, Operand(Abs(divisor))); | 934   __ mov(ip, Operand(Abs(divisor))); | 
| 938   __ mullw(result, result, ip); | 935   __ mullw(result, result, ip); | 
| 939   __ sub(result, dividend, result, LeaveOE, SetRC); | 936   __ sub(result, dividend, result, LeaveOE, SetRC); | 
| 940 | 937 | 
| 941   // Check for negative zero. | 938   // Check for negative zero. | 
| 942   HMod* hmod = instr->hydrogen(); | 939   HMod* hmod = instr->hydrogen(); | 
| 943   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 940   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 944     Label remainder_not_zero; | 941     Label remainder_not_zero; | 
| 945     __ bne(&remainder_not_zero, cr0); | 942     __ bne(&remainder_not_zero, cr0); | 
| 946     __ cmpwi(dividend, Operand::Zero()); | 943     __ cmpwi(dividend, Operand::Zero()); | 
| 947     DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 944     DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 948     __ bind(&remainder_not_zero); | 945     __ bind(&remainder_not_zero); | 
| 949   } | 946   } | 
| 950 } | 947 } | 
| 951 | 948 | 
| 952 | 949 | 
| 953 void LCodeGen::DoModI(LModI* instr) { | 950 void LCodeGen::DoModI(LModI* instr) { | 
| 954   HMod* hmod = instr->hydrogen(); | 951   HMod* hmod = instr->hydrogen(); | 
| 955   Register left_reg = ToRegister(instr->left()); | 952   Register left_reg = ToRegister(instr->left()); | 
| 956   Register right_reg = ToRegister(instr->right()); | 953   Register right_reg = ToRegister(instr->right()); | 
| 957   Register result_reg = ToRegister(instr->result()); | 954   Register result_reg = ToRegister(instr->result()); | 
| 958   Register scratch = scratch0(); | 955   Register scratch = scratch0(); | 
| 959   bool can_overflow = hmod->CheckFlag(HValue::kCanOverflow); | 956   bool can_overflow = hmod->CheckFlag(HValue::kCanOverflow); | 
| 960   Label done; | 957   Label done; | 
| 961 | 958 | 
| 962   if (can_overflow) { | 959   if (can_overflow) { | 
| 963     __ li(r0, Operand::Zero());  // clear xer | 960     __ li(r0, Operand::Zero());  // clear xer | 
| 964     __ mtxer(r0); | 961     __ mtxer(r0); | 
| 965   } | 962   } | 
| 966 | 963 | 
| 967   __ divw(scratch, left_reg, right_reg, SetOE, SetRC); | 964   __ divw(scratch, left_reg, right_reg, SetOE, SetRC); | 
| 968 | 965 | 
| 969   // Check for x % 0. | 966   // Check for x % 0. | 
| 970   if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { | 967   if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { | 
| 971     __ cmpwi(right_reg, Operand::Zero()); | 968     __ cmpwi(right_reg, Operand::Zero()); | 
| 972     DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero); | 969     DeoptimizeIf(eq, instr, DeoptimizeReason::kDivisionByZero); | 
| 973   } | 970   } | 
| 974 | 971 | 
| 975   // Check for kMinInt % -1, divw will return undefined, which is not what we | 972   // Check for kMinInt % -1, divw will return undefined, which is not what we | 
| 976   // want. We have to deopt if we care about -0, because we can't return that. | 973   // want. We have to deopt if we care about -0, because we can't return that. | 
| 977   if (can_overflow) { | 974   if (can_overflow) { | 
| 978     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 975     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 979       DeoptimizeIf(overflow, instr, Deoptimizer::kMinusZero, cr0); | 976       DeoptimizeIf(overflow, instr, DeoptimizeReason::kMinusZero, cr0); | 
| 980     } else { | 977     } else { | 
| 981       if (CpuFeatures::IsSupported(ISELECT)) { | 978       if (CpuFeatures::IsSupported(ISELECT)) { | 
| 982         __ isel(overflow, result_reg, r0, result_reg, cr0); | 979         __ isel(overflow, result_reg, r0, result_reg, cr0); | 
| 983         __ boverflow(&done, cr0); | 980         __ boverflow(&done, cr0); | 
| 984       } else { | 981       } else { | 
| 985         Label no_overflow_possible; | 982         Label no_overflow_possible; | 
| 986         __ bnooverflow(&no_overflow_possible, cr0); | 983         __ bnooverflow(&no_overflow_possible, cr0); | 
| 987         __ li(result_reg, Operand::Zero()); | 984         __ li(result_reg, Operand::Zero()); | 
| 988         __ b(&done); | 985         __ b(&done); | 
| 989         __ bind(&no_overflow_possible); | 986         __ bind(&no_overflow_possible); | 
| 990       } | 987       } | 
| 991     } | 988     } | 
| 992   } | 989   } | 
| 993 | 990 | 
| 994   __ mullw(scratch, right_reg, scratch); | 991   __ mullw(scratch, right_reg, scratch); | 
| 995   __ sub(result_reg, left_reg, scratch, LeaveOE, SetRC); | 992   __ sub(result_reg, left_reg, scratch, LeaveOE, SetRC); | 
| 996 | 993 | 
| 997   // If we care about -0, test if the dividend is <0 and the result is 0. | 994   // If we care about -0, test if the dividend is <0 and the result is 0. | 
| 998   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 995   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 999     __ bne(&done, cr0); | 996     __ bne(&done, cr0); | 
| 1000     __ cmpwi(left_reg, Operand::Zero()); | 997     __ cmpwi(left_reg, Operand::Zero()); | 
| 1001     DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 998     DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 1002   } | 999   } | 
| 1003 | 1000 | 
| 1004   __ bind(&done); | 1001   __ bind(&done); | 
| 1005 } | 1002 } | 
| 1006 | 1003 | 
| 1007 | 1004 | 
| 1008 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { | 1005 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { | 
| 1009   Register dividend = ToRegister(instr->dividend()); | 1006   Register dividend = ToRegister(instr->dividend()); | 
| 1010   int32_t divisor = instr->divisor(); | 1007   int32_t divisor = instr->divisor(); | 
| 1011   Register result = ToRegister(instr->result()); | 1008   Register result = ToRegister(instr->result()); | 
| 1012   DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); | 1009   DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); | 
| 1013   DCHECK(!result.is(dividend)); | 1010   DCHECK(!result.is(dividend)); | 
| 1014 | 1011 | 
| 1015   // Check for (0 / -x) that will produce negative zero. | 1012   // Check for (0 / -x) that will produce negative zero. | 
| 1016   HDiv* hdiv = instr->hydrogen(); | 1013   HDiv* hdiv = instr->hydrogen(); | 
| 1017   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 1014   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 
| 1018     __ cmpwi(dividend, Operand::Zero()); | 1015     __ cmpwi(dividend, Operand::Zero()); | 
| 1019     DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero); | 1016     DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero); | 
| 1020   } | 1017   } | 
| 1021   // Check for (kMinInt / -1). | 1018   // Check for (kMinInt / -1). | 
| 1022   if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { | 1019   if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { | 
| 1023     __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 1020     __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 
| 1024     __ cmpw(dividend, r0); | 1021     __ cmpw(dividend, r0); | 
| 1025     DeoptimizeIf(eq, instr, Deoptimizer::kOverflow); | 1022     DeoptimizeIf(eq, instr, DeoptimizeReason::kOverflow); | 
| 1026   } | 1023   } | 
| 1027 | 1024 | 
| 1028   int32_t shift = WhichPowerOf2Abs(divisor); | 1025   int32_t shift = WhichPowerOf2Abs(divisor); | 
| 1029 | 1026 | 
| 1030   // Deoptimize if remainder will not be 0. | 1027   // Deoptimize if remainder will not be 0. | 
| 1031   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && shift) { | 1028   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && shift) { | 
| 1032     __ TestBitRange(dividend, shift - 1, 0, r0); | 1029     __ TestBitRange(dividend, shift - 1, 0, r0); | 
| 1033     DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecision, cr0); | 1030     DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecision, cr0); | 
| 1034   } | 1031   } | 
| 1035 | 1032 | 
| 1036   if (divisor == -1) {  // Nice shortcut, not needed for correctness. | 1033   if (divisor == -1) {  // Nice shortcut, not needed for correctness. | 
| 1037     __ neg(result, dividend); | 1034     __ neg(result, dividend); | 
| 1038     return; | 1035     return; | 
| 1039   } | 1036   } | 
| 1040   if (shift == 0) { | 1037   if (shift == 0) { | 
| 1041     __ mr(result, dividend); | 1038     __ mr(result, dividend); | 
| 1042   } else { | 1039   } else { | 
| 1043     if (shift == 1) { | 1040     if (shift == 1) { | 
| 1044       __ srwi(result, dividend, Operand(31)); | 1041       __ srwi(result, dividend, Operand(31)); | 
| 1045     } else { | 1042     } else { | 
| 1046       __ srawi(result, dividend, 31); | 1043       __ srawi(result, dividend, 31); | 
| 1047       __ srwi(result, result, Operand(32 - shift)); | 1044       __ srwi(result, result, Operand(32 - shift)); | 
| 1048     } | 1045     } | 
| 1049     __ add(result, dividend, result); | 1046     __ add(result, dividend, result); | 
| 1050     __ srawi(result, result, shift); | 1047     __ srawi(result, result, shift); | 
| 1051   } | 1048   } | 
| 1052   if (divisor < 0) __ neg(result, result); | 1049   if (divisor < 0) __ neg(result, result); | 
| 1053 } | 1050 } | 
| 1054 | 1051 | 
| 1055 | 1052 | 
| 1056 void LCodeGen::DoDivByConstI(LDivByConstI* instr) { | 1053 void LCodeGen::DoDivByConstI(LDivByConstI* instr) { | 
| 1057   Register dividend = ToRegister(instr->dividend()); | 1054   Register dividend = ToRegister(instr->dividend()); | 
| 1058   int32_t divisor = instr->divisor(); | 1055   int32_t divisor = instr->divisor(); | 
| 1059   Register result = ToRegister(instr->result()); | 1056   Register result = ToRegister(instr->result()); | 
| 1060   DCHECK(!dividend.is(result)); | 1057   DCHECK(!dividend.is(result)); | 
| 1061 | 1058 | 
| 1062   if (divisor == 0) { | 1059   if (divisor == 0) { | 
| 1063     DeoptimizeIf(al, instr, Deoptimizer::kDivisionByZero); | 1060     DeoptimizeIf(al, instr, DeoptimizeReason::kDivisionByZero); | 
| 1064     return; | 1061     return; | 
| 1065   } | 1062   } | 
| 1066 | 1063 | 
| 1067   // Check for (0 / -x) that will produce negative zero. | 1064   // Check for (0 / -x) that will produce negative zero. | 
| 1068   HDiv* hdiv = instr->hydrogen(); | 1065   HDiv* hdiv = instr->hydrogen(); | 
| 1069   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 1066   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 
| 1070     __ cmpwi(dividend, Operand::Zero()); | 1067     __ cmpwi(dividend, Operand::Zero()); | 
| 1071     DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero); | 1068     DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero); | 
| 1072   } | 1069   } | 
| 1073 | 1070 | 
| 1074   __ TruncatingDiv(result, dividend, Abs(divisor)); | 1071   __ TruncatingDiv(result, dividend, Abs(divisor)); | 
| 1075   if (divisor < 0) __ neg(result, result); | 1072   if (divisor < 0) __ neg(result, result); | 
| 1076 | 1073 | 
| 1077   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1074   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 
| 1078     Register scratch = scratch0(); | 1075     Register scratch = scratch0(); | 
| 1079     __ mov(ip, Operand(divisor)); | 1076     __ mov(ip, Operand(divisor)); | 
| 1080     __ mullw(scratch, result, ip); | 1077     __ mullw(scratch, result, ip); | 
| 1081     __ cmpw(scratch, dividend); | 1078     __ cmpw(scratch, dividend); | 
| 1082     DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecision); | 1079     DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecision); | 
| 1083   } | 1080   } | 
| 1084 } | 1081 } | 
| 1085 | 1082 | 
| 1086 | 1083 | 
| 1087 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. | 1084 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. | 
| 1088 void LCodeGen::DoDivI(LDivI* instr) { | 1085 void LCodeGen::DoDivI(LDivI* instr) { | 
| 1089   HBinaryOperation* hdiv = instr->hydrogen(); | 1086   HBinaryOperation* hdiv = instr->hydrogen(); | 
| 1090   const Register dividend = ToRegister(instr->dividend()); | 1087   const Register dividend = ToRegister(instr->dividend()); | 
| 1091   const Register divisor = ToRegister(instr->divisor()); | 1088   const Register divisor = ToRegister(instr->divisor()); | 
| 1092   Register result = ToRegister(instr->result()); | 1089   Register result = ToRegister(instr->result()); | 
| 1093   bool can_overflow = hdiv->CheckFlag(HValue::kCanOverflow); | 1090   bool can_overflow = hdiv->CheckFlag(HValue::kCanOverflow); | 
| 1094 | 1091 | 
| 1095   DCHECK(!dividend.is(result)); | 1092   DCHECK(!dividend.is(result)); | 
| 1096   DCHECK(!divisor.is(result)); | 1093   DCHECK(!divisor.is(result)); | 
| 1097 | 1094 | 
| 1098   if (can_overflow) { | 1095   if (can_overflow) { | 
| 1099     __ li(r0, Operand::Zero());  // clear xer | 1096     __ li(r0, Operand::Zero());  // clear xer | 
| 1100     __ mtxer(r0); | 1097     __ mtxer(r0); | 
| 1101   } | 1098   } | 
| 1102 | 1099 | 
| 1103   __ divw(result, dividend, divisor, SetOE, SetRC); | 1100   __ divw(result, dividend, divisor, SetOE, SetRC); | 
| 1104 | 1101 | 
| 1105   // Check for x / 0. | 1102   // Check for x / 0. | 
| 1106   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { | 1103   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { | 
| 1107     __ cmpwi(divisor, Operand::Zero()); | 1104     __ cmpwi(divisor, Operand::Zero()); | 
| 1108     DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero); | 1105     DeoptimizeIf(eq, instr, DeoptimizeReason::kDivisionByZero); | 
| 1109   } | 1106   } | 
| 1110 | 1107 | 
| 1111   // Check for (0 / -x) that will produce negative zero. | 1108   // Check for (0 / -x) that will produce negative zero. | 
| 1112   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1109   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 1113     Label dividend_not_zero; | 1110     Label dividend_not_zero; | 
| 1114     __ cmpwi(dividend, Operand::Zero()); | 1111     __ cmpwi(dividend, Operand::Zero()); | 
| 1115     __ bne(÷nd_not_zero); | 1112     __ bne(÷nd_not_zero); | 
| 1116     __ cmpwi(divisor, Operand::Zero()); | 1113     __ cmpwi(divisor, Operand::Zero()); | 
| 1117     DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 1114     DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 1118     __ bind(÷nd_not_zero); | 1115     __ bind(÷nd_not_zero); | 
| 1119   } | 1116   } | 
| 1120 | 1117 | 
| 1121   // Check for (kMinInt / -1). | 1118   // Check for (kMinInt / -1). | 
| 1122   if (can_overflow) { | 1119   if (can_overflow) { | 
| 1123     if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 1120     if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 
| 1124       DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow, cr0); | 1121       DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow, cr0); | 
| 1125     } else { | 1122     } else { | 
| 1126       // When truncating, we want kMinInt / -1 = kMinInt. | 1123       // When truncating, we want kMinInt / -1 = kMinInt. | 
| 1127       if (CpuFeatures::IsSupported(ISELECT)) { | 1124       if (CpuFeatures::IsSupported(ISELECT)) { | 
| 1128         __ isel(overflow, result, dividend, result, cr0); | 1125         __ isel(overflow, result, dividend, result, cr0); | 
| 1129       } else { | 1126       } else { | 
| 1130         Label no_overflow_possible; | 1127         Label no_overflow_possible; | 
| 1131         __ bnooverflow(&no_overflow_possible, cr0); | 1128         __ bnooverflow(&no_overflow_possible, cr0); | 
| 1132         __ mr(result, dividend); | 1129         __ mr(result, dividend); | 
| 1133         __ bind(&no_overflow_possible); | 1130         __ bind(&no_overflow_possible); | 
| 1134       } | 1131       } | 
| 1135     } | 1132     } | 
| 1136   } | 1133   } | 
| 1137 | 1134 | 
| 1138 #if V8_TARGET_ARCH_PPC64 | 1135 #if V8_TARGET_ARCH_PPC64 | 
| 1139   __ extsw(result, result); | 1136   __ extsw(result, result); | 
| 1140 #endif | 1137 #endif | 
| 1141 | 1138 | 
| 1142   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1139   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 
| 1143     // Deoptimize if remainder is not 0. | 1140     // Deoptimize if remainder is not 0. | 
| 1144     Register scratch = scratch0(); | 1141     Register scratch = scratch0(); | 
| 1145     __ mullw(scratch, divisor, result); | 1142     __ mullw(scratch, divisor, result); | 
| 1146     __ cmpw(dividend, scratch); | 1143     __ cmpw(dividend, scratch); | 
| 1147     DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecision); | 1144     DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecision); | 
| 1148   } | 1145   } | 
| 1149 } | 1146 } | 
| 1150 | 1147 | 
| 1151 | 1148 | 
| 1152 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { | 1149 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { | 
| 1153   HBinaryOperation* hdiv = instr->hydrogen(); | 1150   HBinaryOperation* hdiv = instr->hydrogen(); | 
| 1154   Register dividend = ToRegister(instr->dividend()); | 1151   Register dividend = ToRegister(instr->dividend()); | 
| 1155   Register result = ToRegister(instr->result()); | 1152   Register result = ToRegister(instr->result()); | 
| 1156   int32_t divisor = instr->divisor(); | 1153   int32_t divisor = instr->divisor(); | 
| 1157   bool can_overflow = hdiv->CheckFlag(HValue::kLeftCanBeMinInt); | 1154   bool can_overflow = hdiv->CheckFlag(HValue::kLeftCanBeMinInt); | 
| 1158 | 1155 | 
| 1159   // If the divisor is positive, things are easy: There can be no deopts and we | 1156   // If the divisor is positive, things are easy: There can be no deopts and we | 
| 1160   // can simply do an arithmetic right shift. | 1157   // can simply do an arithmetic right shift. | 
| 1161   int32_t shift = WhichPowerOf2Abs(divisor); | 1158   int32_t shift = WhichPowerOf2Abs(divisor); | 
| 1162   if (divisor > 0) { | 1159   if (divisor > 0) { | 
| 1163     if (shift || !result.is(dividend)) { | 1160     if (shift || !result.is(dividend)) { | 
| 1164       __ srawi(result, dividend, shift); | 1161       __ srawi(result, dividend, shift); | 
| 1165     } | 1162     } | 
| 1166     return; | 1163     return; | 
| 1167   } | 1164   } | 
| 1168 | 1165 | 
| 1169   // If the divisor is negative, we have to negate and handle edge cases. | 1166   // If the divisor is negative, we have to negate and handle edge cases. | 
| 1170   OEBit oe = LeaveOE; | 1167   OEBit oe = LeaveOE; | 
| 1171 #if V8_TARGET_ARCH_PPC64 | 1168 #if V8_TARGET_ARCH_PPC64 | 
| 1172   if (divisor == -1 && can_overflow) { | 1169   if (divisor == -1 && can_overflow) { | 
| 1173     __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 1170     __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 
| 1174     __ cmpw(dividend, r0); | 1171     __ cmpw(dividend, r0); | 
| 1175     DeoptimizeIf(eq, instr, Deoptimizer::kOverflow); | 1172     DeoptimizeIf(eq, instr, DeoptimizeReason::kOverflow); | 
| 1176   } | 1173   } | 
| 1177 #else | 1174 #else | 
| 1178   if (can_overflow) { | 1175   if (can_overflow) { | 
| 1179     __ li(r0, Operand::Zero());  // clear xer | 1176     __ li(r0, Operand::Zero());  // clear xer | 
| 1180     __ mtxer(r0); | 1177     __ mtxer(r0); | 
| 1181     oe = SetOE; | 1178     oe = SetOE; | 
| 1182   } | 1179   } | 
| 1183 #endif | 1180 #endif | 
| 1184 | 1181 | 
| 1185   __ neg(result, dividend, oe, SetRC); | 1182   __ neg(result, dividend, oe, SetRC); | 
| 1186   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1183   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 1187     DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, cr0); | 1184     DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero, cr0); | 
| 1188   } | 1185   } | 
| 1189 | 1186 | 
| 1190 // If the negation could not overflow, simply shifting is OK. | 1187 // If the negation could not overflow, simply shifting is OK. | 
| 1191 #if !V8_TARGET_ARCH_PPC64 | 1188 #if !V8_TARGET_ARCH_PPC64 | 
| 1192   if (!can_overflow) { | 1189   if (!can_overflow) { | 
| 1193 #endif | 1190 #endif | 
| 1194     if (shift) { | 1191     if (shift) { | 
| 1195       __ ShiftRightArithImm(result, result, shift); | 1192       __ ShiftRightArithImm(result, result, shift); | 
| 1196     } | 1193     } | 
| 1197     return; | 1194     return; | 
| 1198 #if !V8_TARGET_ARCH_PPC64 | 1195 #if !V8_TARGET_ARCH_PPC64 | 
| 1199   } | 1196   } | 
| 1200 | 1197 | 
| 1201   // Dividing by -1 is basically negation, unless we overflow. | 1198   // Dividing by -1 is basically negation, unless we overflow. | 
| 1202   if (divisor == -1) { | 1199   if (divisor == -1) { | 
| 1203     DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow, cr0); | 1200     DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow, cr0); | 
| 1204     return; | 1201     return; | 
| 1205   } | 1202   } | 
| 1206 | 1203 | 
| 1207   Label overflow, done; | 1204   Label overflow, done; | 
| 1208   __ boverflow(&overflow, cr0); | 1205   __ boverflow(&overflow, cr0); | 
| 1209   __ srawi(result, result, shift); | 1206   __ srawi(result, result, shift); | 
| 1210   __ b(&done); | 1207   __ b(&done); | 
| 1211   __ bind(&overflow); | 1208   __ bind(&overflow); | 
| 1212   __ mov(result, Operand(kMinInt / divisor)); | 1209   __ mov(result, Operand(kMinInt / divisor)); | 
| 1213   __ bind(&done); | 1210   __ bind(&done); | 
| 1214 #endif | 1211 #endif | 
| 1215 } | 1212 } | 
| 1216 | 1213 | 
| 1217 | 1214 | 
| 1218 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { | 1215 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { | 
| 1219   Register dividend = ToRegister(instr->dividend()); | 1216   Register dividend = ToRegister(instr->dividend()); | 
| 1220   int32_t divisor = instr->divisor(); | 1217   int32_t divisor = instr->divisor(); | 
| 1221   Register result = ToRegister(instr->result()); | 1218   Register result = ToRegister(instr->result()); | 
| 1222   DCHECK(!dividend.is(result)); | 1219   DCHECK(!dividend.is(result)); | 
| 1223 | 1220 | 
| 1224   if (divisor == 0) { | 1221   if (divisor == 0) { | 
| 1225     DeoptimizeIf(al, instr, Deoptimizer::kDivisionByZero); | 1222     DeoptimizeIf(al, instr, DeoptimizeReason::kDivisionByZero); | 
| 1226     return; | 1223     return; | 
| 1227   } | 1224   } | 
| 1228 | 1225 | 
| 1229   // Check for (0 / -x) that will produce negative zero. | 1226   // Check for (0 / -x) that will produce negative zero. | 
| 1230   HMathFloorOfDiv* hdiv = instr->hydrogen(); | 1227   HMathFloorOfDiv* hdiv = instr->hydrogen(); | 
| 1231   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 1228   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 
| 1232     __ cmpwi(dividend, Operand::Zero()); | 1229     __ cmpwi(dividend, Operand::Zero()); | 
| 1233     DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero); | 1230     DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero); | 
| 1234   } | 1231   } | 
| 1235 | 1232 | 
| 1236   // Easy case: We need no dynamic check for the dividend and the flooring | 1233   // Easy case: We need no dynamic check for the dividend and the flooring | 
| 1237   // division is the same as the truncating division. | 1234   // division is the same as the truncating division. | 
| 1238   if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || | 1235   if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || | 
| 1239       (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { | 1236       (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { | 
| 1240     __ TruncatingDiv(result, dividend, Abs(divisor)); | 1237     __ TruncatingDiv(result, dividend, Abs(divisor)); | 
| 1241     if (divisor < 0) __ neg(result, result); | 1238     if (divisor < 0) __ neg(result, result); | 
| 1242     return; | 1239     return; | 
| 1243   } | 1240   } | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1275   if (can_overflow) { | 1272   if (can_overflow) { | 
| 1276     __ li(r0, Operand::Zero());  // clear xer | 1273     __ li(r0, Operand::Zero());  // clear xer | 
| 1277     __ mtxer(r0); | 1274     __ mtxer(r0); | 
| 1278   } | 1275   } | 
| 1279 | 1276 | 
| 1280   __ divw(result, dividend, divisor, SetOE, SetRC); | 1277   __ divw(result, dividend, divisor, SetOE, SetRC); | 
| 1281 | 1278 | 
| 1282   // Check for x / 0. | 1279   // Check for x / 0. | 
| 1283   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { | 1280   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { | 
| 1284     __ cmpwi(divisor, Operand::Zero()); | 1281     __ cmpwi(divisor, Operand::Zero()); | 
| 1285     DeoptimizeIf(eq, instr, Deoptimizer::kDivisionByZero); | 1282     DeoptimizeIf(eq, instr, DeoptimizeReason::kDivisionByZero); | 
| 1286   } | 1283   } | 
| 1287 | 1284 | 
| 1288   // Check for (0 / -x) that will produce negative zero. | 1285   // Check for (0 / -x) that will produce negative zero. | 
| 1289   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1286   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 1290     Label dividend_not_zero; | 1287     Label dividend_not_zero; | 
| 1291     __ cmpwi(dividend, Operand::Zero()); | 1288     __ cmpwi(dividend, Operand::Zero()); | 
| 1292     __ bne(÷nd_not_zero); | 1289     __ bne(÷nd_not_zero); | 
| 1293     __ cmpwi(divisor, Operand::Zero()); | 1290     __ cmpwi(divisor, Operand::Zero()); | 
| 1294     DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 1291     DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 1295     __ bind(÷nd_not_zero); | 1292     __ bind(÷nd_not_zero); | 
| 1296   } | 1293   } | 
| 1297 | 1294 | 
| 1298   // Check for (kMinInt / -1). | 1295   // Check for (kMinInt / -1). | 
| 1299   if (can_overflow) { | 1296   if (can_overflow) { | 
| 1300     if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 1297     if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 
| 1301       DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow, cr0); | 1298       DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow, cr0); | 
| 1302     } else { | 1299     } else { | 
| 1303       // When truncating, we want kMinInt / -1 = kMinInt. | 1300       // When truncating, we want kMinInt / -1 = kMinInt. | 
| 1304       if (CpuFeatures::IsSupported(ISELECT)) { | 1301       if (CpuFeatures::IsSupported(ISELECT)) { | 
| 1305         __ isel(overflow, result, dividend, result, cr0); | 1302         __ isel(overflow, result, dividend, result, cr0); | 
| 1306       } else { | 1303       } else { | 
| 1307         Label no_overflow_possible; | 1304         Label no_overflow_possible; | 
| 1308         __ bnooverflow(&no_overflow_possible, cr0); | 1305         __ bnooverflow(&no_overflow_possible, cr0); | 
| 1309         __ mr(result, dividend); | 1306         __ mr(result, dividend); | 
| 1310         __ bind(&no_overflow_possible); | 1307         __ bind(&no_overflow_possible); | 
| 1311       } | 1308       } | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1369       instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 1366       instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 
| 1370   bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1367   bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 
| 1371 | 1368 | 
| 1372   if (right_op->IsConstantOperand()) { | 1369   if (right_op->IsConstantOperand()) { | 
| 1373     int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); | 1370     int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); | 
| 1374 | 1371 | 
| 1375     if (bailout_on_minus_zero && (constant < 0)) { | 1372     if (bailout_on_minus_zero && (constant < 0)) { | 
| 1376       // The case of a null constant will be handled separately. | 1373       // The case of a null constant will be handled separately. | 
| 1377       // If constant is negative and left is null, the result should be -0. | 1374       // If constant is negative and left is null, the result should be -0. | 
| 1378       __ cmpi(left, Operand::Zero()); | 1375       __ cmpi(left, Operand::Zero()); | 
| 1379       DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero); | 1376       DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero); | 
| 1380     } | 1377     } | 
| 1381 | 1378 | 
| 1382     switch (constant) { | 1379     switch (constant) { | 
| 1383       case -1: | 1380       case -1: | 
| 1384         if (can_overflow) { | 1381         if (can_overflow) { | 
| 1385 #if V8_TARGET_ARCH_PPC64 | 1382 #if V8_TARGET_ARCH_PPC64 | 
| 1386           if (instr->hydrogen()->representation().IsSmi()) { | 1383           if (instr->hydrogen()->representation().IsSmi()) { | 
| 1387 #endif | 1384 #endif | 
| 1388             __ li(r0, Operand::Zero());  // clear xer | 1385             __ li(r0, Operand::Zero());  // clear xer | 
| 1389             __ mtxer(r0); | 1386             __ mtxer(r0); | 
| 1390             __ neg(result, left, SetOE, SetRC); | 1387             __ neg(result, left, SetOE, SetRC); | 
| 1391             DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow, cr0); | 1388             DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow, cr0); | 
| 1392 #if V8_TARGET_ARCH_PPC64 | 1389 #if V8_TARGET_ARCH_PPC64 | 
| 1393           } else { | 1390           } else { | 
| 1394             __ neg(result, left); | 1391             __ neg(result, left); | 
| 1395             __ TestIfInt32(result, r0); | 1392             __ TestIfInt32(result, r0); | 
| 1396             DeoptimizeIf(ne, instr, Deoptimizer::kOverflow); | 1393             DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); | 
| 1397           } | 1394           } | 
| 1398 #endif | 1395 #endif | 
| 1399         } else { | 1396         } else { | 
| 1400           __ neg(result, left); | 1397           __ neg(result, left); | 
| 1401         } | 1398         } | 
| 1402         break; | 1399         break; | 
| 1403       case 0: | 1400       case 0: | 
| 1404         if (bailout_on_minus_zero) { | 1401         if (bailout_on_minus_zero) { | 
| 1405 // If left is strictly negative and the constant is null, the | 1402 // If left is strictly negative and the constant is null, the | 
| 1406 // result is -0. Deoptimize if required, otherwise return 0. | 1403 // result is -0. Deoptimize if required, otherwise return 0. | 
| 1407 #if V8_TARGET_ARCH_PPC64 | 1404 #if V8_TARGET_ARCH_PPC64 | 
| 1408           if (instr->hydrogen()->representation().IsSmi()) { | 1405           if (instr->hydrogen()->representation().IsSmi()) { | 
| 1409 #endif | 1406 #endif | 
| 1410             __ cmpi(left, Operand::Zero()); | 1407             __ cmpi(left, Operand::Zero()); | 
| 1411 #if V8_TARGET_ARCH_PPC64 | 1408 #if V8_TARGET_ARCH_PPC64 | 
| 1412           } else { | 1409           } else { | 
| 1413             __ cmpwi(left, Operand::Zero()); | 1410             __ cmpwi(left, Operand::Zero()); | 
| 1414           } | 1411           } | 
| 1415 #endif | 1412 #endif | 
| 1416           DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 1413           DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 1417         } | 1414         } | 
| 1418         __ li(result, Operand::Zero()); | 1415         __ li(result, Operand::Zero()); | 
| 1419         break; | 1416         break; | 
| 1420       case 1: | 1417       case 1: | 
| 1421         __ Move(result, left); | 1418         __ Move(result, left); | 
| 1422         break; | 1419         break; | 
| 1423       default: | 1420       default: | 
| 1424         // Multiplying by powers of two and powers of two plus or minus | 1421         // Multiplying by powers of two and powers of two plus or minus | 
| 1425         // one can be done faster with shifted operands. | 1422         // one can be done faster with shifted operands. | 
| 1426         // For other constants we emit standard code. | 1423         // For other constants we emit standard code. | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1459 #if V8_TARGET_ARCH_PPC64 | 1456 #if V8_TARGET_ARCH_PPC64 | 
| 1460       // result = left * right. | 1457       // result = left * right. | 
| 1461       if (instr->hydrogen()->representation().IsSmi()) { | 1458       if (instr->hydrogen()->representation().IsSmi()) { | 
| 1462         __ SmiUntag(result, left); | 1459         __ SmiUntag(result, left); | 
| 1463         __ SmiUntag(scratch, right); | 1460         __ SmiUntag(scratch, right); | 
| 1464         __ Mul(result, result, scratch); | 1461         __ Mul(result, result, scratch); | 
| 1465       } else { | 1462       } else { | 
| 1466         __ Mul(result, left, right); | 1463         __ Mul(result, left, right); | 
| 1467       } | 1464       } | 
| 1468       __ TestIfInt32(result, r0); | 1465       __ TestIfInt32(result, r0); | 
| 1469       DeoptimizeIf(ne, instr, Deoptimizer::kOverflow); | 1466       DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); | 
| 1470       if (instr->hydrogen()->representation().IsSmi()) { | 1467       if (instr->hydrogen()->representation().IsSmi()) { | 
| 1471         __ SmiTag(result); | 1468         __ SmiTag(result); | 
| 1472       } | 1469       } | 
| 1473 #else | 1470 #else | 
| 1474       // scratch:result = left * right. | 1471       // scratch:result = left * right. | 
| 1475       if (instr->hydrogen()->representation().IsSmi()) { | 1472       if (instr->hydrogen()->representation().IsSmi()) { | 
| 1476         __ SmiUntag(result, left); | 1473         __ SmiUntag(result, left); | 
| 1477         __ mulhw(scratch, result, right); | 1474         __ mulhw(scratch, result, right); | 
| 1478         __ mullw(result, result, right); | 1475         __ mullw(result, result, right); | 
| 1479       } else { | 1476       } else { | 
| 1480         __ mulhw(scratch, left, right); | 1477         __ mulhw(scratch, left, right); | 
| 1481         __ mullw(result, left, right); | 1478         __ mullw(result, left, right); | 
| 1482       } | 1479       } | 
| 1483       __ TestIfInt32(scratch, result, r0); | 1480       __ TestIfInt32(scratch, result, r0); | 
| 1484       DeoptimizeIf(ne, instr, Deoptimizer::kOverflow); | 1481       DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); | 
| 1485 #endif | 1482 #endif | 
| 1486     } else { | 1483     } else { | 
| 1487       if (instr->hydrogen()->representation().IsSmi()) { | 1484       if (instr->hydrogen()->representation().IsSmi()) { | 
| 1488         __ SmiUntag(result, left); | 1485         __ SmiUntag(result, left); | 
| 1489         __ Mul(result, result, right); | 1486         __ Mul(result, result, right); | 
| 1490       } else { | 1487       } else { | 
| 1491         __ Mul(result, left, right); | 1488         __ Mul(result, left, right); | 
| 1492       } | 1489       } | 
| 1493     } | 1490     } | 
| 1494 | 1491 | 
| 1495     if (bailout_on_minus_zero) { | 1492     if (bailout_on_minus_zero) { | 
| 1496       Label done; | 1493       Label done; | 
| 1497 #if V8_TARGET_ARCH_PPC64 | 1494 #if V8_TARGET_ARCH_PPC64 | 
| 1498       if (instr->hydrogen()->representation().IsSmi()) { | 1495       if (instr->hydrogen()->representation().IsSmi()) { | 
| 1499 #endif | 1496 #endif | 
| 1500         __ xor_(r0, left, right, SetRC); | 1497         __ xor_(r0, left, right, SetRC); | 
| 1501         __ bge(&done, cr0); | 1498         __ bge(&done, cr0); | 
| 1502 #if V8_TARGET_ARCH_PPC64 | 1499 #if V8_TARGET_ARCH_PPC64 | 
| 1503       } else { | 1500       } else { | 
| 1504         __ xor_(r0, left, right); | 1501         __ xor_(r0, left, right); | 
| 1505         __ cmpwi(r0, Operand::Zero()); | 1502         __ cmpwi(r0, Operand::Zero()); | 
| 1506         __ bge(&done); | 1503         __ bge(&done); | 
| 1507       } | 1504       } | 
| 1508 #endif | 1505 #endif | 
| 1509       // Bail out if the result is minus zero. | 1506       // Bail out if the result is minus zero. | 
| 1510       __ cmpi(result, Operand::Zero()); | 1507       __ cmpi(result, Operand::Zero()); | 
| 1511       DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero); | 1508       DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero); | 
| 1512       __ bind(&done); | 1509       __ bind(&done); | 
| 1513     } | 1510     } | 
| 1514   } | 1511   } | 
| 1515 } | 1512 } | 
| 1516 | 1513 | 
| 1517 | 1514 | 
| 1518 void LCodeGen::DoBitI(LBitI* instr) { | 1515 void LCodeGen::DoBitI(LBitI* instr) { | 
| 1519   LOperand* left_op = instr->left(); | 1516   LOperand* left_op = instr->left(); | 
| 1520   LOperand* right_op = instr->right(); | 1517   LOperand* right_op = instr->right(); | 
| 1521   DCHECK(left_op->IsRegister()); | 1518   DCHECK(left_op->IsRegister()); | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1587         break; | 1584         break; | 
| 1588       case Token::SAR: | 1585       case Token::SAR: | 
| 1589         __ sraw(result, left, scratch); | 1586         __ sraw(result, left, scratch); | 
| 1590         break; | 1587         break; | 
| 1591       case Token::SHR: | 1588       case Token::SHR: | 
| 1592         if (instr->can_deopt()) { | 1589         if (instr->can_deopt()) { | 
| 1593           __ srw(result, left, scratch, SetRC); | 1590           __ srw(result, left, scratch, SetRC); | 
| 1594 #if V8_TARGET_ARCH_PPC64 | 1591 #if V8_TARGET_ARCH_PPC64 | 
| 1595           __ extsw(result, result, SetRC); | 1592           __ extsw(result, result, SetRC); | 
| 1596 #endif | 1593 #endif | 
| 1597           DeoptimizeIf(lt, instr, Deoptimizer::kNegativeValue, cr0); | 1594           DeoptimizeIf(lt, instr, DeoptimizeReason::kNegativeValue, cr0); | 
| 1598         } else { | 1595         } else { | 
| 1599           __ srw(result, left, scratch); | 1596           __ srw(result, left, scratch); | 
| 1600         } | 1597         } | 
| 1601         break; | 1598         break; | 
| 1602       case Token::SHL: | 1599       case Token::SHL: | 
| 1603         __ slw(result, left, scratch); | 1600         __ slw(result, left, scratch); | 
| 1604 #if V8_TARGET_ARCH_PPC64 | 1601 #if V8_TARGET_ARCH_PPC64 | 
| 1605         __ extsw(result, result); | 1602         __ extsw(result, result); | 
| 1606 #endif | 1603 #endif | 
| 1607         break; | 1604         break; | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 1627         } else { | 1624         } else { | 
| 1628           __ Move(result, left); | 1625           __ Move(result, left); | 
| 1629         } | 1626         } | 
| 1630         break; | 1627         break; | 
| 1631       case Token::SHR: | 1628       case Token::SHR: | 
| 1632         if (shift_count != 0) { | 1629         if (shift_count != 0) { | 
| 1633           __ srwi(result, left, Operand(shift_count)); | 1630           __ srwi(result, left, Operand(shift_count)); | 
| 1634         } else { | 1631         } else { | 
| 1635           if (instr->can_deopt()) { | 1632           if (instr->can_deopt()) { | 
| 1636             __ cmpwi(left, Operand::Zero()); | 1633             __ cmpwi(left, Operand::Zero()); | 
| 1637             DeoptimizeIf(lt, instr, Deoptimizer::kNegativeValue); | 1634             DeoptimizeIf(lt, instr, DeoptimizeReason::kNegativeValue); | 
| 1638           } | 1635           } | 
| 1639           __ Move(result, left); | 1636           __ Move(result, left); | 
| 1640         } | 1637         } | 
| 1641         break; | 1638         break; | 
| 1642       case Token::SHL: | 1639       case Token::SHL: | 
| 1643         if (shift_count != 0) { | 1640         if (shift_count != 0) { | 
| 1644 #if V8_TARGET_ARCH_PPC64 | 1641 #if V8_TARGET_ARCH_PPC64 | 
| 1645           if (instr->hydrogen_value()->representation().IsSmi()) { | 1642           if (instr->hydrogen_value()->representation().IsSmi()) { | 
| 1646             __ sldi(result, left, Operand(shift_count)); | 1643             __ sldi(result, left, Operand(shift_count)); | 
| 1647 #else | 1644 #else | 
| 1648           if (instr->hydrogen_value()->representation().IsSmi() && | 1645           if (instr->hydrogen_value()->representation().IsSmi() && | 
| 1649               instr->can_deopt()) { | 1646               instr->can_deopt()) { | 
| 1650             if (shift_count != 1) { | 1647             if (shift_count != 1) { | 
| 1651               __ slwi(result, left, Operand(shift_count - 1)); | 1648               __ slwi(result, left, Operand(shift_count - 1)); | 
| 1652               __ SmiTagCheckOverflow(result, result, scratch); | 1649               __ SmiTagCheckOverflow(result, result, scratch); | 
| 1653             } else { | 1650             } else { | 
| 1654               __ SmiTagCheckOverflow(result, left, scratch); | 1651               __ SmiTagCheckOverflow(result, left, scratch); | 
| 1655             } | 1652             } | 
| 1656             DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, cr0); | 1653             DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, cr0); | 
| 1657 #endif | 1654 #endif | 
| 1658           } else { | 1655           } else { | 
| 1659             __ slwi(result, left, Operand(shift_count)); | 1656             __ slwi(result, left, Operand(shift_count)); | 
| 1660 #if V8_TARGET_ARCH_PPC64 | 1657 #if V8_TARGET_ARCH_PPC64 | 
| 1661             __ extsw(result, result); | 1658             __ extsw(result, result); | 
| 1662 #endif | 1659 #endif | 
| 1663           } | 1660           } | 
| 1664         } else { | 1661         } else { | 
| 1665           __ Move(result, left); | 1662           __ Move(result, left); | 
| 1666         } | 1663         } | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 1685 #endif | 1682 #endif | 
| 1686   if (!can_overflow || isInteger) { | 1683   if (!can_overflow || isInteger) { | 
| 1687     if (right->IsConstantOperand()) { | 1684     if (right->IsConstantOperand()) { | 
| 1688       __ Add(result, left, -(ToOperand(right).immediate()), r0); | 1685       __ Add(result, left, -(ToOperand(right).immediate()), r0); | 
| 1689     } else { | 1686     } else { | 
| 1690       __ sub(result, left, EmitLoadRegister(right, ip)); | 1687       __ sub(result, left, EmitLoadRegister(right, ip)); | 
| 1691     } | 1688     } | 
| 1692 #if V8_TARGET_ARCH_PPC64 | 1689 #if V8_TARGET_ARCH_PPC64 | 
| 1693     if (can_overflow) { | 1690     if (can_overflow) { | 
| 1694       __ TestIfInt32(result, r0); | 1691       __ TestIfInt32(result, r0); | 
| 1695       DeoptimizeIf(ne, instr, Deoptimizer::kOverflow); | 1692       DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); | 
| 1696     } | 1693     } | 
| 1697 #endif | 1694 #endif | 
| 1698   } else { | 1695   } else { | 
| 1699     if (right->IsConstantOperand()) { | 1696     if (right->IsConstantOperand()) { | 
| 1700       __ AddAndCheckForOverflow(result, left, -(ToOperand(right).immediate()), | 1697       __ AddAndCheckForOverflow(result, left, -(ToOperand(right).immediate()), | 
| 1701                                 scratch0(), r0); | 1698                                 scratch0(), r0); | 
| 1702     } else { | 1699     } else { | 
| 1703       __ SubAndCheckForOverflow(result, left, EmitLoadRegister(right, ip), | 1700       __ SubAndCheckForOverflow(result, left, EmitLoadRegister(right, ip), | 
| 1704                                 scratch0(), r0); | 1701                                 scratch0(), r0); | 
| 1705     } | 1702     } | 
| 1706     DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, cr0); | 1703     DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, cr0); | 
| 1707   } | 1704   } | 
| 1708 } | 1705 } | 
| 1709 | 1706 | 
| 1710 | 1707 | 
| 1711 void LCodeGen::DoRSubI(LRSubI* instr) { | 1708 void LCodeGen::DoRSubI(LRSubI* instr) { | 
| 1712   LOperand* left = instr->left(); | 1709   LOperand* left = instr->left(); | 
| 1713   LOperand* right = instr->right(); | 1710   LOperand* right = instr->right(); | 
| 1714   LOperand* result = instr->result(); | 1711   LOperand* result = instr->result(); | 
| 1715 | 1712 | 
| 1716   DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow) && | 1713   DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow) && | 
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1862 | 1859 | 
| 1863   if (!can_overflow || isInteger) { | 1860   if (!can_overflow || isInteger) { | 
| 1864     if (right->IsConstantOperand()) { | 1861     if (right->IsConstantOperand()) { | 
| 1865       __ Add(result, left, ToOperand(right).immediate(), r0); | 1862       __ Add(result, left, ToOperand(right).immediate(), r0); | 
| 1866     } else { | 1863     } else { | 
| 1867       __ add(result, left, EmitLoadRegister(right, ip)); | 1864       __ add(result, left, EmitLoadRegister(right, ip)); | 
| 1868     } | 1865     } | 
| 1869 #if V8_TARGET_ARCH_PPC64 | 1866 #if V8_TARGET_ARCH_PPC64 | 
| 1870     if (can_overflow) { | 1867     if (can_overflow) { | 
| 1871       __ TestIfInt32(result, r0); | 1868       __ TestIfInt32(result, r0); | 
| 1872       DeoptimizeIf(ne, instr, Deoptimizer::kOverflow); | 1869       DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); | 
| 1873     } | 1870     } | 
| 1874 #endif | 1871 #endif | 
| 1875   } else { | 1872   } else { | 
| 1876     if (right->IsConstantOperand()) { | 1873     if (right->IsConstantOperand()) { | 
| 1877       __ AddAndCheckForOverflow(result, left, ToOperand(right).immediate(), | 1874       __ AddAndCheckForOverflow(result, left, ToOperand(right).immediate(), | 
| 1878                                 scratch0(), r0); | 1875                                 scratch0(), r0); | 
| 1879     } else { | 1876     } else { | 
| 1880       __ AddAndCheckForOverflow(result, left, EmitLoadRegister(right, ip), | 1877       __ AddAndCheckForOverflow(result, left, EmitLoadRegister(right, ip), | 
| 1881                                 scratch0(), r0); | 1878                                 scratch0(), r0); | 
| 1882     } | 1879     } | 
| 1883     DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, cr0); | 1880     DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, cr0); | 
| 1884   } | 1881   } | 
| 1885 } | 1882 } | 
| 1886 | 1883 | 
| 1887 | 1884 | 
| 1888 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1885 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 
| 1889   LOperand* left = instr->left(); | 1886   LOperand* left = instr->left(); | 
| 1890   LOperand* right = instr->right(); | 1887   LOperand* right = instr->right(); | 
| 1891   HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1888   HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 
| 1892   Condition cond = (operation == HMathMinMax::kMathMin) ? le : ge; | 1889   Condition cond = (operation == HMathMinMax::kMathMin) ? le : ge; | 
| 1893   if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1890   if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2124       } | 2121       } | 
| 2125 | 2122 | 
| 2126       if (expected.Contains(ToBooleanICStub::SMI)) { | 2123       if (expected.Contains(ToBooleanICStub::SMI)) { | 
| 2127         // Smis: 0 -> false, all other -> true. | 2124         // Smis: 0 -> false, all other -> true. | 
| 2128         __ cmpi(reg, Operand::Zero()); | 2125         __ cmpi(reg, Operand::Zero()); | 
| 2129         __ beq(instr->FalseLabel(chunk_)); | 2126         __ beq(instr->FalseLabel(chunk_)); | 
| 2130         __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 2127         __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 
| 2131       } else if (expected.NeedsMap()) { | 2128       } else if (expected.NeedsMap()) { | 
| 2132         // If we need a map later and have a Smi -> deopt. | 2129         // If we need a map later and have a Smi -> deopt. | 
| 2133         __ TestIfSmi(reg, r0); | 2130         __ TestIfSmi(reg, r0); | 
| 2134         DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); | 2131         DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, cr0); | 
| 2135       } | 2132       } | 
| 2136 | 2133 | 
| 2137       const Register map = scratch0(); | 2134       const Register map = scratch0(); | 
| 2138       if (expected.NeedsMap()) { | 2135       if (expected.NeedsMap()) { | 
| 2139         __ LoadP(map, FieldMemOperand(reg, HeapObject::kMapOffset)); | 2136         __ LoadP(map, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| 2140 | 2137 | 
| 2141         if (expected.CanBeUndetectable()) { | 2138         if (expected.CanBeUndetectable()) { | 
| 2142           // Undetectable -> false. | 2139           // Undetectable -> false. | 
| 2143           __ lbz(ip, FieldMemOperand(map, Map::kBitFieldOffset)); | 2140           __ lbz(ip, FieldMemOperand(map, Map::kBitFieldOffset)); | 
| 2144           __ TestBit(ip, Map::kIsUndetectable, r0); | 2141           __ TestBit(ip, Map::kIsUndetectable, r0); | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2188         __ mfcr(r0); | 2185         __ mfcr(r0); | 
| 2189         __ andi(r0, r0, Operand(crZOrNaNBits)); | 2186         __ andi(r0, r0, Operand(crZOrNaNBits)); | 
| 2190         __ bne(instr->FalseLabel(chunk_), cr0); | 2187         __ bne(instr->FalseLabel(chunk_), cr0); | 
| 2191         __ b(instr->TrueLabel(chunk_)); | 2188         __ b(instr->TrueLabel(chunk_)); | 
| 2192         __ bind(¬_heap_number); | 2189         __ bind(¬_heap_number); | 
| 2193       } | 2190       } | 
| 2194 | 2191 | 
| 2195       if (!expected.IsGeneric()) { | 2192       if (!expected.IsGeneric()) { | 
| 2196         // We've seen something for the first time -> deopt. | 2193         // We've seen something for the first time -> deopt. | 
| 2197         // This can only happen if we are not generic already. | 2194         // This can only happen if we are not generic already. | 
| 2198         DeoptimizeIf(al, instr, Deoptimizer::kUnexpectedObject); | 2195         DeoptimizeIf(al, instr, DeoptimizeReason::kUnexpectedObject); | 
| 2199       } | 2196       } | 
| 2200     } | 2197     } | 
| 2201   } | 2198   } | 
| 2202 } | 2199 } | 
| 2203 | 2200 | 
| 2204 | 2201 | 
| 2205 void LCodeGen::EmitGoto(int block) { | 2202 void LCodeGen::EmitGoto(int block) { | 
| 2206   if (!IsNextEmittedBlock(block)) { | 2203   if (!IsNextEmittedBlock(block)) { | 
| 2207     __ b(chunk_->GetAssemblyLabel(LookupDestination(block))); | 2204     __ b(chunk_->GetAssemblyLabel(LookupDestination(block))); | 
| 2208   } | 2205   } | 
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2572 | 2569 | 
| 2573   // Loop through the {object}s prototype chain looking for the {prototype}. | 2570   // Loop through the {object}s prototype chain looking for the {prototype}. | 
| 2574   __ LoadP(object_map, FieldMemOperand(object, HeapObject::kMapOffset)); | 2571   __ LoadP(object_map, FieldMemOperand(object, HeapObject::kMapOffset)); | 
| 2575   Label loop; | 2572   Label loop; | 
| 2576   __ bind(&loop); | 2573   __ bind(&loop); | 
| 2577 | 2574 | 
| 2578   // Deoptimize if the object needs to be access checked. | 2575   // Deoptimize if the object needs to be access checked. | 
| 2579   __ lbz(object_instance_type, | 2576   __ lbz(object_instance_type, | 
| 2580          FieldMemOperand(object_map, Map::kBitFieldOffset)); | 2577          FieldMemOperand(object_map, Map::kBitFieldOffset)); | 
| 2581   __ TestBit(object_instance_type, Map::kIsAccessCheckNeeded, r0); | 2578   __ TestBit(object_instance_type, Map::kIsAccessCheckNeeded, r0); | 
| 2582   DeoptimizeIf(ne, instr, Deoptimizer::kAccessCheck, cr0); | 2579   DeoptimizeIf(ne, instr, DeoptimizeReason::kAccessCheck, cr0); | 
| 2583   // Deoptimize for proxies. | 2580   // Deoptimize for proxies. | 
| 2584   __ CompareInstanceType(object_map, object_instance_type, JS_PROXY_TYPE); | 2581   __ CompareInstanceType(object_map, object_instance_type, JS_PROXY_TYPE); | 
| 2585   DeoptimizeIf(eq, instr, Deoptimizer::kProxy); | 2582   DeoptimizeIf(eq, instr, DeoptimizeReason::kProxy); | 
| 2586   __ LoadP(object_prototype, | 2583   __ LoadP(object_prototype, | 
| 2587            FieldMemOperand(object_map, Map::kPrototypeOffset)); | 2584            FieldMemOperand(object_map, Map::kPrototypeOffset)); | 
| 2588   __ CompareRoot(object_prototype, Heap::kNullValueRootIndex); | 2585   __ CompareRoot(object_prototype, Heap::kNullValueRootIndex); | 
| 2589   EmitFalseBranch(instr, eq); | 2586   EmitFalseBranch(instr, eq); | 
| 2590   __ cmp(object_prototype, prototype); | 2587   __ cmp(object_prototype, prototype); | 
| 2591   EmitTrueBranch(instr, eq); | 2588   EmitTrueBranch(instr, eq); | 
| 2592   __ LoadP(object_map, | 2589   __ LoadP(object_map, | 
| 2593            FieldMemOperand(object_prototype, HeapObject::kMapOffset)); | 2590            FieldMemOperand(object_prototype, HeapObject::kMapOffset)); | 
| 2594   __ b(&loop); | 2591   __ b(&loop); | 
| 2595 } | 2592 } | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2705 | 2702 | 
| 2706 | 2703 | 
| 2707 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2704 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 
| 2708   Register context = ToRegister(instr->context()); | 2705   Register context = ToRegister(instr->context()); | 
| 2709   Register result = ToRegister(instr->result()); | 2706   Register result = ToRegister(instr->result()); | 
| 2710   __ LoadP(result, ContextMemOperand(context, instr->slot_index())); | 2707   __ LoadP(result, ContextMemOperand(context, instr->slot_index())); | 
| 2711   if (instr->hydrogen()->RequiresHoleCheck()) { | 2708   if (instr->hydrogen()->RequiresHoleCheck()) { | 
| 2712     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2709     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 
| 2713     if (instr->hydrogen()->DeoptimizesOnHole()) { | 2710     if (instr->hydrogen()->DeoptimizesOnHole()) { | 
| 2714       __ cmp(result, ip); | 2711       __ cmp(result, ip); | 
| 2715       DeoptimizeIf(eq, instr, Deoptimizer::kHole); | 2712       DeoptimizeIf(eq, instr, DeoptimizeReason::kHole); | 
| 2716     } else { | 2713     } else { | 
| 2717       if (CpuFeatures::IsSupported(ISELECT)) { | 2714       if (CpuFeatures::IsSupported(ISELECT)) { | 
| 2718         Register scratch = scratch0(); | 2715         Register scratch = scratch0(); | 
| 2719         __ mov(scratch, Operand(factory()->undefined_value())); | 2716         __ mov(scratch, Operand(factory()->undefined_value())); | 
| 2720         __ cmp(result, ip); | 2717         __ cmp(result, ip); | 
| 2721         __ isel(eq, result, scratch, result); | 2718         __ isel(eq, result, scratch, result); | 
| 2722       } else { | 2719       } else { | 
| 2723         Label skip; | 2720         Label skip; | 
| 2724         __ cmp(result, ip); | 2721         __ cmp(result, ip); | 
| 2725         __ bne(&skip); | 2722         __ bne(&skip); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 2737   Register scratch = scratch0(); | 2734   Register scratch = scratch0(); | 
| 2738   MemOperand target = ContextMemOperand(context, instr->slot_index()); | 2735   MemOperand target = ContextMemOperand(context, instr->slot_index()); | 
| 2739 | 2736 | 
| 2740   Label skip_assignment; | 2737   Label skip_assignment; | 
| 2741 | 2738 | 
| 2742   if (instr->hydrogen()->RequiresHoleCheck()) { | 2739   if (instr->hydrogen()->RequiresHoleCheck()) { | 
| 2743     __ LoadP(scratch, target); | 2740     __ LoadP(scratch, target); | 
| 2744     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2741     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 
| 2745     __ cmp(scratch, ip); | 2742     __ cmp(scratch, ip); | 
| 2746     if (instr->hydrogen()->DeoptimizesOnHole()) { | 2743     if (instr->hydrogen()->DeoptimizesOnHole()) { | 
| 2747       DeoptimizeIf(eq, instr, Deoptimizer::kHole); | 2744       DeoptimizeIf(eq, instr, DeoptimizeReason::kHole); | 
| 2748     } else { | 2745     } else { | 
| 2749       __ bne(&skip_assignment); | 2746       __ bne(&skip_assignment); | 
| 2750     } | 2747     } | 
| 2751   } | 2748   } | 
| 2752 | 2749 | 
| 2753   __ StoreP(value, target, r0); | 2750   __ StoreP(value, target, r0); | 
| 2754   if (instr->hydrogen()->NeedsWriteBarrier()) { | 2751   if (instr->hydrogen()->NeedsWriteBarrier()) { | 
| 2755     SmiCheck check_needed = instr->hydrogen()->value()->type().IsHeapObject() | 2752     SmiCheck check_needed = instr->hydrogen()->value()->type().IsHeapObject() | 
| 2756                                 ? OMIT_SMI_CHECK | 2753                                 ? OMIT_SMI_CHECK | 
| 2757                                 : INLINE_SMI_CHECK; | 2754                                 : INLINE_SMI_CHECK; | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2824   Register function = ToRegister(instr->function()); | 2821   Register function = ToRegister(instr->function()); | 
| 2825   Register result = ToRegister(instr->result()); | 2822   Register result = ToRegister(instr->result()); | 
| 2826 | 2823 | 
| 2827   // Get the prototype or initial map from the function. | 2824   // Get the prototype or initial map from the function. | 
| 2828   __ LoadP(result, | 2825   __ LoadP(result, | 
| 2829            FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 2826            FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 
| 2830 | 2827 | 
| 2831   // Check that the function has a prototype or an initial map. | 2828   // Check that the function has a prototype or an initial map. | 
| 2832   __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2829   __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 
| 2833   __ cmp(result, ip); | 2830   __ cmp(result, ip); | 
| 2834   DeoptimizeIf(eq, instr, Deoptimizer::kHole); | 2831   DeoptimizeIf(eq, instr, DeoptimizeReason::kHole); | 
| 2835 | 2832 | 
| 2836   // If the function does not have an initial map, we're done. | 2833   // If the function does not have an initial map, we're done. | 
| 2837   if (CpuFeatures::IsSupported(ISELECT)) { | 2834   if (CpuFeatures::IsSupported(ISELECT)) { | 
| 2838     // Get the prototype from the initial map (optimistic). | 2835     // Get the prototype from the initial map (optimistic). | 
| 2839     __ LoadP(ip, FieldMemOperand(result, Map::kPrototypeOffset)); | 2836     __ LoadP(ip, FieldMemOperand(result, Map::kPrototypeOffset)); | 
| 2840     __ CompareObjectType(result, scratch, scratch, MAP_TYPE); | 2837     __ CompareObjectType(result, scratch, scratch, MAP_TYPE); | 
| 2841     __ isel(eq, result, ip, result); | 2838     __ isel(eq, result, ip, result); | 
| 2842   } else { | 2839   } else { | 
| 2843     Label done; | 2840     Label done; | 
| 2844     __ CompareObjectType(result, scratch, scratch, MAP_TYPE); | 2841     __ CompareObjectType(result, scratch, scratch, MAP_TYPE); | 
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2976         break; | 2973         break; | 
| 2977       case UINT32_ELEMENTS: | 2974       case UINT32_ELEMENTS: | 
| 2978         if (key_is_constant) { | 2975         if (key_is_constant) { | 
| 2979           __ LoadWord(result, mem_operand, r0); | 2976           __ LoadWord(result, mem_operand, r0); | 
| 2980         } else { | 2977         } else { | 
| 2981           __ lwzx(result, mem_operand); | 2978           __ lwzx(result, mem_operand); | 
| 2982         } | 2979         } | 
| 2983         if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 2980         if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 
| 2984           __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 2981           __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 
| 2985           __ cmplw(result, r0); | 2982           __ cmplw(result, r0); | 
| 2986           DeoptimizeIf(ge, instr, Deoptimizer::kNegativeValue); | 2983           DeoptimizeIf(ge, instr, DeoptimizeReason::kNegativeValue); | 
| 2987         } | 2984         } | 
| 2988         break; | 2985         break; | 
| 2989       case FLOAT32_ELEMENTS: | 2986       case FLOAT32_ELEMENTS: | 
| 2990       case FLOAT64_ELEMENTS: | 2987       case FLOAT64_ELEMENTS: | 
| 2991       case FAST_HOLEY_DOUBLE_ELEMENTS: | 2988       case FAST_HOLEY_DOUBLE_ELEMENTS: | 
| 2992       case FAST_HOLEY_ELEMENTS: | 2989       case FAST_HOLEY_ELEMENTS: | 
| 2993       case FAST_HOLEY_SMI_ELEMENTS: | 2990       case FAST_HOLEY_SMI_ELEMENTS: | 
| 2994       case FAST_DOUBLE_ELEMENTS: | 2991       case FAST_DOUBLE_ELEMENTS: | 
| 2995       case FAST_ELEMENTS: | 2992       case FAST_ELEMENTS: | 
| 2996       case FAST_SMI_ELEMENTS: | 2993       case FAST_SMI_ELEMENTS: | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3041 | 3038 | 
| 3042   if (instr->hydrogen()->RequiresHoleCheck()) { | 3039   if (instr->hydrogen()->RequiresHoleCheck()) { | 
| 3043     if (is_int16(base_offset + Register::kExponentOffset)) { | 3040     if (is_int16(base_offset + Register::kExponentOffset)) { | 
| 3044       __ lwz(scratch, | 3041       __ lwz(scratch, | 
| 3045              MemOperand(elements, base_offset + Register::kExponentOffset)); | 3042              MemOperand(elements, base_offset + Register::kExponentOffset)); | 
| 3046     } else { | 3043     } else { | 
| 3047       __ addi(scratch, elements, Operand(base_offset)); | 3044       __ addi(scratch, elements, Operand(base_offset)); | 
| 3048       __ lwz(scratch, MemOperand(scratch, Register::kExponentOffset)); | 3045       __ lwz(scratch, MemOperand(scratch, Register::kExponentOffset)); | 
| 3049     } | 3046     } | 
| 3050     __ Cmpi(scratch, Operand(kHoleNanUpper32), r0); | 3047     __ Cmpi(scratch, Operand(kHoleNanUpper32), r0); | 
| 3051     DeoptimizeIf(eq, instr, Deoptimizer::kHole); | 3048     DeoptimizeIf(eq, instr, DeoptimizeReason::kHole); | 
| 3052   } | 3049   } | 
| 3053 } | 3050 } | 
| 3054 | 3051 | 
| 3055 | 3052 | 
| 3056 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3053 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 
| 3057   HLoadKeyed* hinstr = instr->hydrogen(); | 3054   HLoadKeyed* hinstr = instr->hydrogen(); | 
| 3058   Register elements = ToRegister(instr->elements()); | 3055   Register elements = ToRegister(instr->elements()); | 
| 3059   Register result = ToRegister(instr->result()); | 3056   Register result = ToRegister(instr->result()); | 
| 3060   Register scratch = scratch0(); | 3057   Register scratch = scratch0(); | 
| 3061   Register store_base = scratch; | 3058   Register store_base = scratch; | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 3092   } | 3089   } | 
| 3093 #endif | 3090 #endif | 
| 3094 | 3091 | 
| 3095   __ LoadRepresentation(result, MemOperand(store_base, offset), representation, | 3092   __ LoadRepresentation(result, MemOperand(store_base, offset), representation, | 
| 3096                         r0); | 3093                         r0); | 
| 3097 | 3094 | 
| 3098   // Check for the hole value. | 3095   // Check for the hole value. | 
| 3099   if (requires_hole_check) { | 3096   if (requires_hole_check) { | 
| 3100     if (IsFastSmiElementsKind(hinstr->elements_kind())) { | 3097     if (IsFastSmiElementsKind(hinstr->elements_kind())) { | 
| 3101       __ TestIfSmi(result, r0); | 3098       __ TestIfSmi(result, r0); | 
| 3102       DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, cr0); | 3099       DeoptimizeIf(ne, instr, DeoptimizeReason::kNotASmi, cr0); | 
| 3103     } else { | 3100     } else { | 
| 3104       __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3101       __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 
| 3105       __ cmp(result, scratch); | 3102       __ cmp(result, scratch); | 
| 3106       DeoptimizeIf(eq, instr, Deoptimizer::kHole); | 3103       DeoptimizeIf(eq, instr, DeoptimizeReason::kHole); | 
| 3107     } | 3104     } | 
| 3108   } else if (instr->hydrogen()->hole_mode() == CONVERT_HOLE_TO_UNDEFINED) { | 3105   } else if (instr->hydrogen()->hole_mode() == CONVERT_HOLE_TO_UNDEFINED) { | 
| 3109     DCHECK(instr->hydrogen()->elements_kind() == FAST_HOLEY_ELEMENTS); | 3106     DCHECK(instr->hydrogen()->elements_kind() == FAST_HOLEY_ELEMENTS); | 
| 3110     Label done; | 3107     Label done; | 
| 3111     __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3108     __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 
| 3112     __ cmp(result, scratch); | 3109     __ cmp(result, scratch); | 
| 3113     __ bne(&done); | 3110     __ bne(&done); | 
| 3114     if (info()->IsStub()) { | 3111     if (info()->IsStub()) { | 
| 3115       // A stub can safely convert the hole to undefined only if the array | 3112       // A stub can safely convert the hole to undefined only if the array | 
| 3116       // protector cell contains (Smi) Isolate::kArrayProtectorValid. Otherwise | 3113       // protector cell contains (Smi) Isolate::kArrayProtectorValid. Otherwise | 
| 3117       // it needs to bail out. | 3114       // it needs to bail out. | 
| 3118       __ LoadRoot(result, Heap::kArrayProtectorRootIndex); | 3115       __ LoadRoot(result, Heap::kArrayProtectorRootIndex); | 
| 3119       __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset)); | 3116       __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset)); | 
| 3120       __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kArrayProtectorValid), r0); | 3117       __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kArrayProtectorValid), r0); | 
| 3121       DeoptimizeIf(ne, instr, Deoptimizer::kHole); | 3118       DeoptimizeIf(ne, instr, DeoptimizeReason::kHole); | 
| 3122     } | 3119     } | 
| 3123     __ LoadRoot(result, Heap::kUndefinedValueRootIndex); | 3120     __ LoadRoot(result, Heap::kUndefinedValueRootIndex); | 
| 3124     __ bind(&done); | 3121     __ bind(&done); | 
| 3125   } | 3122   } | 
| 3126 } | 3123 } | 
| 3127 | 3124 | 
| 3128 | 3125 | 
| 3129 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3126 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 
| 3130   if (instr->is_fixed_typed_array()) { | 3127   if (instr->is_fixed_typed_array()) { | 
| 3131     DoLoadKeyedExternalArray(instr); | 3128     DoLoadKeyedExternalArray(instr); | 
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3261   // Normal function. Replace undefined or null with global receiver. | 3258   // Normal function. Replace undefined or null with global receiver. | 
| 3262   __ LoadRoot(scratch, Heap::kNullValueRootIndex); | 3259   __ LoadRoot(scratch, Heap::kNullValueRootIndex); | 
| 3263   __ cmp(receiver, scratch); | 3260   __ cmp(receiver, scratch); | 
| 3264   __ beq(&global_object); | 3261   __ beq(&global_object); | 
| 3265   __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 3262   __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 
| 3266   __ cmp(receiver, scratch); | 3263   __ cmp(receiver, scratch); | 
| 3267   __ beq(&global_object); | 3264   __ beq(&global_object); | 
| 3268 | 3265 | 
| 3269   // Deoptimize if the receiver is not a JS object. | 3266   // Deoptimize if the receiver is not a JS object. | 
| 3270   __ TestIfSmi(receiver, r0); | 3267   __ TestIfSmi(receiver, r0); | 
| 3271   DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); | 3268   DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, cr0); | 
| 3272   __ CompareObjectType(receiver, scratch, scratch, FIRST_JS_RECEIVER_TYPE); | 3269   __ CompareObjectType(receiver, scratch, scratch, FIRST_JS_RECEIVER_TYPE); | 
| 3273   DeoptimizeIf(lt, instr, Deoptimizer::kNotAJavaScriptObject); | 3270   DeoptimizeIf(lt, instr, DeoptimizeReason::kNotAJavaScriptObject); | 
| 3274 | 3271 | 
| 3275   __ b(&result_in_receiver); | 3272   __ b(&result_in_receiver); | 
| 3276   __ bind(&global_object); | 3273   __ bind(&global_object); | 
| 3277   __ LoadP(result, FieldMemOperand(function, JSFunction::kContextOffset)); | 3274   __ LoadP(result, FieldMemOperand(function, JSFunction::kContextOffset)); | 
| 3278   __ LoadP(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX)); | 3275   __ LoadP(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX)); | 
| 3279   __ LoadP(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX)); | 3276   __ LoadP(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX)); | 
| 3280 | 3277 | 
| 3281   if (result.is(receiver)) { | 3278   if (result.is(receiver)) { | 
| 3282     __ bind(&result_in_receiver); | 3279     __ bind(&result_in_receiver); | 
| 3283   } else { | 3280   } else { | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 3297   Register elements = ToRegister(instr->elements()); | 3294   Register elements = ToRegister(instr->elements()); | 
| 3298   Register scratch = scratch0(); | 3295   Register scratch = scratch0(); | 
| 3299   DCHECK(receiver.is(r3));  // Used for parameter count. | 3296   DCHECK(receiver.is(r3));  // Used for parameter count. | 
| 3300   DCHECK(function.is(r4));  // Required by InvokeFunction. | 3297   DCHECK(function.is(r4));  // Required by InvokeFunction. | 
| 3301   DCHECK(ToRegister(instr->result()).is(r3)); | 3298   DCHECK(ToRegister(instr->result()).is(r3)); | 
| 3302 | 3299 | 
| 3303   // Copy the arguments to this function possibly from the | 3300   // Copy the arguments to this function possibly from the | 
| 3304   // adaptor frame below it. | 3301   // adaptor frame below it. | 
| 3305   const uint32_t kArgumentsLimit = 1 * KB; | 3302   const uint32_t kArgumentsLimit = 1 * KB; | 
| 3306   __ cmpli(length, Operand(kArgumentsLimit)); | 3303   __ cmpli(length, Operand(kArgumentsLimit)); | 
| 3307   DeoptimizeIf(gt, instr, Deoptimizer::kTooManyArguments); | 3304   DeoptimizeIf(gt, instr, DeoptimizeReason::kTooManyArguments); | 
| 3308 | 3305 | 
| 3309   // Push the receiver and use the register to keep the original | 3306   // Push the receiver and use the register to keep the original | 
| 3310   // number of arguments. | 3307   // number of arguments. | 
| 3311   __ push(receiver); | 3308   __ push(receiver); | 
| 3312   __ mr(receiver, length); | 3309   __ mr(receiver, length); | 
| 3313   // The arguments are at a one pointer size offset from elements. | 3310   // The arguments are at a one pointer size offset from elements. | 
| 3314   __ addi(elements, elements, Operand(1 * kPointerSize)); | 3311   __ addi(elements, elements, Operand(1 * kPointerSize)); | 
| 3315 | 3312 | 
| 3316   // Loop through the arguments pushing them onto the execution | 3313   // Loop through the arguments pushing them onto the execution | 
| 3317   // stack. | 3314   // stack. | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3451   DCHECK(instr->context() != NULL); | 3448   DCHECK(instr->context() != NULL); | 
| 3452   DCHECK(ToRegister(instr->context()).is(cp)); | 3449   DCHECK(ToRegister(instr->context()).is(cp)); | 
| 3453   Register input = ToRegister(instr->value()); | 3450   Register input = ToRegister(instr->value()); | 
| 3454   Register result = ToRegister(instr->result()); | 3451   Register result = ToRegister(instr->result()); | 
| 3455   Register scratch = scratch0(); | 3452   Register scratch = scratch0(); | 
| 3456 | 3453 | 
| 3457   // Deoptimize if not a heap number. | 3454   // Deoptimize if not a heap number. | 
| 3458   __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 3455   __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 
| 3459   __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 3456   __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 
| 3460   __ cmp(scratch, ip); | 3457   __ cmp(scratch, ip); | 
| 3461   DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber); | 3458   DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber); | 
| 3462 | 3459 | 
| 3463   Label done; | 3460   Label done; | 
| 3464   Register exponent = scratch0(); | 3461   Register exponent = scratch0(); | 
| 3465   scratch = no_reg; | 3462   scratch = no_reg; | 
| 3466   __ lwz(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); | 3463   __ lwz(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); | 
| 3467   // Check the sign of the argument. If the argument is positive, just | 3464   // Check the sign of the argument. If the argument is positive, just | 
| 3468   // return it. | 3465   // return it. | 
| 3469   __ cmpwi(exponent, Operand::Zero()); | 3466   __ cmpwi(exponent, Operand::Zero()); | 
| 3470   // Move the input to the result if necessary. | 3467   // Move the input to the result if necessary. | 
| 3471   __ Move(result, input); | 3468   __ Move(result, input); | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3521   Register input = ToRegister(instr->value()); | 3518   Register input = ToRegister(instr->value()); | 
| 3522   Register result = ToRegister(instr->result()); | 3519   Register result = ToRegister(instr->result()); | 
| 3523   Label done; | 3520   Label done; | 
| 3524   __ cmpi(input, Operand::Zero()); | 3521   __ cmpi(input, Operand::Zero()); | 
| 3525   __ Move(result, input); | 3522   __ Move(result, input); | 
| 3526   __ bge(&done); | 3523   __ bge(&done); | 
| 3527   __ li(r0, Operand::Zero());  // clear xer | 3524   __ li(r0, Operand::Zero());  // clear xer | 
| 3528   __ mtxer(r0); | 3525   __ mtxer(r0); | 
| 3529   __ neg(result, result, SetOE, SetRC); | 3526   __ neg(result, result, SetOE, SetRC); | 
| 3530   // Deoptimize on overflow. | 3527   // Deoptimize on overflow. | 
| 3531   DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow, cr0); | 3528   DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow, cr0); | 
| 3532   __ bind(&done); | 3529   __ bind(&done); | 
| 3533 } | 3530 } | 
| 3534 | 3531 | 
| 3535 | 3532 | 
| 3536 #if V8_TARGET_ARCH_PPC64 | 3533 #if V8_TARGET_ARCH_PPC64 | 
| 3537 void LCodeGen::EmitInteger32MathAbs(LMathAbs* instr) { | 3534 void LCodeGen::EmitInteger32MathAbs(LMathAbs* instr) { | 
| 3538   Register input = ToRegister(instr->value()); | 3535   Register input = ToRegister(instr->value()); | 
| 3539   Register result = ToRegister(instr->result()); | 3536   Register result = ToRegister(instr->result()); | 
| 3540   Label done; | 3537   Label done; | 
| 3541   __ cmpwi(input, Operand::Zero()); | 3538   __ cmpwi(input, Operand::Zero()); | 
| 3542   __ Move(result, input); | 3539   __ Move(result, input); | 
| 3543   __ bge(&done); | 3540   __ bge(&done); | 
| 3544 | 3541 | 
| 3545   // Deoptimize on overflow. | 3542   // Deoptimize on overflow. | 
| 3546   __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 3543   __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 
| 3547   __ cmpw(input, r0); | 3544   __ cmpw(input, r0); | 
| 3548   DeoptimizeIf(eq, instr, Deoptimizer::kOverflow); | 3545   DeoptimizeIf(eq, instr, DeoptimizeReason::kOverflow); | 
| 3549 | 3546 | 
| 3550   __ neg(result, result); | 3547   __ neg(result, result); | 
| 3551   __ bind(&done); | 3548   __ bind(&done); | 
| 3552 } | 3549 } | 
| 3553 #endif | 3550 #endif | 
| 3554 | 3551 | 
| 3555 | 3552 | 
| 3556 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3553 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 
| 3557   // Class for deferred case. | 3554   // Class for deferred case. | 
| 3558   class DeferredMathAbsTaggedHeapNumber final : public LDeferredCode { | 3555   class DeferredMathAbsTaggedHeapNumber final : public LDeferredCode { | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3602 | 3599 | 
| 3603 void LCodeGen::DoMathFloorI(LMathFloorI* instr) { | 3600 void LCodeGen::DoMathFloorI(LMathFloorI* instr) { | 
| 3604   DoubleRegister input = ToDoubleRegister(instr->value()); | 3601   DoubleRegister input = ToDoubleRegister(instr->value()); | 
| 3605   Register result = ToRegister(instr->result()); | 3602   Register result = ToRegister(instr->result()); | 
| 3606   Register input_high = scratch0(); | 3603   Register input_high = scratch0(); | 
| 3607   Register scratch = ip; | 3604   Register scratch = ip; | 
| 3608   Label done, exact; | 3605   Label done, exact; | 
| 3609 | 3606 | 
| 3610   __ TryInt32Floor(result, input, input_high, scratch, double_scratch0(), &done, | 3607   __ TryInt32Floor(result, input, input_high, scratch, double_scratch0(), &done, | 
| 3611                    &exact); | 3608                    &exact); | 
| 3612   DeoptimizeIf(al, instr, Deoptimizer::kLostPrecisionOrNaN); | 3609   DeoptimizeIf(al, instr, DeoptimizeReason::kLostPrecisionOrNaN); | 
| 3613 | 3610 | 
| 3614   __ bind(&exact); | 3611   __ bind(&exact); | 
| 3615   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3612   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 3616     // Test for -0. | 3613     // Test for -0. | 
| 3617     __ cmpi(result, Operand::Zero()); | 3614     __ cmpi(result, Operand::Zero()); | 
| 3618     __ bne(&done); | 3615     __ bne(&done); | 
| 3619     __ cmpwi(input_high, Operand::Zero()); | 3616     __ cmpwi(input_high, Operand::Zero()); | 
| 3620     DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 3617     DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 3621   } | 3618   } | 
| 3622   __ bind(&done); | 3619   __ bind(&done); | 
| 3623 } | 3620 } | 
| 3624 | 3621 | 
| 3625 void LCodeGen::DoMathRoundD(LMathRoundD* instr) { | 3622 void LCodeGen::DoMathRoundD(LMathRoundD* instr) { | 
| 3626   DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 3623   DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 
| 3627   DoubleRegister output_reg = ToDoubleRegister(instr->result()); | 3624   DoubleRegister output_reg = ToDoubleRegister(instr->result()); | 
| 3628   DoubleRegister dot_five = double_scratch0(); | 3625   DoubleRegister dot_five = double_scratch0(); | 
| 3629   Label done; | 3626   Label done; | 
| 3630 | 3627 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 3651   DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3648   DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 
| 3652   DoubleRegister input_plus_dot_five = double_scratch1; | 3649   DoubleRegister input_plus_dot_five = double_scratch1; | 
| 3653   Register scratch1 = scratch0(); | 3650   Register scratch1 = scratch0(); | 
| 3654   Register scratch2 = ip; | 3651   Register scratch2 = ip; | 
| 3655   DoubleRegister dot_five = double_scratch0(); | 3652   DoubleRegister dot_five = double_scratch0(); | 
| 3656   Label convert, done; | 3653   Label convert, done; | 
| 3657 | 3654 | 
| 3658   __ LoadDoubleLiteral(dot_five, 0.5, r0); | 3655   __ LoadDoubleLiteral(dot_five, 0.5, r0); | 
| 3659   __ fabs(double_scratch1, input); | 3656   __ fabs(double_scratch1, input); | 
| 3660   __ fcmpu(double_scratch1, dot_five); | 3657   __ fcmpu(double_scratch1, dot_five); | 
| 3661   DeoptimizeIf(unordered, instr, Deoptimizer::kLostPrecisionOrNaN); | 3658   DeoptimizeIf(unordered, instr, DeoptimizeReason::kLostPrecisionOrNaN); | 
| 3662   // If input is in [-0.5, -0], the result is -0. | 3659   // If input is in [-0.5, -0], the result is -0. | 
| 3663   // If input is in [+0, +0.5[, the result is +0. | 3660   // If input is in [+0, +0.5[, the result is +0. | 
| 3664   // If the input is +0.5, the result is 1. | 3661   // If the input is +0.5, the result is 1. | 
| 3665   __ bgt(&convert);  // Out of [-0.5, +0.5]. | 3662   __ bgt(&convert);  // Out of [-0.5, +0.5]. | 
| 3666   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3663   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 3667     // [-0.5, -0] (negative) yields minus zero. | 3664     // [-0.5, -0] (negative) yields minus zero. | 
| 3668     __ TestDoubleSign(input, scratch1); | 3665     __ TestDoubleSign(input, scratch1); | 
| 3669     DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 3666     DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 3670   } | 3667   } | 
| 3671   __ fcmpu(input, dot_five); | 3668   __ fcmpu(input, dot_five); | 
| 3672   if (CpuFeatures::IsSupported(ISELECT)) { | 3669   if (CpuFeatures::IsSupported(ISELECT)) { | 
| 3673     __ li(result, Operand(1)); | 3670     __ li(result, Operand(1)); | 
| 3674     __ isel(lt, result, r0, result); | 3671     __ isel(lt, result, r0, result); | 
| 3675     __ b(&done); | 3672     __ b(&done); | 
| 3676   } else { | 3673   } else { | 
| 3677     Label return_zero; | 3674     Label return_zero; | 
| 3678     __ bne(&return_zero); | 3675     __ bne(&return_zero); | 
| 3679     __ li(result, Operand(1));  // +0.5. | 3676     __ li(result, Operand(1));  // +0.5. | 
| 3680     __ b(&done); | 3677     __ b(&done); | 
| 3681     // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on | 3678     // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on | 
| 3682     // flag kBailoutOnMinusZero. | 3679     // flag kBailoutOnMinusZero. | 
| 3683     __ bind(&return_zero); | 3680     __ bind(&return_zero); | 
| 3684     __ li(result, Operand::Zero()); | 3681     __ li(result, Operand::Zero()); | 
| 3685     __ b(&done); | 3682     __ b(&done); | 
| 3686   } | 3683   } | 
| 3687 | 3684 | 
| 3688   __ bind(&convert); | 3685   __ bind(&convert); | 
| 3689   __ fadd(input_plus_dot_five, input, dot_five); | 3686   __ fadd(input_plus_dot_five, input, dot_five); | 
| 3690   // Reuse dot_five (double_scratch0) as we no longer need this value. | 3687   // Reuse dot_five (double_scratch0) as we no longer need this value. | 
| 3691   __ TryInt32Floor(result, input_plus_dot_five, scratch1, scratch2, | 3688   __ TryInt32Floor(result, input_plus_dot_five, scratch1, scratch2, | 
| 3692                    double_scratch0(), &done, &done); | 3689                    double_scratch0(), &done, &done); | 
| 3693   DeoptimizeIf(al, instr, Deoptimizer::kLostPrecisionOrNaN); | 3690   DeoptimizeIf(al, instr, DeoptimizeReason::kLostPrecisionOrNaN); | 
| 3694   __ bind(&done); | 3691   __ bind(&done); | 
| 3695 } | 3692 } | 
| 3696 | 3693 | 
| 3697 | 3694 | 
| 3698 void LCodeGen::DoMathFround(LMathFround* instr) { | 3695 void LCodeGen::DoMathFround(LMathFround* instr) { | 
| 3699   DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 3696   DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 
| 3700   DoubleRegister output_reg = ToDoubleRegister(instr->result()); | 3697   DoubleRegister output_reg = ToDoubleRegister(instr->result()); | 
| 3701   __ frsp(output_reg, input_reg); | 3698   __ frsp(output_reg, input_reg); | 
| 3702 } | 3699 } | 
| 3703 | 3700 | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3748   if (exponent_type.IsSmi()) { | 3745   if (exponent_type.IsSmi()) { | 
| 3749     MathPowStub stub(isolate(), MathPowStub::TAGGED); | 3746     MathPowStub stub(isolate(), MathPowStub::TAGGED); | 
| 3750     __ CallStub(&stub); | 3747     __ CallStub(&stub); | 
| 3751   } else if (exponent_type.IsTagged()) { | 3748   } else if (exponent_type.IsTagged()) { | 
| 3752     Label no_deopt; | 3749     Label no_deopt; | 
| 3753     __ JumpIfSmi(tagged_exponent, &no_deopt); | 3750     __ JumpIfSmi(tagged_exponent, &no_deopt); | 
| 3754     DCHECK(!r10.is(tagged_exponent)); | 3751     DCHECK(!r10.is(tagged_exponent)); | 
| 3755     __ LoadP(r10, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); | 3752     __ LoadP(r10, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); | 
| 3756     __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 3753     __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 
| 3757     __ cmp(r10, ip); | 3754     __ cmp(r10, ip); | 
| 3758     DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber); | 3755     DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber); | 
| 3759     __ bind(&no_deopt); | 3756     __ bind(&no_deopt); | 
| 3760     MathPowStub stub(isolate(), MathPowStub::TAGGED); | 3757     MathPowStub stub(isolate(), MathPowStub::TAGGED); | 
| 3761     __ CallStub(&stub); | 3758     __ CallStub(&stub); | 
| 3762   } else if (exponent_type.IsInteger32()) { | 3759   } else if (exponent_type.IsInteger32()) { | 
| 3763     MathPowStub stub(isolate(), MathPowStub::INTEGER); | 3760     MathPowStub stub(isolate(), MathPowStub::INTEGER); | 
| 3764     __ CallStub(&stub); | 3761     __ CallStub(&stub); | 
| 3765   } else { | 3762   } else { | 
| 3766     DCHECK(exponent_type.IsDouble()); | 3763     DCHECK(exponent_type.IsDouble()); | 
| 3767     MathPowStub stub(isolate(), MathPowStub::DOUBLE); | 3764     MathPowStub stub(isolate(), MathPowStub::DOUBLE); | 
| 3768     __ CallStub(&stub); | 3765     __ CallStub(&stub); | 
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4132     } else { | 4129     } else { | 
| 4133       __ cmplw(length, index); | 4130       __ cmplw(length, index); | 
| 4134     } | 4131     } | 
| 4135   } | 4132   } | 
| 4136   if (FLAG_debug_code && instr->hydrogen()->skip_check()) { | 4133   if (FLAG_debug_code && instr->hydrogen()->skip_check()) { | 
| 4137     Label done; | 4134     Label done; | 
| 4138     __ b(NegateCondition(cc), &done); | 4135     __ b(NegateCondition(cc), &done); | 
| 4139     __ stop("eliminated bounds check failed"); | 4136     __ stop("eliminated bounds check failed"); | 
| 4140     __ bind(&done); | 4137     __ bind(&done); | 
| 4141   } else { | 4138   } else { | 
| 4142     DeoptimizeIf(cc, instr, Deoptimizer::kOutOfBounds); | 4139     DeoptimizeIf(cc, instr, DeoptimizeReason::kOutOfBounds); | 
| 4143   } | 4140   } | 
| 4144 } | 4141 } | 
| 4145 | 4142 | 
| 4146 | 4143 | 
| 4147 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4144 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 
| 4148   Register external_pointer = ToRegister(instr->elements()); | 4145   Register external_pointer = ToRegister(instr->elements()); | 
| 4149   Register key = no_reg; | 4146   Register key = no_reg; | 
| 4150   ElementsKind elements_kind = instr->elements_kind(); | 4147   ElementsKind elements_kind = instr->elements_kind(); | 
| 4151   bool key_is_constant = instr->key()->IsConstantOperand(); | 4148   bool key_is_constant = instr->key()->IsConstantOperand(); | 
| 4152   int constant_key = 0; | 4149   int constant_key = 0; | 
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4450     GrowArrayElementsStub stub(isolate(), instr->hydrogen()->is_js_array(), | 4447     GrowArrayElementsStub stub(isolate(), instr->hydrogen()->is_js_array(), | 
| 4451                                instr->hydrogen()->kind()); | 4448                                instr->hydrogen()->kind()); | 
| 4452     __ CallStub(&stub); | 4449     __ CallStub(&stub); | 
| 4453     RecordSafepointWithLazyDeopt( | 4450     RecordSafepointWithLazyDeopt( | 
| 4454         instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 4451         instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 
| 4455     __ StoreToSafepointRegisterSlot(result, result); | 4452     __ StoreToSafepointRegisterSlot(result, result); | 
| 4456   } | 4453   } | 
| 4457 | 4454 | 
| 4458   // Deopt on smi, which means the elements array changed to dictionary mode. | 4455   // Deopt on smi, which means the elements array changed to dictionary mode. | 
| 4459   __ TestIfSmi(result, r0); | 4456   __ TestIfSmi(result, r0); | 
| 4460   DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); | 4457   DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, cr0); | 
| 4461 } | 4458 } | 
| 4462 | 4459 | 
| 4463 | 4460 | 
| 4464 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 4461 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 
| 4465   Register object_reg = ToRegister(instr->object()); | 4462   Register object_reg = ToRegister(instr->object()); | 
| 4466   Register scratch = scratch0(); | 4463   Register scratch = scratch0(); | 
| 4467 | 4464 | 
| 4468   Handle<Map> from_map = instr->original_map(); | 4465   Handle<Map> from_map = instr->original_map(); | 
| 4469   Handle<Map> to_map = instr->transitioned_map(); | 4466   Handle<Map> to_map = instr->transitioned_map(); | 
| 4470   ElementsKind from_kind = instr->from_kind(); | 4467   ElementsKind from_kind = instr->from_kind(); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 4496   __ bind(¬_applicable); | 4493   __ bind(¬_applicable); | 
| 4497 } | 4494 } | 
| 4498 | 4495 | 
| 4499 | 4496 | 
| 4500 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 4497 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 
| 4501   Register object = ToRegister(instr->object()); | 4498   Register object = ToRegister(instr->object()); | 
| 4502   Register temp1 = ToRegister(instr->temp1()); | 4499   Register temp1 = ToRegister(instr->temp1()); | 
| 4503   Register temp2 = ToRegister(instr->temp2()); | 4500   Register temp2 = ToRegister(instr->temp2()); | 
| 4504   Label no_memento_found; | 4501   Label no_memento_found; | 
| 4505   __ TestJSArrayForAllocationMemento(object, temp1, temp2, &no_memento_found); | 4502   __ TestJSArrayForAllocationMemento(object, temp1, temp2, &no_memento_found); | 
| 4506   DeoptimizeIf(eq, instr, Deoptimizer::kMementoFound); | 4503   DeoptimizeIf(eq, instr, DeoptimizeReason::kMementoFound); | 
| 4507   __ bind(&no_memento_found); | 4504   __ bind(&no_memento_found); | 
| 4508 } | 4505 } | 
| 4509 | 4506 | 
| 4510 | 4507 | 
| 4511 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4508 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 
| 4512   DCHECK(ToRegister(instr->context()).is(cp)); | 4509   DCHECK(ToRegister(instr->context()).is(cp)); | 
| 4513   DCHECK(ToRegister(instr->left()).is(r4)); | 4510   DCHECK(ToRegister(instr->left()).is(r4)); | 
| 4514   DCHECK(ToRegister(instr->right()).is(r3)); | 4511   DCHECK(ToRegister(instr->right()).is(r3)); | 
| 4515   StringAddStub stub(isolate(), instr->hydrogen()->flags(), | 4512   StringAddStub stub(isolate(), instr->hydrogen()->flags(), | 
| 4516                      instr->hydrogen()->pretenure_flag()); | 4513                      instr->hydrogen()->pretenure_flag()); | 
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4807 } | 4804 } | 
| 4808 | 4805 | 
| 4809 | 4806 | 
| 4810 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 4807 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 
| 4811   HChange* hchange = instr->hydrogen(); | 4808   HChange* hchange = instr->hydrogen(); | 
| 4812   Register input = ToRegister(instr->value()); | 4809   Register input = ToRegister(instr->value()); | 
| 4813   Register output = ToRegister(instr->result()); | 4810   Register output = ToRegister(instr->result()); | 
| 4814   if (hchange->CheckFlag(HValue::kCanOverflow) && | 4811   if (hchange->CheckFlag(HValue::kCanOverflow) && | 
| 4815       hchange->value()->CheckFlag(HValue::kUint32)) { | 4812       hchange->value()->CheckFlag(HValue::kUint32)) { | 
| 4816     __ TestUnsignedSmiCandidate(input, r0); | 4813     __ TestUnsignedSmiCandidate(input, r0); | 
| 4817     DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, cr0); | 4814     DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow, cr0); | 
| 4818   } | 4815   } | 
| 4819 #if !V8_TARGET_ARCH_PPC64 | 4816 #if !V8_TARGET_ARCH_PPC64 | 
| 4820   if (hchange->CheckFlag(HValue::kCanOverflow) && | 4817   if (hchange->CheckFlag(HValue::kCanOverflow) && | 
| 4821       !hchange->value()->CheckFlag(HValue::kUint32)) { | 4818       !hchange->value()->CheckFlag(HValue::kUint32)) { | 
| 4822     __ SmiTagCheckOverflow(output, input, r0); | 4819     __ SmiTagCheckOverflow(output, input, r0); | 
| 4823     DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, cr0); | 4820     DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, cr0); | 
| 4824   } else { | 4821   } else { | 
| 4825 #endif | 4822 #endif | 
| 4826     __ SmiTag(output, input); | 4823     __ SmiTag(output, input); | 
| 4827 #if !V8_TARGET_ARCH_PPC64 | 4824 #if !V8_TARGET_ARCH_PPC64 | 
| 4828   } | 4825   } | 
| 4829 #endif | 4826 #endif | 
| 4830 } | 4827 } | 
| 4831 | 4828 | 
| 4832 | 4829 | 
| 4833 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { | 4830 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { | 
| 4834   Register scratch = scratch0(); | 4831   Register scratch = scratch0(); | 
| 4835   Register input = ToRegister(instr->value()); | 4832   Register input = ToRegister(instr->value()); | 
| 4836   Register result = ToRegister(instr->result()); | 4833   Register result = ToRegister(instr->result()); | 
| 4837   if (instr->needs_check()) { | 4834   if (instr->needs_check()) { | 
| 4838     // If the input is a HeapObject, value of scratch won't be zero. | 4835     // If the input is a HeapObject, value of scratch won't be zero. | 
| 4839     __ andi(scratch, input, Operand(kHeapObjectTag)); | 4836     __ andi(scratch, input, Operand(kHeapObjectTag)); | 
| 4840     __ SmiUntag(result, input); | 4837     __ SmiUntag(result, input); | 
| 4841     DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, cr0); | 4838     DeoptimizeIf(ne, instr, DeoptimizeReason::kNotASmi, cr0); | 
| 4842   } else { | 4839   } else { | 
| 4843     __ SmiUntag(result, input); | 4840     __ SmiUntag(result, input); | 
| 4844   } | 4841   } | 
| 4845 } | 4842 } | 
| 4846 | 4843 | 
| 4847 | 4844 | 
| 4848 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, | 4845 void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, | 
| 4849                                 DoubleRegister result_reg, | 4846                                 DoubleRegister result_reg, | 
| 4850                                 NumberUntagDMode mode) { | 4847                                 NumberUntagDMode mode) { | 
| 4851   bool can_convert_undefined_to_nan = | 4848   bool can_convert_undefined_to_nan = | 
| 4852       instr->hydrogen()->can_convert_undefined_to_nan(); | 4849       instr->hydrogen()->can_convert_undefined_to_nan(); | 
| 4853   bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero(); | 4850   bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero(); | 
| 4854 | 4851 | 
| 4855   Register scratch = scratch0(); | 4852   Register scratch = scratch0(); | 
| 4856   DCHECK(!result_reg.is(double_scratch0())); | 4853   DCHECK(!result_reg.is(double_scratch0())); | 
| 4857 | 4854 | 
| 4858   Label convert, load_smi, done; | 4855   Label convert, load_smi, done; | 
| 4859 | 4856 | 
| 4860   if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 4857   if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 
| 4861     // Smi check. | 4858     // Smi check. | 
| 4862     __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 4859     __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 
| 4863 | 4860 | 
| 4864     // Heap number map check. | 4861     // Heap number map check. | 
| 4865     __ LoadP(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4862     __ LoadP(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 
| 4866     __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4863     __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 
| 4867     __ cmp(scratch, ip); | 4864     __ cmp(scratch, ip); | 
| 4868     if (can_convert_undefined_to_nan) { | 4865     if (can_convert_undefined_to_nan) { | 
| 4869       __ bne(&convert); | 4866       __ bne(&convert); | 
| 4870     } else { | 4867     } else { | 
| 4871       DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber); | 4868       DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber); | 
| 4872     } | 4869     } | 
| 4873     // load heap number | 4870     // load heap number | 
| 4874     __ lfd(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 4871     __ lfd(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 
| 4875     if (deoptimize_on_minus_zero) { | 4872     if (deoptimize_on_minus_zero) { | 
| 4876       __ TestDoubleIsMinusZero(result_reg, scratch, ip); | 4873       __ TestDoubleIsMinusZero(result_reg, scratch, ip); | 
| 4877       DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero); | 4874       DeoptimizeIf(eq, instr, DeoptimizeReason::kMinusZero); | 
| 4878     } | 4875     } | 
| 4879     __ b(&done); | 4876     __ b(&done); | 
| 4880     if (can_convert_undefined_to_nan) { | 4877     if (can_convert_undefined_to_nan) { | 
| 4881       __ bind(&convert); | 4878       __ bind(&convert); | 
| 4882       // Convert undefined (and hole) to NaN. | 4879       // Convert undefined (and hole) to NaN. | 
| 4883       __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 4880       __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 
| 4884       __ cmp(input_reg, ip); | 4881       __ cmp(input_reg, ip); | 
| 4885       DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefined); | 4882       DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined); | 
| 4886       __ LoadRoot(scratch, Heap::kNanValueRootIndex); | 4883       __ LoadRoot(scratch, Heap::kNanValueRootIndex); | 
| 4887       __ lfd(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); | 4884       __ lfd(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); | 
| 4888       __ b(&done); | 4885       __ b(&done); | 
| 4889     } | 4886     } | 
| 4890   } else { | 4887   } else { | 
| 4891     __ SmiUntag(scratch, input_reg); | 4888     __ SmiUntag(scratch, input_reg); | 
| 4892     DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); | 4889     DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); | 
| 4893   } | 4890   } | 
| 4894   // Smi to double register conversion | 4891   // Smi to double register conversion | 
| 4895   __ bind(&load_smi); | 4892   __ bind(&load_smi); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4937     __ bind(&check_bools); | 4934     __ bind(&check_bools); | 
| 4938     __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 4935     __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 
| 4939     __ cmp(input_reg, ip); | 4936     __ cmp(input_reg, ip); | 
| 4940     __ bne(&check_false); | 4937     __ bne(&check_false); | 
| 4941     __ li(input_reg, Operand(1)); | 4938     __ li(input_reg, Operand(1)); | 
| 4942     __ b(&done); | 4939     __ b(&done); | 
| 4943 | 4940 | 
| 4944     __ bind(&check_false); | 4941     __ bind(&check_false); | 
| 4945     __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 4942     __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 
| 4946     __ cmp(input_reg, ip); | 4943     __ cmp(input_reg, ip); | 
| 4947     DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefinedBoolean); | 4944     DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefinedBoolean); | 
| 4948     __ li(input_reg, Operand::Zero()); | 4945     __ li(input_reg, Operand::Zero()); | 
| 4949   } else { | 4946   } else { | 
| 4950     DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumber); | 4947     DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumber); | 
| 4951 | 4948 | 
| 4952     __ lfd(double_scratch2, | 4949     __ lfd(double_scratch2, | 
| 4953            FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 4950            FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 
| 4954     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 4951     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 4955       // preserve heap number pointer in scratch2 for minus zero check below | 4952       // preserve heap number pointer in scratch2 for minus zero check below | 
| 4956       __ mr(scratch2, input_reg); | 4953       __ mr(scratch2, input_reg); | 
| 4957     } | 4954     } | 
| 4958     __ TryDoubleToInt32Exact(input_reg, double_scratch2, scratch1, | 4955     __ TryDoubleToInt32Exact(input_reg, double_scratch2, scratch1, | 
| 4959                              double_scratch); | 4956                              double_scratch); | 
| 4960     DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN); | 4957     DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN); | 
| 4961 | 4958 | 
| 4962     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 4959     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 4963       __ cmpi(input_reg, Operand::Zero()); | 4960       __ cmpi(input_reg, Operand::Zero()); | 
| 4964       __ bne(&done); | 4961       __ bne(&done); | 
| 4965       __ TestHeapNumberSign(scratch2, scratch1); | 4962       __ TestHeapNumberSign(scratch2, scratch1); | 
| 4966       DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 4963       DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 4967     } | 4964     } | 
| 4968   } | 4965   } | 
| 4969   __ bind(&done); | 4966   __ bind(&done); | 
| 4970 } | 4967 } | 
| 4971 | 4968 | 
| 4972 | 4969 | 
| 4973 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 4970 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 
| 4974   class DeferredTaggedToI final : public LDeferredCode { | 4971   class DeferredTaggedToI final : public LDeferredCode { | 
| 4975    public: | 4972    public: | 
| 4976     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 4973     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5025   Register scratch1 = scratch0(); | 5022   Register scratch1 = scratch0(); | 
| 5026   DoubleRegister double_input = ToDoubleRegister(instr->value()); | 5023   DoubleRegister double_input = ToDoubleRegister(instr->value()); | 
| 5027   DoubleRegister double_scratch = double_scratch0(); | 5024   DoubleRegister double_scratch = double_scratch0(); | 
| 5028 | 5025 | 
| 5029   if (instr->truncating()) { | 5026   if (instr->truncating()) { | 
| 5030     __ TruncateDoubleToI(result_reg, double_input); | 5027     __ TruncateDoubleToI(result_reg, double_input); | 
| 5031   } else { | 5028   } else { | 
| 5032     __ TryDoubleToInt32Exact(result_reg, double_input, scratch1, | 5029     __ TryDoubleToInt32Exact(result_reg, double_input, scratch1, | 
| 5033                              double_scratch); | 5030                              double_scratch); | 
| 5034     // Deoptimize if the input wasn't a int32 (inside a double). | 5031     // Deoptimize if the input wasn't a int32 (inside a double). | 
| 5035     DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN); | 5032     DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN); | 
| 5036     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 5033     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 5037       Label done; | 5034       Label done; | 
| 5038       __ cmpi(result_reg, Operand::Zero()); | 5035       __ cmpi(result_reg, Operand::Zero()); | 
| 5039       __ bne(&done); | 5036       __ bne(&done); | 
| 5040       __ TestDoubleSign(double_input, scratch1); | 5037       __ TestDoubleSign(double_input, scratch1); | 
| 5041       DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 5038       DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 5042       __ bind(&done); | 5039       __ bind(&done); | 
| 5043     } | 5040     } | 
| 5044   } | 5041   } | 
| 5045 } | 5042 } | 
| 5046 | 5043 | 
| 5047 | 5044 | 
| 5048 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { | 5045 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { | 
| 5049   Register result_reg = ToRegister(instr->result()); | 5046   Register result_reg = ToRegister(instr->result()); | 
| 5050   Register scratch1 = scratch0(); | 5047   Register scratch1 = scratch0(); | 
| 5051   DoubleRegister double_input = ToDoubleRegister(instr->value()); | 5048   DoubleRegister double_input = ToDoubleRegister(instr->value()); | 
| 5052   DoubleRegister double_scratch = double_scratch0(); | 5049   DoubleRegister double_scratch = double_scratch0(); | 
| 5053 | 5050 | 
| 5054   if (instr->truncating()) { | 5051   if (instr->truncating()) { | 
| 5055     __ TruncateDoubleToI(result_reg, double_input); | 5052     __ TruncateDoubleToI(result_reg, double_input); | 
| 5056   } else { | 5053   } else { | 
| 5057     __ TryDoubleToInt32Exact(result_reg, double_input, scratch1, | 5054     __ TryDoubleToInt32Exact(result_reg, double_input, scratch1, | 
| 5058                              double_scratch); | 5055                              double_scratch); | 
| 5059     // Deoptimize if the input wasn't a int32 (inside a double). | 5056     // Deoptimize if the input wasn't a int32 (inside a double). | 
| 5060     DeoptimizeIf(ne, instr, Deoptimizer::kLostPrecisionOrNaN); | 5057     DeoptimizeIf(ne, instr, DeoptimizeReason::kLostPrecisionOrNaN); | 
| 5061     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 5058     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 5062       Label done; | 5059       Label done; | 
| 5063       __ cmpi(result_reg, Operand::Zero()); | 5060       __ cmpi(result_reg, Operand::Zero()); | 
| 5064       __ bne(&done); | 5061       __ bne(&done); | 
| 5065       __ TestDoubleSign(double_input, scratch1); | 5062       __ TestDoubleSign(double_input, scratch1); | 
| 5066       DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); | 5063       DeoptimizeIf(lt, instr, DeoptimizeReason::kMinusZero); | 
| 5067       __ bind(&done); | 5064       __ bind(&done); | 
| 5068     } | 5065     } | 
| 5069   } | 5066   } | 
| 5070 #if V8_TARGET_ARCH_PPC64 | 5067 #if V8_TARGET_ARCH_PPC64 | 
| 5071   __ SmiTag(result_reg); | 5068   __ SmiTag(result_reg); | 
| 5072 #else | 5069 #else | 
| 5073   __ SmiTagCheckOverflow(result_reg, r0); | 5070   __ SmiTagCheckOverflow(result_reg, r0); | 
| 5074   DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, cr0); | 5071   DeoptimizeIf(lt, instr, DeoptimizeReason::kOverflow, cr0); | 
| 5075 #endif | 5072 #endif | 
| 5076 } | 5073 } | 
| 5077 | 5074 | 
| 5078 | 5075 | 
| 5079 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 5076 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 
| 5080   LOperand* input = instr->value(); | 5077   LOperand* input = instr->value(); | 
| 5081   __ TestIfSmi(ToRegister(input), r0); | 5078   __ TestIfSmi(ToRegister(input), r0); | 
| 5082   DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, cr0); | 5079   DeoptimizeIf(ne, instr, DeoptimizeReason::kNotASmi, cr0); | 
| 5083 } | 5080 } | 
| 5084 | 5081 | 
| 5085 | 5082 | 
| 5086 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 5083 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 
| 5087   if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 5084   if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 
| 5088     LOperand* input = instr->value(); | 5085     LOperand* input = instr->value(); | 
| 5089     __ TestIfSmi(ToRegister(input), r0); | 5086     __ TestIfSmi(ToRegister(input), r0); | 
| 5090     DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); | 5087     DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, cr0); | 
| 5091   } | 5088   } | 
| 5092 } | 5089 } | 
| 5093 | 5090 | 
| 5094 | 5091 | 
| 5095 void LCodeGen::DoCheckArrayBufferNotNeutered( | 5092 void LCodeGen::DoCheckArrayBufferNotNeutered( | 
| 5096     LCheckArrayBufferNotNeutered* instr) { | 5093     LCheckArrayBufferNotNeutered* instr) { | 
| 5097   Register view = ToRegister(instr->view()); | 5094   Register view = ToRegister(instr->view()); | 
| 5098   Register scratch = scratch0(); | 5095   Register scratch = scratch0(); | 
| 5099 | 5096 | 
| 5100   __ LoadP(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); | 5097   __ LoadP(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); | 
| 5101   __ lwz(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); | 5098   __ lwz(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); | 
| 5102   __ andi(r0, scratch, Operand(1 << JSArrayBuffer::WasNeutered::kShift)); | 5099   __ andi(r0, scratch, Operand(1 << JSArrayBuffer::WasNeutered::kShift)); | 
| 5103   DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds, cr0); | 5100   DeoptimizeIf(ne, instr, DeoptimizeReason::kOutOfBounds, cr0); | 
| 5104 } | 5101 } | 
| 5105 | 5102 | 
| 5106 | 5103 | 
| 5107 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 5104 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 
| 5108   Register input = ToRegister(instr->value()); | 5105   Register input = ToRegister(instr->value()); | 
| 5109   Register scratch = scratch0(); | 5106   Register scratch = scratch0(); | 
| 5110 | 5107 | 
| 5111   __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 5108   __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 
| 5112   __ lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | 5109   __ lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | 
| 5113 | 5110 | 
| 5114   if (instr->hydrogen()->is_interval_check()) { | 5111   if (instr->hydrogen()->is_interval_check()) { | 
| 5115     InstanceType first; | 5112     InstanceType first; | 
| 5116     InstanceType last; | 5113     InstanceType last; | 
| 5117     instr->hydrogen()->GetCheckInterval(&first, &last); | 5114     instr->hydrogen()->GetCheckInterval(&first, &last); | 
| 5118 | 5115 | 
| 5119     __ cmpli(scratch, Operand(first)); | 5116     __ cmpli(scratch, Operand(first)); | 
| 5120 | 5117 | 
| 5121     // If there is only one type in the interval check for equality. | 5118     // If there is only one type in the interval check for equality. | 
| 5122     if (first == last) { | 5119     if (first == last) { | 
| 5123       DeoptimizeIf(ne, instr, Deoptimizer::kWrongInstanceType); | 5120       DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongInstanceType); | 
| 5124     } else { | 5121     } else { | 
| 5125       DeoptimizeIf(lt, instr, Deoptimizer::kWrongInstanceType); | 5122       DeoptimizeIf(lt, instr, DeoptimizeReason::kWrongInstanceType); | 
| 5126       // Omit check for the last type. | 5123       // Omit check for the last type. | 
| 5127       if (last != LAST_TYPE) { | 5124       if (last != LAST_TYPE) { | 
| 5128         __ cmpli(scratch, Operand(last)); | 5125         __ cmpli(scratch, Operand(last)); | 
| 5129         DeoptimizeIf(gt, instr, Deoptimizer::kWrongInstanceType); | 5126         DeoptimizeIf(gt, instr, DeoptimizeReason::kWrongInstanceType); | 
| 5130       } | 5127       } | 
| 5131     } | 5128     } | 
| 5132   } else { | 5129   } else { | 
| 5133     uint8_t mask; | 5130     uint8_t mask; | 
| 5134     uint8_t tag; | 5131     uint8_t tag; | 
| 5135     instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); | 5132     instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); | 
| 5136 | 5133 | 
| 5137     if (base::bits::IsPowerOfTwo32(mask)) { | 5134     if (base::bits::IsPowerOfTwo32(mask)) { | 
| 5138       DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); | 5135       DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); | 
| 5139       __ andi(r0, scratch, Operand(mask)); | 5136       __ andi(r0, scratch, Operand(mask)); | 
| 5140       DeoptimizeIf(tag == 0 ? ne : eq, instr, Deoptimizer::kWrongInstanceType, | 5137       DeoptimizeIf(tag == 0 ? ne : eq, instr, | 
| 5141                    cr0); | 5138                    DeoptimizeReason::kWrongInstanceType, cr0); | 
| 5142     } else { | 5139     } else { | 
| 5143       __ andi(scratch, scratch, Operand(mask)); | 5140       __ andi(scratch, scratch, Operand(mask)); | 
| 5144       __ cmpi(scratch, Operand(tag)); | 5141       __ cmpi(scratch, Operand(tag)); | 
| 5145       DeoptimizeIf(ne, instr, Deoptimizer::kWrongInstanceType); | 5142       DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongInstanceType); | 
| 5146     } | 5143     } | 
| 5147   } | 5144   } | 
| 5148 } | 5145 } | 
| 5149 | 5146 | 
| 5150 | 5147 | 
| 5151 void LCodeGen::DoCheckValue(LCheckValue* instr) { | 5148 void LCodeGen::DoCheckValue(LCheckValue* instr) { | 
| 5152   Register reg = ToRegister(instr->value()); | 5149   Register reg = ToRegister(instr->value()); | 
| 5153   Handle<HeapObject> object = instr->hydrogen()->object().handle(); | 5150   Handle<HeapObject> object = instr->hydrogen()->object().handle(); | 
| 5154   AllowDeferredHandleDereference smi_check; | 5151   AllowDeferredHandleDereference smi_check; | 
| 5155   if (isolate()->heap()->InNewSpace(*object)) { | 5152   if (isolate()->heap()->InNewSpace(*object)) { | 
| 5156     Register reg = ToRegister(instr->value()); | 5153     Register reg = ToRegister(instr->value()); | 
| 5157     Handle<Cell> cell = isolate()->factory()->NewCell(object); | 5154     Handle<Cell> cell = isolate()->factory()->NewCell(object); | 
| 5158     __ mov(ip, Operand(cell)); | 5155     __ mov(ip, Operand(cell)); | 
| 5159     __ LoadP(ip, FieldMemOperand(ip, Cell::kValueOffset)); | 5156     __ LoadP(ip, FieldMemOperand(ip, Cell::kValueOffset)); | 
| 5160     __ cmp(reg, ip); | 5157     __ cmp(reg, ip); | 
| 5161   } else { | 5158   } else { | 
| 5162     __ Cmpi(reg, Operand(object), r0); | 5159     __ Cmpi(reg, Operand(object), r0); | 
| 5163   } | 5160   } | 
| 5164   DeoptimizeIf(ne, instr, Deoptimizer::kValueMismatch); | 5161   DeoptimizeIf(ne, instr, DeoptimizeReason::kValueMismatch); | 
| 5165 } | 5162 } | 
| 5166 | 5163 | 
| 5167 | 5164 | 
| 5168 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { | 5165 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { | 
| 5169   Register temp = ToRegister(instr->temp()); | 5166   Register temp = ToRegister(instr->temp()); | 
| 5170   { | 5167   { | 
| 5171     PushSafepointRegistersScope scope(this); | 5168     PushSafepointRegistersScope scope(this); | 
| 5172     __ push(object); | 5169     __ push(object); | 
| 5173     __ li(cp, Operand::Zero()); | 5170     __ li(cp, Operand::Zero()); | 
| 5174     __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); | 5171     __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); | 
| 5175     RecordSafepointWithRegisters(instr->pointer_map(), 1, | 5172     RecordSafepointWithRegisters(instr->pointer_map(), 1, | 
| 5176                                  Safepoint::kNoLazyDeopt); | 5173                                  Safepoint::kNoLazyDeopt); | 
| 5177     __ StoreToSafepointRegisterSlot(r3, temp); | 5174     __ StoreToSafepointRegisterSlot(r3, temp); | 
| 5178   } | 5175   } | 
| 5179   __ TestIfSmi(temp, r0); | 5176   __ TestIfSmi(temp, r0); | 
| 5180   DeoptimizeIf(eq, instr, Deoptimizer::kInstanceMigrationFailed, cr0); | 5177   DeoptimizeIf(eq, instr, DeoptimizeReason::kInstanceMigrationFailed, cr0); | 
| 5181 } | 5178 } | 
| 5182 | 5179 | 
| 5183 | 5180 | 
| 5184 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { | 5181 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { | 
| 5185   class DeferredCheckMaps final : public LDeferredCode { | 5182   class DeferredCheckMaps final : public LDeferredCode { | 
| 5186    public: | 5183    public: | 
| 5187     DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) | 5184     DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) | 
| 5188         : LDeferredCode(codegen), instr_(instr), object_(object) { | 5185         : LDeferredCode(codegen), instr_(instr), object_(object) { | 
| 5189       SetExit(check_maps()); | 5186       SetExit(check_maps()); | 
| 5190     } | 5187     } | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5225     Handle<Map> map = maps->at(i).handle(); | 5222     Handle<Map> map = maps->at(i).handle(); | 
| 5226     __ CompareMap(map_reg, map, &success); | 5223     __ CompareMap(map_reg, map, &success); | 
| 5227     __ beq(&success); | 5224     __ beq(&success); | 
| 5228   } | 5225   } | 
| 5229 | 5226 | 
| 5230   Handle<Map> map = maps->at(maps->size() - 1).handle(); | 5227   Handle<Map> map = maps->at(maps->size() - 1).handle(); | 
| 5231   __ CompareMap(map_reg, map, &success); | 5228   __ CompareMap(map_reg, map, &success); | 
| 5232   if (instr->hydrogen()->HasMigrationTarget()) { | 5229   if (instr->hydrogen()->HasMigrationTarget()) { | 
| 5233     __ bne(deferred->entry()); | 5230     __ bne(deferred->entry()); | 
| 5234   } else { | 5231   } else { | 
| 5235     DeoptimizeIf(ne, instr, Deoptimizer::kWrongMap); | 5232     DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongMap); | 
| 5236   } | 5233   } | 
| 5237 | 5234 | 
| 5238   __ bind(&success); | 5235   __ bind(&success); | 
| 5239 } | 5236 } | 
| 5240 | 5237 | 
| 5241 | 5238 | 
| 5242 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 5239 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 
| 5243   DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); | 5240   DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); | 
| 5244   Register result_reg = ToRegister(instr->result()); | 5241   Register result_reg = ToRegister(instr->result()); | 
| 5245   __ ClampDoubleToUint8(result_reg, value_reg, double_scratch0()); | 5242   __ ClampDoubleToUint8(result_reg, value_reg, double_scratch0()); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 5264   __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); | 5261   __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); | 
| 5265 | 5262 | 
| 5266   // Check for heap number | 5263   // Check for heap number | 
| 5267   __ LoadP(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 5264   __ LoadP(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 
| 5268   __ Cmpi(scratch, Operand(factory()->heap_number_map()), r0); | 5265   __ Cmpi(scratch, Operand(factory()->heap_number_map()), r0); | 
| 5269   __ beq(&heap_number); | 5266   __ beq(&heap_number); | 
| 5270 | 5267 | 
| 5271   // Check for undefined. Undefined is converted to zero for clamping | 5268   // Check for undefined. Undefined is converted to zero for clamping | 
| 5272   // conversions. | 5269   // conversions. | 
| 5273   __ Cmpi(input_reg, Operand(factory()->undefined_value()), r0); | 5270   __ Cmpi(input_reg, Operand(factory()->undefined_value()), r0); | 
| 5274   DeoptimizeIf(ne, instr, Deoptimizer::kNotAHeapNumberUndefined); | 5271   DeoptimizeIf(ne, instr, DeoptimizeReason::kNotAHeapNumberUndefined); | 
| 5275   __ li(result_reg, Operand::Zero()); | 5272   __ li(result_reg, Operand::Zero()); | 
| 5276   __ b(&done); | 5273   __ b(&done); | 
| 5277 | 5274 | 
| 5278   // Heap number | 5275   // Heap number | 
| 5279   __ bind(&heap_number); | 5276   __ bind(&heap_number); | 
| 5280   __ lfd(temp_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 5277   __ lfd(temp_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 
| 5281   __ ClampDoubleToUint8(result_reg, temp_reg, double_scratch0()); | 5278   __ ClampDoubleToUint8(result_reg, temp_reg, double_scratch0()); | 
| 5282   __ b(&done); | 5279   __ b(&done); | 
| 5283 | 5280 | 
| 5284   // smi | 5281   // smi | 
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5695   __ CmpSmiLiteral(result, Smi::FromInt(0), r0); | 5692   __ CmpSmiLiteral(result, Smi::FromInt(0), r0); | 
| 5696   __ bne(&load_cache); | 5693   __ bne(&load_cache); | 
| 5697   __ mov(result, Operand(isolate()->factory()->empty_fixed_array())); | 5694   __ mov(result, Operand(isolate()->factory()->empty_fixed_array())); | 
| 5698   __ b(&done); | 5695   __ b(&done); | 
| 5699 | 5696 | 
| 5700   __ bind(&load_cache); | 5697   __ bind(&load_cache); | 
| 5701   __ LoadInstanceDescriptors(map, result); | 5698   __ LoadInstanceDescriptors(map, result); | 
| 5702   __ LoadP(result, FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); | 5699   __ LoadP(result, FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); | 
| 5703   __ LoadP(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); | 5700   __ LoadP(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); | 
| 5704   __ cmpi(result, Operand::Zero()); | 5701   __ cmpi(result, Operand::Zero()); | 
| 5705   DeoptimizeIf(eq, instr, Deoptimizer::kNoCache); | 5702   DeoptimizeIf(eq, instr, DeoptimizeReason::kNoCache); | 
| 5706 | 5703 | 
| 5707   __ bind(&done); | 5704   __ bind(&done); | 
| 5708 } | 5705 } | 
| 5709 | 5706 | 
| 5710 | 5707 | 
| 5711 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { | 5708 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { | 
| 5712   Register object = ToRegister(instr->value()); | 5709   Register object = ToRegister(instr->value()); | 
| 5713   Register map = ToRegister(instr->map()); | 5710   Register map = ToRegister(instr->map()); | 
| 5714   __ LoadP(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); | 5711   __ LoadP(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); | 
| 5715   __ cmp(map, scratch0()); | 5712   __ cmp(map, scratch0()); | 
| 5716   DeoptimizeIf(ne, instr, Deoptimizer::kWrongMap); | 5713   DeoptimizeIf(ne, instr, DeoptimizeReason::kWrongMap); | 
| 5717 } | 5714 } | 
| 5718 | 5715 | 
| 5719 | 5716 | 
| 5720 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, | 5717 void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, | 
| 5721                                            Register result, Register object, | 5718                                            Register result, Register object, | 
| 5722                                            Register index) { | 5719                                            Register index) { | 
| 5723   PushSafepointRegistersScope scope(this); | 5720   PushSafepointRegistersScope scope(this); | 
| 5724   __ Push(object, index); | 5721   __ Push(object, index); | 
| 5725   __ li(cp, Operand::Zero()); | 5722   __ li(cp, Operand::Zero()); | 
| 5726   __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble); | 5723   __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble); | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5784   __ LoadP(result, | 5781   __ LoadP(result, | 
| 5785            FieldMemOperand(scratch, FixedArray::kHeaderSize - kPointerSize)); | 5782            FieldMemOperand(scratch, FixedArray::kHeaderSize - kPointerSize)); | 
| 5786   __ bind(deferred->exit()); | 5783   __ bind(deferred->exit()); | 
| 5787   __ bind(&done); | 5784   __ bind(&done); | 
| 5788 } | 5785 } | 
| 5789 | 5786 | 
| 5790 #undef __ | 5787 #undef __ | 
| 5791 | 5788 | 
| 5792 }  // namespace internal | 5789 }  // namespace internal | 
| 5793 }  // namespace v8 | 5790 }  // namespace v8 | 
| OLD | NEW | 
|---|