| OLD | NEW |
| 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 <assert.h> // For assert | 5 #include <assert.h> // For assert |
| 6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
| 7 | 7 |
| 8 #if V8_TARGET_ARCH_S390 | 8 #if V8_TARGET_ARCH_S390 |
| 9 | 9 |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 LoadRR(dst, src); | 198 LoadRR(dst, src); |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 | 201 |
| 202 void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) { | 202 void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) { |
| 203 if (!dst.is(src)) { | 203 if (!dst.is(src)) { |
| 204 ldr(dst, src); | 204 ldr(dst, src); |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 | 207 |
| 208 void MacroAssembler::InsertDoubleLow(DoubleRegister dst, Register src) { | |
| 209 StoreDouble(dst, MemOperand(sp, -kDoubleSize)); | |
| 210 #if V8_TARGET_LITTLE_ENDIAN | |
| 211 StoreW(src, MemOperand(sp, -kDoubleSize)); | |
| 212 #else | |
| 213 StoreW(src, MemOperand(sp, -kDoubleSize / 2)); | |
| 214 #endif | |
| 215 ldy(dst, MemOperand(sp, -kDoubleSize)); | |
| 216 } | |
| 217 | |
| 218 void MacroAssembler::InsertDoubleHigh(DoubleRegister dst, Register src) { | |
| 219 StoreDouble(dst, MemOperand(sp, -kDoubleSize)); | |
| 220 #if V8_TARGET_LITTLE_ENDIAN | |
| 221 StoreW(src, MemOperand(sp, -kDoubleSize / 2)); | |
| 222 #else | |
| 223 StoreW(src, MemOperand(sp, -kDoubleSize)); | |
| 224 #endif | |
| 225 ldy(dst, MemOperand(sp, -kDoubleSize)); | |
| 226 } | |
| 227 | |
| 228 void MacroAssembler::MultiPush(RegList regs, Register location) { | 208 void MacroAssembler::MultiPush(RegList regs, Register location) { |
| 229 int16_t num_to_push = NumberOfBitsSet(regs); | 209 int16_t num_to_push = NumberOfBitsSet(regs); |
| 230 int16_t stack_offset = num_to_push * kPointerSize; | 210 int16_t stack_offset = num_to_push * kPointerSize; |
| 231 | 211 |
| 232 SubP(location, location, Operand(stack_offset)); | 212 SubP(location, location, Operand(stack_offset)); |
| 233 for (int16_t i = Register::kNumRegisters - 1; i >= 0; i--) { | 213 for (int16_t i = Register::kNumRegisters - 1; i >= 0; i--) { |
| 234 if ((regs & (1 << i)) != 0) { | 214 if ((regs & (1 << i)) != 0) { |
| 235 stack_offset -= kPointerSize; | 215 stack_offset -= kPointerSize; |
| 236 StoreP(ToRegister(i), MemOperand(location, stack_offset)); | 216 StoreP(ToRegister(i), MemOperand(location, stack_offset)); |
| 237 } | 217 } |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 lay(sp, MemOperand(sp, -stack_space * kPointerSize)); | 1086 lay(sp, MemOperand(sp, -stack_space * kPointerSize)); |
| 1107 | 1087 |
| 1108 // Allocate and align the frame preparing for calling the runtime | 1088 // Allocate and align the frame preparing for calling the runtime |
| 1109 // function. | 1089 // function. |
| 1110 const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); | 1090 const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); |
| 1111 if (frame_alignment > 0) { | 1091 if (frame_alignment > 0) { |
| 1112 DCHECK(frame_alignment == 8); | 1092 DCHECK(frame_alignment == 8); |
| 1113 ClearRightImm(sp, sp, Operand(3)); // equivalent to &= -8 | 1093 ClearRightImm(sp, sp, Operand(3)); // equivalent to &= -8 |
| 1114 } | 1094 } |
| 1115 | 1095 |
| 1116 StoreP(MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize), | |
| 1117 Operand::Zero(), r0); | |
| 1118 lay(sp, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize)); | 1096 lay(sp, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize)); |
| 1097 StoreP(MemOperand(sp), Operand::Zero(), r0); |
| 1119 // Set the exit frame sp value to point just before the return address | 1098 // Set the exit frame sp value to point just before the return address |
| 1120 // location. | 1099 // location. |
| 1121 lay(r1, MemOperand(sp, kStackFrameSPSlot * kPointerSize)); | 1100 lay(r1, MemOperand(sp, kStackFrameSPSlot * kPointerSize)); |
| 1122 StoreP(r1, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 1101 StoreP(r1, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| 1123 } | 1102 } |
| 1124 | 1103 |
| 1125 void MacroAssembler::InitializeNewString(Register string, Register length, | 1104 void MacroAssembler::InitializeNewString(Register string, Register length, |
| 1126 Heap::RootListIndex map_index, | 1105 Heap::RootListIndex map_index, |
| 1127 Register scratch1, Register scratch2) { | 1106 Register scratch1, Register scratch2) { |
| 1128 SmiTag(scratch1, length); | 1107 SmiTag(scratch1, length); |
| (...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2325 CmpP(scratch1, Operand::Zero()); | 2304 CmpP(scratch1, Operand::Zero()); |
| 2326 bne(&done, Label::kNear); | 2305 bne(&done, Label::kNear); |
| 2327 | 2306 |
| 2328 srlg(scratch1, scratch1, Operand(32)); | 2307 srlg(scratch1, scratch1, Operand(32)); |
| 2329 CmpP(scratch1, Operand(HeapNumber::kSignMask)); | 2308 CmpP(scratch1, Operand(HeapNumber::kSignMask)); |
| 2330 bind(&done); | 2309 bind(&done); |
| 2331 #endif | 2310 #endif |
| 2332 } | 2311 } |
| 2333 | 2312 |
| 2334 void MacroAssembler::TestDoubleSign(DoubleRegister input, Register scratch) { | 2313 void MacroAssembler::TestDoubleSign(DoubleRegister input, Register scratch) { |
| 2335 stdy(input, MemOperand(sp, -kDoubleSize)); | 2314 lgdr(scratch, input); |
| 2336 LoadlW(scratch, MemOperand(sp, -kDoubleSize + Register::kExponentOffset)); | 2315 cgfi(scratch, Operand::Zero()); |
| 2337 Cmp32(scratch, Operand::Zero()); | |
| 2338 } | 2316 } |
| 2339 | 2317 |
| 2340 void MacroAssembler::TestHeapNumberSign(Register input, Register scratch) { | 2318 void MacroAssembler::TestHeapNumberSign(Register input, Register scratch) { |
| 2341 LoadlW(scratch, FieldMemOperand(input, HeapNumber::kValueOffset + | 2319 LoadlW(scratch, FieldMemOperand(input, HeapNumber::kValueOffset + |
| 2342 Register::kExponentOffset)); | 2320 Register::kExponentOffset)); |
| 2343 Cmp32(scratch, Operand::Zero()); | 2321 Cmp32(scratch, Operand::Zero()); |
| 2344 } | 2322 } |
| 2345 | 2323 |
| 2346 void MacroAssembler::TryDoubleToInt32Exact(Register result, | 2324 void MacroAssembler::TryDoubleToInt32Exact(Register result, |
| 2347 DoubleRegister double_input, | 2325 DoubleRegister double_input, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2372 | 2350 |
| 2373 void MacroAssembler::TryInt32Floor(Register result, DoubleRegister double_input, | 2351 void MacroAssembler::TryInt32Floor(Register result, DoubleRegister double_input, |
| 2374 Register input_high, Register scratch, | 2352 Register input_high, Register scratch, |
| 2375 DoubleRegister double_scratch, Label* done, | 2353 DoubleRegister double_scratch, Label* done, |
| 2376 Label* exact) { | 2354 Label* exact) { |
| 2377 DCHECK(!result.is(input_high)); | 2355 DCHECK(!result.is(input_high)); |
| 2378 DCHECK(!double_input.is(double_scratch)); | 2356 DCHECK(!double_input.is(double_scratch)); |
| 2379 Label exception; | 2357 Label exception; |
| 2380 | 2358 |
| 2381 // Move high word into input_high | 2359 // Move high word into input_high |
| 2382 StoreDouble(double_input, MemOperand(sp, -kDoubleSize)); | |
| 2383 lay(sp, MemOperand(sp, -kDoubleSize)); | 2360 lay(sp, MemOperand(sp, -kDoubleSize)); |
| 2361 StoreDouble(double_input, MemOperand(sp)); |
| 2384 LoadlW(input_high, MemOperand(sp, Register::kExponentOffset)); | 2362 LoadlW(input_high, MemOperand(sp, Register::kExponentOffset)); |
| 2385 la(sp, MemOperand(sp, kDoubleSize)); | 2363 la(sp, MemOperand(sp, kDoubleSize)); |
| 2386 | 2364 |
| 2387 // Test for NaN/Inf | 2365 // Test for NaN/Inf |
| 2388 ExtractBitMask(result, input_high, HeapNumber::kExponentMask); | 2366 ExtractBitMask(result, input_high, HeapNumber::kExponentMask); |
| 2389 CmpLogicalP(result, Operand(0x7ff)); | 2367 CmpLogicalP(result, Operand(0x7ff)); |
| 2390 beq(&exception); | 2368 beq(&exception); |
| 2391 | 2369 |
| 2392 // Convert (rounding to -Inf) | 2370 // Convert (rounding to -Inf) |
| 2393 ConvertDoubleToInt64(double_input, | 2371 ConvertDoubleToInt64(double_input, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2439 | 2417 |
| 2440 void MacroAssembler::TruncateDoubleToI(Register result, | 2418 void MacroAssembler::TruncateDoubleToI(Register result, |
| 2441 DoubleRegister double_input) { | 2419 DoubleRegister double_input) { |
| 2442 Label done; | 2420 Label done; |
| 2443 | 2421 |
| 2444 TryInlineTruncateDoubleToI(result, double_input, &done); | 2422 TryInlineTruncateDoubleToI(result, double_input, &done); |
| 2445 | 2423 |
| 2446 // If we fell through then inline version didn't succeed - call stub instead. | 2424 // If we fell through then inline version didn't succeed - call stub instead. |
| 2447 push(r14); | 2425 push(r14); |
| 2448 // Put input on stack. | 2426 // Put input on stack. |
| 2449 StoreDouble(double_input, MemOperand(sp, -kDoubleSize)); | |
| 2450 lay(sp, MemOperand(sp, -kDoubleSize)); | 2427 lay(sp, MemOperand(sp, -kDoubleSize)); |
| 2428 StoreDouble(double_input, MemOperand(sp)); |
| 2451 | 2429 |
| 2452 DoubleToIStub stub(isolate(), sp, result, 0, true, true); | 2430 DoubleToIStub stub(isolate(), sp, result, 0, true, true); |
| 2453 CallStub(&stub); | 2431 CallStub(&stub); |
| 2454 | 2432 |
| 2455 la(sp, MemOperand(sp, kDoubleSize)); | 2433 la(sp, MemOperand(sp, kDoubleSize)); |
| 2456 pop(r14); | 2434 pop(r14); |
| 2457 | 2435 |
| 2458 bind(&done); | 2436 bind(&done); |
| 2459 } | 2437 } |
| 2460 | 2438 |
| (...skipping 2755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5216 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { | 5194 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { |
| 5217 srlk(dst, src, val); | 5195 srlk(dst, src, val); |
| 5218 } else { | 5196 } else { |
| 5219 lr(dst, src); | 5197 lr(dst, src); |
| 5220 srl(dst, val); | 5198 srl(dst, val); |
| 5221 } | 5199 } |
| 5222 } | 5200 } |
| 5223 | 5201 |
| 5224 // Shift right logical for 32-bit integer types. | 5202 // Shift right logical for 32-bit integer types. |
| 5225 void MacroAssembler::ShiftRight(Register dst, Register src, Register val) { | 5203 void MacroAssembler::ShiftRight(Register dst, Register src, Register val) { |
| 5226 DCHECK(!dst.is(val)); // The lr/srl path clobbers val. | |
| 5227 if (dst.is(src)) { | 5204 if (dst.is(src)) { |
| 5228 srl(dst, val); | 5205 srl(dst, val); |
| 5229 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { | 5206 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { |
| 5230 srlk(dst, src, val); | 5207 srlk(dst, src, val); |
| 5231 } else { | 5208 } else { |
| 5209 DCHECK(!dst.is(val)); // The lr/srl path clobbers val. |
| 5232 lr(dst, src); | 5210 lr(dst, src); |
| 5233 srl(dst, val); | 5211 srl(dst, val); |
| 5234 } | 5212 } |
| 5235 } | 5213 } |
| 5236 | 5214 |
| 5237 // Shift left arithmetic for 32-bit integer types. | 5215 // Shift left arithmetic for 32-bit integer types. |
| 5238 void MacroAssembler::ShiftLeftArith(Register dst, Register src, | 5216 void MacroAssembler::ShiftLeftArith(Register dst, Register src, |
| 5239 const Operand& val) { | 5217 const Operand& val) { |
| 5240 if (dst.is(src)) { | 5218 if (dst.is(src)) { |
| 5241 sla(dst, val); | 5219 sla(dst, val); |
| 5242 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { | 5220 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { |
| 5243 slak(dst, src, val); | 5221 slak(dst, src, val); |
| 5244 } else { | 5222 } else { |
| 5245 lr(dst, src); | 5223 lr(dst, src); |
| 5246 sla(dst, val); | 5224 sla(dst, val); |
| 5247 } | 5225 } |
| 5248 } | 5226 } |
| 5249 | 5227 |
| 5250 // Shift left arithmetic for 32-bit integer types. | 5228 // Shift left arithmetic for 32-bit integer types. |
| 5251 void MacroAssembler::ShiftLeftArith(Register dst, Register src, Register val) { | 5229 void MacroAssembler::ShiftLeftArith(Register dst, Register src, Register val) { |
| 5252 DCHECK(!dst.is(val)); // The lr/sla path clobbers val. | |
| 5253 if (dst.is(src)) { | 5230 if (dst.is(src)) { |
| 5254 sla(dst, val); | 5231 sla(dst, val); |
| 5255 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { | 5232 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { |
| 5256 slak(dst, src, val); | 5233 slak(dst, src, val); |
| 5257 } else { | 5234 } else { |
| 5235 DCHECK(!dst.is(val)); // The lr/sla path clobbers val. |
| 5258 lr(dst, src); | 5236 lr(dst, src); |
| 5259 sla(dst, val); | 5237 sla(dst, val); |
| 5260 } | 5238 } |
| 5261 } | 5239 } |
| 5262 | 5240 |
| 5263 // Shift right arithmetic for 32-bit integer types. | 5241 // Shift right arithmetic for 32-bit integer types. |
| 5264 void MacroAssembler::ShiftRightArith(Register dst, Register src, | 5242 void MacroAssembler::ShiftRightArith(Register dst, Register src, |
| 5265 const Operand& val) { | 5243 const Operand& val) { |
| 5266 if (dst.is(src)) { | 5244 if (dst.is(src)) { |
| 5267 sra(dst, val); | 5245 sra(dst, val); |
| 5268 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { | 5246 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { |
| 5269 srak(dst, src, val); | 5247 srak(dst, src, val); |
| 5270 } else { | 5248 } else { |
| 5271 lr(dst, src); | 5249 lr(dst, src); |
| 5272 sra(dst, val); | 5250 sra(dst, val); |
| 5273 } | 5251 } |
| 5274 } | 5252 } |
| 5275 | 5253 |
| 5276 // Shift right arithmetic for 32-bit integer types. | 5254 // Shift right arithmetic for 32-bit integer types. |
| 5277 void MacroAssembler::ShiftRightArith(Register dst, Register src, Register val) { | 5255 void MacroAssembler::ShiftRightArith(Register dst, Register src, Register val) { |
| 5278 DCHECK(!dst.is(val)); // The lr/sra path clobbers val. | |
| 5279 if (dst.is(src)) { | 5256 if (dst.is(src)) { |
| 5280 sra(dst, val); | 5257 sra(dst, val); |
| 5281 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { | 5258 } else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { |
| 5282 srak(dst, src, val); | 5259 srak(dst, src, val); |
| 5283 } else { | 5260 } else { |
| 5261 DCHECK(!dst.is(val)); // The lr/sra path clobbers val. |
| 5284 lr(dst, src); | 5262 lr(dst, src); |
| 5285 sra(dst, val); | 5263 sra(dst, val); |
| 5286 } | 5264 } |
| 5287 } | 5265 } |
| 5288 | 5266 |
| 5289 // Clear right most # of bits | 5267 // Clear right most # of bits |
| 5290 void MacroAssembler::ClearRightImm(Register dst, Register src, | 5268 void MacroAssembler::ClearRightImm(Register dst, Register src, |
| 5291 const Operand& val) { | 5269 const Operand& val) { |
| 5292 int numBitsToClear = val.imm_ % (kPointerSize * 8); | 5270 int numBitsToClear = val.imm_ % (kPointerSize * 8); |
| 5293 | 5271 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5422 } | 5400 } |
| 5423 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift)); | 5401 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift)); |
| 5424 ExtractBit(r0, dividend, 31); | 5402 ExtractBit(r0, dividend, 31); |
| 5425 AddP(result, r0); | 5403 AddP(result, r0); |
| 5426 } | 5404 } |
| 5427 | 5405 |
| 5428 } // namespace internal | 5406 } // namespace internal |
| 5429 } // namespace v8 | 5407 } // namespace v8 |
| 5430 | 5408 |
| 5431 #endif // V8_TARGET_ARCH_S390 | 5409 #endif // V8_TARGET_ARCH_S390 |
| OLD | NEW |