Home | History | Annotate | Download | only in ppc64asm
      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