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

Side by Side Diff: src/IceInstX8632.h

Issue 1216963007: Doxygenize the documentation comments (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Rebase to master Created 5 years, 5 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/IceInstMIPS32.h ('k') | src/IceInstX8632.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.h - x86-32 machine instructions -*- C++ -*-===// 1 //===- subzero/src/IceInstX8632.h - x86-32 machine 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 // This file declares the InstX8632 and OperandX8632 classes and 10 /// \file
11 // their subclasses. This represents the machine instructions and 11 /// This file declares the InstX8632 and OperandX8632 classes and
12 // operands used for x86-32 code selection. 12 /// their subclasses. This represents the machine instructions and
13 // 13 /// operands used for x86-32 code selection.
14 ///
14 //===----------------------------------------------------------------------===// 15 //===----------------------------------------------------------------------===//
15 16
16 #ifndef SUBZERO_SRC_ICEINSTX8632_H 17 #ifndef SUBZERO_SRC_ICEINSTX8632_H
17 #define SUBZERO_SRC_ICEINSTX8632_H 18 #define SUBZERO_SRC_ICEINSTX8632_H
18 19
19 #include "IceAssemblerX8632.h" 20 #include "IceAssemblerX8632.h"
20 #include "IceConditionCodesX8632.h" 21 #include "IceConditionCodesX8632.h"
21 #include "IceDefs.h" 22 #include "IceDefs.h"
22 #include "IceInst.h" 23 #include "IceInst.h"
23 #include "IceInstX8632.def" 24 #include "IceInstX8632.def"
24 #include "IceOperand.h" 25 #include "IceOperand.h"
25 #include "IceTargetLoweringX8632Traits.h" 26 #include "IceTargetLoweringX8632Traits.h"
26 27
27 namespace Ice { 28 namespace Ice {
28 29
29 class TargetX8632; 30 class TargetX8632;
30 31
31 // OperandX8632 extends the Operand hierarchy. Its subclasses are 32 /// OperandX8632 extends the Operand hierarchy. Its subclasses are
32 // OperandX8632Mem and VariableSplit. 33 /// OperandX8632Mem and VariableSplit.
33 class OperandX8632 : public Operand { 34 class OperandX8632 : public Operand {
34 OperandX8632() = delete; 35 OperandX8632() = delete;
35 OperandX8632(const OperandX8632 &) = delete; 36 OperandX8632(const OperandX8632 &) = delete;
36 OperandX8632 &operator=(const OperandX8632 &) = delete; 37 OperandX8632 &operator=(const OperandX8632 &) = delete;
37 38
38 public: 39 public:
39 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit }; 40 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit };
40 using Operand::dump; 41 using Operand::dump;
41 void dump(const Cfg *, Ostream &Str) const override { 42 void dump(const Cfg *, Ostream &Str) const override {
42 if (BuildDefs::dump()) 43 if (BuildDefs::dump())
43 Str << "<OperandX8632>"; 44 Str << "<OperandX8632>";
44 } 45 }
45 46
46 protected: 47 protected:
47 OperandX8632(OperandKindX8632 Kind, Type Ty) 48 OperandX8632(OperandKindX8632 Kind, Type Ty)
48 : Operand(static_cast<OperandKind>(Kind), Ty) {} 49 : Operand(static_cast<OperandKind>(Kind), Ty) {}
49 }; 50 };
50 51
51 // OperandX8632Mem represents the m32 addressing mode, with optional 52 /// OperandX8632Mem represents the m32 addressing mode, with optional
52 // base and index registers, a constant offset, and a fixed shift 53 /// base and index registers, a constant offset, and a fixed shift
53 // value for the index register. 54 /// value for the index register.
54 class OperandX8632Mem : public OperandX8632 { 55 class OperandX8632Mem : public OperandX8632 {
55 OperandX8632Mem() = delete; 56 OperandX8632Mem() = delete;
56 OperandX8632Mem(const OperandX8632Mem &) = delete; 57 OperandX8632Mem(const OperandX8632Mem &) = delete;
57 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete; 58 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
58 59
59 public: 60 public:
60 enum SegmentRegisters { 61 enum SegmentRegisters {
61 DefaultSegment = -1, 62 DefaultSegment = -1,
62 #define X(val, name, prefix) val, 63 #define X(val, name, prefix) val,
63 SEG_REGX8632_TABLE 64 SEG_REGX8632_TABLE
(...skipping 28 matching lines...) Expand all
92 93
93 private: 94 private:
94 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, 95 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
95 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg); 96 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
96 97
97 Variable *Base; 98 Variable *Base;
98 Constant *Offset; 99 Constant *Offset;
99 Variable *Index; 100 Variable *Index;
100 uint16_t Shift; 101 uint16_t Shift;
101 SegmentRegisters SegmentReg : 16; 102 SegmentRegisters SegmentReg : 16;
102 // A flag to show if this memory operand is a randomized one. 103 /// A flag to show if this memory operand is a randomized one.
103 // Randomized memory operands are generated in 104 /// Randomized memory operands are generated in
104 // TargetX8632::randomizeOrPoolImmediate() 105 /// TargetX8632::randomizeOrPoolImmediate()
105 bool Randomized; 106 bool Randomized;
106 }; 107 };
107 108
108 // VariableSplit is a way to treat an f64 memory location as a pair 109 /// VariableSplit is a way to treat an f64 memory location as a pair
109 // of i32 locations (Low and High). This is needed for some cases 110 /// of i32 locations (Low and High). This is needed for some cases
110 // of the Bitcast instruction. Since it's not possible for integer 111 /// of the Bitcast instruction. Since it's not possible for integer
111 // registers to access the XMM registers and vice versa, the 112 /// registers to access the XMM registers and vice versa, the
112 // lowering forces the f64 to be spilled to the stack and then 113 /// lowering forces the f64 to be spilled to the stack and then
113 // accesses through the VariableSplit. 114 /// accesses through the VariableSplit.
114 class VariableSplit : public OperandX8632 { 115 class VariableSplit : public OperandX8632 {
115 VariableSplit() = delete; 116 VariableSplit() = delete;
116 VariableSplit(const VariableSplit &) = delete; 117 VariableSplit(const VariableSplit &) = delete;
117 VariableSplit &operator=(const VariableSplit &) = delete; 118 VariableSplit &operator=(const VariableSplit &) = delete;
118 119
119 public: 120 public:
120 enum Portion { Low, High }; 121 enum Portion { Low, High };
121 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) { 122 static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
122 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part); 123 return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
123 } 124 }
(...skipping 14 matching lines...) Expand all
138 assert(Var->getType() == IceType_f64); 139 assert(Var->getType() == IceType_f64);
139 Vars = Func->allocateArrayOf<Variable *>(1); 140 Vars = Func->allocateArrayOf<Variable *>(1);
140 Vars[0] = Var; 141 Vars[0] = Var;
141 NumVars = 1; 142 NumVars = 1;
142 } 143 }
143 144
144 Variable *Var; 145 Variable *Var;
145 Portion Part; 146 Portion Part;
146 }; 147 };
147 148
148 // SpillVariable decorates a Variable by linking it to another 149 /// SpillVariable decorates a Variable by linking it to another
149 // Variable. When stack frame offsets are computed, the SpillVariable 150 /// Variable. When stack frame offsets are computed, the SpillVariable
150 // is given a distinct stack slot only if its linked Variable has a 151 /// is given a distinct stack slot only if its linked Variable has a
151 // register. If the linked Variable has a stack slot, then the 152 /// register. If the linked Variable has a stack slot, then the
152 // Variable and SpillVariable share that slot. 153 /// Variable and SpillVariable share that slot.
153 class SpillVariable : public Variable { 154 class SpillVariable : public Variable {
154 SpillVariable() = delete; 155 SpillVariable() = delete;
155 SpillVariable(const SpillVariable &) = delete; 156 SpillVariable(const SpillVariable &) = delete;
156 SpillVariable &operator=(const SpillVariable &) = delete; 157 SpillVariable &operator=(const SpillVariable &) = delete;
157 158
158 public: 159 public:
159 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) { 160 static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
160 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index); 161 return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
161 } 162 }
162 const static OperandKind SpillVariableKind = 163 const static OperandKind SpillVariableKind =
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 Xor, 278 Xor,
278 XorRMW 279 XorRMW
279 }; 280 };
280 281
281 static const char *getWidthString(Type Ty); 282 static const char *getWidthString(Type Ty);
282 static const char *getFldString(Type Ty); 283 static const char *getFldString(Type Ty);
283 static X8632::Traits::Cond::BrCond 284 static X8632::Traits::Cond::BrCond
284 getOppositeCondition(X8632::Traits::Cond::BrCond Cond); 285 getOppositeCondition(X8632::Traits::Cond::BrCond Cond);
285 void dump(const Cfg *Func) const override; 286 void dump(const Cfg *Func) const override;
286 287
287 // Shared emit routines for common forms of instructions. 288 /// Shared emit routines for common forms of instructions.
288 // See the definition of emitTwoAddress() for a description of 289 /// See the definition of emitTwoAddress() for a description of
289 // ShiftHack. 290 /// ShiftHack.
290 static void emitTwoAddress(const char *Opcode, const Inst *Inst, 291 static void emitTwoAddress(const char *Opcode, const Inst *Inst,
291 const Cfg *Func, bool ShiftHack = false); 292 const Cfg *Func, bool ShiftHack = false);
292 293
293 static void 294 static void
294 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 295 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
295 const Operand *Src, 296 const Operand *Src,
296 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter); 297 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter);
297 298
298 protected: 299 protected:
299 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) 300 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
300 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 301 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
301 302
302 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) { 303 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
303 return Inst->getKind() == static_cast<InstKind>(MyKind); 304 return Inst->getKind() == static_cast<InstKind>(MyKind);
304 } 305 }
305 // Most instructions that operate on vector arguments require vector 306 /// Most instructions that operate on vector arguments require vector
306 // memory operands to be fully aligned (16-byte alignment for PNaCl 307 /// memory operands to be fully aligned (16-byte alignment for PNaCl
307 // vector types). The stack frame layout and call ABI ensure proper 308 /// vector types). The stack frame layout and call ABI ensure proper
308 // alignment for stack operands, but memory operands (originating 309 /// alignment for stack operands, but memory operands (originating
309 // from load/store bitcode instructions) only have element-size 310 /// from load/store bitcode instructions) only have element-size
310 // alignment guarantees. This function validates that none of the 311 /// alignment guarantees. This function validates that none of the
311 // operands is a memory operand of vector type, calling 312 /// operands is a memory operand of vector type, calling
312 // report_fatal_error() if one is found. This function should be 313 /// report_fatal_error() if one is found. This function should be
313 // called during emission, and maybe also in the ctor (as long as 314 /// called during emission, and maybe also in the ctor (as long as
314 // that fits the lowering style). 315 /// that fits the lowering style).
315 void validateVectorAddrMode() const { 316 void validateVectorAddrMode() const {
316 if (getDest()) 317 if (getDest())
317 validateVectorAddrModeOpnd(getDest()); 318 validateVectorAddrModeOpnd(getDest());
318 for (SizeT i = 0; i < getSrcSize(); ++i) { 319 for (SizeT i = 0; i < getSrcSize(); ++i) {
319 validateVectorAddrModeOpnd(getSrc(i)); 320 validateVectorAddrModeOpnd(getSrc(i));
320 } 321 }
321 } 322 }
322 323
323 private: 324 private:
324 static void validateVectorAddrModeOpnd(const Operand *Opnd) { 325 static void validateVectorAddrModeOpnd(const Operand *Opnd) {
325 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) { 326 if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) {
326 llvm::report_fatal_error("Possible misaligned vector memory operation"); 327 llvm::report_fatal_error("Possible misaligned vector memory operation");
327 } 328 }
328 } 329 }
329 }; 330 };
330 331
331 // InstX8632FakeRMW represents a non-atomic read-modify-write operation on a 332 /// InstX8632FakeRMW represents a non-atomic read-modify-write operation on a
332 // memory location. An InstX8632FakeRMW is a "fake" instruction in that it 333 /// memory location. An InstX8632FakeRMW is a "fake" instruction in that it
333 // still needs to be lowered to some actual RMW instruction. 334 /// still needs to be lowered to some actual RMW instruction.
334 // 335 ///
335 // If A is some memory address, D is some data value to apply, and OP is an 336 /// If A is some memory address, D is some data value to apply, and OP is an
336 // arithmetic operator, the instruction operates as: (*A) = (*A) OP D 337 /// arithmetic operator, the instruction operates as: (*A) = (*A) OP D
337 class InstX8632FakeRMW : public InstX8632 { 338 class InstX8632FakeRMW : public InstX8632 {
338 InstX8632FakeRMW() = delete; 339 InstX8632FakeRMW() = delete;
339 InstX8632FakeRMW(const InstX8632FakeRMW &) = delete; 340 InstX8632FakeRMW(const InstX8632FakeRMW &) = delete;
340 InstX8632FakeRMW &operator=(const InstX8632FakeRMW &) = delete; 341 InstX8632FakeRMW &operator=(const InstX8632FakeRMW &) = delete;
341 342
342 public: 343 public:
343 static InstX8632FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr, 344 static InstX8632FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr,
344 Variable *Beacon, InstArithmetic::OpKind Op, 345 Variable *Beacon, InstArithmetic::OpKind Op,
345 uint32_t Align = 1) { 346 uint32_t Align = 1) {
346 // TODO(stichnot): Stop ignoring alignment specification. 347 // TODO(stichnot): Stop ignoring alignment specification.
347 (void)Align; 348 (void)Align;
348 return new (Func->allocate<InstX8632FakeRMW>()) 349 return new (Func->allocate<InstX8632FakeRMW>())
349 InstX8632FakeRMW(Func, Data, Addr, Op, Beacon); 350 InstX8632FakeRMW(Func, Data, Addr, Op, Beacon);
350 } 351 }
351 Operand *getAddr() const { return getSrc(1); } 352 Operand *getAddr() const { return getSrc(1); }
352 Operand *getData() const { return getSrc(0); } 353 Operand *getData() const { return getSrc(0); }
353 InstArithmetic::OpKind getOp() const { return Op; } 354 InstArithmetic::OpKind getOp() const { return Op; }
354 Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); } 355 Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); }
355 void dump(const Cfg *Func) const override; 356 void dump(const Cfg *Func) const override;
356 static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); } 357 static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); }
357 358
358 private: 359 private:
359 InstArithmetic::OpKind Op; 360 InstArithmetic::OpKind Op;
360 InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, 361 InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
361 InstArithmetic::OpKind Op, Variable *Beacon); 362 InstArithmetic::OpKind Op, Variable *Beacon);
362 }; 363 };
363 364
364 // InstX8632Label represents an intra-block label that is the target 365 /// InstX8632Label represents an intra-block label that is the target
365 // of an intra-block branch. The offset between the label and the 366 /// of an intra-block branch. The offset between the label and the
366 // branch must be fit into one byte (considered "near"). These are 367 /// branch must be fit into one byte (considered "near"). These are
367 // used for lowering i1 calculations, Select instructions, and 64-bit 368 /// used for lowering i1 calculations, Select instructions, and 64-bit
368 // compares on a 32-bit architecture, without basic block splitting. 369 /// compares on a 32-bit architecture, without basic block splitting.
369 // Basic block splitting is not so desirable for several reasons, one 370 /// Basic block splitting is not so desirable for several reasons, one
370 // of which is the impact on decisions based on whether a variable's 371 /// of which is the impact on decisions based on whether a variable's
371 // live range spans multiple basic blocks. 372 /// live range spans multiple basic blocks.
372 // 373 ///
373 // Intra-block control flow must be used with caution. Consider the 374 /// Intra-block control flow must be used with caution. Consider the
374 // sequence for "c = (a >= b ? x : y)". 375 /// sequence for "c = (a >= b ? x : y)".
375 // cmp a, b 376 /// cmp a, b
376 // br lt, L1 377 /// br lt, L1
377 // mov c, x 378 /// mov c, x
378 // jmp L2 379 /// jmp L2
379 // L1: 380 /// L1:
380 // mov c, y 381 /// mov c, y
381 // L2: 382 /// L2:
382 // 383 ///
383 // Labels L1 and L2 are intra-block labels. Without knowledge of the 384 /// Labels L1 and L2 are intra-block labels. Without knowledge of the
384 // intra-block control flow, liveness analysis will determine the "mov 385 /// intra-block control flow, liveness analysis will determine the "mov
385 // c, x" instruction to be dead. One way to prevent this is to insert 386 /// c, x" instruction to be dead. One way to prevent this is to insert
386 // a "FakeUse(c)" instruction anywhere between the two "mov c, ..." 387 /// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
387 // instructions, e.g.: 388 /// instructions, e.g.:
388 // 389 ///
389 // cmp a, b 390 /// cmp a, b
390 // br lt, L1 391 /// br lt, L1
391 // mov c, x 392 /// mov c, x
392 // jmp L2 393 /// jmp L2
393 // FakeUse(c) 394 /// FakeUse(c)
394 // L1: 395 /// L1:
395 // mov c, y 396 /// mov c, y
396 // L2: 397 /// L2:
397 // 398 ///
398 // The down-side is that "mov c, x" can never be dead-code eliminated 399 /// The down-side is that "mov c, x" can never be dead-code eliminated
399 // even if there are no uses of c. As unlikely as this situation is, 400 /// even if there are no uses of c. As unlikely as this situation is,
400 // it may be prevented by running dead code elimination before 401 /// it may be prevented by running dead code elimination before
401 // lowering. 402 /// lowering.
402 class InstX8632Label : public InstX8632 { 403 class InstX8632Label : public InstX8632 {
403 InstX8632Label() = delete; 404 InstX8632Label() = delete;
404 InstX8632Label(const InstX8632Label &) = delete; 405 InstX8632Label(const InstX8632Label &) = delete;
405 InstX8632Label &operator=(const InstX8632Label &) = delete; 406 InstX8632Label &operator=(const InstX8632Label &) = delete;
406 407
407 public: 408 public:
408 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) { 409 static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
409 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target); 410 return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
410 } 411 }
411 uint32_t getEmitInstCount() const override { return 0; } 412 uint32_t getEmitInstCount() const override { return 0; }
412 IceString getName(const Cfg *Func) const; 413 IceString getName(const Cfg *Func) const;
413 SizeT getNumber() const { return Number; } 414 SizeT getNumber() const { return Number; }
414 void emit(const Cfg *Func) const override; 415 void emit(const Cfg *Func) const override;
415 void emitIAS(const Cfg *Func) const override; 416 void emitIAS(const Cfg *Func) const override;
416 void dump(const Cfg *Func) const override; 417 void dump(const Cfg *Func) const override;
417 418
418 private: 419 private:
419 InstX8632Label(Cfg *Func, TargetX8632 *Target); 420 InstX8632Label(Cfg *Func, TargetX8632 *Target);
420 421
421 SizeT Number; // used for unique label generation. 422 SizeT Number; /// used for unique label generation.
422 }; 423 };
423 424
424 // Conditional and unconditional branch instruction. 425 /// Conditional and unconditional branch instruction.
425 class InstX8632Br : public InstX8632 { 426 class InstX8632Br : public InstX8632 {
426 InstX8632Br() = delete; 427 InstX8632Br() = delete;
427 InstX8632Br(const InstX8632Br &) = delete; 428 InstX8632Br(const InstX8632Br &) = delete;
428 InstX8632Br &operator=(const InstX8632Br &) = delete; 429 InstX8632Br &operator=(const InstX8632Br &) = delete;
429 430
430 public: 431 public:
431 // Create a conditional branch to a node. 432 /// Create a conditional branch to a node.
432 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, 433 static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
433 CfgNode *TargetFalse, 434 CfgNode *TargetFalse,
434 X8632::Traits::Cond::BrCond Condition) { 435 X8632::Traits::Cond::BrCond Condition) {
435 assert(Condition != X8632::Traits::Cond::Br_None); 436 assert(Condition != X8632::Traits::Cond::Br_None);
436 const InstX8632Label *NoLabel = nullptr; 437 const InstX8632Label *NoLabel = nullptr;
437 return new (Func->allocate<InstX8632Br>()) 438 return new (Func->allocate<InstX8632Br>())
438 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition); 439 InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
439 } 440 }
440 // Create an unconditional branch to a node. 441 /// Create an unconditional branch to a node.
441 static InstX8632Br *create(Cfg *Func, CfgNode *Target) { 442 static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
442 const CfgNode *NoCondTarget = nullptr; 443 const CfgNode *NoCondTarget = nullptr;
443 const InstX8632Label *NoLabel = nullptr; 444 const InstX8632Label *NoLabel = nullptr;
444 return new (Func->allocate<InstX8632Br>()) InstX8632Br( 445 return new (Func->allocate<InstX8632Br>()) InstX8632Br(
445 Func, NoCondTarget, Target, NoLabel, X8632::Traits::Cond::Br_None); 446 Func, NoCondTarget, Target, NoLabel, X8632::Traits::Cond::Br_None);
446 } 447 }
447 // Create a non-terminator conditional branch to a node, with a 448 /// Create a non-terminator conditional branch to a node, with a
448 // fallthrough to the next instruction in the current node. This is 449 /// fallthrough to the next instruction in the current node. This is
449 // used for switch lowering. 450 /// used for switch lowering.
450 static InstX8632Br *create(Cfg *Func, CfgNode *Target, 451 static InstX8632Br *create(Cfg *Func, CfgNode *Target,
451 X8632::Traits::Cond::BrCond Condition) { 452 X8632::Traits::Cond::BrCond Condition) {
452 assert(Condition != X8632::Traits::Cond::Br_None); 453 assert(Condition != X8632::Traits::Cond::Br_None);
453 const CfgNode *NoUncondTarget = nullptr; 454 const CfgNode *NoUncondTarget = nullptr;
454 const InstX8632Label *NoLabel = nullptr; 455 const InstX8632Label *NoLabel = nullptr;
455 return new (Func->allocate<InstX8632Br>()) 456 return new (Func->allocate<InstX8632Br>())
456 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition); 457 InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition);
457 } 458 }
458 // Create a conditional intra-block branch (or unconditional, if 459 /// Create a conditional intra-block branch (or unconditional, if
459 // Condition==Br_None) to a label in the current block. 460 /// Condition==Br_None) to a label in the current block.
460 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label, 461 static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
461 X8632::Traits::Cond::BrCond Condition) { 462 X8632::Traits::Cond::BrCond Condition) {
462 const CfgNode *NoCondTarget = nullptr; 463 const CfgNode *NoCondTarget = nullptr;
463 const CfgNode *NoUncondTarget = nullptr; 464 const CfgNode *NoUncondTarget = nullptr;
464 return new (Func->allocate<InstX8632Br>()) 465 return new (Func->allocate<InstX8632Br>())
465 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition); 466 InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition);
466 } 467 }
467 const CfgNode *getTargetTrue() const { return TargetTrue; } 468 const CfgNode *getTargetTrue() const { return TargetTrue; }
468 const CfgNode *getTargetFalse() const { return TargetFalse; } 469 const CfgNode *getTargetFalse() const { return TargetFalse; }
469 bool optimizeBranch(const CfgNode *NextNode); 470 bool optimizeBranch(const CfgNode *NextNode);
(...skipping 17 matching lines...) Expand all
487 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } 488 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
488 489
489 private: 490 private:
490 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 491 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
491 const InstX8632Label *Label, 492 const InstX8632Label *Label,
492 X8632::Traits::Cond::BrCond Condition); 493 X8632::Traits::Cond::BrCond Condition);
493 494
494 X8632::Traits::Cond::BrCond Condition; 495 X8632::Traits::Cond::BrCond Condition;
495 const CfgNode *TargetTrue; 496 const CfgNode *TargetTrue;
496 const CfgNode *TargetFalse; 497 const CfgNode *TargetFalse;
497 const InstX8632Label *Label; // Intra-block branch target 498 const InstX8632Label *Label; /// Intra-block branch target
498 }; 499 };
499 500
500 // Jump to a target outside this function, such as tailcall, nacljump, 501 /// Jump to a target outside this function, such as tailcall, nacljump,
501 // naclret, unreachable. This is different from a Branch instruction 502 /// naclret, unreachable. This is different from a Branch instruction
502 // in that there is no intra-function control flow to represent. 503 /// in that there is no intra-function control flow to represent.
503 class InstX8632Jmp : public InstX8632 { 504 class InstX8632Jmp : public InstX8632 {
504 InstX8632Jmp() = delete; 505 InstX8632Jmp() = delete;
505 InstX8632Jmp(const InstX8632Jmp &) = delete; 506 InstX8632Jmp(const InstX8632Jmp &) = delete;
506 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete; 507 InstX8632Jmp &operator=(const InstX8632Jmp &) = delete;
507 508
508 public: 509 public:
509 static InstX8632Jmp *create(Cfg *Func, Operand *Target) { 510 static InstX8632Jmp *create(Cfg *Func, Operand *Target) {
510 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target); 511 return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target);
511 } 512 }
512 Operand *getJmpTarget() const { return getSrc(0); } 513 Operand *getJmpTarget() const { return getSrc(0); }
513 void emit(const Cfg *Func) const override; 514 void emit(const Cfg *Func) const override;
514 void emitIAS(const Cfg *Func) const override; 515 void emitIAS(const Cfg *Func) const override;
515 void dump(const Cfg *Func) const override; 516 void dump(const Cfg *Func) const override;
516 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); } 517 static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); }
517 518
518 private: 519 private:
519 InstX8632Jmp(Cfg *Func, Operand *Target); 520 InstX8632Jmp(Cfg *Func, Operand *Target);
520 }; 521 };
521 522
522 // AdjustStack instruction - subtracts esp by the given amount and 523 /// AdjustStack instruction - subtracts esp by the given amount and
523 // updates the stack offset during code emission. 524 /// updates the stack offset during code emission.
524 class InstX8632AdjustStack : public InstX8632 { 525 class InstX8632AdjustStack : public InstX8632 {
525 InstX8632AdjustStack() = delete; 526 InstX8632AdjustStack() = delete;
526 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete; 527 InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
527 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete; 528 InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
528 529
529 public: 530 public:
530 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) { 531 static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
531 return new (Func->allocate<InstX8632AdjustStack>()) 532 return new (Func->allocate<InstX8632AdjustStack>())
532 InstX8632AdjustStack(Func, Amount, Esp); 533 InstX8632AdjustStack(Func, Amount, Esp);
533 } 534 }
534 void emit(const Cfg *Func) const override; 535 void emit(const Cfg *Func) const override;
535 void emitIAS(const Cfg *Func) const override; 536 void emitIAS(const Cfg *Func) const override;
536 void dump(const Cfg *Func) const override; 537 void dump(const Cfg *Func) const override;
537 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } 538 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
538 539
539 private: 540 private:
540 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp); 541 InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
541 SizeT Amount; 542 SizeT Amount;
542 }; 543 };
543 544
544 // Call instruction. Arguments should have already been pushed. 545 /// Call instruction. Arguments should have already been pushed.
545 class InstX8632Call : public InstX8632 { 546 class InstX8632Call : public InstX8632 {
546 InstX8632Call() = delete; 547 InstX8632Call() = delete;
547 InstX8632Call(const InstX8632Call &) = delete; 548 InstX8632Call(const InstX8632Call &) = delete;
548 InstX8632Call &operator=(const InstX8632Call &) = delete; 549 InstX8632Call &operator=(const InstX8632Call &) = delete;
549 550
550 public: 551 public:
551 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 552 static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
552 return new (Func->allocate<InstX8632Call>()) 553 return new (Func->allocate<InstX8632Call>())
553 InstX8632Call(Func, Dest, CallTarget); 554 InstX8632Call(Func, Dest, CallTarget);
554 } 555 }
555 Operand *getCallTarget() const { return getSrc(0); } 556 Operand *getCallTarget() const { return getSrc(0); }
556 void emit(const Cfg *Func) const override; 557 void emit(const Cfg *Func) const override;
557 void emitIAS(const Cfg *Func) const override; 558 void emitIAS(const Cfg *Func) const override;
558 void dump(const Cfg *Func) const override; 559 void dump(const Cfg *Func) const override;
559 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 560 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
560 561
561 private: 562 private:
562 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 563 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
563 }; 564 };
564 565
565 // Emit a one-operand (GPR) instruction. 566 /// Emit a one-operand (GPR) instruction.
566 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, 567 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
567 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter); 568 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter);
568 void emitIASAsAddrOpTyGPR( 569 void emitIASAsAddrOpTyGPR(
569 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, 570 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
570 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter); 571 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter);
571 572
572 // Instructions of the form x := op(x). 573 /// Instructions of the form x := op(x).
573 template <InstX8632::InstKindX8632 K> 574 template <InstX8632::InstKindX8632 K>
574 class InstX8632InplaceopGPR : public InstX8632 { 575 class InstX8632InplaceopGPR : public InstX8632 {
575 InstX8632InplaceopGPR() = delete; 576 InstX8632InplaceopGPR() = delete;
576 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; 577 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
577 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; 578 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
578 579
579 public: 580 public:
580 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { 581 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
581 return new (Func->allocate<InstX8632InplaceopGPR>()) 582 return new (Func->allocate<InstX8632InplaceopGPR>())
582 InstX8632InplaceopGPR(Func, SrcDest); 583 InstX8632InplaceopGPR(Func, SrcDest);
(...skipping 25 matching lines...) Expand all
608 private: 609 private:
609 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) 610 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
610 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { 611 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
611 addSource(SrcDest); 612 addSource(SrcDest);
612 } 613 }
613 614
614 static const char *Opcode; 615 static const char *Opcode;
615 static const X8632::AssemblerX8632::GPREmitterOneOp Emitter; 616 static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
616 }; 617 };
617 618
618 // Emit a two-operand (GPR) instruction, where the dest operand is a 619 /// Emit a two-operand (GPR) instruction, where the dest operand is a
619 // Variable that's guaranteed to be a register. 620 /// Variable that's guaranteed to be a register.
620 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> 621 template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
621 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, 622 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
622 const Operand *Src, 623 const Operand *Src,
623 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter); 624 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter);
624 625
625 // Instructions of the form x := op(y). 626 /// Instructions of the form x := op(y).
626 template <InstX8632::InstKindX8632 K> 627 template <InstX8632::InstKindX8632 K>
627 class InstX8632UnaryopGPR : public InstX8632 { 628 class InstX8632UnaryopGPR : public InstX8632 {
628 InstX8632UnaryopGPR() = delete; 629 InstX8632UnaryopGPR() = delete;
629 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete; 630 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
630 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete; 631 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
631 632
632 public: 633 public:
633 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { 634 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
634 return new (Func->allocate<InstX8632UnaryopGPR>()) 635 return new (Func->allocate<InstX8632UnaryopGPR>())
635 InstX8632UnaryopGPR(Func, Dest, Src); 636 InstX8632UnaryopGPR(Func, Dest, Src);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter; 730 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
730 }; 731 };
731 732
732 template <InstX8632::InstKindX8632 K> 733 template <InstX8632::InstKindX8632 K>
733 class InstX8632BinopGPRShift : public InstX8632 { 734 class InstX8632BinopGPRShift : public InstX8632 {
734 InstX8632BinopGPRShift() = delete; 735 InstX8632BinopGPRShift() = delete;
735 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete; 736 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
736 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; 737 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
737 738
738 public: 739 public:
739 // Create a binary-op GPR shift instruction. 740 /// Create a binary-op GPR shift instruction.
740 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, 741 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest,
741 Operand *Source) { 742 Operand *Source) {
742 return new (Func->allocate<InstX8632BinopGPRShift>()) 743 return new (Func->allocate<InstX8632BinopGPRShift>())
743 InstX8632BinopGPRShift(Func, Dest, Source); 744 InstX8632BinopGPRShift(Func, Dest, Source);
744 } 745 }
745 void emit(const Cfg *Func) const override { 746 void emit(const Cfg *Func) const override {
746 if (!BuildDefs::dump()) 747 if (!BuildDefs::dump())
747 return; 748 return;
748 const bool ShiftHack = true; 749 const bool ShiftHack = true;
749 emitTwoAddress(Opcode, this, Func, ShiftHack); 750 emitTwoAddress(Opcode, this, Func, ShiftHack);
(...skipping 24 matching lines...) Expand all
774 static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter; 775 static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
775 }; 776 };
776 777
777 template <InstX8632::InstKindX8632 K> 778 template <InstX8632::InstKindX8632 K>
778 class InstX8632BinopGPR : public InstX8632 { 779 class InstX8632BinopGPR : public InstX8632 {
779 InstX8632BinopGPR() = delete; 780 InstX8632BinopGPR() = delete;
780 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete; 781 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
781 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete; 782 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
782 783
783 public: 784 public:
784 // Create an ordinary binary-op instruction like add or sub. 785 /// Create an ordinary binary-op instruction like add or sub.
785 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { 786 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
786 return new (Func->allocate<InstX8632BinopGPR>()) 787 return new (Func->allocate<InstX8632BinopGPR>())
787 InstX8632BinopGPR(Func, Dest, Source); 788 InstX8632BinopGPR(Func, Dest, Source);
788 } 789 }
789 void emit(const Cfg *Func) const override { 790 void emit(const Cfg *Func) const override {
790 if (!BuildDefs::dump()) 791 if (!BuildDefs::dump())
791 return; 792 return;
792 const bool ShiftHack = false; 793 const bool ShiftHack = false;
793 emitTwoAddress(Opcode, this, Func, ShiftHack); 794 emitTwoAddress(Opcode, this, Func, ShiftHack);
794 } 795 }
(...skipping 23 matching lines...) Expand all
818 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter; 819 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
819 }; 820 };
820 821
821 template <InstX8632::InstKindX8632 K> 822 template <InstX8632::InstKindX8632 K>
822 class InstX8632BinopRMW : public InstX8632 { 823 class InstX8632BinopRMW : public InstX8632 {
823 InstX8632BinopRMW() = delete; 824 InstX8632BinopRMW() = delete;
824 InstX8632BinopRMW(const InstX8632BinopRMW &) = delete; 825 InstX8632BinopRMW(const InstX8632BinopRMW &) = delete;
825 InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete; 826 InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete;
826 827
827 public: 828 public:
828 // Create an ordinary binary-op instruction like add or sub. 829 /// Create an ordinary binary-op instruction like add or sub.
829 static InstX8632BinopRMW *create(Cfg *Func, OperandX8632Mem *DestSrc0, 830 static InstX8632BinopRMW *create(Cfg *Func, OperandX8632Mem *DestSrc0,
830 Operand *Src1) { 831 Operand *Src1) {
831 return new (Func->allocate<InstX8632BinopRMW>()) 832 return new (Func->allocate<InstX8632BinopRMW>())
832 InstX8632BinopRMW(Func, DestSrc0, Src1); 833 InstX8632BinopRMW(Func, DestSrc0, Src1);
833 } 834 }
834 void emit(const Cfg *Func) const override { 835 void emit(const Cfg *Func) const override {
835 if (!BuildDefs::dump()) 836 if (!BuildDefs::dump())
836 return; 837 return;
837 const bool ShiftHack = false; 838 const bool ShiftHack = false;
838 emitTwoAddress(Opcode, this, Func, ShiftHack); 839 emitTwoAddress(Opcode, this, Func, ShiftHack);
(...skipping 22 matching lines...) Expand all
861 static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter; 862 static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter;
862 }; 863 };
863 864
864 template <InstX8632::InstKindX8632 K, bool NeedsElementType> 865 template <InstX8632::InstKindX8632 K, bool NeedsElementType>
865 class InstX8632BinopXmm : public InstX8632 { 866 class InstX8632BinopXmm : public InstX8632 {
866 InstX8632BinopXmm() = delete; 867 InstX8632BinopXmm() = delete;
867 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; 868 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
868 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; 869 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
869 870
870 public: 871 public:
871 // Create an XMM binary-op instruction like addss or addps. 872 /// Create an XMM binary-op instruction like addss or addps.
872 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { 873 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
873 return new (Func->allocate<InstX8632BinopXmm>()) 874 return new (Func->allocate<InstX8632BinopXmm>())
874 InstX8632BinopXmm(Func, Dest, Source); 875 InstX8632BinopXmm(Func, Dest, Source);
875 } 876 }
876 void emit(const Cfg *Func) const override { 877 void emit(const Cfg *Func) const override {
877 if (!BuildDefs::dump()) 878 if (!BuildDefs::dump())
878 return; 879 return;
879 validateVectorAddrMode(); 880 validateVectorAddrMode();
880 const bool ShiftHack = false; 881 const bool ShiftHack = false;
881 emitTwoAddress(Opcode, this, Func, ShiftHack); 882 emitTwoAddress(Opcode, this, Func, ShiftHack);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 const Operand *Src, 914 const Operand *Src,
914 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter); 915 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter);
915 916
916 template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false> 917 template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false>
917 class InstX8632BinopXmmShift : public InstX8632 { 918 class InstX8632BinopXmmShift : public InstX8632 {
918 InstX8632BinopXmmShift() = delete; 919 InstX8632BinopXmmShift() = delete;
919 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete; 920 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
920 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete; 921 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
921 922
922 public: 923 public:
923 // Create an XMM binary-op shift operation. 924 /// Create an XMM binary-op shift operation.
924 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, 925 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest,
925 Operand *Source) { 926 Operand *Source) {
926 return new (Func->allocate<InstX8632BinopXmmShift>()) 927 return new (Func->allocate<InstX8632BinopXmmShift>())
927 InstX8632BinopXmmShift(Func, Dest, Source); 928 InstX8632BinopXmmShift(Func, Dest, Source);
928 } 929 }
929 void emit(const Cfg *Func) const override { 930 void emit(const Cfg *Func) const override {
930 if (!BuildDefs::dump()) 931 if (!BuildDefs::dump())
931 return; 932 return;
932 validateVectorAddrMode(); 933 validateVectorAddrMode();
933 const bool ShiftHack = false; 934 const bool ShiftHack = false;
(...skipping 27 matching lines...) Expand all
961 static const char *Opcode; 962 static const char *Opcode;
962 static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter; 963 static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
963 }; 964 };
964 965
965 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { 966 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
966 InstX8632Ternop() = delete; 967 InstX8632Ternop() = delete;
967 InstX8632Ternop(const InstX8632Ternop &) = delete; 968 InstX8632Ternop(const InstX8632Ternop &) = delete;
968 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete; 969 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
969 970
970 public: 971 public:
971 // Create a ternary-op instruction like div or idiv. 972 /// Create a ternary-op instruction like div or idiv.
972 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, 973 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
973 Operand *Source2) { 974 Operand *Source2) {
974 return new (Func->allocate<InstX8632Ternop>()) 975 return new (Func->allocate<InstX8632Ternop>())
975 InstX8632Ternop(Func, Dest, Source1, Source2); 976 InstX8632Ternop(Func, Dest, Source1, Source2);
976 } 977 }
977 void emit(const Cfg *Func) const override { 978 void emit(const Cfg *Func) const override {
978 if (!BuildDefs::dump()) 979 if (!BuildDefs::dump())
979 return; 980 return;
980 Ostream &Str = Func->getContext()->getStrEmit(); 981 Ostream &Str = Func->getContext()->getStrEmit();
981 assert(getSrcSize() == 3); 982 assert(getSrcSize() == 3);
(...skipping 19 matching lines...) Expand all
1001 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 1002 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
1002 : InstX8632(Func, K, 3, Dest) { 1003 : InstX8632(Func, K, 3, Dest) {
1003 addSource(Dest); 1004 addSource(Dest);
1004 addSource(Source1); 1005 addSource(Source1);
1005 addSource(Source2); 1006 addSource(Source2);
1006 } 1007 }
1007 1008
1008 static const char *Opcode; 1009 static const char *Opcode;
1009 }; 1010 };
1010 1011
1011 // Instructions of the form x := y op z 1012 /// Instructions of the form x := y op z
1012 template <InstX8632::InstKindX8632 K> 1013 template <InstX8632::InstKindX8632 K>
1013 class InstX8632ThreeAddressop : public InstX8632 { 1014 class InstX8632ThreeAddressop : public InstX8632 {
1014 InstX8632ThreeAddressop() = delete; 1015 InstX8632ThreeAddressop() = delete;
1015 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete; 1016 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
1016 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete; 1017 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
1017 1018
1018 public: 1019 public:
1019 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, 1020 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
1020 Operand *Source0, Operand *Source1) { 1021 Operand *Source0, Operand *Source1) {
1021 return new (Func->allocate<InstX8632ThreeAddressop>()) 1022 return new (Func->allocate<InstX8632ThreeAddressop>())
(...skipping 26 matching lines...) Expand all
1048 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, 1049 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
1049 Operand *Source1) 1050 Operand *Source1)
1050 : InstX8632(Func, K, 2, Dest) { 1051 : InstX8632(Func, K, 2, Dest) {
1051 addSource(Source0); 1052 addSource(Source0);
1052 addSource(Source1); 1053 addSource(Source1);
1053 } 1054 }
1054 1055
1055 static const char *Opcode; 1056 static const char *Opcode;
1056 }; 1057 };
1057 1058
1058 // Base class for assignment instructions 1059 /// Base class for assignment instructions
1059 template <InstX8632::InstKindX8632 K> 1060 template <InstX8632::InstKindX8632 K>
1060 class InstX8632Movlike : public InstX8632 { 1061 class InstX8632Movlike : public InstX8632 {
1061 InstX8632Movlike() = delete; 1062 InstX8632Movlike() = delete;
1062 InstX8632Movlike(const InstX8632Movlike &) = delete; 1063 InstX8632Movlike(const InstX8632Movlike &) = delete;
1063 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete; 1064 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
1064 1065
1065 public: 1066 public:
1066 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) { 1067 static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
1067 return new (Func->allocate<InstX8632Movlike>()) 1068 return new (Func->allocate<InstX8632Movlike>())
1068 InstX8632Movlike(Func, Dest, Source); 1069 InstX8632Movlike(Func, Dest, Source);
(...skipping 22 matching lines...) Expand all
1091 } 1092 }
1092 1093
1093 static const char *Opcode; 1094 static const char *Opcode;
1094 }; 1095 };
1095 1096
1096 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap; 1097 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
1097 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg; 1098 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
1098 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf; 1099 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
1099 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr; 1100 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
1100 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea; 1101 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
1101 // Cbwdq instruction - wrapper for cbw, cwd, and cdq 1102 /// Cbwdq instruction - wrapper for cbw, cwd, and cdq
1102 typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq; 1103 typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq;
1103 typedef InstX8632UnaryopGPR<InstX8632::Movsx> InstX8632Movsx; 1104 typedef InstX8632UnaryopGPR<InstX8632::Movsx> InstX8632Movsx;
1104 typedef InstX8632UnaryopGPR<InstX8632::Movzx> InstX8632Movzx; 1105 typedef InstX8632UnaryopGPR<InstX8632::Movzx> InstX8632Movzx;
1105 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd; 1106 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd;
1106 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; 1107 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss;
1107 // Move/assignment instruction - wrapper for mov/movss/movsd. 1108 /// Move/assignment instruction - wrapper for mov/movss/movsd.
1108 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; 1109 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov;
1109 // Move packed - copy 128 bit values between XMM registers, or mem128 1110 /// Move packed - copy 128 bit values between XMM registers, or mem128
1110 // and XMM registers. 1111 /// and XMM registers.
1111 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; 1112 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
1112 // Movq - copy between XMM registers, or mem64 and XMM registers. 1113 /// Movq - copy between XMM registers, or mem64 and XMM registers.
1113 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; 1114 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
1114 typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add; 1115 typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add;
1115 typedef InstX8632BinopRMW<InstX8632::AddRMW> InstX8632AddRMW; 1116 typedef InstX8632BinopRMW<InstX8632::AddRMW> InstX8632AddRMW;
1116 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; 1117 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps;
1117 typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc; 1118 typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc;
1118 typedef InstX8632BinopRMW<InstX8632::AdcRMW> InstX8632AdcRMW; 1119 typedef InstX8632BinopRMW<InstX8632::AdcRMW> InstX8632AdcRMW;
1119 typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss; 1120 typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss;
1120 typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd; 1121 typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd;
1121 typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub; 1122 typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub;
1122 typedef InstX8632BinopRMW<InstX8632::SubRMW> InstX8632SubRMW; 1123 typedef InstX8632BinopRMW<InstX8632::SubRMW> InstX8632SubRMW;
(...skipping 21 matching lines...) Expand all
1144 typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss; 1145 typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss;
1145 typedef InstX8632BinopGPRShift<InstX8632::Rol> InstX8632Rol; 1146 typedef InstX8632BinopGPRShift<InstX8632::Rol> InstX8632Rol;
1146 typedef InstX8632BinopGPRShift<InstX8632::Shl> InstX8632Shl; 1147 typedef InstX8632BinopGPRShift<InstX8632::Shl> InstX8632Shl;
1147 typedef InstX8632BinopXmmShift<InstX8632::Psll> InstX8632Psll; 1148 typedef InstX8632BinopXmmShift<InstX8632::Psll> InstX8632Psll;
1148 typedef InstX8632BinopXmmShift<InstX8632::Psrl, true> InstX8632Psrl; 1149 typedef InstX8632BinopXmmShift<InstX8632::Psrl, true> InstX8632Psrl;
1149 typedef InstX8632BinopGPRShift<InstX8632::Shr> InstX8632Shr; 1150 typedef InstX8632BinopGPRShift<InstX8632::Shr> InstX8632Shr;
1150 typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar; 1151 typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar;
1151 typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra; 1152 typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra;
1152 typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq; 1153 typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq;
1153 typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt; 1154 typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt;
1154 // movss is only a binary operation when the source and dest 1155 /// movss is only a binary operation when the source and dest
1155 // operands are both registers (the high bits of dest are left untouched). 1156 /// operands are both registers (the high bits of dest are left untouched).
1156 // In other cases, it behaves like a copy (mov-like) operation (and the 1157 /// In other cases, it behaves like a copy (mov-like) operation (and the
1157 // high bits of dest are cleared). 1158 /// high bits of dest are cleared).
1158 // InstX8632Movss will assert that both its source and dest operands are 1159 /// InstX8632Movss will assert that both its source and dest operands are
1159 // registers, so the lowering code should use _mov instead of _movss 1160 /// registers, so the lowering code should use _mov instead of _movss
1160 // in cases where a copy operation is intended. 1161 /// in cases where a copy operation is intended.
1161 typedef InstX8632BinopXmm<InstX8632::MovssRegs, false> InstX8632MovssRegs; 1162 typedef InstX8632BinopXmm<InstX8632::MovssRegs, false> InstX8632MovssRegs;
1162 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; 1163 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
1163 typedef InstX8632Ternop<InstX8632::Div> InstX8632Div; 1164 typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
1164 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps; 1165 typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
1165 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr; 1166 typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
1166 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps; 1167 typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
1167 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps; 1168 typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
1168 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb; 1169 typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
1169 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr; 1170 typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
1170 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd; 1171 typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
1171 1172
1172 // Base class for a lockable x86-32 instruction (emits a locked prefix). 1173 /// Base class for a lockable x86-32 instruction (emits a locked prefix).
1173 class InstX8632Lockable : public InstX8632 { 1174 class InstX8632Lockable : public InstX8632 {
1174 InstX8632Lockable() = delete; 1175 InstX8632Lockable() = delete;
1175 InstX8632Lockable(const InstX8632Lockable &) = delete; 1176 InstX8632Lockable(const InstX8632Lockable &) = delete;
1176 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete; 1177 InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
1177 1178
1178 protected: 1179 protected:
1179 bool Locked; 1180 bool Locked;
1180 1181
1181 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, 1182 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
1182 Variable *Dest, bool Locked) 1183 Variable *Dest, bool Locked)
1183 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { 1184 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
1184 // Assume that such instructions are used for Atomics and be careful 1185 // Assume that such instructions are used for Atomics and be careful
1185 // with optimizations. 1186 // with optimizations.
1186 HasSideEffects = Locked; 1187 HasSideEffects = Locked;
1187 } 1188 }
1188 }; 1189 };
1189 1190
1190 // Mul instruction - unsigned multiply. 1191 /// Mul instruction - unsigned multiply.
1191 class InstX8632Mul : public InstX8632 { 1192 class InstX8632Mul : public InstX8632 {
1192 InstX8632Mul() = delete; 1193 InstX8632Mul() = delete;
1193 InstX8632Mul(const InstX8632Mul &) = delete; 1194 InstX8632Mul(const InstX8632Mul &) = delete;
1194 InstX8632Mul &operator=(const InstX8632Mul &) = delete; 1195 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
1195 1196
1196 public: 1197 public:
1197 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, 1198 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
1198 Operand *Source2) { 1199 Operand *Source2) {
1199 return new (Func->allocate<InstX8632Mul>()) 1200 return new (Func->allocate<InstX8632Mul>())
1200 InstX8632Mul(Func, Dest, Source1, Source2); 1201 InstX8632Mul(Func, Dest, Source1, Source2);
1201 } 1202 }
1202 void emit(const Cfg *Func) const override; 1203 void emit(const Cfg *Func) const override;
1203 void emitIAS(const Cfg *Func) const override; 1204 void emitIAS(const Cfg *Func) const override;
1204 void dump(const Cfg *Func) const override; 1205 void dump(const Cfg *Func) const override;
1205 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } 1206 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
1206 1207
1207 private: 1208 private:
1208 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 1209 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
1209 }; 1210 };
1210 1211
1211 // Shld instruction - shift across a pair of operands. 1212 /// Shld instruction - shift across a pair of operands.
1212 class InstX8632Shld : public InstX8632 { 1213 class InstX8632Shld : public InstX8632 {
1213 InstX8632Shld() = delete; 1214 InstX8632Shld() = delete;
1214 InstX8632Shld(const InstX8632Shld &) = delete; 1215 InstX8632Shld(const InstX8632Shld &) = delete;
1215 InstX8632Shld &operator=(const InstX8632Shld &) = delete; 1216 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
1216 1217
1217 public: 1218 public:
1218 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, 1219 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
1219 Variable *Source2) { 1220 Variable *Source2) {
1220 return new (Func->allocate<InstX8632Shld>()) 1221 return new (Func->allocate<InstX8632Shld>())
1221 InstX8632Shld(Func, Dest, Source1, Source2); 1222 InstX8632Shld(Func, Dest, Source1, Source2);
1222 } 1223 }
1223 void emit(const Cfg *Func) const override; 1224 void emit(const Cfg *Func) const override;
1224 void emitIAS(const Cfg *Func) const override; 1225 void emitIAS(const Cfg *Func) const override;
1225 void dump(const Cfg *Func) const override; 1226 void dump(const Cfg *Func) const override;
1226 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } 1227 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
1227 1228
1228 private: 1229 private:
1229 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, 1230 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
1230 Variable *Source2); 1231 Variable *Source2);
1231 }; 1232 };
1232 1233
1233 // Shrd instruction - shift across a pair of operands. 1234 /// Shrd instruction - shift across a pair of operands.
1234 class InstX8632Shrd : public InstX8632 { 1235 class InstX8632Shrd : public InstX8632 {
1235 InstX8632Shrd() = delete; 1236 InstX8632Shrd() = delete;
1236 InstX8632Shrd(const InstX8632Shrd &) = delete; 1237 InstX8632Shrd(const InstX8632Shrd &) = delete;
1237 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete; 1238 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1238 1239
1239 public: 1240 public:
1240 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, 1241 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
1241 Variable *Source2) { 1242 Variable *Source2) {
1242 return new (Func->allocate<InstX8632Shrd>()) 1243 return new (Func->allocate<InstX8632Shrd>())
1243 InstX8632Shrd(Func, Dest, Source1, Source2); 1244 InstX8632Shrd(Func, Dest, Source1, Source2);
1244 } 1245 }
1245 void emit(const Cfg *Func) const override; 1246 void emit(const Cfg *Func) const override;
1246 void emitIAS(const Cfg *Func) const override; 1247 void emitIAS(const Cfg *Func) const override;
1247 void dump(const Cfg *Func) const override; 1248 void dump(const Cfg *Func) const override;
1248 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } 1249 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
1249 1250
1250 private: 1251 private:
1251 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, 1252 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
1252 Variable *Source2); 1253 Variable *Source2);
1253 }; 1254 };
1254 1255
1255 // Conditional move instruction. 1256 /// Conditional move instruction.
1256 class InstX8632Cmov : public InstX8632 { 1257 class InstX8632Cmov : public InstX8632 {
1257 InstX8632Cmov() = delete; 1258 InstX8632Cmov() = delete;
1258 InstX8632Cmov(const InstX8632Cmov &) = delete; 1259 InstX8632Cmov(const InstX8632Cmov &) = delete;
1259 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete; 1260 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1260 1261
1261 public: 1262 public:
1262 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, 1263 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
1263 X8632::Traits::Cond::BrCond Cond) { 1264 X8632::Traits::Cond::BrCond Cond) {
1264 return new (Func->allocate<InstX8632Cmov>()) 1265 return new (Func->allocate<InstX8632Cmov>())
1265 InstX8632Cmov(Func, Dest, Source, Cond); 1266 InstX8632Cmov(Func, Dest, Source, Cond);
1266 } 1267 }
1267 void emit(const Cfg *Func) const override; 1268 void emit(const Cfg *Func) const override;
1268 void emitIAS(const Cfg *Func) const override; 1269 void emitIAS(const Cfg *Func) const override;
1269 void dump(const Cfg *Func) const override; 1270 void dump(const Cfg *Func) const override;
1270 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } 1271 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
1271 1272
1272 private: 1273 private:
1273 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, 1274 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
1274 X8632::Traits::Cond::BrCond Cond); 1275 X8632::Traits::Cond::BrCond Cond);
1275 1276
1276 X8632::Traits::Cond::BrCond Condition; 1277 X8632::Traits::Cond::BrCond Condition;
1277 }; 1278 };
1278 1279
1279 // Cmpps instruction - compare packed singled-precision floating point 1280 /// Cmpps instruction - compare packed singled-precision floating point
1280 // values 1281 /// values
1281 class InstX8632Cmpps : public InstX8632 { 1282 class InstX8632Cmpps : public InstX8632 {
1282 InstX8632Cmpps() = delete; 1283 InstX8632Cmpps() = delete;
1283 InstX8632Cmpps(const InstX8632Cmpps &) = delete; 1284 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1284 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete; 1285 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1285 1286
1286 public: 1287 public:
1287 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, 1288 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
1288 X8632::Traits::Cond::CmppsCond Condition) { 1289 X8632::Traits::Cond::CmppsCond Condition) {
1289 return new (Func->allocate<InstX8632Cmpps>()) 1290 return new (Func->allocate<InstX8632Cmpps>())
1290 InstX8632Cmpps(Func, Dest, Source, Condition); 1291 InstX8632Cmpps(Func, Dest, Source, Condition);
1291 } 1292 }
1292 void emit(const Cfg *Func) const override; 1293 void emit(const Cfg *Func) const override;
1293 void emitIAS(const Cfg *Func) const override; 1294 void emitIAS(const Cfg *Func) const override;
1294 void dump(const Cfg *Func) const override; 1295 void dump(const Cfg *Func) const override;
1295 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } 1296 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
1296 1297
1297 private: 1298 private:
1298 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, 1299 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
1299 X8632::Traits::Cond::CmppsCond Cond); 1300 X8632::Traits::Cond::CmppsCond Cond);
1300 1301
1301 X8632::Traits::Cond::CmppsCond Condition; 1302 X8632::Traits::Cond::CmppsCond Condition;
1302 }; 1303 };
1303 1304
1304 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> 1305 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
1305 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. 1306 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
1306 // If not, ZF is cleared and <dest> is copied to eax (or subregister). 1307 /// If not, ZF is cleared and <dest> is copied to eax (or subregister).
1307 // <dest> can be a register or memory, while <desired> must be a register. 1308 /// <dest> can be a register or memory, while <desired> must be a register.
1308 // It is the user's responsiblity to mark eax with a FakeDef. 1309 /// It is the user's responsiblity to mark eax with a FakeDef.
1309 class InstX8632Cmpxchg : public InstX8632Lockable { 1310 class InstX8632Cmpxchg : public InstX8632Lockable {
1310 InstX8632Cmpxchg() = delete; 1311 InstX8632Cmpxchg() = delete;
1311 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete; 1312 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1312 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete; 1313 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1313 1314
1314 public: 1315 public:
1315 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1316 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1316 Variable *Desired, bool Locked) { 1317 Variable *Desired, bool Locked) {
1317 return new (Func->allocate<InstX8632Cmpxchg>()) 1318 return new (Func->allocate<InstX8632Cmpxchg>())
1318 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); 1319 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1319 } 1320 }
1320 void emit(const Cfg *Func) const override; 1321 void emit(const Cfg *Func) const override;
1321 void emitIAS(const Cfg *Func) const override; 1322 void emitIAS(const Cfg *Func) const override;
1322 void dump(const Cfg *Func) const override; 1323 void dump(const Cfg *Func) const override;
1323 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } 1324 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1324 1325
1325 private: 1326 private:
1326 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1327 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1327 Variable *Desired, bool Locked); 1328 Variable *Desired, bool Locked);
1328 }; 1329 };
1329 1330
1330 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> 1331 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1331 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. 1332 /// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1332 // If not, ZF is cleared and <m64> is copied to edx:eax. 1333 /// If not, ZF is cleared and <m64> is copied to edx:eax.
1333 // The caller is responsible for inserting FakeDefs to mark edx 1334 /// The caller is responsible for inserting FakeDefs to mark edx
1334 // and eax as modified. 1335 /// and eax as modified.
1335 // <m64> must be a memory operand. 1336 /// <m64> must be a memory operand.
1336 class InstX8632Cmpxchg8b : public InstX8632Lockable { 1337 class InstX8632Cmpxchg8b : public InstX8632Lockable {
1337 InstX8632Cmpxchg8b() = delete; 1338 InstX8632Cmpxchg8b() = delete;
1338 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete; 1339 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1339 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete; 1340 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1340 1341
1341 public: 1342 public:
1342 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, 1343 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
1343 Variable *Edx, Variable *Eax, Variable *Ecx, 1344 Variable *Edx, Variable *Eax, Variable *Ecx,
1344 Variable *Ebx, bool Locked) { 1345 Variable *Ebx, bool Locked) {
1345 return new (Func->allocate<InstX8632Cmpxchg8b>()) 1346 return new (Func->allocate<InstX8632Cmpxchg8b>())
1346 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); 1347 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
1347 } 1348 }
1348 void emit(const Cfg *Func) const override; 1349 void emit(const Cfg *Func) const override;
1349 void emitIAS(const Cfg *Func) const override; 1350 void emitIAS(const Cfg *Func) const override;
1350 void dump(const Cfg *Func) const override; 1351 void dump(const Cfg *Func) const override;
1351 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } 1352 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1352 1353
1353 private: 1354 private:
1354 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, 1355 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
1355 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); 1356 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
1356 }; 1357 };
1357 1358
1358 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} 1359 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1359 // as appropriate. s=float, d=double, i=int. X and Y are determined 1360 /// as appropriate. s=float, d=double, i=int. X and Y are determined
1360 // from dest/src types. Sign and zero extension on the integer 1361 /// from dest/src types. Sign and zero extension on the integer
1361 // operand needs to be done separately. 1362 /// operand needs to be done separately.
1362 class InstX8632Cvt : public InstX8632 { 1363 class InstX8632Cvt : public InstX8632 {
1363 InstX8632Cvt() = delete; 1364 InstX8632Cvt() = delete;
1364 InstX8632Cvt(const InstX8632Cvt &) = delete; 1365 InstX8632Cvt(const InstX8632Cvt &) = delete;
1365 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete; 1366 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1366 1367
1367 public: 1368 public:
1368 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; 1369 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
1369 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, 1370 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
1370 CvtVariant Variant) { 1371 CvtVariant Variant) {
1371 return new (Func->allocate<InstX8632Cvt>()) 1372 return new (Func->allocate<InstX8632Cvt>())
1372 InstX8632Cvt(Func, Dest, Source, Variant); 1373 InstX8632Cvt(Func, Dest, Source, Variant);
1373 } 1374 }
1374 void emit(const Cfg *Func) const override; 1375 void emit(const Cfg *Func) const override;
1375 void emitIAS(const Cfg *Func) const override; 1376 void emitIAS(const Cfg *Func) const override;
1376 void dump(const Cfg *Func) const override; 1377 void dump(const Cfg *Func) const override;
1377 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } 1378 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
1378 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } 1379 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
1379 1380
1380 private: 1381 private:
1381 CvtVariant Variant; 1382 CvtVariant Variant;
1382 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); 1383 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
1383 }; 1384 };
1384 1385
1385 // cmp - Integer compare instruction. 1386 /// cmp - Integer compare instruction.
1386 class InstX8632Icmp : public InstX8632 { 1387 class InstX8632Icmp : public InstX8632 {
1387 InstX8632Icmp() = delete; 1388 InstX8632Icmp() = delete;
1388 InstX8632Icmp(const InstX8632Icmp &) = delete; 1389 InstX8632Icmp(const InstX8632Icmp &) = delete;
1389 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete; 1390 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1390 1391
1391 public: 1392 public:
1392 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1393 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1393 return new (Func->allocate<InstX8632Icmp>()) 1394 return new (Func->allocate<InstX8632Icmp>())
1394 InstX8632Icmp(Func, Src1, Src2); 1395 InstX8632Icmp(Func, Src1, Src2);
1395 } 1396 }
1396 void emit(const Cfg *Func) const override; 1397 void emit(const Cfg *Func) const override;
1397 void emitIAS(const Cfg *Func) const override; 1398 void emitIAS(const Cfg *Func) const override;
1398 void dump(const Cfg *Func) const override; 1399 void dump(const Cfg *Func) const override;
1399 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } 1400 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1400 1401
1401 private: 1402 private:
1402 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); 1403 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
1403 }; 1404 };
1404 1405
1405 // ucomiss/ucomisd - floating-point compare instruction. 1406 /// ucomiss/ucomisd - floating-point compare instruction.
1406 class InstX8632Ucomiss : public InstX8632 { 1407 class InstX8632Ucomiss : public InstX8632 {
1407 InstX8632Ucomiss() = delete; 1408 InstX8632Ucomiss() = delete;
1408 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete; 1409 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1409 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete; 1410 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1410 1411
1411 public: 1412 public:
1412 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1413 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1413 return new (Func->allocate<InstX8632Ucomiss>()) 1414 return new (Func->allocate<InstX8632Ucomiss>())
1414 InstX8632Ucomiss(Func, Src1, Src2); 1415 InstX8632Ucomiss(Func, Src1, Src2);
1415 } 1416 }
1416 void emit(const Cfg *Func) const override; 1417 void emit(const Cfg *Func) const override;
1417 void emitIAS(const Cfg *Func) const override; 1418 void emitIAS(const Cfg *Func) const override;
1418 void dump(const Cfg *Func) const override; 1419 void dump(const Cfg *Func) const override;
1419 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } 1420 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1420 1421
1421 private: 1422 private:
1422 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); 1423 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
1423 }; 1424 };
1424 1425
1425 // UD2 instruction. 1426 /// UD2 instruction.
1426 class InstX8632UD2 : public InstX8632 { 1427 class InstX8632UD2 : public InstX8632 {
1427 InstX8632UD2() = delete; 1428 InstX8632UD2() = delete;
1428 InstX8632UD2(const InstX8632UD2 &) = delete; 1429 InstX8632UD2(const InstX8632UD2 &) = delete;
1429 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete; 1430 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1430 1431
1431 public: 1432 public:
1432 static InstX8632UD2 *create(Cfg *Func) { 1433 static InstX8632UD2 *create(Cfg *Func) {
1433 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); 1434 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1434 } 1435 }
1435 void emit(const Cfg *Func) const override; 1436 void emit(const Cfg *Func) const override;
1436 void emitIAS(const Cfg *Func) const override; 1437 void emitIAS(const Cfg *Func) const override;
1437 void dump(const Cfg *Func) const override; 1438 void dump(const Cfg *Func) const override;
1438 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } 1439 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1439 1440
1440 private: 1441 private:
1441 explicit InstX8632UD2(Cfg *Func); 1442 explicit InstX8632UD2(Cfg *Func);
1442 }; 1443 };
1443 1444
1444 // Test instruction. 1445 /// Test instruction.
1445 class InstX8632Test : public InstX8632 { 1446 class InstX8632Test : public InstX8632 {
1446 InstX8632Test() = delete; 1447 InstX8632Test() = delete;
1447 InstX8632Test(const InstX8632Test &) = delete; 1448 InstX8632Test(const InstX8632Test &) = delete;
1448 InstX8632Test &operator=(const InstX8632Test &) = delete; 1449 InstX8632Test &operator=(const InstX8632Test &) = delete;
1449 1450
1450 public: 1451 public:
1451 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { 1452 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1452 return new (Func->allocate<InstX8632Test>()) 1453 return new (Func->allocate<InstX8632Test>())
1453 InstX8632Test(Func, Source1, Source2); 1454 InstX8632Test(Func, Source1, Source2);
1454 } 1455 }
1455 void emit(const Cfg *Func) const override; 1456 void emit(const Cfg *Func) const override;
1456 void emitIAS(const Cfg *Func) const override; 1457 void emitIAS(const Cfg *Func) const override;
1457 void dump(const Cfg *Func) const override; 1458 void dump(const Cfg *Func) const override;
1458 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } 1459 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1459 1460
1460 private: 1461 private:
1461 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); 1462 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
1462 }; 1463 };
1463 1464
1464 // Mfence instruction. 1465 /// Mfence instruction.
1465 class InstX8632Mfence : public InstX8632 { 1466 class InstX8632Mfence : public InstX8632 {
1466 InstX8632Mfence() = delete; 1467 InstX8632Mfence() = delete;
1467 InstX8632Mfence(const InstX8632Mfence &) = delete; 1468 InstX8632Mfence(const InstX8632Mfence &) = delete;
1468 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete; 1469 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1469 1470
1470 public: 1471 public:
1471 static InstX8632Mfence *create(Cfg *Func) { 1472 static InstX8632Mfence *create(Cfg *Func) {
1472 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); 1473 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1473 } 1474 }
1474 void emit(const Cfg *Func) const override; 1475 void emit(const Cfg *Func) const override;
1475 void emitIAS(const Cfg *Func) const override; 1476 void emitIAS(const Cfg *Func) const override;
1476 void dump(const Cfg *Func) const override; 1477 void dump(const Cfg *Func) const override;
1477 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } 1478 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1478 1479
1479 private: 1480 private:
1480 explicit InstX8632Mfence(Cfg *Func); 1481 explicit InstX8632Mfence(Cfg *Func);
1481 }; 1482 };
1482 1483
1483 // This is essentially a "mov" instruction with an OperandX8632Mem 1484 /// This is essentially a "mov" instruction with an OperandX8632Mem
1484 // operand instead of Variable as the destination. It's important 1485 /// operand instead of Variable as the destination. It's important
1485 // for liveness that there is no Dest operand. 1486 /// for liveness that there is no Dest operand.
1486 class InstX8632Store : public InstX8632 { 1487 class InstX8632Store : public InstX8632 {
1487 InstX8632Store() = delete; 1488 InstX8632Store() = delete;
1488 InstX8632Store(const InstX8632Store &) = delete; 1489 InstX8632Store(const InstX8632Store &) = delete;
1489 InstX8632Store &operator=(const InstX8632Store &) = delete; 1490 InstX8632Store &operator=(const InstX8632Store &) = delete;
1490 1491
1491 public: 1492 public:
1492 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { 1493 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1493 return new (Func->allocate<InstX8632Store>()) 1494 return new (Func->allocate<InstX8632Store>())
1494 InstX8632Store(Func, Value, Mem); 1495 InstX8632Store(Func, Value, Mem);
1495 } 1496 }
1496 void emit(const Cfg *Func) const override; 1497 void emit(const Cfg *Func) const override;
1497 void emitIAS(const Cfg *Func) const override; 1498 void emitIAS(const Cfg *Func) const override;
1498 void dump(const Cfg *Func) const override; 1499 void dump(const Cfg *Func) const override;
1499 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } 1500 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1500 1501
1501 private: 1502 private:
1502 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); 1503 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
1503 }; 1504 };
1504 1505
1505 // This is essentially a vector "mov" instruction with an OperandX8632Mem 1506 /// This is essentially a vector "mov" instruction with an OperandX8632Mem
1506 // operand instead of Variable as the destination. It's important 1507 /// operand instead of Variable as the destination. It's important
1507 // for liveness that there is no Dest operand. The source must be an 1508 /// for liveness that there is no Dest operand. The source must be an
1508 // Xmm register, since Dest is mem. 1509 /// Xmm register, since Dest is mem.
1509 class InstX8632StoreP : public InstX8632 { 1510 class InstX8632StoreP : public InstX8632 {
1510 InstX8632StoreP() = delete; 1511 InstX8632StoreP() = delete;
1511 InstX8632StoreP(const InstX8632StoreP &) = delete; 1512 InstX8632StoreP(const InstX8632StoreP &) = delete;
1512 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete; 1513 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1513 1514
1514 public: 1515 public:
1515 static InstX8632StoreP *create(Cfg *Func, Variable *Value, 1516 static InstX8632StoreP *create(Cfg *Func, Variable *Value,
1516 OperandX8632Mem *Mem) { 1517 OperandX8632Mem *Mem) {
1517 return new (Func->allocate<InstX8632StoreP>()) 1518 return new (Func->allocate<InstX8632StoreP>())
1518 InstX8632StoreP(Func, Value, Mem); 1519 InstX8632StoreP(Func, Value, Mem);
(...skipping 20 matching lines...) Expand all
1539 } 1540 }
1540 void emit(const Cfg *Func) const override; 1541 void emit(const Cfg *Func) const override;
1541 void emitIAS(const Cfg *Func) const override; 1542 void emitIAS(const Cfg *Func) const override;
1542 void dump(const Cfg *Func) const override; 1543 void dump(const Cfg *Func) const override;
1543 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } 1544 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1544 1545
1545 private: 1546 private:
1546 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); 1547 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
1547 }; 1548 };
1548 1549
1549 // Nop instructions of varying length 1550 /// Nop instructions of varying length
1550 class InstX8632Nop : public InstX8632 { 1551 class InstX8632Nop : public InstX8632 {
1551 InstX8632Nop() = delete; 1552 InstX8632Nop() = delete;
1552 InstX8632Nop(const InstX8632Nop &) = delete; 1553 InstX8632Nop(const InstX8632Nop &) = delete;
1553 InstX8632Nop &operator=(const InstX8632Nop &) = delete; 1554 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1554 1555
1555 public: 1556 public:
1556 // TODO: Replace with enum. 1557 // TODO: Replace with enum.
1557 typedef unsigned NopVariant; 1558 typedef unsigned NopVariant;
1558 1559
1559 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { 1560 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1560 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); 1561 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1561 } 1562 }
1562 void emit(const Cfg *Func) const override; 1563 void emit(const Cfg *Func) const override;
1563 void emitIAS(const Cfg *Func) const override; 1564 void emitIAS(const Cfg *Func) const override;
1564 void dump(const Cfg *Func) const override; 1565 void dump(const Cfg *Func) const override;
1565 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } 1566 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1566 1567
1567 private: 1568 private:
1568 InstX8632Nop(Cfg *Func, SizeT Length); 1569 InstX8632Nop(Cfg *Func, SizeT Length);
1569 1570
1570 NopVariant Variant; 1571 NopVariant Variant;
1571 }; 1572 };
1572 1573
1573 // Fld - load a value onto the x87 FP stack. 1574 /// Fld - load a value onto the x87 FP stack.
1574 class InstX8632Fld : public InstX8632 { 1575 class InstX8632Fld : public InstX8632 {
1575 InstX8632Fld() = delete; 1576 InstX8632Fld() = delete;
1576 InstX8632Fld(const InstX8632Fld &) = delete; 1577 InstX8632Fld(const InstX8632Fld &) = delete;
1577 InstX8632Fld &operator=(const InstX8632Fld &) = delete; 1578 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1578 1579
1579 public: 1580 public:
1580 static InstX8632Fld *create(Cfg *Func, Operand *Src) { 1581 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1581 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); 1582 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1582 } 1583 }
1583 void emit(const Cfg *Func) const override; 1584 void emit(const Cfg *Func) const override;
1584 void emitIAS(const Cfg *Func) const override; 1585 void emitIAS(const Cfg *Func) const override;
1585 void dump(const Cfg *Func) const override; 1586 void dump(const Cfg *Func) const override;
1586 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } 1587 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1587 1588
1588 private: 1589 private:
1589 InstX8632Fld(Cfg *Func, Operand *Src); 1590 InstX8632Fld(Cfg *Func, Operand *Src);
1590 }; 1591 };
1591 1592
1592 // Fstp - store x87 st(0) into memory and pop st(0). 1593 /// Fstp - store x87 st(0) into memory and pop st(0).
1593 class InstX8632Fstp : public InstX8632 { 1594 class InstX8632Fstp : public InstX8632 {
1594 InstX8632Fstp() = delete; 1595 InstX8632Fstp() = delete;
1595 InstX8632Fstp(const InstX8632Fstp &) = delete; 1596 InstX8632Fstp(const InstX8632Fstp &) = delete;
1596 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete; 1597 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1597 1598
1598 public: 1599 public:
1599 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { 1600 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1600 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); 1601 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1601 } 1602 }
1602 void emit(const Cfg *Func) const override; 1603 void emit(const Cfg *Func) const override;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 } 1638 }
1638 void emit(const Cfg *Func) const override; 1639 void emit(const Cfg *Func) const override;
1639 void emitIAS(const Cfg *Func) const override; 1640 void emitIAS(const Cfg *Func) const override;
1640 void dump(const Cfg *Func) const override; 1641 void dump(const Cfg *Func) const override;
1641 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } 1642 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1642 1643
1643 private: 1644 private:
1644 InstX8632Push(Cfg *Func, Variable *Source); 1645 InstX8632Push(Cfg *Func, Variable *Source);
1645 }; 1646 };
1646 1647
1647 // Ret instruction. Currently only supports the "ret" version that 1648 /// Ret instruction. Currently only supports the "ret" version that
1648 // does not pop arguments. This instruction takes a Source operand 1649 /// does not pop arguments. This instruction takes a Source operand
1649 // (for non-void returning functions) for liveness analysis, though 1650 /// (for non-void returning functions) for liveness analysis, though
1650 // a FakeUse before the ret would do just as well. 1651 /// a FakeUse before the ret would do just as well.
1651 class InstX8632Ret : public InstX8632 { 1652 class InstX8632Ret : public InstX8632 {
1652 InstX8632Ret() = delete; 1653 InstX8632Ret() = delete;
1653 InstX8632Ret(const InstX8632Ret &) = delete; 1654 InstX8632Ret(const InstX8632Ret &) = delete;
1654 InstX8632Ret &operator=(const InstX8632Ret &) = delete; 1655 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1655 1656
1656 public: 1657 public:
1657 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) { 1658 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) {
1658 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); 1659 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1659 } 1660 }
1660 void emit(const Cfg *Func) const override; 1661 void emit(const Cfg *Func) const override;
1661 void emitIAS(const Cfg *Func) const override; 1662 void emitIAS(const Cfg *Func) const override;
1662 void dump(const Cfg *Func) const override; 1663 void dump(const Cfg *Func) const override;
1663 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 1664 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1664 1665
1665 private: 1666 private:
1666 InstX8632Ret(Cfg *Func, Variable *Source); 1667 InstX8632Ret(Cfg *Func, Variable *Source);
1667 }; 1668 };
1668 1669
1669 // Conditional set-byte instruction. 1670 /// Conditional set-byte instruction.
1670 class InstX8632Setcc : public InstX8632 { 1671 class InstX8632Setcc : public InstX8632 {
1671 InstX8632Setcc() = delete; 1672 InstX8632Setcc() = delete;
1672 InstX8632Setcc(const InstX8632Cmov &) = delete; 1673 InstX8632Setcc(const InstX8632Cmov &) = delete;
1673 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete; 1674 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete;
1674 1675
1675 public: 1676 public:
1676 static InstX8632Setcc *create(Cfg *Func, Variable *Dest, 1677 static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
1677 X8632::Traits::Cond::BrCond Cond) { 1678 X8632::Traits::Cond::BrCond Cond) {
1678 return new (Func->allocate<InstX8632Setcc>()) 1679 return new (Func->allocate<InstX8632Setcc>())
1679 InstX8632Setcc(Func, Dest, Cond); 1680 InstX8632Setcc(Func, Dest, Cond);
1680 } 1681 }
1681 void emit(const Cfg *Func) const override; 1682 void emit(const Cfg *Func) const override;
1682 void emitIAS(const Cfg *Func) const override; 1683 void emitIAS(const Cfg *Func) const override;
1683 void dump(const Cfg *Func) const override; 1684 void dump(const Cfg *Func) const override;
1684 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); } 1685 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
1685 1686
1686 private: 1687 private:
1687 InstX8632Setcc(Cfg *Func, Variable *Dest, X8632::Traits::Cond::BrCond Cond); 1688 InstX8632Setcc(Cfg *Func, Variable *Dest, X8632::Traits::Cond::BrCond Cond);
1688 1689
1689 const X8632::Traits::Cond::BrCond Condition; 1690 const X8632::Traits::Cond::BrCond Condition;
1690 }; 1691 };
1691 1692
1692 // Exchanging Add instruction. Exchanges the first operand (destination 1693 /// Exchanging Add instruction. Exchanges the first operand (destination
1693 // operand) with the second operand (source operand), then loads the sum 1694 /// operand) with the second operand (source operand), then loads the sum
1694 // of the two values into the destination operand. The destination may be 1695 /// of the two values into the destination operand. The destination may be
1695 // a register or memory, while the source must be a register. 1696 /// a register or memory, while the source must be a register.
1696 // 1697 ///
1697 // Both the dest and source are updated. The caller should then insert a 1698 /// Both the dest and source are updated. The caller should then insert a
1698 // FakeDef to reflect the second udpate. 1699 /// FakeDef to reflect the second udpate.
1699 class InstX8632Xadd : public InstX8632Lockable { 1700 class InstX8632Xadd : public InstX8632Lockable {
1700 InstX8632Xadd() = delete; 1701 InstX8632Xadd() = delete;
1701 InstX8632Xadd(const InstX8632Xadd &) = delete; 1702 InstX8632Xadd(const InstX8632Xadd &) = delete;
1702 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete; 1703 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1703 1704
1704 public: 1705 public:
1705 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, 1706 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1706 bool Locked) { 1707 bool Locked) {
1707 return new (Func->allocate<InstX8632Xadd>()) 1708 return new (Func->allocate<InstX8632Xadd>())
1708 InstX8632Xadd(Func, Dest, Source, Locked); 1709 InstX8632Xadd(Func, Dest, Source, Locked);
1709 } 1710 }
1710 void emit(const Cfg *Func) const override; 1711 void emit(const Cfg *Func) const override;
1711 void emitIAS(const Cfg *Func) const override; 1712 void emitIAS(const Cfg *Func) const override;
1712 void dump(const Cfg *Func) const override; 1713 void dump(const Cfg *Func) const override;
1713 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } 1714 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1714 1715
1715 private: 1716 private:
1716 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); 1717 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
1717 }; 1718 };
1718 1719
1719 // Exchange instruction. Exchanges the first operand (destination 1720 /// Exchange instruction. Exchanges the first operand (destination
1720 // operand) with the second operand (source operand). At least one of 1721 /// operand) with the second operand (source operand). At least one of
1721 // the operands must be a register (and the other can be reg or mem). 1722 /// the operands must be a register (and the other can be reg or mem).
1722 // Both the Dest and Source are updated. If there is a memory operand, 1723 /// Both the Dest and Source are updated. If there is a memory operand,
1723 // then the instruction is automatically "locked" without the need for 1724 /// then the instruction is automatically "locked" without the need for
1724 // a lock prefix. 1725 /// a lock prefix.
1725 class InstX8632Xchg : public InstX8632 { 1726 class InstX8632Xchg : public InstX8632 {
1726 InstX8632Xchg() = delete; 1727 InstX8632Xchg() = delete;
1727 InstX8632Xchg(const InstX8632Xchg &) = delete; 1728 InstX8632Xchg(const InstX8632Xchg &) = delete;
1728 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete; 1729 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1729 1730
1730 public: 1731 public:
1731 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { 1732 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1732 return new (Func->allocate<InstX8632Xchg>()) 1733 return new (Func->allocate<InstX8632Xchg>())
1733 InstX8632Xchg(Func, Dest, Source); 1734 InstX8632Xchg(Func, Dest, Source);
1734 } 1735 }
1735 void emit(const Cfg *Func) const override; 1736 void emit(const Cfg *Func) const override;
1736 void emitIAS(const Cfg *Func) const override; 1737 void emitIAS(const Cfg *Func) const override;
1737 void dump(const Cfg *Func) const override; 1738 void dump(const Cfg *Func) const override;
1738 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); } 1739 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1739 1740
1740 private: 1741 private:
1741 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source); 1742 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
1742 }; 1743 };
1743 1744
1744 // Declare partial template specializations of emit() methods that 1745 /// Declare partial template specializations of emit() methods that
1745 // already have default implementations. Without this, there is the 1746 /// already have default implementations. Without this, there is the
1746 // possibility of ODR violations and link errors. 1747 /// possibility of ODR violations and link errors.
1747 template <> void InstX8632Addss::emit(const Cfg *Func) const; 1748 template <> void InstX8632Addss::emit(const Cfg *Func) const;
1748 template <> void InstX8632Blendvps::emit(const Cfg *Func) const; 1749 template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
1749 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const; 1750 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
1750 template <> void InstX8632Div::emit(const Cfg *Func) const; 1751 template <> void InstX8632Div::emit(const Cfg *Func) const;
1751 template <> void InstX8632Divss::emit(const Cfg *Func) const; 1752 template <> void InstX8632Divss::emit(const Cfg *Func) const;
1752 template <> void InstX8632Idiv::emit(const Cfg *Func) const; 1753 template <> void InstX8632Idiv::emit(const Cfg *Func) const;
1753 template <> void InstX8632Imul::emit(const Cfg *Func) const; 1754 template <> void InstX8632Imul::emit(const Cfg *Func) const;
1754 template <> void InstX8632Lea::emit(const Cfg *Func) const; 1755 template <> void InstX8632Lea::emit(const Cfg *Func) const;
1755 template <> void InstX8632Mulss::emit(const Cfg *Func) const; 1756 template <> void InstX8632Mulss::emit(const Cfg *Func) const;
1756 template <> void InstX8632Padd::emit(const Cfg *Func) const; 1757 template <> void InstX8632Padd::emit(const Cfg *Func) const;
(...skipping 24 matching lines...) Expand all
1781 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; 1782 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
1782 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; 1783 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const;
1783 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; 1784 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const;
1784 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; 1785 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
1785 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; 1786 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
1786 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; 1787 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
1787 1788
1788 } // end of namespace Ice 1789 } // end of namespace Ice
1789 1790
1790 #endif // SUBZERO_SRC_ICEINSTX8632_H 1791 #endif // SUBZERO_SRC_ICEINSTX8632_H
OLDNEW
« no previous file with comments | « src/IceInstMIPS32.h ('k') | src/IceInstX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698