github.com/jflude/taocp@v0.0.0-20240210234939-99f2a91af3c2/mix/field.go (about)

     1  package mix
     2  
     3  import "errors"
     4  
     5  var ErrInvalidSpec = errors.New("mix: invalid field specification")
     6  
     7  // Spec returns the integer equivalent of a MIX field specification.
     8  func Spec(left, right int) int {
     9  	return 8*left + right
    10  }
    11  
    12  func checkSpec(f int) {
    13  	if f >= len(fields) || fields[f].shift == -1 {
    14  		panic(ErrInvalidSpec)
    15  	}
    16  }
    17  
    18  // Field returns the value of MIX word w's field f, as a MIX word.
    19  func (w Word) Field(f int) Word {
    20  	if f == 5 {
    21  		return w
    22  	}
    23  	checkSpec(f)
    24  	return Word((int32(w) >> fields[f].shift) & fields[f].reg)
    25  }
    26  
    27  // SetField changes the field f of the MIX word w to the given value.
    28  func (w *Word) SetField(f int, val Word) {
    29  	if f == 5 {
    30  		*w = val
    31  		return
    32  	}
    33  	checkSpec(f)
    34  	*w = Word((int32(*w) &^ fields[f].mem) |
    35  		((int32(val) << fields[f].shift) & fields[f].mem) |
    36  		(int32(val) & fields[f].sign))
    37  }
    38  
    39  // PackOp composes a MIX word from a MIX instruction's address, index, field
    40  // and opcode.
    41  func (w *Word) PackOp(aa Word, i, f, c int) {
    42  	*w = Word((int32(aa) & fields[02].sign) |
    43  		(int32(aa) << fields[02].shift & fields[02].mem) |
    44  		(int32(i) << fields[033].shift & fields[033].mem) |
    45  		(int32(f) << fields[044].shift & fields[044].mem) |
    46  		(int32(c) << fields[055].shift & fields[055].mem))
    47  }
    48  
    49  // UnpackOp extracts a MIX instruction's address, index, field and opcode
    50  // from a MIX word.
    51  func (w Word) UnpackOp() (aa Word, i, f, c int) {
    52  	aa = Word((int32(w) >> fields[02].shift) & fields[02].reg)
    53  	i = int((int32(w) & fields[033].mem) >> fields[033].shift)
    54  	f = int((int32(w) & fields[044].mem) >> fields[044].shift)
    55  	c = int((int32(w) & fields[055].mem) >> fields[055].shift)
    56  	return
    57  }
    58  
    59  // PackFloat composes a MIX word from a floating point number's exponent
    60  // and fraction.
    61  func (w *Word) PackFloat(e, f int) {
    62  	*w = Word(0) // TODO
    63  }
    64  
    65  // UnpackFloat extracts the exponent and fraction of a floating point number
    66  // in a MIX word.
    67  func (w Word) UnpackFloat() (e, f int) {
    68  	e = int((int32(w) & fields[011].mem) >> fields[011].shift) // ??
    69  	f = int(0) // TODO
    70  	return
    71  }
    72  
    73  var fields = [...]struct {
    74  	mem   int32 // memory mask
    75  	reg   int32 // register mask
    76  	sign  int32 // sign affected
    77  	shift int   // how much to shift to align receiver and source
    78  }{
    79  	{signBit, signBit, signBit, 0},                              // [0:0]
    80  	{07700000000 | signBit, 00000000077 | signBit, signBit, 24}, // [0:1]
    81  	{07777000000 | signBit, 00000007777 | signBit, signBit, 18}, // [0:2]
    82  	{07777770000 | signBit, 00000777777 | signBit, signBit, 12}, // [0:3]
    83  	{07777777700 | signBit, 00077777777 | signBit, signBit, 6},  // [0:4]
    84  	{07777777777 | signBit, 07777777777 | signBit, signBit, 0},  // [0:5]
    85  	{0, 0, 0, -1},
    86  	{0, 0, 0, -1},
    87  	{0, 0, 0, -1},
    88  	{07700000000, 000000000077, 0, 24}, // [1:1]
    89  	{07777000000, 000000007777, 0, 18}, // [1:2]
    90  	{07777770000, 000000777777, 0, 12}, // [1:3]
    91  	{07777777700, 000077777777, 0, 6},  // [1:4]
    92  	{07777777777, 007777777777, 0, 0},  // [1:5]
    93  	{0, 0, 0, -1},
    94  	{0, 0, 0, -1},
    95  	{0, 0, 0, -1},
    96  	{0, 0, 0, -1},
    97  	{00077000000, 000000000077, 0, 18}, // [2:2]
    98  	{00077770000, 000000007777, 0, 12}, // [2:3]
    99  	{00077777700, 000000777777, 0, 6},  // [2:4]
   100  	{00077777777, 000077777777, 0, 0},  // [2:5]
   101  	{0, 0, 0, -1},
   102  	{0, 0, 0, -1},
   103  	{0, 0, 0, -1},
   104  	{0, 0, 0, -1},
   105  	{0, 0, 0, -1},
   106  	{00000770000, 000000000077, 0, 12}, // [3:3]
   107  	{00000777700, 000000007777, 0, 6},  // [3:4]
   108  	{00000777777, 000000777777, 0, 0},  // [3:5]
   109  	{0, 0, 0, -1},
   110  	{0, 0, 0, -1},
   111  	{0, 0, 0, -1},
   112  	{0, 0, 0, -1},
   113  	{0, 0, 0, -1},
   114  	{0, 0, 0, -1},
   115  	{00000007700, 000000000077, 0, 6}, // [4:4]
   116  	{00000007777, 000000007777, 0, 0}, // [4:5]
   117  	{0, 0, 0, -1},
   118  	{0, 0, 0, -1},
   119  	{0, 0, 0, -1},
   120  	{0, 0, 0, -1},
   121  	{0, 0, 0, -1},
   122  	{0, 0, 0, -1},
   123  	{0, 0, 0, -1},
   124  	{00000000077, 000000000077, 0, 0}, // [5:5]
   125  }