CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

[solved]PIC18f series Hardware multiply

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
edmundopt



Joined: 08 Dec 2011
Posts: 15
Location: Portugal

View user's profile Send private message

[solved]PIC18f series Hardware multiply
PostPosted: Thu Dec 08, 2011 3:58 pm     Reply with quote

First of all, personaly I do not use CCS, but I'm translating my Microchip C18 to CCS v4.124, my question is, when the IC is included, example:

#include <18F4620.h>

the following code :

unsigned int8 num_high, num_low;
unsigned int16 result;

result = num_high * 256;
result = result + num_low;

or the following code:

result = make16(num_high,num_low);

should it not the assembly code use the ASM instruction MULWF??
is there a way to change the resulting assembly code?

I'm refering pic18f series hardware multiply very usefull capability
sorry for any mistakes.


Last edited by edmundopt on Thu Dec 08, 2011 5:19 pm; edited 1 time in total
Battery David



Joined: 01 Feb 2010
Posts: 25

View user's profile Send private message

PostPosted: Thu Dec 08, 2011 4:19 pm     Reply with quote

I haven't tried it but the manual lists a _mul() function to use the hardware multiplier.

Please let us know how it works.

David
edmundopt



Joined: 08 Dec 2011
Posts: 15
Location: Portugal

View user's profile Send private message

PostPosted: Thu Dec 08, 2011 4:23 pm     Reply with quote

Thank you, I found out that :

unsigned int8 num_high, num_low;
unsigned int8 factor = 256;
unsigned int16 result;

result = num_high * factor;
result = result + num_low;

uses the MULWF..


strange.....
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Dec 08, 2011 4:48 pm     Reply with quote

Quote:
unsigned int8 num_high, num_low;
unsigned int16 result;

result = num_high * 256;
result = result + num_low;

or the following code:

result = make16(num_high,num_low);

should it not the assembly code use the ASM instruction MULWF??
No, multiplication by 256 is a special situation and can be done way more efficiently by shifting a whole byte to the left.

The make16 is a whole other function where you move two bytes to the new int16 variable. Again no multiplication required.
I guess you are confused because you are thinking in decimal values; to combine the two 8-bit values you write: 16-bit = msb*256 + lsb
For humans a difficult calculation but for a computer calculating in 8-bit quantities this is much easier and just involves moving two bytes. Cool

Quote:
unsigned int8 num_high, num_low;
unsigned int8 factor = 256;
unsigned int16 result;

result = num_high * factor;
result = result + num_low;

uses the MULWF..
Yes, this uses multiplication because you are now multiplying two variables and this can not be optimized by the compiler. In the first example one of the components was a constant and then 256 is a special constant that can be optimized a lot. This is one of the reasons why I like the CCS compiler, the optimization is quiet good.

Note the bug in this example: 256 does not fit into an int8 and is truncated to the lower 8 bits, i.e. 1. The result will not be as expected.
edmundopt



Joined: 08 Dec 2011
Posts: 15
Location: Portugal

View user's profile Send private message

PostPosted: Thu Dec 08, 2011 5:17 pm     Reply with quote

you are right, really bad example about multiplication, because 256 is out of range for int8, anyway thanks because that was the problem in my code, out of range values!

and yes, something like :

result = result + high_int8;
result = (result<<8);
result = result + low_int8;

thanks
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Dec 09, 2011 3:37 am     Reply with quote

CCS will generally often optimise multiplication by constant powers of two into shifts. So

b = a * 2;
c = a * 8;
d = a * 64;

will be implemented as:

b = a << 1;
c = a << 3;
d = a << 5;

this is generally true even with 8 bit values , which can be multiplied in a single instruction by hardware and for which the speed and code size gains are relatively small, and is certainly true for 16 and more bit variables which gain substantially by this optimisation.

Whatever the compiler does however, always remember the calculation must be done in a form that is big enough to contain the expected result, and that C selects its arithmetic based on the input variables, NOT the result. If you want a 16 bit result, you must cast if needed to ensure the arithmetic is done as 16 bit.

RF Developer
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group