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