github.com/llir/llvm@v0.3.6/ir/constant/expr_other.go (about) 1 package constant 2 3 import ( 4 "fmt" 5 6 "github.com/llir/llvm/ir/enum" 7 "github.com/llir/llvm/ir/types" 8 ) 9 10 // --- [ Other expressions ] --------------------------------------------------- 11 12 // ~~~ [ icmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 14 // ExprICmp is an LLVM IR icmp expression. 15 type ExprICmp struct { 16 // Integer comparison predicate. 17 Pred enum.IPred 18 // Integer scalar or vector operands. 19 X, Y Constant 20 21 // extra. 22 23 // Type of result produced by the constant expression. 24 Typ types.Type 25 } 26 27 // NewICmp returns a new icmp expression based on the given integer comparison 28 // predicate and integer scalar or vector operands. 29 func NewICmp(pred enum.IPred, x, y Constant) *ExprICmp { 30 e := &ExprICmp{Pred: pred, X: x, Y: y} 31 // Compute type. 32 e.Type() 33 return e 34 } 35 36 // String returns the LLVM syntax representation of the constant expression as a 37 // type-value pair. 38 func (e *ExprICmp) String() string { 39 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 40 } 41 42 // Type returns the type of the constant expression. 43 func (e *ExprICmp) Type() types.Type { 44 // Cache type if not present. 45 if e.Typ == nil { 46 switch xType := e.X.Type().(type) { 47 case *types.IntType, *types.PointerType: 48 e.Typ = types.I1 49 case *types.VectorType: 50 e.Typ = types.NewVector(xType.Len, types.I1) 51 default: 52 panic(fmt.Errorf("invalid icmp operand type; expected *types.IntType, *types.PointerType or *types.VectorType, got %T", xType)) 53 } 54 } 55 return e.Typ 56 } 57 58 // Ident returns the identifier associated with the constant expression. 59 func (e *ExprICmp) Ident() string { 60 // 'icmp' Pred=IPred '(' X=TypeConst ',' Y=TypeConst ')' 61 return fmt.Sprintf("icmp %s (%s, %s)", e.Pred, e.X, e.Y) 62 } 63 64 // ~~~ [ fcmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65 66 // ExprFCmp is an LLVM IR fcmp expression. 67 type ExprFCmp struct { 68 // Floating-point comparison predicate. 69 Pred enum.FPred 70 // Floating-point scalar or vector operands. 71 X, Y Constant 72 73 // extra. 74 75 // Type of result produced by the constant expression. 76 Typ types.Type 77 } 78 79 // NewFCmp returns a new fcmp expression based on the given floating-point 80 // comparison predicate and floating-point scalar or vector operands. 81 func NewFCmp(pred enum.FPred, x, y Constant) *ExprFCmp { 82 e := &ExprFCmp{Pred: pred, X: x, Y: y} 83 // Compute type. 84 e.Type() 85 return e 86 } 87 88 // String returns the LLVM syntax representation of the constant expression as a 89 // type-value pair. 90 func (e *ExprFCmp) String() string { 91 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 92 } 93 94 // Type returns the type of the constant expression. 95 func (e *ExprFCmp) Type() types.Type { 96 // Cache type if not present. 97 if e.Typ == nil { 98 switch xType := e.X.Type().(type) { 99 case *types.FloatType: 100 e.Typ = types.I1 101 case *types.VectorType: 102 e.Typ = types.NewVector(xType.Len, types.I1) 103 default: 104 panic(fmt.Errorf("invalid fcmp operand type; expected *types.FloatType or *types.VectorType, got %T", xType)) 105 } 106 } 107 return e.Typ 108 } 109 110 // Ident returns the identifier associated with the constant expression. 111 func (e *ExprFCmp) Ident() string { 112 // 'fcmp' Pred=FPred '(' X=TypeConst ',' Y=TypeConst ')' 113 return fmt.Sprintf("fcmp %s (%s, %s)", e.Pred, e.X, e.Y) 114 } 115 116 // ~~~ [ select ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 117 118 // ExprSelect is an LLVM IR select expression. 119 type ExprSelect struct { 120 // Selection condition. 121 Cond Constant 122 // Operands. 123 X, Y Constant 124 125 // extra. 126 127 // Type of result produced by the constant expression. 128 Typ types.Type 129 } 130 131 // NewSelect returns a new select expression based on the given selection 132 // condition and operands. 133 func NewSelect(cond, x, y Constant) *ExprSelect { 134 e := &ExprSelect{Cond: cond, X: x, Y: y} 135 // Compute type. 136 e.Type() 137 return e 138 } 139 140 // String returns the LLVM syntax representation of the constant expression as a 141 // type-value pair. 142 func (e *ExprSelect) String() string { 143 return fmt.Sprintf("%s %s", e.Type(), e.Ident()) 144 } 145 146 // Type returns the type of the constant expression. 147 func (e *ExprSelect) Type() types.Type { 148 // Cache type if not present. 149 if e.Typ == nil { 150 e.Typ = e.X.Type() 151 } 152 return e.Typ 153 } 154 155 // Ident returns the identifier associated with the constant expression. 156 func (e *ExprSelect) Ident() string { 157 // 'select' '(' Cond=TypeConst ',' X=TypeConst ',' Y=TypeConst ')' 158 return fmt.Sprintf("select (%s, %s, %s)", e.Cond, e.X, e.Y) 159 }