| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
| 8 | 8 |
| 9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 5004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5015 | 5015 |
| 5016 | 5016 |
| 5017 void MacroAssembler::SmiToDoubleFPURegister(Register smi, | 5017 void MacroAssembler::SmiToDoubleFPURegister(Register smi, |
| 5018 FPURegister value, | 5018 FPURegister value, |
| 5019 Register scratch1) { | 5019 Register scratch1) { |
| 5020 dsra32(scratch1, smi, 0); | 5020 dsra32(scratch1, smi, 0); |
| 5021 mtc1(scratch1, value); | 5021 mtc1(scratch1, value); |
| 5022 cvt_d_w(value, value); | 5022 cvt_d_w(value, value); |
| 5023 } | 5023 } |
| 5024 | 5024 |
| 5025 | |
| 5026 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, | |
| 5027 const Operand& right, | |
| 5028 Register overflow_dst, | |
| 5029 Register scratch) { | |
| 5030 if (right.is_reg()) { | |
| 5031 AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | |
| 5032 } else { | |
| 5033 if (dst.is(left)) { | |
| 5034 li(t9, right); // Load right. | |
| 5035 mov(scratch, left); // Preserve left. | |
| 5036 addu(dst, left, t9); // Left is overwritten. | |
| 5037 xor_(scratch, dst, scratch); // Original left. | |
| 5038 xor_(overflow_dst, dst, t9); | |
| 5039 and_(overflow_dst, overflow_dst, scratch); | |
| 5040 } else { | |
| 5041 li(t9, right); | |
| 5042 addu(dst, left, t9); | |
| 5043 xor_(overflow_dst, dst, left); | |
| 5044 xor_(scratch, dst, t9); | |
| 5045 and_(overflow_dst, scratch, overflow_dst); | |
| 5046 } | |
| 5047 } | |
| 5048 } | |
| 5049 | |
| 5050 | |
| 5051 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, | |
| 5052 Register right, | |
| 5053 Register overflow_dst, | |
| 5054 Register scratch) { | |
| 5055 DCHECK(!dst.is(overflow_dst)); | |
| 5056 DCHECK(!dst.is(scratch)); | |
| 5057 DCHECK(!overflow_dst.is(scratch)); | |
| 5058 DCHECK(!overflow_dst.is(left)); | |
| 5059 DCHECK(!overflow_dst.is(right)); | |
| 5060 | |
| 5061 if (left.is(right) && dst.is(left)) { | |
| 5062 DCHECK(!dst.is(t9)); | |
| 5063 DCHECK(!scratch.is(t9)); | |
| 5064 DCHECK(!left.is(t9)); | |
| 5065 DCHECK(!right.is(t9)); | |
| 5066 DCHECK(!overflow_dst.is(t9)); | |
| 5067 mov(t9, right); | |
| 5068 right = t9; | |
| 5069 } | |
| 5070 | |
| 5071 if (dst.is(left)) { | |
| 5072 mov(scratch, left); // Preserve left. | |
| 5073 addu(dst, left, right); // Left is overwritten. | |
| 5074 xor_(scratch, dst, scratch); // Original left. | |
| 5075 xor_(overflow_dst, dst, right); | |
| 5076 and_(overflow_dst, overflow_dst, scratch); | |
| 5077 } else if (dst.is(right)) { | |
| 5078 mov(scratch, right); // Preserve right. | |
| 5079 addu(dst, left, right); // Right is overwritten. | |
| 5080 xor_(scratch, dst, scratch); // Original right. | |
| 5081 xor_(overflow_dst, dst, left); | |
| 5082 and_(overflow_dst, overflow_dst, scratch); | |
| 5083 } else { | |
| 5084 addu(dst, left, right); | |
| 5085 xor_(overflow_dst, dst, left); | |
| 5086 xor_(scratch, dst, right); | |
| 5087 and_(overflow_dst, scratch, overflow_dst); | |
| 5088 } | |
| 5089 } | |
| 5090 | |
| 5091 | |
| 5092 void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left, | |
| 5093 const Operand& right, | |
| 5094 Register overflow_dst, | |
| 5095 Register scratch) { | |
| 5096 if (right.is_reg()) { | |
| 5097 DadduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | |
| 5098 } else { | |
| 5099 if (dst.is(left)) { | |
| 5100 li(t9, right); // Load right. | |
| 5101 mov(scratch, left); // Preserve left. | |
| 5102 daddu(dst, left, t9); // Left is overwritten. | |
| 5103 xor_(scratch, dst, scratch); // Original left. | |
| 5104 xor_(overflow_dst, dst, t9); | |
| 5105 and_(overflow_dst, overflow_dst, scratch); | |
| 5106 } else { | |
| 5107 li(t9, right); // Load right. | |
| 5108 Daddu(dst, left, t9); | |
| 5109 xor_(overflow_dst, dst, left); | |
| 5110 xor_(scratch, dst, t9); | |
| 5111 and_(overflow_dst, scratch, overflow_dst); | |
| 5112 } | |
| 5113 } | |
| 5114 } | |
| 5115 | |
| 5116 | |
| 5117 void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left, | |
| 5118 Register right, | |
| 5119 Register overflow_dst, | |
| 5120 Register scratch) { | |
| 5121 DCHECK(!dst.is(overflow_dst)); | |
| 5122 DCHECK(!dst.is(scratch)); | |
| 5123 DCHECK(!overflow_dst.is(scratch)); | |
| 5124 DCHECK(!overflow_dst.is(left)); | |
| 5125 DCHECK(!overflow_dst.is(right)); | |
| 5126 | |
| 5127 if (left.is(right) && dst.is(left)) { | |
| 5128 DCHECK(!dst.is(t9)); | |
| 5129 DCHECK(!scratch.is(t9)); | |
| 5130 DCHECK(!left.is(t9)); | |
| 5131 DCHECK(!right.is(t9)); | |
| 5132 DCHECK(!overflow_dst.is(t9)); | |
| 5133 mov(t9, right); | |
| 5134 right = t9; | |
| 5135 } | |
| 5136 | |
| 5137 if (dst.is(left)) { | |
| 5138 mov(scratch, left); // Preserve left. | |
| 5139 daddu(dst, left, right); // Left is overwritten. | |
| 5140 xor_(scratch, dst, scratch); // Original left. | |
| 5141 xor_(overflow_dst, dst, right); | |
| 5142 and_(overflow_dst, overflow_dst, scratch); | |
| 5143 } else if (dst.is(right)) { | |
| 5144 mov(scratch, right); // Preserve right. | |
| 5145 daddu(dst, left, right); // Right is overwritten. | |
| 5146 xor_(scratch, dst, scratch); // Original right. | |
| 5147 xor_(overflow_dst, dst, left); | |
| 5148 and_(overflow_dst, overflow_dst, scratch); | |
| 5149 } else { | |
| 5150 daddu(dst, left, right); | |
| 5151 xor_(overflow_dst, dst, left); | |
| 5152 xor_(scratch, dst, right); | |
| 5153 and_(overflow_dst, scratch, overflow_dst); | |
| 5154 } | |
| 5155 } | |
| 5156 | |
| 5157 | |
| 5158 static inline void BranchOvfHelper(MacroAssembler* masm, Register overflow_dst, | 5025 static inline void BranchOvfHelper(MacroAssembler* masm, Register overflow_dst, |
| 5159 Label* overflow_label, | 5026 Label* overflow_label, |
| 5160 Label* no_overflow_label) { | 5027 Label* no_overflow_label) { |
| 5161 DCHECK(overflow_label || no_overflow_label); | 5028 DCHECK(overflow_label || no_overflow_label); |
| 5162 if (!overflow_label) { | 5029 if (!overflow_label) { |
| 5163 DCHECK(no_overflow_label); | 5030 DCHECK(no_overflow_label); |
| 5164 masm->Branch(no_overflow_label, ge, overflow_dst, Operand(zero_reg)); | 5031 masm->Branch(no_overflow_label, ge, overflow_dst, Operand(zero_reg)); |
| 5165 } else { | 5032 } else { |
| 5166 masm->Branch(overflow_label, lt, overflow_dst, Operand(zero_reg)); | 5033 masm->Branch(overflow_label, lt, overflow_dst, Operand(zero_reg)); |
| 5167 if (no_overflow_label) masm->Branch(no_overflow_label); | 5034 if (no_overflow_label) masm->Branch(no_overflow_label); |
| 5168 } | 5035 } |
| 5169 } | 5036 } |
| 5170 | 5037 |
| 5038 void MacroAssembler::AddBranchOvf(Register dst, Register left, |
| 5039 const Operand& right, Label* overflow_label, |
| 5040 Label* no_overflow_label, Register scratch) { |
| 5041 if (right.is_reg()) { |
| 5042 AddBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 5043 scratch); |
| 5044 } else { |
| 5045 if (kArchVariant == kMips64r6) { |
| 5046 Register right_reg = t9; |
| 5047 DCHECK(!left.is(right_reg)); |
| 5048 li(right_reg, Operand(right)); |
| 5049 AddBranchOvf(dst, left, right_reg, overflow_label, no_overflow_label); |
| 5050 } else { |
| 5051 Register overflow_dst = t9; |
| 5052 DCHECK(!dst.is(scratch)); |
| 5053 DCHECK(!dst.is(overflow_dst)); |
| 5054 DCHECK(!scratch.is(overflow_dst)); |
| 5055 DCHECK(!left.is(overflow_dst)); |
| 5056 if (dst.is(left)) { |
| 5057 mov(scratch, left); // Preserve left. |
| 5058 // Left is overwritten. |
| 5059 Addu(dst, left, static_cast<int32_t>(right.immediate())); |
| 5060 xor_(scratch, dst, scratch); // Original left. |
| 5061 // Load right since xori takes uint16 as immediate. |
| 5062 Addu(overflow_dst, zero_reg, right); |
| 5063 xor_(overflow_dst, dst, overflow_dst); |
| 5064 and_(overflow_dst, overflow_dst, scratch); |
| 5065 } else { |
| 5066 Addu(dst, left, static_cast<int32_t>(right.immediate())); |
| 5067 xor_(overflow_dst, dst, left); |
| 5068 // Load right since xori takes uint16 as immediate. |
| 5069 Addu(scratch, zero_reg, right); |
| 5070 xor_(scratch, dst, scratch); |
| 5071 and_(overflow_dst, scratch, overflow_dst); |
| 5072 } |
| 5073 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 5074 } |
| 5075 } |
| 5076 } |
| 5077 |
| 5078 void MacroAssembler::AddBranchOvf(Register dst, Register left, Register right, |
| 5079 Label* overflow_label, |
| 5080 Label* no_overflow_label, Register scratch) { |
| 5081 if (kArchVariant == kMips64r6) { |
| 5082 if (!overflow_label) { |
| 5083 DCHECK(no_overflow_label); |
| 5084 DCHECK(!dst.is(scratch)); |
| 5085 Register left_reg = left.is(dst) ? scratch : left; |
| 5086 Register right_reg = right.is(dst) ? t9 : right; |
| 5087 DCHECK(!dst.is(left_reg)); |
| 5088 DCHECK(!dst.is(right_reg)); |
| 5089 Move(left_reg, left); |
| 5090 Move(right_reg, right); |
| 5091 addu(dst, left, right); |
| 5092 bnvc(left_reg, right_reg, no_overflow_label); |
| 5093 } else { |
| 5094 bovc(left, right, overflow_label); |
| 5095 addu(dst, left, right); |
| 5096 if (no_overflow_label) bc(no_overflow_label); |
| 5097 } |
| 5098 } else { |
| 5099 Register overflow_dst = t9; |
| 5100 DCHECK(!dst.is(scratch)); |
| 5101 DCHECK(!dst.is(overflow_dst)); |
| 5102 DCHECK(!scratch.is(overflow_dst)); |
| 5103 DCHECK(!left.is(overflow_dst)); |
| 5104 DCHECK(!right.is(overflow_dst)); |
| 5105 DCHECK(!left.is(scratch)); |
| 5106 DCHECK(!right.is(scratch)); |
| 5107 |
| 5108 if (left.is(right) && dst.is(left)) { |
| 5109 mov(overflow_dst, right); |
| 5110 right = overflow_dst; |
| 5111 } |
| 5112 |
| 5113 if (dst.is(left)) { |
| 5114 mov(scratch, left); // Preserve left. |
| 5115 addu(dst, left, right); // Left is overwritten. |
| 5116 xor_(scratch, dst, scratch); // Original left. |
| 5117 xor_(overflow_dst, dst, right); |
| 5118 and_(overflow_dst, overflow_dst, scratch); |
| 5119 } else if (dst.is(right)) { |
| 5120 mov(scratch, right); // Preserve right. |
| 5121 addu(dst, left, right); // Right is overwritten. |
| 5122 xor_(scratch, dst, scratch); // Original right. |
| 5123 xor_(overflow_dst, dst, left); |
| 5124 and_(overflow_dst, overflow_dst, scratch); |
| 5125 } else { |
| 5126 addu(dst, left, right); |
| 5127 xor_(overflow_dst, dst, left); |
| 5128 xor_(scratch, dst, right); |
| 5129 and_(overflow_dst, scratch, overflow_dst); |
| 5130 } |
| 5131 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 5132 } |
| 5133 } |
| 5134 |
| 5135 void MacroAssembler::SubBranchOvf(Register dst, Register left, |
| 5136 const Operand& right, Label* overflow_label, |
| 5137 Label* no_overflow_label, Register scratch) { |
| 5138 DCHECK(overflow_label || no_overflow_label); |
| 5139 if (right.is_reg()) { |
| 5140 SubBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 5141 scratch); |
| 5142 } else { |
| 5143 Register overflow_dst = t9; |
| 5144 DCHECK(!dst.is(scratch)); |
| 5145 DCHECK(!dst.is(overflow_dst)); |
| 5146 DCHECK(!scratch.is(overflow_dst)); |
| 5147 DCHECK(!left.is(overflow_dst)); |
| 5148 DCHECK(!left.is(scratch)); |
| 5149 if (dst.is(left)) { |
| 5150 mov(scratch, left); // Preserve left. |
| 5151 // Left is overwritten. |
| 5152 Subu(dst, left, static_cast<int32_t>(right.immediate())); |
| 5153 // Load right since xori takes uint16 as immediate. |
| 5154 Addu(overflow_dst, zero_reg, right); |
| 5155 xor_(overflow_dst, scratch, overflow_dst); // scratch is original left. |
| 5156 xor_(scratch, dst, scratch); // scratch is original left. |
| 5157 and_(overflow_dst, scratch, overflow_dst); |
| 5158 } else { |
| 5159 Subu(dst, left, right); |
| 5160 xor_(overflow_dst, dst, left); |
| 5161 // Load right since xori takes uint16 as immediate. |
| 5162 Addu(scratch, zero_reg, right); |
| 5163 xor_(scratch, left, scratch); |
| 5164 and_(overflow_dst, scratch, overflow_dst); |
| 5165 } |
| 5166 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 5167 } |
| 5168 } |
| 5169 |
| 5170 void MacroAssembler::SubBranchOvf(Register dst, Register left, Register right, |
| 5171 Label* overflow_label, |
| 5172 Label* no_overflow_label, Register scratch) { |
| 5173 DCHECK(overflow_label || no_overflow_label); |
| 5174 Register overflow_dst = t9; |
| 5175 DCHECK(!dst.is(scratch)); |
| 5176 DCHECK(!dst.is(overflow_dst)); |
| 5177 DCHECK(!scratch.is(overflow_dst)); |
| 5178 DCHECK(!overflow_dst.is(left)); |
| 5179 DCHECK(!overflow_dst.is(right)); |
| 5180 DCHECK(!scratch.is(left)); |
| 5181 DCHECK(!scratch.is(right)); |
| 5182 |
| 5183 // This happens with some crankshaft code. Since Subu works fine if |
| 5184 // left == right, let's not make that restriction here. |
| 5185 if (left.is(right)) { |
| 5186 mov(dst, zero_reg); |
| 5187 if (no_overflow_label) { |
| 5188 Branch(no_overflow_label); |
| 5189 } |
| 5190 } |
| 5191 |
| 5192 if (dst.is(left)) { |
| 5193 mov(scratch, left); // Preserve left. |
| 5194 subu(dst, left, right); // Left is overwritten. |
| 5195 xor_(overflow_dst, dst, scratch); // scratch is original left. |
| 5196 xor_(scratch, scratch, right); // scratch is original left. |
| 5197 and_(overflow_dst, scratch, overflow_dst); |
| 5198 } else if (dst.is(right)) { |
| 5199 mov(scratch, right); // Preserve right. |
| 5200 subu(dst, left, right); // Right is overwritten. |
| 5201 xor_(overflow_dst, dst, left); |
| 5202 xor_(scratch, left, scratch); // Original right. |
| 5203 and_(overflow_dst, scratch, overflow_dst); |
| 5204 } else { |
| 5205 subu(dst, left, right); |
| 5206 xor_(overflow_dst, dst, left); |
| 5207 xor_(scratch, left, right); |
| 5208 and_(overflow_dst, scratch, overflow_dst); |
| 5209 } |
| 5210 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 5211 } |
| 5171 | 5212 |
| 5172 void MacroAssembler::DaddBranchOvf(Register dst, Register left, | 5213 void MacroAssembler::DaddBranchOvf(Register dst, Register left, |
| 5173 const Operand& right, Label* overflow_label, | 5214 const Operand& right, Label* overflow_label, |
| 5174 Label* no_overflow_label, Register scratch) { | 5215 Label* no_overflow_label, Register scratch) { |
| 5175 if (right.is_reg()) { | 5216 if (right.is_reg()) { |
| 5176 DaddBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, | 5217 DaddBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 5177 scratch); | 5218 scratch); |
| 5178 } else { | 5219 } else { |
| 5179 Register overflow_dst = t9; | 5220 Register overflow_dst = t9; |
| 5180 DCHECK(!dst.is(scratch)); | 5221 DCHECK(!dst.is(scratch)); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5231 } else { | 5272 } else { |
| 5232 daddu(dst, left, right); | 5273 daddu(dst, left, right); |
| 5233 xor_(overflow_dst, dst, left); | 5274 xor_(overflow_dst, dst, left); |
| 5234 xor_(scratch, dst, right); | 5275 xor_(scratch, dst, right); |
| 5235 and_(overflow_dst, scratch, overflow_dst); | 5276 and_(overflow_dst, scratch, overflow_dst); |
| 5236 } | 5277 } |
| 5237 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); | 5278 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
| 5238 } | 5279 } |
| 5239 | 5280 |
| 5240 | 5281 |
| 5241 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, | |
| 5242 const Operand& right, | |
| 5243 Register overflow_dst, | |
| 5244 Register scratch) { | |
| 5245 if (right.is_reg()) { | |
| 5246 SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | |
| 5247 } else { | |
| 5248 if (dst.is(left)) { | |
| 5249 li(t9, right); // Load right. | |
| 5250 mov(scratch, left); // Preserve left. | |
| 5251 Subu(dst, left, t9); // Left is overwritten. | |
| 5252 xor_(overflow_dst, dst, scratch); // scratch is original left. | |
| 5253 xor_(scratch, scratch, t9); // scratch is original left. | |
| 5254 and_(overflow_dst, scratch, overflow_dst); | |
| 5255 } else { | |
| 5256 li(t9, right); | |
| 5257 subu(dst, left, t9); | |
| 5258 xor_(overflow_dst, dst, left); | |
| 5259 xor_(scratch, left, t9); | |
| 5260 and_(overflow_dst, scratch, overflow_dst); | |
| 5261 } | |
| 5262 } | |
| 5263 } | |
| 5264 | |
| 5265 | |
| 5266 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, | |
| 5267 Register right, | |
| 5268 Register overflow_dst, | |
| 5269 Register scratch) { | |
| 5270 DCHECK(!dst.is(overflow_dst)); | |
| 5271 DCHECK(!dst.is(scratch)); | |
| 5272 DCHECK(!overflow_dst.is(scratch)); | |
| 5273 DCHECK(!overflow_dst.is(left)); | |
| 5274 DCHECK(!overflow_dst.is(right)); | |
| 5275 DCHECK(!scratch.is(left)); | |
| 5276 DCHECK(!scratch.is(right)); | |
| 5277 | |
| 5278 // This happens with some crankshaft code. Since Subu works fine if | |
| 5279 // left == right, let's not make that restriction here. | |
| 5280 if (left.is(right)) { | |
| 5281 mov(dst, zero_reg); | |
| 5282 mov(overflow_dst, zero_reg); | |
| 5283 return; | |
| 5284 } | |
| 5285 | |
| 5286 if (dst.is(left)) { | |
| 5287 mov(scratch, left); // Preserve left. | |
| 5288 subu(dst, left, right); // Left is overwritten. | |
| 5289 xor_(overflow_dst, dst, scratch); // scratch is original left. | |
| 5290 xor_(scratch, scratch, right); // scratch is original left. | |
| 5291 and_(overflow_dst, scratch, overflow_dst); | |
| 5292 } else if (dst.is(right)) { | |
| 5293 mov(scratch, right); // Preserve right. | |
| 5294 subu(dst, left, right); // Right is overwritten. | |
| 5295 xor_(overflow_dst, dst, left); | |
| 5296 xor_(scratch, left, scratch); // Original right. | |
| 5297 and_(overflow_dst, scratch, overflow_dst); | |
| 5298 } else { | |
| 5299 subu(dst, left, right); | |
| 5300 xor_(overflow_dst, dst, left); | |
| 5301 xor_(scratch, left, right); | |
| 5302 and_(overflow_dst, scratch, overflow_dst); | |
| 5303 } | |
| 5304 } | |
| 5305 | |
| 5306 | |
| 5307 void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left, | |
| 5308 const Operand& right, | |
| 5309 Register overflow_dst, | |
| 5310 Register scratch) { | |
| 5311 if (right.is_reg()) { | |
| 5312 DsubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | |
| 5313 } else { | |
| 5314 if (dst.is(left)) { | |
| 5315 li(t9, right); // Load right. | |
| 5316 mov(scratch, left); // Preserve left. | |
| 5317 dsubu(dst, left, t9); // Left is overwritten. | |
| 5318 xor_(overflow_dst, dst, scratch); // scratch is original left. | |
| 5319 xor_(scratch, scratch, t9); // scratch is original left. | |
| 5320 and_(overflow_dst, scratch, overflow_dst); | |
| 5321 } else { | |
| 5322 li(t9, right); | |
| 5323 dsubu(dst, left, t9); | |
| 5324 xor_(overflow_dst, dst, left); | |
| 5325 xor_(scratch, left, t9); | |
| 5326 and_(overflow_dst, scratch, overflow_dst); | |
| 5327 } | |
| 5328 } | |
| 5329 } | |
| 5330 | |
| 5331 | |
| 5332 void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left, | |
| 5333 Register right, | |
| 5334 Register overflow_dst, | |
| 5335 Register scratch) { | |
| 5336 DCHECK(!dst.is(overflow_dst)); | |
| 5337 DCHECK(!dst.is(scratch)); | |
| 5338 DCHECK(!overflow_dst.is(scratch)); | |
| 5339 DCHECK(!overflow_dst.is(left)); | |
| 5340 DCHECK(!overflow_dst.is(right)); | |
| 5341 DCHECK(!scratch.is(left)); | |
| 5342 DCHECK(!scratch.is(right)); | |
| 5343 | |
| 5344 // This happens with some crankshaft code. Since Subu works fine if | |
| 5345 // left == right, let's not make that restriction here. | |
| 5346 if (left.is(right)) { | |
| 5347 mov(dst, zero_reg); | |
| 5348 mov(overflow_dst, zero_reg); | |
| 5349 return; | |
| 5350 } | |
| 5351 | |
| 5352 if (dst.is(left)) { | |
| 5353 mov(scratch, left); // Preserve left. | |
| 5354 dsubu(dst, left, right); // Left is overwritten. | |
| 5355 xor_(overflow_dst, dst, scratch); // scratch is original left. | |
| 5356 xor_(scratch, scratch, right); // scratch is original left. | |
| 5357 and_(overflow_dst, scratch, overflow_dst); | |
| 5358 } else if (dst.is(right)) { | |
| 5359 mov(scratch, right); // Preserve right. | |
| 5360 dsubu(dst, left, right); // Right is overwritten. | |
| 5361 xor_(overflow_dst, dst, left); | |
| 5362 xor_(scratch, left, scratch); // Original right. | |
| 5363 and_(overflow_dst, scratch, overflow_dst); | |
| 5364 } else { | |
| 5365 dsubu(dst, left, right); | |
| 5366 xor_(overflow_dst, dst, left); | |
| 5367 xor_(scratch, left, right); | |
| 5368 and_(overflow_dst, scratch, overflow_dst); | |
| 5369 } | |
| 5370 } | |
| 5371 | |
| 5372 | |
| 5373 void MacroAssembler::DsubBranchOvf(Register dst, Register left, | 5282 void MacroAssembler::DsubBranchOvf(Register dst, Register left, |
| 5374 const Operand& right, Label* overflow_label, | 5283 const Operand& right, Label* overflow_label, |
| 5375 Label* no_overflow_label, Register scratch) { | 5284 Label* no_overflow_label, Register scratch) { |
| 5376 DCHECK(overflow_label || no_overflow_label); | 5285 DCHECK(overflow_label || no_overflow_label); |
| 5377 if (right.is_reg()) { | 5286 if (right.is_reg()) { |
| 5378 DsubBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, | 5287 DsubBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 5379 scratch); | 5288 scratch); |
| 5380 } else { | 5289 } else { |
| 5381 Register overflow_dst = t9; | 5290 Register overflow_dst = t9; |
| 5382 DCHECK(!dst.is(scratch)); | 5291 DCHECK(!dst.is(scratch)); |
| (...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6783 if (mag.shift > 0) sra(result, result, mag.shift); | 6692 if (mag.shift > 0) sra(result, result, mag.shift); |
| 6784 srl(at, dividend, 31); | 6693 srl(at, dividend, 31); |
| 6785 Addu(result, result, Operand(at)); | 6694 Addu(result, result, Operand(at)); |
| 6786 } | 6695 } |
| 6787 | 6696 |
| 6788 | 6697 |
| 6789 } // namespace internal | 6698 } // namespace internal |
| 6790 } // namespace v8 | 6699 } // namespace v8 |
| 6791 | 6700 |
| 6792 #endif // V8_TARGET_ARCH_MIPS64 | 6701 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |