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 }