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

Side by Side Diff: src/IceInstX86Base.h

Issue 1341423002: Reflow comments to use the full width. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix spelling and rebase Created 5 years, 3 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/IceInstX8664.cpp ('k') | src/IceInstX86BaseImpl.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/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===// 1 //===- subzero/src/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===//
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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 IacaStart, 139 IacaStart,
140 IacaEnd 140 IacaEnd
141 }; 141 };
142 142
143 static const char *getWidthString(Type Ty); 143 static const char *getWidthString(Type Ty);
144 static const char *getFldString(Type Ty); 144 static const char *getFldString(Type Ty);
145 static typename Traits::Cond::BrCond 145 static typename Traits::Cond::BrCond
146 getOppositeCondition(typename Traits::Cond::BrCond Cond); 146 getOppositeCondition(typename Traits::Cond::BrCond Cond);
147 void dump(const Cfg *Func) const override; 147 void dump(const Cfg *Func) const override;
148 148
149 // Shared emit routines for common forms of instructions. 149 // Shared emit routines for common forms of instructions. See the definition
150 // See the definition of emitTwoAddress() for a description of 150 // of emitTwoAddress() for a description of ShiftHack.
151 // ShiftHack.
152 static void emitTwoAddress(const char *Opcode, const Inst *Inst, 151 static void emitTwoAddress(const char *Opcode, const Inst *Inst,
153 const Cfg *Func, bool ShiftHack = false); 152 const Cfg *Func, bool ShiftHack = false);
154 153
155 static void 154 static void
156 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 155 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
157 const Operand *Src, 156 const Operand *Src,
158 const typename Traits::Assembler::GPREmitterShiftOp &Emitter); 157 const typename Traits::Assembler::GPREmitterShiftOp &Emitter);
159 158
160 protected: 159 protected:
161 InstX86Base<Machine>(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, 160 InstX86Base<Machine>(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs,
162 Variable *Dest) 161 Variable *Dest)
163 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 162 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
164 163
165 static bool isClassof(const Inst *Inst, InstKindX86 MyKind) { 164 static bool isClassof(const Inst *Inst, InstKindX86 MyKind) {
166 return Inst->getKind() == static_cast<InstKind>(MyKind); 165 return Inst->getKind() == static_cast<InstKind>(MyKind);
167 } 166 }
168 // Most instructions that operate on vector arguments require vector 167 // Most instructions that operate on vector arguments require vector memory
169 // memory operands to be fully aligned (16-byte alignment for PNaCl 168 // operands to be fully aligned (16-byte alignment for PNaCl vector types).
170 // vector types). The stack frame layout and call ABI ensure proper 169 // The stack frame layout and call ABI ensure proper alignment for stack
171 // alignment for stack operands, but memory operands (originating 170 // operands, but memory operands (originating from load/store bitcode
172 // from load/store bitcode instructions) only have element-size 171 // instructions) only have element-size alignment guarantees. This function
173 // alignment guarantees. This function validates that none of the 172 // validates that none of the operands is a memory operand of vector type,
174 // operands is a memory operand of vector type, calling 173 // calling report_fatal_error() if one is found. This function should be
175 // report_fatal_error() if one is found. This function should be 174 // called during emission, and maybe also in the ctor (as long as that fits
176 // called during emission, and maybe also in the ctor (as long as 175 // the lowering style).
177 // that fits the lowering style).
178 void validateVectorAddrMode() const { 176 void validateVectorAddrMode() const {
179 if (this->getDest()) 177 if (this->getDest())
180 this->validateVectorAddrModeOpnd(this->getDest()); 178 this->validateVectorAddrModeOpnd(this->getDest());
181 for (SizeT i = 0; i < this->getSrcSize(); ++i) { 179 for (SizeT i = 0; i < this->getSrcSize(); ++i) {
182 this->validateVectorAddrModeOpnd(this->getSrc(i)); 180 this->validateVectorAddrModeOpnd(this->getSrc(i));
183 } 181 }
184 } 182 }
185 183
186 private: 184 private:
187 static void validateVectorAddrModeOpnd(const Operand *Opnd) { 185 static void validateVectorAddrModeOpnd(const Operand *Opnd) {
188 if (llvm::isa<typename InstX86Base<Machine>::Traits::X86OperandMem>(Opnd) && 186 if (llvm::isa<typename InstX86Base<Machine>::Traits::X86OperandMem>(Opnd) &&
189 isVectorType(Opnd->getType())) { 187 isVectorType(Opnd->getType())) {
190 llvm::report_fatal_error("Possible misaligned vector memory operation"); 188 llvm::report_fatal_error("Possible misaligned vector memory operation");
191 } 189 }
192 } 190 }
193 }; 191 };
194 192
195 /// InstX86FakeRMW represents a non-atomic read-modify-write operation on a 193 /// InstX86FakeRMW represents a non-atomic read-modify-write operation on a
196 /// memory location. An InstX86FakeRMW is a "fake" instruction in that it 194 /// memory location. An InstX86FakeRMW is a "fake" instruction in that it still
197 /// still needs to be lowered to some actual RMW instruction. 195 /// needs to be lowered to some actual RMW instruction.
198 /// 196 ///
199 /// If A is some memory address, D is some data value to apply, and OP is an 197 /// If A is some memory address, D is some data value to apply, and OP is an
200 /// arithmetic operator, the instruction operates as: (*A) = (*A) OP D 198 /// arithmetic operator, the instruction operates as: (*A) = (*A) OP D
201 template <class Machine> 199 template <class Machine>
202 class InstX86FakeRMW final : public InstX86Base<Machine> { 200 class InstX86FakeRMW final : public InstX86Base<Machine> {
203 InstX86FakeRMW() = delete; 201 InstX86FakeRMW() = delete;
204 InstX86FakeRMW(const InstX86FakeRMW &) = delete; 202 InstX86FakeRMW(const InstX86FakeRMW &) = delete;
205 InstX86FakeRMW &operator=(const InstX86FakeRMW &) = delete; 203 InstX86FakeRMW &operator=(const InstX86FakeRMW &) = delete;
206 204
207 public: 205 public:
(...skipping 13 matching lines...) Expand all
221 static bool classof(const Inst *Inst) { 219 static bool classof(const Inst *Inst) {
222 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::FakeRMW); 220 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::FakeRMW);
223 } 221 }
224 222
225 private: 223 private:
226 InstArithmetic::OpKind Op; 224 InstArithmetic::OpKind Op;
227 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, 225 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
228 InstArithmetic::OpKind Op, Variable *Beacon); 226 InstArithmetic::OpKind Op, Variable *Beacon);
229 }; 227 };
230 228
231 /// InstX86Label represents an intra-block label that is the target 229 /// InstX86Label represents an intra-block label that is the target of an
232 /// of an intra-block branch. The offset between the label and the 230 /// intra-block branch. The offset between the label and the branch must be fit
233 /// branch must be fit into one byte (considered "near"). These are 231 /// into one byte (considered "near"). These are used for lowering i1
234 /// used for lowering i1 calculations, Select instructions, and 64-bit 232 /// calculations, Select instructions, and 64-bit compares on a 32-bit
235 /// compares on a 32-bit architecture, without basic block splitting. 233 /// architecture, without basic block splitting. Basic block splitting is not so
236 /// Basic block splitting is not so desirable for several reasons, one 234 /// desirable for several reasons, one of which is the impact on decisions based
237 /// of which is the impact on decisions based on whether a variable's 235 /// on whether a variable's live range spans multiple basic blocks.
238 /// live range spans multiple basic blocks.
239 /// 236 ///
240 /// Intra-block control flow must be used with caution. Consider the 237 /// Intra-block control flow must be used with caution. Consider the sequence
241 /// sequence for "c = (a >= b ? x : y)". 238 /// for "c = (a >= b ? x : y)".
242 /// cmp a, b 239 /// cmp a, b
243 /// br lt, L1 240 /// br lt, L1
244 /// mov c, x 241 /// mov c, x
245 /// jmp L2 242 /// jmp L2
246 /// L1: 243 /// L1:
247 /// mov c, y 244 /// mov c, y
248 /// L2: 245 /// L2:
249 /// 246 ///
250 /// Labels L1 and L2 are intra-block labels. Without knowledge of the 247 /// Labels L1 and L2 are intra-block labels. Without knowledge of the
251 /// intra-block control flow, liveness analysis will determine the "mov 248 /// intra-block control flow, liveness analysis will determine the "mov c, x"
252 /// c, x" instruction to be dead. One way to prevent this is to insert 249 /// instruction to be dead. One way to prevent this is to insert a "FakeUse(c)"
253 /// a "FakeUse(c)" instruction anywhere between the two "mov c, ..." 250 /// instruction anywhere between the two "mov c, ..." instructions, e.g.:
254 /// instructions, e.g.:
255 /// 251 ///
256 /// cmp a, b 252 /// cmp a, b
257 /// br lt, L1 253 /// br lt, L1
258 /// mov c, x 254 /// mov c, x
259 /// jmp L2 255 /// jmp L2
260 /// FakeUse(c) 256 /// FakeUse(c)
261 /// L1: 257 /// L1:
262 /// mov c, y 258 /// mov c, y
263 /// L2: 259 /// L2:
264 /// 260 ///
265 /// The down-side is that "mov c, x" can never be dead-code eliminated 261 /// The down-side is that "mov c, x" can never be dead-code eliminated even if
266 /// even if there are no uses of c. As unlikely as this situation is, 262 /// there are no uses of c. As unlikely as this situation is, it may be
267 /// it may be prevented by running dead code elimination before 263 /// prevented by running dead code elimination before lowering.
268 /// lowering.
269 template <class Machine> 264 template <class Machine>
270 class InstX86Label final : public InstX86Base<Machine> { 265 class InstX86Label final : public InstX86Base<Machine> {
271 InstX86Label() = delete; 266 InstX86Label() = delete;
272 InstX86Label(const InstX86Label &) = delete; 267 InstX86Label(const InstX86Label &) = delete;
273 InstX86Label &operator=(const InstX86Label &) = delete; 268 InstX86Label &operator=(const InstX86Label &) = delete;
274 269
275 public: 270 public:
276 static InstX86Label * 271 static InstX86Label *
277 create(Cfg *Func, 272 create(Cfg *Func,
278 typename InstX86Base<Machine>::Traits::TargetLowering *Target) { 273 typename InstX86Base<Machine>::Traits::TargetLowering *Target) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 InstX86Br(Func, TargetTrue, TargetFalse, NoLabel, Condition, Kind); 307 InstX86Br(Func, TargetTrue, TargetFalse, NoLabel, Condition, Kind);
313 } 308 }
314 /// Create an unconditional branch to a node. 309 /// Create an unconditional branch to a node.
315 static InstX86Br *create(Cfg *Func, CfgNode *Target, Mode Kind) { 310 static InstX86Br *create(Cfg *Func, CfgNode *Target, Mode Kind) {
316 const CfgNode *NoCondTarget = nullptr; 311 const CfgNode *NoCondTarget = nullptr;
317 const InstX86Label<Machine> *NoLabel = nullptr; 312 const InstX86Label<Machine> *NoLabel = nullptr;
318 return new (Func->allocate<InstX86Br>()) 313 return new (Func->allocate<InstX86Br>())
319 InstX86Br(Func, NoCondTarget, Target, NoLabel, 314 InstX86Br(Func, NoCondTarget, Target, NoLabel,
320 InstX86Base<Machine>::Traits::Cond::Br_None, Kind); 315 InstX86Base<Machine>::Traits::Cond::Br_None, Kind);
321 } 316 }
322 /// Create a non-terminator conditional branch to a node, with a 317 /// Create a non-terminator conditional branch to a node, with a fallthrough
323 /// fallthrough to the next instruction in the current node. This is 318 /// to the next instruction in the current node. This is used for switch
324 /// used for switch lowering. 319 /// lowering.
325 static InstX86Br * 320 static InstX86Br *
326 create(Cfg *Func, CfgNode *Target, 321 create(Cfg *Func, CfgNode *Target,
327 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition, 322 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition,
328 Mode Kind) { 323 Mode Kind) {
329 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); 324 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
330 const CfgNode *NoUncondTarget = nullptr; 325 const CfgNode *NoUncondTarget = nullptr;
331 const InstX86Label<Machine> *NoLabel = nullptr; 326 const InstX86Label<Machine> *NoLabel = nullptr;
332 return new (Func->allocate<InstX86Br>()) 327 return new (Func->allocate<InstX86Br>())
333 InstX86Br(Func, Target, NoUncondTarget, NoLabel, Condition, Kind); 328 InstX86Br(Func, Target, NoUncondTarget, NoLabel, Condition, Kind);
334 } 329 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition, 369 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition,
375 Mode Kind); 370 Mode Kind);
376 371
377 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition; 372 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
378 const CfgNode *TargetTrue; 373 const CfgNode *TargetTrue;
379 const CfgNode *TargetFalse; 374 const CfgNode *TargetFalse;
380 const InstX86Label<Machine> *Label; // Intra-block branch target 375 const InstX86Label<Machine> *Label; // Intra-block branch target
381 const Mode Kind; 376 const Mode Kind;
382 }; 377 };
383 378
384 /// Jump to a target outside this function, such as tailcall, nacljump, 379 /// Jump to a target outside this function, such as tailcall, nacljump, naclret,
385 /// naclret, unreachable. This is different from a Branch instruction 380 /// unreachable. This is different from a Branch instruction in that there is no
386 /// in that there is no intra-function control flow to represent. 381 /// intra-function control flow to represent.
387 template <class Machine> class InstX86Jmp final : public InstX86Base<Machine> { 382 template <class Machine> class InstX86Jmp final : public InstX86Base<Machine> {
388 InstX86Jmp() = delete; 383 InstX86Jmp() = delete;
389 InstX86Jmp(const InstX86Jmp &) = delete; 384 InstX86Jmp(const InstX86Jmp &) = delete;
390 InstX86Jmp &operator=(const InstX86Jmp &) = delete; 385 InstX86Jmp &operator=(const InstX86Jmp &) = delete;
391 386
392 public: 387 public:
393 static InstX86Jmp *create(Cfg *Func, Operand *Target) { 388 static InstX86Jmp *create(Cfg *Func, Operand *Target) {
394 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target); 389 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target);
395 } 390 }
396 Operand *getJmpTarget() const { return this->getSrc(0); } 391 Operand *getJmpTarget() const { return this->getSrc(0); }
397 void emit(const Cfg *Func) const override; 392 void emit(const Cfg *Func) const override;
398 void emitIAS(const Cfg *Func) const override; 393 void emitIAS(const Cfg *Func) const override;
399 void dump(const Cfg *Func) const override; 394 void dump(const Cfg *Func) const override;
400 static bool classof(const Inst *Inst) { 395 static bool classof(const Inst *Inst) {
401 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Jmp); 396 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Jmp);
402 } 397 }
403 398
404 private: 399 private:
405 InstX86Jmp(Cfg *Func, Operand *Target); 400 InstX86Jmp(Cfg *Func, Operand *Target);
406 }; 401 };
407 402
408 /// AdjustStack instruction - subtracts esp by the given amount and 403 /// AdjustStack instruction - subtracts esp by the given amount and updates the
409 /// updates the stack offset during code emission. 404 /// stack offset during code emission.
410 template <class Machine> 405 template <class Machine>
411 class InstX86AdjustStack final : public InstX86Base<Machine> { 406 class InstX86AdjustStack final : public InstX86Base<Machine> {
412 InstX86AdjustStack() = delete; 407 InstX86AdjustStack() = delete;
413 InstX86AdjustStack(const InstX86AdjustStack &) = delete; 408 InstX86AdjustStack(const InstX86AdjustStack &) = delete;
414 InstX86AdjustStack &operator=(const InstX86AdjustStack &) = delete; 409 InstX86AdjustStack &operator=(const InstX86AdjustStack &) = delete;
415 410
416 public: 411 public:
417 static InstX86AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { 412 static InstX86AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
418 return new (Func->allocate<InstX86AdjustStack>()) 413 return new (Func->allocate<InstX86AdjustStack>())
419 InstX86AdjustStack(Func, Amount, Esp); 414 InstX86AdjustStack(Func, Amount, Esp);
420 } 415 }
421 void emit(const Cfg *Func) const override; 416 void emit(const Cfg *Func) const override;
422 void emitIAS(const Cfg *Func) const override; 417 void emitIAS(const Cfg *Func) const override;
423 void dump(const Cfg *Func) const override; 418 void dump(const Cfg *Func) const override;
424 static bool classof(const Inst *Inst) { 419 static bool classof(const Inst *Inst) {
425 return InstX86Base<Machine>::isClassof(Inst, 420 return InstX86Base<Machine>::isClassof(Inst,
426 InstX86Base<Machine>::Adjuststack); 421 InstX86Base<Machine>::Adjuststack);
427 } 422 }
428 423
429 private: 424 private:
430 InstX86AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); 425 InstX86AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
431 SizeT Amount; 426 SizeT Amount;
432 }; 427 };
433 428
434 /// Call instruction. Arguments should have already been pushed. 429 /// Call instruction. Arguments should have already been pushed.
435 template <class Machine> class InstX86Call final : public InstX86Base<Machine> { 430 template <class Machine> class InstX86Call final : public InstX86Base<Machine> {
436 InstX86Call() = delete; 431 InstX86Call() = delete;
437 InstX86Call(const InstX86Call &) = delete; 432 InstX86Call(const InstX86Call &) = delete;
438 InstX86Call &operator=(const InstX86Call &) = delete; 433 InstX86Call &operator=(const InstX86Call &) = delete;
439 434
440 public: 435 public:
441 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 436 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
442 return new (Func->allocate<InstX86Call>()) 437 return new (Func->allocate<InstX86Call>())
443 InstX86Call(Func, Dest, CallTarget); 438 InstX86Call(Func, Dest, CallTarget);
444 } 439 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 : InstX86Base<Machine>(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { 502 : InstX86Base<Machine>(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
508 this->addSource(SrcDest); 503 this->addSource(SrcDest);
509 } 504 }
510 505
511 private: 506 private:
512 static const char *Opcode; 507 static const char *Opcode;
513 static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp 508 static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
514 Emitter; 509 Emitter;
515 }; 510 };
516 511
517 /// Emit a two-operand (GPR) instruction, where the dest operand is a 512 /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable
518 /// Variable that's guaranteed to be a register. 513 /// that's guaranteed to be a register.
519 template <class Machine, bool VarCanBeByte = true, bool SrcCanBeByte = true> 514 template <class Machine, bool VarCanBeByte = true, bool SrcCanBeByte = true>
520 void emitIASRegOpTyGPR( 515 void emitIASRegOpTyGPR(
521 const Cfg *Func, Type Ty, const Variable *Dst, const Operand *Src, 516 const Cfg *Func, Type Ty, const Variable *Dst, const Operand *Src,
522 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp 517 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
523 &Emitter); 518 &Emitter);
524 519
525 /// Instructions of the form x := op(y). 520 /// Instructions of the form x := op(y).
526 template <class Machine, typename InstX86Base<Machine>::InstKindX86 K> 521 template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
527 class InstX86BaseUnaryopGPR : public InstX86Base<Machine> { 522 class InstX86BaseUnaryopGPR : public InstX86Base<Machine> {
528 InstX86BaseUnaryopGPR() = delete; 523 InstX86BaseUnaryopGPR() = delete;
529 InstX86BaseUnaryopGPR(const InstX86BaseUnaryopGPR &) = delete; 524 InstX86BaseUnaryopGPR(const InstX86BaseUnaryopGPR &) = delete;
530 InstX86BaseUnaryopGPR &operator=(const InstX86BaseUnaryopGPR &) = delete; 525 InstX86BaseUnaryopGPR &operator=(const InstX86BaseUnaryopGPR &) = delete;
531 526
532 public: 527 public:
533 using Base = InstX86BaseUnaryopGPR<Machine, K>; 528 using Base = InstX86BaseUnaryopGPR<Machine, K>;
534 529
535 void emit(const Cfg *Func) const override { 530 void emit(const Cfg *Func) const override {
536 if (!BuildDefs::dump()) 531 if (!BuildDefs::dump())
537 return; 532 return;
538 Ostream &Str = Func->getContext()->getStrEmit(); 533 Ostream &Str = Func->getContext()->getStrEmit();
539 assert(this->getSrcSize() == 1); 534 assert(this->getSrcSize() == 1);
540 Type SrcTy = this->getSrc(0)->getType(); 535 Type SrcTy = this->getSrc(0)->getType();
541 Type DestTy = this->getDest()->getType(); 536 Type DestTy = this->getDest()->getType();
542 Str << "\t" << Opcode << this->getWidthString(SrcTy); 537 Str << "\t" << Opcode << this->getWidthString(SrcTy);
543 // Movsx and movzx need both the source and dest type width letter 538 // Movsx and movzx need both the source and dest type width letter to
544 // to define the operation. The other unary operations have the 539 // define the operation. The other unary operations have the same source
545 // same source and dest type and as a result need only one letter. 540 // and dest type and as a result need only one letter.
546 if (SrcTy != DestTy) 541 if (SrcTy != DestTy)
547 Str << this->getWidthString(DestTy); 542 Str << this->getWidthString(DestTy);
548 Str << "\t"; 543 Str << "\t";
549 this->getSrc(0)->emit(Func); 544 this->getSrc(0)->emit(Func);
550 Str << ", "; 545 Str << ", ";
551 this->getDest()->emit(Func); 546 this->getDest()->emit(Func);
552 } 547 }
553 void emitIAS(const Cfg *Func) const override { 548 void emitIAS(const Cfg *Func) const override {
554 assert(this->getSrcSize() == 1); 549 assert(this->getSrcSize() == 1);
555 const Variable *Var = this->getDest(); 550 const Variable *Var = this->getDest();
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 1169
1175 void emit(const Cfg *Func) const override; 1170 void emit(const Cfg *Func) const override;
1176 void emitIAS(const Cfg *Func) const override; 1171 void emitIAS(const Cfg *Func) const override;
1177 1172
1178 private: 1173 private:
1179 InstX86Mov(Cfg *Func, Variable *Dest, Operand *Source) 1174 InstX86Mov(Cfg *Func, Variable *Dest, Operand *Source)
1180 : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Mov>(Func, Dest, 1175 : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Mov>(Func, Dest,
1181 Source) {} 1176 Source) {}
1182 }; 1177 };
1183 1178
1184 /// Move packed - copy 128 bit values between XMM registers, or mem128 1179 /// Move packed - copy 128 bit values between XMM registers, or mem128 and XMM
1185 /// and XMM registers. 1180 /// registers.
1186 template <class Machine> 1181 template <class Machine>
1187 class InstX86Movp 1182 class InstX86Movp
1188 : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movp> { 1183 : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movp> {
1189 public: 1184 public:
1190 static InstX86Movp *create(Cfg *Func, Variable *Dest, Operand *Source) { 1185 static InstX86Movp *create(Cfg *Func, Variable *Dest, Operand *Source) {
1191 return new (Func->allocate<InstX86Movp>()) InstX86Movp(Func, Dest, Source); 1186 return new (Func->allocate<InstX86Movp>()) InstX86Movp(Func, Dest, Source);
1192 } 1187 }
1193 1188
1194 void emit(const Cfg *Func) const override; 1189 void emit(const Cfg *Func) const override;
1195 void emitIAS(const Cfg *Func) const override; 1190 void emitIAS(const Cfg *Func) const override;
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 } 1853 }
1859 1854
1860 void emit(const Cfg *Func) const override; 1855 void emit(const Cfg *Func) const override;
1861 1856
1862 private: 1857 private:
1863 InstX86Pcmpgt(Cfg *Func, Variable *Dest, Operand *Source) 1858 InstX86Pcmpgt(Cfg *Func, Variable *Dest, Operand *Source)
1864 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true>( 1859 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true>(
1865 Func, Dest, Source) {} 1860 Func, Dest, Source) {}
1866 }; 1861 };
1867 1862
1868 /// movss is only a binary operation when the source and dest 1863 /// movss is only a binary operation when the source and dest operands are both
1869 /// operands are both registers (the high bits of dest are left untouched). 1864 /// registers (the high bits of dest are left untouched). In other cases, it
1870 /// In other cases, it behaves like a copy (mov-like) operation (and the 1865 /// behaves like a copy (mov-like) operation (and the high bits of dest are
1871 /// high bits of dest are cleared). 1866 /// cleared). InstX86Movss will assert that both its source and dest operands
1872 /// InstX86Movss will assert that both its source and dest operands are 1867 /// are registers, so the lowering code should use _mov instead of _movss in
1873 /// registers, so the lowering code should use _mov instead of _movss 1868 /// cases where a copy operation is intended.
1874 /// in cases where a copy operation is intended.
1875 template <class Machine> 1869 template <class Machine>
1876 class InstX86MovssRegs 1870 class InstX86MovssRegs
1877 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs, 1871 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs,
1878 false> { 1872 false> {
1879 public: 1873 public:
1880 static InstX86MovssRegs *create(Cfg *Func, Variable *Dest, Operand *Source) { 1874 static InstX86MovssRegs *create(Cfg *Func, Variable *Dest, Operand *Source) {
1881 return new (Func->allocate<InstX86MovssRegs>()) 1875 return new (Func->allocate<InstX86MovssRegs>())
1882 InstX86MovssRegs(Func, Dest, Source); 1876 InstX86MovssRegs(Func, Dest, Source);
1883 } 1877 }
1884 1878
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
2065 InstX86BaseLockable(const InstX86BaseLockable &) = delete; 2059 InstX86BaseLockable(const InstX86BaseLockable &) = delete;
2066 InstX86BaseLockable &operator=(const InstX86BaseLockable &) = delete; 2060 InstX86BaseLockable &operator=(const InstX86BaseLockable &) = delete;
2067 2061
2068 protected: 2062 protected:
2069 bool Locked; 2063 bool Locked;
2070 2064
2071 InstX86BaseLockable(Cfg *Func, 2065 InstX86BaseLockable(Cfg *Func,
2072 typename InstX86Base<Machine>::InstKindX86 Kind, 2066 typename InstX86Base<Machine>::InstKindX86 Kind,
2073 SizeT Maxsrcs, Variable *Dest, bool Locked) 2067 SizeT Maxsrcs, Variable *Dest, bool Locked)
2074 : InstX86Base<Machine>(Func, Kind, Maxsrcs, Dest), Locked(Locked) { 2068 : InstX86Base<Machine>(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
2075 // Assume that such instructions are used for Atomics and be careful 2069 // Assume that such instructions are used for Atomics and be careful with
2076 // with optimizations. 2070 // optimizations.
2077 this->HasSideEffects = Locked; 2071 this->HasSideEffects = Locked;
2078 } 2072 }
2079 }; 2073 };
2080 2074
2081 /// Mul instruction - unsigned multiply. 2075 /// Mul instruction - unsigned multiply.
2082 template <class Machine> class InstX86Mul final : public InstX86Base<Machine> { 2076 template <class Machine> class InstX86Mul final : public InstX86Base<Machine> {
2083 InstX86Mul() = delete; 2077 InstX86Mul() = delete;
2084 InstX86Mul(const InstX86Mul &) = delete; 2078 InstX86Mul(const InstX86Mul &) = delete;
2085 InstX86Mul &operator=(const InstX86Mul &) = delete; 2079 InstX86Mul &operator=(const InstX86Mul &) = delete;
2086 2080
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2167 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmov); 2161 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmov);
2168 } 2162 }
2169 2163
2170 private: 2164 private:
2171 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, 2165 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source,
2172 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond); 2166 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond);
2173 2167
2174 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition; 2168 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
2175 }; 2169 };
2176 2170
2177 /// Cmpps instruction - compare packed singled-precision floating point 2171 /// Cmpps instruction - compare packed singled-precision floating point values
2178 /// values
2179 template <class Machine> 2172 template <class Machine>
2180 class InstX86Cmpps final : public InstX86Base<Machine> { 2173 class InstX86Cmpps final : public InstX86Base<Machine> {
2181 InstX86Cmpps() = delete; 2174 InstX86Cmpps() = delete;
2182 InstX86Cmpps(const InstX86Cmpps &) = delete; 2175 InstX86Cmpps(const InstX86Cmpps &) = delete;
2183 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete; 2176 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete;
2184 2177
2185 public: 2178 public:
2186 static InstX86Cmpps * 2179 static InstX86Cmpps *
2187 create(Cfg *Func, Variable *Dest, Operand *Source, 2180 create(Cfg *Func, Variable *Dest, Operand *Source,
2188 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition) { 2181 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition) {
2189 return new (Func->allocate<InstX86Cmpps>()) 2182 return new (Func->allocate<InstX86Cmpps>())
2190 InstX86Cmpps(Func, Dest, Source, Condition); 2183 InstX86Cmpps(Func, Dest, Source, Condition);
2191 } 2184 }
2192 void emit(const Cfg *Func) const override; 2185 void emit(const Cfg *Func) const override;
2193 void emitIAS(const Cfg *Func) const override; 2186 void emitIAS(const Cfg *Func) const override;
2194 void dump(const Cfg *Func) const override; 2187 void dump(const Cfg *Func) const override;
2195 static bool classof(const Inst *Inst) { 2188 static bool classof(const Inst *Inst) {
2196 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpps); 2189 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpps);
2197 } 2190 }
2198 2191
2199 private: 2192 private:
2200 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, 2193 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
2201 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Cond); 2194 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Cond);
2202 2195
2203 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition; 2196 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition;
2204 }; 2197 };
2205 2198
2206 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> 2199 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
2207 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. 2200 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If not,
2208 /// If not, ZF is cleared and <dest> is copied to eax (or subregister). 2201 /// ZF is cleared and <dest> is copied to eax (or subregister). <dest> can be a
2209 /// <dest> can be a register or memory, while <desired> must be a register. 2202 /// register or memory, while <desired> must be a register. It is the user's
2210 /// It is the user's responsiblity to mark eax with a FakeDef. 2203 /// responsibility to mark eax with a FakeDef.
2211 template <class Machine> 2204 template <class Machine>
2212 class InstX86Cmpxchg final : public InstX86BaseLockable<Machine> { 2205 class InstX86Cmpxchg final : public InstX86BaseLockable<Machine> {
2213 InstX86Cmpxchg() = delete; 2206 InstX86Cmpxchg() = delete;
2214 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete; 2207 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete;
2215 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete; 2208 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete;
2216 2209
2217 public: 2210 public:
2218 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 2211 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
2219 Variable *Desired, bool Locked) { 2212 Variable *Desired, bool Locked) {
2220 return new (Func->allocate<InstX86Cmpxchg>()) 2213 return new (Func->allocate<InstX86Cmpxchg>())
2221 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); 2214 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
2222 } 2215 }
2223 void emit(const Cfg *Func) const override; 2216 void emit(const Cfg *Func) const override;
2224 void emitIAS(const Cfg *Func) const override; 2217 void emitIAS(const Cfg *Func) const override;
2225 void dump(const Cfg *Func) const override; 2218 void dump(const Cfg *Func) const override;
2226 static bool classof(const Inst *Inst) { 2219 static bool classof(const Inst *Inst) {
2227 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpxchg); 2220 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpxchg);
2228 } 2221 }
2229 2222
2230 private: 2223 private:
2231 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 2224 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
2232 Variable *Desired, bool Locked); 2225 Variable *Desired, bool Locked);
2233 }; 2226 };
2234 2227
2235 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> 2228 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals
2236 /// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. 2229 /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF is
2237 /// If not, ZF is cleared and <m64> is copied to edx:eax. 2230 /// cleared and <m64> is copied to edx:eax. The caller is responsible for
2238 /// The caller is responsible for inserting FakeDefs to mark edx 2231 /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory
2239 /// and eax as modified. 2232 /// operand.
2240 /// <m64> must be a memory operand.
2241 template <class Machine> 2233 template <class Machine>
2242 class InstX86Cmpxchg8b final : public InstX86BaseLockable<Machine> { 2234 class InstX86Cmpxchg8b final : public InstX86BaseLockable<Machine> {
2243 InstX86Cmpxchg8b() = delete; 2235 InstX86Cmpxchg8b() = delete;
2244 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete; 2236 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete;
2245 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete; 2237 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete;
2246 2238
2247 public: 2239 public:
2248 static InstX86Cmpxchg8b * 2240 static InstX86Cmpxchg8b *
2249 create(Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Dest, 2241 create(Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Dest,
2250 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, 2242 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx,
2251 bool Locked) { 2243 bool Locked) {
2252 return new (Func->allocate<InstX86Cmpxchg8b>()) 2244 return new (Func->allocate<InstX86Cmpxchg8b>())
2253 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); 2245 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
2254 } 2246 }
2255 void emit(const Cfg *Func) const override; 2247 void emit(const Cfg *Func) const override;
2256 void emitIAS(const Cfg *Func) const override; 2248 void emitIAS(const Cfg *Func) const override;
2257 void dump(const Cfg *Func) const override; 2249 void dump(const Cfg *Func) const override;
2258 static bool classof(const Inst *Inst) { 2250 static bool classof(const Inst *Inst) {
2259 return InstX86Base<Machine>::isClassof(Inst, 2251 return InstX86Base<Machine>::isClassof(Inst,
2260 InstX86Base<Machine>::Cmpxchg8b); 2252 InstX86Base<Machine>::Cmpxchg8b);
2261 } 2253 }
2262 2254
2263 private: 2255 private:
2264 InstX86Cmpxchg8b(Cfg *Func, 2256 InstX86Cmpxchg8b(Cfg *Func,
2265 typename InstX86Base<Machine>::Traits::X86OperandMem *Dest, 2257 typename InstX86Base<Machine>::Traits::X86OperandMem *Dest,
2266 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, 2258 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx,
2267 bool Locked); 2259 bool Locked);
2268 }; 2260 };
2269 2261
2270 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} 2262 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as
2271 /// as appropriate. s=float, d=double, i=int. X and Y are determined 2263 /// appropriate. s=float, d=double, i=int. X and Y are determined from dest/src
2272 /// from dest/src types. Sign and zero extension on the integer 2264 /// types. Sign and zero extension on the integer operand needs to be done
2273 /// operand needs to be done separately. 2265 /// separately.
2274 template <class Machine> class InstX86Cvt final : public InstX86Base<Machine> { 2266 template <class Machine> class InstX86Cvt final : public InstX86Base<Machine> {
2275 InstX86Cvt() = delete; 2267 InstX86Cvt() = delete;
2276 InstX86Cvt(const InstX86Cvt &) = delete; 2268 InstX86Cvt(const InstX86Cvt &) = delete;
2277 InstX86Cvt &operator=(const InstX86Cvt &) = delete; 2269 InstX86Cvt &operator=(const InstX86Cvt &) = delete;
2278 2270
2279 public: 2271 public:
2280 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; 2272 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
2281 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, 2273 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
2282 CvtVariant Variant) { 2274 CvtVariant Variant) {
2283 return new (Func->allocate<InstX86Cvt>()) 2275 return new (Func->allocate<InstX86Cvt>())
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2399 void dump(const Cfg *Func) const override; 2391 void dump(const Cfg *Func) const override;
2400 static bool classof(const Inst *Inst) { 2392 static bool classof(const Inst *Inst) {
2401 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Mfence); 2393 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Mfence);
2402 } 2394 }
2403 2395
2404 private: 2396 private:
2405 explicit InstX86Mfence(Cfg *Func); 2397 explicit InstX86Mfence(Cfg *Func);
2406 }; 2398 };
2407 2399
2408 /// This is essentially a "mov" instruction with an 2400 /// This is essentially a "mov" instruction with an
2409 /// InstX86Base<Machine>::Traits::X86OperandMem 2401 /// InstX86Base<Machine>::Traits::X86OperandMem operand instead of Variable as
2410 /// operand instead of Variable as the destination. It's important 2402 /// the destination. It's important for liveness that there is no Dest operand.
2411 /// for liveness that there is no Dest operand.
2412 template <class Machine> 2403 template <class Machine>
2413 class InstX86Store final : public InstX86Base<Machine> { 2404 class InstX86Store final : public InstX86Base<Machine> {
2414 InstX86Store() = delete; 2405 InstX86Store() = delete;
2415 InstX86Store(const InstX86Store &) = delete; 2406 InstX86Store(const InstX86Store &) = delete;
2416 InstX86Store &operator=(const InstX86Store &) = delete; 2407 InstX86Store &operator=(const InstX86Store &) = delete;
2417 2408
2418 public: 2409 public:
2419 static InstX86Store * 2410 static InstX86Store *
2420 create(Cfg *Func, Operand *Value, 2411 create(Cfg *Func, Operand *Value,
2421 typename InstX86Base<Machine>::Traits::X86Operand *Mem) { 2412 typename InstX86Base<Machine>::Traits::X86Operand *Mem) {
2422 return new (Func->allocate<InstX86Store>()) InstX86Store(Func, Value, Mem); 2413 return new (Func->allocate<InstX86Store>()) InstX86Store(Func, Value, Mem);
2423 } 2414 }
2424 void emit(const Cfg *Func) const override; 2415 void emit(const Cfg *Func) const override;
2425 void emitIAS(const Cfg *Func) const override; 2416 void emitIAS(const Cfg *Func) const override;
2426 void dump(const Cfg *Func) const override; 2417 void dump(const Cfg *Func) const override;
2427 static bool classof(const Inst *Inst) { 2418 static bool classof(const Inst *Inst) {
2428 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Store); 2419 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Store);
2429 } 2420 }
2430 2421
2431 private: 2422 private:
2432 InstX86Store(Cfg *Func, Operand *Value, 2423 InstX86Store(Cfg *Func, Operand *Value,
2433 typename InstX86Base<Machine>::Traits::X86Operand *Mem); 2424 typename InstX86Base<Machine>::Traits::X86Operand *Mem);
2434 }; 2425 };
2435 2426
2436 /// This is essentially a vector "mov" instruction with an typename 2427 /// This is essentially a vector "mov" instruction with an typename
2437 /// InstX86Base<Machine>::Traits::X86OperandMem 2428 /// InstX86Base<Machine>::Traits::X86OperandMem operand instead of Variable as
2438 /// operand instead of Variable as the destination. It's important 2429 /// the destination. It's important for liveness that there is no Dest operand.
2439 /// for liveness that there is no Dest operand. The source must be an 2430 /// The source must be an Xmm register, since Dest is mem.
2440 /// Xmm register, since Dest is mem.
2441 template <class Machine> 2431 template <class Machine>
2442 class InstX86StoreP final : public InstX86Base<Machine> { 2432 class InstX86StoreP final : public InstX86Base<Machine> {
2443 InstX86StoreP() = delete; 2433 InstX86StoreP() = delete;
2444 InstX86StoreP(const InstX86StoreP &) = delete; 2434 InstX86StoreP(const InstX86StoreP &) = delete;
2445 InstX86StoreP &operator=(const InstX86StoreP &) = delete; 2435 InstX86StoreP &operator=(const InstX86StoreP &) = delete;
2446 2436
2447 public: 2437 public:
2448 static InstX86StoreP * 2438 static InstX86StoreP *
2449 create(Cfg *Func, Variable *Value, 2439 create(Cfg *Func, Variable *Value,
2450 typename InstX86Base<Machine>::Traits::X86OperandMem *Mem) { 2440 typename InstX86Base<Machine>::Traits::X86OperandMem *Mem) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2589 void emitIAS(const Cfg *Func) const override; 2579 void emitIAS(const Cfg *Func) const override;
2590 void dump(const Cfg *Func) const override; 2580 void dump(const Cfg *Func) const override;
2591 static bool classof(const Inst *Inst) { 2581 static bool classof(const Inst *Inst) {
2592 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Push); 2582 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Push);
2593 } 2583 }
2594 2584
2595 private: 2585 private:
2596 InstX86Push(Cfg *Func, Variable *Source); 2586 InstX86Push(Cfg *Func, Variable *Source);
2597 }; 2587 };
2598 2588
2599 /// Ret instruction. Currently only supports the "ret" version that 2589 /// Ret instruction. Currently only supports the "ret" version that does not pop
2600 /// does not pop arguments. This instruction takes a Source operand 2590 /// arguments. This instruction takes a Source operand (for non-void returning
2601 /// (for non-void returning functions) for liveness analysis, though 2591 /// functions) for liveness analysis, though a FakeUse before the ret would do
2602 /// a FakeUse before the ret would do just as well. 2592 /// just as well.
2603 template <class Machine> class InstX86Ret final : public InstX86Base<Machine> { 2593 template <class Machine> class InstX86Ret final : public InstX86Base<Machine> {
2604 InstX86Ret() = delete; 2594 InstX86Ret() = delete;
2605 InstX86Ret(const InstX86Ret &) = delete; 2595 InstX86Ret(const InstX86Ret &) = delete;
2606 InstX86Ret &operator=(const InstX86Ret &) = delete; 2596 InstX86Ret &operator=(const InstX86Ret &) = delete;
2607 2597
2608 public: 2598 public:
2609 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) { 2599 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) {
2610 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source); 2600 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source);
2611 } 2601 }
2612 void emit(const Cfg *Func) const override; 2602 void emit(const Cfg *Func) const override;
(...skipping 27 matching lines...) Expand all
2640 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Setcc); 2630 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Setcc);
2641 } 2631 }
2642 2632
2643 private: 2633 private:
2644 InstX86Setcc(Cfg *Func, Variable *Dest, 2634 InstX86Setcc(Cfg *Func, Variable *Dest,
2645 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond); 2635 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond);
2646 2636
2647 const typename InstX86Base<Machine>::Traits::Cond::BrCond Condition; 2637 const typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
2648 }; 2638 };
2649 2639
2650 /// Exchanging Add instruction. Exchanges the first operand (destination 2640 /// Exchanging Add instruction. Exchanges the first operand (destination
2651 /// operand) with the second operand (source operand), then loads the sum 2641 /// operand) with the second operand (source operand), then loads the sum of the
2652 /// of the two values into the destination operand. The destination may be 2642 /// two values into the destination operand. The destination may be a register
2653 /// a register or memory, while the source must be a register. 2643 /// or memory, while the source must be a register.
2654 /// 2644 ///
2655 /// Both the dest and source are updated. The caller should then insert a 2645 /// Both the dest and source are updated. The caller should then insert a
2656 /// FakeDef to reflect the second udpate. 2646 /// FakeDef to reflect the second udpate.
2657 template <class Machine> 2647 template <class Machine>
2658 class InstX86Xadd final : public InstX86BaseLockable<Machine> { 2648 class InstX86Xadd final : public InstX86BaseLockable<Machine> {
2659 InstX86Xadd() = delete; 2649 InstX86Xadd() = delete;
2660 InstX86Xadd(const InstX86Xadd &) = delete; 2650 InstX86Xadd(const InstX86Xadd &) = delete;
2661 InstX86Xadd &operator=(const InstX86Xadd &) = delete; 2651 InstX86Xadd &operator=(const InstX86Xadd &) = delete;
2662 2652
2663 public: 2653 public:
2664 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, 2654 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
2665 bool Locked) { 2655 bool Locked) {
2666 return new (Func->allocate<InstX86Xadd>()) 2656 return new (Func->allocate<InstX86Xadd>())
2667 InstX86Xadd(Func, Dest, Source, Locked); 2657 InstX86Xadd(Func, Dest, Source, Locked);
2668 } 2658 }
2669 void emit(const Cfg *Func) const override; 2659 void emit(const Cfg *Func) const override;
2670 void emitIAS(const Cfg *Func) const override; 2660 void emitIAS(const Cfg *Func) const override;
2671 void dump(const Cfg *Func) const override; 2661 void dump(const Cfg *Func) const override;
2672 static bool classof(const Inst *Inst) { 2662 static bool classof(const Inst *Inst) {
2673 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Xadd); 2663 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Xadd);
2674 } 2664 }
2675 2665
2676 private: 2666 private:
2677 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); 2667 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
2678 }; 2668 };
2679 2669
2680 /// Exchange instruction. Exchanges the first operand (destination 2670 /// Exchange instruction. Exchanges the first operand (destination operand) with
2681 /// operand) with the second operand (source operand). At least one of 2671 /// the second operand (source operand). At least one of the operands must be a
2682 /// the operands must be a register (and the other can be reg or mem). 2672 /// register (and the other can be reg or mem). Both the Dest and Source are
2683 /// Both the Dest and Source are updated. If there is a memory operand, 2673 /// updated. If there is a memory operand, then the instruction is automatically
2684 /// then the instruction is automatically "locked" without the need for 2674 /// "locked" without the need for a lock prefix.
2685 /// a lock prefix.
2686 template <class Machine> class InstX86Xchg final : public InstX86Base<Machine> { 2675 template <class Machine> class InstX86Xchg final : public InstX86Base<Machine> {
2687 InstX86Xchg() = delete; 2676 InstX86Xchg() = delete;
2688 InstX86Xchg(const InstX86Xchg &) = delete; 2677 InstX86Xchg(const InstX86Xchg &) = delete;
2689 InstX86Xchg &operator=(const InstX86Xchg &) = delete; 2678 InstX86Xchg &operator=(const InstX86Xchg &) = delete;
2690 2679
2691 public: 2680 public:
2692 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { 2681 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
2693 return new (Func->allocate<InstX86Xchg>()) InstX86Xchg(Func, Dest, Source); 2682 return new (Func->allocate<InstX86Xchg>()) InstX86Xchg(Func, Dest, Source);
2694 } 2683 }
2695 void emit(const Cfg *Func) const override; 2684 void emit(const Cfg *Func) const override;
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
3208 &InstX86Base<Machine>::Traits::Assembler::psrl}; \ 3197 &InstX86Base<Machine>::Traits::Assembler::psrl}; \
3209 } \ 3198 } \
3210 } 3199 }
3211 3200
3212 } // end of namespace X86Internal 3201 } // end of namespace X86Internal
3213 } // end of namespace Ice 3202 } // end of namespace Ice
3214 3203
3215 #include "IceInstX86BaseImpl.h" 3204 #include "IceInstX86BaseImpl.h"
3216 3205
3217 #endif // SUBZERO_SRC_ICEINSTX86BASE_H 3206 #endif // SUBZERO_SRC_ICEINSTX86BASE_H
OLDNEW
« no previous file with comments | « src/IceInstX8664.cpp ('k') | src/IceInstX86BaseImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698