]> git.sur5r.net Git - cc65/blobdiff - src/cc65/stdfunc.c
So far the built-in inlining of several known standard function was always (!) enable...
[cc65] / src / cc65 / stdfunc.c
index 720e6db15fdcac43c8980c31b1734067726c7685..7a04501468f2ce9c9fcbea4dbe52727a04bd39dd 100644 (file)
@@ -261,262 +261,277 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
         goto ExitPoint;
     }
 
-    /* We've generated the complete code for the function now and know the
-    ** types of all parameters. Check for situations where better code can
-    ** be generated. If such a situation is detected, throw away the
-    ** generated, and emit better code.
-    */
-    if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
-        ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
-         (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
-        ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
-         (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) {
+    if (IS_Get (&InlineStdFuncs)) {
 
-        int Reg1 = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr);
-        int Reg2 = ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr);
+        /* We've generated the complete code for the function now and know the
+        ** types of all parameters. Check for situations where better code can
+        ** be generated. If such a situation is detected, throw away the
+        ** generated, and emit better code.
+        */
+        if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
+            ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
+             (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
+            ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
+             (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) {
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+            int Reg1 = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr);
+            int Reg2 = ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr);
 
-        /* We need a label */
-        Label = GetLocalLabel ();
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
 
-        /* Generate memcpy code */
-        if (Arg3.Expr.IVal <= 127) {
+            /* We need a label */
+            Label = GetLocalLabel ();
 
-            AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
-            g_defcodelabel (Label);
-            if (Reg2) {
-                AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0));
-            } else {
-                AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0));
-            }
-            if (Reg1) {
-                AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
-            } else {
-                AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
-            }
-            AddCodeLine ("dey");
-            AddCodeLine ("bpl %s", LocalLabelName (Label));
+            /* Generate memcpy code */
+            if (Arg3.Expr.IVal <= 127) {
 
-        } else {
+                AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
+                g_defcodelabel (Label);
+                if (Reg2) {
+                    AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0));
+                } else {
+                    AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0));
+                }
+                if (Reg1) {
+                    AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
+                } else {
+                    AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
+                }
+                AddCodeLine ("dey");
+                AddCodeLine ("bpl %s", LocalLabelName (Label));
 
-            AddCodeLine ("ldy #$00");
-            g_defcodelabel (Label);
-            if (Reg2) {
-                AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0));
-            } else {
-                AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0));
-            }
-            if (Reg1) {
-                AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
             } else {
-                AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
-            }
-            AddCodeLine ("iny");
-            AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
-            AddCodeLine ("bne %s", LocalLabelName (Label));
 
-        }
+                AddCodeLine ("ldy #$00");
+                g_defcodelabel (Label);
+                if (Reg2) {
+                    AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg2.Expr, 0));
+                } else {
+                    AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, 0));
+                }
+                if (Reg1) {
+                    AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
+                } else {
+                    AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
+                }
+                AddCodeLine ("iny");
+                AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
+                AddCodeLine ("bne %s", LocalLabelName (Label));
 
-        /* memcpy returns the address, so the result is actually identical
-        ** to the first argument.
-        */
-        *Expr = Arg1.Expr;
+            }
 
-    } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
-               ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) &&
-               ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) &&
-               (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) {
-
-        /* It is possible to just use one index register even if the stack
-        ** offset is not zero, by adjusting the offset to the constant
-        ** address accordingly. But we cannot do this if the data in
-        ** question is in the register space or at an absolute address less
-        ** than 256. Register space is zero page, which means that the
-        ** address calculation could overflow in the linker.
-        */
-        int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) &&
-                            !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256);
+            /* memcpy returns the address, so the result is actually identical
+            ** to the first argument.
+            */
+            *Expr = Arg1.Expr;
 
-        /* Calculate the real stack offset */
-        Offs = ED_GetStackOffs (&Arg1.Expr, 0);
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+        if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
+            ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) &&
+            ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) &&
+            (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) {
+
+            /* It is possible to just use one index register even if the stack
+            ** offset is not zero, by adjusting the offset to the constant
+            ** address accordingly. But we cannot do this if the data in
+            ** question is in the register space or at an absolute address less
+            ** than 256. Register space is zero page, which means that the
+            ** address calculation could overflow in the linker.
+            */
+            int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) &&
+                                !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256);
 
-        /* We need a label */
-        Label = GetLocalLabel ();
+            /* Calculate the real stack offset */
+            Offs = ED_GetStackOffs (&Arg1.Expr, 0);
 
-        /* Generate memcpy code */
-        if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) {
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
+
+            /* We need a label */
+            Label = GetLocalLabel ();
+
+            /* Generate memcpy code */
+            if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) {
+
+                if (Offs == 0) {
+                    AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1));
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs));
+                    AddCodeLine ("sta (sp),y");
+                    AddCodeLine ("dey");
+                    AddCodeLine ("bpl %s", LocalLabelName (Label));
+                } else {
+                    AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
+                    AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1));
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0));
+                    AddCodeLine ("sta (sp),y");
+                    AddCodeLine ("dey");
+                    AddCodeLine ("dex");
+                    AddCodeLine ("bpl %s", LocalLabelName (Label));
+                }
 
-            if (Offs == 0) {
-                AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1));
-                g_defcodelabel (Label);
-                AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs));
-                AddCodeLine ("sta (sp),y");
-                AddCodeLine ("dey");
-                AddCodeLine ("bpl %s", LocalLabelName (Label));
             } else {
-                AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
-                AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1));
-                g_defcodelabel (Label);
-                AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0));
-                AddCodeLine ("sta (sp),y");
-                AddCodeLine ("dey");
-                AddCodeLine ("dex");
-                AddCodeLine ("bpl %s", LocalLabelName (Label));
-            }
 
-        } else {
+                if (Offs == 0 || AllowOneIndex) {
+                    AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs));
+                    AddCodeLine ("sta (sp),y");
+                    AddCodeLine ("iny");
+                    AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal);
+                    AddCodeLine ("bne %s", LocalLabelName (Label));
+                } else {
+                    AddCodeLine ("ldx #$00");
+                    AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0));
+                    AddCodeLine ("sta (sp),y");
+                    AddCodeLine ("iny");
+                    AddCodeLine ("inx");
+                    AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal);
+                    AddCodeLine ("bne %s", LocalLabelName (Label));
+                }
 
