summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2021-08-20 21:00:20 -0400
committerPikalaxALT <pikalaxalt@gmail.com>2021-08-20 21:00:20 -0400
commitcb6f5a1c7ad38e09cb47d402b2b5d78fdd5965cc (patch)
treeb6202c549aa1f981e96e3233b714eb589ce8122a
parent36eef8e744976e708abc3652a95f662346ee7072 (diff)
AllocFromHead, ALlocFromTail
-rw-r--r--arm9/asm/NNS_FND_expheap_s.s111
-rw-r--r--arm9/lib/libnns/include/NNS_FND_heapcommon.h8
-rw-r--r--arm9/lib/libnns/src/NNS_FND_expheap.c65
3 files changed, 75 insertions, 109 deletions
diff --git a/arm9/asm/NNS_FND_expheap_s.s b/arm9/asm/NNS_FND_expheap_s.s
index 494e3c21..d173bef0 100644
--- a/arm9/asm/NNS_FND_expheap_s.s
+++ b/arm9/asm/NNS_FND_expheap_s.s
@@ -8,6 +8,8 @@
.extern InitMBlock
.extern InitExpHeap
.extern AllocUsedBlockFromFreeBlock
+ .extern AllocFromHead
+ .extern AllocFromTail
.text
arm_func_start NNS_FndGetSizeForMBlockExpHeap
@@ -274,112 +276,3 @@ _020AE0D4:
.balign 4
_020AE118: .word 0x00004652
arm_func_end RecycleRegion
-
- local_arm_func_start AllocFromTail
-AllocFromTail: ; 0x020AE11C
- stmdb sp!, {r4-r9,lr}
- sub sp, sp, #0x4
- add r0, r0, #0x24
- ldrh r4, [r0, #0x12]
- mov r3, r1
- mvn lr, #0x0
- and r1, r4, #0x1
- mov r1, r1, lsl #0x10
- movs r1, r1, lsr #0x10
- moveq r5, #0x1
- mov r1, #0x0
- ldr r4, [r0, #0x4]
- movne r5, #0x0
- mov r12, r1
- cmp r4, #0x0
- beq _020AE1B0
- sub r2, r2, #0x1
- mvn r2, r2
-_020AE164:
- ldr r8, [r4, #0x4]
- add r9, r4, #0x10
- add r6, r8, r9
- sub r6, r6, r3
- and r7, r2, r6
- subs r6, r7, r9
- bmi _020AE1A4
- cmp lr, r8
- bls _020AE1A4
- mov r1, r4
- mov lr, r8
- mov r12, r7
- cmp r5, #0x0
- bne _020AE1B0
- cmp r8, r3
- beq _020AE1B0
-_020AE1A4:
- ldr r4, [r4, #0x8]
- cmp r4, #0x0
- bne _020AE164
-_020AE1B0:
- cmp r1, #0x0
- addeq sp, sp, #0x4
- moveq r0, #0x0
- ldmeqia sp!, {r4-r9,pc}
- mov r4, #0x1
- mov r2, r12
- str r4, [sp, #0x0]
- bl AllocUsedBlockFromFreeBlock
- add sp, sp, #0x4
- ldmia sp!, {r4-r9,pc}
- arm_func_end AllocFromTail
-
- local_arm_func_start AllocFromHead
-AllocFromHead: ; 0x020AE1D8
- stmdb sp!, {r4-r9,lr}
- sub sp, sp, #0x4
- add r0, r0, #0x24
- ldrh r4, [r0, #0x12]
- mov r3, r1
- ldr r5, [r0, #0x0]
- and r1, r4, #0x1
- mov r1, r1, lsl #0x10
- movs r1, r1, lsr #0x10
- moveq r6, #0x1
- mov r1, #0x0
- movne r6, #0x0
- mov lr, r1
- cmp r5, #0x0
- mvn r4, #0x0
- beq _020AE270
- sub r12, r2, #0x1
- mvn r2, r12
-_020AE220:
- add r8, r5, #0x10
- add r7, r12, r8
- and r9, r2, r7
- sub r7, r9, r8
- ldr r8, [r5, #0x4]
- add r7, r3, r7
- cmp r8, r7
- blo _020AE264
- cmp r4, r8
- bls _020AE264
- mov r1, r5
- mov r4, r8
- mov lr, r9
- cmp r6, #0x0
- bne _020AE270
- cmp r8, r3
- beq _020AE270
-_020AE264:
- ldr r5, [r5, #0xc]
- cmp r5, #0x0
- bne _020AE220
-_020AE270:
- cmp r1, #0x0
- addeq sp, sp, #0x4
- moveq r0, #0x0
- ldmeqia sp!, {r4-r9,pc}
- mov r4, #0x0
- mov r2, lr
- str r4, [sp, #0x0]
- bl AllocUsedBlockFromFreeBlock
- add sp, sp, #0x4
- ldmia sp!, {r4-r9,pc}
- arm_func_end AllocFromHead
diff --git a/arm9/lib/libnns/include/NNS_FND_heapcommon.h b/arm9/lib/libnns/include/NNS_FND_heapcommon.h
index 77473efe..f35bf097 100644
--- a/arm9/lib/libnns/include/NNS_FND_heapcommon.h
+++ b/arm9/lib/libnns/include/NNS_FND_heapcommon.h
@@ -98,4 +98,12 @@ static inline void FillAllocMemory(NNSiFndHeapHead* pHeapHd, void* address, u32
void NNSi_FndInitHeapHead(NNSiFndHeapHead *pHead, u32 signature, void* heapStart, void* heapEnd, u16 optionFlag);
+#define NNSi_FndRoundUp(value, alignment) (((value) + (alignment - 1)) & ~(alignment - 1))
+
+#define NNSi_FndRoundUpPtr(ptr, alignment) ((void*)NNSi_FndRoundUp(NNSiGetUIntPtr(ptr), alignment))
+
+#define NNSi_FndRoundDown(value, alignment) ((value) & ~(alignment - 1))
+
+#define NNSi_FndRoundDownPtr(ptr, alignment) ((void*)NNSi_FndRoundDown(NNSiGetUIntPtr(ptr), alignment))
+
#endif //GUARD_NNS_FND_HEAPCOMMON_H
diff --git a/arm9/lib/libnns/src/NNS_FND_expheap.c b/arm9/lib/libnns/src/NNS_FND_expheap.c
index f5a74dc4..31ea5fbe 100644
--- a/arm9/lib/libnns/src/NNS_FND_expheap.c
+++ b/arm9/lib/libnns/src/NNS_FND_expheap.c
@@ -36,6 +36,11 @@ static inline void* GetMBlockEndAddr(NNSiFndExpHeapMBlockHead* block)
return AddU32ToPtr(GetMemPtrForMBlock(block), block->blockSize);
}
+static inline u16 GetAllocMode(NNSiFndExpHeapHead* pExHeapHd)
+{
+ return NNSi_FndGetBitValue(pExHeapHd->feature, 0, 1);
+}
+
static inline void SetAllocMode(NNSiFndExpHeapHead* pExHeapHd, u16 mode)
{
NNSi_FndSetBitValue(pExHeapHd->feature, 0, 1, mode);
@@ -202,3 +207,63 @@ void* AllocUsedBlockFromFreeBlock(NNSiFndExpHeapHead* pEHHead, NNSiFndExpHeapMBl
return mblock;
}
+
+void* AllocFromHead(NNSiFndHeapHead* pHeapHd, u32 size, int alignment)
+{
+ NNSiFndExpHeapHead* pExpHeapHd = GetExpHeapHeadPtrFromHeapHead(pHeapHd);
+ const BOOL bAllocFirst = GetAllocMode(pExpHeapHd) == 0;
+ NNSiFndExpHeapMBlockHead* pMBlkHd = NULL;
+ NNSiFndExpHeapMBlockHead* pMBlkHdFound = NULL;
+ u32 foundSize = 0xFFFFFFFF;
+ void* foundMBlock = NULL;
+
+ for (pMBlkHd = pExpHeapHd->mbFreeList.head; pMBlkHd; pMBlkHd = pMBlkHd->pMBHeadNext)
+ {
+ void *const mblock = GetMemPtrForMBlock(pMBlkHd);
+ void *const reqMBlock = NNSi_FndRoundUpPtr(mblock, alignment);
+ const u32 offset = GetOffsetFromPtr(mblock, reqMBlock);
+ if (pMBlkHd->blockSize >= size + offset && foundSize > pMBlkHd->blockSize)
+ {
+ pMBlkHdFound = pMBlkHd;
+ foundSize = pMBlkHd->blockSize;
+ foundMBlock = reqMBlock;
+ if (bAllocFirst || foundSize == size)
+ break;
+ }
+ }
+
+ if (!pMBlkHdFound)
+ return NULL;
+
+ return AllocUsedBlockFromFreeBlock(pExpHeapHd, pMBlkHdFound, foundMBlock, size, 0);
+}
+
+void* AllocFromTail(NNSiFndHeapHead* pHeapHd, u32 size, int alignment)
+{
+ NNSiFndExpHeapHead* pExpHeapHd = GetExpHeapHeadPtrFromHeapHead(pHeapHd);
+ const BOOL bAllocFirst = GetAllocMode(pExpHeapHd) == 0;
+ NNSiFndExpHeapMBlockHead* pMBlkHd = NULL;
+ NNSiFndExpHeapMBlockHead* pMBlkHdFound = NULL;
+ u32 foundSize = 0xFFFFFFFF;
+ void* foundMBlock = NULL;
+
+ for (pMBlkHd = pExpHeapHd->mbFreeList.tail; pMBlkHd; pMBlkHd = pMBlkHd->pMBHeadPrev)
+ {
+ void *const mblock = GetMemPtrForMBlock(pMBlkHd);
+ void *const mBlockEnd = AddU32ToPtr(mblock, pMBlkHd->blockSize);
+ void *const reqMBlock = NNSi_FndRoundDownPtr(SubU32ToPtr(mBlockEnd, size), alignment);
+ if (ComparePtr(reqMBlock, mblock) >= 0 && foundSize > pMBlkHd->blockSize)
+ {
+ pMBlkHdFound = pMBlkHd;
+ foundSize = pMBlkHd->blockSize;
+ foundMBlock = reqMBlock;
+ if (bAllocFirst || foundSize == size)
+ break;
+ }
+ }
+
+ if (!pMBlkHdFound)
+ return NULL;
+
+ return AllocUsedBlockFromFreeBlock(pExpHeapHd, pMBlkHdFound, foundMBlock, size, 1);
+}