X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=9637d52dd11313e42b2129658c337727efd3e67e;hb=67ed241504134df14b300e4ccd6e16a896977e71;hp=a59ed4ef99c591daa9a79c57fcc3a5636d358913;hpb=77fcb4b638332e6c6494f5060c716ae6fe3c94b8;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index a59ed4ef..9637d52d 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -69,6 +69,8 @@ PRINTFUNC (picJumpTable); PRINTFUNC (picInline); PRINTFUNC (picReceive); PRINTFUNC (picDummyRead); +PRINTFUNC (picCritical); +PRINTFUNC (picEndCritical); iCodeTable codeTable[] = { @@ -115,7 +117,9 @@ iCodeTable codeTable[] = {RECEIVE, "recv", picReceive, NULL}, {SEND, "send", picGenericOne, NULL}, {ARRAYINIT, "arrayInit", picGenericOne, NULL}, - {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL} + {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL}, + {CRITICAL, "critical_start", picCritical, NULL}, + {ENDCRITICAL, "critical_end", picEndCritical, NULL} }; /*-----------------------------------------------------------------*/ @@ -473,6 +477,28 @@ PRINTFUNC (picDummyRead) fprintf (of, "\n"); } +PRINTFUNC (picCritical) +{ + fprintf (of, "\t"); + if (IC_RESULT (ic)) + printOperand (IC_RESULT (ic), of); + else + fprintf (of, "(stack)"); + fprintf (of, " = %s ", s); + fprintf (of, "\n"); +} + +PRINTFUNC (picEndCritical) +{ + fprintf (of, "\t"); + fprintf (of, "%s = ", s); + if (IC_RIGHT (ic)) + printOperand (IC_RIGHT (ic), of); + else + fprintf (of, "(stack)"); + fprintf (of, "\n"); +} + /*-----------------------------------------------------------------*/ /* piCode - prints one iCode */ /*-----------------------------------------------------------------*/ @@ -995,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 */ /*-----------------------------------------------------------------*/ @@ -1094,8 +1135,7 @@ operandOperation (operand * left, operand * right, (TYPE_UWORD) operandLitValue (right); retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul)); - if (!options.lessPedantic && - ul != (TYPE_UWORD) ul) + if (ul != (TYPE_UWORD) ul) werror (W_INT_OVL); } else /* signed int */ @@ -1105,8 +1145,7 @@ operandOperation (operand * left, operand * right, (TYPE_WORD) operandLitValue (right); retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l)); - if (!options.lessPedantic && - l != (TYPE_WORD) l) + if (l != (TYPE_WORD) l) werror (W_INT_OVL); } } @@ -1455,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; @@ -1734,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; @@ -1743,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); @@ -2068,7 +2108,7 @@ subtractExit: if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) { return result; } - + // should we really do this? is this ANSI? return geniCodeDivision (result, operandFromLit (getSize (ltype->next))); @@ -2136,11 +2176,11 @@ geniCodeAdd (operand * left, operand * right, int lvl) /* if the right side is LITERAL zero */ /* return the left side */ - if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype))) + if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype))) return left; /* if left is literal zero return right */ - if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype))) + if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype))) return right; /* if left is a pointer then size */ @@ -2162,8 +2202,8 @@ geniCodeAdd (operand * left, operand * right, int lvl) /* if they are both literals then we know */ if (IS_LITERAL (letype) && IS_LITERAL (retype) && left->isLiteral && right->isLiteral) - return operandFromValue (valPlus (valFromType (letype), - valFromType (retype))); + return operandFromValue (valPlus (valFromType (ltype), + valFromType (rtype))); ic = newiCode ('+', left, right); @@ -2228,13 +2268,14 @@ geniCodeArray (operand * left, operand * right,int lvl) { iCode *ic; sym_link *ltype = operandType (left); - + if (IS_PTR (ltype)) { if (IS_PTR (ltype->next) && left->isaddr) { left = geniCodeRValue (left, FALSE); } + return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl); } @@ -2260,6 +2301,7 @@ geniCodeArray (operand * left, operand * right,int lvl) IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next)); ADDTOCHAIN (ic); + return IC_RESULT (ic); } @@ -2350,7 +2392,7 @@ geniCodePostInc (operand * op) /* geniCodePreInc - generate code for preIncrement */ /*-----------------------------------------------------------------*/ operand * -geniCodePreInc (operand * op) +geniCodePreInc (operand * op, bool lvalue) { iCode *ic; sym_link *optype = operandType (op); @@ -2376,8 +2418,11 @@ geniCodePreInc (operand * op) IC_RESULT (ic) = result = newiTempOperand (roptype, 0); ADDTOCHAIN (ic); - - return geniCodeAssign (op, result, 0); + (void) geniCodeAssign (op, result, 0); + if (lvalue || IS_TRUE_SYMOP (op)) + return op; + else + return result; } /*-----------------------------------------------------------------*/ @@ -2430,7 +2475,7 @@ geniCodePostDec (operand * op) /* geniCodePreDec - generate code for pre decrement */ /*-----------------------------------------------------------------*/ operand * -geniCodePreDec (operand * op) +geniCodePreDec (operand * op, bool lvalue) { iCode *ic; sym_link *optype = operandType (op); @@ -2456,8 +2501,11 @@ geniCodePreDec (operand * op) IC_RESULT (ic) = result = newiTempOperand (roptype, 0); ADDTOCHAIN (ic); - - return geniCodeAssign (op, result, 0); + (void) geniCodeAssign (op, result, 0); + if (lvalue || IS_TRUE_SYMOP (op)) + return op; + else + return result; } @@ -2491,6 +2539,13 @@ geniCodeAddressOf (operand * op) sym_link *optype = operandType (op); sym_link *opetype = getSpec (optype); + if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype)) + { + op = operandFromOperand (op); + op->isaddr = 0; + return op; + } + /* lvalue check already done in decorateType */ /* this must be a lvalue */ /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */ @@ -2830,11 +2885,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)) @@ -2862,6 +2918,24 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) return left; } +/*-----------------------------------------------------------------*/ +/* geniCodeDummyRead - generate code for dummy read */ +/*-----------------------------------------------------------------*/ +static void +geniCodeDummyRead (operand * op) +{ + iCode *ic; + sym_link *type = operandType (op); + + if (!IS_VOLATILE(type)) + return; + + ic = newiCode (DUMMY_READ_VOLATILE, NULL, op); + ADDTOCHAIN (ic); + + ic->nosupdate = 1; +} + /*-----------------------------------------------------------------*/ /* geniCodeSEParms - generate code for side effecting fcalls */ /*-----------------------------------------------------------------*/ @@ -2992,7 +3066,7 @@ geniCodeCall (operand * left, ast * parms,int lvl) if (!IS_FUNC(OP_SYMBOL(left)->type) && !IS_CODEPTR(OP_SYMBOL(left)->type)) { werror (E_FUNCTION_EXPECTED); - return NULL; + return operandFromValue(valueFromLit(0)); } /* take care of parameters with side-effecting @@ -3045,7 +3119,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)) ) { @@ -3408,6 +3482,34 @@ geniCodeArrayInit (ast * tree, operand *array) } ADDTOCHAIN (ic); } + +/*-----------------------------------------------------------------*/ +/* geniCodeCritical - intermediate code for a critical statement */ +/*-----------------------------------------------------------------*/ +static void +geniCodeCritical (ast *tree, int lvl) +{ + iCode *ic; + operand *op = NULL; + + /* If op is NULL, the original interrupt state will saved on */ + /* the stack. Otherwise, it will be saved in op. */ + + /* Generate a save of the current interrupt state & disabled */ + ic = newiCode (CRITICAL, NULL, NULL); + IC_RESULT (ic) = op; + ADDTOCHAIN (ic); + + /* Generate the critical code sequence */ + if (tree->left && tree->left->type == EX_VALUE) + geniCodeDummyRead (ast2iCode (tree->left,lvl+1)); + else + ast2iCode (tree->left,lvl+1); + + /* Generate a restore of the original interrupt state */ + ic = newiCode (ENDCRITICAL, NULL, op); + ADDTOCHAIN (ic); +} /*-----------------------------------------------------------------*/ /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */ @@ -3503,8 +3605,14 @@ ast2iCode (ast * tree,int lvl) (tree->opval.op == NULLOP || tree->opval.op == BLOCK)) { - ast2iCode (tree->left,lvl+1); - ast2iCode (tree->right,lvl+1); + if (tree->left && tree->left->type == EX_VALUE) + geniCodeDummyRead (ast2iCode (tree->left,lvl+1)); + else + ast2iCode (tree->left,lvl+1); + if (tree->right && tree->right->type == EX_VALUE) + geniCodeDummyRead (ast2iCode (tree->right,lvl+1)); + else + ast2iCode (tree->right,lvl+1); return NULL; } @@ -3517,7 +3625,8 @@ ast2iCode (ast * tree,int lvl) tree->opval.op != GOTO && tree->opval.op != SWITCH && tree->opval.op != FUNCTION && - tree->opval.op != INLINEASM) + tree->opval.op != INLINEASM && + tree->opval.op != CRITICAL) { if (IS_ASSIGN_OP (tree->opval.op) || @@ -3590,13 +3699,13 @@ ast2iCode (ast * tree,int lvl) if (left) return geniCodePostInc (left); else - return geniCodePreInc (right); + return geniCodePreInc (right, tree->lvalue); case DEC_OP: /* decrement operator */ if (left) return geniCodePostDec (left); else - return geniCodePreDec (right); + return geniCodePreDec (right, tree->lvalue); case '&': /* bitwise and or address of operator */ if (right) @@ -3630,7 +3739,7 @@ ast2iCode (ast * tree,int lvl) return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); case '-': - if (right) + if (right) return geniCodeSubtract (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE)); else @@ -3673,6 +3782,7 @@ ast2iCode (ast * tree,int lvl) case '~': case RRC: case RLC: + case SWAP: return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); case '!': @@ -3851,6 +3961,9 @@ ast2iCode (ast * tree,int lvl) case ARRAYINIT: geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1)); return NULL; + + case CRITICAL: + geniCodeCritical (tree, lvl); } return NULL;