-            if (Offs == 0 || AllowOneIndex) {
-                AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
-                g_defcodelabel (Label);
-                AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs));
-                AddCodeLine ("sta (sp),y");
-                AddCodeLine ("iny");
-                AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal);
-                AddCodeLine ("bne %s", LocalLabelName (Label));
-            } else {
-                AddCodeLine ("ldx #$00");
-                AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
-                g_defcodelabel (Label);
-                AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0));
-                AddCodeLine ("sta (sp),y");
-                AddCodeLine ("iny");
-                AddCodeLine ("inx");
-                AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal);
-                AddCodeLine ("bne %s", LocalLabelName (Label));
             }
 
+            /* memcpy returns the address, so the result is actually identical
+            ** to the first argument.
+            */
+            *Expr = Arg1.Expr;
+
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
         }
 
-        /* memcpy returns the address, so the result is actually identical
-        ** to the first argument.
-        */
-        *Expr = Arg1.Expr;
+        if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
+            ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) &&
+            (Arg2.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256 &&
+            ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) {
+
+            /* It is possible to just use one index register even if the stack
+            ** offset is not zero, by adjusting the offset to the constant
+            ** address accordingly. But we cannot do this if the data in
+            ** question is in the register space or at an absolute address less
+            ** than 256. Register space is zero page, which means that the
+            ** address calculation could overflow in the linker.
+            */
+            int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) &&
+                                !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256);
 
-    } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
-               ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) &&
-               (Arg2.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256 &&
-               ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) {
-
-        /* It is possible to just use one index register even if the stack
-        ** offset is not zero, by adjusting the offset to the constant
-        ** address accordingly. But we cannot do this if the data in
-        ** question is in the register space or at an absolute address less
-        ** than 256. Register space is zero page, which means that the
-        ** address calculation could overflow in the linker.
-        */
-        int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) &&
-                            !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256);
+            /* Calculate the real stack offset */
+            Offs = ED_GetStackOffs (&Arg2.Expr, 0);
+
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
+
+            /* We need a label */
+            Label = GetLocalLabel ();
+
+            /* Generate memcpy code */
+            if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) {
+
+                if (Offs == 0) {
+                    AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1));
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda (sp),y");
+                    AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
+                    AddCodeLine ("dey");
+                    AddCodeLine ("bpl %s", LocalLabelName (Label));
+                } else {
+                    AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
+                    AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1));
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda (sp),y");
+                    AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0));
+                    AddCodeLine ("dey");
+                    AddCodeLine ("dex");
+                    AddCodeLine ("bpl %s", LocalLabelName (Label));
+                }
+
+            } else {
+
+                if (Offs == 0 || AllowOneIndex) {
+                    AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda (sp),y");
+                    AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs));
+                    AddCodeLine ("iny");
+                    AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal);
+                    AddCodeLine ("bne %s", LocalLabelName (Label));
+                } else {
+                    AddCodeLine ("ldx #$00");
+                    AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
+                    g_defcodelabel (Label);
+                    AddCodeLine ("lda (sp),y");
+                    AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0));
+                    AddCodeLine ("iny");
+                    AddCodeLine ("inx");
+                    AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal);
+                    AddCodeLine ("bne %s", LocalLabelName (Label));
+                }
 
-        /* Calculate the real stack offset */
-        Offs = ED_GetStackOffs (&Arg2.Expr, 0);
+            }
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+            /* memcpy returns the address, so the result is actually identical
+            ** to the first argument.
+            */
+            *Expr = Arg1.Expr;
 
-        /* We need a label */
-        Label = GetLocalLabel ();
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
 
-        /* Generate memcpy code */
-        if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) {
+        if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256   &&
+            ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr)     &&
+            (Offs = ED_GetStackOffs (&Arg2.Expr, 0)) == 0) {
 
-            if (Offs == 0) {
+            /* Drop the generated code but leave the load of the first argument*/
+            RemoveCode (&Arg1.Push);
+
+            /* We need a label */
+            Label = GetLocalLabel ();
+
+            /* Generate memcpy code */
+            AddCodeLine ("sta ptr1");
+            AddCodeLine ("stx ptr1+1");
+            if (Arg3.Expr.IVal <= 127) {
                 AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1));
                 g_defcodelabel (Label);
                 AddCodeLine ("lda (sp),y");
-                AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
+                AddCodeLine ("sta (ptr1),y");
                 AddCodeLine ("dey");
                 AddCodeLine ("bpl %s", LocalLabelName (Label));
             } else {
-                AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
-                AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1));
+                AddCodeLine ("ldy #$00");
                 g_defcodelabel (Label);
                 AddCodeLine ("lda (sp),y");
-                AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0));
-                AddCodeLine ("dey");
-                AddCodeLine ("dex");
-                AddCodeLine ("bpl %s", LocalLabelName (Label));
-            }
-
-        } else {
-
-            if (Offs == 0 || AllowOneIndex) {
-                AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
-                g_defcodelabel (Label);
-                AddCodeLine ("lda (sp),y");
-                AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs));
+                AddCodeLine ("sta (ptr1),y");
                 AddCodeLine ("iny");
-                AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal);
-                AddCodeLine ("bne %s", LocalLabelName (Label));
-            } else {
-                AddCodeLine ("ldx #$00");
-                AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
-                g_defcodelabel (Label);
-                AddCodeLine ("lda (sp),y");
-                AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0));
-                AddCodeLine ("iny");
-                AddCodeLine ("inx");
-                AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal);
+                AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
                 AddCodeLine ("bne %s", LocalLabelName (Label));
             }
 
-        }
+            /* Reload result - X hasn't changed by the code above */
+            AddCodeLine ("lda ptr1");
 
