Jump to content
Sign in to follow this  
LasseT

Comparing Two 32 Bit Words

Recommended Posts

Problem description:

==============

 

Compare problems for 32 bit words. (Possible bug)

Please notice that my test works fine when running the compiler for a target like 16F877A and 16F648. NO PROBLEM THERE. My problem can be found when running the compiler for a target like 18F458 or 18F4580 (those I have tested).

 

I use SourceBoost IDE Version 6.25

 

Compare like

 

ptest1.s1_charlie == ptest2.s2_charlie WORKING OK :-)

ptest1.s1_charlie == s->s2_charlie WORKING OK :-)

p->s1_charlie == ptest2.s2_charlie NOT OK :-(

p->s1_charlie == s->s2_charlie NOT OK :-(

s->s2_charlie == p->s1_charlie NOT OK :-(

 

Please see my testprogram below to clarify some of this.

 

 

When I try to singelstep in assembler it looks like the "second byte" compare is the problem. The first byte compare works ok, no problem there, so the "first byte" of long s1 is compared with the "first byte" of long s2.

Next step shall compare the second byte of s1 and s2 but, the "first byte" of long s1 is compared with the "second byte" of long s2.

 

When I fake the second compare everything runs ok.

 

I modified the compiler output below and removed two lines of code and it "worked" as far as I could test it. But I will not say that this is the best (or correct) solution. This might violate something else for the compiler, I can not check that :-).

 

Assembler code output from compiler

==========================================

p->s1_charlie == s->s2_charlie

 

MOVF main_1_s+D'1', W

MOVWF FSR0H

MOVF main_1_s, W

ADDLW 0x03

MOVWF FSR0L

MOVF INDF0, W

MOVWF CompTempVar76

MOVF PREINC0, W

MOVWF CompTempVar76+D'1'

MOVF PREINC0, W

MOVWF CompTempVar76+D'2'

MOVF PREINC0, W

MOVWF CompTempVar76+D'3'

MOVF main_1_p+D'1', W

MOVWF FSR0H

MOVF main_1_p, W

ADDLW 0x03

MOVWF FSR0L

MOVF CompTempVar76, W

SUBWF INDF0, W

BNZ label268436489 first value byte compare

----------------------------------------------

MOVF CompTempVar76+D'1', W

DECF FSR0L, F <=========REMOVE ??????

SUBWF PREINC0, W

BNZ label268436489 second value byte compare

---------------------------------------------------------------

MOVF CompTempVar76+D'2', W

INCF FSR0L, F <=========REMOVE ??????

MOVF PREINC0, W

MOVWF CompTempVar77

DECF FSR0L, F

DECF FSR0L, F

SUBWF CompTempVar77, W

BNZ label268436489 third value byte compare

---------------------------------------------------------------

MOVF CompTempVar76+D'3', W

INCF FSR0L, F

INCF FSR0L, F

MOVF PREINC0, W

MOVWF CompTempVar78

DECF FSR0L, F

DECF FSR0L, F

DECF FSR0L, F

SUBWF CompTempVar78, W

BNZ label268436489 fourth value byte compare

-------------------------------------------------------------

MOVLW 0xAA

MOVWF main_1_ifequal

 

=================================================

 

Simple Testprogram for 32 bit compares:

------------------------------------------------

 

 

#include <system.h>

#include <boostc.h>

 

 

 

 

typedef struct _STRUCT1

{

char s1_alfa;

int s1_bravo;

long s1_charlie;

int s1_delta;

char s1_foxtrot;

} STRUCT1;

 

typedef struct _STRUCT2

{

char s2_alfa;

int s2_bravo;

long s2_charlie;

int s2_delta;

char s2_foxtrot;

} STRUCT2;

 

 

 

 

 

 

 

void main()

{

char ifequal = 0x00;

 

STRUCT2 ptest2;

ptest2.s2_charlie = 0x33445566;

 

STRUCT2 *s;

s = &ptest2;

 

STRUCT1 ptest1;

ptest1.s1_charlie = 0x99887766;

 

STRUCT1 *p;

p = &ptest1;

 

p->s1_alfa = 0x12;

p->s1_bravo = 0x3456;

p->s1_delta = 0x7889;

p->s1_foxtrot = 0x34;

 

 

//=========================================================================

//

// COMPARE TEST STARTS HERE

//

//=========================================================================

//

//

// PLEASE NOTICE THAT THIS TEST WORKS FOR PIC16F877A and PIC16F648

// IF THOSE ARE THE TARGET CHIPS !!!!!!!!!!!!!!!!!!

//

// IT DOES NOT WORK FOR TARGET PIC 18F458 and 18F4580

//

//==========================================================================

 

p->s1_charlie = 0x11223344;

s->s2_charlie = 0x11223344;

 

 

 

 

 

if (ptest1.s1_charlie == ptest2.s2_charlie) ifequal = 0x33; //WORKING OK :-)

 

if (ptest1.s1_charlie == s->s2_charlie) ifequal = 0x88; //WORKING OK :-)

 

if (p->s1_charlie == ptest2.s2_charlie) ifequal = 0x55; // NOT OK :-(

 

if (p->s1_charlie == s->s2_charlie) ifequal = 0xAA; // NOT OK :-(

 

if (s->s2_charlie == p->s1_charlie) ifequal = 0x99; // NOT OK :-(

 

 

 

}

 

==========================================

 

Regards,

Lasse

Share this post


Link to post
Share on other sites

Yes this is bug. Now fixed. Fix will be available in the next release. Thanks for reporting.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

The same kind of problem can be found when using != instead of ==.

 

I guess that it is more or less the same code part in the compiler so it will be corrected at the same time.

 

Regards,

 

Lasse

 

By the way! The SourceBoostC is a very nice "tool" to work with :-)!

I have a lot of fun designing with this environment.

Share this post


Link to post
Share on other sites
The same kind of problem can be found when using  !=  instead of ==.

 

I guess that it is more or less the same code part in the compiler so it will be corrected at the same time.

 

I guess this is the same problem. But to be sure can you post some code that shows this problem so we can verify if it's been fixed too.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Hi!

 

I have done some more testing and you can find my testprogram attached.

 

I think this problem also can be found for 16F chip. I tested this program compiled for 16F877A and found the same problem there ( == and !=).

 

I have tested the program for 16F877A (16F in table below) and 18F458 (18F in table below).

 

Hera are my comments on the tests and you can find the testnumbers in the program.

( queston mark indicates that it looks ok but the test is not done in a correct way. It fooled at least me when I first tested this :-) )

 

