From feddd68be35917362867a364ba8c51b7986cd67b Mon Sep 17 00:00:00 2001 From: epetrich Date: Thu, 6 Nov 2003 07:16:24 +0000 Subject: [PATCH] * src/port.h, * src/hc08/main.c, * src/mcs51/main.c, * src/ds390/main.c, * src/z80/main.c, * src/avr/main.c, * src/pic/main.c, * src/pic16/main.c, * src/xa51/main.c: added hasExtBitOp & oclsExpense functions to ports * src/SDCCicode.c: changed several IS_FARSPACE tests to isOclsExpensive tests (which uses the port's oclsExpense function) * src/SDCC.y, * src/SDCCast.c, * src/SDCCicode.c, * src/hc08/gen.c, * src/ds390/gen.c, * src/mcs51/gen.c: added support for the SWAP iCode (RFE #834167) git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2993 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 20 +++++++++++ src/SDCC.y | 2 +- src/SDCCast.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ src/SDCCicode.c | 30 ++++++++++++---- src/avr/main.c | 25 +++++++++++++ src/ds390/gen.c | 63 ++++++++++++++++++++++++++++++++ src/ds390/main.c | 30 ++++++++++++++++ src/hc08/gen.c | 52 +++++++++++++++++++++++++++ src/hc08/main.c | 35 ++++++++++++++++++ src/mcs51/gen.c | 64 +++++++++++++++++++++++++++++++++ src/mcs51/main.c | 26 ++++++++++++++ src/pic/main.c | 28 +++++++++++++++ src/pic16/main.c | 28 +++++++++++++++ src/port.h | 10 ++++++ src/xa51/main.c | 26 ++++++++++++++ src/z80/main.c | 24 +++++++++++++ 16 files changed, 550 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0be62c65..ea172b90 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2003-11-06 Erik Petrich + + * src/port.h, + * src/hc08/main.c, + * src/mcs51/main.c, + * src/ds390/main.c, + * src/z80/main.c, + * src/avr/main.c, + * src/pic/main.c, + * src/pic16/main.c, + * src/xa51/main.c: added hasExtBitOp & oclsExpense functions to ports + * src/SDCCicode.c: changed several IS_FARSPACE tests to isOclsExpensive + tests (which uses the port's oclsExpense function) + * src/SDCC.y, + * src/SDCCast.c, + * src/SDCCicode.c, + * src/hc08/gen.c, + * src/ds390/gen.c, + * src/mcs51/gen.c: added support for the SWAP iCode (RFE #834167) + 2003-11-04 Erik Petrich * src/SDCCcse.c (ifxOptimize), diff --git a/src/SDCC.y b/src/SDCC.y index 96fbfb10..0dc2de06 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -94,7 +94,7 @@ bool uselessDecl = TRUE; %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE %token RRC RLC %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT -%token DUMMY_READ_VOLATILE ENDCRITICAL +%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP %type Interrupt_storage %type identifier declarator declarator2 enumerator_list enumerator diff --git a/src/SDCCast.c b/src/SDCCast.c index 21372879..d0ba0c9b 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -52,6 +52,7 @@ static ast *createIval (ast *, sym_link *, initList *, ast *); static ast *createIvalCharPtr (ast *, sym_link *, ast *); static ast *optimizeCompare (ast *); ast *optimizeRRCRLC (ast *); +ast *optimizeSWAP (ast *); ast *optimizeGetHbit (ast *); ast *backPatchLabels (ast *, symbol *, symbol *); void PA(ast *t); @@ -1664,6 +1665,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) case RRC: case RLC: case GETHBIT: + case SWAP: if (IS_AST_SYM_VALUE (pbody->left) && isSymbolEqual (AST_SYMBOL (pbody->left), sym)) return FALSE; @@ -2408,6 +2410,11 @@ decorateType (ast * tree) ast *wtree = optimizeRRCRLC (tree); if (wtree != tree) return decorateType (wtree); + + wtree = optimizeSWAP (tree); + if (wtree != tree) + return decorateType (wtree); + // fall through } @@ -3008,6 +3015,7 @@ decorateType (ast * tree) /*----------------------------*/ case RRC: case RLC: + case SWAP: TTYPE (tree) = LTYPE (tree); TETYPE (tree) = LETYPE (tree); return tree; @@ -4346,6 +4354,11 @@ optimizeGetHbit (ast * tree) if ((i = (int) AST_LIT_VALUE (tree->left->right)) != (j = (getSize (TTYPE (tree->left->left)) * 8 - 1))) return tree; + + /* make sure the port supports GETHBIT */ + if (port->hasExtBitOp + && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left)))) + return tree; return decorateType (newNode (GETHBIT, tree->left->left, NULL)); @@ -4398,6 +4411,11 @@ optimizeRRCRLC (ast * root) (getSize (TTYPE (root->left->left)) * 8 - 1)) goto tryNext0; + /* make sure the port supports RLC */ + if (port->hasExtBitOp + && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left)))) + return root; + /* whew got the first case : create the AST */ return newNode (RLC, root->left->left, NULL); } @@ -4428,6 +4446,11 @@ tryNext0: (getSize (TTYPE (root->left->left)) * 8 - 1)) goto tryNext1; + /* make sure the port supports RLC */ + if (port->hasExtBitOp + && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left)))) + return root; + /* whew got the first case : create the AST */ return newNode (RLC, root->left->left, NULL); @@ -4459,6 +4482,11 @@ tryNext1: (getSize (TTYPE (root->left->left)) * 8 - 1)) goto tryNext2; + /* make sure the port supports RRC */ + if (port->hasExtBitOp + && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left)))) + return root; + /* whew got the first case : create the AST */ return newNode (RRC, root->left->left, NULL); @@ -4489,6 +4517,11 @@ tryNext2: (getSize (TTYPE (root->left->left)) * 8 - 1)) return root; + /* make sure the port supports RRC */ + if (port->hasExtBitOp + && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left)))) + return root; + /* whew got the first case : create the AST */ return newNode (RRC, root->left->left, NULL); @@ -4498,6 +4531,61 @@ tryNext2: return root; } +/*-----------------------------------------------------------------*/ +/* optimizeSWAP :- optimize for nibble/byte/word swaps */ +/*-----------------------------------------------------------------*/ +ast * +optimizeSWAP (ast * root) +{ + /* will look for trees of the form + (?expr << 4) | (?expr >> 4) or + (?expr >> 4) | (?expr << 4) will make that + into a SWAP : operation .. + note : by 4 I mean (number of bits required to hold the + variable /2 ) */ + /* if the root operations is not a | operation the not */ + if (!IS_BITOR (root)) + return root; + + /* (?expr << 4) | (?expr >> 4) */ + if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right)) + || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right))) + { + + if (!SPEC_USIGN (TETYPE (root->left->left))) + return root; + + if (!IS_AST_LIT_VALUE (root->left->right) || + !IS_AST_LIT_VALUE (root->right->right)) + return root; + + /* make sure it is the same expression */ + if (!isAstEqual (root->left->left, + root->right->left)) + return root; + + if (AST_LIT_VALUE (root->left->right) != + (getSize (TTYPE (root->left->left)) * 4)) + return root; + + if (AST_LIT_VALUE (root->right->right) != + (getSize (TTYPE (root->left->left)) * 4)) + return root; + + /* make sure the port supports SWAP */ + if (port->hasExtBitOp + && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left)))) + return root; + + /* found it : create the AST */ + return newNode (SWAP, root->left->left, NULL); + } + + + /* not found return root */ + return root; +} + /*-----------------------------------------------------------------*/ /* optimizeCompare - otimizes compares for bit variables */ /*-----------------------------------------------------------------*/ @@ -5182,6 +5270,12 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,")\n"); ast_print(tree->left,outfile,indent+2); return ; + case SWAP: + fprintf(outfile,"SWAP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+2); + return ; case GETHBIT: fprintf(outfile,"GETHBIT (%p) type (",tree); printTypeChain(tree->ftype,outfile); diff --git a/src/SDCCicode.c b/src/SDCCicode.c index ad97a2a8..dbb17c25 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -1021,6 +1021,21 @@ isOperandOnStack (operand * op) return FALSE; } +/*-----------------------------------------------------------------*/ +/* isOclsExpensive - will return true if accesses to an output */ +/* storage class are expensive */ +/*-----------------------------------------------------------------*/ +bool +isOclsExpensive (struct memmap *oclass) +{ + if (port->oclsExpense) + return port->oclsExpense (oclass) > 0; + + /* In the absence of port specific guidance, assume only */ + /* farspace is expensive. */ + return IN_FARSPACE (oclass); +} + /*-----------------------------------------------------------------*/ /* operandLitValue - literal value of an operand */ /*-----------------------------------------------------------------*/ @@ -1479,6 +1494,7 @@ operandFromSymbol (symbol * sym) register equivalent for a local symbol */ if (sym->level && sym->etype && SPEC_OCLS (sym->etype) && (IN_FARSPACE (SPEC_OCLS (sym->etype)) && + !TARGET_IS_HC08 && (!(options.model == MODEL_FLAT24)) ) && options.stackAuto == 0) ok = 0; @@ -1758,7 +1774,7 @@ geniCodeRValue (operand * op, bool force) /* if this is not a temp symbol then */ if (!IS_ITEMP (op) && !force && - !IN_FARSPACE (SPEC_OCLS (etype))) + !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08)) { op = operandFromOperand (op); op->isaddr = 0; @@ -1767,7 +1783,7 @@ geniCodeRValue (operand * op, bool force) if (IS_SPEC (type) && IS_TRUE_SYMOP (op) && - (!IN_FARSPACE (SPEC_OCLS (etype)) || + (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) || (options.model == MODEL_FLAT24) )) { op = operandFromOperand (op); @@ -2861,11 +2877,12 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) else if (compareType (ltype, rtype) < 0) right = geniCodeCast (ltype, right, TRUE); - /* if left is a true symbol & ! volatile + /* If left is a true symbol & ! volatile create an assignment to temporary for the right & then assign this temporary - to the symbol this is SSA . isn't it simple - and folks have published mountains of paper on it */ + to the symbol. This is SSA (static single + assignment). Isn't it simple and folks have + published mountains of paper on it */ if (IS_TRUE_SYMOP (left) && !isOperandVolatile (left, FALSE) && isOperandGlobal (left)) @@ -3094,7 +3111,7 @@ geniCodeReceive (value * args) if (!sym->addrtaken && !IS_VOLATILE (sym->etype)) { - if (IN_FARSPACE (SPEC_OCLS (sym->etype)) && + if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) && options.stackAuto == 0 && (!(options.model == MODEL_FLAT24)) ) { @@ -3757,6 +3774,7 @@ ast2iCode (ast * tree,int lvl) case '~': case RRC: case RLC: + case SWAP: return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); case '!': diff --git a/src/avr/main.c b/src/avr/main.c index e60bcec6..b5f958ca 100644 --- a/src/avr/main.c +++ b/src/avr/main.c @@ -131,6 +131,29 @@ _avr_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) return TRUE; } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + || op == GETHBIT + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -221,6 +244,8 @@ PORT avr_port = { NULL, NULL, NULL, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, TRUE, /* little endian */ 0, /* leave lt */ diff --git a/src/ds390/gen.c b/src/ds390/gen.c index b5ffdff7..8a55bcd4 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -7331,6 +7331,65 @@ genGetHbit (iCode * ic) freeAsmop (result, NULL, ic, TRUE); } +/*-----------------------------------------------------------------*/ +/* genSwap - generates code to swap nibbles or bytes */ +/*-----------------------------------------------------------------*/ +static void +genSwap (iCode * ic) +{ + operand *left, *result; + + D(emitcode ("; genSwap","")); + + left = IC_LEFT (ic); + result = IC_RESULT (ic); + aopOp (left, ic, FALSE, FALSE); + aopOp (result, ic, FALSE, AOP_USESDPTR(left)); + + _startLazyDPSEvaluation (); + switch (AOP_SIZE (left)) + { + case 1: /* swap nibbles in byte */ + MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL)); + emitcode ("swap", "a"); + aopPut (AOP (result), "a", 0); + break; + case 2: /* swap bytes in word */ + if (AOP_TYPE(left) == AOP_REG && sameRegs(AOP(left), AOP(result))) + { + MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL)); + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE, NULL), 0); + aopPut (AOP (result), "a", 1); + } + else if (operandsEqu (left, result)) + { + char * reg = "a"; + MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL)); + if (AOP_NEEDSACC (left) || AOP_NEEDSACC (result)) + { + emitcode ("mov", "b,a"); + reg = "b"; + _G.bInUse=1; + } + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE, NULL), 0); + aopPut (AOP (result), reg, 1); + _G.bInUse=0; + } + else + { + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE, NULL), 0); + aopPut (AOP (result), aopGet (AOP (left), 0, FALSE, FALSE, NULL), 1); + } + break; + default: + wassertl(FALSE, "unsupported SWAP operand size"); + } + _endLazyDPSEvaluation (); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); +} + /*-----------------------------------------------------------------*/ /* AccRol - rotate left accumulator by known count */ /*-----------------------------------------------------------------*/ @@ -13119,6 +13178,10 @@ gen390Code (iCode * lic) case ENDCRITICAL: genEndCritical (ic); break; + + case SWAP: + genSwap (ic); + break; #if 0 // obsolete, and buggy for != xdata case ARRAYINIT: diff --git a/src/ds390/main.c b/src/ds390/main.c index 330b8d7e..66577044 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -314,6 +314,30 @@ bool _ds390_nativeMulCheck(iCode *ic, sym_link *left, sym_link *right) return FALSE; // #STUB } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + || op == GETHBIT + || (op == SWAP && size <= 2) + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + /** $1 is always the basename. $2 is always the output file. @@ -411,6 +435,8 @@ PORT ds390_port = NULL, NULL, _ds390_nativeMulCheck, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, TRUE, /* little endian */ 0, /* leave lt */ @@ -702,6 +728,8 @@ PORT tininative_port = NULL, NULL, NULL, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, TRUE, /* little endian */ 0, /* leave lt */ @@ -911,6 +939,8 @@ PORT ds400_port = NULL, NULL, _ds390_nativeMulCheck, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, TRUE, /* little endian */ 0, /* leave lt */ diff --git a/src/hc08/gen.c b/src/hc08/gen.c index 284fa042..1a71fd2e 100644 --- a/src/hc08/gen.c +++ b/src/hc08/gen.c @@ -4968,7 +4968,55 @@ genGetHbit (iCode * ic) emitcode ("rola", ""); hc08_dirtyReg (hc08_reg_a, FALSE); storeRegToFullAop (hc08_reg_a, AOP (result), FALSE); + hc08_freeReg (hc08_reg_a); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); +} + +/*-----------------------------------------------------------------*/ +/* genSwap - generates code to swap nibbles or bytes */ +/*-----------------------------------------------------------------*/ +static void +genSwap (iCode * ic) +{ + operand *left, *result; + + D(emitcode ("; genSwap","")); + + left = IC_LEFT (ic); + result = IC_RESULT (ic); + aopOp (left, ic, FALSE); + aopOp (result, ic, FALSE); + switch (AOP_SIZE (left)) + { + case 1: /* swap nibbles in byte */ + loadRegFromAop (hc08_reg_a, AOP (left), 0); + emitcode ("nsa", ""); + hc08_dirtyReg (hc08_reg_a, FALSE); + storeRegToAop (hc08_reg_a, AOP (result), 0); + hc08_freeReg (hc08_reg_a); + break; + case 2: /* swap bytes in a word */ + if (operandsEqu (left, result)) + { + loadRegFromAop (hc08_reg_a, AOP (left), 0); + hc08_useReg (hc08_reg_a); + transferAopAop (AOP (left), 1, AOP (result), 0); + storeRegToAop (hc08_reg_a, AOP (result), 1); + hc08_freeReg (hc08_reg_a); + } + else + { + transferAopAop (AOP (left), 0, AOP (result), 1); + transferAopAop (AOP (left), 1, AOP (result), 0); + } + break; + default: + wassertl(FALSE, "unsupported SWAP operand size"); + } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -7629,6 +7677,10 @@ genhc08Code (iCode * lic) case ENDCRITICAL: genEndCritical (ic); break; + + case SWAP: + genSwap (ic); + break; default: ic = ic; diff --git a/src/hc08/main.c b/src/hc08/main.c index 600e768d..86e75757 100644 --- a/src/hc08/main.c +++ b/src/hc08/main.c @@ -276,6 +276,39 @@ static bool cseCostEstimation (iCode *ic, iCode *pdic) } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + || op == GETHBIT + || (op == SWAP && size <= 2) + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + /* The hc08's addressing modes allow access to all storage classes */ + /* inexpensively (<=0) */ + + if (IN_DIRSPACE (oclass)) /* direct addressing mode is fastest */ + return -2; + if (IN_FARSPACE (oclass)) /* extended addressing mode is almost at fast */ + return -1; + if (oclass == istack) /* stack is the slowest, but still faster than */ + return 0; /* trying to copy to a temp location elsewhere */ + + return 0; /* anything we missed */ +} + + + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -374,6 +407,8 @@ PORT hc08_port = NULL, /* process_pragma */ NULL, /* getMangledFunctionName */ NULL, /* hasNativeMulFor */ + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ TRUE, /* use_dw_for_init */ FALSE, /* little endian */ 0, /* leave lt */ diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 7f254ef7..fe034342 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -5751,6 +5751,66 @@ genGetHbit (iCode * ic) freeAsmop (result, NULL, ic, TRUE); } +/*-----------------------------------------------------------------*/ +/* genSwap - generates code to swap nibbles or bytes */ +/*-----------------------------------------------------------------*/ +static void +genSwap (iCode * ic) +{ + operand *left, *result; + + D(emitcode ("; genSwap","")); + + left = IC_LEFT (ic); + result = IC_RESULT (ic); + aopOp (left, ic, FALSE); + aopOp (result, ic, FALSE); + + switch (AOP_SIZE (left)) + { + case 1: /* swap nibbles in byte */ + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + emitcode ("swap", "a"); + aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); + break; + case 2: /* swap bytes in word */ + if (AOP_TYPE(left) == AOP_REG && sameRegs(AOP(left), AOP(result))) + { + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE), + 0, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", 1, isOperandVolatile (result, FALSE)); + } + else if (operandsEqu (left, result)) + { + char * reg = "a"; + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + if (aopGetUsesAcc(AOP (left), 1) || aopGetUsesAcc(AOP (result), 0)) + { + emitcode ("mov", "b,a"); + reg = "b"; + } + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE), + 0, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), reg, 1, isOperandVolatile (result, FALSE)); + } + else + { + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE), + 0, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), aopGet (AOP (left), 0, FALSE, FALSE), + 1, isOperandVolatile (result, FALSE)); + } + break; + default: + wassertl(FALSE, "unsupported SWAP operand size"); + } + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); +} + + /*-----------------------------------------------------------------*/ /* AccRol - rotate left accumulator by known count */ /*-----------------------------------------------------------------*/ @@ -9335,6 +9395,10 @@ gen51Code (iCode * lic) genEndCritical (ic); break; + case SWAP: + genSwap (ic); + break; + default: ic = ic; } diff --git a/src/mcs51/main.c b/src/mcs51/main.c index 30adbfd8..dfda2822 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -202,6 +202,30 @@ static bool cseCostEstimation (iCode *ic, iCode *pdic) return 1; } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + || op == GETHBIT + || (op == SWAP && size <= 2) + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -299,6 +323,8 @@ PORT mcs51_port = NULL, NULL, NULL, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, TRUE, /* little endian */ 0, /* leave lt */ diff --git a/src/pic/main.c b/src/pic/main.c index 2a818bf3..b3515d09 100644 --- a/src/pic/main.c +++ b/src/pic/main.c @@ -320,6 +320,32 @@ _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) */ } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + /* || op == GETHBIT */ /* GETHBIT doesn't look complete for PIC */ + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + /* The IN_FARSPACE test is compatible with historical behaviour, */ + /* but I don't think it is applicable to PIC. If so, please feel */ + /* free to remove this test -- EEP */ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -423,6 +449,8 @@ PORT pic_port = _process_pragma, /* process a pragma */ NULL, _hasNativeMulFor, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, TRUE, /* little endian */ 0, /* leave lt */ diff --git a/src/pic16/main.c b/src/pic16/main.c index d41540df..e1c6f24c 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -381,6 +381,32 @@ _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) */ } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + /* || op == GETHBIT */ /* GETHBIT doesn't look complete for PIC */ + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + /* The IN_FARSPACE test is compatible with historical behaviour, */ + /* but I don't think it is applicable to PIC. If so, please feel */ + /* free to remove this test -- EEP */ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -488,6 +514,8 @@ PORT pic16_port = _process_pragma, /* process a pragma */ NULL, _hasNativeMulFor, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, TRUE, /* little endian */ 0, /* leave lt */ diff --git a/src/port.h b/src/port.h index 3e3aec94..3f1745ec 100644 --- a/src/port.h +++ b/src/port.h @@ -249,6 +249,16 @@ typedef struct */ bool (*hasNativeMulFor) (iCode *ic, sym_link *left, sym_link *right); + /** Returns true if the port has implemented certain bit + manipulation iCodes (RRC, RLC, SWAP, GETHBIT) + */ + bool (*hasExtBitOp) (int op, int size); + + /** Returns the relative expense of accessing a particular output + storage class. Larger values indicate higher expense. + */ + int (*oclsExpense) (struct memmap *oclass); + /** If TRUE, then tprintf and !dw will be used for some initalisers */ bool use_dw_for_init; diff --git a/src/xa51/main.c b/src/xa51/main.c index 1a9ae3ed..3ef77a26 100755 --- a/src/xa51/main.c +++ b/src/xa51/main.c @@ -192,6 +192,30 @@ static bool cseCostEstimation (iCode *ic, iCode *pdic) return 1; } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + || op == GETHBIT + ) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -294,6 +318,8 @@ PORT xa51_port = NULL, // process_pragma() NULL, // getMangledFunctionName() NULL, // hasNativeMulFor() + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ TRUE, // use_dw_for_init TRUE, /* little endian */ 0, /* leave lt */ diff --git a/src/z80/main.c b/src/z80/main.c index 2768d4d6..3545430f 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -478,6 +478,26 @@ _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) return FALSE; } +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == GETHBIT) + return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; +} + #define LINKCMD "link-{port} -nf {dstfilename}" /* @@ -573,6 +593,8 @@ PORT z80_port = _process_pragma, _mangleSupportFunctionName, _hasNativeMulFor, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ TRUE, TRUE, /* little endian */ 0, /* leave lt */ @@ -670,6 +692,8 @@ PORT gbz80_port = _process_pragma, _mangleSupportFunctionName, _hasNativeMulFor, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ TRUE, TRUE, /* little endian */ 0, /* leave lt */ -- 2.47.2