OLD | NEW |
1 //===- subzero/src/WasmTranslator.cpp - WASM to Subzero Translation -------===// | 1 //===- subzero/src/WasmTranslator.cpp - WASM to Subzero Translation -------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 case kExprI32LtS: | 222 case kExprI32LtS: |
223 case kExprI64LtS: | 223 case kExprI64LtS: |
224 case kExprI32LtU: | 224 case kExprI32LtU: |
225 case kExprI64LtU: | 225 case kExprI64LtU: |
226 case kExprI32GeS: | 226 case kExprI32GeS: |
227 case kExprI64GeS: | 227 case kExprI64GeS: |
228 case kExprI32GtS: | 228 case kExprI32GtS: |
229 case kExprI64GtS: | 229 case kExprI64GtS: |
230 case kExprI32GtU: | 230 case kExprI32GtU: |
231 case kExprI64GtU: | 231 case kExprI64GtU: |
| 232 case kExprF32Eq: |
| 233 case kExprF64Eq: |
232 case kExprF32Ne: | 234 case kExprF32Ne: |
233 case kExprF64Ne: | 235 case kExprF64Ne: |
234 case kExprF32Le: | 236 case kExprF32Le: |
235 case kExprF64Le: | 237 case kExprF64Le: |
| 238 case kExprF32Lt: |
| 239 case kExprF64Lt: |
| 240 case kExprF32Ge: |
| 241 case kExprF64Ge: |
| 242 case kExprF32Gt: |
| 243 case kExprF64Gt: |
236 case kExprI32LeS: | 244 case kExprI32LeS: |
237 case kExprI64LeS: | 245 case kExprI64LeS: |
238 case kExprI32GeU: | 246 case kExprI32GeU: |
239 case kExprI64GeU: | 247 case kExprI64GeU: |
240 case kExprI32LeU: | 248 case kExprI32LeU: |
241 case kExprI64LeU: | 249 case kExprI64LeU: |
242 return true; | 250 return true; |
243 default: | 251 default: |
244 return false; | 252 return false; |
245 } | 253 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 assert(Count == InEdges.size()); | 325 assert(Count == InEdges.size()); |
318 | 326 |
319 assert(Count > 0); | 327 assert(Count > 0); |
320 | 328 |
321 auto *Dest = makeVariable(Vals[0].toOperand()->getType(), Control); | 329 auto *Dest = makeVariable(Vals[0].toOperand()->getType(), Control); |
322 | 330 |
323 // Multiply by 10 in case more things get added later. | 331 // Multiply by 10 in case more things get added later. |
324 | 332 |
325 // TODO(eholk): find a better way besides multiplying by some arbitrary | 333 // TODO(eholk): find a better way besides multiplying by some arbitrary |
326 // constant. | 334 // constant. |
327 auto *Phi = InstPhi::create(Func, Count * 10, Dest); | 335 auto *Phi = InstPhi::create(Func, Count * 200, Dest); |
328 for (uint32_t i = 0; i < Count; ++i) { | 336 for (uint32_t i = 0; i < Count; ++i) { |
329 auto *Op = Vals[i].toOperand(); | 337 auto *Op = Vals[i].toOperand(); |
330 assert(Op); | 338 assert(Op); |
331 Phi->addArgument(Op, InEdges[i]); | 339 Phi->addArgument(Op, InEdges[i]); |
332 } | 340 } |
333 setDefiningInst(Dest, Phi); | 341 setDefiningInst(Dest, Phi); |
334 Control.toCfgNode()->appendInst(Phi); | 342 Control.toCfgNode()->appendInst(Phi); |
335 LOG(out << Node(Dest) << "\n"); | 343 LOG(out << Node(Dest) << "\n"); |
336 return OperandNode(Dest); | 344 return OperandNode(Dest); |
337 } | 345 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 case kExprF32Add: | 394 case kExprF32Add: |
387 case kExprF64Add: | 395 case kExprF64Add: |
388 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fadd, | 396 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fadd, |
389 Dest, Left, Right)); | 397 Dest, Left, Right)); |
390 break; | 398 break; |
391 case kExprI32Sub: | 399 case kExprI32Sub: |
392 case kExprI64Sub: | 400 case kExprI64Sub: |
393 Control()->appendInst( | 401 Control()->appendInst( |
394 InstArithmetic::create(Func, InstArithmetic::Sub, Dest, Left, Right)); | 402 InstArithmetic::create(Func, InstArithmetic::Sub, Dest, Left, Right)); |
395 break; | 403 break; |
| 404 case kExprF32Sub: |
| 405 case kExprF64Sub: |
| 406 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fsub, |
| 407 Dest, Left, Right)); |
| 408 break; |
396 case kExprI32Mul: | 409 case kExprI32Mul: |
397 case kExprI64Mul: | 410 case kExprI64Mul: |
398 Control()->appendInst( | 411 Control()->appendInst( |
399 InstArithmetic::create(Func, InstArithmetic::Mul, Dest, Left, Right)); | 412 InstArithmetic::create(Func, InstArithmetic::Mul, Dest, Left, Right)); |
400 break; | 413 break; |
| 414 case kExprF32Mul: |
| 415 case kExprF64Mul: |
| 416 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fmul, |
| 417 Dest, Left, Right)); |
| 418 break; |
| 419 case kExprI32DivS: |
| 420 case kExprI64DivS: |
| 421 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Sdiv, |
| 422 Dest, Left, Right)); |
| 423 break; |
401 case kExprI32DivU: | 424 case kExprI32DivU: |
402 case kExprI64DivU: | 425 case kExprI64DivU: |
403 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Udiv, | 426 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Udiv, |
404 Dest, Left, Right)); | 427 Dest, Left, Right)); |
405 break; | 428 break; |
| 429 case kExprF32Div: |
| 430 case kExprF64Div: |
| 431 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Fdiv, |
| 432 Dest, Left, Right)); |
| 433 break; |
406 case kExprI32RemU: | 434 case kExprI32RemU: |
407 case kExprI64RemU: | 435 case kExprI64RemU: |
408 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Urem, | 436 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Urem, |
409 Dest, Left, Right)); | 437 Dest, Left, Right)); |
410 break; | 438 break; |
411 case kExprI32RemS: | 439 case kExprI32RemS: |
412 case kExprI64RemS: | 440 case kExprI64RemS: |
413 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Srem, | 441 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Srem, |
414 Dest, Left, Right)); | 442 Dest, Left, Right)); |
415 break; | 443 break; |
416 case kExprI32Ior: | 444 case kExprI32Ior: |
417 case kExprI64Ior: | 445 case kExprI64Ior: |
418 Control()->appendInst( | 446 Control()->appendInst( |
419 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Left, Right)); | 447 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Left, Right)); |
420 break; | 448 break; |
421 case kExprI32Xor: | 449 case kExprI32Xor: |
422 case kExprI64Xor: | 450 case kExprI64Xor: |
423 Control()->appendInst( | 451 Control()->appendInst( |
424 InstArithmetic::create(Func, InstArithmetic::Xor, Dest, Left, Right)); | 452 InstArithmetic::create(Func, InstArithmetic::Xor, Dest, Left, Right)); |
425 break; | 453 break; |
426 case kExprI32Shl: | 454 case kExprI32Shl: |
427 case kExprI64Shl: | 455 case kExprI64Shl: |
428 Control()->appendInst( | 456 Control()->appendInst( |
429 InstArithmetic::create(Func, InstArithmetic::Shl, Dest, Left, Right)); | 457 InstArithmetic::create(Func, InstArithmetic::Shl, Dest, Left, Right)); |
430 break; | 458 break; |
431 case kExprI32Rol: { | 459 case kExprI32Rol: |
| 460 case kExprI64Rol: { |
432 // TODO(eholk): add rotate as an ICE instruction to make it easier to take | 461 // TODO(eholk): add rotate as an ICE instruction to make it easier to take |
433 // advantage of hardware support. | 462 // advantage of hardware support. |
434 | 463 |
435 // TODO(eholk): don't hardcode so many numbers. | 464 const auto DestTy = Left.toOperand()->getType(); |
436 auto *Masked = makeVariable(IceType_i32); | 465 const SizeT BitCount = typeWidthInBytes(DestTy) * 8; |
437 auto *Bottom = makeVariable(IceType_i32); | 466 |
438 auto *Top = makeVariable(IceType_i32); | 467 auto *Masked = makeVariable(DestTy); |
439 Control()->appendInst(InstArithmetic::create( | 468 auto *Bottom = makeVariable(DestTy); |
440 Func, InstArithmetic::And, Masked, Right, Ctx->getConstantInt32(31))); | 469 auto *Top = makeVariable(DestTy); |
| 470 Control()->appendInst( |
| 471 InstArithmetic::create(Func, InstArithmetic::And, Masked, Right, |
| 472 Ctx->getConstantInt(DestTy, BitCount - 1))); |
441 Control()->appendInst( | 473 Control()->appendInst( |
442 InstArithmetic::create(Func, InstArithmetic::Shl, Top, Left, Masked)); | 474 InstArithmetic::create(Func, InstArithmetic::Shl, Top, Left, Masked)); |
443 auto *RotShift = makeVariable(IceType_i32); | 475 auto *RotShift = makeVariable(DestTy); |
| 476 Control()->appendInst(InstArithmetic::create( |
| 477 Func, InstArithmetic::Sub, RotShift, |
| 478 Ctx->getConstantInt(DestTy, BitCount), Masked)); |
| 479 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, |
| 480 Bottom, Left, RotShift)); |
444 Control()->appendInst( | 481 Control()->appendInst( |
445 InstArithmetic::create(Func, InstArithmetic::Sub, RotShift, | 482 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom)); |
446 Ctx->getConstantInt32(32), Masked)); | 483 break; |
| 484 } |
| 485 case kExprI32Ror: |
| 486 case kExprI64Ror: { |
| 487 // TODO(eholk): add rotate as an ICE instruction to make it easier to take |
| 488 // advantage of hardware support. |
| 489 |
| 490 const auto DestTy = Left.toOperand()->getType(); |
| 491 const SizeT BitCount = typeWidthInBytes(DestTy) * 8; |
| 492 |
| 493 auto *Masked = makeVariable(DestTy); |
| 494 auto *Bottom = makeVariable(DestTy); |
| 495 auto *Top = makeVariable(DestTy); |
| 496 Control()->appendInst( |
| 497 InstArithmetic::create(Func, InstArithmetic::And, Masked, Right, |
| 498 Ctx->getConstantInt(DestTy, BitCount - 1))); |
447 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, | 499 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, |
448 Bottom, Left, Masked)); | 500 Top, Left, Masked)); |
| 501 auto *RotShift = makeVariable(DestTy); |
| 502 Control()->appendInst(InstArithmetic::create( |
| 503 Func, InstArithmetic::Sub, RotShift, |
| 504 Ctx->getConstantInt(DestTy, BitCount), Masked)); |
| 505 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Shl, |
| 506 Bottom, Left, RotShift)); |
449 Control()->appendInst( | 507 Control()->appendInst( |
450 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom)); | 508 InstArithmetic::create(Func, InstArithmetic::Or, Dest, Top, Bottom)); |
451 break; | 509 break; |
452 } | 510 } |
453 case kExprI32ShrU: | 511 case kExprI32ShrU: |
454 case kExprI64ShrU: | 512 case kExprI64ShrU: |
| 513 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Lshr, |
| 514 Dest, Left, Right)); |
| 515 break; |
455 case kExprI32ShrS: | 516 case kExprI32ShrS: |
456 case kExprI64ShrS: | 517 case kExprI64ShrS: |
457 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Ashr, | 518 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Ashr, |
458 Dest, Left, Right)); | 519 Dest, Left, Right)); |
459 break; | 520 break; |
460 case kExprI32And: | 521 case kExprI32And: |
461 case kExprI64And: | 522 case kExprI64And: |
462 Control()->appendInst( | 523 Control()->appendInst( |
463 InstArithmetic::create(Func, InstArithmetic::And, Dest, Left, Right)); | 524 InstArithmetic::create(Func, InstArithmetic::And, Dest, Left, Right)); |
464 break; | 525 break; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 586 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
526 break; | 587 break; |
527 } | 588 } |
528 case kExprI32GeS: | 589 case kExprI32GeS: |
529 case kExprI64GeS: { | 590 case kExprI64GeS: { |
530 auto *TmpDest = makeVariable(IceType_i1); | 591 auto *TmpDest = makeVariable(IceType_i1); |
531 Control()->appendInst( | 592 Control()->appendInst( |
532 InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right)); | 593 InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right)); |
533 Control()->appendInst( | 594 Control()->appendInst( |
534 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 595 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 596 break; |
535 } | 597 } |
536 case kExprI32GtS: | 598 case kExprI32GtS: |
537 case kExprI64GtS: { | 599 case kExprI64GtS: { |
538 auto *TmpDest = makeVariable(IceType_i1); | 600 auto *TmpDest = makeVariable(IceType_i1); |
539 Control()->appendInst( | 601 Control()->appendInst( |
540 InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right)); | 602 InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right)); |
541 Control()->appendInst( | 603 Control()->appendInst( |
542 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 604 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
543 break; | 605 break; |
544 } | 606 } |
545 case kExprI32GtU: | 607 case kExprI32GtU: |
546 case kExprI64GtU: { | 608 case kExprI64GtU: { |
547 auto *TmpDest = makeVariable(IceType_i1); | 609 auto *TmpDest = makeVariable(IceType_i1); |
548 Control()->appendInst( | 610 Control()->appendInst( |
549 InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right)); | 611 InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right)); |
550 Control()->appendInst( | 612 Control()->appendInst( |
551 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 613 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
552 break; | 614 break; |
553 } | 615 } |
| 616 case kExprF32Eq: |
| 617 case kExprF64Eq: { |
| 618 auto *TmpDest = makeVariable(IceType_i1); |
| 619 Control()->appendInst( |
| 620 InstFcmp::create(Func, InstFcmp::Ueq, TmpDest, Left, Right)); |
| 621 Control()->appendInst( |
| 622 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 623 break; |
| 624 } |
554 case kExprF32Ne: | 625 case kExprF32Ne: |
555 case kExprF64Ne: { | 626 case kExprF64Ne: { |
556 auto *TmpDest = makeVariable(IceType_i1); | 627 auto *TmpDest = makeVariable(IceType_i1); |
557 Control()->appendInst( | 628 Control()->appendInst( |
558 InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right)); | 629 InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right)); |
559 Control()->appendInst( | 630 Control()->appendInst( |
560 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 631 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
561 break; | 632 break; |
562 } | 633 } |
563 case kExprF32Le: | 634 case kExprF32Le: |
564 case kExprF64Le: { | 635 case kExprF64Le: { |
565 auto *TmpDest = makeVariable(IceType_i1); | 636 auto *TmpDest = makeVariable(IceType_i1); |
566 Control()->appendInst( | 637 Control()->appendInst( |
567 InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right)); | 638 InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right)); |
568 Control()->appendInst( | 639 Control()->appendInst( |
569 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); | 640 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
570 break; | 641 break; |
571 } | 642 } |
| 643 case kExprF32Lt: |
| 644 case kExprF64Lt: { |
| 645 auto *TmpDest = makeVariable(IceType_i1); |
| 646 Control()->appendInst( |
| 647 InstFcmp::create(Func, InstFcmp::Ult, TmpDest, Left, Right)); |
| 648 Control()->appendInst( |
| 649 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 650 break; |
| 651 } |
| 652 case kExprF32Ge: |
| 653 case kExprF64Ge: { |
| 654 auto *TmpDest = makeVariable(IceType_i1); |
| 655 Control()->appendInst( |
| 656 InstFcmp::create(Func, InstFcmp::Uge, TmpDest, Left, Right)); |
| 657 Control()->appendInst( |
| 658 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 659 break; |
| 660 } |
| 661 case kExprF32Gt: |
| 662 case kExprF64Gt: { |
| 663 auto *TmpDest = makeVariable(IceType_i1); |
| 664 Control()->appendInst( |
| 665 InstFcmp::create(Func, InstFcmp::Ugt, TmpDest, Left, Right)); |
| 666 Control()->appendInst( |
| 667 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 668 break; |
| 669 } |
572 default: | 670 default: |
573 LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); | 671 LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); |
574 llvm::report_fatal_error("Uncovered or invalid binop."); | 672 llvm::report_fatal_error("Uncovered or invalid binop."); |
575 return OperandNode(nullptr); | 673 return OperandNode(nullptr); |
576 } | 674 } |
577 LOG(out << Dest << "\n"); | 675 LOG(out << Dest << "\n"); |
578 return OperandNode(Dest); | 676 return OperandNode(Dest); |
579 } | 677 } |
580 Node Unop(wasm::WasmOpcode Opcode, Node Input) { | 678 Node Unop(wasm::WasmOpcode Opcode, Node Input) { |
581 LOG(out << "Unop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Input | 679 LOG(out << "Unop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Input |
582 << ") = "); | 680 << ") = "); |
583 Ice::Variable *Dest = nullptr; | 681 Ice::Variable *Dest = nullptr; |
584 switch (Opcode) { | 682 switch (Opcode) { |
585 case kExprI32Eqz: { | 683 case kExprI32Eqz: { |
586 Dest = makeVariable(IceType_i32); | 684 Dest = makeVariable(IceType_i32); |
587 auto *Tmp = makeVariable(IceType_i1); | 685 auto *Tmp = makeVariable(IceType_i1); |
588 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, | 686 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, |
589 Ctx->getConstantInt32(0))); | 687 Ctx->getConstantInt32(0))); |
590 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); | 688 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); |
591 break; | 689 break; |
592 } | 690 } |
593 case kExprI64Eqz: { | 691 case kExprI64Eqz: { |
594 Dest = makeVariable(IceType_i32); | 692 Dest = makeVariable(IceType_i32); |
595 auto *Tmp = makeVariable(IceType_i1); | 693 auto *Tmp = makeVariable(IceType_i1); |
596 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, | 694 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, |
597 Ctx->getConstantInt64(0))); | 695 Ctx->getConstantInt64(0))); |
598 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); | 696 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); |
599 break; | 697 break; |
600 } | 698 } |
| 699 case kExprI32Ctz: { |
| 700 Dest = makeVariable(IceType_i32); |
| 701 const auto FnName = Ctx->getGlobalString("llvm.cttz.i32"); |
| 702 bool BadInstrinsic = false; |
| 703 const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic); |
| 704 assert(!BadInstrinsic); |
| 705 assert(Info); |
| 706 |
| 707 auto *Call = InstIntrinsicCall::create( |
| 708 Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info); |
| 709 Call->addArg(Input); |
| 710 Control()->appendInst(Call); |
| 711 break; |
| 712 } |
601 case kExprF32Neg: { | 713 case kExprF32Neg: { |
602 Dest = makeVariable(IceType_f32); | 714 Dest = makeVariable(IceType_f32); |
603 Control()->appendInst(InstArithmetic::create( | 715 Control()->appendInst(InstArithmetic::create( |
604 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantFloat(0), Input)); | 716 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantFloat(0), Input)); |
605 break; | 717 break; |
606 } | 718 } |
607 case kExprF64Neg: { | 719 case kExprF64Neg: { |
608 Dest = makeVariable(IceType_f64); | 720 Dest = makeVariable(IceType_f64); |
609 Control()->appendInst(InstArithmetic::create( | 721 Control()->appendInst(InstArithmetic::create( |
610 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantDouble(0), Input)); | 722 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantDouble(0), Input)); |
611 break; | 723 break; |
612 } | 724 } |
| 725 case kExprF32Abs: { |
| 726 Dest = makeVariable(IceType_f32); |
| 727 const auto FnName = Ctx->getGlobalString("llvm.fabs.f32"); |
| 728 bool BadInstrinsic = false; |
| 729 const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic); |
| 730 assert(!BadInstrinsic); |
| 731 assert(Info); |
| 732 |
| 733 auto *Call = InstIntrinsicCall::create( |
| 734 Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info); |
| 735 Call->addArg(Input); |
| 736 Control()->appendInst(Call); |
| 737 break; |
| 738 } |
| 739 case kExprF64Abs: { |
| 740 Dest = makeVariable(IceType_f64); |
| 741 const auto FnName = Ctx->getGlobalString("llvm.fabs.f64"); |
| 742 bool BadInstrinsic = false; |
| 743 const auto *Info = Ctx->getIntrinsicsInfo().find(FnName, BadInstrinsic); |
| 744 assert(!BadInstrinsic); |
| 745 assert(Info); |
| 746 |
| 747 auto *Call = InstIntrinsicCall::create( |
| 748 Func, 1, Dest, Ctx->getConstantExternSym(FnName), Info->Info); |
| 749 Call->addArg(Input); |
| 750 Control()->appendInst(Call); |
| 751 break; |
| 752 } |
| 753 case kExprF32Floor: { |
| 754 Dest = makeVariable(IceType_f64); |
| 755 const auto FnName = Ctx->getGlobalString("_ZN3env5floorEf"); |
| 756 constexpr bool HasTailCall = false; |
| 757 |
| 758 auto *Call = InstCall::create( |
| 759 Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall); |
| 760 Call->addArg(Input); |
| 761 Control()->appendInst(Call); |
| 762 break; |
| 763 } |
| 764 case kExprF64Floor: { |
| 765 Dest = makeVariable(IceType_f64); |
| 766 const auto FnName = Ctx->getGlobalString("_ZN3env5floorEd"); |
| 767 constexpr bool HasTailCall = false; |
| 768 |
| 769 auto *Call = InstCall::create( |
| 770 Func, 1, Dest, Ctx->getConstantExternSym(FnName), HasTailCall); |
| 771 Call->addArg(Input); |
| 772 Control()->appendInst(Call); |
| 773 break; |
| 774 } |
613 case kExprI64UConvertI32: | 775 case kExprI64UConvertI32: |
614 Dest = makeVariable(IceType_i64); | 776 Dest = makeVariable(IceType_i64); |
615 Control()->appendInst( | 777 Control()->appendInst( |
616 InstCast::create(Func, InstCast::Zext, Dest, Input)); | 778 InstCast::create(Func, InstCast::Zext, Dest, Input)); |
617 break; | 779 break; |
618 case kExprI64SConvertI32: | 780 case kExprI64SConvertI32: |
619 Dest = makeVariable(IceType_i64); | 781 Dest = makeVariable(IceType_i64); |
620 Control()->appendInst( | 782 Control()->appendInst( |
621 InstCast::create(Func, InstCast::Sext, Dest, Input)); | 783 InstCast::create(Func, InstCast::Sext, Dest, Input)); |
622 break; | 784 break; |
| 785 case kExprI32SConvertF32: |
| 786 Dest = makeVariable(IceType_i32); |
| 787 Control()->appendInst( |
| 788 InstCast::create(Func, InstCast::Fptosi, Dest, Input)); |
| 789 break; |
| 790 case kExprI32UConvertF32: |
| 791 Dest = makeVariable(IceType_i32); |
| 792 Control()->appendInst( |
| 793 InstCast::create(Func, InstCast::Fptoui, Dest, Input)); |
| 794 break; |
| 795 case kExprI32SConvertF64: |
| 796 Dest = makeVariable(IceType_i32); |
| 797 Control()->appendInst( |
| 798 InstCast::create(Func, InstCast::Fptosi, Dest, Input)); |
| 799 break; |
| 800 case kExprI32UConvertF64: |
| 801 Dest = makeVariable(IceType_i32); |
| 802 Control()->appendInst( |
| 803 InstCast::create(Func, InstCast::Fptoui, Dest, Input)); |
| 804 break; |
| 805 case kExprI32ReinterpretF32: |
| 806 Dest = makeVariable(IceType_i32); |
| 807 Control()->appendInst( |
| 808 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 809 break; |
| 810 case kExprI64ReinterpretF64: |
| 811 Dest = makeVariable(IceType_i64); |
| 812 Control()->appendInst( |
| 813 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 814 break; |
| 815 case kExprF64ReinterpretI64: |
| 816 Dest = makeVariable(IceType_f64); |
| 817 Control()->appendInst( |
| 818 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 819 break; |
623 case kExprI32ConvertI64: | 820 case kExprI32ConvertI64: |
624 Dest = makeVariable(IceType_i32); | 821 Dest = makeVariable(IceType_i32); |
625 Control()->appendInst( | 822 Control()->appendInst( |
626 InstCast::create(Func, InstCast::Trunc, Dest, Input)); | 823 InstCast::create(Func, InstCast::Trunc, Dest, Input)); |
627 break; | 824 break; |
628 case kExprF64SConvertI32: | 825 case kExprF64SConvertI32: |
629 Dest = makeVariable(IceType_f64); | 826 Dest = makeVariable(IceType_f64); |
630 Control()->appendInst( | 827 Control()->appendInst( |
631 InstCast::create(Func, InstCast::Sitofp, Dest, Input)); | 828 InstCast::create(Func, InstCast::Sitofp, Dest, Input)); |
632 break; | 829 break; |
| 830 case kExprF64UConvertI32: |
| 831 Dest = makeVariable(IceType_f64); |
| 832 Control()->appendInst( |
| 833 InstCast::create(Func, InstCast::Uitofp, Dest, Input)); |
| 834 break; |
| 835 case kExprF64ConvertF32: |
| 836 Dest = makeVariable(IceType_f64); |
| 837 Control()->appendInst( |
| 838 InstCast::create(Func, InstCast::Fpext, Dest, Input)); |
| 839 break; |
| 840 case kExprF32SConvertI32: |
| 841 Dest = makeVariable(IceType_f32); |
| 842 Control()->appendInst( |
| 843 InstCast::create(Func, InstCast::Sitofp, Dest, Input)); |
| 844 break; |
| 845 case kExprF32UConvertI32: |
| 846 Dest = makeVariable(IceType_f32); |
| 847 Control()->appendInst( |
| 848 InstCast::create(Func, InstCast::Uitofp, Dest, Input)); |
| 849 break; |
| 850 case kExprF32ReinterpretI32: |
| 851 Dest = makeVariable(IceType_f32); |
| 852 Control()->appendInst( |
| 853 InstCast::create(Func, InstCast::Bitcast, Dest, Input)); |
| 854 break; |
| 855 case kExprF32ConvertF64: |
| 856 Dest = makeVariable(IceType_f32); |
| 857 Control()->appendInst( |
| 858 InstCast::create(Func, InstCast::Fptrunc, Dest, Input)); |
| 859 break; |
633 default: | 860 default: |
634 LOG(out << "Unknown unop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); | 861 LOG(out << "Unknown unop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); |
635 llvm::report_fatal_error("Uncovered or invalid unop."); | 862 llvm::report_fatal_error("Uncovered or invalid unop."); |
636 return OperandNode(nullptr); | 863 return OperandNode(nullptr); |
637 } | 864 } |
638 LOG(out << Dest << "\n"); | 865 LOG(out << Dest << "\n"); |
639 return OperandNode(Dest); | 866 return OperandNode(Dest); |
640 } | 867 } |
641 uint32_t InputCount(CfgNode *Node) const { return Node->getInEdges().size(); } | 868 uint32_t InputCount(CfgNode *Node) const { return Node->getInEdges().size(); } |
642 bool IsPhiWithMerge(Node Phi, Node Merge) const { | 869 bool IsPhiWithMerge(Node Phi, Node Merge) const { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 | 1173 |
947 RealAddr = RealAddrV; | 1174 RealAddr = RealAddrV; |
948 } else { | 1175 } else { |
949 RealAddr = MemBase; | 1176 RealAddr = MemBase; |
950 } | 1177 } |
951 return RealAddr; | 1178 return RealAddr; |
952 } | 1179 } |
953 | 1180 |
954 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index, | 1181 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index, |
955 uint32_t Offset) { | 1182 uint32_t Offset) { |
956 LOG(out << "LoadMem(" << Index << "[" << Offset << "]) = "); | 1183 LOG(out << "LoadMem." << toIceType(MemType) << "(" << Index << "[" << Offset |
| 1184 << "]) = "); |
957 | 1185 |
958 auto *RealAddr = sanitizeAddress(Index, Offset); | 1186 auto *RealAddr = sanitizeAddress(Index, Offset); |
959 | 1187 |
960 auto *LoadResult = makeVariable(toIceType(MemType)); | 1188 auto *LoadResult = makeVariable(toIceType(MemType)); |
961 Control()->appendInst(InstLoad::create(Func, LoadResult, RealAddr)); | 1189 Control()->appendInst(InstLoad::create(Func, LoadResult, RealAddr)); |
962 | 1190 |
963 // and cast, if needed | 1191 // and cast, if needed |
964 Ice::Variable *Result = nullptr; | 1192 Ice::Variable *Result = nullptr; |
965 if (toIceType(Type) != toIceType(MemType)) { | 1193 if (toIceType(Type) != toIceType(MemType)) { |
966 auto DestType = toIceType(Type); | 1194 auto DestType = toIceType(Type); |
(...skipping 14 matching lines...) Expand all Loading... |
981 llvm::report_fatal_error("Unsupported type for memory load"); | 1209 llvm::report_fatal_error("Unsupported type for memory load"); |
982 } | 1210 } |
983 } else { | 1211 } else { |
984 Result = LoadResult; | 1212 Result = LoadResult; |
985 } | 1213 } |
986 | 1214 |
987 LOG(out << Result << "\n"); | 1215 LOG(out << Result << "\n"); |
988 return OperandNode(Result); | 1216 return OperandNode(Result); |
989 } | 1217 } |
990 void StoreMem(MachineType Type, Node Index, uint32_t Offset, Node Val) { | 1218 void StoreMem(MachineType Type, Node Index, uint32_t Offset, Node Val) { |
991 LOG(out << "StoreMem(" << Index << "[" << Offset << "] = " << Val << ")" | 1219 LOG(out << "StoreMem." << toIceType(Type) << "(" << Index << "[" << Offset |
| 1220 << "] = " << Val << ")" |
992 << "\n"); | 1221 << "\n"); |
993 | 1222 |
994 auto *RealAddr = sanitizeAddress(Index, Offset); | 1223 auto *RealAddr = sanitizeAddress(Index, Offset); |
995 | 1224 |
996 // cast the value to the right type, if needed | 1225 // cast the value to the right type, if needed |
997 Operand *StoreVal = nullptr; | 1226 Operand *StoreVal = nullptr; |
998 if (toIceType(Type) != Val.toOperand()->getType()) { | 1227 if (toIceType(Type) != Val.toOperand()->getType()) { |
999 auto *LocalStoreVal = makeVariable(toIceType(Type)); | 1228 auto *LocalStoreVal = makeVariable(toIceType(Type)); |
1000 Control()->appendInst( | 1229 Control()->appendInst( |
1001 InstCast::create(Func, InstCast::Trunc, LocalStoreVal, Val)); | 1230 InstCast::create(Func, InstCast::Trunc, LocalStoreVal, Val)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1094 | 1323 |
1095 // We don't always know where the incoming branches are in phi nodes, so this | 1324 // We don't always know where the incoming branches are in phi nodes, so this |
1096 // function finds them. | 1325 // function finds them. |
1097 Func->fixPhiNodes(); | 1326 Func->fixPhiNodes(); |
1098 | 1327 |
1099 Func->computeInOutEdges(); | 1328 Func->computeInOutEdges(); |
1100 | 1329 |
1101 return Func; | 1330 return Func; |
1102 } | 1331 } |
1103 | 1332 |
| 1333 // TODO(eholk): compute the correct buffer size. This uses 256k by default, |
| 1334 // which has been big enough for testing but is not a general solution. |
| 1335 constexpr SizeT BUFFER_SIZE = 256 << 10; |
| 1336 |
1104 WasmTranslator::WasmTranslator(GlobalContext *Ctx) | 1337 WasmTranslator::WasmTranslator(GlobalContext *Ctx) |
1105 : Translator(Ctx), Buffer(new uint8_t[24 << 10]), BufferSize(24 << 10) { | 1338 : Translator(Ctx), Buffer(new uint8_t[BUFFER_SIZE]), |
1106 // TODO(eholk): compute the correct buffer size. This uses 24k by default, | 1339 BufferSize(BUFFER_SIZE) {} |
1107 // which has been big enough for testing but is not a general solution. | |
1108 } | |
1109 | 1340 |
1110 void WasmTranslator::translate( | 1341 void WasmTranslator::translate( |
1111 const std::string &IRFilename, | 1342 const std::string &IRFilename, |
1112 std::unique_ptr<llvm::DataStreamer> InputStream) { | 1343 std::unique_ptr<llvm::DataStreamer> InputStream) { |
1113 LOG(out << "Initializing v8/wasm stuff..." | 1344 LOG(out << "Initializing v8/wasm stuff..." |
1114 << "\n"); | 1345 << "\n"); |
1115 Zone Zone; | 1346 Zone Zone; |
1116 ZoneScope _(&Zone); | 1347 ZoneScope _(&Zone); |
1117 | 1348 |
1118 SizeT BytesRead = InputStream->GetBytes(Buffer.get(), BufferSize); | 1349 SizeT BytesRead = InputStream->GetBytes(Buffer.get(), BufferSize); |
1119 LOG(out << "Read " << BytesRead << " bytes" | 1350 LOG(out << "Read " << BytesRead << " bytes" |
1120 << "\n"); | 1351 << "\n"); |
| 1352 assert(BytesRead < BufferSize); |
1121 | 1353 |
1122 LOG(out << "Decoding module " << IRFilename << "\n"); | 1354 LOG(out << "Decoding module " << IRFilename << "\n"); |
1123 | 1355 |
1124 constexpr v8::internal::Isolate *NoIsolate = nullptr; | 1356 constexpr v8::internal::Isolate *NoIsolate = nullptr; |
1125 auto Result = DecodeWasmModule(NoIsolate, &Zone, Buffer.get(), | 1357 auto Result = DecodeWasmModule(NoIsolate, &Zone, Buffer.get(), |
1126 Buffer.get() + BytesRead, false, kWasmOrigin); | 1358 Buffer.get() + BytesRead, false, kWasmOrigin); |
1127 | 1359 |
1128 auto Module = Result.val; | 1360 auto Module = Result.val; |
1129 | 1361 |
1130 LOG(out << "Module info:" | 1362 LOG(out << "Module info:" |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 Func->setFunctionName(Ctx->getGlobalString(FnName)); | 1497 Func->setFunctionName(Ctx->getGlobalString(FnName)); |
1266 | 1498 |
1267 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func))); | 1499 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func))); |
1268 LOG(out << "done.\n"); | 1500 LOG(out << "done.\n"); |
1269 } | 1501 } |
1270 | 1502 |
1271 return; | 1503 return; |
1272 } | 1504 } |
1273 | 1505 |
1274 #endif // ALLOW_WASM | 1506 #endif // ALLOW_WASM |
OLD | NEW |