forked from KolibriOS/kolibrios
kolibri-libc:
- Added full import console.obj - Added dir.h - Fixed dirent bug - Added dirent example - Fixed localtime bug. git-svn-id: svn://kolibrios.org@8744 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
4bc3d82296
commit
a749f672ce
@ -96,8 +96,7 @@ extern int _FUNC(getc)(FILE *);
|
|||||||
#define getc() _FUNC(fgetc)(stdin)
|
#define getc() _FUNC(fgetc)(stdin)
|
||||||
extern int _FUNC(getchar)(void);
|
extern int _FUNC(getchar)(void);
|
||||||
extern int _FUNC(printf)(const char *restrict, ...);
|
extern int _FUNC(printf)(const char *restrict, ...);
|
||||||
extern int _FUNC(putc)(int, FILE *);
|
#define putc(ch) _FUNC(fputc)(ch, stdout)
|
||||||
extern int _FUNC(putchar)(int);
|
|
||||||
extern int _FUNC(puts)(const char *);
|
extern int _FUNC(puts)(const char *);
|
||||||
extern int _FUNC(scanf)(const char *restrict, ...);
|
extern int _FUNC(scanf)(const char *restrict, ...);
|
||||||
extern char* _FUNC(gets)(char *str);
|
extern char* _FUNC(gets)(char *str);
|
||||||
@ -136,6 +135,4 @@ extern size_t _FUNC(fread)(void *restrict, size_t, size_t, FILE *restrict);
|
|||||||
|
|
||||||
extern int _FUNC(getchar)(void);
|
extern int _FUNC(getchar)(void);
|
||||||
|
|
||||||
extern void _FUNC(con_set_title)(const char*);
|
|
||||||
|
|
||||||
#endif // _STDIO_H_
|
#endif // _STDIO_H_
|
||||||
|
@ -24,11 +24,11 @@ typedef struct{
|
|||||||
}DIR;
|
}DIR;
|
||||||
|
|
||||||
|
|
||||||
int _FUNC(closedir)(DIR *dir);
|
extern int _FUNC(closedir)(DIR *dir);
|
||||||
DIR* _FUNC(opendir)(const char *path);
|
extern DIR* _FUNC(opendir)(const char *path);
|
||||||
struct dirent* _FUNC(readdir)(DIR *);
|
extern struct dirent* _FUNC(readdir)(DIR *);
|
||||||
void _FUNC(rewinddir)(DIR *dir);
|
extern void _FUNC(rewinddir)(DIR *dir);
|
||||||
void _FUNC(seekdir)(DIR *dir, unsigned pos);
|
extern void _FUNC(seekdir)(DIR *dir, unsigned pos);
|
||||||
unsigned _FUNC(telldir)(DIR *dir);
|
extern unsigned _FUNC(telldir)(DIR *dir);
|
||||||
|
|
||||||
#endif // _DIRENT_H_
|
#endif // _DIRENT_H_
|
||||||
|
Binary file not shown.
@ -0,0 +1,45 @@
|
|||||||
|
#include <sys/dirent.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
|
const char *folder_type = "Folder";
|
||||||
|
const char *file_type = "File";
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char *path=getcwd(NULL, PATH_MAX);
|
||||||
|
printf("Current directory: %s\n", path);
|
||||||
|
if(mkdir("test")){
|
||||||
|
puts("Test folder created!");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
puts("Error creating folder!");
|
||||||
|
}
|
||||||
|
|
||||||
|
DIR *mydir = opendir(path);
|
||||||
|
if(!mydir){
|
||||||
|
puts("File system error.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *file_info;
|
||||||
|
char *str_type=NULL;
|
||||||
|
putc(' ');
|
||||||
|
while((file_info = readdir(mydir))!=NULL){
|
||||||
|
if(file_info->d_type==IS_FOLDER){
|
||||||
|
(*con_set_flags)(CON_COLOR_GREEN);
|
||||||
|
str_type = (char*)folder_type;
|
||||||
|
}else {
|
||||||
|
(*con_set_flags)(7);
|
||||||
|
str_type = (char*)file_type;
|
||||||
|
}
|
||||||
|
printf("%3d %20s %s\n ", file_info->d_ino ,file_info->d_name, str_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
setcwd("/sys/develop");
|
||||||
|
path=getcwd(NULL, PATH_MAX);
|
||||||
|
printf("Move to the directory: %s\n", path);
|
||||||
|
free(path);
|
||||||
|
}
|
@ -14,6 +14,7 @@ unsigned _libc_get_version(){
|
|||||||
#include "sys/opendir.c"
|
#include "sys/opendir.c"
|
||||||
#include "sys/telldir.c"
|
#include "sys/telldir.c"
|
||||||
#include "sys/closedir.c"
|
#include "sys/closedir.c"
|
||||||
|
#include "sys/dir.c"
|
||||||
|
|
||||||
#include "stdio/clearerr.c"
|
#include "stdio/clearerr.c"
|
||||||
#include "stdio/gets.c"
|
#include "stdio/gets.c"
|
||||||
|
@ -1,56 +1,62 @@
|
|||||||
#include <sys/ksys.h>
|
#include <sys/ksys.h>
|
||||||
#include "conio.h"
|
#include <conio.h>
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
static char* __con_caption = "Console application";
|
static char* __con_caption = "Console application";
|
||||||
static char* __con_dllname = "/sys/lib/console.obj";
|
static char* __con_dllname = "/sys/lib/console.obj";
|
||||||
|
|
||||||
int __con_is_load = 0;
|
int __con_is_load = 0;
|
||||||
|
|
||||||
void stdcall (*__con_init_hidden)(int wnd_width, int wnd_height,int scr_width, int scr_height, const char* title);
|
void stdcall (*__con_init_hidden)(int wnd_width, unsigned wnd_height, int scr_width, int scr_height, const char* title);
|
||||||
void stdcall (*__con_write_asciiz)(const char* str);
|
void stdcall (*con_exit)(int);
|
||||||
void stdcall (*__con_write_string)(const char* str, unsigned length);
|
void stdcall (*con_set_title)(const char* title);
|
||||||
int stdcall (*__con_getch)(void);
|
void stdcall (*con_write_asciiz)(const char* str);
|
||||||
short stdcall (*__con_getch2)(void);
|
void stdcall (*con_write_string)(const char* str, dword length);
|
||||||
int stdcall (*__con_kbhit)(void);
|
int cdecl (*con_printf)(const char* format, ...);
|
||||||
char* stdcall (*__con_gets)(char* str, int n);
|
dword stdcall (*con_get_flags)(void);
|
||||||
char* stdcall (*__con_gets2)(__con_gets2_callback callback, char* str, int n);
|
dword stdcall (*con_set_flags)(dword new_flags);
|
||||||
void stdcall (*__con_exit)(int status);
|
int stdcall (*con_get_font_height)(void);
|
||||||
void stdcall (*__con_set_title)(const char* title);
|
int stdcall (*con_get_cursor_height)(void);
|
||||||
|
int stdcall (*con_set_cursor_height)(int new_height);
|
||||||
|
int stdcall (*con_getch)(void);
|
||||||
|
word stdcall (*con_getch2)(void);
|
||||||
|
int stdcall (*con_kbhit)(void);
|
||||||
|
char* stdcall (*con_gets)(char* str, int n);
|
||||||
|
char* stdcall (*con_gets2)(con_gets2_callback callback, char* str, int n);
|
||||||
|
void stdcall (*con_cls)();
|
||||||
|
void stdcall (*con_get_cursor_pos)(int* px, int* py);
|
||||||
|
void stdcall (*con_set_cursor_pos)(int x, int y);
|
||||||
|
|
||||||
static void __con_panic(char* func_name)
|
static void __con_panic(char* func_name)
|
||||||
{
|
{
|
||||||
_ksys_debug_puts("libc.obj: ");
|
debug_printf("In console.obj %s=NULL!\n", func_name);
|
||||||
_ksys_debug_puts(func_name);
|
|
||||||
_ksys_debug_puts(" = NULL\n");
|
|
||||||
_ksys_exit();
|
_ksys_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __con_lib_link(ksys_coff_etable_t *exp)
|
static void __con_lib_link(ksys_coff_etable_t *exp)
|
||||||
{
|
{
|
||||||
__con_init_hidden = _ksys_get_coff_func(exp, "con_init", __con_panic);
|
__con_init_hidden = _ksys_get_coff_func(exp, "con_init", __con_panic);
|
||||||
__con_write_asciiz = _ksys_get_coff_func(exp, "con_write_asciiz", __con_panic);
|
con_exit = _ksys_get_coff_func(exp, "con_exit", __con_panic);
|
||||||
__con_write_string = _ksys_get_coff_func(exp, "con_write_string", __con_panic);
|
con_set_title = _ksys_get_coff_func(exp, "con_set_title", __con_panic);
|
||||||
__con_getch = _ksys_get_coff_func(exp, "con_getch", __con_panic);
|
con_write_asciiz = _ksys_get_coff_func(exp, "con_write_asciiz", __con_panic);
|
||||||
__con_getch2 = _ksys_get_coff_func(exp, "con_getch2", __con_panic);
|
con_write_string = _ksys_get_coff_func(exp, "con_write_string", __con_panic);
|
||||||
__con_kbhit = _ksys_get_coff_func(exp, "con_kbhit", __con_panic);
|
con_printf = _ksys_get_coff_func(exp, "con_printf", __con_panic);
|
||||||
__con_gets = _ksys_get_coff_func(exp, "con_gets", __con_panic);
|
con_get_flags = _ksys_get_coff_func(exp, "con_get_flags", __con_panic);
|
||||||
__con_gets2 = _ksys_get_coff_func(exp, "con_gets2", __con_panic);
|
con_set_flags = _ksys_get_coff_func(exp, "con_set_flags", __con_panic);
|
||||||
__con_exit = _ksys_get_coff_func(exp, "con_exit", __con_panic);
|
con_get_font_height = _ksys_get_coff_func(exp, "con_get_font_height", __con_panic);
|
||||||
__con_set_title = _ksys_get_coff_func(exp, "con_set_title", __con_panic);
|
con_get_cursor_height = _ksys_get_coff_func(exp, "con_get_cursor_height", __con_panic);
|
||||||
|
con_set_cursor_height = _ksys_get_coff_func(exp, "con_set_cursor_height", __con_panic);
|
||||||
|
con_getch = _ksys_get_coff_func(exp, "con_getch", __con_panic);
|
||||||
|
con_getch2 = _ksys_get_coff_func(exp, "con_getch2", __con_panic);
|
||||||
|
con_kbhit = _ksys_get_coff_func(exp, "con_kbhit", __con_panic);
|
||||||
|
con_gets = _ksys_get_coff_func(exp, "con_gets", __con_panic);
|
||||||
|
con_gets2 = _ksys_get_coff_func(exp, "con_gets2", __con_panic);
|
||||||
|
con_cls = _ksys_get_coff_func(exp, "con_cls", __con_panic);
|
||||||
|
con_get_cursor_pos = _ksys_get_coff_func(exp, "con_get_cursor_pos", __con_panic);
|
||||||
|
con_set_cursor_pos = _ksys_get_coff_func(exp, "con_set_cursor_pos", __con_panic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int con_init_opt(dword wnd_width, dword wnd_height, dword scr_width, dword scr_height, const char* title)
|
||||||
int __con_init(void)
|
|
||||||
{
|
|
||||||
return __con_init_opt(-1, -1, -1, -1, __con_caption);
|
|
||||||
}
|
|
||||||
|
|
||||||
void con_set_title(const char* title){
|
|
||||||
__con_init();
|
|
||||||
__con_set_title(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
int __con_init_opt(int wnd_width, int wnd_height,int scr_width, int scr_height, const char* title)
|
|
||||||
{
|
{
|
||||||
if(!__con_is_load){
|
if(!__con_is_load){
|
||||||
ksys_coff_etable_t *__con_lib;
|
ksys_coff_etable_t *__con_lib;
|
||||||
@ -66,3 +72,10 @@ int __con_init_opt(int wnd_width, int wnd_height,int scr_width, int scr_height,
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int con_init(void)
|
||||||
|
{
|
||||||
|
return con_init_opt(-1, -1, -1, -1, __con_caption);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This is adapded thunk for console.obj sys library
|
|
||||||
Only for internal use in stdio.h
|
|
||||||
|
|
||||||
Adapted for tcc by Siemargl, 2016
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef _CONIO_H_
|
|
||||||
#define _CONIO_H_
|
|
||||||
|
|
||||||
#define cdecl __attribute__ ((cdecl))
|
|
||||||
#define stdcall __attribute__ ((stdcall))
|
|
||||||
|
|
||||||
void stdcall (*__con_write_asciiz)(const char* str);
|
|
||||||
/* Display ASCIIZ-string to the console at the current position, shifting
|
|
||||||
the current position. */
|
|
||||||
|
|
||||||
void stdcall (*__con_write_string)(const char* str, unsigned length);
|
|
||||||
/* Similar to __con_write_asciiz, but length of the string must be given as a
|
|
||||||
separate parameter */
|
|
||||||
|
|
||||||
int stdcall (*__con_getch)(void);
|
|
||||||
/* Get one character from the keyboard.
|
|
||||||
|
|
||||||
For normal characters function returns ASCII-code. For extended
|
|
||||||
characters (eg, Fx, and arrows), first function call returns 0
|
|
||||||
and second call returns the extended code (similar to the DOS-function
|
|
||||||
input). Starting from version 7, after closing the console window,
|
|
||||||
this function returns 0. */
|
|
||||||
|
|
||||||
short stdcall (*__con_getch2)(void);
|
|
||||||
/* Reads a character from the keyboard. Low byte contains the ASCII-code
|
|
||||||
(0 for extended characters), high byte - advanced code (like in BIOS
|
|
||||||
input functions). Starting from version 7, after closing the console
|
|
||||||
window, this function returns 0. */
|
|
||||||
|
|
||||||
int stdcall (*__con_kbhit)(void);
|
|
||||||
/* Returns 1 if a key was pressed, 0 otherwise. To read pressed keys use
|
|
||||||
__con_getch and __con_getch2. Starting from version 6, after closing
|
|
||||||
the console window, this function returns 1. */
|
|
||||||
|
|
||||||
char* stdcall (*__con_gets)(char* str, int n);
|
|
||||||
/* Reads a string from the keyboard. Reading is interrupted when got
|
|
||||||
"new line" character, or after reading the (n-1) characters (depending on
|
|
||||||
what comes first). In the first case the newline is also recorded in the
|
|
||||||
str. The acquired line is complemented by a null character.
|
|
||||||
Starting from version 6, the function returns a pointer to the entered
|
|
||||||
line if reading was successful, and NULL if the console window was closed. */
|
|
||||||
|
|
||||||
typedef int (stdcall * __con_gets2_callback)(int keycode, char** pstr, int* pn,
|
|
||||||
int* ppos);
|
|
||||||
|
|
||||||
char* stdcall (*__con_gets2)(__con_gets2_callback callback, char* str, int n);
|
|
||||||
/* Con_gets completely analogous, except that when the user
|
|
||||||
press unrecognized key, it calls the specified callback-procedure
|
|
||||||
(which may, for example, handle up / down for history and tab to enter
|
|
||||||
autocompletion). You should pass to the procedure: key code and three pointers
|
|
||||||
- to the string, to the maximum length and to the current position.
|
|
||||||
function may change the contents of string and may change the string
|
|
||||||
itself (for example, to reallocate memory for increase the limit),
|
|
||||||
maximum length, and position of the line - pointers are passed for it.
|
|
||||||
Return value: 0 = line wasn't changed 1 = line changed, you should
|
|
||||||
remove old string and display new, 2 = line changed, it is necessary
|
|
||||||
to display it; 3 = immediately exit the function.
|
|
||||||
Starting from version 6, the function returns a pointer to the entered
|
|
||||||
line with the successful reading, and NULL if the console window was closed. */
|
|
||||||
|
|
||||||
int __con_is_load;
|
|
||||||
unsigned *__con_dll_ver;
|
|
||||||
|
|
||||||
int __con_init(void);
|
|
||||||
int __con_init_opt(int wnd_width, int wnd_height, int scr_width, int scr_height, const char* title);
|
|
||||||
void stdcall (*__con_exit)(int status);
|
|
||||||
|
|
||||||
#endif
|
|
@ -13,8 +13,8 @@ size_t fread(void *restrict ptr, size_t size, size_t nmemb, FILE *restrict strea
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(stream==stdin){
|
if(stream==stdin){
|
||||||
__con_init();
|
con_init();
|
||||||
__con_gets((char*)ptr, bytes_count+1);
|
con_gets((char*)ptr, bytes_count+1);
|
||||||
return nmemb;
|
return nmemb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <sys/ksys.h>
|
#include <sys/ksys.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
size_t fwrite(const void *restrict ptr, size_t size, size_t nmemb, FILE *restrict stream) {
|
size_t fwrite(const void *restrict ptr, size_t size, size_t nmemb, FILE *restrict stream) {
|
||||||
unsigned bytes_written = 0;
|
unsigned bytes_written = 0;
|
||||||
unsigned bytes_count = size * nmemb;
|
unsigned bytes_count = size * nmemb;
|
||||||
@ -14,8 +13,8 @@ size_t fwrite(const void *restrict ptr, size_t size, size_t nmemb, FILE *restric
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(stream==stdout){
|
if(stream==stdout){
|
||||||
__con_init();
|
con_init();
|
||||||
__con_write_string((char*)ptr, bytes_count);
|
con_write_string((char*)ptr, bytes_count);
|
||||||
return nmemb;
|
return nmemb;
|
||||||
}
|
}
|
||||||
else if(stream==stderr){
|
else if(stream==stderr){
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "conio.h"
|
#include <conio.h>
|
||||||
|
|
||||||
int getchar(void) {
|
int getchar(void) {
|
||||||
__con_init();
|
con_init();
|
||||||
char c = 0;
|
char c = 0;
|
||||||
__con_gets(&c, 2);
|
con_gets(&c, 2);
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
c = EOF;
|
c = EOF;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
char *gets(char* str)
|
char *gets(char* str)
|
||||||
{
|
{
|
||||||
__con_init();
|
con_init();
|
||||||
if(__con_gets(str, STDIO_MAX_MEM)==NULL){
|
if(con_gets(str, STDIO_MAX_MEM)==NULL){
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
int puts(const char *str)
|
int puts(const char *str)
|
||||||
{
|
{
|
||||||
__con_init();
|
con_init();
|
||||||
__con_write_asciiz(str);
|
con_write_asciiz(str);
|
||||||
__con_write_asciiz("\n");
|
con_write_asciiz("\n");
|
||||||
return strlen(str);
|
return strlen(str);
|
||||||
}
|
}
|
@ -18,9 +18,9 @@ int vprintf ( const char * format, va_list arg )
|
|||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
__con_init();
|
con_init();
|
||||||
len = vsnprintf(s, STDIO_MAX_MEM, format, arg);
|
len = vsnprintf(s, STDIO_MAX_MEM, format, arg);
|
||||||
__con_write_string(s, len);
|
con_write_string(s, len);
|
||||||
free(s);
|
free(s);
|
||||||
return(len);
|
return(len);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
|
/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */
|
||||||
|
|
||||||
#include "../stdio/conio.h"
|
#include <conio.h>
|
||||||
#include <sys/ksys.h>
|
#include <sys/ksys.h>
|
||||||
|
|
||||||
void exit(int status)
|
void exit(int status)
|
||||||
{
|
{
|
||||||
if(__con_is_load){
|
if(__con_is_load){
|
||||||
__con_exit(status);
|
con_exit(status);
|
||||||
}
|
}
|
||||||
_ksys_exit();
|
_ksys_exit();
|
||||||
}
|
}
|
||||||
|
@ -1,763 +0,0 @@
|
|||||||
/* 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
|
|
@ -15,7 +15,7 @@ struct tm * localtime (const time_t * timer)
|
|||||||
int bcd_year = (kos_date & 0xFF);
|
int bcd_year = (kos_date & 0xFF);
|
||||||
buffertime.tm_mday = ((bcd_day & 0xF0)>>4)*10 + (bcd_day & 0x0F);
|
buffertime.tm_mday = ((bcd_day & 0xF0)>>4)*10 + (bcd_day & 0x0F);
|
||||||
buffertime.tm_mon = ((bcd_mon & 0xF0)>>4)*10 + (bcd_mon & 0x0F) - 1;
|
buffertime.tm_mon = ((bcd_mon & 0xF0)>>4)*10 + (bcd_mon & 0x0F) - 1;
|
||||||
buffertime.tm_year = ((bcd_year & 0xF0)>>4)*10 + (bcd_year & 0x0F) + 100;
|
buffertime.tm_year = ((bcd_year & 0xF0)>>4)*10 + (bcd_year & 0x0F);
|
||||||
|
|
||||||
buffertime.tm_wday = buffertime.tm_yday = buffertime.tm_isdst = -1; /* temporary */
|
buffertime.tm_wday = buffertime.tm_yday = buffertime.tm_isdst = -1; /* temporary */
|
||||||
|
|
||||||
|
@ -96,6 +96,11 @@ readdir
|
|||||||
rewinddir
|
rewinddir
|
||||||
seekdir
|
seekdir
|
||||||
telldir
|
telldir
|
||||||
|
getcwd
|
||||||
|
mkdir
|
||||||
|
rmdir
|
||||||
|
setcwd
|
||||||
|
getcwd
|
||||||
!____UNISTD____
|
!____UNISTD____
|
||||||
!____MATH____
|
!____MATH____
|
||||||
acosh
|
acosh
|
||||||
@ -132,5 +137,24 @@ tolower
|
|||||||
toupper
|
toupper
|
||||||
!___CONIO___
|
!___CONIO___
|
||||||
con_set_title
|
con_set_title
|
||||||
|
con_init
|
||||||
|
con_init_opt
|
||||||
|
con_write_asciiz
|
||||||
|
con_write_string
|
||||||
|
con_printf
|
||||||
|
con_exit
|
||||||
|
con_get_flags
|
||||||
|
con_set_flags
|
||||||
|
con_kbhit
|
||||||
|
con_getch
|
||||||
|
con_getch2
|
||||||
|
con_gets
|
||||||
|
con_gets2
|
||||||
|
con_get_font_height
|
||||||
|
con_get_cursor_height
|
||||||
|
con_set_cursor_height
|
||||||
|
con_cls
|
||||||
|
con_get_cursor_pos
|
||||||
|
con_set_cursor_pos
|
||||||
!___LIBC_VERSION___
|
!___LIBC_VERSION___
|
||||||
_libc_get_version
|
_libc_get_version
|
25
programs/develop/libraries/kolibri-libc/source/sys/dir.c
Normal file
25
programs/develop/libraries/kolibri-libc/source/sys/dir.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <sys/ksys.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char *getcwd(char *buf, unsigned size){
|
||||||
|
if(!buf){
|
||||||
|
if((buf = malloc(size))==NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ksys_getcwd(buf, size);
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setcwd(const char* cwd){
|
||||||
|
_ksys_setcwd((char*)cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rmdir(const char* dir){
|
||||||
|
return _ksys_file_delete(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mkdir(const char* dir){
|
||||||
|
return _ksys_mkdir(dir);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user