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 |