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

Side by Side Diff: src/IceInstX8632.cpp

Issue 466733005: Subzero: Factor our commonalities between mov-like instructions. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Comments, round 1 Created 6 years, 4 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') | no next file » | 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 : InstX8632(Func, InstX8632::Mfence, 0, NULL) { 212 : InstX8632(Func, InstX8632::Mfence, 0, NULL) {
213 HasSideEffects = true; 213 HasSideEffects = true;
214 } 214 }
215 215
216 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) 216 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem)
217 : InstX8632(Func, InstX8632::Store, 2, NULL) { 217 : InstX8632(Func, InstX8632::Store, 2, NULL) {
218 addSource(Value); 218 addSource(Value);
219 addSource(Mem); 219 addSource(Mem);
220 } 220 }
221 221
222 InstX8632Mov::InstX8632Mov(Cfg *Func, Variable *Dest, Operand *Source)
223 : InstX8632(Func, InstX8632::Mov, 1, Dest) {
224 addSource(Source);
225 }
226
227 InstX8632Movp::InstX8632Movp(Cfg *Func, Variable *Dest, Operand *Source)
228 : InstX8632(Func, InstX8632::Movp, 1, Dest) {
229 addSource(Source);
230 }
231
232 InstX8632StoreP::InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem) 222 InstX8632StoreP::InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem)
233 : InstX8632(Func, InstX8632::StoreP, 2, NULL) { 223 : InstX8632(Func, InstX8632::StoreP, 2, NULL) {
234 addSource(Value); 224 addSource(Value);
235 addSource(Mem); 225 addSource(Mem);
236 } 226 }
237 227
238 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem) 228 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem)
239 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { 229 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) {
240 addSource(Value); 230 addSource(Value);
241 addSource(Mem); 231 addSource(Mem);
242 } 232 }
243 233
244 InstX8632Movq::InstX8632Movq(Cfg *Func, Variable *Dest, Operand *Source)
245 : InstX8632(Func, InstX8632::Movq, 1, Dest) {
246 addSource(Source);
247 }
248
249 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source) 234 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source)
250 : InstX8632(Func, InstX8632::Movsx, 1, Dest) { 235 : InstX8632(Func, InstX8632::Movsx, 1, Dest) {
251 addSource(Source); 236 addSource(Source);
252 } 237 }
253 238
254 InstX8632Movzx::InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source) 239 InstX8632Movzx::InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source)
255 : InstX8632(Func, InstX8632::Movzx, 1, Dest) { 240 : InstX8632(Func, InstX8632::Movzx, 1, Dest) {
256 addSource(Source); 241 addSource(Source);
257 } 242 }
258 243
259 InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src) 244 InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src)
260 : InstX8632(Func, InstX8632::Fld, 1, NULL) { 245 : InstX8632(Func, InstX8632::Fld, 1, NULL) {
261 addSource(Src); 246 addSource(Src);
262 } 247 }
263 248
264 InstX8632Fstp::InstX8632Fstp(Cfg *Func, Variable *Dest) 249 InstX8632Fstp::InstX8632Fstp(Cfg *Func, Variable *Dest)
265 : InstX8632(Func, InstX8632::Fstp, 0, Dest) {} 250 : InstX8632(Func, InstX8632::Fstp, 0, Dest) {}
266 251
267 InstX8632Pop::InstX8632Pop(Cfg *Func, Variable *Dest) 252 InstX8632Pop::InstX8632Pop(Cfg *Func, Variable *Dest)
268 : InstX8632(Func, InstX8632::Pop, 0, Dest) {} 253 : InstX8632(Func, InstX8632::Pop, 0, Dest) {}
269 254
270 InstX8632Push::InstX8632Push(Cfg *Func, Operand *Source, 255 InstX8632Push::InstX8632Push(Cfg *Func, Operand *Source,
271 bool SuppressStackAdjustment) 256 bool SuppressStackAdjustment)
272 : InstX8632(Func, InstX8632::Push, 1, NULL), 257 : InstX8632(Func, InstX8632::Push, 1, NULL),
273 SuppressStackAdjustment(SuppressStackAdjustment) { 258 SuppressStackAdjustment(SuppressStackAdjustment) {
274 addSource(Source); 259 addSource(Source);
275 } 260 }
276 261
277 bool InstX8632Mov::isRedundantAssign() const {
278 // TODO(stichnot): The isRedundantAssign() implementations for
279 // InstX8632Mov, InstX8632Movp, and InstX8632Movq are
280 // identical. Consolidate them.
281 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0));
282 if (Src == NULL)
283 return false;
284 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) {
285 // TODO: On x86-64, instructions like "mov eax, eax" are used to
286 // clear the upper 32 bits of rax. We need to recognize and
287 // preserve these.
288 return true;
289 }
290 if (!getDest()->hasReg() && !Src->hasReg() &&
291 Dest->getStackOffset() == Src->getStackOffset())
292 return true;
293 return false;
294 }
295
296 bool InstX8632Movp::isRedundantAssign() const {
297 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0));
298 if (Src == NULL)
299 return false;
300 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) {
301 return true;
302 }
303 if (!getDest()->hasReg() && !Src->hasReg() &&
304 Dest->getStackOffset() == Src->getStackOffset())
305 return true;
306 return false;
307 }
308
309 bool InstX8632Movq::isRedundantAssign() const {
310 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0));
311 if (Src == NULL)
312 return false;
313 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) {
314 return true;
315 }
316 if (!getDest()->hasReg() && !Src->hasReg() &&
317 Dest->getStackOffset() == Src->getStackOffset())
318 return true;
319 return false;
320 }
321
322 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) 262 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source)
323 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { 263 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) {
324 if (Source) 264 if (Source)
325 addSource(Source); 265 addSource(Source);
326 } 266 }
327 267
328 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, 268 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source,
329 bool Locked) 269 bool Locked)
330 : InstX8632Lockable(Func, InstX8632::Xadd, 2, 270 : InstX8632Lockable(Func, InstX8632::Xadd, 2,
331 llvm::dyn_cast<Variable>(Dest), Locked) { 271 llvm::dyn_cast<Variable>(Dest), Locked) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) { 379 if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) {
440 Str << "cl"; 380 Str << "cl";
441 EmittedSrc1 = true; 381 EmittedSrc1 = true;
442 } 382 }
443 } 383 }
444 if (!EmittedSrc1) 384 if (!EmittedSrc1)
445 Inst->getSrc(1)->emit(Func); 385 Inst->getSrc(1)->emit(Func);
446 Str << "\n"; 386 Str << "\n";
447 } 387 }
448 388
389 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) {
390 const Variable *Src = llvm::dyn_cast<const Variable>(Source);
391 if (Src == NULL)
392 return false;
393 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) {
394 // TODO: On x86-64, instructions like "mov eax, eax" are used to
395 // clear the upper 32 bits of rax. We need to recognize and
396 // preserve these.
397 return true;
398 }
399 if (!Dest->hasReg() && !Src->hasReg() &&
400 Dest->getStackOffset() == Src->getStackOffset())
401 return true;
402 return false;
403 }
449 404
450 // In-place ops 405 // In-place ops
451 template <> const char *InstX8632Bswap::Opcode = "bswap"; 406 template <> const char *InstX8632Bswap::Opcode = "bswap";
452 template <> const char *InstX8632Neg::Opcode = "neg"; 407 template <> const char *InstX8632Neg::Opcode = "neg";
453 // Unary ops 408 // Unary ops
454 template <> const char *InstX8632Bsf::Opcode = "bsf"; 409 template <> const char *InstX8632Bsf::Opcode = "bsf";
455 template <> const char *InstX8632Bsr::Opcode = "bsr"; 410 template <> const char *InstX8632Bsr::Opcode = "bsr";
456 template <> const char *InstX8632Lea::Opcode = "lea"; 411 template <> const char *InstX8632Lea::Opcode = "lea";
457 template <> const char *InstX8632Movd::Opcode = "movd"; 412 template <> const char *InstX8632Movd::Opcode = "movd";
458 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss"; 413 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss";
459 template <> const char *InstX8632Cbwdq::Opcode = "cbw/cwd/cdq"; 414 template <> const char *InstX8632Cbwdq::Opcode = "cbw/cwd/cdq";
415 // Mov-like ops
416 template <> const char *InstX8632Mov::Opcode = "mov";
417 template <> const char *InstX8632Movp::Opcode = "movups";
418 template <> const char *InstX8632Movq::Opcode = "movq";
460 // Binary ops 419 // Binary ops
461 template <> const char *InstX8632Add::Opcode = "add"; 420 template <> const char *InstX8632Add::Opcode = "add";
462 template <> const char *InstX8632Addps::Opcode = "addps"; 421 template <> const char *InstX8632Addps::Opcode = "addps";
463 template <> const char *InstX8632Adc::Opcode = "adc"; 422 template <> const char *InstX8632Adc::Opcode = "adc";
464 template <> const char *InstX8632Addss::Opcode = "addss"; 423 template <> const char *InstX8632Addss::Opcode = "addss";
465 template <> const char *InstX8632Padd::Opcode = "padd"; 424 template <> const char *InstX8632Padd::Opcode = "padd";
466 template <> const char *InstX8632Sub::Opcode = "sub"; 425 template <> const char *InstX8632Sub::Opcode = "sub";
467 template <> const char *InstX8632Subps::Opcode = "subps"; 426 template <> const char *InstX8632Subps::Opcode = "subps";
468 template <> const char *InstX8632Subss::Opcode = "subss"; 427 template <> const char *InstX8632Subss::Opcode = "subss";
469 template <> const char *InstX8632Sbb::Opcode = "sbb"; 428 template <> const char *InstX8632Sbb::Opcode = "sbb";
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 Type Ty = VSrc0->getType(); 951 Type Ty = VSrc0->getType();
993 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an 952 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
994 // acceptable type. 953 // acceptable type.
995 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); 954 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func);
996 } else { 955 } else {
997 Src0->emit(Func); 956 Src0->emit(Func);
998 } 957 }
999 Str << "\n"; 958 Str << "\n";
1000 } 959 }
1001 960
1002 void InstX8632Mov::emit(const Cfg *Func) const { 961 template <> void InstX8632Mov::emit(const Cfg *Func) const {
1003 Ostream &Str = Func->getContext()->getStrEmit(); 962 Ostream &Str = Func->getContext()->getStrEmit();
1004 assert(getSrcSize() == 1); 963 assert(getSrcSize() == 1);
1005 Operand *Src = getSrc(0); 964 Operand *Src = getSrc(0);
1006 // The llvm-mc assembler using Intel syntax has a bug in which "mov 965 // The llvm-mc assembler using Intel syntax has a bug in which "mov
1007 // reg, RelocatableConstant" does not generate the right instruction 966 // reg, RelocatableConstant" does not generate the right instruction
1008 // with a relocation. To work around, we emit "lea reg, 967 // with a relocation. To work around, we emit "lea reg,
1009 // [RelocatableConstant]". Also, the lowering and legalization is 968 // [RelocatableConstant]". Also, the lowering and legalization is
1010 // changed to allow relocatable constants only in Assign and Call 969 // changed to allow relocatable constants only in Assign and Call
1011 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK 970 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK
1012 // once a proper emitter is used. 971 // once a proper emitter is used.
(...skipping 15 matching lines...) Expand all
1028 // value between a vector and a scalar (which movss is used for). 987 // value between a vector and a scalar (which movss is used for).
1029 // Clean this up. 988 // Clean this up.
1030 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == 989 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) ==
1031 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); 990 Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
1032 getDest()->asType(Src->getType()).emit(Func); 991 getDest()->asType(Src->getType()).emit(Func);
1033 Str << ", "; 992 Str << ", ";
1034 Src->emit(Func); 993 Src->emit(Func);
1035 Str << "\n"; 994 Str << "\n";
1036 } 995 }
1037 996
1038 void InstX8632Mov::dump(const Cfg *Func) const { 997 template <> void InstX8632Movp::emit(const Cfg *Func) const {
1039 Ostream &Str = Func->getContext()->getStrDump();
1040 Str << "mov." << getDest()->getType() << " ";
1041 dumpDest(Func);
1042 Str << ", ";
1043 dumpSources(Func);
1044 }
1045
1046 void InstX8632Movp::emit(const Cfg *Func) const {
1047 // TODO(wala,stichnot): movups works with all vector operands, but 998 // TODO(wala,stichnot): movups works with all vector operands, but
1048 // there exist other instructions (movaps, movdqa, movdqu) that may 999 // there exist other instructions (movaps, movdqa, movdqu) that may
1049 // perform better, depending on the data type and alignment of the 1000 // perform better, depending on the data type and alignment of the
1050 // operands. 1001 // operands.
1051 Ostream &Str = Func->getContext()->getStrEmit(); 1002 Ostream &Str = Func->getContext()->getStrEmit();
1052 assert(getSrcSize() == 1); 1003 assert(getSrcSize() == 1);
1053 Str << "\tmovups\t"; 1004 Str << "\tmovups\t";
1054 getDest()->emit(Func); 1005 getDest()->emit(Func);
1055 Str << ", "; 1006 Str << ", ";
1056 getSrc(0)->emit(Func); 1007 getSrc(0)->emit(Func);
1057 Str << "\n"; 1008 Str << "\n";
1058 } 1009 }
1059 1010
1060 void InstX8632Movp::dump(const Cfg *Func) const { 1011 template <> void InstX8632Movq::emit(const Cfg *Func) const {
1061 Ostream &Str = Func->getContext()->getStrDump();
1062 Str << "movups." << getDest()->getType() << " ";
1063 dumpDest(Func);
1064 Str << ", ";
1065 dumpSources(Func);
1066 }
1067
1068 void InstX8632Movq::emit(const Cfg *Func) const {
1069 Ostream &Str = Func->getContext()->getStrEmit(); 1012 Ostream &Str = Func->getContext()->getStrEmit();
1070 assert(getSrcSize() == 1); 1013 assert(getSrcSize() == 1);
1071 assert(getDest()->getType() == IceType_i64 || 1014 assert(getDest()->getType() == IceType_i64 ||
1072 getDest()->getType() == IceType_f64); 1015 getDest()->getType() == IceType_f64);
1073 Str << "\tmovq\t"; 1016 Str << "\tmovq\t";
1074 getDest()->emit(Func); 1017 getDest()->emit(Func);
1075 Str << ", "; 1018 Str << ", ";
1076 getSrc(0)->emit(Func); 1019 getSrc(0)->emit(Func);
1077 Str << "\n"; 1020 Str << "\n";
1078 } 1021 }
1079 1022
1080 void InstX8632Movq::dump(const Cfg *Func) const {
1081 Ostream &Str = Func->getContext()->getStrDump();
1082 Str << "movq." << getDest()->getType() << " ";
1083 dumpDest(Func);
1084 Str << ", ";
1085 dumpSources(Func);
1086 }
1087
1088 void InstX8632Movsx::emit(const Cfg *Func) const { 1023 void InstX8632Movsx::emit(const Cfg *Func) const {
1089 Ostream &Str = Func->getContext()->getStrEmit(); 1024 Ostream &Str = Func->getContext()->getStrEmit();
1090 assert(getSrcSize() == 1); 1025 assert(getSrcSize() == 1);
1091 Str << "\tmovsx\t"; 1026 Str << "\tmovsx\t";
1092 getDest()->emit(Func); 1027 getDest()->emit(Func);
1093 Str << ", "; 1028 Str << ", ";
1094 getSrc(0)->emit(Func); 1029 getSrc(0)->emit(Func);
1095 Str << "\n"; 1030 Str << "\n";
1096 } 1031 }
1097 1032
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 default: 1445 default:
1511 Str << "???"; 1446 Str << "???";
1512 break; 1447 break;
1513 } 1448 }
1514 Str << "("; 1449 Str << "(";
1515 Var->dump(Func); 1450 Var->dump(Func);
1516 Str << ")"; 1451 Str << ")";
1517 } 1452 }
1518 1453
1519 } // end of namespace Ice 1454 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698