1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ppc64asm 6 7 import ( 8 "fmt" 9 "strings" 10 ) 11 12 // A BitField is a bit-field in a 32-bit word. 13 // Bits are counted from 0 from the MSB to 31 as the LSB. 14 type BitField struct { 15 Offs uint8 // the offset of the left-most bit. 16 Bits uint8 // length in bits. 17 } 18 19 func (b BitField) String() string { 20 if b.Bits > 1 { 21 return fmt.Sprintf("[%d:%d]", b.Offs, int(b.Offs+b.Bits)-1) 22 } else if b.Bits == 1 { 23 return fmt.Sprintf("[%d]", b.Offs) 24 } else { 25 return fmt.Sprintf("[%d, len=0]", b.Offs) 26 } 27 } 28 29 // Parse extracts the bitfield b from i, and return it as an unsigned integer. 30 // Parse will panic if b is invalid. 31 func (b BitField) Parse(i uint32) uint32 { 32 if b.Bits > 32 || b.Bits == 0 || b.Offs > 31 || b.Offs+b.Bits > 32 { 33 panic(fmt.Sprintf("invalid bitfiled %v", b)) 34 } 35 return (i >> (32 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1) 36 } 37 38 // ParseSigned extracts the bitfield b from i, and return it as a signed integer. 39 // ParseSigned will panic if b is invalid. 40 func (b BitField) ParseSigned(i uint32) int32 { 41 u := int32(b.Parse(i)) 42 return u << (32 - b.Bits) >> (32 - b.Bits) 43 } 44 45 // BitFields is a series of BitFields representing a single number. 46 type BitFields []BitField 47 48 func (bs BitFields) String() string { 49 ss := make([]string, len(bs)) 50 for i, bf := range bs { 51 ss[i] = bf.String() 52 } 53 return fmt.Sprintf("<%s>", strings.Join(ss, "|")) 54 } 55 56 func (bs *BitFields) Append(b BitField) { 57 *bs = append(*bs, b) 58 } 59 60 // parse extracts the bitfields from i, concatenate them and return the result 61 // as an unsigned integer and the total length of all the bitfields. 62 // parse will panic if any bitfield in b is invalid, but it doesn't check if 63 // the sequence of bitfields is reasonable. 64 func (bs BitFields) parse(i uint32) (u uint32, Bits uint8) { 65 for _, b := range bs { 66 u = (u << b.Bits) | b.Parse(i) 67 Bits += b.Bits 68 } 69 return u, Bits 70 } 71 72 // Parse extracts the bitfields from i, concatenate them and return the result 73 // as an unsigned integer. Parse will panic if any bitfield in b is invalid. 74 func (bs BitFields) Parse(i uint32) uint32 { 75 u, _ := bs.parse(i) 76 return u 77 } 78 79 // Parse extracts the bitfields from i, concatenate them and return the result 80 // as a signed integer. Parse will panic if any bitfield in b is invalid. 81 func (bs BitFields) ParseSigned(i uint32) int32 { 82 u, l := bs.parse(i) 83 return int32(u) << (32 - l) >> (32 - l) 84 } 85