|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
PIC24EP512GP806 - Bit rolling and shifting issues? |
Posted: Fri Jun 02, 2023 10:23 am |
|
|
Device: PIC24EP512GP806
Compiler: 5.026
I'm working on making some code return the same result on both my PC and my MCU and I think that some of the operations are problematic on the MCU and I can't figure-out how/why.
I have the following code:
Code: |
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) \
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
#define S0(x) ( ROTR( x, 7 ) ^ ROTR( x, 18 ) ^ SHR( x, 3 ))
#define S1(x) ( ROTR( x, 17 ) ^ ROTR( x, 19 ) ^ SHR( x,10 ))
#define S2(x) ( ROTR( x, 2 ) ^ ROTR( x, 13 ) ^ ROTR( x,22 ))
#define S3(x) ( ROTR( x, 6 ) ^ ROTR( x, 11 ) ^ ROTR( x,25 ))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define R(t) \
( \
W[t] = S1(W[t - 2]) + W[t - 7] + \
S0(W[t - 15]) + W[t - 16] \
)
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \ <<< Line I'm interested in for now
temp2 = S2(a) + F0(a,b,c); \
d += temp1; \
h = temp1 + temp2; \
}
|
These are all macros.
Then I have the following values associated with the letters in the P macro:
unsigned int A = 0x6A09E667;
unsigned int B = 0xBB67AE85;
unsigned int C = 0x3C6EF372;
unsigned int D = 0xA54FF53A;
unsigned int E = 0x510E527F;
unsigned int F = 0x9B05688C;
unsigned int G = 0x1F83D9AB;
unsigned int H = 0x5BE0CD19;
unsigned int K = 0x428A2F98;
unsigned int X = 0x80000000;
Then the P macro is called like this:
P( A, B, C, D, E, F, G, H, X, K );
Then I run this macro on both my PC in a C application and on the PIC with CCS. When the macro runs, it prints-out the value of temp1 and in both cases, I get the following results:
PC: 0x7377ED68
PIC: 0x737723DC
I manually did the equation by hand on a piece of paper and I get the same result as the PC - 0x7377ED68.
Why and where does the PIC have the 2 high bytes correct (7377) but the two low-bytes incorrect (ED68)?
Will continue to do some testing in the meantime. CCS is picky when using fprintf in a macro and for some reason I can't seem to be able to put fprintf's in the underlying macros used by P.
Thanks!
Ben |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Fri Jun 02, 2023 12:18 pm |
|
|
How is int defined in your program? It would be better to use unsigned int32 or uint32_t to explicitly use a 32 bit. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri Jun 02, 2023 12:30 pm |
|
|
Actually, that's my mistake, yes, all the values are uint32_t. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Sat Jun 03, 2023 2:42 am |
|
|
You are almost certainly overflowing the internal ability to carry results
'forward'. The line involved is excruciatingly long once the macros
all expand, meaning a lot of temporary values. It has been a warning here
in the past, to try to keep maths lines down in length. The compiler has
internal buffers used for jobs like this, and if a line gets too long, it runs
out. No warning given on this.
So split the line. Do one operation at a time. This also then means
you can see where it goes wrong. I suspect you will find if you do split
it up it'll then start to work right.
So:
Code: |
temp1 = h;
temp1 += S3(e);
temp1 += F1(e,f,g);
temp1 += K;
temp1 += x; // <<< Line I'm interested in for now
|
Yes, just confirmed, if I split the line up like this, the result matches
your PC value. You are trying to build an expansion that it longer than the
compiler can cope with.
Macros support a maximum result size. I think it is about 230 characters
You are building a resulting expansion that is just too long. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Sat Jun 03, 2023 5:55 am |
|
|
Good day,
Thanks for your reply. Yesterday, that's exactly what I did, I separated the equations in individual equations but also, I changed the macros to be functions so that I could add code like fprintf's to them and it worked.
So really, what's the principle or goal of a macro if the function can do the same thing?
Ben |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Sat Jun 03, 2023 7:35 am |
|
|
to me a 'macro' was some clever bit of code when you program in machine language...whereas a 'function' is similar but created using a 'high level' language like 'C'.
yeah, I'm a dinosaur...did a LOT of Assembler in the 'prehistoric dayze'......
BTW I've been stung BIG time with the '230 character limit', in MS Windows last year. Seems 'long file names' Do have a limit( maybe 250 ?), couldn't delete a file I'd gotten off the web. Man what a pain.tried all the normal things and some DOS tricks. Ended up getting 'ZIP7' ,which 'magically' deleted the file.
I'm getting to old for this nonsense......
..though I'm thinking of getting an ESPxxxx with camera for $2.88 CDN.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Sun Jun 04, 2023 1:40 am |
|
|
Several 'bits' to this.
A Macro, is a fabulous tool for giving a 'name' to something. So for example,
saying that PIN_A2, is your red LED.
#define RED_LED PIN_A2
Then in your code, output_high(RED_LED) is much more informative than
doing the same with PIN_A2.
Then the next thing is speed. The macro is expanded at compile time. So
results in a single block of code executed 'inline'. No function calls, so
potentially a little faster. This though carries a complementary downside
that it means the code is repeated every time. So in your original code
doing the XOR's and rotations as a macro (if this is only going to be used
a very few times), gives a nice shortcut notation in the code.
The big downside is that excessive use of macros can lead to lines
growing excessively. In this case you have macros, inside macros,
inside macros. It'd be fun (terrifying), to type out the resulting code
block. The 'P' operation shouldn't be a problem as a whole, because
it generates separate lines. However the temp1 operation is scary.
You have S3, expanding to two ROTR operations, and a SHR operation.
The ROTR operations then each expand to a SHR operation, and a
rotation and an addition. This is then appended to the F1 operation,
and then has another four operations appended to this.The line gets to
having something like twenty operations, and being several screen lines
long. Now CCS uses a limited size buffer when performing such
expansions. For any normal line, not an issue, but this screamed that
it was probably getting too long.
Macros are a great tool for writing shortcuts to operations. So both the
SHR and ROTR macros are sensible uses on their own. However nesting
these in the Sx macros starts to become slightly worrying, and then
nesting these again in the P macro is 'asking for trouble'...
Historically, a lot of compilers offered the option to display the expanded
output, so you could debug when such a problem was likely to happen.
So use macros as a tool to simplify writing code, but be very wary of
nesting macros inside macros, inside macros..... |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Sun Jun 04, 2023 8:08 am |
|
|
Ah, gotcha! Well this is code I got off the web to generate an SHA256 hash and so far it appears to work as expected on my PC. Porting it to the PIC was another story due to the macros. But now that I've converted the macros to functions, the code is smaller and appears to be working as of Friday afternoon just before the week-end (which is good because I didn't need to think of why it was not working while not at work!).
Thanks for your insight and help!
Ben |
|
|
|
|
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
|