EQ1 Correct for 16F and 18F.

EQ2 Correct for 16F and 18F.

EQ3 16F ?? test always OK? / 18F error

EQ4 16F ?? test always OK? / 18F error

EQ5 16F ?? test always OK? / 18F error

EQ6 Correct for 16F and 18F.

EQ7 Correct for 16F and 18F.

EQ8 16F error / 18F ?? test always not ok?

EQ9 16F error / 18F ?? test always not ok?

EQ10 16F error / 18F ?? test always not ok?

 

NOT_EQ1 Correct for 16F and 18F

NOT_EQ2 Correct for 16F and 18F

NOT_EQ3 16F ?? test always not ok? / 18F error

NOT_EQ4 16F ?? test always not ok? / 18F error

NOT_EQ5 16F ?? test always not ok? / 18F error

NOT_EQ6 Correct for 16F and 18F

NOT_EQ7 Correct for 16F and 18F

NOT_EQ8 16F error / 18F ?? test always ok?

NOT_EQ9 16F error / 18F ?? test always ok?

NOT_EQ10 16F error / 18F ?? test always ok?

 

 

I have checked the assembler output from the compiler (18F) and think you can use the same correction for != as you used for == .

 

I have not checked the assembler for the 16F.

 

===============================

TESTPROGRAM

===============================

 

#include <system.h>

#include <boostc.h>

 

 

 

 

typedef struct _STRUCT1

{

char s1_alfa;

int s1_bravo;

long s1_charlie;

int s1_delta;

char s1_foxtrot;

} STRUCT1;

 

typedef struct _STRUCT2

{

char s2_alfa;

int s2_bravo;

long s2_charlie;

int s2_delta;

char s2_foxtrot;

} STRUCT2;

 

 

 

void main()

