mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-08 20:55:01 +00:00
458 lines
13 KiB
C++
458 lines
13 KiB
C++
/*
|
|
Copyright (c) 2014-2015 Intel Corporation. All Rights Reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
* 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.
|
|
* Neither the name of Intel Corporation nor the names of its
|
|
contributors may be used to endorse or promote products derived
|
|
from this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"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 THE COPYRIGHT
|
|
HOLDER 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.
|
|
*/
|
|
|
|
|
|
/*! \file
|
|
\brief Function and Variable tables used by the runtime library
|
|
*/
|
|
|
|
#ifndef OFFLOAD_TABLE_H_INCLUDED
|
|
#define OFFLOAD_TABLE_H_INCLUDED
|
|
|
|
#include "offload_util.h"
|
|
|
|
// Template representing double linked list of tables
|
|
template <typename T> class TableList {
|
|
public:
|
|
// table type
|
|
typedef T Table;
|
|
|
|
// List node
|
|
struct Node {
|
|
Table table;
|
|
Node* prev;
|
|
Node* next;
|
|
};
|
|
|
|
public:
|
|
explicit TableList(Node *node = 0) : m_head(node) {}
|
|
|
|
void add_table(Node *node) {
|
|
m_lock.lock();
|
|
if (m_head != 0) {
|
|
node->next = m_head;
|
|
m_head->prev = node;
|
|
}
|
|
m_head = node;
|
|
|
|
m_lock.unlock();
|
|
}
|
|
|
|
void remove_table(Node *node) {
|
|
if (node->next != 0) {
|
|
node->next->prev = node->prev;
|
|
}
|
|
if (node->prev != 0) {
|
|
node->prev->next = node->next;
|
|
}
|
|
if (m_head == node) {
|
|
m_head = node->next;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
Node* m_head;
|
|
mutex_t m_lock;
|
|
};
|
|
|
|
// Function lookup table.
|
|
struct FuncTable {
|
|
//! Function table entry
|
|
/*! This table contains functions created from offload regions. */
|
|
/*! Each entry consists of a pointer to the function's "key"
|
|
and the function address. */
|
|
/*! Each shared library or executable may contain one such table. */
|
|
/*! The end of the table is marked with an entry whose name field
|
|
has value -1. */
|
|
struct Entry {
|
|
const char* name; //!< Name of the function
|
|
void* func; //!< Address of the function
|
|
};
|
|
|
|
// entries
|
|
const Entry *entries;
|
|
|
|
// max name length
|
|
int64_t max_name_len;
|
|
};
|
|
|
|
// Function table
|
|
class DLL_LOCAL FuncList : public TableList<FuncTable> {
|
|
public:
|
|
explicit FuncList(Node *node = 0) : TableList<Table>(node),
|
|
m_max_name_len(-1)
|
|
{}
|
|
|
|
// add table to the list
|
|
void add_table(Node *node) {
|
|
// recalculate max function name length
|
|
m_max_name_len = -1;
|
|
|
|
// add table
|
|
TableList<Table>::add_table(node);
|
|
}
|
|
|
|
// find function address for the given name
|
|
const void* find_addr(const char *name);
|
|
|
|
// find function name for the given address
|
|
const char* find_name(const void *addr);
|
|
|
|
// max name length from all tables in the list
|
|
int64_t max_name_length(void);
|
|
|
|
// debug dump
|
|
void dump(void);
|
|
|
|
private:
|
|
// max name length within from all tables
|
|
int64_t m_max_name_len;
|
|
};
|
|
|
|
// Table entry for static variables
|
|
struct VarTable {
|
|
//! Variable table entry
|
|
/*! This table contains statically allocated variables marked with
|
|
__declspec(target(mic) or #pragma omp declare target. */
|
|
/*! Each entry consists of a pointer to the variable's "key",
|
|
the variable address and its size in bytes. */
|
|
/*! Because memory allocation is done from the host,
|
|
the MIC table does not need the size of the variable. */
|
|
/*! Padding to make the table entry size a power of 2 is necessary
|
|
to avoid "holes" between table contributions from different object
|
|
files on Windows when debug information is specified with /Zi. */
|
|
struct Entry {
|
|
const char* name; //!< Name of the variable
|
|
void* addr; //!< Address of the variable
|
|
|
|
#if HOST_LIBRARY
|
|
uint64_t size;
|
|
|
|
#ifdef TARGET_WINNT
|
|
// padding to make entry size a power of 2
|
|
uint64_t padding;
|
|
#endif // TARGET_WINNT
|
|
#endif
|
|
};
|
|
|
|
// Table terminated by an entry with name == -1
|
|
const Entry *entries;
|
|
};
|
|
|
|
// List of var tables
|
|
class DLL_LOCAL VarList : public TableList<VarTable> {
|
|
public:
|
|
VarList() : TableList<Table>()
|
|
{}
|
|
|
|
// debug dump
|
|
void dump();
|
|
|
|
public:
|
|
|
|
Node * get_head() {
|
|
return m_head;
|
|
}
|
|
|
|
public:
|
|
// Entry representation in a copy buffer
|
|
struct BufEntry {
|
|
intptr_t name;
|
|
intptr_t addr;
|
|
};
|
|
|
|
// Calculate the number of elements in the table and
|
|
// returns the size of buffer for the table
|
|
int64_t table_size(int64_t &nelems);
|
|
|
|
// Copy table contents to given buffer. It is supposed to be large
|
|
// enough to hold all elements as string table.
|
|
void table_copy(void *buf, int64_t nelems);
|
|
|
|
// Patch name offsets in a table after it's been copied to other side
|
|
static void table_patch_names(void *buf, int64_t nelems);
|
|
};
|
|
|
|
DLL_LOCAL extern FuncList __offload_entries;
|
|
DLL_LOCAL extern FuncList __offload_funcs;
|
|
DLL_LOCAL extern VarList __offload_vars;
|
|
|
|
// Section names where the lookup tables are stored
|
|
#ifdef TARGET_WINNT
|
|
#define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a"
|
|
#define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z"
|
|
|
|
#define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a"
|
|
#define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z"
|
|
|
|
#define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a"
|
|
#define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z"
|
|
|
|
#define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT"
|
|
|
|
#pragma section(OFFLOAD_CRTINIT_SECTION_START, read)
|
|
|
|
#else // TARGET_WINNT
|
|
|
|
#define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable."
|
|
#define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable."
|
|
|
|
#define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable."
|
|
#define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable."
|
|
|
|
#define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable."
|
|
#define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable."
|
|
#endif // TARGET_WINNT
|
|
|
|
#pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write)
|
|
#pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write)
|
|
|
|
#pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write)
|
|
#pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write)
|
|
|
|
#pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write)
|
|
#pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write)
|
|
|
|
|
|
// register/unregister given tables
|
|
extern "C" void __offload_register_tables(
|
|
FuncList::Node *entry_table,
|
|
FuncList::Node *func_table,
|
|
VarList::Node *var_table
|
|
);
|
|
|
|
extern "C" void __offload_unregister_tables(
|
|
FuncList::Node *entry_table,
|
|
FuncList::Node *func_table,
|
|
VarList::Node *var_table
|
|
);
|
|
|
|
|
|
#ifdef MYO_SUPPORT
|
|
|
|
#include <myotypes.h>
|
|
#include <myoimpl.h>
|
|
#include <myo.h>
|
|
|
|
#ifdef TARGET_WINNT
|
|
#define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(-1)
|
|
#else // TARGET_WINNT
|
|
#define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(0)
|
|
#endif // TARGET_WINNT
|
|
|
|
// Host and Target-side MYO shared variable table entry layout
|
|
typedef MyoiSharedVarEntry SharedTableEntry;
|
|
|
|
#if HOST_LIBRARY
|
|
|
|
// Host-side MYO function table entry layout
|
|
typedef struct {
|
|
//! Function Name
|
|
const char *funcName;
|
|
//! Function Address
|
|
void *funcAddr;
|
|
//! Local Thunk Address
|
|
void *localThunkAddr;
|
|
#ifdef TARGET_WINNT
|
|
// Dummy to pad up to 32 bytes
|
|
void *dummy;
|
|
#endif // TARGET_WINNT
|
|
} FptrTableEntry;
|
|
|
|
// Host-side MYO init routine table entry layout
|
|
typedef struct {
|
|
#ifdef TARGET_WINNT
|
|
// Dummy to pad up to 16 bytes
|
|
// Function Name
|
|
const char *funcName;
|
|
#endif // TARGET_WINNT
|
|
void (*func)(MyoArena);
|
|
} InitTableEntry;
|
|
|
|
#else // HOST_LIBRARY
|
|
|
|
// Target-side MYO function table entry layout
|
|
typedef MyoiTargetSharedFptrEntry FptrTableEntry;
|
|
|
|
// Target-side MYO init routine table entry layout
|
|
struct InitTableEntry {
|
|
void (*func)(void);
|
|
};
|
|
|
|
#endif // HOST_LIBRARY
|
|
|
|
#ifdef TARGET_WINNT
|
|
|
|
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a"
|
|
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z"
|
|
|
|
#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable$a"
|
|
#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable$z"
|
|
|
|
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a"
|
|
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z"
|
|
|
|
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a"
|
|
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z"
|
|
|
|
#else // TARGET_WINNT
|
|
|
|
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable."
|
|
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable."
|
|
|
|
#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable."
|
|
#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable."
|
|
|
|
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable."
|
|
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable."
|
|
|
|
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable."
|
|
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable."
|
|
|
|
#endif // TARGET_WINNT
|
|
|
|
#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write)
|
|
#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write)
|
|
|
|
#pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START, read, write)
|
|
#pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_END, read, write)
|
|
|
|
#pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write)
|
|
#pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write)
|
|
|
|
#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write)
|
|
#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write)
|
|
|
|
// List of MYO shared variable tables
|
|
struct MYOVarTable {
|
|
typedef SharedTableEntry Entry;
|
|
const Entry *entries;
|
|
};
|
|
|
|
class MYOVarTableList : public TableList<MYOVarTable> {
|
|
public:
|
|
MYOVarTableList() : TableList<Table>()
|
|
{}
|
|
|
|
// add table to the list
|
|
void add_table(Node *node) {
|
|
// add table
|
|
TableList<Table>::add_table(node);
|
|
}
|
|
|
|
// debug dump
|
|
void dump(void);
|
|
|
|
// check if any shared variables
|
|
bool is_empty();
|
|
|
|
// process the table contents for ordinary variables
|
|
void process();
|
|
|
|
// process the table contents for vtable objects
|
|
void process_vtable();
|
|
};
|
|
|
|
// List of MYO shared function tables
|
|
struct MYOFuncTable {
|
|
typedef FptrTableEntry Entry;
|
|
const Entry *entries;
|
|
};
|
|
|
|
class MYOFuncTableList : public TableList<MYOFuncTable> {
|
|
public:
|
|
MYOFuncTableList() : TableList<Table>()
|
|
{}
|
|
|
|
// add table to the list
|
|
void add_table(Node *node) {
|
|
// add table
|
|
TableList<Table>::add_table(node);
|
|
}
|
|
|
|
// debug dump
|
|
void dump(void);
|
|
|
|
// check if any shared functions
|
|
bool is_empty();
|
|
|
|
// process the table contents
|
|
void process();
|
|
};
|
|
|
|
// List of MYO shared variable initialization routine tables
|
|
struct MYOInitTable {
|
|
typedef InitTableEntry Entry;
|
|
const Entry *entries;
|
|
};
|
|
|
|
class MYOInitTableList : public TableList<MYOInitTable> {
|
|
public:
|
|
MYOInitTableList() : TableList<Table>()
|
|
{}
|
|
|
|
// add table to the list
|
|
void add_table(Node *node) {
|
|
// add table
|
|
TableList<Table>::add_table(node);
|
|
}
|
|
|
|
// debug dump
|
|
void dump(void);
|
|
|
|
// check if any init routines
|
|
bool is_empty();
|
|
|
|
// process the table contents
|
|
void process();
|
|
};
|
|
|
|
extern MYOVarTableList __offload_myo_var_tables;
|
|
extern MYOVarTableList __offload_myo_vtable_tables;
|
|
extern MYOFuncTableList __offload_myo_func_tables;
|
|
extern MYOInitTableList __offload_myo_init_tables;
|
|
|
|
extern "C" void __offload_myoRegisterTables1(
|
|
MYOInitTableList::Node *init_table,
|
|
MYOVarTableList::Node *shared_table,
|
|
MYOVarTableList::Node *shared_vtable,
|
|
MYOFuncTableList::Node *fptr_table
|
|
);
|
|
|
|
extern "C" void __offload_myoRemoveTables(
|
|
MYOInitTableList::Node *init_table,
|
|
MYOVarTableList::Node *shared_table,
|
|
MYOVarTableList::Node *shared_vtable,
|
|
MYOFuncTableList::Node *fptr_table
|
|
);
|
|
|
|
#endif // MYO_SUPPORT
|
|
|
|
#endif // OFFLOAD_TABLE_H_INCLUDED
|