|
|
View previous topic :: View next topic |
Author |
Message |
Diego Guest
|
Possible bug in ccsc 4.104 using PIC16F57 compiling subtract |
Posted: Mon Feb 22, 2010 4:51 am |
|
|
hi,
I have this behavior when I compile this C line:
Code: |
signed char tre;
signed char bass;
tre=(0x1-bass)|0x80;
|
this is a one substraction and a seven bit set.
the output in Disassembly Listing:
Code: |
362: tre=(0x1-bass)|0x80;
569 217 MOVF 0x17, W
56A 081 SUBWF 0x1, W
56B D80 IORLW 0x80
56C 036 MOVWF 0x16
|
If I put tre=(0x10-bass)|0x80;
Code: |
362: tre=(0x10-bass)|0x80;
569 217 MOVF 0x17, W
56A 090 SUBWF 0x10, W
56B D80 IORLW 0x80
56C 036 MOVWF 0x16
|
It seems that the literal value is taken as direction. Address 0x17 is bass variable and 0x16 is tre.
Is it a bug? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Feb 22, 2010 7:31 am |
|
|
It's correct in my V4.104 compilation
CCS PCM C Compiler, Version 4.104, 48030 22-Feb-10 14:29
.................... signed char tre;
.................... signed char bass;
.................... tre=(0x1-bass)|0x80;
040A: MOVF 4F,W
040B: SUBLW 01
040C: IORLW 80
040D: MOVWF 4E |
|
|
Ttelmah Guest
|
|
Posted: Mon Feb 22, 2010 11:37 am |
|
|
Yes, it ilooks like the old 'multiple CCS releases' syndrome:
CCS PCB C Compiler, Version 4.104, 51458 22-Feb-10 17:25
Simple test code:
Code: |
#include <16F57.h>
#FUSES XT
#use delay(clock=4000000)
signed char tre;
signed char bass;
#define x &
void main(void) {
tre=(0x1-bass)|0x80;
while (TRUE) {
delay_ms(1);
}
}
|
Note it has selected 'PCB'!.
Generates:
Code: |
.................... tre=(0x1-bass)|0x80;
0017: MOVF 0B,W
0018: SUBWF 01,W
0019: IORLW 80
001A: MOVWF 0A
|
It looks as if this earlier release, really gets confused by the 16F57....
Change the chip to 16F84, and it correctly selects PCM, and generates the right code....
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Feb 22, 2010 1:18 pm |
|
|
I wasn't aware that CCS C requests PCB with 16F57.
The bug is also present with various previous PCB V4 versions, but not all.
V4.084 and V4.087 generated correct, but rather long-winded code
Code: | CCS PCB C Compiler, Version 4.084, 45911
.................... signed char tre;
.................... signed char bass;
.................... tre=(0x1-bass)|0x80;
*
0004: MOVF 0C,W
0005: MOVWF 09
0006: MOVLW 01
0007: MOVWF 0C
0008: MOVF 09,W
0009: SUBWF 0C,W
000A: IORLW 80
000B: MOVWF 0B |
At lest since V4.093, the code is incorrect
Code: | .................... signed char tre;
.................... signed char bass;
.................... tre=(0x1-bass)|0x80;
*
0004: MOVF 0C,W
0005: SUBWF 01,W
0006: IORLW 80
0007: MOVWF 0B |
|
|
|
Ttelmah Guest
|
|
Posted: Mon Feb 22, 2010 1:53 pm |
|
|
Sorry about the #define, I was trying some silly defines, like the one shown, to see if it triggered the fault, then found none was needed....
They make no difference.
To the original poster, report it. It seems to be a real 'gaffe' with this particular chip...
Best Wishes |
|
|
Diego Guest
|
|
Posted: Tue Feb 23, 2010 3:32 am |
|
|
I`m trying to get a workaround, I paste this simple code.
Note that in the pic16f84 there is a SUBLW opcode. So the result is always right for pic16f84.
Is there any limitation of several literals per line?
This could be the cause of the problem.
Code: |
//#define 16f57
//#include <16f57.h>
#define 16f84
#include <16f84.h>
unsigned char result,op,literal;
void main(){
op=1;
result=1;
literal=20;
//work fine with one literal per line
result=(literal-op)|0x80;
// don't work with two literal per line
result=(20-op)|0x80;
//workaround
result=20-op;
result=result|0x80;
}
|
Disasembly Listing for 16f84
Code: |
1: //#define 16f57
000 3000 MOVLW 0
001 008A MOVWF 0xa
002 2804 GOTO 0x4
003 0000 NOP
2: //#include <16f57.h>
3: #define 16f84
4: #include <16f84.h>
5: unsigned char result,op,literal;
6: void main(){
004 0184 CLRF 0x4
005 301F MOVLW 0x1f
006 0583 ANDWF 0x3, F
7: op=1;
007 3001 MOVLW 0x1
008 0091 MOVWF 0x11
8: result=1;
009 0090 MOVWF 0x10
9: literal=20;
00A 3014 MOVLW 0x14
00B 0092 MOVWF 0x12
10: //work fine with one literal per line
11: result=(literal-op)|0x80;
00C 0811 MOVF 0x11, W
00D 0212 SUBWF 0x12, W
00E 3880 IORLW 0x80
00F 0090 MOVWF 0x10
12: // don't work with two literal per line
13: result=(20-op)|0x80;
010 0811 MOVF 0x11, W
011 3C14 SUBLW 0x14
012 3880 IORLW 0x80
013 0090 MOVWF 0x10
14: //workaround
15: result=20-op;
014 0811 MOVF 0x11, W
015 3C14 SUBLW 0x14
016 0090 MOVWF 0x10
16: result=result|0x80;
017 1790 BSF 0x10, 0x7
018 0063 SLEEP
|
Disasembly Listing for 16f57
Code: |
1: #define 16f57
000 A01 GOTO 0x1
7FF A00 GOTO 0
2: #include <16f57.h>
3: //#define 16f84
4: //#include <16f84.h>
5: unsigned char result,op,literal;
6: void main(){
001 064 CLRF 0x4
7: op=1;
002 C01 MOVLW 0x1
003 02B MOVWF 0xb
8: result=1;
004 C01 MOVLW 0x1
005 02A MOVWF 0xa
9: literal=20;
006 C14 MOVLW 0x14
007 02C MOVWF 0xc
10: //work fine with one literal per line
11: result=(literal-op)|0x80;
008 20B MOVF 0xb, W
009 08C SUBWF 0xc, W
00A D80 IORLW 0x80
00B 02A MOVWF 0xa
12: // don't work with two literal per line
13: result=(20-op)|0x80;
00C 20B MOVF 0xb, W
00D 094 SUBWF 0x14, W
00E D80 IORLW 0x80
00F 02A MOVWF 0xa
14: //workaround
15: result=20-op;
010 C14 MOVLW 0x14
011 02A MOVWF 0xa
012 20B MOVF 0xb, W
013 0AA SUBWF 0xa, F
16: result=result|0x80;
014 5EA BSF 0xa, 0x7
015 003 SLEEP
|
|
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 23, 2010 3:47 am |
|
|
You can 'code round' the problem using:
tre=(0x1+(-bass))|0x80;
The problem seems to only apply to what are effectively '12' chips. A few chips like the 16x57, have the more limited instruction set from these smaller chips, lacking the SUBLW instruction. On chips with this instruction, everything is fine, but on the ones without, the compiler doesn't seem to understand how to subtract a signed value...
On these chips, the 'PCB' compiler is used.
The bodge, simply performs an addition, of a negative value. This codes correctly....
There almost certainly is a compiler limitation on 'literals per line', but it is a long way past this point.
I really would complain, since it is rather fundamental....
Best Wishes |
|
|
|
|
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
|