This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.
See the CrossGCC FAQ for lots more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Is result global? If not, gcc can legally nuke it, I think...
It might help to show your actual source.
-- Bryce Schober Design Engineer Dynon Avionics, Inc. www.dynonavionics.com
#ifndef __FIXP_MUL_H__ #define __FIXP_MUL_H__ /* File: Multiplication Functions (fixp_mul.h) This set of functions implement fixed-point multiplication for signed and unsigned numbers in a variety of <Qm.n Format>s. There are several different functions which behave in slightly different ways. The function names specify this behavior. The "32s" in the function name indicates that the inputs are 32-bit signed integer types. For unsigned inputs, use the "32u" functions. The "nXX" part of the function name indicates the <Qm.n Format> of the inputs and output. For 8.24 fixed- point numbers the "_n24" functions should be used. If an output format different than that of the input is needed, then the "_nX" functions should be used. The n parameter should specify the "n" part of the <Qm.n Format> for _both_ a and b for the normally expected result. More specifically, the n argument specifies the right-shift amount performed on the 64-bit intermediate result of the 32x32 multiply. It can, however, be used in abnormal ways to re-format the resulting number to a different <Qm.n Format>. For example, if a and b are in 24.8 format, but you wanted to keep all precision from the multiply and get the result in 16.16 format, you can simply call the function with n=0 (but _make sure_ that your answer won't overflow). Another example would be converting degrees to radians. Given an input degrees in 16.16 format and a desired radian output in 8.24 format, simply call the function with a=<input in degrees>, b=74961321 (pi/180*2^32), and n=24. Parameters: x - The first fixed-point number. y - The second fixed-point number. n - [Optional] The UNS_8 shift amount (1<=n<=32). (usually the n part of the input Qm.n fixed-point format) Returns: ( x * y ) >> n (with rounding) Macros Used: - <fixp_mul_32s_nX> - <fixp_mul_32u_nX> */ #include <SMA_types.h> #include "fixp_macros.h" /* Function: fixp_mul_32s_nX Multiplies two *signed* m.n fixed-point numbers, using user-specified shift with rounding. Parameters: x - The first INT_32 fixed-point number. y - The second INT_32 fixed-point number. n - The UNS_8 shift amount (1<=n<=32). (usually the n part of the input Qm.n fixed-point format) Returns: (INT_32) ( x * y ) >> n (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline INT_32 fixp_mul_32s_nX( INT_32 x, INT_32 y, UNS_8 n ) { INT_32 res, tmp; __asm__ __volatile__ ( "smull %0, %1, %3, %4 \n\t" "movs %0, %0, lsr %2 \n\t" "rsb %2, %2, #32 \n\t" "adc %1, %0, %1, lsl %2 \n\t" : "=&r" (tmp), "=&r" (res), "+r" (n) : "r" (x), "r" (y) ); return res; } /* Function: fixp_mul_32u_nX Multiplies two *unsigned* m.n fixed-point numbers, using user-specified shift with rounding. Parameters: x - The first UNS_32 fixed-point number. y - The second UNS_32 fixed-point number. n - The UNS_8 shift amount (1<=n<=32). (usually the n part of the input Qm.n fixed-point format) Returns: (UNS_32) ( x * y ) >> n (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline UNS_32 fixp_mul_32u_nX( UNS_32 x, UNS_32 y, UNS_8 n ) { UNS_32 res, tmp; __asm__ __volatile__ ( "umull %0, %1, %3, %4 \n\t" "movs %0, %0, lsr %2 \n\t" "rsb %2, %2, #32 \n\t" "adc %1, %0, %1, lsl %2 \n\t" : "=&r" (tmp), "=&r" (res), "+r" (n) : "r" (x), "r" (y) ); return res; } /* Function: fixp_mul_32s_n8 Multiplies two *signed* 24.8 fixed-point numbers Parameters: x - The first INT_32 fixed-point number. y - The second INT_32 fixed-point number. Returns: (INT_32) ( x * y ) >> 8 (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline INT_32 fixp_mul_32s_n8( INT_32 x, INT_32 y ) { return fixp_mul_32s_nX( x, y, 8 ); } /* Function: fixp_mul_32u_n8 Multiplies two *unsigned* 24.8 fixed-point numbers Parameters: x - The first UNS_32 fixed-point number. y - The second UNS_32 fixed-point number. Returns: (UNS_32) ( x * y ) >> 8 (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline UNS_32 fixp_mul_32u_n8( UNS_32 x, UNS_32 y ) { return fixp_mul_32u_nX( x, y, 8 ); } /* Function: fixp_mul_32s_n16 Multiplies two *signed* 16.16 fixed-point numbers Parameters: x - The first INT_32 fixed-point number. y - The second INT_32 fixed-point number. Returns: (INT_32) ( x * y ) >> 16 (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline INT_32 fixp_mul_32s_n16( INT_32 x, INT_32 y ) { return fixp_mul_32s_nX( x, y, 16 ); } /* Function: fixp_mul_32u_n16 Multiplies two *unsigned* 16.16 fixed-point numbers Parameters: x - The first UNS_32 fixed-point number. y - The second UNS_32 fixed-point number. Returns: (UNS_32) ( x * y ) >> 16 (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline UNS_32 fixp_mul_32u_n16( UNS_32 x, UNS_32 y ) { return fixp_mul_32u_nX( x, y, 16 ); } /* Function: fixp_mul_32s_n24 Multiplies two *signed* 8.24 fixed-point numbers Parameters: x - The first INT_32 fixed-point number. y - The second INT_32 fixed-point number. Returns: (INT_32) ( x * y ) >> 24 (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline INT_32 fixp_mul_32s_n24( INT_32 x, INT_32 y ) { return fixp_mul_32s_nX( x, y, 24 ); } /* Function: fixp_mul_32u_n24 Multiplies two *unsigned* 8.24 fixed-point numbers Parameters: x - The first UNS_32 fixed-point number. y - The second UNS_32 fixed-point number. Returns: (UNS_32) ( x * y ) >> 24 (with rounding) See Also: <Multiplication Functions>, <Qm.n Format> */ static inline UNS_32 fixp_mul_32u_n24( UNS_32 x, UNS_32 y ) { return fixp_mul_32u_nX( x, y, 24); } #endif /* __FIXP_MUL_H__ */
#ifndef __FIXP_H__ #define __FIXP_H__ /* File: Fixed-Point Math Library (fixp.h) This is the fixed-point math library for Dynon Avionics. Its current implementation is optimized ARM7 assembly, and will likely be extended to include generic C implementations for debugging on i386 machines in the near future. Because of limitations between the GNU C compiler and its inline assembly syntax, some of the highly optimized functions are implemented as macros which use inline assembly. These functions can be found in the <Macros> file, fixp_macros.h. This library is loosely based on the functions offered by Intel's Graphics Performance Primitives Library, found here: - http://developer.intel.com/design/pca/applicationsprocessors/swsup/gpp.htm It may be helpful to the programmer to review the introductory text for the above library found here: - http://www.devx.com/Intel/Article/16478 This file is basically a placeholder for this documentation and for including the entire fixed-point library at once. Files: - <General Functions> - <Multiplication Functions> - <Macros> */ #include "fixp_gen.h" #include "fixp_mul.h" /* Topic: Qm.n Format The <Fixed-Point Math Library> library uses the Qm.n fixed-point representation of data for its functions. The Qm.n format provides a standard mechanism for representing fixed-point values. The integer binary word is partitioned using an imaginary fixed point. The n-bits to the right of the imaginary point comprise the fractional portion of the value being represented, and these n-bits act as weights for negative powers of 2. The m-bits to the left of the imaginary point comprise the integer portion of the value being represented, and these m-bits act as weights for positive powers of 2. The overall signed Qm.n representation requires a total of m+n bits for unsigned numbers or 1+m+n bits for signed numbers, with the additional bit used to indicate the sign. */ #endif /* __FIXP_H__ */
/* File: Test Suite This file is the test suite for the <Fixed-Point Math Library>. */ #include <stdlib.h> #include <math.h> #include <SMA_types.h> #include <DDB_globals.h> #include <LH79520_map.h> #include "fixp.h" #include "fixp_test_data.h" #define TEST_LOOPS 1 #define NUM_SET_SIZE 1002 void uart0_init(); void uart0_out_str( char *string ); float float_rand[NUM_SET_SIZE], float_res[NUM_SET_SIZE]; int int_rand[NUM_SET_SIZE], int_res[NUM_SET_SIZE]; /* Function: main This is the main() function for the <Fixed-Point Math Library> <Test Suite>. */ int main() { float float_a, float_b; INT_32 int_a, int_b, result; register int i, j; char outline[81]; uart0_init(); // Initialize uart0 /* Initialize the random number arrays. Both arrays should get numbers * between 0 and 32767. The integerss will be interpreted as 16.16 * fixed-point numbers and the floats will be assigned accordingly. */ uart0_out_str( "\rInitializing random operands...\r" ); srand(1); // Seed the random number generator for( i=0; i<6; i++ ) { for( j=i*NUM_SET_SIZE/6; j<(i+1)*NUM_SET_SIZE/6; j++ ) { switch( i ) { case 0: int_rand[j] = rand() >> 8; break; case 1: case 2: case 3: int_rand[j] = rand() >> 16; break; case 4: case 5: int_rand[j] = rand() >> 8; break; } float_rand[j] = (float) int_rand[j] / (float) 65536; } } uart0_out_str( "Operand initialization complete.\r" ); /* Initialize wiggle pins to be general-purpose output */ IOCON->lcdmux = 0x0000; // Set all LCD pins to be general-purpose GPIOC->ddr = 0xFF; // Set data direction to output GPIOC->dr &= ~0x08; // Set PortC[3] low GPIOC->dr ^= 0x08; // Toggle PortC[3] /* Do baseline loop */ uart0_out_str( "Running baseline loop...\r" ); for( i=0; i<TEST_LOOPS; i++ ) { for( j=0; j<NUM_SET_SIZE; j++ ) { int_a = int_rand[j]; int_b = int_rand[NUM_SET_SIZE-j]; int_res[j] = int_b; } GPIOC->dr ^= 0x08; // Toggle PortC[3] } uart0_out_str( "Baseline loop complete.\r" ); for( i=0; i<TEST_LOOPS*TEST_LOOPS; i++ ) { GPIOC->dr ^= 0x08;} /* Do fixed-point rounded multiply loop */ uart0_out_str( "Running fixed-point rounded loop...\r" ); for( i=0; i<TEST_LOOPS; i++ ) { for( j=0; j<NUM_SET_SIZE; j++ ) { int_a = int_rand[j]; int_b = int_rand[NUM_SET_SIZE-j-1]; int_res[j] = fixp_mul_32u_n16( int_a, int_b ); } GPIOC->dr ^= 0x08; // Toggle PortC[3] } uart0_out_str( "Fixed-point rounded loop complete.\r" ); for( i=0; i<TEST_LOOPS*TEST_LOOPS; i++ ) { GPIOC->dr ^= 0x08;} /* Do floating-point multiply loop */ uart0_out_str( "Running floating-point loop...\r" ); for( i=0; i<TEST_LOOPS; i++ ) { for( j=0; j<NUM_SET_SIZE; j++ ) { float_a = float_rand[j]; float_b = float_rand[NUM_SET_SIZE-j-1]; float_res[j] = float_a * float_b; } GPIOC->dr ^= 0x08; // Toggle PortC[3] } uart0_out_str( "Floating-point loop complete.\r\r" ); /* Print inputs & outputs */ for( i=0; i<NUM_SET_SIZE; i++ ) { result = sprintf( outline, "%d,%d,%.14e,%.14e\r", int_rand[i], int_res[i], float_rand[i], float_res[i] ); uart0_out_str( outline ); } int_a = int_rand[0]; int_b = int_rand[1]; result = fixp_mul_32u_n16( int_a, int_b ); int_a = int_rand[2]; int_b = int_rand[3]; result = result + fixp_mul_32u_n16( int_a, int_b ); /* Loop forever */ while(1) { GPIOC->dr ^= 0x08; } return 0; } /* Function: uart0_init This function initializes the uart on the Sharp LH79520 Dynon Display Board for use in reporting the test results of the <Fixed-Point Math Library> <Test Suite>. It has no parameters or return value. */ void uart0_init() { UART0->cr = 0x0; // Disable uart to enable settings changes UART0->imsc = 0x0; // Disable all uart interrupts UART0->ibrd = UARTBRINT_115200; // Integer baud rate setting UART0->fbrd = UARTBRFRAC_115200; // Fraction baud rate setting UART0->lcr_h = UARTLCR_WLEN8 | UARTLCR_PARITY_NONE | UARTLCR_STP1; // 8 N 1 UART0->cr = UARTCR_ENABLE | UARTCR_TXE | UARTCR_RXE; // Enable the uart } /* Function: uart0_out_str This function writes a null-terminated string to UART0. It has no return value. Parameters: *string - Pointer to a null-terminated string. */ void uart0_out_str( char *string ) { while ( *string ) { // Wait while TX fifo is full while ( UART0->fr & UARTFR_TXFF ) { } // Output char and increment pointer UART0->dr = *string; string++; } return; }
------ Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/ Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |