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

Unified Diff: src/IceInstX8632.cpp

Issue 595093002: Handle "inplace" ops and unary ops w/ assembler (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: format Created 6 years, 3 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/IceInstX8632.h ('k') | src/IceRegistersX8632.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceInstX8632.cpp
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index 3fd74f94beeae4e7de44eb76ebb1e2cc58ab66c0..72d75458f7153317f42bea8fcf30132c60be3bee 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -478,10 +478,66 @@ void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
Str << "\n";
}
+void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
+ const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ if (Var->hasReg()) {
+ // We cheat a little and use GPRRegister even for byte operations.
+ RegX8632::GPRRegister VarReg =
+ RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
+ (Asm->*(Emitter.Reg))(Ty, VarReg);
+ } else {
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(Var));
+ (Asm->*(Emitter.Addr))(Ty, StackAddr);
+ }
+ Ostream &Str = Func->getContext()->getStrEmit();
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
+void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
+ const Operand *Src,
+ const x86::AssemblerX86::GPREmitterRegOp &Emitter) {
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ assert(Var->hasReg());
+ // We cheat a little and use GPRRegister even for byte operations.
+ RegX8632::GPRRegister VarReg =
+ RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
+ if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ if (SrcVar->hasReg()) {
+ RegX8632::GPRRegister SrcReg;
+ if (Ty == IceType_i8 || Ty == IceType_i1) {
+ SrcReg = static_cast<RegX8632::GPRRegister>(
+ RegX8632::getEncodedByteReg(SrcVar->getRegNum()));
+ } else {
+ SrcReg = RegX8632::getEncodedGPR(SrcVar->getRegNum());
+ }
+ (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
+ } else {
+ x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(SrcVar);
+ (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
+ }
+ } else if (const OperandX8632Mem *Mem =
+ llvm::dyn_cast<OperandX8632Mem>(Src)) {
+ x86::Address SrcAddr = Mem->toAsmAddress(Asm);
+ (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr);
+ } else if (const ConstantInteger32 *Imm =
+ llvm::dyn_cast<ConstantInteger32>(Src)) {
+ (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
+ } else {
+ llvm_unreachable("Unexpected operand type");
+ }
+ Ostream &Str = Func->getContext()->getStrEmit();
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
void
emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
const Operand *Src,
- const x86::AssemblerX86::TypedXmmEmitters &Emitter) {
+ const x86::AssemblerX86::XmmEmitterTwoOps &Emitter) {
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
assert(Var->hasReg());
@@ -586,54 +642,75 @@ template <> const char *InstX8632Pblendvb::Opcode = "pblendvb";
template <> const char *InstX8632Pextr::Opcode = "pextr";
template <> const char *InstX8632Pshufd::Opcode = "pshufd";
+// Inplace GPR ops
+template <>
+const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = {
+ &x86::AssemblerX86::bswap, NULL /* only a reg form exists */};
+template <>
+const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = {
+ &x86::AssemblerX86::neg, &x86::AssemblerX86::neg};
+
+// Unary GPR ops
+template <>
+const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = {
+ &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL};
+template <>
+const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = {
+ &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL};
+template <>
+const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = {
+ /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL};
+
+// Unary XMM ops
+template <>
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = {
+ &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL};
+
// Binary XMM ops
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Addss::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = {
&x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Addps::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = {
&x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Divss::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = {
&x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Divps::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divps::Emitter = {
&x86::AssemblerX86::divps, &x86::AssemblerX86::divps, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulss::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulss::Emitter = {
&x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulps::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulps::Emitter = {
&x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Padd::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Padd::Emitter = {
&x86::AssemblerX86::padd, &x86::AssemblerX86::padd, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Pand::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pand::Emitter = {
&x86::AssemblerX86::pand, &x86::AssemblerX86::pand, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Pandn::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pandn::Emitter = {
&x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Pmuludq::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = {
&x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Por::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Por::Emitter = {
&x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Psub::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Psub::Emitter = {
&x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Pxor::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pxor::Emitter = {
&x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Sqrtss::Emitter = {
- &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL};
-template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Subss::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subss::Emitter = {
&x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL};
template <>
-const x86::AssemblerX86::TypedXmmEmitters InstX8632Subps::Emitter = {
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = {
&x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL};
template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
@@ -1125,7 +1202,7 @@ void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
assert(llvm::isa<Variable>(getSrc(0)));
const Variable *Src0 = llvm::cast<Variable>(getSrc(0));
Type Ty = Src0->getType();
- const static x86::AssemblerX86::TypedXmmEmitters Emitter = {
+ const static x86::AssemblerX86::XmmEmitterTwoOps Emitter = {
&x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss, NULL};
emitIASVarOperandTyXMM(Func, Ty, Src0, getSrc(1), Emitter);
}
@@ -1300,6 +1377,42 @@ template <> void InstX8632Mov::emit(const Cfg *Func) const {
}
}
+template <> void InstX8632Movd::emitIAS(const Cfg *Func) const {
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ assert(getSrcSize() == 1);
+ const Variable *Dest = getDest();
+ const Variable *Src = llvm::cast<Variable>(getSrc(0));
+ // For insert/extract element (one of Src/Dest is an Xmm vector and
+ // the other is an int type).
+ if (Src->getType() == IceType_i32) {
+ assert(isVectorType(Dest->getType()));
+ assert(Dest->hasReg());
+ RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
+ if (Src->hasReg()) {
+ Asm->movd(DestReg, RegX8632::getEncodedGPR(Src->getRegNum()));
+ } else {
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(Src));
+ Asm->movd(DestReg, StackAddr);
+ }
+ } else {
+ assert(isVectorType(Src->getType()));
+ assert(Src->hasReg());
+ assert(Dest->getType() == IceType_i32);
+ RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum());
+ if (Dest->hasReg()) {
+ Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg);
+ } else {
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(Dest));
+ Asm->movd(StackAddr, SrcReg);
+ }
+ }
+ Ostream &Str = Func->getContext()->getStrEmit();
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
template <> void InstX8632Movp::emit(const Cfg *Func) const {
// TODO(wala,stichnot): movups works with all vector operands, but
// there exist other instructions (movaps, movdqa, movdqu) that may
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceRegistersX8632.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698