#937 Incorrect structure and pointer code generation

closed-fixed
5
2013-05-25
2005-06-15
xander
No

I've run into an odd code generation problem with SDCC
2.5.
Changing one line of code causes another line of code to
be compiled differently. The unfortunate thing is that
one of the compilations is faulty.

The code at issue is just two lines long. I've included an
abbreviated file that demonstrates at bottom of
message. The problem is associated with taking the
address of a structure, and referencing an element of the
structure.

These two lines work:
outPtr = (byte *)&configDescriptor;
wCount = *(outPtr + 2);

These two lines (in either order) don't work:
outPtr = (byte *)&configDescriptor;
wCount = configDescriptor.configHeader[2];

Fundamentally these two lines are identical. The only
difference
that should come out of the compiler is shorter code for
the
second version (call to __gptrget1 replaced by a simple
offset).
The code for "wCount = ..." comes out correctly.

Version:
SDCC :
mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51
/ds400/hc08 2.5.1 #
030 (May 31 2005) (MSVC)

Line to compile:
> sdcc -c -Ic:\sdcc\include -mpic16 -pp18f2550
sdccErr1.c

Hopefully someone can figure out why this difference in
code generation
occurs. I've tried many variations on turning
optimization on/off,
without any difference in the resulting code.

Xander

--------------------- Details below --------------------------

This is how the code ought to look:

; .line 62; sdccErr1.c outPtr =
(byte *)&configDescriptor;
MOVLW LOW(_configDescriptor)
BANKSEL _outPtr
MOVWF _outPtr, B
MOVLW HIGH(_configDescriptor)
BANKSEL (_outPtr + 1)
MOVWF (_outPtr + 1), B
MOVLW UPPER(_configDescriptor)
BANKSEL (_outPtr + 2)
MOVWF (_outPtr + 2), B
; .line 67; sdccErr1.c wCount = *
(outPtr + 2);
MOVFF _outPtr, r0x00
MOVFF (_outPtr + 1), r0x01
MOVFF (_outPtr + 2), r0x02
CLRF WREG
BANKSEL (_outPtr + 2)
BTFSC (_outPtr + 2), 7
SETF WREG
MOVLW 0x02
ADDWF r0x00, F
MOVLW 0x00
ADDWFC r0x01, F
MOVLW 0x00
ADDWFC r0x02, F
MOVFF r0x00, FSR0L
MOVFF r0x01, PRODL
MOVF r0x02, W
CALL __gptrget1
MOVWF r0x00
MOVFF r0x00, _wCount
BANKSEL (_wCount + 1)
CLRF (_wCount + 1), B

When the second line of the code is changed to access
an element of
the structure, the first line of code is compiled
incorrectly. Note
that the contents of configDescriptor are being moved
into outPtr,
rather than the address of configDescriptor.

The compiler generates the warning:
.\gen.c:12487 symbol outPtr = [ iTemp20 ] is in code
space

; .line 70; sdccErr1.c outPtr =
(byte *)&configDescriptor;
MOVLW LOW(_configDescriptor)
MOVWF TBLPTRL
MOVLW HIGH(_configDescriptor)
MOVWF TBLPTRH
MOVLW UPPER(_configDescriptor)
MOVWF TBLPTRU
TBLRD*+
MOVFF TABLAT, _outPtr
TBLRD*+
MOVFF TABLAT, (_outPtr + 1)
TBLRD*+
MOVFF TABLAT, (_outPtr + 2)
; .line 71; sdccErr1.c wCount =
configDescriptor.configHeader[2]; // Note: SDCC makes
bad code with this
MOVLW LOW(_configDescriptor + 2)
MOVWF TBLPTRL
MOVLW HIGH(_configDescriptor + 2)
MOVWF TBLPTRH
MOVLW UPPER(_configDescriptor + 2)
MOVWF TBLPTRU
TBLRD*+
MOVFF TABLAT, r0x00
MOVFF r0x00, _wCount
BANKSEL (_wCount + 1)
CLRF (_wCount + 1), B

Below is the entire file needed to reproduce the problem:

#include <pic18fregs.h>

typedef unsigned char byte;
typedef unsigned int word;

byte *outPtr;
word wCount;

#define HOSZ 8
#define HISZ 8

#define CONFIG_HEADER_SIZE 0x09
#define HID_DESCRIPTOR_SIZE 0x20
#define CFSZ 0x29

typedef struct _configStruct
{
byte configHeader[CONFIG_HEADER_SIZE];
byte HIDDescriptor
[HID_DESCRIPTOR_SIZE];
} ConfigStruct;

code ConfigStruct configDescriptor =
{
{
// Configuration descriptor
0x09, 0x02, // bLength, bDescriptorType
(Configuration)
CFSZ, 0x00, // wTotalLength (low),
wTotalLength (high)
0x01, 0x01, // bNumInterfaces,
bConfigurationValue
0x00, 0xA0, // iConfiguration, bmAttributes ()
0x32, // bMaxPower
},
{
// HID Interface descriptor
0x09, 0x04, // bLength, bDescriptorType
(Interface)
0x00, 0x00, // bInterfaceNumber,
bAlternateSetting
0x02, 0x03, // bNumEndpoints,
bInterfaceClass (HID)
0x00, 0x00, // bInterfaceSubclass,
bInterfaceProtocol,
0x00, // iInterface
// Hid descriptor
0x09, 0x21, // bLength, bDescriptorType
(HID)
0x01, 0x01, // bcdHID (low), bcdHID (high)
0x00, 0x01, // bCountryCode,
bNumDescriptors
0x22, 0x2F, // bDescriptorType,
wDescriptorLength (low)
0x00, // wDescriptorLength (high)
// HID Endpoint 1 In
0x07, 0x05, // bLength, bDescriptorType
(Endpoint)
0x81, 0x03, // bEndpointAddress,
bmAttributes (Interrupt)
HISZ, 0x00, // wMaxPacketSize (low),
wMaxPacketSize (high)
0x0A, // bInterval (10 milliseconds)
// HID Endpoint 1 Out
0x07, 0x05, // bLength, bDescriptorType
(Endpoint)
0x01, 0x03, // bEndpointAddress,
bmAttributes (Interrupt)
HOSZ, 0x00, // wMaxPacketSize (low),
wMaxPacketSize (high)
0x0A, // bInterval (10 milliseconds)
}
};

void asmTest1()
{
#if 0
// This branch creates working code.
outPtr = (byte *)&configDescriptor;

// Either of the following two lines works.
The former just generates
// a little more code (but is more general).

// wCount = *(outPtr + 2);
wCount = CFSZ;
#else
// SDCC 2.5 makes bad code with the
following two lines. The
// unusual thing is that it is the first of the
two lines that
// is compiled incorrectly (outPtr gets the
contents of
// configDescriptor rather than the address),
even though it
// is the second line that changes from above.
outPtr = (byte *)&configDescriptor;
wCount = configDescriptor.configHeader[2]; // Note:
SDCC makes bad code with this
#endif
}

Discussion

  • Raphael Neider

    Raphael Neider - 2005-06-15

    Logged In: YES
    user_id=1115835

    The problem was the iTemp generated in the second case --
    the PIC16 port did not handle them correctly. Fixed in SDCC
    #1043.

    By the way, long attachments (source code, assembler dumps)
    should better be attached rather than included
    (copy'n'paste) in the report...

     
  • Raphael Neider

    Raphael Neider - 2005-06-15
    • milestone: --> fixed
    • assigned_to: nobody --> tecodev
    • status: open --> closed-fixed
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks