forked from KolibriOS/kolibrios
kolibri-libc:
[include] - ksys.h : fixed sruct name - string.h: set memcpy, memset, and memove as static for libtcc - stdio.h: added sscanf and ungetc - stdint.h: added int64 limits [stdio] fixed *scanf functions added ungetc functon [lib] - upated binaries - added libtcc.a for tcc optimization [crt] - removed duplicate files [samples] - added fasm libc.obj example - updated old examples git-svn-id: svn://kolibrios.org@8718 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
611fac2831
commit
1c24cac315
@ -23,6 +23,10 @@
|
||||
#define INT64_MIN (-9223372036854775807LL-1LL)
|
||||
#define INT64_MAX (9223372036854775807LL)
|
||||
#define UINT64_MAX (18446744073709551615ULL)
|
||||
#else
|
||||
#define INT64_MAX 0x7fffffffffffffffLL
|
||||
#define INT64_MIN (-INT64_MAX - 1LL)
|
||||
#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL)
|
||||
#endif
|
||||
|
||||
#endif /* _STDINT_H_*/
|
||||
|
@ -107,11 +107,12 @@ extern int _FUNC(putchar)(int);
|
||||
extern int _FUNC(puts)(const char *);
|
||||
extern int _FUNC(scanf)(const char *restrict, ...);
|
||||
extern char* _FUNC(gets)(char *str);
|
||||
//extern int _FUNC(ungetc)(int, FILE *);
|
||||
extern int _FUNC(ungetc)(int, FILE *);
|
||||
extern int _FUNC(vfprintf)(FILE *restrict, const char *restrict, va_list);
|
||||
extern int _FUNC(vfscanf)(FILE *restrict, const char *restrict, va_list);
|
||||
extern int _FUNC(vprintf)(const char *restrict, va_list);
|
||||
extern int _FUNC(vscanf)(const char *restrict, va_list);
|
||||
extern int _FUNC(sscanf)(const char*, const char *restrict, ...);
|
||||
extern int _FUNC(vsscanf)(const char *, const char*, va_list);
|
||||
|
||||
extern int _FUNC(remove)(const char *);
|
||||
|
@ -29,13 +29,16 @@ extern void* _FUNC(memccpy)(void *restrict dest, const void *restrict src, int c
|
||||
area pointed to by s1. If the two areas overlap, behaviour is undefined.
|
||||
Returns the value of s1.
|
||||
*/
|
||||
extern void* _FUNC(memcpy)(void* s1, const void* s2, size_t n);
|
||||
|
||||
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
||||
area pointed to by s1. The two areas may overlap.
|
||||
Returns the value of s1.
|
||||
*/
|
||||
#ifdef __TINYC__
|
||||
extern void* memcpy(void* s1, const void* s2, size_t n);
|
||||
extern void* memset(void* s, int c, size_t n);
|
||||
extern void* memmove(void* s1, const void* s2, size_t n);
|
||||
#else
|
||||
extern void* _FUNC(memcpy)(void* s1, const void* s2, size_t n);
|
||||
extern void* _FUNC(memset)(void* s, int c, size_t n);
|
||||
extern void* _FUNC(memmove)(void* s1, const void* s2, size_t n);
|
||||
#endif
|
||||
|
||||
/* Copy the character array s2 (including terminating '\0' byte) into the
|
||||
character array s1.
|
||||
@ -160,14 +163,6 @@ extern char* _FUNC(strstr)(const char * s1, const char * s2);
|
||||
*/
|
||||
extern char* _FUNC(strtok)(char* s1, const char* s2);
|
||||
|
||||
/* Miscellaneous functions */
|
||||
|
||||
/* Write the character c (interpreted as unsigned char) to the first n
|
||||
characters of the memory area pointed to by s.
|
||||
Returns s.
|
||||
*/
|
||||
extern void* _FUNC(memset)(void* s, int c, size_t n);
|
||||
|
||||
/* Map an error number to a (locale-specific) error message string. Error
|
||||
numbers are typically errno values, but any number is mapped to a message.
|
||||
TODO: PDCLib does not yet support locales.
|
||||
|
@ -152,7 +152,7 @@ typedef struct{
|
||||
unsigned in_data_size;
|
||||
void* out_data_ptr;
|
||||
unsigned out_data_size;
|
||||
}ksys_drv_ctl_t;
|
||||
}ksys_ioctl_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
@ -1028,7 +1028,7 @@ ksys_drv_hand_t _ksys_load_pe_driver(char *driver_path, char *cmd_line)
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned _ksys_work_driver(ksys_drv_ctl_t *ioctl)
|
||||
unsigned _ksys_work_driver(ksys_ioctl_t *ioctl)
|
||||
{
|
||||
unsigned status;
|
||||
asm_inline(
|
||||
|
Binary file not shown.
BIN
programs/develop/libraries/kolibri-libc/lib/libtcc.a
Normal file
BIN
programs/develop/libraries/kolibri-libc/lib/libtcc.a
Normal file
Binary file not shown.
@ -1,5 +1,6 @@
|
||||
|
||||
KTCC=../../../ktcc/trunk/bin/kos32-tcc
|
||||
FASM= fasm
|
||||
KPACK = kpack
|
||||
CFLAGS = -I../include
|
||||
LDFLAGS = -nostdlib -L../lib ../lib/crt0.o
|
||||
@ -12,13 +13,16 @@ string_test.kex \
|
||||
whois.kex \
|
||||
file_io.kex \
|
||||
tmpdisk_work.kex \
|
||||
exp_drv_work.kex
|
||||
|
||||
fasm/sprintf_test.kex
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
%.kex : %.c
|
||||
$(KTCC) $(CFLAGS) $(LDFLAGS) $< -o $@ -lnetwork -lc.obj
|
||||
$(KTCC) $(CFLAGS) $(LDFLAGS) $< -o $@ -ltcc -lnetwork -lc.obj
|
||||
$(KPACK) --nologo $@
|
||||
|
||||
%.kex : %.asm
|
||||
$(FASM) $< $@
|
||||
$(KPACK) --nologo $@
|
||||
|
||||
clean:
|
||||
|
@ -64,7 +64,7 @@ int main()
|
||||
ksys_pos_t mouse_pos;
|
||||
strcpy(statusbar, "Program running...Double click on TEXT for details");
|
||||
|
||||
_ksys_get_colors(&sys_color_table);
|
||||
_ksys_get_system_colors(&sys_color_table);
|
||||
_ksys_set_event_mask(0xC0000027); // mouse events only when focused window and mouse inside
|
||||
|
||||
do{
|
||||
|
@ -0,0 +1,81 @@
|
||||
format binary as "kex"
|
||||
|
||||
use32
|
||||
org 0x0
|
||||
db 'MENUET01'
|
||||
dd 0x01
|
||||
dd START
|
||||
dd IM_END
|
||||
dd MEM
|
||||
dd MEM
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
include '../../../../../macros.inc'
|
||||
include '../../../../../proc32.inc'
|
||||
include '../../../../../KOSfuncs.inc'
|
||||
include '../../../../../dll.inc'
|
||||
;include '../../../../../debug-fdo.inc'
|
||||
|
||||
;__DEBUG__ = 1
|
||||
;__DEBUG_LEVEL__ = 2
|
||||
|
||||
START:
|
||||
stdcall dll.Load, @IMPORT
|
||||
test eax, eax
|
||||
jnz exit
|
||||
|
||||
cinvoke libc_strlen, test_str1
|
||||
;DEBUGF 2, "%d", eax
|
||||
mcall SF_SYS_MISC, SSF_MEM_ALLOC, eax
|
||||
mov [test_str2], eax
|
||||
|
||||
cinvoke libc_sprintf, [test_str2], format_str, str_var, [dec_var], dword [float_var], dword[float_var+4], [hex_var]
|
||||
cinvoke libc_puts, test_str1
|
||||
cinvoke libc_puts, [test_str2]
|
||||
|
||||
cinvoke libc_strcmp, test_str1, [test_str2]
|
||||
|
||||
test eax, eax
|
||||
jz print_succ
|
||||
jmp print_fail
|
||||
|
||||
print_succ:
|
||||
cinvoke libc_puts, success_msg
|
||||
jmp exit
|
||||
|
||||
print_fail:
|
||||
cinvoke libc_puts, failed_msg
|
||||
|
||||
exit:
|
||||
mcall SF_SYS_MISC, SSF_MEM_FREE, [test_str2]
|
||||
mcall SF_TERMINATE_PROCESS
|
||||
|
||||
; data
|
||||
|
||||
format_str db "%s %d %f 0x%x", 0
|
||||
test_str1 db "Test 463 -26.432100 0x9d81", 0
|
||||
test_str2 dd 0
|
||||
|
||||
str_var db "Test",0
|
||||
dec_var dd 463
|
||||
float_var dq -26.4321
|
||||
hex_var dd 40321
|
||||
|
||||
success_msg db "Test successful!", 0
|
||||
failed_msg db "Test failed!", 0
|
||||
|
||||
align 4
|
||||
|
||||
@IMPORT:
|
||||
library libc, 'libc.obj'
|
||||
import libc, \
|
||||
libc_sprintf, 'sprintf', \
|
||||
libc_strcmp, 'strcmp', \
|
||||
libc_strlen, 'strlen', \
|
||||
libc_puts, 'puts'
|
||||
|
||||
IM_END:
|
||||
align 4
|
||||
rb 1024 ; stack
|
||||
MEM:
|
@ -3,8 +3,11 @@
|
||||
#include <limits.h>
|
||||
|
||||
char* test_string1 = "Hello world!";
|
||||
int a, b;
|
||||
|
||||
int main(int argc, char** argv){
|
||||
sscanf("43 53","%d %d",&a, &b);
|
||||
printf("(43 53) = (%d %d)\n", a, b);
|
||||
printf("Hello world! = %s\n", test_string1);
|
||||
printf("345.358980 = %f\n", 345.35898);
|
||||
printf("345 = %d\n", (int)345.35898);
|
||||
|
@ -37,7 +37,7 @@ int main(){
|
||||
tmpdisk_add.disk_size = TMPDISK_SIZE*1024*1024/512;
|
||||
tmpdisk_add.disk_id = 5;
|
||||
|
||||
ksys_drv_ctl_t ioctl;
|
||||
ksys_ioctl_t ioctl;
|
||||
ioctl.func_num = DEV_ADD_DISK;
|
||||
ioctl.handler = tmpdisk_drv;
|
||||
ioctl.in_data_ptr = &tmpdisk_add;
|
||||
@ -53,4 +53,4 @@ int main(){
|
||||
puts(tmpdisk_res_text[6]);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,10 @@ all:
|
||||
$(KPACK) $(LIB)
|
||||
../linuxtools/LoaderGen symbols.txt ../loader
|
||||
../linuxtools/LoaderBuild ../loader
|
||||
$(MAKE) -C libtcc
|
||||
rm -rf exports
|
||||
install:
|
||||
cp -f ../lib/libc.obj ~/.kex/root/RD/1/LIB
|
||||
|
||||
clean:
|
||||
rm ../lib/libc.obj
|
||||
rm ../lib/*
|
||||
|
@ -1 +0,0 @@
|
||||
__CPU_type fix p5
|
@ -4,11 +4,10 @@ public start
|
||||
public start as '_start'
|
||||
;extrn mf_init
|
||||
extrn main
|
||||
;include 'debug2.inc'
|
||||
include 'proc32.inc'
|
||||
include 'macros.inc'
|
||||
include 'dll.inc'
|
||||
__DEBUG__=0
|
||||
include '../../../../../proc32.inc'
|
||||
include '../../../../../macros.inc'
|
||||
include '../../../../../dll.inc'
|
||||
;include '../../../../../debug.inc'
|
||||
|
||||
;start_:
|
||||
virtual at 0
|
||||
@ -151,9 +150,12 @@ load_imports:
|
||||
mov dword[ebx], eax
|
||||
jmp .handle_next_import
|
||||
.done:
|
||||
;DEBUGF 1, "Library: %s not loaded!\n", esi
|
||||
;mcall -1
|
||||
ret
|
||||
.fail:
|
||||
ret
|
||||
|
||||
;==============================
|
||||
|
||||
;==============================
|
||||
@ -200,38 +202,7 @@ load_library:
|
||||
.fail:
|
||||
mov eax, 0
|
||||
ret
|
||||
|
||||
; ==== memmove for tcc ======
|
||||
|
||||
proc memmove c, to:dword,from:dword,count:dword
|
||||
|
||||
push esi
|
||||
push edi
|
||||
mov ecx,[count]
|
||||
test ecx,ecx
|
||||
jz no_copy_block_
|
||||
mov esi,[from]
|
||||
mov edi,[to]
|
||||
cmp esi, edi
|
||||
je no_copy_block_
|
||||
jg copy_
|
||||
add esi, ecx
|
||||
add edi, ecx
|
||||
dec esi
|
||||
dec edi
|
||||
std
|
||||
copy_:
|
||||
rep movsb
|
||||
cld
|
||||
no_copy_block_:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
mov eax,[to]
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
;==============================
|
||||
|
||||
lib_init_str db 'lib_init', 0
|
||||
@ -239,7 +210,6 @@ lib_init_str db 'lib_init', 0
|
||||
public argc as '__argc'
|
||||
public params as '__argv'
|
||||
public path as '__path'
|
||||
public memmove
|
||||
|
||||
section '.bss'
|
||||
buf_len = 0x400
|
||||
@ -249,5 +219,3 @@ argv rd max_parameters
|
||||
path rb buf_len
|
||||
params rb buf_len
|
||||
|
||||
;section '.data'
|
||||
;include_debug_strings ; ALWAYS present in data section
|
||||
|
@ -1,193 +0,0 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public start
|
||||
public start as '_start'
|
||||
;extrn mf_init
|
||||
extrn main
|
||||
include '../../../../programs/proc32.inc'
|
||||
;include 'debug2.inc'
|
||||
__DEBUG__=0
|
||||
|
||||
;start_:
|
||||
virtual at 0
|
||||
db 'MENUET01' ; 1. Magic number (8 bytes)
|
||||
dd 0x01 ; 2. Version of executable file
|
||||
dd start ; 3. Start address
|
||||
dd 0x0 ; 4. Size of image
|
||||
dd 0x100000 ; 5. Size of needed memory
|
||||
dd 0x100000 ; 6. Pointer to stack
|
||||
hparams dd 0x0 ; 7. Pointer to program arguments
|
||||
hpath dd 0x0 ; 8. Pointer to program path
|
||||
end virtual
|
||||
|
||||
start:
|
||||
;DEBUGF 'Start programm\n'
|
||||
;init heap of memory
|
||||
mov eax,68
|
||||
mov ebx,11
|
||||
int 0x40
|
||||
|
||||
;DEBUGF ' path "%s"\n params "%s"\n', .path, .params
|
||||
; check for overflow
|
||||
;; that not work
|
||||
; mov al, [path+buf_len-1]
|
||||
; or al, [params+buf_len-1]
|
||||
; jnz .crash
|
||||
; check if path written by OS
|
||||
mov [argc], 0
|
||||
mov eax, [hparams]
|
||||
test eax, eax
|
||||
jz .without_path
|
||||
mov eax, path
|
||||
cmp word ptr eax, 32fh ; '/#3' UTF8
|
||||
jne .without_path
|
||||
mov word ptr eax, 12fh ; '/#1' fix to CP866
|
||||
.without_path:
|
||||
mov esi, eax
|
||||
call push_param
|
||||
; retrieving parameters
|
||||
mov esi, params
|
||||
xor edx, edx ; dl - èä¸ò ïàðàìåòð(1) èëè ðàçäåëèòåëè(0)
|
||||
; dh - ñèìâîë ñ êîòîðîãî íà÷àëñÿ ïàðàìåòð (1 êàâû÷êè, 0 îñòàëüíîå)
|
||||
mov ecx, 1 ; cl = 1
|
||||
; ch = 0 ïðîñòî íîëü
|
||||
.parse:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .run
|
||||
test dl, dl
|
||||
jnz .findendparam
|
||||
;{åñëè áûë ðàçäåëèòåëü
|
||||
cmp al, ' '
|
||||
jz .parse ;çàãðóæåí ïðîáåë, ãðóçèì ñëåäóþùèé ñèìâîë
|
||||
mov dl, cl ;íà÷èíàåòñÿ ïàðàìåòð
|
||||
cmp al, '"'
|
||||
jz @f ;çàãðóæåíû êàâû÷êè
|
||||
mov dh, ch ;ïàðàìåòð áåç êàâû÷åê
|
||||
dec esi
|
||||
call push_param
|
||||
inc esi
|
||||
jmp .parse
|
||||
|
||||
@@:
|
||||
mov dh, cl ;ïàðàìåòð â êàâû÷åêàõ
|
||||
call push_param ;åñëè íå ïðîáåë çíà÷èò íà÷èíàåòñÿ êàêîé òî ïàðàìåòð
|
||||
jmp .parse ;åñëè áûë ðàçäåëèòåëü}
|
||||
|
||||
.findendparam:
|
||||
test dh, dh
|
||||
jz @f ; áåç êàâû÷åê
|
||||
cmp al, '"'
|
||||
jz .clear
|
||||
jmp .parse
|
||||
@@:
|
||||
cmp al, ' '
|
||||
jnz .parse
|
||||
|
||||
.clear:
|
||||
lea ebx, [esi - 1]
|
||||
mov [ebx], ch
|
||||
mov dl, ch
|
||||
jmp .parse
|
||||
|
||||
.run:
|
||||
;DEBUGF 'call main(%x, %x) with params:\n', [argc], argv
|
||||
if __DEBUG__ = 1
|
||||
mov ecx, [argc]
|
||||
@@:
|
||||
lea esi, [ecx * 4 + argv-4]
|
||||
DEBUGF '0x%x) "%s"\n', cx, [esi]
|
||||
loop @b
|
||||
end if
|
||||
push argv
|
||||
push [argc]
|
||||
call main
|
||||
.exit:
|
||||
;DEBUGF 'Exit from prog\n';
|
||||
xor eax,eax
|
||||
dec eax
|
||||
int 0x40
|
||||
dd -1
|
||||
.crash:
|
||||
;DEBUGF 'E:buffer overflowed\n'
|
||||
jmp .exit
|
||||
;============================
|
||||
push_param:
|
||||
;============================
|
||||
;parameters
|
||||
; esi - pointer
|
||||
;description
|
||||
; procedure increase argc
|
||||
; and add pointer to array argv
|
||||
; procedure changes ebx
|
||||
mov ebx, [argc]
|
||||
cmp ebx, max_parameters
|
||||
jae .dont_add
|
||||
mov [argv+4*ebx], esi
|
||||
inc [argc]
|
||||
.dont_add:
|
||||
ret
|
||||
|
||||
proc memcpy c, to:dword,from:dword,count:dword
|
||||
push esi
|
||||
push edi
|
||||
mov ecx,[count]
|
||||
test ecx,ecx
|
||||
jz no_copy_block
|
||||
mov esi,[from]
|
||||
mov edi,[to]
|
||||
cld
|
||||
rep movsb
|
||||
no_copy_block:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
mov eax, [to]
|
||||
ret
|
||||
endp
|
||||
|
||||
proc memmove c, to:dword,from:dword,count:dword
|
||||
|
||||
push esi
|
||||
push edi
|
||||
mov ecx,[count]
|
||||
test ecx,ecx
|
||||
jz no_copy_block_
|
||||
mov esi,[from]
|
||||
mov edi,[to]
|
||||
cmp esi, edi
|
||||
je no_copy_block_
|
||||
jg copy_
|
||||
add esi, ecx
|
||||
add edi, ecx
|
||||
dec esi
|
||||
dec edi
|
||||
std
|
||||
copy_:
|
||||
rep movsb
|
||||
cld
|
||||
no_copy_block_:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
mov eax,[to]
|
||||
ret
|
||||
endp
|
||||
|
||||
;==============================
|
||||
public argc as '__argc'
|
||||
public params as '__argv'
|
||||
public path as '__path'
|
||||
public memcpy
|
||||
public memmove
|
||||
|
||||
section '.bss'
|
||||
buf_len = 0x400
|
||||
max_parameters=0x20
|
||||
argc rd 1
|
||||
argv rd max_parameters
|
||||
path rb buf_len
|
||||
params rb buf_len
|
||||
|
||||
;section '.data'
|
||||
;include_debug_strings ; ALWAYS present in data section
|
@ -1,158 +0,0 @@
|
||||
;-----------------------------------------------------------------------------
|
||||
; load one or more DLL file in COFF format and try to import functions by our list
|
||||
; if first function in import list begins with 'lib_', call it as DLL initialization
|
||||
; return eax = 1 as fail, if anyone of .obj file not found in /sys/lib
|
||||
; return 0 if all fine, but 0 not garantees in succesfull import - see dll.Link comment
|
||||
; dirties all registers! eax, ebx, ecx, edx, esi, edi
|
||||
proc dll.Load, import_table:dword
|
||||
mov esi, [import_table]
|
||||
.next_lib:
|
||||
mov edx, [esi]
|
||||
or edx, edx
|
||||
jz .exit
|
||||
push esi
|
||||
mov esi, [esi + 4]
|
||||
mov edi, s_libdir.fname
|
||||
@@:
|
||||
lodsb
|
||||
stosb
|
||||
or al, al
|
||||
jnz @b
|
||||
mcall 68, 19, s_libdir
|
||||
or eax, eax
|
||||
jz .fail
|
||||
stdcall dll.Link, eax, edx
|
||||
push eax
|
||||
mov eax, [eax]
|
||||
cmp dword[eax], 'lib_'
|
||||
pop eax
|
||||
jnz @f
|
||||
stdcall dll.Init, [eax + 4]
|
||||
@@:
|
||||
pop esi
|
||||
add esi, 8
|
||||
jmp .next_lib
|
||||
.exit:
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
add esp, 4
|
||||
xor eax, eax
|
||||
inc eax
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
||||
; scans dll export table for a functions we want to import
|
||||
; break scan on first unresolved import
|
||||
; no return value
|
||||
proc dll.Link, exp:dword, imp:dword
|
||||
push eax
|
||||
mov esi, [imp]
|
||||
test esi, esi
|
||||
jz .done
|
||||
.next:
|
||||
lodsd
|
||||
test eax, eax
|
||||
jz .done
|
||||
stdcall dll.GetProcAddress, [exp], eax
|
||||
or eax, eax
|
||||
jz @f
|
||||
mov [esi - 4], eax
|
||||
jmp .next
|
||||
@@:
|
||||
mov dword[esp], 0
|
||||
.done:
|
||||
pop eax
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
||||
; calls lib_init with predefined parameters
|
||||
; no return value
|
||||
proc dll.Init, dllentry:dword
|
||||
pushad
|
||||
mov eax, mem.Alloc
|
||||
mov ebx, mem.Free
|
||||
mov ecx, mem.ReAlloc
|
||||
mov edx, dll.Load
|
||||
stdcall [dllentry]
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
||||
; scans export table for a sz_name function
|
||||
; returns in eax function address or 0 if not found
|
||||
proc dll.GetProcAddress, exp:dword, sz_name:dword
|
||||
mov edx, [exp]
|
||||
xor eax, eax
|
||||
.next:
|
||||
or edx, edx
|
||||
jz .end
|
||||
cmp dword[edx], 0
|
||||
jz .end
|
||||
stdcall strcmp, [edx], [sz_name]
|
||||
test eax, eax
|
||||
jz .ok
|
||||
add edx, 8
|
||||
jmp .next
|
||||
.ok:
|
||||
mov eax, [edx + 4]
|
||||
.end:
|
||||
cmp eax, -1
|
||||
jnz @f
|
||||
xor eax, eax
|
||||
@@:
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
||||
; compares strings
|
||||
; returns eax = 0 if equal, -1 otherwise
|
||||
proc strcmp, str1:dword, str2:dword
|
||||
push esi edi
|
||||
mov esi, [str1]
|
||||
mov edi, [str2]
|
||||
xor eax, eax
|
||||
@@:
|
||||
lodsb
|
||||
scasb
|
||||
jne .fail
|
||||
or al, al
|
||||
jnz @b
|
||||
jmp .ok
|
||||
.fail:
|
||||
or eax, -1
|
||||
.ok:
|
||||
pop edi esi
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
||||
if defined dll.Load
|
||||
s_libdir:
|
||||
db '/sys/lib/'
|
||||
.fname rb 32
|
||||
end if
|
||||
;-----------------------------------------------------------------------------
|
||||
proc mem.Alloc, size
|
||||
push ebx ecx
|
||||
mov ecx, [size]
|
||||
mcall 68, 12
|
||||
pop ecx ebx
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
||||
proc mem.ReAlloc, mptr, size
|
||||
push ebx ecx edx
|
||||
mov ecx, [size]
|
||||
mov edx, [mptr]
|
||||
mcall 68, 20
|
||||
pop edx ecx ebx
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
||||
proc mem.Free, mptr
|
||||
push ebx ecx
|
||||
mov ecx,[mptr]
|
||||
mcall 68, 13
|
||||
pop ecx ebx
|
||||
ret
|
||||
endp
|
||||
;-----------------------------------------------------------------------------
|
@ -1,597 +0,0 @@
|
||||
@^ fix macro comment {
|
||||
^@ fix }
|
||||
|
||||
; --------------------------
|
||||
macro library [lname,fname]
|
||||
{
|
||||
forward
|
||||
dd __#lname#_library_table__,__#lname#_library_name__
|
||||
common
|
||||
dd 0
|
||||
forward
|
||||
align 4
|
||||
__#lname#_library_name__ db fname,0
|
||||
}
|
||||
|
||||
macro import lname,[name,sname]
|
||||
{
|
||||
common
|
||||
align 4
|
||||
__#lname#_library_table__:
|
||||
forward
|
||||
if used name
|
||||
name dd __#name#_import_name__
|
||||
end if
|
||||
common
|
||||
dd 0
|
||||
forward
|
||||
if used name
|
||||
align 4
|
||||
__#name#_import_name__ db sname,0
|
||||
end if
|
||||
}
|
||||
|
||||
macro export [name,sname]
|
||||
{
|
||||
forward
|
||||
dd __#name#_export_name__,name
|
||||
common
|
||||
dd 0
|
||||
forward
|
||||
align 4
|
||||
__#name#_export_name__ db sname,0
|
||||
}
|
||||
; -------------------------
|
||||
|
||||
macro m2m dest,src {
|
||||
push src
|
||||
pop dest
|
||||
}
|
||||
|
||||
|
||||
macro iglobal {
|
||||
IGlobals equ IGlobals,
|
||||
macro __IGlobalBlock { }
|
||||
|
||||
macro uglobal {
|
||||
UGlobals equ UGlobals,
|
||||
macro __UGlobalBlock { }
|
||||
|
||||
endg fix } ; Use endg for ending iglobal and uglobal blocks.
|
||||
|
||||
|
||||
macro IncludeIGlobals{
|
||||
macro IGlobals dummy,[n] \{ __IGlobalBlock
|
||||
purge __IGlobalBlock \}
|
||||
match I, IGlobals \{ I \} }
|
||||
|
||||
macro IncludeUGlobals{
|
||||
macro UGlobals dummy,[n] \{
|
||||
\common
|
||||
\local begin, size
|
||||
begin = $
|
||||
virtual at $
|
||||
\forward
|
||||
__UGlobalBlock
|
||||
purge __UGlobalBlock
|
||||
\common
|
||||
size = $ - begin
|
||||
end virtual
|
||||
rb size
|
||||
\}
|
||||
match U, UGlobals \{ U \} }
|
||||
|
||||
uglobal
|
||||
endg
|
||||
|
||||
iglobal
|
||||
endg
|
||||
|
||||
|
||||
; new application structure
|
||||
macro meos_app_start
|
||||
{
|
||||
use32
|
||||
org 0x0
|
||||
|
||||
db 'MENUET01'
|
||||
dd 0x01
|
||||
dd __start
|
||||
dd __end
|
||||
dd __memory
|
||||
dd __stack
|
||||
|
||||
if used __params & ~defined __params
|
||||
dd __params
|
||||
else
|
||||
dd 0x0
|
||||
end if
|
||||
|
||||
dd 0x0
|
||||
}
|
||||
MEOS_APP_START fix meos_app_start
|
||||
KOS_APP_START fix meos_app_start
|
||||
|
||||
macro code
|
||||
{
|
||||
__start:
|
||||
}
|
||||
CODE fix code
|
||||
|
||||
macro data
|
||||
{
|
||||
__data:
|
||||
IncludeIGlobals
|
||||
}
|
||||
DATA fix data
|
||||
|
||||
macro udata
|
||||
{
|
||||
if used __params & ~defined __params
|
||||
__params:
|
||||
db 0
|
||||
__end:
|
||||
rb 255
|
||||
else
|
||||
__end:
|
||||
end if
|
||||
__udata:
|
||||
IncludeUGlobals
|
||||
}
|
||||
UDATA fix udata
|
||||
|
||||
macro meos_app_end
|
||||
{
|
||||
align 32
|
||||
rb 2048
|
||||
__stack:
|
||||
__memory:
|
||||
}
|
||||
MEOS_APP_END fix meos_app_end
|
||||
KOS_APP_END fix meos_app_end
|
||||
|
||||
|
||||
; macro for defining multiline text data
|
||||
struc mstr [sstring]
|
||||
{
|
||||
forward
|
||||
local ssize
|
||||
virtual at 0
|
||||
db sstring
|
||||
ssize = $
|
||||
end virtual
|
||||
dd ssize
|
||||
db sstring
|
||||
common
|
||||
dd -1
|
||||
}
|
||||
|
||||
; macro for defining multiline text data
|
||||
struc mls [sstring]
|
||||
{
|
||||
forward
|
||||
local ssize
|
||||
virtual at 0
|
||||
db sstring ; mod
|
||||
ssize = $
|
||||
end virtual
|
||||
db ssize
|
||||
db sstring
|
||||
common
|
||||
db -1 ; mod
|
||||
}
|
||||
|
||||
|
||||
|
||||
; strings
|
||||
macro sz name,[data] { ; [mike.dld]
|
||||
common
|
||||
if used name
|
||||
name db data
|
||||
.size = $-name
|
||||
end if
|
||||
}
|
||||
|
||||
macro szZ name,[data] { ; same as sz, but for zero terminated string [dunkaist]
|
||||
common
|
||||
if used name
|
||||
name db data,0
|
||||
.size = $-name-1
|
||||
end if
|
||||
}
|
||||
sz0 fix szZ
|
||||
|
||||
macro lsz name,[lng,data] { ; [mike.dld]
|
||||
common
|
||||
if used name
|
||||
label name
|
||||
forward
|
||||
if lang eq lng
|
||||
db data
|
||||
end if
|
||||
common
|
||||
.size = $-name
|
||||
end if
|
||||
}
|
||||
|
||||
macro szc name,elsz,[data] { ; [mike.dld]
|
||||
common
|
||||
local s,m
|
||||
m = 0
|
||||
if used name
|
||||
label name
|
||||
forward
|
||||
virtual at 0
|
||||
db data
|
||||
s = $
|
||||
end virtual
|
||||
d#elsz s
|
||||
if m < s
|
||||
m = s
|
||||
end if
|
||||
db data
|
||||
common
|
||||
.size = $-name
|
||||
.maxl = m
|
||||
end if
|
||||
}
|
||||
|
||||
macro lszc name,elsz,[lng,data] { ; [mike.dld]
|
||||
common
|
||||
local s,m,c
|
||||
m = 0
|
||||
c = 0
|
||||
if used name
|
||||
label name
|
||||
forward
|
||||
if lang eq lng
|
||||
virtual at 0
|
||||
db data
|
||||
s = $
|
||||
end virtual
|
||||
d#elsz s
|
||||
if m < s
|
||||
m = s
|
||||
end if
|
||||
db data
|
||||
c = c+1
|
||||
end if
|
||||
common
|
||||
.size = $-name
|
||||
.maxl = m
|
||||
.count = c
|
||||
end if
|
||||
}
|
||||
|
||||
|
||||
; easy system call macro
|
||||
macro mpack dest, hsrc, lsrc
|
||||
{
|
||||
if (hsrc eqtype 0) & (lsrc eqtype 0)
|
||||
mov dest, (hsrc) shl 16 + lsrc
|
||||
else
|
||||
if (hsrc eqtype 0) & (~lsrc eqtype 0)
|
||||
mov dest, (hsrc) shl 16
|
||||
add dest, lsrc
|
||||
else
|
||||
mov dest, hsrc
|
||||
shl dest, 16
|
||||
add dest, lsrc
|
||||
end if
|
||||
end if
|
||||
}
|
||||
|
||||
macro __mov reg,a,b { ; mike.dld
|
||||
if (~a eq)&(~b eq)
|
||||
mpack reg,a,b
|
||||
else if (~a eq)&(b eq)
|
||||
mov reg,a
|
||||
end if
|
||||
}
|
||||
|
||||
|
||||
include 'config.inc'
|
||||
;__CPU_type equ p5
|
||||
SYSENTER_VAR equ 0
|
||||
|
||||
macro mcall a,b,c,d,e,f,g { ; [mike.dld], [Ghost]
|
||||
local ..ret_point
|
||||
__mov eax,a
|
||||
__mov ebx,b
|
||||
__mov ecx,c
|
||||
__mov edx,d
|
||||
__mov esi,e
|
||||
__mov edi,f
|
||||
__mov ebp,g
|
||||
|
||||
if __CPU_type eq p5
|
||||
int 0x40
|
||||
else
|
||||
if __CPU_type eq p6
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push ..ret_point ; it may be 2 or 5 byte
|
||||
sysenter
|
||||
..ret_point:
|
||||
pop edx
|
||||
pop ecx
|
||||
|
||||
else
|
||||
if __CPU_type eq k6
|
||||
push ecx
|
||||
syscall
|
||||
pop ecx
|
||||
else
|
||||
display 'ERROR : unknown CPU type (set to p5)', 10, 13
|
||||
__CPU_type equ p5
|
||||
int 0x40
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
}
|
||||
|
||||
|
||||
; -------------------------
|
||||
macro __header a,[b] {
|
||||
common
|
||||
use32
|
||||
org 0
|
||||
db 'MENUET',a
|
||||
forward
|
||||
if b eq
|
||||
dd 0
|
||||
else
|
||||
dd b
|
||||
end if
|
||||
}
|
||||
|
||||
macro __section name {
|
||||
align 16
|
||||
label name
|
||||
}
|
||||
|
||||
macro __func name {
|
||||
if ~used name
|
||||
display 'FUNC NOT USED: ',`name,13,10
|
||||
else
|
||||
align 4
|
||||
name:
|
||||
;diff16 `name,0,name
|
||||
}
|
||||
|
||||
macro endf { end if }
|
||||
|
||||
macro diff16 title,l1,l2
|
||||
{
|
||||
local s,d
|
||||
s = l2-l1
|
||||
display title,': 0x'
|
||||
repeat 8
|
||||
d = '0' + s shr ((8-%) shl 2) and $0F
|
||||
if d > '9'
|
||||
d = d + 'A'-'9'-1
|
||||
end if
|
||||
display d
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
macro diff10 title,l1,l2
|
||||
{
|
||||
local s,d,z,m
|
||||
s = l2-l1
|
||||
z = 0
|
||||
m = 1000000000
|
||||
display title,': '
|
||||
repeat 10
|
||||
d = '0' + s / m
|
||||
s = s - (s/m)*m
|
||||
m = m / 10
|
||||
if d <> '0'
|
||||
z = 1
|
||||
end if
|
||||
if z <> 0
|
||||
display d
|
||||
end if
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
|
||||
macro movi arg1,arg2
|
||||
{
|
||||
if (arg1 in <eax,ebx,ecx,edx,esi,edi,ebp,esp>) & ((arg2 eqtype 0) | (arg2 eqtype '0'))
|
||||
if (arg2) = 0
|
||||
xor arg1,arg1
|
||||
else if (arg2) = 1
|
||||
xor arg1,arg1
|
||||
inc arg1
|
||||
else if (arg2) = -1
|
||||
or arg1,-1
|
||||
else if (arg2) >= -128 & (arg2) <= 127
|
||||
push arg2
|
||||
pop arg1
|
||||
else
|
||||
mov arg1,arg2
|
||||
end if
|
||||
else
|
||||
mov arg1,arg2
|
||||
end if
|
||||
}
|
||||
|
||||
|
||||
macro RGB [a] {
|
||||
common
|
||||
match (r=,g=,b),a \{
|
||||
\dd ((r) shl 16) or ((g) shl 8) or (b)
|
||||
\}
|
||||
}
|
||||
|
||||
|
||||
struc POINT _t,_dx,_dy {
|
||||
.x _t _dx
|
||||
.y _t _dy
|
||||
}
|
||||
|
||||
; structure definition helper
|
||||
include 'struct.inc'
|
||||
|
||||
struct RECT
|
||||
left dd ?
|
||||
top dd ?
|
||||
right dd ?
|
||||
bottom dd ?
|
||||
ends
|
||||
|
||||
struct BOX
|
||||
left dd ?
|
||||
top dd ?
|
||||
width dd ?
|
||||
height dd ?
|
||||
ends
|
||||
|
||||
; structures used in KolibriOS
|
||||
struct process_information
|
||||
cpu_usage dd ? ; +0
|
||||
window_stack_position dw ? ; +4
|
||||
window_stack_value dw ? ; +6
|
||||
dw ? ; +8
|
||||
process_name rb 12 ; +10
|
||||
memory_start dd ? ; +22
|
||||
used_memory dd ? ; +26
|
||||
PID dd ? ; +30
|
||||
box BOX ; +34
|
||||
slot_state dw ? ; +50
|
||||
dw ? ; +52
|
||||
client_box BOX ; +54
|
||||
wnd_state db ? ; +70
|
||||
rb (1024-71)
|
||||
ends
|
||||
|
||||
struct system_colors
|
||||
frame dd ? ;nonset1
|
||||
grab dd ? ;nonset2
|
||||
work_dark dd ?
|
||||
work_light dd ?
|
||||
grab_text dd ? ;window_title
|
||||
work dd ?
|
||||
work_button dd ?
|
||||
work_button_text dd ?
|
||||
work_text dd ?
|
||||
work_graph dd ?
|
||||
ends
|
||||
|
||||
struct FILEDATE
|
||||
Second db ?
|
||||
Minute db ?
|
||||
Hour db ?
|
||||
db ?
|
||||
Day db ?
|
||||
Month db ?
|
||||
Year dw ?
|
||||
ends
|
||||
|
||||
struct FILEINFO
|
||||
Attributes dd ?
|
||||
IsUnicode db ?
|
||||
db 3 dup(?)
|
||||
DateCreate FILEDATE
|
||||
DateAccess FILEDATE
|
||||
DateModify FILEDATE
|
||||
Size dq ?
|
||||
ends
|
||||
|
||||
cmove fix cmovz
|
||||
|
||||
macro cmovz reg1, reg2 {
|
||||
|
||||
local ..jumpaddr
|
||||
|
||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
||||
jnz ..jumpaddr
|
||||
mov reg1, reg2
|
||||
..jumpaddr:
|
||||
else
|
||||
cmovz reg1, reg2
|
||||
end if
|
||||
|
||||
}
|
||||
|
||||
cmovne fix cmovnz
|
||||
|
||||
macro cmovnz reg1, reg2 {
|
||||
|
||||
local ..jumpaddr
|
||||
|
||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
||||
jz ..jumpaddr
|
||||
mov reg1, reg2
|
||||
..jumpaddr:
|
||||
else
|
||||
cmovnz reg1, reg2
|
||||
end if
|
||||
|
||||
}
|
||||
|
||||
macro cmovg reg1, reg2 {
|
||||
|
||||
local ..jumpaddr
|
||||
|
||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
||||
jle ..jumpaddr
|
||||
mov reg1, reg2
|
||||
..jumpaddr:
|
||||
else
|
||||
cmovg reg1, reg2
|
||||
end if
|
||||
}
|
||||
|
||||
macro cmovl reg1, reg2 {
|
||||
|
||||
local ..jumpaddr
|
||||
|
||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
||||
jge ..jumpaddr
|
||||
mov reg1, reg2
|
||||
..jumpaddr:
|
||||
else
|
||||
cmovl reg1, reg2
|
||||
end if
|
||||
}
|
||||
|
||||
; replaces /programs/cmp.inc
|
||||
irp cond, e, ne, g, ng, l, nl, ge, le {
|
||||
macro cmp#cond a, b, c\{
|
||||
cmp a, b
|
||||
j#cond c
|
||||
\}
|
||||
}
|
||||
|
||||
; constants
|
||||
|
||||
; events
|
||||
EV_IDLE = 0
|
||||
EV_TIMER = 0
|
||||
EV_REDRAW = 1
|
||||
EV_KEY = 2
|
||||
EV_BUTTON = 3
|
||||
EV_EXIT = 4
|
||||
EV_BACKGROUND = 5
|
||||
EV_MOUSE = 6
|
||||
EV_IPC = 7
|
||||
EV_STACK = 8
|
||||
|
||||
; event mask bits for function 40
|
||||
EVM_REDRAW = 1b
|
||||
EVM_KEY = 10b
|
||||
EVM_BUTTON = 100b
|
||||
EVM_EXIT = 1000b
|
||||
EVM_BACKGROUND = 10000b
|
||||
EVM_MOUSE = 100000b
|
||||
EVM_IPC = 1000000b
|
||||
EVM_STACK = 10000000b
|
||||
EVM_DEBUG = 100000000b
|
||||
EVM_STACK2 = 1000000000b
|
||||
|
||||
EVM_MOUSE_FILTER = 0x80000000
|
||||
EVM_CURSOR_FILTER = 0x40000000
|
@ -1,301 +0,0 @@
|
||||
|
||||
; Macroinstructions for defining and calling procedures
|
||||
|
||||
macro stdcall proc,[arg] ; directly call STDCALL procedure
|
||||
{ common
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
common
|
||||
end if
|
||||
call proc }
|
||||
|
||||
macro invoke proc,[arg] ; indirectly call STDCALL procedure
|
||||
{ common
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
common
|
||||
end if
|
||||
call [proc] }
|
||||
|
||||
macro ccall proc,[arg] ; directly call CDECL procedure
|
||||
{ common
|
||||
size@ccall = 0
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
size@ccall = size@ccall+4
|
||||
common
|
||||
end if
|
||||
call proc
|
||||
if size@ccall
|
||||
add esp,size@ccall
|
||||
end if }
|
||||
|
||||
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
|
||||
{ common
|
||||
size@ccall = 0
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
size@ccall = size@ccall+4
|
||||
common
|
||||
end if
|
||||
call [proc]
|
||||
if size@ccall
|
||||
add esp,size@ccall
|
||||
end if }
|
||||
|
||||
macro proc [args] ; define procedure
|
||||
{ common
|
||||
match name params, args>
|
||||
\{ define@proc name,<params \} }
|
||||
|
||||
prologue@proc equ prologuedef
|
||||
|
||||
macro prologuedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ local loc
|
||||
loc = (localbytes+3) and (not 3)
|
||||
parmbase@proc equ ebp+8
|
||||
localbase@proc equ ebp-loc
|
||||
if parmbytes | localbytes
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
if localbytes
|
||||
sub esp,loc
|
||||
end if
|
||||
end if
|
||||
irps reg, reglist \{ push reg \} }
|
||||
|
||||
epilogue@proc equ epiloguedef
|
||||
|
||||
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ irps reg, reglist \{ reverse pop reg \}
|
||||
if parmbytes | localbytes
|
||||
leave
|
||||
end if
|
||||
if flag and 10000b
|
||||
retn
|
||||
else
|
||||
retn parmbytes
|
||||
end if }
|
||||
|
||||
close@proc equ
|
||||
|
||||
macro define@proc name,statement
|
||||
{ local params,flag,regs,parmbytes,localbytes,current
|
||||
if used name
|
||||
name:
|
||||
match =stdcall args, statement \{ params equ args
|
||||
flag = 11b \}
|
||||
match =stdcall, statement \{ params equ
|
||||
flag = 11b \}
|
||||
match =c args, statement \{ params equ args
|
||||
flag = 10001b \}
|
||||
match =c, statement \{ params equ
|
||||
flag = 10001b \}
|
||||
match =params, params \{ params equ statement
|
||||
flag = 0 \}
|
||||
match =uses reglist=,args, params \{ regs equ reglist
|
||||
params equ args \}
|
||||
match =regs =uses reglist, regs params \{ regs equ reglist
|
||||
params equ \}
|
||||
match =regs, regs \{ regs equ \}
|
||||
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
|
||||
virtual at parmbase@proc
|
||||
match =,args, params \{ defargs@proc args \}
|
||||
match =args@proc args, args@proc params \{ defargs@proc args \}
|
||||
parmbytes = $-(parmbase@proc)
|
||||
end virtual
|
||||
name # % = parmbytes/4
|
||||
all@vars equ
|
||||
current = 0
|
||||
macro locals
|
||||
\{ virtual at localbase@proc+current
|
||||
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
|
||||
struc db [val] \\{ \common deflocal@proc .,db,val \\}
|
||||
struc du [val] \\{ \common deflocal@proc .,du,val \\}
|
||||
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
|
||||
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
|
||||
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
|
||||
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
|
||||
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
|
||||
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
|
||||
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
|
||||
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
|
||||
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
|
||||
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
|
||||
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
|
||||
macro endl
|
||||
\{ purge label
|
||||
restruc db,du,dw,dp,dd,dt,dq
|
||||
restruc rb,rw,rp,rd,rt,rq
|
||||
current = $-(localbase@proc)
|
||||
end virtual \}
|
||||
macro ret operand
|
||||
\{ match any, operand \\{ retn operand \\}
|
||||
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
|
||||
macro finish@proc
|
||||
\{ localbytes = current
|
||||
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
|
||||
end if \} }
|
||||
|
||||
macro defargs@proc [arg]
|
||||
{ common
|
||||
if ~ arg eq
|
||||
forward
|
||||
local ..arg,current@arg
|
||||
match argname:type, arg
|
||||
\{ current@arg equ argname
|
||||
label ..arg type
|
||||
argname equ ..arg
|
||||
if qqword eq type
|
||||
dd ?,?,?,?,?,?,?,?
|
||||
else if dqword eq type
|
||||
dd ?,?,?,?
|
||||
else if tbyte eq type
|
||||
dd ?,?,?
|
||||
else if qword eq type | pword eq type
|
||||
dd ?,?
|
||||
else
|
||||
dd ?
|
||||
end if \}
|
||||
match =current@arg,current@arg
|
||||
\{ current@arg equ arg
|
||||
arg equ ..arg
|
||||
..arg dd ? \}
|
||||
common
|
||||
args@proc equ current@arg
|
||||
forward
|
||||
restore current@arg
|
||||
common
|
||||
end if }
|
||||
|
||||
macro deflocal@proc name,def,[val] { name def val }
|
||||
|
||||
macro deflocal@proc name,def,[val]
|
||||
{ common
|
||||
match vars, all@vars \{ all@vars equ all@vars, \}
|
||||
all@vars equ all@vars name
|
||||
forward
|
||||
local ..var,..tmp
|
||||
..var def val
|
||||
match =?, val \{ ..tmp equ \}
|
||||
match any =?, val \{ ..tmp equ \}
|
||||
match any (=?), val \{ ..tmp equ \}
|
||||
match =label, def \{ ..tmp equ \}
|
||||
match tmp : value, ..tmp : val
|
||||
\{ tmp: end virtual
|
||||
initlocal@proc ..var,def value
|
||||
virtual at tmp\}
|
||||
common
|
||||
match first rest, ..var, \{ name equ first \} }
|
||||
|
||||
struc label type { label . type }
|
||||
|
||||
macro initlocal@proc name,def
|
||||
{ virtual at name
|
||||
def
|
||||
size@initlocal = $ - name
|
||||
end virtual
|
||||
position@initlocal = 0
|
||||
while size@initlocal > position@initlocal
|
||||
virtual at name
|
||||
def
|
||||
if size@initlocal - position@initlocal < 2
|
||||
current@initlocal = 1
|
||||
load byte@initlocal byte from name+position@initlocal
|
||||
else if size@initlocal - position@initlocal < 4
|
||||
current@initlocal = 2
|
||||
load word@initlocal word from name+position@initlocal
|
||||
else
|
||||
current@initlocal = 4
|
||||
load dword@initlocal dword from name+position@initlocal
|
||||
end if
|
||||
end virtual
|
||||
if current@initlocal = 1
|
||||
mov byte [name+position@initlocal],byte@initlocal
|
||||
else if current@initlocal = 2
|
||||
mov word [name+position@initlocal],word@initlocal
|
||||
else
|
||||
mov dword [name+position@initlocal],dword@initlocal
|
||||
end if
|
||||
position@initlocal = position@initlocal + current@initlocal
|
||||
end while }
|
||||
|
||||
macro endp
|
||||
{ purge ret,locals,endl
|
||||
finish@proc
|
||||
purge finish@proc
|
||||
restore regs@proc
|
||||
match all,args@proc \{ restore all \}
|
||||
restore args@proc
|
||||
match all,all@vars \{ restore all \} }
|
||||
|
||||
macro local [var]
|
||||
{ common
|
||||
locals
|
||||
forward done@local equ
|
||||
match varname[count]:vartype, var
|
||||
\{ match =BYTE, vartype \\{ varname rb count
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname rw count
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname rd count
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname rp count
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname rq count
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname rt count
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
rq count*2
|
||||
restore done@local \\}
|
||||
match =QQWORD, vartype \\{ label varname qqword
|
||||
rq count*4
|
||||
restore done@local \\}
|
||||
match =XWORD, vartype \\{ label varname xword
|
||||
rq count*2
|
||||
restore done@local \\}
|
||||
match =YWORD, vartype \\{ label varname yword
|
||||
rq count*4
|
||||
restore done@local \\}
|
||||
match , done@local \\{ virtual
|
||||
varname vartype
|
||||
end virtual
|
||||
rb count*sizeof.\#vartype
|
||||
restore done@local \\} \}
|
||||
match :varname:vartype, done@local:var
|
||||
\{ match =BYTE, vartype \\{ varname db ?
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname dw ?
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname dd ?
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname dp ?
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname dq ?
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname dt ?
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
dq ?,?
|
||||
restore done@local \\}
|
||||
match =QQWORD, vartype \\{ label varname qqword
|
||||
dq ?,?,?,?
|
||||
restore done@local \\}
|
||||
match =XWORD, vartype \\{ label varname xword
|
||||
dq ?,?
|
||||
restore done@local \\}
|
||||
match =YWORD, vartype \\{ label varname yword
|
||||
dq ?,?,?,?
|
||||
restore done@local \\}
|
||||
match , done@local \\{ varname vartype
|
||||
restore done@local \\} \}
|
||||
match ,done@local
|
||||
\{ var
|
||||
restore done@local \}
|
||||
common
|
||||
endl }
|
@ -1,240 +0,0 @@
|
||||
|
||||
; Macroinstructions for defining data structures
|
||||
|
||||
macro struct name
|
||||
{ virtual at 0
|
||||
fields@struct equ name
|
||||
match child parent, name \{ fields@struct equ child,fields@\#parent \}
|
||||
sub@struct equ
|
||||
struc db [val] \{ \common define field@struct .,db,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dw [val] \{ \common define field@struct .,dw,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc du [val] \{ \common define field@struct .,du,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dd [val] \{ \common define field@struct .,dd,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dp [val] \{ \common define field@struct .,dp,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dq [val] \{ \common define field@struct .,dq,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc dt [val] \{ \common define field@struct .,dt,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rb count \{ define field@struct .,db,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rw count \{ define field@struct .,dw,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rd count \{ define field@struct .,dd,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rp count \{ define field@struct .,dp,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rq count \{ define field@struct .,dq,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
struc rt count \{ define field@struct .,dt,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro db [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,db,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dw [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dw,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro du [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,du,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dd [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dd,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dp [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dp,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dq [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dq,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro dt [val] \{ \common \local anonymous
|
||||
define field@struct anonymous,dt,<val>
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rb count \{ \local anonymous
|
||||
define field@struct anonymous,db,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rw count \{ \local anonymous
|
||||
define field@struct anonymous,dw,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rd count \{ \local anonymous
|
||||
define field@struct anonymous,dd,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rp count \{ \local anonymous
|
||||
define field@struct anonymous,dp,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rq count \{ \local anonymous
|
||||
define field@struct anonymous,dq,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro rt count \{ \local anonymous
|
||||
define field@struct anonymous,dt,count dup (?)
|
||||
fields@struct equ fields@struct,field@struct \}
|
||||
macro union \{ fields@struct equ fields@struct,,union,<
|
||||
sub@struct equ union \}
|
||||
macro struct \{ fields@struct equ fields@struct,,substruct,<
|
||||
sub@struct equ substruct \} }
|
||||
|
||||
macro ends
|
||||
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
|
||||
restruc rb,rw,rd,rp,rq,rt
|
||||
purge db,dw,du,dd,dp,dq,dt
|
||||
purge rb,rw,rd,rp,rq,rt
|
||||
purge union,struct
|
||||
match name tail,fields@struct, \\{ if $
|
||||
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
|
||||
err
|
||||
end if \\}
|
||||
match name=,fields,fields@struct \\{ fields@struct equ
|
||||
make@struct name,fields
|
||||
define fields@\\#name fields \\}
|
||||
end virtual \}
|
||||
match any, sub@struct \{ fields@struct equ fields@struct> \}
|
||||
restore sub@struct }
|
||||
|
||||
macro make@struct name,[field,type,def]
|
||||
{ common
|
||||
local define
|
||||
define equ name
|
||||
forward
|
||||
local sub
|
||||
match , field \{ make@substruct type,name,sub def
|
||||
define equ define,.,sub, \}
|
||||
match any, field \{ define equ define,.#field,type,<def> \}
|
||||
common
|
||||
match fields, define \{ define@struct fields \} }
|
||||
|
||||
macro define@struct name,[field,type,def]
|
||||
{ common
|
||||
virtual
|
||||
db `name
|
||||
load initial@struct byte from 0
|
||||
if initial@struct = '.'
|
||||
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
|
||||
err
|
||||
end if
|
||||
end virtual
|
||||
local list
|
||||
list equ
|
||||
forward
|
||||
if ~ field eq .
|
||||
name#field type def
|
||||
sizeof.#name#field = $ - name#field
|
||||
else
|
||||
label name#.#type
|
||||
rb sizeof.#type
|
||||
end if
|
||||
local value
|
||||
match any, list \{ list equ list, \}
|
||||
list equ list <value>
|
||||
common
|
||||
sizeof.#name = $
|
||||
restruc name
|
||||
match values, list \{
|
||||
struc name value \\{ \\local \\..base
|
||||
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
|
||||
match , fields@struct \\\{ label \\..base
|
||||
forward
|
||||
match , value \\\\{ field type def \\\\}
|
||||
match any, value \\\\{ field type value
|
||||
if ~ field eq .
|
||||
rb sizeof.#name#field - ($-field)
|
||||
end if \\\\}
|
||||
common label . at \\..base \\\}
|
||||
\\}
|
||||
macro name value \\{
|
||||
match any, fields@struct \\\{ \\\local anonymous
|
||||
fields@struct equ fields@struct,anonymous,name,<values> \\\}
|
||||
match , fields@struct \\\{
|
||||
forward
|
||||
match , value \\\\{ type def \\\\}
|
||||
match any, value \\\\{ \\\\local ..field
|
||||
..field = $
|
||||
type value
|
||||
if ~ field eq .
|
||||
rb sizeof.#name#field - ($-..field)
|
||||
end if \\\\}
|
||||
common \\\} \\} \} }
|
||||
|
||||
macro enable@substruct
|
||||
{ macro make@substruct substruct,parent,name,[field,type,def]
|
||||
\{ \common
|
||||
\local define
|
||||
define equ parent,name
|
||||
\forward
|
||||
\local sub
|
||||
match , field \\{ match any, type \\\{ enable@substruct
|
||||
make@substruct type,parent,sub def
|
||||
purge make@substruct
|
||||
define equ define,.,sub, \\\} \\}
|
||||
match any, field \\{ define equ define,.\#field,type,<def> \\}
|
||||
\common
|
||||
match fields, define \\{ define@\#substruct fields \\} \} }
|
||||
|
||||
enable@substruct
|
||||
|
||||
macro define@union parent,name,[field,type,def]
|
||||
{ common
|
||||
virtual at parent#.#name
|
||||
forward
|
||||
if ~ field eq .
|
||||
virtual at parent#.#name
|
||||
parent#field type def
|
||||
sizeof.#parent#field = $ - parent#field
|
||||
end virtual
|
||||
if sizeof.#parent#field > $ - parent#.#name
|
||||
rb sizeof.#parent#field - ($ - parent#.#name)
|
||||
end if
|
||||
else
|
||||
virtual at parent#.#name
|
||||
label parent#.#type
|
||||
type def
|
||||
end virtual
|
||||
label name#.#type at parent#.#name
|
||||
if sizeof.#type > $ - parent#.#name
|
||||
rb sizeof.#type - ($ - parent#.#name)
|
||||
end if
|
||||
end if
|
||||
common
|
||||
sizeof.#name = $ - parent#.#name
|
||||
end virtual
|
||||
struc name [value] \{ \common
|
||||
label .\#name
|
||||
last@union equ
|
||||
forward
|
||||
match any, last@union \\{ virtual at .\#name
|
||||
field type def
|
||||
end virtual \\}
|
||||
match , last@union \\{ match , value \\\{ field type def \\\}
|
||||
match any, value \\\{ field type value \\\} \\}
|
||||
last@union equ field
|
||||
common rb sizeof.#name - ($ - .\#name) \}
|
||||
macro name [value] \{ \common \local ..anonymous
|
||||
..anonymous name value \} }
|
||||
|
||||
macro define@substruct parent,name,[field,type,def]
|
||||
{ common
|
||||
virtual at parent#.#name
|
||||
forward
|
||||
if ~ field eq .
|
||||
parent#field type def
|
||||
sizeof.#parent#field = $ - parent#field
|
||||
else
|
||||
label parent#.#type
|
||||
rb sizeof.#type
|
||||
end if
|
||||
common
|
||||
sizeof.#name = $ - parent#.#name
|
||||
end virtual
|
||||
struc name value \{
|
||||
label .\#name
|
||||
forward
|
||||
match , value \\{ field type def \\}
|
||||
match any, value \\{ field type value
|
||||
if ~ field eq .
|
||||
rb sizeof.#parent#field - ($-field)
|
||||
end if \\}
|
||||
common \}
|
||||
macro name value \{ \local ..anonymous
|
||||
..anonymous name \} }
|
@ -8,7 +8,6 @@
|
||||
#include "sys/closedir.c"
|
||||
|
||||
#include "stdio/clearerr.c"
|
||||
#include "stdio/vscanf.c"
|
||||
#include "stdio/gets.c"
|
||||
#include "stdio/setbuf.c"
|
||||
#include "stdio/fgetc.c"
|
||||
@ -21,7 +20,6 @@
|
||||
#include "stdio/fseek.c"
|
||||
#include "stdio/fgetpos.c"
|
||||
#include "stdio/fclose.c"
|
||||
#include "stdio/vsscanf.c"
|
||||
#include "stdio/snprintf.c"
|
||||
#include "stdio/rename.c"
|
||||
#include "stdio/getchar.c"
|
||||
@ -31,7 +29,6 @@
|
||||
#include "stdio/fputs.c"
|
||||
#include "stdio/fputc.c"
|
||||
#include "stdio/fgets.c"
|
||||
#include "stdio/vfscanf.c"
|
||||
#include "stdio/fflush.c"
|
||||
#include "stdio/format_scan.c"
|
||||
#include "stdio/printf.c"
|
||||
@ -93,7 +90,6 @@
|
||||
#include "stdlib/difftime.c"
|
||||
#include "stdlib/realloc.c"
|
||||
#include "stdlib/ldiv.c"
|
||||
#include "stdlib/libtcc1.c"
|
||||
#include "stdlib/abs.c"
|
||||
#include "stdlib/div.c"
|
||||
#include "stdlib/atol.c"
|
||||
@ -138,4 +134,4 @@ __asm__(
|
||||
|
||||
#include "stdlib/___chkstk_ms.c"
|
||||
|
||||
#include "exports/exports.c"
|
||||
#include "exports/exports.c"
|
||||
|
17
programs/develop/libraries/kolibri-libc/source/libtcc/Makefile
Executable file
17
programs/develop/libraries/kolibri-libc/source/libtcc/Makefile
Executable file
@ -0,0 +1,17 @@
|
||||
KTCC_DIR=../../../../ktcc/trunk
|
||||
|
||||
KTCC=$(KTCC_DIR)/bin/kos32-tcc
|
||||
FASM=fasm
|
||||
|
||||
OBJ= memcpy.o memmove.o memset.o libtcc1.o
|
||||
|
||||
all: $(OBJ)
|
||||
ar -crs ../../lib/libtcc.a $(OBJ)
|
||||
rm -f *.o
|
||||
|
||||
%.o : %.c
|
||||
$(KTCC) -c $< -o $@
|
||||
|
||||
%.o : %.asm
|
||||
$(FASM) $< $@
|
||||
|
763
programs/develop/libraries/kolibri-libc/source/libtcc/libtcc1.c
Normal file
763
programs/develop/libraries/kolibri-libc/source/libtcc/libtcc1.c
Normal file
@ -0,0 +1,763 @@
|
||||
/* TCC runtime library.
|
||||
Parts of this code are (c) 2002 Fabrice Bellard
|
||||
|
||||
Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file 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 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file into combinations with other programs,
|
||||
and to distribute those combinations without any restriction coming
|
||||
from the use of this file. (The General Public License restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
This file 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//#include <stdint.h>
|
||||
#define TCC_TARGET_I386
|
||||
|
||||
#define W_TYPE_SIZE 32
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
typedef int Wtype;
|
||||
typedef unsigned int UWtype;
|
||||
typedef unsigned int USItype;
|
||||
typedef long long DWtype;
|
||||
typedef unsigned long long UDWtype;
|
||||
|
||||
struct DWstruct {
|
||||
Wtype low, high;
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct DWstruct s;
|
||||
DWtype ll;
|
||||
} DWunion;
|
||||
|
||||
typedef long double XFtype;
|
||||
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
||||
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
||||
|
||||
/* the following deal with IEEE single-precision numbers */
|
||||
#define EXCESS 126
|
||||
#define SIGNBIT 0x80000000
|
||||
#define HIDDEN (1 << 23)
|
||||
#define SIGN(fp) ((fp) & SIGNBIT)
|
||||
#define EXP(fp) (((fp) >> 23) & 0xFF)
|
||||
#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN)
|
||||
#define PACK(s,e,m) ((s) | ((e) << 23) | (m))
|
||||
|
||||
/* the following deal with IEEE double-precision numbers */
|
||||
#define EXCESSD 1022
|
||||
#define HIDDEND (1 << 20)
|
||||
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
|
||||
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
|
||||
#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
|
||||
(fp.l.lower >> 22))
|
||||
#define HIDDEND_LL ((long long)1 << 52)
|
||||
#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
|
||||
#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
|
||||
|
||||
/* the following deal with x86 long double-precision numbers */
|
||||
#define EXCESSLD 16382
|
||||
#define EXPLD(fp) (fp.l.upper & 0x7fff)
|
||||
#define SIGNLD(fp) ((fp.l.upper) & 0x8000)
|
||||
|
||||
/* only for x86 */
|
||||
union ldouble_long {
|
||||
long double ld;
|
||||
struct {
|
||||
unsigned long long lower;
|
||||
unsigned short upper;
|
||||
} l;
|
||||
};
|
||||
|
||||
union double_long {
|
||||
double d;
|
||||
#if 1
|
||||
struct {
|
||||
unsigned int lower;
|
||||
int upper;
|
||||
} l;
|
||||
#else
|
||||
struct {
|
||||
int upper;
|
||||
unsigned int lower;
|
||||
} l;
|
||||
#endif
|
||||
long long ll;
|
||||
};
|
||||
|
||||
union float_long {
|
||||
float f;
|
||||
unsigned int l;
|
||||
};
|
||||
|
||||
/* XXX: we don't support several builtin supports for now */
|
||||
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM)
|
||||
|
||||
/* XXX: use gcc/tcc intrinsic ? */
|
||||
#if defined(TCC_TARGET_I386)
|
||||
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
||||
__asm__ ("subl %5,%1\n\tsbbl %3,%0" \
|
||||
: "=r" ((USItype) (sh)), \
|
||||
"=&r" ((USItype) (sl)) \
|
||||
: "0" ((USItype) (ah)), \
|
||||
"g" ((USItype) (bh)), \
|
||||
"1" ((USItype) (al)), \
|
||||
"g" ((USItype) (bl)))
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__ ("mull %3" \
|
||||
: "=a" ((USItype) (w0)), \
|
||||
"=d" ((USItype) (w1)) \
|
||||
: "%0" ((USItype) (u)), \
|
||||
"rm" ((USItype) (v)))
|
||||
#define udiv_qrnnd(q, r, n1, n0, dv) \
|
||||
__asm__ ("divl %4" \
|
||||
: "=a" ((USItype) (q)), \
|
||||
"=d" ((USItype) (r)) \
|
||||
: "0" ((USItype) (n0)), \
|
||||
"1" ((USItype) (n1)), \
|
||||
"rm" ((USItype) (dv)))
|
||||
#define count_leading_zeros(count, x) \
|
||||
do { \
|
||||
USItype __cbtmp; \
|
||||
__asm__ ("bsrl %1,%0" \
|
||||
: "=r" (__cbtmp) : "rm" ((USItype) (x))); \
|
||||
(count) = __cbtmp ^ 31; \
|
||||
} while (0)
|
||||
#else
|
||||
#error unsupported CPU type
|
||||
#endif
|
||||
|
||||
/* most of this code is taken from libgcc2.c from gcc */
|
||||
UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
|
||||
{
|
||||
DWunion ww;
|
||||
DWunion nn, dd;
|
||||
DWunion rr;
|
||||
UWtype d0, d1, n0, n1, n2;
|
||||
UWtype q0, q1;
|
||||
UWtype b, bm;
|
||||
|
||||
nn.ll = n;
|
||||
dd.ll = d;
|
||||
|
||||
d0 = dd.s.low;
|
||||
d1 = dd.s.high;
|
||||
n0 = nn.s.low;
|
||||
n1 = nn.s.high;
|
||||
|
||||
#if !defined(UDIV_NEEDS_NORMALIZATION)
|
||||
if (d1 == 0)
|
||||
{
|
||||
if (d0 > n1)
|
||||
{
|
||||
/* 0q = nn / 0D */
|
||||
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n0. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* qq = NN / 0d */
|
||||
|
||||
if (d0 == 0)
|
||||
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||
|
||||
udiv_qrnnd (q1, n1, 0, n1, d0);
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
|
||||
/* Remainder in n0. */
|
||||
}
|
||||
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0;
|
||||
rr.s.high = 0;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* UDIV_NEEDS_NORMALIZATION */
|
||||
|
||||
if (d1 == 0)
|
||||
{
|
||||
if (d0 > n1)
|
||||
{
|
||||
/* 0q = nn / 0D */
|
||||
|
||||
count_leading_zeros (bm, d0);
|
||||
|
||||
if (bm != 0)
|
||||
{
|
||||
/* Normalize, i.e. make the most significant bit of the
|
||||
denominator set. */
|
||||
|
||||
d0 = d0 << bm;
|
||||
n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
|
||||
n0 = n0 << bm;
|
||||
}
|
||||
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n0 >> bm. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* qq = NN / 0d */
|
||||
|
||||
if (d0 == 0)
|
||||
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||
|
||||
count_leading_zeros (bm, d0);
|
||||
|
||||
if (bm == 0)
|
||||
{
|
||||
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
|
||||
conclude (the most significant bit of n1 is set) /\ (the
|
||||
leading quotient digit q1 = 1).
|
||||
|
||||
This special case is necessary, not an optimization.
|
||||
(Shifts counts of W_TYPE_SIZE are undefined.) */
|
||||
|
||||
n1 -= d0;
|
||||
q1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normalize. */
|
||||
|
||||
b = W_TYPE_SIZE - bm;
|
||||
|
||||
d0 = d0 << bm;
|
||||
n2 = n1 >> b;
|
||||
n1 = (n1 << bm) | (n0 >> b);
|
||||
n0 = n0 << bm;
|
||||
|
||||
udiv_qrnnd (q1, n1, n2, n1, d0);
|
||||
}
|
||||
|
||||
/* n1 != d0... */
|
||||
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
|
||||
/* Remainder in n0 >> bm. */
|
||||
}
|
||||
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0 >> bm;
|
||||
rr.s.high = 0;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
#endif /* UDIV_NEEDS_NORMALIZATION */
|
||||
|
||||
else
|
||||
{
|
||||
if (d1 > n1)
|
||||
{
|
||||
/* 00 = nn / DD */
|
||||
|
||||
q0 = 0;
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n1n0. */
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0;
|
||||
rr.s.high = n1;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 0q = NN / dd */
|
||||
|
||||
count_leading_zeros (bm, d1);
|
||||
if (bm == 0)
|
||||
{
|
||||
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
|
||||
conclude (the most significant bit of n1 is set) /\ (the
|
||||
quotient digit q0 = 0 or 1).
|
||||
|
||||
This special case is necessary, not an optimization. */
|
||||
|
||||
/* The condition on the next line takes advantage of that
|
||||
n1 >= d1 (true due to program flow). */
|
||||
if (n1 > d1 || n0 >= d0)
|
||||
{
|
||||
q0 = 1;
|
||||
sub_ddmmss (n1, n0, n1, n0, d1, d0);
|
||||
}
|
||||
else
|
||||
q0 = 0;
|
||||
|
||||
q1 = 0;
|
||||
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0;
|
||||
rr.s.high = n1;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UWtype m1, m0;
|
||||
/* Normalize. */
|
||||
|
||||
b = W_TYPE_SIZE - bm;
|
||||
|
||||
d1 = (d1 << bm) | (d0 >> b);
|
||||
d0 = d0 << bm;
|
||||
n2 = n1 >> b;
|
||||
n1 = (n1 << bm) | (n0 >> b);
|
||||
n0 = n0 << bm;
|
||||
|
||||
udiv_qrnnd (q0, n1, n2, n1, d1);
|
||||
umul_ppmm (m1, m0, q0, d0);
|
||||
|
||||
if (m1 > n1 || (m1 == n1 && m0 > n0))
|
||||
{
|
||||
q0--;
|
||||
sub_ddmmss (m1, m0, m1, m0, d1, d0);
|
||||
}
|
||||
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in (n1n0 - m1m0) >> bm. */
|
||||
if (rp != 0)
|
||||
{
|
||||
sub_ddmmss (n1, n0, n1, n0, m1, m0);
|
||||
rr.s.low = (n1 << b) | (n0 >> bm);
|
||||
rr.s.high = n1 >> bm;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ww.s.low = q0;
|
||||
ww.s.high = q1;
|
||||
return ww.ll;
|
||||
}
|
||||
|
||||
#define __negdi2(a) (-(a))
|
||||
|
||||
long long __divdi3(long long u, long long v)
|
||||
{
|
||||
int c = 0;
|
||||
DWunion uu, vv;
|
||||
DWtype w;
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c;
|
||||
uu.ll = __negdi2 (uu.ll);
|
||||
}
|
||||
if (vv.s.high < 0) {
|
||||
c = ~c;
|
||||
vv.ll = __negdi2 (vv.ll);
|
||||
}
|
||||
w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
|
||||
if (c)
|
||||
w = __negdi2 (w);
|
||||
return w;
|
||||
}
|
||||
|
||||
// https://github.com/KaMeHb-UA/UE4m/blob/1d9ad5bfead06520570c7f24dad062f9f8717c1a/\
|
||||
Engine/Extras/ThirdPartyNotUE/emsdk/emscripten/incoming/system/lib/compiler-rt/lib/\
|
||||
builtins/divmoddi4.c
|
||||
long long __divmoddi4(long long a, long long b, long long* rem)
|
||||
{
|
||||
long long d = __divdi3(a, b);
|
||||
*rem = a - (d * b);
|
||||
return d;
|
||||
}
|
||||
|
||||
long long __moddi3(long long u, long long v)
|
||||
{
|
||||
int c = 0;
|
||||
DWunion uu, vv;
|
||||
DWtype w;
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c;
|
||||
uu.ll = __negdi2 (uu.ll);
|
||||
}
|
||||
if (vv.s.high < 0)
|
||||
vv.ll = __negdi2 (vv.ll);
|
||||
|
||||
__udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
|
||||
if (c)
|
||||
w = __negdi2 (w);
|
||||
return w;
|
||||
}
|
||||
|
||||
unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
|
||||
{
|
||||
return __udivmoddi4 (u, v, (UDWtype *) 0);
|
||||
}
|
||||
|
||||
unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
|
||||
{
|
||||
UDWtype w;
|
||||
|
||||
__udivmoddi4 (u, v, &w);
|
||||
return w;
|
||||
}
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
long long __ashrdi3(long long a, int b)
|
||||
{
|
||||
#ifdef __TINYC__
|
||||
DWunion u;
|
||||
u.ll = a;
|
||||
if (b >= 32) {
|
||||
u.s.low = u.s.high >> (b - 32);
|
||||
u.s.high = u.s.high >> 31;
|
||||
} else if (b != 0) {
|
||||
u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
|
||||
u.s.high = u.s.high >> b;
|
||||
}
|
||||
return u.ll;
|
||||
#else
|
||||
return a >> b;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
unsigned long long __lshrdi3(unsigned long long a, int b)
|
||||
{
|
||||
#ifdef __TINYC__
|
||||
DWunion u;
|
||||
u.ll = a;
|
||||
if (b >= 32) {
|
||||
u.s.low = (unsigned)u.s.high >> (b - 32);
|
||||
u.s.high = 0;
|
||||
} else if (b != 0) {
|
||||
u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
|
||||
u.s.high = (unsigned)u.s.high >> b;
|
||||
}
|
||||
return u.ll;
|
||||
#else
|
||||
return a >> b;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
long long __ashldi3(long long a, int b)
|
||||
{
|
||||
#ifdef __TINYC__
|
||||
DWunion u;
|
||||
u.ll = a;
|
||||
if (b >= 32) {
|
||||
u.s.high = (unsigned)u.s.low << (b - 32);
|
||||
u.s.low = 0;
|
||||
} else if (b != 0) {
|
||||
u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
|
||||
u.s.low = (unsigned)u.s.low << b;
|
||||
}
|
||||
return u.ll;
|
||||
#else
|
||||
return a << b;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef COMMIT_4ad186c5ef61_IS_FIXED
|
||||
long long __tcc_cvt_ftol(long double x)
|
||||
{
|
||||
unsigned c0, c1;
|
||||
long long ret;
|
||||
__asm__ __volatile__ ("fnstcw %0" : "=m" (c0));
|
||||
c1 = c0 | 0x0C00;
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (c1));
|
||||
__asm__ __volatile__ ("fistpll %0" : "=m" (ret));
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (c0));
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !__x86_64__ */
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
float __floatundisf(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
if (uu.s.high >= 0) {
|
||||
return (float)uu.ll;
|
||||
} else {
|
||||
r = (XFtype)uu.ll;
|
||||
r += 18446744073709551616.0;
|
||||
return (float)r;
|
||||
}
|
||||
}
|
||||
|
||||
double __floatundidf(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
if (uu.s.high >= 0) {
|
||||
return (double)uu.ll;
|
||||
} else {
|
||||
r = (XFtype)uu.ll;
|
||||
r += 18446744073709551616.0;
|
||||
return (double)r;
|
||||
}
|
||||
}
|
||||
|
||||
long double __floatundixf(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
if (uu.s.high >= 0) {
|
||||
return (long double)uu.ll;
|
||||
} else {
|
||||
r = (XFtype)uu.ll;
|
||||
r += 18446744073709551616.0;
|
||||
return (long double)r;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long __fixunssfdi (float a1)
|
||||
{
|
||||
register union float_long fl1;
|
||||
register int exp;
|
||||
register unsigned long l;
|
||||
|
||||
fl1.f = a1;
|
||||
|
||||
if (fl1.l == 0)
|
||||
return (0);
|
||||
|
||||
exp = EXP (fl1.l) - EXCESS - 24;
|
||||
|
||||
l = MANT(fl1.l);
|
||||
if (exp >= 41)
|
||||
return (unsigned long long)-1;
|
||||
else if (exp >= 0)
|
||||
return (unsigned long long)l << exp;
|
||||
else if (exp >= -23)
|
||||
return l >> -exp;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long __fixunsdfdi (double a1)
|
||||
{
|
||||
register union double_long dl1;
|
||||
register int exp;
|
||||
register unsigned long long l;
|
||||
|
||||
dl1.d = a1;
|
||||
|
||||
if (dl1.ll == 0)
|
||||
return (0);
|
||||
|
||||
exp = EXPD (dl1) - EXCESSD - 53;
|
||||
|
||||
l = MANTD_LL(dl1);
|
||||
|
||||
if (exp >= 12)
|
||||
return (unsigned long long)-1;
|
||||
else if (exp >= 0)
|
||||
return l << exp;
|
||||
else if (exp >= -52)
|
||||
return l >> -exp;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long __fixunsxfdi (long double a1)
|
||||
{
|
||||
register union ldouble_long dl1;
|
||||
register int exp;
|
||||
register unsigned long long l;
|
||||
|
||||
dl1.ld = a1;
|
||||
|
||||
if (dl1.l.lower == 0 && dl1.l.upper == 0)
|
||||
return (0);
|
||||
|
||||
exp = EXPLD (dl1) - EXCESSLD - 64;
|
||||
|
||||
l = dl1.l.lower;
|
||||
|
||||
if (exp > 0)
|
||||
return (unsigned long long)-1;
|
||||
else if (exp >= -63)
|
||||
return l >> -exp;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
long long __fixsfdi (float a1)
|
||||
{
|
||||
long long ret; int s;
|
||||
ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
|
||||
return s ? ret : -ret;
|
||||
}
|
||||
|
||||
long long __fixdfdi (double a1)
|
||||
{
|
||||
long long ret; int s;
|
||||
ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
|
||||
return s ? ret : -ret;
|
||||
}
|
||||
|
||||
long long __fixxfdi (long double a1)
|
||||
{
|
||||
long long ret; int s;
|
||||
ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
|
||||
return s ? ret : -ret;
|
||||
}
|
||||
|
||||
#if defined(TCC_TARGET_X86_64) && !defined(_WIN64)
|
||||
|
||||
#ifndef __TINYC__
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
/* Avoid including stdlib.h because it is not easily available when
|
||||
cross compiling */
|
||||
#include <stddef.h> /* size_t definition is needed for a x86_64-tcc to parse memset() */
|
||||
void *malloc(unsigned long long);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void free(void*);
|
||||
void abort(void);
|
||||
#endif
|
||||
|
||||
enum __va_arg_type {
|
||||
__va_gen_reg, __va_float_reg, __va_stack
|
||||
};
|
||||
|
||||
//This should be in sync with the declaration on our include/stdarg.h
|
||||
/* GCC compatible definition of va_list. */
|
||||
typedef struct {
|
||||
unsigned int gp_offset;
|
||||
unsigned int fp_offset;
|
||||
union {
|
||||
unsigned int overflow_offset;
|
||||
char *overflow_arg_area;
|
||||
};
|
||||
char *reg_save_area;
|
||||
} __va_list_struct;
|
||||
|
||||
#undef __va_start
|
||||
#undef __va_arg
|
||||
#undef __va_copy
|
||||
#undef __va_end
|
||||
|
||||
void __va_start(__va_list_struct *ap, void *fp)
|
||||
{
|
||||
memset(ap, 0, sizeof(__va_list_struct));
|
||||
*ap = *(__va_list_struct *)((char *)fp - 16);
|
||||
ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
|
||||
ap->reg_save_area = (char *)fp - 176 - 16;
|
||||
}
|
||||
|
||||
void *__va_arg(__va_list_struct *ap,
|
||||
enum __va_arg_type arg_type,
|
||||
int size, int align)
|
||||
{
|
||||
size = (size + 7) & ~7;
|
||||
align = (align + 7) & ~7;
|
||||
switch (arg_type) {
|
||||
case __va_gen_reg:
|
||||
if (ap->gp_offset + size <= 48) {
|
||||
ap->gp_offset += size;
|
||||
return ap->reg_save_area + ap->gp_offset - size;
|
||||
}
|
||||
goto use_overflow_area;
|
||||
|
||||
case __va_float_reg:
|
||||
if (ap->fp_offset < 128 + 48) {
|
||||
ap->fp_offset += 16;
|
||||
return ap->reg_save_area + ap->fp_offset - 16;
|
||||
}
|
||||
size = 8;
|
||||
goto use_overflow_area;
|
||||
|
||||
case __va_stack:
|
||||
use_overflow_area:
|
||||
ap->overflow_arg_area += size;
|
||||
ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
|
||||
return ap->overflow_arg_area - size;
|
||||
|
||||
default:
|
||||
#ifndef __TINYC__
|
||||
fprintf(stderr, "unknown ABI type for __va_arg\n");
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
/* Flushing for tccrun */
|
||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_I386)
|
||||
|
||||
void __clear_cache(void *beginning, void *end)
|
||||
{
|
||||
}
|
||||
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void __clear_cache(void *beginning, void *end)
|
||||
{
|
||||
/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
|
||||
* However, there is no ARM asm parser in tcc so we use it for now */
|
||||
#if 1
|
||||
syscall(__ARM_NR_cacheflush, beginning, end, 0);
|
||||
#else
|
||||
__asm__ ("push {r7}\n\t"
|
||||
"mov r7, #0xf0002\n\t"
|
||||
"mov r2, #0\n\t"
|
||||
"swi 0\n\t"
|
||||
"pop {r7}\n\t"
|
||||
"ret");
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
#warning __clear_cache not defined for this architecture, avoid using tcc -run
|
||||
#endif
|
@ -0,0 +1,24 @@
|
||||
format ELF
|
||||
|
||||
section '.text' executable
|
||||
include '../../../../../proc32.inc'
|
||||
|
||||
public memcpy
|
||||
|
||||
proc memcpy c, to:dword,from:dword,count:dword
|
||||
push esi
|
||||
push edi
|
||||
mov ecx,[count]
|
||||
test ecx,ecx
|
||||
jz no_copy_block
|
||||
mov esi,[from]
|
||||
mov edi,[to]
|
||||
cld
|
||||
rep movsb
|
||||
no_copy_block:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
mov eax, [to]
|
||||
ret
|
||||
endp
|
@ -0,0 +1,34 @@
|
||||
format ELF
|
||||
|
||||
section '.text' executable
|
||||
include '../../../../../proc32.inc'
|
||||
|
||||
public memmove
|
||||
|
||||
proc memmove c, to:dword,from:dword,count:dword
|
||||
|
||||
push esi
|
||||
push edi
|
||||
mov ecx,[count]
|
||||
test ecx,ecx
|
||||
jz no_copy_block_
|
||||
mov esi,[from]
|
||||
mov edi,[to]
|
||||
cmp esi, edi
|
||||
je no_copy_block_
|
||||
jg copy_
|
||||
add esi, ecx
|
||||
add edi, ecx
|
||||
dec esi
|
||||
dec edi
|
||||
std
|
||||
copy_:
|
||||
rep movsb
|
||||
cld
|
||||
no_copy_block_:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
mov eax,[to]
|
||||
ret
|
||||
endp
|
@ -0,0 +1,16 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public memset
|
||||
|
||||
memset:
|
||||
push edi
|
||||
mov edi,[esp+8]
|
||||
mov eax,[esp+12]
|
||||
mov ecx,[esp+16]
|
||||
jecxz .no_set
|
||||
cld
|
||||
rep stosb
|
||||
.no_set:
|
||||
mov eax, [esp+8]
|
||||
pop edi
|
||||
ret
|
@ -13,13 +13,28 @@ todo:
|
||||
-radix point always '.', no LOCALEs
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include "format_scan.h"
|
||||
|
||||
static int __try_parse_real(long double *real, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||
typedef int (*virtual_getc)(void *sp, const void *obj);
|
||||
typedef void (*virtual_ungetc)(void *sp, int c, const void *obj);
|
||||
|
||||
enum flags_t
|
||||
{
|
||||
flag_unsigned = 0x02,
|
||||
flag_register = 0x04,
|
||||
flag_plus = 0x08,
|
||||
flag_left_just = 0x10,
|
||||
flag_lead_zeros = 0x20,
|
||||
flag_space_plus = 0x40,
|
||||
flag_hash_sign = 0x80,
|
||||
flag_point = 0x100
|
||||
};
|
||||
|
||||
int try_parse_real(long double *real, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||
// returns 1 if OK, -1 == EOF, -2 parse broken
|
||||
{
|
||||
int sign = 1, have_digits = 0;
|
||||
@ -133,12 +148,12 @@ static int __try_parse_real(long double *real, int ch, const void *src, void *sa
|
||||
}
|
||||
}
|
||||
div *= sign;
|
||||
*real *= pow(10,div);
|
||||
*real *= pow(10, div);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __try_parse_int(long long *digit, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||
int try_parse_int(long long *digit, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||
{
|
||||
int sign = 1, base = 10, have_digits = 0;
|
||||
|
||||
@ -208,20 +223,20 @@ static int __try_parse_int(long long *digit, int ch, const void *src, void *save
|
||||
|
||||
|
||||
|
||||
int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||
int format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||
{
|
||||
int i;
|
||||
int length;
|
||||
int fmt1, fmt2; // width, precision
|
||||
size_t pos, posc;
|
||||
const char *fmtc; // first point to %, fmtc points to specifier
|
||||
int ch;
|
||||
int format_flag;
|
||||
int flag_long; // 2 = long double or long long int or wchar
|
||||
int *point_to_n = NULL, nread = 0;
|
||||
int flags; // parsed flags
|
||||
int save = 0;
|
||||
char *arg_str;
|
||||
int i;
|
||||
int length;
|
||||
int fmt1, fmt2; // width, precision
|
||||
size_t pos, posc;
|
||||
const char *fmtc; // first point to %, fmtc points to specifier
|
||||
int ch;
|
||||
int format_flag;
|
||||
int flag_long; // 2 = long double or long long int or wchar
|
||||
int *point_to_n = NULL, nread = 0;
|
||||
int flags; // parsed flags
|
||||
int save = 0;
|
||||
char *arg_str;
|
||||
int *arg_int;
|
||||
long *arg_long;
|
||||
long long *arg_longlong;
|
||||
@ -363,7 +378,7 @@ int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vg
|
||||
break;
|
||||
case 's':
|
||||
arg_str = va_arg(argp, char*);
|
||||
if (fmt1 == 0) length = STDIO_MAX_MEM; // max string scan 4096
|
||||
if (fmt1 == 0) length = 4095; // max string scan 4096
|
||||
else length = fmt1;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
@ -375,7 +390,7 @@ int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vg
|
||||
break;
|
||||
case 'd': case 'i': case 'u':
|
||||
case 'o': case 'p': case 'x':
|
||||
i = __try_parse_int(&digit, ch, src, &save, vgetc, vungetc);
|
||||
i = try_parse_int(&digit, ch, src, &save, vgetc, vungetc);
|
||||
if (i < 0) goto exit_me;
|
||||
|
||||
if (flag_long == 0) { arg_int = va_arg(argp, int*); *arg_int = (int)digit; } else
|
||||
@ -385,7 +400,7 @@ int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vg
|
||||
case 'a': case 'A': case 'f': case 'F':
|
||||
case 'e': case 'E':
|
||||
case 'g': case 'G':
|
||||
i = __try_parse_real(&real, ch, src, &save, vgetc, vungetc);
|
||||
i = try_parse_real(&real, ch, src, &save, vgetc, vungetc);
|
||||
if (i < 0) goto exit_me;
|
||||
|
||||
if (flag_long == 0) { arg_float = va_arg(argp, float*); *arg_float = (float)real; } else
|
||||
|
@ -1,11 +1,40 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int fscanf(FILE* stream, const char* format, ...)
|
||||
int virtual_getc_file(void *sp, const void *obj)
|
||||
// get next chat from file obj, save point is ptr to string char ptr
|
||||
{
|
||||
va_list arg;
|
||||
int n;
|
||||
FILE *f = (FILE *)obj;
|
||||
int ch = fgetc(f);
|
||||
|
||||
//printf("getc '%c'[%d];", ch, ch);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
void virtual_ungetc_file(void *sp, int c, const void *obj)
|
||||
// if can, one step back savepoint in s
|
||||
{
|
||||
FILE *f = (FILE *)obj;
|
||||
|
||||
if (f) ungetc(c, f);
|
||||
}
|
||||
|
||||
|
||||
int vfscanf ( FILE * stream, const char * format, va_list arg )
|
||||
{
|
||||
return format_scan(stream, format, arg, &virtual_getc_file, &virtual_ungetc_file);
|
||||
};
|
||||
|
||||
int fscanf ( FILE * stream, const char * format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int n;
|
||||
va_start(arg, format);
|
||||
|
||||
n = vfscanf(stream, format, arg);
|
||||
|
||||
va_end(arg);
|
||||
return n;
|
||||
}
|
||||
|
@ -1,15 +1,59 @@
|
||||
//#include "format_scan.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
char *__scanf_buffer = 0;
|
||||
|
||||
int virtual_getc_con(void *sp, const void *obj)
|
||||
// get next chat from string obj, save point is ptr to string char ptr
|
||||
{
|
||||
int ch;
|
||||
const char**spc= (const char**)sp;
|
||||
if (!spc) return EOF; // error
|
||||
|
||||
if (!*spc) *spc = __scanf_buffer; // first call, init savepoint
|
||||
|
||||
while (!**spc) // need to read more
|
||||
{
|
||||
if(!gets(__scanf_buffer)) return EOF;
|
||||
*spc = __scanf_buffer;
|
||||
strcat(__scanf_buffer,"\n"); // imitate delimiter
|
||||
}
|
||||
if (**spc == 26 || **spc == 3) // ^C ^Z end of scan, clear buffer
|
||||
{
|
||||
*spc = __scanf_buffer;
|
||||
*__scanf_buffer = 0;
|
||||
return EOF; // ^C ^Z
|
||||
}
|
||||
|
||||
ch = **spc; (*spc)++ ;
|
||||
|
||||
//printf("getc '%c'[%d];", ch, ch);
|
||||
return ch;
|
||||
}
|
||||
|
||||
void virtual_ungetc_con(void *sp, int c, const void *obj)
|
||||
// if can, one step back savepoint in s
|
||||
{
|
||||
const char**spc= (const char**)sp;
|
||||
|
||||
if (spc && *spc > __scanf_buffer) (*spc)--;
|
||||
//printf("Ungetc '%c'[%d];", c, c);
|
||||
}
|
||||
|
||||
int vscanf ( const char * format, va_list arg )
|
||||
{
|
||||
return format_scan(NULL, format, arg, &virtual_getc_con, &virtual_ungetc_con);
|
||||
};
|
||||
|
||||
int scanf ( const char * format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_list arg;
|
||||
int n;
|
||||
va_start(arg, format);
|
||||
|
||||
if(__scanf_buffer == NULL) __scanf_buffer = malloc(STDIO_MAX_MEM);
|
||||
if(__scanf_buffer == NULL) errno = ENOMEM; return ENOMEM;
|
||||
if(__scanf_buffer == NULL) __scanf_buffer = malloc(4096);
|
||||
if(__scanf_buffer == NULL) return -3;
|
||||
|
||||
*__scanf_buffer = 0;
|
||||
n = vscanf(format, arg);
|
||||
|
@ -1,11 +1,45 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int sscanf(const char * s, const char * format, ...)
|
||||
int virtual_getc_str(void *sp, const void *obj)
|
||||
// get next chat from string obj, save point is ptr to string char ptr
|
||||
{
|
||||
va_list arg;
|
||||
int ch;
|
||||
const char *s = (const char *)obj;
|
||||
const char**spc= (const char**)sp;
|
||||
if (!s || !spc) return EOF; // error
|
||||
|
||||
if (!*spc) *spc = s; // first call, init savepoint
|
||||
|
||||
if (!**spc) return EOF; // EOS
|
||||
|
||||
ch = **spc; (*spc)++ ;
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
void virtual_ungetc_str(void *sp, int c, const void *obj)
|
||||
// if can, one step back savepoint in s
|
||||
{
|
||||
const char *s = (const char *)obj;
|
||||
const char**spc= (const char**)sp;
|
||||
|
||||
if (s && spc && *spc > s) (*spc)--;
|
||||
}
|
||||
|
||||
int vsscanf ( const char * s, const char * format, va_list arg )
|
||||
{
|
||||
return format_scan(s, format, arg, &virtual_getc_str, &virtual_ungetc_str);
|
||||
};
|
||||
|
||||
int sscanf ( const char * s, const char * format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int n;
|
||||
va_start(arg, format);
|
||||
|
||||
n = vsscanf(s, format, arg);
|
||||
|
||||
va_end(arg);
|
||||
return n;
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
// non standard realization - support for virtually change ONLY ONE char
|
||||
|
||||
int ungetc(int c, FILE* file)
|
||||
{
|
||||
int res;
|
||||
|
||||
if(!file){
|
||||
errno = EBADF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (file->mode != _STDIO_F_R){
|
||||
errno = EACCES;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (file->position > file->start_size || file->position == 0 || c == EOF || file->__ungetc_emu_buff != EOF)
|
||||
{
|
||||
errno = EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
file->__ungetc_emu_buff = c;
|
||||
file->position--;
|
||||
return c;
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
//#include "format_scan.h"
|
||||
#include <errno.h>
|
||||
|
||||
// non standard realization - support for virtually change ONLY ONE char
|
||||
|
||||
static int __ungetc_emu(int c, FILE* stream)
|
||||
{
|
||||
unsigned res;
|
||||
if(stream){
|
||||
errno = EINVAL;
|
||||
return EOF;
|
||||
}
|
||||
if ((stream->mode & 3) != _STDIO_F_R && (stream->mode & _STDIO_F_A) == 0){
|
||||
errno = EACCES;
|
||||
return EOF;
|
||||
}
|
||||
ksys_bdfe_t *file_info = malloc(sizeof(ksys_bdfe_t));
|
||||
if(file_info==NULL){
|
||||
errno = ENOMEM;
|
||||
return EOF;
|
||||
}
|
||||
if(!_ksys_file_get_info(stream->name, file_info)){
|
||||
errno = ENFILE;
|
||||
return EOF;
|
||||
}
|
||||
if (stream->position > file_info->size || stream->position == 0 || c == EOF || stream->__ungetc_emu_buff != EOF){
|
||||
errno = EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
stream->__ungetc_emu_buff = c;
|
||||
stream->position --;
|
||||
return c;
|
||||
}
|
||||
|
||||
static int __virtual_getc_file(void *sp, const void *obj)
|
||||
{
|
||||
FILE *f = (FILE *)obj;
|
||||
int ch = fgetc(f);
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void __virtual_ungetc_file(void *sp, int c, const void *obj)
|
||||
{
|
||||
FILE *f = (FILE *)obj;
|
||||
if (f) __ungetc_emu(c, f);
|
||||
}
|
||||
|
||||
int vfscanf(FILE * stream, const char * format, va_list arg)
|
||||
{
|
||||
return _format_scan(stream, format, arg, &__virtual_getc_file, &__virtual_ungetc_file);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#include <string.h>
|
||||
|
||||
char *__scanf_buffer=NULL;
|
||||
typedef int (*virtual_getc)(void *sp, const void *obj);
|
||||
typedef void (*virtual_ungetc)(void *sp, int c, const void *obj);
|
||||
|
||||
char *__scanf_buffer;
|
||||
|
||||
extern int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc);
|
||||
|
||||
static int __virtual_getc_con(void *sp, const void *obj)
|
||||
// get next chat from string obj, save point is ptr to string char ptr
|
||||
{
|
||||
int ch;
|
||||
const char**spc= (const char**)sp;
|
||||
if (!spc) return EOF; // error
|
||||
if (!*spc) *spc = __scanf_buffer; // first call, init savepoint
|
||||
|
||||
while (!**spc) // need to read more
|
||||
{
|
||||
if(!gets(__scanf_buffer)) return EOF;
|
||||
*spc = __scanf_buffer;
|
||||
strcat(__scanf_buffer,"\n"); // imitate delimiter
|
||||
}
|
||||
if (**spc == 26 || **spc == 3) // ^C ^Z end of scan, clear buffer
|
||||
{
|
||||
*spc = __scanf_buffer;
|
||||
*__scanf_buffer = 0;
|
||||
return EOF; // ^C ^Z
|
||||
}
|
||||
|
||||
ch = **spc; (*spc)++ ;
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void __virtual_ungetc_con(void *sp, int c, const void *obj)
|
||||
// if can, one step back savepoint in s
|
||||
{
|
||||
const char**spc= (const char**)sp;
|
||||
|
||||
if (spc && *spc > __scanf_buffer) (*spc)--;
|
||||
//printf("Ungetc '%c'[%d];", c, c);
|
||||
}
|
||||
|
||||
|
||||
int vscanf(const char * format, va_list arg)
|
||||
{
|
||||
return _format_scan(NULL, format, arg, &__virtual_getc_con, &__virtual_ungetc_con);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
//#include "format_scan.h"
|
||||
|
||||
static int __virtual_getc_str(void *sp, const void *obj)
|
||||
// get next chat from string obj, save point is ptr to string char ptr
|
||||
{
|
||||
int ch;
|
||||
const char *s = (const char *)obj;
|
||||
const char**spc= (const char**)sp;
|
||||
if (!s || !spc) return EOF; // error
|
||||
|
||||
if (!*spc) *spc = s; // first call, init savepoint
|
||||
|
||||
if (!**spc) return EOF; // EOS
|
||||
|
||||
ch = **spc; (*spc)++ ;
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
void __virtual_ungetc_str(void *sp, int c, const void *obj)
|
||||
// if can, one step back savepoint in s
|
||||
{
|
||||
const char *s = (const char *)obj;
|
||||
const char**spc= (const char**)sp;
|
||||
|
||||
if (s && spc && *spc > s) (*spc)--;
|
||||
}
|
||||
|
||||
int vsscanf(const char * s, const char * format, va_list arg)
|
||||
{
|
||||
return _format_scan(s, format, arg, &__virtual_getc_str, &__virtual_ungetc_str);
|
||||
};
|
Loading…
Reference in New Issue
Block a user