asm(amd64): ROL and ROR on Register To Memory type. (#423)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
@@ -1299,6 +1299,26 @@ func (a *AssemblerImpl) EncodeRegisterToMemory(n *NodeImpl) (err error) {
|
||||
modRM |= 0b00_101_000
|
||||
opcode = []byte{0xd3}
|
||||
isShiftInstruction = true
|
||||
case ROLL:
|
||||
// https://www.felixcloutier.com/x86/rcl:rcr:rol:ror
|
||||
opcode = []byte{0xd3}
|
||||
isShiftInstruction = true
|
||||
case ROLQ:
|
||||
// https://www.felixcloutier.com/x86/rcl:rcr:rol:ror
|
||||
RexPrefix |= RexPrefixW
|
||||
opcode = []byte{0xd3}
|
||||
isShiftInstruction = true
|
||||
case RORL:
|
||||
// https://www.felixcloutier.com/x86/rcl:rcr:rol:ror
|
||||
modRM |= 0b00_001_000
|
||||
opcode = []byte{0xd3}
|
||||
isShiftInstruction = true
|
||||
case RORQ:
|
||||
// https://www.felixcloutier.com/x86/rcl:rcr:rol:ror
|
||||
RexPrefix |= RexPrefixW
|
||||
opcode = []byte{0xd3}
|
||||
modRM |= 0b00_001_000
|
||||
isShiftInstruction = true
|
||||
default:
|
||||
return errorEncodingUnsupported(n)
|
||||
}
|
||||
|
||||
@@ -1036,7 +1036,10 @@ func TestAssemblerImpl_EncodeRegisterToMemory(t *testing.T) {
|
||||
t.Run("shift", func(t *testing.T) {
|
||||
regs := []asm.Register{amd64.REG_AX, amd64.REG_R8}
|
||||
scales := []byte{1, 4}
|
||||
for _, instruction := range []asm.Instruction{amd64.SARL, amd64.SARQ, amd64.SHLL, amd64.SHLQ, amd64.SHRL, amd64.SHRQ} {
|
||||
for _, instruction := range []asm.Instruction{
|
||||
amd64.SARL, amd64.SARQ, amd64.SHLL, amd64.SHLQ, amd64.SHRL, amd64.SHRQ,
|
||||
amd64.ROLL, amd64.ROLQ, amd64.RORL, amd64.RORQ,
|
||||
} {
|
||||
for _, DstReg := range regs {
|
||||
DstReg := DstReg
|
||||
for _, offset := range []int64{
|
||||
|
||||
@@ -279,21 +279,35 @@ func TestCompiler_compile_And_Or_Xor_Shl_Rotl_Rotr(t *testing.T) {
|
||||
{1 << 63, 1}, {1, 1 << 63}, {1 << 63, 1 << 63},
|
||||
} {
|
||||
x1, x2 := values[0], values[1]
|
||||
t.Run(fmt.Sprintf("x1=0x%x,x2=0x%x", x1, x2), func(t *testing.T) {
|
||||
for _, x1OnRegister := range []bool{
|
||||
true, false,
|
||||
} {
|
||||
x1OnRegister := x1OnRegister
|
||||
t.Run(fmt.Sprintf("x1=0x%x(on_register=%v),x2=0x%x", x1, x1OnRegister, x2), func(t *testing.T) {
|
||||
env := newJITEnvironment()
|
||||
compiler := env.requireNewCompiler(t, newCompiler, nil)
|
||||
err := compiler.compilePreamble()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Emit consts operands.
|
||||
for _, v := range []uint64{x1, x2} {
|
||||
var x1Location *valueLocation
|
||||
switch unsignedInt {
|
||||
case wazeroir.UnsignedInt32:
|
||||
err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: uint32(v)})
|
||||
case wazeroir.UnsignedInt64:
|
||||
err = compiler.compileConstI64(&wazeroir.OperationConstI64{Value: v})
|
||||
}
|
||||
err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: uint32(x1)})
|
||||
require.NoError(t, err)
|
||||
x1Location = compiler.valueLocationStack().peek()
|
||||
err = compiler.compileConstI64(&wazeroir.OperationConstI64{Value: x2})
|
||||
require.NoError(t, err)
|
||||
case wazeroir.UnsignedInt64:
|
||||
err = compiler.compileConstI64(&wazeroir.OperationConstI64{Value: x1})
|
||||
require.NoError(t, err)
|
||||
x1Location = compiler.valueLocationStack().peek()
|
||||
err = compiler.compileConstI64(&wazeroir.OperationConstI64{Value: x2})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if !x1OnRegister {
|
||||
compiler.compileReleaseRegisterToStack(x1Location)
|
||||
}
|
||||
|
||||
// At this point, two values exist.
|
||||
@@ -319,8 +333,6 @@ func TestCompiler_compile_And_Or_Xor_Shl_Rotl_Rotr(t *testing.T) {
|
||||
// We consumed two values, but push the result back.
|
||||
require.Equal(t, uint64(1), compiler.valueLocationStack().sp)
|
||||
resultLocation := compiler.valueLocationStack().peek()
|
||||
// Plus the result must be located on a register.
|
||||
require.True(t, resultLocation.onRegister())
|
||||
// Also, the result must have an appropriate register type.
|
||||
require.Equal(t, generalPurposeRegisterTypeInt, resultLocation.regType)
|
||||
|
||||
@@ -381,6 +393,7 @@ func TestCompiler_compile_And_Or_Xor_Shl_Rotl_Rotr(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user