Date: Tue, 30 Jun 92 18:23:52 PRT From: "Jose M. Cerqueira Esteves" Subject: 387 instructions in asm. To: djgpp AT sun DOT soe DOT clarkson DOT edu Hi I am converting a recent random number generator package (by George Marsaglia and Arif Zaman) for use with GCC on the PC. The original routines were written in assembler, but, since I am going to use them also on other computers, I am rewriting them in C, using the "asm" instruction only for a few instructions which would be much slower if coded in C. To do this, I read the section "Assembler instructions with C expression operands", in "Using and porting GNU CC". I had no problems when using instructions not related to the numeric processor, but I have some doubts about usage of 80387 instructions. To be specific, I would like to write a routine of the form float RSuni(void) { float random_float; . . /* instructions converting a 31 bit integer . (from an external array) into a float, . assigning the result to random_float */ return random_float; } and/or (for GNU CC): #define RSuni() \ ({ \ float random_float; \ . \ . /* instructions converting a 31 bit integer \ . (from an external array) into a float, \ . assigning the result to random_float */ \ random_float; \ }) The conversion from the 31 bit int (a positive 32 bit int) to random_float is made dividing by 2^p, where p=-31 except when the first byte of the int is 0 (in this case, another leading byte is generated and p is decremented by 7). The original assembler program does this scaling by loading p and the integer into the 80387 stack and then using the "fscale" and "fstp st(1)" instructions. This leaves the result in the top register of the floating-point stack. I tried to code this as follows: register float random_float asm ("%st"); . . /* C code .... */ . asm volatile ("fildl %1; fildl %2; fscale; fstp %%st(1)" : "=f" (random_float) : "g" (p), "g" (the_integer_to_be_converted) ); return random_float; /* or simply "random_float;", if defined as a macro */ GCC did not accept the above, saying "Output constant 0 must specify a single register". I then replaced "=f" with "=%st" and no errors were reported. Is this OK (and safe)? I expect this to always leave the result (random_float) on the stack top, ready to be used in subsequent calculations. But I expect trouble when the 80387 stack is almost full immediately before the above is run. Will GCC take care of this problem if I specify (in the asm instruction) all or some (which?) of the stack registers as clobbered? Perhaps I could get the answers by trial and error, but I haven't got much time for it (also, this is only the second time I use assembler). I am using GCC 2.01 (DJGPP 1.06) Thanks in advance for any information. (Also, many thanks to DJ for DJGPP!)