Bug 968524 - Add atomic_inc32(), atomic_dec32(), and atomic_cmpxchg32() to x86/x64. r=bbouvier

This commit is contained in:
Sean Stangl 2014-02-06 14:57:26 -08:00
parent 393770a388
commit 6f916bbe24
3 changed files with 89 additions and 0 deletions

View File

@ -316,6 +316,7 @@ private:
OP2_JCC_rel32 = 0x80,
OP_SETCC = 0x90,
OP2_IMUL_GvEv = 0xAF,
OP2_CMPXCHG_GvEw = 0xB1,
OP2_MOVSX_GvEb = 0xBE,
OP2_MOVSX_GvEw = 0xBF,
OP2_MOVZX_GvEb = 0xB6,
@ -368,6 +369,8 @@ private:
GROUP3_OP_DIV = 6,
GROUP3_OP_IDIV = 7,
GROUP5_OP_INC = 0,
GROUP5_OP_DEC = 1,
GROUP5_OP_CALLN = 2,
GROUP5_OP_JMPN = 4,
GROUP5_OP_PUSH = 6,
@ -1173,6 +1176,36 @@ public:
m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_DIV, divisor);
}
void prefix_lock()
{
spew("lock");
m_formatter.oneByteOp(PRE_LOCK);
}
void incl_m32(int offset, RegisterID base)
{
spew("incl %s0x%x(%s)", PRETTY_PRINT_OFFSET(offset), nameIReg(base));
m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_INC, base, offset);
}
void decl_m32(int offset, RegisterID base)
{
spew("decl %s0x%x(%s)", PRETTY_PRINT_OFFSET(offset), nameIReg(base));
m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_DEC, base, offset);
}
void cmpxchg32(RegisterID src, int offset, RegisterID base)
{
// Note that 32-bit CMPXCHG performs comparison against %eax.
// If %eax == [%base+offset], then %src -> [%base+offset].
// Otherwise, [%base+offset] -> %eax.
spew("cmpxchg %s, %s0x%x(%s)",
nameIReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
m_formatter.oneByteOp(PRE_LOCK);
m_formatter.twoByteOp(OP2_CMPXCHG_GvEw, src, base, offset);
}
// Comparisons:
void cmpl_rr(RegisterID src, RegisterID dst)

View File

@ -1106,6 +1106,45 @@ class AssemblerX86Shared
masm.sarl_CLr(dest.code());
}
void incl(const Operand &op) {
switch (op.kind()) {
case Operand::MEM_REG_DISP:
masm.incl_m32(op.disp(), op.base());
break;
default:
MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
}
}
void lock_incl(const Operand &op) {
masm.prefix_lock();
incl(op);
}
void decl(const Operand &op) {
switch (op.kind()) {
case Operand::MEM_REG_DISP:
masm.decl_m32(op.disp(), op.base());
break;
default:
MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
}
}
void lock_decl(const Operand &op) {
masm.prefix_lock();
decl(op);
}
void lock_cmpxchg32(const Register &src, const Operand &op) {
masm.prefix_lock();
switch (op.kind()) {
case Operand::MEM_REG_DISP:
masm.cmpxchg32(src.code(), op.disp(), op.base());
break;
default:
MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
}
}
void xaddl(const Register &srcdest, const Operand &mem) {
switch (mem.kind()) {
case Operand::MEM_REG_DISP:

View File

@ -159,6 +159,23 @@ class MacroAssemblerX86Shared : public Assembler
void not32(Register reg) {
notl(reg);
}
void inc32(const Operand &addr) {
incl(addr);
}
void atomic_inc32(const Operand &addr) {
lock_incl(addr);
}
void dec32(const Operand &addr) {
decl(addr);
}
void atomic_dec32(const Operand &addr) {
lock_decl(addr);
}
void atomic_cmpxchg32(const Register &src, const Operand &addr, const Register &dest) {
// %eax must be explicitly provided for calling clarity.
MOZ_ASSERT(dest.code() == JSC::X86Registers::eax);
lock_cmpxchg32(src, addr);
}
void branch32(Condition cond, const Operand &lhs, const Register &rhs, Label *label) {
cmpl(lhs, rhs);