Skip to content

Commit

Permalink
wazevo(amd64): lock xadd
Browse files Browse the repository at this point in the history
Signed-off-by: Takeshi Yoneda <[email protected]>
  • Loading branch information
mathetake committed Mar 6, 2024
1 parent e326bc3 commit 701752f
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
26 changes: 26 additions & 0 deletions internal/engine/wazevo/backend/isa/amd64/instr.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,19 @@ func (i *instruction) String() string {
suffix = "q"
}
return fmt.Sprintf("lock cmpxchg.%s %s, %s", suffix, i.op1.format(true), i.op2.format(true))
case lockxadd:
var suffix string
switch i.u1 {
case 1:
suffix = "b"
case 2:
suffix = "w"
case 4:
suffix = "l"
case 8:
suffix = "q"
}
return fmt.Sprintf("lock xadd.%s %s, %s", suffix, i.op1.format(true), i.op2.format(true))
default:
panic(fmt.Sprintf("BUG: %d", int(i.kind)))
}
Expand Down Expand Up @@ -786,6 +799,9 @@ const (
// mfence is https://www.felixcloutier.com/x86/mfence
mfence

// lockxadd is xadd https://www.felixcloutier.com/x86/xadd with a lock prefix.
lockxadd

instrMax
)

Expand Down Expand Up @@ -1019,6 +1035,8 @@ func (k instructionKind) String() string {
return "mfence"
case lockcmpxchg:
return "lockcmpxchg"
case lockxadd:
return "lockxadd"
default:
panic("BUG")
}
Expand Down Expand Up @@ -1463,6 +1481,14 @@ func (i *instruction) asLockCmpXCHG(rm regalloc.VReg, rd *amode, size byte) *ins
return i
}

func (i *instruction) asLockXAdd(rm regalloc.VReg, rd *amode, size byte) *instruction {
i.kind = lockxadd
i.op1 = newOperandReg(rm)
i.op2 = newOperandMem(rd)
i.u1 = uint64(size)
return i
}

type unaryRmROpcode byte

const (
Expand Down
36 changes: 36 additions & 0 deletions internal/engine/wazevo/backend/isa/amd64/instr_encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,42 @@ func (i *instruction) encode(c backend.Compiler) (needsLabelResolution bool) {
panic("BUG: invalid operand kind")
}

case lockxadd:
src, dst := regEncodings[i.op1.reg().RealReg()], i.op2
size := i.u1

var rex rexInfo
var opcode uint32
lp := legacyPrefixes0xF0 // Lock prefix.
switch size {
case 8:
opcode = 0x0FC1
rex = rexInfo(0).setW()
case 4:
opcode = 0x0FC1
rex = rexInfo(0).clearW()
case 2:
lp = legacyPrefixes0x660xF0 // Legacy prefix + Lock prefix.
opcode = 0x0FC1
rex = rexInfo(0).clearW()
case 1:
opcode = 0x0FC0
// Some destinations must be encoded with REX.R = 1.
if e := src.encoding(); e >= 4 && e <= 7 {
rex = rexInfo(0).always()
}
default:
panic(fmt.Sprintf("BUG: invalid size %d: %s", size, i.String()))
}

switch dst.kind {
case operandKindMem:
m := dst.addressMode()
encodeRegMem(c, lp, opcode, 2, src, m, rex)
default:
panic("BUG: invalid operand kind")
}

case zeros:
r := i.op2.reg()
if r.RegType() == regalloc.RegTypeInt {
Expand Down
55 changes: 55 additions & 0 deletions internal/engine/wazevo/backend/isa/amd64/instr_encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4176,6 +4176,61 @@ func TestInstruction_format_encode(t *testing.T) {
want: "f0400fb07e7b",
wantFormat: "lock cmpxchg.b %rdi, 123(%rsi)",
},
{
setup: func(i *instruction) { i.asLockXAdd(rsiVReg, newAmodeImmReg(123, raxVReg), 8) },
want: "f0480fc1707b",
wantFormat: "lock xadd.q %rsi, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(r11VReg, newAmodeImmReg(123, raxVReg), 8) },
want: "f04c0fc1587b",
wantFormat: "lock xadd.q %r11, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(rsiVReg, newAmodeImmReg(123, raxVReg), 4) },
want: "f00fc1707b",
wantFormat: "lock xadd.l %rsi, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(r11VReg, newAmodeImmReg(123, raxVReg), 4) },
want: "f0440fc1587b",
wantFormat: "lock xadd.l %r11, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(r11VReg, newAmodeImmReg(123, raxVReg), 2) },
want: "66f0440fc1587b",
wantFormat: "lock xadd.w %r11, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(rsiVReg, newAmodeImmReg(123, raxVReg), 2) },
want: "66f00fc1707b",
wantFormat: "lock xadd.w %rsi, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(r11VReg, newAmodeImmReg(123, raxVReg), 1) },
want: "f0440fc0587b",
wantFormat: "lock xadd.b %r11, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(r11VReg, newAmodeImmReg(123, rdiVReg), 1) },
want: "f0440fc05f7b",
wantFormat: "lock xadd.b %r11, 123(%rdi)",
},
{
setup: func(i *instruction) { i.asLockXAdd(rsiVReg, newAmodeImmReg(123, raxVReg), 1) },
want: "f0400fc0707b",
wantFormat: "lock xadd.b %rsi, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(rdiVReg, newAmodeImmReg(123, raxVReg), 1) },
want: "f0400fc0787b",
wantFormat: "lock xadd.b %rdi, 123(%rax)",
},
{
setup: func(i *instruction) { i.asLockXAdd(rdiVReg, newAmodeImmReg(123, rsiVReg), 1) },
want: "f0400fc07e7b",
wantFormat: "lock xadd.b %rdi, 123(%rsi)",
},
} {
tc := tc
t.Run(tc.wantFormat, func(t *testing.T) {
Expand Down

0 comments on commit 701752f

Please sign in to comment.