-        /* memcpy returns the address, so the result is actually identical
-        ** to the first argument.
-        */
-        *Expr = Arg1.Expr;
-
-    } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256   &&
-               ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr)     &&
-               (Offs = ED_GetStackOffs (&Arg2.Expr, 0)) == 0) {
-
-        /* Drop the generated code but leave the load of the first argument*/
-        RemoveCode (&Arg1.Push);
+            /* The function result is an rvalue in the primary register */
+            ED_MakeRValExpr (Expr);
+            Expr->Type = GetFuncReturn (Expr->Type);
 
-        /* We need a label */
-        Label = GetLocalLabel ();
-
-        /* Generate memcpy code */
-        AddCodeLine ("sta ptr1");
-        AddCodeLine ("stx ptr1+1");
-        if (Arg3.Expr.IVal <= 127) {
-            AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1));
-            g_defcodelabel (Label);
-            AddCodeLine ("lda (sp),y");
-            AddCodeLine ("sta (ptr1),y");
-            AddCodeLine ("dey");
-            AddCodeLine ("bpl %s", LocalLabelName (Label));
-        } else {
-            AddCodeLine ("ldy #$00");
-            g_defcodelabel (Label);
-            AddCodeLine ("lda (sp),y");
-            AddCodeLine ("sta (ptr1),y");
-            AddCodeLine ("iny");
-            AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
-            AddCodeLine ("bne %s", LocalLabelName (Label));
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
         }
-
-        /* Reload result - X hasn't changed by the code above */
-        AddCodeLine ("lda ptr1");
-
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = GetFuncReturn (Expr->Type);
-
-    } else {
-
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = GetFuncReturn (Expr->Type);
-
     }
 
+    /* The function result is an rvalue in the primary register */
+    ED_MakeRValExpr (Expr);
+    Expr->Type = GetFuncReturn (Expr->Type);
+
 ExitPoint:
     /* We expect the closing brace */
     ConsumeRParen ();
@@ -595,140 +610,151 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
         goto ExitPoint;
     }
 
-    /* We've generated the complete code for the function now and know the
-    ** types of all parameters. Check for situations where better code can
-    ** be generated. If such a situation is detected, throw away the
-    ** generated, and emit better code.
-    ** Note: Lots of improvements would be possible here, but I will
-    ** concentrate on the most common case: memset with arguments 2 and 3
-    ** being constant numerical values. Some checks have shown that this
-    ** covers nearly 90% of all memset calls.
-    */
-    if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
-        ED_IsConstAbsInt (&Arg2.Expr) &&
-        ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
-         (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) {
+    if (IS_Get (&InlineStdFuncs)) {
 
-        int Reg = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr);
+        /* We've generated the complete code for the function now and know the
+        ** types of all parameters. Check for situations where better code can
+        ** be generated. If such a situation is detected, throw away the
+        ** generated, and emit better code.
+        ** Note: Lots of improvements would be possible here, but I will
+        ** concentrate on the most common case: memset with arguments 2 and 3
+        ** being constant numerical values. Some checks have shown that this
+        ** covers nearly 90% of all memset calls.
+        */
+        if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
+            ED_IsConstAbsInt (&Arg2.Expr) &&
+            ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
+             (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)))) {
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+            int Reg = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr);
 
-        /* We need a label */
-        Label = GetLocalLabel ();
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
 
-        /* Generate memset code */
-        if (Arg3.Expr.IVal <= 127) {
+            /* We need a label */
+            Label = GetLocalLabel ();
 
-            AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
-            AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
-            g_defcodelabel (Label);
-            if (Reg) {
-                AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
-            } else {
-                AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
-            }
-            AddCodeLine ("dey");
-            AddCodeLine ("bpl %s", LocalLabelName (Label));
+            /* Generate memset code */
+            if (Arg3.Expr.IVal <= 127) {
 
-        } else {
+                AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
+                AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
+                g_defcodelabel (Label);
+                if (Reg) {
+                    AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
+                } else {
+                    AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
+                }
+                AddCodeLine ("dey");
+                AddCodeLine ("bpl %s", LocalLabelName (Label));
 
-            AddCodeLine ("ldy #$00");
-            AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
-            g_defcodelabel (Label);
-            if (Reg) {
-                AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
             } else {
-                AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
-            }
-            AddCodeLine ("iny");
-            AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
-            AddCodeLine ("bne %s", LocalLabelName (Label));
 
-        }
-
-        /* memset returns the address, so the result is actually identical
-        ** to the first argument.
-        */
-        *Expr = Arg1.Expr;
-
-    } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
-               ED_IsConstAbsInt (&Arg2.Expr) &&
-               ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) &&
-               (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) {
-
-        /* Calculate the real stack offset */
-        int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
+                AddCodeLine ("ldy #$00");
+                AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
+                g_defcodelabel (Label);
+                if (Reg) {
+                    AddCodeLine ("sta (%s),y", ED_GetLabelName (&Arg1.Expr, 0));
+                } else {
+                    AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0));
+                }
+                AddCodeLine ("iny");
+                AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
+                AddCodeLine ("bne %s", LocalLabelName (Label));
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+            }
 
-        /* We need a label */
-        Label = GetLocalLabel ();
+            /* memset returns the address, so the result is actually identical
+            ** to the first argument.
+            */
+            *Expr = Arg1.Expr;
 
-        /* Generate memset code */
-        AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
-        AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
-        g_defcodelabel (Label);
-        AddCodeLine ("sta (sp),y");
-        AddCodeLine ("iny");
-        AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal);
-        AddCodeLine ("bne %s", LocalLabelName (Label));
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
 
-        /* memset returns the address, so the result is actually identical
-        ** to the first argument.
-        */
-        *Expr = Arg1.Expr;
+        if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
+            ED_IsConstAbsInt (&Arg2.Expr) &&
+            ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) &&
+            (Arg1.Expr.IVal - StackPtr) + Arg3.Expr.IVal < 256) {
 
-    } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
-               ED_IsConstAbsInt (&Arg2.Expr) &&
-               (Arg2.Expr.IVal != 0 || IS_Get (&CodeSizeFactor) > 200)) {
+            /* Calculate the real stack offset */
+            int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
 
-        /* Remove all of the generated code but the load of the first
-        ** argument.
-        */
-        RemoveCode (&Arg1.Push);
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
 
-        /* We need a label */
-        Label = GetLocalLabel ();
+            /* We need a label */
+            Label = GetLocalLabel ();
 
-        /* Generate code */
-        AddCodeLine ("sta ptr1");
-        AddCodeLine ("stx ptr1+1");
-        if (Arg3.Expr.IVal <= 127) {
-            AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
+            /* Generate memset code */
+            AddCodeLine ("ldy #$%02X", (unsigned char) Offs);
             AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
             g_defcodelabel (Label);
-            AddCodeLine ("sta (ptr1),y");
-            AddCodeLine ("dey");
-            AddCodeLine ("bpl %s", LocalLabelName (Label));
-        } else {
-            AddCodeLine ("ldy #$00");
-            AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
-            g_defcodelabel (Label);
-            AddCodeLine ("sta (ptr1),y");
+            AddCodeLine ("sta (sp),y");
             AddCodeLine ("iny");
-            AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
+            AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal);
             AddCodeLine ("bne %s", LocalLabelName (Label));
+
+            /* memset returns the address, so the result is actually identical
+            ** to the first argument.
+            */
+            *Expr = Arg1.Expr;
+
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
         }
 
