OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 int reg_size, int reg_count, RegList allowed) { | 214 int reg_size, int reg_count, RegList allowed) { |
215 RegList list = 0; | 215 RegList list = 0; |
216 int i = 0; | 216 int i = 0; |
217 for (unsigned n = 0; (n < kNumberOfRegisters) && (i < reg_count); n++) { | 217 for (unsigned n = 0; (n < kNumberOfRegisters) && (i < reg_count); n++) { |
218 if (((1UL << n) & allowed) != 0) { | 218 if (((1UL << n) & allowed) != 0) { |
219 // Only assign allowed registers. | 219 // Only assign allowed registers. |
220 if (r) { | 220 if (r) { |
221 r[i] = Register::Create(n, reg_size); | 221 r[i] = Register::Create(n, reg_size); |
222 } | 222 } |
223 if (x) { | 223 if (x) { |
224 x[i] = Register::Create(n, kXRegSize); | 224 x[i] = Register::Create(n, kXRegSizeInBits); |
225 } | 225 } |
226 if (w) { | 226 if (w) { |
227 w[i] = Register::Create(n, kWRegSize); | 227 w[i] = Register::Create(n, kWRegSizeInBits); |
228 } | 228 } |
229 list |= (1UL << n); | 229 list |= (1UL << n); |
230 i++; | 230 i++; |
231 } | 231 } |
232 } | 232 } |
233 // Check that we got enough registers. | 233 // Check that we got enough registers. |
234 ASSERT(CountSetBits(list, kNumberOfRegisters) == reg_count); | 234 ASSERT(CountSetBits(list, kNumberOfRegisters) == reg_count); |
235 | 235 |
236 return list; | 236 return list; |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, | 240 RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, |
241 int reg_size, int reg_count, RegList allowed) { | 241 int reg_size, int reg_count, RegList allowed) { |
242 RegList list = 0; | 242 RegList list = 0; |
243 int i = 0; | 243 int i = 0; |
244 for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { | 244 for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { |
245 if (((1UL << n) & allowed) != 0) { | 245 if (((1UL << n) & allowed) != 0) { |
246 // Only assigned allowed registers. | 246 // Only assigned allowed registers. |
247 if (v) { | 247 if (v) { |
248 v[i] = FPRegister::Create(n, reg_size); | 248 v[i] = FPRegister::Create(n, reg_size); |
249 } | 249 } |
250 if (d) { | 250 if (d) { |
251 d[i] = FPRegister::Create(n, kDRegSize); | 251 d[i] = FPRegister::Create(n, kDRegSizeInBits); |
252 } | 252 } |
253 if (s) { | 253 if (s) { |
254 s[i] = FPRegister::Create(n, kSRegSize); | 254 s[i] = FPRegister::Create(n, kSRegSizeInBits); |
255 } | 255 } |
256 list |= (1UL << n); | 256 list |= (1UL << n); |
257 i++; | 257 i++; |
258 } | 258 } |
259 } | 259 } |
260 // Check that we got enough registers. | 260 // Check that we got enough registers. |
261 ASSERT(CountSetBits(list, kNumberOfFPRegisters) == reg_count); | 261 ASSERT(CountSetBits(list, kNumberOfFPRegisters) == reg_count); |
262 | 262 |
263 return list; | 263 return list; |
264 } | 264 } |
265 | 265 |
266 | 266 |
267 void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { | 267 void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { |
268 Register first = NoReg; | 268 Register first = NoReg; |
269 for (unsigned i = 0; i < kNumberOfRegisters; i++) { | 269 for (unsigned i = 0; i < kNumberOfRegisters; i++) { |
270 if (reg_list & (1UL << i)) { | 270 if (reg_list & (1UL << i)) { |
271 Register xn = Register::Create(i, kXRegSize); | 271 Register xn = Register::Create(i, kXRegSizeInBits); |
272 // We should never write into csp here. | 272 // We should never write into csp here. |
273 ASSERT(!xn.Is(csp)); | 273 ASSERT(!xn.Is(csp)); |
274 if (!xn.IsZero()) { | 274 if (!xn.IsZero()) { |
275 if (!first.IsValid()) { | 275 if (!first.IsValid()) { |
276 // This is the first register we've hit, so construct the literal. | 276 // This is the first register we've hit, so construct the literal. |
277 __ Mov(xn, value); | 277 __ Mov(xn, value); |
278 first = xn; | 278 first = xn; |
279 } else { | 279 } else { |
280 // We've already loaded the literal, so re-use the value already | 280 // We've already loaded the literal, so re-use the value already |
281 // loaded into the first register we hit. | 281 // loaded into the first register we hit. |
282 __ Mov(xn, first); | 282 __ Mov(xn, first); |
283 } | 283 } |
284 } | 284 } |
285 } | 285 } |
286 } | 286 } |
287 } | 287 } |
288 | 288 |
289 | 289 |
290 void ClobberFP(MacroAssembler* masm, RegList reg_list, double const value) { | 290 void ClobberFP(MacroAssembler* masm, RegList reg_list, double const value) { |
291 FPRegister first = NoFPReg; | 291 FPRegister first = NoFPReg; |
292 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { | 292 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { |
293 if (reg_list & (1UL << i)) { | 293 if (reg_list & (1UL << i)) { |
294 FPRegister dn = FPRegister::Create(i, kDRegSize); | 294 FPRegister dn = FPRegister::Create(i, kDRegSizeInBits); |
295 if (!first.IsValid()) { | 295 if (!first.IsValid()) { |
296 // This is the first register we've hit, so construct the literal. | 296 // This is the first register we've hit, so construct the literal. |
297 __ Fmov(dn, value); | 297 __ Fmov(dn, value); |
298 first = dn; | 298 first = dn; |
299 } else { | 299 } else { |
300 // We've already loaded the literal, so re-use the value already loaded | 300 // We've already loaded the literal, so re-use the value already loaded |
301 // into the first register we hit. | 301 // into the first register we hit. |
302 __ Fmov(dn, first); | 302 __ Fmov(dn, first); |
303 } | 303 } |
304 } | 304 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 | 347 |
348 __ Push(xzr, dump_base, dump, tmp); | 348 __ Push(xzr, dump_base, dump, tmp); |
349 | 349 |
350 // Load the address where we will dump the state. | 350 // Load the address where we will dump the state. |
351 __ Mov(dump_base, reinterpret_cast<uint64_t>(&dump_)); | 351 __ Mov(dump_base, reinterpret_cast<uint64_t>(&dump_)); |
352 | 352 |
353 // Dump the stack pointer (csp and wcsp). | 353 // Dump the stack pointer (csp and wcsp). |
354 // The stack pointer cannot be stored directly; it needs to be moved into | 354 // The stack pointer cannot be stored directly; it needs to be moved into |
355 // another register first. Also, we pushed four X registers, so we need to | 355 // another register first. Also, we pushed four X registers, so we need to |
356 // compensate here. | 356 // compensate here. |
357 __ Add(tmp, csp, 4 * kXRegSizeInBytes); | 357 __ Add(tmp, csp, 4 * kXRegSize); |
358 __ Str(tmp, MemOperand(dump_base, sp_offset)); | 358 __ Str(tmp, MemOperand(dump_base, sp_offset)); |
359 __ Add(tmp_w, wcsp, 4 * kXRegSizeInBytes); | 359 __ Add(tmp_w, wcsp, 4 * kXRegSize); |
360 __ Str(tmp_w, MemOperand(dump_base, wsp_offset)); | 360 __ Str(tmp_w, MemOperand(dump_base, wsp_offset)); |
361 | 361 |
362 // Dump X registers. | 362 // Dump X registers. |
363 __ Add(dump, dump_base, x_offset); | 363 __ Add(dump, dump_base, x_offset); |
364 for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { | 364 for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { |
365 __ Stp(Register::XRegFromCode(i), Register::XRegFromCode(i + 1), | 365 __ Stp(Register::XRegFromCode(i), Register::XRegFromCode(i + 1), |
366 MemOperand(dump, i * kXRegSizeInBytes)); | 366 MemOperand(dump, i * kXRegSize)); |
367 } | 367 } |
368 | 368 |
369 // Dump W registers. | 369 // Dump W registers. |
370 __ Add(dump, dump_base, w_offset); | 370 __ Add(dump, dump_base, w_offset); |
371 for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { | 371 for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { |
372 __ Stp(Register::WRegFromCode(i), Register::WRegFromCode(i + 1), | 372 __ Stp(Register::WRegFromCode(i), Register::WRegFromCode(i + 1), |
373 MemOperand(dump, i * kWRegSizeInBytes)); | 373 MemOperand(dump, i * kWRegSize)); |
374 } | 374 } |
375 | 375 |
376 // Dump D registers. | 376 // Dump D registers. |
377 __ Add(dump, dump_base, d_offset); | 377 __ Add(dump, dump_base, d_offset); |
378 for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { | 378 for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { |
379 __ Stp(FPRegister::DRegFromCode(i), FPRegister::DRegFromCode(i + 1), | 379 __ Stp(FPRegister::DRegFromCode(i), FPRegister::DRegFromCode(i + 1), |
380 MemOperand(dump, i * kDRegSizeInBytes)); | 380 MemOperand(dump, i * kDRegSize)); |
381 } | 381 } |
382 | 382 |
383 // Dump S registers. | 383 // Dump S registers. |
384 __ Add(dump, dump_base, s_offset); | 384 __ Add(dump, dump_base, s_offset); |
385 for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { | 385 for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { |
386 __ Stp(FPRegister::SRegFromCode(i), FPRegister::SRegFromCode(i + 1), | 386 __ Stp(FPRegister::SRegFromCode(i), FPRegister::SRegFromCode(i + 1), |
387 MemOperand(dump, i * kSRegSizeInBytes)); | 387 MemOperand(dump, i * kSRegSize)); |
388 } | 388 } |
389 | 389 |
390 // Dump the flags. | 390 // Dump the flags. |
391 __ Mrs(tmp, NZCV); | 391 __ Mrs(tmp, NZCV); |
392 __ Str(tmp, MemOperand(dump_base, flags_offset)); | 392 __ Str(tmp, MemOperand(dump_base, flags_offset)); |
393 | 393 |
394 // To dump the values that were in tmp amd dump, we need a new scratch | 394 // To dump the values that were in tmp amd dump, we need a new scratch |
395 // register. We can use any of the already dumped registers since we can | 395 // register. We can use any of the already dumped registers since we can |
396 // easily restore them. | 396 // easily restore them. |
397 Register dump2_base = x10; | 397 Register dump2_base = x10; |
398 Register dump2 = x11; | 398 Register dump2 = x11; |
399 ASSERT(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); | 399 ASSERT(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); |
400 | 400 |
401 // Don't lose the dump_ address. | 401 // Don't lose the dump_ address. |
402 __ Mov(dump2_base, dump_base); | 402 __ Mov(dump2_base, dump_base); |
403 | 403 |
404 __ Pop(tmp, dump, dump_base, xzr); | 404 __ Pop(tmp, dump, dump_base, xzr); |
405 | 405 |
406 __ Add(dump2, dump2_base, w_offset); | 406 __ Add(dump2, dump2_base, w_offset); |
407 __ Str(dump_base_w, MemOperand(dump2, dump_base.code() * kWRegSizeInBytes)); | 407 __ Str(dump_base_w, MemOperand(dump2, dump_base.code() * kWRegSize)); |
408 __ Str(dump_w, MemOperand(dump2, dump.code() * kWRegSizeInBytes)); | 408 __ Str(dump_w, MemOperand(dump2, dump.code() * kWRegSize)); |
409 __ Str(tmp_w, MemOperand(dump2, tmp.code() * kWRegSizeInBytes)); | 409 __ Str(tmp_w, MemOperand(dump2, tmp.code() * kWRegSize)); |
410 | 410 |
411 __ Add(dump2, dump2_base, x_offset); | 411 __ Add(dump2, dump2_base, x_offset); |
412 __ Str(dump_base, MemOperand(dump2, dump_base.code() * kXRegSizeInBytes)); | 412 __ Str(dump_base, MemOperand(dump2, dump_base.code() * kXRegSize)); |
413 __ Str(dump, MemOperand(dump2, dump.code() * kXRegSizeInBytes)); | 413 __ Str(dump, MemOperand(dump2, dump.code() * kXRegSize)); |
414 __ Str(tmp, MemOperand(dump2, tmp.code() * kXRegSizeInBytes)); | 414 __ Str(tmp, MemOperand(dump2, tmp.code() * kXRegSize)); |
415 | 415 |
416 // Finally, restore dump2_base and dump2. | 416 // Finally, restore dump2_base and dump2. |
417 __ Ldr(dump2_base, MemOperand(dump2, dump2_base.code() * kXRegSizeInBytes)); | 417 __ Ldr(dump2_base, MemOperand(dump2, dump2_base.code() * kXRegSize)); |
418 __ Ldr(dump2, MemOperand(dump2, dump2.code() * kXRegSizeInBytes)); | 418 __ Ldr(dump2, MemOperand(dump2, dump2.code() * kXRegSize)); |
419 | 419 |
420 // Restore the MacroAssembler's scratch registers. | 420 // Restore the MacroAssembler's scratch registers. |
421 masm->TmpList()->set_list(old_tmp_list); | 421 masm->TmpList()->set_list(old_tmp_list); |
422 masm->FPTmpList()->set_list(old_fptmp_list); | 422 masm->FPTmpList()->set_list(old_fptmp_list); |
423 | 423 |
424 completed_ = true; | 424 completed_ = true; |
425 } | 425 } |
OLD | NEW |