github.com/llir/llvm@v0.3.6/asm/const_expr.go (about)

     1  package asm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/llir/ll/ast"
     7  	asmenum "github.com/llir/llvm/asm/enum"
     8  	"github.com/llir/llvm/ir/constant"
     9  	"github.com/llir/llvm/ir/types"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // === [ Translate AST to IR ] =================================================
    14  
    15  // irConstantExpr translates the AST constant expression into an equivalent IR
    16  // constant expression.
    17  func (gen *generator) irConstantExpr(t types.Type, old ast.ConstantExpr) (constant.Expression, error) {
    18  	switch old := old.(type) {
    19  	// Unary expressions
    20  	case *ast.FNegExpr:
    21  		return gen.irFNegExpr(t, old)
    22  	// Binary expressions
    23  	case *ast.AddExpr:
    24  		return gen.irAddExpr(t, old)
    25  	case *ast.FAddExpr:
    26  		return gen.irFAddExpr(t, old)
    27  	case *ast.SubExpr:
    28  		return gen.irSubExpr(t, old)
    29  	case *ast.FSubExpr:
    30  		return gen.irFSubExpr(t, old)
    31  	case *ast.MulExpr:
    32  		return gen.irMulExpr(t, old)
    33  	case *ast.FMulExpr:
    34  		return gen.irFMulExpr(t, old)
    35  	case *ast.UDivExpr:
    36  		return gen.irUDivExpr(t, old)
    37  	case *ast.SDivExpr:
    38  		return gen.irSDivExpr(t, old)
    39  	case *ast.FDivExpr:
    40  		return gen.irFDivExpr(t, old)
    41  	case *ast.URemExpr:
    42  		return gen.irURemExpr(t, old)
    43  	case *ast.SRemExpr:
    44  		return gen.irSRemExpr(t, old)
    45  	case *ast.FRemExpr:
    46  		return gen.irFRemExpr(t, old)
    47  	// Bitwise expressions
    48  	case *ast.ShlExpr:
    49  		return gen.irShlExpr(t, old)
    50  	case *ast.LShrExpr:
    51  		return gen.irLShrExpr(t, old)
    52  	case *ast.AShrExpr:
    53  		return gen.irAShrExpr(t, old)
    54  	case *ast.AndExpr:
    55  		return gen.irAndExpr(t, old)
    56  	case *ast.OrExpr:
    57  		return gen.irOrExpr(t, old)
    58  	case *ast.XorExpr:
    59  		return gen.irXorExpr(t, old)
    60  	// Vector expressions
    61  	case *ast.ExtractElementExpr:
    62  		return gen.irExtractElementExpr(t, old)
    63  	case *ast.InsertElementExpr:
    64  		return gen.irInsertElementExpr(t, old)
    65  	case *ast.ShuffleVectorExpr:
    66  		return gen.irShuffleVectorExpr(t, old)
    67  	// Aggregate expressions
    68  	case *ast.ExtractValueExpr:
    69  		return gen.irExtractValueExpr(t, old)
    70  	case *ast.InsertValueExpr:
    71  		return gen.irInsertValueExpr(t, old)
    72  	// Memory expressions
    73  	case *ast.GetElementPtrExpr:
    74  		return gen.irGetElementPtrExpr(t, old)
    75  	// Conversion expressions
    76  	case *ast.TruncExpr:
    77  		return gen.irTruncExpr(t, old)
    78  	case *ast.ZExtExpr:
    79  		return gen.irZExtExpr(t, old)
    80  	case *ast.SExtExpr:
    81  		return gen.irSExtExpr(t, old)
    82  	case *ast.FPTruncExpr:
    83  		return gen.irFPTruncExpr(t, old)
    84  	case *ast.FPExtExpr:
    85  		return gen.irFPExtExpr(t, old)
    86  	case *ast.FPToUIExpr:
    87  		return gen.irFPToUIExpr(t, old)
    88  	case *ast.FPToSIExpr:
    89  		return gen.irFPToSIExpr(t, old)
    90  	case *ast.UIToFPExpr:
    91  		return gen.irUIToFPExpr(t, old)
    92  	case *ast.SIToFPExpr:
    93  		return gen.irSIToFPExpr(t, old)
    94  	case *ast.PtrToIntExpr:
    95  		return gen.irPtrToIntExpr(t, old)
    96  	case *ast.IntToPtrExpr:
    97  		return gen.irIntToPtrExpr(t, old)
    98  	case *ast.BitCastExpr:
    99  		return gen.irBitCastExpr(t, old)
   100  	case *ast.AddrSpaceCastExpr:
   101  		return gen.irAddrSpaceCastExpr(t, old)
   102  	// Other expressions
   103  	case *ast.ICmpExpr:
   104  		return gen.irICmpExpr(t, old)
   105  	case *ast.FCmpExpr:
   106  		return gen.irFCmpExpr(t, old)
   107  	case *ast.SelectExpr:
   108  		return gen.irSelectExpr(t, old)
   109  	default:
   110  		panic(fmt.Errorf("support for AST constant expression %T not yet implemented", old))
   111  	}
   112  }
   113  
   114  // --- [ Unary expressions ] ---------------------------------------------------
   115  
   116  // ~~~ [ fneg ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   117  
   118  // irFNegExpr translates the AST fneg constant expression into an equivalent IR
   119  // constant expression.
   120  func (gen *generator) irFNegExpr(t types.Type, old *ast.FNegExpr) (*constant.ExprFNeg, error) {
   121  	// X operand.
   122  	x, err := gen.irTypeConst(old.X())
   123  	if err != nil {
   124  		return nil, errors.WithStack(err)
   125  	}
   126  	expr := constant.NewFNeg(x)
   127  	if !t.Equal(expr.Typ) {
   128  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   129  	}
   130  	return expr, nil
   131  }
   132  
   133  // --- [ Binary expressions ] --------------------------------------------------
   134  
   135  // ~~~ [ add ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   136  
   137  // irAddExpr translates the AST add constant expression into an equivalent IR
   138  // constant expression.
   139  func (gen *generator) irAddExpr(t types.Type, old *ast.AddExpr) (*constant.ExprAdd, error) {
   140  	// X operand.
   141  	x, err := gen.irTypeConst(old.X())
   142  	if err != nil {
   143  		return nil, errors.WithStack(err)
   144  	}
   145  	// Y operand.
   146  	y, err := gen.irTypeConst(old.Y())
   147  	if err != nil {
   148  		return nil, errors.WithStack(err)
   149  	}
   150  	expr := constant.NewAdd(x, y)
   151  	// (optional) Overflow flags.
   152  	expr.OverflowFlags = irOverflowFlags(old.OverflowFlags())
   153  	if !t.Equal(expr.Typ) {
   154  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   155  	}
   156  	return expr, nil
   157  }
   158  
   159  // ~~~ [ fadd ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   160  
   161  // irFAddExpr translates the AST fadd constant expression into an equivalent IR
   162  // constant expression.
   163  func (gen *generator) irFAddExpr(t types.Type, old *ast.FAddExpr) (*constant.ExprFAdd, error) {
   164  	// X operand.
   165  	x, err := gen.irTypeConst(old.X())
   166  	if err != nil {
   167  		return nil, errors.WithStack(err)
   168  	}
   169  	// Y operand.
   170  	y, err := gen.irTypeConst(old.Y())
   171  	if err != nil {
   172  		return nil, errors.WithStack(err)
   173  	}
   174  	expr := constant.NewFAdd(x, y)
   175  	if !t.Equal(expr.Typ) {
   176  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   177  	}
   178  	return expr, nil
   179  }
   180  
   181  // ~~~ [ sub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   182  
   183  // irSubExpr translates the AST sub constant expression into an equivalent IR
   184  // constant expression.
   185  func (gen *generator) irSubExpr(t types.Type, old *ast.SubExpr) (*constant.ExprSub, error) {
   186  	// X operand.
   187  	x, err := gen.irTypeConst(old.X())
   188  	if err != nil {
   189  		return nil, errors.WithStack(err)
   190  	}
   191  	// Y operand.
   192  	y, err := gen.irTypeConst(old.Y())
   193  	if err != nil {
   194  		return nil, errors.WithStack(err)
   195  	}
   196  	expr := constant.NewSub(x, y)
   197  	// (optional) Overflow flags.
   198  	expr.OverflowFlags = irOverflowFlags(old.OverflowFlags())
   199  	if !t.Equal(expr.Typ) {
   200  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   201  	}
   202  	return expr, nil
   203  }
   204  
   205  // ~~~ [ fsub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   206  
   207  // irFSubExpr translates the AST fsub constant expression into an equivalent IR
   208  // constant expression.
   209  func (gen *generator) irFSubExpr(t types.Type, old *ast.FSubExpr) (*constant.ExprFSub, error) {
   210  	// X operand.
   211  	x, err := gen.irTypeConst(old.X())
   212  	if err != nil {
   213  		return nil, errors.WithStack(err)
   214  	}
   215  	// Y operand.
   216  	y, err := gen.irTypeConst(old.Y())
   217  	if err != nil {
   218  		return nil, errors.WithStack(err)
   219  	}
   220  	expr := constant.NewFSub(x, y)
   221  	if !t.Equal(expr.Typ) {
   222  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   223  	}
   224  	return expr, nil
   225  }
   226  
   227  // ~~~ [ mul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   228  
   229  // irMulExpr translates the AST mul constant expression into an equivalent IR
   230  // constant expression.
   231  func (gen *generator) irMulExpr(t types.Type, old *ast.MulExpr) (*constant.ExprMul, error) {
   232  	// X operand.
   233  	x, err := gen.irTypeConst(old.X())
   234  	if err != nil {
   235  		return nil, errors.WithStack(err)
   236  	}
   237  	// Y operand.
   238  	y, err := gen.irTypeConst(old.Y())
   239  	if err != nil {
   240  		return nil, errors.WithStack(err)
   241  	}
   242  	expr := constant.NewMul(x, y)
   243  	// (optional) Overflow flags.
   244  	expr.OverflowFlags = irOverflowFlags(old.OverflowFlags())
   245  	if !t.Equal(expr.Typ) {
   246  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   247  	}
   248  	return expr, nil
   249  }
   250  
   251  // ~~~ [ fmul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   252  
   253  // irFMulExpr translates the AST fmul constant expression into an equivalent IR
   254  // constant expression.
   255  func (gen *generator) irFMulExpr(t types.Type, old *ast.FMulExpr) (*constant.ExprFMul, error) {
   256  	// X operand.
   257  	x, err := gen.irTypeConst(old.X())
   258  	if err != nil {
   259  		return nil, errors.WithStack(err)
   260  	}
   261  	// Y operand.
   262  	y, err := gen.irTypeConst(old.Y())
   263  	if err != nil {
   264  		return nil, errors.WithStack(err)
   265  	}
   266  	expr := constant.NewFMul(x, y)
   267  	if !t.Equal(expr.Typ) {
   268  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   269  	}
   270  	return expr, nil
   271  }
   272  
   273  // ~~~ [ udiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   274  
   275  // irUDivExpr translates the AST udiv constant expression into an equivalent IR
   276  // constant expression.
   277  func (gen *generator) irUDivExpr(t types.Type, old *ast.UDivExpr) (*constant.ExprUDiv, error) {
   278  	// X operand.
   279  	x, err := gen.irTypeConst(old.X())
   280  	if err != nil {
   281  		return nil, errors.WithStack(err)
   282  	}
   283  	// Y operand.
   284  	y, err := gen.irTypeConst(old.Y())
   285  	if err != nil {
   286  		return nil, errors.WithStack(err)
   287  	}
   288  	expr := constant.NewUDiv(x, y)
   289  	// (optional) Exact.
   290  	_, expr.Exact = old.Exact()
   291  	if !t.Equal(expr.Typ) {
   292  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   293  	}
   294  	return expr, nil
   295  }
   296  
   297  // ~~~ [ sdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   298  
   299  // irSDivExpr translates the AST sdiv constant expression into an equivalent IR
   300  // constant expression.
   301  func (gen *generator) irSDivExpr(t types.Type, old *ast.SDivExpr) (*constant.ExprSDiv, error) {
   302  	// X operand.
   303  	x, err := gen.irTypeConst(old.X())
   304  	if err != nil {
   305  		return nil, errors.WithStack(err)
   306  	}
   307  	// Y operand.
   308  	y, err := gen.irTypeConst(old.Y())
   309  	if err != nil {
   310  		return nil, errors.WithStack(err)
   311  	}
   312  	expr := constant.NewSDiv(x, y)
   313  	// (optional) Exact.
   314  	_, expr.Exact = old.Exact()
   315  	if !t.Equal(expr.Typ) {
   316  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   317  	}
   318  	return expr, nil
   319  }
   320  
   321  // ~~~ [ fdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   322  
   323  // irFDivExpr translates the AST fdiv constant expression into an equivalent IR
   324  // constant expression.
   325  func (gen *generator) irFDivExpr(t types.Type, old *ast.FDivExpr) (*constant.ExprFDiv, error) {
   326  	// X operand.
   327  	x, err := gen.irTypeConst(old.X())
   328  	if err != nil {
   329  		return nil, errors.WithStack(err)
   330  	}
   331  	// Y operand.
   332  	y, err := gen.irTypeConst(old.Y())
   333  	if err != nil {
   334  		return nil, errors.WithStack(err)
   335  	}
   336  	expr := constant.NewFDiv(x, y)
   337  	if !t.Equal(expr.Typ) {
   338  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   339  	}
   340  	return expr, nil
   341  }
   342  
   343  // ~~~ [ urem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   344  
   345  // irURemExpr translates the AST urem constant expression into an equivalent IR
   346  // constant expression.
   347  func (gen *generator) irURemExpr(t types.Type, old *ast.URemExpr) (*constant.ExprURem, error) {
   348  	// X operand.
   349  	x, err := gen.irTypeConst(old.X())
   350  	if err != nil {
   351  		return nil, errors.WithStack(err)
   352  	}
   353  	// Y operand.
   354  	y, err := gen.irTypeConst(old.Y())
   355  	if err != nil {
   356  		return nil, errors.WithStack(err)
   357  	}
   358  	expr := constant.NewURem(x, y)
   359  	if !t.Equal(expr.Typ) {
   360  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   361  	}
   362  	return expr, nil
   363  }
   364  
   365  // ~~~ [ srem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   366  
   367  // irSRemExpr translates the AST srem constant expression into an equivalent IR
   368  // constant expression.
   369  func (gen *generator) irSRemExpr(t types.Type, old *ast.SRemExpr) (*constant.ExprSRem, error) {
   370  	// X operand.
   371  	x, err := gen.irTypeConst(old.X())
   372  	if err != nil {
   373  		return nil, errors.WithStack(err)
   374  	}
   375  	// Y operand.
   376  	y, err := gen.irTypeConst(old.Y())
   377  	if err != nil {
   378  		return nil, errors.WithStack(err)
   379  	}
   380  	expr := constant.NewSRem(x, y)
   381  	if !t.Equal(expr.Typ) {
   382  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   383  	}
   384  	return expr, nil
   385  }
   386  
   387  // ~~~ [ frem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   388  
   389  // irFRemExpr translates the AST frem constant expression into an equivalent IR
   390  // constant expression.
   391  func (gen *generator) irFRemExpr(t types.Type, old *ast.FRemExpr) (*constant.ExprFRem, error) {
   392  	// X operand.
   393  	x, err := gen.irTypeConst(old.X())
   394  	if err != nil {
   395  		return nil, errors.WithStack(err)
   396  	}
   397  	// Y operand.
   398  	y, err := gen.irTypeConst(old.Y())
   399  	if err != nil {
   400  		return nil, errors.WithStack(err)
   401  	}
   402  	expr := constant.NewFRem(x, y)
   403  	if !t.Equal(expr.Typ) {
   404  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   405  	}
   406  	return expr, nil
   407  }
   408  
   409  // --- [ Bitwise expressions ] -------------------------------------------------
   410  
   411  // ~~~ [ shl ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   412  
   413  // irShlExpr translates the AST shl constant expression into an equivalent IR
   414  // constant expression.
   415  func (gen *generator) irShlExpr(t types.Type, old *ast.ShlExpr) (*constant.ExprShl, error) {
   416  	// X operand.
   417  	x, err := gen.irTypeConst(old.X())
   418  	if err != nil {
   419  		return nil, errors.WithStack(err)
   420  	}
   421  	// Y operand.
   422  	y, err := gen.irTypeConst(old.Y())
   423  	if err != nil {
   424  		return nil, errors.WithStack(err)
   425  	}
   426  	expr := constant.NewShl(x, y)
   427  	// (optional) Overflow flags.
   428  	expr.OverflowFlags = irOverflowFlags(old.OverflowFlags())
   429  	if !t.Equal(expr.Typ) {
   430  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   431  	}
   432  	return expr, nil
   433  }
   434  
   435  // ~~~ [ lshr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   436  
   437  // irLShrExpr translates the AST lshr constant expression into an equivalent IR
   438  // constant expression.
   439  func (gen *generator) irLShrExpr(t types.Type, old *ast.LShrExpr) (*constant.ExprLShr, error) {
   440  	// X operand.
   441  	x, err := gen.irTypeConst(old.X())
   442  	if err != nil {
   443  		return nil, errors.WithStack(err)
   444  	}
   445  	// Y operand.
   446  	y, err := gen.irTypeConst(old.Y())
   447  	if err != nil {
   448  		return nil, errors.WithStack(err)
   449  	}
   450  	expr := constant.NewLShr(x, y)
   451  	// (optional) Exact.
   452  	_, expr.Exact = old.Exact()
   453  	if !t.Equal(expr.Typ) {
   454  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   455  	}
   456  	return expr, nil
   457  }
   458  
   459  // ~~~ [ ashr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   460  
   461  // irAShrExpr translates the AST ashr constant expression into an equivalent IR
   462  // constant expression.
   463  func (gen *generator) irAShrExpr(t types.Type, old *ast.AShrExpr) (*constant.ExprAShr, error) {
   464  	// X operand.
   465  	x, err := gen.irTypeConst(old.X())
   466  	if err != nil {
   467  		return nil, errors.WithStack(err)
   468  	}
   469  	// Y operand.
   470  	y, err := gen.irTypeConst(old.Y())
   471  	if err != nil {
   472  		return nil, errors.WithStack(err)
   473  	}
   474  	expr := constant.NewAShr(x, y)
   475  	// (optional) Exact.
   476  	_, expr.Exact = old.Exact()
   477  	if !t.Equal(expr.Typ) {
   478  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   479  	}
   480  	return expr, nil
   481  }
   482  
   483  // ~~~ [ and ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   484  
   485  // irAndExpr translates the AST and constant expression into an equivalent IR
   486  // constant expression.
   487  func (gen *generator) irAndExpr(t types.Type, old *ast.AndExpr) (*constant.ExprAnd, error) {
   488  	// X operand.
   489  	x, err := gen.irTypeConst(old.X())
   490  	if err != nil {
   491  		return nil, errors.WithStack(err)
   492  	}
   493  	// Y operand.
   494  	y, err := gen.irTypeConst(old.Y())
   495  	if err != nil {
   496  		return nil, errors.WithStack(err)
   497  	}
   498  	expr := constant.NewAnd(x, y)
   499  	if !t.Equal(expr.Typ) {
   500  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   501  	}
   502  	return expr, nil
   503  }
   504  
   505  // ~~~ [ or ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   506  
   507  // irOrExpr translates the AST or constant expression into an equivalent IR
   508  // constant expression.
   509  func (gen *generator) irOrExpr(t types.Type, old *ast.OrExpr) (*constant.ExprOr, error) {
   510  	// X operand.
   511  	x, err := gen.irTypeConst(old.X())
   512  	if err != nil {
   513  		return nil, errors.WithStack(err)
   514  	}
   515  	// Y operand.
   516  	y, err := gen.irTypeConst(old.Y())
   517  	if err != nil {
   518  		return nil, errors.WithStack(err)
   519  	}
   520  	expr := constant.NewOr(x, y)
   521  	if !t.Equal(expr.Typ) {
   522  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   523  	}
   524  	return expr, nil
   525  }
   526  
   527  // ~~~ [ xor ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   528  
   529  // irXorExpr translates the AST xor constant expression into an equivalent IR
   530  // constant expression.
   531  func (gen *generator) irXorExpr(t types.Type, old *ast.XorExpr) (*constant.ExprXor, error) {
   532  	// X operand.
   533  	x, err := gen.irTypeConst(old.X())
   534  	if err != nil {
   535  		return nil, errors.WithStack(err)
   536  	}
   537  	// Y operand.
   538  	y, err := gen.irTypeConst(old.Y())
   539  	if err != nil {
   540  		return nil, errors.WithStack(err)
   541  	}
   542  	expr := constant.NewXor(x, y)
   543  	if !t.Equal(expr.Typ) {
   544  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   545  	}
   546  	return expr, nil
   547  }
   548  
   549  // --- [ Vector expressions ] --------------------------------------------------
   550  
   551  // ~~~ [ extractelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   552  
   553  // irExtractElementExpr translates the AST extractelement constant expression
   554  // into an equivalent IR constant expression.
   555  func (gen *generator) irExtractElementExpr(t types.Type, old *ast.ExtractElementExpr) (*constant.ExprExtractElement, error) {
   556  	// Vector.
   557  	x, err := gen.irTypeConst(old.X())
   558  	if err != nil {
   559  		return nil, errors.WithStack(err)
   560  	}
   561  	// Index.
   562  	index, err := gen.irTypeConst(old.Index())
   563  	if err != nil {
   564  		return nil, errors.WithStack(err)
   565  	}
   566  	expr := constant.NewExtractElement(x, index)
   567  	if !t.Equal(expr.Typ) {
   568  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   569  	}
   570  	return expr, nil
   571  }
   572  
   573  // ~~~ [ insertelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   574  
   575  // irInsertElementExpr translates the AST insertelement constant expression into
   576  // an equivalent IR constant expression.
   577  func (gen *generator) irInsertElementExpr(t types.Type, old *ast.InsertElementExpr) (*constant.ExprInsertElement, error) {
   578  	// Vector.
   579  	x, err := gen.irTypeConst(old.X())
   580  	if err != nil {
   581  		return nil, errors.WithStack(err)
   582  	}
   583  	// Element.
   584  	elem, err := gen.irTypeConst(old.Elem())
   585  	if err != nil {
   586  		return nil, errors.WithStack(err)
   587  	}
   588  	// Index.
   589  	index, err := gen.irTypeConst(old.Index())
   590  	if err != nil {
   591  		return nil, errors.WithStack(err)
   592  	}
   593  	expr := constant.NewInsertElement(x, elem, index)
   594  	if !t.Equal(expr.Typ) {
   595  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   596  	}
   597  	return expr, nil
   598  }
   599  
   600  // ~~~ [ shufflevector ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   601  
   602  // irShuffleVectorExpr translates the AST shufflevector constant expression into
   603  // an equivalent IR constant expression.
   604  func (gen *generator) irShuffleVectorExpr(t types.Type, old *ast.ShuffleVectorExpr) (*constant.ExprShuffleVector, error) {
   605  	// X vector.
   606  	x, err := gen.irTypeConst(old.X())
   607  	if err != nil {
   608  		return nil, errors.WithStack(err)
   609  	}
   610  	// Y vector.
   611  	y, err := gen.irTypeConst(old.Y())
   612  	if err != nil {
   613  		return nil, errors.WithStack(err)
   614  	}
   615  	// Shuffle mask.
   616  	mask, err := gen.irTypeConst(old.Mask())
   617  	if err != nil {
   618  		return nil, errors.WithStack(err)
   619  	}
   620  	expr := constant.NewShuffleVector(x, y, mask)
   621  	if !t.Equal(expr.Typ) {
   622  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   623  	}
   624  	return expr, nil
   625  }
   626  
   627  // --- [ Aggregate expressions ] -----------------------------------------------
   628  
   629  // ~~~ [ extractvalue ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   630  
   631  // irExtractValueExpr translates the AST extractvalue constant expression into
   632  // an equivalent IR constant expression.
   633  func (gen *generator) irExtractValueExpr(t types.Type, old *ast.ExtractValueExpr) (*constant.ExprExtractValue, error) {
   634  	// Aggregate value.
   635  	x, err := gen.irTypeConst(old.X())
   636  	if err != nil {
   637  		return nil, errors.WithStack(err)
   638  	}
   639  	// Element indices.
   640  	indices := uintSlice(old.Indices())
   641  	expr := constant.NewExtractValue(x, indices...)
   642  	if !t.Equal(expr.Typ) {
   643  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   644  	}
   645  	return expr, nil
   646  }
   647  
   648  // ~~~ [ insertvalue ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   649  
   650  // irInsertValueExpr translates the AST insertvalue constant expression into an
   651  // equivalent IR constant expression.
   652  func (gen *generator) irInsertValueExpr(t types.Type, old *ast.InsertValueExpr) (*constant.ExprInsertValue, error) {
   653  	// Aggregate value.
   654  	x, err := gen.irTypeConst(old.X())
   655  	if err != nil {
   656  		return nil, errors.WithStack(err)
   657  	}
   658  	// Element.
   659  	elem, err := gen.irTypeConst(old.Elem())
   660  	if err != nil {
   661  		return nil, errors.WithStack(err)
   662  	}
   663  	// Element indices.
   664  	indices := uintSlice(old.Indices())
   665  	expr := constant.NewInsertValue(x, elem, indices...)
   666  	if !t.Equal(expr.Typ) {
   667  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
   668  	}
   669  	return expr, nil
   670  }
   671  
   672  // --- [ Memory expressions ] --------------------------------------------------
   673  
   674  // ~~~ [ getelementptr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   675  
   676  // irGetElementPtrExpr translates the AST getelementptr constant expression into
   677  // an equivalent IR constant expression.
   678  func (gen *generator) irGetElementPtrExpr(t types.Type, old *ast.GetElementPtrExpr) (*constant.ExprGetElementPtr, error) {
   679  	// Element type.
   680  	elemType, err := gen.irType(old.ElemType())
   681  	if err != nil {
   682  		return nil, errors.WithStack(err)
   683  	}
   684  	// Source.
   685  	src, err := gen.irTypeConst(old.Src())
   686  	if err != nil {
   687  		return nil, errors.WithStack(err)
   688  	}
   689  	// Indices.
   690  	var indices []constant.Constant
   691  	if oldIndices := old.Indices(); len(oldIndices) > 0 {
   692  		indices = make([]constant.Constant, len(oldIndices))
   693  		for i, oldIndex := range oldIndices {
   694  			index, err := gen.irGEPIndex(oldIndex)
   695  			if err != nil {
   696  				return nil, errors.WithStack(err)
   697  			}
   698  			indices[i] = index
   699  		}
   700  	}
   701  	expr := constant.NewGetElementPtr(elemType, src, indices...)
   702  	// (optional) In-bounds.
   703  	_, expr.InBounds = old.InBounds()
   704  	if !elemType.Equal(expr.ElemType) {
   705  		return nil, errors.Errorf("constant expression element type mismatch; expected %q, got %q", expr.ElemType, elemType)
   706  	}
   707  	if !t.Equal(expr.Typ) {
   708  		return nil, errors.Errorf("constant expression type mismatch of `%v`; expected %q, got %q", expr, expr.Typ, t)
   709  	}
   710  	return expr, nil
   711  }
   712  
   713  // irGEPIndex translates the AST getelementptr index into an equivalent IR
   714  // getelementptr index.
   715  func (gen *generator) irGEPIndex(old ast.GEPIndex) (*constant.Index, error) {
   716  	// Index.
   717  	idx, err := gen.irTypeConst(old.Index())
   718  	if err != nil {
   719  		return nil, errors.WithStack(err)
   720  	}
   721  	index := constant.NewIndex(idx)
   722  	// (optional) In-range.
   723  	_, index.InRange = old.InRange()
   724  	return index, nil
   725  }
   726  
   727  // --- [ Conversion expressions ] ----------------------------------------------
   728  
   729  // ~~~ [ trunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   730  
   731  // irTruncExpr translates the AST trunc constant expression into an equivalent
   732  // IR constant expression.
   733  func (gen *generator) irTruncExpr(t types.Type, old *ast.TruncExpr) (*constant.ExprTrunc, error) {
   734  	// From.
   735  	from, err := gen.irTypeConst(old.From())
   736  	if err != nil {
   737  		return nil, errors.WithStack(err)
   738  	}
   739  	// To.
   740  	to, err := gen.irType(old.To())
   741  	if err != nil {
   742  		return nil, errors.WithStack(err)
   743  	}
   744  	expr := constant.NewTrunc(from, to)
   745  	if !t.Equal(expr.To) {
   746  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   747  	}
   748  	return expr, nil
   749  }
   750  
   751  // ~~~ [ zext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   752  
   753  // irZExtExpr translates the AST zext constant expression into an equivalent IR
   754  // constant expression.
   755  func (gen *generator) irZExtExpr(t types.Type, old *ast.ZExtExpr) (*constant.ExprZExt, error) {
   756  	// From.
   757  	from, err := gen.irTypeConst(old.From())
   758  	if err != nil {
   759  		return nil, errors.WithStack(err)
   760  	}
   761  	// To.
   762  	to, err := gen.irType(old.To())
   763  	if err != nil {
   764  		return nil, errors.WithStack(err)
   765  	}
   766  	expr := constant.NewZExt(from, to)
   767  	if !t.Equal(expr.To) {
   768  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   769  	}
   770  	return expr, nil
   771  }
   772  
   773  // ~~~ [ sext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   774  
   775  // irSExtExpr translates the AST sext constant expression into an equivalent IR
   776  // constant expression.
   777  func (gen *generator) irSExtExpr(t types.Type, old *ast.SExtExpr) (*constant.ExprSExt, error) {
   778  	// From.
   779  	from, err := gen.irTypeConst(old.From())
   780  	if err != nil {
   781  		return nil, errors.WithStack(err)
   782  	}
   783  	// To.
   784  	to, err := gen.irType(old.To())
   785  	if err != nil {
   786  		return nil, errors.WithStack(err)
   787  	}
   788  	expr := constant.NewSExt(from, to)
   789  	if !t.Equal(expr.To) {
   790  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   791  	}
   792  	return expr, nil
   793  }
   794  
   795  // ~~~ [ fptrunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   796  
   797  // irFPTruncExpr translates the AST fptrunc constant expression into an
   798  // equivalent IR constant expression.
   799  func (gen *generator) irFPTruncExpr(t types.Type, old *ast.FPTruncExpr) (*constant.ExprFPTrunc, error) {
   800  	// From.
   801  	from, err := gen.irTypeConst(old.From())
   802  	if err != nil {
   803  		return nil, errors.WithStack(err)
   804  	}
   805  	// To.
   806  	to, err := gen.irType(old.To())
   807  	if err != nil {
   808  		return nil, errors.WithStack(err)
   809  	}
   810  	expr := constant.NewFPTrunc(from, to)
   811  	if !t.Equal(expr.To) {
   812  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   813  	}
   814  	return expr, nil
   815  }
   816  
   817  // ~~~ [ fpext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   818  
   819  // irFPExtExpr translates the AST fpext constant expression into an equivalent
   820  // IR constant expression.
   821  func (gen *generator) irFPExtExpr(t types.Type, old *ast.FPExtExpr) (*constant.ExprFPExt, error) {
   822  	// From.
   823  	from, err := gen.irTypeConst(old.From())
   824  	if err != nil {
   825  		return nil, errors.WithStack(err)
   826  	}
   827  	// To.
   828  	to, err := gen.irType(old.To())
   829  	if err != nil {
   830  		return nil, errors.WithStack(err)
   831  	}
   832  	expr := constant.NewFPExt(from, to)
   833  	if !t.Equal(expr.To) {
   834  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   835  	}
   836  	return expr, nil
   837  }
   838  
   839  // ~~~ [ fptoui ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   840  
   841  // irFPToUIExpr translates the AST fptoui constant expression into an equivalent
   842  // IR constant expression.
   843  func (gen *generator) irFPToUIExpr(t types.Type, old *ast.FPToUIExpr) (*constant.ExprFPToUI, error) {
   844  	// From.
   845  	from, err := gen.irTypeConst(old.From())
   846  	if err != nil {
   847  		return nil, errors.WithStack(err)
   848  	}
   849  	// To.
   850  	to, err := gen.irType(old.To())
   851  	if err != nil {
   852  		return nil, errors.WithStack(err)
   853  	}
   854  	expr := constant.NewFPToUI(from, to)
   855  	if !t.Equal(expr.To) {
   856  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   857  	}
   858  	return expr, nil
   859  }
   860  
   861  // ~~~ [ fptosi ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   862  
   863  // irFPToSIExpr translates the AST fptosi constant expression into an equivalent
   864  // IR constant expression.
   865  func (gen *generator) irFPToSIExpr(t types.Type, old *ast.FPToSIExpr) (*constant.ExprFPToSI, error) {
   866  	// From.
   867  	from, err := gen.irTypeConst(old.From())
   868  	if err != nil {
   869  		return nil, errors.WithStack(err)
   870  	}
   871  	// To.
   872  	to, err := gen.irType(old.To())
   873  	if err != nil {
   874  		return nil, errors.WithStack(err)
   875  	}
   876  	expr := constant.NewFPToSI(from, to)
   877  	if !t.Equal(expr.To) {
   878  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   879  	}
   880  	return expr, nil
   881  }
   882  
   883  // ~~~ [ uitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   884  
   885  // irUIToFPExpr translates the AST uitofp constant expression into an equivalent
   886  // IR constant expression.
   887  func (gen *generator) irUIToFPExpr(t types.Type, old *ast.UIToFPExpr) (*constant.ExprUIToFP, error) {
   888  	// From.
   889  	from, err := gen.irTypeConst(old.From())
   890  	if err != nil {
   891  		return nil, errors.WithStack(err)
   892  	}
   893  	// To.
   894  	to, err := gen.irType(old.To())
   895  	if err != nil {
   896  		return nil, errors.WithStack(err)
   897  	}
   898  	expr := constant.NewUIToFP(from, to)
   899  	if !t.Equal(expr.To) {
   900  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   901  	}
   902  	return expr, nil
   903  }
   904  
   905  // ~~~ [ sitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   906  
   907  // irSIToFPExpr translates the AST sitofp constant expression into an equivalent
   908  // IR constant expression.
   909  func (gen *generator) irSIToFPExpr(t types.Type, old *ast.SIToFPExpr) (*constant.ExprSIToFP, error) {
   910  	// From.
   911  	from, err := gen.irTypeConst(old.From())
   912  	if err != nil {
   913  		return nil, errors.WithStack(err)
   914  	}
   915  	// To.
   916  	to, err := gen.irType(old.To())
   917  	if err != nil {
   918  		return nil, errors.WithStack(err)
   919  	}
   920  	expr := constant.NewSIToFP(from, to)
   921  	if !t.Equal(expr.To) {
   922  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   923  	}
   924  	return expr, nil
   925  }
   926  
   927  // ~~~ [ ptrtoint ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   928  
   929  // irPtrToIntExpr translates the AST ptrtoint constant expression into an
   930  // equivalent IR constant expression.
   931  func (gen *generator) irPtrToIntExpr(t types.Type, old *ast.PtrToIntExpr) (*constant.ExprPtrToInt, error) {
   932  	// From.
   933  	from, err := gen.irTypeConst(old.From())
   934  	if err != nil {
   935  		return nil, errors.WithStack(err)
   936  	}
   937  	// To.
   938  	to, err := gen.irType(old.To())
   939  	if err != nil {
   940  		return nil, errors.WithStack(err)
   941  	}
   942  	expr := constant.NewPtrToInt(from, to)
   943  	if !t.Equal(expr.To) {
   944  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   945  	}
   946  	return expr, nil
   947  }
   948  
   949  // ~~~ [ inttoptr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   950  
   951  // irIntToPtrExpr translates the AST inttoptr constant expression into an
   952  // equivalent IR constant expression.
   953  func (gen *generator) irIntToPtrExpr(t types.Type, old *ast.IntToPtrExpr) (*constant.ExprIntToPtr, error) {
   954  	// From.
   955  	from, err := gen.irTypeConst(old.From())
   956  	if err != nil {
   957  		return nil, errors.WithStack(err)
   958  	}
   959  	// To.
   960  	to, err := gen.irType(old.To())
   961  	if err != nil {
   962  		return nil, errors.WithStack(err)
   963  	}
   964  	expr := constant.NewIntToPtr(from, to)
   965  	if !t.Equal(expr.To) {
   966  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   967  	}
   968  	return expr, nil
   969  }
   970  
   971  // ~~~ [ bitcast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   972  
   973  // irBitCastExpr translates the AST bitcast constant expression into an
   974  // equivalent IR constant expression.
   975  func (gen *generator) irBitCastExpr(t types.Type, old *ast.BitCastExpr) (*constant.ExprBitCast, error) {
   976  	// From.
   977  	from, err := gen.irTypeConst(old.From())
   978  	if err != nil {
   979  		return nil, errors.WithStack(err)
   980  	}
   981  	// To.
   982  	to, err := gen.irType(old.To())
   983  	if err != nil {
   984  		return nil, errors.WithStack(err)
   985  	}
   986  	expr := constant.NewBitCast(from, to)
   987  	if !t.Equal(expr.To) {
   988  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
   989  	}
   990  	return expr, nil
   991  }
   992  
   993  // ~~~ [ addrspacecast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   994  
   995  // irAddrSpaceCastExpr translates the AST addrspacecast constant expression into
   996  // an equivalent IR constant expression.
   997  func (gen *generator) irAddrSpaceCastExpr(t types.Type, old *ast.AddrSpaceCastExpr) (*constant.ExprAddrSpaceCast, error) {
   998  	// From.
   999  	from, err := gen.irTypeConst(old.From())
  1000  	if err != nil {
  1001  		return nil, errors.WithStack(err)
  1002  	}
  1003  	// To.
  1004  	to, err := gen.irType(old.To())
  1005  	if err != nil {
  1006  		return nil, errors.WithStack(err)
  1007  	}
  1008  	expr := constant.NewAddrSpaceCast(from, to)
  1009  	if !t.Equal(expr.To) {
  1010  		return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t)
  1011  	}
  1012  	return expr, nil
  1013  }
  1014  
  1015  // --- [ Other expressions ] ---------------------------------------------------
  1016  
  1017  // ~~~ [ icmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1018  
  1019  // irICmpExpr translates the AST icmp constant expression into an equivalent IR
  1020  // constant expression.
  1021  func (gen *generator) irICmpExpr(t types.Type, old *ast.ICmpExpr) (*constant.ExprICmp, error) {
  1022  	// Integer comparison predicate.
  1023  	pred := asmenum.IPredFromString(old.Pred().Text())
  1024  	// X operand.
  1025  	x, err := gen.irTypeConst(old.X())
  1026  	if err != nil {
  1027  		return nil, errors.WithStack(err)
  1028  	}
  1029  	// Y operand.
  1030  	y, err := gen.irTypeConst(old.Y())
  1031  	if err != nil {
  1032  		return nil, errors.WithStack(err)
  1033  	}
  1034  	expr := constant.NewICmp(pred, x, y)
  1035  	if !t.Equal(expr.Typ) {
  1036  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
  1037  	}
  1038  	return expr, nil
  1039  }
  1040  
  1041  // ~~~ [ fcmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1042  
  1043  // irFCmpExpr translates the AST fcmp constant expression into an equivalent IR
  1044  // constant expression.
  1045  func (gen *generator) irFCmpExpr(t types.Type, old *ast.FCmpExpr) (*constant.ExprFCmp, error) {
  1046  	// Floating-point comparison predicate.
  1047  	pred := asmenum.FPredFromString(old.Pred().Text())
  1048  	// X operand.
  1049  	x, err := gen.irTypeConst(old.X())
  1050  	if err != nil {
  1051  		return nil, errors.WithStack(err)
  1052  	}
  1053  	// Y operand.
  1054  	y, err := gen.irTypeConst(old.Y())
  1055  	if err != nil {
  1056  		return nil, errors.WithStack(err)
  1057  	}
  1058  	expr := constant.NewFCmp(pred, x, y)
  1059  	if !t.Equal(expr.Typ) {
  1060  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
  1061  	}
  1062  	return expr, nil
  1063  }
  1064  
  1065  // ~~~ [ select ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1066  
  1067  // irSelectExpr translates the AST select constant expression into an equivalent
  1068  // IR constant expression.
  1069  func (gen *generator) irSelectExpr(t types.Type, old *ast.SelectExpr) (*constant.ExprSelect, error) {
  1070  	// Selection condition.
  1071  	cond, err := gen.irTypeConst(old.Cond())
  1072  	if err != nil {
  1073  		return nil, errors.WithStack(err)
  1074  	}
  1075  	// X operand.
  1076  	x, err := gen.irTypeConst(old.X())
  1077  	if err != nil {
  1078  		return nil, errors.WithStack(err)
  1079  	}
  1080  	// Y operand.
  1081  	y, err := gen.irTypeConst(old.Y())
  1082  	if err != nil {
  1083  		return nil, errors.WithStack(err)
  1084  	}
  1085  	expr := constant.NewSelect(cond, x, y)
  1086  	if !t.Equal(expr.Typ) {
  1087  		return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t)
  1088  	}
  1089  	return expr, nil
  1090  }