/* * ffb_asm.s: Fast Creator raster op inner loops. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * JAKUB JELINEK OR DAVID MILLER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ /* $XFree86$ */ /* Hardware register offsets */ #define FFB_BY 0x0060 #define FFB_DY 0x0068 #define FFB_BH 0x0070 #define FFB_PPC 0x0200 #define FFB_DRAWOP 0x0300 #define FFB_UCSR 0x0900 #define FFB_DRAWOP_VSCROLL 0x0b #define FIFO_CACHE 0x00 #define BOX_X1 0x00 #define BOX_Y1 0x02 #define BOX_X2 0x04 #define BOX_Y2 0x06 #define POINT_X 0x00 #define POINT_Y 0x02 #define RECT_X 0x00 #define RECT_Y 0x02 #define RECT_W 0x04 #define RECT_H 0x06 #define SEG_X1 0x00 #define SEG_Y1 0x02 #define SEG_X2 0x04 #define SEG_Y2 0x06 .text .align 32 .globl FFB_STIPPLE_LOAD /* %o0 = &ffbregs->pattern[0] * %o1 = &stipple->bits[0] */ FFB_STIPPLE_LOAD: cmp %g0, 0 1: ldx [%o1 + 0x00], %g1 ldx [%o1 + 0x08], %g2 ldx [%o1 + 0x10], %g3 ldx [%o1 + 0x18], %g4 add %o0, 0x40, %o0 ldx [%o1 + 0x20], %g5 ldx [%o1 + 0x28], %o2 ldx [%o1 + 0x30], %o3 ldx [%o1 + 0x38], %o4 stx %g1, [%o0 - 0x40] stx %g2, [%o0 - 0x38] stx %g3, [%o0 - 0x30] stx %g4, [%o0 - 0x28] add %o1, 0x40, %o1 stx %g5, [%o0 - 0x20] stx %o2, [%o0 - 0x18] stx %o3, [%o0 - 0x10] stx %o4, [%o0 - 0x08] be,pt %icc, 1b cmp %g0, 1 retl nop #define FIFO_WAIT(ffbregs, goal, this_label, done_label) \ this_label: \ lduw [ffbregs + FFB_UCSR], %g1; \ and %g1, 0xfff, %g1; \ subcc %g1, (4 + goal), %g1; \ bge,pt %icc, done_label; \ nop; \ ba,a,pt %xcc, this_label .align 32 .globl FFB_PPT_BOX_LOOP /* This is only used (currently) by vscroll, so we put * the creator hwbug workaround in here (writing * the drawop each iteration). * * %o0 = ffbpriv, %o1 = ffbregs, * %o2 = pbox, %o3 = pbox_last, %o4 = ppt */ FFB_PPT_BOX_LOOP: lduh [%o0 + FIFO_CACHE], %g1 /* Load Group */ sethi %hi(FFB_DRAWOP), %g2 /* IEU0 */ cmp %o2, %o3 /* IEU1 */ bgu,pn %icc, 2f /* CTI */ or %g2,%lo(FFB_DRAWOP),%g2 /* IEU0 Group */ 1: lduh [%o4 + POINT_X], %g3 /* Load Group */ lduh [%o4 + POINT_Y], %g4 /* Load Group */ lduh [%o2 + BOX_Y2], %g5 /* Load Group */ lduh [%o2 + BOX_Y1], %o5 /* Load Group */ sllx %g4, 32, %g4 /* IEU0 */ or %g3, %g4, %g3 /* IEU0 Group */ sub %g5, %o5, %g5 /* IEU1 */ sllx %o5, 32, %g4 /* IEU0 Group */ sllx %g5, 32, %g5 /* IEU0 Group */ lduh [%o2 + BOX_X2], %o5 /* Load */ add %o4, 0x4, %o4 /* IEU1 */ lduh [%o2 + BOX_X1], %g7 /* Load Group */ add %o2, 0x8, %o2 /* IEU0 */ sub %o5, %g7, %o5 /* IEU0 Group */ or %g4, %g7, %g4 /* IEU1 */ or %g5, %o5, %g5 /* IEU0 Group */ subcc %g1, 7, %g1 /* IEU1 */ bl,pn %icc, FFB_PPT_BOX_WAIT /* CTI */ 9: cmp %o2, %o3 /* IEU1 Group */ /* This works around BUG ID 1189858 -DaveM */ mov FFB_DRAWOP_VSCROLL, %o5 /* IEU0 */ stw %o5, [%o1 + %g2] /* STORE */ stx %g3, [%o1 + FFB_BY] /* STORE Group */ stx %g4, [%o1 + FFB_DY] /* STORE Group */ bleu,pt %icc, 1b /* CTI */ stx %g5, [%o1 + FFB_BH] /* STORE Group */ 2: retl /* CTI Group */ sth %g1, [%o0 + FIFO_CACHE] /* STORE */ FIFO_WAIT(%o1, 7, FFB_PPT_BOX_WAIT, 9b) .align 32 .globl FFB_BOX_LOOP /* %o0 = ffbpriv, %o1 = ffbregs, * %o2 = pbox, %o3 = pbox_last */ FFB_BOX_LOOP: lduh [%o0 + FIFO_CACHE], %g1 /* Load Group */ cmp %o2, %o3 /* IEU0 */ bgu,pn %icc, 2f /* CTI */ nop /* IEU0 Group */ 1: lduw [%o2 + BOX_X1], %g4 /* Load Group */ lduw [%o2 + BOX_X2], %g3 /* Load Group */ sllx %g4, 32, %o5 /* IEU0 */ srl %g4, 16, %g7 /* IEU0 Group */ add %o2, 8, %o2 /* IEU1 */ sllx %g3, 32, %g5 /* IEU0 Group */ subcc %g1, 4, %g1 /* IEU1 */ srl %g3, 16, %o4 /* IEU0 Group */ or %o5, %g7, %o5 /* IEU1 */ or %g5, %o4, %g5 /* IEU0 Group */ bl,pn %icc, FFB_BOX_WAIT /* CTI */ sub %g5, %o5, %g5 /* IEU0 Group */ 9: cmp %o2, %o3 /* IEU1 */ stx %o5, [%o1 + FFB_BY] /* Store */ bleu,pt %icc, 1b /* CTI Group */ stx %g5, [%o1 + FFB_BH] /* Store */ 2: retl /* CTI Group */ sth %g1, [%o0 + FIFO_CACHE] /* Store */ FIFO_WAIT(%o1, 4, FFB_BOX_WAIT, 9b) .align 32 .globl FFB_RECT_LOOP /* %o0 = ffbpriv, %o1 = ffbregs, * %o2 = prect, %o3 = prect_last, * %o4 = xOrg, %o5 = yOrg */ FFB_RECT_LOOP: lduh [%o0 + FIFO_CACHE], %g1 /* Load Group */ sllx %o5, 32, %o5 /* IEU0 */ cmp %o2, %o3 /* IEU1 */ bgu,pn %icc, 2f /* CTI */ or %o4, %o5, %o4 /* IEU0 Group */ 1: lduh [%o2 + RECT_X], %g4 /* Load Group */ lduh [%o2 + RECT_Y], %o5 /* Load Group */ lduh [%o2 + RECT_W], %g3 /* Load Group */ lduh [%o2 + RECT_H], %g2 /* Load Group */ sllx %o5, 32, %g7 /* IEU0 */ add %o2, 8, %o2 /* IEU1 */ orcc %g7, %g4, %g7 /* IEU1 Group */ sllx %g2, 32, %g5 /* IEU0 */ or %g5, %g3, %g5 /* IEU0 Group */ add %g7, %o4, %g7 /* IEU1 */ subcc %g1, 4, %g1 /* IEU1 Group */ bl,pn %icc, FFB_RECT_WAIT /* CTI */ 9: cmp %o2, %o3 /* IEU1 Group */ stx %g7, [%o1 + FFB_BY] /* Store */ bleu,pt %icc, 1b /* CTI */ stx %g5, [%o1 + FFB_BH] /* Store Group */ 2: retl /* CTI Group */ sth %g1, [%o0 + FIFO_CACHE] /* Store */ FIFO_WAIT(%o1, 4, FFB_RECT_WAIT, 9b) .align 32 .globl FFB_PPT_WIDTH_LOOP /* %o0 = ffbpriv, %o1 = ffbregs, * %o2 = ppt, %o3 = ppt_last, * %o4 = pwidth */ FFB_PPT_WIDTH_LOOP: lduh [%o0 + FIFO_CACHE], %g1 /* Load Group */ cmp %o2, %o3 /* IEU1 */ bgu,pn %icc, 2f /* CTI */ nop 8: lduw [%o2 + POINT_X], %g4 /* Load Group */ lduw [%o4], %g2 /* Load Group */ sllx %g4, 32, %g7 1: srl %g4, 16, %g5 /* IEU0 Group */ add %o2, 4, %o2 /* IEU1 */ brz,pn %g2, 8b /* CTI+IEU1 Group */ add %o4, 4, %o4 /* IEU0 */ or %g5, %g7, %g7 /* IEU0 Group */ subcc %g1, 5, %g1 /* IEU1 */ bl,pn %icc, FFB_PPT_WIDTH_WAIT/* CTI */ add %g7, %g2, %o5 /* IEU0 Group */ 9: stw %g0, [%o1 + FFB_PPC] /* Store Group */ cmp %o2, %o3 /* IEU1 */ stx %g7, [%o1 + FFB_BY] /* Store Group */ bleu,pt %icc, 8b /* CTI */ stx %o5, [%o1 + FFB_BH] /* Store Group */ 2: retl /* CTI Group */ sth %g1, [%o0 + FIFO_CACHE] /* Store */ FIFO_WAIT(%o1, 5, FFB_PPT_WIDTH_WAIT, 9b) .align 32 .globl FFB_LINE_LOOP1 /* %o0 = ffbpriv, %o1 = ffbregs, * %o2 = ppt, %o3 = ppt_last, * %o4 = xOrg, %o5 = yOrg * * We return ppt_last + 1. */ FFB_LINE_LOOP1: lduh [%o0 + FIFO_CACHE], %g1 sllx %o5, 32, %o5 and %o4, 0x7ff, %o4 cmp %o2, %o3 bgu,pn %icc, 2f or %o4, %o5, %o4 1: lduw [%o2 + POINT_X], %g4 sllx %g4, 32, %g7 srl %g4, 16, %g3 add %o2, 4, %o2 or %g7, %g3, %g7 subcc %g1, 3, %g1 bl,pn %icc, FFB_LINE1_WAIT add %g7, %o4, %g7 9: cmp %o2, %o3 stw %g0, [%o1 + FFB_PPC] bleu,pt %icc, 1b stx %g7, [%o1 + FFB_BH] 2: nop sth %g1, [%o0 + FIFO_CACHE] retl mov %o2, %o0 FIFO_WAIT(%o1, 3, FFB_LINE1_WAIT, 9b) .align 32 .globl FFB_LINE_LOOP2 /* %o0 = ffbpriv, %o1 = ffbregs, * %o2 = ppt, %o3 = ppt_last, * %o4 = &xOrg, %o5 = &yOrg * * We return ppt_last + 1. * The only difference between the previous routine * is that here we accumulate the origin values. */ FFB_LINE_LOOP2: lduw [%o5], %g5 lduw [%o4], %g2 lduh [%o0 + FIFO_CACHE], %g1 sllx %g5, 32, %g5 and %g2, 0x7ff, %g2 cmp %o2, %o3 bgu,pn %icc, 2f or %g5, %g2, %g5 1: lduw [%o2 + POINT_X], %g4 sllx %g4, 32, %g7 srl %g4, 16, %g3 add %o2, 4, %o2 or %g7, %g3, %g7 subcc %g1, 3, %g1 bl,pn %icc, FFB_LINE2_WAIT add %g7, %g5, %g5 9: cmp %o2, %o3 stw %g0, [%o1 + FFB_PPC] bleu,pt %icc, 1b stx %g5, [%o1 + FFB_BH] 2: sth %g1, [%o0 + FIFO_CACHE] srlx %g5, 32, %g4 stw %g5, [%o4] stw %g4, [%o5] retl mov %o2, %o0 FIFO_WAIT(%o1, 3, FFB_LINE2_WAIT, 9b)