// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package s390x import ( "math/bits" ) // RotateParams represents the immediates required for a "rotate // then ... selected bits instruction". // // The Start and End values are the indexes that represent // the masked region. They are inclusive and are in big- // endian order (bit 0 is the MSB, bit 63 is the LSB). They // may wrap around. // // Some examples: // // Masked region | Start | End // --------------------------+-------+---- // 0x00_00_00_00_00_00_00_0f | 60 | 63 // 0xf0_00_00_00_00_00_00_00 | 0 | 3 // 0xf0_00_00_00_00_00_00_0f | 60 | 3 // // The Amount value represents the amount to rotate the // input left by. Note that this rotation is performed // before the masked region is used. type RotateParams struct { Start uint8 // big-endian start bit index [0..63] End uint8 // big-endian end bit index [0..63] Amount uint8 // amount to rotate left } // NewRotateParams creates a set of parameters representing a // rotation left by the amount provided and a selection of the bits // between the provided start and end indexes (inclusive). // // The start and end indexes and the rotation amount must all // be in the range 0-63 inclusive or this function will panic. func NewRotateParams(start, end, amount uint8) RotateParams { if start&^63 != 0 { panic("start out of bounds") } if end&^63 != 0 { panic("end out of bounds") } if amount&^63 != 0 { panic("amount out of bounds") } return RotateParams{ Start: start, End: end, Amount: amount, } } // RotateLeft generates a new set of parameters with the rotation amount // increased by the given value. The selected bits are left unchanged. func (r RotateParams) RotateLeft(amount uint8) RotateParams { r.Amount += amount r.Amount &= 63 return r } // OutMask provides a mask representing the selected bits. func (r RotateParams) OutMask() uint64 { // Note: z must be unsigned for bootstrap compiler z := uint8(63-r.End+r.Start) & 63 // number of zero bits in mask return bits.RotateLeft64(^uint64(0)<