X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=960a6964ac563891238a9eaef7a24b8d8cce2946;hb=d3e9a3c6e43e6623ed168709704e410609302ddd;hp=d62a96fe8281e78aeed1497e177b672ed756cf05;hpb=ff00cfcd27b7a5648a406db0464bf39afcbe13df;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index d62a96fe..960a6964 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -51,6 +51,7 @@ operand *geniCodeArray2Ptr (operand *); operand *geniCodeRValue (operand *, bool); operand *geniCodeDerefPtr (operand *,int); int isLvaluereq(int lvl); +void setOClass (sym_link * ptr, sym_link * spec); #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s) /* forward definition of ic print functions */ @@ -1800,7 +1801,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) if (IS_INTEGRAL(optype)) { // maybe this is NULL, than it's ok. if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) { - if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) { + if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) { // no way to set the storage if (IS_LITERAL(optype)) { werror(E_LITERAL_GENERIC); @@ -1823,7 +1824,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) } } } else { // from a pointer to a pointer - if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) { + if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) { // 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 @@ -2189,7 +2190,6 @@ aggrToPtr (sym_link * type, bool force) sym_link *etype; sym_link *ptype; - if (IS_PTR (type) && !force) return type; @@ -2198,19 +2198,8 @@ aggrToPtr (sym_link * type, bool force) ptype->next = type; - /* if the output class is code */ - if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER) - DCL_PTR_CONST (ptype) = port->mem.code_ro; - - /* if the variable was declared a constant */ - /* then the pointer points to a constant */ - if (IS_CONSTANT (etype)) - DCL_PTR_CONST (ptype) = 1; - - /* the variable was volatile then pointer to volatile */ - if (IS_VOLATILE (etype)) - DCL_PTR_VOLATILE (ptype) = 1; - + /* set the pointer depending on the storage class */ + DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype)); return ptype; } @@ -2224,17 +2213,7 @@ geniCodeArray2Ptr (operand * op) sym_link *opetype = getSpec (optype); /* set the pointer depending on the storage class */ - if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER) - DCL_PTR_CONST (optype) = port->mem.code_ro; - - /* if the variable was declared a constant */ - /* then the pointer points to a constant */ - if (IS_CONSTANT (opetype)) - DCL_PTR_CONST (optype) = 1; - - /* the variable was volatile then pointer to volatile */ - if (IS_VOLATILE (opetype)) - DCL_PTR_VOLATILE (optype) = 1; + DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype)); op->isaddr = 0; return op; @@ -2310,13 +2289,13 @@ geniCodeStruct (operand * left, operand * right, bool islval) SPEC_SCLS (retype) = SPEC_SCLS (etype); SPEC_OCLS (retype) = SPEC_OCLS (etype); SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype); - + SPEC_CONST (retype) |= SPEC_CONST (etype); + if (IS_PTR (element->type)) setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE)); - + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type)); - ADDTOCHAIN (ic); return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE)); } @@ -2522,15 +2501,7 @@ geniCodeAddressOf (operand * op) p = newLink (DECLARATOR); /* set the pointer depending on the storage class */ - if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER) - DCL_PTR_CONST (p) = port->mem.code_ro; - - /* make sure we preserve the const & volatile */ - if (IS_CONSTANT (opetype)) - DCL_PTR_CONST (p) = 1; - - if (IS_VOLATILE (opetype)) - DCL_PTR_VOLATILE (p) = 1; + DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype)); p->next = copyLinkChain (optype); @@ -2623,18 +2594,12 @@ geniCodeDerefPtr (operand * op,int lvl) else { retype = getSpec (rtype = copyLinkChain (optype->next)); + /* outputclass needs 2b updated */ + setOClass (optype, retype); } - - /* outputclass needs 2b updated */ - setOClass (optype, retype); - + op->isGptr = IS_GENPTR (optype); - /* if the pointer was declared as a constant */ - /* then we cannot allow assignment to the derefed */ - if (IS_PTR_CONST (optype)) - SPEC_CONST (retype) = 1; - op->isaddr = (IS_PTR (rtype) || IS_STRUCT (rtype) || IS_INT (rtype) || @@ -2897,6 +2862,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 */ /*-----------------------------------------------------------------*/ @@ -3246,6 +3229,8 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) operand *boundary; symbol *falseLabel; set *labels = NULL; + int needRangeCheck = !optimize.noJTabBoundary + || tree->values.switchVals.swDefault; if (!tree || !caseVals) return 0; @@ -3281,7 +3266,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* if the number of case statements <= 2 then */ /* it is not economical to create the jump table */ /* since two compares are needed for boundary conditions */ - if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3)) + if ((needRangeCheck && cnt <= 2) || max > (255 / 3)) return 0; if (tree->values.switchVals.swDefault) @@ -3299,7 +3284,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* so we can create a jumptable */ /* first we rule out the boundary conditions */ /* if only optimization says so */ - if (!optimize.noJTabBoundary) + if (needRangeCheck) { sym_link *cetype = getSpec (operandType (cond)); /* no need to check the lower bound if @@ -3321,7 +3306,8 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) if (min) { cond = geniCodeSubtract (cond, operandFromLit (min)); - setOperandType (cond, UCHARTYPE); + if (!IS_LITERAL(getSpec(operandType(cond)))) + setOperandType (cond, UCHARTYPE); } /* now create the jumptable */ @@ -3342,6 +3328,29 @@ geniCodeSwitch (ast * tree,int lvl) operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE); value *caseVals = tree->values.switchVals.swVals; symbol *trueLabel, *falseLabel; + + /* If the condition is a literal, then just jump to the */ + /* appropriate case label. */ + if (IS_LITERAL(getSpec(operandType(cond)))) + { + int switchVal, caseVal; + + switchVal = (int) floatFromVal (cond->operand.valOperand); + while (caseVals) + { + caseVal = (int) floatFromVal (caseVals); + if (caseVal == switchVal) + { + SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d", + tree->values.switchVals.swNum, caseVal); + trueLabel = newiTempLabel (buffer); + geniCodeGoto (trueLabel); + goto jumpTable; + } + caseVals = caseVals->next; + } + goto defaultOrBreak; + } /* if we can make this a jump table */ if (geniCodeJumpTable (cond, caseVals, tree)) @@ -3366,7 +3375,7 @@ geniCodeSwitch (ast * tree,int lvl) } - +defaultOrBreak: /* if default is present then goto break else break */ if (tree->values.switchVals.swDefault) { @@ -3512,8 +3521,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; }