From: MaartenBrock Date: Tue, 16 Sep 2008 19:34:18 +0000 (+0000) Subject: * device/lib/z80/mul.s (__mulsuchar_rrx_s, __muluschar_rrx_s), X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=ac2a3bee4ffe024a919c1b360cc888679a45f326;hp=24a948a79cc9a76ee83dc2d90b6f5a3604fa617d;p=fw%2Fsdcc * device/lib/z80/mul.s (__mulsuchar_rrx_s, __muluschar_rrx_s), * device/lib/z80/div.s (__divsuchar_rrx_s, __modsuchar_rrx_s, __divuschar_rrx_s, __moduschar_rrx_s): added mixed signedness versions * device/lib/z80/stubs.s: added stubs for above functions * src/SDCCopt.c (convilong), * src/SDCCsymt.c (initCSupport): fixed bug 1900961 * src/SDCCsymt.h (__muldiv): enlarged for mixed signedness * src/z80/main.c (_hasNativeMulFor): fixed bug, I think * support/regression/tests/onebyte.c: enabled all tests for z80 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5241 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 723558c4..4eda2d3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-09-16 Maarten Brock + + * device/lib/z80/mul.s (__mulsuchar_rrx_s, __muluschar_rrx_s), + * device/lib/z80/div.s (__divsuchar_rrx_s, __modsuchar_rrx_s, + __divuschar_rrx_s, __moduschar_rrx_s): added mixed signedness versions + * device/lib/z80/stubs.s: added stubs for above functions + * src/SDCCopt.c (convilong), + * src/SDCCsymt.c (initCSupport): fixed bug 1900961 + * src/SDCCsymt.h (__muldiv): enlarged for mixed signedness + * src/z80/main.c (_hasNativeMulFor): fixed bug, I think + * support/regression/tests/onebyte.c: enabled all tests for z80 + 2008-09-15 Borut Razem * device/include/pic16/stdio.h, device/lib/pic16/libc/stdio/streams.c, diff --git a/device/lib/z80/div.s b/device/lib/z80/div.s index e20c31b2..c34176b8 100644 --- a/device/lib/z80/div.s +++ b/device/lib/z80/div.s @@ -175,12 +175,87 @@ __moduint_rrx_hds:: ret +__divsuchar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld e,(hl) + dec hl + ld c,(hl) + ld b, #0 + + call signexte + + ld l,c + ld h,b + + ret + +__modsuchar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld e,(hl) + dec hl + ld c,(hl) + ld b, #0 + + call signexte + + ld l,e + ld h,d + + ret + +__divuschar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld e,(hl) + ld d, #0 + dec hl + ld c,(hl) + + ld a,c ; Sign extend + rlca + sbc a + ld b,a + + call .div16 + + ld l,c + ld h,b + + ret + +__moduschar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld e,(hl) + ld d, #0 + dec hl + ld c,(hl) + + ld a,c ; Sign extend + rlca + sbc a + ld b,a + + call .div16 + + ld l,e + ld h,d + + ret + .div8:: .mod8:: ld a,c ; Sign extend rlca sbc a ld b,a +signexte: ld a,e ; Sign extend rlca sbc a diff --git a/device/lib/z80/mul.s b/device/lib/z80/mul.s index a638e068..424554a7 100644 --- a/device/lib/z80/mul.s +++ b/device/lib/z80/mul.s @@ -4,10 +4,10 @@ ; from Rodnay Zaks, "Programming the Z80". __muluchar_rrx_s:: - ld hl, #2 + ld hl, #2+1 add hl, sp ld e, (hl) - inc hl + dec hl ld h, (hl) ld l, #0 ld d, l @@ -20,14 +20,36 @@ muluchar_rrx_s_noadd: djnz muluchar_rrx_s_loop ret +; operands have different sign + +__mulsuchar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld e,(hl) + dec hl + ld c,(hl) + ld b, #0 + jr signexte + +__muluschar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld c,(hl) + ld b, #0 + dec hl + ld e,(hl) + jr signexte + ;; Originally from GBDK by Pascal Felber. __mulschar_rrx_s:: - ld hl,#2 + ld hl,#2+1 add hl,sp ld e,(hl) - inc hl + dec hl ld l,(hl) ;; Fall through @@ -39,13 +61,13 @@ __mulschar_rrx_hds:: rla sbc a,a ld b,a - +signexte: ld a,e rla sbc a,a ld d,a - jp .mul16 + jr .mul16 __mulint_rrx_s:: ld hl,#2 @@ -65,7 +87,7 @@ __mulint_rrx_s:: __muluchar_rrx_hds:: __mulint_rrx_hds:: ;; Parameters: - ;; HL, DE (left, right irrelivent) + ;; HL, DE (left, right irrelevant) ld b,h ld c,l @@ -88,7 +110,7 @@ __mulint_rrx_hds:: ;; Optimise for the case when this side has 8 bits of data or ;; less. This is often the case with support address calls. or a - jp NZ,1$ + jr NZ,1$ ld b,#8 ld a,c diff --git a/device/lib/z80/stubs.s b/device/lib/z80/stubs.s index 10211be3..667662a0 100644 --- a/device/lib/z80/stubs.s +++ b/device/lib/z80/stubs.s @@ -7,14 +7,20 @@ .globl __divslong .globl __divulong .globl __divschar_rrx_s - .globl __divsint_rrx_s .globl __divuchar_rrx_s + .globl __divsuchar_rrx_s + .globl __divuschar_rrx_s + .globl __divsint_rrx_s .globl __divuint_rrx_s .globl __mulschar_rrx_s .globl __muluchar_rrx_s + .globl __mulsuchar_rrx_s + .globl __muluschar_rrx_s .globl __mulint_rrx_s - .globl __moduchar_rrx_s .globl __modschar_rrx_s + .globl __moduchar_rrx_s + .globl __modsuchar_rrx_s + .globl __moduschar_rrx_s .globl __moduint_rrx_s .globl __modsint_rrx_s .globl __rrulong_rrx_s @@ -67,6 +73,11 @@ __divschar_rrf_s:: rst 0x08 jp __divschar_rrx_s +__modschar_rrf_s:: + ld a,#5 + rst 0x08 + jp __modschar_rrx_s + __muluchar_rrf_s:: ld a,#5 rst 0x08 @@ -77,15 +88,40 @@ __divuchar_rrf_s:: rst 0x08 jp __divuchar_rrx_s -__modschar_rrf_s:: +__moduchar_rrf_s:: ld a,#5 rst 0x08 - jp __modschar_rrx_s + jp __moduchar_rrx_s -__moduchar_rrf_s:: +__mulsuchar_rrf_s:: ld a,#5 rst 0x08 - jp __moduchar_rrx_s + jp __mulsuchar_rrx_s + +__divsuchar_rrf_s:: + ld a,#5 + rst 0x08 + jp __divsuchar_rrx_s + +__modsuchar_rrf_s:: + ld a,#5 + rst 0x08 + jp __modsuchar_rrx_s + +__muluschar_rrf_s:: + ld a,#5 + rst 0x08 + jp __muluschar_rrx_s + +__divuschar_rrf_s:: + ld a,#5 + rst 0x08 + jp __divuschar_rrx_s + +__moduschar_rrf_s:: + ld a,#5 + rst 0x08 + jp __moduschar_rrx_s __modsint_rrf_s:: ld a,#5 diff --git a/src/SDCCopt.c b/src/SDCCopt.c index d5b39650..c799bed2 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -654,8 +654,9 @@ extern operand *geniCodeRValue (operand *, bool); /* convilong - converts int or long mults or divs to fcalls */ /*-----------------------------------------------------------------*/ static void -convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) +convilong (iCode * ic, eBBlock * ebp) { + int op = ic->op; symbol *func = NULL; iCode *ip = ic->next; iCode *newic; @@ -664,16 +665,48 @@ convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) int bwd; int su; int bytesPushed=0; + sym_link *leftType = operandType (IC_LEFT (ic)); + sym_link *rightType = operandType (IC_RIGHT (ic)); remiCodeFromeBBlock (ebp, ic); + if (getSize (leftType) == 1 && getSize (rightType) == 1) + { + int muldivmod; + + if (op == '*') + muldivmod = 0; + else if (op == '/') + muldivmod = 1; + else if (op == '%') + muldivmod = 2; + else + muldivmod = -1; + + for (su = 0; su < 4 && muldivmod >= 0; su++) + { + if ((compareType (leftType, __multypes[0][su%2]) == 1) && + (compareType (rightType, __multypes[0][su/2]) == 1)) + { + func = __muldiv[muldivmod][0][su]; + goto found; + } + } + } + /* depending on the type */ for (bwd = 0; bwd < 3; bwd++) { for (su = 0; su < 2; su++) { - if (compareType (type, __multypes[bwd][su]) == 1) + if (compareType (leftType, __multypes[bwd][su]) == 1) { + if ((op=='*' || op=='/' || op=='%') && + compareType (rightType, __multypes[bwd][su]) != 1) + { + assert(0); + } + if (op == '*') func = __muldiv[0][bwd][su]; else if (op == '/') @@ -883,7 +916,7 @@ convertToFcall (eBBlock ** ebbs, int count) } else { - convilong (ic, ebbs[i], leftType, ic->op); + convilong (ic, ebbs[i]); } } } @@ -894,7 +927,7 @@ convertToFcall (eBBlock ** ebbs, int count) if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0) { - convilong (ic, ebbs[i], type, ic->op); + convilong (ic, ebbs[i]); } } } diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index a27c0ec6..e17d7c51 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -184,6 +184,7 @@ deleteSym (bucket ** stab, void *sym, char *sname) if (!bp) /* did not find it */ return; + /* if this is the first one in the chain */ if (!bp->prev) { @@ -199,7 +200,6 @@ deleteSym (bucket ** stab, void *sym, char *sname) bp->prev->next = bp->next; } - } /*-----------------------------------------------------------------*/ @@ -592,7 +592,6 @@ void checkTypeSanity(sym_link *etype, char *name) { // short AND long werror (E_LONG_AND_SHORT_INVALID, noun, name); } - } /*------------------------------------------------------------------*/ @@ -1088,7 +1087,7 @@ addSymChain (symbol ** symHead) { /* if not formal parameter and not in file scope then show symbol redefined error - else check if symbols have conpatible types */ + else check if symbols have compatible types */ if (!sym->_isparm && sym->level > 0) error = 1; else @@ -3286,8 +3285,8 @@ symbol *__fps16x16_lteq; symbol *__fps16x16_gt; symbol *__fps16x16_gteq; -/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ -symbol *__muldiv[3][3][2]; +/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */ +symbol *__muldiv[3][3][4]; /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */ sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ @@ -3441,7 +3440,7 @@ initCSupport () }; const char *ssu[] = { - "s", "u" + "s", "su", "us", "u" }; const char *srlrr[] = { @@ -3511,12 +3510,12 @@ initCSupport () { if (tofrom) { - SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su*3], sbwd[bwd]); __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent); } else { - SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su*3], sbwd[bwd]); __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent); } } @@ -3531,7 +3530,7 @@ initCSupport () { if (tofrom) { - SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su*3], fp16x16sbwd[bwd]); if(bwd == 3) { __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent); } else @@ -3539,7 +3538,7 @@ initCSupport () } else { - SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]); + SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su*3], fp16x16sbwd[bwd]); if(bwd == 3) { __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent); } else @@ -3559,7 +3558,7 @@ initCSupport () SNPRINTF (buffer, sizeof(buffer), "_%s%s%s", smuldivmod[muldivmod], - ssu[su], + ssu[su*3], sbwd[bwd]); __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; @@ -3571,7 +3570,34 @@ initCSupport () Therefore they've been merged into mulint() and mullong(). */ - for (bwd = 0; bwd < 3; bwd++) + /* byte */ + bwd = 0; + for (su = 0; su < 4; su++) + { + for (muldivmod = 0; muldivmod < 3; muldivmod++) + { + /* muluchar, mulschar, mulsuchar and muluschar are separate functions, because e.g. the z80 + port is sign/zero-extending to int before calling mulint() */ + /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */ + if (!TARGET_IS_PIC16 || muldivmod != 1 || su != 0) + { + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType ( + _mangleFunctionName(buffer), + __multypes[bwd][su%2], + __multypes[bwd][su/2], + 2, + options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + } + } + } + + for (bwd = 1; bwd < 3; bwd++) { for (su = 0; su < 2; su++) { @@ -3583,7 +3609,7 @@ initCSupport () SNPRINTF (buffer, sizeof(buffer), "_%s%s%s", smuldivmod[muldivmod], - ssu[su], + ssu[su*3], sbwd[bwd]); __muldiv[muldivmod][bwd][su] = funcOfType ( _mangleFunctionName(buffer), @@ -3623,20 +3649,6 @@ initCSupport () /* mul only */ muldivmod = 0; - /* byte */ - bwd = 0; - for (su = 0; su < 2; su++) - { - /* muluchar and mulschar are still separate functions, because e.g. the z80 - port is sign/zero-extending to int before calling mulint() */ - SNPRINTF (buffer, sizeof(buffer), - "_%s%s%s", - smuldivmod[muldivmod], - ssu[su], - sbwd[bwd]); - __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); - FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; - } /* signed only */ su = 0; /* word and doubleword */ @@ -3662,7 +3674,7 @@ initCSupport () SNPRINTF (buffer, sizeof(buffer), "_%s%s%s", srlrr[rlrr], - ssu[su], + ssu[su*3], sbwd[bwd]); __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent); FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1; diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 0aa29c69..ae82145e 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -549,8 +549,8 @@ extern symbol *__fps16x16_lteq; extern symbol *__fps16x16_gt; extern symbol *__fps16x16_gteq; -/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ -extern symbol *__muldiv[3][3][2]; +/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */ +extern symbol *__muldiv[3][3][4]; /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */ extern sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ diff --git a/src/z80/main.c b/src/z80/main.c index fcdd870d..86501c99 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -587,7 +587,7 @@ _setDefaultOptions (void) optimize.loopInduction = 1; } -/* Mangaling format: +/* Mangling format: _fun_policy_params where: policy is the function policy @@ -598,7 +598,7 @@ _setDefaultOptions (void) where: r is 'r' for reentrant, 's' for static functions s is 'c' for callee saves, 'r' for caller saves - p is 'p' for profiling on, 'x' for profiling off + f is 'f' for profiling on, 'x' for profiling off examples: rr - reentrant, caller saves params format: @@ -614,7 +614,7 @@ _mangleSupportFunctionName(char *original) sprintf(buffer, "%s_rr%s_%s", original, options.profile ? "f" : "x", - options.noRegParams ? "s" : "bds" + options.noRegParams ? "s" : "bds" /* MB: but the library only has hds variants ??? */ ); return Safe_strdup(buffer); @@ -649,7 +649,7 @@ _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) } else if ( IS_LITERAL (right)) { - test = left; + test = right; val = OP_VALUE (IC_RIGHT (ic)); } else diff --git a/support/regression/tests/onebyte.c b/support/regression/tests/onebyte.c index 8cee1139..ea5d8147 100644 --- a/support/regression/tests/onebyte.c +++ b/support/regression/tests/onebyte.c @@ -26,10 +26,8 @@ testMul (void) cL = -128; cR = 1; r8 = cL * cR; r8b = cR * cL; ASSERT ( r8 == -128); ASSERT ( r8b == -128); cL = 128; cR = 1; ur8 = cL * cR; ur8b = cR * cL; ASSERT (ur8 == 128); ASSERT (ur8b == 128); -#ifndef SDCC_z80 ucL = 128; cR = -5; r16 = ucL * cR; r16b = cR * ucL; ASSERT (r16 == -640); ASSERT (r16b == -640); ucL = 128; cR = 5; r16 = ucL * cR; r16b = cR * ucL; ASSERT (r16 == 640); ASSERT (r16b == 640); -#endif ucL = 127; cR = -1; r8 = ucL * cR; r8b = cR * ucL; ASSERT ( r8 == -127); ASSERT ( r8b == -127); ucL = 128; cR = 1; ur8 = ucL * cR; ur8b = cR * ucL; ASSERT (ur8 == 128); ASSERT (ur8b == 128); @@ -62,10 +60,8 @@ testDiv (void) ucL = 127; cR = 3; r8 = ucL / cR; ASSERT (r8 == 42); ucL = 255; cR = 3; r8 = ucL / cR; ASSERT (r8 == 85); -#ifndef SDCC_z80 ucL = 127; cR = -3; r8 = ucL / cR; ASSERT (r8 == -42); ucL = 255; cR = -3; r8 = ucL / cR; ASSERT (r8 == -85); -#endif cL = 127; ucR = 3; r8 = cL / ucR; ASSERT (r8 == 42); cL = -127; ucR = 3; r8 = cL / ucR; ASSERT (r8 == -42); @@ -78,12 +74,10 @@ testDiv (void) ucL = 251; cR = 1; ur8 = ucL / cR; ASSERT (ur8 == 251); ucL = 251; cR = 1; r16 = ucL / cR; ASSERT (r16 == 251); -#ifndef SDCC_z80 ucL = 253; cR = -3; r8 = ucL / cR; ASSERT (r8 == -84); ucL = 253; cR = -3; r16 = ucL / cR; ASSERT (r16 == -84); ucL = 254; cR = -1; r16 = ucL / cR; ASSERT (r16 == -254); -#endif cL = -128; cR = -1; r16 = cL / cR; ASSERT (r16 == 128); } @@ -99,9 +93,7 @@ testMod (void) volatile short r16; ucL = 128; cR = 5; r16 = ucL % cR; ASSERT (r16 == 3); -#ifndef SDCC_z80 ucL = 128; cR = -5; r16 = ucL % cR; ASSERT (r16 == 3); -#endif ucL = 128; ucR = 5; r16 = ucL % ucR; ASSERT (r16 == 3); ucL = 128; ucR = 255; ur8 = ucL % ucR; ASSERT (ur8 == 128);