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

Unified Diff: src/IceInstX8632.cpp

Issue 622113002: Handle GPR and vector shift ops. Handle pmull also. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: test encodings Created 6 years, 2 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/assembler_ia32.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 ab323350e5649774e8ff46e0e47e4a1997c375f8..8930a17a634df5632b8f8d914d0b0fef059c2356 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -536,6 +536,65 @@ void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
emitIASBytes(Str, Asm, StartPosition);
}
+void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
+ const Operand *Src,
+ const x86::AssemblerX86::GPREmitterShiftOp &Emitter) {
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ // Technically, the Dest Var can be mem as well, but we only use Reg.
+ // We can extend this to check Dest if we decide to use that form.
+ assert(Var->hasReg());
+ // We cheat a little and use GPRRegister even for byte operations.
+ RegX8632::GPRRegister VarReg =
+ RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
+ // Src must be reg == ECX or an Imm8.
+ // This is asserted by the assembler.
+ if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ assert(SrcVar->hasReg());
+ RegX8632::GPRRegister SrcReg =
+ RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
+ (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
+ } 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 emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
+ const Operand *Src,
+ const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) {
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ assert(Var->hasReg());
+ RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum());
+ if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) {
+ if (SrcVar->hasReg()) {
+ RegX8632::XmmRegister SrcReg =
+ RegX8632::getEncodedXmm(SrcVar->getRegNum());
+ (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
+ } else {
+ x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(SrcVar);
+ (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
+ }
+ } else if (const OperandX8632Mem *Mem =
+ llvm::dyn_cast<OperandX8632Mem>(Src)) {
+ x86::Address SrcAddr = Mem->toAsmAddress(Asm);
+ (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr);
+ } else if (const ConstantInteger32 *Imm =
+ llvm::dyn_cast<ConstantInteger32>(Src)) {
+ (Asm->*(Emitter.XmmImm))(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,
@@ -691,6 +750,20 @@ template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = {
&x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor};
+// Binary Shift GPR ops
+template <>
+const x86::AssemblerX86::GPREmitterShiftOp InstX8632Rol::Emitter = {
+ &x86::AssemblerX86::rol, &x86::AssemblerX86::rol};
+template <>
+const x86::AssemblerX86::GPREmitterShiftOp InstX8632Sar::Emitter = {
+ &x86::AssemblerX86::sar, &x86::AssemblerX86::sar};
+template <>
+const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = {
+ &x86::AssemblerX86::shl, &x86::AssemblerX86::shl};
+template <>
+const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = {
+ &x86::AssemblerX86::shr, &x86::AssemblerX86::shr};
+
// Binary XMM ops
template <>
const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = {
@@ -726,6 +799,9 @@ template <>
const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpgt::Emitter = {
&x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt, NULL};
template <>
+const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmull::Emitter = {
+ &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull, NULL};
+template <>
const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = {
&x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL};
template <>
@@ -744,6 +820,16 @@ template <>
const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = {
&x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL};
+// Binary XMM Shift ops
+template <>
+const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = {
+ &x86::AssemblerX86::psll, &x86::AssemblerX86::psll,
+ &x86::AssemblerX86::psll};
+template <>
+const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = {
+ &x86::AssemblerX86::psra, &x86::AssemblerX86::psra,
+ &x86::AssemblerX86::psra};
+
template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 1);
@@ -787,6 +873,22 @@ template <> void InstX8632Pmull::emit(const Cfg *Func) const {
emitTwoAddress(buf, this, Func);
}
+template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const {
+ Type Ty = getDest()->getType();
+ bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16;
+ bool InstructionSetIsValid =
+ Ty == IceType_v8i16 ||
+ static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
+ TargetX8632::SSE4_1;
+ (void)TypesAreValid;
+ (void)InstructionSetIsValid;
+ assert(TypesAreValid);
+ assert(InstructionSetIsValid);
+ assert(getSrcSize() == 2);
+ Type ElementTy = typeElementType(Ty);
+ emitIASVarOperandTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter);
+}
+
template <> void InstX8632Subss::emit(const Cfg *Func) const {
char buf[30];
snprintf(buf, llvm::array_lengthof(buf), "sub%s",
« no previous file with comments | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698