1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include <mos/lib/structures/stack.h>
4#include <mos/moslib_global.h>
5#include <mos_stdio.h>
6#include <mos_string.h>
7
8void stack_init(downwards_stack_t *stack, void *mem_region_bottom, size_t size)
9{
10 // the stack grows downwards
11 ptr_t stack_top = (ptr_t) mem_region_bottom + size;
12 stack->top = stack_top;
13 stack->head = stack_top;
14 stack->capacity = size;
15}
16
17void stack_deinit(downwards_stack_t *stack)
18{
19 memset(s: stack, c: 0, n: sizeof(downwards_stack_t));
20}
21
22void *stack_grow(downwards_stack_t *stack, size_t size)
23{
24 // high memory | top -----> head -----> top - capacity | low memory
25 if (unlikely(stack->head - (stack->top - stack->capacity) < size))
26 mos_panic("stack overflow on stack %p, attempted to push %zu bytes", (void *) stack, size);
27
28 stack->head = stack->head - size;
29 return (void *) stack->head;
30}
31
32void *stack_push(downwards_stack_t *stack, const void *data, size_t size)
33{
34 // high memory | top -----> head -----> top - capacity | low memory
35 if (unlikely(stack->head - (stack->top - stack->capacity) < size))
36 mos_panic("stack overflow on stack %p, attempted to push %zu bytes", (void *) stack, size);
37
38 stack->head = stack->head - size;
39 memcpy(dest: (void *) stack->head, src: data, n: size);
40 return (void *) stack->head;
41}
42
43void stack_pop(downwards_stack_t *stack, size_t size, void *data)
44{
45 // high memory | top -----> head -----> top - capacity | low memory
46 if (unlikely(stack->head - stack->top < size))
47 mos_panic("stack underflow on stack %p, attempted to pop %zu bytes", (void *) stack, size);
48
49 if (data != NULL)
50 memcpy(dest: data, src: (void *) stack->head, n: size);
51 stack->head = stack->head + size;
52}
53