asm/ds390/features.h and asm/mcs51/features.h
* device/include/asm/default/features.h,
* device/include/asm/gbz80/features.h,
* device/include/asm/z80/features.h: added empty _AUTOMEM
and _STATMEM
* device/include/asm/ds390/features.h,
* device/include/asm/mcs51/features.h: added files with defines for
_AUTOMEM and _STATMEM indicating automatic and static storage class
* device/lib/printf_large.c (_print_format): optimized & used _AUTOMEM
* doc/sdccman.lyx: version 2.4.7, updated xstack documentation
* src/SDCCicode.c (geniCodeCast),
* src/SDCCsymt.c (compareType): allow cast of data-ptr to idata-ptr
* src/SDCCloop.c (loopInduction): removed unused variable lr
* src/SDCCopt.c (convilong, convertToFcall): moved "easy special case"
to convertToFcall to include char modulo (RFE
1065037), added check
if left operand is unsigned and use abs of literal value
* src/SDCCpeeph.c (setFromConditionArgs): removed double quotes option
as it doesn't work after conversion from peephole.def to peephole.rul
* src/mcs51/gen.c (toBoolean): added check for size,
(genModOneByte): optimized code for signed char modulo a literal
power of 2 (thanks to Hubert Sack),
(genRRC): removed unnecessary "clr c",
(genRLC): replaced "add a,acc" with cheaper "rlc a"
* src/mcs51/peeph.def: renamed 115 to 115.a, added rule 115.b: another
jump optimization,
swapped rules 256.c and 256.d,
extended 256.d by using new multiple checks (thanks Erik),
added rules 256.e and 256.f,
updated rule 261.a and 261.b to new generated code
* support/regression/tests/muldiv.c: added test div/mod by a power of 2
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3605
4a8a32a2-be11-0410-ad9d-
d568d2c75423
+2004-12-09 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * device/include/sdcc-lib.h: inserted LGPL, added includes
+ asm/ds390/features.h and asm/mcs51/features.h
+ * device/include/asm/default/features.h,
+ * device/include/asm/gbz80/features.h,
+ * device/include/asm/z80/features.h: added empty _AUTOMEM
+ and _STATMEM
+ * device/include/asm/ds390/features.h,
+ * device/include/asm/mcs51/features.h: added files with defines for
+ _AUTOMEM and _STATMEM indicating automatic and static storage class
+ * device/lib/printf_large.c (_print_format): optimized & used _AUTOMEM
+ * doc/sdccman.lyx: version 2.4.7, updated xstack documentation
+ * src/SDCCicode.c (geniCodeCast),
+ * src/SDCCsymt.c (compareType): allow cast of data-ptr to idata-ptr
+ * src/SDCCloop.c (loopInduction): removed unused variable lr
+ * src/SDCCopt.c (convilong, convertToFcall): moved "easy special case"
+ to convertToFcall to include char modulo (RFE 1065037), added check
+ if left operand is unsigned and use abs of literal value
+ * src/SDCCpeeph.c (setFromConditionArgs): removed double quotes option
+ as it doesn't work after conversion from peephole.def to peephole.rul
+ * src/mcs51/gen.c (toBoolean): added check for size,
+ (genModOneByte): optimized code for signed char modulo a literal
+ power of 2 (thanks to Hubert Sack),
+ (genRRC): removed unnecessary "clr c",
+ (genRLC): replaced "add a,acc" with cheaper "rlc a"
+ * src/mcs51/peeph.def: renamed 115 to 115.a, added rule 115.b: another
+ jump optimization,
+ swapped rules 256.c and 256.d,
+ extended 256.d by using new multiple checks (thanks Erik),
+ added rules 256.e and 256.f,
+ updated rule 261.a and 261.b to new generated code
+ * support/regression/tests/muldiv.c: added test div/mod by a power of 2
+
2004-12-07 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
* src/SDCCloop.c (basicInduction, loopInduction): fixed several
#define _REENTRANT reentrant
#define _CODE code
+#define _AUTOMEM
+#define _STATMEM
#endif
--- /dev/null
+/** DS390/DS400 specific features.
+ */
+#ifndef __SDC51_ASM_DS390_FEATURES_H
+#define __SDC51_ASM_DS390_FEATURES_H 1
+
+#define _REENTRANT reentrant
+#define _CODE code
+
+/* define _AUTOMEM to indicate the default storage class for
+ automatic variables. To be used with pointers to automatic variables.
+ Cannot be used in reentrant declared functions!
+
+ void foo(void)
+ {
+ char Ar[10];
+ char _AUTOMEM * pAr = Ar;
+ }
+*/
+#if defined(SDCC_STACK_AUTO)
+ #if defined(SDCC_USE_XSTACK)
+ #define _AUTOMEM pdata
+ #else
+ #define _AUTOMEM idata
+ #endif
+#elif defined(SDCC_MODEL_SMALL)
+ #define _AUTOMEM data
+#else
+ #define _AUTOMEM xdata
+#endif
+
+/* define _STATMEM to indicate the default storage class for
+ global/static variables. To be used with pointers to static variables.
+
+ char Ar[10];
+ void foo(void)
+ {
+ char _STATMEM * pAr = Ar;
+ }
+*/
+#if defined(SDCC_MODEL_SMALL)
+ #define _STATMEM data
+#else
+ #define _STATMEM xdata
+#endif
+
+#endif
#define _REENTRANT
#define _CODE
+#define _AUTOMEM
+#define _STATMEM
#define _SDCC_MANGLES_SUPPORT_FUNS 1
#define _SDCC_Z80_STYLE_LIB_OPT 1
--- /dev/null
+/** MCS51 specific features.
+ */
+#ifndef __SDC51_ASM_MCS51_FEATURES_H
+#define __SDC51_ASM_MCS51_FEATURES_H 1
+
+#define _REENTRANT reentrant
+#define _CODE code
+
+/* define _AUTOMEM to indicate the default storage class for
+ automatic variables. To be used with pointers to automatic variables.
+ Cannot be used in reentrant declared functions!
+
+ void foo(void)
+ {
+ char Ar[10];
+ char _AUTOMEM * pAr = Ar;
+ }
+*/
+#if defined(SDCC_STACK_AUTO)
+ #if defined(SDCC_USE_XSTACK)
+ #define _AUTOMEM pdata
+ #else
+ #define _AUTOMEM idata
+ #endif
+#elif defined(SDCC_MODEL_SMALL)
+ #define _AUTOMEM data
+#else
+ #define _AUTOMEM xdata
+#endif
+
+/* define _STATMEM to indicate the default storage class for
+ global/static variables. To be used with pointers to static variables.
+
+ char Ar[10];
+ void foo(void)
+ {
+ char _STATMEM * pAr = Ar;
+ }
+*/
+#if defined(SDCC_MODEL_SMALL)
+ #define _STATMEM data
+#else
+ #define _STATMEM xdata
+#endif
+
+#endif
#define _REENTRANT
#define _CODE
+#define _AUTOMEM
+#define _STATMEM
#define _SDCC_MANGLES_SUPPORT_FUNS 1
#define _SDCC_Z80_STYLE_LIB_OPT 1
-/** Top level header file for the sdcc libraries that enables target
+/*-------------------------------------------------------------------------
+ Top level header file for the sdcc libraries that enables target
specific features.
-*/
+
+ Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-------------------------------------------------------------------------*/
+
#ifndef __SDC51_SDCC_LIB_H
#define __SDC51_SDCC_LIB_H 1
#elif defined(__gbz80)
#include <asm/gbz80/features.h>
+#elif defined(__mcs51)
+#include <asm/mcs51/features.h>
+
+#elif defined(__ds390)
+#include <asm/ds390/features.h>
+
#else
/* PENDING */
#include <asm/default/features.h>
#endif
#endif
-#if defined(SDCC_mcs51)
- #if defined(SDCC_STACK_AUTO)
- #if defined(SDCC_USE_XSTACK)
- #define NEAR pdata
- #else
- //strange enough "idata" doesn't work
- #define NEAR data
- #endif
- #elif defined(SDCC_MODEL_LARGE)
- #define NEAR xdata
- #else
- #define NEAR data
- #endif
-#else
- #define NEAR
-#endif
-
#if defined(__ds390)
#define USE_FLOATS 1
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
+#include <sdcc-lib.h>
#define PTR value.ptr
// with radix "radix"
#ifndef ASM_ALLOWED
unsigned char store[6];
- unsigned char NEAR *pstore = &store[5];
+ unsigned char _AUTOMEM *pstore = &store[5];
#endif
// store value in byte[0] (LSB) ... byte[3] (MSB)
#endif
length++;
lsd = !lsd;
- } while( (value.byte[0] != 0) || (value.byte[1] != 0) ||
- (value.byte[2] != 0) || (value.byte[3] != 0) );
+ } while( value.ul );
if (width == 0)
{
\size normal
-SDCC 2.4.6
+SDCC 2.4.7
\size footnotesize
\newline
\layout Standard
-
-\series bold
-Attention
-\series default
-: this option wasn't maintained for a long time and is quite buggy.
- Small programs might work.
- You've been warned!
-\layout Standard
-
The external stack (-
\begin_inset ERT
status Collapsed
\end_inset
- memory (usually at the start of the external ram segment) and is 256 bytes
- in size.
+ memory (usually at the start of the external ram segment) and uses all
+ unused space in pdata (max.
+ 256 bytes).
When -
\begin_inset ERT
status Collapsed
option, all parameters and local variables are allocated on the external
stack (note: support libraries will need to be recompiled with the same
- options).
+ options.
+ There is a predefined target in the library makefile).
\layout Standard
The compiler outputs the higher order address byte of the external ram segment
fprintf (file, "]");
}
}
-
#endif
break;
if (s)
{
- itmplbl = newSymbol (s, 1);
+ itmplbl = newSymbol (s, 1);
}
else
{
// if not a pointer to a function
if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
if (implicit) { // if not to generic, they have to match
- if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
+ if (!IS_GENPTR(type) &&
+ !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
+ ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
+ )
+ )
+ {
werror(E_INCOMPAT_PTYPES);
errors++;
}
{
operand *aSym;
long litVal;
- int lr = 0;
/* consider only * & / */
if (ic->op != '*' && ic->op != '/')
int su;
int bytesPushed=0;
- // Easy special case which avoids function call: modulo by a literal power
- // of two can be replaced by a bitwise AND.
- if (op == '%' && isOperandLiteral(IC_RIGHT(ic)))
- {
- unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic)));
-
- // See if literal value is a power of 2.
- while (litVal && !(litVal & 1))
- {
- litVal >>= 1;
- }
- if (litVal)
- {
- // discard first high bit set.
- litVal >>= 1;
- }
-
- if (!litVal)
- {
- ic->op = BITWISEAND;
- IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
- return;
- }
- }
-
remiCodeFromeBBlock (ebp, ic);
-
/* depending on the type */
for (bwd = 0; bwd < 3; bwd++)
{
cnvToFloatCast (ic, ebbs[i]);
}
+ // Easy special case which avoids function call: modulo by a literal power
+ // of two can be replaced by a bitwise AND.
+ if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
+ IS_UNSIGNED(operandType(IC_LEFT(ic))))
+ {
+ unsigned litVal = abs(operandLitValue(IC_RIGHT(ic)));
+
+ // See if literal value is a power of 2.
+ while (litVal && !(litVal & 1))
+ {
+ litVal >>= 1;
+ }
+ if (litVal)
+ {
+ // discard lowest set bit.
+ litVal >>= 1;
+ }
+
+ if (!litVal)
+ {
+ ic->op = BITWISEAND;
+ IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
+ continue;
+ }
+ }
+
/* if long / int mult or divide or mod */
if (ic->op == '*' || ic->op == '/' || ic->op == '%')
{
/*------------------------------------------------------------------*/
/* setFromConditionArgs - parse a peephole condition's arguments */
/* to produce a set of strings, one per argument. Variables %x will */
-/* be replaced with their values. String literals (in single or */
-/* double quotes) are accepted an return in unquoted form. */
+/* be replaced with their values. String literals (in single quotes)*/
+/* are accepted and return in unquoted form. */
/*------------------------------------------------------------------*/
static set *
setFromConditionArgs (char *cmdLine, hTab * vars)
else
goto error;
}
- else if (*cmdLine == '"' || *cmdLine == '\'' )
+ else if (*cmdLine == '\'' )
{
char quote = *cmdLine;
if (!operands)
{
fprintf (stderr,
- "*** internal error: operandsUnrelated peephole restriction"
+ "*** internal error: operandsNotRelated peephole restriction"
" malformed: %s\n", cmdLine);
return FALSE;
}
if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
return -1;
}
- if (IS_PTR (src) && IS_GENPTR (dest))
+ if (IS_PTR (src) &&
+ (IS_GENPTR (dest) ||
+ ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
+ ))
return -1;
if (IS_PTR (dest) && IS_ARRAY (src)) {
value *val=aggregateToPointer (valFromType(src));
size = AOP_SIZE (oper) - 1;
offset = 1;
MOVA (aopGet (AOP (oper), 0, FALSE, FALSE));
- if (AccUsed && (AOP (oper)->type != AOP_ACC))
+ if (size && AccUsed && (AOP (oper)->type != AOP_ACC))
{
pushedB = pushB ();
emitcode("mov", "b,a");
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
+ /* if right is a literal, check it for 2^n */
+ if (AOP_TYPE(right) == AOP_LIT)
+ {
+ unsigned char val = abs(operandLitValue(right));
+ symbol *lbl2 = NULL;
+
+ switch (val)
+ {
+ case 1: /* sometimes it makes sense (on tricky code and hardware)... */
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ if (lUnsigned)
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "modulus of unsigned char by 2^n literal shouldn't be processed here");
+ /* because iCode should have been changed to genAnd */
+ /* see file "SDCCopt.c", function "convertToFcall()" */
+
+ MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+ emitcode ("mov", "c,acc.7");
+ emitcode ("anl", "a,#0x%02x", val - 1);
+ lbl = newiTempLabel (NULL);
+ emitcode ("jz", "%05d$", (lbl->key + 100));
+ emitcode ("jnc", "%05d$", (lbl->key + 100));
+ emitcode ("orl", "a,#0x%02x", 0xff ^ (val - 1));
+ if (size)
+ {
+ int size2 = size;
+ int offs2 = offset;
+
+ aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
+ while (size2--)
+ aopPut (AOP (result), "#0xff", offs2++, isOperandVolatile (result, FALSE));
+ lbl2 = newiTempLabel (NULL);
+ emitcode ("sjmp", "%05d$", (lbl2->key + 100));
+ }
+ emitcode ("", "%05d$:", (lbl->key + 100));
+ aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE));
+ while (size--)
+ aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE));
+ if (lbl2)
+ {
+ emitcode ("", "%05d$:", (lbl2->key + 100));
+ }
+ return;
+
+ default:
+ break;
+ }
+ }
+
pushedB = pushB ();
/* signed or unsigned */
/* modulus: sign of the right operand has no influence on the result! */
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) operandLitValue(right);
if (!rUnsigned && val < 0)
emitcode ("mov", "b,#0x%02x", -val);
D(emitcode ("; genMod",""));
- /* assign the amsops */
+ /* assign the asmops */
aopOp (left, ic, FALSE);
aopOp (right, ic, FALSE);
aopOp (result, ic, TRUE);
emitcode ("rr", "a");
goto release;
}
- CLRC;
+ /* no need to clear carry, bit7 will be written later */
while (size--)
{
l = aopGet (AOP (left), offset, FALSE, FALSE);
emitcode("rl","a");
goto release;
}
- emitcode ("add", "a,acc");
+ emitcode("rlc","a"); /* bit0 will be written later */
if (AOP_SIZE (result) > 1)
aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE));
while (size--)
%1:
} if labelInRange
-
replace {
clr a
cjne %1,%2,%3
%3:
jnz %4
} by {
- ; Peephole 115 jump optimization
+ ; Peephole 115.a jump optimization
cjne %1,%2,%3
sjmp %4
%3:
} if labelRefCount %3 1
+replace {
+ mov %1,a
+ cjne %1,#0x00,%2
+ sjmp %3
+%2:
+} by {
+ ; Peephole 115.b jump optimization
+ mov %1,a
+ jz %3
+%2:
+}
+
replace {
clr a
cjne %1,%2,%3
%2:
} if labelRefCount %2 0
-// applies to f.e. malloc.c
+// applies to f.e. bug-905492.c
replace {
jnz %1
%2:
mov %3,#0x00
- mov %4,#0x00
} by {
- ; Peephole 256.c loading %3,%4 with zero from a
+ ; Peephole 256.c loading %3 with zero from a
jnz %1
+%2:
mov %3,a
- mov %4,a
} if labelRefCount %2 0
-// applies to f.e. bug-905492.c
+// applies to f.e. malloc.c
replace {
jnz %1
%2:
+ mov %4,%5
mov %3,#0x00
} by {
; Peephole 256.d loading %3 with zero from a
jnz %1
+%2:
+ mov %4,%5
mov %3,a
-} if labelRefCount %2 0
+} if labelRefCount(%2 0),operandsNotRelated('a' %4)
+
+replace {
+ jnz %1
+%2:
+ mov %4,%5
+ mov %6,%7
+ mov %3,#0x00
+} by {
+ ; Peephole 256.e loading %3 with zero from a
+ jnz %1
+%2:
+ mov %4,%5
+ mov %6,%7
+ mov %3,a
+} if labelRefCount(%2 0),operandsNotRelated('a' %4 %6)
+
+replace {
+ jnz %1
+%2:
+ mov %4,%5
+ mov %6,%7
+ mov %8,%9
+ mov %3,#0x00
+} by {
+ ; Peephole 256.f loading %2 with zero from a
+ jnz %1
+%2:
+ mov %4,%5
+ mov %6,%7
+ mov %8,%9
+ mov %3,a
+} if labelRefCount(%2 0),operandsNotRelated('a' %4 %6 %8)
// unsigned char i=8; do{ } while(--i != 0);
// applies to: a = (a << 1) | (a >> 15);
replace {
mov a,%1
- add a,%1
+ rlc a
mov %1,a
mov a,%2
rlc a
// applies to: a = (a << 15) | (a >> 1);
replace {
- clr c
mov a,%1
rrc a
mov %1,a
ASSERT(i/25 == -2);
LOG(("i/-12 == 4 = %u\n", (int)i/-12));
ASSERT(i/-12 == 4);
+ //power of 2
+ ASSERT(i/4 == -12);
}
void
// LOG(("i%%-7 == 2 = %u\n", (int)i%-7));
ASSERT(i%-7 == 2);
+ //power of 2
+ ASSERT(i%-8 == 4);
i = -49;
// LOG(("i%%3 == -1 = %u\n", (int)i%3));
ASSERT(i%3 == -1);
// LOG(("i%%-5 == -4 = %u\n", (int)i%-5));
ASSERT(i%-5 == -4);
+ //power of 2
+ ASSERT(i%4 == -1);
}