-        /* Load the function result pointer into a/x (x is still valid). This
-        ** code will get removed by the optimizer if it is not used later.
-        */
-        AddCodeLine ("lda ptr1");
+        if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 &&
+            ED_IsConstAbsInt (&Arg2.Expr) &&
+            (Arg2.Expr.IVal != 0 || IS_Get (&CodeSizeFactor) > 200)) {
 
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = GetFuncReturn (Expr->Type);
+            /* Remove all of the generated code but the load of the first
+            ** argument.
+            */
+            RemoveCode (&Arg1.Push);
 
-    } else {
+            /* We need a label */
+            Label = GetLocalLabel ();
+
+            /* Generate code */
+            AddCodeLine ("sta ptr1");
+            AddCodeLine ("stx ptr1+1");
+            if (Arg3.Expr.IVal <= 127) {
+                AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal-1));
+                AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
+                g_defcodelabel (Label);
+                AddCodeLine ("sta (ptr1),y");
+                AddCodeLine ("dey");
+                AddCodeLine ("bpl %s", LocalLabelName (Label));
+            } else {
+                AddCodeLine ("ldy #$00");
+                AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal);
+                g_defcodelabel (Label);
+                AddCodeLine ("sta (ptr1),y");
+                AddCodeLine ("iny");
+                AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal);
+                AddCodeLine ("bne %s", LocalLabelName (Label));
+            }
 
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = GetFuncReturn (Expr->Type);
+            /* Load the function result pointer into a/x (x is still valid). This
+            ** code will get removed by the optimizer if it is not used later.
+            */
+            AddCodeLine ("lda ptr1");
+
+            /* The function result is an rvalue in the primary register */
+            ED_MakeRValExpr (Expr);
+            Expr->Type = GetFuncReturn (Expr->Type);
 
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
     }
 
+    /* The function result is an rvalue in the primary register */
+    ED_MakeRValExpr (Expr);
+    Expr->Type = GetFuncReturn (Expr->Type);
+
 ExitPoint:
     /* We expect the closing brace */
     ConsumeRParen ();
@@ -790,142 +816,142 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
         ECount1 = ECount2;
     }
 
