| Index: src/IceInstX8632.h
|
| diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
|
| index 7ab8592a2daf6045bc5d3cb2f81c6032648e3506..514c37463394b548916ffd669b9cf88df3e39ac3 100644
|
| --- a/src/IceInstX8632.h
|
| +++ b/src/IceInstX8632.h
|
| @@ -16,6 +16,7 @@
|
| #ifndef SUBZERO_SRC_ICEINSTX8632_H
|
| #define SUBZERO_SRC_ICEINSTX8632_H
|
|
|
| +#include "assembler_ia32.h"
|
| #include "IceDefs.h"
|
| #include "IceInst.h"
|
| #include "IceConditionCodesX8632.h"
|
| @@ -75,6 +76,7 @@ public:
|
| Variable *getIndex() const { return Index; }
|
| uint16_t getShift() const { return Shift; }
|
| SegmentRegisters getSegmentRegister() const { return SegmentReg; }
|
| + x86::Address toAsmAddress(Assembler *Asm) const;
|
| virtual void emit(const Cfg *Func) const;
|
| using OperandX8632::dump;
|
| virtual void dump(const Cfg *Func, Ostream &Str) const;
|
| @@ -396,6 +398,7 @@ public:
|
| InstX8632AdjustStack(Func, Amount, Esp);
|
| }
|
| virtual void emit(const Cfg *Func) const;
|
| + virtual void emitIAS(const Cfg *Func) const;
|
| virtual void dump(const Cfg *Func) const;
|
| static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
|
|
|
| @@ -478,6 +481,7 @@ public:
|
| getSrc(0)->emit(Func);
|
| Str << "\n";
|
| }
|
| + virtual void emitIAS(const Cfg *Func) const { emit(Func); }
|
| virtual void dump(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrDump();
|
| dumpDest(Func);
|
| @@ -497,6 +501,52 @@ private:
|
| static const char *Opcode;
|
| };
|
|
|
| +void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
|
| + const Operand *Src,
|
| + const x86::AssemblerX86::TypedXmmEmitters &Emitter);
|
| +
|
| +template <InstX8632::InstKindX8632 K>
|
| +class InstX8632UnaryopXmm : public InstX8632 {
|
| +public:
|
| + static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
|
| + return new (Func->allocate<InstX8632UnaryopXmm>())
|
| + InstX8632UnaryopXmm(Func, Dest, Src);
|
| + }
|
| + virtual void emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + assert(getSrcSize() == 1);
|
| + Str << "\t" << Opcode << "\t";
|
| + getDest()->emit(Func);
|
| + Str << ", ";
|
| + getSrc(0)->emit(Func);
|
| + Str << "\n";
|
| + }
|
| + virtual void emitIAS(const Cfg *Func) const {
|
| + Type Ty = getDest()->getType();
|
| + assert(getSrcSize() == 1);
|
| + emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(0), Emitter);
|
| + }
|
| + 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:
|
| + InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
|
| + : InstX8632(Func, K, 1, Dest) {
|
| + addSource(Src);
|
| + }
|
| + InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION;
|
| + InstX8632UnaryopXmm &
|
| + operator=(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION;
|
| + virtual ~InstX8632UnaryopXmm() {}
|
| + static const char *Opcode;
|
| + static const x86::AssemblerX86::TypedXmmEmitters Emitter;
|
| +};
|
| +
|
| // See the definition of emitTwoAddress() for a description of
|
| // ShiftHack.
|
| void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
|
| @@ -533,6 +583,46 @@ private:
|
| static const char *Opcode;
|
| };
|
|
|
| +template <InstX8632::InstKindX8632 K, bool NeedsElementType>
|
| +class InstX8632BinopXmm : public InstX8632 {
|
| +public:
|
| + // Create an XMM binary-op instruction like addss or addps.
|
| + static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
|
| + return new (Func->allocate<InstX8632BinopXmm>())
|
| + InstX8632BinopXmm(Func, Dest, Source);
|
| + }
|
| + virtual void emit(const Cfg *Func) const {
|
| + const bool ShiftHack = false;
|
| + emitTwoAddress(Opcode, this, Func, ShiftHack);
|
| + }
|
| + virtual void emitIAS(const Cfg *Func) const {
|
| + Type Ty = getDest()->getType();
|
| + if (NeedsElementType)
|
| + Ty = typeElementType(Ty);
|
| + assert(getSrcSize() == 2);
|
| + emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(1), Emitter);
|
| + }
|
| + 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:
|
| + InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
|
| + : InstX8632(Func, K, 2, Dest) {
|
| + addSource(Dest);
|
| + addSource(Source);
|
| + }
|
| + InstX8632BinopXmm(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION;
|
| + InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION;
|
| + virtual ~InstX8632BinopXmm() {}
|
| + static const char *Opcode;
|
| + static const x86::AssemblerX86::TypedXmmEmitters Emitter;
|
| +};
|
| +
|
| template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
|
| public:
|
| // Create a ternary-op instruction like div or idiv.
|
| @@ -657,7 +747,7 @@ typedef InstX8632Unaryop<InstX8632::Bsf> InstX8632Bsf;
|
| typedef InstX8632Unaryop<InstX8632::Bsr> InstX8632Bsr;
|
| typedef InstX8632Unaryop<InstX8632::Lea> InstX8632Lea;
|
| typedef InstX8632Unaryop<InstX8632::Movd> InstX8632Movd;
|
| -typedef InstX8632Unaryop<InstX8632::Sqrtss> InstX8632Sqrtss;
|
| +typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss;
|
| // Cbwdq instruction - wrapper for cbw, cwd, and cdq
|
| typedef InstX8632Unaryop<InstX8632::Cbwdq> InstX8632Cbwdq;
|
| // Move/assignment instruction - wrapper for mov/movss/movsd.
|
| @@ -668,29 +758,29 @@ typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
|
| // Movq - copy between XMM registers, or mem64 and XMM registers.
|
| typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
|
| typedef InstX8632Binop<InstX8632::Add> InstX8632Add;
|
| -typedef InstX8632Binop<InstX8632::Addps> InstX8632Addps;
|
| +typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps;
|
| typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc;
|
| -typedef InstX8632Binop<InstX8632::Addss> InstX8632Addss;
|
| -typedef InstX8632Binop<InstX8632::Padd> InstX8632Padd;
|
| +typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss;
|
| +typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd;
|
| typedef InstX8632Binop<InstX8632::Sub> InstX8632Sub;
|
| -typedef InstX8632Binop<InstX8632::Subps> InstX8632Subps;
|
| -typedef InstX8632Binop<InstX8632::Subss> InstX8632Subss;
|
| +typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps;
|
| +typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss;
|
| typedef InstX8632Binop<InstX8632::Sbb> InstX8632Sbb;
|
| -typedef InstX8632Binop<InstX8632::Psub> InstX8632Psub;
|
| +typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub;
|
| typedef InstX8632Binop<InstX8632::And> InstX8632And;
|
| -typedef InstX8632Binop<InstX8632::Pand> InstX8632Pand;
|
| -typedef InstX8632Binop<InstX8632::Pandn> InstX8632Pandn;
|
| +typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand;
|
| +typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn;
|
| typedef InstX8632Binop<InstX8632::Or> InstX8632Or;
|
| -typedef InstX8632Binop<InstX8632::Por> InstX8632Por;
|
| +typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por;
|
| typedef InstX8632Binop<InstX8632::Xor> InstX8632Xor;
|
| -typedef InstX8632Binop<InstX8632::Pxor> InstX8632Pxor;
|
| +typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor;
|
| typedef InstX8632Binop<InstX8632::Imul> InstX8632Imul;
|
| -typedef InstX8632Binop<InstX8632::Mulps> InstX8632Mulps;
|
| -typedef InstX8632Binop<InstX8632::Mulss> InstX8632Mulss;
|
| +typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps;
|
| +typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss;
|
| typedef InstX8632Binop<InstX8632::Pmull> InstX8632Pmull;
|
| -typedef InstX8632Binop<InstX8632::Pmuludq> InstX8632Pmuludq;
|
| -typedef InstX8632Binop<InstX8632::Divps> InstX8632Divps;
|
| -typedef InstX8632Binop<InstX8632::Divss> InstX8632Divss;
|
| +typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq;
|
| +typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps;
|
| +typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss;
|
| typedef InstX8632Binop<InstX8632::Rol, true> InstX8632Rol;
|
| typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl;
|
| typedef InstX8632Binop<InstX8632::Psll> InstX8632Psll;
|
| @@ -828,6 +918,7 @@ public:
|
| InstX8632Cmpps(Func, Dest, Source, Condition);
|
| }
|
| virtual void emit(const Cfg *Func) const;
|
| + virtual void emitIAS(const Cfg *Func) const;
|
| virtual void dump(const Cfg *Func) const;
|
| static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
|
|
|
| @@ -941,6 +1032,7 @@ public:
|
| InstX8632Ucomiss(Func, Src1, Src2);
|
| }
|
| virtual void emit(const Cfg *Func) const;
|
| + virtual void emitIAS(const Cfg *Func) const;
|
| virtual void dump(const Cfg *Func) const;
|
| static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
|
|
|
| @@ -1108,6 +1200,7 @@ public:
|
| return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
|
| }
|
| virtual void emit(const Cfg *Func) const;
|
| + virtual void emitIAS(const Cfg *Func) const;
|
| virtual void dump(const Cfg *Func) const;
|
| static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
|
|
|
| @@ -1160,6 +1253,7 @@ public:
|
| return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
|
| }
|
| virtual void emit(const Cfg *Func) const;
|
| + virtual void emitIAS(const Cfg *Func) const;
|
| virtual void dump(const Cfg *Func) const;
|
| static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
|
|
|
| @@ -1199,6 +1293,7 @@ public:
|
| return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
|
| }
|
| virtual void emit(const Cfg *Func) const;
|
| + virtual void emitIAS(const Cfg *Func) const;
|
| virtual void dump(const Cfg *Func) const;
|
| static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
|
|
|
|
|