View previous topic :: View next topic |
Author |
Message |
edmundopt
Joined: 08 Dec 2011 Posts: 15 Location: Portugal
|
[solved]PIC18f series Hardware multiply |
Posted: Thu Dec 08, 2011 3:58 pm |
|
|
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
|
|
Posted: Thu Dec 08, 2011 4:19 pm |
|
|
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
|
|
Posted: Thu Dec 08, 2011 4:23 pm |
|
|
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
|
|
Posted: Thu Dec 08, 2011 4:48 pm |
|
|
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.
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
|
|
Posted: Thu Dec 08, 2011 5:17 pm |
|
|
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
|
|
Posted: Fri Dec 09, 2011 3:37 am |
|
|
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 |
|
|
|