/*****************************************************************************/
/* */
-/* stdfunc.c */
+/* stdfunc.c */
/* */
-/* Handle inlining of known functions for the cc65 compiler */
+/* Handle inlining of known functions for the cc65 compiler */
/* */
/* */
/* */
/*****************************************************************************/
-/* Function forwards */
+/* Function forwards */
/*****************************************************************************/
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
* alphabetically!
*/
static struct StdFuncDesc {
- const char* Name;
- void (*Handler) (FuncDesc*, ExprDesc*);
+ const char* Name;
+ void (*Handler) (FuncDesc*, ExprDesc*);
} StdFuncs[] = {
- { "memcpy", StdFunc_memcpy },
- { "memset", StdFunc_memset },
- { "strcmp", StdFunc_strcmp },
- { "strcpy", StdFunc_strcpy },
- { "strlen", StdFunc_strlen },
+ { "memcpy", StdFunc_memcpy },
+ { "memset", StdFunc_memset },
+ { "strcmp", StdFunc_strcmp },
+ { "strcpy", StdFunc_strcpy },
+ { "strlen", StdFunc_strlen },
};
-#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0]))
+#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0]))
typedef struct ArgDesc ArgDesc;
struct ArgDesc {
/*****************************************************************************/
-/* Helper functions */
+/* Helper functions */
/*****************************************************************************/
ArgDesc Arg1, Arg2, Arg3;
unsigned ParamSize = 0;
unsigned Label;
+ int Offs;
/* Argument #1 */
ParseArg (&Arg1, Arg1Type);
!(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256);
/* Calculate the real stack offset */
- int Offs = ED_GetStackOffs (&Arg1.Expr, 0);
+ Offs = ED_GetStackOffs (&Arg1.Expr, 0);
/* Drop the generated code */
RemoveCode (&Arg1.Expr.Start);
!(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256);
/* Calculate the real stack offset */
- int Offs = ED_GetStackOffs (&Arg2.Expr, 0);
+ Offs = ED_GetStackOffs (&Arg2.Expr, 0);
/* Drop the generated code */
RemoveCode (&Arg1.Expr.Start);
*/
*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);
+
+ /* 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");
+ AddCodeLine ("cpy #$%02X", (unsigned char) Arg3.Expr.IVal);
+ AddCodeLine ("bne %s", LocalLabelName (Label));
+ }
+
+ /* 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 */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/