/*
** ppc.library emulation
** (c)1998-99 Frank Wille <frank@phoenix.owl.de>
**
** M68k inlines
**
** V0.5d (05.04.1999) phx
**       _head(), _headsucc(), _tail().
** V0.5  (24.01.1999) phx
**       Check for zero-length in _memset() and _memcpy().
**       Rewrote _memset().
** V0.4c (21.01.1999) phx
**       _strncat(), _newlist(), _remhead(), _addhead().
** V0.1  (15.11.1998) phx
**       First partially working ppc.library emulation. Synchronous PPC
**       tasks, started by runelf, which only use the basic PowerUp kernel
**       functions for I/O, memory and context-switch seem to work fine.
** V0.0  (14.11.1998) phx
**       created
*/

#ifndef INLINE68K_H
#define INLINE68K_H

/* common inline functions */
void _memset(__reg("a0")void *,__reg("d0")unsigned long,
             __reg("d1")unsigned char) =
        "\ttst.l\td0\n"
        "\tbeq.b\t*+6\n"
        "\tmove.b\td1,(a0)+\n"
        "\tsubq.l\t#1,d0\n"
        "\tbne.b\t*-6";

void _memcpy(__reg("a0")void *,__reg("a1")void *,__reg("d0")unsigned long) =
        "\ttst.l\td0\n"
        "\tbeq.b\t*+6\n"
        "\tmove.b\t(a1)+,(a0)+\n"
        "\tsubq.l\t#1,d0\n"
        "\tbne.b\t*-6";

int _strlen(__reg("a0")char *) =
        "\tmoveq\t#-1,d0\n"
        "\ttst.b\t(a0)+\n"
        "\tdbeq\td0,*-4\n"
        "\tnot.l\td0";

char *_strcpy(__reg("a0") char *, __reg("a1") const char *) =
        "\tmove.l\ta0,d0\n"
        "\tmove.b\t(a1)+,(a0)+\n"
        "\tbne.b\t*-4";

char *_strncpy(__reg("a0") char *, __reg("a1") const char *,
               __reg("d1") int) =
        "\tmove.l\ta0,d0\n"
        "\tbra.b\t*+4\n"
        "\tmove.b\t(a1)+,(a0)+\n"
        "\tbeq.b\t*+4\n"
        "\tsubq.l\t#1,d1\n"
        "\tbpl.b\t*-8";

int _strcmp(__reg("a0") const char *, __reg("a1") const char *) =
        "\tmove.b\t(a0)+,d0\n"
        "\tbeq.b\t*+6\n"
        "\tsub.b\t(a1)+,d0\n"
        "\tbeq.b\t*-8\n"
        "\tbra.b\t*+2\n"
        "\tsub.b\t(a1),d0\n"
        "\textb.l\td0";

int _strncmp(__reg("a0") const char *, __reg("a1") const char *,
             __reg("d1") int) =
        "\tmoveq\t#0,d0\n"
        "\tsubq.l\t#1,d1\n"
        "\tbmi.b\t*+12\n"
        "\tmove.b\t(a0)+,d0\n"
        "\tbeq.b\t*+6\n"
        "\tsub.b\t(a1)+,d0\n"
        "\tbeq.b\t*-12\n"
        "\tbra.b\t*+2\n"
        "\tsub.b\t(a1),d0\n"
        "\textb.l\td0";

char *_strncat(__reg("a0") const char *, __reg("a1") const char *,
             __reg("d1") int) =         /* n=65536 is maximum! */
        "\tmove.l\ta0,d0\n"
        "\tsubq.l\t#1,d1\n"
        "\tbmi.b\t*+12\n"
        "\ttst.b\t(a0)+\n"
        "\tbne.b\t*-4\n"
        "\tsubq.l\t#1,a0\n"
        "\tmove.b\t(a1)+,(a0)+\n"
        "\tdbeq\td1,*-4";

void _newlist(__reg("a0") void *) =
        "\tmove.l\ta0,8(a0)\n"
        "\taddq.l\t#4,a0\n"
        "\tclr.l\t(a0)\n"
        "\tmove.l\ta0,-(a0)";

void _addhead(__reg("a0") void *, __reg("a1") void *) =
        "\tmove.l\t(a0),d0\n"
        "\tmove.l\ta1,(a0)\n"
        "\tmovem.l\td0/a0,(a1)\n"
        "\tmove.l\td0,a0\n"
        "\tmove.l\ta1,4(a0)";

void _addtail(__reg("a0") void *, __reg("a1") void *) =
        "\taddq.l\t#4,a0\n"
        "\tmove.l\t4(a0),d0\n"
        "\tmove.l\ta1,4(a0)\n"
        "\texg\td0,a0\n"
        "\tmovem.l\td0/a0,(a1)\n"
        "\tmove.l\ta1,(a0)";

void *_head(__reg("a0") void *) =
        "\tmove.l\t(a0)+,d0\n"
        "\tcmp.l\td0,a0\n"
        "\tbne.b\t*+2\n"
        "\tmoveq\t#0,d0\n"
        ";=barrier";

void *_headsucc(__reg("a0") void *) =
        "\tmove.l\t(a0)+,a1\n"
        "\tmove.l\t(a1),d0\n"
        "\tbeq.b\t*+6\n"
        "\tcmp.l\td0,a0\n"
        "\tbne.b\t*+2\n"
        "\tmoveq\t#0,d0\n"
        ";=barrier";

void *_remhead(__reg("a0") void *) =
        "\tmove.l\t(a0),a1\n"
        "\tmove.l\t(a1),d0\n"
        "\tbeq.b\t*+8\n"
        "\tmove.l\td0,(a0)\n"
        "\texg\td0,a1\n"
        "\tmove.l\ta0,4(a1)\n"
        ";=barrier";

void *_tail(__reg("a0") void *) =
        "\tmove.l\t8(a0),d0\n"
        "\tcmp.l\td0,a0\n"
        "\tbne.b\t*+2\n"
        "\tmoveq\t#0,d0\n"
        ";=barrier";

void _remove(__reg("a1") void *) =
        "\tmove.l\t(a1)+,a0\n"
        "\tmove.l\t(a1),a1\n"
        "\tmove.l\ta0,(a1)\n"
        "\tmove.l\ta1,4(a0)";

ULONG _callhook(__reg("a0")struct Hook *,__reg("a2")APTR,__reg("a1")APTR) =
        "\tjsr\t([8,a0])";


#endif /* INLINE68K_H */
