; Copyright 2005-2013 Intel Corporation.  All Rights Reserved.
;
; This file is part of Threading Building Blocks.
;
; Threading Building Blocks is free software; you can redistribute it
; and/or modify it under the terms of the GNU General Public License
; version 2 as published by the Free Software Foundation.
;
; Threading Building Blocks is distributed in the hope that it will be
; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Threading Building Blocks; if not, write to the Free Software
; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
;
; As a special exception, you may use this file as part of a free software
; library without restriction.  Specifically, if other files instantiate
; templates or use macros or inline functions from this file, or you compile
; this file and link it with other files to produce an executable, this
; file does not by itself cause the resulting executable to be covered by
; the GNU General Public License.  This exception does not however
; invalidate any other reasons why the executable file might be covered by
; the GNU General Public License.

#include "tbb/tbb_config.h"

// __TBB_STRING macro defined in "tbb_stddef.h". However, we cannot include "tbb_stddef.h"
// because it contains a lot of C/C++ definitions. So, we have to define __TBB_STRING here:
#define __TBB_STRING_AUX( x ) #x
#define __TBB_STRING( x ) __TBB_STRING_AUX( x )

// Eliminate difference between IA-32 and Intel 64: AWORD is a type of pointer, LANG is language
// specification for extern directive.
#ifdef ARCH_ia32
    #define AWORD dword
    #define LANG  c
#else
    #define AWORD qword
    #define LANG
#endif

#ifdef ARCH_ia32
    // These directives are required for IA32 architecture only.
    .686
    .model flat, syscall
#endif

/*
    Symbol names.
*/

// Note: masm for IA-32 does not like symbols defined as "name:" in data sections,
// so we have to define symbols with "name label type" directive instead.

fname macro sym:req
    align sizeof AWORD
    Ln_&sym& label byte
    byte "&sym&", 0
endm

.const        // Symbol names are constants.
#define __TBB_SYMBOL( sym ) fname sym
#include __TBB_STRING( __TBB_LST )

/*
    Symbol descriptors.
*/

extern LANG __tbb_internal_runtime_loader_stub : AWORD

fsymbol macro sym:req
    Ls_&sym& label AWORD
    AWORD __tbb_internal_runtime_loader_stub
    AWORD Ln_&sym&
    dword sizeof AWORD
    dword 1
endm

.data
align sizeof AWORD
public LANG __tbb_internal_runtime_loader_symbols
__tbb_internal_runtime_loader_symbols label AWORD
#define __TBB_SYMBOL( sym ) fsymbol sym
#include __TBB_STRING( __TBB_LST )
AWORD 0, 0        // Terminator of the __tbb_internal_runtime_loader_symbols array.
dword 0, 0

/*
    Generate functions.
*/

// Helper assembler macro to handle different naming conventions on IA-32 and Intel 64:
// IA-32: C++ names preserved, C names require leading underscore.
// Intel 64: All names preserved.
mangle  macro name:req
    #ifdef ARCH_ia32
        if @instr( 1, name, <?> )
            exitm @catstr( name )
        else
            exitm @catstr( <_>, name )
        endif
    #else
        exitm @catstr( name )
    #endif
endm

function macro sym:req
    mangle( sym )  proc
        jmp AWORD ptr Ls_&sym&
    mangle( sym )  endp
endm

.code
#define __TBB_SYMBOL( sym ) function sym
#include __TBB_STRING( __TBB_LST )

end

// end of file //
