ENTRY(rop__sparc_flip_area) save %sp,-104,%sp /* %i0 pointer to bits (longword-aligned) %i1 longs-per-row [bytes-per-row] %i2 x-offset %i3 width %i4 height */ /* Convert %i1 to bytes-per-row */ sll %i1,2,%i1 /* Is it a river down a single word? */ add %i2,%i3,%l0 cmp %l0,32 bgeu sflipa_not_river .empty /* Yes - construct the mask and do it */ not %g0,%l1 srl %l1,%i3,%l1 not %l1 srl %l1,%i2,%l0 1: ld [%i0],%l2 xor %l2,%l0,%l2 st %l2,[%i0] deccc %i4 bgu 1b add %i0,%i1,%i0 ret restore sflipa_not_river: /* Check for partial river at left edge, handle if present */ tst %i2 be sflipa_left_edge_done .empty not %g0,%l0 srl %l0,%i2,%l0 mov %i0,%o0 mov %i4,%o1 1: ld [%o0],%l2 xor %l2,%l0,%l2 st %l2,[%o0] deccc %o1 bgu 1b add %o0,%i1,%o0 add %i0,4,%i0 add %i3,%i2,%i3 sub %i3,32,%i3 sflipa_left_edge_done: /* %i2 is now scratch; the effective %i2 value is zero. */ /* Check for river at right edge, handle if present */ andcc %i3,31,%l7 be sflipa_right_edge_done .empty not %g0,%l0 srl %l0,%l7,%l0 andn %i3,31,%i3 srl %i3,3,%o0 add %o0,%i0,%o0 mov %i4,%o1 1: ld [%o0],%l2 xnor %l2,%l0,%l2 st %l2,[%o0] deccc %o1 bgu 1b add %o0,%i1,%o0 sflipa_right_edge_done: tst %i3 bne 1f nop 9: ret restore 1: /* Non-doubleword-aligned longword at left edge? */ andcc %i0,4,%g0 be 1f .empty /* Yes - do it. */ mov %i0,%o0 mov %i4,%o1 2: ld [%o0],%l6 not %l6,%l6 st %l6,[%o0] deccc %o1 bgu 2b add %o0,%i1,%o0 subcc %i3,32,%i3 be 9b add %i0,4,%i0 1: /* Lone longword at right edge? */ andcc %i3,32,%g0 be 1f .empty /* Yes - do it. */ andn %i3,63,%i3 srl %i3,3,%o0 add %o0,%i0,%o0 mov %i4,%o1 2: ld [%o0],%l6 not %l6,%l6 st %l6,[%o0] deccc %o1 bgu 2b add %o0,%i1,%o0 1: /* Flip rows of doubleword-aligned doublewords. */ tst %i3 be 9b nop 2: mov %i0,%o0 mov %i3,%o1 1: ldd [%o0],%l6 not %l6,%l6 not %l7,%l7 std %l6,[%o0] subcc %o1,64,%o1 bgu 1b add %o0,8,%o0 deccc %i4 bgu 2b add %i0,%i1,%i0 ret restore