1*272efad7SDavid du ColombierTEXT memcpy(SB), $0 2*272efad7SDavid du Colombier MOVQ RARG, DI 3*272efad7SDavid du Colombier MOVQ DI, AX /* return value */ 4*272efad7SDavid du Colombier MOVQ p2+8(FP), SI 5*272efad7SDavid du Colombier MOVL n+16(FP), BX 6*272efad7SDavid du Colombier CMPL BX, $0 7*272efad7SDavid du Colombier JGT _ok 8*272efad7SDavid du Colombier JEQ _return /* nothing to do if n == 0 */ 9*272efad7SDavid du Colombier MOVL $0, SI /* fault if n < 0 */ 10*272efad7SDavid du Colombier 11*272efad7SDavid du Colombier/* 12*272efad7SDavid du Colombier * check and set for backwards: 13*272efad7SDavid du Colombier * (p2 < p1) && ((p2+n) > p1) 14*272efad7SDavid du Colombier */ 15*272efad7SDavid du Colombier_ok: 16*272efad7SDavid du Colombier CMPQ SI, DI 17*272efad7SDavid du Colombier JGT _forward 18*272efad7SDavid du Colombier JEQ _return /* nothing to do if p2 == p1 */ 19*272efad7SDavid du Colombier MOVQ SI, DX 20*272efad7SDavid du Colombier ADDQ BX, DX 21*272efad7SDavid du Colombier CMPQ DX, DI 22*272efad7SDavid du Colombier JGT _back 23*272efad7SDavid du Colombier 24*272efad7SDavid du Colombier/* 25*272efad7SDavid du Colombier * copy whole longs if aligned 26*272efad7SDavid du Colombier */ 27*272efad7SDavid du Colombier_forward: 28*272efad7SDavid du Colombier CLD 29*272efad7SDavid du Colombier MOVQ SI, DX 30*272efad7SDavid du Colombier ORQ DI, DX 31*272efad7SDavid du Colombier ANDL $3, DX 32*272efad7SDavid du Colombier JNE c3f 33*272efad7SDavid du Colombier MOVQ BX, CX 34*272efad7SDavid du Colombier SHRQ $2, CX 35*272efad7SDavid du Colombier ANDL $3, BX 36*272efad7SDavid du Colombier REP; MOVSL 37*272efad7SDavid du Colombier 38*272efad7SDavid du Colombier/* 39*272efad7SDavid du Colombier * copy the rest, by bytes 40*272efad7SDavid du Colombier */ 41*272efad7SDavid du Colombier JEQ _return /* flags set by above ANDL */ 42*272efad7SDavid du Colombierc3f: 43*272efad7SDavid du Colombier MOVL BX, CX 44*272efad7SDavid du Colombier REP; MOVSB 45*272efad7SDavid du Colombier 46*272efad7SDavid du Colombier RET 47*272efad7SDavid du Colombier 48*272efad7SDavid du Colombier/* 49*272efad7SDavid du Colombier * whole thing backwards has 50*272efad7SDavid du Colombier * adjusted addresses 51*272efad7SDavid du Colombier */ 52*272efad7SDavid du Colombier_back: 53*272efad7SDavid du Colombier ADDQ BX, DI 54*272efad7SDavid du Colombier ADDQ BX, SI 55*272efad7SDavid du Colombier STD 56*272efad7SDavid du Colombier SUBQ $4, DI 57*272efad7SDavid du Colombier SUBQ $4, SI 58*272efad7SDavid du Colombier/* 59*272efad7SDavid du Colombier * copy whole longs, if aligned 60*272efad7SDavid du Colombier */ 61*272efad7SDavid du Colombier MOVQ DI, DX 62*272efad7SDavid du Colombier ORQ SI, DX 63*272efad7SDavid du Colombier ANDL $3, DX 64*272efad7SDavid du Colombier JNE c3b 65*272efad7SDavid du Colombier MOVL BX, CX 66*272efad7SDavid du Colombier SHRQ $2, CX 67*272efad7SDavid du Colombier ANDL $3, BX 68*272efad7SDavid du Colombier REP; MOVSL 69*272efad7SDavid du Colombier/* 70*272efad7SDavid du Colombier * copy the rest, by bytes 71*272efad7SDavid du Colombier */ 72*272efad7SDavid du Colombier JEQ _return /* flags set by above ANDL */ 73*272efad7SDavid du Colombier 74*272efad7SDavid du Colombierc3b: 75*272efad7SDavid du Colombier ADDQ $3, DI 76*272efad7SDavid du Colombier ADDQ $3, SI 77*272efad7SDavid du Colombier MOVL BX, CX 78*272efad7SDavid du Colombier REP; MOVSB 79*272efad7SDavid du Colombier 80*272efad7SDavid du Colombier_return: 81*272efad7SDavid du Colombier RET 82