-    /* If the second argument is the empty string literal, we can generate
-    ** more efficient code.
-    */
-    if (ED_IsLocLiteral (&Arg2.Expr) &&
-        IS_Get (&WritableStrings) == 0 &&
-        GetLiteralSize (Arg2.Expr.LVal) == 1 &&
-        GetLiteralStr (Arg2.Expr.LVal)[0] == '\0') {
+    if (IS_Get (&InlineStdFuncs)) {
 
-        /* Drop the generated code so we have the first argument in the
-        ** primary
+        /* If the second argument is the empty string literal, we can generate
+        ** more efficient code.
         */
-        RemoveCode (&Arg1.Push);
+        if (ED_IsLocLiteral (&Arg2.Expr) &&
+            IS_Get (&WritableStrings) == 0 &&
+            GetLiteralSize (Arg2.Expr.LVal) == 1 &&
+            GetLiteralStr (Arg2.Expr.LVal)[0] == '\0') {
 
-        /* We don't need the literal any longer */
-        ReleaseLiteral (Arg2.Expr.LVal);
-
-        /* We do now have Arg1 in the primary. Load the first character from
-        ** this string and cast to int. This is the function result.
-        */
-        IsArray = IsTypeArray (Arg1.Type) && ED_IsRVal (&Arg1.Expr);
-        if (IsArray && ED_IsLocStack (&Arg1.Expr) &&
-            (Offs = ED_GetStackOffs (&Arg1.Expr, 0) < 256)) {
-            /* Drop the generated code */
-            RemoveCode (&Arg1.Load);
+            /* Drop the generated code so we have the first argument in the
+            ** primary
+            */
+            RemoveCode (&Arg1.Push);
 
-            /* Generate code */
-            AddCodeLine ("ldy #$%02X", Offs);
-            AddCodeLine ("ldx #$00");
-            AddCodeLine ("lda (sp),y");
-        } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) {
-            /* Drop the generated code */
-            RemoveCode (&Arg1.Load);
+            /* We don't need the literal any longer */
+            ReleaseLiteral (Arg2.Expr.LVal);
 
-            /* Generate code */
-            AddCodeLine ("ldx #$00");
-            AddCodeLine ("lda %s", ED_GetLabelName (&Arg1.Expr, 0));
-        } else {
-            /* Drop part of the generated code so we have the first argument
-            ** in the primary
+            /* We do now have Arg1 in the primary. Load the first character from
+            ** this string and cast to int. This is the function result.
             */
-            RemoveCode (&Arg1.Push);
+            IsArray = IsTypeArray (Arg1.Type) && ED_IsRVal (&Arg1.Expr);
+            if (IsArray && ED_IsLocStack (&Arg1.Expr) &&
+                (Offs = ED_GetStackOffs (&Arg1.Expr, 0) < 256)) {
+                /* Drop the generated code */
+                RemoveCode (&Arg1.Load);
+
+                /* Generate code */
+                AddCodeLine ("ldy #$%02X", Offs);
+                AddCodeLine ("ldx #$00");
+                AddCodeLine ("lda (sp),y");
+            } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) {
+                /* Drop the generated code */
+                RemoveCode (&Arg1.Load);
 
-            /* Fetch the first char */
-            g_getind (CF_CHAR | CF_UNSIGNED, 0);
-        }
+                /* Generate code */
+                AddCodeLine ("ldx #$00");
+                AddCodeLine ("lda %s", ED_GetLabelName (&Arg1.Expr, 0));
+            } else {
+                /* Drop part of the generated code so we have the first argument
+                ** in the primary
+                */
+                RemoveCode (&Arg1.Push);
 
-    } else if ((IS_Get (&CodeSizeFactor) >= 165) &&
-               ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
-                (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
-               ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
-                (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) &&
-               (IS_Get (&InlineStdFuncs) || (ECount1 > 0 && ECount1 < 256))) {
+                /* Fetch the first char */
+                g_getind (CF_CHAR | CF_UNSIGNED, 0);
+            }
 
+        } else if ((IS_Get (&CodeSizeFactor) >= 165) &&
+                   ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
+                    (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
+                   ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
+                    (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) &&
+                   (IS_Get (&EagerlyInlineFuncs) || (ECount1 > 0 && ECount1 < 256))) {
 
-        unsigned    Entry, Loop, Fin;   /* Labels */
-        const char* Load;
-        const char* Compare;
+            unsigned    Entry, Loop, Fin;   /* Labels */
+            const char* Load;
+            const char* Compare;
 
-        if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) {
-            Load = "lda (%s),y";
-        } else {
-            Load = "lda %s,y";
-        }
-        if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) {
-            Compare = "cmp (%s),y";
-        } else {
-            Compare = "cmp %s,y";
-        }
+            if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) {
+                Load = "lda (%s),y";
+            } else {
+                Load = "lda %s,y";
+            }
+            if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) {
+                Compare = "cmp (%s),y";
+            } else {
+                Compare = "cmp %s,y";
+            }
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
-
-        /* We need labels */
-        Entry = GetLocalLabel ();
-        Loop  = GetLocalLabel ();
-        Fin   = GetLocalLabel ();
-
-        /* Generate strcmp code */
-        AddCodeLine ("ldy #$00");
-        AddCodeLine ("beq %s", LocalLabelName (Entry));
-        g_defcodelabel (Loop);
-        AddCodeLine ("tax");
-        AddCodeLine ("beq %s", LocalLabelName (Fin));
-        AddCodeLine ("iny");
-        g_defcodelabel (Entry);
-        AddCodeLine (Load, ED_GetLabelName (&Arg1.Expr, 0));
-        AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0));
-        AddCodeLine ("beq %s", LocalLabelName (Loop));
-        AddCodeLine ("ldx #$01");
-        AddCodeLine ("bcs %s", LocalLabelName (Fin));
-        AddCodeLine ("ldx #$FF");
-        g_defcodelabel (Fin);
-
-    } else if ((IS_Get (&CodeSizeFactor) > 190) &&
-               ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
-                (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
-               (IS_Get (&InlineStdFuncs) || (ECount1 > 0 && ECount1 < 256))) {
-
-
-        unsigned    Entry, Loop, Fin;   /* Labels */
-        const char* Compare;
-
-        if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) {
-            Compare = "cmp (%s),y";
-        } else {
-            Compare = "cmp %s,y";
-        }
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Push);
+            /* We need labels */
+            Entry = GetLocalLabel ();
+            Loop  = GetLocalLabel ();
+            Fin   = GetLocalLabel ();
+
+            /* Generate strcmp code */
+            AddCodeLine ("ldy #$00");
+            AddCodeLine ("beq %s", LocalLabelName (Entry));
+            g_defcodelabel (Loop);
+            AddCodeLine ("tax");
+            AddCodeLine ("beq %s", LocalLabelName (Fin));
+            AddCodeLine ("iny");
+            g_defcodelabel (Entry);
+            AddCodeLine (Load, ED_GetLabelName (&Arg1.Expr, 0));
+            AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0));
+            AddCodeLine ("beq %s", LocalLabelName (Loop));
+            AddCodeLine ("ldx #$01");
+            AddCodeLine ("bcs %s", LocalLabelName (Fin));
+            AddCodeLine ("ldx #$FF");
+            g_defcodelabel (Fin);
+
+        } else if ((IS_Get (&CodeSizeFactor) > 190) &&
+                   ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
+                    (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
+                   (IS_Get (&EagerlyInlineFuncs) || (ECount1 > 0 && ECount1 < 256))) {
 
-        /* We need labels */
-        Entry = GetLocalLabel ();
-        Loop  = GetLocalLabel ();
-        Fin   = GetLocalLabel ();
-
-        /* Store Arg1 into ptr1 */
-        AddCodeLine ("sta ptr1");
-        AddCodeLine ("stx ptr1+1");
-
-        /* Generate strcmp code */
-        AddCodeLine ("ldy #$00");
-        AddCodeLine ("beq %s", LocalLabelName (Entry));
-        g_defcodelabel (Loop);
-        AddCodeLine ("tax");
-        AddCodeLine ("beq %s", LocalLabelName (Fin));
-        AddCodeLine ("iny");
-        g_defcodelabel (Entry);
-        AddCodeLine ("lda (ptr1),y");
-        AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0));
-        AddCodeLine ("beq %s", LocalLabelName (Loop));
-        AddCodeLine ("ldx #$01");
-        AddCodeLine ("bcs %s", LocalLabelName (Fin));
-        AddCodeLine ("ldx #$FF");
-        g_defcodelabel (Fin);
+            unsigned    Entry, Loop, Fin;   /* Labels */
+            const char* Compare;
 
+            if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) {
+                Compare = "cmp (%s),y";
+            } else {
+                Compare = "cmp %s,y";
+            }
+
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Push);
+
+            /* We need labels */
+            Entry = GetLocalLabel ();
+            Loop  = GetLocalLabel ();
+            Fin   = GetLocalLabel ();
+
+            /* Store Arg1 into ptr1 */
+            AddCodeLine ("sta ptr1");
+            AddCodeLine ("stx ptr1+1");
+
+            /* Generate strcmp code */
+            AddCodeLine ("ldy #$00");
+            AddCodeLine ("beq %s", LocalLabelName (Entry));
+            g_defcodelabel (Loop);
+            AddCodeLine ("tax");
+            AddCodeLine ("beq %s", LocalLabelName (Fin));
+            AddCodeLine ("iny");
+            g_defcodelabel (Entry);
+            AddCodeLine ("lda (ptr1),y");
+            AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0));
+            AddCodeLine ("beq %s", LocalLabelName (Loop));
+            AddCodeLine ("ldx #$01");
+            AddCodeLine ("bcs %s", LocalLabelName (Fin));
+            AddCodeLine ("ldx #$FF");
+            g_defcodelabel (Fin);
+        }
     }
 
     /* The function result is an rvalue in the primary register */