{

char cmp_taken = 0x00;

 

 

STRUCT2 ptest2;

ptest2.s2_charlie = 0x33445566;

 

STRUCT2 *s;

s = &ptest2;

 

STRUCT1 ptest1;

ptest1.s1_charlie = 0x99887766;

 

STRUCT1 *p;

p = &ptest1;

 

p->s1_alfa = 0x12;

p->s1_bravo = 0x3456;

p->s1_delta = 0x7889;

p->s1_foxtrot = 0x34;

 

 

 

//=========================================================================

//

// COMPARE TEST STARTS HERE

//

//=========================================================================

//

// TEST of 32bit word == 32 bit word

//

//==========================================================================

 

//***********************************

// Testcode VALUE

// value s1_charlie is equal value s2_charlie

//***********************************

 

p->s1_charlie = 0x11223344;

s->s2_charlie = 0x11223344;

 

if (ptest1.s1_charlie == ptest2.s2_charlie) cmp_taken = 0x51; //TEST EQ1

cmp_taken = 0;

if (ptest1.s1_charlie == s->s2_charlie) cmp_taken = 0x52; //TEST EQ2

cmp_taken = 0;

if (p->s1_charlie == ptest2.s2_charlie) cmp_taken = 0x53; //TEST EQ3

cmp_taken = 0;

if (p->s1_charlie == s->s2_charlie) cmp_taken = 0x54; //TEST EQ4

cmp_taken = 0;

if (s->s2_charlie == p->s1_charlie) cmp_taken = 0x55; //TEST EQ5

cmp_taken = 0;

 

//***********************************

// Testcode VALUE

// value s1_charlie is NOT equal value s2_charlie

//***********************************

p->s1_charlie = 0x11223344;

s->s2_charlie = 0x11221144;

 

if (ptest1.s1_charlie == ptest2.s2_charlie) cmp_taken = 0x56; //TEST EQ6

cmp_taken = 0;

if (ptest1.s1_charlie == s->s2_charlie) cmp_taken = 0x57; //TEST EQ7

cmp_taken = 0;

if (p->s1_charlie == ptest2.s2_charlie) cmp_taken = 0x58; //TEST EQ8

cmp_taken = 0;

if (p->s1_charlie == s->s2_charlie) cmp_taken = 0x59; //TEST EQ9

cmp_taken = 0;

if (s->s2_charlie == p->s1_charlie) cmp_taken = 0x5A; //TEST EQ10

cmp_taken = 0;

 

 

 

//=========================================================================

//

// TEST of 32bit word != 32 bit word

//

//==========================================================================

//***********************************

// Testcode VALUE

// value s1_charlie is equal value s2_charlie

//***********************************

 

p->s1_charlie = 0x11223344;

s->s2_charlie = 0x11223344;

 

 

if (ptest1.s1_charlie != ptest2.s2_charlie) cmp_taken = 0xA1; //TEST NOT_EQ1

cmp_taken = 0;

if (ptest1.s1_charlie != s->s2_charlie) cmp_taken = 0xA2; //TEST NOT_EQ2

cmp_taken = 0;

if (p->s1_charlie != ptest2.s2_charlie) cmp_taken = 0xA3; //TEST NOT_EQ3

cmp_taken = 0;

if (p->s1_charlie != s->s2_charlie) cmp_taken = 0xA4; //TEST NOT_EQ4

cmp_taken = 0;

if (s->s2_charlie != p->s1_charlie) cmp_taken = 0xA5; //TEST NOT_EQ5

cmp_taken = 0;

 

//***********************************

// Testcode VALUE

// value s1_charlie is NOT equal value s2_charlie

//***********************************

p->s1_charlie = 0x11223344;

s->s2_charlie = 0x11221144;

 

if (ptest1.s1_charlie != ptest2.s2_charlie) cmp_taken = 0xA6; //TEST NOT_EQ6

cmp_taken = 0;

if (ptest1.s1_charlie != s->s2_charlie) cmp_taken = 0xA7; //TEST NOT_EQ7

cmp_taken = 0;

if (p->s1_charlie != ptest2.s2_charlie) cmp_taken = 0xA8; //TEST NOT_EQ8

cmp_taken = 0;

if (p->s1_charlie != s->s2_charlie) cmp_taken = 0xA9; //TEST NOT_EQ9

cmp_taken = 0;

if (s->s2_charlie != p->s1_charlie) cmp_taken = 0xAA; //TEST NOT_EQ10

cmp_taken = 0;

 

 

 

}

 

 

==========================

 

 

I hope this helps to explain the problem better!

 

Regards,

 

Lasse

Share this post


Link to post
Share on other sites

I checked your latest test code with the latest compiler. The problem seems to be fixed (as you already suggested).

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...