blob: 82503865c4a27482495cfd6989819ab9bc1e510c [file] [log] [blame]
/*
* Copyright (C) 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <wtf/Platform.h>
#if ENABLE(YARR_JIT)
#include <JavaScriptCore/FPRInfo.h>
#include <JavaScriptCore/GPRInfo.h>
namespace JSC {
namespace Yarr {
enum class YarrRegisters { DefaultRegisters, AllocatedRegisters };
struct YarrJITDefaultRegisters {
public:
static constexpr YarrRegisters registersAssignments = YarrRegisters::DefaultRegisters;
#if CPU(ARM_THUMB2)
static constexpr GPRReg input = ARMRegisters::r0;
static constexpr GPRReg index = ARMRegisters::r1;
static constexpr GPRReg length = ARMRegisters::r2;
static constexpr GPRReg output = ARMRegisters::r3;
static constexpr GPRReg regT0 = ARMRegisters::r4;
static constexpr GPRReg regT1 = ARMRegisters::r5;
// r6 is reserved for MacroAssemblerARMv7,
// r7 is fp.
static constexpr GPRReg regT2 = ARMRegisters::r8;
// r9 is sb in EABI.
static constexpr GPRReg initialStart = ARMRegisters::r10; // r10 is SL, but no longer a special register.
static constexpr GPRReg returnRegister = ARMRegisters::r0;
static constexpr GPRReg returnRegister2 = ARMRegisters::r1;
#elif CPU(ARM64)
// Argument registers
static constexpr GPRReg input = ARM64Registers::x0;
static constexpr GPRReg index = ARM64Registers::x1;
static constexpr GPRReg length = ARM64Registers::x2;
static constexpr GPRReg output = ARM64Registers::x3;
static constexpr GPRReg matchingContext = ARM64Registers::x4;
static constexpr GPRReg freelistRegister = ARM64Registers::x13;
// Scratch registers
static constexpr GPRReg regT0 = ARM64Registers::x6;
static constexpr GPRReg regT1 = ARM64Registers::x7;
static constexpr GPRReg regT2 = ARM64Registers::x8;
static constexpr GPRReg remainingMatchCount = ARM64Registers::x9;
static constexpr GPRReg regUnicodeInputAndTrail = ARM64Registers::x10;
static constexpr GPRReg unicodeAndSubpatternIdTemp = ARM64Registers::x5;
static constexpr GPRReg initialStart = ARM64Registers::x11;
static constexpr GPRReg firstCharacterAdditionalReadSize { ARM64Registers::x12 };
static constexpr GPRReg endOfStringAddress = ARM64Registers::x15;
static constexpr GPRReg returnRegister = ARM64Registers::x0;
static constexpr GPRReg returnRegister2 = ARM64Registers::x1;
// SIMD registers for Boyer-Moore SIMD lookahead (caller-saved, safe to use)
// Pattern constants (persistent across loop iterations)
static constexpr FPRReg vectorTemp0 = ARM64Registers::q0;
static constexpr FPRReg vectorTemp1 = ARM64Registers::q1;
static constexpr FPRReg vectorTemp2 = ARM64Registers::q2;
static constexpr FPRReg vectorTemp3 = ARM64Registers::q3;
static constexpr FPRReg vectorTemp4 = ARM64Registers::q4;
static constexpr FPRReg vectorInput0 = ARM64Registers::q16;
static constexpr FPRReg vectorInput1 = ARM64Registers::q17;
static constexpr FPRReg vectorInput2 = ARM64Registers::q18;
static constexpr FPRReg vectorInput3 = ARM64Registers::q19;
static constexpr FPRReg vectorScratch0 = ARM64Registers::q20;
static constexpr FPRReg vectorScratch1 = ARM64Registers::q21;
static constexpr FPRReg vectorScratch2 = ARM64Registers::q22;
static constexpr FPRReg vectorScratch3 = ARM64Registers::q23;
#elif CPU(X86_64)
// Argument registers
static constexpr GPRReg input = X86Registers::edi;
static constexpr GPRReg index = X86Registers::esi;
static constexpr GPRReg length = X86Registers::edx;
static constexpr GPRReg output = X86Registers::ecx;
static constexpr GPRReg matchingContext = X86Registers::r8;
static constexpr GPRReg freelistRegister = InvalidGPRReg;
// Scratch registers
static constexpr GPRReg regT0 = X86Registers::eax;
static constexpr GPRReg regT1 = X86Registers::r9;
static constexpr GPRReg regT2 = X86Registers::r10;
static constexpr GPRReg initialStart = X86Registers::ebx;
static constexpr GPRReg remainingMatchCount = X86Registers::r12;
static constexpr GPRReg regUnicodeInputAndTrail = X86Registers::r13;
static constexpr GPRReg unicodeAndSubpatternIdTemp = X86Registers::r14;
static constexpr GPRReg endOfStringAddress = X86Registers::r15;
static constexpr GPRReg returnRegister = X86Registers::eax;
static constexpr GPRReg returnRegister2 = X86Registers::edx;
#elif CPU(RISCV64)
// Argument registers
static constexpr GPRReg input = RISCV64Registers::x10;
static constexpr GPRReg index = RISCV64Registers::x11;
static constexpr GPRReg length = RISCV64Registers::x12;
static constexpr GPRReg output = RISCV64Registers::x13;
static constexpr GPRReg matchingContext = RISCV64Registers::x14;
static constexpr GPRReg freelistRegister = InvalidGPRReg;
// Scratch registers
static constexpr GPRReg regT0 = RISCV64Registers::x16;
static constexpr GPRReg regT1 = RISCV64Registers::x17;
static constexpr GPRReg regT2 = RISCV64Registers::x5;
static constexpr GPRReg remainingMatchCount = RISCV64Registers::x6;
static constexpr GPRReg regUnicodeInputAndTrail = RISCV64Registers::x7;
static constexpr GPRReg unicodeAndSubpatternIdTemp = RISCV64Registers::x15;
static constexpr GPRReg initialStart = RISCV64Registers::x28;
static constexpr GPRReg endOfStringAddress = RISCV64Registers::x29;
static constexpr GPRReg returnRegister = RISCV64Registers::x10;
static constexpr GPRReg returnRegister2 = RISCV64Registers::x11;
#endif
};
#if ENABLE(YARR_JIT_REGEXP_TEST_INLINE)
class YarrJITRegisters {
public:
YarrJITRegisters() = default;
void validate()
{
#if ASSERT_ENABLED
ASSERT(input != InvalidGPRReg);
ASSERT(index != InvalidGPRReg);
ASSERT(length != InvalidGPRReg);
ASSERT(output != InvalidGPRReg);
ASSERT(returnRegister != InvalidGPRReg);
ASSERT(returnRegister2 != InvalidGPRReg);
ASSERT(regT0 != InvalidGPRReg);
ASSERT(regT1 != InvalidGPRReg);
ASSERT(noOverlap(input, index, length, output, regT0, regT1));
ASSERT(noOverlap(returnRegister, returnRegister2));
ASSERT(noOverlap(index, output, returnRegister));
#endif
}
// Argument registers
GPRReg input { InvalidGPRReg };
GPRReg index { InvalidGPRReg };
GPRReg length { InvalidGPRReg };
GPRReg output { InvalidGPRReg };
GPRReg matchingContext { InvalidGPRReg };
GPRReg freelistRegister { InvalidGPRReg };
GPRReg returnRegister { InvalidGPRReg };
GPRReg returnRegister2 { InvalidGPRReg };
// Scratch registers
GPRReg regT0 { InvalidGPRReg };
GPRReg regT1 { InvalidGPRReg };
GPRReg regT2 { InvalidGPRReg };
// DotStarEnclosure
GPRReg initialStart { InvalidGPRReg };
// Unicode character processing
GPRReg remainingMatchCount { InvalidGPRReg };
GPRReg regUnicodeInputAndTrail { InvalidGPRReg };
GPRReg unicodeAndSubpatternIdTemp { InvalidGPRReg };
GPRReg endOfStringAddress { InvalidGPRReg };
GPRReg firstCharacterAdditionalReadSize { InvalidGPRReg };
#if CPU(ARM64)
// SIMD registers for Boyer-Moore SIMD lookahead
// These are not used for inline JIT, but need to be present for template instantiation.
static constexpr FPRReg vectorTemp0 = InvalidFPRReg;
static constexpr FPRReg vectorTemp1 = InvalidFPRReg;
static constexpr FPRReg vectorTemp2 = InvalidFPRReg;
static constexpr FPRReg vectorTemp3 = InvalidFPRReg;
static constexpr FPRReg vectorTemp4 = InvalidFPRReg;
static constexpr FPRReg vectorInput0 = InvalidFPRReg;
static constexpr FPRReg vectorInput1 = InvalidFPRReg;
static constexpr FPRReg vectorInput2 = InvalidFPRReg;
static constexpr FPRReg vectorInput3 = InvalidFPRReg;
static constexpr FPRReg vectorScratch0 = InvalidFPRReg;
static constexpr FPRReg vectorScratch1 = InvalidFPRReg;
static constexpr FPRReg vectorScratch2 = InvalidFPRReg;
static constexpr FPRReg vectorScratch3 = InvalidFPRReg;
#endif
};
#endif
} } // namespace JSC::Yarr
#endif