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

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

Powered by Google App Engine
This is Rietveld 408576698