github.com/llir/llvm@v0.3.6/asm/inst_bitwise.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 // newShlInst returns a new IR shl instruction (without body but with type) 14 // based on the given AST shl instruction. 15 func (fgen *funcGen) newShlInst(ident ir.LocalIdent, old *ast.ShlInst) (*ir.InstShl, error) { 16 typ, err := fgen.gen.irType(old.X().Typ()) 17 if err != nil { 18 return nil, errors.WithStack(err) 19 } 20 return &ir.InstShl{LocalIdent: ident, Typ: typ}, nil 21 } 22 23 // newLShrInst returns a new IR lshr instruction (without body but with type) 24 // based on the given AST lshr instruction. 25 func (fgen *funcGen) newLShrInst(ident ir.LocalIdent, old *ast.LShrInst) (*ir.InstLShr, error) { 26 typ, err := fgen.gen.irType(old.X().Typ()) 27 if err != nil { 28 return nil, errors.WithStack(err) 29 } 30 return &ir.InstLShr{LocalIdent: ident, Typ: typ}, nil 31 } 32 33 // newAShrInst returns a new IR ashr instruction (without body but with type) 34 // based on the given AST ashr instruction. 35 func (fgen *funcGen) newAShrInst(ident ir.LocalIdent, old *ast.AShrInst) (*ir.InstAShr, error) { 36 typ, err := fgen.gen.irType(old.X().Typ()) 37 if err != nil { 38 return nil, errors.WithStack(err) 39 } 40 return &ir.InstAShr{LocalIdent: ident, Typ: typ}, nil 41 } 42 43 // newAndInst returns a new IR and instruction (without body but with type) 44 // based on the given AST and instruction. 45 func (fgen *funcGen) newAndInst(ident ir.LocalIdent, old *ast.AndInst) (*ir.InstAnd, error) { 46 typ, err := fgen.gen.irType(old.X().Typ()) 47 if err != nil { 48 return nil, errors.WithStack(err) 49 } 50 return &ir.InstAnd{LocalIdent: ident, Typ: typ}, nil 51 } 52 53 // newOrInst returns a new IR or instruction (without body but with type) based 54 // on the given AST or instruction. 55 func (fgen *funcGen) newOrInst(ident ir.LocalIdent, old *ast.OrInst) (*ir.InstOr, error) { 56 typ, err := fgen.gen.irType(old.X().Typ()) 57 if err != nil { 58 return nil, errors.WithStack(err) 59 } 60 return &ir.InstOr{LocalIdent: ident, Typ: typ}, nil 61 } 62 63 // newXorInst returns a new IR xor instruction (without body but with type) 64 // based on the given AST xor instruction. 65 func (fgen *funcGen) newXorInst(ident ir.LocalIdent, old *ast.XorInst) (*ir.InstXor, error) { 66 typ, err := fgen.gen.irType(old.X().Typ()) 67 if err != nil { 68 return nil, errors.WithStack(err) 69 } 70 return &ir.InstXor{LocalIdent: ident, Typ: typ}, nil 71 } 72 73 // === [ Translate AST to IR ] ================================================= 74 75 // --- [ shl ] ----------------------------------------------------------------- 76 77 // irShlInst translates the given AST shl instruction into an equivalent IR 78 // instruction. 79 func (fgen *funcGen) irShlInst(new ir.Instruction, old *ast.ShlInst) error { 80 inst, ok := new.(*ir.InstShl) 81 if !ok { 82 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstShl, got %T", new)) 83 } 84 // X operand. 85 x, err := fgen.irTypeValue(old.X()) 86 if err != nil { 87 return errors.WithStack(err) 88 } 89 inst.X = x 90 // Y operand. 91 y, err := fgen.irValue(x.Type(), old.Y()) 92 if err != nil { 93 return errors.WithStack(err) 94 } 95 inst.Y = y 96 // (optional) Overflow flags. 97 inst.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 98 // (optional) Metadata. 99 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 100 if err != nil { 101 return errors.WithStack(err) 102 } 103 inst.Metadata = md 104 return nil 105 } 106 107 // --- [ lshr ] ---------------------------------------------------------------- 108 109 // irLShrInst translates the given AST lshr instruction into an equivalent IR 110 // instruction. 111 func (fgen *funcGen) irLShrInst(new ir.Instruction, old *ast.LShrInst) error { 112 inst, ok := new.(*ir.InstLShr) 113 if !ok { 114 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstLShr, got %T", new)) 115 } 116 // X operand. 117 x, err := fgen.irTypeValue(old.X()) 118 if err != nil { 119 return errors.WithStack(err) 120 } 121 inst.X = x 122 // Y operand. 123 y, err := fgen.irValue(x.Type(), old.Y()) 124 if err != nil { 125 return errors.WithStack(err) 126 } 127 inst.Y = y 128 // (optional) Exact. 129 _, inst.Exact = old.Exact() 130 // (optional) Metadata. 131 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 132 if err != nil { 133 return errors.WithStack(err) 134 } 135 inst.Metadata = md 136 return nil 137 } 138 139 // --- [ ashr ] ---------------------------------------------------------------- 140 141 // irAShrInst translates the given AST ashr instruction into an equivalent IR 142 // instruction. 143 func (fgen *funcGen) irAShrInst(new ir.Instruction, old *ast.AShrInst) error { 144 inst, ok := new.(*ir.InstAShr) 145 if !ok { 146 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstAShr, got %T", new)) 147 } 148 // X operand. 149 x, err := fgen.irTypeValue(old.X()) 150 if err != nil { 151 return errors.WithStack(err) 152 } 153 inst.X = x 154 // Y operand. 155 y, err := fgen.irValue(x.Type(), old.Y()) 156 if err != nil { 157 return errors.WithStack(err) 158 } 159 inst.Y = y 160 // (optional) Exact. 161 _, inst.Exact = old.Exact() 162 // (optional) Metadata. 163 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 164 if err != nil { 165 return errors.WithStack(err) 166 } 167 inst.Metadata = md 168 return nil 169 } 170 171 // --- [ and ] ----------------------------------------------------------------- 172 173 // irAndInst translates the given AST and instruction into an equivalent IR 174 // instruction. 175 func (fgen *funcGen) irAndInst(new ir.Instruction, old *ast.AndInst) error { 176 inst, ok := new.(*ir.InstAnd) 177 if !ok { 178 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstAnd, got %T", new)) 179 } 180 // X operand. 181 x, err := fgen.irTypeValue(old.X()) 182 if err != nil { 183 return errors.WithStack(err) 184 } 185 inst.X = x 186 // Y operand. 187 y, err := fgen.irValue(x.Type(), old.Y()) 188 if err != nil { 189 return errors.WithStack(err) 190 } 191 inst.Y = y 192 // (optional) Metadata. 193 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 194 if err != nil { 195 return errors.WithStack(err) 196 } 197 inst.Metadata = md 198 return nil 199 } 200 201 // --- [ or ] ------------------------------------------------------------------ 202 203 // irOrInst translates the given AST or instruction into an equivalent IR 204 // instruction. 205 func (fgen *funcGen) irOrInst(new ir.Instruction, old *ast.OrInst) error { 206 inst, ok := new.(*ir.InstOr) 207 if !ok { 208 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstOr, got %T", new)) 209 } 210 // X operand. 211 x, err := fgen.irTypeValue(old.X()) 212 if err != nil { 213 return errors.WithStack(err) 214 } 215 inst.X = x 216 // Y operand. 217 y, err := fgen.irValue(x.Type(), old.Y()) 218 if err != nil { 219 return errors.WithStack(err) 220 } 221 inst.Y = y 222 // (optional) Metadata. 223 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 224 if err != nil { 225 return errors.WithStack(err) 226 } 227 inst.Metadata = md 228 return nil 229 } 230 231 // --- [ xor ] ----------------------------------------------------------------- 232 233 // irXorInst translates the given AST xor instruction into an equivalent IR 234 // instruction. 235 func (fgen *funcGen) irXorInst(new ir.Instruction, old *ast.XorInst) error { 236 inst, ok := new.(*ir.InstXor) 237 if !ok { 238 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstXor, got %T", new)) 239 } 240 // X operand. 241 x, err := fgen.irTypeValue(old.X()) 242 if err != nil { 243 return errors.WithStack(err) 244 } 245 inst.X = x 246 // Y operand. 247 y, err := fgen.irValue(x.Type(), old.Y()) 248 if err != nil { 249 return errors.WithStack(err) 250 } 251 inst.Y = y 252 // (optional) Metadata. 253 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 254 if err != nil { 255 return errors.WithStack(err) 256 } 257 inst.Metadata = md 258 return nil 259 }