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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 // This is a helper class to manage the registers associated with the stub. | 203 // This is a helper class to manage the registers associated with the stub. |
204 // The 'object' and 'address' registers must be preserved. | 204 // The 'object' and 'address' registers must be preserved. |
205 class RegisterAllocation { | 205 class RegisterAllocation { |
206 public: | 206 public: |
207 RegisterAllocation(Register object, | 207 RegisterAllocation(Register object, |
208 Register address, | 208 Register address, |
209 Register scratch) | 209 Register scratch) |
210 : object_(object), | 210 : object_(object), |
211 address_(address), | 211 address_(address), |
212 scratch0_(scratch), | 212 scratch0_(scratch), |
213 saved_regs_(kCallerSaved) { | 213 saved_regs_(kCallerSaved), |
| 214 saved_fp_regs_(kCallerSavedFP) { |
214 ASSERT(!AreAliased(scratch, object, address)); | 215 ASSERT(!AreAliased(scratch, object, address)); |
215 | 216 |
| 217 // The SaveCallerSaveRegisters method needs to save caller-saved |
| 218 // registers, but we don't bother saving MacroAssembler scratch registers. |
| 219 saved_regs_.Remove(MacroAssembler::DefaultTmpList()); |
| 220 saved_fp_regs_.Remove(MacroAssembler::DefaultFPTmpList()); |
| 221 |
216 // We would like to require more scratch registers for this stub, | 222 // We would like to require more scratch registers for this stub, |
217 // but the number of registers comes down to the ones used in | 223 // but the number of registers comes down to the ones used in |
218 // FullCodeGen::SetVar(), which is architecture independent. | 224 // FullCodeGen::SetVar(), which is architecture independent. |
219 // We allocate 2 extra scratch registers that we'll save on the stack. | 225 // We allocate 2 extra scratch registers that we'll save on the stack. |
220 CPURegList pool_available = GetValidRegistersForAllocation(); | 226 CPURegList pool_available = GetValidRegistersForAllocation(); |
221 CPURegList used_regs(object, address, scratch); | 227 CPURegList used_regs(object, address, scratch); |
222 pool_available.Remove(used_regs); | 228 pool_available.Remove(used_regs); |
223 scratch1_ = Register(pool_available.PopLowestIndex()); | 229 scratch1_ = Register(pool_available.PopLowestIndex()); |
224 scratch2_ = Register(pool_available.PopLowestIndex()); | 230 scratch2_ = Register(pool_available.PopLowestIndex()); |
225 | 231 |
226 // SaveCallerRegisters method needs to save caller saved register, however | |
227 // we don't bother saving ip0 and ip1 because they are used as scratch | |
228 // registers by the MacroAssembler. | |
229 saved_regs_.Remove(ip0); | |
230 saved_regs_.Remove(ip1); | |
231 | |
232 // The scratch registers will be restored by other means so we don't need | 232 // The scratch registers will be restored by other means so we don't need |
233 // to save them with the other caller saved registers. | 233 // to save them with the other caller saved registers. |
234 saved_regs_.Remove(scratch0_); | 234 saved_regs_.Remove(scratch0_); |
235 saved_regs_.Remove(scratch1_); | 235 saved_regs_.Remove(scratch1_); |
236 saved_regs_.Remove(scratch2_); | 236 saved_regs_.Remove(scratch2_); |
237 } | 237 } |
238 | 238 |
239 void Save(MacroAssembler* masm) { | 239 void Save(MacroAssembler* masm) { |
240 // We don't have to save scratch0_ because it was given to us as | 240 // We don't have to save scratch0_ because it was given to us as |
241 // a scratch register. | 241 // a scratch register. |
242 masm->Push(scratch1_, scratch2_); | 242 masm->Push(scratch1_, scratch2_); |
243 } | 243 } |
244 | 244 |
245 void Restore(MacroAssembler* masm) { | 245 void Restore(MacroAssembler* masm) { |
246 masm->Pop(scratch2_, scratch1_); | 246 masm->Pop(scratch2_, scratch1_); |
247 } | 247 } |
248 | 248 |
249 // If we have to call into C then we need to save and restore all caller- | 249 // If we have to call into C then we need to save and restore all caller- |
250 // saved registers that were not already preserved. | 250 // saved registers that were not already preserved. |
251 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { | 251 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { |
252 // TODO(all): This can be very expensive, and it is likely that not every | 252 // TODO(all): This can be very expensive, and it is likely that not every |
253 // register will need to be preserved. Can we improve this? | 253 // register will need to be preserved. Can we improve this? |
254 masm->PushCPURegList(saved_regs_); | 254 masm->PushCPURegList(saved_regs_); |
255 if (mode == kSaveFPRegs) { | 255 if (mode == kSaveFPRegs) { |
256 masm->PushCPURegList(kCallerSavedFP); | 256 masm->PushCPURegList(saved_fp_regs_); |
257 } | 257 } |
258 } | 258 } |
259 | 259 |
260 void RestoreCallerSaveRegisters(MacroAssembler*masm, SaveFPRegsMode mode) { | 260 void RestoreCallerSaveRegisters(MacroAssembler*masm, SaveFPRegsMode mode) { |
261 // TODO(all): This can be very expensive, and it is likely that not every | 261 // TODO(all): This can be very expensive, and it is likely that not every |
262 // register will need to be preserved. Can we improve this? | 262 // register will need to be preserved. Can we improve this? |
263 if (mode == kSaveFPRegs) { | 263 if (mode == kSaveFPRegs) { |
264 masm->PopCPURegList(kCallerSavedFP); | 264 masm->PopCPURegList(saved_fp_regs_); |
265 } | 265 } |
266 masm->PopCPURegList(saved_regs_); | 266 masm->PopCPURegList(saved_regs_); |
267 } | 267 } |
268 | 268 |
269 Register object() { return object_; } | 269 Register object() { return object_; } |
270 Register address() { return address_; } | 270 Register address() { return address_; } |
271 Register scratch0() { return scratch0_; } | 271 Register scratch0() { return scratch0_; } |
272 Register scratch1() { return scratch1_; } | 272 Register scratch1() { return scratch1_; } |
273 Register scratch2() { return scratch2_; } | 273 Register scratch2() { return scratch2_; } |
274 | 274 |
275 private: | 275 private: |
276 Register object_; | 276 Register object_; |
277 Register address_; | 277 Register address_; |
278 Register scratch0_; | 278 Register scratch0_; |
279 Register scratch1_; | 279 Register scratch1_; |
280 Register scratch2_; | 280 Register scratch2_; |
281 CPURegList saved_regs_; | 281 CPURegList saved_regs_; |
| 282 CPURegList saved_fp_regs_; |
282 | 283 |
283 // TODO(all): We should consider moving this somewhere else. | 284 // TODO(all): We should consider moving this somewhere else. |
284 static CPURegList GetValidRegistersForAllocation() { | 285 static CPURegList GetValidRegistersForAllocation() { |
285 // The list of valid registers for allocation is defined as all the | 286 // The list of valid registers for allocation is defined as all the |
286 // registers without those with a special meaning. | 287 // registers without those with a special meaning. |
287 // | 288 // |
288 // The default list excludes registers x26 to x31 because they are | 289 // The default list excludes registers x26 to x31 because they are |
289 // reserved for the following purpose: | 290 // reserved for the following purpose: |
290 // - x26 root register | 291 // - x26 root register |
291 // - x27 context pointer register | 292 // - x27 context pointer register |
292 // - x28 jssp | 293 // - x28 jssp |
293 // - x29 frame pointer | 294 // - x29 frame pointer |
294 // - x30 link register(lr) | 295 // - x30 link register(lr) |
295 // - x31 xzr/stack pointer | 296 // - x31 xzr/stack pointer |
296 CPURegList list(CPURegister::kRegister, kXRegSizeInBits, 0, 25); | 297 CPURegList list(CPURegister::kRegister, kXRegSizeInBits, 0, 25); |
297 | 298 |
298 // We also remove MacroAssembler's scratch registers. | 299 // We also remove MacroAssembler's scratch registers. |
299 list.Remove(ip0); | 300 list.Remove(MacroAssembler::DefaultTmpList()); |
300 list.Remove(ip1); | |
301 list.Remove(x8); | |
302 list.Remove(x9); | |
303 | 301 |
304 return list; | 302 return list; |
305 } | 303 } |
306 | 304 |
307 friend class RecordWriteStub; | 305 friend class RecordWriteStub; |
308 }; | 306 }; |
309 | 307 |
310 // A list of stub variants which are pregenerated. | 308 // A list of stub variants which are pregenerated. |
311 // The variants are stored in the same format as the minor key, so | 309 // The variants are stored in the same format as the minor key, so |
312 // MinorKeyFor() can be used to populate and check this list. | 310 // MinorKeyFor() can be used to populate and check this list. |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 TargetAddressStorageMode storage_mode() { return storage_mode_; } | 489 TargetAddressStorageMode storage_mode() { return storage_mode_; } |
492 | 490 |
493 private: | 491 private: |
494 TargetAddressStorageMode storage_mode_; | 492 TargetAddressStorageMode storage_mode_; |
495 }; | 493 }; |
496 | 494 |
497 | 495 |
498 } } // namespace v8::internal | 496 } } // namespace v8::internal |
499 | 497 |
500 #endif // V8_ARM64_CODE_STUBS_ARM64_H_ | 498 #endif // V8_ARM64_CODE_STUBS_ARM64_H_ |
OLD | NEW |