Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!uunet!viusys!uxui!unislc!bryce!netw23!val From: val@netw23.uucp (Oberon Kenobi) Newsgroups: comp.sys.amiga.programmer Subject: SAS/C Assembler bug + FPU quiz Message-ID: <177235@netw23.uucp> Date: 11 May 91 18:11:48 GMT Organization: Weber State University, CS DEPT. Lines: 199 I am a programmer who uses C mostly, but I use assembler for things that "are difficult or impossible in pure C." I sometimes resort to optimizing in assembler. (The 90/10 rule: 90% of the code is run 10% of the time, and 10% of the code is run 90% of the time.) It's more portable to program in a high level language. Now, back to the purpose of this posting. Following is actual code compiled and run on an Amiga 3000. (NOTE: it requires a 68881 or 68882 to run this code on any system. The A3000/16 has a 68881, and the A3000/25 has a 68882.) The purpose of this code is to: 1) demonstrate a bug in the SAS/C Assembler 2) give a small quiz on how well you know what's going on in your CPU 3) provide some useful code 1) Notice the macro definition (consts.asm). The commented line is what I wanted to do, but the assembler has a bug. No matter which floating poing constant I ask for, I get constant #0 (pi). (Beware of this problem when writing your own code.) This was frustrating, so I had to actually insert the instruction words myself. 2) Notice the self-modifying version, which was the first that I tried. All caches were turned off, but it was still one constant behind. (i.e.: In my loop, I ask for $3F and I get pi, $3E -> 10^4096, $3D ->10^2048, etc..) Please don't mail me nor post the answer. This is a quiz for which I will post the answer in two weeks. 3) This provides a way of getting these floating point constants as accurately as possible without having to type them into your code. There are trade-offs as always. I was using it to try to find out, for curiosity's sake, what the undocumented floating point constants are. (Most of them appear to be zero by the way.) The FMOVECR macro may be used in C, but note the cautions in the SAS/C manual on using the emit() built-in function. fpconsts.c====================================================================== #include /* FMOVECR macro not actually tested, but it should work. */ #define FMOVECR(fp_reg,const) emit(0xF200); \ emit(0x5C00 | ((fp_reg)<<6) | ((const)&0x3F) ) extern double fpconst(int i); main() { int i; for(i=0x3f; i>=0; --i) printf("0x%02x\t=%g\n",i,fpconst(i)); } consts.asm====================================================================== macro retcr const ; Return constant register in FP0 ; fmovecr.x const,fp0 ; Move constant to fp0 dc.w $F200 dc.w $5c00+const ; Because of a bug in the SAS/C assembler rts nop ; Cause alignment on 4-word (8-byte) boundary endm csect text xdef _fpconst ; Parameter on top of stack entry point xdef _fpconst_d0 ; Parameter-in-R0 entry point xdef _fpconst_sm ; Self-modifying version xdef _fpconst_sm_r0 ; Parameter-in-R0 entry point for self-modifying V csect code _fpconst: move.l 4(a7),d0 ; Get it from the stack if called that way _fpconst_d0: and.l #63,d0 ; Only pay attention to the lower six bits lsl.l #3,d0 ; Multiply it by eight to get an offset jmp 2(pc,d0) ; Jump to appropriate constant-fetch code case0: retcr $00 retcr $01 retcr $02 retcr $03 retcr $04 retcr $05 retcr $06 retcr $07 retcr $08 retcr $09 retcr $0A retcr $0B retcr $0C retcr $0D retcr $0E retcr $0F retcr $10 retcr $11 retcr $12 retcr $13 retcr $14 retcr $15 retcr $16 retcr $17 retcr $18 retcr $19 retcr $1A retcr $1B retcr $1C retcr $1D retcr $1E retcr $1F retcr $20 retcr $21 retcr $22 retcr $23 retcr $24 retcr $25 retcr $26 retcr $27 retcr $28 retcr $29 retcr $2A retcr $2B retcr $2C retcr $2D retcr $2E retcr $2F retcr $30 retcr $31 retcr $32 retcr $33 retcr $34 retcr $35 retcr $36 retcr $37 retcr $38 retcr $39 retcr $3A retcr $3B retcr $3C retcr $3D retcr $3E retcr $3F _fpconst_sm: move.l 4(a7),d0 ; Get it from the stack if called that way _fpconst_sm_r0: and.b #63,d0 ; Only pay attention to the lower six bits lea 7(pc),a0 ; The location that is going to be changed move.b d0,(a0) ; Change the location fmovecr.x #0,fp0 ; Move the constant rts end constants====================================================================== ROM Constants from FMOVECR instruction in "Programmer's Reference Manual" (M68000PM/AD) from Motorola. (Quoted without permission.) Offset Constant ------ -------- $00 pi $0B log10(2) $0C e $0D log2(e) $0E log10(e) $0F 0.0 $30 ln(2) $31 ln(10) $32 10^0 $33 10^1 $34 10^2 $35 10^4 $36 10^8 $37 10^16 $38 10^32 $39 10^64 $3A 10^128 $3B 10^256 $3C 10^512 $3D 10^1024 $3E 10^2048 $3F 10^4096 The on-chip ROM contains other constants useful only to the on-chip microcode routines. The values contained at offsets other than those defined above are reserved for the use of Motorola, and may be different on various mask sets of the FPCP. signature======================================================================= ____ ____ ____ |=============================================================| \ \/ \/ / | "vi? Because I don't have a real editor." -- U*x user | \Weber State/ |=============================================================| \University/ | Internet: val@csulx.weber.edu, val@net23.weber.edu |Oberon| \___/\___/ | Usenet: uunet!viusys!uxui!unislc!bryce!netw23!val |Kenobi| Computer Science |=============================================================| end of message==================================================================