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 647193003: emitIAS for store and indirect calls. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: stuff 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
« src/IceInst.h ('K') | « 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 e41fe8227684ca626a5d87d74f596864e81c18d1..dbacd58a87bdcb65a911de3849a96ea7c20692c6 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -447,6 +447,52 @@ void InstX8632Call::emit(const Cfg *Func) const {
Func->getTarget()->resetStackAdjustment();
}
+void InstX8632Call::emitIAS(const Cfg *Func) const {
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ Operand *Target = getCallTarget();
+ bool NeedsFallback = false;
+ if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
+ if (Var->hasReg()) {
+ Asm->call(RegX8632::getEncodedGPR(Var->getRegNum()));
+ } else {
+ Asm->call(static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(Var));
+ }
+ } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) {
+ assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
+ Asm->call(Mem->toAsmAddress(Asm));
+ } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
+ assert(CR->getOffset() == 0 && "We only support calling a function");
Jim Stichnoth 2014/10/16 02:48:16 llvm_unreachable here too?
jvoung (off chromium) 2014/10/16 15:22:11 Oh, this one is actually reachable. I let it go th
+ Asm->call(CR);
+ NeedsFallback = true;
+ } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
+ // NaCl trampoline calls refer to an address within the sandbox directly.
+ // This is usually only needed for non-IRT builds and otherwise not
+ // very portable or stable. For this, we would use the 0xE8 opcode
+ // (relative version of call) and there should be a PC32 reloc too.
+ // The PC32 reloc will have symbol index 0, and the absolute address
+ // would be encoded as an offset relative to the next instruction.
+ // TODO(jvoung): Do we need to support this?
+ (void)Imm;
+ llvm_unreachable("Unexpected call to absolute address");
+ } else {
+ llvm_unreachable("Unexpected operand type");
+ }
+ if (NeedsFallback) {
+ // TODO(jvoung): The ".long sym" hack doesn't work, since we need
+ // a pc-rel relocation and not an absolute relocation.
+ //
+ // Still, we have at least filled the assembler buffer so that the
+ // instruction sizes/positions are correct for jumps.
+ // For now, fall back to the regular .s emission, after filling the buffer.
+ emit(Func);
+ } else {
+ emitIASBytes(Func, Asm, StartPosition);
+ }
+ Func->getTarget()->resetStackAdjustment();
+}
+
void InstX8632Call::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
if (getDest()) {
@@ -539,8 +585,7 @@ void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
(Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup));
} else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) {
- x86::Address SrcAddr = Split->toAsmAddress(Func);
- (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr);
+ (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
} else {
llvm_unreachable("Unexpected operand type");
}
@@ -570,6 +615,25 @@ void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr,
emitIASBytes(Func, Asm, StartPosition);
}
+void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0,
+ const Operand *Op1,
+ const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
+ if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
+ assert(!Op0Var->hasReg());
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(Op0Var));
+ emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter);
+ } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) {
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ Op0Mem->emitSegmentOverride(Asm);
+ emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter);
+ } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) {
+ emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter);
+ } else {
+ llvm_unreachable("Unexpected operand type");
+ }
+}
+
void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
const Operand *Src,
const x86::AssemblerX86::GPREmitterShiftOp &Emitter) {
@@ -1662,20 +1726,13 @@ void InstX8632Icmp::emitIAS(const Cfg *Func) const {
static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
&x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp
};
- if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
+ if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
if (SrcVar0->hasReg()) {
emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
- } else {
- x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
- ->stackVarToAsmOperand(SrcVar0));
- emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter);
+ return;
}
- } else if (const OperandX8632Mem *SrcMem0 =
- llvm::dyn_cast<OperandX8632Mem>(Src0)) {
- x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
- SrcMem0->emitSegmentOverride(Asm);
- emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter);
}
+ emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
}
void InstX8632Icmp::dump(const Cfg *Func) const {
@@ -1754,22 +1811,14 @@ void InstX8632Test::emitIAS(const Cfg *Func) const {
static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
&x86::AssemblerX86::test, &x86::AssemblerX86::test
};
- if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
+ if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
if (SrcVar0->hasReg()) {
emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
- } else {
- llvm_unreachable("Nothing actually generates this so it's untested");
- x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
- ->stackVarToAsmOperand(SrcVar0));
- emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter);
+ return;
}
- } else if (const OperandX8632Mem *SrcMem0 =
- llvm::dyn_cast<OperandX8632Mem>(Src0)) {
- llvm_unreachable("Nothing actually generates this so it's untested");
- x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
- SrcMem0->emitSegmentOverride(Asm);
- emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter);
}
+ llvm_unreachable("Nothing actually generates this so it's untested");
+ emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
}
void InstX8632Test::dump(const Cfg *Func) const {
@@ -1807,6 +1856,38 @@ void InstX8632Store::emit(const Cfg *Func) const {
Str << "\n";
}
+void InstX8632Store::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 2);
+ const Operand *Dest = getSrc(1);
+ const Operand *Src = getSrc(0);
+ Type DestTy = Dest->getType();
+ if (isScalarFloatingType(DestTy)) {
+ // Src must be a register, since Dest is a Mem operand of some kind.
+ const Variable *SrcVar = llvm::cast<Variable>(Src);
+ assert(SrcVar->hasReg());
+ RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
+ intptr_t StartPosition = Asm->GetPosition();
+ if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
+ assert(!DestVar->hasReg());
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
+ ->stackVarToAsmOperand(DestVar));
+ Asm->movss(DestTy, StackAddr, SrcReg);
+ } else {
+ const auto DestMem = llvm::cast<OperandX8632Mem>(Dest);
+ assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
+ Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg);
+ }
+ emitIASBytes(Func, Asm, StartPosition);
+ return;
+ } else {
+ assert(isScalarIntegerType(DestTy));
+ static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = {
+ &x86::AssemblerX86::mov, &x86::AssemblerX86::mov};
+ emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter);
+ }
+}
+
void InstX8632Store::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Str << "mov." << getSrc(0)->getType() << " ";
« src/IceInst.h ('K') | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698