mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 968524 - Add atomic_inc32(), atomic_dec32(), and atomic_cmpxchg32() to x86/x64. r=bbouvier
This commit is contained in:
parent
393770a388
commit
6f916bbe24
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user