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

Side by Side Diff: src/IceInstX8632.cpp

Issue 647223004: emitIAS for movsx and movzx. (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/IceTargetLoweringX8632.cpp » ('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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 addSource(Mem); 280 addSource(Mem);
281 } 281 }
282 282
283 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value, 283 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value,
284 OperandX8632Mem *Mem) 284 OperandX8632Mem *Mem)
285 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { 285 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) {
286 addSource(Value); 286 addSource(Value);
287 addSource(Mem); 287 addSource(Mem);
288 } 288 }
289 289
290 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source)
291 : InstX8632(Func, InstX8632::Movsx, 1, Dest) {
292 addSource(Source);
293 }
294
295 InstX8632Movzx::InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source)
296 : InstX8632(Func, InstX8632::Movzx, 1, Dest) {
297 addSource(Source);
298 }
299
300 InstX8632Nop::InstX8632Nop(Cfg *Func, InstX8632Nop::NopVariant Variant) 290 InstX8632Nop::InstX8632Nop(Cfg *Func, InstX8632Nop::NopVariant Variant)
301 : InstX8632(Func, InstX8632::Nop, 0, NULL), Variant(Variant) {} 291 : InstX8632(Func, InstX8632::Nop, 0, NULL), Variant(Variant) {}
302 292
303 InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src) 293 InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src)
304 : InstX8632(Func, InstX8632::Fld, 1, NULL) { 294 : InstX8632(Func, InstX8632::Fld, 1, NULL) {
305 addSource(Src); 295 addSource(Src);
306 } 296 }
307 297
308 InstX8632Fstp::InstX8632Fstp(Cfg *Func, Variable *Dest) 298 InstX8632Fstp::InstX8632Fstp(Cfg *Func, Variable *Dest)
309 : InstX8632(Func, InstX8632::Fstp, 0, Dest) {} 299 : InstX8632(Func, InstX8632::Fstp, 0, Dest) {}
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 } 499 }
510 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { 500 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) {
511 Mem->emitSegmentOverride(Asm); 501 Mem->emitSegmentOverride(Asm);
512 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); 502 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
513 } else { 503 } else {
514 llvm_unreachable("Unexpected operand type"); 504 llvm_unreachable("Unexpected operand type");
515 } 505 }
516 emitIASBytes(Func, Asm, StartPosition); 506 emitIASBytes(Func, Asm, StartPosition);
517 } 507 }
518 508
509 template <bool VarCanBeByte, bool SrcCanBeByte>
519 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, 510 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
520 const Operand *Src, 511 const Operand *Src,
521 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { 512 const x86::AssemblerX86::GPREmitterRegOp &Emitter) {
522 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 513 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
523 intptr_t StartPosition = Asm->GetPosition(); 514 intptr_t StartPosition = Asm->GetPosition();
524 assert(Var->hasReg()); 515 assert(Var->hasReg());
525 // We cheat a little and use GPRRegister even for byte operations. 516 // We cheat a little and use GPRRegister even for byte operations.
526 RegX8632::GPRRegister VarReg = 517 RegX8632::GPRRegister VarReg =
527 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); 518 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum())
519 : RegX8632::getEncodedGPR(Var->getRegNum());
528 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 520 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
529 if (SrcVar->hasReg()) { 521 if (SrcVar->hasReg()) {
530 RegX8632::GPRRegister SrcReg = 522 RegX8632::GPRRegister SrcReg =
531 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); 523 SrcCanBeByte
524 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum())
525 : RegX8632::getEncodedGPR(SrcVar->getRegNum());
532 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); 526 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
533 } else { 527 } else {
534 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 528 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
535 ->stackVarToAsmOperand(SrcVar); 529 ->stackVarToAsmOperand(SrcVar);
536 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); 530 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
537 } 531 }
538 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 532 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
539 Mem->emitSegmentOverride(Asm); 533 Mem->emitSegmentOverride(Asm);
540 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); 534 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
541 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { 535 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 } 786 }
793 787
794 // In-place ops 788 // In-place ops
795 template <> const char *InstX8632Bswap::Opcode = "bswap"; 789 template <> const char *InstX8632Bswap::Opcode = "bswap";
796 template <> const char *InstX8632Neg::Opcode = "neg"; 790 template <> const char *InstX8632Neg::Opcode = "neg";
797 // Unary ops 791 // Unary ops
798 template <> const char *InstX8632Bsf::Opcode = "bsf"; 792 template <> const char *InstX8632Bsf::Opcode = "bsf";
799 template <> const char *InstX8632Bsr::Opcode = "bsr"; 793 template <> const char *InstX8632Bsr::Opcode = "bsr";
800 template <> const char *InstX8632Lea::Opcode = "lea"; 794 template <> const char *InstX8632Lea::Opcode = "lea";
801 template <> const char *InstX8632Movd::Opcode = "movd"; 795 template <> const char *InstX8632Movd::Opcode = "movd";
796 template <> const char *InstX8632Movsx::Opcode = "movsx";
797 template <> const char *InstX8632Movzx::Opcode = "movzx";
802 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss"; 798 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss";
803 template <> const char *InstX8632Cbwdq::Opcode = "cbw/cwd/cdq"; 799 template <> const char *InstX8632Cbwdq::Opcode = "cbw/cwd/cdq";
804 // Mov-like ops 800 // Mov-like ops
805 template <> const char *InstX8632Mov::Opcode = "mov"; 801 template <> const char *InstX8632Mov::Opcode = "mov";
806 template <> const char *InstX8632Movp::Opcode = "movups"; 802 template <> const char *InstX8632Movp::Opcode = "movups";
807 template <> const char *InstX8632Movq::Opcode = "movq"; 803 template <> const char *InstX8632Movq::Opcode = "movq";
808 // Binary ops 804 // Binary ops
809 template <> const char *InstX8632Add::Opcode = "add"; 805 template <> const char *InstX8632Add::Opcode = "add";
810 template <> const char *InstX8632Addps::Opcode = "addps"; 806 template <> const char *InstX8632Addps::Opcode = "addps";
811 template <> const char *InstX8632Adc::Opcode = "adc"; 807 template <> const char *InstX8632Adc::Opcode = "adc";
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 // Unary GPR ops 858 // Unary GPR ops
863 template <> 859 template <>
864 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = { 860 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = {
865 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; 861 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL};
866 template <> 862 template <>
867 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { 863 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = {
868 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; 864 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL};
869 template <> 865 template <>
870 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { 866 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = {
871 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; 867 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL};
868 template <>
869 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = {
870 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, NULL};
871 template <>
872 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = {
873 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, NULL};
872 874
873 // Unary XMM ops 875 // Unary XMM ops
874 template <> 876 template <>
875 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { 877 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = {
876 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss 878 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss
877 }; 879 };
878 880
879 // Binary GPR ops 881 // Binary GPR ops
880 template <> 882 template <>
881 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { 883 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = {
(...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2110 assert(Dest == getSrc(0)); 2112 assert(Dest == getSrc(0));
2111 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 2113 const Variable *Src = llvm::cast<Variable>(getSrc(1));
2112 assert(Dest->hasReg() && Src->hasReg()); 2114 assert(Dest->hasReg() && Src->hasReg());
2113 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2115 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2114 intptr_t StartPosition = Asm->GetPosition(); 2116 intptr_t StartPosition = Asm->GetPosition();
2115 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), 2117 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()),
2116 RegX8632::getEncodedXmm(Src->getRegNum())); 2118 RegX8632::getEncodedXmm(Src->getRegNum()));
2117 emitIASBytes(Func, Asm, StartPosition); 2119 emitIASBytes(Func, Asm, StartPosition);
2118 } 2120 }
2119 2121
2120 void InstX8632Movsx::emit(const Cfg *Func) const { 2122 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const {
2121 Ostream &Str = Func->getContext()->getStrEmit();
2122 assert(getSrcSize() == 1); 2123 assert(getSrcSize() == 1);
2123 Str << "\tmovsx\t"; 2124 const Variable *Dest = getDest();
2124 getDest()->emit(Func); 2125 const Operand *Src = getSrc(0);
2125 Str << ", "; 2126 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice
2126 getSrc(0)->emit(Func); 2127 // we just use the full register for Dest to avoid having an
2127 Str << "\n"; 2128 // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy.
2129 Type SrcTy = Src->getType();
2130 assert(typeWidthInBytes(Dest->getType()) > 1);
2131 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
2132 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter);
2128 } 2133 }
2129 2134
2130 void InstX8632Movsx::dump(const Cfg *Func) const { 2135 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const {
2131 Ostream &Str = Func->getContext()->getStrDump();
2132 Str << "movsx." << getDest()->getType() << "." << getSrc(0)->getType();
2133 Str << " ";
2134 dumpDest(Func);
2135 Str << ", ";
2136 dumpSources(Func);
2137 }
2138
2139 void InstX8632Movzx::emit(const Cfg *Func) const {
2140 Ostream &Str = Func->getContext()->getStrEmit();
2141 assert(getSrcSize() == 1); 2136 assert(getSrcSize() == 1);
2142 Str << "\tmovzx\t"; 2137 const Variable *Dest = getDest();
2143 getDest()->emit(Func); 2138 const Operand *Src = getSrc(0);
2144 Str << ", "; 2139 Type SrcTy = Src->getType();
2145 getSrc(0)->emit(Func); 2140 assert(typeWidthInBytes(Dest->getType()) > 1);
2146 Str << "\n"; 2141 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
2147 } 2142 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter);
2148
2149 void InstX8632Movzx::dump(const Cfg *Func) const {
2150 Ostream &Str = Func->getContext()->getStrDump();
2151 Str << "movzx." << getDest()->getType() << "." << getSrc(0)->getType();
2152 Str << " ";
2153 dumpDest(Func);
2154 Str << ", ";
2155 dumpSources(Func);
2156 } 2143 }
2157 2144
2158 void InstX8632Nop::emit(const Cfg *Func) const { 2145 void InstX8632Nop::emit(const Cfg *Func) const {
2159 Ostream &Str = Func->getContext()->getStrEmit(); 2146 Ostream &Str = Func->getContext()->getStrEmit();
2160 // TODO: Emit the right code for each variant. 2147 // TODO: Emit the right code for each variant.
2161 Str << "\tnop\t# variant = " << Variant << "\n"; 2148 Str << "\tnop\t# variant = " << Variant << "\n";
2162 } 2149 }
2163 2150
2164 void InstX8632Nop::emitIAS(const Cfg *Func) const { 2151 void InstX8632Nop::emitIAS(const Cfg *Func) const {
2165 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2152 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
2808 } 2795 }
2809 Str << "("; 2796 Str << "(";
2810 if (Func) 2797 if (Func)
2811 Var->dump(Func); 2798 Var->dump(Func);
2812 else 2799 else
2813 Var->dump(Str); 2800 Var->dump(Str);
2814 Str << ")"; 2801 Str << ")";
2815 } 2802 }
2816 2803
2817 } // end of namespace Ice 2804 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698