// all args take signed inputs, or don't care whether their inputs
// are signed or unsigned.
-// Unused portions of AuxInt are filled by sign-extending the used portion.
-// Users of AuxInt which interpret AuxInt as unsigned (e.g. shifts) must be careful.
var genericOps = []opData{
// 2-input arithmetic
// Types must be consistent with Go typing. Add, for example, must take two values
r = reverseBits[r]
}
if v != nil && w.isGenericIntConst() {
- c := w.AuxInt
// Note: all the +1/-1 below could overflow/underflow. Either will
// still generate correct results, it will just lead to imprecision.
// In fact if there is overflow/underflow, the corresponding
lim := noLimit
switch d {
case signed:
+ c := w.AuxInt
switch r {
case lt:
lim.max = c - 1
lim.umax = uint64(lim.max)
}
case unsigned:
- var uc uint64
- switch w.Op {
- case OpConst64:
- uc = uint64(c)
- case OpConst32:
- uc = uint64(uint32(c))
- case OpConst16:
- uc = uint64(uint16(c))
- case OpConst8:
- uc = uint64(uint8(c))
- }
+ uc := w.AuxUnsigned()
switch r {
case lt:
lim.umax = uc - 1
// Auxiliary info for this value. The type of this information depends on the opcode and type.
// AuxInt is used for integer values, Aux is used for other values.
// Floats are stored in AuxInt using math.Float64bits(f).
+ // Unused portions of AuxInt are filled by sign-extending the used portion,
+ // even if the represented value is unsigned.
+ // Users of AuxInt which interpret AuxInt as unsigned (e.g. shifts) must be careful.
+ // Use Value.AuxUnsigned to get the zero-extended value of AuxInt.
AuxInt int64
Aux interface{}
return int32(v.AuxInt)
}
+// AuxUnsigned returns v.AuxInt as an unsigned value for OpConst*.
+// v.AuxInt is always sign-extended to 64 bits, even if the
+// represented value is unsigned. This undoes that sign extension.
+func (v *Value) AuxUnsigned() uint64 {
+ c := v.AuxInt
+ switch v.Op {
+ case OpConst64:
+ return uint64(c)
+ case OpConst32:
+ return uint64(uint32(c))
+ case OpConst16:
+ return uint64(uint16(c))
+ case OpConst8:
+ return uint64(uint8(c))
+ }
+ v.Fatalf("op %s isn't OpConst*", v.Op)
+ return 0
+}
+
func (v *Value) AuxFloat() float64 {
if opcodeTable[v.Op].auxType != auxFloat32 && opcodeTable[v.Op].auxType != auxFloat64 {
v.Fatalf("op %s doesn't have a float aux field", v.Op)