From d63ed925a95ab17f1bcdb31981008f05674bb5dd Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Wed, 6 Dec 2017 19:33:48 +0100 Subject: [PATCH] Add unfinished TLSF as test case fwiw --- tests/compiler/declare.ts | 3 +- tests/compiler/tlsf.optimized.wast | 313 +++++++++++++++++++++ tests/compiler/tlsf.ts | 139 +++++++++ tests/compiler/tlsf.wast | 433 +++++++++++++++++++++++++++++ 4 files changed, 887 insertions(+), 1 deletion(-) create mode 100644 tests/compiler/tlsf.optimized.wast create mode 100644 tests/compiler/tlsf.ts create mode 100644 tests/compiler/tlsf.wast diff --git a/tests/compiler/declare.ts b/tests/compiler/declare.ts index f0c8f543..f74e909a 100644 --- a/tests/compiler/declare.ts +++ b/tests/compiler/declare.ts @@ -1,4 +1,5 @@ declare function external(): void; -// FIXME: "unexpected false: module function exports must be found" +// "unexpected false: module function exports must be found" +// see: https://github.com/WebAssembly/binaryen/issues/1325 export { external }; diff --git a/tests/compiler/tlsf.optimized.wast b/tests/compiler/tlsf.optimized.wast new file mode 100644 index 00000000..5f0c8b56 --- /dev/null +++ b/tests/compiler/tlsf.optimized.wast @@ -0,0 +1,313 @@ +(module + (type $ii (func (param i32) (result i32))) + (type $iiv (func (param i32 i32))) + (type $iiiv (func (param i32 i32 i32))) + (type $iiiiv (func (param i32 i32 i32 i32))) + (type $iv (func (param i32))) + (type $v (func)) + (global $tlsf/ALIGN_SIZE_LOG2 i32 (i32.const 3)) + (global $tlsf/ALIGN_SIZE (mut i32) (i32.const 0)) + (global $tlsf/BLOCK_PREV_PHYS_OFFSET i32 (i32.const 0)) + (global $tlsf/BLOCK_SIZE_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/BLOCK_NEXT_FREE_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/BLOCK_PREV_FREE_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/CONTROL_FL_BITMAP_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/FL_INDEX_MAX i32 (i32.const 30)) + (global $tlsf/SL_INDEX_COUNT_LOG2 i32 (i32.const 5)) + (global $tlsf/FL_INDEX_SHIFT (mut i32) (i32.const 0)) + (global $tlsf/FL_INDEX_COUNT (mut i32) (i32.const 0)) + (global $tlsf/SL_INDEX_COUNT (mut i32) (i32.const 0)) + (memory $0 1) + (data (i32.const 4) "\08") + (export "control_construct" (func $tlsf/control_construct)) + (export "memory" (memory $0)) + (start $start) + (func $tlsf/fls (; 0 ;) (type $ii) (param $0 i32) (result i32) + (if (result i32) + (get_local $0) + (i32.sub + (i32.const 31) + (i32.clz + (get_local $0) + ) + ) + (i32.const -1) + ) + ) + (func $tlsf/ffs (; 1 ;) (type $ii) (param $0 i32) (result i32) + (if (result i32) + (get_local $0) + (i32.ctz + (get_local $0) + ) + (i32.const -1) + ) + ) + (func $tlsf/block_set_next_free (; 2 ;) (type $iiv) (param $0 i32) (param $1 i32) + (i32.store + (i32.add + (get_local $0) + (get_global $tlsf/BLOCK_NEXT_FREE_OFFSET) + ) + (get_local $1) + ) + ) + (func $tlsf/block_set_prev_free (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32) + (i32.store + (i32.add + (get_local $0) + (get_global $tlsf/BLOCK_PREV_FREE_OFFSET) + ) + (get_local $1) + ) + ) + (func $tlsf/control_set_fl (; 4 ;) (type $iiv) (param $0 i32) (param $1 i32) + (i32.store + (i32.add + (get_local $0) + (get_global $tlsf/CONTROL_FL_BITMAP_OFFSET) + ) + (get_local $1) + ) + ) + (func $tlsf/control_set_sl (; 5 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32) + (if + (i32.ge_s + (get_local $1) + (get_global $tlsf/FL_INDEX_COUNT) + ) + (unreachable) + ) + (i32.store + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 4) + ) + ) + (get_local $2) + ) + ) + (func $tlsf/control_set_block (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (if + (i32.ge_s + (get_local $1) + (get_global $tlsf/FL_INDEX_COUNT) + ) + (unreachable) + ) + (if + (i32.ge_s + (get_local $2) + (get_global $tlsf/SL_INDEX_COUNT) + ) + (unreachable) + ) + (i32.store + (i32.add + (get_local $0) + (i32.mul + (i32.add + (i32.mul + (get_local $1) + (get_global $tlsf/SL_INDEX_COUNT) + ) + (get_local $2) + ) + (i32.const 4) + ) + ) + (get_local $3) + ) + ) + (func $tlsf/control_construct (; 7 ;) (type $iv) (param $0 i32) + (local $1 i32) + (local $2 i32) + (call $tlsf/block_set_next_free + (get_local $0) + (get_local $0) + ) + (call $tlsf/block_set_prev_free + (get_local $0) + (get_local $0) + ) + (call $tlsf/control_set_fl + (get_local $0) + (i32.const 0) + ) + (set_local $1 + (i32.const 0) + ) + (loop $continue|1.1 + (if + (i32.lt_s + (get_local $1) + (get_global $tlsf/FL_INDEX_COUNT) + ) + (block + (call $tlsf/control_set_sl + (get_local $0) + (get_local $1) + (i32.const 0) + ) + (set_local $2 + (i32.const 0) + ) + (loop $continue|1.2 + (if + (i32.lt_s + (get_local $2) + (get_global $tlsf/SL_INDEX_COUNT) + ) + (block + (call $tlsf/control_set_block + (get_local $0) + (get_local $1) + (get_local $2) + (get_local $0) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (br $continue|1.2) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (br $continue|1.1) + ) + ) + ) + ) + (func $start (; 8 ;) (type $v) + (if + (i32.ne + (call $tlsf/fls + (i32.const 0) + ) + (i32.const -1) + ) + (unreachable) + ) + (if + (call $tlsf/fls + (i32.const 1) + ) + (unreachable) + ) + (if + (i32.ne + (call $tlsf/fls + (i32.const -2147483640) + ) + (i32.const 31) + ) + (unreachable) + ) + (if + (i32.ne + (call $tlsf/fls + (i32.const 2147483647) + ) + (i32.const 30) + ) + (unreachable) + ) + (if + (i32.ne + (call $tlsf/ffs + (i32.const 0) + ) + (i32.const -1) + ) + (unreachable) + ) + (if + (call $tlsf/ffs + (i32.const 1) + ) + (unreachable) + ) + (if + (i32.ne + (call $tlsf/ffs + (i32.const -2147483648) + ) + (i32.const 31) + ) + (unreachable) + ) + (set_global $tlsf/ALIGN_SIZE + (i32.shl + (i32.const 1) + (get_global $tlsf/ALIGN_SIZE_LOG2) + ) + ) + (if + (i32.ne + (get_global $tlsf/ALIGN_SIZE) + (i32.const 8) + ) + (unreachable) + ) + (set_global $tlsf/BLOCK_SIZE_OFFSET + (i32.add + (get_global $tlsf/BLOCK_PREV_PHYS_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/BLOCK_NEXT_FREE_OFFSET + (i32.add + (get_global $tlsf/BLOCK_SIZE_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/BLOCK_PREV_FREE_OFFSET + (i32.add + (get_global $tlsf/BLOCK_NEXT_FREE_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/CONTROL_FL_BITMAP_OFFSET + (i32.add + (get_global $tlsf/BLOCK_PREV_FREE_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/FL_INDEX_SHIFT + (i32.add + (get_global $tlsf/SL_INDEX_COUNT_LOG2) + (get_global $tlsf/ALIGN_SIZE_LOG2) + ) + ) + (set_global $tlsf/FL_INDEX_COUNT + (i32.add + (i32.sub + (get_global $tlsf/FL_INDEX_MAX) + (get_global $tlsf/FL_INDEX_SHIFT) + ) + (i32.const 1) + ) + ) + (set_global $tlsf/SL_INDEX_COUNT + (i32.shl + (i32.const 1) + (get_global $tlsf/SL_INDEX_COUNT_LOG2) + ) + ) + (call $tlsf/control_construct + (i32.load + (i32.const 8) + ) + ) + ) +) diff --git a/tests/compiler/tlsf.ts b/tests/compiler/tlsf.ts new file mode 100644 index 00000000..e5fa4e16 --- /dev/null +++ b/tests/compiler/tlsf.ts @@ -0,0 +1,139 @@ +// An unfinished implementation of tlsf in low-level AssemblyScript. +// Useful as a compiler test in this state, but nothing more. +// based upon: https://github.com/mattconte/tlsf/blob/master/tlsf.c (BSD) + +/// + +/** Finds the index of the least bit set. */ +function fls(word: u32): i32 { + return !word ? -1: 31 - clz(word); +} + +assert(fls(0) == -1); +assert(fls(1) == 0); +assert(fls(0x80000008) == 31); +assert(fls(0x7FFFFFFF) == 30); + +/** Finds the index of the first bit set. */ +function ffs(word: u32): i32 { + return !word ? -1 : ctz(word); +} + +assert(ffs(0) == -1); +assert(ffs(1) == 0); +assert(ffs(0x80000000) == 31); + +// Align allocated blocks to 8 bytes so that any native type is aligned + +const ALIGN_SIZE_LOG2: i32 = 3; +const ALIGN_SIZE: i32 = 1 << ALIGN_SIZE_LOG2; + +assert(ALIGN_SIZE == 8); + +// Define bitmap constants + +const SL_INDEX_COUNT_LOG2: i32 = 5; +const FL_INDEX_MAX: i32 = 30; +const SL_INDEX_COUNT: i32 = 1 << SL_INDEX_COUNT_LOG2; +const FL_INDEX_SHIFT: i32 = SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2; +const FL_INDEX_COUNT: i32 = FL_INDEX_MAX - FL_INDEX_SHIFT + 1; +const SMALL_BLOCK_SIZE: i32 = 1 << FL_INDEX_SHIFT; + +// struct block_header_t { +// struct block_header_t* prev_phys_block; +// size_t size; +// struct block_header_t* next_free; +// struct block_header_t* prev_free; +// } + +const BLOCK_PREV_PHYS_OFFSET: usize = 0; +const BLOCK_SIZE_OFFSET: usize = BLOCK_PREV_PHYS_OFFSET + sizeof(); +const BLOCK_NEXT_FREE_OFFSET: usize = BLOCK_SIZE_OFFSET + sizeof(); +const BLOCK_PREV_FREE_OFFSET: usize = BLOCK_NEXT_FREE_OFFSET + sizeof(); + +function block_get_prev_phys_block(ptr: usize): usize { + return load(ptr + BLOCK_PREV_PHYS_OFFSET); +} + +function block_set_prev_phys_block(ptr: usize, value: usize): void { + store(ptr + BLOCK_PREV_PHYS_OFFSET, value); +} + +function block_get_size(ptr: usize): usize { + return load(ptr + BLOCK_SIZE_OFFSET); +} + +function block_set_size(ptr: usize, value: usize): void { + store(ptr + BLOCK_SIZE_OFFSET, value); +} + +function block_get_next_free(ptr: usize): usize { + return load(ptr + BLOCK_NEXT_FREE_OFFSET); +} + +function block_set_next_free(ptr: usize, value: usize): void { + store(ptr + BLOCK_NEXT_FREE_OFFSET, value); +} + +function block_get_prev_free(ptr: usize): usize { + return load(ptr + BLOCK_PREV_FREE_OFFSET); +} + +function block_set_prev_free(ptr: usize, value: usize): void { + store(ptr + BLOCK_PREV_FREE_OFFSET, value); +} + +// struct control_t { +// block_header_t block_null; +// unsigned int fl_bitmap; +// unsigned int sl_bitmap[FL_INDEX_COUNT]; +// block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; +// } + +const CONTROL_FL_BITMAP_OFFSET: usize = BLOCK_PREV_FREE_OFFSET + sizeof(); +const CONTROL_SL_BITMAP_OFFSET: usize = CONTROL_FL_BITMAP_OFFSET + sizeof(); +const CONTROL_BLOCKS_OFFSET: usize = CONTROL_SL_BITMAP_OFFSET + FL_INDEX_COUNT * sizeof(); + +function control_get_fl(ptr: usize): u32 { + return load(ptr + CONTROL_FL_BITMAP_OFFSET); +} + +function control_set_fl(ptr: usize, value: u32): void { + store(ptr + CONTROL_FL_BITMAP_OFFSET, value); +} + +function control_get_sl(ptr: usize, flIndex: usize): u32 { + assert(flIndex < FL_INDEX_COUNT); + return load(ptr + flIndex * sizeof()); +} + +function control_set_sl(ptr: usize, flIndex: usize, value: u32): void { + assert(flIndex < FL_INDEX_COUNT); + store(ptr + flIndex * sizeof(), value); +} + +function control_get_block(ptr: usize, flIndex: usize, slIndex: usize): usize { + assert(flIndex < FL_INDEX_COUNT); + assert(slIndex < SL_INDEX_COUNT); + return load(ptr + (flIndex * SL_INDEX_COUNT + slIndex) * sizeof()); +} + +function control_set_block(ptr: usize, flIndex: usize, slIndex: usize, value: usize): void { + assert(flIndex < FL_INDEX_COUNT); + assert(slIndex < SL_INDEX_COUNT); + store(ptr + (flIndex * SL_INDEX_COUNT + slIndex) * sizeof(), value); +} + +/* Clear structure and point all empty lists at the null block. */ +export function control_construct(ptr: usize): void { + block_set_next_free(ptr, ptr); + block_set_prev_free(ptr, ptr); + control_set_fl(ptr, 0); + for (let flIndex: usize = 0; flIndex < FL_INDEX_COUNT; ++flIndex) { + control_set_sl(ptr, flIndex, 0); + for (let slIndex: usize = 0; slIndex < SL_INDEX_COUNT; ++slIndex) + control_set_block(ptr, flIndex, slIndex, ptr); + } +} + +control_construct(load(8)); diff --git a/tests/compiler/tlsf.wast b/tests/compiler/tlsf.wast new file mode 100644 index 00000000..c595249f --- /dev/null +++ b/tests/compiler/tlsf.wast @@ -0,0 +1,433 @@ +(module + (type $ii (func (param i32) (result i32))) + (type $iiv (func (param i32 i32))) + (type $iiiv (func (param i32 i32 i32))) + (type $iiiiv (func (param i32 i32 i32 i32))) + (type $iv (func (param i32))) + (type $v (func)) + (global $tlsf/ALIGN_SIZE_LOG2 i32 (i32.const 3)) + (global $tlsf/ALIGN_SIZE (mut i32) (i32.const 0)) + (global $tlsf/BLOCK_PREV_PHYS_OFFSET i32 (i32.const 0)) + (global $tlsf/BLOCK_SIZE_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/BLOCK_NEXT_FREE_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/BLOCK_PREV_FREE_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/CONTROL_FL_BITMAP_OFFSET (mut i32) (i32.const 0)) + (global $tlsf/FL_INDEX_MAX i32 (i32.const 30)) + (global $tlsf/SL_INDEX_COUNT_LOG2 i32 (i32.const 5)) + (global $tlsf/FL_INDEX_SHIFT (mut i32) (i32.const 0)) + (global $tlsf/FL_INDEX_COUNT (mut i32) (i32.const 0)) + (global $tlsf/SL_INDEX_COUNT (mut i32) (i32.const 0)) + (memory $0 1) + (data (i32.const 4) "\08\00\00\00") + (export "control_construct" (func $tlsf/control_construct)) + (export "memory" (memory $0)) + (start $start) + (func $tlsf/fls (; 0 ;) (type $ii) (param $0 i32) (result i32) + (return + (if (result i32) + (i32.eqz + (get_local $0) + ) + (i32.sub + (i32.const 0) + (i32.const 1) + ) + (i32.sub + (i32.const 31) + (i32.clz + (get_local $0) + ) + ) + ) + ) + ) + (func $tlsf/ffs (; 1 ;) (type $ii) (param $0 i32) (result i32) + (return + (if (result i32) + (i32.eqz + (get_local $0) + ) + (i32.sub + (i32.const 0) + (i32.const 1) + ) + (i32.ctz + (get_local $0) + ) + ) + ) + ) + (func $tlsf/block_set_next_free (; 2 ;) (type $iiv) (param $0 i32) (param $1 i32) + (i32.store + (i32.add + (get_local $0) + (get_global $tlsf/BLOCK_NEXT_FREE_OFFSET) + ) + (get_local $1) + ) + ) + (func $tlsf/block_set_prev_free (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32) + (i32.store + (i32.add + (get_local $0) + (get_global $tlsf/BLOCK_PREV_FREE_OFFSET) + ) + (get_local $1) + ) + ) + (func $tlsf/control_set_fl (; 4 ;) (type $iiv) (param $0 i32) (param $1 i32) + (i32.store + (i32.add + (get_local $0) + (get_global $tlsf/CONTROL_FL_BITMAP_OFFSET) + ) + (get_local $1) + ) + ) + (func $tlsf/control_set_sl (; 5 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32) + (if + (i32.eqz + (i32.lt_s + (get_local $1) + (get_global $tlsf/FL_INDEX_COUNT) + ) + ) + (unreachable) + ) + (i32.store + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 4) + ) + ) + (get_local $2) + ) + ) + (func $tlsf/control_set_block (; 6 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (if + (i32.eqz + (i32.lt_s + (get_local $1) + (get_global $tlsf/FL_INDEX_COUNT) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.lt_s + (get_local $2) + (get_global $tlsf/SL_INDEX_COUNT) + ) + ) + (unreachable) + ) + (i32.store + (i32.add + (get_local $0) + (i32.mul + (i32.add + (i32.mul + (get_local $1) + (get_global $tlsf/SL_INDEX_COUNT) + ) + (get_local $2) + ) + (i32.const 4) + ) + ) + (get_local $3) + ) + ) + (func $tlsf/control_construct (; 7 ;) (type $iv) (param $0 i32) + (local $1 i32) + (local $2 i32) + (call $tlsf/block_set_next_free + (get_local $0) + (get_local $0) + ) + (call $tlsf/block_set_prev_free + (get_local $0) + (get_local $0) + ) + (call $tlsf/control_set_fl + (get_local $0) + (i32.const 0) + ) + (block $break|1.1 + (block + (set_local $1 + (i32.const 0) + ) + ) + (loop $continue|1.1 + (if + (i32.lt_s + (get_local $1) + (get_global $tlsf/FL_INDEX_COUNT) + ) + (block + (block + (call $tlsf/control_set_sl + (get_local $0) + (get_local $1) + (i32.const 0) + ) + (block $break|1.2 + (block + (set_local $2 + (i32.const 0) + ) + ) + (loop $continue|1.2 + (if + (i32.lt_s + (get_local $2) + (get_global $tlsf/SL_INDEX_COUNT) + ) + (block + (call $tlsf/control_set_block + (get_local $0) + (get_local $1) + (get_local $2) + (get_local $0) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (br $continue|1.2) + ) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (br $continue|1.1) + ) + ) + ) + ) + ) + (func $start (; 8 ;) (type $v) + (if + (i32.eqz + (i32.eq + (call $tlsf/fls + (i32.const 0) + ) + (i32.sub + (i32.const 0) + (i32.const 1) + ) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (call $tlsf/fls + (i32.const 1) + ) + (i32.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (call $tlsf/fls + (i32.const -2147483640) + ) + (i32.const 31) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (call $tlsf/fls + (i32.const 2147483647) + ) + (i32.const 30) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (call $tlsf/ffs + (i32.const 0) + ) + (i32.sub + (i32.const 0) + (i32.const 1) + ) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (call $tlsf/ffs + (i32.const 1) + ) + (i32.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (call $tlsf/ffs + (i32.const -2147483648) + ) + (i32.const 31) + ) + ) + (unreachable) + ) + (set_global $tlsf/ALIGN_SIZE + (i32.shl + (i32.const 1) + (get_global $tlsf/ALIGN_SIZE_LOG2) + ) + ) + (if + (i32.eqz + (i32.eq + (get_global $tlsf/ALIGN_SIZE) + (i32.const 8) + ) + ) + (unreachable) + ) + (set_global $tlsf/BLOCK_SIZE_OFFSET + (i32.add + (get_global $tlsf/BLOCK_PREV_PHYS_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/BLOCK_NEXT_FREE_OFFSET + (i32.add + (get_global $tlsf/BLOCK_SIZE_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/BLOCK_PREV_FREE_OFFSET + (i32.add + (get_global $tlsf/BLOCK_NEXT_FREE_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/CONTROL_FL_BITMAP_OFFSET + (i32.add + (get_global $tlsf/BLOCK_PREV_FREE_OFFSET) + (i32.const 4) + ) + ) + (set_global $tlsf/FL_INDEX_SHIFT + (i32.add + (get_global $tlsf/SL_INDEX_COUNT_LOG2) + (get_global $tlsf/ALIGN_SIZE_LOG2) + ) + ) + (set_global $tlsf/FL_INDEX_COUNT + (i32.add + (i32.sub + (get_global $tlsf/FL_INDEX_MAX) + (get_global $tlsf/FL_INDEX_SHIFT) + ) + (i32.const 1) + ) + ) + (set_global $tlsf/SL_INDEX_COUNT + (i32.shl + (i32.const 1) + (get_global $tlsf/SL_INDEX_COUNT_LOG2) + ) + ) + (call $tlsf/control_construct + (i32.load + (i32.const 8) + ) + ) + ) +) +(; +[program.elements] + clz + ctz + popcnt + rotl + rotr + abs + ceil + copysign + floor + max + min + nearest + sqrt + trunc + current_memory + grow_memory + unreachable + load + store + reinterpret + select + sizeof + isNaN + isFinite + assert + tlsf/fls + tlsf/ffs + tlsf/ALIGN_SIZE_LOG2 + tlsf/ALIGN_SIZE + tlsf/SL_INDEX_COUNT_LOG2 + tlsf/FL_INDEX_MAX + tlsf/SL_INDEX_COUNT + tlsf/FL_INDEX_SHIFT + tlsf/FL_INDEX_COUNT + tlsf/SMALL_BLOCK_SIZE + tlsf/BLOCK_PREV_PHYS_OFFSET + tlsf/BLOCK_SIZE_OFFSET + tlsf/BLOCK_NEXT_FREE_OFFSET + tlsf/BLOCK_PREV_FREE_OFFSET + tlsf/block_get_prev_phys_block + tlsf/block_set_prev_phys_block + tlsf/block_get_size + tlsf/block_set_size + tlsf/block_get_next_free + tlsf/block_set_next_free + tlsf/block_get_prev_free + tlsf/block_set_prev_free + tlsf/CONTROL_FL_BITMAP_OFFSET + tlsf/CONTROL_SL_BITMAP_OFFSET + tlsf/CONTROL_BLOCKS_OFFSET + tlsf/control_get_fl + tlsf/control_set_fl + tlsf/control_get_sl + tlsf/control_set_sl + tlsf/control_get_block + tlsf/control_set_block + tlsf/control_construct +[program.exports] + tlsf/control_construct +;)