| OLD | NEW |
| 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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 : InstX8632(Func, InstX8632::Store, 2, NULL) { | 175 : InstX8632(Func, InstX8632::Store, 2, NULL) { |
| 176 addSource(Value); | 176 addSource(Value); |
| 177 addSource(Mem); | 177 addSource(Mem); |
| 178 } | 178 } |
| 179 | 179 |
| 180 InstX8632Mov::InstX8632Mov(Cfg *Func, Variable *Dest, Operand *Source) | 180 InstX8632Mov::InstX8632Mov(Cfg *Func, Variable *Dest, Operand *Source) |
| 181 : InstX8632(Func, InstX8632::Mov, 1, Dest) { | 181 : InstX8632(Func, InstX8632::Mov, 1, Dest) { |
| 182 addSource(Source); | 182 addSource(Source); |
| 183 } | 183 } |
| 184 | 184 |
| 185 InstX8632Movp::InstX8632Movp(Cfg *Func, Variable *Dest, Operand *Source) |
| 186 : InstX8632(Func, InstX8632::Movp, 1, Dest) { |
| 187 addSource(Source); |
| 188 } |
| 189 |
| 185 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 190 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
| 186 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { | 191 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { |
| 187 addSource(Value); | 192 addSource(Value); |
| 188 addSource(Mem); | 193 addSource(Mem); |
| 189 } | 194 } |
| 190 | 195 |
| 191 InstX8632Movq::InstX8632Movq(Cfg *Func, Variable *Dest, Operand *Source) | 196 InstX8632Movq::InstX8632Movq(Cfg *Func, Variable *Dest, Operand *Source) |
| 192 : InstX8632(Func, InstX8632::Movq, 1, Dest) { | 197 : InstX8632(Func, InstX8632::Movq, 1, Dest) { |
| 193 addSource(Source); | 198 addSource(Source); |
| 194 } | 199 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 215 : InstX8632(Func, InstX8632::Pop, 0, Dest) {} | 220 : InstX8632(Func, InstX8632::Pop, 0, Dest) {} |
| 216 | 221 |
| 217 InstX8632Push::InstX8632Push(Cfg *Func, Operand *Source, | 222 InstX8632Push::InstX8632Push(Cfg *Func, Operand *Source, |
| 218 bool SuppressStackAdjustment) | 223 bool SuppressStackAdjustment) |
| 219 : InstX8632(Func, InstX8632::Push, 1, NULL), | 224 : InstX8632(Func, InstX8632::Push, 1, NULL), |
| 220 SuppressStackAdjustment(SuppressStackAdjustment) { | 225 SuppressStackAdjustment(SuppressStackAdjustment) { |
| 221 addSource(Source); | 226 addSource(Source); |
| 222 } | 227 } |
| 223 | 228 |
| 224 bool InstX8632Mov::isRedundantAssign() const { | 229 bool InstX8632Mov::isRedundantAssign() const { |
| 230 // TODO(stichnot): The isRedundantAssign() implementations for |
| 231 // InstX8632Mov, InstX8632Movp, and InstX8632Movq are |
| 232 // identical. Consolidate them. |
| 225 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0)); | 233 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0)); |
| 226 if (Src == NULL) | 234 if (Src == NULL) |
| 227 return false; | 235 return false; |
| 228 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { | 236 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { |
| 229 // TODO: On x86-64, instructions like "mov eax, eax" are used to | 237 // TODO: On x86-64, instructions like "mov eax, eax" are used to |
| 230 // clear the upper 32 bits of rax. We need to recognize and | 238 // clear the upper 32 bits of rax. We need to recognize and |
| 231 // preserve these. | 239 // preserve these. |
| 232 return true; | 240 return true; |
| 233 } | 241 } |
| 234 if (!getDest()->hasReg() && !Src->hasReg() && | 242 if (!getDest()->hasReg() && !Src->hasReg() && |
| 235 Dest->getStackOffset() == Src->getStackOffset()) | 243 Dest->getStackOffset() == Src->getStackOffset()) |
| 236 return true; | 244 return true; |
| 237 return false; | 245 return false; |
| 238 } | 246 } |
| 239 | 247 |
| 248 bool InstX8632Movp::isRedundantAssign() const { |
| 249 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0)); |
| 250 if (Src == NULL) |
| 251 return false; |
| 252 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { |
| 253 return true; |
| 254 } |
| 255 if (!getDest()->hasReg() && !Src->hasReg() && |
| 256 Dest->getStackOffset() == Src->getStackOffset()) |
| 257 return true; |
| 258 return false; |
| 259 } |
| 260 |
| 240 bool InstX8632Movq::isRedundantAssign() const { | 261 bool InstX8632Movq::isRedundantAssign() const { |
| 241 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0)); | 262 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0)); |
| 242 if (Src == NULL) | 263 if (Src == NULL) |
| 243 return false; | 264 return false; |
| 244 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { | 265 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { |
| 245 return true; | 266 return true; |
| 246 } | 267 } |
| 247 if (!getDest()->hasReg() && !Src->hasReg() && | 268 if (!getDest()->hasReg() && !Src->hasReg() && |
| 248 Dest->getStackOffset() == Src->getStackOffset()) | 269 Dest->getStackOffset() == Src->getStackOffset()) |
| 249 return true; | 270 return true; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 | 395 |
| 375 template <> const char *InstX8632Add::Opcode = "add"; | 396 template <> const char *InstX8632Add::Opcode = "add"; |
| 376 template <> const char *InstX8632Adc::Opcode = "adc"; | 397 template <> const char *InstX8632Adc::Opcode = "adc"; |
| 377 template <> const char *InstX8632Addss::Opcode = "addss"; | 398 template <> const char *InstX8632Addss::Opcode = "addss"; |
| 378 template <> const char *InstX8632Sub::Opcode = "sub"; | 399 template <> const char *InstX8632Sub::Opcode = "sub"; |
| 379 template <> const char *InstX8632Subss::Opcode = "subss"; | 400 template <> const char *InstX8632Subss::Opcode = "subss"; |
| 380 template <> const char *InstX8632Sbb::Opcode = "sbb"; | 401 template <> const char *InstX8632Sbb::Opcode = "sbb"; |
| 381 template <> const char *InstX8632And::Opcode = "and"; | 402 template <> const char *InstX8632And::Opcode = "and"; |
| 382 template <> const char *InstX8632Or::Opcode = "or"; | 403 template <> const char *InstX8632Or::Opcode = "or"; |
| 383 template <> const char *InstX8632Xor::Opcode = "xor"; | 404 template <> const char *InstX8632Xor::Opcode = "xor"; |
| 405 template <> const char *InstX8632Pxor::Opcode = "pxor"; |
| 384 template <> const char *InstX8632Imul::Opcode = "imul"; | 406 template <> const char *InstX8632Imul::Opcode = "imul"; |
| 385 template <> const char *InstX8632Mulss::Opcode = "mulss"; | 407 template <> const char *InstX8632Mulss::Opcode = "mulss"; |
| 386 template <> const char *InstX8632Div::Opcode = "div"; | 408 template <> const char *InstX8632Div::Opcode = "div"; |
| 387 template <> const char *InstX8632Idiv::Opcode = "idiv"; | 409 template <> const char *InstX8632Idiv::Opcode = "idiv"; |
| 388 template <> const char *InstX8632Divss::Opcode = "divss"; | 410 template <> const char *InstX8632Divss::Opcode = "divss"; |
| 389 template <> const char *InstX8632Shl::Opcode = "shl"; | 411 template <> const char *InstX8632Shl::Opcode = "shl"; |
| 390 template <> const char *InstX8632Shr::Opcode = "shr"; | 412 template <> const char *InstX8632Shr::Opcode = "shr"; |
| 391 template <> const char *InstX8632Sar::Opcode = "sar"; | 413 template <> const char *InstX8632Sar::Opcode = "sar"; |
| 392 | 414 |
| 393 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 415 template <> void InstX8632Addss::emit(const Cfg *Func) const { |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 } | 708 } |
| 687 | 709 |
| 688 void InstX8632Mov::dump(const Cfg *Func) const { | 710 void InstX8632Mov::dump(const Cfg *Func) const { |
| 689 Ostream &Str = Func->getContext()->getStrDump(); | 711 Ostream &Str = Func->getContext()->getStrDump(); |
| 690 Str << "mov." << getDest()->getType() << " "; | 712 Str << "mov." << getDest()->getType() << " "; |
| 691 dumpDest(Func); | 713 dumpDest(Func); |
| 692 Str << ", "; | 714 Str << ", "; |
| 693 dumpSources(Func); | 715 dumpSources(Func); |
| 694 } | 716 } |
| 695 | 717 |
| 718 void InstX8632Movp::emit(const Cfg *Func) const { |
| 719 // TODO(wala,stichnot): movups works with all vector operands, but |
| 720 // there exist other instructions (movaps, movdqa, movdqu) that may |
| 721 // perform better, depending on the data type and alignment of the |
| 722 // operands. |
| 723 Ostream &Str = Func->getContext()->getStrEmit(); |
| 724 assert(getSrcSize() == 1); |
| 725 Str << "\tmovups\t"; |
| 726 getDest()->emit(Func); |
| 727 Str << ", "; |
| 728 getSrc(0)->emit(Func); |
| 729 Str << "\n"; |
| 730 } |
| 731 |
| 696 void InstX8632Movq::emit(const Cfg *Func) const { | 732 void InstX8632Movq::emit(const Cfg *Func) const { |
| 697 Ostream &Str = Func->getContext()->getStrEmit(); | 733 Ostream &Str = Func->getContext()->getStrEmit(); |
| 698 assert(getSrcSize() == 1); | 734 assert(getSrcSize() == 1); |
| 699 assert(getDest()->getType() == IceType_i64 || | 735 assert(getDest()->getType() == IceType_i64 || |
| 700 getDest()->getType() == IceType_f64); | 736 getDest()->getType() == IceType_f64); |
| 701 Str << "\tmovq\t"; | 737 Str << "\tmovq\t"; |
| 702 getDest()->emit(Func); | 738 getDest()->emit(Func); |
| 703 Str << ", "; | 739 Str << ", "; |
| 704 getSrc(0)->emit(Func); | 740 getSrc(0)->emit(Func); |
| 705 Str << "\n"; | 741 Str << "\n"; |
| 706 } | 742 } |
| 707 | 743 |
| 744 void InstX8632Movp::dump(const Cfg *Func) const { |
| 745 Ostream &Str = Func->getContext()->getStrDump(); |
| 746 Str << "movups." << getDest()->getType() << " "; |
| 747 dumpDest(Func); |
| 748 Str << ", "; |
| 749 dumpSources(Func); |
| 750 } |
| 751 |
| 708 void InstX8632Movq::dump(const Cfg *Func) const { | 752 void InstX8632Movq::dump(const Cfg *Func) const { |
| 709 Ostream &Str = Func->getContext()->getStrDump(); | 753 Ostream &Str = Func->getContext()->getStrDump(); |
| 710 Str << "movq." << getDest()->getType() << " "; | 754 Str << "movq." << getDest()->getType() << " "; |
| 711 dumpDest(Func); | 755 dumpDest(Func); |
| 712 Str << ", "; | 756 Str << ", "; |
| 713 dumpSources(Func); | 757 dumpSources(Func); |
| 714 } | 758 } |
| 715 | 759 |
| 716 void InstX8632Movsx::emit(const Cfg *Func) const { | 760 void InstX8632Movsx::emit(const Cfg *Func) const { |
| 717 Ostream &Str = Func->getContext()->getStrEmit(); | 761 Ostream &Str = Func->getContext()->getStrEmit(); |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 default: | 1068 default: |
| 1025 Str << "???"; | 1069 Str << "???"; |
| 1026 break; | 1070 break; |
| 1027 } | 1071 } |
| 1028 Str << "("; | 1072 Str << "("; |
| 1029 Var->dump(Func); | 1073 Var->dump(Func); |
| 1030 Str << ")"; | 1074 Str << ")"; |
| 1031 } | 1075 } |
| 1032 | 1076 |
| 1033 } // end of namespace Ice | 1077 } // end of namespace Ice |
| OLD | NEW |