Commit 03532e59 by Jan Voung

Handle a few more instructions in assembler (cmov, cdq, cmpxchg, xadd, xchg).

BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/597643002
parent 8acded03
......@@ -213,7 +213,7 @@ InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr,
addSource(Desired);
}
InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Addr,
InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Addr,
Variable *Edx, Variable *Eax,
Variable *Ecx, Variable *Ebx,
bool Locked)
......@@ -810,6 +810,34 @@ template <> void InstX8632Cbwdq::emit(const Cfg *Func) const {
}
}
template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
assert(getSrcSize() == 1);
Operand *Src0 = getSrc(0);
assert(llvm::isa<Variable>(Src0));
assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax);
switch (Src0->getType()) {
default:
llvm_unreachable("unexpected source type!");
break;
case IceType_i8:
assert(getDest()->getRegNum() == RegX8632::Reg_eax);
Asm->cbw();
break;
case IceType_i16:
assert(getDest()->getRegNum() == RegX8632::Reg_edx);
Asm->cwd();
break;
case IceType_i32:
assert(getDest()->getRegNum() == RegX8632::Reg_edx);
Asm->cdq();
break;
}
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Mul::emit(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 2);
......@@ -892,6 +920,23 @@ void InstX8632Cmov::emit(const Cfg *Func) const {
Str << "\n";
}
void InstX8632Cmov::emitIAS(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
Str << "\t";
assert(Condition != CondX86::Br_None);
assert(getDest()->hasReg());
assert(getSrcSize() == 2);
// Only need the reg/reg form now.
const Variable *Src = llvm::cast<Variable>(getSrc(1));
assert(Src->hasReg());
assert(Src->getType() == IceType_i32);
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
RegX8632::getEncodedGPR(Src->getRegNum()));
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Cmov::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
......@@ -958,6 +1003,26 @@ void InstX8632Cmpxchg::emit(const Cfg *Func) const {
Str << "\n";
}
void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 3);
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
Type Ty = getSrc(0)->getType();
const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
const x86::Address Addr = Mem->toAsmAddress(Asm);
const Variable *VarReg = llvm::cast<Variable>(getSrc(2));
assert(VarReg->hasReg());
const RegX8632::GPRRegister Reg =
RegX8632::getEncodedGPR(VarReg->getRegNum());
if (Locked) {
Asm->LockCmpxchg(Ty, Addr, Reg);
} else {
Asm->cmpxchg(Ty, Addr, Reg);
}
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Cmpxchg::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
if (Locked) {
......@@ -978,6 +1043,20 @@ void InstX8632Cmpxchg8b::emit(const Cfg *Func) const {
Str << "\n";
}
void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 5);
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
const x86::Address Addr = Mem->toAsmAddress(Asm);
if (Locked) {
Asm->lock();
}
Asm->cmpxchg8b(Addr);
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
if (Locked) {
......@@ -1573,6 +1652,25 @@ void InstX8632Xadd::emit(const Cfg *Func) const {
Str << "\n";
}
void InstX8632Xadd::emitIAS(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 2);
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
Type Ty = getSrc(0)->getType();
const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
const x86::Address Addr = Mem->toAsmAddress(Asm);
const Variable *VarReg = llvm::cast<Variable>(getSrc(1));
assert(VarReg->hasReg());
const RegX8632::GPRRegister Reg =
RegX8632::getEncodedGPR(VarReg->getRegNum());
if (Locked) {
Asm->lock();
}
Asm->xadd(Ty, Addr, Reg);
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Xadd::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
if (Locked) {
......@@ -1592,6 +1690,22 @@ void InstX8632Xchg::emit(const Cfg *Func) const {
Str << "\n";
}
void InstX8632Xchg::emitIAS(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 2);
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
Type Ty = getSrc(0)->getType();
const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
const x86::Address Addr = Mem->toAsmAddress(Asm);
const Variable *VarReg = llvm::cast<Variable>(getSrc(1));
assert(VarReg->hasReg());
const RegX8632::GPRRegister Reg =
RegX8632::getEncodedGPR(VarReg->getRegNum());
Asm->xchg(Ty, Addr, Reg);
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Xchg::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Type Ty = getSrc(0)->getType();
......
......@@ -895,6 +895,7 @@ public:
InstX8632Cmov(Func, Dest, Source, Cond);
}
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, Cmov); }
......@@ -945,6 +946,7 @@ public:
InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
}
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, Cmpxchg); }
......@@ -964,18 +966,19 @@ private:
// <m64> must be a memory operand.
class InstX8632Cmpxchg8b : public InstX8632Lockable {
public:
static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632 *Dest,
static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
Variable *Edx, Variable *Eax, Variable *Ecx,
Variable *Ebx, bool Locked) {
return new (Func->allocate<InstX8632Cmpxchg8b>())
InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
}
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, Cmpxchg8b); }
private:
InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Dest, Variable *Edx,
InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION;
InstX8632Cmpxchg8b &
......@@ -1319,6 +1322,7 @@ public:
InstX8632Xadd(Func, Dest, Source, Locked);
}
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, Xadd); }
......@@ -1342,6 +1346,7 @@ public:
InstX8632Xchg(Func, Dest, 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, Xchg); }
......@@ -1378,6 +1383,8 @@ template <> void InstX8632Psub::emit(const Cfg *Func) const;
template <> void InstX8632Sqrtss::emit(const Cfg *Func) const;
template <> void InstX8632Subss::emit(const Cfg *Func) const;
template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const;
} // end of namespace Ice
#endif // SUBZERO_SRC_ICEINSTX8632_H
......@@ -250,7 +250,7 @@ protected:
Context.insert(
InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr)));
}
void _cmpxchg8b(OperandX8632 *Addr, Variable *Edx, Variable *Eax,
void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax,
Variable *Ecx, Variable *Ebx, bool Locked) {
Context.insert(
InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked));
......
......@@ -1110,12 +1110,6 @@ void AssemblerX86::fincstp() {
EmitUint8(0xF7);
}
void AssemblerX86::xchgl(GPRRegister dst, GPRRegister src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x87);
EmitRegisterOperand(dst, src);
}
void AssemblerX86::cmpl(GPRRegister reg, const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitComplex(7, Operand(reg), imm);
......@@ -1307,6 +1301,18 @@ void AssemblerX86::subl(const Address &address, GPRRegister reg) {
EmitOperand(reg, address);
}
void AssemblerX86::cbw() {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitOperandSizeOverride();
EmitUint8(0x98);
}
void AssemblerX86::cwd() {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitOperandSizeOverride();
EmitUint8(0x99);
}
void AssemblerX86::cdq() {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x99);
......@@ -1674,13 +1680,48 @@ void AssemblerX86::lock() {
EmitUint8(0xF0);
}
void AssemblerX86::cmpxchgl(const Address &address, GPRRegister reg) {
void AssemblerX86::cmpxchg(Type Ty, const Address &address, GPRRegister reg) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
if (Ty == IceType_i16)
EmitOperandSizeOverride();
EmitUint8(0x0F);
EmitUint8(0xB1);
if (Ty == IceType_i8 || Ty == IceType_i1)
EmitUint8(0xB0);
else
EmitUint8(0xB1);
EmitOperand(reg, address);
}
void AssemblerX86::cmpxchg8b(const Address &address) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x0F);
EmitUint8(0xC7);
EmitOperand(1, address);
}
void AssemblerX86::xadd(Type Ty, const Address &addr, GPRRegister reg) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
if (Ty == IceType_i16)
EmitOperandSizeOverride();
EmitUint8(0x0F);
if (Ty == IceType_i8 || Ty == IceType_i1)
EmitUint8(0xC0);
else
EmitUint8(0xC1);
EmitOperand(reg, addr);
}
void AssemblerX86::xchg(Type Ty, const Address &addr, GPRRegister reg) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
if (Ty == IceType_i16)
EmitOperandSizeOverride();
if (Ty == IceType_i8 || Ty == IceType_i1)
EmitUint8(0x86);
else
EmitUint8(0x87);
EmitOperand(reg, addr);
}
void AssemblerX86::Align(intptr_t alignment, intptr_t offset) {
assert(llvm::isPowerOf2_32(alignment));
intptr_t pos = offset + buffer_.GetPosition();
......
......@@ -541,8 +541,6 @@ public:
void fincstp();
void xchgl(GPRRegister dst, GPRRegister src);
void cmpl(GPRRegister reg, const Immediate &imm);
void cmpl(GPRRegister reg0, GPRRegister reg1);
void cmpl(GPRRegister reg, const Address &address);
......@@ -582,6 +580,8 @@ public:
void subl(GPRRegister reg, const Address &address);
void subl(const Address &address, GPRRegister reg);
void cbw();
void cwd();
void cdq();
void idivl(GPRRegister reg);
......@@ -645,11 +645,14 @@ public:
void jmp(const ConstantRelocatable *label);
void lock();
void cmpxchgl(const Address &address, GPRRegister reg);
void cmpxchg(Type Ty, const Address &address, GPRRegister reg);
void cmpxchg8b(const Address &address);
void xadd(Type Ty, const Address &address, GPRRegister reg);
void xchg(Type Ty, const Address &address, GPRRegister reg);
void LockCmpxchgl(const Address &address, GPRRegister reg) {
void LockCmpxchg(Type Ty, const Address &address, GPRRegister reg) {
lock();
cmpxchgl(address, reg);
cmpxchg(Ty, address, reg);
}
intptr_t PreferredLoopAlignment() { return 16; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment