github.com/llir/llvm@v0.3.6/asm/inst.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  // newInst returns a new IR instruction (without body but with type) based on
    14  // the given AST instruction.
    15  func (fgen *funcGen) newInst(old ast.Instruction) (ir.Instruction, error) {
    16  	switch old := old.(type) {
    17  	// Value instructions.
    18  	case *ast.LocalDefInst:
    19  		ident := localIdent(old.Name())
    20  		return fgen.newValueInst(ident, old.Inst())
    21  	case ast.ValueInstruction:
    22  		unnamed := ir.LocalIdent{}
    23  		return fgen.newValueInst(unnamed, old)
    24  	// Non-value instructions.
    25  	case *ast.StoreInst:
    26  		return &ir.InstStore{}, nil
    27  	case *ast.FenceInst:
    28  		return &ir.InstFence{}, nil
    29  	default:
    30  		panic(fmt.Errorf("support for AST instruction type %T not yet implemented", old))
    31  	}
    32  }
    33  
    34  // newValueInst returns a new IR value instruction (without body but with type)
    35  // based on the given AST value instruction.
    36  func (fgen *funcGen) newValueInst(ident ir.LocalIdent, old ast.ValueInstruction) (ir.Instruction, error) {
    37  	switch old := old.(type) {
    38  	// Unary instructions
    39  	case *ast.FNegInst:
    40  		return fgen.newFNegInst(ident, old)
    41  	// Binary instructions
    42  	case *ast.AddInst:
    43  		return fgen.newAddInst(ident, old)
    44  	case *ast.FAddInst:
    45  		return fgen.newFAddInst(ident, old)
    46  	case *ast.SubInst:
    47  		return fgen.newSubInst(ident, old)
    48  	case *ast.FSubInst:
    49  		return fgen.newFSubInst(ident, old)
    50  	case *ast.MulInst:
    51  		return fgen.newMulInst(ident, old)
    52  	case *ast.FMulInst:
    53  		return fgen.newFMulInst(ident, old)
    54  	case *ast.UDivInst:
    55  		return fgen.newUDivInst(ident, old)
    56  	case *ast.SDivInst:
    57  		return fgen.newSDivInst(ident, old)
    58  	case *ast.FDivInst:
    59  		return fgen.newFDivInst(ident, old)
    60  	case *ast.URemInst:
    61  		return fgen.newURemInst(ident, old)
    62  	case *ast.SRemInst:
    63  		return fgen.newSRemInst(ident, old)
    64  	case *ast.FRemInst:
    65  		return fgen.newFRemInst(ident, old)
    66  	// Bitwise instructions
    67  	case *ast.ShlInst:
    68  		return fgen.newShlInst(ident, old)
    69  	case *ast.LShrInst:
    70  		return fgen.newLShrInst(ident, old)
    71  	case *ast.AShrInst:
    72  		return fgen.newAShrInst(ident, old)
    73  	case *ast.AndInst:
    74  		return fgen.newAndInst(ident, old)
    75  	case *ast.OrInst:
    76  		return fgen.newOrInst(ident, old)
    77  	case *ast.XorInst:
    78  		return fgen.newXorInst(ident, old)
    79  	// Vector instructions
    80  	case *ast.ExtractElementInst:
    81  		return fgen.newExtractElementInst(ident, old)
    82  	case *ast.InsertElementInst:
    83  		return fgen.newInsertElementInst(ident, old)
    84  	case *ast.ShuffleVectorInst:
    85  		return fgen.newShuffleVectorInst(ident, old)
    86  	// Aggregate instructions
    87  	case *ast.ExtractValueInst:
    88  		return fgen.newExtractValueInst(ident, old)
    89  	case *ast.InsertValueInst:
    90  		return fgen.newInsertValueInst(ident, old)
    91  	// Memory instructions
    92  	case *ast.AllocaInst:
    93  		return fgen.newAllocaInst(ident, old)
    94  	case *ast.LoadInst:
    95  		return fgen.newLoadInst(ident, old)
    96  	case *ast.CmpXchgInst:
    97  		return fgen.newCmpXchgInst(ident, old)
    98  	case *ast.AtomicRMWInst:
    99  		return fgen.newAtomicRMWInst(ident, old)
   100  	case *ast.GetElementPtrInst:
   101  		return fgen.newGetElementPtrInst(ident, old)
   102  	// Conversion instructions
   103  	case *ast.TruncInst:
   104  		return fgen.newTruncInst(ident, old)
   105  	case *ast.ZExtInst:
   106  		return fgen.newZExtInst(ident, old)
   107  	case *ast.SExtInst:
   108  		return fgen.newSExtInst(ident, old)
   109  	case *ast.FPTruncInst:
   110  		return fgen.newFPTruncInst(ident, old)
   111  	case *ast.FPExtInst:
   112  		return fgen.newFPExtInst(ident, old)
   113  	case *ast.FPToUIInst:
   114  		return fgen.newFPToUIInst(ident, old)
   115  	case *ast.FPToSIInst:
   116  		return fgen.newFPToSIInst(ident, old)
   117  	case *ast.UIToFPInst:
   118  		return fgen.newUIToFPInst(ident, old)
   119  	case *ast.SIToFPInst:
   120  		return fgen.newSIToFPInst(ident, old)
   121  	case *ast.PtrToIntInst:
   122  		return fgen.newPtrToIntInst(ident, old)
   123  	case *ast.IntToPtrInst:
   124  		return fgen.newIntToPtrInst(ident, old)
   125  	case *ast.BitCastInst:
   126  		return fgen.newBitCastInst(ident, old)
   127  	case *ast.AddrSpaceCastInst:
   128  		return fgen.newAddrSpaceCastInst(ident, old)
   129  	// Other instructions
   130  	case *ast.ICmpInst:
   131  		return fgen.newICmpInst(ident, old)
   132  	case *ast.FCmpInst:
   133  		return fgen.newFCmpInst(ident, old)
   134  	case *ast.PhiInst:
   135  		return fgen.newPhiInst(ident, old)
   136  	case *ast.SelectInst:
   137  		return fgen.newSelectInst(ident, old)
   138  	case *ast.FreezeInst:
   139  		return fgen.newFreezeInst(ident, old)
   140  	case *ast.CallInst:
   141  		return fgen.newCallInst(ident, old)
   142  	case *ast.VAArgInst:
   143  		return fgen.newVAArgInst(ident, old)
   144  	case *ast.LandingPadInst:
   145  		return fgen.newLandingPadInst(ident, old)
   146  	case *ast.CatchPadInst:
   147  		// Result type is always token.
   148  		return &ir.InstCatchPad{LocalIdent: ident}, nil
   149  	case *ast.CleanupPadInst:
   150  		// Result type is always token.
   151  		return &ir.InstCleanupPad{LocalIdent: ident}, nil
   152  	default:
   153  		panic(fmt.Errorf("support for AST value instruction type %T not yet implemented", old))
   154  	}
   155  }
   156  
   157  // === [ Translate AST to IR ] =================================================
   158  
   159  // translateInsts translates the AST instructions of the given function to IR.
   160  func (fgen *funcGen) translateInsts(oldBlocks []ast.BasicBlock) error {
   161  	for i, oldBlock := range oldBlocks {
   162  		block := fgen.f.Blocks[i]
   163  		for j, old := range oldBlock.Insts() {
   164  			new := block.Insts[j]
   165  			if err := fgen.irInst(new, old); err != nil {
   166  				return errors.WithStack(err)
   167  			}
   168  		}
   169  	}
   170  	return nil
   171  }
   172  
   173  // irInst translates the AST instruction into an equivalent IR instruction.
   174  func (fgen *funcGen) irInst(new ir.Instruction, old ast.Instruction) error {
   175  	switch old := old.(type) {
   176  	// Value instructions.
   177  	case *ast.LocalDefInst:
   178  		return fgen.irValueInst(new, old.Inst())
   179  	case ast.ValueInstruction:
   180  		return fgen.irValueInst(new, old)
   181  	// Non-value instructions.
   182  	case *ast.StoreInst:
   183  		return fgen.irStoreInst(new, old)
   184  	case *ast.FenceInst:
   185  		return fgen.irFenceInst(new, old)
   186  	default:
   187  		panic(fmt.Errorf("support for AST instruction type %T not yet implemented", old))
   188  	}
   189  }
   190  
   191  // irValueInst translates the AST value instruction into an equivalent IR value
   192  // instruction.
   193  func (fgen *funcGen) irValueInst(new ir.Instruction, old ast.ValueInstruction) error {
   194  	switch old := old.(type) {
   195  	// Unary instructions
   196  	case *ast.FNegInst:
   197  		return fgen.irFNegInst(new, old)
   198  	// Binary instructions
   199  	case *ast.AddInst:
   200  		return fgen.irAddInst(new, old)
   201  	case *ast.FAddInst:
   202  		return fgen.irFAddInst(new, old)
   203  	case *ast.SubInst:
   204  		return fgen.irSubInst(new, old)
   205  	case *ast.FSubInst:
   206  		return fgen.irFSubInst(new, old)
   207  	case *ast.MulInst:
   208  		return fgen.irMulInst(new, old)
   209  	case *ast.FMulInst:
   210  		return fgen.irFMulInst(new, old)
   211  	case *ast.UDivInst:
   212  		return fgen.irUDivInst(new, old)
   213  	case *ast.SDivInst:
   214  		return fgen.irSDivInst(new, old)
   215  	case *ast.FDivInst:
   216  		return fgen.irFDivInst(new, old)
   217  	case *ast.URemInst:
   218  		return fgen.irURemInst(new, old)
   219  	case *ast.SRemInst:
   220  		return fgen.irSRemInst(new, old)
   221  	case *ast.FRemInst:
   222  		return fgen.irFRemInst(new, old)
   223  	// Bitwise instructions
   224  	case *ast.ShlInst:
   225  		return fgen.irShlInst(new, old)
   226  	case *ast.LShrInst:
   227  		return fgen.irLShrInst(new, old)
   228  	case *ast.AShrInst:
   229  		return fgen.irAShrInst(new, old)
   230  	case *ast.AndInst:
   231  		return fgen.irAndInst(new, old)
   232  	case *ast.OrInst:
   233  		return fgen.irOrInst(new, old)
   234  	case *ast.XorInst:
   235  		return fgen.irXorInst(new, old)
   236  	// Vector instructions
   237  	case *ast.ExtractElementInst:
   238  		return fgen.irExtractElementInst(new, old)
   239  	case *ast.InsertElementInst:
   240  		return fgen.irInsertElementInst(new, old)
   241  	case *ast.ShuffleVectorInst:
   242  		return fgen.irShuffleVectorInst(new, old)
   243  	// Aggregate instructions
   244  	case *ast.ExtractValueInst:
   245  		return fgen.irExtractValueInst(new, old)
   246  	case *ast.InsertValueInst:
   247  		return fgen.irInsertValueInst(new, old)
   248  	// Memory instructions
   249  	case *ast.AllocaInst:
   250  		return fgen.irAllocaInst(new, old)
   251  	case *ast.LoadInst:
   252  		return fgen.irLoadInst(new, old)
   253  	case *ast.CmpXchgInst:
   254  		return fgen.irCmpXchgInst(new, old)
   255  	case *ast.AtomicRMWInst:
   256  		return fgen.irAtomicRMWInst(new, old)
   257  	case *ast.GetElementPtrInst:
   258  		return fgen.irGetElementPtrInst(new, old)
   259  	// Conversion instructions
   260  	case *ast.TruncInst:
   261  		return fgen.irTruncInst(new, old)
   262  	case *ast.ZExtInst:
   263  		return fgen.irZExtInst(new, old)
   264  	case *ast.SExtInst:
   265  		return fgen.irSExtInst(new, old)
   266  	case *ast.FPTruncInst:
   267  		return fgen.irFPTruncInst(new, old)
   268  	case *ast.FPExtInst:
   269  		return fgen.irFPExtInst(new, old)
   270  	case *ast.FPToUIInst:
   271  		return fgen.irFPToUIInst(new, old)
   272  	case *ast.FPToSIInst:
   273  		return fgen.irFPToSIInst(new, old)
   274  	case *ast.UIToFPInst:
   275  		return fgen.irUIToFPInst(new, old)
   276  	case *ast.SIToFPInst:
   277  		return fgen.irSIToFPInst(new, old)
   278  	case *ast.PtrToIntInst:
   279  		return fgen.irPtrToIntInst(new, old)
   280  	case *ast.IntToPtrInst:
   281  		return fgen.irIntToPtrInst(new, old)
   282  	case *ast.BitCastInst:
   283  		return fgen.irBitCastInst(new, old)
   284  	case *ast.AddrSpaceCastInst:
   285  		return fgen.irAddrSpaceCastInst(new, old)
   286  	// Other instructions
   287  	case *ast.ICmpInst:
   288  		return fgen.irICmpInst(new, old)
   289  	case *ast.FCmpInst:
   290  		return fgen.irFCmpInst(new, old)
   291  	case *ast.PhiInst:
   292  		return fgen.irPhiInst(new, old)
   293  	case *ast.SelectInst:
   294  		return fgen.irSelectInst(new, old)
   295  	case *ast.FreezeInst:
   296  		return fgen.irFreezeInst(new, old)
   297  	case *ast.CallInst:
   298  		return fgen.irCallInst(new, old)
   299  	case *ast.VAArgInst:
   300  		return fgen.irVAArgInst(new, old)
   301  	case *ast.LandingPadInst:
   302  		return fgen.irLandingPadInst(new, old)
   303  	case *ast.CatchPadInst:
   304  		return fgen.irCatchPadInst(new, old)
   305  	case *ast.CleanupPadInst:
   306  		return fgen.irCleanupPadInst(new, old)
   307  	default:
   308  		panic(fmt.Errorf("support for AST value instruction type %T not yet implemented", old))
   309  	}
   310  }