github.com/llir/llvm@v0.3.6/asm/inst_binary.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 // newAddInst returns a new IR add instruction (without body but with type) 14 // based on the given AST add instruction. 15 func (fgen *funcGen) newAddInst(ident ir.LocalIdent, old *ast.AddInst) (*ir.InstAdd, error) { 16 typ, err := fgen.gen.irType(old.X().Typ()) 17 if err != nil { 18 return nil, errors.WithStack(err) 19 } 20 return &ir.InstAdd{LocalIdent: ident, Typ: typ}, nil 21 } 22 23 // newFAddInst returns a new IR fadd instruction (without body but with type) 24 // based on the given AST fadd instruction. 25 func (fgen *funcGen) newFAddInst(ident ir.LocalIdent, old *ast.FAddInst) (*ir.InstFAdd, error) { 26 typ, err := fgen.gen.irType(old.X().Typ()) 27 if err != nil { 28 return nil, errors.WithStack(err) 29 } 30 return &ir.InstFAdd{LocalIdent: ident, Typ: typ}, nil 31 } 32 33 // newSubInst returns a new IR sub instruction (without body but with type) 34 // based on the given AST sub instruction. 35 func (fgen *funcGen) newSubInst(ident ir.LocalIdent, old *ast.SubInst) (*ir.InstSub, error) { 36 typ, err := fgen.gen.irType(old.X().Typ()) 37 if err != nil { 38 return nil, errors.WithStack(err) 39 } 40 return &ir.InstSub{LocalIdent: ident, Typ: typ}, nil 41 } 42 43 // newFSubInst returns a new IR fsub instruction (without body but with type) 44 // based on the given AST fsub instruction. 45 func (fgen *funcGen) newFSubInst(ident ir.LocalIdent, old *ast.FSubInst) (*ir.InstFSub, error) { 46 typ, err := fgen.gen.irType(old.X().Typ()) 47 if err != nil { 48 return nil, errors.WithStack(err) 49 } 50 return &ir.InstFSub{LocalIdent: ident, Typ: typ}, nil 51 } 52 53 // newMulInst returns a new IR mul instruction (without body but with type) 54 // based on the given AST mul instruction. 55 func (fgen *funcGen) newMulInst(ident ir.LocalIdent, old *ast.MulInst) (*ir.InstMul, error) { 56 typ, err := fgen.gen.irType(old.X().Typ()) 57 if err != nil { 58 return nil, errors.WithStack(err) 59 } 60 return &ir.InstMul{LocalIdent: ident, Typ: typ}, nil 61 } 62 63 // newFMulInst returns a new IR fmul instruction (without body but with type) 64 // based on the given AST fmul instruction. 65 func (fgen *funcGen) newFMulInst(ident ir.LocalIdent, old *ast.FMulInst) (*ir.InstFMul, error) { 66 typ, err := fgen.gen.irType(old.X().Typ()) 67 if err != nil { 68 return nil, errors.WithStack(err) 69 } 70 return &ir.InstFMul{LocalIdent: ident, Typ: typ}, nil 71 } 72 73 // newUDivInst returns a new IR udiv instruction (without body but with type) 74 // based on the given AST udiv instruction. 75 func (fgen *funcGen) newUDivInst(ident ir.LocalIdent, old *ast.UDivInst) (*ir.InstUDiv, error) { 76 typ, err := fgen.gen.irType(old.X().Typ()) 77 if err != nil { 78 return nil, errors.WithStack(err) 79 } 80 return &ir.InstUDiv{LocalIdent: ident, Typ: typ}, nil 81 } 82 83 // newSDivInst returns a new IR sdiv instruction (without body but with type) 84 // based on the given AST sdiv instruction. 85 func (fgen *funcGen) newSDivInst(ident ir.LocalIdent, old *ast.SDivInst) (*ir.InstSDiv, error) { 86 typ, err := fgen.gen.irType(old.X().Typ()) 87 if err != nil { 88 return nil, errors.WithStack(err) 89 } 90 return &ir.InstSDiv{LocalIdent: ident, Typ: typ}, nil 91 } 92 93 // newFDivInst returns a new IR fdiv instruction (without body but with type) 94 // based on the given AST fdiv instruction. 95 func (fgen *funcGen) newFDivInst(ident ir.LocalIdent, old *ast.FDivInst) (*ir.InstFDiv, error) { 96 typ, err := fgen.gen.irType(old.X().Typ()) 97 if err != nil { 98 return nil, errors.WithStack(err) 99 } 100 return &ir.InstFDiv{LocalIdent: ident, Typ: typ}, nil 101 } 102 103 // newURemInst returns a new IR urem instruction (without body but with type) 104 // based on the given AST urem instruction. 105 func (fgen *funcGen) newURemInst(ident ir.LocalIdent, old *ast.URemInst) (*ir.InstURem, error) { 106 typ, err := fgen.gen.irType(old.X().Typ()) 107 if err != nil { 108 return nil, errors.WithStack(err) 109 } 110 return &ir.InstURem{LocalIdent: ident, Typ: typ}, nil 111 } 112 113 // newSRemInst returns a new IR srem instruction (without body but with type) 114 // based on the given AST srem instruction. 115 func (fgen *funcGen) newSRemInst(ident ir.LocalIdent, old *ast.SRemInst) (*ir.InstSRem, error) { 116 typ, err := fgen.gen.irType(old.X().Typ()) 117 if err != nil { 118 return nil, errors.WithStack(err) 119 } 120 return &ir.InstSRem{LocalIdent: ident, Typ: typ}, nil 121 } 122 123 // newFRemInst returns a new IR frem instruction (without body but with type) 124 // based on the given AST frem instruction. 125 func (fgen *funcGen) newFRemInst(ident ir.LocalIdent, old *ast.FRemInst) (*ir.InstFRem, error) { 126 typ, err := fgen.gen.irType(old.X().Typ()) 127 if err != nil { 128 return nil, errors.WithStack(err) 129 } 130 return &ir.InstFRem{LocalIdent: ident, Typ: typ}, nil 131 } 132 133 // === [ Translate AST to IR ] ================================================= 134 135 // --- [ add ] ----------------------------------------------------------------- 136 137 // irAddInst translates the given AST add instruction into an equivalent IR 138 // instruction. 139 func (fgen *funcGen) irAddInst(new ir.Instruction, old *ast.AddInst) error { 140 inst, ok := new.(*ir.InstAdd) 141 if !ok { 142 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstAdd, got %T", new)) 143 } 144 // X operand. 145 x, err := fgen.irTypeValue(old.X()) 146 if err != nil { 147 return errors.WithStack(err) 148 } 149 inst.X = x 150 // Y operand. 151 y, err := fgen.irValue(x.Type(), old.Y()) 152 if err != nil { 153 return errors.WithStack(err) 154 } 155 inst.Y = y 156 // (optional) Overflow flags. 157 inst.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 158 // (optional) Metadata. 159 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 160 if err != nil { 161 return errors.WithStack(err) 162 } 163 inst.Metadata = md 164 return nil 165 } 166 167 // --- [ fadd ] ---------------------------------------------------------------- 168 169 // irFAddInst translates the given AST fadd instruction into an equivalent IR 170 // instruction. 171 func (fgen *funcGen) irFAddInst(new ir.Instruction, old *ast.FAddInst) error { 172 inst, ok := new.(*ir.InstFAdd) 173 if !ok { 174 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFAdd, got %T", new)) 175 } 176 // X operand. 177 x, err := fgen.irTypeValue(old.X()) 178 if err != nil { 179 return errors.WithStack(err) 180 } 181 inst.X = x 182 // Y operand. 183 y, err := fgen.irValue(x.Type(), old.Y()) 184 if err != nil { 185 return errors.WithStack(err) 186 } 187 inst.Y = y 188 // (optional) Fast math flags. 189 inst.FastMathFlags = irFastMathFlags(old.FastMathFlags()) 190 // (optional) Metadata. 191 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 192 if err != nil { 193 return errors.WithStack(err) 194 } 195 inst.Metadata = md 196 return nil 197 } 198 199 // --- [ sub ] ----------------------------------------------------------------- 200 201 // irSubInst translates the given AST sub instruction into an equivalent IR 202 // instruction. 203 func (fgen *funcGen) irSubInst(new ir.Instruction, old *ast.SubInst) error { 204 inst, ok := new.(*ir.InstSub) 205 if !ok { 206 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstSub, got %T", new)) 207 } 208 // X operand. 209 x, err := fgen.irTypeValue(old.X()) 210 if err != nil { 211 return errors.WithStack(err) 212 } 213 inst.X = x 214 // Y operand. 215 y, err := fgen.irValue(x.Type(), old.Y()) 216 if err != nil { 217 return errors.WithStack(err) 218 } 219 inst.Y = y 220 // (optional) Overflow flags. 221 inst.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 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 // --- [ fsub ] ---------------------------------------------------------------- 232 233 // irFSubInst translates the given AST fsub instruction into an equivalent IR 234 // instruction. 235 func (fgen *funcGen) irFSubInst(new ir.Instruction, old *ast.FSubInst) error { 236 inst, ok := new.(*ir.InstFSub) 237 if !ok { 238 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFSub, 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) Fast math flags. 253 inst.FastMathFlags = irFastMathFlags(old.FastMathFlags()) 254 // (optional) Metadata. 255 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 256 if err != nil { 257 return errors.WithStack(err) 258 } 259 inst.Metadata = md 260 return nil 261 } 262 263 // --- [ mul ] ----------------------------------------------------------------- 264 265 // irMulInst translates the given AST mul instruction into an equivalent IR 266 // instruction. 267 func (fgen *funcGen) irMulInst(new ir.Instruction, old *ast.MulInst) error { 268 inst, ok := new.(*ir.InstMul) 269 if !ok { 270 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstMul, got %T", new)) 271 } 272 // X operand. 273 x, err := fgen.irTypeValue(old.X()) 274 if err != nil { 275 return errors.WithStack(err) 276 } 277 inst.X = x 278 // Y operand. 279 y, err := fgen.irValue(x.Type(), old.Y()) 280 if err != nil { 281 return errors.WithStack(err) 282 } 283 inst.Y = y 284 // (optional) Overflow flags. 285 inst.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 286 // (optional) Metadata. 287 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 288 if err != nil { 289 return errors.WithStack(err) 290 } 291 inst.Metadata = md 292 return nil 293 } 294 295 // --- [ fmul ] ---------------------------------------------------------------- 296 297 // irFMulInst translates the given AST fmul instruction into an equivalent IR 298 // instruction. 299 func (fgen *funcGen) irFMulInst(new ir.Instruction, old *ast.FMulInst) error { 300 inst, ok := new.(*ir.InstFMul) 301 if !ok { 302 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFMul, got %T", new)) 303 } 304 // X operand. 305 x, err := fgen.irTypeValue(old.X()) 306 if err != nil { 307 return errors.WithStack(err) 308 } 309 inst.X = x 310 // Y operand. 311 y, err := fgen.irValue(x.Type(), old.Y()) 312 if err != nil { 313 return errors.WithStack(err) 314 } 315 inst.Y = y 316 // (optional) Fast math flags. 317 inst.FastMathFlags = irFastMathFlags(old.FastMathFlags()) 318 // (optional) Metadata. 319 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 320 if err != nil { 321 return errors.WithStack(err) 322 } 323 inst.Metadata = md 324 return nil 325 } 326 327 // --- [ udiv ] ---------------------------------------------------------------- 328 329 // irUDivInst translates the given AST udiv instruction into an equivalent IR 330 // instruction. 331 func (fgen *funcGen) irUDivInst(new ir.Instruction, old *ast.UDivInst) error { 332 inst, ok := new.(*ir.InstUDiv) 333 if !ok { 334 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstUDiv, got %T", new)) 335 } 336 // X operand. 337 x, err := fgen.irTypeValue(old.X()) 338 if err != nil { 339 return errors.WithStack(err) 340 } 341 inst.X = x 342 // Y operand. 343 y, err := fgen.irValue(x.Type(), old.Y()) 344 if err != nil { 345 return errors.WithStack(err) 346 } 347 inst.Y = y 348 // (optional) Exact. 349 _, inst.Exact = old.Exact() 350 // (optional) Metadata. 351 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 352 if err != nil { 353 return errors.WithStack(err) 354 } 355 inst.Metadata = md 356 return nil 357 } 358 359 // --- [ sdiv ] ---------------------------------------------------------------- 360 361 // irSDivInst translates the given AST sdiv instruction into an equivalent IR 362 // instruction. 363 func (fgen *funcGen) irSDivInst(new ir.Instruction, old *ast.SDivInst) error { 364 inst, ok := new.(*ir.InstSDiv) 365 if !ok { 366 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstSDiv, got %T", new)) 367 } 368 // X operand. 369 x, err := fgen.irTypeValue(old.X()) 370 if err != nil { 371 return errors.WithStack(err) 372 } 373 inst.X = x 374 // Y operand. 375 y, err := fgen.irValue(x.Type(), old.Y()) 376 if err != nil { 377 return errors.WithStack(err) 378 } 379 inst.Y = y 380 // (optional) Exact. 381 _, inst.Exact = old.Exact() 382 // (optional) Metadata. 383 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 384 if err != nil { 385 return errors.WithStack(err) 386 } 387 inst.Metadata = md 388 return nil 389 } 390 391 // --- [ fdiv ] ---------------------------------------------------------------- 392 393 // irFDivInst translates the given AST fdiv instruction into an equivalent IR 394 // instruction. 395 func (fgen *funcGen) irFDivInst(new ir.Instruction, old *ast.FDivInst) error { 396 inst, ok := new.(*ir.InstFDiv) 397 if !ok { 398 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFDiv, got %T", new)) 399 } 400 // X operand. 401 x, err := fgen.irTypeValue(old.X()) 402 if err != nil { 403 return errors.WithStack(err) 404 } 405 inst.X = x 406 // Y operand. 407 y, err := fgen.irValue(x.Type(), old.Y()) 408 if err != nil { 409 return errors.WithStack(err) 410 } 411 inst.Y = y 412 // (optional) Fast math flags. 413 inst.FastMathFlags = irFastMathFlags(old.FastMathFlags()) 414 // (optional) Metadata. 415 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 416 if err != nil { 417 return errors.WithStack(err) 418 } 419 inst.Metadata = md 420 return nil 421 } 422 423 // --- [ urem ] ---------------------------------------------------------------- 424 425 // irURemInst translates the given AST urem instruction into an equivalent IR 426 // instruction. 427 func (fgen *funcGen) irURemInst(new ir.Instruction, old *ast.URemInst) error { 428 inst, ok := new.(*ir.InstURem) 429 if !ok { 430 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstURem, got %T", new)) 431 } 432 // X operand. 433 x, err := fgen.irTypeValue(old.X()) 434 if err != nil { 435 return errors.WithStack(err) 436 } 437 inst.X = x 438 // Y operand. 439 y, err := fgen.irValue(x.Type(), old.Y()) 440 if err != nil { 441 return errors.WithStack(err) 442 } 443 inst.Y = y 444 // (optional) Metadata. 445 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 446 if err != nil { 447 return errors.WithStack(err) 448 } 449 inst.Metadata = md 450 return nil 451 } 452 453 // --- [ srem ] ---------------------------------------------------------------- 454 455 // irSRemInst translates the given AST srem instruction into an equivalent IR 456 // instruction. 457 func (fgen *funcGen) irSRemInst(new ir.Instruction, old *ast.SRemInst) error { 458 inst, ok := new.(*ir.InstSRem) 459 if !ok { 460 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstSRem, got %T", new)) 461 } 462 // X operand. 463 x, err := fgen.irTypeValue(old.X()) 464 if err != nil { 465 return errors.WithStack(err) 466 } 467 inst.X = x 468 // Y operand. 469 y, err := fgen.irValue(x.Type(), old.Y()) 470 if err != nil { 471 return errors.WithStack(err) 472 } 473 inst.Y = y 474 // (optional) Metadata. 475 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 476 if err != nil { 477 return errors.WithStack(err) 478 } 479 inst.Metadata = md 480 return nil 481 } 482 483 // --- [ frem ] ---------------------------------------------------------------- 484 485 // irFRemInst translates the given AST frem instruction into an equivalent IR 486 // instruction. 487 func (fgen *funcGen) irFRemInst(new ir.Instruction, old *ast.FRemInst) error { 488 inst, ok := new.(*ir.InstFRem) 489 if !ok { 490 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFRem, got %T", new)) 491 } 492 // X operand. 493 x, err := fgen.irTypeValue(old.X()) 494 if err != nil { 495 return errors.WithStack(err) 496 } 497 inst.X = x 498 // Y operand. 499 y, err := fgen.irValue(x.Type(), old.Y()) 500 if err != nil { 501 return errors.WithStack(err) 502 } 503 inst.Y = y 504 // (optional) Fast math flags. 505 inst.FastMathFlags = irFastMathFlags(old.FastMathFlags()) 506 // (optional) Metadata. 507 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 508 if err != nil { 509 return errors.WithStack(err) 510 } 511 inst.Metadata = md 512 return nil 513 }