// Note, the float scratch regs cannot be registers that are used for parameter // passing in any ABI we use. Argregs tend to be low-numbered; register 30 // should be safe.
#ifdef JS_CODEGEN_X86 // The selection of EBX here steps gingerly around: the need for EDX // to be allocatable for multiply/divide; ECX to be allocatable for // shift/rotate; EAX (= ReturnReg) to be allocatable as the result // register; EBX not being one of the WasmTableCall registers; and // needing a temp register for load/store that has a single-byte // persona. // // The compiler assumes that RabaldrScratchI32 has a single-byte // persona. Code for 8-byte atomic operations assumes that // RabaldrScratchI32 is in fact ebx.
#ifdef JS_CODEGEN_ARM // We use our own scratch register, because the macro assembler uses // the regular scratch register(s) pretty liberally. We could // work around that in several cases but the mess does not seem // worth it yet. CallTempReg2 seems safe.
#ifdef JS_CODEGEN_LOONG64 // We use our own scratch register, because the macro assembler uses // the regular scratch register(s) pretty liberally. We could // work around that in several cases but the mess does not seem // worth it yet. CallTempReg2 seems safe.
// The strongly typed register wrappers are especially useful to distinguish // float registers from double registers, but they also clearly distinguish // 32-bit registers from 64-bit register pairs on 32-bit systems.
AnyRegister any() const { switch (tag) { case F32: return AnyRegister(f32_); case F64: return AnyRegister(f64_); #ifdef ENABLE_WASM_SIMD case V128: return AnyRegister(v128_); #endif case I32: return AnyRegister(i32_); case I64: #ifdef JS_PUNBOX64 return AnyRegister(i64_.reg); #else // The compiler is written so that this is never needed: any() is // called on arbitrary registers for asm.js but asm.js does not have // 64-bit ints. For wasm, any() is called on arbitrary registers // only on 64-bit platforms.
MOZ_CRASH("AnyReg::any() on 32-bit platform"); #endif case REF:
MOZ_CRASH("AnyReg::any() not implemented for ref types"); default:
MOZ_CRASH();
} // Work around GCC 5 analysis/warning bug.
MOZ_CRASH("AnyReg::any(): impossible case");
}
};
////////////////////////////////////////////////////////////////////////////// // // Platform-specific registers. // // All platforms must define struct SpecificRegs. All 32-bit platforms must // have an abiReturnRegI64 member in that struct.
class BaseRegAlloc { // Notes on float register allocation. // // The general rule in SpiderMonkey is that float registers can alias double // registers, but there are predicates to handle exceptions to that rule: // hasUnaliasedDouble() and hasMultiAlias(). The way aliasing actually // works is platform dependent and exposed through the aliased(n, &r) // predicate, etc. // // - hasUnaliasedDouble(): on ARM VFPv3-D32 there are double registers that // cannot be treated as float. // - hasMultiAlias(): on ARM and MIPS a double register aliases two float // registers. // // On some platforms (x86, x64, ARM64) but not all (ARM) // ScratchFloat32Register is the same as ScratchDoubleRegister. // // It's a basic invariant of the AllocatableRegisterSet that it deals // properly with aliasing of registers: if s0 or s1 are allocated then d0 is // not allocatable; if s0 and s1 are freed individually then d0 becomes // allocatable.
BaseCompiler* bc;
AllocatableGeneralRegisterSet availGPR;
AllocatableFloatRegisterSet availFPU; #ifdef DEBUG // The registers available after removing ScratchReg, HeapReg, etc.
AllocatableGeneralRegisterSet allGPR;
AllocatableFloatRegisterSet allFPU;
uint32_t scratchTaken; #endif #ifdef JS_CODEGEN_X86
AllocatableGeneralRegisterSet singleByteRegs; #endif
bool hasGPR() { return !availGPR.empty(); }
bool hasGPR64() { #ifdef JS_PUNBOX64 return !availGPR.empty(); #else if (availGPR.empty()) { returnfalse;
} Register r = allocGPR(); bool available = !availGPR.empty();
freeGPR(r); return available; #endif
}
#ifdef JS_CODEGEN_ARM // r12 is normally the ScratchRegister and r13 is always the stack pointer, // so the highest possible pair has r10 as the even-numbered register.
static constexpr uint32_t PAIR_LIMIT = 10;
bool hasGPRPair() { for (uint32_t i = 0; i <= PAIR_LIMIT; i += 2) { if (isAvailableGPR(Register::FromCode(i)) &&
isAvailableGPR(Register::FromCode(i + 1))) { returntrue;
}
} returnfalse;
}
void allocGPRPair(Register* low, Register* high) {
MOZ_ASSERT(hasGPRPair()); for (uint32_t i = 0; i <= PAIR_LIMIT; i += 2) { if (isAvailableGPR(Register::FromCode(i)) &&
isAvailableGPR(Register::FromCode(i + 1))) {
*low = Register::FromCode(i);
*high = Register::FromCode(i + 1);
allocGPR(*low);
allocGPR(*high); return;
}
}
MOZ_CRASH("No pair");
} #endif
// Use when you need a register for a short time but explicitly want to avoid // a full sync().
[[nodiscard]] inline RegPtr needTempPtr(RegPtr fallback, bool* saved); inlinevoid freeTempPtr(RegPtr r, bool saved);
// Scratch register abstractions. // // We define our own scratch registers when the platform doesn't provide what we // need. A notable use case is that we will need a private scratch register // when the platform masm uses its scratch register very frequently (eg, ARM).
class BaseScratchRegister { #ifdef DEBUG
BaseRegAlloc& ra;
BaseRegAlloc::ScratchKind kind_;
using ScratchI32 = ScratchGPR<RegI32>; using ScratchPtr = ScratchGPR<RegPtr>; using ScratchRef = ScratchGPR<RegRef>;
#ifdefined(JS_CODEGEN_X86) // ScratchEBX is a mnemonic device: For some atomic ops we really need EBX, // no other register will do. And we would normally have to allocate that // register using ScratchI32 since normally the scratch register is EBX. // But the whole point of ScratchI32 is to hide that relationship. By using // the ScratchEBX alias, we document that at that point we require the // scratch register to be EBX. using ScratchEBX = ScratchI32;
// ScratchI8 is a mnemonic device: For some ops we need a register with a // byte subregister. using ScratchI8 = ScratchI32; #endif
} // namespace wasm
} // namespace js
#endif// wasm_wasm_baseline_regdefs_h
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.