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

Unified Diff: src/IceInstX8632.h

Issue 265703002: Add Om1 lowering with no optimizations (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Merge changed from Karl's committed CL Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceInst.def ('k') | src/IceInstX8632.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceInstX8632.h
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a6f14a9efe5cce8a3d7e2ebfb3ea8e6dccbb2c0
--- /dev/null
+++ b/src/IceInstX8632.h
@@ -0,0 +1,720 @@
+//===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the InstX8632 and OperandX8632 classes and
+// their subclasses. This represents the machine instructions and
+// operands used for x86-32 code selection.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEINSTX8632_H
+#define SUBZERO_SRC_ICEINSTX8632_H
+
+#include "IceDefs.h"
+#include "IceInst.h"
+#include "IceInstX8632.def"
+#include "IceOperand.h"
+
+namespace Ice {
+
+class TargetX8632;
+
+// OperandX8632 extends the Operand hierarchy. Its subclasses are
+// OperandX8632Mem and VariableSplit.
+class OperandX8632 : public Operand {
+public:
+ enum OperandKindX8632 {
+ k__Start = Operand::kTarget,
+ kMem,
+ kSplit
+ };
+ virtual void emit(const Cfg *Func) const = 0;
+ void dump(const Cfg *Func) const;
+
+protected:
+ OperandX8632(OperandKindX8632 Kind, Type Ty)
+ : Operand(static_cast<OperandKind>(Kind), Ty) {}
+ virtual ~OperandX8632() {}
+
+private:
+ OperandX8632(const OperandX8632 &) LLVM_DELETED_FUNCTION;
+ OperandX8632 &operator=(const OperandX8632 &) LLVM_DELETED_FUNCTION;
+};
+
+// OperandX8632Mem represents the m32 addressing mode, with optional
+// base and index registers, a constant offset, and a fixed shift
+// value for the index register.
+class OperandX8632Mem : public OperandX8632 {
+public:
+ static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base,
+ Constant *Offset, Variable *Index = NULL,
+ uint32_t Shift = 0) {
+ return new (Func->allocate<OperandX8632Mem>())
+ OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift);
+ }
+ Variable *getBase() const { return Base; }
+ Constant *getOffset() const { return Offset; }
+ Variable *getIndex() const { return Index; }
+ uint32_t getShift() const { return Shift; }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+
+ static bool classof(const Operand *Operand) {
+ return Operand->getKind() == static_cast<OperandKind>(kMem);
+ }
+
+private:
+ OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
+ Variable *Index, uint32_t Shift);
+ OperandX8632Mem(const OperandX8632Mem &) LLVM_DELETED_FUNCTION;
+ OperandX8632Mem &operator=(const OperandX8632Mem &) LLVM_DELETED_FUNCTION;
+ virtual ~OperandX8632Mem() {}
+ Variable *Base;
+ Constant *Offset;
+ Variable *Index;
+ uint32_t Shift;
+};
+
+// VariableSplit is a way to treat an f64 memory location as a pair
+// of i32 locations (Low and High). This is needed for some cases
+// of the Bitcast instruction. Since it's not possible for integer
+// registers to access the XMM registers and vice versa, the
+// lowering forces the f64 to be spilled to the stack and then
+// accesses through the VariableSplit.
+class VariableSplit : public OperandX8632 {
+public:
+ enum Portion {
+ Low,
+ High
+ };
+ static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
+ return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+
+ static bool classof(const Operand *Operand) {
+ return Operand->getKind() == static_cast<OperandKind>(kSplit);
+ }
+
+private:
+ VariableSplit(Cfg *Func, Variable *Var, Portion Part)
+ : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) {
+ assert(Var->getType() == IceType_f64);
+ Vars = Func->allocateArrayOf<Variable *>(1);
+ Vars[0] = Var;
+ NumVars = 1;
+ }
+ VariableSplit(const VariableSplit &) LLVM_DELETED_FUNCTION;
+ VariableSplit &operator=(const VariableSplit &) LLVM_DELETED_FUNCTION;
+ virtual ~VariableSplit() { Func->deallocateArrayOf<Variable *>(Vars); }
+ Cfg *Func; // Held only for the destructor.
+ Variable *Var;
+ Portion Part;
+};
+
+class InstX8632 : public InstTarget {
+public:
+ enum InstKindX8632 {
+ k__Start = Inst::Target,
+ Adc,
+ Add,
+ Addss,
+ And,
+ Br,
+ Call,
+ Cdq,
+ Cvt,
+ Div,
+ Divss,
+ Fld,
+ Fstp,
+ Icmp,
+ Idiv,
+ Imul,
+ Label,
+ Load,
+ Mov,
+ Movsx,
+ Movzx,
+ Mul,
+ Mulss,
+ Or,
+ Pop,
+ Push,
+ Ret,
+ Sar,
+ Sbb,
+ Shl,
+ Shld,
+ Shr,
+ Shrd,
+ Store,
+ Sub,
+ Subss,
+ Test,
+ Ucomiss,
+ Xor
+ };
+ static const char *getWidthString(Type Ty);
+ virtual void emit(const Cfg *Func) const = 0;
+ virtual void dump(const Cfg *Func) const;
+
+protected:
+ InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
+ : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
+ virtual ~InstX8632() {}
+ static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
+ return Inst->getKind() == static_cast<InstKind>(MyKind);
+ }
+
+private:
+ InstX8632(const InstX8632 &) LLVM_DELETED_FUNCTION;
+ InstX8632 &operator=(const InstX8632 &) LLVM_DELETED_FUNCTION;
+};
+
+// InstX8632Label represents an intra-block label that is the
+// target of an intra-block branch. These are used for lowering i1
+// calculations, Select instructions, and 64-bit compares on a 32-bit
+// architecture, without basic block splitting. Basic block splitting
+// is not so desirable for several reasons, one of which is the impact
+// on decisions based on whether a variable's live range spans
+// multiple basic blocks.
+//
+// Intra-block control flow must be used with caution. Consider the
+// sequence for "c = (a >= b ? x : y)".
+// cmp a, b
+// br lt, L1
+// mov c, x
+// jmp L2
+// L1:
+// mov c, y
+// L2:
+//
+// Labels L1 and L2 are intra-block labels. Without knowledge of the
+// intra-block control flow, liveness analysis will determine the "mov
+// c, x" instruction to be dead. One way to prevent this is to insert
+// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
+// instructions, e.g.:
+//
+// cmp a, b
+// br lt, L1
+// mov c, x
+// jmp L2
+// FakeUse(c)
+// L1:
+// mov c, y
+// L2:
+//
+// The down-side is that "mov c, x" can never be dead-code eliminated
+// even if there are no uses of c. As unlikely as this situation is,
+// it may be prevented by running dead code elimination before
+// lowering.
+class InstX8632Label : public InstX8632 {
+public:
+ static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
+ return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
+ }
+ IceString getName(const Cfg *Func) const;
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+
+private:
+ InstX8632Label(Cfg *Func, TargetX8632 *Target);
+ InstX8632Label(const InstX8632Label &) LLVM_DELETED_FUNCTION;
+ InstX8632Label &operator=(const InstX8632Label &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Label() {}
+ SizeT Number; // used only for unique label string generation
+};
+
+// Conditional and unconditional branch instruction.
+class InstX8632Br : public InstX8632 {
+public:
+ enum BrCond {
+#define X(tag, dump, emit) tag,
+ ICEINSTX8632BR_TABLE
+#undef X
+ Br_None
+ };
+
+ // Create a conditional branch to a node.
+ static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
+ CfgNode *TargetFalse, BrCond Condition) {
+ return new (Func->allocate<InstX8632Br>())
+ InstX8632Br(Func, TargetTrue, TargetFalse, NULL, Condition);
+ }
+ // Create an unconditional branch to a node.
+ static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
+ return new (Func->allocate<InstX8632Br>())
+ InstX8632Br(Func, NULL, Target, NULL, Br_None);
+ }
+ // Create a non-terminator conditional branch to a node, with a
+ // fallthrough to the next instruction in the current node. This is
+ // used for switch lowering.
+ static InstX8632Br *create(Cfg *Func, CfgNode *Target, BrCond Condition) {
+ return new (Func->allocate<InstX8632Br>())
+ InstX8632Br(Func, Target, NULL, NULL, Condition);
+ }
+ // Create a conditional intra-block branch (or unconditional, if
+ // Condition==None) to a label in the current block.
+ static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
+ BrCond Condition) {
+ return new (Func->allocate<InstX8632Br>())
+ InstX8632Br(Func, NULL, NULL, Label, Condition);
+ }
+ CfgNode *getTargetTrue() const { return TargetTrue; }
+ CfgNode *getTargetFalse() const { return TargetFalse; }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
+
+private:
+ InstX8632Br(Cfg *Func, CfgNode *TargetTrue, CfgNode *TargetFalse,
+ InstX8632Label *Label, BrCond Condition);
+ InstX8632Br(const InstX8632Br &) LLVM_DELETED_FUNCTION;
+ InstX8632Br &operator=(const InstX8632Br &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Br() {}
+ BrCond Condition;
+ CfgNode *TargetTrue;
+ CfgNode *TargetFalse;
+ InstX8632Label *Label; // Intra-block branch target
+};
+
+// Call instruction. Arguments should have already been pushed.
+class InstX8632Call : public InstX8632 {
+public:
+ static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
+ return new (Func->allocate<InstX8632Call>())
+ InstX8632Call(Func, Dest, CallTarget);
+ }
+ Operand *getCallTarget() const { return getSrc(0); }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
+
+private:
+ InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
+ InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION;
+ InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Call() {}
+};
+
+// See the definition of emitTwoAddress() for a description of
+// ShiftHack.
+void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
+ bool ShiftHack = false);
+
+template <InstX8632::InstKindX8632 K, bool ShiftHack = false>
+class InstX8632Binop : public InstX8632 {
+public:
+ // Create an ordinary binary-op instruction like add or sub.
+ static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) {
+ return new (Func->allocate<InstX8632Binop>())
+ InstX8632Binop(Func, Dest, Source);
+ }
+ virtual void emit(const Cfg *Func) const {
+ emitTwoAddress(Opcode, this, Func, ShiftHack);
+ }
+ virtual void dump(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrDump();
+ dumpDest(Func);
+ Str << " = " << Opcode << "." << getDest()->getType() << " ";
+ dumpSources(Func);
+ }
+ static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
+
+private:
+ InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source)
+ : InstX8632(Func, K, 2, Dest) {
+ addSource(Dest);
+ addSource(Source);
+ }
+ InstX8632Binop(const InstX8632Binop &) LLVM_DELETED_FUNCTION;
+ InstX8632Binop &operator=(const InstX8632Binop &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Binop() {}
+ static const char *Opcode;
+};
+
+template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
+public:
+ // Create a ternary-op instruction like div or idiv.
+ static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
+ Operand *Source2) {
+ return new (Func->allocate<InstX8632Ternop>())
+ InstX8632Ternop(Func, Dest, Source1, Source2);
+ }
+ virtual void emit(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 3);
+ Str << "\t" << Opcode << "\t";
+ getSrc(1)->emit(Func);
+ Str << "\n";
+ }
+ virtual void dump(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrDump();
+ dumpDest(Func);
+ Str << " = " << Opcode << "." << getDest()->getType() << " ";
+ dumpSources(Func);
+ }
+ static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
+
+private:
+ InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+ : InstX8632(Func, K, 3, Dest) {
+ addSource(Dest);
+ addSource(Source1);
+ addSource(Source2);
+ }
+ InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION;
+ InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Ternop() {}
+ static const char *Opcode;
+};
+
+typedef InstX8632Binop<InstX8632::Add> InstX8632Add;
+typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc;
+typedef InstX8632Binop<InstX8632::Addss> InstX8632Addss;
+typedef InstX8632Binop<InstX8632::Sub> InstX8632Sub;
+typedef InstX8632Binop<InstX8632::Subss> InstX8632Subss;
+typedef InstX8632Binop<InstX8632::Sbb> InstX8632Sbb;
+typedef InstX8632Binop<InstX8632::And> InstX8632And;
+typedef InstX8632Binop<InstX8632::Or> InstX8632Or;
+typedef InstX8632Binop<InstX8632::Xor> InstX8632Xor;
+typedef InstX8632Binop<InstX8632::Imul> InstX8632Imul;
+typedef InstX8632Binop<InstX8632::Mulss> InstX8632Mulss;
+typedef InstX8632Binop<InstX8632::Divss> InstX8632Divss;
+typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl;
+typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr;
+typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar;
+typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
+typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
+
+// Mul instruction - unsigned multiply.
+class InstX8632Mul : public InstX8632 {
+public:
+ static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
+ Operand *Source2) {
+ return new (Func->allocate<InstX8632Mul>())
+ InstX8632Mul(Func, Dest, Source1, Source2);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
+
+private:
+ InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
+ InstX8632Mul(const InstX8632Mul &) LLVM_DELETED_FUNCTION;
+ InstX8632Mul &operator=(const InstX8632Mul &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Mul() {}
+};
+
+// Shld instruction - shift across a pair of operands. TODO: Verify
+// that the validator accepts the shld instruction.
+class InstX8632Shld : public InstX8632 {
+public:
+ static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
+ Variable *Source2) {
+ return new (Func->allocate<InstX8632Shld>())
+ InstX8632Shld(Func, Dest, Source1, Source2);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
+
+private:
+ InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
+ Variable *Source2);
+ InstX8632Shld(const InstX8632Shld &) LLVM_DELETED_FUNCTION;
+ InstX8632Shld &operator=(const InstX8632Shld &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Shld() {}
+};
+
+// Shrd instruction - shift across a pair of operands. TODO: Verify
+// that the validator accepts the shrd instruction.
+class InstX8632Shrd : public InstX8632 {
+public:
+ static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
+ Variable *Source2) {
+ return new (Func->allocate<InstX8632Shrd>())
+ InstX8632Shrd(Func, Dest, Source1, Source2);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
+
+private:
+ InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
+ Variable *Source2);
+ InstX8632Shrd(const InstX8632Shrd &) LLVM_DELETED_FUNCTION;
+ InstX8632Shrd &operator=(const InstX8632Shrd &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Shrd() {}
+};
+
+// Cdq instruction - sign-extend eax into edx
+class InstX8632Cdq : public InstX8632 {
+public:
+ static InstX8632Cdq *create(Cfg *Func, Variable *Dest, Operand *Source) {
+ return new (Func->allocate<InstX8632Cdq>())
+ InstX8632Cdq(Func, Dest, Source);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Cdq); }
+
+private:
+ InstX8632Cdq(Cfg *Func, Variable *Dest, Operand *Source);
+ InstX8632Cdq(const InstX8632Cdq &) LLVM_DELETED_FUNCTION;
+ InstX8632Cdq &operator=(const InstX8632Cdq &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Cdq() {}
+};
+
+// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
+// as appropriate. s=float, d=double, i=int. X and Y are determined
+// from dest/src types. Sign and zero extension on the integer
+// operand needs to be done separately.
+class InstX8632Cvt : public InstX8632 {
+public:
+ static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source) {
+ return new (Func->allocate<InstX8632Cvt>())
+ InstX8632Cvt(Func, Dest, Source);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
+
+private:
+ InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source);
+ InstX8632Cvt(const InstX8632Cvt &) LLVM_DELETED_FUNCTION;
+ InstX8632Cvt &operator=(const InstX8632Cvt &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Cvt() {}
+};
+
+// cmp - Integer compare instruction.
+class InstX8632Icmp : public InstX8632 {
+public:
+ static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
+ return new (Func->allocate<InstX8632Icmp>())
+ InstX8632Icmp(Func, Src1, Src2);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
+
+private:
+ InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
+ InstX8632Icmp(const InstX8632Icmp &) LLVM_DELETED_FUNCTION;
+ InstX8632Icmp &operator=(const InstX8632Icmp &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Icmp() {}
+};
+
+// ucomiss/ucomisd - floating-point compare instruction.
+class InstX8632Ucomiss : public InstX8632 {
+public:
+ static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
+ return new (Func->allocate<InstX8632Ucomiss>())
+ InstX8632Ucomiss(Func, Src1, Src2);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
+
+private:
+ InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
+ InstX8632Ucomiss(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION;
+ InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Ucomiss() {}
+};
+
+// Test instruction.
+class InstX8632Test : public InstX8632 {
+public:
+ static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
+ return new (Func->allocate<InstX8632Test>())
+ InstX8632Test(Func, Source1, Source2);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
+
+private:
+ InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
+ InstX8632Test(const InstX8632Test &) LLVM_DELETED_FUNCTION;
+ InstX8632Test &operator=(const InstX8632Test &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Test() {}
+};
+
+// This is essentially a "mov" instruction with an OperandX8632Mem
+// operand instead of Variable as the destination. It's important
+// for liveness that there is no Dest operand.
+class InstX8632Store : public InstX8632 {
+public:
+ static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
+ return new (Func->allocate<InstX8632Store>())
+ InstX8632Store(Func, Value, Mem);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
+
+private:
+ InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
+ InstX8632Store(const InstX8632Store &) LLVM_DELETED_FUNCTION;
+ InstX8632Store &operator=(const InstX8632Store &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Store() {}
+};
+
+// Move/assignment instruction - wrapper for mov/movss/movsd.
+class InstX8632Mov : public InstX8632 {
+public:
+ static InstX8632Mov *create(Cfg *Func, Variable *Dest, Operand *Source) {
+ return new (Func->allocate<InstX8632Mov>())
+ InstX8632Mov(Func, Dest, Source);
+ }
+ virtual bool isRedundantAssign() const;
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Mov); }
+
+private:
+ InstX8632Mov(Cfg *Func, Variable *Dest, Operand *Source);
+ InstX8632Mov(const InstX8632Mov &) LLVM_DELETED_FUNCTION;
+ InstX8632Mov &operator=(const InstX8632Mov &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Mov() {}
+};
+
+// Movsx - copy from a narrower integer type to a wider integer
+// type, with sign extension.
+class InstX8632Movsx : public InstX8632 {
+public:
+ static InstX8632Movsx *create(Cfg *Func, Variable *Dest, Operand *Source) {
+ return new (Func->allocate<InstX8632Movsx>())
+ InstX8632Movsx(Func, Dest, Source);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Movsx); }
+
+private:
+ InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source);
+ InstX8632Movsx(const InstX8632Movsx &) LLVM_DELETED_FUNCTION;
+ InstX8632Movsx &operator=(const InstX8632Movsx &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Movsx() {}
+};
+
+// Movsx - copy from a narrower integer type to a wider integer
+// type, with zero extension.
+class InstX8632Movzx : public InstX8632 {
+public:
+ static InstX8632Movzx *create(Cfg *Func, Variable *Dest, Operand *Source) {
+ return new (Func->allocate<InstX8632Movzx>())
+ InstX8632Movzx(Func, Dest, Source);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Movzx); }
+
+private:
+ InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source);
+ InstX8632Movzx(const InstX8632Movzx &) LLVM_DELETED_FUNCTION;
+ InstX8632Movzx &operator=(const InstX8632Movzx &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Movzx() {}
+};
+
+// Fld - load a value onto the x87 FP stack.
+class InstX8632Fld : public InstX8632 {
+public:
+ static InstX8632Fld *create(Cfg *Func, Operand *Src) {
+ return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
+
+private:
+ InstX8632Fld(Cfg *Func, Operand *Src);
+ InstX8632Fld(const InstX8632Fld &) LLVM_DELETED_FUNCTION;
+ InstX8632Fld &operator=(const InstX8632Fld &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Fld() {}
+};
+
+// Fstp - store x87 st(0) into memory and pop st(0).
+class InstX8632Fstp : public InstX8632 {
+public:
+ static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
+ return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
+
+private:
+ InstX8632Fstp(Cfg *Func, Variable *Dest);
+ InstX8632Fstp(const InstX8632Fstp &) LLVM_DELETED_FUNCTION;
+ InstX8632Fstp &operator=(const InstX8632Fstp &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Fstp() {}
+};
+
+class InstX8632Pop : public InstX8632 {
+public:
+ static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
+ return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
+
+private:
+ InstX8632Pop(Cfg *Func, Variable *Dest);
+ InstX8632Pop(const InstX8632Pop &) LLVM_DELETED_FUNCTION;
+ InstX8632Pop &operator=(const InstX8632Pop &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Pop() {}
+};
+
+class InstX8632Push : public InstX8632 {
+public:
+ static InstX8632Push *create(Cfg *Func, Operand *Source,
+ bool SuppressStackAdjustment) {
+ return new (Func->allocate<InstX8632Push>())
+ InstX8632Push(Func, Source, SuppressStackAdjustment);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
+
+private:
+ InstX8632Push(Cfg *Func, Operand *Source, bool SuppressStackAdjustment);
+ InstX8632Push(const InstX8632Push &) LLVM_DELETED_FUNCTION;
+ InstX8632Push &operator=(const InstX8632Push &) LLVM_DELETED_FUNCTION;
+ bool SuppressStackAdjustment;
+ virtual ~InstX8632Push() {}
+};
+
+// Ret instruction. Currently only supports the "ret" version that
+// does not pop arguments. This instruction takes a Source operand
+// (for non-void returning functions) for liveness analysis, though
+// a FakeUse before the ret would do just as well.
+class InstX8632Ret : public InstX8632 {
+public:
+ static InstX8632Ret *create(Cfg *Func, Variable *Source = NULL) {
+ return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
+ }
+ virtual void emit(const Cfg *Func) const;
+ virtual void dump(const Cfg *Func) const;
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
+
+private:
+ InstX8632Ret(Cfg *Func, Variable *Source);
+ InstX8632Ret(const InstX8632Ret &) LLVM_DELETED_FUNCTION;
+ InstX8632Ret &operator=(const InstX8632Ret &) LLVM_DELETED_FUNCTION;
+ virtual ~InstX8632Ret() {}
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEINSTX8632_H
« no previous file with comments | « src/IceInst.def ('k') | src/IceInstX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698