C multiplication with GCC

Thread Tools Search this Thread
Top Forums Programming C multiplication with GCC
# 1  
Old 08-04-2011
C multiplication with GCC

Hi all, newbie here.
Does anyone know if it is possible to use GCC or Clang to multiply
two unsigned numbers and have it use for intel instructions, the mull instruction or an imul. I can't figure how to word this to accomplish this task:
(int)(((unsigned long long)result * (unsigned)2290649225) >> 37);

result is max of 2^17 bits, and trying to retrieve high word >> 5 after a
mull or imul instruction. The above wording creates two multiply instructions.
This wording creates one instruction:
(int)(((unsigned long long)result * (unsigned)1145324613) >> 36);

Not sure intel can handle first and that's why gcc breaks into two multiplies???
I believe the second will accomplish my task, but now need to recheck all my code.
Thanx, and I'll probably get kicked (was smoking and typing)

Last edited by pludi; 08-04-2011 at 04:56 PM..
# 2  
Old 08-04-2011
How many bits is your architecture?

---------- Post updated at 10:25 AM ---------- Previous update was at 10:06 AM ----------

Researching this a bit, gcc asm doesn't have MUL/MULL, differentiating between the two based on their source operands. Or rather, it does have MULL, but if you use it it's VERY picky about which types it'll accept. Trying to figure out how to work this...

---------- Post updated at 10:33 AM ---------- Previous update was at 10:25 AM ----------

Here is how you get a 64-bit result from a 32-bit multiply in x86 gcc:
#include <stdio.h>
#include <limits.h>

int main(void)
        unsigned long a=INT_MAX,b=INT_MAX-1;

        printf("a=%lu b=%lu\n", a, b);

        // Need to use the special one-operand mul instruction, which
        // dumps its result in eax:edx.
        asm( "mul %1"
                : "=a"(a), "=d"(b) /* output registers eax, edx */
                : "a"(a), "r"(b) /* input registers eax, any */ );

        printf("a=%lu b=%lu\n", a, b);

Hope this helps.
# 3  
Old 08-04-2011
Thanx for reply, however maybe title a little misleading? I am trying to write "C"
code, usable by different processors. On an Intel processor using GCC or Clang
I wish to have:
(int)(((unsigned long long)result * (unsigned)2290649225) >> 37);

to look like:
mov $2290649225, %eax
imul (%ebp)
mov %edx, %eax
shr   %5, %eax
instead of:
imul $-2004318071, %edx, %esi
mov $-2004318071,%ecx
mov (%ebp), %eax
mull %ecx
lots more code
shr %5, %eax

if I use the second "C" language code:
(int)(((unsigned long long)result * (unsigned)1145324613) >> 36);

which is half of $2290649225 i get the first compiled result.
On i386 vs x86_64 the above codes should only differ in extension "l""d", but I believe the exact register reference with get you though both as "asm".
Again, I am trying to write "C" code, so I guess is there a way to tell compilers that (unsigned)2290649225, (uint32_t)2290649225, 2290649225U is an unsigned 32-bit number so shorter code is used?

Thanx Corona688! You got me in the direction I needed! Had me explain so understood what GCC might think? Strange that the 31st bit of a constant does this. Apparently the int result gets converted as long long then unsigned long long.
(int)(((unsigned long long)((unsigned)result) * (unsigned)2290649225) >> 37);

Sincere thanks! Pheonix

Last edited by pludi; 08-04-2011 at 05:16 PM..
# 4  
Old 08-05-2011
Originally Posted by pheonix
Thanx for reply, however maybe title a little misleading? I am trying to write "C"
code, usable by different processors.
Not all processors have imul.

If you insist on an exact sequence of instructions for it to follow, inline asm is the way to go.
# 5  
Old 08-05-2011
It wasn't about the imul instruction of intel, it was about GCC insisting that my "C" language statement wasn't a 32x32bit multiply just because the constant had the 31st bit set. GCC insisted that it should be done as a 64x32bit multiply. I saw no reason for a 2^17 * 2^32 should be done differently than a 2^17 *( 2^32 >> 1) considering they were unsigned multiplication. No reason to take high 32 of 2^17 = 0 * 2290649225 + low 32 of 2^17 * 2290649225, add in sign adjustment for the 2^17 for the answer. Especially since it doesn't do that on 2^17 * (2^32 >> 1).

I probably really shouldn't care how a compiler interprets a "C" statement. By the use of one "unsigned" where you normally don't need it, I can execute 4 instructions instead of 12 instructions. I never knew that it considered converting to "unsigned long long" was the same as converting to "long long" in this one instance. On a PPC execute 9 instructions instead of 21. And if done ppc asm only 5 (extra mr).
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Matrix multiplication

