| 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 | 
|---|