github.com/llir/llvm@v0.3.6/ir/constant/expr_binary.go (about)

     1  package constant
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/llir/llvm/ir/enum"
     8  	"github.com/llir/llvm/ir/types"
     9  )
    10  
    11  // --- [ Binary expressions ] --------------------------------------------------
    12  
    13  // ~~~ [ add ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    14  
    15  // ExprAdd is an LLVM IR add expression.
    16  type ExprAdd struct {
    17  	// Operands.
    18  	X, Y Constant // integer scalar or vector constants
    19  
    20  	// extra.
    21  
    22  	// Type of result produced by the constant expression.
    23  	Typ types.Type
    24  	// (optional) Integer overflow flags.
    25  	OverflowFlags []enum.OverflowFlag
    26  }
    27  
    28  // NewAdd returns a new add expression based on the given operands.
    29  func NewAdd(x, y Constant) *ExprAdd {
    30  	e := &ExprAdd{X: x, Y: y}
    31  	// Compute type.
    32  	e.Type()
    33  	return e
    34  }
    35  
    36  // String returns the LLVM syntax representation of the constant expression as a
    37  // type-value pair.
    38  func (e *ExprAdd) String() string {
    39  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
    40  }
    41  
    42  // Type returns the type of the constant expression.
    43  func (e *ExprAdd) Type() types.Type {
    44  	// Cache type if not present.
    45  	if e.Typ == nil {
    46  		e.Typ = e.X.Type()
    47  	}
    48  	return e.Typ
    49  }
    50  
    51  // Ident returns the identifier associated with the constant expression.
    52  func (e *ExprAdd) Ident() string {
    53  	// 'add' OverflowFlags=OverflowFlag* '(' X=TypeConst ',' Y=TypeConst ')'
    54  	buf := &strings.Builder{}
    55  	buf.WriteString("add")
    56  	for _, flag := range e.OverflowFlags {
    57  		fmt.Fprintf(buf, " %s", flag)
    58  	}
    59  	fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y)
    60  	return buf.String()
    61  }
    62  
    63  // ~~~ [ fadd ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    64  
    65  // ExprFAdd is an LLVM IR fadd expression.
    66  type ExprFAdd struct {
    67  	// Operands.
    68  	X, Y Constant // floating-point scalar or vector constants
    69  
    70  	// extra.
    71  
    72  	// Type of result produced by the constant expression.
    73  	Typ types.Type
    74  }
    75  
    76  // NewFAdd returns a new fadd expression based on the given operands.
    77  func NewFAdd(x, y Constant) *ExprFAdd {
    78  	e := &ExprFAdd{X: x, Y: y}
    79  	// Compute type.
    80  	e.Type()
    81  	return e
    82  }
    83  
    84  // String returns the LLVM syntax representation of the constant expression as a
    85  // type-value pair.
    86  func (e *ExprFAdd) String() string {
    87  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
    88  }
    89  
    90  // Type returns the type of the constant expression.
    91  func (e *ExprFAdd) Type() types.Type {
    92  	// Cache type if not present.
    93  	if e.Typ == nil {
    94  		e.Typ = e.X.Type()
    95  	}
    96  	return e.Typ
    97  }
    98  
    99  // Ident returns the identifier associated with the constant expression.
   100  func (e *ExprFAdd) Ident() string {
   101  	// 'fadd' '(' X=TypeConst ',' Y=TypeConst ')'
   102  	return fmt.Sprintf("fadd (%s, %s)", e.X, e.Y)
   103  }
   104  
   105  // ~~~ [ sub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   106  
   107  // ExprSub is an LLVM IR sub expression.
   108  type ExprSub struct {
   109  	// Operands.
   110  	X, Y Constant // integer scalar or vector constants
   111  
   112  	// extra.
   113  
   114  	// Type of result produced by the constant expression.
   115  	Typ types.Type
   116  	// (optional) Integer overflow flags.
   117  	OverflowFlags []enum.OverflowFlag
   118  }
   119  
   120  // NewSub returns a new sub expression based on the given operands.
   121  func NewSub(x, y Constant) *ExprSub {
   122  	e := &ExprSub{X: x, Y: y}
   123  	// Compute type.
   124  	e.Type()
   125  	return e
   126  }
   127  
   128  // String returns the LLVM syntax representation of the constant expression as a
   129  // type-value pair.
   130  func (e *ExprSub) String() string {
   131  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   132  }
   133  
   134  // Type returns the type of the constant expression.
   135  func (e *ExprSub) Type() types.Type {
   136  	// Cache type if not present.
   137  	if e.Typ == nil {
   138  		e.Typ = e.X.Type()
   139  	}
   140  	return e.Typ
   141  }
   142  
   143  // Ident returns the identifier associated with the constant expression.
   144  func (e *ExprSub) Ident() string {
   145  	// 'sub' OverflowFlags=OverflowFlag* '(' X=TypeConst ',' Y=TypeConst ')'
   146  	buf := &strings.Builder{}
   147  	buf.WriteString("sub")
   148  	for _, flag := range e.OverflowFlags {
   149  		fmt.Fprintf(buf, " %s", flag)
   150  	}
   151  	fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y)
   152  	return buf.String()
   153  }
   154  
   155  // ~~~ [ fsub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   156  
   157  // ExprFSub is an LLVM IR fsub expression.
   158  type ExprFSub struct {
   159  	// Operands.
   160  	X, Y Constant // floating-point scalar or vector constants
   161  
   162  	// extra.
   163  
   164  	// Type of result produced by the constant expression.
   165  	Typ types.Type
   166  }
   167  
   168  // NewFSub returns a new fsub expression based on the given operands.
   169  func NewFSub(x, y Constant) *ExprFSub {
   170  	e := &ExprFSub{X: x, Y: y}
   171  	// Compute type.
   172  	e.Type()
   173  	return e
   174  }
   175  
   176  // String returns the LLVM syntax representation of the constant expression as a
   177  // type-value pair.
   178  func (e *ExprFSub) String() string {
   179  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   180  }
   181  
   182  // Type returns the type of the constant expression.
   183  func (e *ExprFSub) Type() types.Type {
   184  	// Cache type if not present.
   185  	if e.Typ == nil {
   186  		e.Typ = e.X.Type()
   187  	}
   188  	return e.Typ
   189  }
   190  
   191  // Ident returns the identifier associated with the constant expression.
   192  func (e *ExprFSub) Ident() string {
   193  	// 'fsub' '(' X=TypeConst ',' Y=TypeConst ')'
   194  	return fmt.Sprintf("fsub (%s, %s)", e.X, e.Y)
   195  }
   196  
   197  // ~~~ [ mul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   198  
   199  // ExprMul is an LLVM IR mul expression.
   200  type ExprMul struct {
   201  	// Operands.
   202  	X, Y Constant // integer scalar or vector constants
   203  
   204  	// extra.
   205  
   206  	// Type of result produced by the constant expression.
   207  	Typ types.Type
   208  	// (optional) Integer overflow flags.
   209  	OverflowFlags []enum.OverflowFlag
   210  }
   211  
   212  // NewMul returns a new mul expression based on the given operands.
   213  func NewMul(x, y Constant) *ExprMul {
   214  	e := &ExprMul{X: x, Y: y}
   215  	// Compute type.
   216  	e.Type()
   217  	return e
   218  }
   219  
   220  // String returns the LLVM syntax representation of the constant expression as a
   221  // type-value pair.
   222  func (e *ExprMul) String() string {
   223  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   224  }
   225  
   226  // Type returns the type of the constant expression.
   227  func (e *ExprMul) Type() types.Type {
   228  	// Cache type if not present.
   229  	if e.Typ == nil {
   230  		e.Typ = e.X.Type()
   231  	}
   232  	return e.Typ
   233  }
   234  
   235  // Ident returns the identifier associated with the constant expression.
   236  func (e *ExprMul) Ident() string {
   237  	// 'mul' OverflowFlags=OverflowFlag* '(' X=TypeConst ',' Y=TypeConst ')'
   238  	buf := &strings.Builder{}
   239  	buf.WriteString("mul")
   240  	for _, flag := range e.OverflowFlags {
   241  		fmt.Fprintf(buf, " %s", flag)
   242  	}
   243  	fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y)
   244  	return buf.String()
   245  }
   246  
   247  // ~~~ [ fmul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   248  
   249  // ExprFMul is an LLVM IR fmul expression.
   250  type ExprFMul struct {
   251  	// Operands.
   252  	X, Y Constant // floating-point scalar or vector constants
   253  
   254  	// extra.
   255  
   256  	// Type of result produced by the constant expression.
   257  	Typ types.Type
   258  }
   259  
   260  // NewFMul returns a new fmul expression based on the given operands.
   261  func NewFMul(x, y Constant) *ExprFMul {
   262  	e := &ExprFMul{X: x, Y: y}
   263  	// Compute type.
   264  	e.Type()
   265  	return e
   266  }
   267  
   268  // String returns the LLVM syntax representation of the constant expression as a
   269  // type-value pair.
   270  func (e *ExprFMul) String() string {
   271  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   272  }
   273  
   274  // Type returns the type of the constant expression.
   275  func (e *ExprFMul) Type() types.Type {
   276  	// Cache type if not present.
   277  	if e.Typ == nil {
   278  		e.Typ = e.X.Type()
   279  	}
   280  	return e.Typ
   281  }
   282  
   283  // Ident returns the identifier associated with the constant expression.
   284  func (e *ExprFMul) Ident() string {
   285  	// 'fmul' '(' X=TypeConst ',' Y=TypeConst ')'
   286  	return fmt.Sprintf("fmul (%s, %s)", e.X, e.Y)
   287  }
   288  
   289  // ~~~ [ udiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   290  
   291  // ExprUDiv is an LLVM IR udiv expression.
   292  type ExprUDiv struct {
   293  	// Operands.
   294  	X, Y Constant // integer scalar or vector constants
   295  
   296  	// extra.
   297  
   298  	// Type of result produced by the constant expression.
   299  	Typ types.Type
   300  	// (optional) The result is a poison value if X is not a multiple of Y.
   301  	Exact bool
   302  }
   303  
   304  // NewUDiv returns a new udiv expression based on the given operands.
   305  func NewUDiv(x, y Constant) *ExprUDiv {
   306  	e := &ExprUDiv{X: x, Y: y}
   307  	// Compute type.
   308  	e.Type()
   309  	return e
   310  }
   311  
   312  // String returns the LLVM syntax representation of the constant expression as a
   313  // type-value pair.
   314  func (e *ExprUDiv) String() string {
   315  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   316  }
   317  
   318  // Type returns the type of the constant expression.
   319  func (e *ExprUDiv) Type() types.Type {
   320  	// Cache type if not present.
   321  	if e.Typ == nil {
   322  		e.Typ = e.X.Type()
   323  	}
   324  	return e.Typ
   325  }
   326  
   327  // Ident returns the identifier associated with the constant expression.
   328  func (e *ExprUDiv) Ident() string {
   329  	// 'udiv' Exactopt '(' X=TypeConst ',' Y=TypeConst ')'
   330  	buf := &strings.Builder{}
   331  	buf.WriteString("udiv")
   332  	if e.Exact {
   333  		buf.WriteString(" exact")
   334  	}
   335  	fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y)
   336  	return buf.String()
   337  }
   338  
   339  // ~~~ [ sdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   340  
   341  // ExprSDiv is an LLVM IR sdiv expression.
   342  type ExprSDiv struct {
   343  	// Operands.
   344  	X, Y Constant // integer scalar or vector constants
   345  
   346  	// extra.
   347  
   348  	// Type of result produced by the constant expression.
   349  	Typ types.Type
   350  	// (optional) The result is a poison value if the result would be rounded.
   351  	Exact bool
   352  }
   353  
   354  // NewSDiv returns a new sdiv expression based on the given operands.
   355  func NewSDiv(x, y Constant) *ExprSDiv {
   356  	e := &ExprSDiv{X: x, Y: y}
   357  	// Compute type.
   358  	e.Type()
   359  	return e
   360  }
   361  
   362  // String returns the LLVM syntax representation of the constant expression as a
   363  // type-value pair.
   364  func (e *ExprSDiv) String() string {
   365  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   366  }
   367  
   368  // Type returns the type of the constant expression.
   369  func (e *ExprSDiv) Type() types.Type {
   370  	// Cache type if not present.
   371  	if e.Typ == nil {
   372  		e.Typ = e.X.Type()
   373  	}
   374  	return e.Typ
   375  }
   376  
   377  // Ident returns the identifier associated with the constant expression.
   378  func (e *ExprSDiv) Ident() string {
   379  	// 'sdiv' Exactopt '(' X=TypeConst ',' Y=TypeConst ')'
   380  	buf := &strings.Builder{}
   381  	buf.WriteString("sdiv")
   382  	if e.Exact {
   383  		buf.WriteString(" exact")
   384  	}
   385  	fmt.Fprintf(buf, " (%s, %s)", e.X, e.Y)
   386  	return buf.String()
   387  }
   388  
   389  // ~~~ [ fdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   390  
   391  // ExprFDiv is an LLVM IR fdiv expression.
   392  type ExprFDiv struct {
   393  	// Operands.
   394  	X, Y Constant // floating-point scalar or vector constants
   395  
   396  	// extra.
   397  
   398  	// Type of result produced by the constant expression.
   399  	Typ types.Type
   400  }
   401  
   402  // NewFDiv returns a new fdiv expression based on the given operands.
   403  func NewFDiv(x, y Constant) *ExprFDiv {
   404  	e := &ExprFDiv{X: x, Y: y}
   405  	// Compute type.
   406  	e.Type()
   407  	return e
   408  }
   409  
   410  // String returns the LLVM syntax representation of the constant expression as a
   411  // type-value pair.
   412  func (e *ExprFDiv) String() string {
   413  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   414  }
   415  
   416  // Type returns the type of the constant expression.
   417  func (e *ExprFDiv) Type() types.Type {
   418  	// Cache type if not present.
   419  	if e.Typ == nil {
   420  		e.Typ = e.X.Type()
   421  	}
   422  	return e.Typ
   423  }
   424  
   425  // Ident returns the identifier associated with the constant expression.
   426  func (e *ExprFDiv) Ident() string {
   427  	// 'fdiv' '(' X=TypeConst ',' Y=TypeConst ')'
   428  	return fmt.Sprintf("fdiv (%s, %s)", e.X, e.Y)
   429  }
   430  
   431  // ~~~ [ urem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   432  
   433  // ExprURem is an LLVM IR urem expression.
   434  type ExprURem struct {
   435  	// Operands.
   436  	X, Y Constant // integer scalar or vector constants
   437  
   438  	// extra.
   439  
   440  	// Type of result produced by the constant expression.
   441  	Typ types.Type
   442  }
   443  
   444  // NewURem returns a new urem expression based on the given operands.
   445  func NewURem(x, y Constant) *ExprURem {
   446  	e := &ExprURem{X: x, Y: y}
   447  	// Compute type.
   448  	e.Type()
   449  	return e
   450  }
   451  
   452  // String returns the LLVM syntax representation of the constant expression as a
   453  // type-value pair.
   454  func (e *ExprURem) String() string {
   455  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   456  }
   457  
   458  // Type returns the type of the constant expression.
   459  func (e *ExprURem) Type() types.Type {
   460  	// Cache type if not present.
   461  	if e.Typ == nil {
   462  		e.Typ = e.X.Type()
   463  	}
   464  	return e.Typ
   465  }
   466  
   467  // Ident returns the identifier associated with the constant expression.
   468  func (e *ExprURem) Ident() string {
   469  	// 'urem' '(' X=TypeConst ',' Y=TypeConst ')'
   470  	return fmt.Sprintf("urem (%s, %s)", e.X, e.Y)
   471  }
   472  
   473  // ~~~ [ srem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   474  
   475  // ExprSRem is an LLVM IR srem expression.
   476  type ExprSRem struct {
   477  	// Operands.
   478  	X, Y Constant // integer scalar or vector constants
   479  
   480  	// extra.
   481  
   482  	// Type of result produced by the constant expression.
   483  	Typ types.Type
   484  }
   485  
   486  // NewSRem returns a new srem expression based on the given operands.
   487  func NewSRem(x, y Constant) *ExprSRem {
   488  	e := &ExprSRem{X: x, Y: y}
   489  	// Compute type.
   490  	e.Type()
   491  	return e
   492  }
   493  
   494  // String returns the LLVM syntax representation of the constant expression as a
   495  // type-value pair.
   496  func (e *ExprSRem) String() string {
   497  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   498  }
   499  
   500  // Type returns the type of the constant expression.
   501  func (e *ExprSRem) Type() types.Type {
   502  	// Cache type if not present.
   503  	if e.Typ == nil {
   504  		e.Typ = e.X.Type()
   505  	}
   506  	return e.Typ
   507  }
   508  
   509  // Ident returns the identifier associated with the constant expression.
   510  func (e *ExprSRem) Ident() string {
   511  	// 'srem' '(' X=TypeConst ',' Y=TypeConst ')'
   512  	return fmt.Sprintf("srem (%s, %s)", e.X, e.Y)
   513  }
   514  
   515  // ~~~ [ frem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   516  
   517  // ExprFRem is an LLVM IR frem expression.
   518  type ExprFRem struct {
   519  	// Operands.
   520  	X, Y Constant // floating-point scalar or vector constants
   521  
   522  	// extra.
   523  
   524  	// Type of result produced by the constant expression.
   525  	Typ types.Type
   526  }
   527  
   528  // NewFRem returns a new frem expression based on the given operands.
   529  func NewFRem(x, y Constant) *ExprFRem {
   530  	e := &ExprFRem{X: x, Y: y}
   531  	// Compute type.
   532  	e.Type()
   533  	return e
   534  }
   535  
   536  // String returns the LLVM syntax representation of the constant expression as a
   537  // type-value pair.
   538  func (e *ExprFRem) String() string {
   539  	return fmt.Sprintf("%s %s", e.Type(), e.Ident())
   540  }
   541  
   542  // Type returns the type of the constant expression.
   543  func (e *ExprFRem) Type() types.Type {
   544  	// Cache type if not present.
   545  	if e.Typ == nil {
   546  		e.Typ = e.X.Type()
   547  	}
   548  	return e.Typ
   549  }
   550  
   551  // Ident returns the identifier associated with the constant expression.
   552  func (e *ExprFRem) Ident() string {
   553  	// 'frem' '(' X=TypeConst ',' Y=TypeConst ')'
   554  	return fmt.Sprintf("frem (%s, %s)", e.X, e.Y)
   555  }