From 6d6c41d9b29342a7c3c3b5250157fbcfc0bc4aa5 Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Fri, 25 May 2007 06:05:06 +0000 Subject: [PATCH] * doc/sdccman.lyx: inserted footnotes about inline assembler labels, thanks Jan Waclawek * src/mcs51/gen.c (aopPut): fixed part of bug 1723128 when result is AOP_CRY and ruonly (gencjneshort): optimized when left is AOP_DIR * src/SDCCglue.c (printIvalStruct): fixed other part of bug 1723128 for initializing unions in a struct/array * support/regression/fwk/include/testfwk.h: added defines for data, near and far for host and z80 * support/regression/tests/bug1723128.c: new, added git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4814 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 13 ++++ doc/sdccman.lyx | 50 ++++++++++++-- src/SDCCglue.c | 2 +- src/mcs51/gen.c | 52 ++++++++++----- support/regression/fwk/include/testfwk.h | 5 +- support/regression/tests/bug1723128.c | 83 ++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 24 deletions(-) create mode 100644 support/regression/tests/bug1723128.c diff --git a/ChangeLog b/ChangeLog index 3d1d0d37..91de91f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-05-25 Maarten Brock + + * doc/sdccman.lyx: inserted footnotes about inline assembler labels, + thanks Jan Waclawek + * src/mcs51/gen.c (aopPut): fixed part of bug 1723128 when result is + AOP_CRY and ruonly + (gencjneshort): optimized when left is AOP_DIR + * src/SDCCglue.c (printIvalStruct): fixed other part of bug 1723128 for + initializing unions in a struct/array + * support/regression/fwk/include/testfwk.h: added defines for data, near + and far for host and z80 + * support/regression/tests/bug1723128.c: new, added + 2007-05-22 Borut Razem * doc/knownbugs.html: updated diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 9e709c2b..59561b9a 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -17350,8 +17350,8 @@ Use of Labels within Inline Assembler \begin_layout Standard SDCC allows the use of in-line assembler with a few restrictions regarding labels. - In older versions of the compiler all labels defined within inline assembler - code had to be of the form + All labels defined within inline assembler code have to be of the form + \emph on nnnnn$ \emph default @@ -17364,6 +17364,33 @@ per function ) \noun default . +\begin_inset Foot +status open + +\begin_layout Standard +This is a slightly more stringent rule than absolutely necessary, but stays + always on the safe side. + Labels in the form of nnnnn$ are local labels in the assembler, locality + of which is confined within two labels of the standard form. + The compiler uses the same form for labels within a function (but starting + from nnnnn=00100); and places always a standard label at the beginning + of a function, thus limiting the locality of labels within the scope of + the function. + So, if the inline assembler part would be embedded into C-code, an improperly + placed non-local label in the assembler would break up the reference space + for labels created by the compiler for the C-code, leading to an assembling + error. +\end_layout + +\begin_layout Standard +The numeric part of local labels does not need to have 5 digits (although + this is the form of labels output by the compiler), any valid integer will + do. + Please refer to the assemblers documentation for further details. +\end_layout + +\end_inset + \end_layout @@ -17459,7 +17486,7 @@ _asm \InsetSpace ~ \InsetSpace ~ \InsetSpace ~ -ljmp $0003 +ljmp 0003$ \newline \InsetSpace ~ \InsetSpace ~ @@ -17478,6 +17505,21 @@ clabel:\InsetSpace ~ \InsetSpace ~ /* inline assembler cannot reference this label */ +\begin_inset Foot +status open + +\begin_layout Standard +Here, the C-label +\family typewriter +clabel +\family default + is translated by the compiler into a local label, so the locality of labels + within the function is not broken. +\end_layout + +\end_inset + + \newline \InsetSpace ~ \InsetSpace ~ @@ -17489,7 +17531,7 @@ _asm \InsetSpace ~ \InsetSpace ~ \InsetSpace ~ -$0003: ;label (can be referenced by inline assembler only) +0003$: ;label (can be referenced by inline assembler only) \newline \InsetSpace ~ diff --git a/src/SDCCglue.c b/src/SDCCglue.c index c507e03d..96f4635b 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -747,7 +747,7 @@ printIvalStruct (symbol * sym, sym_link * type, if (SPEC_STRUCT (type)->type == UNION) { printIval (sym, sflds->type, iloop, oBuf); - iloop = iloop->next; + iloop = iloop ? iloop->next : NULL; } else { for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) { if (IS_BITFIELD(sflds->type)) { diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index be482612..39a01cbe 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -66,6 +66,8 @@ static char *accUse[] = static unsigned short rbank = -1; +#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) + #define REG_WITH_INDEX mcs51_regWithIdx #define AOP(op) op->aop @@ -1492,6 +1494,7 @@ aopPut (operand * result, const char *s, int offset) bool bvolatile = isOperandVolatile (result, FALSE); bool accuse = FALSE; asmop * aop = AOP (result); + const char *d = NULL; if (aop->size && offset > (aop->size - 1)) { @@ -1667,28 +1670,40 @@ aopPut (operand * result, const char *s, int offset) break; case AOP_CRY: - /* if result no bit variable */ - if (!aop->aopu.aop_dir) - { - assert (!strcmp (s, "c")); - /* inefficient: move carry into A and use jz/jnz */ - emitcode ("clr", "a"); - emitcode ("rlc", "a"); - accuse = TRUE; - } - else if (s == zero) - emitcode ("clr", "%s", aop->aopu.aop_dir); - else if (s == one) - emitcode ("setb", "%s", aop->aopu.aop_dir); - else if (!strcmp (s, "c")) - emitcode ("mov", "%s,c", aop->aopu.aop_dir); - else if (strcmp (s, aop->aopu.aop_dir)) + // destination is carry for return-use-only + d = (IS_OP_RUONLY (result)) ? "c" : aop->aopu.aop_dir; + // source is no literal and not in carry + if ((s != zero) && (s != one) && strcmp (s, "c")) { MOVA (s); /* set C, if a >= 1 */ emitcode ("add", "a,#0xff"); - emitcode ("mov", "%s,c", aop->aopu.aop_dir); + s = "c"; + } + // now source is zero, one or carry + + /* if result no bit variable */ + if (!d) + { + if (!strcmp (s, "c")) + { + /* inefficient: move carry into A and use jz/jnz */ + emitcode ("clr", "a"); + emitcode ("rlc", "a"); + accuse = TRUE; + } + else + { + MOVA (s); + accuse = TRUE; + } } + else if (s == zero) + emitcode ("clr", "%s", d); + else if (s == one) + emitcode ("setb", "%s", d); + else if (strcmp (s, d)) + emitcode ("mov", "%s,c", d); break; case AOP_STR: @@ -6034,8 +6049,9 @@ gencjneshort (operand * left, operand * right, symbol * lbl) /* if the left side is a literal or if the right is in a pointer register and left is not */ - if ((AOP_TYPE (left) == AOP_LIT) || + if ((AOP_TYPE (left) == AOP_LIT) || (AOP_TYPE (left) == AOP_IMMD) || + (AOP_TYPE (left) == AOP_DIR) || (IS_AOP_PREG (right) && !IS_AOP_PREG (left))) { operand *t = right; diff --git a/support/regression/fwk/include/testfwk.h b/support/regression/fwk/include/testfwk.h index 467e2055..41689935 100644 --- a/support/regression/fwk/include/testfwk.h +++ b/support/regression/fwk/include/testfwk.h @@ -12,10 +12,13 @@ void __printf(const char *szFormat, ...); #endif #if defined(PORT_HOST) || defined(SDCC_z80) || defined(SDCC_gbz80) +# define data # define idata # define pdata # define xdata # define code +# define near +# define far # define at(x) #endif @@ -43,4 +46,4 @@ void __runSuite(void); #define UNUSED(_a) if (_a) { } -#endif +#endif //__TESTFWK_H diff --git a/support/regression/tests/bug1723128.c b/support/regression/tests/bug1723128.c new file mode 100644 index 00000000..2565011b --- /dev/null +++ b/support/regression/tests/bug1723128.c @@ -0,0 +1,83 @@ +/* + bug 1723128 +*/ + +#include +#include + +union USUINT { + unsigned int value; + struct { + unsigned char A; // LS byte + unsigned char B; // HS byte + }; +}; // could name variables here + +typedef struct { + unsigned char CRC_seed; // 1 + union USUINT cal_burst_duration; // 3 + union USUINT cal_calibration; // 5 + union USUINT cal_number_of_bursts; // 7 + union USUINT cal_holdoff_delay; // 9 + unsigned char CRC; // 10 +} AUTOCAL_CFG; + +code at (0x8000) AUTOCAL_CFG AutoCal_CFG = {0}; + +static code unsigned char crc_table[256] = +{ 0x00,0x2F,0x5E,0x71,0xBC,0x93,0xE2,0xCD, + 0x57,0x78,0x09,0x26,0xEB,0xC4,0xB5,0x9A, + 0xAE,0x81,0xF0,0xDF,0x12,0x3D,0x4C,0x63, + 0xF9,0xD6,0xA7,0x88,0x45,0x6A,0x1B,0x34, + 0x73,0x5C,0x2D,0x02,0xCF,0xE0,0x91,0xBE, + 0x24,0x0B,0x7A,0x55,0x98,0xB7,0xC6,0xE9, + 0xDD,0xF2,0x83,0xAC,0x61,0x4E,0x3F,0x10, + 0x8A,0xA5,0xD4,0xFB,0x36,0x19,0x68,0x47, + 0xE6,0xC9,0xB8,0x97,0x5A,0x75,0x04,0x2B, + 0xB1,0x9E,0xEF,0xC0,0x0D,0x22,0x53,0x7C, + 0x48,0x67,0x16,0x39,0xF4,0xDB,0xAA,0x85, + 0x1F,0x30,0x41,0x6E,0xA3,0x8C,0xFD,0xD2, + 0x95,0xBA,0xCB,0xE4,0x29,0x06,0x77,0x58, + 0xC2,0xED,0x9C,0xB3,0x7E,0x51,0x20,0x0F, + 0x3B,0x14,0x65,0x4A,0x87,0xA8,0xD9,0xF6, + 0x6C,0x43,0x32,0x1D,0xD0,0xFF,0x8E,0xA1, + 0xE3,0xCC,0xBD,0x92,0x5F,0x70,0x01,0x2E, + 0xB4,0x9B,0xEA,0xC5,0x08,0x27,0x56,0x79, + 0x4D,0x62,0x13,0x3C,0xF1,0xDE,0xAF,0x80, + 0x1A,0x35,0x44,0x6B,0xA6,0x89,0xF8,0xD7, + 0x90,0xBF,0xCE,0xE1,0x2C,0x03,0x72,0x5D, + 0xC7,0xE8,0x99,0xB6,0x7B,0x54,0x25,0x0A, + 0x3E,0x11,0x60,0x4F,0x82,0xAD,0xDC,0xF3, + 0x69,0x46,0x37,0x18,0xD5,0xFA,0x8B,0xA4, + 0x05,0x2A,0x5B,0x74,0xB9,0x96,0xE7,0xC8, + 0x52,0x7D,0x0C,0x23,0xEE,0xC1,0xB0,0x9F, + 0xAB,0x84,0xF5,0xDA,0x17,0x38,0x49,0x66, + 0xFC,0xD3,0xA2,0x8D,0x40,0x6F,0x1E,0x31, + 0x76,0x59,0x28,0x07,0xCA,0xE5,0x94,0xBB, + 0x21,0x0E,0x7F,0x50,0x9D,0xB2,0xC3,0xEC, + 0xD8,0xF7,0x86,0xA9,0x64,0x4B,0x3A,0x15, + 0x8F,0xA0,0xD1,0xFE,0x33,0x1C,0x6D,0x42 +}; + +data unsigned char crc; + +static xdata unsigned char rx_buffer[8]; +static unsigned char rx_index; + +bool VerifyCRC(void) +{ + unsigned char i; + + crc = 0 ; + + for (i=0; i<(rx_index-1); i++) + crc = crc_table[rx_buffer[i] ^ crc] ; + return (crc == rx_buffer[rx_index-1]) ; +} + +void +testBug(void) +{ + rx_index = 1; + ASSERT (VerifyCRC()); +} -- 2.30.2