modernc.org/cc@v1.0.1/v2/operand.go (about)

     1  // Copyright 2017 The CC 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 cc // import "modernc.org/cc/v2"
     6  
     7  // [0]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
     8  
     9  import (
    10  	"fmt"
    11  	"math"
    12  	"math/bits"
    13  
    14  	"modernc.org/ir"
    15  )
    16  
    17  var (
    18  	// [0]6.3.1.1-1
    19  	//
    20  	// Every integer type has an integer conversion rank defined as
    21  	// follows:
    22  	intConvRank = [maxTypeKind]int{
    23  		Bool:      1,
    24  		Char:      2,
    25  		SChar:     2,
    26  		UChar:     2,
    27  		Short:     3,
    28  		UShort:    3,
    29  		Int:       4,
    30  		UInt:      4,
    31  		Long:      5,
    32  		ULong:     5,
    33  		LongLong:  6,
    34  		ULongLong: 6,
    35  	}
    36  
    37  	isSigned = [maxTypeKind]bool{
    38  		Bool:     true,
    39  		Char:     true,
    40  		SChar:    true,
    41  		Short:    true,
    42  		Int:      true,
    43  		Long:     true,
    44  		LongLong: true,
    45  	}
    46  
    47  	isArithmeticType = [maxTypeKind]bool{
    48  		Bool:      true,
    49  		Char:      true,
    50  		Enum:      true,
    51  		Int:       true,
    52  		Long:      true,
    53  		LongLong:  true,
    54  		SChar:     true,
    55  		Short:     true,
    56  		UChar:     true,
    57  		UInt:      true,
    58  		ULong:     true,
    59  		ULongLong: true,
    60  		UShort:    true,
    61  
    62  		Float:      true,
    63  		Double:     true,
    64  		LongDouble: true,
    65  
    66  		FloatImaginary:      true,
    67  		DoubleImaginary:     true,
    68  		LongDoubleImaginary: true,
    69  
    70  		FloatComplex:      true,
    71  		DoubleComplex:     true,
    72  		LongDoubleComplex: true,
    73  	}
    74  )
    75  
    76  // Address represents the address of a variable.
    77  type Address struct { //TODO-
    78  	Declarator *Declarator
    79  	Offset     uintptr
    80  }
    81  
    82  func (a *Address) String() string {
    83  	return fmt.Sprintf("(%s+%d, %s)", dict.S(a.Declarator.Name()), a.Offset, a.Declarator.Linkage)
    84  }
    85  
    86  // UsualArithmeticConversions performs transformations of operands of a binary
    87  // operation. The function panics if either of the operands is not an
    88  // artithmetic type.
    89  //
    90  // [0]6.3.1.8
    91  //
    92  // Many operators that expect operands of arithmetic type cause conversions and
    93  // yield result types in a similar way. The purpose is to determine a common
    94  // real type for the operands and result. For the specified operands, each
    95  // operand is converted, without change of type domain, to a type whose
    96  // corresponding real type is the common real type. Unless explicitly stated
    97  // otherwise, the common real type is also the corresponding real type of the
    98  // result, whose type domain is the type domain of the operands if they are the
    99  // same, and complex otherwise. This pattern is called the usual arithmetic
   100  // conversions:
   101  func UsualArithmeticConversions(m Model, a, b Operand) (Operand, Operand) {
   102  	if !a.isArithmeticType() || !b.isArithmeticType() {
   103  		panic(fmt.Sprint(a, b))
   104  	}
   105  
   106  	a = a.normalize(m)
   107  	b = b.normalize(m)
   108  	// First, if the corresponding real type of either operand is long
   109  	// double, the other operand is converted, without change of type
   110  	// domain, to a type whose corresponding real type is long double.
   111  	if a.Type.Kind() == LongDoubleComplex || b.Type.Kind() == LongDoubleComplex {
   112  		return a.ConvertTo(m, LongDoubleComplex), b.ConvertTo(m, LongDoubleComplex)
   113  	}
   114  
   115  	if a.Type.Kind() == LongDouble || b.Type.Kind() == LongDouble {
   116  		return a.ConvertTo(m, LongDouble), b.ConvertTo(m, LongDouble)
   117  	}
   118  
   119  	// Otherwise, if the corresponding real type of either operand is
   120  	// double, the other operand is converted, without change of type
   121  	// domain, to a type whose corresponding real type is double.
   122  	if a.Type.Kind() == DoubleComplex || b.Type.Kind() == DoubleComplex {
   123  		return a.ConvertTo(m, DoubleComplex), b.ConvertTo(m, DoubleComplex)
   124  	}
   125  
   126  	if a.Type.Kind() == Double || b.Type.Kind() == Double {
   127  		return a.ConvertTo(m, Double), b.ConvertTo(m, Double)
   128  	}
   129  
   130  	// Otherwise, if the corresponding real type of either operand is
   131  	// float, the other operand is converted, without change of type
   132  	// domain, to a type whose corresponding real type is float.)
   133  	if a.Type.Kind() == FloatComplex || b.Type.Kind() == FloatComplex {
   134  		return a.ConvertTo(m, FloatComplex), b.ConvertTo(m, FloatComplex)
   135  	}
   136  
   137  	if a.Type.Kind() == Float || b.Type.Kind() == Float {
   138  		return a.ConvertTo(m, Float), b.ConvertTo(m, Float)
   139  	}
   140  
   141  	// Otherwise, the integer promotions are performed on both operands.
   142  	// Then the following rules are applied to the promoted operands:
   143  	if !a.isIntegerType() || !b.isIntegerType() {
   144  		//dbg("", a)
   145  		//dbg("", b)
   146  		panic("TODO")
   147  	}
   148  
   149  	a = a.integerPromotion(m)
   150  	b = b.integerPromotion(m)
   151  
   152  	// If both operands have the same type, then no further conversion is
   153  	// needed.
   154  	if a.Type.Equal(b.Type) {
   155  		return a, b
   156  	}
   157  
   158  	// Otherwise, if both operands have signed integer types or both have
   159  	// unsigned integer types, the operand with the type of lesser integer
   160  	// conversion rank is converted to the type of the operand with greater
   161  	// rank.
   162  	if a.isSigned() == b.isSigned() {
   163  		t := a.Type
   164  		if intConvRank[b.Type.Kind()] > intConvRank[a.Type.Kind()] {
   165  			t = b.Type
   166  		}
   167  		return a.ConvertTo(m, t), b.ConvertTo(m, t)
   168  	}
   169  
   170  	// Otherwise, if the operand that has unsigned integer type has rank
   171  	// greater or equal to the rank of the type of the other operand, then
   172  	// the operand with signed integer type is converted to the type of the
   173  	// operand with unsigned integer type.
   174  	switch {
   175  	case a.isSigned(): // b is unsigned
   176  		if intConvRank[b.Type.Kind()] >= intConvRank[a.Type.Kind()] {
   177  			return a.ConvertTo(m, b.Type), b
   178  		}
   179  	case b.isSigned(): // a is unsigned
   180  		if intConvRank[a.Type.Kind()] >= intConvRank[b.Type.Kind()] {
   181  			return a, b.ConvertTo(m, a.Type)
   182  		}
   183  	default:
   184  		panic(fmt.Errorf("TODO %v %v", a, b))
   185  	}
   186  
   187  	var signed Type
   188  	// Otherwise, if the type of the operand with signed integer type can
   189  	// represent all of the values of the type of the operand with unsigned
   190  	// integer type, then the operand with unsigned integer type is
   191  	// converted to the type of the operand with signed integer type.
   192  	switch {
   193  	case a.isSigned(): // b is unsigned
   194  		signed = a.Type
   195  		if m.Sizeof(a.Type) > m.Sizeof(b.Type) {
   196  			return a, b.ConvertTo(m, a.Type)
   197  		}
   198  	case b.isSigned(): // a is unsigned
   199  		signed = b.Type
   200  		if m.Sizeof(b.Type) > m.Sizeof(a.Type) {
   201  			return a.ConvertTo(m, b.Type), b
   202  		}
   203  	default:
   204  		panic(fmt.Errorf("TODO %v %v", a, b))
   205  	}
   206  
   207  	// Otherwise, both operands are converted to the unsigned integer type
   208  	// corresponding to the type of the operand with signed integer type.
   209  	switch signed.Kind() {
   210  	case Int:
   211  		if a.IsEnumConst || b.IsEnumConst {
   212  			return a, b
   213  		}
   214  
   215  		return a.ConvertTo(m, UInt), b.ConvertTo(m, UInt)
   216  	case Long:
   217  		return a.ConvertTo(m, ULong), b.ConvertTo(m, ULong)
   218  	case LongLong:
   219  		return a.ConvertTo(m, ULongLong), b.ConvertTo(m, ULongLong)
   220  	default:
   221  		panic(signed)
   222  	}
   223  }
   224  
   225  // Operand represents the type and optionally the value of an expression.
   226  type Operand struct {
   227  	Type Type
   228  	ir.Value
   229  	FieldProperties *FieldProperties
   230  
   231  	IsEnumConst bool // Blocks int -> unsigned int promotions. See [0]6.4.4.3/2
   232  }
   233  
   234  // Bits return the width of a bit field operand or zero othewise
   235  func (o *Operand) Bits() int {
   236  	if fp := o.FieldProperties; fp != nil {
   237  		return fp.Bits
   238  	}
   239  
   240  	return 0
   241  }
   242  
   243  func newIntConst(ctx *context, n Node, v uint64, t ...TypeKind) (r Operand) {
   244  	b := bits.Len64(v)
   245  	for _, t := range t {
   246  		sign := 1
   247  		if t.IsUnsigned() {
   248  			sign = 0
   249  		}
   250  		if ctx.model[t].Size*8 >= b+sign {
   251  			return Operand{Type: t, Value: &ir.Int64Value{Value: int64(v)}}.normalize(ctx.model)
   252  		}
   253  	}
   254  
   255  	last := t[len(t)-1]
   256  	if ctx.model[last].Size*8 == b {
   257  		return Operand{Type: last, Value: &ir.Int64Value{Value: int64(v)}}.normalize(ctx.model)
   258  	}
   259  
   260  	ctx.err(n, "invalid integer constant")
   261  	return Operand{Type: Int}.normalize(ctx.model)
   262  }
   263  
   264  func (o Operand) String() string {
   265  	return fmt.Sprintf("(type %v, value %v, fieldProps %+v)", o.Type, o.Value, o.FieldProperties)
   266  }
   267  
   268  func (o Operand) isArithmeticType() bool { return o.Type.IsArithmeticType() }
   269  func (o Operand) isIntegerType() bool    { return o.Type.IsIntegerType() }
   270  func (o Operand) isPointerType() bool    { return o.Type.IsPointerType() }
   271  func (o Operand) isScalarType() bool     { return o.Type.IsScalarType() } // [0]6.2.5-21
   272  func (o Operand) isSigned() bool         { return isSigned[o.Type.Kind()] }
   273  
   274  func (o Operand) add(ctx *context, p Operand) (r Operand) {
   275  	o, p = UsualArithmeticConversions(ctx.model, o, p)
   276  	if p.IsZero() {
   277  		return o.normalize(ctx.model)
   278  	}
   279  
   280  	if o.Value == nil || p.Value == nil {
   281  		o.Value = nil
   282  		return o.normalize(ctx.model)
   283  	}
   284  
   285  	switch x := o.Value.(type) {
   286  	case *ir.Int64Value:
   287  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value + p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
   288  	case *ir.Float64Value:
   289  		return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value + p.Value.(*ir.Float64Value).Value}}.normalize(ctx.model)
   290  	default:
   291  		panic(fmt.Errorf("TODO %T %v %v", x, o, p))
   292  	}
   293  }
   294  
   295  func (o Operand) and(ctx *context, p Operand) (r Operand) {
   296  	if !o.isIntegerType() || !p.isIntegerType() {
   297  		panic(fmt.Errorf("TODO %v & %v", o, p))
   298  	}
   299  
   300  	o, p = UsualArithmeticConversions(ctx.model, o, p)
   301  	if o.IsZero() || p.IsZero() {
   302  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: 0}}.normalize(ctx.model)
   303  	}
   304  
   305  	if o.Value == nil || p.Value == nil {
   306  		return Operand{Type: o.Type}.normalize(ctx.model)
   307  	}
   308  
   309  	switch x := o.Value.(type) {
   310  	case *ir.Int64Value:
   311  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value & p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
   312  	default:
   313  		panic(fmt.Errorf("TODO %T", x))
   314  	}
   315  }
   316  
   317  // ConvertTo converts o to type t.
   318  func (o Operand) ConvertTo(m Model, t Type) (r Operand) {
   319  	if o.Type.Equal(t) {
   320  		return o.normalize(m)
   321  	}
   322  
   323  	switch x := t.(type) {
   324  	case
   325  		*EnumType,
   326  		*PointerType,
   327  		*TaggedEnumType,
   328  		*TaggedUnionType:
   329  
   330  		// ok
   331  	case TypeKind:
   332  		switch x {
   333  		case
   334  			Bool,
   335  			Char,
   336  			Double,
   337  			DoubleComplex,
   338  			DoubleImaginary,
   339  			Float,
   340  			FloatComplex,
   341  			FloatImaginary,
   342  			Int,
   343  			Long,
   344  			LongDouble,
   345  			LongDoubleComplex,
   346  			LongDoubleImaginary,
   347  			LongLong,
   348  			SChar,
   349  			Short,
   350  			UChar,
   351  			UInt,
   352  			ULong,
   353  			ULongLong,
   354  			UShort:
   355  
   356  			// ok
   357  		default:
   358  			panic(x)
   359  		}
   360  	case *NamedType:
   361  		return o.ConvertTo(m, x.Type)
   362  	default:
   363  		panic(fmt.Errorf("%T", x))
   364  	}
   365  
   366  	if o.Value == nil {
   367  		o.Type = t
   368  		return o.normalize(m)
   369  	}
   370  
   371  	if o.isIntegerType() {
   372  		v := *o.Value.(*ir.Int64Value)
   373  		if t.IsIntegerType() {
   374  			return Operand{Type: t, Value: &v}.normalize(m)
   375  		}
   376  
   377  		if t.IsPointerType() {
   378  			// [0]6.3.2.3
   379  			if o.IsZero() {
   380  				// 3. An integer constant expression with the
   381  				// value 0, or such an expression cast to type
   382  				// void *, is called a null pointer constant.
   383  				// If a null pointer constant is converted to a
   384  				// pointer type, the resulting pointer, called
   385  				// a null pointer, is guaranteed to compare
   386  				// unequal to a pointer to any object or
   387  				// function.
   388  				return Operand{Type: t, Value: Null}
   389  			}
   390  
   391  			return Operand{Type: t, Value: &v}.normalize(m)
   392  		}
   393  
   394  		if t.Kind() == Union {
   395  			if v.Value != 0 {
   396  				panic("TODO")
   397  			}
   398  
   399  			return Operand{Type: t}
   400  		}
   401  
   402  		switch {
   403  		case o.Type.IsUnsigned():
   404  			val := uint64(v.Value)
   405  			switch t.Kind() {
   406  			case Double, LongDouble:
   407  				return Operand{Type: t, Value: &ir.Float64Value{Value: float64(val)}}.normalize(m)
   408  			case DoubleComplex:
   409  				return Operand{Type: t, Value: &ir.Complex128Value{Value: complex(float64(val), 0)}}.normalize(m)
   410  			case Float:
   411  				return Operand{Type: t, Value: &ir.Float32Value{Value: float32(val)}}.normalize(m)
   412  			case FloatComplex:
   413  				return Operand{Type: t, Value: &ir.Complex64Value{Value: complex(float32(val), 0)}}.normalize(m)
   414  			default:
   415  				panic(t)
   416  			}
   417  		default:
   418  			val := v.Value
   419  			switch t.Kind() {
   420  			case Double, LongDouble:
   421  				return Operand{Type: t, Value: &ir.Float64Value{Value: float64(val)}}.normalize(m)
   422  			case DoubleComplex:
   423  				return Operand{Type: t, Value: &ir.Complex128Value{Value: complex(float64(val), 0)}}.normalize(m)
   424  			case Float:
   425  				return Operand{Type: t, Value: &ir.Float32Value{Value: float32(val)}}.normalize(m)
   426  			case FloatComplex:
   427  				return Operand{Type: t, Value: &ir.Complex64Value{Value: complex(float32(val), 0)}}.normalize(m)
   428  			default:
   429  				panic(t)
   430  			}
   431  		}
   432  	}
   433  
   434  	if o.Type.Kind() == Double {
   435  		v := o.Value.(*ir.Float64Value).Value
   436  		if t.IsIntegerType() {
   437  			return Operand{Type: t, Value: &ir.Int64Value{Value: ConvertFloat64(v, t, m)}}.normalize(m)
   438  		}
   439  
   440  		switch x := t.(type) {
   441  		case TypeKind:
   442  			switch x {
   443  			case Float:
   444  				return Operand{Type: t, Value: &ir.Float32Value{Value: float32(o.Value.(*ir.Float64Value).Value)}}.normalize(m)
   445  			case LongDouble:
   446  				v := *o.Value.(*ir.Float64Value)
   447  				return Operand{Type: t, Value: &v}.normalize(m)
   448  			default:
   449  				panic(x)
   450  			}
   451  		default:
   452  			panic(x)
   453  		}
   454  	}
   455  
   456  	if o.Type.Kind() == Float {
   457  		v := o.Value.(*ir.Float32Value).Value
   458  		if t.IsIntegerType() {
   459  			return Operand{Type: t, Value: &ir.Int64Value{Value: ConvertFloat64(float64(v), t, m)}}.normalize(m)
   460  		}
   461  
   462  		switch x := t.(type) {
   463  		case TypeKind:
   464  			switch x {
   465  			case
   466  				Double,
   467  				LongDouble:
   468  
   469  				return Operand{Type: t, Value: &ir.Float64Value{Value: float64(v)}}.normalize(m)
   470  			default:
   471  				panic(x)
   472  			}
   473  		default:
   474  			panic(x)
   475  		}
   476  	}
   477  
   478  	if o.isPointerType() && t.IsPointerType() {
   479  		o.Type = t
   480  		return o.normalize(m)
   481  	}
   482  
   483  	if o.isPointerType() && t.IsIntegerType() {
   484  		o.Type = t
   485  		switch x := o.Value.(type) {
   486  		case *ir.AddressValue:
   487  			if x.NameID != 0 {
   488  				o.Value = nil
   489  				break
   490  			}
   491  
   492  			o.Value = &ir.Int64Value{Value: int64(x.Offset)}
   493  		case
   494  			*ir.Int64Value,
   495  			*ir.StringValue:
   496  
   497  			// nop
   498  		default:
   499  			//fmt.Printf("TODO405 %T %v -> %v\n", x, o, t) //TODO-
   500  			panic(fmt.Errorf("%T %v -> %v", x, o, t))
   501  		}
   502  		return o.normalize(m)
   503  	}
   504  
   505  	panic(fmt.Errorf("%T(%v) -> %T(%v)", o.Type, o, t, t))
   506  }
   507  
   508  func (o Operand) cpl(ctx *context) Operand {
   509  	if o.isIntegerType() {
   510  		o = o.integerPromotion(ctx.model)
   511  	}
   512  
   513  	switch x := o.Value.(type) {
   514  	case nil:
   515  		return o
   516  	case *ir.Int64Value:
   517  		o.Value = &ir.Int64Value{Value: ^o.Value.(*ir.Int64Value).Value}
   518  		return o.normalize(ctx.model)
   519  	default:
   520  		panic(fmt.Errorf("TODO %T", x))
   521  	}
   522  }
   523  
   524  func (o Operand) div(ctx *context, n Node, p Operand) (r Operand) {
   525  	o, p = UsualArithmeticConversions(ctx.model, o, p)
   526  	if o.Value == nil || p.Value == nil {
   527  		o.Value = nil
   528  		return o.normalize(ctx.model)
   529  	}
   530  
   531  	switch x := o.Value.(type) {
   532  	case *ir.Int64Value:
   533  		if p.IsZero() {
   534  			ctx.err(n, "division by zero")
   535  			return Operand{Type: o.Type}.normalize(ctx.model)
   536  		}
   537  
   538  		switch {
   539  		case o.Type.IsUnsigned():
   540  			return Operand{Type: o.Type, Value: &ir.Int64Value{Value: int64(uint64(x.Value) / uint64(p.Value.(*ir.Int64Value).Value))}}.normalize(ctx.model)
   541  		default:
   542  			return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value / p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
   543  		}
   544  	case *ir.Float32Value:
   545  		return Operand{Type: o.Type, Value: &ir.Float32Value{Value: x.Value / p.Value.(*ir.Float32Value).Value}}.normalize(ctx.model)
   546  	case *ir.Float64Value:
   547  		return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value / p.Value.(*ir.Float64Value).Value}}.normalize(ctx.model)
   548  	default:
   549  		panic(fmt.Errorf("TODO %T", x))
   550  	}
   551  }
   552  
   553  func (o Operand) eq(ctx *context, p Operand) (r Operand) {
   554  	r = Operand{Type: Int}
   555  	if o.isArithmeticType() && p.isArithmeticType() {
   556  		o, p = UsualArithmeticConversions(ctx.model, o, p)
   557  	}
   558  	if o.Value == nil || p.Value == nil {
   559  		return r.normalize(ctx.model)
   560  	}
   561  
   562  	switch x := o.Value.(type) {
   563  	case *ir.Int64Value:
   564  		var val int64
   565  		if x.Value == p.Value.(*ir.Int64Value).Value {
   566  			val = 1
   567  		}
   568  		r.Value = &ir.Int64Value{Value: val}
   569  	case *ir.Float64Value:
   570  		var val int64
   571  		if x.Value == p.Value.(*ir.Float64Value).Value {
   572  			val = 1
   573  		}
   574  		r.Value = &ir.Int64Value{Value: val}
   575  	default:
   576  		panic(fmt.Errorf("TODO %T", x))
   577  	}
   578  	return r.normalize(ctx.model)
   579  }
   580  
   581  func (o Operand) ge(ctx *context, p Operand) (r Operand) {
   582  	r = Operand{Type: Int}
   583  	if o.isArithmeticType() && p.isArithmeticType() {
   584  		o, p = UsualArithmeticConversions(ctx.model, o, p)
   585  	}
   586  	if o.Value == nil || p.Value == nil {
   587  		return r.normalize(ctx.model)
   588  	}
   589  
   590  	switch x := o.Value.(type) {
   591  	case *ir.Int64Value:
   592  		var val int64
   593  		switch {
   594  		case o.isSigned():
   595  			if x.Value >= p.Value.(*ir.Int64Value).Value {
   596  				val = 1
   597  			}
   598  		default:
   599  			if uint64(x.Value) >= uint64(p.Value.(*ir.Int64Value).Value) {
   600  				val = 1
   601  			}
   602  		}
   603  		r.Value = &ir.Int64Value{Value: val}
   604  	case *ir.Float64Value:
   605  		var val int64
   606  		if x.Value >= p.Value.(*ir.Float64Value).Value {
   607  			val = 1
   608  		}
   609  		r.Value = &ir.Int64Value{Value: val}
   610  	default:
   611  		panic(fmt.Errorf("TODO %T", x))
   612  	}
   613  	return r.normalize(ctx.model)
   614  }
   615  
   616  func (o Operand) gt(ctx *context, p Operand) (r Operand) {
   617  	r = Operand{Type: Int}
   618  	if o.isArithmeticType() && p.isArithmeticType() {
   619  		o, p = UsualArithmeticConversions(ctx.model, o, p)
   620  	}
   621  	if o.Value == nil || p.Value == nil {
   622  		return r.normalize(ctx.model)
   623  	}
   624  
   625  	switch x := o.Value.(type) {
   626  	case *ir.Int64Value:
   627  		var val int64
   628  		switch {
   629  		case o.isSigned():
   630  			if x.Value > p.Value.(*ir.Int64Value).Value {
   631  				val = 1
   632  			}
   633  		default:
   634  			if uint64(x.Value) > uint64(p.Value.(*ir.Int64Value).Value) {
   635  				val = 1
   636  			}
   637  		}
   638  		r.Value = &ir.Int64Value{Value: val}
   639  	case *ir.Float64Value:
   640  		var val int64
   641  		if x.Value > p.Value.(*ir.Float64Value).Value {
   642  			val = 1
   643  		}
   644  		r.Value = &ir.Int64Value{Value: val}
   645  	default:
   646  		panic(fmt.Errorf("TODO %T", x))
   647  	}
   648  	return r.normalize(ctx.model)
   649  }
   650  
   651  // integerPromotion computes the integer promotion of o.
   652  //
   653  // [0]6.3.1.1-2
   654  //
   655  // If an int can represent all values of the original type, the value is
   656  // converted to an int; otherwise, it is converted to an unsigned int. These
   657  // are called the integer promotions. All other types are unchanged by the
   658  // integer promotions.
   659  func (o Operand) integerPromotion(m Model) Operand {
   660  	t := o.Type
   661  	for {
   662  		switch x := t.(type) {
   663  		case *EnumType:
   664  			t = x.Enums[0].Operand.Type
   665  		case *NamedType:
   666  			t = x.Type
   667  		case *TaggedEnumType:
   668  			t = x.getType().(*EnumType).Enums[0].Operand.Type
   669  		case TypeKind:
   670  			// github.com/gcc-mirror/gcc/gcc/testsuite/gcc.c-torture/execute/bf-sign-2.c
   671  			//
   672  			// This test checks promotion of bitfields.  Bitfields
   673  			// should be promoted very much like chars and shorts:
   674  			//
   675  			// Bitfields (signed or unsigned) should be promoted to
   676  			// signed int if their value will fit in a signed int,
   677  			// otherwise to an unsigned int if their value will fit
   678  			// in an unsigned int, otherwise we don't promote them
   679  			// (ANSI/ISO does not specify the behavior of bitfields
   680  			// larger than an unsigned int).
   681  			if x.IsIntegerType() && o.Bits() != 0 {
   682  				bits := m[Int].Size * 8
   683  				switch {
   684  				case x.IsUnsigned():
   685  					if o.Bits() < bits {
   686  						return o.ConvertTo(m, Int)
   687  					}
   688  				default:
   689  					if o.Bits() < bits-1 {
   690  						return o.ConvertTo(m, Int)
   691  					}
   692  				}
   693  			}
   694  
   695  			switch x {
   696  			case
   697  				Double,
   698  				Float,
   699  				Int,
   700  				Long,
   701  				LongDouble,
   702  				LongLong,
   703  				UInt,
   704  				ULong,
   705  				ULongLong:
   706  
   707  				return o
   708  			case
   709  				Char,
   710  				SChar,
   711  				Short,
   712  				UChar,
   713  				UShort:
   714  
   715  				return o.ConvertTo(m, Int)
   716  			default:
   717  				panic(x)
   718  			}
   719  		default:
   720  			panic(x)
   721  		}
   722  	}
   723  }
   724  
   725  // IsNonZero returns true when the value of o is known to be non-zero.
   726  func (o Operand) IsNonZero() bool {
   727  	switch x := o.Value.(type) {
   728  	case nil:
   729  		return false
   730  	case *ir.Float32Value:
   731  		return x.Value != 0
   732  	case *ir.Float64Value:
   733  		return x.Value != 0
   734  	case *ir.Int64Value:
   735  		return x.Value != 0
   736  	case *ir.StringValue:
   737  		return true
   738  	case *ir.AddressValue:
   739  		return x != Null
   740  	default:
   741  		panic(fmt.Errorf("TODO %T", x))
   742  	}
   743  }
   744  
   745  // IsZero returns true when the value of o is known to be zero.
   746  func (o Operand) IsZero() bool {
   747  	switch x := o.Value.(type) {
   748  	case nil:
   749  		return false
   750  	case *ir.Complex128Value:
   751  		return x.Value == 0
   752  	case *ir.Float32Value:
   753  		return x.Value == 0
   754  	case *ir.Float64Value:
   755  		return x.Value == 0
   756  	case *ir.Int64Value:
   757  		return x.Value == 0
   758  	case
   759  		*ir.StringValue,
   760  		*ir.WideStringValue:
   761  
   762  		return false
   763  	case *ir.AddressValue:
   764  		return x == Null
   765  	default:
   766  		panic(fmt.Errorf("TODO %T", x))
   767  	}
   768  }
   769  
   770  func (o Operand) isNullPtrConst() bool {
   771  	return o.isIntegerType() && o.IsZero() || o.Value == Null
   772  }
   773  
   774  func (o Operand) le(ctx *context, p Operand) (r Operand) {
   775  	r = Operand{Type: Int}
   776  	if o.isArithmeticType() && p.isArithmeticType() {
   777  		o, p = UsualArithmeticConversions(ctx.model, o, p)
   778  	}
   779  	if o.Value == nil || p.Value == nil {
   780  		return r.normalize(ctx.model)
   781  	}
   782  
   783  	switch x := o.Value.(type) {
   784  	case *ir.Int64Value:
   785  		var val int64
   786  		switch {
   787  		case o.isSigned():
   788  			if x.Value <= p.Value.(*ir.Int64Value).Value {
   789  				val = 1
   790  			}
   791  		default:
   792  			if uint64(x.Value) <= uint64(p.Value.(*ir.Int64Value).Value) {
   793  				val = 1
   794  			}
   795  		}
   796  		r.Value = &ir.Int64Value{Value: val}
   797  	case *ir.Float64Value:
   798  		var val int64
   799  		if x.Value <= p.Value.(*ir.Float64Value).Value {
   800  			val = 1
   801  		}
   802  		r.Value = &ir.Int64Value{Value: val}
   803  	default:
   804  		panic(fmt.Errorf("TODO %T", x))
   805  	}
   806  	return r.normalize(ctx.model)
   807  }
   808  
   809  func (o Operand) lsh(ctx *context, p Operand) (r Operand) { // [0]6.5.7
   810  	// 2. Each of the operands shall have integer type.
   811  	if !o.isIntegerType() || !p.isIntegerType() {
   812  		panic("TODO")
   813  	}
   814  
   815  	// 3. The integer promotions are performed on each of the operands. The
   816  	// type of the result is that of the promoted left operand. If the
   817  	// value of the right operand is negative or is greater than or equal
   818  	// to the width of the promoted left operand, the behavior is
   819  	// undefined.
   820  	o = o.integerPromotion(ctx.model)
   821  	p = p.integerPromotion(ctx.model)
   822  	if o.IsZero() {
   823  		return o.normalize(ctx.model)
   824  	}
   825  
   826  	m := uint64(32)
   827  	if ctx.model.Sizeof(o.Type) > 4 {
   828  		m = 64
   829  	}
   830  	if o.Value == nil || p.Value == nil {
   831  		return Operand{Type: o.Type}.normalize(ctx.model)
   832  	}
   833  
   834  	switch x := o.Value.(type) {
   835  	case *ir.Int64Value:
   836  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value << (uint64(p.Value.(*ir.Int64Value).Value) % m)}}.normalize(ctx.model)
   837  	default:
   838  		panic(fmt.Errorf("TODO %T", x))
   839  	}
   840  }
   841  
   842  func (o Operand) lt(ctx *context, p Operand) (r Operand) {
   843  	r = Operand{Type: Int}
   844  	if o.isArithmeticType() && p.isArithmeticType() {
   845  		o, p = UsualArithmeticConversions(ctx.model, o, p)
   846  	}
   847  	if o.Value == nil || p.Value == nil {
   848  		return r.normalize(ctx.model)
   849  	}
   850  
   851  	switch x := o.Value.(type) {
   852  	case *ir.Int64Value:
   853  		var val int64
   854  		switch {
   855  		case o.isSigned():
   856  			if x.Value < p.Value.(*ir.Int64Value).Value {
   857  				val = 1
   858  			}
   859  		default:
   860  			if uint64(x.Value) < uint64(p.Value.(*ir.Int64Value).Value) {
   861  				val = 1
   862  			}
   863  		}
   864  		r.Value = &ir.Int64Value{Value: val}
   865  	case *ir.Float64Value:
   866  		var val int64
   867  		if x.Value < p.Value.(*ir.Float64Value).Value {
   868  			val = 1
   869  		}
   870  		r.Value = &ir.Int64Value{Value: val}
   871  	default:
   872  		panic(fmt.Errorf("TODO %T", x))
   873  	}
   874  	return r.normalize(ctx.model)
   875  }
   876  
   877  func (o Operand) mod(ctx *context, n Node, p Operand) (r Operand) {
   878  	o, p = UsualArithmeticConversions(ctx.model, o, p)
   879  	if p.IsZero() {
   880  		ctx.err(n, "division by zero")
   881  		return p.normalize(ctx.model)
   882  	}
   883  
   884  	if o.IsZero() { // 0 % x == 0
   885  		return o.normalize(ctx.model)
   886  	}
   887  
   888  	if y, ok := p.Value.(*ir.Int64Value); ok && (y.Value == 1 || y.Value == -1) {
   889  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: 0}}.normalize(ctx.model) //  y % {1,-1} == 0
   890  	}
   891  
   892  	if o.Value == nil || p.Value == nil {
   893  		return Operand{Type: o.Type}.normalize(ctx.model)
   894  	}
   895  
   896  	switch x := o.Value.(type) {
   897  	case *ir.Int64Value:
   898  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value % p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
   899  	default:
   900  		panic(fmt.Errorf("TODO %T", x))
   901  	}
   902  }
   903  
   904  func (o Operand) mul(ctx *context, p Operand) (r Operand) {
   905  	o, p = UsualArithmeticConversions(ctx.model, o, p)
   906  	if o.IsZero() || p.IsZero() {
   907  		switch x := UnderlyingType(o.Type).(type) {
   908  		case TypeKind:
   909  			if x.IsIntegerType() {
   910  				return Operand{Type: o.Type, Value: &ir.Int64Value{Value: 0}}.normalize(ctx.model)
   911  			}
   912  		default:
   913  			panic(fmt.Errorf("TODO %T", x))
   914  		}
   915  	}
   916  
   917  	if o.Value == nil || p.Value == nil {
   918  		return Operand{Type: o.Type}.normalize(ctx.model)
   919  	}
   920  
   921  	switch x := o.Value.(type) {
   922  	case *ir.Int64Value:
   923  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value * p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
   924  	case *ir.Float32Value:
   925  		return Operand{Type: o.Type, Value: &ir.Float32Value{Value: x.Value * p.Value.(*ir.Float32Value).Value}}
   926  	case *ir.Float64Value:
   927  		return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value * p.Value.(*ir.Float64Value).Value}}
   928  	default:
   929  		panic(fmt.Errorf("TODO %T", x))
   930  	}
   931  }
   932  
   933  func (o Operand) ne(ctx *context, p Operand) (r Operand) {
   934  	r = Operand{Type: Int}
   935  	if o.isArithmeticType() && p.isArithmeticType() {
   936  		o, p = UsualArithmeticConversions(ctx.model, o, p)
   937  	}
   938  	if o.Value == nil || p.Value == nil {
   939  		return r.normalize(ctx.model)
   940  	}
   941  
   942  	switch x := o.Value.(type) {
   943  	case *ir.Int64Value:
   944  		var val int64
   945  		if x.Value != p.Value.(*ir.Int64Value).Value {
   946  			val = 1
   947  		}
   948  		r.Value = &ir.Int64Value{Value: val}
   949  	case *ir.Float32Value:
   950  		var val int64
   951  		if x.Value != p.Value.(*ir.Float32Value).Value {
   952  			val = 1
   953  		}
   954  		r.Value = &ir.Int64Value{Value: val}
   955  	case *ir.Float64Value:
   956  		var val int64
   957  		if x.Value != p.Value.(*ir.Float64Value).Value {
   958  			val = 1
   959  		}
   960  		r.Value = &ir.Int64Value{Value: val}
   961  	default:
   962  		panic(fmt.Errorf("TODO %T", x))
   963  	}
   964  	return r.normalize(ctx.model)
   965  }
   966  
   967  // ConvertFloat64 converts v to t, which must be an integer type.
   968  func ConvertFloat64(v float64, t Type, m Model) int64 {
   969  	if !t.IsIntegerType() {
   970  		panic(fmt.Errorf("ConvertFloat64: %T", t))
   971  	}
   972  
   973  	switch sz := m.Sizeof(t); {
   974  	case t.IsUnsigned():
   975  		switch sz {
   976  		case 1:
   977  			if v > math.Nextafter(math.MaxUint8, 0) {
   978  				return math.MaxUint8
   979  			}
   980  
   981  			if v <= 0 {
   982  				return 0
   983  			}
   984  		case 2:
   985  			if v > math.Nextafter(math.MaxUint16, 0) {
   986  				return math.MaxUint16
   987  			}
   988  
   989  			if v <= 0 {
   990  				return 0
   991  			}
   992  		case 4:
   993  			if v > math.Nextafter(math.MaxUint32, 0) {
   994  				return math.MaxUint32
   995  			}
   996  
   997  			if v <= 0 {
   998  				return 0
   999  			}
  1000  		case 8:
  1001  			if v > math.Nextafter(math.MaxUint64, 0) {
  1002  				return -1 // int64(math,MaxUint64)
  1003  			}
  1004  
  1005  			if v <= 0 {
  1006  				return 0
  1007  			}
  1008  		default:
  1009  			panic(sz)
  1010  		}
  1011  	default:
  1012  		switch sz {
  1013  		case 1:
  1014  			if v > math.Nextafter(math.MaxInt8, 0) {
  1015  				return math.MaxInt8
  1016  			}
  1017  
  1018  			if v < math.Nextafter(math.MinInt8, 0) {
  1019  				return math.MinInt8
  1020  			}
  1021  		case 2:
  1022  			if v > math.Nextafter(math.MaxInt16, 0) {
  1023  				return math.MaxInt16
  1024  			}
  1025  
  1026  			if v < math.Nextafter(math.MinInt16, 0) {
  1027  				return math.MinInt16
  1028  			}
  1029  		case 4:
  1030  			if v > math.Nextafter(math.MaxInt32, 0) {
  1031  				return math.MaxInt32
  1032  			}
  1033  
  1034  			if v < math.Nextafter(math.MinInt32, 0) {
  1035  				return math.MinInt32
  1036  			}
  1037  		case 8:
  1038  			if v > math.Nextafter(math.MaxInt64, 0) {
  1039  				return math.MaxInt64
  1040  			}
  1041  
  1042  			if v < math.Nextafter(math.MinInt64, 0) {
  1043  				return math.MinInt64
  1044  			}
  1045  		default:
  1046  			panic(sz)
  1047  		}
  1048  	}
  1049  	return int64(v)
  1050  }
  1051  
  1052  // ConvertInt64 converts n to t, which must be an integer or enum type, doing
  1053  // masking and/or sign extending as appropriate.
  1054  func ConvertInt64(n int64, t Type, m Model) int64 {
  1055  	switch x := UnderlyingType(t).(type) {
  1056  	case *EnumType:
  1057  		t = x.Enums[0].Operand.Type
  1058  	}
  1059  	signed := !t.IsUnsigned()
  1060  	switch sz := m[UnderlyingType(t).Kind()].Size; sz {
  1061  	case 1:
  1062  		switch {
  1063  		case signed:
  1064  			switch {
  1065  			case int8(n) < 0:
  1066  				return n | ^math.MaxUint8
  1067  			default:
  1068  				return n & math.MaxUint8
  1069  			}
  1070  		default:
  1071  			return n & math.MaxUint8
  1072  		}
  1073  	case 2:
  1074  		switch {
  1075  		case signed:
  1076  			switch {
  1077  			case int16(n) < 0:
  1078  				return n | ^math.MaxUint16
  1079  			default:
  1080  				return n & math.MaxUint16
  1081  			}
  1082  		default:
  1083  			return n & math.MaxUint16
  1084  		}
  1085  	case 4:
  1086  		switch {
  1087  		case signed:
  1088  			switch {
  1089  			case int32(n) < 0:
  1090  				return n | ^math.MaxUint32
  1091  			default:
  1092  				return n & math.MaxUint32
  1093  			}
  1094  		default:
  1095  			return n & math.MaxUint32
  1096  		}
  1097  	case 8:
  1098  		return n
  1099  	default:
  1100  		panic(fmt.Errorf("TODO %v %T %v", sz, t, t))
  1101  	}
  1102  }
  1103  
  1104  func (o Operand) normalize(m Model) (r Operand) {
  1105  	switch x := o.Value.(type) {
  1106  	case *ir.Int64Value:
  1107  		if v := ConvertInt64(x.Value, o.Type, m); v != x.Value {
  1108  			n := *x
  1109  			n.Value = v
  1110  			x = &n
  1111  			o.Value = x
  1112  		}
  1113  	case nil:
  1114  		// nop
  1115  	case
  1116  		*ir.AddressValue,
  1117  		*ir.Complex128Value,
  1118  		*ir.Complex64Value,
  1119  		*ir.Float32Value,
  1120  		*ir.Float64Value,
  1121  		*ir.StringValue,
  1122  		*ir.WideStringValue:
  1123  
  1124  		// nop
  1125  	default:
  1126  		panic(fmt.Errorf("TODO %T", x))
  1127  	}
  1128  	return o
  1129  }
  1130  
  1131  func (o Operand) or(ctx *context, p Operand) (r Operand) {
  1132  	if !o.isIntegerType() || !p.isIntegerType() {
  1133  		panic("TODO")
  1134  	}
  1135  	o, p = UsualArithmeticConversions(ctx.model, o, p)
  1136  	r.Type = o.Type
  1137  	if o.Value == nil || p.Value == nil {
  1138  		return Operand{Type: o.Type}.normalize(ctx.model)
  1139  	}
  1140  
  1141  	switch x := o.Value.(type) {
  1142  	case *ir.Int64Value:
  1143  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value | p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
  1144  	default:
  1145  		panic(fmt.Errorf("TODO %T", x))
  1146  	}
  1147  }
  1148  
  1149  func (o Operand) rsh(ctx *context, p Operand) (r Operand) { // [0]6.5.7
  1150  	// 2. Each of the operands shall have integer type.
  1151  	if !o.isIntegerType() || !p.isIntegerType() {
  1152  		panic("TODO")
  1153  	}
  1154  
  1155  	// 3. The integer promotions are performed on each of the operands. The
  1156  	// type of the result is that of the promoted left operand. If the
  1157  	// value of the right operand is negative or is greater than or equal
  1158  	// to the width of the promoted left operand, the behavior is
  1159  	// undefined.
  1160  	o = o.integerPromotion(ctx.model)
  1161  	p = p.integerPromotion(ctx.model)
  1162  	r.Type = o.Type
  1163  	m := uint64(32)
  1164  	if ctx.model.Sizeof(o.Type) > 4 {
  1165  		m = 64
  1166  	}
  1167  	if o.Value == nil || p.Value == nil {
  1168  		return Operand{Type: o.Type}.normalize(ctx.model)
  1169  	}
  1170  
  1171  	switch x := o.Value.(type) {
  1172  	case *ir.Int64Value:
  1173  		switch {
  1174  		case o.isSigned():
  1175  			return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value >> (uint64(p.Value.(*ir.Int64Value).Value) % m)}}.normalize(ctx.model)
  1176  		default:
  1177  			return Operand{Type: o.Type, Value: &ir.Int64Value{Value: int64(uint64(x.Value) >> (uint64(p.Value.(*ir.Int64Value).Value) % m))}}.normalize(ctx.model)
  1178  		}
  1179  	default:
  1180  		panic(fmt.Errorf("TODO %T", x))
  1181  	}
  1182  }
  1183  
  1184  func (o Operand) sub(ctx *context, p Operand) (r Operand) {
  1185  	o, p = UsualArithmeticConversions(ctx.model, o, p)
  1186  	if p.IsZero() {
  1187  		return o.normalize(ctx.model)
  1188  	}
  1189  
  1190  	if o.Value == nil || p.Value == nil {
  1191  		return Operand{Type: o.Type}.normalize(ctx.model)
  1192  	}
  1193  
  1194  	switch x := o.Value.(type) {
  1195  	case *ir.Int64Value:
  1196  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value - p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
  1197  	case *ir.Float32Value:
  1198  		return Operand{Type: o.Type, Value: &ir.Float32Value{Value: x.Value - p.Value.(*ir.Float32Value).Value}}.normalize(ctx.model)
  1199  	case *ir.Float64Value:
  1200  		return Operand{Type: o.Type, Value: &ir.Float64Value{Value: x.Value - p.Value.(*ir.Float64Value).Value}}.normalize(ctx.model)
  1201  	default:
  1202  		panic(fmt.Errorf("TODO %T", x))
  1203  	}
  1204  }
  1205  
  1206  func (o Operand) unaryMinus(ctx *context) Operand {
  1207  	if o.isIntegerType() {
  1208  		o = o.integerPromotion(ctx.model)
  1209  	}
  1210  
  1211  	switch x := o.Value.(type) {
  1212  	case nil:
  1213  		return o
  1214  	case *ir.Int64Value:
  1215  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: -x.Value}}.normalize(ctx.model)
  1216  	case *ir.Float32Value:
  1217  		return Operand{Type: o.Type, Value: &ir.Float32Value{Value: -x.Value}}
  1218  	case *ir.Float64Value:
  1219  		return Operand{Type: o.Type, Value: &ir.Float64Value{Value: -x.Value}}
  1220  	default:
  1221  		panic(fmt.Errorf("TODO %T", x))
  1222  	}
  1223  }
  1224  
  1225  func (o Operand) xor(ctx *context, p Operand) (r Operand) {
  1226  	if !o.isIntegerType() || !p.isIntegerType() {
  1227  		panic("TODO")
  1228  	}
  1229  	o, p = UsualArithmeticConversions(ctx.model, o, p)
  1230  	if o.Value == nil || p.Value == nil {
  1231  		return Operand{Type: o.Type}
  1232  	}
  1233  
  1234  	switch x := o.Value.(type) {
  1235  	case *ir.Int64Value:
  1236  		return Operand{Type: o.Type, Value: &ir.Int64Value{Value: x.Value ^ p.Value.(*ir.Int64Value).Value}}.normalize(ctx.model)
  1237  	default:
  1238  		panic(fmt.Errorf("TODO %T", x))
  1239  	}
  1240  }