@@ -983,142 +1009,154 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
     /* Get the element count of argument 1 if it is an array */
     ECount = ArrayElementCount (&Arg1);
 
-    /* We've generated the complete code for the function now and know the
-    ** types of all parameters. Check for situations where better code can
-    ** be generated. If such a situation is detected, throw away the
-    ** generated, and emit better code.
-    */
-    if (((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
-         (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
-        ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
-         (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) &&
-        (IS_Get (&InlineStdFuncs) ||
-        (ECount != UNSPECIFIED && ECount < 256))) {
-
-        const char* Load;
-        const char* Store;
-        if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) {
-            Load = "lda (%s),y";
-        } else {
-            Load = "lda %s,y";
-        }
-        if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) {
-            Store = "sta (%s),y";
-        } else {
-            Store = "sta %s,y";
-        }
+    if (IS_Get (&InlineStdFuncs)) {
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+        /* We've generated the complete code for the function now and know the
+        ** types of all parameters. Check for situations where better code can
+        ** be generated. If such a situation is detected, throw away the
+        ** generated, and emit better code.
+        */
+        if (((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) ||
+             (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) &&
+            ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) ||
+             (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) &&
+            (IS_Get (&EagerlyInlineFuncs) ||
+            (ECount != UNSPECIFIED && ECount < 256))) {
+
+            const char* Load;
+            const char* Store;
+            if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) {
+                Load = "lda (%s),y";
+            } else {
+                Load = "lda %s,y";
+            }
+            if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) {
+                Store = "sta (%s),y";
+            } else {
+                Store = "sta %s,y";
+            }
 
-        /* We need labels */
-        L1 = GetLocalLabel ();
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
 
-        /* Generate strcpy code */
-        AddCodeLine ("ldy #$FF");
-        g_defcodelabel (L1);
-        AddCodeLine ("iny");
-        AddCodeLine (Load, ED_GetLabelName (&Arg2.Expr, 0));
-        AddCodeLine (Store, ED_GetLabelName (&Arg1.Expr, 0));
-        AddCodeLine ("bne %s", LocalLabelName (L1));
+            /* We need labels */
+            L1 = GetLocalLabel ();
 
-        /* strcpy returns argument #1 */
-        *Expr = Arg1.Expr;
+            /* Generate strcpy code */
+            AddCodeLine ("ldy #$FF");
+            g_defcodelabel (L1);
+            AddCodeLine ("iny");
+            AddCodeLine (Load, ED_GetLabelName (&Arg2.Expr, 0));
+            AddCodeLine (Store, ED_GetLabelName (&Arg1.Expr, 0));
+            AddCodeLine ("bne %s", LocalLabelName (L1));
 
-    } else if (ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) &&
-               StackPtr >= -255 &&
-               ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) {
+            /* strcpy returns argument #1 */
+            *Expr = Arg1.Expr;
 
-        /* It is possible to just use one index register even if the stack
-        ** offset is not zero, by adjusting the offset to the constant
-        ** address accordingly. But we cannot do this if the data in
-        ** question is in the register space or at an absolute address less
-        ** than 256. Register space is zero page, which means that the
-        ** address calculation could overflow in the linker.
-        */
-        int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) &&
-                            !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256);
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
 
-        /* Calculate the real stack offset */
-        int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
+        if (ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) &&
+            StackPtr >= -255 &&
+            ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) {
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+            /* It is possible to just use one index register even if the stack
+            ** offset is not zero, by adjusting the offset to the constant
+            ** address accordingly. But we cannot do this if the data in
+            ** question is in the register space or at an absolute address less
+            ** than 256. Register space is zero page, which means that the
+            ** address calculation could overflow in the linker.
+            */
+            int AllowOneIndex = !ED_IsLocRegister (&Arg1.Expr) &&
+                                !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256);
 
-        /* We need labels */
-        L1 = GetLocalLabel ();
+            /* Calculate the real stack offset */
+            int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
 
-        /* Generate strcpy code */
-        AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1));
-        if (Offs == 0 || AllowOneIndex) {
-            g_defcodelabel (L1);
-            AddCodeLine ("iny");
-            AddCodeLine ("lda (sp),y");
-            AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs));
-        } else {
-            AddCodeLine ("ldx #$FF");
-            g_defcodelabel (L1);
-            AddCodeLine ("iny");
-            AddCodeLine ("inx");
-            AddCodeLine ("lda (sp),y");
-            AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0));
-        }
-        AddCodeLine ("bne %s", LocalLabelName (L1));
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
 
-        /* strcpy returns argument #1 */
-        *Expr = Arg1.Expr;
+            /* We need labels */
+            L1 = GetLocalLabel ();
 
-    } else if (ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) &&
-               ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) &&
-               StackPtr >= -255) {
+            /* Generate strcpy code */
+            AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1));
+            if (Offs == 0 || AllowOneIndex) {
+                g_defcodelabel (L1);
+                AddCodeLine ("iny");
+                AddCodeLine ("lda (sp),y");
+                AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs));
+            } else {
+                AddCodeLine ("ldx #$FF");
+                g_defcodelabel (L1);
+                AddCodeLine ("iny");
+                AddCodeLine ("inx");
+                AddCodeLine ("lda (sp),y");
+                AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0));
+            }
+            AddCodeLine ("bne %s", LocalLabelName (L1));
 
-        /* It is possible to just use one index register even if the stack
-        ** offset is not zero, by adjusting the offset to the constant
-        ** address accordingly. But we cannot do this if the data in
-        ** question is in the register space or at an absolute address less
-        ** than 256. Register space is zero page, which means that the
-        ** address calculation could overflow in the linker.
-        */
-        int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) &&
-                            !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256);
+            /* strcpy returns argument #1 */
+            *Expr = Arg1.Expr;
 
-        /* Calculate the real stack offset */
-        int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
 
