From d46b4a50e1b8b1819d974533a9012b013090f8fd Mon Sep 17 00:00:00 2001 From: michaelh Date: Thu, 2 Aug 2001 15:21:20 +0000 Subject: [PATCH] * Added support for doing shifts by helper functions * Fleshed out long support in the z80 port * Fixed left and right shift in the z80 port. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1122 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/SDCCicode.c | 2 +- src/SDCCloop.c | 4 +- src/SDCCopt.c | 41 ++++++++--- src/SDCCsymt.c | 42 ++++++----- src/SDCCsymt.h | 2 + src/avr/main.c | 3 +- src/ds390/main.c | 2 +- src/izt/tlcs900h.c | 2 +- src/mcs51/main.c | 2 +- src/pic/main.c | 2 +- src/port.h | 9 +-- src/z80/gen.c | 178 ++++++++++++++++++++------------------------- src/z80/main.c | 2 +- 13 files changed, 148 insertions(+), 143 deletions(-) diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 44403c9f..4e93c888 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -1632,7 +1632,7 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt) if port has 1 byte muldiv */ if (p2 && !IS_FLOAT (letype) && !((resultIsInt) && (getSize (resType) != getSize (ltype)) && - (port->muldiv.native_below == 1))) + (port->support.muldiv == 1))) { if ((resultIsInt) && (getSize (resType) != getSize (ltype))) { diff --git a/src/SDCCloop.c b/src/SDCCloop.c index ca70d4b3..a50bac49 100644 --- a/src/SDCCloop.c +++ b/src/SDCCloop.c @@ -947,8 +947,8 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count) /* ask port for size not worth if native instruction exist for multiply & divide */ - if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->muldiv.native_below || - getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->muldiv.native_below) + if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->support.muldiv || + getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->support.muldiv) continue; /* if this is a division then the remainder should be zero diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 8ed9c597..33d7a351 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -340,6 +340,14 @@ convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) func = __muldiv[1][bwd][su]; else if (op == '%') func = __muldiv[2][bwd][su]; + else if (op == RRC) + func = __rlrr[1][bwd][su]; + else if (op == RLC) + func = __rlrr[0][bwd][su]; + else if (op == RIGHT_OP) + func = __rlrr[1][bwd][su]; + else if (op == LEFT_OP) + func = __rlrr[0][bwd][su]; else assert (0); goto found; @@ -373,32 +381,36 @@ found: addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; - } else { - /* compiled as reentrant then push */ /* push right */ if (IS_REGPARM (func->args->next->etype)) - newic = newiCode (SEND, IC_RIGHT (ic), NULL); + { + newic = newiCode (SEND, IC_RIGHT (ic), NULL); + } else { newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); newic->parmPush = 1; - bytesPushed += getSize(type); + + bytesPushed += getSize(operandType(IC_RIGHT(ic))); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; /* insert push left */ if (IS_REGPARM (func->args->etype)) - newic = newiCode (SEND, IC_LEFT (ic), NULL); + { + newic = newiCode (SEND, IC_LEFT (ic), NULL); + } else { newic = newiCode (IPUSH, IC_LEFT (ic), NULL); newic->parmPush = 1; - bytesPushed += getSize(type); + + bytesPushed += getSize(operandType(IC_LEFT(ic))); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; @@ -452,11 +464,22 @@ convertToFcall (eBBlock ** ebbs, int count) /* if long / int mult or divide or mod */ if (ic->op == '*' || ic->op == '/' || ic->op == '%') { - sym_link *type = operandType (IC_LEFT (ic)); - if (IS_INTEGRAL (type) && getSize (type) > port->muldiv.native_below) - convilong (ic, ebbs[i], type, ic->op); + if (IS_INTEGRAL (type) && getSize (type) > port->support.muldiv) + { + convilong (ic, ebbs[i], type, ic->op); + } } + + if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP) + { + sym_link *type = operandType (IC_LEFT (ic)); + + if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0) + { + convilong (ic, ebbs[i], type, ic->op); + } + } } } } diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index f8301369..2037ea60 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -2261,25 +2261,11 @@ symbol *__muldiv[3][3][2]; sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ symbol *__conv[2][3][2]; +/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ +symbol *__rlrr[2][3][2]; sym_link *floatType; -static void -_makeRegParam (symbol * sym) -{ - value *val; - - val = sym->args; /* loop thru all the arguments */ - - /* reset regparm for the port */ - (*port->reset_regparms) (); - while (val) - { - SPEC_REGPARM (val->etype) = 1; - val = val->next; - } -} - static char * _mangleFunctionName(char *in) { @@ -2311,8 +2297,12 @@ initCSupport () { "s", "u" }; + const char *srlrr[] = + { + "rl", "rr" + }; - int bwd, su, muldivmod, tofrom; + int bwd, su, muldivmod, tofrom, rlrr; floatType = newFloatLink (); @@ -2381,8 +2371,22 @@ initCSupport () sbwd[bwd]); __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1; - if (bwd < port->muldiv.force_reg_param_below) - _makeRegParam (__muldiv[muldivmod][bwd][su]); + } + } + } + + for (rlrr = 0; rlrr < 2; rlrr++) + { + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + sprintf (buffer, "_%s%s%s", + srlrr[rlrr], + ssu[su], + sbwd[bwd]); + __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent); + SPEC_NONBANKED (__rlrr[rlrr][bwd][su]->etype) = 1; } } } diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 7033b2cd..2b06d0dd 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -383,6 +383,8 @@ extern symbol *__muldiv[3][3][2]; extern sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ extern symbol *__conv[2][3][2]; +/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ +symbol *__rlrr[2][3][2]; #define CHARTYPE __multypes[0][0] #define UCHARTYPE __multypes[0][1] diff --git a/src/avr/main.c b/src/avr/main.c index 5ddc571e..a9bcd469 100644 --- a/src/avr/main.c +++ b/src/avr/main.c @@ -190,7 +190,8 @@ PORT avr_port = { -1, 1, 4, 1, 1, 0}, /* avr has an 8 bit mul */ { - 1, 0}, + 1, -1 + }, "_", _avr_init, _avr_parseOptions, diff --git a/src/ds390/main.c b/src/ds390/main.c index 1301e603..3bafacb7 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -248,7 +248,7 @@ PORT ds390_port = }, /* ds390 has an 8 bit mul */ { - 1, 0 + 1, -1 }, "_", _ds390_init, diff --git a/src/izt/tlcs900h.c b/src/izt/tlcs900h.c index addb8597..bc9d8d50 100644 --- a/src/izt/tlcs900h.c +++ b/src/izt/tlcs900h.c @@ -181,7 +181,7 @@ PORT tlcs900h_port = }, /* tlcs900h has an 16 bit mul */ { - 2, 0 + 2, -1 }, "_", _tlcs900h_init, diff --git a/src/mcs51/main.c b/src/mcs51/main.c index f7af7756..68e32ea3 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -188,7 +188,7 @@ PORT mcs51_port = }, /* mcs51 has an 8 bit mul */ { - 1, 0 + 1, -1 }, "_", _mcs51_init, diff --git a/src/pic/main.c b/src/pic/main.c index d2222421..d411f500 100644 --- a/src/pic/main.c +++ b/src/pic/main.c @@ -272,7 +272,7 @@ PORT pic_port = }, /* pic14 has an 8 bit mul */ { - 1, 0 + 1, -1 }, "_", _pic14_init, diff --git a/src/port.h b/src/port.h index 9bf97e49..d53dd0ce 100644 --- a/src/port.h +++ b/src/port.h @@ -148,13 +148,10 @@ typedef struct /** One more than the smallest mul/div operation the processor can do nativley Eg if the processor has an 8 bit mul, nativebelow is 2 */ - unsigned native_below; - /** The mul/div/mod functions will be made to use regparams - for sizeof(param) < log2(force_reg) - i.e. Use 2 for WORD and BYTE, 0 for none. */ - int force_reg_param_below; + unsigned muldiv; + unsigned shift; } - muldiv; + support; /** Prefix to add to a C function (eg "_") */ const char *fun_prefix; diff --git a/src/z80/gen.c b/src/z80/gen.c index ffef3648..77764b7f 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -794,10 +794,6 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash) char *s = buffer; char *rs; -#if 0 - if (aop->size != 2 && aop->type != AOP_HL) - return NULL; -#endif /* depending on type */ switch (aop->type) { @@ -809,9 +805,9 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash) tsprintf (s, "!hashedstr + %d", aop->aopu.aop_immd, offset); else tsprintf (s, "%s + %d", aop->aopu.aop_immd, offset); - rs = Safe_calloc (1, strlen (s) + 1); - strcpy (rs, s); - return rs; + + return gc_strdup(s); + case AOP_LIT: { value *val = aop->aopu.aop_lit; @@ -822,14 +818,24 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash) unsigned long v = (unsigned long) floatFromVal (val); if (offset == 2) - v >>= 16; + { + v >>= 16; + } + else if (offset == 0) + { + // OK + } + else + { + wassertl(0, "Encountered an invalid offset while fetching a literal"); + } if (with_hash) tsprintf (buffer, "!immedword", v); else tsprintf (buffer, "!constword", v); - rs = Safe_calloc (1, strlen (buffer) + 1); - return strcpy (rs, buffer); + + return gc_strdup(buffer); } else { @@ -938,7 +944,7 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset) { const char *l; const char *pair = _pairs[pairId].name; - l = aopGetLitWordLong (left, 0, FALSE); + l = aopGetLitWordLong (left, offset, FALSE); wassert (l && pair); if (isPtr (pair)) @@ -980,10 +986,7 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset) _G.pairs[pairId].offset = offset; } /* Both a lit on the right and a true symbol on the left */ - if (offset) - emit2 ("ld %s,!hashedstr + %u", pair, l, offset); - else - emit2 ("ld %s,!hashedstr", pair, l); + emit2 ("ld %s,!hashedstr", pair, l); } static void @@ -1796,42 +1799,6 @@ genIpush (iCode * ic) if (!ic->parmPush) { wassertl(0, "Encountered an unsupported spill push."); -#if 0 - /* and the item is spilt then do nothing */ - if (OP_SYMBOL (IC_LEFT (ic))->isspilt) - return; - - aopOp (IC_LEFT (ic), ic, FALSE, FALSE); - size = AOP_SIZE (IC_LEFT (ic)); - /* push it on the stack */ - if (isPair (AOP (IC_LEFT (ic)))) - { - emit2 ("push %s", getPairName (AOP (IC_LEFT (ic)))); - _G.stack.pushed += 2; - } - else - { - offset = size; - while (size--) - { - /* Simple for now - load into A and PUSH AF */ - if (AOP (IC_LEFT (ic))->type == AOP_IY) - { - char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE); - wassert (l); - emit2 ("ld a,(%s)", l); - } - else - { - l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE); - emit2 ("ld a,%s", l); - } - emit2 ("push af"); - emit2 ("inc sp"); - _G.stack.pushed++; - } - } -#endif return; } @@ -4308,47 +4275,48 @@ genRLC (iCode * ic) static void shiftR2Left2Result (operand * left, int offl, operand * result, int offr, - int shCount, int sign) + int shCount, int is_signed) { + int size = 2; + int offset = 0; + symbol *tlbl, *tlbl1; + const char *l; + movLeft2Result (left, offl, result, offr, 0); movLeft2Result (left, offl + 1, result, offr + 1, 0); - if (sign) + /* if (AOP(result)->type == AOP_REG) { */ + + tlbl = newiTempLabel (NULL); + tlbl1 = newiTempLabel (NULL); + + /* Left is already in result - so now do the shift */ + if (shCount > 1) { - wassert (0); + emit2 ("ld a,!immedbyte+1", shCount); + emit2 ("!shortjp !tlabel", tlbl1->key + 100); + emitLabel (tlbl->key + 100); } - else + + offset = 0; + while (size--) { - /* if (AOP(result)->type == AOP_REG) { */ - int size = 2; - int offset = 0; - symbol *tlbl, *tlbl1; - const char *l; - - tlbl = newiTempLabel (NULL); - tlbl1 = newiTempLabel (NULL); - - /* Left is already in result - so now do the shift */ - if (shCount > 1) - { - emit2 ("ld a,!immedbyte+1", shCount); - emit2 ("!shortjp !tlabel", tlbl1->key + 100); - emitLabel (tlbl->key + 100); - } - - emit2 ("or a,a"); - offset = size; - while (size--) - { - l = aopGet (AOP (result), --offset, FALSE); - emit2 ("rr %s", l); - } - if (shCount > 1) - { - emitLabel (tlbl1->key + 100); - emit2 ("dec a"); - emit2 ("!shortjp nz,!tlabel", tlbl->key + 100); - } + l = aopGet (AOP (result), size, FALSE); + if (offset == 0) + { + emit2 ("%s %s", is_signed ? "sra" : "srl", l); + } + else + { + emit2 ("rr %s", l); + } + offset++; + } + if (shCount > 1) + { + emitLabel (tlbl1->key + 100); + emit2 ("dec a"); + emit2 ("!shortjp nz,!tlabel", tlbl->key + 100); } } @@ -4392,8 +4360,11 @@ shiftL2Left2Result (operand * left, int offl, emit2 ("or a,a"); while (size--) { - l = aopGet (AOP (result), offset++, FALSE); + l = aopGet (AOP (result), offset, FALSE); + emit2 ("rl %s", l); + + offset++; } if (shCount > 1) { @@ -4681,7 +4652,9 @@ genLeftShift (iCode * ic) emit2 ("!shortjp !tlabel", tlbl1->key + 100); emitLabel (tlbl->key + 100); l = aopGet (AOP (result), offset, FALSE); + emit2 ("or a,a"); + while (size--) { l = aopGet (AOP (result), offset++, FALSE); @@ -4699,7 +4672,7 @@ genLeftShift (iCode * ic) /* genrshOne - left shift two bytes by known amount != 0 */ /*-----------------------------------------------------------------*/ static void -genrshOne (operand * result, operand * left, int shCount) +genrshOne (operand * result, operand * left, int shCount, int is_signed) { /* Errk */ int size = AOP_SIZE (result); @@ -4709,19 +4682,24 @@ genrshOne (operand * result, operand * left, int shCount) wassert (shCount < 8); l = aopGet (AOP (left), 0, FALSE); + + emit2 ("or a,a"); + if (AOP (result)->type == AOP_REG) { aopPut (AOP (result), l, 0); l = aopGet (AOP (result), 0, FALSE); while (shCount--) - emit2 ("srl %s", l); + { + emit2 ("%s %s", is_signed ? "sra" : "srl", l); + } } else { _moveA (l); while (shCount--) { - emit2 ("srl a"); + emit2 ("%s a", is_signed ? "sra" : "srl"); } aopPut (AOP (result), "a", 0); } @@ -4803,7 +4781,8 @@ static void genRightShiftLiteral (operand * left, operand * right, operand * result, - iCode * ic) + iCode * ic, + int sign) { int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit); int size; @@ -4832,17 +4811,17 @@ genRightShiftLiteral (operand * left, switch (size) { case 1: - genrshOne (result, left, shCount); + genrshOne (result, left, shCount, sign); break; case 2: /* PENDING: sign support */ - genrshTwo (result, left, shCount, FALSE); + genrshTwo (result, left, shCount, sign); break; case 4: - wassert (0); + wassertl (0, "Asked to shift right a long which should be a function call"); break; default: - wassert (0); + wassertl (0, "Entered default case in right shift delegate"); } } freeAsmop (left, NULL, ic); @@ -4886,7 +4865,7 @@ genRightShift (iCode * ic) as efficiently as possible */ if (AOP_TYPE (right) == AOP_LIT) { - genRightShiftLiteral (left, right, result, ic); + genRightShiftLiteral (left, right, result, ic, is_signed); return; } @@ -4925,14 +4904,13 @@ genRightShift (iCode * ic) l = aopGet (AOP (result), offset--, FALSE); if (first) { - if (is_signed) - emit2 ("sra %s", l); - else - emit2 ("srl %s", l); + emit2 ("%s %s", is_signed ? "sra" : "srl", l); first = 0; } else - emit2 ("rr %s", l); + { + emit2 ("rr %s", l); + } } emitLabel (tlbl1->key + 100); emit2 ("dec a"); diff --git a/src/z80/main.c b/src/z80/main.c index aa8d569c..9fb9b075 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -511,7 +511,7 @@ PORT z80_port = }, /* Z80 has no native mul/div commands */ { - 0, 0 + 0, 2 }, "_", _z80_init, -- 2.30.2