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

     1  package ir
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/llir/llvm/ir/enum"
     8  	"github.com/llir/llvm/ir/types"
     9  	"github.com/llir/llvm/ir/value"
    10  )
    11  
    12  // --- [ Bitwise instructions ] ------------------------------------------------
    13  
    14  // ~~~ [ shl ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    15  
    16  // InstShl is an LLVM IR shl instruction.
    17  type InstShl struct {
    18  	// Name of local variable associated with the result.
    19  	LocalIdent
    20  	// Operands.
    21  	X, Y value.Value // integer scalar or integer vector
    22  
    23  	// extra.
    24  
    25  	// Type of result produced by the instruction.
    26  	Typ types.Type
    27  	// (optional) Overflow flags.
    28  	OverflowFlags []enum.OverflowFlag
    29  	// (optional) Metadata.
    30  	Metadata
    31  }
    32  
    33  // NewShl returns a new shl instruction based on the given operands.
    34  func NewShl(x, y value.Value) *InstShl {
    35  	inst := &InstShl{X: x, Y: y}
    36  	// Compute type.
    37  	inst.Type()
    38  	return inst
    39  }
    40  
    41  // String returns the LLVM syntax representation of the instruction as a
    42  // type-value pair.
    43  func (inst *InstShl) String() string {
    44  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
    45  }
    46  
    47  // Type returns the type of the instruction.
    48  func (inst *InstShl) Type() types.Type {
    49  	// Cache type if not present.
    50  	if inst.Typ == nil {
    51  		inst.Typ = inst.X.Type()
    52  	}
    53  	return inst.Typ
    54  }
    55  
    56  // LLString returns the LLVM syntax representation of the instruction.
    57  //
    58  // 'shl' OverflowFlags=OverflowFlag* X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+?
    59  func (inst *InstShl) LLString() string {
    60  	buf := &strings.Builder{}
    61  	fmt.Fprintf(buf, "%s = ", inst.Ident())
    62  	buf.WriteString("shl")
    63  	for _, flag := range inst.OverflowFlags {
    64  		fmt.Fprintf(buf, " %s", flag)
    65  	}
    66  	fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident())
    67  	for _, md := range inst.Metadata {
    68  		fmt.Fprintf(buf, ", %s", md)
    69  	}
    70  	return buf.String()
    71  }
    72  
    73  // Operands returns a mutable list of operands of the given instruction.
    74  func (inst *InstShl) Operands() []*value.Value {
    75  	return []*value.Value{&inst.X, &inst.Y}
    76  }
    77  
    78  // ~~~ [ lshr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    79  
    80  // InstLShr is an LLVM IR lshr instruction.
    81  type InstLShr struct {
    82  	// Name of local variable associated with the result.
    83  	LocalIdent
    84  	// Operands.
    85  	X, Y value.Value // integer scalars or vectors
    86  
    87  	// extra.
    88  
    89  	// Type of result produced by the instruction.
    90  	Typ types.Type
    91  	// (optional) Exact.
    92  	Exact bool
    93  	// (optional) Metadata.
    94  	Metadata
    95  }
    96  
    97  // NewLShr returns a new lshr instruction based on the given operands.
    98  func NewLShr(x, y value.Value) *InstLShr {
    99  	inst := &InstLShr{X: x, Y: y}
   100  	// Compute type.
   101  	inst.Type()
   102  	return inst
   103  }
   104  
   105  // String returns the LLVM syntax representation of the instruction as a
   106  // type-value pair.
   107  func (inst *InstLShr) String() string {
   108  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   109  }
   110  
   111  // Type returns the type of the instruction.
   112  func (inst *InstLShr) Type() types.Type {
   113  	// Cache type if not present.
   114  	if inst.Typ == nil {
   115  		inst.Typ = inst.X.Type()
   116  	}
   117  	return inst.Typ
   118  }
   119  
   120  // LLString returns the LLVM syntax representation of the instruction.
   121  //
   122  // 'lshr' Exactopt X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+?
   123  func (inst *InstLShr) LLString() string {
   124  	buf := &strings.Builder{}
   125  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   126  	buf.WriteString("lshr")
   127  	if inst.Exact {
   128  		buf.WriteString(" exact")
   129  	}
   130  	fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident())
   131  	for _, md := range inst.Metadata {
   132  		fmt.Fprintf(buf, ", %s", md)
   133  	}
   134  	return buf.String()
   135  }
   136  
   137  // Operands returns a mutable list of operands of the given instruction.
   138  func (inst *InstLShr) Operands() []*value.Value {
   139  	return []*value.Value{&inst.X, &inst.Y}
   140  }
   141  
   142  // ~~~ [ ashr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   143  
   144  // InstAShr is an LLVM IR ashr instruction.
   145  type InstAShr struct {
   146  	// Name of local variable associated with the result.
   147  	LocalIdent
   148  	// Operands.
   149  	X, Y value.Value // integer scalars or vectors
   150  
   151  	// extra.
   152  
   153  	// Type of result produced by the instruction.
   154  	Typ types.Type
   155  	// (optional) Exact.
   156  	Exact bool
   157  	// (optional) Metadata.
   158  	Metadata
   159  }
   160  
   161  // NewAShr returns a new ashr instruction based on the given operands.
   162  func NewAShr(x, y value.Value) *InstAShr {
   163  	inst := &InstAShr{X: x, Y: y}
   164  	// Compute type.
   165  	inst.Type()
   166  	return inst
   167  }
   168  
   169  // String returns the LLVM syntax representation of the instruction as a
   170  // type-value pair.
   171  func (inst *InstAShr) String() string {
   172  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   173  }
   174  
   175  // Type returns the type of the instruction.
   176  func (inst *InstAShr) Type() types.Type {
   177  	// Cache type if not present.
   178  	if inst.Typ == nil {
   179  		inst.Typ = inst.X.Type()
   180  	}
   181  	return inst.Typ
   182  }
   183  
   184  // LLString returns the LLVM syntax representation of the instruction.
   185  //
   186  // 'ashr' Exactopt X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+?
   187  func (inst *InstAShr) LLString() string {
   188  	buf := &strings.Builder{}
   189  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   190  	buf.WriteString("ashr")
   191  	if inst.Exact {
   192  		buf.WriteString(" exact")
   193  	}
   194  	fmt.Fprintf(buf, " %s, %s", inst.X, inst.Y.Ident())
   195  	for _, md := range inst.Metadata {
   196  		fmt.Fprintf(buf, ", %s", md)
   197  	}
   198  	return buf.String()
   199  }
   200  
   201  // Operands returns a mutable list of operands of the given instruction.
   202  func (inst *InstAShr) Operands() []*value.Value {
   203  	return []*value.Value{&inst.X, &inst.Y}
   204  }
   205  
   206  // ~~~ [ and ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   207  
   208  // InstAnd is an LLVM IR and instruction.
   209  type InstAnd struct {
   210  	// Name of local variable associated with the result.
   211  	LocalIdent
   212  	// Operands.
   213  	X, Y value.Value // integer scalars or vectors
   214  
   215  	// extra.
   216  
   217  	// Type of result produced by the instruction.
   218  	Typ types.Type
   219  	// (optional) Metadata.
   220  	Metadata
   221  }
   222  
   223  // NewAnd returns a new and instruction based on the given operands.
   224  func NewAnd(x, y value.Value) *InstAnd {
   225  	inst := &InstAnd{X: x, Y: y}
   226  	// Compute type.
   227  	inst.Type()
   228  	return inst
   229  }
   230  
   231  // String returns the LLVM syntax representation of the instruction as a
   232  // type-value pair.
   233  func (inst *InstAnd) String() string {
   234  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   235  }
   236  
   237  // Type returns the type of the instruction.
   238  func (inst *InstAnd) Type() types.Type {
   239  	// Cache type if not present.
   240  	if inst.Typ == nil {
   241  		inst.Typ = inst.X.Type()
   242  	}
   243  	return inst.Typ
   244  }
   245  
   246  // LLString returns the LLVM syntax representation of the instruction.
   247  //
   248  // 'and' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+?
   249  func (inst *InstAnd) LLString() string {
   250  	buf := &strings.Builder{}
   251  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   252  	fmt.Fprintf(buf, "and %s, %s", inst.X, inst.Y.Ident())
   253  	for _, md := range inst.Metadata {
   254  		fmt.Fprintf(buf, ", %s", md)
   255  	}
   256  	return buf.String()
   257  }
   258  
   259  // Operands returns a mutable list of operands of the given instruction.
   260  func (inst *InstAnd) Operands() []*value.Value {
   261  	return []*value.Value{&inst.X, &inst.Y}
   262  }
   263  
   264  // ~~~ [ or ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   265  
   266  // InstOr is an LLVM IR or instruction.
   267  type InstOr struct {
   268  	// Name of local variable associated with the result.
   269  	LocalIdent
   270  	// Operands.
   271  	X, Y value.Value // integer scalars or vectors
   272  
   273  	// extra.
   274  
   275  	// Type of result produced by the instruction.
   276  	Typ types.Type
   277  	// (optional) Metadata.
   278  	Metadata
   279  }
   280  
   281  // NewOr returns a new or instruction based on the given operands.
   282  func NewOr(x, y value.Value) *InstOr {
   283  	inst := &InstOr{X: x, Y: y}
   284  	// Compute type.
   285  	inst.Type()
   286  	return inst
   287  }
   288  
   289  // String returns the LLVM syntax representation of the instruction as a
   290  // type-value pair.
   291  func (inst *InstOr) String() string {
   292  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   293  }
   294  
   295  // Type returns the type of the instruction.
   296  func (inst *InstOr) Type() types.Type {
   297  	// Cache type if not present.
   298  	if inst.Typ == nil {
   299  		inst.Typ = inst.X.Type()
   300  	}
   301  	return inst.Typ
   302  }
   303  
   304  // LLString returns the LLVM syntax representation of the instruction.
   305  //
   306  // 'or' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+?
   307  func (inst *InstOr) LLString() string {
   308  	buf := &strings.Builder{}
   309  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   310  	fmt.Fprintf(buf, "or %s, %s", inst.X, inst.Y.Ident())
   311  	for _, md := range inst.Metadata {
   312  		fmt.Fprintf(buf, ", %s", md)
   313  	}
   314  	return buf.String()
   315  }
   316  
   317  // Operands returns a mutable list of operands of the given instruction.
   318  func (inst *InstOr) Operands() []*value.Value {
   319  	return []*value.Value{&inst.X, &inst.Y}
   320  }
   321  
   322  // ~~~ [ xor ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   323  
   324  // InstXor is an LLVM IR xor instruction.
   325  type InstXor struct {
   326  	// Name of local variable associated with the result.
   327  	LocalIdent
   328  	// Operands.
   329  	X, Y value.Value // integer scalars or vectors
   330  
   331  	// extra.
   332  
   333  	// Type of result produced by the instruction.
   334  	Typ types.Type
   335  	// (optional) Metadata.
   336  	Metadata
   337  }
   338  
   339  // NewXor returns a new xor instruction based on the given operands.
   340  func NewXor(x, y value.Value) *InstXor {
   341  	inst := &InstXor{X: x, Y: y}
   342  	// Compute type.
   343  	inst.Type()
   344  	return inst
   345  }
   346  
   347  // String returns the LLVM syntax representation of the instruction as a
   348  // type-value pair.
   349  func (inst *InstXor) String() string {
   350  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   351  }
   352  
   353  // Type returns the type of the instruction.
   354  func (inst *InstXor) Type() types.Type {
   355  	// Cache type if not present.
   356  	if inst.Typ == nil {
   357  		inst.Typ = inst.X.Type()
   358  	}
   359  	return inst.Typ
   360  }
   361  
   362  // LLString returns the LLVM syntax representation of the instruction.
   363  //
   364  // 'xor' X=TypeValue ',' Y=Value Metadata=(',' MetadataAttachment)+?
   365  func (inst *InstXor) LLString() string {
   366  	buf := &strings.Builder{}
   367  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   368  	fmt.Fprintf(buf, "xor %s, %s", inst.X, inst.Y.Ident())
   369  	for _, md := range inst.Metadata {
   370  		fmt.Fprintf(buf, ", %s", md)
   371  	}
   372  	return buf.String()
   373  }
   374  
   375  // Operands returns a mutable list of operands of the given instruction.
   376  func (inst *InstXor) Operands() []*value.Value {
   377  	return []*value.Value{&inst.X, &inst.Y}
   378  }