-        /* Drop the generated code */
-        RemoveCode (&Arg1.Expr.Start);
+        if (ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr) &&
+            ED_IsRVal (&Arg1.Expr) && ED_IsLocStack (&Arg1.Expr) &&
+            StackPtr >= -255) {
 
-        /* We need labels */
-        L1 = GetLocalLabel ();
+            /* It is possible to just use one index register even if the stack
+            ** offset is not zero, by adjusting the offset to the constant
+            ** address accordingly. But we cannot do this if the data in
+            ** question is in the register space or at an absolute address less
+            ** than 256. Register space is zero page, which means that the
+            ** address calculation could overflow in the linker.
+            */
+            int AllowOneIndex = !ED_IsLocRegister (&Arg2.Expr) &&
+                                !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256);
 
-        /* Generate strcpy code */
-        AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1));
-        if (Offs == 0 || AllowOneIndex) {
-            g_defcodelabel (L1);
-            AddCodeLine ("iny");
-            AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs));
-            AddCodeLine ("sta (sp),y");
-        } else {
-            AddCodeLine ("ldx #$FF");
-            g_defcodelabel (L1);
-            AddCodeLine ("iny");
-            AddCodeLine ("inx");
-            AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0));
-            AddCodeLine ("sta (sp),y");
-        }
-        AddCodeLine ("bne %s", LocalLabelName (L1));
+            /* Calculate the real stack offset */
+            int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
 
-        /* strcpy returns argument #1 */
-        *Expr = Arg1.Expr;
+            /* Drop the generated code */
+            RemoveCode (&Arg1.Expr.Start);
 
-    } else {
+            /* We need labels */
+            L1 = GetLocalLabel ();
+
+            /* Generate strcpy code */
+            AddCodeLine ("ldy #$%02X", (unsigned char) (Offs - 1));
+            if (Offs == 0 || AllowOneIndex) {
+                g_defcodelabel (L1);
+                AddCodeLine ("iny");
+                AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs));
+                AddCodeLine ("sta (sp),y");
+            } else {
+                AddCodeLine ("ldx #$FF");
+                g_defcodelabel (L1);
+                AddCodeLine ("iny");
+                AddCodeLine ("inx");
+                AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0));
+                AddCodeLine ("sta (sp),y");
+            }
+            AddCodeLine ("bne %s", LocalLabelName (L1));
 
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = GetFuncReturn (Expr->Type);
+            /* strcpy returns argument #1 */
+            *Expr = Arg1.Expr;
 
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
     }
 
+    /* The function result is an rvalue in the primary register */
+    ED_MakeRValExpr (Expr);
+    Expr->Type = GetFuncReturn (Expr->Type);
+
+ExitPoint:
     /* We expect the closing brace */
     ConsumeRParen ();
 }
@@ -1142,8 +1180,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
     long        ECount;
     unsigned    L;
 
-
-
     /* Setup the argument type string */
     ArgType[1].C = GetDefaultChar () | T_QUAL_CONST;
 
@@ -1175,125 +1211,148 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
     /* Do type conversion */
     TypeConversion (&Arg, ArgType);
 
