Changeset 230717 in webkit
- Timestamp:
- Apr 17, 2018 10:05:21 AM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r230711 r230717 1 2018-04-17 Dominik Infuehr <dinfuehr@igalia.com> 2 3 Implement setupArgumentsImpl for ARM and MIPS 4 https://bugs.webkit.org/show_bug.cgi?id=183786 5 6 Reviewed by Yusuke Suzuki. 7 8 Implement setupArgumentsImpl for ARM (hardfp and softfp) and MIPS calling convention. Added 9 numCrossSources and extraGPRArgs to ArgCollection to keep track of extra 10 registers used for 64-bit values on 32-bit architectures. numCrossSources 11 keeps track of assignments from FPR to GPR registers as happens e.g. on MIPS. 12 13 * assembler/MacroAssemblerARMv7.h: 14 (JSC::MacroAssemblerARMv7::moveDouble): 15 * assembler/MacroAssemblerMIPS.h: 16 (JSC::MacroAssemblerMIPS::moveDouble): 17 * jit/CCallHelpers.h: 18 (JSC::CCallHelpers::setupStubCrossArgs): 19 (JSC::CCallHelpers::ArgCollection::ArgCollection): 20 (JSC::CCallHelpers::ArgCollection::pushRegArg): 21 (JSC::CCallHelpers::ArgCollection::pushExtraRegArg): 22 (JSC::CCallHelpers::ArgCollection::addGPRArg): 23 (JSC::CCallHelpers::ArgCollection::addGPRExtraArg): 24 (JSC::CCallHelpers::ArgCollection::addStackArg): 25 (JSC::CCallHelpers::ArgCollection::addPoke): 26 (JSC::CCallHelpers::ArgCollection::argCount): 27 (JSC::CCallHelpers::calculatePokeOffset): 28 (JSC::CCallHelpers::pokeForArgument): 29 (JSC::CCallHelpers::stackAligned): 30 (JSC::CCallHelpers::marshallArgumentRegister): 31 (JSC::CCallHelpers::setupArgumentsImpl): 32 (JSC::CCallHelpers::pokeArgumentsAligned): 33 (JSC::CCallHelpers::std::is_integral<CURRENT_ARGUMENT_TYPE>::value): 34 (JSC::CCallHelpers::std::is_pointer<CURRENT_ARGUMENT_TYPE>::value): 35 (JSC::CCallHelpers::setupArguments): 36 * jit/FPRInfo.h: 37 (JSC::FPRInfo::toArgumentRegister): 38 1 39 2018-04-17 Saam Barati <sbarati@apple.com> 2 40 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r230592 r230717 965 965 } 966 966 967 void moveDouble(FPRegisterID src, RegisterID dest) 968 { 969 m_assembler.vmov(dest, RegisterID(dest + 1), src); 970 } 971 967 972 void moveZeroToDouble(FPRegisterID reg) 968 973 { -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
r230592 r230717 3062 3062 } 3063 3063 3064 void moveDouble(FPRegisterID src, RegisterID dest) 3065 { 3066 m_assembler.mfc1(dest, src); 3067 m_assembler.mfc1(RegisterID(dest + 1), FPRegisterID(src + 1)); 3068 } 3069 3064 3070 void moveZeroToDouble(FPRegisterID reg) 3065 3071 { -
trunk/Source/JavaScriptCore/jit/CCallHelpers.h
r230556 r230717 192 192 } 193 193 194 #if CPU(MIPS) || (CPU(ARM) && !CPU(ARM_HARDFP)) 195 template<unsigned NumCrossSources, unsigned NumberOfRegisters> 196 ALWAYS_INLINE void setupStubCrossArgs(std::array<GPRReg, NumberOfRegisters> destinations, std::array<FPRReg, NumberOfRegisters> sources) { 197 for (unsigned i = 0; i < NumCrossSources; i++) { 198 GPRReg dest = destinations[i]; 199 FPRReg source = sources[i]; 200 201 moveDouble(source, dest); 202 } 203 } 204 #endif 205 194 206 template<typename RegType> 195 207 using InfoTypeForReg = decltype(toInfoFromReg(RegType(-1))); 196 208 209 // extraGPRArgs is used to track 64-bit argument types passed in register on 32-bit architectures. 197 210 // extraPoke is used to track 64-bit argument types passed on the stack. 198 template<unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke>211 template<unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke> 199 212 struct ArgCollection { 200 213 ArgCollection() … … 204 217 fprSources.fill(InvalidFPRReg); 205 218 fprDestinations.fill(InvalidFPRReg); 206 } 207 208 template<unsigned a, unsigned b, unsigned c, unsigned d, unsigned e> 209 ArgCollection(ArgCollection<a, b, c, d, e>& other) 219 crossSources.fill(InvalidFPRReg); 220 crossDestinations.fill(InvalidGPRReg); 221 } 222 223 template<unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f, unsigned g> 224 ArgCollection(ArgCollection<a, b, c, d, e, f, g>& other) 210 225 { 211 226 gprSources = other.gprSources; … … 213 228 fprSources = other.fprSources; 214 229 fprDestinations = other.fprDestinations; 215 } 216 217 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, extraPoke> pushRegArg(GPRReg argument, GPRReg destination) 218 { 219 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, extraPoke> result(*this); 230 crossSources = other.crossSources; 231 crossDestinations = other.crossDestinations; 232 } 233 234 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> pushRegArg(GPRReg argument, GPRReg destination) 235 { 236 ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> result(*this); 220 237 221 238 result.gprSources[numGPRSources] = argument; … … 224 241 } 225 242 226 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, extraPoke> pushRegArg(FPRReg argument, FPRReg destination)227 { 228 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, extraPoke> result(*this);243 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, extraPoke> pushRegArg(FPRReg argument, FPRReg destination) 244 { 245 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, extraPoke> result(*this); 229 246 230 247 result.fprSources[numFPRSources] = argument; … … 233 250 } 234 251 235 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke> addGPRArg() 236 { 237 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke>(*this); 238 } 239 240 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke> addStackArg(GPRReg) 241 { 242 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke>(*this); 243 } 244 245 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, extraPoke> addStackArg(FPRReg) 246 { 247 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, extraPoke>(*this); 248 } 249 250 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke + 1> addPoke() 251 { 252 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke + 1>(*this); 252 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, extraPoke> pushRegArg(FPRReg argument, GPRReg destination) 253 { 254 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, extraPoke> result(*this); 255 256 result.crossSources[numCrossSources] = argument; 257 result.crossDestinations[numCrossSources] = destination; 258 return result; 259 } 260 261 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> pushExtraRegArg(GPRReg argument, GPRReg destination) 262 { 263 ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> result(*this); 264 265 result.gprSources[numGPRSources] = argument; 266 result.gprDestinations[numGPRSources] = destination; 267 return result; 268 } 269 270 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addGPRArg() 271 { 272 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this); 273 } 274 275 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> addGPRExtraArg() 276 { 277 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke>(*this); 278 } 279 280 ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addStackArg(GPRReg) 281 { 282 return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this); 283 } 284 285 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addStackArg(FPRReg) 286 { 287 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this); 288 } 289 290 ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke + 1> addPoke() 291 { 292 return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke + 1>(*this); 253 293 } 254 294 … … 257 297 unsigned argCount(FPRReg) { return numGPRArgs + numFPRArgs; } 258 298 #else 259 unsigned argCount(GPRReg) { return numGPRArgs ; }299 unsigned argCount(GPRReg) { return numGPRArgs + extraGPRArgs; } 260 300 unsigned argCount(FPRReg) { return numFPRArgs; } 261 301 #endif 262 302 303 // store GPR -> GPR assignments 263 304 std::array<GPRReg, GPRInfo::numberOfRegisters> gprSources; 264 305 std::array<GPRReg, GPRInfo::numberOfRegisters> gprDestinations; 306 307 // store FPR -> FPR assignments 265 308 std::array<FPRReg, FPRInfo::numberOfRegisters> fprSources; 266 309 std::array<FPRReg, FPRInfo::numberOfRegisters> fprDestinations; 310 311 // store FPR -> GPR assignments 312 std::array<FPRReg, GPRInfo::numberOfRegisters> crossSources; 313 std::array<GPRReg, GPRInfo::numberOfRegisters> crossDestinations; 267 314 }; 268 315 … … 283 330 } 284 331 285 template<typename ArgType> 286 ALWAYS_INLINE void pokeForArgument(ArgType arg, unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned extraPoke) 332 ALWAYS_INLINE unsigned calculatePokeOffset(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke) 287 333 { 288 334 // Clang claims that it cannot find the symbol for FPRReg/GPRReg::numberOfArgumentRegisters when they are passed directly to std::max... seems like a bug 289 335 unsigned numberOfFPArgumentRegisters = FPRInfo::numberOfArgumentRegisters; 290 336 unsigned numberOfGPArgumentRegisters = GPRInfo::numberOfArgumentRegisters; 337 338 currentGPRArgument += extraGPRArgs; 339 currentFPRArgument -= numCrossSources; 291 340 ASSERT(currentGPRArgument >= GPRInfo::numberOfArgumentRegisters || currentFPRArgument >= FPRInfo::numberOfArgumentRegisters); 292 341 … … 294 343 pokeOffset += std::max(currentGPRArgument, numberOfGPArgumentRegisters) - numberOfGPArgumentRegisters; 295 344 pokeOffset += std::max(currentFPRArgument, numberOfFPArgumentRegisters) - numberOfFPArgumentRegisters; 345 return pokeOffset; 346 } 347 348 template<typename ArgType> 349 ALWAYS_INLINE void pokeForArgument(ArgType arg, unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke) 350 { 351 unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, extraPoke); 296 352 poke(arg, pokeOffset); 353 } 354 355 ALWAYS_INLINE bool stackAligned(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke) 356 { 357 unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, extraPoke); 358 return !(pokeOffset & 1); 297 359 } 298 360 … … 311 373 312 374 // Avoid MSVC optimization time explosion associated with __forceinline in recursive templates. 313 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename RegType, typename... Args>314 ALWAYS_INLINE_EXCEPT_MSVC void marshallArgumentRegister(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, RegType arg, Args... args)375 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename RegType, typename... Args> 376 ALWAYS_INLINE_EXCEPT_MSVC void marshallArgumentRegister(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, RegType arg, Args... args) 315 377 { 316 378 using InfoType = InfoTypeForReg<RegType>; … … 327 389 } 328 390 329 pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);391 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 330 392 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg), args...); 331 393 } 332 394 333 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>334 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, FPRReg arg, Args... args)395 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 396 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args) 335 397 { 336 398 static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double"); … … 338 400 } 339 401 340 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>341 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, GPRReg arg, Args... args)402 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 403 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args) 342 404 { 343 405 marshallArgumentRegister<OperationType>(argSourceRegs, arg, args...); 344 406 } 345 407 346 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>347 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)408 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 409 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args) 348 410 { 349 411 marshallArgumentRegister<OperationType>(argSourceRegs, arg.gpr(), args...); 350 412 } 351 413 352 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>353 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, CellValue arg, Args... args)414 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 415 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue arg, Args... args) 354 416 { 355 417 marshallArgumentRegister<OperationType>(argSourceRegs, arg.gpr(), args...); … … 357 419 358 420 #else // USE(JSVALUE64) 359 360 // These functions are a hack for X86 since it has no argument gprs... 361 362 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args> 363 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, FPRReg arg, Args... args) 421 #if CPU(X86) 422 423 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 424 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args) 364 425 { 365 426 static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double"); 366 pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);427 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 367 428 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke(), args...); 368 429 } 369 430 370 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>431 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 371 432 ALWAYS_INLINE std::enable_if_t<sizeof(CURRENT_ARGUMENT_TYPE) <= 4> 372 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, GPRReg arg, Args... args)373 { 374 pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);433 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args) 434 { 435 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 375 436 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg(), args...); 376 437 } 377 438 378 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>439 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 379 440 ALWAYS_INLINE std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value> 380 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)381 { 382 pokeForArgument( arg.payloadGPR(), numGPRArgs, numFPRArgs, extraPoke);383 pokeForArgument( arg.tagGPR(), numGPRArgs, numFPRArgs, extraPoke + 1);441 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue payload, Args... args) 442 { 443 pokeForArgument(payload.gpr(), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 444 pokeForArgument(TrustedImm32(JSValue::CellTag), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1); 384 445 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke(), args...); 385 446 } 386 447 387 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>448 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 388 449 ALWAYS_INLINE std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value> 389 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, CellValuearg, Args... args)390 { 391 pokeForArgument(arg. gpr(), numGPRArgs, numFPRArgs, extraPoke);392 pokeForArgument( TrustedImm32(JSValue::CellTag), numGPRArgs, numFPRArgs, extraPoke + 1);450 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args) 451 { 452 pokeForArgument(arg.payloadGPR(), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 453 pokeForArgument(arg.tagGPR(), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1); 393 454 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke(), args...); 394 455 } 395 456 457 #elif CPU(ARM) || CPU(MIPS) 458 459 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 460 void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args) 461 { 462 static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double"); 463 464 // MIPS and ARM-hardfp pass FP arguments in FP registers. 465 #if CPU(MIPS) 466 unsigned numberOfFPArgumentRegisters = FPRInfo::numberOfArgumentRegisters; 467 unsigned currentFPArgCount = argSourceRegs.argCount(arg); 468 469 // MIPS can only use FP argument registers if it isn't preceeded by any GP argument. 470 if (currentFPArgCount < numberOfFPArgumentRegisters && !numGPRArgs) { 471 auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, FPRInfo::toArgumentRegister(currentFPArgCount)); 472 setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg(), args...); 473 return; 474 } 475 #elif CPU(ARM) && CPU(ARM_HARDFP) 476 unsigned numberOfFPArgumentRegisters = FPRInfo::numberOfArgumentRegisters; 477 unsigned currentFPArgCount = argSourceRegs.argCount(arg); 478 479 if (currentFPArgCount < numberOfFPArgumentRegisters) { 480 auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, FPRInfo::toArgumentRegister(currentFPArgCount)); 481 setupArgumentsImpl<OperationType>(updatedArgSourceRegs, args...); 482 return; 483 } 484 #endif 485 486 #if CPU(MIPS) || (CPU(ARM) && !CPU(ARM_HARDFP)) 487 // On MIPS and ARM-softfp FP arguments can be passed in GP registers. 488 unsigned numberOfGPArgumentRegisters = GPRInfo::numberOfArgumentRegisters; 489 unsigned currentGPArgCount = argSourceRegs.argCount(GPRInfo::regT0); 490 unsigned alignedGPArgCount = roundUpToMultipleOf<2>(currentGPArgCount); 491 492 if (alignedGPArgCount + 1 < numberOfGPArgumentRegisters) { 493 auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, GPRInfo::toArgumentRegister(alignedGPArgCount)); 494 495 if (alignedGPArgCount > currentGPArgCount) 496 setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg().addGPRExtraArg(), args...); 497 else 498 setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg(), args...); 499 500 return; 501 } 502 503 if (currentGPArgCount < numberOfGPArgumentRegisters) { 504 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke); 505 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRExtraArg().addStackArg(arg).addPoke(), args...); 506 return; 507 } 508 #endif 509 510 // Otherwise pass FP argument on stack. 511 if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke)) { 512 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 513 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke(), args...); 514 } else { 515 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1); 516 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke().addPoke(), args...); 517 } 518 } 519 520 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 521 std::enable_if_t<sizeof(CURRENT_ARGUMENT_TYPE) <= 4> 522 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args) 523 { 524 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; 525 unsigned currentArgCount = argSourceRegs.argCount(arg); 526 if (currentArgCount < numArgRegisters) { 527 auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, GPRInfo::toArgumentRegister(currentArgCount)); 528 setupArgumentsImpl<OperationType>(updatedArgSourceRegs, args...); 529 return; 530 } 531 532 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 533 setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg), args...); 534 } 535 536 template<typename OperationType, typename Arg1, typename Arg2, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 537 void pokeArgumentsAligned(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg1 arg1, Arg2 arg2, Args... args) 538 { 539 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; 540 unsigned currentArgCount = argSourceRegs.argCount(GPRInfo::regT0); 541 542 if (currentArgCount + 1 == numArgRegisters) { 543 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke); 544 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke + 1); 545 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRExtraArg().addGPRArg().addPoke(), args...); 546 } else if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke)) { 547 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 548 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1); 549 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke(), args...); 550 } else { 551 pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1); 552 pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 2); 553 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke().addPoke(), args...); 554 } 555 } 556 557 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 558 std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value> 559 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue payload, Args... args) 560 { 561 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; 562 unsigned currentArgCount = argSourceRegs.argCount(payload.gpr()); 563 unsigned alignedArgCount = roundUpToMultipleOf<2>(currentArgCount); 564 565 if (alignedArgCount + 1 < numArgRegisters) { 566 auto updatedArgSourceRegs = argSourceRegs.pushRegArg(payload.gpr(), GPRInfo::toArgumentRegister(alignedArgCount)); 567 568 if (alignedArgCount > currentArgCount) 569 setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg(), args...); 570 else 571 setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg(), args...); 572 573 move(TrustedImm32(JSValue::CellTag), GPRInfo::toArgumentRegister(alignedArgCount + 1)); 574 575 } else 576 pokeArgumentsAligned<OperationType>(argSourceRegs, payload.gpr(), TrustedImm32(JSValue::CellTag), args...); 577 } 578 579 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args> 580 std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value> 581 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args) 582 { 583 unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters; 584 unsigned currentArgCount = argSourceRegs.argCount(arg.tagGPR()); 585 unsigned alignedArgCount = roundUpToMultipleOf<2>(currentArgCount); 586 587 if (alignedArgCount + 1 < numArgRegisters) { 588 // JSValueRegs is passed in two 32-bit registers on these architectures. Increase both numGPRArgs and extraGPRArgs by 1. 589 // We can't just add 2 to numGPRArgs, since it is used for CURRENT_ARGUMENT_TYPE. Adding 2 would lead to a skipped argument. 590 auto updatedArgSourceRegs1 = argSourceRegs.pushRegArg(arg.payloadGPR(), GPRInfo::toArgumentRegister(alignedArgCount)); 591 auto updatedArgSourceRegs2 = updatedArgSourceRegs1.pushExtraRegArg(arg.tagGPR(), GPRInfo::toArgumentRegister(alignedArgCount + 1)); 592 593 if (alignedArgCount > currentArgCount) 594 setupArgumentsImpl<OperationType>(updatedArgSourceRegs2.addGPRExtraArg(), args...); 595 else 596 setupArgumentsImpl<OperationType>(updatedArgSourceRegs2, args...); 597 } else 598 pokeArgumentsAligned<OperationType>(argSourceRegs, arg.payloadGPR(), arg.tagGPR(), args...); 599 } 600 601 #endif // CPU(ARM) || CPU(MIPS) 396 602 #endif // USE(JSVALUE64) 397 603 398 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>604 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args> 399 605 ALWAYS_INLINE std::enable_if_t< 400 606 std::is_base_of<TrustedImm, Arg>::value 401 607 || std::is_convertible<Arg, TrustedImm>::value> // We have this since DFGSpeculativeJIT has it's own implementation of TrustedImmPtr 402 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)608 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args) 403 609 { 404 610 // Right now this only supports non-floating point immediate arguments since we never call operations with non-register values. … … 410 616 auto currentArgCount = numGPRArgs + numFPRArgs + (std::is_same<RESULT_TYPE, SlowPathReturnType>::value ? 1 : 0); 411 617 #else 412 auto currentArgCount = numGPRArgs ;618 auto currentArgCount = numGPRArgs + extraGPRArgs; 413 619 #endif 414 620 if (currentArgCount < numArgRegisters) { … … 418 624 } 419 625 420 pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);626 pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke); 421 627 setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg(), args...); 422 628 } 423 629 424 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>630 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args> 425 631 ALWAYS_INLINE std::enable_if_t< 426 632 std::is_same<CURRENT_ARGUMENT_TYPE, Arg>::value 427 633 && std::is_integral<CURRENT_ARGUMENT_TYPE>::value 428 634 && (sizeof(CURRENT_ARGUMENT_TYPE) <= 4)> 429 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)635 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args) 430 636 { 431 637 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImm32(arg), args...); 432 638 } 433 639 434 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>640 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args> 435 641 ALWAYS_INLINE std::enable_if_t< 436 642 std::is_same<CURRENT_ARGUMENT_TYPE, Arg>::value 437 643 && std::is_integral<CURRENT_ARGUMENT_TYPE>::value 438 644 && (sizeof(CURRENT_ARGUMENT_TYPE) == 8)> 439 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)645 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args) 440 646 { 441 647 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImm64(arg), args...); 442 648 } 443 649 444 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>650 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args> 445 651 ALWAYS_INLINE std::enable_if_t< 446 652 std::is_pointer<CURRENT_ARGUMENT_TYPE>::value 447 653 && ((std::is_pointer<Arg>::value && std::is_convertible<std::remove_const_t<std::remove_pointer_t<Arg>>*, CURRENT_ARGUMENT_TYPE>::value) 448 654 || std::is_same<Arg, std::nullptr_t>::value)> 449 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)655 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args) 450 656 { 451 657 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImmPtr(arg), args...); … … 453 659 454 660 // Special case DFG::RegisteredStructure because it's really annoying to deal with otherwise... 455 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>661 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args> 456 662 ALWAYS_INLINE std::enable_if_t< 457 663 std::is_same<CURRENT_ARGUMENT_TYPE, Structure*>::value 458 664 && std::is_same<Arg, DFG::RegisteredStructure>::value> 459 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)665 setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args) 460 666 { 461 667 setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImmPtr(arg.get()), args...); … … 466 672 467 673 // Base case; set up the argument registers. 468 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke>469 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs)674 template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke> 675 ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs) 470 676 { 471 677 static_assert(FunctionTraits<OperationType>::arity == numGPRArgs + numFPRArgs, "One last sanity check"); 678 #if CPU(JSVALUE64) || CPU(X86) 472 679 static_assert(FunctionTraits<OperationType>::cCallArity() == numGPRArgs + numFPRArgs + extraPoke, "Check the CCall arity"); 680 #endif 473 681 setupStubArgs<numGPRSources, GPRReg>(clampArrayToSize<numGPRSources, GPRReg>(argSourceRegs.gprDestinations), clampArrayToSize<numGPRSources, GPRReg>(argSourceRegs.gprSources)); 474 682 #if CPU(MIPS) || (CPU(ARM) && !CPU(ARM_HARDFP)) 683 setupStubCrossArgs<numCrossSources>(argSourceRegs.crossDestinations, argSourceRegs.crossSources); 684 #else 685 static_assert(!numCrossSources, "shouldn't be used on this architecture."); 686 #endif 475 687 setupStubArgs<numFPRSources, FPRReg>(clampArrayToSize<numFPRSources, FPRReg>(argSourceRegs.fprDestinations), clampArrayToSize<numFPRSources, FPRReg>(argSourceRegs.fprSources)); 476 688 } … … 487 699 static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args) + 1, "Basic sanity check"); 488 700 #endif 489 setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0 >(ArgCollection<0, 0, 0, 0, 0>(), GPRInfo::callFrameRegister, args...);701 setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0, 0, 0>(), GPRInfo::callFrameRegister, args...); 490 702 } 491 703 … … 497 709 static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args), "Basic sanity check"); 498 710 #endif 499 setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0 >(ArgCollection<0, 0, 0, 0, 0>(), args...);711 setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0, 0, 0>(), args...); 500 712 } 501 713 -
trunk/Source/JavaScriptCore/jit/FPRInfo.h
r229772 r230717 108 108 typedef FPRReg RegisterType; 109 109 static const unsigned numberOfRegisters = 6; 110 111 #if CPU(ARM_HARDFP) 112 static const unsigned numberOfArgumentRegisters = 8; 113 #else 110 114 static const unsigned numberOfArgumentRegisters = 0; 115 #endif 111 116 112 117 // Temporary registers. … … 144 149 return (unsigned)reg; 145 150 } 151 152 #if CPU(ARM_HARDFP) 153 static FPRReg toArgumentRegister(unsigned index) 154 { 155 ASSERT(index < numberOfArgumentRegisters); 156 return static_cast<FPRReg>(index); 157 } 158 #endif 146 159 147 160 static const char* debugName(FPRReg reg) … … 282 295 } 283 296 297 static FPRReg toArgumentRegister(unsigned index) 298 { 299 ASSERT(index < numberOfArgumentRegisters); 300 static const FPRReg indexForRegister[2] = { 301 argumentFPR0, argumentFPR1 302 }; 303 return indexForRegister[index]; 304 } 305 284 306 static unsigned toIndex(FPRReg reg) 285 307 {
Note: See TracChangeset
for help on using the changeset viewer.