Chromium Code Reviews| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 using namespace Ice; | 51 using namespace Ice; |
| 52 using namespace v8; | 52 using namespace v8; |
| 53 using namespace v8::internal; | 53 using namespace v8::internal; |
| 54 using namespace v8::internal::wasm; | 54 using namespace v8::internal::wasm; |
| 55 using v8::internal::wasm::DecodeWasmModule; | 55 using v8::internal::wasm::DecodeWasmModule; |
| 56 | 56 |
| 57 #undef LOG | 57 #undef LOG |
| 58 #define LOG(Expr) log([&](Ostream & out) { Expr; }) | 58 #define LOG(Expr) log([&](Ostream & out) { Expr; }) |
| 59 | 59 |
| 60 namespace { | 60 namespace { |
| 61 // 64KB | |
| 62 const uint32_t WASM_PAGE_SIZE = 64 << 10; | |
| 61 | 63 |
| 62 std::string toStdString(WasmName Name) { | 64 std::string toStdString(WasmName Name) { |
| 63 return std::string(Name.name, Name.length); | 65 return std::string(Name.name, Name.length); |
| 64 } | 66 } |
| 65 | 67 |
| 66 Ice::Type toIceType(wasm::LocalType Type) { | 68 Ice::Type toIceType(wasm::LocalType Type) { |
| 67 switch (Type) { | 69 switch (Type) { |
| 68 case MachineRepresentation::kNone: | 70 case MachineRepresentation::kNone: |
| 69 llvm::report_fatal_error("kNone type not supported"); | 71 llvm::report_fatal_error("kNone type not supported"); |
| 70 case MachineRepresentation::kBit: | 72 case MachineRepresentation::kBit: |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 return OperandNode(MergedNode); | 307 return OperandNode(MergedNode); |
| 306 } | 308 } |
| 307 Node Phi(wasm::LocalType, uint32_t Count, Node *Vals, Node Control) { | 309 Node Phi(wasm::LocalType, uint32_t Count, Node *Vals, Node Control) { |
| 308 LOG(out << "Phi(" << Count << ", " << Control); | 310 LOG(out << "Phi(" << Count << ", " << Control); |
| 309 for (uint32_t i = 0; i < Count; ++i) { | 311 for (uint32_t i = 0; i < Count; ++i) { |
| 310 LOG(out << ", " << Vals[i]); | 312 LOG(out << ", " << Vals[i]); |
| 311 } | 313 } |
| 312 LOG(out << ") = "); | 314 LOG(out << ") = "); |
| 313 | 315 |
| 314 const auto &InEdges = Control.toCfgNode()->getInEdges(); | 316 const auto &InEdges = Control.toCfgNode()->getInEdges(); |
| 315 assert(Count == InEdges.size()); | 317 //assert(Count == InEdges.size()); |
|
John
2016/04/18 19:15:54
why?
Eric Holk
2016/04/18 20:57:24
This is leftover from one of my ill-fated debuggin
| |
| 316 | 318 |
| 317 assert(Count > 0); | 319 assert(Count > 0); |
| 318 | 320 |
| 319 auto *Dest = makeVariable(Vals[0].toOperand()->getType(), Control); | 321 auto *Dest = makeVariable(Vals[0].toOperand()->getType(), Control); |
| 320 | 322 |
| 321 // Multiply by 10 in case more things get added later. | 323 // Multiply by 10 in case more things get added later. |
| 322 | 324 |
| 323 // TODO(eholk): find a better way besides multiplying by some arbitrary | 325 // TODO(eholk): find a better way besides multiplying by some arbitrary |
| 324 // constant. | 326 // constant. |
| 325 auto *Phi = InstPhi::create(Func, Count * 10, Dest); | 327 auto *Phi = InstPhi::create(Func, Count * 10, Dest); |
| 326 for (uint32_t i = 0; i < Count; ++i) { | 328 for (uint32_t i = 0; i < Count; ++i) { |
| 327 auto *Op = Vals[i].toOperand(); | 329 auto *Op = Vals[i].toOperand(); |
| 328 assert(Op); | 330 assert(Op); |
| 329 Phi->addArgument(Op, InEdges[i]); | 331 Phi->addArgument(Op, InEdges[i]); |
| 330 } | 332 } |
| 331 setDefiningInst(Dest, Phi); | 333 setDefiningInst(Dest, Phi); |
| 332 Control.toCfgNode()->appendInst(Phi); | 334 constexpr bool AllowPhisAnywhere = true; |
|
John
2016/04/18 19:15:54
Why is this needed? It seems weird to me to have a
Eric Holk
2016/04/18 20:57:25
Another relic of a misguided debugging adventure.
| |
| 335 Control.toCfgNode()->appendInst(Phi, AllowPhisAnywhere); | |
| 333 LOG(out << Node(Dest) << "\n"); | 336 LOG(out << Node(Dest) << "\n"); |
| 334 return OperandNode(Dest); | 337 return OperandNode(Dest); |
| 335 } | 338 } |
| 336 Node EffectPhi(uint32_t Count, Node *Effects, Node Control) { | 339 Node EffectPhi(uint32_t Count, Node *Effects, Node Control) { |
| 337 // TODO(eholk): this function is almost certainly wrong. | 340 // TODO(eholk): this function is almost certainly wrong. |
| 338 LOG(out << "EffectPhi(" << Count << ", " << Control << "):\n"); | 341 LOG(out << "EffectPhi(" << Count << ", " << Control << "):\n"); |
| 339 for (uint32_t i = 0; i < Count; ++i) { | 342 for (uint32_t i = 0; i < Count; ++i) { |
| 340 LOG(out << " " << Effects[i] << "\n"); | 343 LOG(out << " " << Effects[i] << "\n"); |
| 341 } | 344 } |
| 342 return OperandNode(nullptr); | 345 return OperandNode(nullptr); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 case kExprI64And: | 462 case kExprI64And: |
| 460 Control()->appendInst( | 463 Control()->appendInst( |
| 461 InstArithmetic::create(Func, InstArithmetic::And, Dest, Left, Right)); | 464 InstArithmetic::create(Func, InstArithmetic::And, Dest, Left, Right)); |
| 462 break; | 465 break; |
| 463 case kExprI32Ne: | 466 case kExprI32Ne: |
| 464 case kExprI64Ne: { | 467 case kExprI64Ne: { |
| 465 auto *TmpDest = makeVariable(IceType_i1); | 468 auto *TmpDest = makeVariable(IceType_i1); |
| 466 Control()->appendInst( | 469 Control()->appendInst( |
| 467 InstIcmp::create(Func, InstIcmp::Ne, TmpDest, Left, Right)); | 470 InstIcmp::create(Func, InstIcmp::Ne, TmpDest, Left, Right)); |
| 468 Control()->appendInst( | 471 Control()->appendInst( |
| 469 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 472 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 470 break; | 473 break; |
| 471 } | 474 } |
| 472 case kExprI32Eq: | 475 case kExprI32Eq: |
| 473 case kExprI64Eq: { | 476 case kExprI64Eq: { |
| 474 auto *TmpDest = makeVariable(IceType_i1); | 477 auto *TmpDest = makeVariable(IceType_i1); |
| 475 Control()->appendInst( | 478 Control()->appendInst( |
| 476 InstIcmp::create(Func, InstIcmp::Eq, TmpDest, Left, Right)); | 479 InstIcmp::create(Func, InstIcmp::Eq, TmpDest, Left, Right)); |
| 477 Control()->appendInst( | 480 Control()->appendInst( |
| 478 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 481 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 479 break; | 482 break; |
| 480 } | 483 } |
| 481 case kExprI32LtS: | 484 case kExprI32LtS: |
| 482 case kExprI64LtS: { | 485 case kExprI64LtS: { |
| 483 auto *TmpDest = makeVariable(IceType_i1); | 486 auto *TmpDest = makeVariable(IceType_i1); |
| 484 Control()->appendInst( | 487 Control()->appendInst( |
| 485 InstIcmp::create(Func, InstIcmp::Slt, TmpDest, Left, Right)); | 488 InstIcmp::create(Func, InstIcmp::Slt, TmpDest, Left, Right)); |
| 486 Control()->appendInst( | 489 Control()->appendInst( |
| 487 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 490 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 488 break; | 491 break; |
| 489 } | 492 } |
| 490 case kExprI32LeS: | 493 case kExprI32LeS: |
| 491 case kExprI64LeS: { | 494 case kExprI64LeS: { |
| 492 auto *TmpDest = makeVariable(IceType_i1); | 495 auto *TmpDest = makeVariable(IceType_i1); |
| 493 Control()->appendInst( | 496 Control()->appendInst( |
| 494 InstIcmp::create(Func, InstIcmp::Sle, TmpDest, Left, Right)); | 497 InstIcmp::create(Func, InstIcmp::Sle, TmpDest, Left, Right)); |
| 495 Control()->appendInst( | 498 Control()->appendInst( |
| 496 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 499 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 497 break; | 500 break; |
| 498 } | 501 } |
| 499 case kExprI32GeU: | 502 case kExprI32GeU: |
| 500 case kExprI64GeU: { | 503 case kExprI64GeU: { |
| 501 auto *TmpDest = makeVariable(IceType_i1); | 504 auto *TmpDest = makeVariable(IceType_i1); |
| 502 Control()->appendInst( | 505 Control()->appendInst( |
| 503 InstIcmp::create(Func, InstIcmp::Uge, TmpDest, Left, Right)); | 506 InstIcmp::create(Func, InstIcmp::Uge, TmpDest, Left, Right)); |
| 504 Control()->appendInst( | 507 Control()->appendInst( |
| 505 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 508 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 506 break; | 509 break; |
| 507 } | 510 } |
| 508 case kExprI32LeU: | 511 case kExprI32LeU: |
| 509 case kExprI64LeU: { | 512 case kExprI64LeU: { |
| 510 auto *TmpDest = makeVariable(IceType_i1); | 513 auto *TmpDest = makeVariable(IceType_i1); |
| 511 Control()->appendInst( | 514 Control()->appendInst( |
| 512 InstIcmp::create(Func, InstIcmp::Ule, TmpDest, Left, Right)); | 515 InstIcmp::create(Func, InstIcmp::Ule, TmpDest, Left, Right)); |
| 513 Control()->appendInst( | 516 Control()->appendInst( |
| 514 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 517 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 515 break; | 518 break; |
| 516 } | 519 } |
| 517 case kExprI32LtU: | 520 case kExprI32LtU: |
| 518 case kExprI64LtU: { | 521 case kExprI64LtU: { |
| 519 auto *TmpDest = makeVariable(IceType_i1); | 522 auto *TmpDest = makeVariable(IceType_i1); |
| 520 Control()->appendInst( | 523 Control()->appendInst( |
| 521 InstIcmp::create(Func, InstIcmp::Ult, TmpDest, Left, Right)); | 524 InstIcmp::create(Func, InstIcmp::Ult, TmpDest, Left, Right)); |
| 522 Control()->appendInst( | 525 Control()->appendInst( |
| 523 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 526 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 524 break; | 527 break; |
| 525 } | 528 } |
| 526 case kExprI32GeS: | 529 case kExprI32GeS: |
| 527 case kExprI64GeS: { | 530 case kExprI64GeS: { |
| 528 auto *TmpDest = makeVariable(IceType_i1); | 531 auto *TmpDest = makeVariable(IceType_i1); |
| 529 Control()->appendInst( | 532 Control()->appendInst( |
| 530 InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right)); | 533 InstIcmp::create(Func, InstIcmp::Sge, TmpDest, Left, Right)); |
| 531 Control()->appendInst( | 534 Control()->appendInst( |
| 532 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 535 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 533 } | 536 } |
| 534 case kExprI32GtS: | 537 case kExprI32GtS: |
| 535 case kExprI64GtS: { | 538 case kExprI64GtS: { |
| 536 auto *TmpDest = makeVariable(IceType_i1); | 539 auto *TmpDest = makeVariable(IceType_i1); |
| 537 Control()->appendInst( | 540 Control()->appendInst( |
| 538 InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right)); | 541 InstIcmp::create(Func, InstIcmp::Sgt, TmpDest, Left, Right)); |
| 539 Control()->appendInst( | 542 Control()->appendInst( |
| 540 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 543 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 541 break; | 544 break; |
| 542 } | 545 } |
| 543 case kExprI32GtU: | 546 case kExprI32GtU: |
| 544 case kExprI64GtU: { | 547 case kExprI64GtU: { |
| 545 auto *TmpDest = makeVariable(IceType_i1); | 548 auto *TmpDest = makeVariable(IceType_i1); |
| 546 Control()->appendInst( | 549 Control()->appendInst( |
| 547 InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right)); | 550 InstIcmp::create(Func, InstIcmp::Ugt, TmpDest, Left, Right)); |
| 548 Control()->appendInst( | 551 Control()->appendInst( |
| 549 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 552 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 550 break; | 553 break; |
| 551 } | 554 } |
| 552 case kExprF32Ne: | 555 case kExprF32Ne: |
| 553 case kExprF64Ne: { | 556 case kExprF64Ne: { |
| 554 auto *TmpDest = makeVariable(IceType_i1); | 557 auto *TmpDest = makeVariable(IceType_i1); |
| 555 Control()->appendInst( | 558 Control()->appendInst( |
| 556 InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right)); | 559 InstFcmp::create(Func, InstFcmp::Une, TmpDest, Left, Right)); |
| 557 Control()->appendInst( | 560 Control()->appendInst( |
| 558 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 561 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 559 break; | 562 break; |
| 560 } | 563 } |
| 561 case kExprF32Le: | 564 case kExprF32Le: |
| 562 case kExprF64Le: { | 565 case kExprF64Le: { |
| 563 auto *TmpDest = makeVariable(IceType_i1); | 566 auto *TmpDest = makeVariable(IceType_i1); |
| 564 Control()->appendInst( | 567 Control()->appendInst( |
| 565 InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right)); | 568 InstFcmp::create(Func, InstFcmp::Ule, TmpDest, Left, Right)); |
| 566 Control()->appendInst( | 569 Control()->appendInst( |
| 567 InstCast::create(Func, InstCast::Sext, Dest, TmpDest)); | 570 InstCast::create(Func, InstCast::Zext, Dest, TmpDest)); |
| 568 break; | 571 break; |
| 569 } | 572 } |
| 570 default: | 573 default: |
| 571 LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); | 574 LOG(out << "Unknown binop: " << WasmOpcodes::OpcodeName(Opcode) << "\n"); |
| 572 llvm::report_fatal_error("Uncovered or invalid binop."); | 575 llvm::report_fatal_error("Uncovered or invalid binop."); |
| 573 return OperandNode(nullptr); | 576 return OperandNode(nullptr); |
| 574 } | 577 } |
| 575 LOG(out << Dest << "\n"); | 578 LOG(out << Dest << "\n"); |
| 576 return OperandNode(Dest); | 579 return OperandNode(Dest); |
| 577 } | 580 } |
| 578 Node Unop(wasm::WasmOpcode Opcode, Node Input) { | 581 Node Unop(wasm::WasmOpcode Opcode, Node Input) { |
| 579 LOG(out << "Unop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Input | 582 LOG(out << "Unop(" << WasmOpcodes::OpcodeName(Opcode) << ", " << Input |
| 580 << ") = "); | 583 << ") = "); |
| 581 Ice::Variable *Dest = nullptr; | 584 Ice::Variable *Dest = nullptr; |
| 582 switch (Opcode) { | 585 switch (Opcode) { |
| 583 case kExprI32Eqz: { | 586 case kExprI32Eqz: { |
| 584 Dest = makeVariable(IceType_i32); | 587 Dest = makeVariable(IceType_i32); |
| 585 auto *Tmp = makeVariable(IceType_i1); | 588 auto *Tmp = makeVariable(IceType_i1); |
| 586 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, | 589 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, |
| 587 Ctx->getConstantInt32(0))); | 590 Ctx->getConstantInt32(0))); |
| 588 Control()->appendInst(InstCast::create(Func, InstCast::Sext, Dest, Tmp)); | 591 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); |
| 592 break; | |
| 593 } | |
| 594 case kExprI64Eqz: { | |
| 595 Dest = makeVariable(IceType_i32); | |
|
John
2016/04/18 19:15:54
i1?
Eric Holk
2016/04/18 20:57:24
Eqz corresponds to the C expression `x == 0`. It's
John
2016/04/18 21:10:01
That (zext followed by truncates) also plague pnac
| |
| 596 auto *Tmp = makeVariable(IceType_i1); | |
| 597 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Eq, Tmp, Input, | |
| 598 Ctx->getConstantInt64(0))); | |
| 599 Control()->appendInst(InstCast::create(Func, InstCast::Zext, Dest, Tmp)); | |
| 589 break; | 600 break; |
| 590 } | 601 } |
| 591 case kExprF32Neg: { | 602 case kExprF32Neg: { |
| 592 Dest = makeVariable(IceType_f32); | 603 Dest = makeVariable(IceType_f32); |
| 593 Control()->appendInst(InstArithmetic::create( | 604 Control()->appendInst(InstArithmetic::create( |
| 594 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantFloat(0), Input)); | 605 Func, InstArithmetic::Fsub, Dest, Ctx->getConstantFloat(0), Input)); |
| 595 break; | 606 break; |
| 596 } | 607 } |
| 597 case kExprF64Neg: { | 608 case kExprF64Neg: { |
| 598 Dest = makeVariable(IceType_f64); | 609 Dest = makeVariable(IceType_f64); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 // save control here because true_node appears to alias control. | 677 // save control here because true_node appears to alias control. |
| 667 auto *Ctrl = Control(); | 678 auto *Ctrl = Control(); |
| 668 | 679 |
| 669 *TrueNode = OperandNode(Func->makeNode()); | 680 *TrueNode = OperandNode(Func->makeNode()); |
| 670 *FalseNode = OperandNode(Func->makeNode()); | 681 *FalseNode = OperandNode(Func->makeNode()); |
| 671 | 682 |
| 672 LOG(out << *TrueNode << ", " << *FalseNode << ")" | 683 LOG(out << *TrueNode << ", " << *FalseNode << ")" |
| 673 << "\n"); | 684 << "\n"); |
| 674 | 685 |
| 675 auto *CondBool = makeVariable(IceType_i1); | 686 auto *CondBool = makeVariable(IceType_i1); |
| 676 Ctrl->appendInst(InstCast::create(Func, InstCast::Trunc, CondBool, Cond)); | 687 Ctrl->appendInst(InstIcmp::create(Func, InstIcmp::Ne, CondBool, Cond, |
| 688 Ctx->getConstantInt32(0))); | |
| 677 | 689 |
| 678 Ctrl->appendInst(InstBr::create(Func, CondBool, *TrueNode, *FalseNode)); | 690 Ctrl->appendInst(InstBr::create(Func, CondBool, *TrueNode, *FalseNode)); |
| 679 return OperandNode(nullptr); | 691 return OperandNode(nullptr); |
| 680 } | 692 } |
| 681 InstSwitch *CurrentSwitch = nullptr; | 693 InstSwitch *CurrentSwitch = nullptr; |
| 682 CfgNode *SwitchNode = nullptr; | 694 CfgNode *SwitchNode = nullptr; |
| 683 SizeT SwitchIndex = 0; | 695 SizeT SwitchIndex = 0; |
| 684 Node Switch(uint32_t Count, Node Key) { | 696 Node Switch(uint32_t Count, Node Key) { |
| 685 LOG(out << "Switch(" << Count << ", " << Key << ")\n"); | 697 LOG(out << "Switch(" << Count << ", " << Key << ")\n"); |
| 686 | 698 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 891 (void)Index; | 903 (void)Index; |
| 892 llvm::report_fatal_error("LoadGlobal"); | 904 llvm::report_fatal_error("LoadGlobal"); |
| 893 } | 905 } |
| 894 Node StoreGlobal(uint32_t Index, Node Val) { | 906 Node StoreGlobal(uint32_t Index, Node Val) { |
| 895 (void)Index; | 907 (void)Index; |
| 896 (void)Val; | 908 (void)Val; |
| 897 llvm::report_fatal_error("StoreGlobal"); | 909 llvm::report_fatal_error("StoreGlobal"); |
| 898 } | 910 } |
| 899 | 911 |
| 900 Operand *sanitizeAddress(Operand *Base, uint32_t Offset) { | 912 Operand *sanitizeAddress(Operand *Base, uint32_t Offset) { |
| 913 SizeT MemSize = Module->module->min_mem_pages * WASM_PAGE_SIZE; | |
| 914 SizeT MemMask = MemSize - 1; | |
| 915 | |
| 916 bool ConstZeroBase = false; | |
| 917 | |
| 901 // first, add the index and the offset together. | 918 // first, add the index and the offset together. |
| 902 if (0 != Offset) { | 919 if (auto *ConstBase = llvm::dyn_cast<ConstantInteger32>(Base)) { |
| 920 uint32_t RealOffset = Offset + ConstBase->getValue(); | |
| 921 RealOffset &= MemMask; | |
| 922 Base = Ctx->getConstantInt32(RealOffset); | |
| 923 ConstZeroBase = (0 == RealOffset); | |
| 924 } else if (0 != Offset) { | |
| 903 auto *Addr = makeVariable(IceType_i32); | 925 auto *Addr = makeVariable(IceType_i32); |
| 904 auto *OffsetConstant = Ctx->getConstantInt32(Offset); | 926 auto *OffsetConstant = Ctx->getConstantInt32(Offset); |
| 905 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add, | 927 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add, |
| 906 Addr, Base, OffsetConstant)); | 928 Addr, Base, OffsetConstant)); |
| 929 | |
| 907 Base = Addr; | 930 Base = Addr; |
| 908 } | 931 } |
| 909 | 932 |
| 910 SizeT MemSize = Module->module->min_mem_pages * (16 << 10); | 933 if (!llvm::dyn_cast<ConstantInteger32>(Base)) { |
| 911 auto *WrappedAddr = makeVariable(IceType_i32); | 934 auto ClampedAddr = makeVariable(IceType_i32); |
|
John
2016/04/18 19:15:54
auto *
Also, maybe you should use
Ice::getPointe
Eric Holk
2016/04/18 20:57:24
Done.
I switch to Ice::getPointerType here and in
| |
| 912 Control()->appendInst( | 935 Control()->appendInst( |
| 913 InstArithmetic::create(Func, InstArithmetic::Add, WrappedAddr, Base, | 936 InstArithmetic::create(Func, InstArithmetic::And, ClampedAddr, Base, |
| 914 Ctx->getConstantInt32(MemSize))); | 937 Ctx->getConstantInt32(MemSize - 1))); |
| 938 Base = ClampedAddr; | |
| 939 } | |
| 915 | 940 |
| 916 auto ClampedAddr = makeVariable(IceType_i32); | 941 Ice::Operand *RealAddr = nullptr; |
| 917 Control()->appendInst( | 942 auto MemBase = Ctx->getConstantSym(0, Ctx->getGlobalString("WASM_MEMORY")); |
| 918 InstArithmetic::create(Func, InstArithmetic::And, ClampedAddr, Base, | 943 if (!ConstZeroBase) { |
| 919 Ctx->getConstantInt32(MemSize - 1))); | 944 auto RealAddrV = Func->makeVariable(IceType_i32); |
| 945 Control()->appendInst(InstArithmetic::create( | |
| 946 Func, InstArithmetic::Add, RealAddrV, Base, MemBase)); | |
| 920 | 947 |
| 921 auto RealAddr = Func->makeVariable(IceType_i32); | 948 RealAddr = RealAddrV; |
| 922 auto MemBase = Ctx->getConstantSym(0, Ctx->getGlobalString("WASM_MEMORY")); | 949 } else { |
| 923 Control()->appendInst(InstArithmetic::create( | 950 RealAddr = MemBase; |
| 924 Func, InstArithmetic::Add, RealAddr, ClampedAddr, MemBase)); | 951 } |
| 925 return RealAddr; | 952 return RealAddr; |
| 926 } | 953 } |
| 927 | 954 |
| 928 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index, | 955 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index, |
| 929 uint32_t Offset) { | 956 uint32_t Offset) { |
| 930 LOG(out << "LoadMem(" << Index << "[" << Offset << "]) = "); | 957 LOG(out << "LoadMem(" << Index << "[" << Offset << "]) = "); |
| 931 | 958 |
| 932 auto *RealAddr = sanitizeAddress(Index, Offset); | 959 auto *RealAddr = sanitizeAddress(Index, Offset); |
| 933 | 960 |
| 934 auto *LoadResult = makeVariable(toIceType(MemType)); | 961 auto *LoadResult = makeVariable(toIceType(MemType)); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1206 // Add the data | 1233 // Add the data |
| 1207 WasmMemory->addInitializer(VariableDeclaration::DataInitializer::create( | 1234 WasmMemory->addInitializer(VariableDeclaration::DataInitializer::create( |
| 1208 Globals.get(), reinterpret_cast<const char *>(Module->module_start) + | 1235 Globals.get(), reinterpret_cast<const char *>(Module->module_start) + |
| 1209 Seg.source_offset, | 1236 Seg.source_offset, |
| 1210 Seg.source_size)); | 1237 Seg.source_size)); |
| 1211 | 1238 |
| 1212 WritePtr += Seg.source_size; | 1239 WritePtr += Seg.source_size; |
| 1213 } | 1240 } |
| 1214 | 1241 |
| 1215 // Pad the rest with zeros | 1242 // Pad the rest with zeros |
| 1216 SizeT DataSize = Module->min_mem_pages * (64 << 10); | 1243 SizeT DataSize = Module->min_mem_pages * WASM_PAGE_SIZE; |
| 1217 if (WritePtr < DataSize) { | 1244 if (WritePtr < DataSize) { |
| 1218 WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create( | 1245 WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create( |
| 1219 Globals.get(), DataSize - WritePtr)); | 1246 Globals.get(), DataSize - WritePtr)); |
| 1220 } | 1247 } |
| 1221 | 1248 |
| 1222 WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create( | |
| 1223 Globals.get(), Module->min_mem_pages * (64 << 10))); | |
| 1224 | |
| 1225 Globals->push_back(WasmMemory); | 1249 Globals->push_back(WasmMemory); |
| 1226 | 1250 |
| 1227 lowerGlobals(std::move(Globals)); | 1251 lowerGlobals(std::move(Globals)); |
| 1228 } | 1252 } |
| 1229 | 1253 |
| 1230 // Translate each function. | 1254 // Translate each function. |
| 1231 for (const auto Fn : Module->functions) { | 1255 for (const auto Fn : Module->functions) { |
| 1232 const auto FnName = getFunctionName(Module, Fn.func_index); | 1256 const auto FnName = getFunctionName(Module, Fn.func_index); |
| 1233 | 1257 |
| 1234 LOG(out << " " << Fn.func_index << ": " << FnName << "..."); | 1258 LOG(out << " " << Fn.func_index << ": " << FnName << "..."); |
| 1235 | 1259 |
| 1236 Body.sig = Fn.sig; | 1260 Body.sig = Fn.sig; |
| 1237 Body.base = Buffer.get(); | 1261 Body.base = Buffer.get(); |
| 1238 Body.start = Buffer.get() + Fn.code_start_offset; | 1262 Body.start = Buffer.get() + Fn.code_start_offset; |
| 1239 Body.end = Buffer.get() + Fn.code_end_offset; | 1263 Body.end = Buffer.get() + Fn.code_end_offset; |
| 1240 | 1264 |
| 1241 auto Func = translateFunction(&Zone, Body); | 1265 auto Func = translateFunction(&Zone, Body); |
| 1242 Func->setFunctionName(Ctx->getGlobalString(FnName)); | 1266 Func->setFunctionName(Ctx->getGlobalString(FnName)); |
| 1243 | 1267 |
| 1244 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func))); | 1268 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func))); |
| 1245 LOG(out << "done.\n"); | 1269 LOG(out << "done.\n"); |
| 1246 } | 1270 } |
| 1247 | 1271 |
| 1248 return; | 1272 return; |
| 1249 } | 1273 } |
| 1250 | 1274 |
| 1251 #endif // ALLOW_WASM | 1275 #endif // ALLOW_WASM |
| OLD | NEW |