|
From: Greg P. <gp...@us...> - 2005-09-06 20:56:53
|
Julian Seward writes:
> Let us know of any other insns you need.
I think I'm getting the hang of vex's IR, so I should be able to
write ordinary instructions myself now. I have implementations
of lswi and stswi, though they need a bit more testing.
[lswx/stswx]
> Can you show me the insns in context? In particular it would
> be useful to know how XER is set up prior to the insns.
The uses I've seen so far are the G3 and G4 hand-written bcopy(),
which use lswx/stswx pairs for copying some parts of some lengths.
They're in the Darwin source at xnu:osfmk/ppc/commpage/bcopy_g3.s
and bcopy_g4.s .
Two excerpts are below. They include:
* G3, length <= 32 bytes
* G3, handle misaligned bytes at the start
* G4, handle misaligned bytes at the start.
I've hilited the more relevant instructions in uppercase.
#define rs r4
#define rd r12
#define rc r5
#define w1 r6
#define w2 r7
#define w3 r8
#define w4 r9
#define w5 r10
#define w6 r11
// G3 bcopy(src=r3, dst=r4 (later rd), len=r5)
bcopy_g3:
cmplwi r5,kLong // length > 32 bytes?
sub w1,r4,r3 // must move in reverse if (rd-rs)<rc
mr rd,r4 // start to move source & dest to canonic spot
bge LLong0 // skip if long operand
MTXER r5 // set length for string ops
LSWX r5,0,r3 // load bytes into r5-r12
STSWX r5,0,r4 // store them
blr
// Long operands (more than 32 bytes.)
// w1 = (rd-rs), used to check for alignment
LLong0: // enter from bcopy()
mr rs,r3 // must leave r3 alone (it is return value for memcpy)
LLong1: // enter from memcpy() and memmove()
cmplw cr1,w1,rc // set cr1 blt iff we must move reverse
rlwinm r0,w1,0,0x3 // are operands relatively word-aligned?
NEG w2,rd // prepare to align destination
cmpwi cr5,r0,0 // set cr5 beq if relatively word aligned
blt cr1,LLongReverse // handle reverse move
ANDI. w4,w2,3 // w4 <- #bytes to word align destination
beq cr5,LLongFloat // relatively aligned so use FPRs
sub rc,rc,w4 // adjust count for alignment
srwi r0,rc,5 // get #chunks to xfer (>=1)
rlwinm rc,rc,0,0x1F // mask down to leftover bytes
mtctr r0 // set up loop count
beq 1f // dest already word aligned
// Word align the destination.
MTXER w4 // byte count to xer
cmpwi r0,0 // any chunks to xfer?
LSWX w1,0,rs // move w4 bytes to align dest
add rs,rs,w4
STSWX w1,0,rd
add rd,rd,w4
beq- 2f // pathologic case, no chunks to xfer
1: [...]
// G4 bcopy, "medium" length (32..95 bytes)
// bcopy(src=rs, dst=rd, len=rc)
// Medium and long operands. Use Altivec if long enough, else scalar loops.
// w1 = (rd-rs), used to check for alignment
// cr1 = blt iff we must move reverse
LMedium:
dcbtst 0,rd // touch in destination
cmplwi cr7,rc,kLong // >= 96, long enough for vectors?
NEG w3,rd // start to compute #bytes to align destination
rlwinm r0,w1,0,0x7 // check relative 8-byte alignment
ANDI. w6,w3,7 // w6 <- #bytes to 8-byte align destination
blt cr1,LMediumReverse // handle reverse moves
rlwinm w4,w3,0,0x1F // w4 <- #bytes to 32-byte align destination
cmpwi cr6,r0,0 // set cr6 beq if relatively aligned
bge cr7,LFwdLong // long enough for vectors
// Medium length: use scalar loops.
// w6/cr0 = #bytes to 8-byte align destination
// cr6 = beq if relatively doubleword aligned
sub rc,rc,w6 // decrement length remaining
beq 1f // skip if dest already doubleword aligned
MTXER w6 // set up count for move
LSWX w1,0,rs // move w6 bytes to align destination
STSWX w1,0,rd
[...]
|