// WebAssembly definitions
// Copyright (C) Florian Negele

// This file is part of the Eigen Compiler Suite.

// The ECS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The ECS 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.

// Under Section 7 of the GNU General Public License version 3,
// the copyright holder grants you additional permissions to use
// this file as described in the ECS Runtime Support Exception.

// You should have received a copy of the GNU General Public License
// and a copy of the ECS Runtime Support Exception along with
// the ECS.  If not, see <https://www.gnu.org/licenses/>.

#ifndef ECS_DEF_WASM_HEADER_INCLUDED
#define ECS_DEF_WASM_HEADER_INCLUDED

#include "assembly"

// values

#define VEC(n_u32) n_u32

#define NAME(b_vec_byte) b_vec_byte

// types

#define NUMTYPE_I32 BYTE (0x7F)
#define NUMTYPE_I64 BYTE (0x7E)
#define NUMTYPE_F32 BYTE (0x7D)
#define NUMTYPE_F64 BYTE (0x7C)

#define VECTYPE BYTE (0x7B)

#define REFTYPE_FUNCREF BYTE (0x70)
#define REFTYPE_EXTERNREF BYTE (0x6F)

#define VALTYPE_NUMTYPE (t_numtype) t_numtype
#define VALTYPE_VECTYPE (t_vectype) t_vectype
#define VALTYPE_REFTYPE (t_reftype) t_reftype

#define RESULTTYPE(t_vec_valtype) t_vec_valtype

#define FUNCTYPE(rt1_resulttype, rt2_resulttype) BYTE (0x60) rt1_resulttype rt2_resulttype

#define LIMITS_MIN(n_u32) BYTE (0x00) n_u32
#define LIMITS_MIN_MAX(n_u32, m_u32) BYTE (0x01) n_u32 m_u32

#define MEMTYPE(lim_limits) lim_limits

#define TABLETYPE(et_reftype, lim_limits) et_reftype lim_limits

#define GLOBALTYPE(t_valtype, m_mut) t_valtype, m_mut

#define MUT_CONST BYTE (0x00)
#define MUT_VAR BYTE (0x01)

// indices

#define TYPEIDX(x_u32) x_u32
#define FUNCIDX(x_u32) x_u32
#define TABLEIDX(x_u32) x_u32
#define MEMIDX(x_u32) x_u32
#define GLOBALIDX(x_u32) x_u32
#define ELEMIDX(x_u32) x_u32
#define DATAIDX(x_u32) x_u32
#define LOCALIDX(x_u32) x_u32
#define LABELIDX(l_32) l_u32

// instructions

#define I32(n) INSTR (i32 n)
#define I32_CONST(n) INSTR (i32.const) I32 (n)
#define U32(n) INSTR (u32 n)
#define EXPR(in_instr) in_instr

// sections

#define SECTION(n_byte, size_u32) BYTE (n_byte) size_u32

#define CUSTOMSEC(size_u32, custom) SECTION (0, size_u32) custom
#define CUSTOM(name, byte) name byte

#define TYPESEC(size_u32, vec_functype) SECTION (1, size_u32) vec_functype

#define IMPORTSEC(size_u32, vec_import) SECTION (2, size_u32) vec_import
#define IMPORT(mod_name, nm_name, d_importdesc) mod_name nm_name d_importdesc
#define IMPORTDESC_FUNC(x_funcidx) BYTE (0x00) x_funcidx
#define IMPORTDESC_TABLE(x_tableix) BYTE (0x01) x_tableix
#define IMPORTDESC_MEM(x_memidx) BYTE (0x02) memidx
#define IMPORTDESC_GLOBAL(x_globalidx) BYTE (0x03) x_globalidx

#define FUNCSEC(size_u32, vec_typeidx) SECTION (3, size_u32) vec_typeidx

#define TABLESEC(size_u32, vec_table) SECTION (4, size_u32) vec_table
#define TABLE(tt_tabletype) tt_tabletype

#define MEMSEC(size_u32, vec_mem) SECTION (5, size_u32) vec_mem

#define GLOBALSEC(size_u32, vec_global) SECTION (6, size_u32) vec_global
#define GLOBAL(gt_globaltype, e_expr) gt_globaltype e_expr

#define EXPORTSEC(size_u32, vec_export) SECTION (7, size_u32) vec_export
#define EXPORT(nm_name, d_exportdesc) nm_name d_exportdesc
#define EXPORTDESC_FUNC(x_funcidx) BYTE (0x00) x_funcidx
#define EXPORTDESC_TABLE(x_tableix) BYTE (0x01) x_tableix
#define EXPORTDESC_MEM(x_memidx) BYTE (0x02) memidx
#define EXPORTDESC_GLOBAL(x_globalidx) BYTE (0x03) x_globalidx

#define STARTSEC(size_u32, start) SECTION (8, size_u32) start
#define START(x_funcidx) x_funcidx

#define CODESEC(size_u32, vec_code) SECTION (10, size_u32) vec_code
#define CODE_(size_u32, code_func) size_u32 code_func

#define FUNC(t_vec_locals, e_expr) t_vec_locals e_expr
#define LOCALS(n_u32, t_valtype) n_u32, t_valtype

#define DATASEC(size_u32, vec_data) SECTION (11, size_u32) vec_data
#define DATA_MODE_ACTIVE_MEMORY_0(e_expr, b_vec_byte) U32 (0) e_expr b_vec_byte
#define DATA_MODE_PASSIVE(b_vec_byte) U32 (1) b_vec_byte
#define DATA_MODE_ACTIVE_MEMORY_X(x_memidx, e_expr, b_vec_byte) U32 (2) x_memidx e_expr b_vec_byte

#define DATACOUNTSEC(size_u32, u32) SECTION (12, size_u32) u32

// modules

#define MODULE(magic, version) magic version
#define MAGIC BYTE (0x00, 0x61, 0x73, 0x6D)
#define VERSION BYTE (0x01, 0x00, 0x00, 0x00)

#endif // ECS_DEF_WASM_HEADER_INCLUDED