-    /* If the expression is a literal, and if string literals are read
-    ** only, we can calculate the length of the string and remove it
-    ** from the literal pool. Otherwise we have to calculate the length
-    ** at runtime.
-    */
-    if (ED_IsLocLiteral (&Arg) && IS_Get (&WritableStrings) == 0) {
+    if (IS_Get (&Optimize)) {
 
-        /* Constant string literal */
-        ED_MakeConstAbs (Expr, GetLiteralSize (Arg.LVal) - 1, type_size_t);
+        /* If the expression is a literal, and if string literals are read
+        ** only, we can calculate the length of the string and remove it
+        ** from the literal pool. Otherwise we have to calculate the length
+        ** at runtime.
+        */
+        if (ED_IsLocLiteral (&Arg) && IS_Get (&WritableStrings) == 0) {
 
-        /* We don't need the literal any longer */
-        ReleaseLiteral (Arg.LVal);
+            /* Constant string literal */
+            ED_MakeConstAbs (Expr, GetLiteralSize (Arg.LVal) - 1, type_size_t);
 
-    /* We will inline strlen for arrays with constant addresses, if either the
-    ** inlining was forced on the command line, or the array is smaller than
-    ** 256, so the inlining is considered safe.
-    */
-    } else if (ED_IsLocConst (&Arg) && IsArray &&
-               (IS_Get (&InlineStdFuncs) || IsByteIndex)) {
-
-        /* Generate the strlen code */
-        L = GetLocalLabel ();
-        AddCodeLine ("ldy #$FF");
-        g_defcodelabel (L);
-        AddCodeLine ("iny");
-        AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg, 0));
-        AddCodeLine ("bne %s", LocalLabelName (L));
-        AddCodeLine ("tax");
-        AddCodeLine ("tya");
-
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = type_size_t;
-
-    /* We will inline strlen for arrays on the stack, if the array is
-    ** completely within the reach of a byte sized index register.
-    */
-    } else if (ED_IsLocStack (&Arg) && IsArray && IsByteIndex &&
-               (Arg.IVal - StackPtr) + ECount < 256) {
-
-        /* Calculate the true stack offset */
-        int Offs = ED_GetStackOffs (&Arg, 0);
-
-        /* Generate the strlen code */
-        L = GetLocalLabel ();
-        AddCodeLine ("ldx #$FF");
-        AddCodeLine ("ldy #$%02X", (unsigned char) (Offs-1));
-        g_defcodelabel (L);
-        AddCodeLine ("inx");
-        AddCodeLine ("iny");
-        AddCodeLine ("lda (sp),y");
-        AddCodeLine ("bne %s", LocalLabelName (L));
-        AddCodeLine ("txa");
-        AddCodeLine ("ldx #$00");
-
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = type_size_t;
-
-    /* strlen for a string that is pointed to by a register variable will only
-    ** get inlined if requested on the command line, since we cannot know how
-    ** big the buffer actually is, so inlining is not always safe.
-    */
-    } else if (ED_IsLocRegister (&Arg) && ED_IsLVal (&Arg) && IsPtr &&
-               IS_Get (&InlineStdFuncs)) {
-
-        /* Generate the strlen code */
-        L = GetLocalLabel ();
-        AddCodeLine ("ldy #$FF");
-        g_defcodelabel (L);
-        AddCodeLine ("iny");
-        AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg, 0));
-        AddCodeLine ("bne %s", LocalLabelName (L));
-        AddCodeLine ("tax");
-        AddCodeLine ("tya");
-
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = type_size_t;
-
-    /* Last check: We will inline a generic strlen routine if inlining was
-    ** requested on the command line, and the code size factor is more than
-    ** 400 (code is 13 bytes vs. 3 for a jsr call).
-    */
-    } else if (IS_Get (&CodeSizeFactor) > 400 && IS_Get (&InlineStdFuncs)) {
-
-        /* Load the expression into the primary */
-        LoadExpr (CF_NONE, &Arg);
-
-        /* Inline the function */
-        L = GetLocalLabel ();
-        AddCodeLine ("sta ptr1");
-        AddCodeLine ("stx ptr1+1");
-        AddCodeLine ("ldy #$FF");
-        g_defcodelabel (L);
-        AddCodeLine ("iny");
-        AddCodeLine ("lda (ptr1),y");
-        AddCodeLine ("bne %s", LocalLabelName (L));
-        AddCodeLine ("tax");
-        AddCodeLine ("tya");
-
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = type_size_t;
+            /* We don't need the literal any longer */
+            ReleaseLiteral (Arg.LVal);
 
-    } else {
+            /* Bail out, no need for further improvements */
+            goto ExitPoint;
+        }
+    }
+
+    if (IS_Get (&InlineStdFuncs)) {
+
+        /* We will inline strlen for arrays with constant addresses, if either
+        ** requested on the command line, or the array is smaller than 256,
+        ** so the inlining is considered safe.
+        */
+        if (ED_IsLocConst (&Arg) && IsArray &&
+            (IS_Get (&EagerlyInlineFuncs) || IsByteIndex)) {
+
+            /* Generate the strlen code */
+            L = GetLocalLabel ();
+            AddCodeLine ("ldy #$FF");
+            g_defcodelabel (L);
+            AddCodeLine ("iny");
+            AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg, 0));
+            AddCodeLine ("bne %s", LocalLabelName (L));
+            AddCodeLine ("tax");
+            AddCodeLine ("tya");
+
+            /* The function result is an rvalue in the primary register */
+            ED_MakeRValExpr (Expr);
+            Expr->Type = type_size_t;
+
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
+
+        /* We will inline strlen for arrays on the stack, if the array is
+        ** completely within the reach of a byte sized index register.
+        */
+        if (ED_IsLocStack (&Arg) && IsArray && IsByteIndex &&
+            (Arg.IVal - StackPtr) + ECount < 256) {
+
+            /* Calculate the true stack offset */
+            int Offs = ED_GetStackOffs (&Arg, 0);
+
+            /* Generate the strlen code */
+            L = GetLocalLabel ();
+            AddCodeLine ("ldx #$FF");
+            AddCodeLine ("ldy #$%02X", (unsigned char) (Offs-1));
+            g_defcodelabel (L);
+            AddCodeLine ("inx");
+            AddCodeLine ("iny");
+            AddCodeLine ("lda (sp),y");
+            AddCodeLine ("bne %s", LocalLabelName (L));
+            AddCodeLine ("txa");
+            AddCodeLine ("ldx #$00");
+
+            /* The function result is an rvalue in the primary register */
+            ED_MakeRValExpr (Expr);
+            Expr->Type = type_size_t;
+
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
 
-        /* Load the expression into the primary */
-        LoadExpr (CF_NONE, &Arg);
+        /* strlen for a string that is pointed to by a register variable will only
+        ** get inlined if requested on the command line, since we cannot know how
+        ** big the buffer actually is, so inlining is not always safe.
+        */
+        if (ED_IsLocRegister (&Arg) && ED_IsLVal (&Arg) && IsPtr &&
+            IS_Get (&EagerlyInlineFuncs)) {
 
-        /* Call the strlen function */
-        AddCodeLine ("jsr _%s", Func_strlen);
+            /* Generate the strlen code */
+            L = GetLocalLabel ();
+            AddCodeLine ("ldy #$FF");
+            g_defcodelabel (L);
+            AddCodeLine ("iny");
+            AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg, 0));
+            AddCodeLine ("bne %s", LocalLabelName (L));
+            AddCodeLine ("tax");
+            AddCodeLine ("tya");
+
+            /* The function result is an rvalue in the primary register */
+            ED_MakeRValExpr (Expr);
+            Expr->Type = type_size_t;
+
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
+
+        /* Last check: We will inline a generic strlen routine if inlining was
+        ** requested on the command line, and the code size factor is more than
+        ** 400 (code is 13 bytes vs. 3 for a jsr call).
+        */
+        if (IS_Get (&CodeSizeFactor) > 400 && IS_Get (&EagerlyInlineFuncs)) {
 
-        /* The function result is an rvalue in the primary register */
-        ED_MakeRValExpr (Expr);
-        Expr->Type = type_size_t;
+            /* Load the expression into the primary */
+            LoadExpr (CF_NONE, &Arg);
 
+            /* Inline the function */
+            L = GetLocalLabel ();
+            AddCodeLine ("sta ptr1");
+            AddCodeLine ("stx ptr1+1");
+            AddCodeLine ("ldy #$FF");
+            g_defcodelabel (L);
+            AddCodeLine ("iny");
+            AddCodeLine ("lda (ptr1),y");
+            AddCodeLine ("bne %s", LocalLabelName (L));
+            AddCodeLine ("tax");
+            AddCodeLine ("tya");
+
+            /* The function result is an rvalue in the primary register */
+            ED_MakeRValExpr (Expr);
+            Expr->Type = type_size_t;
+
+            /* Bail out, no need for further processing */
+            goto ExitPoint;
+        }
     }
 
+    /* Load the expression into the primary */
+    LoadExpr (CF_NONE, &Arg);
+
+    /* Call the strlen function */
+    AddCodeLine ("jsr _%s", Func_strlen);
+
+    /* The function result is an rvalue in the primary register */
+    ED_MakeRValExpr (Expr);
+    Expr->Type = type_size_t;
+
+ExitPoint:
     /* We expect the closing brace */
     ConsumeRParen ();
 }