I have two files. Row id in File1 matches the column id in file2 (starting from column7 )except the last 2 characters. File1 has 50 rows and File 2 has 56 columns. If the id matches I want to multiply the value in column3 of File1 to the entire column in File2. and in the final output print only... (11 Replies)
Discussion started by: Akang
11 Replies

2. UNIX for Dummies Questions & Answers

Multiplication of two matrices

Hi there! I have two files like below File1(with a header, ~1000 rows, ~50 columns) ID1 ID2 ID3 ID4 ID5 MI1_A MI1_H MI2_A MI2_H 0 1 0 0 0 1 0 2 1 0 2 0 0 0 2 1 0 1 File2 (without a header, ~50 rows) MI1 A 0.4 3.1 MI2 B -0.2 0.1 Output ID2 M1_A M2_A 1 1*0.4 2*-0.2 2 2*0.4 0*-0.2 ... (22 Replies)
Discussion started by: Akang
22 Replies

3. Shell Programming and Scripting

Multiplication of array elements

Hi, I can't find out how to create correct code to get multiplication of each elements of array. Let's say I enter array into command line (2 3 4 5 6 8) and i need output 2*3*4*5*6*8=5760. I tried this one, but answer is 0. for i in $@; do mult=$((mult*i))done echo "mult: " $mult ... (4 Replies)
Discussion started by: rimasbimas
4 Replies

4. UNIX for Dummies Questions & Answers

Matrix multiplication with different files

Hi, i have file1 which looks like: x1 y1 z1 x2 y2 z2 ...(and so on) and file2 which looks like: a11 a12 a13 a21 a22 a23 a31 a32 a33 and i want to replace file1 with the following values: x1' y1' z1' x2' y2' z2' ...(and so on) (2 Replies)
Discussion started by: ezitoc
2 Replies

5. UNIX for Dummies Questions & Answers

Multiplication using bc in a for loop

Hi, I would like to carry out a multiplication in a for loop but some how I get always zero. The result of the multiplication must be assigned to the variable x. Here is teh code for (( i=1;i<=15;i++)); do x=$( printf "%s\n " 'scale = 10; i*5.0*335.0*3.0/1000.0' | bc) echo $x $i... (5 Replies)
Discussion started by: f_o_555
5 Replies

6. UNIX for Dummies Questions & Answers

Exact Multiplication

Hi, I am writing a script in Bourne shell #!/bin/sh used=`quota -v | tail -1 | awk '{print $2}'` total=`quota -v | tail -1 | awk '{print $3}'` echo "$used" echo "$total" perc=`expr ${used} / ${total} * 100 | bc` echo "$perc" I want to get a percentage of quota used to total limit I... (5 Replies)
Discussion started by: desai.rishabh
5 Replies

7. Shell Programming and Scripting

using awk multiplication

Suppose i have a file A 1*2*3*4 2*4*4*22 and second file B 2*3*4*5 4*4*6*7 By multiplying file A by file B that is file A by first column in file B respectively output shud be 2*6*12*20 8*16*24*154 my code is =$1 next } {for (f=1;f<=NF;f++) (2 Replies)
Discussion started by: cdfd123
2 Replies

8. Solaris

Installing gcc - recieve error message gcc : cannot execute

AIM- Install Oracle 11g on Solaris using VMWare Steps 1.Logged on as root 2.Created subfolders /usr/local/bin & /usr/local/bin/gcc 3.Downloaded gcc & libiconv & unzipped them on my harddrive & burnt them on CD 4.Copied files from CD to /usr/local/bin/gcc 5.Terminal (root) pkgadd -d... (8 Replies)
Discussion started by: Ackers
8 Replies

9. Linux

Multiplication with Fractions

Hello there, how do i multiply a fraction and a whole number? Example 20% of 50,000. I had gotten 0.2 using the following: chk=echo 20 100 | awk `{print $1/$2}` echo $chk $chk \* 50000 displays the error: non-numeric expression. (1 Reply)
Discussion started by: alby
1 Replies

10. UNIX for Dummies Questions & Answers

Simple multiplication problem

I'am doing a tutorial where a simple calculator was given, then i noticed that you can't actually multiply this is how i have approached the problem so far. i just need if the user enters "*" to change it to "/*" ,is it possible? i know that * means the name of the last file in the directory... (8 Replies)
Discussion started by: greekozz
8 Replies
Login or Register to Ask a Question