// Copyright 2024 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 s390xasm import ( "fmt" ) // A BitField is a bit-field in a 64-bit double word. // Bits are counted from 0 from the MSB to 63 as the LSB. type BitField struct { Offs uint8 // the offset of the left-most bit. Bits uint8 // length in bits. } func (b BitField) String() string { if b.Bits > 1 { return fmt.Sprintf("[%d:%d]", b.Offs, int(b.Offs+b.Bits)-1) } else if b.Bits == 1 { return fmt.Sprintf("[%d]", b.Offs) } else { return fmt.Sprintf("[%d, len=0]", b.Offs) } } // Parse extracts the bitfield b from i, and return it as an unsigned integer. // Parse will panic if b is invalid. func (b BitField) Parse(i uint64) uint64 { if b.Bits > 64 || b.Bits == 0 || b.Offs > 63 || b.Offs+b.Bits > 64 { panic(fmt.Sprintf("invalid bitfiled %v", b)) } if b.Bits == 20 { return ((((i >> (64 - b.Offs - b.Bits)) & ((1 << 8) - 1)) << 12) | ((i >> (64 - b.Offs - b.Bits + 8)) & 0xFFF)) } else { return (i >> (64 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1) } } // ParseSigned extracts the bitfield b from i, and return it as a signed integer. // ParseSigned will panic if b is invalid. func (b BitField) ParseSigned(i uint64) int64 { u := int64(b.Parse(i)) return u << (64 - b.Bits) >> (64 - b.Bits) }