github.com/llir/llvm@v0.3.6/asm/const_expr.go (about) 1 package asm 2 3 import ( 4 "fmt" 5 6 "github.com/llir/ll/ast" 7 asmenum "github.com/llir/llvm/asm/enum" 8 "github.com/llir/llvm/ir/constant" 9 "github.com/llir/llvm/ir/types" 10 "github.com/pkg/errors" 11 ) 12 13 // === [ Translate AST to IR ] ================================================= 14 15 // irConstantExpr translates the AST constant expression into an equivalent IR 16 // constant expression. 17 func (gen *generator) irConstantExpr(t types.Type, old ast.ConstantExpr) (constant.Expression, error) { 18 switch old := old.(type) { 19 // Unary expressions 20 case *ast.FNegExpr: 21 return gen.irFNegExpr(t, old) 22 // Binary expressions 23 case *ast.AddExpr: 24 return gen.irAddExpr(t, old) 25 case *ast.FAddExpr: 26 return gen.irFAddExpr(t, old) 27 case *ast.SubExpr: 28 return gen.irSubExpr(t, old) 29 case *ast.FSubExpr: 30 return gen.irFSubExpr(t, old) 31 case *ast.MulExpr: 32 return gen.irMulExpr(t, old) 33 case *ast.FMulExpr: 34 return gen.irFMulExpr(t, old) 35 case *ast.UDivExpr: 36 return gen.irUDivExpr(t, old) 37 case *ast.SDivExpr: 38 return gen.irSDivExpr(t, old) 39 case *ast.FDivExpr: 40 return gen.irFDivExpr(t, old) 41 case *ast.URemExpr: 42 return gen.irURemExpr(t, old) 43 case *ast.SRemExpr: 44 return gen.irSRemExpr(t, old) 45 case *ast.FRemExpr: 46 return gen.irFRemExpr(t, old) 47 // Bitwise expressions 48 case *ast.ShlExpr: 49 return gen.irShlExpr(t, old) 50 case *ast.LShrExpr: 51 return gen.irLShrExpr(t, old) 52 case *ast.AShrExpr: 53 return gen.irAShrExpr(t, old) 54 case *ast.AndExpr: 55 return gen.irAndExpr(t, old) 56 case *ast.OrExpr: 57 return gen.irOrExpr(t, old) 58 case *ast.XorExpr: 59 return gen.irXorExpr(t, old) 60 // Vector expressions 61 case *ast.ExtractElementExpr: 62 return gen.irExtractElementExpr(t, old) 63 case *ast.InsertElementExpr: 64 return gen.irInsertElementExpr(t, old) 65 case *ast.ShuffleVectorExpr: 66 return gen.irShuffleVectorExpr(t, old) 67 // Aggregate expressions 68 case *ast.ExtractValueExpr: 69 return gen.irExtractValueExpr(t, old) 70 case *ast.InsertValueExpr: 71 return gen.irInsertValueExpr(t, old) 72 // Memory expressions 73 case *ast.GetElementPtrExpr: 74 return gen.irGetElementPtrExpr(t, old) 75 // Conversion expressions 76 case *ast.TruncExpr: 77 return gen.irTruncExpr(t, old) 78 case *ast.ZExtExpr: 79 return gen.irZExtExpr(t, old) 80 case *ast.SExtExpr: 81 return gen.irSExtExpr(t, old) 82 case *ast.FPTruncExpr: 83 return gen.irFPTruncExpr(t, old) 84 case *ast.FPExtExpr: 85 return gen.irFPExtExpr(t, old) 86 case *ast.FPToUIExpr: 87 return gen.irFPToUIExpr(t, old) 88 case *ast.FPToSIExpr: 89 return gen.irFPToSIExpr(t, old) 90 case *ast.UIToFPExpr: 91 return gen.irUIToFPExpr(t, old) 92 case *ast.SIToFPExpr: 93 return gen.irSIToFPExpr(t, old) 94 case *ast.PtrToIntExpr: 95 return gen.irPtrToIntExpr(t, old) 96 case *ast.IntToPtrExpr: 97 return gen.irIntToPtrExpr(t, old) 98 case *ast.BitCastExpr: 99 return gen.irBitCastExpr(t, old) 100 case *ast.AddrSpaceCastExpr: 101 return gen.irAddrSpaceCastExpr(t, old) 102 // Other expressions 103 case *ast.ICmpExpr: 104 return gen.irICmpExpr(t, old) 105 case *ast.FCmpExpr: 106 return gen.irFCmpExpr(t, old) 107 case *ast.SelectExpr: 108 return gen.irSelectExpr(t, old) 109 default: 110 panic(fmt.Errorf("support for AST constant expression %T not yet implemented", old)) 111 } 112 } 113 114 // --- [ Unary expressions ] --------------------------------------------------- 115 116 // ~~~ [ fneg ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 117 118 // irFNegExpr translates the AST fneg constant expression into an equivalent IR 119 // constant expression. 120 func (gen *generator) irFNegExpr(t types.Type, old *ast.FNegExpr) (*constant.ExprFNeg, error) { 121 // X operand. 122 x, err := gen.irTypeConst(old.X()) 123 if err != nil { 124 return nil, errors.WithStack(err) 125 } 126 expr := constant.NewFNeg(x) 127 if !t.Equal(expr.Typ) { 128 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 129 } 130 return expr, nil 131 } 132 133 // --- [ Binary expressions ] -------------------------------------------------- 134 135 // ~~~ [ add ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 137 // irAddExpr translates the AST add constant expression into an equivalent IR 138 // constant expression. 139 func (gen *generator) irAddExpr(t types.Type, old *ast.AddExpr) (*constant.ExprAdd, error) { 140 // X operand. 141 x, err := gen.irTypeConst(old.X()) 142 if err != nil { 143 return nil, errors.WithStack(err) 144 } 145 // Y operand. 146 y, err := gen.irTypeConst(old.Y()) 147 if err != nil { 148 return nil, errors.WithStack(err) 149 } 150 expr := constant.NewAdd(x, y) 151 // (optional) Overflow flags. 152 expr.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 153 if !t.Equal(expr.Typ) { 154 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 155 } 156 return expr, nil 157 } 158 159 // ~~~ [ fadd ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 160 161 // irFAddExpr translates the AST fadd constant expression into an equivalent IR 162 // constant expression. 163 func (gen *generator) irFAddExpr(t types.Type, old *ast.FAddExpr) (*constant.ExprFAdd, error) { 164 // X operand. 165 x, err := gen.irTypeConst(old.X()) 166 if err != nil { 167 return nil, errors.WithStack(err) 168 } 169 // Y operand. 170 y, err := gen.irTypeConst(old.Y()) 171 if err != nil { 172 return nil, errors.WithStack(err) 173 } 174 expr := constant.NewFAdd(x, y) 175 if !t.Equal(expr.Typ) { 176 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 177 } 178 return expr, nil 179 } 180 181 // ~~~ [ sub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182 183 // irSubExpr translates the AST sub constant expression into an equivalent IR 184 // constant expression. 185 func (gen *generator) irSubExpr(t types.Type, old *ast.SubExpr) (*constant.ExprSub, error) { 186 // X operand. 187 x, err := gen.irTypeConst(old.X()) 188 if err != nil { 189 return nil, errors.WithStack(err) 190 } 191 // Y operand. 192 y, err := gen.irTypeConst(old.Y()) 193 if err != nil { 194 return nil, errors.WithStack(err) 195 } 196 expr := constant.NewSub(x, y) 197 // (optional) Overflow flags. 198 expr.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 199 if !t.Equal(expr.Typ) { 200 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 201 } 202 return expr, nil 203 } 204 205 // ~~~ [ fsub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 206 207 // irFSubExpr translates the AST fsub constant expression into an equivalent IR 208 // constant expression. 209 func (gen *generator) irFSubExpr(t types.Type, old *ast.FSubExpr) (*constant.ExprFSub, error) { 210 // X operand. 211 x, err := gen.irTypeConst(old.X()) 212 if err != nil { 213 return nil, errors.WithStack(err) 214 } 215 // Y operand. 216 y, err := gen.irTypeConst(old.Y()) 217 if err != nil { 218 return nil, errors.WithStack(err) 219 } 220 expr := constant.NewFSub(x, y) 221 if !t.Equal(expr.Typ) { 222 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 223 } 224 return expr, nil 225 } 226 227 // ~~~ [ mul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 229 // irMulExpr translates the AST mul constant expression into an equivalent IR 230 // constant expression. 231 func (gen *generator) irMulExpr(t types.Type, old *ast.MulExpr) (*constant.ExprMul, error) { 232 // X operand. 233 x, err := gen.irTypeConst(old.X()) 234 if err != nil { 235 return nil, errors.WithStack(err) 236 } 237 // Y operand. 238 y, err := gen.irTypeConst(old.Y()) 239 if err != nil { 240 return nil, errors.WithStack(err) 241 } 242 expr := constant.NewMul(x, y) 243 // (optional) Overflow flags. 244 expr.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 245 if !t.Equal(expr.Typ) { 246 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 247 } 248 return expr, nil 249 } 250 251 // ~~~ [ fmul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 252 253 // irFMulExpr translates the AST fmul constant expression into an equivalent IR 254 // constant expression. 255 func (gen *generator) irFMulExpr(t types.Type, old *ast.FMulExpr) (*constant.ExprFMul, error) { 256 // X operand. 257 x, err := gen.irTypeConst(old.X()) 258 if err != nil { 259 return nil, errors.WithStack(err) 260 } 261 // Y operand. 262 y, err := gen.irTypeConst(old.Y()) 263 if err != nil { 264 return nil, errors.WithStack(err) 265 } 266 expr := constant.NewFMul(x, y) 267 if !t.Equal(expr.Typ) { 268 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 269 } 270 return expr, nil 271 } 272 273 // ~~~ [ udiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 274 275 // irUDivExpr translates the AST udiv constant expression into an equivalent IR 276 // constant expression. 277 func (gen *generator) irUDivExpr(t types.Type, old *ast.UDivExpr) (*constant.ExprUDiv, error) { 278 // X operand. 279 x, err := gen.irTypeConst(old.X()) 280 if err != nil { 281 return nil, errors.WithStack(err) 282 } 283 // Y operand. 284 y, err := gen.irTypeConst(old.Y()) 285 if err != nil { 286 return nil, errors.WithStack(err) 287 } 288 expr := constant.NewUDiv(x, y) 289 // (optional) Exact. 290 _, expr.Exact = old.Exact() 291 if !t.Equal(expr.Typ) { 292 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 293 } 294 return expr, nil 295 } 296 297 // ~~~ [ sdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 299 // irSDivExpr translates the AST sdiv constant expression into an equivalent IR 300 // constant expression. 301 func (gen *generator) irSDivExpr(t types.Type, old *ast.SDivExpr) (*constant.ExprSDiv, error) { 302 // X operand. 303 x, err := gen.irTypeConst(old.X()) 304 if err != nil { 305 return nil, errors.WithStack(err) 306 } 307 // Y operand. 308 y, err := gen.irTypeConst(old.Y()) 309 if err != nil { 310 return nil, errors.WithStack(err) 311 } 312 expr := constant.NewSDiv(x, y) 313 // (optional) Exact. 314 _, expr.Exact = old.Exact() 315 if !t.Equal(expr.Typ) { 316 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 317 } 318 return expr, nil 319 } 320 321 // ~~~ [ fdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 322 323 // irFDivExpr translates the AST fdiv constant expression into an equivalent IR 324 // constant expression. 325 func (gen *generator) irFDivExpr(t types.Type, old *ast.FDivExpr) (*constant.ExprFDiv, error) { 326 // X operand. 327 x, err := gen.irTypeConst(old.X()) 328 if err != nil { 329 return nil, errors.WithStack(err) 330 } 331 // Y operand. 332 y, err := gen.irTypeConst(old.Y()) 333 if err != nil { 334 return nil, errors.WithStack(err) 335 } 336 expr := constant.NewFDiv(x, y) 337 if !t.Equal(expr.Typ) { 338 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 339 } 340 return expr, nil 341 } 342 343 // ~~~ [ urem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 344 345 // irURemExpr translates the AST urem constant expression into an equivalent IR 346 // constant expression. 347 func (gen *generator) irURemExpr(t types.Type, old *ast.URemExpr) (*constant.ExprURem, error) { 348 // X operand. 349 x, err := gen.irTypeConst(old.X()) 350 if err != nil { 351 return nil, errors.WithStack(err) 352 } 353 // Y operand. 354 y, err := gen.irTypeConst(old.Y()) 355 if err != nil { 356 return nil, errors.WithStack(err) 357 } 358 expr := constant.NewURem(x, y) 359 if !t.Equal(expr.Typ) { 360 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 361 } 362 return expr, nil 363 } 364 365 // ~~~ [ srem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 367 // irSRemExpr translates the AST srem constant expression into an equivalent IR 368 // constant expression. 369 func (gen *generator) irSRemExpr(t types.Type, old *ast.SRemExpr) (*constant.ExprSRem, error) { 370 // X operand. 371 x, err := gen.irTypeConst(old.X()) 372 if err != nil { 373 return nil, errors.WithStack(err) 374 } 375 // Y operand. 376 y, err := gen.irTypeConst(old.Y()) 377 if err != nil { 378 return nil, errors.WithStack(err) 379 } 380 expr := constant.NewSRem(x, y) 381 if !t.Equal(expr.Typ) { 382 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 383 } 384 return expr, nil 385 } 386 387 // ~~~ [ frem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 388 389 // irFRemExpr translates the AST frem constant expression into an equivalent IR 390 // constant expression. 391 func (gen *generator) irFRemExpr(t types.Type, old *ast.FRemExpr) (*constant.ExprFRem, error) { 392 // X operand. 393 x, err := gen.irTypeConst(old.X()) 394 if err != nil { 395 return nil, errors.WithStack(err) 396 } 397 // Y operand. 398 y, err := gen.irTypeConst(old.Y()) 399 if err != nil { 400 return nil, errors.WithStack(err) 401 } 402 expr := constant.NewFRem(x, y) 403 if !t.Equal(expr.Typ) { 404 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 405 } 406 return expr, nil 407 } 408 409 // --- [ Bitwise expressions ] ------------------------------------------------- 410 411 // ~~~ [ shl ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 412 413 // irShlExpr translates the AST shl constant expression into an equivalent IR 414 // constant expression. 415 func (gen *generator) irShlExpr(t types.Type, old *ast.ShlExpr) (*constant.ExprShl, error) { 416 // X operand. 417 x, err := gen.irTypeConst(old.X()) 418 if err != nil { 419 return nil, errors.WithStack(err) 420 } 421 // Y operand. 422 y, err := gen.irTypeConst(old.Y()) 423 if err != nil { 424 return nil, errors.WithStack(err) 425 } 426 expr := constant.NewShl(x, y) 427 // (optional) Overflow flags. 428 expr.OverflowFlags = irOverflowFlags(old.OverflowFlags()) 429 if !t.Equal(expr.Typ) { 430 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 431 } 432 return expr, nil 433 } 434 435 // ~~~ [ lshr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 436 437 // irLShrExpr translates the AST lshr constant expression into an equivalent IR 438 // constant expression. 439 func (gen *generator) irLShrExpr(t types.Type, old *ast.LShrExpr) (*constant.ExprLShr, error) { 440 // X operand. 441 x, err := gen.irTypeConst(old.X()) 442 if err != nil { 443 return nil, errors.WithStack(err) 444 } 445 // Y operand. 446 y, err := gen.irTypeConst(old.Y()) 447 if err != nil { 448 return nil, errors.WithStack(err) 449 } 450 expr := constant.NewLShr(x, y) 451 // (optional) Exact. 452 _, expr.Exact = old.Exact() 453 if !t.Equal(expr.Typ) { 454 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 455 } 456 return expr, nil 457 } 458 459 // ~~~ [ ashr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 460 461 // irAShrExpr translates the AST ashr constant expression into an equivalent IR 462 // constant expression. 463 func (gen *generator) irAShrExpr(t types.Type, old *ast.AShrExpr) (*constant.ExprAShr, error) { 464 // X operand. 465 x, err := gen.irTypeConst(old.X()) 466 if err != nil { 467 return nil, errors.WithStack(err) 468 } 469 // Y operand. 470 y, err := gen.irTypeConst(old.Y()) 471 if err != nil { 472 return nil, errors.WithStack(err) 473 } 474 expr := constant.NewAShr(x, y) 475 // (optional) Exact. 476 _, expr.Exact = old.Exact() 477 if !t.Equal(expr.Typ) { 478 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 479 } 480 return expr, nil 481 } 482 483 // ~~~ [ and ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 484 485 // irAndExpr translates the AST and constant expression into an equivalent IR 486 // constant expression. 487 func (gen *generator) irAndExpr(t types.Type, old *ast.AndExpr) (*constant.ExprAnd, error) { 488 // X operand. 489 x, err := gen.irTypeConst(old.X()) 490 if err != nil { 491 return nil, errors.WithStack(err) 492 } 493 // Y operand. 494 y, err := gen.irTypeConst(old.Y()) 495 if err != nil { 496 return nil, errors.WithStack(err) 497 } 498 expr := constant.NewAnd(x, y) 499 if !t.Equal(expr.Typ) { 500 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 501 } 502 return expr, nil 503 } 504 505 // ~~~ [ or ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 507 // irOrExpr translates the AST or constant expression into an equivalent IR 508 // constant expression. 509 func (gen *generator) irOrExpr(t types.Type, old *ast.OrExpr) (*constant.ExprOr, error) { 510 // X operand. 511 x, err := gen.irTypeConst(old.X()) 512 if err != nil { 513 return nil, errors.WithStack(err) 514 } 515 // Y operand. 516 y, err := gen.irTypeConst(old.Y()) 517 if err != nil { 518 return nil, errors.WithStack(err) 519 } 520 expr := constant.NewOr(x, y) 521 if !t.Equal(expr.Typ) { 522 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 523 } 524 return expr, nil 525 } 526 527 // ~~~ [ xor ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 528 529 // irXorExpr translates the AST xor constant expression into an equivalent IR 530 // constant expression. 531 func (gen *generator) irXorExpr(t types.Type, old *ast.XorExpr) (*constant.ExprXor, error) { 532 // X operand. 533 x, err := gen.irTypeConst(old.X()) 534 if err != nil { 535 return nil, errors.WithStack(err) 536 } 537 // Y operand. 538 y, err := gen.irTypeConst(old.Y()) 539 if err != nil { 540 return nil, errors.WithStack(err) 541 } 542 expr := constant.NewXor(x, y) 543 if !t.Equal(expr.Typ) { 544 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 545 } 546 return expr, nil 547 } 548 549 // --- [ Vector expressions ] -------------------------------------------------- 550 551 // ~~~ [ extractelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 553 // irExtractElementExpr translates the AST extractelement constant expression 554 // into an equivalent IR constant expression. 555 func (gen *generator) irExtractElementExpr(t types.Type, old *ast.ExtractElementExpr) (*constant.ExprExtractElement, error) { 556 // Vector. 557 x, err := gen.irTypeConst(old.X()) 558 if err != nil { 559 return nil, errors.WithStack(err) 560 } 561 // Index. 562 index, err := gen.irTypeConst(old.Index()) 563 if err != nil { 564 return nil, errors.WithStack(err) 565 } 566 expr := constant.NewExtractElement(x, index) 567 if !t.Equal(expr.Typ) { 568 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 569 } 570 return expr, nil 571 } 572 573 // ~~~ [ insertelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 574 575 // irInsertElementExpr translates the AST insertelement constant expression into 576 // an equivalent IR constant expression. 577 func (gen *generator) irInsertElementExpr(t types.Type, old *ast.InsertElementExpr) (*constant.ExprInsertElement, error) { 578 // Vector. 579 x, err := gen.irTypeConst(old.X()) 580 if err != nil { 581 return nil, errors.WithStack(err) 582 } 583 // Element. 584 elem, err := gen.irTypeConst(old.Elem()) 585 if err != nil { 586 return nil, errors.WithStack(err) 587 } 588 // Index. 589 index, err := gen.irTypeConst(old.Index()) 590 if err != nil { 591 return nil, errors.WithStack(err) 592 } 593 expr := constant.NewInsertElement(x, elem, index) 594 if !t.Equal(expr.Typ) { 595 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 596 } 597 return expr, nil 598 } 599 600 // ~~~ [ shufflevector ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 601 602 // irShuffleVectorExpr translates the AST shufflevector constant expression into 603 // an equivalent IR constant expression. 604 func (gen *generator) irShuffleVectorExpr(t types.Type, old *ast.ShuffleVectorExpr) (*constant.ExprShuffleVector, error) { 605 // X vector. 606 x, err := gen.irTypeConst(old.X()) 607 if err != nil { 608 return nil, errors.WithStack(err) 609 } 610 // Y vector. 611 y, err := gen.irTypeConst(old.Y()) 612 if err != nil { 613 return nil, errors.WithStack(err) 614 } 615 // Shuffle mask. 616 mask, err := gen.irTypeConst(old.Mask()) 617 if err != nil { 618 return nil, errors.WithStack(err) 619 } 620 expr := constant.NewShuffleVector(x, y, mask) 621 if !t.Equal(expr.Typ) { 622 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 623 } 624 return expr, nil 625 } 626 627 // --- [ Aggregate expressions ] ----------------------------------------------- 628 629 // ~~~ [ extractvalue ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 630 631 // irExtractValueExpr translates the AST extractvalue constant expression into 632 // an equivalent IR constant expression. 633 func (gen *generator) irExtractValueExpr(t types.Type, old *ast.ExtractValueExpr) (*constant.ExprExtractValue, error) { 634 // Aggregate value. 635 x, err := gen.irTypeConst(old.X()) 636 if err != nil { 637 return nil, errors.WithStack(err) 638 } 639 // Element indices. 640 indices := uintSlice(old.Indices()) 641 expr := constant.NewExtractValue(x, indices...) 642 if !t.Equal(expr.Typ) { 643 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 644 } 645 return expr, nil 646 } 647 648 // ~~~ [ insertvalue ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 649 650 // irInsertValueExpr translates the AST insertvalue constant expression into an 651 // equivalent IR constant expression. 652 func (gen *generator) irInsertValueExpr(t types.Type, old *ast.InsertValueExpr) (*constant.ExprInsertValue, error) { 653 // Aggregate value. 654 x, err := gen.irTypeConst(old.X()) 655 if err != nil { 656 return nil, errors.WithStack(err) 657 } 658 // Element. 659 elem, err := gen.irTypeConst(old.Elem()) 660 if err != nil { 661 return nil, errors.WithStack(err) 662 } 663 // Element indices. 664 indices := uintSlice(old.Indices()) 665 expr := constant.NewInsertValue(x, elem, indices...) 666 if !t.Equal(expr.Typ) { 667 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 668 } 669 return expr, nil 670 } 671 672 // --- [ Memory expressions ] -------------------------------------------------- 673 674 // ~~~ [ getelementptr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 675 676 // irGetElementPtrExpr translates the AST getelementptr constant expression into 677 // an equivalent IR constant expression. 678 func (gen *generator) irGetElementPtrExpr(t types.Type, old *ast.GetElementPtrExpr) (*constant.ExprGetElementPtr, error) { 679 // Element type. 680 elemType, err := gen.irType(old.ElemType()) 681 if err != nil { 682 return nil, errors.WithStack(err) 683 } 684 // Source. 685 src, err := gen.irTypeConst(old.Src()) 686 if err != nil { 687 return nil, errors.WithStack(err) 688 } 689 // Indices. 690 var indices []constant.Constant 691 if oldIndices := old.Indices(); len(oldIndices) > 0 { 692 indices = make([]constant.Constant, len(oldIndices)) 693 for i, oldIndex := range oldIndices { 694 index, err := gen.irGEPIndex(oldIndex) 695 if err != nil { 696 return nil, errors.WithStack(err) 697 } 698 indices[i] = index 699 } 700 } 701 expr := constant.NewGetElementPtr(elemType, src, indices...) 702 // (optional) In-bounds. 703 _, expr.InBounds = old.InBounds() 704 if !elemType.Equal(expr.ElemType) { 705 return nil, errors.Errorf("constant expression element type mismatch; expected %q, got %q", expr.ElemType, elemType) 706 } 707 if !t.Equal(expr.Typ) { 708 return nil, errors.Errorf("constant expression type mismatch of `%v`; expected %q, got %q", expr, expr.Typ, t) 709 } 710 return expr, nil 711 } 712 713 // irGEPIndex translates the AST getelementptr index into an equivalent IR 714 // getelementptr index. 715 func (gen *generator) irGEPIndex(old ast.GEPIndex) (*constant.Index, error) { 716 // Index. 717 idx, err := gen.irTypeConst(old.Index()) 718 if err != nil { 719 return nil, errors.WithStack(err) 720 } 721 index := constant.NewIndex(idx) 722 // (optional) In-range. 723 _, index.InRange = old.InRange() 724 return index, nil 725 } 726 727 // --- [ Conversion expressions ] ---------------------------------------------- 728 729 // ~~~ [ trunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 730 731 // irTruncExpr translates the AST trunc constant expression into an equivalent 732 // IR constant expression. 733 func (gen *generator) irTruncExpr(t types.Type, old *ast.TruncExpr) (*constant.ExprTrunc, error) { 734 // From. 735 from, err := gen.irTypeConst(old.From()) 736 if err != nil { 737 return nil, errors.WithStack(err) 738 } 739 // To. 740 to, err := gen.irType(old.To()) 741 if err != nil { 742 return nil, errors.WithStack(err) 743 } 744 expr := constant.NewTrunc(from, to) 745 if !t.Equal(expr.To) { 746 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 747 } 748 return expr, nil 749 } 750 751 // ~~~ [ zext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 752 753 // irZExtExpr translates the AST zext constant expression into an equivalent IR 754 // constant expression. 755 func (gen *generator) irZExtExpr(t types.Type, old *ast.ZExtExpr) (*constant.ExprZExt, error) { 756 // From. 757 from, err := gen.irTypeConst(old.From()) 758 if err != nil { 759 return nil, errors.WithStack(err) 760 } 761 // To. 762 to, err := gen.irType(old.To()) 763 if err != nil { 764 return nil, errors.WithStack(err) 765 } 766 expr := constant.NewZExt(from, to) 767 if !t.Equal(expr.To) { 768 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 769 } 770 return expr, nil 771 } 772 773 // ~~~ [ sext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 774 775 // irSExtExpr translates the AST sext constant expression into an equivalent IR 776 // constant expression. 777 func (gen *generator) irSExtExpr(t types.Type, old *ast.SExtExpr) (*constant.ExprSExt, error) { 778 // From. 779 from, err := gen.irTypeConst(old.From()) 780 if err != nil { 781 return nil, errors.WithStack(err) 782 } 783 // To. 784 to, err := gen.irType(old.To()) 785 if err != nil { 786 return nil, errors.WithStack(err) 787 } 788 expr := constant.NewSExt(from, to) 789 if !t.Equal(expr.To) { 790 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 791 } 792 return expr, nil 793 } 794 795 // ~~~ [ fptrunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 796 797 // irFPTruncExpr translates the AST fptrunc constant expression into an 798 // equivalent IR constant expression. 799 func (gen *generator) irFPTruncExpr(t types.Type, old *ast.FPTruncExpr) (*constant.ExprFPTrunc, error) { 800 // From. 801 from, err := gen.irTypeConst(old.From()) 802 if err != nil { 803 return nil, errors.WithStack(err) 804 } 805 // To. 806 to, err := gen.irType(old.To()) 807 if err != nil { 808 return nil, errors.WithStack(err) 809 } 810 expr := constant.NewFPTrunc(from, to) 811 if !t.Equal(expr.To) { 812 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 813 } 814 return expr, nil 815 } 816 817 // ~~~ [ fpext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 819 // irFPExtExpr translates the AST fpext constant expression into an equivalent 820 // IR constant expression. 821 func (gen *generator) irFPExtExpr(t types.Type, old *ast.FPExtExpr) (*constant.ExprFPExt, error) { 822 // From. 823 from, err := gen.irTypeConst(old.From()) 824 if err != nil { 825 return nil, errors.WithStack(err) 826 } 827 // To. 828 to, err := gen.irType(old.To()) 829 if err != nil { 830 return nil, errors.WithStack(err) 831 } 832 expr := constant.NewFPExt(from, to) 833 if !t.Equal(expr.To) { 834 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 835 } 836 return expr, nil 837 } 838 839 // ~~~ [ fptoui ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 840 841 // irFPToUIExpr translates the AST fptoui constant expression into an equivalent 842 // IR constant expression. 843 func (gen *generator) irFPToUIExpr(t types.Type, old *ast.FPToUIExpr) (*constant.ExprFPToUI, error) { 844 // From. 845 from, err := gen.irTypeConst(old.From()) 846 if err != nil { 847 return nil, errors.WithStack(err) 848 } 849 // To. 850 to, err := gen.irType(old.To()) 851 if err != nil { 852 return nil, errors.WithStack(err) 853 } 854 expr := constant.NewFPToUI(from, to) 855 if !t.Equal(expr.To) { 856 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 857 } 858 return expr, nil 859 } 860 861 // ~~~ [ fptosi ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 863 // irFPToSIExpr translates the AST fptosi constant expression into an equivalent 864 // IR constant expression. 865 func (gen *generator) irFPToSIExpr(t types.Type, old *ast.FPToSIExpr) (*constant.ExprFPToSI, error) { 866 // From. 867 from, err := gen.irTypeConst(old.From()) 868 if err != nil { 869 return nil, errors.WithStack(err) 870 } 871 // To. 872 to, err := gen.irType(old.To()) 873 if err != nil { 874 return nil, errors.WithStack(err) 875 } 876 expr := constant.NewFPToSI(from, to) 877 if !t.Equal(expr.To) { 878 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 879 } 880 return expr, nil 881 } 882 883 // ~~~ [ uitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 885 // irUIToFPExpr translates the AST uitofp constant expression into an equivalent 886 // IR constant expression. 887 func (gen *generator) irUIToFPExpr(t types.Type, old *ast.UIToFPExpr) (*constant.ExprUIToFP, error) { 888 // From. 889 from, err := gen.irTypeConst(old.From()) 890 if err != nil { 891 return nil, errors.WithStack(err) 892 } 893 // To. 894 to, err := gen.irType(old.To()) 895 if err != nil { 896 return nil, errors.WithStack(err) 897 } 898 expr := constant.NewUIToFP(from, to) 899 if !t.Equal(expr.To) { 900 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 901 } 902 return expr, nil 903 } 904 905 // ~~~ [ sitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 906 907 // irSIToFPExpr translates the AST sitofp constant expression into an equivalent 908 // IR constant expression. 909 func (gen *generator) irSIToFPExpr(t types.Type, old *ast.SIToFPExpr) (*constant.ExprSIToFP, error) { 910 // From. 911 from, err := gen.irTypeConst(old.From()) 912 if err != nil { 913 return nil, errors.WithStack(err) 914 } 915 // To. 916 to, err := gen.irType(old.To()) 917 if err != nil { 918 return nil, errors.WithStack(err) 919 } 920 expr := constant.NewSIToFP(from, to) 921 if !t.Equal(expr.To) { 922 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 923 } 924 return expr, nil 925 } 926 927 // ~~~ [ ptrtoint ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 928 929 // irPtrToIntExpr translates the AST ptrtoint constant expression into an 930 // equivalent IR constant expression. 931 func (gen *generator) irPtrToIntExpr(t types.Type, old *ast.PtrToIntExpr) (*constant.ExprPtrToInt, error) { 932 // From. 933 from, err := gen.irTypeConst(old.From()) 934 if err != nil { 935 return nil, errors.WithStack(err) 936 } 937 // To. 938 to, err := gen.irType(old.To()) 939 if err != nil { 940 return nil, errors.WithStack(err) 941 } 942 expr := constant.NewPtrToInt(from, to) 943 if !t.Equal(expr.To) { 944 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 945 } 946 return expr, nil 947 } 948 949 // ~~~ [ inttoptr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 950 951 // irIntToPtrExpr translates the AST inttoptr constant expression into an 952 // equivalent IR constant expression. 953 func (gen *generator) irIntToPtrExpr(t types.Type, old *ast.IntToPtrExpr) (*constant.ExprIntToPtr, error) { 954 // From. 955 from, err := gen.irTypeConst(old.From()) 956 if err != nil { 957 return nil, errors.WithStack(err) 958 } 959 // To. 960 to, err := gen.irType(old.To()) 961 if err != nil { 962 return nil, errors.WithStack(err) 963 } 964 expr := constant.NewIntToPtr(from, to) 965 if !t.Equal(expr.To) { 966 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 967 } 968 return expr, nil 969 } 970 971 // ~~~ [ bitcast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 972 973 // irBitCastExpr translates the AST bitcast constant expression into an 974 // equivalent IR constant expression. 975 func (gen *generator) irBitCastExpr(t types.Type, old *ast.BitCastExpr) (*constant.ExprBitCast, error) { 976 // From. 977 from, err := gen.irTypeConst(old.From()) 978 if err != nil { 979 return nil, errors.WithStack(err) 980 } 981 // To. 982 to, err := gen.irType(old.To()) 983 if err != nil { 984 return nil, errors.WithStack(err) 985 } 986 expr := constant.NewBitCast(from, to) 987 if !t.Equal(expr.To) { 988 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 989 } 990 return expr, nil 991 } 992 993 // ~~~ [ addrspacecast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 994 995 // irAddrSpaceCastExpr translates the AST addrspacecast constant expression into 996 // an equivalent IR constant expression. 997 func (gen *generator) irAddrSpaceCastExpr(t types.Type, old *ast.AddrSpaceCastExpr) (*constant.ExprAddrSpaceCast, error) { 998 // From. 999 from, err := gen.irTypeConst(old.From()) 1000 if err != nil { 1001 return nil, errors.WithStack(err) 1002 } 1003 // To. 1004 to, err := gen.irType(old.To()) 1005 if err != nil { 1006 return nil, errors.WithStack(err) 1007 } 1008 expr := constant.NewAddrSpaceCast(from, to) 1009 if !t.Equal(expr.To) { 1010 return nil, errors.Errorf("constant expression type mismatch; expected %q, got %q", expr.To, t) 1011 } 1012 return expr, nil 1013 } 1014 1015 // --- [ Other expressions ] --------------------------------------------------- 1016 1017 // ~~~ [ icmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1018 1019 // irICmpExpr translates the AST icmp constant expression into an equivalent IR 1020 // constant expression. 1021 func (gen *generator) irICmpExpr(t types.Type, old *ast.ICmpExpr) (*constant.ExprICmp, error) { 1022 // Integer comparison predicate. 1023 pred := asmenum.IPredFromString(old.Pred().Text()) 1024 // X operand. 1025 x, err := gen.irTypeConst(old.X()) 1026 if err != nil { 1027 return nil, errors.WithStack(err) 1028 } 1029 // Y operand. 1030 y, err := gen.irTypeConst(old.Y()) 1031 if err != nil { 1032 return nil, errors.WithStack(err) 1033 } 1034 expr := constant.NewICmp(pred, x, y) 1035 if !t.Equal(expr.Typ) { 1036 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 1037 } 1038 return expr, nil 1039 } 1040 1041 // ~~~ [ fcmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1042 1043 // irFCmpExpr translates the AST fcmp constant expression into an equivalent IR 1044 // constant expression. 1045 func (gen *generator) irFCmpExpr(t types.Type, old *ast.FCmpExpr) (*constant.ExprFCmp, error) { 1046 // Floating-point comparison predicate. 1047 pred := asmenum.FPredFromString(old.Pred().Text()) 1048 // X operand. 1049 x, err := gen.irTypeConst(old.X()) 1050 if err != nil { 1051 return nil, errors.WithStack(err) 1052 } 1053 // Y operand. 1054 y, err := gen.irTypeConst(old.Y()) 1055 if err != nil { 1056 return nil, errors.WithStack(err) 1057 } 1058 expr := constant.NewFCmp(pred, x, y) 1059 if !t.Equal(expr.Typ) { 1060 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 1061 } 1062 return expr, nil 1063 } 1064 1065 // ~~~ [ select ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1066 1067 // irSelectExpr translates the AST select constant expression into an equivalent 1068 // IR constant expression. 1069 func (gen *generator) irSelectExpr(t types.Type, old *ast.SelectExpr) (*constant.ExprSelect, error) { 1070 // Selection condition. 1071 cond, err := gen.irTypeConst(old.Cond()) 1072 if err != nil { 1073 return nil, errors.WithStack(err) 1074 } 1075 // X operand. 1076 x, err := gen.irTypeConst(old.X()) 1077 if err != nil { 1078 return nil, errors.WithStack(err) 1079 } 1080 // Y operand. 1081 y, err := gen.irTypeConst(old.Y()) 1082 if err != nil { 1083 return nil, errors.WithStack(err) 1084 } 1085 expr := constant.NewSelect(cond, x, y) 1086 if !t.Equal(expr.Typ) { 1087 return nil, errors.Errorf("constant expression type mismatch in `%v`; expected %q, got %q", expr, expr.Typ, t) 1088 } 1089 return expr, nil 1090 }