1
1
Fork 0
mirror of https://github.com/QB64Official/qb64.git synced 2024-07-05 15:50:25 +00:00

Explicitly set x87 fpu to extended precision mode

This commit is contained in:
Luke Ceddia 2021-06-17 23:51:08 +10:00
parent e452241a28
commit bf32a6a0fc
No known key found for this signature in database
GPG key ID: 319344384A0759B0
2 changed files with 37 additions and 158 deletions

View file

@ -64,90 +64,58 @@ return (word << shift) | (word >> (32 - shift));
uint64 qbr_longdouble_to_uint64(long double f){if (f<0) return(f-0.5f); else return(f+0.5f);}
int32 qbr_float_to_long(float f){if (f<0) return(f-0.5f); else return(f+0.5f);}
int32 qbr_double_to_long(double f){if (f<0) return(f-0.5f); else return(f+0.5f);}
void fpu_reinit() { // do nothing }
#else
//QBASIC compatible rounding via FPU:
#ifdef QB64_MICROSOFT
int64 qbr(long double f){
int64 i; int temp=0;
if (f>9223372036854775807) {temp=1;f=f-9223372036854775808u;} //if it's too large for a signed int64, make it an unsigned int64 and return that value if possible.
__asm{
fld f
fistp i
}
if (temp) return i|0x8000000000000000;//+9223372036854775808;
return i;
}
uint64 qbr_longdouble_to_uint64(long double f){
uint64 i;
__asm{
fld f
fistp i
}
return i;
}
int32 qbr_float_to_long(float f){
int32 i;
__asm{
fld f
fistp i
}
return i;
}
int32 qbr_double_to_long(double f){
int32 i;
__asm{
fld f
fistp i
}
return i;
}
#else
//FLDS=load single
//FLDL=load double
//FLDT=load long double
int64 qbr(long double f){
int64 i; int temp=0;
if (f>9223372036854775807) {temp=1;f=f-9223372036854775808u;} //if it's too large for a signed int64, make it an unsigned int64 and return that value if possible.
__asm__ (
//FLDS=load single
//FLDL=load double
//FLDT=load long double
int64 qbr(long double f){
int64 i; int temp=0;
if (f>9223372036854775807) {temp=1;f=f-9223372036854775808u;} //if it's too large for a signed int64, make it an unsigned int64 and return that value if possible.
__asm__ (
"fldt %1;"
"fistpll %0;"
:"=m" (i)
:"m" (f)
);
if (temp) return i|0x8000000000000000;// if it's an unsigned int64, manually set the bit flag
return i;
}
uint64 qbr_longdouble_to_uint64(long double f){
uint64 i;
__asm__ (
);
if (temp) return i|0x8000000000000000;// if it's an unsigned int64, manually set the bit flag
return i;
}
uint64 qbr_longdouble_to_uint64(long double f){
uint64 i;
__asm__ (
"fldt %1;"
"fistpll %0;"
:"=m" (i)
:"m" (f)
);
return i;
}
int32 qbr_float_to_long(float f){
int32 i;
__asm__ (
);
return i;
}
int32 qbr_float_to_long(float f){
int32 i;
__asm__ (
"flds %1;"
"fistpl %0;"
:"=m" (i)
:"m" (f)
);
return i;
}
int32 qbr_double_to_long(double f){
int32 i;
__asm__ (
);
return i;
}
int32 qbr_double_to_long(double f){
int32 i;
__asm__ (
"fldl %1;"
"fistpl %0;"
:"=m" (i)
:"m" (f)
);
return i;
}
#endif
);
return i;
}
void fpu_reinit(){
unsigned int mode = 0x37F;
asm("fldcw %0" : : "m" (*&mode));
}
#endif //x86 support
//bit-array access functions (note: used to be included through 'bit.cpp')
uint64 getubits(uint32 bsize,uint8 *base,ptrszint i){

95
internal/c/qbx.cpp Normal file → Executable file
View file

@ -656,6 +656,7 @@ extern int64 qbr(long double f);
extern uint64 qbr_longdouble_to_uint64(long double f);
extern int32 qbr_float_to_long(float f);
extern int32 qbr_double_to_long(double f);
extern void fpu_reinit(void);
extern uint64 getubits(uint32 bsize,uint8 *base,ptrszint i);
extern int64 getbits(uint32 bsize,uint8 *base,ptrszint i);
@ -2087,80 +2088,7 @@ void division_by_zero_handler(int ignore){
#endif
void QBMAIN(void *unused)
{
/*
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 44100);
//lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
*/
/*
///OPENAL
dev = alcOpenDevice(NULL); if(!dev) exit(111);
ctx = alcCreateContext(dev, NULL);
alcMakeContextCurrent(ctx); if(!ctx) exit(222);
#define NUM_BUFFERS 3
#define BUFFER_SIZE 4096
ALuint source, buffers[NUM_BUFFERS];
ALuint frequency;
ALenum format;
unsigned char *buf;
alGenBuffers(NUM_BUFFERS, buffers);
alGenSources(1, &source);
if(alGetError() != AL_NO_ERROR) exit(333);
int channels, bits;
channels=1;
bits=8;
frequency=22050;
format = 0;
if(bits == 8)
{
if(channels == 1)
format = AL_FORMAT_MONO8;
else if(channels == 2)
format = AL_FORMAT_STEREO8;
}
else if(bits == 16)
{
if(channels == 1)
format = AL_FORMAT_MONO16;
else if(channels == 2)
format = AL_FORMAT_STEREO16;
}
int ret;
//qbs_print(qbs_str((int32)ALC_FREQUENCY),1);
//uint8 *buf;
buf=(unsigned char*)malloc(4096);
//fill with crap!
int ii;
for (ii=0;ii<4096;ii++){
buf[ii]=func_rnd(NULL,0)*255.0;
}
alBufferData(buffers[0], format, buf, BUFFER_SIZE, frequency);
alBufferData(buffers[1], format, buf, BUFFER_SIZE, frequency);
alBufferData(buffers[2], format, buf, BUFFER_SIZE, frequency);
alSourceQueueBuffers(source, NUM_BUFFERS, buffers);
alSourcePlay(source);
if(alGetError() != AL_NO_ERROR) exit(444);
*/
#ifdef QB64_WINDOWS
static uint8 controlfp_set=0;
if (!controlfp_set){controlfp_set=1; _controlfp(_PC_64,0x00030000);}//_MCW_PC=0x00030000
#endif
fpu_reinit();
#ifdef QB64_WINDOWS
signal(SIGFPE, division_by_zero_handler);
//signal(SIGSEGV, SIGSEGV_handler);
@ -2171,28 +2099,11 @@ void QBMAIN(void *unused)
sig_act.sa_flags = 0;
sigaction(SIGFPE, &sig_act, NULL);
#endif
/*
ptrszint z;
z=(ptrszint)&dummyfunc;
myfunc=(functype*)z;
exit(myfunc(0,0));
*/
ptrszint tmp_long;
int32 tmp_fileno;
qbs* tqbs;
uint32 qbs_tmp_base=qbs_tmp_list_nexti;
static mem_lock *sf_mem_lock=NULL;
if (!sf_mem_lock){new_mem_lock(); sf_mem_lock=mem_lock_tmp; sf_mem_lock->type=3;}