MSL: match alloc/signal/string and most of printf

This commit is contained in:
mrshigure 2025-01-29 14:19:43 -08:00
parent 6347294c14
commit b353af7d23
7 changed files with 1346 additions and 858 deletions

View file

@ -227,6 +227,7 @@ cflags_thp = [
# Metrowerks library flags # Metrowerks library flags
cflags_msl = [ cflags_msl = [
*cflags_base, *cflags_base,
"-char signed",
"-use_lmw_stmw on", "-use_lmw_stmw on",
"-str reuse,pool,readonly", "-str reuse,pool,readonly",
"-common off", "-common off",
@ -681,7 +682,7 @@ config.libs = [
"host": False, "host": False,
"objects": [ "objects": [
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/abort_exit.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/abort_exit.c"),
Object(NonMatching, "MSL_C.PPCEABI.bare.H/alloc.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/alloc.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/errno.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/errno.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/ansi_files.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/ansi_files.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/ansi_fp.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/ansi_fp.c"),
@ -697,8 +698,8 @@ config.libs = [
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/misc_io.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/misc_io.c"),
Object(NonMatching, "MSL_C.PPCEABI.bare.H/printf.c"), Object(NonMatching, "MSL_C.PPCEABI.bare.H/printf.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/float.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/float.c"),
Object(NonMatching, "MSL_C.PPCEABI.bare.H/signal.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/signal.c"),
Object(NonMatching, "MSL_C.PPCEABI.bare.H/string.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/string.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/uart_console_io.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/uart_console_io.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/wchar_io.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/wchar_io.c"),
Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/e_acos.c"), Object(MatchingFor("GMPE01_00", "GMPE01_01"), "MSL_C.PPCEABI.bare.H/e_acos.c"),

View file

@ -85,7 +85,7 @@ typedef struct _FILE {
file_modes file_mode; file_modes file_mode;
file_states file_state; file_states file_state;
char is_dynamically_allocated; unsigned char is_dynamically_allocated;
char char_buffer; char char_buffer;
char char_buffer_overflow; char char_buffer_overflow;
char ungetc_buffer[2]; char ungetc_buffer[2];

View file

@ -10,7 +10,7 @@ char* strrchr(const char* str, int c);
char* strchr(const char* str, int c); char* strchr(const char* str, int c);
int strncmp(const char* str1, const char* str2, size_t n); int strncmp(const char* str1, const char* str2, size_t n);
int strcmp(const char* str1, const char* str2); int strcmp(const char* str1, const char* str2);
char* strcat(char* dst, const char* src); char* strcat(char* dst, const char* src, size_t n);
char* strncpy(char* dst, const char* src, size_t n); char* strncpy(char* dst, const char* src, size_t n);
char* strcpy(char* dst, const char* src); char* strcpy(char* dst, const char* src);
size_t strlen(const char* str); size_t strlen(const char* str);

410
src/MSL_C.PPCEABI.bare.H/alloc.c Executable file
View file

@ -0,0 +1,410 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/alloc.h"
typedef struct Block {
struct Block* prev;
struct Block* next;
unsigned long max_size;
unsigned long size;
} Block;
typedef struct SubBlock {
unsigned long size;
Block* block;
struct SubBlock* prev;
struct SubBlock* next;
} SubBlock;
struct FixSubBlock;
typedef struct FixBlock {
struct FixBlock* prev_;
struct FixBlock* next_;
unsigned long client_size_;
struct FixSubBlock* start_;
unsigned long n_allocated_;
} FixBlock;
typedef struct FixSubBlock {
FixBlock* block_;
struct FixSubBlock* next_;
} FixSubBlock;
typedef struct FixStart {
FixBlock* tail_;
FixBlock* head_;
} FixStart;
typedef struct __mem_pool_obj {
Block* start_;
FixStart fix_start[6];
} __mem_pool_obj;
typedef struct __mem_pool {
void* reserved[14];
} __mem_pool;
typedef signed long tag_word;
typedef struct block_header {
tag_word tag;
struct block_header * prev;
struct block_header * next;
} block_header;
typedef struct list_header {
block_header * rover;
block_header header;
} list_header;
typedef struct heap_header {
struct heap_header* prev;
struct heap_header* next;
} heap_header;
struct mem_pool_obj;
typedef void * (*sys_alloc_ptr)(unsigned long, struct mem_pool_obj*);
typedef void (*sys_free_ptr)(void *, struct mem_pool_obj*);
typedef struct pool_options{
sys_alloc_ptr sys_alloc_func;
sys_free_ptr sys_free_func;
unsigned long min_heap_size;
int always_search_first;
} pool_options;
typedef struct mem_pool_obj {
list_header free_list;
pool_options options;
heap_header* heap_list;
void* userData;
} mem_pool_obj;
mem_pool_obj __malloc_pool;
static int initialized = 0;
static SubBlock* SubBlock_merge_prev(SubBlock*, SubBlock**);
static void SubBlock_merge_next(SubBlock* , SubBlock** );
static const unsigned long fix_pool_sizes[] = {4, 12, 20, 36, 52, 68};
#define SubBlock_size(ths) ((ths)->size & 0xFFFFFFF8)
#define SubBlock_block(ths) ((Block*)((unsigned long)((ths)->block) & ~0x1))
#define Block_size(ths) ((ths)->size & 0xFFFFFFF8)
#define Block_start(ths) (*(SubBlock**)((char*)(ths) + Block_size((ths)) - sizeof(unsigned long)))
#define SubBlock_set_free(ths) \
unsigned long this_size = SubBlock_size((ths)); \
(ths)->size &= ~0x2; \
*(unsigned long*)((char*)(ths) + this_size) &= ~0x4; \
*(unsigned long*)((char*)(ths) + this_size - sizeof(unsigned long)) = this_size
#define SubBlock_is_free(ths) !((ths)->size & 2)
#define SubBlock_set_size(ths, sz) \
(ths)->size &= ~0xFFFFFFF8; \
(ths)->size |= (sz) & 0xFFFFFFF8; \
if (SubBlock_is_free((ths))) \
*(unsigned long*)((char*)(ths) + (sz) - sizeof(unsigned long)) = (sz)
#define SubBlock_from_pointer(ptr) ((SubBlock*)((char*)(ptr) - 8))
#define FixSubBlock_from_pointer(ptr) ((FixSubBlock*)((char*)(ptr) - 4))
#define FixBlock_client_size(ths) ((ths)->client_size_)
#define FixSubBlock_size(ths) (FixBlock_client_size((ths)->block_))
#define classify(ptr) (*(unsigned long*)((char*)(ptr) - sizeof(unsigned long)) & 1)
#define __msize_inline(ptr) (!classify(ptr) ? FixSubBlock_size(FixSubBlock_from_pointer(ptr)) : SubBlock_size(SubBlock_from_pointer(ptr)) - 8)
#define Block_empty(ths) \
(_sb = (SubBlock*)((char*)(ths) + 16)), \
SubBlock_is_free(_sb) && SubBlock_size(_sb) == Block_size((ths)) - 24
//unused
void Block_subBlock(){
}
void Block_link(Block* ths, SubBlock* sb) {
SubBlock** st;
SubBlock_set_free(sb);
st = &Block_start(ths);
if (*st != 0)
{
sb->prev = (*st)->prev;
sb->prev->next = sb;
sb->next = *st;
(*st)->prev = sb;
*st = sb;
*st = SubBlock_merge_prev(*st, st);
SubBlock_merge_next(*st, st);
}
else
{
*st = sb;
sb->prev = sb;
sb->next = sb;
}
if (ths->max_size < SubBlock_size(*st))
ths->max_size = SubBlock_size(*st);
}
static SubBlock* SubBlock_merge_prev(SubBlock *ths, SubBlock **start) {
unsigned long prevsz;
SubBlock* p;
if (!(ths->size & 0x04))
{
prevsz = *(unsigned long*)((char*)ths - sizeof(unsigned long));
if (prevsz & 0x2)
return ths;
p = (SubBlock*)((char*)ths - prevsz);
SubBlock_set_size(p, prevsz + SubBlock_size(ths));
if (*start == ths)
*start = (*start)->next;
ths->next->prev = ths->prev;
ths->next->prev->next = ths->next;
return p;
}
return ths;
}
static void SubBlock_merge_next(SubBlock *pBlock, SubBlock **pStart) {
SubBlock* next_sub_block;
unsigned long this_cur_size;
next_sub_block = (SubBlock*)((char*)pBlock + (pBlock->size & 0xFFFFFFF8));
if (!(next_sub_block->size & 2)) {
this_cur_size = (pBlock->size & 0xFFFFFFF8) + (next_sub_block->size & 0xFFFFFFF8);
pBlock->size &= ~0xFFFFFFF8;
pBlock->size |= this_cur_size & 0xFFFFFFF8;
if (!(pBlock->size & 2)) {
*(unsigned long*)((char*)(pBlock) + (this_cur_size) - 4) = (this_cur_size);
}
if (!(pBlock->size & 2)) {
*(unsigned long *)((char*)pBlock + this_cur_size) &= ~4;
}
else {
*(unsigned long *)((char*)pBlock + this_cur_size) |= 4;
}
if (*pStart == next_sub_block) {
*pStart = (*pStart)->next;
}
if (*pStart == next_sub_block) {
*pStart = 0;
}
next_sub_block->next->prev = next_sub_block->prev;
next_sub_block->prev->next = next_sub_block->next;
}
}
static Block* __unlink(__mem_pool_obj* pool_obj, Block* bp) {
Block* result = bp->next;
if (result == bp) {
result = 0;
}
if (pool_obj->start_ == bp) {
pool_obj->start_ = result;
}
if (result != 0) {
result->prev = bp->prev;
result->prev->next = result;
}
bp->next = 0;
bp->prev = 0;
return result;
}
//unused
void allocate_from_var_pools(){
}
//unused
void soft_allocate_from_var_pools(){
}
static void deallocate_from_var_pools(__mem_pool_obj* pool_obj, void *ptr) {
SubBlock* sb = SubBlock_from_pointer(ptr);
SubBlock* _sb;
Block* bp = SubBlock_block(sb);
Block_link(bp, sb);
if (Block_empty(bp)) {
__unlink(pool_obj, bp);
__sys_free(bp);
}
}
//unused
void FixBlock_construct(){
}
void __init_pool_obj(__mem_pool* pool_obj) {
memset(pool_obj, 0, sizeof(__mem_pool_obj));
}
static __mem_pool* get_malloc_pool(void) {
static __mem_pool protopool;
static unsigned char init = 0;
if (!init) {
__init_pool_obj(&protopool);
init = 1;
}
return &protopool;
}
//unused
void allocate_from_fixed_pools(){
}
void deallocate_from_fixed_pools(__mem_pool_obj* pool_obj, void* ptr, unsigned long size) {
unsigned long i = 0;
FixSubBlock* p;
FixBlock* b;
FixStart* fs;
while (size > fix_pool_sizes[i]) {
++i;
}
fs = &pool_obj->fix_start[i];
p = FixSubBlock_from_pointer(ptr);
b = p->block_;
if (b->start_ == 0 && fs->head_ != b) {
if (fs->tail_ == b) {
fs->head_ = fs->head_->prev_;
fs->tail_ = fs->tail_->prev_;
}
else {
b->prev_->next_ = b->next_;
b->next_->prev_ = b->prev_;
b->next_ = fs->head_;
b->prev_ = b->next_->prev_;
b->prev_->next_ = b;
b->next_->prev_ = b;
fs->head_ = b;
}
}
p->next_ = b->start_;
b->start_ = p;
if (--b->n_allocated_ == 0) {
if (fs->head_ == b) {
fs->head_ = b->next_;
}
if (fs->tail_ == b) {
fs->tail_ = b->prev_;
}
b->prev_->next_ = b->next_;
b->next_->prev_ = b->prev_;
if (fs->head_ == b) {
fs->head_ = 0;
}
if (fs->tail_ == b) {
fs->tail_ = 0;
}
deallocate_from_var_pools(pool_obj, b);
}
}
//unused
void __pool_allocate_resize(){
}
//unused
void __msize(){
}
//unused
void __pool_alloc(){
}
//unused
void __allocate_size(){
}
//unused
void __allocate(){
}
//unused
void __allocate_resize(){
}
//unused
void __allocate_expand(){
}
void __pool_free(__mem_pool *pool, void *ptr) {
__mem_pool_obj* pool_obj;
unsigned long size;
if (ptr == 0) {
return;
}
pool_obj = (__mem_pool_obj*)pool;
size = __msize_inline(ptr);
if (size <= 68) {
deallocate_from_fixed_pools(pool_obj, ptr, size);
}
else {
deallocate_from_var_pools(pool_obj, ptr);
}
}
//unused
void __pool_realloc(){
}
//unused
void __pool_alloc_clear(){
}
//unused
void malloc(){
}
void free(void *ptr) {
__pool_free(get_malloc_pool(), ptr);
}
//unused
void realloc(){
}
//unused
void calloc(){
}
//unused
void __pool_free_all(){
}
//unused
void __malloc_free_all(){
}

File diff suppressed because it is too large Load diff

View file

@ -1,26 +1,24 @@
#include <stddef.h> #include <stddef.h>
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/signal.h"
void* signal_funcs[6]; __signal_func_ptr signal_funcs[6];
// regalloc: https://decomp.me/scratch/ufAYK int raise(int sig) {
int raise(int arg0) { __signal_func_ptr temp_r31;
void (*temp_r31)(int);
void** temp_r3;
if (arg0 < 1 || arg0 > 6) { if (sig < 1 || sig > 6) {
return -1; return -1;
} }
temp_r3 = &signal_funcs[arg0]; temp_r31 = signal_funcs[sig - 1];
temp_r31 = *(--temp_r3);
if ((unsigned long) temp_r31 != 1) { if ((unsigned long) temp_r31 != 1) {
*temp_r3 = NULL; signal_funcs[sig - 1] = NULL;
} }
if ((unsigned long) temp_r31 == 1 || (temp_r31 == NULL && arg0 == 1)) { if ((unsigned long) temp_r31 == 1 || (temp_r31 == NULL && sig == 1)) {
return 0; return 0;
} }
if (temp_r31 == NULL) { if (temp_r31 == NULL) {
exit(0); exit(0);
} }
temp_r31(arg0); temp_r31(sig);
return 0; return 0;
} }

View file

@ -1,8 +1,8 @@
#include "string.h" #include "string.h"
#include "stddef.h" #include "stddef.h"
static int K1 = 0x80808080; #define K1 0x80808080
static int K2 = 0xFEFEFEFF; #define K2 0xFEFEFEFF
size_t strlen(const char* str) size_t strlen(const char* str)
{ {
@ -20,8 +20,6 @@ char* strcpy(char* dst, const char* src)
{ {
register unsigned char *destb, *fromb; register unsigned char *destb, *fromb;
register unsigned long w, t, align; register unsigned long w, t, align;
register unsigned int k1;
register unsigned int k2;
fromb = (unsigned char*)src; fromb = (unsigned char*)src;
destb = (unsigned char*)dst; destb = (unsigned char*)dst;
@ -44,14 +42,11 @@ char* strcpy(char* dst, const char* src)
++fromb; ++fromb;
} }
k1 = K1;
k2 = K2;
w = *((int*)(fromb)); w = *((int*)(fromb));
t = w + k2; t = w + K2;
t &= k1; t &= K1;
if (t) { if (t) {
goto bytecopy; goto bytecopy;
} }
@ -61,8 +56,8 @@ char* strcpy(char* dst, const char* src)
*(++((int*)(destb))) = w; *(++((int*)(destb))) = w;
w = *(++((int*)(fromb))); w = *(++((int*)(fromb)));
t = w + k2; t = w + K2;
t &= k1; t &= K1;
if (t) { if (t) {
goto adjust; goto adjust;
} }
@ -103,16 +98,21 @@ char* strncpy(char* dst, const char* src, size_t n)
return dst; return dst;
} }
char* strcat(char* dst, const char* src) // TODO: same implementation as strncpy?
char* strcat(char* dst, const char* src, size_t n)
{ {
const unsigned char* p = (unsigned char*)src - 1; const unsigned char* p = (const unsigned char*)src - 1;
unsigned char* q = (unsigned char*)dst - 1; unsigned char* q = (unsigned char*)dst - 1;
while (*++q) { } n++;
while (--n) {
q--; if (!(*++q = *++p)) {
while (--n) {
while (*++q = *++p) { } *++q = 0;
}
break;
}
}
return dst; return dst;
} }
@ -196,6 +196,22 @@ bytecopy:
} while (1); } while (1);
} }
int strncmp(const char* str1, const char* str2, size_t n)
{
const unsigned char* p1 = (unsigned char*)str1 - 1;
const unsigned char* p2 = (unsigned char*)str2 - 1;
unsigned long c1, c2;
n++;
while (--n)
if ((c1 = *++p1) != (c2 = *++p2))
return (c1 - c2);
else if (!c1)
break;
return 0;
}
char* strchr(const char* str, int c) char* strchr(const char* str, int c)
{ {
const unsigned char* p = (unsigned char*)str - 1; const unsigned char* p = (unsigned char*)str - 1;