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

Unified Diff: src/IceInstX8632.cpp

Issue 574133002: Add initial integrated assembler w/ some Xmm ops. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: remove duplicate pxor, and use enum 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/IceMemoryRegion.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 93c193f2785934204fc0e6d8b7ab2e92ffce11d4..8c6b99a65ff3d3dcb26428cbf9e6fcb90994a79c 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -12,6 +12,7 @@
//
//===----------------------------------------------------------------------===//
+#include "assembler_ia32.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceConditionCodesX8632.h"
@@ -331,6 +332,47 @@ InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source)
// ======================== Dump routines ======================== //
+namespace {
+
+void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm,
+ intptr_t StartPosition) {
+ intptr_t EndPosition = Asm->GetPosition();
+ intptr_t LastFixupLoc = -1;
+ AssemblerFixup *LastFixup = NULL;
+ if (Asm->GetLatestFixup()) {
+ LastFixup = Asm->GetLatestFixup();
+ LastFixupLoc = LastFixup->position();
+ }
+ if (LastFixupLoc < StartPosition) {
+ // The fixup doesn't apply to this current block.
+ for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) {
+ Str << "\t.byte "
+ << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i))
+ << "\n";
+ }
+ return;
+ }
+ const intptr_t FixupSize = 4;
+ assert(LastFixupLoc + FixupSize <= EndPosition);
+ // The fixup does apply to this current block.
+ for (intptr_t i = 0; i < LastFixupLoc - StartPosition; ++i) {
+ Str << "\t.byte "
+ << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i))
+ << "\n";
+ }
+ Str << "\t.long " << LastFixup->value()->getName();
+ if (LastFixup->value()->getOffset()) {
+ Str << " + " << LastFixup->value()->getOffset();
+ }
+ Str << "\n";
+ for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) {
+ Str << "\t.byte " << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(i))
+ << "\n";
+ }
+}
+
+} // end of anonymous namespace
+
void InstX8632::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Str << "[X8632] ";
@@ -436,6 +478,38 @@ void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
Str << "\n";
}
+void
+emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
+ const Operand *Src,
+ const x86::AssemblerX86::TypedXmmEmitters &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 Constant *Imm = llvm::dyn_cast<Constant>(Src)) {
+ (Asm->*(Emitter.XmmAddr))(
+ Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
+ } else {
+ llvm_unreachable("Unexpected operand type");
+ }
+ Ostream &Str = Func->getContext()->getStrEmit();
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) {
const Variable *Src = llvm::dyn_cast<const Variable>(Source);
if (Src == NULL)
@@ -512,6 +586,56 @@ template <> const char *InstX8632Pblendvb::Opcode = "pblendvb";
template <> const char *InstX8632Pextr::Opcode = "pextr";
template <> const char *InstX8632Pshufd::Opcode = "pshufd";
+// Binary XMM ops
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Addss::Emitter = {
+ &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Addps::Emitter = {
+ &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Divss::Emitter = {
+ &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Divps::Emitter = {
+ &x86::AssemblerX86::divps, &x86::AssemblerX86::divps, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulss::Emitter = {
+ &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulps::Emitter = {
+ &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Padd::Emitter = {
+ &x86::AssemblerX86::padd, &x86::AssemblerX86::padd, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Pand::Emitter = {
+ &x86::AssemblerX86::pand, &x86::AssemblerX86::pand, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Pandn::Emitter = {
+ &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Pmuludq::Emitter = {
+ &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Por::Emitter = {
+ &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Psub::Emitter = {
+ &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters 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 = {
+ &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL};
+template <>
+const x86::AssemblerX86::TypedXmmEmitters InstX8632Subps::Emitter = {
+ &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL};
+
template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 1);
@@ -790,6 +914,28 @@ void InstX8632Cmpps::emit(const Cfg *Func) const {
Str << "\n";
}
+void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrEmit();
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ assert(getSrcSize() == 2);
+ assert(Condition < CondX86::Cmpps_Invalid);
+ // Assuming there isn't any load folding for cmpps, and vector constants
+ // are not allowed in PNaCl.
+ assert(llvm::isa<Variable>(getSrc(1)));
+ const Variable *SrcVar = llvm::cast<Variable>(getSrc(1));
+ if (SrcVar->hasReg()) {
+ Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()),
+ RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition);
+ } else {
+ x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(SrcVar);
+ Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr,
+ Condition);
+ }
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
void InstX8632Cmpps::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
assert(Condition < CondX86::Cmpps_Invalid);
@@ -893,6 +1039,18 @@ void InstX8632Ucomiss::emit(const Cfg *Func) const {
Str << "\n";
}
+void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 2);
+ // Currently src0 is always a variable by convention, to avoid having
+ // two memory operands.
+ assert(llvm::isa<Variable>(getSrc(0)));
+ const Variable *Src0 = llvm::cast<Variable>(getSrc(0));
+ Type Ty = Src0->getType();
+ const static x86::AssemblerX86::TypedXmmEmitters Emitter = {
+ &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss, NULL};
+ emitIASVarOperandTyXMM(Func, Ty, Src0, getSrc(1), Emitter);
+}
+
void InstX8632Ucomiss::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Str << "ucomiss." << getSrc(0)->getType() << " ";
@@ -1133,6 +1291,15 @@ void InstX8632Nop::emit(const Cfg *Func) const {
Str << "\tnop\t# variant = " << Variant << "\n";
}
+void InstX8632Nop::emitIAS(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrEmit();
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ // TODO: Emit the right code for the variant.
+ Asm->nop();
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
void InstX8632Nop::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Str << "nop (variant = " << Variant << ")";
@@ -1272,6 +1439,20 @@ void InstX8632Pop::emit(const Cfg *Func) const {
Str << "\n";
}
+void InstX8632Pop::emitIAS(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 0);
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ if (getDest()->hasReg()) {
+ Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum()));
+ } else {
+ Asm->popl(static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(getDest()));
+ }
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
void InstX8632Pop::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
dumpDest(Func);
@@ -1284,6 +1465,15 @@ void InstX8632AdjustStack::emit(const Cfg *Func) const {
Func->getTarget()->updateStackAdjustment(Amount);
}
+void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrEmit();
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ Asm->subl(RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
+ emitIASBytes(Str, Asm, StartPosition);
+ Func->getTarget()->updateStackAdjustment(Amount);
+}
+
void InstX8632AdjustStack::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Str << "esp = sub.i32 esp, " << Amount;
@@ -1356,6 +1546,14 @@ void InstX8632Ret::emit(const Cfg *Func) const {
Str << "\tret\n";
}
+void InstX8632Ret::emitIAS(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrEmit();
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ Asm->ret();
+ emitIASBytes(Str, Asm, StartPosition);
+}
+
void InstX8632Ret::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
@@ -1498,6 +1696,41 @@ void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
Str << "]";
}
+x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
+ int32_t Disp = 0;
+ AssemblerFixup *Fixup = NULL;
+ // Determine the offset (is it relocatable?)
+ if (getOffset()) {
+ if (ConstantInteger32 *CI =
+ llvm::dyn_cast<ConstantInteger32>(getOffset())) {
+ Disp = static_cast<int32_t>(CI->getValue());
+ } else if (ConstantRelocatable *CR =
+ llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
+ // TODO(jvoung): CR + non-zero-offset isn't really tested yet,
+ // since the addressing mode optimization doesn't try to combine
+ // ConstantRelocatable with something else.
+ assert(CR->getOffset() == 0);
+ Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR);
+ } else {
+ llvm_unreachable("Unexpected offset type");
+ }
+ }
+
+ // Now convert to the various possible forms.
+ if (getBase() && getIndex()) {
+ return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()),
+ RegX8632::getEncodedGPR(getIndex()->getRegNum()),
+ x86::ScaleFactor(getShift()), Disp);
+ } else if (getBase()) {
+ return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp);
+ } else if (getIndex()) {
+ return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()),
+ x86::ScaleFactor(getShift()), Disp);
+ } else {
+ return x86::Address::Absolute(Disp, Fixup);
+ }
+}
+
void VariableSplit::emit(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(!Var->hasReg());
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceMemoryRegion.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698