mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1046 lines
44 KiB
1046 lines
44 KiB
//++
|
|
//
|
|
// Copyright (c) 1993 IBM Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// tiler.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements code to copy a pattern to a target surface.
|
|
//
|
|
// Author:
|
|
//
|
|
// Curtis R. Fawcett (crf) 31-Aug-1993
|
|
//
|
|
// Environment:
|
|
//
|
|
// User mode only.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Curtis R. Fawcett (crf) 18-Jan-1994 Removed register names
|
|
// as requested
|
|
//
|
|
// Curtis R. Fawcett (crf) 10-Mar-1994 Fixed problem in the
|
|
// vFetchAndMerge routine
|
|
//
|
|
//--
|
|
|
|
#include <kxppc.h>
|
|
#include <gdippc.h>
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// vFetchAndCopy (
|
|
// IN PFETCHFRAME pff
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine repeatedly tiles one scan line of an aligned pattern.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// pff (r.3) - Supplies a pointer to a fetch frame.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
//
|
|
// Define entry points
|
|
//
|
|
LEAF_ENTRY(vCopyPattern)
|
|
|
|
ALTERNATE_ENTRY(vFetchAndCopy)
|
|
//
|
|
// Fetch and Copy pattern
|
|
//
|
|
lwz r.4,ff_pvTrg(r.3) // Get starting target address
|
|
lwz r.5,ff_pvPat(r.3) // Get base pattern address
|
|
lwz r.6,ff_xPat(r.3) // Get pattern offset in bytes
|
|
lwz r.8,ff_culFill(r.3) // Get fill length
|
|
lwz r.7,ff_cxPat(r.3) // Get pattern width in pixels
|
|
slwi r.9,r.8,2 // Get word length
|
|
//
|
|
// Do some parameter checking
|
|
//
|
|
cmpwi r.9,0 // Check for zero fill
|
|
add r.8,r.4,r.9 // Get ending target address
|
|
add r.10,r.5,r.6 // Get pattern address
|
|
beq- FtchCpyExit // If so, jump to return
|
|
cmpwi r.7,0 // Check for zero pattern size
|
|
beq- FtchCpyExit // If so, jump to return
|
|
cmpwi r.7,8 // Check for width of 8 bytes
|
|
bne- FCNot8Bytes // Jump if not eight bytes
|
|
//
|
|
// Fetch the pattern (8 bytes)
|
|
//
|
|
cmpwi r.6,0 // Check for zero offset
|
|
lwz r.12,0(r.10) // Get low 4-bytes of pattern
|
|
lwz r.3,4(r.10) // Get high 4-bytes of pattern
|
|
mr r.10,r.9 // Set length of target
|
|
beq+ CopyPattern // If so jump to copy
|
|
lwz r.3,0(r.5) // Refetch hi 4-bytes of pattern
|
|
b CopyPattern // Jump to copy
|
|
//
|
|
// Fetch Pattern and store the results (not 8 bytes)
|
|
//
|
|
|
|
FCNot8Bytes:
|
|
lwz r.12,0(r.10) // Get low 4-bytes of pattern
|
|
add r.7,r.5,r.7 // Get ending pattern address
|
|
FtchCpyLp:
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.10,r.10,4 // Incrment the pattern pointer
|
|
beq- FtchCpyExit // If so jump to return
|
|
sub. r.9,r.10,r.7 // Check for end of pattern
|
|
lwz r.12,0(r.10) // Fetch next section of pattern
|
|
bne+ FtchCpyLp // Jump if more pattern
|
|
mr r.10,r.5 // Reset pattern pointer
|
|
lwz r.12,0(r.10) // Fetch next section of pattern
|
|
b FtchCpyLp // Jump to continue fills
|
|
//
|
|
// Exit Fetch and Copy
|
|
//
|
|
FtchCpyExit:
|
|
ALTERNATE_EXIT(vFetchAndCopy)
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// vFetchShiftAndCopy (
|
|
// IN PFETCHFRAME pff
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine repeatedly tiles one line of an unaligned pattern
|
|
// using rop (P).
|
|
//
|
|
// Arguments:
|
|
//
|
|
// pff (r.3) - Supplies a pointer to a fetch frame.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
ALTERNATE_ENTRY(vFetchShiftAndCopy)
|
|
//
|
|
// Fetch Shift and Copy pattern
|
|
//
|
|
lwz r.4,ff_pvTrg(r.3) // Get starting target address
|
|
lwz r.5,ff_pvPat(r.3) // Get base pattern address
|
|
lwz r.6,ff_xPat(r.3) // Get pattern offset in bytes
|
|
lwz r.8,ff_culFill(r.3) // Get fill length
|
|
lwz r.7,ff_cxPat(r.3) // Get pattern width in pixels
|
|
slwi r.9,r.8,2 // Get word length
|
|
//
|
|
// Do some parameter checking
|
|
//
|
|
cmpwi r.9,0 // Check for zero fill
|
|
add r.8,r.4,r.9 // Get ending target address
|
|
add r.10,r.5,r.6 // Get pattern address
|
|
beq- FSCExit // If so, jump to return
|
|
cmpwi r.7,0 // Check for zero pattern size
|
|
beq- FSCExit // If so, jump to return
|
|
cmpwi r.7,8 // Check for width of 8 bytes
|
|
bne- FSCNot8Bytes // Jump if not eight bytes
|
|
//
|
|
// Fetch and shift the pattern (8 bytes)
|
|
//
|
|
// Check for alignment
|
|
//
|
|
mr r.11,r.9 // Save count
|
|
andi. r.9,r.10,3 // Check alignment
|
|
cmpwi r.9,0 // Check for word shifted
|
|
beq- FSC8BWd // Jump for word offset case
|
|
cmpwi r.9,1 // Check for 1 byte offset case
|
|
beq+ FSC8B1B // Jump for word offset case
|
|
cmpwi r.9,2 // Check for halfword offset case
|
|
beq- FSC8BHw // jump for halfword offset case
|
|
//
|
|
// Fetch the pattern (3 byte offset case) and jump to CopyPattern
|
|
//
|
|
FSC8B3B:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pattrn word
|
|
lhz r.9,1(r.10) // Get byte 3 & 2 of low pttrn wd
|
|
slwi r.12,r.12,16 // Shift byte 4
|
|
or r.12,r.12,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,0(r.10) // Get byte 1 of low pattrn word
|
|
slwi r.12,r.12,8 // Shift bytes 2, 3 and 4
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lbz r.9,-2(r.10) // Get byte 3 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 3 and 4
|
|
lbz r.9,-3(r.10) // Get byte 2 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,4(r.10) // Get byte 1 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 2, 3, and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
// Fetch the pattern (Halfword offset case) and jump to CopyPattern
|
|
//
|
|
FSC8BHw:
|
|
lhz r.12,2(r.10) // Get bytes 3 & 4 of low pttn wd
|
|
lhz r.9,0(r.10) // Get bytes 1 & 2 of low pttrn wd
|
|
slwi r.12,r.12,16 // Shift bytes 3 & 4
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lbz r.9,-2(r.10) // Get byte 3 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 3 and 4
|
|
lhz r.9,4(r.10) // Get bytes 1 & 2 of hi pttrn wd
|
|
slwi r.3,r.3,16 // Shift bytes 3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
// Fetch the pattern (1 byte offset case) and jump to CopyPattern
|
|
//
|
|
FSC8B1B:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pattrn word
|
|
lhz r.9,1(r.10) // Get byte 3 & 2 of low pttrn wd
|
|
slwi r.12,r.12,16 // Shift byte 4
|
|
or r.12,r.12,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,0(r.10) // Get byte 1 of low pattrn word
|
|
slwi r.12,r.12,8 // Shift bytes 2, 3 and 4
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lhz r.9,5(r.10) // Get byte 2 & 3 of hi pttn wd
|
|
slwi r.3,r.3,16 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,4(r.10) // Get byte 1 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 2,3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
// Fetch the pattern (word offset case) and jump to CopyPattern
|
|
//
|
|
FSC8BWd:
|
|
lwz r.12,0(r.10) // Get low part of pttrn
|
|
lwz r.3,-4(r.10) // Get high part of pttrn
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
//
|
|
// Fetch Pattern and store the results (not 8 bytes)
|
|
//
|
|
|
|
FSCNot8Bytes:
|
|
andi. r.9,r.10,3 // Check the offset
|
|
beq FSCLp2 // Jump if word aligned
|
|
cmpwi r.9,2 // Check for hw offset
|
|
beq FSCLp3 // Jump to halfword offset case
|
|
//
|
|
// Fetch and shift pattern (Not 8 bytes) - 1 and 3 byte offset cases
|
|
//
|
|
|
|
FSCLp1:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pttrn bytes
|
|
lhz r.9,1(r.10) // Get byte 3 of low pttrn bytes
|
|
slwi r.12,r.12,16 // Shift low order pattern bytes
|
|
or r.12,r.12,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,0(r.10) // Get byte 1 of low pttrn bytes
|
|
slwi r.12,r.12,8 // Shift low order pattern bytes
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSCExit // If so jump to return
|
|
sub. r.9,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSCLp1 // Jump back for more pattern
|
|
mr r.6,r.9 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSCNot8Bytes // Jump to continue fills
|
|
//
|
|
// Fetch and shift pattern (Not 8 bytes) - word aligned case
|
|
//
|
|
|
|
FSCLp2:
|
|
lwz r.12,0(r.10) // Get 4 bytes of pattern
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSCExit // If so jump to return
|
|
sub. r.9,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSCLp2 // Jump back for more pattern
|
|
mr r.6,r.9 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSCNot8Bytes // Jump to continue fills
|
|
//
|
|
// Fetch and shift pattern (Not 8 bytes) - halfword offset case
|
|
//
|
|
|
|
FSCLp3:
|
|
lhz r.12,2(r.10) // Get 2 bytes of pattern
|
|
lhz r.9,0(r.10) // Get 2 bytes of pattern
|
|
slwi r.12,r.12,16 // Shift the hi bytes
|
|
or r.12,r.12,r.9 // Get 4 bytes of pattern
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSCExit // If so jump to return
|
|
sub. r.9,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSCLp3 // Jump back for more pattern
|
|
mr r.6,r.9 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSCNot8Bytes // Jump to continue fills
|
|
//
|
|
// Exit Fetch Shift and Copy
|
|
//
|
|
FSCExit:
|
|
ALTERNATE_EXIT(vFetchShiftAndCopy)
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// vFetchNotAndCopy (
|
|
// IN PFETCHFRAME pff
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine repeatedly tiles one line of an aligned pattern.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// pff (r.3) - Supplies a pointer to a fetch frame.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
ALTERNATE_ENTRY(vFetchNotAndCopy)
|
|
//
|
|
// Fetch Not and Copy pattern
|
|
//
|
|
lwz r.4,ff_pvTrg(r.3) // Get starting target address
|
|
lwz r.5,ff_pvPat(r.3) // Get base pattern address
|
|
lwz r.6,ff_xPat(r.3) // Get pattern offset in bytes
|
|
lwz r.8,ff_culFill(r.3) // Get fill length
|
|
lwz r.7,ff_cxPat(r.3) // Get pattern width in pixels
|
|
slwi r.9,r.8,2 // Get word length
|
|
//
|
|
// Do some parameter checking
|
|
//
|
|
cmpwi r.9,0 // Check for zero fill
|
|
add r.8,r.4,r.9 // Get ending target address
|
|
add r.10,r.5,r.6 // Get pattern address
|
|
beq- FtchNotCpyExit // If so, jump to return
|
|
cmpwi r.7,0 // Check for zero pattern size
|
|
beq- FtchNotCpyExit // If so, jump to return
|
|
cmpwi r.7,8 // Check for width of 8 bytes
|
|
bne- FNCNot8Bytes // Jump if not eight bytes
|
|
//
|
|
// Fetch the pattern (8 bytes)
|
|
//
|
|
cmpwi r.6,0 // Check for zero offset
|
|
lwz r.12,0(r.10) // Get low 4-bytes of pattern
|
|
lwz r.3,4(r.10) // Get high 4-bytes of pattern
|
|
mr r.10,r.9 // Set length of target
|
|
beq+ FNCNotPattern // If so, jmp to complement pttrn
|
|
lwz r.3,0(r.5) // Refetch hi 4-bytes of pattern
|
|
FNCNotPattern:
|
|
li r.9,0 // Get "NOR" value
|
|
nor r.12,r.12,r.9 // Complement low pattern part
|
|
nor r.3,r.3,r.9 // Complement high pattern part
|
|
b CopyPattern // Jump to copy
|
|
//
|
|
// Fetch and complement pattern then store the results (not 8 bytes)
|
|
//
|
|
FNCNot8Bytes:
|
|
lwz r.12,0(r.10) // Get low 4-bytes of pattern
|
|
add r.7,r.5,r.7 // Get ending pattern address
|
|
FtchNotCpyLp:
|
|
li r.9,0 // Get "NOR" value
|
|
nor r.12,r.12,r.9 // Complement low pattern part
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.10,r.10,4 // Incrment the pattern pointer
|
|
beq- FtchNotCpyExit // If so jump to return
|
|
sub. r.9,r.10,r.7 // Check for end of pattern
|
|
lwz r.12,0(r.10) // Fetch next section of pattern
|
|
bne+ FtchNotCpyLp // Jump if more pattern
|
|
mr r.10,r.5 // Reset pattern pointer
|
|
lwz r.12,0(r.10) // Fetch next section of pattern
|
|
b FtchNotCpyLp // Jump to continue fills
|
|
//
|
|
// Exit Fetch Not and Copy
|
|
//
|
|
FtchNotCpyExit:
|
|
ALTERNATE_EXIT(vFetchNotAndCopy)
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// vFetchShiftNotAndCopy (
|
|
// IN PFETCHFRAME pff
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine repeatedly tiles one line of an unaligned pattern
|
|
// using rop (Pn).
|
|
//
|
|
// Arguments:
|
|
//
|
|
// pff (r.3) - Supplies a pointer to a fetch frame.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
ALTERNATE_ENTRY(vFetchShiftNotAndCopy)
|
|
//
|
|
// Fetch, Shift, Not and Copy pattern
|
|
//
|
|
lwz r.4,ff_pvTrg(r.3) // Get starting target address
|
|
lwz r.5,ff_pvPat(r.3) // Get base pattern address
|
|
lwz r.6,ff_xPat(r.3) // Get pattern offset in bytes
|
|
lwz r.8,ff_culFill(r.3) // Get fill length
|
|
lwz r.7,ff_cxPat(r.3) // Get pattern width in pixels
|
|
slwi r.9,r.8,2 // Get word length
|
|
//
|
|
// Do some parameter checking
|
|
//
|
|
cmpwi r.9,0 // Check for zero fill
|
|
add r.8,r.4,r.9 // Get ending target address
|
|
add r.10,r.5,r.6 // Get pattern address
|
|
beq- FSNCExit // If so, jump to return
|
|
cmpwi r.7,0 // Check for zero pattern size
|
|
beq- FSNCExit // If so, jump to return
|
|
cmpwi r.7,8 // Check for width of 8 bytes
|
|
bne- FSNCNot8Bytes // Jump if not eight bytes
|
|
//
|
|
// Fetch and shift the pattern (8 bytes)
|
|
//
|
|
// Check for alignment
|
|
//
|
|
mr r.11,r.9 // Save count
|
|
andi. r.9,r.10,3 // Check alignment
|
|
cmpwi r.9,0 // Check for word shifted
|
|
beq- FSN8BWd // Jump for word offset case
|
|
cmpwi r.9,1 // Check for 1 byte offset case
|
|
beq+ FSN8B1B // Jump for word offset case
|
|
cmpwi r.9,2 // Check for halfword offset case
|
|
beq- FSN8BHw // jump for halfword offset case
|
|
//
|
|
// Fetch the pattern (3 byte offset case) and jump to CopyPattern
|
|
//
|
|
FSN8B3B:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pattrn word
|
|
lhz r.9,1(r.10) // Get byte 3 & 2 of low pttrn wd
|
|
slwi r.12,r.12,16 // Shift byte 4
|
|
or r.12,r.12,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,0(r.10) // Get byte 1 of low pattrn word
|
|
slwi r.12,r.12,8 // Shift bytes 2, 3 and 4
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lbz r.9,-2(r.10) // Get byte 3 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 3 and 4
|
|
lbz r.9,-3(r.10) // Get byte 2 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,4(r.10) // Get byte 1 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 2, 3, and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
li r.9,0 // Set "NOR" value
|
|
nor r.12,r.12,r.9 // Complement the low pttrn part
|
|
nor r.3,r.3,r.9 // Complement the hi pttrn part
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
// Fetch the pattern (Halfword offset case) and jump to CopyPattern
|
|
//
|
|
FSN8BHw:
|
|
lhz r.12,2(r.10) // Get bytes 3 & 4 of low pttn wd
|
|
lhz r.9,0(r.10) // Get bytes 1 & 2 of low pttn wd
|
|
slwi r.12,r.12,16 // Shift bytes 3 & 4
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lbz r.9,-2(r.10) // Get byte 3 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 3 and 4
|
|
lhz r.9,4(r.10) // Get bytes 1 & 2 of hi pttrn wd
|
|
slwi r.3,r.3,16 // Shift bytes 3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
li r.9,0 // Set "NOR" value
|
|
nor r.12,r.12,r.9 // Complement the low pttrn part
|
|
nor r.3,r.3,r.9 // Complement the hi pttrn part
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
// Fetch the pattern (1 byte offset case) and jump to CopyPattern
|
|
//
|
|
FSN8B1B:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pattrn word
|
|
lhz r.9,1(r.10) // Get byte 3 & 2 of low pttrn wd
|
|
slwi r.12,r.12,16 // Shift byte 4
|
|
or r.12,r.12,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,0(r.10) // Get byte 1 of low pattrn word
|
|
slwi r.12,r.12,8 // Shift bytes 2, 3 and 4
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lhz r.9,5(r.10) // Get byte 2 & 3 of hi pttn wd
|
|
slwi r.3,r.3,16 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,4(r.10) // Get byte 1 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 2,3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
li r.9,0 // Set "NOR" value
|
|
nor r.12,r.12,r.9 // Complement the low pttrn part
|
|
nor r.3,r.3,r.9 // Complement the hi pttrn part
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
// Fetch the pattern (word offset case) and jump to CopyPattern
|
|
//
|
|
FSN8BWd:
|
|
lwz r.12,0(r.10) // Get low part of pttrn
|
|
lwz r.3,-4(r.10) // Get high part of pttrn
|
|
li r.9,0 // Set "NOR" value
|
|
nor r.12,r.12,r.9 // Complement the low pttrn part
|
|
nor r.3,r.3,r.9 // Complement the hi pttrn part
|
|
mr r.10,r.11 // Save word length
|
|
b CopyPattern // Jump to copy the pattern
|
|
//
|
|
// Fetch, Shift and Not pattern then store the results (not 8 bytes)
|
|
//
|
|
|
|
FSNCNot8Bytes:
|
|
li r.3,0 // Set "NOR" value
|
|
andi. r.9,r.10,3 // Check the offset
|
|
beq FSNCLp2 // Jump if word aligned
|
|
cmpwi r.9,2 // Check for hw offset
|
|
beq FSNCLp3 // Jump to halfword offset case
|
|
//
|
|
// Fetch, Shift and Not pattern (Not 8 bytes) - 1 and 3 byte offset cases
|
|
//
|
|
|
|
FSNCLp1:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pttrn bytes
|
|
lhz r.9,1(r.10) // Get byte 3 of low pttrn bytes
|
|
slwi r.12,r.12,16 // Shift low order pattern bytes
|
|
or r.12,r.12,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,0(r.10) // Get byte 1 of low pttrn bytes
|
|
slwi r.12,r.12,8 // Shift low order pattern bytes
|
|
or r.12,r.12,r.9 // Combine bytes 1, 2, 3 and 4
|
|
nor r.12,r.12,r.3 // Complement the pattern
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSNCExit // If so jump to return
|
|
sub. r.9,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSNCLp1 // Jump back for more pattern
|
|
mr r.6,r.9 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSNCNot8Bytes // Jump to continue fills
|
|
//
|
|
// Fetch, Shift and Not the pattern (Not 8 bytes) - word aligned case
|
|
//
|
|
|
|
FSNCLp2:
|
|
lwz r.12,0(r.10) // Get 4 bytes of pattern
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
nor r.12,r.12,r.3 // Complement the pattern
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSNCExit // If so jump to return
|
|
sub. r.9,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSNCLp2 // Jump back for more pattern
|
|
mr r.6,r.9 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSNCNot8Bytes // Jump to continue fills
|
|
//
|
|
// Fetch, Shift and NOT pattern (Not 8 bytes) - halfword offset case
|
|
//
|
|
|
|
FSNCLp3:
|
|
lhz r.12,2(r.10) // Get 2 bytes of pattern
|
|
lhz r.3,0(r.10) // Get 2 bytes of pattern
|
|
slwi r.12,r.12,16 // Shift the hi 2 bytes
|
|
or r.12,r.12,r.3 // Comn=bine to get 4 bytes
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
nor r.12,r.12,r.3 // Complement the pattern
|
|
cmpw r.4,r.8 // Check for completion
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSNCExit // If so jump to return
|
|
sub. r.9,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSNCLp3 // Jump back for more pattern
|
|
mr r.6,r.9 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSNCNot8Bytes // Jump to continue fills
|
|
//
|
|
// Exit Fetch Shift Not and Copy
|
|
//
|
|
FSNCExit:
|
|
//
|
|
ALTERNATE_EXIT(vFetchShiftNotAndCopy)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine contains common code for copying an 8-byte pattern to
|
|
// a target surface.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// TLEN (r.10) - Supplies the size of the fill in bytes.
|
|
// PATLO(r.12) and PATHI (r.3) - Supplies the 8-byte pattern to copy.
|
|
// TARG (r.4) - Supplies the starting target surface address.
|
|
// TARGEND (r.8) - Supplies the ending target surface address.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
//
|
|
// Copy a Pattern
|
|
//
|
|
CopyPattern:
|
|
andi. r.9,r.10,0x4 // Check if even nmber of 8 bytes
|
|
beq+ CpyPttrnEven // If so, jump to even copy
|
|
//
|
|
// Fill 1 word then swap pattern for even multiple copies
|
|
//
|
|
subi r.10,r.10,4 // Decrement Target Length
|
|
cmpwi r.10,0 // Check for completion
|
|
stw r.12,0(r.4) // Store low 4-bytes of pattern
|
|
addi r.4,r.4,4 // Update target pointer
|
|
beq- CopyExit // Jump if copy completed
|
|
mr r.9,r.12 // Start swap
|
|
mr r.12,r.3 // Swap PATHI
|
|
mr r.3,r.9 // Swap PATLO
|
|
//
|
|
// Fill by even multiples of 8 bytes
|
|
//
|
|
CpyPttrnEven:
|
|
andi. r.9,r.10,0x8 // Check if even # of 16 bytes
|
|
beq CpyBy16Bytes // Jump if even number of copies
|
|
//
|
|
// Fill 1st 8 bytes then check for more fills
|
|
//
|
|
stw r.12,0(r.4) // Store lo 4 bytes of pattern
|
|
stw r.3,4(r.4) // Store hi 4 bytes of pattern
|
|
addi r.4,r.4,8 // Increment the target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
beq- CopyExit // Jump if done
|
|
//
|
|
// Fill 16 bytes at a time until done
|
|
//
|
|
CpyBy16Bytes:
|
|
stw r.12,0(r.4) // Store lo 4 bytes of pattern
|
|
stw r.3,4(r.4) // Store hi 4 bytes of pattern
|
|
stw r.12,8(r.4) // Store lo 4 bytes of pattern
|
|
stw r.3,12(r.4) // Store hi 4 bytes of pattern
|
|
addi r.4,r.4,16 // Increment the target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
bne+ CpyBy16Bytes // Jump if done
|
|
//
|
|
// Copy Pattern exit
|
|
//
|
|
CopyExit:
|
|
LEAF_EXIT(vCopyPattern)
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// vFetchAndMerge (
|
|
// IN PFETCHFRAME pff
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine repeatedly tiles one line of an aligned pattern.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// pff (r.3) - Supplies a pointer to a fetch frame.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(vMergePattern)
|
|
|
|
ALTERNATE_ENTRY(vFetchAndMerge)
|
|
//
|
|
// Fetch and Merge pattern
|
|
//
|
|
lwz r.4,ff_pvTrg(r.3) // Get starting target address
|
|
lwz r.5,ff_pvPat(r.3) // Get base pattern address
|
|
lwz r.6,ff_xPat(r.3) // Get pattern offset in bytes
|
|
lwz r.8,ff_culFill(r.3) // Get fill length
|
|
lwz r.7,ff_cxPat(r.3) // Get pattern width in pixels
|
|
slwi r.3,r.8,2 // Get word length
|
|
//
|
|
// Do some parameter checking
|
|
//
|
|
cmpwi r.3,0 // Check for zero fill
|
|
add r.8,r.4,r.3 // Get ending target address
|
|
add r.10,r.5,r.6 // Get pattern address
|
|
beq- FtchMergeExit // If so, jump to return
|
|
cmpwi r.7,0 // Check for zero pattern size
|
|
beq- FtchMergeExit // If so, jump to return
|
|
cmpwi r.7,8 // Check for width of 8 bytes
|
|
bne- FMNot8Bytes // Jump if not eight bytes
|
|
//
|
|
// Fetch the pattern (8 bytes)
|
|
//
|
|
cmpwi r.6,0 // Check for zero offset
|
|
lwz r.12,0(r.10) // Get low 4-bytes of pattern
|
|
mr r.7,r.3 // Save fill Length
|
|
lwz r.3,4(r.10) // Get high 4-bytes of pattern
|
|
mr r.10,r.7 // Get fill length
|
|
beq+ MergePattern // If so, jump to merge pattern
|
|
lwz r.3,0(r.5) // Refetch high 4-bytes of pttrn
|
|
b MergePattern // Jump to merge pattern
|
|
//
|
|
// Fetch and merge the pattern then store the results (not 8 bytes)
|
|
//
|
|
FMNot8Bytes:
|
|
lwz r.12,0(r.10) // Get low 4-bytes of pattern
|
|
add r.7,r.5,r.7 // Get ending pattern address
|
|
FtchMergeLp:
|
|
lwz r.11,0(r.4) // Get target value
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
xor r.12,r.11,r.12 // Merge target and pointer
|
|
stw r.12,-4(r.4) // Store pattern in target
|
|
beq- FtchMergeExit // If so jump to return
|
|
addi r.10,r.10,4 // Increment the pattern pointer
|
|
sub. r.3,r.10,r.7 // Check for end of pattern
|
|
lwz r.12,0(r.10) // Fetch next section of pattern
|
|
bne+ FtchMergeLp // Jump if more pattern
|
|
mr r.10,r.5 // Reset pattern pointer
|
|
lwz r.12,0(r.10) // Fetch next section of pattern
|
|
b FtchMergeLp // Jump to continue fills
|
|
//
|
|
// Exit Fetch and Merge
|
|
//
|
|
FtchMergeExit:
|
|
ALTERNATE_EXIT(vFetchAndMerge)
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// vFetchShiftAndMerge (
|
|
// IN PFETCHFRAME pff
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine repeatedly tiles one line of an unaligned pattern
|
|
// using rop (DPx).
|
|
//
|
|
// Arguments:
|
|
//
|
|
// pff (r.3) - Supplies a pointer to a fetch frame.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
ALTERNATE_ENTRY(vFetchShiftAndMerge)
|
|
//
|
|
// Fetch Shift and Merge pattern
|
|
//
|
|
lwz r.4,ff_pvTrg(r.3) // Get starting target address
|
|
lwz r.5,ff_pvPat(r.3) // Get base pattern address
|
|
lwz r.6,ff_xPat(r.3) // Get pattern offset in bytes
|
|
lwz r.8,ff_culFill(r.3) // Get fill length
|
|
lwz r.7,ff_cxPat(r.3) // Get pattern width in pixels
|
|
slwi r.3,r.8,2 // Get word length
|
|
//
|
|
// Do some parameter checking
|
|
//
|
|
cmpwi r.3,0 // Check for zero fill
|
|
add r.8,r.4,r.3 // Get ending target address
|
|
add r.10,r.5,r.6 // Get pattern address
|
|
beq- FSMExit // If so, jump to return
|
|
cmpwi r.7,0 // Check for zero pattern size
|
|
beq- FSMExit // If so, jump to return
|
|
cmpwi r.7,8 // Check for width of 8 bytes
|
|
bne- FSMNot8Bytes // Jump if not eight bytes
|
|
//
|
|
// Fetch and shift the pattern (8 bytes)
|
|
//
|
|
// Check for alignment
|
|
//
|
|
andi. r.9,r.10,3 // Check alignment
|
|
cmpwi r.9,0 // Check for word shifted
|
|
mr r.11,r.3 // Save count
|
|
beq- FSM8BWd // Jump for word offset case
|
|
cmpwi r.9,1 // Check for 1 byte offset case
|
|
beq+ FSM8B1B // Jump for word offset case
|
|
cmpwi r.9,2 // Check for halfword offset case
|
|
beq- FSM8BHw // jump for halfword offset case
|
|
//
|
|
// Fetch the pattern (3 byte offset case) and jump to MergePattern
|
|
//
|
|
FSM8B3B:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pattrn word
|
|
lhz r.3,1(r.10) // Get byte 3 & 2 of low pttrn wd
|
|
slwi r.12,r.12,16 // Shift byte 4
|
|
or r.12,r.12,r.3 // Combine bytes 2, 3 and 4
|
|
lbz r.3,0(r.10) // Get byte 1 of low pattrn word
|
|
slwi r.12,r.12,8 // Shift bytes 2, 3 and 4
|
|
or r.12,r.12,r.3 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lbz r.9,-2(r.10) // Get byte 3 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 3 and 4
|
|
lbz r.9,-3(r.10) // Get byte 2 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,4(r.10) // Get byte 1 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 2, 3, and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
mr r.10,r.11 // Save word length
|
|
b MergePattern // Jump to merge the pattern
|
|
//
|
|
// Fetch the pattern (Halfword offset case) and jump to MergePattern
|
|
//
|
|
FSM8BHw:
|
|
lhz r.12,2(r.10) // Get bytes 3 & 4 of low pttn wd
|
|
lhz r.3,0(r.10) // Get bytes 1 & 2 of low pttn wd
|
|
slwi r.12,r.12,16 // Shift bytes 3 & 4
|
|
or r.12,r.12,r.3 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lbz r.9,-2(r.10) // Get byte 3 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 3 and 4
|
|
lhz r.9,4(r.10) // Get bytes 1 & 2 of hi pttrn wd
|
|
slwi r.3,r.3,16 // Shift bytes 3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
mr r.10,r.11 // Save word length
|
|
b MergePattern // Jump to merge the pattern
|
|
//
|
|
// Fetch the pattern (1 byte offset case) and jump to MergePattern
|
|
//
|
|
FSM8B1B:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pattrn word
|
|
lhz r.3,1(r.10) // Get byte 3 & 2 of low pttrn wd
|
|
slwi r.12,r.12,16 // Shift byte 4
|
|
or r.12,r.12,r.3 // Combine bytes 2, 3 and 4
|
|
lbz r.3,0(r.10) // Get byte 1 of low pattrn word
|
|
slwi r.12,r.12,8 // Shift bytes 2, 3 and 4
|
|
or r.12,r.12,r.3 // Combine bytes 1, 2, 3 and 4
|
|
lbz r.3,-1(r.10) // Get byte 4 of hi pattrn word
|
|
lhz r.9,5(r.10) // Get byte 2 & 3 of hi pttn wd
|
|
slwi r.3,r.3,16 // Shift byte 4
|
|
or r.3,r.3,r.9 // Combine bytes 2, 3 and 4
|
|
lbz r.9,4(r.10) // Get byte 1 of hi pattrn word
|
|
slwi r.3,r.3,8 // Shift bytes 2,3 and 4
|
|
or r.3,r.3,r.9 // Combine bytes 1, 2, 3 and 4
|
|
mr r.10,r.11 // Save word length
|
|
b MergePattern // Jump to merge the pattern
|
|
//
|
|
// Fetch the pattern (word offset case) and jump to MergePattern
|
|
//
|
|
FSM8BWd:
|
|
lwz r.12,0(r.10) // Get low part of pttrn
|
|
lwz r.3,-4(r.10) // Get high part of pttrn
|
|
mr r.10,r.11 // Save word length
|
|
b MergePattern // Jump to merge the pattern
|
|
//
|
|
// Fetch Pattern, merge and store the results (not 8 bytes)
|
|
//
|
|
|
|
FSMNot8Bytes:
|
|
andi. r.9,r.10,3 // Check the offset
|
|
beq FSMLp2 // Jump if word aligned
|
|
cmpwi r.9,2 // Check for hw offset
|
|
beq FSMLp3 // Jump to halfword offset case
|
|
//
|
|
// Fetch, shift and merge pttrn (Not 8 bytes) - 1 and 3 byte offset cases
|
|
//
|
|
|
|
FSMLp1:
|
|
lbz r.12,3(r.10) // Get byte 4 of low pttrn bytes
|
|
lhz r.3,1(r.10) // Get byte 3 of low pttrn bytes
|
|
slwi r.12,r.12,16 // Shift low order pattern bytes
|
|
or r.12,r.12,r.3 // Combine bytes 2, 3 and 4
|
|
lbz r.3,0(r.10) // Get byte 1 of low pttrn bytes
|
|
slwi r.12,r.12,8 // Shift low order pattern bytes
|
|
or r.12,r.12,r.3 // Combine bytes 1, 2, 3 and 4
|
|
lwz r.11,0(r.4) // Get target value
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
xor r.11,r.11,r.12 // Merge the values
|
|
stw r.11,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSMExit // If so jump to return
|
|
sub. r.3,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSMLp1 // Jump back for more pattern
|
|
mr r.6,r.3 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSMNot8Bytes // Jump to continue fills
|
|
//
|
|
// Fetch, shift and merge pattern (Not 8 bytes) - word aligned case
|
|
//
|
|
|
|
FSMLp2:
|
|
lwz r.12,0(r.10) // Get 4 bytes of pattern
|
|
lwz r.11,0(r.4) // Get target value
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
xor r.11,r.11,r.12 // Merge the values
|
|
stw r.11,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSMExit // If so jump to return
|
|
sub. r.3,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSCLp2 // Jump back for more pattern
|
|
mr r.6,r.3 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSMNot8Bytes // Jump to continue fills
|
|
//
|
|
// Fetch, shift and merge pattern (Not 8 bytes) - halfword offset case
|
|
//
|
|
|
|
FSMLp3:
|
|
lhz r.12,2(r.10) // Get 2 bytes of pattern
|
|
lhz r.3,0(r.10) // Get 2 bytes of pattern
|
|
slwi r.12,r.12,16 // Shift the hi bytes
|
|
or r.12,r.12,r.3 // Get 4 bytes of pattern
|
|
lwz r.11,0(r.4) // Get target value
|
|
addi r.4,r.4,4 // Increment target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
xor r.11,r.11,r.12 // Merge the values
|
|
stw r.11,-4(r.4) // Store pattern in target
|
|
addi r.6,r.6,4 // Incrment the pattern pointer
|
|
beq- FSMExit // If so jump to return
|
|
sub. r.3,r.6,r.7 // Check for end of pattern
|
|
add r.10,r.5,r.6 // Get new offset
|
|
blt+ FSMLp3 // Jump back for more pattern
|
|
mr r.6,r.3 // Get new offset
|
|
add r.10,r.5,r.6 // Get new offset
|
|
b FSMNot8Bytes // Jump to continue fills
|
|
//
|
|
// Exit Fetch Shift and Merge
|
|
//
|
|
FSMExit:
|
|
ALTERNATE_EXIT(vFetchShiftAndMerge)
|
|
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine contains common code for merging an 8-byte pattern to
|
|
// a target surface.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// TLEN (r.10) - Supplies the size of the fill in bytes.
|
|
// PATLO (r.12) and PATHI (r.3) - Supplies 8-byte pattern to merge.
|
|
// TARG (r.4) - Supplies the starting target surface address.
|
|
// TARGEND (r.8) - Supplies the ending target surface address.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
//
|
|
// Merge a Pattern
|
|
//
|
|
|
|
MergePattern:
|
|
andi. r.9,r.10,0x4 // Check if even nmber of 8 bytes
|
|
beq+ MrgPttrnEven // If so, jump to even copy
|
|
//
|
|
// Merge 1 word then swap pattern for even multiple merges
|
|
//
|
|
lwz r.7,0(r.4) // Get target value
|
|
addi r.4,r.4,4 // Update target pointer
|
|
subi r.10,r.10,4 // Decrement Target Length
|
|
cmpwi r.10,0 // Check for completion
|
|
xor r.7,r.7,r.12 // Merge the pattern
|
|
stw r.7,-4(r.4) // Store low 4-bytes of pattern
|
|
mr r.9,r.12 // Start swap
|
|
mr r.12,r.3 // Swap PATHI
|
|
mr r.3,r.9 // Swap PATLO
|
|
beq MergeExit // Jump if merge completed
|
|
//
|
|
// Merge by even multiples of 8 bytes
|
|
//
|
|
MrgPttrnEven:
|
|
andi. r.9,r.10,0x8 // Check if even nmber of 8 bytes
|
|
beq MrgBy16Bytes // Jump if even number of merges
|
|
//
|
|
// Merge 1st 8 bytes then check for more merges
|
|
//
|
|
lwz r.7,0(r.4) // Get low target value
|
|
lwz r.9,4(r.4) // Get high target value
|
|
xor r.7,r.7,r.12 // Merge low 4 bytes of pattern
|
|
xor r.9,r.9,r.3 // Merge high 4 bytes of pattern
|
|
stw r.7,0(r.4) // Store lo 4 bytes of pattern
|
|
stw r.9,4(r.4) // Store hi 4 bytes of pattern
|
|
addi r.4,r.4,8 // Increment the target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
beq- MergeExit // Jump if done
|
|
//
|
|
// Merge 16 bytes at a time until done
|
|
//
|
|
MrgBy16Bytes:
|
|
lwz r.7,0(r.4) // Get low target value
|
|
lwz r.9,4(r.4 ) // Get high target value
|
|
xor r.7,r.7,r.12 // Merge low 4 bytes of pattern
|
|
xor r.9,r.9,r.3 // Merge high 4 bytes of pattern
|
|
stw r.7,0(r.4) // Store lo 4 bytes of pattern
|
|
stw r.9,4(r.4) // Store hi 4 bytes of pattern
|
|
lwz r.7,8(r.4) // Get low target value
|
|
lwz r.9,12(r.4) // Get high target value
|
|
xor r.7,r.7,r.12 // Merge low 4 bytes of pattern
|
|
xor r.9,r.9,r.3 // Merge high 4 bytes of pattern
|
|
stw r.7,8(r.4) // Store lo 4 bytes of pattern
|
|
stw r.9,12(r.4) // Store hi 4 bytes of pattern
|
|
addi r.4,r.4,16 // Increment the target pointer
|
|
cmpw r.4,r.8 // Check for completion
|
|
bne+ MrgBy16Bytes // Jump if done
|
|
//
|
|
// Merge Pattern exit
|
|
//
|
|
MergeExit:
|
|
LEAF_EXIT(vMergePattern)
|