/programs/develop/ktcc/trunk/libc/math/fmod.c |
---|
0,0 → 1,86 |
#include <math.h> |
double remainder(double numer, double denom) |
{ |
double res; |
asm("fldl %2;" |
"fldl %1;" |
"fprem1;" |
"fstpl %0;" |
"fstp %%st;" |
: "=m"(res) |
: "m"(numer), "m"(denom) |
); |
return res; |
} |
//remainder of 5.3 / 2 is -0.700000 |
//remainder of 18.5 / 4.2 is 1.700000 |
double fmod(double numer, double denom) |
{ |
double res; |
asm("fldl %2;" |
"fldl %1;" |
"fprem;" |
"fstpl %0;" |
"fstp %%st;" |
: "=m"(res) |
: "m"(numer), "m"(denom) |
); |
return res; |
} |
// fmod of 5.3 / 2 is 1.300000 |
// fmod of 18.5 / 4.2 is 1.700000 |
double modf(double x, double *intpart) |
{ |
double res, intp; |
asm("fldl %2;" |
"fldl %2;" |
"frndint;" |
"fstl %1;" |
"fxch;" |
"fsubp %%st, %%st(1);" |
"fstpl %0" |
: "=m"(res), "=m"(intp) |
: "m"(x) |
); |
*intpart = intp; |
return res; |
} |
double ldexp (double x, int expon) |
// = x * 2^expot |
{ |
double res; |
asm("fildl %2;" |
"fldl %1;" |
"fscale;" |
"fstpl %0;" |
"fstp %%st;" |
: "=m"(res) |
: "m"(x), "m"(expon) |
); |
return res; |
} |
double frexp (double x, int* expon) |
{ |
double res; |
asm("fldl %2;" |
"fxtract;" |
"fstpl %0;" |
"fistpl %1;" |
"fstp %%st;" |
: "=m"(res), "=m"(*expon) |
: "m"(x) |
); |
// *expon = (int)ex; |
return res; |
} |
// 8.000000 = 0.500000 * 2^ 4 |
/programs/develop/ktcc/trunk/samples/asm_ex.c |
---|
0,0 → 1,68 |
/* examples for interoperability with assembler |
1. Calling assembler code from .c : see in libc\math any .asm file |
2. Using inline assembler: see \include\kos32sys1.h and libc\math\fmod.c |
- https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Extended-Asm.html |
- not all constraints from gcc are supported, no "f" or "t" for example |
- not supported clobberring st registers, must manual add "fstp %%st" at end or similar |
- need full suffixes for opcodes, fstpl but not fstp |
3. Calling c functions from .asm: see \libc\start\start.asm:99 |
Remember: |
- small ints always passed as int32, floating point params as 64-bit |
- returned structs passed on stack with additional hidden 1st param |
- c functions can use EAX, ECX, EDX without warnings |
- .c default is cdecl calling convention https://en.wikipedia.org/wiki/X86_calling_conventions |
- dont use fastcall calling convention, tinycc realized it non-conformant way |
- tinycc supports only ELF object files |
tcc can be used as a linker |
*/ |
#include <stdio.h> |
#include <math.h> |
main() |
{ |
int i; |
for (i = 0; i < 20; i++) |
{ |
printf("------------------------------------------------------\n"); |
printf ( "remainder of 5.3 / 2 is %f\n", remainder (5.3,2) ); |
printf ( "remainder of 18.5 / 4.2 is %f\n", remainder (18.5,4.2) ); |
//remainder of 5.3 / 2 is -0.700000 |
//remainder of 18.5 / 4.2 is 1.700000 |
printf ( "fmod of 5.3 / 2 is %f\n", fmod (5.3,2) ); |
printf ( "fmod of 18.5 / 4.2 is %f\n", fmod (18.5,4.2) ); |
// fmod of 5.3 / 2 is 1.300000 |
// fmod of 18.5 / 4.2 is 1.700000 |
double param, fractpart, intpart, result; |
int n; |
param = 3.14159265; |
fractpart = modf (param , &intpart); |
printf ("%f = %f + %f \n", param, intpart, fractpart); |
//3.141593 = 3.000000 + 0.141593 |
param = 0.95; |
n = 4; |
result = ldexp (param , n); |
printf ("%f * 2^%d = %f\n", param, n, result); |
//0.950000 * 2^4 = 15.200000 |
param = 8.0; |
result = frexp (param , &n); |
printf ("%f = %f * 2^%d\n", param, result, n); |
//8.000000 = 0.500000 * 2^4 |
param = 50; |
result = frexp (param , &n); |
printf ("%f = %f * 2^%d\n", param, result, n); |
} |
} |
/programs/develop/ktcc/trunk/source/config.h |
---|
4,5 → 4,7 |
#define TCC_TARGET_I386 |
#define ONE_SOURCE |
//#define TCC_TARGET_COFF |
//#define COMMIT_4ad186c5ef61_IS_FIXED |
//#define CONFIG_TCC_BCHECK |
/programs/develop/ktcc/trunk/source/libtcc.c |
---|
2126,6 → 2126,12 |
int optind = 0; |
ParseArgsState *pas = s->parse_args_state; |
/* |
#ifdef TCC_TARGET_MEOS |
// siemargl testing |
s->output_format = TCC_OUTPUT_FORMAT_COFF; |
#endif |
*/ |
while (optind < argc) { |
r = argv[optind++]; |
/programs/develop/ktcc/trunk/source/readme_kos32.txt |
---|
61,7 → 61,7 |
limits.h |
locale.h |
setjmp.h |
signall.h |
signal.h |
time.h - can use get_tick_count()/100 from kos32sys1.h |
wchar.h |
wctype.h |
70,14 → 70,6 |
functions absent list: |
math.h |
frexp |
ldexp |
modf |
fmod |
HUGE_VAL |
stdio.h: |
remove |
rename |
/programs/develop/ktcc/trunk/source/tcc.h |
---|
348,6 → 348,11 |
/* -------------------------------------------- */ |
/* include the target specific definitions */ |
#ifdef TCC_TARGET_COFF |
# include "coff.h" |
#endif |
#define TARGET_DEFS_ONLY |
#ifdef TCC_TARGET_I386 |
# include "i386-gen.c" |
362,7 → 367,6 |
# include "arm64-gen.c" |
#endif |
#ifdef TCC_TARGET_C67 |
# include "coff.h" |
# include "c67-gen.c" |
#endif |
#undef TARGET_DEFS_ONLY |
/programs/develop/ktcc/trunk/source/tcccoff.c |
---|
876,24 → 876,24 |
} |
if (fread(&file_hdr, FILHSZ, 1, f) != 1) |
tcc_error("error reading .out file for input"); |
tcc_error("error 1 reading .out file for input"); |
if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1) |
tcc_error("error reading .out file for input"); |
tcc_error("error 2 reading .out file for input"); |
// first read the string table |
if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET)) |
tcc_error("error reading .out file for input"); |
tcc_error("error 3 reading .out file for input"); |
if (fread(&str_size, sizeof(int), 1, f) != 1) |
tcc_error("error reading .out file for input"); |
tcc_error("error 4 reading .out file for input"); |
Coff_str_table = (char *) tcc_malloc(str_size); |
if (fread(Coff_str_table, str_size - 4, 1, f) != 1) |
tcc_error("error reading .out file for input"); |
tcc_error("error 5 reading .out file for input"); |
// read/process all the symbols |
900,11 → 900,11 |
// seek back to symbols |
if (fseek(f, file_hdr.f_symptr, SEEK_SET)) |
tcc_error("error reading .out file for input"); |
tcc_error("error 6 reading .out file for input"); |
for (i = 0; i < file_hdr.f_nsyms; i++) { |
if (fread(&csym, SYMESZ, 1, f) != 1) |
tcc_error("error reading .out file for input"); |
tcc_error("error 7 reading .out file for input"); |
if (csym._n._n_n._n_zeroes == 0) { |
name = Coff_str_table + csym._n._n_n._n_offset - 4; |