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

     1  package ir
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/llir/llvm/ir/types"
     8  	"github.com/llir/llvm/ir/value"
     9  )
    10  
    11  // --- [ Conversion instructions ] ---------------------------------------------
    12  
    13  // ~~~ [ trunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    14  
    15  // InstTrunc is an LLVM IR trunc instruction.
    16  type InstTrunc struct {
    17  	// Name of local variable associated with the result.
    18  	LocalIdent
    19  	// Value before conversion.
    20  	From value.Value
    21  	// Type after conversion.
    22  	To types.Type
    23  
    24  	// extra.
    25  
    26  	// (optional) Metadata.
    27  	Metadata
    28  }
    29  
    30  // NewTrunc returns a new trunc instruction based on the given source value and
    31  // target type.
    32  func NewTrunc(from value.Value, to types.Type) *InstTrunc {
    33  	// Type-check operands.
    34  	fromType := from.Type()
    35  	// Note: intentional alias, so we can use it for checking
    36  	// the integer types within vectors.
    37  	toType := to
    38  	if fromVectorT, ok := fromType.(*types.VectorType); ok {
    39  		toVectorT, ok := toType.(*types.VectorType)
    40  		if !ok {
    41  			panic(fmt.Errorf("trunc operands are not compatible: from=%v; to=%v", fromVectorT, to))
    42  		}
    43  		if fromVectorT.Len != toVectorT.Len {
    44  			panic(fmt.Errorf("trunc vector operand length mismatch: from=%v; to=%v", from.Type(), to))
    45  		}
    46  		fromType = fromVectorT.ElemType
    47  		toType = toVectorT.ElemType
    48  	}
    49  	if fromIntT, ok := fromType.(*types.IntType); ok {
    50  		toIntT, ok := toType.(*types.IntType)
    51  		if !ok {
    52  			panic(fmt.Errorf("trunc operands are not compatible: from=%v; to=%T", fromIntT, to))
    53  		}
    54  		fromSize := fromIntT.BitSize
    55  		toSize := toIntT.BitSize
    56  		if fromSize < toSize {
    57  			panic(fmt.Errorf("invalid trunc operands: from.BitSize < to.BitSize (%v is smaller than %v)", from.Type(), to))
    58  		}
    59  	}
    60  	return &InstTrunc{From: from, To: to}
    61  }
    62  
    63  // String returns the LLVM syntax representation of the instruction as a
    64  // type-value pair.
    65  func (inst *InstTrunc) String() string {
    66  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
    67  }
    68  
    69  // Type returns the type of the instruction.
    70  func (inst *InstTrunc) Type() types.Type {
    71  	return inst.To
    72  }
    73  
    74  // LLString returns the LLVM syntax representation of the instruction.
    75  //
    76  // 'trunc' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
    77  func (inst *InstTrunc) LLString() string {
    78  	buf := &strings.Builder{}
    79  	fmt.Fprintf(buf, "%s = ", inst.Ident())
    80  	fmt.Fprintf(buf, "trunc %s to %s", inst.From, inst.To)
    81  	for _, md := range inst.Metadata {
    82  		fmt.Fprintf(buf, ", %s", md)
    83  	}
    84  	return buf.String()
    85  }
    86  
    87  // Operands returns a mutable list of operands of the given instruction.
    88  func (inst *InstTrunc) Operands() []*value.Value {
    89  	return []*value.Value{&inst.From}
    90  }
    91  
    92  // ~~~ [ zext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    93  
    94  // InstZExt is an LLVM IR zext instruction.
    95  type InstZExt struct {
    96  	// Name of local variable associated with the result.
    97  	LocalIdent
    98  	// Value before conversion.
    99  	From value.Value
   100  	// Type after conversion.
   101  	To types.Type
   102  
   103  	// extra.
   104  
   105  	// (optional) Metadata.
   106  	Metadata
   107  }
   108  
   109  // NewZExt returns a new zext instruction based on the given source value and
   110  // target type.
   111  func NewZExt(from value.Value, to types.Type) *InstZExt {
   112  	return &InstZExt{From: from, To: to}
   113  }
   114  
   115  // String returns the LLVM syntax representation of the instruction as a
   116  // type-value pair.
   117  func (inst *InstZExt) String() string {
   118  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   119  }
   120  
   121  // Type returns the type of the instruction.
   122  func (inst *InstZExt) Type() types.Type {
   123  	return inst.To
   124  }
   125  
   126  // LLString returns the LLVM syntax representation of the instruction.
   127  //
   128  // 'zext' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   129  func (inst *InstZExt) LLString() string {
   130  	buf := &strings.Builder{}
   131  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   132  	fmt.Fprintf(buf, "zext %s to %s", inst.From, inst.To)
   133  	for _, md := range inst.Metadata {
   134  		fmt.Fprintf(buf, ", %s", md)
   135  	}
   136  	return buf.String()
   137  }
   138  
   139  // Operands returns a mutable list of operands of the given instruction.
   140  func (inst *InstZExt) Operands() []*value.Value {
   141  	return []*value.Value{&inst.From}
   142  }
   143  
   144  // ~~~ [ sext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   145  
   146  // InstSExt is an LLVM IR sext instruction.
   147  type InstSExt struct {
   148  	// Name of local variable associated with the result.
   149  	LocalIdent
   150  	// Value before conversion.
   151  	From value.Value
   152  	// Type after conversion.
   153  	To types.Type
   154  
   155  	// extra.
   156  
   157  	// (optional) Metadata.
   158  	Metadata
   159  }
   160  
   161  // NewSExt returns a new sext instruction based on the given source value and
   162  // target type.
   163  func NewSExt(from value.Value, to types.Type) *InstSExt {
   164  	return &InstSExt{From: from, To: to}
   165  }
   166  
   167  // String returns the LLVM syntax representation of the instruction as a
   168  // type-value pair.
   169  func (inst *InstSExt) String() string {
   170  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   171  }
   172  
   173  // Type returns the type of the instruction.
   174  func (inst *InstSExt) Type() types.Type {
   175  	return inst.To
   176  }
   177  
   178  // LLString returns the LLVM syntax representation of the instruction.
   179  //
   180  // 'sext' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   181  func (inst *InstSExt) LLString() string {
   182  	buf := &strings.Builder{}
   183  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   184  	fmt.Fprintf(buf, "sext %s to %s", inst.From, inst.To)
   185  	for _, md := range inst.Metadata {
   186  		fmt.Fprintf(buf, ", %s", md)
   187  	}
   188  	return buf.String()
   189  }
   190  
   191  // Operands returns a mutable list of operands of the given instruction.
   192  func (inst *InstSExt) Operands() []*value.Value {
   193  	return []*value.Value{&inst.From}
   194  }
   195  
   196  // ~~~ [ fptrunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   197  
   198  // InstFPTrunc is an LLVM IR fptrunc instruction.
   199  type InstFPTrunc struct {
   200  	// Name of local variable associated with the result.
   201  	LocalIdent
   202  	// Value before conversion.
   203  	From value.Value
   204  	// Type after conversion.
   205  	To types.Type
   206  
   207  	// extra.
   208  
   209  	// (optional) Metadata.
   210  	Metadata
   211  }
   212  
   213  // NewFPTrunc returns a new fptrunc instruction based on the given source value
   214  // and target type.
   215  func NewFPTrunc(from value.Value, to types.Type) *InstFPTrunc {
   216  	return &InstFPTrunc{From: from, To: to}
   217  }
   218  
   219  // String returns the LLVM syntax representation of the instruction as a
   220  // type-value pair.
   221  func (inst *InstFPTrunc) String() string {
   222  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   223  }
   224  
   225  // Type returns the type of the instruction.
   226  func (inst *InstFPTrunc) Type() types.Type {
   227  	return inst.To
   228  }
   229  
   230  // LLString returns the LLVM syntax representation of the instruction.
   231  //
   232  // 'fptrunc' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   233  func (inst *InstFPTrunc) LLString() string {
   234  	buf := &strings.Builder{}
   235  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   236  	fmt.Fprintf(buf, "fptrunc %s to %s", inst.From, inst.To)
   237  	for _, md := range inst.Metadata {
   238  		fmt.Fprintf(buf, ", %s", md)
   239  	}
   240  	return buf.String()
   241  }
   242  
   243  // Operands returns a mutable list of operands of the given instruction.
   244  func (inst *InstFPTrunc) Operands() []*value.Value {
   245  	return []*value.Value{&inst.From}
   246  }
   247  
   248  // ~~~ [ fpext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   249  
   250  // InstFPExt is an LLVM IR fpext instruction.
   251  type InstFPExt struct {
   252  	// Name of local variable associated with the result.
   253  	LocalIdent
   254  	// Value before conversion.
   255  	From value.Value
   256  	// Type after conversion.
   257  	To types.Type
   258  
   259  	// extra.
   260  
   261  	// (optional) Metadata.
   262  	Metadata
   263  }
   264  
   265  // NewFPExt returns a new fpext instruction based on the given source value and
   266  // target type.
   267  func NewFPExt(from value.Value, to types.Type) *InstFPExt {
   268  	return &InstFPExt{From: from, To: to}
   269  }
   270  
   271  // String returns the LLVM syntax representation of the instruction as a
   272  // type-value pair.
   273  func (inst *InstFPExt) String() string {
   274  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   275  }
   276  
   277  // Type returns the type of the instruction.
   278  func (inst *InstFPExt) Type() types.Type {
   279  	return inst.To
   280  }
   281  
   282  // LLString returns the LLVM syntax representation of the instruction.
   283  //
   284  // 'fpext' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   285  func (inst *InstFPExt) LLString() string {
   286  	buf := &strings.Builder{}
   287  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   288  	fmt.Fprintf(buf, "fpext %s to %s", inst.From, inst.To)
   289  	for _, md := range inst.Metadata {
   290  		fmt.Fprintf(buf, ", %s", md)
   291  	}
   292  	return buf.String()
   293  }
   294  
   295  // Operands returns a mutable list of operands of the given instruction.
   296  func (inst *InstFPExt) Operands() []*value.Value {
   297  	return []*value.Value{&inst.From}
   298  }
   299  
   300  // ~~~ [ fptoui ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   301  
   302  // InstFPToUI is an LLVM IR fptoui instruction.
   303  type InstFPToUI struct {
   304  	// Name of local variable associated with the result.
   305  	LocalIdent
   306  	// Value before conversion.
   307  	From value.Value
   308  	// Type after conversion.
   309  	To types.Type
   310  
   311  	// extra.
   312  
   313  	// (optional) Metadata.
   314  	Metadata
   315  }
   316  
   317  // NewFPToUI returns a new fptoui instruction based on the given source value
   318  // and target type.
   319  func NewFPToUI(from value.Value, to types.Type) *InstFPToUI {
   320  	return &InstFPToUI{From: from, To: to}
   321  }
   322  
   323  // String returns the LLVM syntax representation of the instruction as a
   324  // type-value pair.
   325  func (inst *InstFPToUI) String() string {
   326  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   327  }
   328  
   329  // Type returns the type of the instruction.
   330  func (inst *InstFPToUI) Type() types.Type {
   331  	return inst.To
   332  }
   333  
   334  // LLString returns the LLVM syntax representation of the instruction.
   335  //
   336  // 'fptoui' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   337  func (inst *InstFPToUI) LLString() string {
   338  	buf := &strings.Builder{}
   339  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   340  	fmt.Fprintf(buf, "fptoui %s to %s", inst.From, inst.To)
   341  	for _, md := range inst.Metadata {
   342  		fmt.Fprintf(buf, ", %s", md)
   343  	}
   344  	return buf.String()
   345  }
   346  
   347  // Operands returns a mutable list of operands of the given instruction.
   348  func (inst *InstFPToUI) Operands() []*value.Value {
   349  	return []*value.Value{&inst.From}
   350  }
   351  
   352  // ~~~ [ fptosi ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   353  
   354  // InstFPToSI is an LLVM IR fptosi instruction.
   355  type InstFPToSI struct {
   356  	// Name of local variable associated with the result.
   357  	LocalIdent
   358  	// Value before conversion.
   359  	From value.Value
   360  	// Type after conversion.
   361  	To types.Type
   362  
   363  	// extra.
   364  
   365  	// (optional) Metadata.
   366  	Metadata
   367  }
   368  
   369  // NewFPToSI returns a new fptosi instruction based on the given source value
   370  // and target type.
   371  func NewFPToSI(from value.Value, to types.Type) *InstFPToSI {
   372  	return &InstFPToSI{From: from, To: to}
   373  }
   374  
   375  // String returns the LLVM syntax representation of the instruction as a
   376  // type-value pair.
   377  func (inst *InstFPToSI) String() string {
   378  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   379  }
   380  
   381  // Type returns the type of the instruction.
   382  func (inst *InstFPToSI) Type() types.Type {
   383  	return inst.To
   384  }
   385  
   386  // LLString returns the LLVM syntax representation of the instruction.
   387  //
   388  // 'fptosi' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   389  func (inst *InstFPToSI) LLString() string {
   390  	buf := &strings.Builder{}
   391  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   392  	fmt.Fprintf(buf, "fptosi %s to %s", inst.From, inst.To)
   393  	for _, md := range inst.Metadata {
   394  		fmt.Fprintf(buf, ", %s", md)
   395  	}
   396  	return buf.String()
   397  }
   398  
   399  // Operands returns a mutable list of operands of the given instruction.
   400  func (inst *InstFPToSI) Operands() []*value.Value {
   401  	return []*value.Value{&inst.From}
   402  }
   403  
   404  // ~~~ [ uitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   405  
   406  // InstUIToFP is an LLVM IR uitofp instruction.
   407  type InstUIToFP struct {
   408  	// Name of local variable associated with the result.
   409  	LocalIdent
   410  	// Value before conversion.
   411  	From value.Value
   412  	// Type after conversion.
   413  	To types.Type
   414  
   415  	// extra.
   416  
   417  	// (optional) Metadata.
   418  	Metadata
   419  }
   420  
   421  // NewUIToFP returns a new uitofp instruction based on the given source value
   422  // and target type.
   423  func NewUIToFP(from value.Value, to types.Type) *InstUIToFP {
   424  	return &InstUIToFP{From: from, To: to}
   425  }
   426  
   427  // String returns the LLVM syntax representation of the instruction as a
   428  // type-value pair.
   429  func (inst *InstUIToFP) String() string {
   430  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   431  }
   432  
   433  // Type returns the type of the instruction.
   434  func (inst *InstUIToFP) Type() types.Type {
   435  	return inst.To
   436  }
   437  
   438  // LLString returns the LLVM syntax representation of the instruction.
   439  //
   440  // 'uitofp' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   441  func (inst *InstUIToFP) LLString() string {
   442  	buf := &strings.Builder{}
   443  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   444  	fmt.Fprintf(buf, "uitofp %s to %s", inst.From, inst.To)
   445  	for _, md := range inst.Metadata {
   446  		fmt.Fprintf(buf, ", %s", md)
   447  	}
   448  	return buf.String()
   449  }
   450  
   451  // Operands returns a mutable list of operands of the given instruction.
   452  func (inst *InstUIToFP) Operands() []*value.Value {
   453  	return []*value.Value{&inst.From}
   454  }
   455  
   456  // ~~~ [ sitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   457  
   458  // InstSIToFP is an LLVM IR sitofp instruction.
   459  type InstSIToFP struct {
   460  	// Name of local variable associated with the result.
   461  	LocalIdent
   462  	// Value before conversion.
   463  	From value.Value
   464  	// Type after conversion.
   465  	To types.Type
   466  
   467  	// extra.
   468  
   469  	// (optional) Metadata.
   470  	Metadata
   471  }
   472  
   473  // NewSIToFP returns a new sitofp instruction based on the given source value
   474  // and target type.
   475  func NewSIToFP(from value.Value, to types.Type) *InstSIToFP {
   476  	return &InstSIToFP{From: from, To: to}
   477  }
   478  
   479  // String returns the LLVM syntax representation of the instruction as a
   480  // type-value pair.
   481  func (inst *InstSIToFP) String() string {
   482  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   483  }
   484  
   485  // Type returns the type of the instruction.
   486  func (inst *InstSIToFP) Type() types.Type {
   487  	return inst.To
   488  }
   489  
   490  // LLString returns the LLVM syntax representation of the instruction.
   491  //
   492  // 'sitofp' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   493  func (inst *InstSIToFP) LLString() string {
   494  	buf := &strings.Builder{}
   495  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   496  	fmt.Fprintf(buf, "sitofp %s to %s", inst.From, inst.To)
   497  	for _, md := range inst.Metadata {
   498  		fmt.Fprintf(buf, ", %s", md)
   499  	}
   500  	return buf.String()
   501  }
   502  
   503  // Operands returns a mutable list of operands of the given instruction.
   504  func (inst *InstSIToFP) Operands() []*value.Value {
   505  	return []*value.Value{&inst.From}
   506  }
   507  
   508  // ~~~ [ ptrtoint ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   509  
   510  // InstPtrToInt is an LLVM IR ptrtoint instruction.
   511  type InstPtrToInt struct {
   512  	// Name of local variable associated with the result.
   513  	LocalIdent
   514  	// Value before conversion.
   515  	From value.Value
   516  	// Type after conversion.
   517  	To types.Type
   518  
   519  	// extra.
   520  
   521  	// (optional) Metadata.
   522  	Metadata
   523  }
   524  
   525  // NewPtrToInt returns a new ptrtoint instruction based on the given source
   526  // value and target type.
   527  func NewPtrToInt(from value.Value, to types.Type) *InstPtrToInt {
   528  	return &InstPtrToInt{From: from, To: to}
   529  }
   530  
   531  // String returns the LLVM syntax representation of the instruction as a
   532  // type-value pair.
   533  func (inst *InstPtrToInt) String() string {
   534  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   535  }
   536  
   537  // Type returns the type of the instruction.
   538  func (inst *InstPtrToInt) Type() types.Type {
   539  	return inst.To
   540  }
   541  
   542  // LLString returns the LLVM syntax representation of the instruction.
   543  //
   544  // 'ptrtoint' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   545  func (inst *InstPtrToInt) LLString() string {
   546  	buf := &strings.Builder{}
   547  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   548  	fmt.Fprintf(buf, "ptrtoint %s to %s", inst.From, inst.To)
   549  	for _, md := range inst.Metadata {
   550  		fmt.Fprintf(buf, ", %s", md)
   551  	}
   552  	return buf.String()
   553  }
   554  
   555  // Operands returns a mutable list of operands of the given instruction.
   556  func (inst *InstPtrToInt) Operands() []*value.Value {
   557  	return []*value.Value{&inst.From}
   558  }
   559  
   560  // ~~~ [ inttoptr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   561  
   562  // InstIntToPtr is an LLVM IR inttoptr instruction.
   563  type InstIntToPtr struct {
   564  	// Name of local variable associated with the result.
   565  	LocalIdent
   566  	// Value before conversion.
   567  	From value.Value
   568  	// Type after conversion.
   569  	To types.Type
   570  
   571  	// extra.
   572  
   573  	// (optional) Metadata.
   574  	Metadata
   575  }
   576  
   577  // NewIntToPtr returns a new inttoptr instruction based on the given source
   578  // value and target type.
   579  func NewIntToPtr(from value.Value, to types.Type) *InstIntToPtr {
   580  	return &InstIntToPtr{From: from, To: to}
   581  }
   582  
   583  // String returns the LLVM syntax representation of the instruction as a
   584  // type-value pair.
   585  func (inst *InstIntToPtr) String() string {
   586  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   587  }
   588  
   589  // Type returns the type of the instruction.
   590  func (inst *InstIntToPtr) Type() types.Type {
   591  	return inst.To
   592  }
   593  
   594  // LLString returns the LLVM syntax representation of the instruction.
   595  //
   596  // 'inttoptr' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   597  func (inst *InstIntToPtr) LLString() string {
   598  	buf := &strings.Builder{}
   599  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   600  	fmt.Fprintf(buf, "inttoptr %s to %s", inst.From, inst.To)
   601  	for _, md := range inst.Metadata {
   602  		fmt.Fprintf(buf, ", %s", md)
   603  	}
   604  	return buf.String()
   605  }
   606  
   607  // Operands returns a mutable list of operands of the given instruction.
   608  func (inst *InstIntToPtr) Operands() []*value.Value {
   609  	return []*value.Value{&inst.From}
   610  }
   611  
   612  // ~~~ [ bitcast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   613  
   614  // InstBitCast is an LLVM IR bitcast instruction.
   615  type InstBitCast struct {
   616  	// Name of local variable associated with the result.
   617  	LocalIdent
   618  	// Value before conversion.
   619  	From value.Value
   620  	// Type after conversion.
   621  	To types.Type
   622  
   623  	// extra.
   624  
   625  	// (optional) Metadata.
   626  	Metadata
   627  }
   628  
   629  // NewBitCast returns a new bitcast instruction based on the given source value
   630  // and target type.
   631  func NewBitCast(from value.Value, to types.Type) *InstBitCast {
   632  	return &InstBitCast{From: from, To: to}
   633  }
   634  
   635  // String returns the LLVM syntax representation of the instruction as a
   636  // type-value pair.
   637  func (inst *InstBitCast) String() string {
   638  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   639  }
   640  
   641  // Type returns the type of the instruction.
   642  func (inst *InstBitCast) Type() types.Type {
   643  	return inst.To
   644  }
   645  
   646  // LLString returns the LLVM syntax representation of the instruction.
   647  //
   648  // 'bitcast' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   649  func (inst *InstBitCast) LLString() string {
   650  	buf := &strings.Builder{}
   651  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   652  	fmt.Fprintf(buf, "bitcast %s to %s", inst.From, inst.To)
   653  	for _, md := range inst.Metadata {
   654  		fmt.Fprintf(buf, ", %s", md)
   655  	}
   656  	return buf.String()
   657  }
   658  
   659  // Operands returns a mutable list of operands of the given instruction.
   660  func (inst *InstBitCast) Operands() []*value.Value {
   661  	return []*value.Value{&inst.From}
   662  }
   663  
   664  // ~~~ [ addrspacecast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   665  
   666  // InstAddrSpaceCast is an LLVM IR addrspacecast instruction.
   667  type InstAddrSpaceCast struct {
   668  	// Name of local variable associated with the result.
   669  	LocalIdent
   670  	// Value before conversion.
   671  	From value.Value
   672  	// Type after conversion.
   673  	To types.Type
   674  
   675  	// extra.
   676  
   677  	// (optional) Metadata.
   678  	Metadata
   679  }
   680  
   681  // NewAddrSpaceCast returns a new addrspacecast instruction based on the given
   682  // source value and target type.
   683  func NewAddrSpaceCast(from value.Value, to types.Type) *InstAddrSpaceCast {
   684  	return &InstAddrSpaceCast{From: from, To: to}
   685  }
   686  
   687  // String returns the LLVM syntax representation of the instruction as a
   688  // type-value pair.
   689  func (inst *InstAddrSpaceCast) String() string {
   690  	return fmt.Sprintf("%s %s", inst.Type(), inst.Ident())
   691  }
   692  
   693  // Type returns the type of the instruction.
   694  func (inst *InstAddrSpaceCast) Type() types.Type {
   695  	return inst.To
   696  }
   697  
   698  // LLString returns the LLVM syntax representation of the instruction.
   699  //
   700  // 'addrspacecast' From=TypeValue 'to' To=Type Metadata=(',' MetadataAttachment)+?
   701  func (inst *InstAddrSpaceCast) LLString() string {
   702  	buf := &strings.Builder{}
   703  	fmt.Fprintf(buf, "%s = ", inst.Ident())
   704  	fmt.Fprintf(buf, "addrspacecast %s to %s", inst.From, inst.To)
   705  	for _, md := range inst.Metadata {
   706  		fmt.Fprintf(buf, ", %s", md)
   707  	}
   708  	return buf.String()
   709  }
   710  
   711  // Operands returns a mutable list of operands of the given instruction.
   712  func (inst *InstAddrSpaceCast) Operands() []*value.Value {
   713  	return []*value.Value{&inst.From}
   714  }