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

     1  package asm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/llir/ll/ast"
     7  	"github.com/llir/llvm/ir"
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // === [ Create IR ] ===========================================================
    12  
    13  // newTruncInst returns a new IR trunc instruction (without body but with type)
    14  // based on the given AST trunc instruction.
    15  func (fgen *funcGen) newTruncInst(ident ir.LocalIdent, old *ast.TruncInst) (*ir.InstTrunc, error) {
    16  	to, err := fgen.gen.irType(old.To())
    17  	if err != nil {
    18  		return nil, errors.WithStack(err)
    19  	}
    20  	return &ir.InstTrunc{LocalIdent: ident, To: to}, nil
    21  }
    22  
    23  // newZExtInst returns a new IR zext instruction (without body but with type)
    24  // based on the given AST zext instruction.
    25  func (fgen *funcGen) newZExtInst(ident ir.LocalIdent, old *ast.ZExtInst) (*ir.InstZExt, error) {
    26  	to, err := fgen.gen.irType(old.To())
    27  	if err != nil {
    28  		return nil, errors.WithStack(err)
    29  	}
    30  	return &ir.InstZExt{LocalIdent: ident, To: to}, nil
    31  }
    32  
    33  // newSExtInst returns a new IR sext instruction (without body but with type)
    34  // based on the given AST sext instruction.
    35  func (fgen *funcGen) newSExtInst(ident ir.LocalIdent, old *ast.SExtInst) (*ir.InstSExt, error) {
    36  	to, err := fgen.gen.irType(old.To())
    37  	if err != nil {
    38  		return nil, errors.WithStack(err)
    39  	}
    40  	return &ir.InstSExt{LocalIdent: ident, To: to}, nil
    41  }
    42  
    43  // newFPTruncInst returns a new IR fptrunc instruction (without body but with
    44  // type) based on the given AST fptrunc instruction.
    45  func (fgen *funcGen) newFPTruncInst(ident ir.LocalIdent, old *ast.FPTruncInst) (*ir.InstFPTrunc, error) {
    46  	to, err := fgen.gen.irType(old.To())
    47  	if err != nil {
    48  		return nil, errors.WithStack(err)
    49  	}
    50  	return &ir.InstFPTrunc{LocalIdent: ident, To: to}, nil
    51  }
    52  
    53  // newFPExtInst returns a new IR fpext instruction (without body but with type)
    54  // based on the given AST fpext instruction.
    55  func (fgen *funcGen) newFPExtInst(ident ir.LocalIdent, old *ast.FPExtInst) (*ir.InstFPExt, error) {
    56  	to, err := fgen.gen.irType(old.To())
    57  	if err != nil {
    58  		return nil, errors.WithStack(err)
    59  	}
    60  	return &ir.InstFPExt{LocalIdent: ident, To: to}, nil
    61  }
    62  
    63  // newFPToUIInst returns a new IR fptoui instruction (without body but with
    64  // type) based on the given AST fptoui instruction.
    65  func (fgen *funcGen) newFPToUIInst(ident ir.LocalIdent, old *ast.FPToUIInst) (*ir.InstFPToUI, error) {
    66  	to, err := fgen.gen.irType(old.To())
    67  	if err != nil {
    68  		return nil, errors.WithStack(err)
    69  	}
    70  	return &ir.InstFPToUI{LocalIdent: ident, To: to}, nil
    71  }
    72  
    73  // newFPToSIInst returns a new IR fptosi instruction (without body but with
    74  // type) based on the given AST fptosi instruction.
    75  func (fgen *funcGen) newFPToSIInst(ident ir.LocalIdent, old *ast.FPToSIInst) (*ir.InstFPToSI, error) {
    76  	to, err := fgen.gen.irType(old.To())
    77  	if err != nil {
    78  		return nil, errors.WithStack(err)
    79  	}
    80  	return &ir.InstFPToSI{LocalIdent: ident, To: to}, nil
    81  }
    82  
    83  // newUIToFPInst returns a new IR uitofp instruction (without body but with
    84  // type) based on the given AST uitofp instruction.
    85  func (fgen *funcGen) newUIToFPInst(ident ir.LocalIdent, old *ast.UIToFPInst) (*ir.InstUIToFP, error) {
    86  	to, err := fgen.gen.irType(old.To())
    87  	if err != nil {
    88  		return nil, errors.WithStack(err)
    89  	}
    90  	return &ir.InstUIToFP{LocalIdent: ident, To: to}, nil
    91  }
    92  
    93  // newSIToFPInst returns a new IR sitofp instruction (without body but with
    94  // type) based on the given AST sitofp instruction.
    95  func (fgen *funcGen) newSIToFPInst(ident ir.LocalIdent, old *ast.SIToFPInst) (*ir.InstSIToFP, error) {
    96  	to, err := fgen.gen.irType(old.To())
    97  	if err != nil {
    98  		return nil, errors.WithStack(err)
    99  	}
   100  	return &ir.InstSIToFP{LocalIdent: ident, To: to}, nil
   101  }
   102  
   103  // newPtrToIntInst returns a new IR ptrtoint instruction (without body but with
   104  // type) based on the given AST ptrtoint instruction.
   105  func (fgen *funcGen) newPtrToIntInst(ident ir.LocalIdent, old *ast.PtrToIntInst) (*ir.InstPtrToInt, error) {
   106  	to, err := fgen.gen.irType(old.To())
   107  	if err != nil {
   108  		return nil, errors.WithStack(err)
   109  	}
   110  	return &ir.InstPtrToInt{LocalIdent: ident, To: to}, nil
   111  }
   112  
   113  // newIntToPtrInst returns a new IR inttoptr instruction (without body but with
   114  // type) based on the given AST inttoptr instruction.
   115  func (fgen *funcGen) newIntToPtrInst(ident ir.LocalIdent, old *ast.IntToPtrInst) (*ir.InstIntToPtr, error) {
   116  	to, err := fgen.gen.irType(old.To())
   117  	if err != nil {
   118  		return nil, errors.WithStack(err)
   119  	}
   120  	return &ir.InstIntToPtr{LocalIdent: ident, To: to}, nil
   121  }
   122  
   123  // newBitCastInst returns a new IR bitcast instruction (without body but with
   124  // type) based on the given AST bitcast instruction.
   125  func (fgen *funcGen) newBitCastInst(ident ir.LocalIdent, old *ast.BitCastInst) (*ir.InstBitCast, error) {
   126  	to, err := fgen.gen.irType(old.To())
   127  	if err != nil {
   128  		return nil, errors.WithStack(err)
   129  	}
   130  	return &ir.InstBitCast{LocalIdent: ident, To: to}, nil
   131  }
   132  
   133  // newAddrSpaceCastInst returns a new IR addrspacecast instruction (without body
   134  // but with type) based on the given AST addrspacecast instruction.
   135  func (fgen *funcGen) newAddrSpaceCastInst(ident ir.LocalIdent, old *ast.AddrSpaceCastInst) (*ir.InstAddrSpaceCast, error) {
   136  	to, err := fgen.gen.irType(old.To())
   137  	if err != nil {
   138  		return nil, errors.WithStack(err)
   139  	}
   140  	return &ir.InstAddrSpaceCast{LocalIdent: ident, To: to}, nil
   141  }
   142  
   143  // === [ Translate AST to IR ] =================================================
   144  
   145  // --- [ trunc ] ---------------------------------------------------------------
   146  
   147  // irTruncInst translates the given AST trunc instruction into an equivalent IR
   148  // instruction.
   149  func (fgen *funcGen) irTruncInst(new ir.Instruction, old *ast.TruncInst) error {
   150  	inst, ok := new.(*ir.InstTrunc)
   151  	if !ok {
   152  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstTrunc, got %T", new))
   153  	}
   154  	// Value before conversion.
   155  	from, err := fgen.irTypeValue(old.From())
   156  	if err != nil {
   157  		return errors.WithStack(err)
   158  	}
   159  	inst.From = from
   160  	// Type after conversion.
   161  	to, err := fgen.gen.irType(old.To())
   162  	if err != nil {
   163  		return errors.WithStack(err)
   164  	}
   165  	inst.To = to
   166  	// (optional) Metadata.
   167  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   168  	if err != nil {
   169  		return errors.WithStack(err)
   170  	}
   171  	inst.Metadata = md
   172  	return nil
   173  }
   174  
   175  // --- [ zext ] ----------------------------------------------------------------
   176  
   177  // irZExtInst translates the given AST zext instruction into an equivalent IR
   178  // instruction.
   179  func (fgen *funcGen) irZExtInst(new ir.Instruction, old *ast.ZExtInst) error {
   180  	inst, ok := new.(*ir.InstZExt)
   181  	if !ok {
   182  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstZExt, got %T", new))
   183  	}
   184  	// Value before conversion.
   185  	from, err := fgen.irTypeValue(old.From())
   186  	if err != nil {
   187  		return errors.WithStack(err)
   188  	}
   189  	inst.From = from
   190  	// Type after conversion.
   191  	to, err := fgen.gen.irType(old.To())
   192  	if err != nil {
   193  		return errors.WithStack(err)
   194  	}
   195  	inst.To = to
   196  	// (optional) Metadata.
   197  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   198  	if err != nil {
   199  		return errors.WithStack(err)
   200  	}
   201  	inst.Metadata = md
   202  	return nil
   203  }
   204  
   205  // --- [ sext ] ----------------------------------------------------------------
   206  
   207  // irSExtInst translates the given AST sext instruction into an equivalent IR
   208  // instruction.
   209  func (fgen *funcGen) irSExtInst(new ir.Instruction, old *ast.SExtInst) error {
   210  	inst, ok := new.(*ir.InstSExt)
   211  	if !ok {
   212  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstSExt, got %T", new))
   213  	}
   214  	// Value before conversion.
   215  	from, err := fgen.irTypeValue(old.From())
   216  	if err != nil {
   217  		return errors.WithStack(err)
   218  	}
   219  	inst.From = from
   220  	// Type after conversion.
   221  	to, err := fgen.gen.irType(old.To())
   222  	if err != nil {
   223  		return errors.WithStack(err)
   224  	}
   225  	inst.To = to
   226  	// (optional) Metadata.
   227  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   228  	if err != nil {
   229  		return errors.WithStack(err)
   230  	}
   231  	inst.Metadata = md
   232  	return nil
   233  }
   234  
   235  // --- [ fptrunc ] -------------------------------------------------------------
   236  
   237  // irFPTruncInst translates the given AST fptrunc instruction into an equivalent
   238  // IR instruction.
   239  func (fgen *funcGen) irFPTruncInst(new ir.Instruction, old *ast.FPTruncInst) error {
   240  	inst, ok := new.(*ir.InstFPTrunc)
   241  	if !ok {
   242  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPTrunc, got %T", new))
   243  	}
   244  	// Value before conversion.
   245  	from, err := fgen.irTypeValue(old.From())
   246  	if err != nil {
   247  		return errors.WithStack(err)
   248  	}
   249  	inst.From = from
   250  	// Type after conversion.
   251  	to, err := fgen.gen.irType(old.To())
   252  	if err != nil {
   253  		return errors.WithStack(err)
   254  	}
   255  	inst.To = to
   256  	// (optional) Metadata.
   257  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   258  	if err != nil {
   259  		return errors.WithStack(err)
   260  	}
   261  	inst.Metadata = md
   262  	return nil
   263  }
   264  
   265  // --- [ fpext ] ---------------------------------------------------------------
   266  
   267  // irFPExtInst translates the given AST fpext instruction into an equivalent IR
   268  // instruction.
   269  func (fgen *funcGen) irFPExtInst(new ir.Instruction, old *ast.FPExtInst) error {
   270  	inst, ok := new.(*ir.InstFPExt)
   271  	if !ok {
   272  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPExt, got %T", new))
   273  	}
   274  	// Value before conversion.
   275  	from, err := fgen.irTypeValue(old.From())
   276  	if err != nil {
   277  		return errors.WithStack(err)
   278  	}
   279  	inst.From = from
   280  	// Type after conversion.
   281  	to, err := fgen.gen.irType(old.To())
   282  	if err != nil {
   283  		return errors.WithStack(err)
   284  	}
   285  	inst.To = to
   286  	// (optional) Metadata.
   287  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   288  	if err != nil {
   289  		return errors.WithStack(err)
   290  	}
   291  	inst.Metadata = md
   292  	return nil
   293  }
   294  
   295  // --- [ fptoui ] --------------------------------------------------------------
   296  
   297  // irFPToUIInst translates the given AST fptoui instruction into an equivalent
   298  // IR instruction.
   299  func (fgen *funcGen) irFPToUIInst(new ir.Instruction, old *ast.FPToUIInst) error {
   300  	inst, ok := new.(*ir.InstFPToUI)
   301  	if !ok {
   302  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPToUI, got %T", new))
   303  	}
   304  	// Value before conversion.
   305  	from, err := fgen.irTypeValue(old.From())
   306  	if err != nil {
   307  		return errors.WithStack(err)
   308  	}
   309  	inst.From = from
   310  	// Type after conversion.
   311  	to, err := fgen.gen.irType(old.To())
   312  	if err != nil {
   313  		return errors.WithStack(err)
   314  	}
   315  	inst.To = to
   316  	// (optional) Metadata.
   317  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   318  	if err != nil {
   319  		return errors.WithStack(err)
   320  	}
   321  	inst.Metadata = md
   322  	return nil
   323  }
   324  
   325  // --- [ fptosi ] --------------------------------------------------------------
   326  
   327  // irFPToSIInst translates the given AST fptosi instruction into an equivalent
   328  // IR instruction.
   329  func (fgen *funcGen) irFPToSIInst(new ir.Instruction, old *ast.FPToSIInst) error {
   330  	inst, ok := new.(*ir.InstFPToSI)
   331  	if !ok {
   332  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPToSI, got %T", new))
   333  	}
   334  	// Value before conversion.
   335  	from, err := fgen.irTypeValue(old.From())
   336  	if err != nil {
   337  		return errors.WithStack(err)
   338  	}
   339  	inst.From = from
   340  	// Type after conversion.
   341  	to, err := fgen.gen.irType(old.To())
   342  	if err != nil {
   343  		return errors.WithStack(err)
   344  	}
   345  	inst.To = to
   346  	// (optional) Metadata.
   347  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   348  	if err != nil {
   349  		return errors.WithStack(err)
   350  	}
   351  	inst.Metadata = md
   352  	return nil
   353  }
   354  
   355  // --- [ uitofp ] --------------------------------------------------------------
   356  
   357  // irUIToFPInst translates the given AST uitofp instruction into an equivalent
   358  // IR instruction.
   359  func (fgen *funcGen) irUIToFPInst(new ir.Instruction, old *ast.UIToFPInst) error {
   360  	inst, ok := new.(*ir.InstUIToFP)
   361  	if !ok {
   362  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstUIToFP, got %T", new))
   363  	}
   364  	// Value before conversion.
   365  	from, err := fgen.irTypeValue(old.From())
   366  	if err != nil {
   367  		return errors.WithStack(err)
   368  	}
   369  	inst.From = from
   370  	// Type after conversion.
   371  	to, err := fgen.gen.irType(old.To())
   372  	if err != nil {
   373  		return errors.WithStack(err)
   374  	}
   375  	inst.To = to
   376  	// (optional) Metadata.
   377  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   378  	if err != nil {
   379  		return errors.WithStack(err)
   380  	}
   381  	inst.Metadata = md
   382  	return nil
   383  }
   384  
   385  // --- [ sitofp ] --------------------------------------------------------------
   386  
   387  // irSIToFPInst translates the given AST sitofp instruction into an equivalent
   388  // IR instruction.
   389  func (fgen *funcGen) irSIToFPInst(new ir.Instruction, old *ast.SIToFPInst) error {
   390  	inst, ok := new.(*ir.InstSIToFP)
   391  	if !ok {
   392  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstSIToFP, got %T", new))
   393  	}
   394  	// Value before conversion.
   395  	from, err := fgen.irTypeValue(old.From())
   396  	if err != nil {
   397  		return errors.WithStack(err)
   398  	}
   399  	inst.From = from
   400  	// Type after conversion.
   401  	to, err := fgen.gen.irType(old.To())
   402  	if err != nil {
   403  		return errors.WithStack(err)
   404  	}
   405  	inst.To = to
   406  	// (optional) Metadata.
   407  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   408  	if err != nil {
   409  		return errors.WithStack(err)
   410  	}
   411  	inst.Metadata = md
   412  	return nil
   413  }
   414  
   415  // --- [ ptrtoint ] ------------------------------------------------------------
   416  
   417  // irPtrToIntInst translates the given AST ptrtoint instruction into an
   418  // equivalent IR instruction.
   419  func (fgen *funcGen) irPtrToIntInst(new ir.Instruction, old *ast.PtrToIntInst) error {
   420  	inst, ok := new.(*ir.InstPtrToInt)
   421  	if !ok {
   422  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstPtrToInt, got %T", new))
   423  	}
   424  	// Value before conversion.
   425  	from, err := fgen.irTypeValue(old.From())
   426  	if err != nil {
   427  		return errors.WithStack(err)
   428  	}
   429  	inst.From = from
   430  	// Type after conversion.
   431  	to, err := fgen.gen.irType(old.To())
   432  	if err != nil {
   433  		return errors.WithStack(err)
   434  	}
   435  	inst.To = to
   436  	// (optional) Metadata.
   437  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   438  	if err != nil {
   439  		return errors.WithStack(err)
   440  	}
   441  	inst.Metadata = md
   442  	return nil
   443  }
   444  
   445  // --- [ inttoptr ] ------------------------------------------------------------
   446  
   447  // irIntToPtrInst translates the given AST inttoptr instruction into an
   448  // equivalent IR instruction.
   449  func (fgen *funcGen) irIntToPtrInst(new ir.Instruction, old *ast.IntToPtrInst) error {
   450  	inst, ok := new.(*ir.InstIntToPtr)
   451  	if !ok {
   452  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstIntToPtr, got %T", new))
   453  	}
   454  	// Value before conversion.
   455  	from, err := fgen.irTypeValue(old.From())
   456  	if err != nil {
   457  		return errors.WithStack(err)
   458  	}
   459  	inst.From = from
   460  	// Type after conversion.
   461  	to, err := fgen.gen.irType(old.To())
   462  	if err != nil {
   463  		return errors.WithStack(err)
   464  	}
   465  	inst.To = to
   466  	// (optional) Metadata.
   467  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   468  	if err != nil {
   469  		return errors.WithStack(err)
   470  	}
   471  	inst.Metadata = md
   472  	return nil
   473  }
   474  
   475  // --- [ bitcast ] -------------------------------------------------------------
   476  
   477  // irBitCastInst translates the given AST bitcast instruction into an equivalent
   478  // IR instruction.
   479  func (fgen *funcGen) irBitCastInst(new ir.Instruction, old *ast.BitCastInst) error {
   480  	inst, ok := new.(*ir.InstBitCast)
   481  	if !ok {
   482  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstBitCast, got %T", new))
   483  	}
   484  	// Value before conversion.
   485  	from, err := fgen.irTypeValue(old.From())
   486  	if err != nil {
   487  		return errors.WithStack(err)
   488  	}
   489  	inst.From = from
   490  	// Type after conversion.
   491  	to, err := fgen.gen.irType(old.To())
   492  	if err != nil {
   493  		return errors.WithStack(err)
   494  	}
   495  	inst.To = to
   496  	// (optional) Metadata.
   497  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   498  	if err != nil {
   499  		return errors.WithStack(err)
   500  	}
   501  	inst.Metadata = md
   502  	return nil
   503  }
   504  
   505  // --- [ addrspacecast ] -------------------------------------------------------
   506  
   507  // irAddrSpaceCastInst translates the given AST addrspacecast instruction into
   508  // an equivalent IR instruction.
   509  func (fgen *funcGen) irAddrSpaceCastInst(new ir.Instruction, old *ast.AddrSpaceCastInst) error {
   510  	inst, ok := new.(*ir.InstAddrSpaceCast)
   511  	if !ok {
   512  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstAddrSpaceCast, got %T", new))
   513  	}
   514  	// Value before conversion.
   515  	from, err := fgen.irTypeValue(old.From())
   516  	if err != nil {
   517  		return errors.WithStack(err)
   518  	}
   519  	inst.From = from
   520  	// Type after conversion.
   521  	to, err := fgen.gen.irType(old.To())
   522  	if err != nil {
   523  		return errors.WithStack(err)
   524  	}
   525  	inst.To = to
   526  	// (optional) Metadata.
   527  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   528  	if err != nil {
   529  		return errors.WithStack(err)
   530  	}
   531  	inst.Metadata = md
   532  	return nil
   533  }