| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), | 1006 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), |
| 1007 0, | 1007 0, |
| 1008 Safepoint::kNoDeoptimizationIndex); | 1008 Safepoint::kNoDeoptimizationIndex); |
| 1009 // Overwrite the stored value of r0 with the result of the stub. | 1009 // Overwrite the stored value of r0 with the result of the stub. |
| 1010 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); | 1010 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); |
| 1011 __ PopSafepointRegistersAndDoubles(); | 1011 __ PopSafepointRegistersAndDoubles(); |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 | 1014 |
| 1015 void LCodeGen::DoMulI(LMulI* instr) { | 1015 void LCodeGen::DoMulI(LMulI* instr) { |
| 1016 LOperand* left_op = instr->InputAt(0); | 1016 Register scratch = scratch0(); |
| 1017 LOperand* right_op = instr->InputAt(1); | 1017 Register left = ToRegister(instr->InputAt(0)); |
| 1018 Register right = EmitLoadRegister(instr->InputAt(1), scratch); |
| 1018 | 1019 |
| 1019 Register scratch = scratch0(); | 1020 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1020 Register left = ToRegister(left_op); | 1021 !instr->InputAt(1)->IsConstantOperand()) { |
| 1022 __ orr(ToRegister(instr->TempAt(0)), left, right); |
| 1023 } |
| 1021 | 1024 |
| 1022 ASSERT(left_op->Equals(instr->result())); | 1025 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1026 // scratch:left = left * right. |
| 1027 __ smull(left, scratch, left, right); |
| 1028 __ mov(ip, Operand(left, ASR, 31)); |
| 1029 __ cmp(ip, Operand(scratch)); |
| 1030 DeoptimizeIf(ne, instr->environment()); |
| 1031 } else { |
| 1032 __ mul(left, left, right); |
| 1033 } |
| 1023 | 1034 |
| 1024 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1035 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1025 bool bailout_on_minus_zero = | 1036 // Bail out if the result is supposed to be negative zero. |
| 1026 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 1037 Label done; |
| 1027 | 1038 __ tst(left, Operand(left)); |
| 1028 if (right_op->IsConstantOperand()) { | 1039 __ b(ne, &done); |
| 1029 // Use optimized code for specific constants. | 1040 if (instr->InputAt(1)->IsConstantOperand()) { |
| 1030 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); | 1041 if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) { |
| 1031 Condition overflow_deopt_cond = kNoCondition; | 1042 DeoptimizeIf(al, instr->environment()); |
| 1032 switch (constant) { | 1043 } |
| 1033 case -1: | |
| 1034 overflow_deopt_cond = can_overflow ? vs : kNoCondition; | |
| 1035 __ rsb(left, | |
| 1036 left, | |
| 1037 Operand(0), | |
| 1038 can_overflow ? SetCC : LeaveCC); | |
| 1039 break; | |
| 1040 case 0: | |
| 1041 if (bailout_on_minus_zero) { | |
| 1042 // If left is strictly negative and the constant is null, the | |
| 1043 // result is -0. Deoptimize if required, otherwise return 0. | |
| 1044 __ cmp(left, Operand(0)); | |
| 1045 DeoptimizeIf(mi, instr->environment()); | |
| 1046 } | |
| 1047 __ mov(left, Operand(0)); | |
| 1048 break; | |
| 1049 case 1: | |
| 1050 // Do nothing. | |
| 1051 break; | |
| 1052 default: | |
| 1053 // Multiplying by powers of two and powers of two plus or minus | |
| 1054 // one can be done faster with shifted operands. | |
| 1055 // For other constants we emit standard code. | |
| 1056 int32_t mask = constant >> 31; | |
| 1057 uint32_t constant_abs = (constant + mask) ^ mask; | |
| 1058 if (IsPowerOf2(constant_abs)) { | |
| 1059 if (!can_overflow) { | |
| 1060 int32_t shift = WhichPowerOf2(constant_abs); | |
| 1061 __ mov(left, Operand(left, LSL, shift)); | |
| 1062 if (constant < 0) __ rsb(left, left, Operand(0)); | |
| 1063 } else { | |
| 1064 // scratch:left = left * constant. | |
| 1065 __ mov(ip, Operand(constant)); | |
| 1066 __ smull(left, scratch, left, ip); | |
| 1067 __ cmp(scratch, Operand(left, ASR, 31)); | |
| 1068 overflow_deopt_cond = ne; | |
| 1069 } | |
| 1070 } else if (IsPowerOf2(constant_abs - 1)) { | |
| 1071 int32_t shift = WhichPowerOf2(constant_abs - 1); | |
| 1072 __ add(left, | |
| 1073 left, | |
| 1074 Operand(left, LSL, shift), | |
| 1075 can_overflow ? SetCC : LeaveCC); | |
| 1076 overflow_deopt_cond = can_overflow ? vs : kNoCondition; | |
| 1077 if (constant < 0) __ rsb(left, left, Operand(0)); | |
| 1078 } else if (IsPowerOf2(constant_abs + 1)) { | |
| 1079 int32_t shift = WhichPowerOf2(constant_abs + 1); | |
| 1080 __ rsb(left, | |
| 1081 left, | |
| 1082 Operand(left, LSL, shift), | |
| 1083 can_overflow ? SetCC : LeaveCC); | |
| 1084 overflow_deopt_cond = can_overflow ? vs : kNoCondition; | |
| 1085 if (constant < 0) __ rsb(left, left, Operand(0)); | |
| 1086 } else { | |
| 1087 if (!can_overflow) { | |
| 1088 __ mov(ip, Operand(constant)); | |
| 1089 __ mul(left, left, ip); | |
| 1090 } else { | |
| 1091 // scratch:left = left * constant. | |
| 1092 __ mov(ip, Operand(constant)); | |
| 1093 __ smull(left, scratch, left, ip); | |
| 1094 __ cmp(scratch, Operand(left, ASR, 31)); | |
| 1095 overflow_deopt_cond = ne; | |
| 1096 } | |
| 1097 } | |
| 1098 break; | |
| 1099 } | |
| 1100 | |
| 1101 if (can_overflow && (constant != 0) && (constant != 1)) { | |
| 1102 ASSERT(overflow_deopt_cond != kNoCondition); | |
| 1103 DeoptimizeIf(overflow_deopt_cond, instr->environment()); | |
| 1104 } | |
| 1105 if (bailout_on_minus_zero && (constant < 0)) { | |
| 1106 // The case of a null constant was handled separately. | |
| 1107 // If constant is negative and left is null, the result should be -0. | |
| 1108 __ cmp(left, Operand(0)); | |
| 1109 DeoptimizeIf(eq, instr->environment()); | |
| 1110 } | |
| 1111 } else { | |
| 1112 Register right = EmitLoadRegister(right_op, scratch); | |
| 1113 if (bailout_on_minus_zero) { | |
| 1114 __ orr(ToRegister(instr->TempAt(0)), left, right); | |
| 1115 } | |
| 1116 if (can_overflow) { | |
| 1117 // scratch:left = left * right. | |
| 1118 __ smull(left, scratch, left, right); | |
| 1119 __ cmp(scratch, Operand(left, ASR, 31)); | |
| 1120 DeoptimizeIf(ne, instr->environment()); | |
| 1121 } else { | 1044 } else { |
| 1122 __ mul(left, left, right); | 1045 // Test the non-zero operand for negative sign. |
| 1123 } | |
| 1124 if (bailout_on_minus_zero) { | |
| 1125 // Bail out if the result is supposed to be negative zero. | |
| 1126 Label done; | |
| 1127 __ cmp(left, Operand(0)); | |
| 1128 __ b(ne, &done); | |
| 1129 __ cmp(ToRegister(instr->TempAt(0)), Operand(0)); | 1046 __ cmp(ToRegister(instr->TempAt(0)), Operand(0)); |
| 1130 DeoptimizeIf(mi, instr->environment()); | 1047 DeoptimizeIf(mi, instr->environment()); |
| 1131 __ bind(&done); | |
| 1132 } | 1048 } |
| 1049 __ bind(&done); |
| 1133 } | 1050 } |
| 1134 } | 1051 } |
| 1135 | 1052 |
| 1136 | 1053 |
| 1137 void LCodeGen::DoBitI(LBitI* instr) { | 1054 void LCodeGen::DoBitI(LBitI* instr) { |
| 1138 LOperand* left = instr->InputAt(0); | 1055 LOperand* left = instr->InputAt(0); |
| 1139 LOperand* right = instr->InputAt(1); | 1056 LOperand* right = instr->InputAt(1); |
| 1140 ASSERT(left->Equals(instr->result())); | 1057 ASSERT(left->Equals(instr->result())); |
| 1141 ASSERT(left->IsRegister()); | 1058 ASSERT(left->IsRegister()); |
| 1142 Register result = ToRegister(left); | 1059 Register result = ToRegister(left); |
| (...skipping 2912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4055 ASSERT(!environment->HasBeenRegistered()); | 3972 ASSERT(!environment->HasBeenRegistered()); |
| 4056 RegisterEnvironmentForDeoptimization(environment); | 3973 RegisterEnvironmentForDeoptimization(environment); |
| 4057 ASSERT(osr_pc_offset_ == -1); | 3974 ASSERT(osr_pc_offset_ == -1); |
| 4058 osr_pc_offset_ = masm()->pc_offset(); | 3975 osr_pc_offset_ = masm()->pc_offset(); |
| 4059 } | 3976 } |
| 4060 | 3977 |
| 4061 | 3978 |
| 4062 #undef __ | 3979 #undef __ |
| 4063 | 3980 |
| 4064 } } // namespace v8::internal | 3981 } } // namespace v8::internal |
| OLD | NEW |