Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: src/IceInstX8632.cpp

Issue 604873003: Handle add, adc, etc., mfence, div, idiv, mul in the assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: rebase Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===//
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 // This file implements the InstX8632 and OperandX8632 classes, 10 // This file implements the InstX8632 and OperandX8632 classes,
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 intptr_t StartPosition) { 338 intptr_t StartPosition) {
339 intptr_t EndPosition = Asm->GetPosition(); 339 intptr_t EndPosition = Asm->GetPosition();
340 intptr_t LastFixupLoc = -1; 340 intptr_t LastFixupLoc = -1;
341 AssemblerFixup *LastFixup = NULL; 341 AssemblerFixup *LastFixup = NULL;
342 if (Asm->GetLatestFixup()) { 342 if (Asm->GetLatestFixup()) {
343 LastFixup = Asm->GetLatestFixup(); 343 LastFixup = Asm->GetLatestFixup();
344 LastFixupLoc = LastFixup->position(); 344 LastFixupLoc = LastFixup->position();
345 } 345 }
346 if (LastFixupLoc < StartPosition) { 346 if (LastFixupLoc < StartPosition) {
347 // The fixup doesn't apply to this current block. 347 // The fixup doesn't apply to this current block.
348 for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) { 348 for (intptr_t i = StartPosition; i < EndPosition; ++i) {
349 Str << "\t.byte " 349 Str << "\t.byte 0x";
350 << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i)) 350 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
351 << "\n"; 351 Str << "\n";
352 } 352 }
353 return; 353 return;
354 } 354 }
355 const intptr_t FixupSize = 4; 355 const intptr_t FixupSize = 4;
356 assert(LastFixupLoc + FixupSize <= EndPosition); 356 assert(LastFixupLoc + FixupSize <= EndPosition);
357 // The fixup does apply to this current block. 357 // The fixup does apply to this current block.
358 for (intptr_t i = 0; i < LastFixupLoc - StartPosition; ++i) { 358 for (intptr_t i = StartPosition; i < LastFixupLoc; ++i) {
359 Str << "\t.byte " 359 Str << "\t.byte 0x";
360 << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i)) 360 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
361 << "\n"; 361 Str << "\n";
362 } 362 }
363 Str << "\t.long " << LastFixup->value()->getName(); 363 Str << "\t.long " << LastFixup->value()->getName();
364 if (LastFixup->value()->getOffset()) { 364 if (LastFixup->value()->getOffset()) {
365 Str << " + " << LastFixup->value()->getOffset(); 365 Str << " + " << LastFixup->value()->getOffset();
366 } 366 }
367 Str << "\n"; 367 Str << "\n";
368 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { 368 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) {
369 Str << "\t.byte " << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(i)) 369 Str << "\t.byte 0x";
370 << "\n"; 370 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
371 Str << "\n";
371 } 372 }
372 } 373 }
373 374
374 } // end of anonymous namespace 375 } // end of anonymous namespace
375 376
376 void InstX8632::dump(const Cfg *Func) const { 377 void InstX8632::dump(const Cfg *Func) const {
377 Ostream &Str = Func->getContext()->getStrDump(); 378 Ostream &Str = Func->getContext()->getStrDump();
378 Str << "[X8632] "; 379 Str << "[X8632] ";
379 Inst::dump(Func); 380 Inst::dump(Func);
380 } 381 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) { 472 if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) {
472 Str << "cl"; 473 Str << "cl";
473 EmittedSrc1 = true; 474 EmittedSrc1 = true;
474 } 475 }
475 } 476 }
476 if (!EmittedSrc1) 477 if (!EmittedSrc1)
477 Inst->getSrc(1)->emit(Func); 478 Inst->getSrc(1)->emit(Func);
478 Str << "\n"; 479 Str << "\n";
479 } 480 }
480 481
481 void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var, 482 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
482 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { 483 const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
483 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 484 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
484 intptr_t StartPosition = Asm->GetPosition(); 485 intptr_t StartPosition = Asm->GetPosition();
485 if (Var->hasReg()) { 486 if (const Variable *Var = llvm::dyn_cast<Variable>(Op)) {
486 // We cheat a little and use GPRRegister even for byte operations. 487 if (Var->hasReg()) {
487 RegX8632::GPRRegister VarReg = 488 // We cheat a little and use GPRRegister even for byte operations.
488 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); 489 RegX8632::GPRRegister VarReg =
489 (Asm->*(Emitter.Reg))(Ty, VarReg); 490 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
491 (Asm->*(Emitter.Reg))(Ty, VarReg);
492 } else {
493 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
494 ->stackVarToAsmOperand(Var));
495 (Asm->*(Emitter.Addr))(Ty, StackAddr);
496 }
497 } else if (const OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) {
498 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
490 } else { 499 } else {
491 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 500 llvm_unreachable("Unexpected operand type");
492 ->stackVarToAsmOperand(Var));
493 (Asm->*(Emitter.Addr))(Ty, StackAddr);
494 } 501 }
495 Ostream &Str = Func->getContext()->getStrEmit(); 502 Ostream &Str = Func->getContext()->getStrEmit();
496 emitIASBytes(Str, Asm, StartPosition); 503 emitIASBytes(Str, Asm, StartPosition);
497 } 504 }
498 505
499 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, 506 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
500 const Operand *Src, 507 const Operand *Src,
501 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { 508 const x86::AssemblerX86::GPREmitterRegOp &Emitter) {
502 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 509 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
503 intptr_t StartPosition = Asm->GetPosition(); 510 intptr_t StartPosition = Asm->GetPosition();
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; 666 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL};
660 template <> 667 template <>
661 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { 668 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = {
662 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; 669 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL};
663 670
664 // Unary XMM ops 671 // Unary XMM ops
665 template <> 672 template <>
666 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = { 673 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = {
667 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL}; 674 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL};
668 675
676 // Binary GPR ops
677 template <>
678 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = {
679 &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add};
680 template <>
681 const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = {
682 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc};
683 template <>
684 const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = {
685 &x86::AssemblerX86::And, &x86::AssemblerX86::And, &x86::AssemblerX86::And};
686 template <>
687 const x86::AssemblerX86::GPREmitterRegOp InstX8632Or::Emitter = {
688 &x86::AssemblerX86::Or, &x86::AssemblerX86::Or, &x86::AssemblerX86::Or};
689 template <>
690 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sbb::Emitter = {
691 &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb};
692 template <>
693 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sub::Emitter = {
694 &x86::AssemblerX86::sub, &x86::AssemblerX86::sub, &x86::AssemblerX86::sub};
695 template <>
696 const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = {
697 &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor};
698
669 // Binary XMM ops 699 // Binary XMM ops
670 template <> 700 template <>
671 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = { 701 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = {
672 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL}; 702 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL};
673 template <> 703 template <>
674 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = { 704 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = {
675 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL}; 705 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL};
676 template <> 706 template <>
677 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = { 707 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = {
678 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL}; 708 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL};
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 } 821 }
792 822
793 template <> void InstX8632Div::emit(const Cfg *Func) const { 823 template <> void InstX8632Div::emit(const Cfg *Func) const {
794 Ostream &Str = Func->getContext()->getStrEmit(); 824 Ostream &Str = Func->getContext()->getStrEmit();
795 assert(getSrcSize() == 3); 825 assert(getSrcSize() == 3);
796 Str << "\t" << Opcode << "\t"; 826 Str << "\t" << Opcode << "\t";
797 getSrc(1)->emit(Func); 827 getSrc(1)->emit(Func);
798 Str << "\n"; 828 Str << "\n";
799 } 829 }
800 830
831 template <> void InstX8632Div::emitIAS(const Cfg *Func) const {
832 assert(getSrcSize() == 3);
833 const Operand *Src = getSrc(1);
834 Type Ty = Src->getType();
835 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
836 &x86::AssemblerX86::div, &x86::AssemblerX86::div};
837 emitIASOpTyGPR(Func, Ty, Src, Emitter);
838 }
839
801 template <> void InstX8632Idiv::emit(const Cfg *Func) const { 840 template <> void InstX8632Idiv::emit(const Cfg *Func) const {
802 Ostream &Str = Func->getContext()->getStrEmit(); 841 Ostream &Str = Func->getContext()->getStrEmit();
803 assert(getSrcSize() == 3); 842 assert(getSrcSize() == 3);
804 Str << "\t" << Opcode << "\t"; 843 Str << "\t" << Opcode << "\t";
805 getSrc(1)->emit(Func); 844 getSrc(1)->emit(Func);
806 Str << "\n"; 845 Str << "\n";
807 } 846 }
808 847
848 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const {
849 assert(getSrcSize() == 3);
850 const Operand *Src = getSrc(1);
851 Type Ty = Src->getType();
852 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
853 &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv};
854 emitIASOpTyGPR(Func, Ty, Src, Emitter);
855 }
809 856
810 namespace { 857 namespace {
811 858
812 // pblendvb and blendvps take xmm0 as a final implicit argument. 859 // pblendvb and blendvps take xmm0 as a final implicit argument.
813 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, 860 void emitVariableBlendInst(const char *Opcode, const Inst *Inst,
814 const Cfg *Func) { 861 const Cfg *Func) {
815 Ostream &Str = Func->getContext()->getStrEmit(); 862 Ostream &Str = Func->getContext()->getStrEmit();
816 assert(Inst->getSrcSize() == 3); 863 assert(Inst->getSrcSize() == 3);
817 assert(llvm::isa<Variable>(Inst->getSrc(2))); 864 assert(llvm::isa<Variable>(Inst->getSrc(2)));
818 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == 865 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 Ostream &Str = Func->getContext()->getStrEmit(); 966 Ostream &Str = Func->getContext()->getStrEmit();
920 assert(getSrcSize() == 2); 967 assert(getSrcSize() == 2);
921 assert(llvm::isa<Variable>(getSrc(0))); 968 assert(llvm::isa<Variable>(getSrc(0)));
922 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 969 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
923 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 970 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
924 Str << "\tmul\t"; 971 Str << "\tmul\t";
925 getSrc(1)->emit(Func); 972 getSrc(1)->emit(Func);
926 Str << "\n"; 973 Str << "\n";
927 } 974 }
928 975
976 void InstX8632Mul::emitIAS(const Cfg *Func) const {
977 assert(getSrcSize() == 2);
978 assert(llvm::isa<Variable>(getSrc(0)));
979 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
980 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
981 const Operand *Src = getSrc(1);
982 Type Ty = Src->getType();
983 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
984 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul};
985 emitIASOpTyGPR(Func, Ty, Src, Emitter);
986 }
987
929 void InstX8632Mul::dump(const Cfg *Func) const { 988 void InstX8632Mul::dump(const Cfg *Func) const {
930 Ostream &Str = Func->getContext()->getStrDump(); 989 Ostream &Str = Func->getContext()->getStrDump();
931 dumpDest(Func); 990 dumpDest(Func);
932 Str << " = mul." << getDest()->getType() << " "; 991 Str << " = mul." << getDest()->getType() << " ";
933 dumpSources(Func); 992 dumpSources(Func);
934 } 993 }
935 994
936 void InstX8632Shld::emit(const Cfg *Func) const { 995 void InstX8632Shld::emit(const Cfg *Func) const {
937 Ostream &Str = Func->getContext()->getStrEmit(); 996 Ostream &Str = Func->getContext()->getStrEmit();
938 assert(getSrcSize() == 3); 997 assert(getSrcSize() == 3);
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 Str << "test." << getSrc(0)->getType() << " "; 1298 Str << "test." << getSrc(0)->getType() << " ";
1240 dumpSources(Func); 1299 dumpSources(Func);
1241 } 1300 }
1242 1301
1243 void InstX8632Mfence::emit(const Cfg *Func) const { 1302 void InstX8632Mfence::emit(const Cfg *Func) const {
1244 Ostream &Str = Func->getContext()->getStrEmit(); 1303 Ostream &Str = Func->getContext()->getStrEmit();
1245 assert(getSrcSize() == 0); 1304 assert(getSrcSize() == 0);
1246 Str << "\tmfence\n"; 1305 Str << "\tmfence\n";
1247 } 1306 }
1248 1307
1308 void InstX8632Mfence::emitIAS(const Cfg *Func) const {
1309 Ostream &Str = Func->getContext()->getStrEmit();
1310 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1311 intptr_t StartPosition = Asm->GetPosition();
1312 Asm->mfence();
1313 emitIASBytes(Str, Asm, StartPosition);
1314 }
1315
1249 void InstX8632Mfence::dump(const Cfg *Func) const { 1316 void InstX8632Mfence::dump(const Cfg *Func) const {
1250 Ostream &Str = Func->getContext()->getStrDump(); 1317 Ostream &Str = Func->getContext()->getStrDump();
1251 Str << "mfence\n"; 1318 Str << "mfence\n";
1252 } 1319 }
1253 1320
1254 void InstX8632Store::emit(const Cfg *Func) const { 1321 void InstX8632Store::emit(const Cfg *Func) const {
1255 Ostream &Str = Func->getContext()->getStrEmit(); 1322 Ostream &Str = Func->getContext()->getStrEmit();
1256 assert(getSrcSize() == 2); 1323 assert(getSrcSize() == 2);
1257 Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString 1324 Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString
1258 << "\t"; 1325 << "\t";
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 void InstX8632AdjustStack::emit(const Cfg *Func) const { 1721 void InstX8632AdjustStack::emit(const Cfg *Func) const {
1655 Ostream &Str = Func->getContext()->getStrEmit(); 1722 Ostream &Str = Func->getContext()->getStrEmit();
1656 Str << "\tsub\tesp, " << Amount << "\n"; 1723 Str << "\tsub\tesp, " << Amount << "\n";
1657 Func->getTarget()->updateStackAdjustment(Amount); 1724 Func->getTarget()->updateStackAdjustment(Amount);
1658 } 1725 }
1659 1726
1660 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { 1727 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
1661 Ostream &Str = Func->getContext()->getStrEmit(); 1728 Ostream &Str = Func->getContext()->getStrEmit();
1662 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1729 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1663 intptr_t StartPosition = Asm->GetPosition(); 1730 intptr_t StartPosition = Asm->GetPosition();
1664 Asm->subl(RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); 1731 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
1665 emitIASBytes(Str, Asm, StartPosition); 1732 emitIASBytes(Str, Asm, StartPosition);
1666 Func->getTarget()->updateStackAdjustment(Amount); 1733 Func->getTarget()->updateStackAdjustment(Amount);
1667 } 1734 }
1668 1735
1669 void InstX8632AdjustStack::dump(const Cfg *Func) const { 1736 void InstX8632AdjustStack::dump(const Cfg *Func) const {
1670 Ostream &Str = Func->getContext()->getStrDump(); 1737 Ostream &Str = Func->getContext()->getStrDump();
1671 Str << "esp = sub.i32 esp, " << Amount; 1738 Str << "esp = sub.i32 esp, " << Amount;
1672 } 1739 }
1673 1740
1674 void InstX8632Push::emit(const Cfg *Func) const { 1741 void InstX8632Push::emit(const Cfg *Func) const {
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 } 2058 }
1992 Str << "("; 2059 Str << "(";
1993 if (Func) 2060 if (Func)
1994 Var->dump(Func); 2061 Var->dump(Func);
1995 else 2062 else
1996 Var->dump(Str); 2063 Var->dump(Str);
1997 Str << ")"; 2064 Str << ")";
1998 } 2065 }
1999 2066
2000 } // end of namespace Ice 2067 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698