github.com/llir/llvm@v0.3.6/asm/inst_vector.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/llir/llvm/ir/types"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  // === [ Create IR ] ===========================================================
    13  
    14  // newExtractElementInst returns a new IR extractelement instruction (without
    15  // body but with type) based on the given AST extractelement instruction.
    16  func (fgen *funcGen) newExtractElementInst(ident ir.LocalIdent, old *ast.ExtractElementInst) (*ir.InstExtractElement, error) {
    17  	xType, err := fgen.gen.irType(old.X().Typ())
    18  	if err != nil {
    19  		return nil, errors.WithStack(err)
    20  	}
    21  	xt, ok := xType.(*types.VectorType)
    22  	if !ok {
    23  		panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", xType))
    24  	}
    25  	return &ir.InstExtractElement{LocalIdent: ident, Typ: xt.ElemType}, nil
    26  }
    27  
    28  // newInsertElementInst returns a new IR insertelement instruction (without body
    29  // but with type) based on the given AST insertelement instruction.
    30  func (fgen *funcGen) newInsertElementInst(ident ir.LocalIdent, old *ast.InsertElementInst) (*ir.InstInsertElement, error) {
    31  	xType, err := fgen.gen.irType(old.X().Typ())
    32  	if err != nil {
    33  		return nil, errors.WithStack(err)
    34  	}
    35  	xt, ok := xType.(*types.VectorType)
    36  	if !ok {
    37  		panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", xType))
    38  	}
    39  	return &ir.InstInsertElement{LocalIdent: ident, Typ: xt}, nil
    40  }
    41  
    42  // newShuffleVectorInst returns a new IR shufflevector instruction (without body
    43  // but with type) based on the given AST shufflevector instruction.
    44  func (fgen *funcGen) newShuffleVectorInst(ident ir.LocalIdent, old *ast.ShuffleVectorInst) (*ir.InstShuffleVector, error) {
    45  	xType, err := fgen.gen.irType(old.X().Typ())
    46  	if err != nil {
    47  		return nil, errors.WithStack(err)
    48  	}
    49  	xt, ok := xType.(*types.VectorType)
    50  	if !ok {
    51  		panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", xType))
    52  	}
    53  	maskType, err := fgen.gen.irType(old.Mask().Typ())
    54  	if err != nil {
    55  		return nil, errors.WithStack(err)
    56  	}
    57  	mt, ok := maskType.(*types.VectorType)
    58  	if !ok {
    59  		panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", maskType))
    60  	}
    61  	typ := types.NewVector(mt.Len, xt.ElemType)
    62  	return &ir.InstShuffleVector{LocalIdent: ident, Typ: typ}, nil
    63  }
    64  
    65  // === [ Translate AST to IR ] =================================================
    66  
    67  // --- [ extractelement ] ------------------------------------------------------
    68  
    69  // irExtractElementInst translates the given AST extractelement instruction into
    70  // an equivalent IR instruction.
    71  func (fgen *funcGen) irExtractElementInst(new ir.Instruction, old *ast.ExtractElementInst) error {
    72  	inst, ok := new.(*ir.InstExtractElement)
    73  	if !ok {
    74  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstExtractElement, got %T", new))
    75  	}
    76  	// Vector.
    77  	x, err := fgen.irTypeValue(old.X())
    78  	if err != nil {
    79  		return errors.WithStack(err)
    80  	}
    81  	inst.X = x
    82  	// Element index.
    83  	index, err := fgen.irTypeValue(old.Index())
    84  	if err != nil {
    85  		return errors.WithStack(err)
    86  	}
    87  	inst.Index = index
    88  	// (optional) Metadata.
    89  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
    90  	if err != nil {
    91  		return errors.WithStack(err)
    92  	}
    93  	inst.Metadata = md
    94  	return nil
    95  }
    96  
    97  // --- [ insertelement ] -------------------------------------------------------
    98  
    99  // irInsertElementInst translates the given AST insertelement instruction into
   100  // an equivalent IR instruction.
   101  func (fgen *funcGen) irInsertElementInst(new ir.Instruction, old *ast.InsertElementInst) error {
   102  	inst, ok := new.(*ir.InstInsertElement)
   103  	if !ok {
   104  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstInsertElement, got %T", new))
   105  	}
   106  	// Vector.
   107  	x, err := fgen.irTypeValue(old.X())
   108  	if err != nil {
   109  		return errors.WithStack(err)
   110  	}
   111  	inst.X = x
   112  	// Element to insert.
   113  	elem, err := fgen.irTypeValue(old.Elem())
   114  	if err != nil {
   115  		return errors.WithStack(err)
   116  	}
   117  	inst.Elem = elem
   118  	// Element index.
   119  	index, err := fgen.irTypeValue(old.Index())
   120  	if err != nil {
   121  		return errors.WithStack(err)
   122  	}
   123  	inst.Index = index
   124  	// (optional) Metadata.
   125  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   126  	if err != nil {
   127  		return errors.WithStack(err)
   128  	}
   129  	inst.Metadata = md
   130  	return nil
   131  }
   132  
   133  // --- [ shufflevector ] -------------------------------------------------------
   134  
   135  // irShuffleVectorInst translates the given AST shufflevector instruction into
   136  // an equivalent IR instruction.
   137  func (fgen *funcGen) irShuffleVectorInst(new ir.Instruction, old *ast.ShuffleVectorInst) error {
   138  	inst, ok := new.(*ir.InstShuffleVector)
   139  	if !ok {
   140  		panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstShuffleVector, got %T", new))
   141  	}
   142  	// X vector.
   143  	x, err := fgen.irTypeValue(old.X())
   144  	if err != nil {
   145  		return errors.WithStack(err)
   146  	}
   147  	inst.X = x
   148  	// Y vector.
   149  	y, err := fgen.irTypeValue(old.Y())
   150  	if err != nil {
   151  		return errors.WithStack(err)
   152  	}
   153  	inst.Y = y
   154  	// Shuffle mask.
   155  	mask, err := fgen.irTypeValue(old.Mask())
   156  	if err != nil {
   157  		return errors.WithStack(err)
   158  	}
   159  	inst.Mask = mask
   160  	// (optional) Metadata.
   161  	md, err := fgen.gen.irMetadataAttachments(old.Metadata())
   162  	if err != nil {
   163  		return errors.WithStack(err)
   164  	}
   165  	inst.Metadata = md
   166  	return nil
   167  }