// operation. Masks can also extend from the msb and wrap to
// the lsb too. That is, the valid masks are 32 bit strings
// of the form: 0..01..10..0 or 1..10..01..1 or 1...1
+//
+// Note: This ignores the upper 32 bits of the input. When a
+// zero extended result is desired (e.g a 64 bit result), the
+// user must verify the upper 32 bits are 0 and the mask is
+// contiguous (that is, non-wrapping).
func isPPC64WordRotateMask(v64 int64) bool {
// Isolate rightmost 1 (if none 0) and add.
v := uint32(v64)
return (v&vp == 0 || vn&vpn == 0) && v != 0
}
+// Test if this mask is a valid, contiguous bitmask which can be
+// represented by a RLWNM mask and also clears the upper 32 bits
+// of the register.
+func isPPC64WordRotateMaskNonWrapping(v64 int64) bool {
+ // Isolate rightmost 1 (if none 0) and add.
+ v := uint32(v64)
+ vp := (v & -v) + v
+ return (v&vp == 0) && v != 0 && uint64(uint32(v64)) == uint64(v64)
+}
+
// Compress mask and shift into single value of the form
// me | mb<<8 | rotate<<16 | nbits<<24 where me and mb can
// be used to regenerate the input mask.
if rv&uint64(mask) != 0 {
return 0
}
- if !isPPC64WordRotateMask(mask) {
+ if !isPPC64WordRotateMaskNonWrapping(mask) {
return 0
}
return encodePPC64RotateMask((32-s)&31, mask, 32)
if rv&uint64(mask) != 0 {
return 0
}
- if !isPPC64WordRotateMask(mask) {
+ if !isPPC64WordRotateMaskNonWrapping(mask) {
return 0
}
return encodePPC64RotateMask(s&31, mask, 32)
b[1] = b[(v>>20)&0xFF]
// ppc64x: "RLWNM", -"SLD"
b[2] = b[((uint64((uint32(v) >> 21)) & 0x3f) << 4)]
+ // ppc64x: -"RLWNM"
+ b[3] = (b[3] << 24) & 0xFFFFFF000000
+ // ppc64x: "RLWNM\t[$]24, R[0-9]+, [$]0, [$]7,"
+ b[4] = (b[4] << 24) & 0xFF000000
+ // ppc64x: "RLWNM\t[$]24, R[0-9]+, [$]0, [$]7,"
+ b[5] = (b[5] << 24) & 0xFF00000F
+ // ppc64x: -"RLWNM"
+ b[6] = (b[6] << 0) & 0xFF00000F
+ // ppc64x: "RLWNM\t[$]4, R[0-9]+, [$]28, [$]31,"
+ b[7] = (b[7] >> 28) & 0xF
// ppc64x: "RLWNM\t[$]11, R[0-9]+, [$]10, [$]15"
c[0] = c[((v>>5)&0x3F)<<16]
// ppc64x: "ANDCC\t[$]8064,"