Merge pull request #9793 from sepalani/template-mmio

MMIOHandlers: Move method definitions to MMIO.cpp
This commit is contained in:
Léo Lam 2021-06-24 02:42:52 +02:00 committed by GitHub
commit 0087eed235
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 22 deletions

View File

@ -290,6 +290,18 @@ void ReadHandler<T>::Visit(ReadHandlingMethodVisitor<T>& visitor)
m_Method->AcceptReadVisitor(visitor);
}
template <typename T>
T ReadHandler<T>::Read(u32 addr)
{
// Check if the handler has already been initialized. For real
// handlers, this will always be the case, so this branch should be
// easily predictable.
if (!m_Method)
InitializeInvalid();
return m_ReadFunc(addr);
}
template <typename T>
void ReadHandler<T>::ResetMethod(ReadHandlingMethod<T>* method)
{
@ -319,6 +331,12 @@ void ReadHandler<T>::ResetMethod(ReadHandlingMethod<T>* method)
m_ReadFunc = v.ret;
}
template <typename T>
void ReadHandler<T>::InitializeInvalid()
{
ResetMethod(InvalidRead<T>());
}
template <typename T>
WriteHandler<T>::WriteHandler()
{
@ -344,6 +362,18 @@ void WriteHandler<T>::Visit(WriteHandlingMethodVisitor<T>& visitor)
m_Method->AcceptWriteVisitor(visitor);
}
template <typename T>
void WriteHandler<T>::Write(u32 addr, T val)
{
// Check if the handler has already been initialized. For real
// handlers, this will always be the case, so this branch should be
// easily predictable.
if (!m_Method)
InitializeInvalid();
m_WriteFunc(addr, val);
}
template <typename T>
void WriteHandler<T>::ResetMethod(WriteHandlingMethod<T>* method)
{
@ -373,6 +403,12 @@ void WriteHandler<T>::ResetMethod(WriteHandlingMethod<T>* method)
m_WriteFunc = v.ret;
}
template <typename T>
void WriteHandler<T>::InitializeInvalid()
{
ResetMethod(InvalidWrite<T>());
}
// Define all the public specializations that are exported in MMIOHandlers.h.
#define MaybeExtern
MMIO_PUBLIC_SPECIALIZATIONS()

View File

@ -127,16 +127,7 @@ public:
// Entry point for read handling method visitors.
void Visit(ReadHandlingMethodVisitor<T>& visitor);
T Read(u32 addr)
{
// Check if the handler has already been initialized. For real
// handlers, this will always be the case, so this branch should be
// easily predictable.
if (!m_Method)
InitializeInvalid();
return m_ReadFunc(addr);
}
T Read(u32 addr);
// Internal method called when changing the internal method object. Its
// main role is to make sure the read function is updated at the same time.
@ -145,7 +136,7 @@ public:
private:
// Initialize this handler to an invalid handler. Done lazily to avoid
// useless initialization of thousands of unused handler objects.
void InitializeInvalid() { ResetMethod(InvalidRead<T>()); }
void InitializeInvalid();
std::unique_ptr<ReadHandlingMethod<T>> m_Method;
std::function<T(u32)> m_ReadFunc;
};
@ -163,16 +154,7 @@ public:
// Entry point for write handling method visitors.
void Visit(WriteHandlingMethodVisitor<T>& visitor);
void Write(u32 addr, T val)
{
// Check if the handler has already been initialized. For real
// handlers, this will always be the case, so this branch should be
// easily predictable.
if (!m_Method)
InitializeInvalid();
m_WriteFunc(addr, val);
}
void Write(u32 addr, T val);
// Internal method called when changing the internal method object. Its
// main role is to make sure the write function is updated at the same
@ -182,7 +164,7 @@ public:
private:
// Initialize this handler to an invalid handler. Done lazily to avoid
// useless initialization of thousands of unused handler objects.
void InitializeInvalid() { ResetMethod(InvalidWrite<T>()); }
void InitializeInvalid();
std::unique_ptr<WriteHandlingMethod<T>> m_Method;
std::function<void(u32, T)> m_WriteFunc;
};