github.com/llir/llvm@v0.3.6/asm/inst_conversion.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 // newTruncInst returns a new IR trunc instruction (without body but with type) 14 // based on the given AST trunc instruction. 15 func (fgen *funcGen) newTruncInst(ident ir.LocalIdent, old *ast.TruncInst) (*ir.InstTrunc, error) { 16 to, err := fgen.gen.irType(old.To()) 17 if err != nil { 18 return nil, errors.WithStack(err) 19 } 20 return &ir.InstTrunc{LocalIdent: ident, To: to}, nil 21 } 22 23 // newZExtInst returns a new IR zext instruction (without body but with type) 24 // based on the given AST zext instruction. 25 func (fgen *funcGen) newZExtInst(ident ir.LocalIdent, old *ast.ZExtInst) (*ir.InstZExt, error) { 26 to, err := fgen.gen.irType(old.To()) 27 if err != nil { 28 return nil, errors.WithStack(err) 29 } 30 return &ir.InstZExt{LocalIdent: ident, To: to}, nil 31 } 32 33 // newSExtInst returns a new IR sext instruction (without body but with type) 34 // based on the given AST sext instruction. 35 func (fgen *funcGen) newSExtInst(ident ir.LocalIdent, old *ast.SExtInst) (*ir.InstSExt, error) { 36 to, err := fgen.gen.irType(old.To()) 37 if err != nil { 38 return nil, errors.WithStack(err) 39 } 40 return &ir.InstSExt{LocalIdent: ident, To: to}, nil 41 } 42 43 // newFPTruncInst returns a new IR fptrunc instruction (without body but with 44 // type) based on the given AST fptrunc instruction. 45 func (fgen *funcGen) newFPTruncInst(ident ir.LocalIdent, old *ast.FPTruncInst) (*ir.InstFPTrunc, error) { 46 to, err := fgen.gen.irType(old.To()) 47 if err != nil { 48 return nil, errors.WithStack(err) 49 } 50 return &ir.InstFPTrunc{LocalIdent: ident, To: to}, nil 51 } 52 53 // newFPExtInst returns a new IR fpext instruction (without body but with type) 54 // based on the given AST fpext instruction. 55 func (fgen *funcGen) newFPExtInst(ident ir.LocalIdent, old *ast.FPExtInst) (*ir.InstFPExt, error) { 56 to, err := fgen.gen.irType(old.To()) 57 if err != nil { 58 return nil, errors.WithStack(err) 59 } 60 return &ir.InstFPExt{LocalIdent: ident, To: to}, nil 61 } 62 63 // newFPToUIInst returns a new IR fptoui instruction (without body but with 64 // type) based on the given AST fptoui instruction. 65 func (fgen *funcGen) newFPToUIInst(ident ir.LocalIdent, old *ast.FPToUIInst) (*ir.InstFPToUI, error) { 66 to, err := fgen.gen.irType(old.To()) 67 if err != nil { 68 return nil, errors.WithStack(err) 69 } 70 return &ir.InstFPToUI{LocalIdent: ident, To: to}, nil 71 } 72 73 // newFPToSIInst returns a new IR fptosi instruction (without body but with 74 // type) based on the given AST fptosi instruction. 75 func (fgen *funcGen) newFPToSIInst(ident ir.LocalIdent, old *ast.FPToSIInst) (*ir.InstFPToSI, error) { 76 to, err := fgen.gen.irType(old.To()) 77 if err != nil { 78 return nil, errors.WithStack(err) 79 } 80 return &ir.InstFPToSI{LocalIdent: ident, To: to}, nil 81 } 82 83 // newUIToFPInst returns a new IR uitofp instruction (without body but with 84 // type) based on the given AST uitofp instruction. 85 func (fgen *funcGen) newUIToFPInst(ident ir.LocalIdent, old *ast.UIToFPInst) (*ir.InstUIToFP, error) { 86 to, err := fgen.gen.irType(old.To()) 87 if err != nil { 88 return nil, errors.WithStack(err) 89 } 90 return &ir.InstUIToFP{LocalIdent: ident, To: to}, nil 91 } 92 93 // newSIToFPInst returns a new IR sitofp instruction (without body but with 94 // type) based on the given AST sitofp instruction. 95 func (fgen *funcGen) newSIToFPInst(ident ir.LocalIdent, old *ast.SIToFPInst) (*ir.InstSIToFP, error) { 96 to, err := fgen.gen.irType(old.To()) 97 if err != nil { 98 return nil, errors.WithStack(err) 99 } 100 return &ir.InstSIToFP{LocalIdent: ident, To: to}, nil 101 } 102 103 // newPtrToIntInst returns a new IR ptrtoint instruction (without body but with 104 // type) based on the given AST ptrtoint instruction. 105 func (fgen *funcGen) newPtrToIntInst(ident ir.LocalIdent, old *ast.PtrToIntInst) (*ir.InstPtrToInt, error) { 106 to, err := fgen.gen.irType(old.To()) 107 if err != nil { 108 return nil, errors.WithStack(err) 109 } 110 return &ir.InstPtrToInt{LocalIdent: ident, To: to}, nil 111 } 112 113 // newIntToPtrInst returns a new IR inttoptr instruction (without body but with 114 // type) based on the given AST inttoptr instruction. 115 func (fgen *funcGen) newIntToPtrInst(ident ir.LocalIdent, old *ast.IntToPtrInst) (*ir.InstIntToPtr, error) { 116 to, err := fgen.gen.irType(old.To()) 117 if err != nil { 118 return nil, errors.WithStack(err) 119 } 120 return &ir.InstIntToPtr{LocalIdent: ident, To: to}, nil 121 } 122 123 // newBitCastInst returns a new IR bitcast instruction (without body but with 124 // type) based on the given AST bitcast instruction. 125 func (fgen *funcGen) newBitCastInst(ident ir.LocalIdent, old *ast.BitCastInst) (*ir.InstBitCast, error) { 126 to, err := fgen.gen.irType(old.To()) 127 if err != nil { 128 return nil, errors.WithStack(err) 129 } 130 return &ir.InstBitCast{LocalIdent: ident, To: to}, nil 131 } 132 133 // newAddrSpaceCastInst returns a new IR addrspacecast instruction (without body 134 // but with type) based on the given AST addrspacecast instruction. 135 func (fgen *funcGen) newAddrSpaceCastInst(ident ir.LocalIdent, old *ast.AddrSpaceCastInst) (*ir.InstAddrSpaceCast, error) { 136 to, err := fgen.gen.irType(old.To()) 137 if err != nil { 138 return nil, errors.WithStack(err) 139 } 140 return &ir.InstAddrSpaceCast{LocalIdent: ident, To: to}, nil 141 } 142 143 // === [ Translate AST to IR ] ================================================= 144 145 // --- [ trunc ] --------------------------------------------------------------- 146 147 // irTruncInst translates the given AST trunc instruction into an equivalent IR 148 // instruction. 149 func (fgen *funcGen) irTruncInst(new ir.Instruction, old *ast.TruncInst) error { 150 inst, ok := new.(*ir.InstTrunc) 151 if !ok { 152 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstTrunc, got %T", new)) 153 } 154 // Value before conversion. 155 from, err := fgen.irTypeValue(old.From()) 156 if err != nil { 157 return errors.WithStack(err) 158 } 159 inst.From = from 160 // Type after conversion. 161 to, err := fgen.gen.irType(old.To()) 162 if err != nil { 163 return errors.WithStack(err) 164 } 165 inst.To = to 166 // (optional) Metadata. 167 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 168 if err != nil { 169 return errors.WithStack(err) 170 } 171 inst.Metadata = md 172 return nil 173 } 174 175 // --- [ zext ] ---------------------------------------------------------------- 176 177 // irZExtInst translates the given AST zext instruction into an equivalent IR 178 // instruction. 179 func (fgen *funcGen) irZExtInst(new ir.Instruction, old *ast.ZExtInst) error { 180 inst, ok := new.(*ir.InstZExt) 181 if !ok { 182 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstZExt, got %T", new)) 183 } 184 // Value before conversion. 185 from, err := fgen.irTypeValue(old.From()) 186 if err != nil { 187 return errors.WithStack(err) 188 } 189 inst.From = from 190 // Type after conversion. 191 to, err := fgen.gen.irType(old.To()) 192 if err != nil { 193 return errors.WithStack(err) 194 } 195 inst.To = to 196 // (optional) Metadata. 197 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 198 if err != nil { 199 return errors.WithStack(err) 200 } 201 inst.Metadata = md 202 return nil 203 } 204 205 // --- [ sext ] ---------------------------------------------------------------- 206 207 // irSExtInst translates the given AST sext instruction into an equivalent IR 208 // instruction. 209 func (fgen *funcGen) irSExtInst(new ir.Instruction, old *ast.SExtInst) error { 210 inst, ok := new.(*ir.InstSExt) 211 if !ok { 212 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstSExt, got %T", new)) 213 } 214 // Value before conversion. 215 from, err := fgen.irTypeValue(old.From()) 216 if err != nil { 217 return errors.WithStack(err) 218 } 219 inst.From = from 220 // Type after conversion. 221 to, err := fgen.gen.irType(old.To()) 222 if err != nil { 223 return errors.WithStack(err) 224 } 225 inst.To = to 226 // (optional) Metadata. 227 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 228 if err != nil { 229 return errors.WithStack(err) 230 } 231 inst.Metadata = md 232 return nil 233 } 234 235 // --- [ fptrunc ] ------------------------------------------------------------- 236 237 // irFPTruncInst translates the given AST fptrunc instruction into an equivalent 238 // IR instruction. 239 func (fgen *funcGen) irFPTruncInst(new ir.Instruction, old *ast.FPTruncInst) error { 240 inst, ok := new.(*ir.InstFPTrunc) 241 if !ok { 242 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPTrunc, got %T", new)) 243 } 244 // Value before conversion. 245 from, err := fgen.irTypeValue(old.From()) 246 if err != nil { 247 return errors.WithStack(err) 248 } 249 inst.From = from 250 // Type after conversion. 251 to, err := fgen.gen.irType(old.To()) 252 if err != nil { 253 return errors.WithStack(err) 254 } 255 inst.To = to 256 // (optional) Metadata. 257 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 258 if err != nil { 259 return errors.WithStack(err) 260 } 261 inst.Metadata = md 262 return nil 263 } 264 265 // --- [ fpext ] --------------------------------------------------------------- 266 267 // irFPExtInst translates the given AST fpext instruction into an equivalent IR 268 // instruction. 269 func (fgen *funcGen) irFPExtInst(new ir.Instruction, old *ast.FPExtInst) error { 270 inst, ok := new.(*ir.InstFPExt) 271 if !ok { 272 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPExt, got %T", new)) 273 } 274 // Value before conversion. 275 from, err := fgen.irTypeValue(old.From()) 276 if err != nil { 277 return errors.WithStack(err) 278 } 279 inst.From = from 280 // Type after conversion. 281 to, err := fgen.gen.irType(old.To()) 282 if err != nil { 283 return errors.WithStack(err) 284 } 285 inst.To = to 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 // --- [ fptoui ] -------------------------------------------------------------- 296 297 // irFPToUIInst translates the given AST fptoui instruction into an equivalent 298 // IR instruction. 299 func (fgen *funcGen) irFPToUIInst(new ir.Instruction, old *ast.FPToUIInst) error { 300 inst, ok := new.(*ir.InstFPToUI) 301 if !ok { 302 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPToUI, got %T", new)) 303 } 304 // Value before conversion. 305 from, err := fgen.irTypeValue(old.From()) 306 if err != nil { 307 return errors.WithStack(err) 308 } 309 inst.From = from 310 // Type after conversion. 311 to, err := fgen.gen.irType(old.To()) 312 if err != nil { 313 return errors.WithStack(err) 314 } 315 inst.To = to 316 // (optional) Metadata. 317 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 318 if err != nil { 319 return errors.WithStack(err) 320 } 321 inst.Metadata = md 322 return nil 323 } 324 325 // --- [ fptosi ] -------------------------------------------------------------- 326 327 // irFPToSIInst translates the given AST fptosi instruction into an equivalent 328 // IR instruction. 329 func (fgen *funcGen) irFPToSIInst(new ir.Instruction, old *ast.FPToSIInst) error { 330 inst, ok := new.(*ir.InstFPToSI) 331 if !ok { 332 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstFPToSI, got %T", new)) 333 } 334 // Value before conversion. 335 from, err := fgen.irTypeValue(old.From()) 336 if err != nil { 337 return errors.WithStack(err) 338 } 339 inst.From = from 340 // Type after conversion. 341 to, err := fgen.gen.irType(old.To()) 342 if err != nil { 343 return errors.WithStack(err) 344 } 345 inst.To = to 346 // (optional) Metadata. 347 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 348 if err != nil { 349 return errors.WithStack(err) 350 } 351 inst.Metadata = md 352 return nil 353 } 354 355 // --- [ uitofp ] -------------------------------------------------------------- 356 357 // irUIToFPInst translates the given AST uitofp instruction into an equivalent 358 // IR instruction. 359 func (fgen *funcGen) irUIToFPInst(new ir.Instruction, old *ast.UIToFPInst) error { 360 inst, ok := new.(*ir.InstUIToFP) 361 if !ok { 362 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstUIToFP, got %T", new)) 363 } 364 // Value before conversion. 365 from, err := fgen.irTypeValue(old.From()) 366 if err != nil { 367 return errors.WithStack(err) 368 } 369 inst.From = from 370 // Type after conversion. 371 to, err := fgen.gen.irType(old.To()) 372 if err != nil { 373 return errors.WithStack(err) 374 } 375 inst.To = to 376 // (optional) Metadata. 377 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 378 if err != nil { 379 return errors.WithStack(err) 380 } 381 inst.Metadata = md 382 return nil 383 } 384 385 // --- [ sitofp ] -------------------------------------------------------------- 386 387 // irSIToFPInst translates the given AST sitofp instruction into an equivalent 388 // IR instruction. 389 func (fgen *funcGen) irSIToFPInst(new ir.Instruction, old *ast.SIToFPInst) error { 390 inst, ok := new.(*ir.InstSIToFP) 391 if !ok { 392 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstSIToFP, got %T", new)) 393 } 394 // Value before conversion. 395 from, err := fgen.irTypeValue(old.From()) 396 if err != nil { 397 return errors.WithStack(err) 398 } 399 inst.From = from 400 // Type after conversion. 401 to, err := fgen.gen.irType(old.To()) 402 if err != nil { 403 return errors.WithStack(err) 404 } 405 inst.To = to 406 // (optional) Metadata. 407 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 408 if err != nil { 409 return errors.WithStack(err) 410 } 411 inst.Metadata = md 412 return nil 413 } 414 415 // --- [ ptrtoint ] ------------------------------------------------------------ 416 417 // irPtrToIntInst translates the given AST ptrtoint instruction into an 418 // equivalent IR instruction. 419 func (fgen *funcGen) irPtrToIntInst(new ir.Instruction, old *ast.PtrToIntInst) error { 420 inst, ok := new.(*ir.InstPtrToInt) 421 if !ok { 422 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstPtrToInt, got %T", new)) 423 } 424 // Value before conversion. 425 from, err := fgen.irTypeValue(old.From()) 426 if err != nil { 427 return errors.WithStack(err) 428 } 429 inst.From = from 430 // Type after conversion. 431 to, err := fgen.gen.irType(old.To()) 432 if err != nil { 433 return errors.WithStack(err) 434 } 435 inst.To = to 436 // (optional) Metadata. 437 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 438 if err != nil { 439 return errors.WithStack(err) 440 } 441 inst.Metadata = md 442 return nil 443 } 444 445 // --- [ inttoptr ] ------------------------------------------------------------ 446 447 // irIntToPtrInst translates the given AST inttoptr instruction into an 448 // equivalent IR instruction. 449 func (fgen *funcGen) irIntToPtrInst(new ir.Instruction, old *ast.IntToPtrInst) error { 450 inst, ok := new.(*ir.InstIntToPtr) 451 if !ok { 452 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstIntToPtr, got %T", new)) 453 } 454 // Value before conversion. 455 from, err := fgen.irTypeValue(old.From()) 456 if err != nil { 457 return errors.WithStack(err) 458 } 459 inst.From = from 460 // Type after conversion. 461 to, err := fgen.gen.irType(old.To()) 462 if err != nil { 463 return errors.WithStack(err) 464 } 465 inst.To = to 466 // (optional) Metadata. 467 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 468 if err != nil { 469 return errors.WithStack(err) 470 } 471 inst.Metadata = md 472 return nil 473 } 474 475 // --- [ bitcast ] ------------------------------------------------------------- 476 477 // irBitCastInst translates the given AST bitcast instruction into an equivalent 478 // IR instruction. 479 func (fgen *funcGen) irBitCastInst(new ir.Instruction, old *ast.BitCastInst) error { 480 inst, ok := new.(*ir.InstBitCast) 481 if !ok { 482 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstBitCast, got %T", new)) 483 } 484 // Value before conversion. 485 from, err := fgen.irTypeValue(old.From()) 486 if err != nil { 487 return errors.WithStack(err) 488 } 489 inst.From = from 490 // Type after conversion. 491 to, err := fgen.gen.irType(old.To()) 492 if err != nil { 493 return errors.WithStack(err) 494 } 495 inst.To = to 496 // (optional) Metadata. 497 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 498 if err != nil { 499 return errors.WithStack(err) 500 } 501 inst.Metadata = md 502 return nil 503 } 504 505 // --- [ addrspacecast ] ------------------------------------------------------- 506 507 // irAddrSpaceCastInst translates the given AST addrspacecast instruction into 508 // an equivalent IR instruction. 509 func (fgen *funcGen) irAddrSpaceCastInst(new ir.Instruction, old *ast.AddrSpaceCastInst) error { 510 inst, ok := new.(*ir.InstAddrSpaceCast) 511 if !ok { 512 panic(fmt.Errorf("invalid IR instruction for AST instruction; expected *ir.InstAddrSpaceCast, got %T", new)) 513 } 514 // Value before conversion. 515 from, err := fgen.irTypeValue(old.From()) 516 if err != nil { 517 return errors.WithStack(err) 518 } 519 inst.From = from 520 // Type after conversion. 521 to, err := fgen.gen.irType(old.To()) 522 if err != nil { 523 return errors.WithStack(err) 524 } 525 inst.To = to 526 // (optional) Metadata. 527 md, err := fgen.gen.irMetadataAttachments(old.Metadata()) 528 if err != nil { 529 return errors.WithStack(err) 530 } 531 inst.Metadata = md 532 return nil 533 }