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

Side by Side Diff: src/crankshaft/ppc/lithium-codegen-ppc.cc

Issue 2161543002: [turbofan] Add support for eager/soft deoptimization reasons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Do the ports properly Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/crankshaft/ppc/lithium-codegen-ppc.h ('k') | src/crankshaft/s390/lithium-codegen-s390.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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(&dividend_is_not_negative); 895 __ bge(&dividend_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(&dividend_is_not_negative); 912 __ bind(&dividend_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(&dividend_not_zero); 1112 __ bne(&dividend_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(&dividend_not_zero); 1115 __ bind(&dividend_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
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(&dividend_not_zero); 1289 __ bne(&dividend_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(&dividend_not_zero); 1292 __ bind(&dividend_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
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
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
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
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
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
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
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
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(&not_heap_number); 2189 __ bind(&not_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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
4496 __ bind(&not_applicable); 4493 __ bind(&not_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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/crankshaft/ppc/lithium-codegen-ppc.h ('k') | src/crankshaft/s390/lithium-codegen-s390.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698