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

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

Powered by Google App Engine
This is Rietveld 408576698