RJIT: Use lambda constants to match operands
This commit is contained in:
parent
8835f9d3bf
commit
9c220bf5e1
@ -35,6 +35,13 @@ module RubyVM::RJIT
|
|||||||
REX_R = 0b01000100
|
REX_R = 0b01000100
|
||||||
REX_W = 0b01001000
|
REX_W = 0b01001000
|
||||||
|
|
||||||
|
# Operand matchers
|
||||||
|
R32 = -> (op) { op.is_a?(Symbol) && r32?(op) }
|
||||||
|
R64 = -> (op) { op.is_a?(Symbol) && r64?(op) }
|
||||||
|
IMM8 = -> (op) { op.is_a?(Integer) && imm8?(op) }
|
||||||
|
IMM32 = -> (op) { op.is_a?(Integer) && imm32?(op) }
|
||||||
|
IMM64 = -> (op) { op.is_a?(Integer) && imm64?(op) }
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@bytes = []
|
@bytes = []
|
||||||
@labels = {}
|
@labels = {}
|
||||||
@ -72,7 +79,7 @@ module RubyVM::RJIT
|
|||||||
def add(dst, src)
|
def add(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# ADD r/m64, imm8 (Mod 00: [reg])
|
# ADD r/m64, imm8 (Mod 00: [reg])
|
||||||
in [QwordPtr[Symbol => dst_reg], Integer => src_imm] if r64?(dst_reg) && imm8?(src_imm)
|
in [QwordPtr[R64 => dst_reg], IMM8 => src_imm]
|
||||||
# REX.W + 83 /0 ib
|
# REX.W + 83 /0 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -82,7 +89,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(src_imm),
|
imm: imm8(src_imm),
|
||||||
)
|
)
|
||||||
# ADD r/m64, imm8 (Mod 11: reg)
|
# ADD r/m64, imm8 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm8?(src_imm)
|
in [R64 => dst_reg, IMM8 => src_imm]
|
||||||
# REX.W + 83 /0 ib
|
# REX.W + 83 /0 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -92,7 +99,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(src_imm),
|
imm: imm8(src_imm),
|
||||||
)
|
)
|
||||||
# ADD r/m64 imm32 (Mod 11: reg)
|
# ADD r/m64 imm32 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm32?(src_imm)
|
in [R64 => dst_reg, IMM32 => src_imm]
|
||||||
# REX.W + 81 /0 id
|
# REX.W + 81 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -102,7 +109,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(src_imm),
|
imm: imm32(src_imm),
|
||||||
)
|
)
|
||||||
# ADD r/m64, r64 (Mod 11: reg)
|
# ADD r/m64, r64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 01 /r
|
# REX.W + 01 /r
|
||||||
# MR: Operand 1: ModRM:r/m (r, w), Operand 2: ModRM:reg (r)
|
# MR: Operand 1: ModRM:r/m (r, w), Operand 2: ModRM:reg (r)
|
||||||
insn(
|
insn(
|
||||||
@ -116,7 +123,7 @@ module RubyVM::RJIT
|
|||||||
def and(dst, src)
|
def and(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# AND r/m64, imm8 (Mod 11: reg)
|
# AND r/m64, imm8 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm8?(src_imm)
|
in [R64 => dst_reg, IMM8 => src_imm]
|
||||||
# REX.W + 83 /4 ib
|
# REX.W + 83 /4 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -126,7 +133,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(src_imm),
|
imm: imm8(src_imm),
|
||||||
)
|
)
|
||||||
# AND r/m64, imm32 (Mod 11: reg)
|
# AND r/m64, imm32 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm32?(src_imm)
|
in [R64 => dst_reg, IMM32 => src_imm]
|
||||||
# REX.W + 81 /4 id
|
# REX.W + 81 /4 id
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -136,7 +143,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(src_imm),
|
imm: imm32(src_imm),
|
||||||
)
|
)
|
||||||
# AND r64, r/m64 (Mod 01: [reg]+disp8)
|
# AND r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
in [Symbol => dst_reg, QwordPtr[Symbol => src_reg, Integer => src_disp]] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
|
in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
|
||||||
# REX.W + 23 /r
|
# REX.W + 23 /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -156,7 +163,7 @@ module RubyVM::RJIT
|
|||||||
# D: Operand 1: Offset
|
# D: Operand 1: Offset
|
||||||
insn(opcode: 0xe8, imm: rel32(dst_addr))
|
insn(opcode: 0xe8, imm: rel32(dst_addr))
|
||||||
# CALL r/m64 (Mod 11: reg)
|
# CALL r/m64 (Mod 11: reg)
|
||||||
in Symbol => dst_reg if r64?(dst_reg)
|
in R64 => dst_reg
|
||||||
# FF /2
|
# FF /2
|
||||||
# M: Operand 1: ModRM:r/m (r)
|
# M: Operand 1: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -169,7 +176,7 @@ module RubyVM::RJIT
|
|||||||
def cmove(dst, src)
|
def cmove(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# CMOVE r64, r/m64 (Mod 11: reg)
|
# CMOVE r64, r/m64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 0F 44 /r
|
# REX.W + 0F 44 /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -183,7 +190,7 @@ module RubyVM::RJIT
|
|||||||
def cmovg(dst, src)
|
def cmovg(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# CMOVG r64, r/m64 (Mod 11: reg)
|
# CMOVG r64, r/m64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 0F 4F /r
|
# REX.W + 0F 4F /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -197,7 +204,7 @@ module RubyVM::RJIT
|
|||||||
def cmovge(dst, src)
|
def cmovge(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# CMOVGE r64, r/m64 (Mod 11: reg)
|
# CMOVGE r64, r/m64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 0F 4D /r
|
# REX.W + 0F 4D /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -211,7 +218,7 @@ module RubyVM::RJIT
|
|||||||
def cmovl(dst, src)
|
def cmovl(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# CMOVL r64, r/m64 (Mod 11: reg)
|
# CMOVL r64, r/m64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 0F 4C /r
|
# REX.W + 0F 4C /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -225,7 +232,7 @@ module RubyVM::RJIT
|
|||||||
def cmovle(dst, src)
|
def cmovle(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# CMOVLE r64, r/m64 (Mod 11: reg)
|
# CMOVLE r64, r/m64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 0F 4E /r
|
# REX.W + 0F 4E /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -239,7 +246,7 @@ module RubyVM::RJIT
|
|||||||
def cmovnz(dst, src)
|
def cmovnz(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# CMOVNZ r64, r/m64 (Mod 11: reg)
|
# CMOVNZ r64, r/m64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 0F 45 /r
|
# REX.W + 0F 45 /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -253,7 +260,7 @@ module RubyVM::RJIT
|
|||||||
def cmovz(dst, src)
|
def cmovz(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# CMOVZ r64, r/m64 (Mod 11: reg)
|
# CMOVZ r64, r/m64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 0F 44 /r
|
# REX.W + 0F 44 /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -262,7 +269,7 @@ module RubyVM::RJIT
|
|||||||
mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
|
mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
|
||||||
)
|
)
|
||||||
# CMOVZ r64, r/m64 (Mod 01: [reg]+disp8)
|
# CMOVZ r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
in [Symbol => dst_reg, QwordPtr[Symbol => src_reg, Integer => src_disp]] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
|
in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
|
||||||
# REX.W + 0F 44 /r
|
# REX.W + 0F 44 /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -277,7 +284,7 @@ module RubyVM::RJIT
|
|||||||
def cmp(left, right)
|
def cmp(left, right)
|
||||||
case [left, right]
|
case [left, right]
|
||||||
# CMP r/m8, imm8 (Mod 01: [reg]+disp8)
|
# CMP r/m8, imm8 (Mod 01: [reg]+disp8)
|
||||||
in [BytePtr[reg: left_reg, disp: left_disp], Integer => right_imm] if r64?(left_reg) && imm8?(left_disp) && imm8?(right_imm)
|
in [BytePtr[R64 => left_reg, IMM8 => left_disp], IMM8 => right_imm]
|
||||||
# 80 /7 ib
|
# 80 /7 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -287,7 +294,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(right_imm),
|
imm: imm8(right_imm),
|
||||||
)
|
)
|
||||||
# CMP r/m32, imm32 (Mod 01: [reg]+disp8)
|
# CMP r/m32, imm32 (Mod 01: [reg]+disp8)
|
||||||
in [DwordPtr[reg: left_reg, disp: left_disp], Integer => right_imm] if imm8?(left_disp) && imm32?(right_imm)
|
in [DwordPtr[R64 => left_reg, IMM8 => left_disp], IMM32 => right_imm]
|
||||||
# 81 /7 id
|
# 81 /7 id
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -297,7 +304,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(right_imm),
|
imm: imm32(right_imm),
|
||||||
)
|
)
|
||||||
# CMP r/m64, imm8 (Mod 01: [reg]+disp8)
|
# CMP r/m64, imm8 (Mod 01: [reg]+disp8)
|
||||||
in [QwordPtr[Symbol => left_reg, Integer => left_disp], Integer => right_imm] if r64?(left_reg) && imm8?(left_disp) && imm8?(right_imm)
|
in [QwordPtr[R64 => left_reg, IMM8 => left_disp], IMM8 => right_imm]
|
||||||
# REX.W + 83 /7 ib
|
# REX.W + 83 /7 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -308,7 +315,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(right_imm),
|
imm: imm8(right_imm),
|
||||||
)
|
)
|
||||||
# CMP r/m64, imm8 (Mod 10: [reg]+disp32)
|
# CMP r/m64, imm8 (Mod 10: [reg]+disp32)
|
||||||
in [QwordPtr[Symbol => left_reg, Integer => left_disp], Integer => right_imm] if r64?(left_reg) && imm32?(left_disp) && imm8?(right_imm)
|
in [QwordPtr[R64 => left_reg, IMM32 => left_disp], IMM8 => right_imm]
|
||||||
# REX.W + 83 /7 ib
|
# REX.W + 83 /7 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -319,7 +326,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(right_imm),
|
imm: imm8(right_imm),
|
||||||
)
|
)
|
||||||
# CMP r/m64, imm8 (Mod 11: reg)
|
# CMP r/m64, imm8 (Mod 11: reg)
|
||||||
in [Symbol => left_reg, Integer => right_imm] if r64?(left_reg) && imm8?(right_imm)
|
in [R64 => left_reg, IMM8 => right_imm]
|
||||||
# REX.W + 83 /7 ib
|
# REX.W + 83 /7 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -329,7 +336,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(right_imm),
|
imm: imm8(right_imm),
|
||||||
)
|
)
|
||||||
# CMP r/m64, imm32 (Mod 11: reg)
|
# CMP r/m64, imm32 (Mod 11: reg)
|
||||||
in [Symbol => left_reg, Integer => right_imm] if r64?(left_reg) && imm32?(right_imm)
|
in [R64 => left_reg, IMM32 => right_imm]
|
||||||
# REX.W + 81 /7 id
|
# REX.W + 81 /7 id
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -339,7 +346,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(right_imm),
|
imm: imm32(right_imm),
|
||||||
)
|
)
|
||||||
# CMP r/m64, r64 (Mod 01: [reg]+disp8)
|
# CMP r/m64, r64 (Mod 01: [reg]+disp8)
|
||||||
in [QwordPtr[Symbol => left_reg, Integer => left_disp], Symbol => right_reg] if r64?(right_reg)
|
in [QwordPtr[R64 => left_reg, IMM8 => left_disp], R64 => right_reg]
|
||||||
# REX.W + 39 /r
|
# REX.W + 39 /r
|
||||||
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
||||||
insn(
|
insn(
|
||||||
@ -349,7 +356,7 @@ module RubyVM::RJIT
|
|||||||
disp: left_disp,
|
disp: left_disp,
|
||||||
)
|
)
|
||||||
# CMP r/m64, r64 (Mod 11: reg)
|
# CMP r/m64, r64 (Mod 11: reg)
|
||||||
in [Symbol => left_reg, Symbol => right_reg] if r64?(left_reg) && r64?(right_reg)
|
in [R64 => left_reg, R64 => right_reg]
|
||||||
# REX.W + 39 /r
|
# REX.W + 39 /r
|
||||||
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
||||||
insn(
|
insn(
|
||||||
@ -406,11 +413,11 @@ module RubyVM::RJIT
|
|||||||
# E9 cd
|
# E9 cd
|
||||||
insn(opcode: 0xe9, imm: rel32(dst_addr))
|
insn(opcode: 0xe9, imm: rel32(dst_addr))
|
||||||
# JMP r/m64 (Mod 01: [reg]+disp8)
|
# JMP r/m64 (Mod 01: [reg]+disp8)
|
||||||
in QwordPtr[Symbol => dst_reg, Integer => dst_disp] if r64?(dst_reg) && imm8?(dst_disp)
|
in QwordPtr[R64 => dst_reg, IMM8 => dst_disp]
|
||||||
# FF /4
|
# FF /4
|
||||||
insn(opcode: 0xff, mod_rm: ModRM[mod: Mod01, reg: 4, rm: dst_reg], disp: dst_disp)
|
insn(opcode: 0xff, mod_rm: ModRM[mod: Mod01, reg: 4, rm: dst_reg], disp: dst_disp)
|
||||||
# JMP r/m64 (Mod 11: reg)
|
# JMP r/m64 (Mod 11: reg)
|
||||||
in Symbol => dst_reg if r64?(dst_reg)
|
in R64 => dst_reg
|
||||||
# FF /4
|
# FF /4
|
||||||
insn(opcode: 0xff, mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg])
|
insn(opcode: 0xff, mod_rm: ModRM[mod: Mod11, reg: 4, rm: dst_reg])
|
||||||
end
|
end
|
||||||
@ -463,7 +470,7 @@ module RubyVM::RJIT
|
|||||||
def lea(dst, src)
|
def lea(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# LEA r64,m (Mod 01: [reg]+disp8)
|
# LEA r64,m (Mod 01: [reg]+disp8)
|
||||||
in [Symbol => dst_reg, QwordPtr[Symbol => src_reg, Integer => src_disp]] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
|
in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
|
||||||
# REX.W + 8D /r
|
# REX.W + 8D /r
|
||||||
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -473,7 +480,7 @@ module RubyVM::RJIT
|
|||||||
disp: imm8(src_disp),
|
disp: imm8(src_disp),
|
||||||
)
|
)
|
||||||
# LEA r64,m (Mod 10: [reg]+disp32)
|
# LEA r64,m (Mod 10: [reg]+disp32)
|
||||||
in [Symbol => dst_reg, QwordPtr[Symbol => src_reg, Integer => src_disp]] if r64?(dst_reg) && r64?(src_reg) && imm32?(src_disp)
|
in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM32 => src_disp]]
|
||||||
# REX.W + 8D /r
|
# REX.W + 8D /r
|
||||||
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -487,10 +494,31 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def mov(dst, src)
|
def mov(dst, src)
|
||||||
case dst
|
case dst
|
||||||
in Symbol => dst_reg
|
in R32 => dst_reg
|
||||||
|
case src
|
||||||
|
# MOV r32 r/m32 (Mod 01: [reg]+disp8)
|
||||||
|
in DwordPtr[R64 => src_reg, IMM8 => src_disp]
|
||||||
|
# 8B /r
|
||||||
|
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
||||||
|
insn(
|
||||||
|
opcode: 0x8b,
|
||||||
|
mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
|
||||||
|
disp: src_disp,
|
||||||
|
)
|
||||||
|
# MOV r32, imm32 (Mod 11: reg)
|
||||||
|
in IMM32 => src_imm
|
||||||
|
# B8+ rd id
|
||||||
|
# OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
|
||||||
|
insn(
|
||||||
|
opcode: 0xb8,
|
||||||
|
rd: dst_reg,
|
||||||
|
imm: imm32(src_imm),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
in R64 => dst_reg
|
||||||
case src
|
case src
|
||||||
# MOV r64, r/m64 (Mod 00: [reg])
|
# MOV r64, r/m64 (Mod 00: [reg])
|
||||||
in QwordPtr[Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in QwordPtr[R64 => src_reg]
|
||||||
# REX.W + 8B /r
|
# REX.W + 8B /r
|
||||||
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -499,7 +527,7 @@ module RubyVM::RJIT
|
|||||||
mod_rm: ModRM[mod: Mod00, reg: dst_reg, rm: src_reg],
|
mod_rm: ModRM[mod: Mod00, reg: dst_reg, rm: src_reg],
|
||||||
)
|
)
|
||||||
# MOV r64, r/m64 (Mod 01: [reg]+disp8)
|
# MOV r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
in QwordPtr[Symbol => src_reg, Integer => src_disp] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
|
in QwordPtr[R64 => src_reg, IMM8 => src_disp]
|
||||||
# REX.W + 8B /r
|
# REX.W + 8B /r
|
||||||
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -508,8 +536,8 @@ module RubyVM::RJIT
|
|||||||
mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
|
mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
|
||||||
disp: src_disp,
|
disp: src_disp,
|
||||||
)
|
)
|
||||||
# MOV r64, r/m64 (Mod 10: [reg]+disp16)
|
# MOV r64, r/m64 (Mod 10: [reg]+disp32)
|
||||||
in QwordPtr[Symbol => src_reg, Integer => src_disp] if r64?(dst_reg) && r64?(src_reg) && imm32?(src_disp)
|
in QwordPtr[R64 => src_reg, IMM32 => src_disp]
|
||||||
# REX.W + 8B /r
|
# REX.W + 8B /r
|
||||||
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -519,7 +547,7 @@ module RubyVM::RJIT
|
|||||||
disp: imm32(src_disp),
|
disp: imm32(src_disp),
|
||||||
)
|
)
|
||||||
# MOV r64, r/m64 (Mod 11: reg)
|
# MOV r64, r/m64 (Mod 11: reg)
|
||||||
in Symbol => src_reg if r64?(dst_reg) && r64?(src_reg)
|
in R64 => src_reg
|
||||||
# REX.W + 8B /r
|
# REX.W + 8B /r
|
||||||
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -527,26 +555,8 @@ module RubyVM::RJIT
|
|||||||
opcode: 0x8b,
|
opcode: 0x8b,
|
||||||
mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
|
mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
|
||||||
)
|
)
|
||||||
# MOV r32 r/m32 (Mod 01: [reg]+disp8)
|
|
||||||
in QwordPtr[Symbol => src_reg, Integer => src_disp] if r32?(dst_reg) && imm8?(src_disp)
|
|
||||||
# 8B /r
|
|
||||||
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
|
|
||||||
insn(
|
|
||||||
opcode: 0x8b,
|
|
||||||
mod_rm: ModRM[mod: Mod01, reg: dst_reg, rm: src_reg],
|
|
||||||
disp: src_disp,
|
|
||||||
)
|
|
||||||
# MOV r32, imm32 (Mod 11: reg)
|
|
||||||
in Integer => src_imm if r32?(dst_reg) && imm32?(src_imm)
|
|
||||||
# B8+ rd id
|
|
||||||
# OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
|
|
||||||
insn(
|
|
||||||
opcode: 0xb8,
|
|
||||||
rd: dst_reg,
|
|
||||||
imm: imm32(src_imm),
|
|
||||||
)
|
|
||||||
# MOV r/m64, imm32 (Mod 11: reg)
|
# MOV r/m64, imm32 (Mod 11: reg)
|
||||||
in Integer => src_imm if r64?(dst_reg) && imm32?(src_imm)
|
in IMM32 => src_imm
|
||||||
# REX.W + C7 /0 id
|
# REX.W + C7 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
||||||
insn(
|
insn(
|
||||||
@ -556,7 +566,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(src_imm),
|
imm: imm32(src_imm),
|
||||||
)
|
)
|
||||||
# MOV r64, imm64
|
# MOV r64, imm64
|
||||||
in Integer => src_imm if r64?(dst_reg) && imm64?(src_imm)
|
in IMM64 => src_imm
|
||||||
# REX.W + B8+ rd io
|
# REX.W + B8+ rd io
|
||||||
# OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
|
# OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
|
||||||
insn(
|
insn(
|
||||||
@ -566,32 +576,10 @@ module RubyVM::RJIT
|
|||||||
imm: imm64(src_imm),
|
imm: imm64(src_imm),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
in QwordPtr[Symbol => dst_reg]
|
in DwordPtr[R64 => dst_reg, IMM8 => dst_disp]
|
||||||
case src
|
|
||||||
# MOV r/m64, imm32 (Mod 00: [reg])
|
|
||||||
in Integer => src_imm if r64?(dst_reg) && imm32?(src_imm)
|
|
||||||
# REX.W + C7 /0 id
|
|
||||||
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
|
||||||
insn(
|
|
||||||
prefix: REX_W,
|
|
||||||
opcode: 0xc7,
|
|
||||||
mod_rm: ModRM[mod: Mod00, reg: 0, rm: dst_reg],
|
|
||||||
imm: imm32(src_imm),
|
|
||||||
)
|
|
||||||
# MOV r/m64, r64 (Mod 00: [reg])
|
|
||||||
in Symbol => src_reg if r64?(dst_reg) && r64?(src_reg)
|
|
||||||
# REX.W + 89 /r
|
|
||||||
# MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
|
|
||||||
insn(
|
|
||||||
prefix: REX_W,
|
|
||||||
opcode: 0x89,
|
|
||||||
mod_rm: ModRM[mod: Mod00, reg: src_reg, rm: dst_reg],
|
|
||||||
)
|
|
||||||
end
|
|
||||||
in DwordPtr[reg: dst_reg, disp: dst_disp]
|
|
||||||
case src
|
case src
|
||||||
# MOV r/m32, imm32 (Mod 01: [reg]+disp8)
|
# MOV r/m32, imm32 (Mod 01: [reg]+disp8)
|
||||||
in Integer => src_imm if r64?(dst_reg) && imm8?(dst_disp) && imm32?(src_imm)
|
in IMM32 => src_imm
|
||||||
# C7 /0 id
|
# C7 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
||||||
insn(
|
insn(
|
||||||
@ -601,13 +589,35 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(src_imm),
|
imm: imm32(src_imm),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
in QwordPtr[Symbol => dst_reg, Integer => dst_disp]
|
in QwordPtr[R64 => dst_reg]
|
||||||
|
case src
|
||||||
|
# MOV r/m64, imm32 (Mod 00: [reg])
|
||||||
|
in IMM32 => src_imm
|
||||||
|
# REX.W + C7 /0 id
|
||||||
|
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
||||||
|
insn(
|
||||||
|
prefix: REX_W,
|
||||||
|
opcode: 0xc7,
|
||||||
|
mod_rm: ModRM[mod: Mod00, reg: 0, rm: dst_reg],
|
||||||
|
imm: imm32(src_imm),
|
||||||
|
)
|
||||||
|
# MOV r/m64, r64 (Mod 00: [reg])
|
||||||
|
in R64 => src_reg
|
||||||
|
# REX.W + 89 /r
|
||||||
|
# MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
|
||||||
|
insn(
|
||||||
|
prefix: REX_W,
|
||||||
|
opcode: 0x89,
|
||||||
|
mod_rm: ModRM[mod: Mod00, reg: src_reg, rm: dst_reg],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
in QwordPtr[R64 => dst_reg, IMM8 => dst_disp]
|
||||||
# Optimize encoding when disp is 0
|
# Optimize encoding when disp is 0
|
||||||
return mov([dst_reg], src) if dst_disp == 0
|
return mov([dst_reg], src) if dst_disp == 0
|
||||||
|
|
||||||
case src
|
case src
|
||||||
# MOV r/m64, imm32 (Mod 01: [reg]+disp8)
|
# MOV r/m64, imm32 (Mod 01: [reg]+disp8)
|
||||||
in Integer => src_imm if r64?(dst_reg) && imm8?(dst_disp) && imm32?(src_imm)
|
in IMM32 => src_imm
|
||||||
# REX.W + C7 /0 id
|
# REX.W + C7 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
||||||
insn(
|
insn(
|
||||||
@ -617,8 +627,21 @@ module RubyVM::RJIT
|
|||||||
disp: dst_disp,
|
disp: dst_disp,
|
||||||
imm: imm32(src_imm),
|
imm: imm32(src_imm),
|
||||||
)
|
)
|
||||||
|
# MOV r/m64, r64 (Mod 01: [reg]+disp8)
|
||||||
|
in R64 => src_reg
|
||||||
|
# REX.W + 89 /r
|
||||||
|
# MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
|
||||||
|
insn(
|
||||||
|
prefix: REX_W,
|
||||||
|
opcode: 0x89,
|
||||||
|
mod_rm: ModRM[mod: Mod01, reg: src_reg, rm: dst_reg],
|
||||||
|
disp: dst_disp,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
in QwordPtr[R64 => dst_reg, IMM32 => dst_disp]
|
||||||
|
case src
|
||||||
# MOV r/m64, imm32 (Mod 10: [reg]+disp32)
|
# MOV r/m64, imm32 (Mod 10: [reg]+disp32)
|
||||||
in Integer => src_imm if r64?(dst_reg) && imm32?(dst_disp) && imm32?(src_imm)
|
in IMM32 => src_imm
|
||||||
# REX.W + C7 /0 id
|
# REX.W + C7 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
|
||||||
insn(
|
insn(
|
||||||
@ -628,18 +651,8 @@ module RubyVM::RJIT
|
|||||||
disp: imm32(dst_disp),
|
disp: imm32(dst_disp),
|
||||||
imm: imm32(src_imm),
|
imm: imm32(src_imm),
|
||||||
)
|
)
|
||||||
# MOV r/m64, r64 (Mod 01: [reg]+disp8)
|
|
||||||
in Symbol => src_reg if r64?(dst_reg) && imm8?(dst_disp) && r64?(src_reg)
|
|
||||||
# REX.W + 89 /r
|
|
||||||
# MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
|
|
||||||
insn(
|
|
||||||
prefix: REX_W,
|
|
||||||
opcode: 0x89,
|
|
||||||
mod_rm: ModRM[mod: Mod01, reg: src_reg, rm: dst_reg],
|
|
||||||
disp: dst_disp,
|
|
||||||
)
|
|
||||||
# MOV r/m64, r64 (Mod 10: [reg]+disp32)
|
# MOV r/m64, r64 (Mod 10: [reg]+disp32)
|
||||||
in Symbol => src_reg if r64?(dst_reg) && imm32?(dst_disp) && r64?(src_reg)
|
in R64 => src_reg
|
||||||
# REX.W + 89 /r
|
# REX.W + 89 /r
|
||||||
# MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
|
# MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r)
|
||||||
insn(
|
insn(
|
||||||
@ -655,7 +668,7 @@ module RubyVM::RJIT
|
|||||||
def or(dst, src)
|
def or(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# OR r/m64, imm8 (Mod 11: reg)
|
# OR r/m64, imm8 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm8?(src_imm)
|
in [R64 => dst_reg, IMM8 => src_imm]
|
||||||
# REX.W + 83 /1 ib
|
# REX.W + 83 /1 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -665,7 +678,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(src_imm),
|
imm: imm8(src_imm),
|
||||||
)
|
)
|
||||||
# OR r/m64, imm32 (Mod 11: reg)
|
# OR r/m64, imm32 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm32?(src_imm)
|
in [R64 => dst_reg, IMM32 => src_imm]
|
||||||
# REX.W + 81 /1 id
|
# REX.W + 81 /1 id
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -675,7 +688,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(src_imm),
|
imm: imm32(src_imm),
|
||||||
)
|
)
|
||||||
# OR r64, r/m64 (Mod 01: [reg]+disp8)
|
# OR r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
in [Symbol => dst_reg, QwordPtr[Symbol => src_reg, Integer => src_disp]] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
|
in [R64 => dst_reg, QwordPtr[R64 => src_reg, IMM8 => src_disp]]
|
||||||
# REX.W + 0B /r
|
# REX.W + 0B /r
|
||||||
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
|
||||||
insn(
|
insn(
|
||||||
@ -690,7 +703,7 @@ module RubyVM::RJIT
|
|||||||
def push(src)
|
def push(src)
|
||||||
case src
|
case src
|
||||||
# PUSH r64
|
# PUSH r64
|
||||||
in Symbol => src_reg if r64?(src_reg)
|
in R64 => src_reg
|
||||||
# 50+rd
|
# 50+rd
|
||||||
# O: Operand 1: opcode + rd (r)
|
# O: Operand 1: opcode + rd (r)
|
||||||
insn(opcode: 0x50, rd: src_reg)
|
insn(opcode: 0x50, rd: src_reg)
|
||||||
@ -700,7 +713,7 @@ module RubyVM::RJIT
|
|||||||
def pop(dst)
|
def pop(dst)
|
||||||
case dst
|
case dst
|
||||||
# POP r64
|
# POP r64
|
||||||
in Symbol => dst_reg if r64?(dst_reg)
|
in R64 => dst_reg
|
||||||
# 58+ rd
|
# 58+ rd
|
||||||
# O: Operand 1: opcode + rd (r)
|
# O: Operand 1: opcode + rd (r)
|
||||||
insn(opcode: 0x58, rd: dst_reg)
|
insn(opcode: 0x58, rd: dst_reg)
|
||||||
@ -715,7 +728,7 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def sar(dst, src)
|
def sar(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm8?(src_imm)
|
in [R64 => dst_reg, IMM8 => src_imm]
|
||||||
# REX.W + C1 /7 ib
|
# REX.W + C1 /7 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8
|
||||||
insn(
|
insn(
|
||||||
@ -729,8 +742,8 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def sub(dst, src)
|
def sub(dst, src)
|
||||||
case [dst, src]
|
case [dst, src]
|
||||||
# SUB r/m64, imm8
|
# SUB r/m64, imm8 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm8?(src_imm)
|
in [R64 => dst_reg, IMM8 => src_imm]
|
||||||
# REX.W + 83 /5 ib
|
# REX.W + 83 /5 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r, w), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -740,7 +753,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(src_imm),
|
imm: imm8(src_imm),
|
||||||
)
|
)
|
||||||
# SUB r/m64, r64 (Mod 11: reg)
|
# SUB r/m64, r64 (Mod 11: reg)
|
||||||
in [Symbol => dst_reg, Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
|
in [R64 => dst_reg, R64 => src_reg]
|
||||||
# REX.W + 29 /r
|
# REX.W + 29 /r
|
||||||
# MR: Operand 1: ModRM:r/m (r, w), Operand 2: ModRM:reg (r)
|
# MR: Operand 1: ModRM:r/m (r, w), Operand 2: ModRM:reg (r)
|
||||||
insn(
|
insn(
|
||||||
@ -754,7 +767,7 @@ module RubyVM::RJIT
|
|||||||
def test(left, right)
|
def test(left, right)
|
||||||
case [left, right]
|
case [left, right]
|
||||||
# TEST r/m8*, imm8 (Mod 01: [reg]+disp8)
|
# TEST r/m8*, imm8 (Mod 01: [reg]+disp8)
|
||||||
in [BytePtr[Symbol => left_reg, Integer => left_disp], Integer => right_imm] if imm8?(right_imm) && right_imm >= 0
|
in [BytePtr[R64 => left_reg, IMM8 => left_disp], IMM8 => right_imm]
|
||||||
# REX + F6 /0 ib
|
# REX + F6 /0 ib
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -764,7 +777,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm8(right_imm),
|
imm: imm8(right_imm),
|
||||||
)
|
)
|
||||||
# TEST r/m64, imm32 (Mod 01: [reg]+disp8)
|
# TEST r/m64, imm32 (Mod 01: [reg]+disp8)
|
||||||
in [QwordPtr[Symbol => left_reg, Integer => left_disp], Integer => right_imm] if imm8?(left_disp) && imm32?(right_imm)
|
in [QwordPtr[R64 => left_reg, IMM8 => left_disp], IMM32 => right_imm]
|
||||||
# REX.W + F7 /0 id
|
# REX.W + F7 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -775,7 +788,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(right_imm),
|
imm: imm32(right_imm),
|
||||||
)
|
)
|
||||||
# TEST r/m64, imm32 (Mod 10: [reg]+disp32)
|
# TEST r/m64, imm32 (Mod 10: [reg]+disp32)
|
||||||
in [QwordPtr[Symbol => left_reg, Integer => left_disp], Integer => right_imm] if imm32?(left_disp) && imm32?(right_imm)
|
in [QwordPtr[R64 => left_reg, IMM32 => left_disp], IMM32 => right_imm]
|
||||||
# REX.W + F7 /0 id
|
# REX.W + F7 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -786,7 +799,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(right_imm),
|
imm: imm32(right_imm),
|
||||||
)
|
)
|
||||||
# TEST r/m64, imm32 (Mod 11: reg)
|
# TEST r/m64, imm32 (Mod 11: reg)
|
||||||
in [Symbol => left_reg, Integer => right_imm] if r64?(left_reg) && imm32?(right_imm)
|
in [R64 => left_reg, IMM32 => right_imm]
|
||||||
# REX.W + F7 /0 id
|
# REX.W + F7 /0 id
|
||||||
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
# MI: Operand 1: ModRM:r/m (r), Operand 2: imm8/16/32
|
||||||
insn(
|
insn(
|
||||||
@ -796,7 +809,7 @@ module RubyVM::RJIT
|
|||||||
imm: imm32(right_imm),
|
imm: imm32(right_imm),
|
||||||
)
|
)
|
||||||
# TEST r/m32, r32 (Mod 11: reg)
|
# TEST r/m32, r32 (Mod 11: reg)
|
||||||
in [Symbol => left_reg, Symbol => right_reg] if r32?(left_reg) && r32?(right_reg)
|
in [R32 => left_reg, R32 => right_reg]
|
||||||
# 85 /r
|
# 85 /r
|
||||||
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
||||||
insn(
|
insn(
|
||||||
@ -804,7 +817,7 @@ module RubyVM::RJIT
|
|||||||
mod_rm: ModRM[mod: Mod11, reg: right_reg, rm: left_reg],
|
mod_rm: ModRM[mod: Mod11, reg: right_reg, rm: left_reg],
|
||||||
)
|
)
|
||||||
# TEST r/m64, r64 (Mod 11: reg)
|
# TEST r/m64, r64 (Mod 11: reg)
|
||||||
in [Symbol => left_reg, Symbol => right_reg] if r64?(left_reg) && r64?(right_reg)
|
in [R64 => left_reg, R64 => right_reg]
|
||||||
# REX.W + 85 /r
|
# REX.W + 85 /r
|
||||||
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
# MR: Operand 1: ModRM:r/m (r), Operand 2: ModRM:reg (r)
|
||||||
insn(
|
insn(
|
||||||
@ -859,10 +872,6 @@ module RubyVM::RJIT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def imm32?(imm)
|
|
||||||
(-0x8000_0000..0x7fff_ffff).include?(imm) # TODO: consider uimm
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def insn(prefix: 0, opcode:, rd: nil, mod_rm: nil, disp: nil, imm: nil)
|
def insn(prefix: 0, opcode:, rd: nil, mod_rm: nil, disp: nil, imm: nil)
|
||||||
@ -901,34 +910,6 @@ module RubyVM::RJIT
|
|||||||
reg_code_extended(reg).first
|
reg_code_extended(reg).first
|
||||||
end
|
end
|
||||||
|
|
||||||
def extended_reg?(reg)
|
|
||||||
reg_code_extended(reg).last
|
|
||||||
end
|
|
||||||
|
|
||||||
def reg_code_extended(reg)
|
|
||||||
case reg
|
|
||||||
# Not extended
|
|
||||||
when :al, :ax, :eax, :rax then [0, false]
|
|
||||||
when :cl, :cx, :ecx, :rcx then [1, false]
|
|
||||||
when :dl, :dx, :edx, :rdx then [2, false]
|
|
||||||
when :bl, :bx, :ebx, :rbx then [3, false]
|
|
||||||
when :ah, :sp, :esp, :rsp then [4, false]
|
|
||||||
when :ch, :bp, :ebp, :rbp then [5, false]
|
|
||||||
when :dh, :si, :esi, :rsi then [6, false]
|
|
||||||
when :bh, :di, :edi, :rdi then [7, false]
|
|
||||||
# Extended
|
|
||||||
when :r8b, :r8w, :r8d, :r8 then [0, true]
|
|
||||||
when :r9b, :r9w, :r9d, :r9 then [1, true]
|
|
||||||
when :r10b, :r10w, :r10d, :r10 then [2, true]
|
|
||||||
when :r11b, :r11w, :r11d, :r11 then [3, true]
|
|
||||||
when :r12b, :r12w, :r12d, :r12 then [4, true]
|
|
||||||
when :r13b, :r13w, :r13d, :r13 then [5, true]
|
|
||||||
when :r14b, :r14w, :r14d, :r14 then [6, true]
|
|
||||||
when :r15b, :r15w, :r15d, :r15 then [7, true]
|
|
||||||
else raise ArgumentError, "unexpected reg: #{reg.inspect}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte
|
# Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte
|
||||||
#
|
#
|
||||||
# 7 6 5 4 3 2 1 0
|
# 7 6 5 4 3 2 1 0
|
||||||
@ -992,30 +973,6 @@ module RubyVM::RJIT
|
|||||||
bytes
|
bytes
|
||||||
end
|
end
|
||||||
|
|
||||||
def imm8?(imm)
|
|
||||||
(-0x80..0x7f).include?(imm)
|
|
||||||
end
|
|
||||||
|
|
||||||
def imm64?(imm)
|
|
||||||
(-0x8000_0000_0000_0000..0xffff_ffff_ffff_ffff).include?(imm)
|
|
||||||
end
|
|
||||||
|
|
||||||
def r32?(reg)
|
|
||||||
if extended_reg?(reg)
|
|
||||||
reg.end_with?('d')
|
|
||||||
else
|
|
||||||
reg.start_with?('e')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def r64?(reg)
|
|
||||||
if extended_reg?(reg)
|
|
||||||
reg.match?(/\Ar\d+\z/)
|
|
||||||
else
|
|
||||||
reg.start_with?('r')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def rel32(addr)
|
def rel32(addr)
|
||||||
[Rel32.new(addr), Rel32Pad, Rel32Pad, Rel32Pad]
|
[Rel32.new(addr), Rel32Pad, Rel32Pad, Rel32Pad]
|
||||||
end
|
end
|
||||||
@ -1064,4 +1021,67 @@ module RubyVM::RJIT
|
|||||||
Fiddle::Pointer.new(addr)[0, @bytes.size] = @bytes.pack('c*')
|
Fiddle::Pointer.new(addr)[0, @bytes.size] = @bytes.pack('c*')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module OperandMatcher
|
||||||
|
def imm8?(imm)
|
||||||
|
(-0x80..0x7f).include?(imm)
|
||||||
|
end
|
||||||
|
|
||||||
|
def imm32?(imm)
|
||||||
|
(-0x8000_0000..0x7fff_ffff).include?(imm) # TODO: consider uimm
|
||||||
|
end
|
||||||
|
|
||||||
|
def imm64?(imm)
|
||||||
|
(-0x8000_0000_0000_0000..0xffff_ffff_ffff_ffff).include?(imm)
|
||||||
|
end
|
||||||
|
|
||||||
|
def r32?(reg)
|
||||||
|
if extended_reg?(reg)
|
||||||
|
reg.end_with?('d')
|
||||||
|
else
|
||||||
|
reg.start_with?('e')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def r64?(reg)
|
||||||
|
if extended_reg?(reg)
|
||||||
|
reg.match?(/\Ar\d+\z/)
|
||||||
|
else
|
||||||
|
reg.start_with?('r')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def extended_reg?(reg)
|
||||||
|
reg_code_extended(reg).last
|
||||||
|
end
|
||||||
|
|
||||||
|
def reg_code_extended(reg)
|
||||||
|
case reg
|
||||||
|
# Not extended
|
||||||
|
when :al, :ax, :eax, :rax then [0, false]
|
||||||
|
when :cl, :cx, :ecx, :rcx then [1, false]
|
||||||
|
when :dl, :dx, :edx, :rdx then [2, false]
|
||||||
|
when :bl, :bx, :ebx, :rbx then [3, false]
|
||||||
|
when :ah, :sp, :esp, :rsp then [4, false]
|
||||||
|
when :ch, :bp, :ebp, :rbp then [5, false]
|
||||||
|
when :dh, :si, :esi, :rsi then [6, false]
|
||||||
|
when :bh, :di, :edi, :rdi then [7, false]
|
||||||
|
# Extended
|
||||||
|
when :r8b, :r8w, :r8d, :r8 then [0, true]
|
||||||
|
when :r9b, :r9w, :r9d, :r9 then [1, true]
|
||||||
|
when :r10b, :r10w, :r10d, :r10 then [2, true]
|
||||||
|
when :r11b, :r11w, :r11d, :r11 then [3, true]
|
||||||
|
when :r12b, :r12w, :r12d, :r12 then [4, true]
|
||||||
|
when :r13b, :r13w, :r13d, :r13 then [5, true]
|
||||||
|
when :r14b, :r14w, :r14d, :r14 then [6, true]
|
||||||
|
when :r15b, :r15w, :r15d, :r15 then [7, true]
|
||||||
|
else raise ArgumentError, "unexpected reg: #{reg.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Assembler
|
||||||
|
include OperandMatcher
|
||||||
|
extend OperandMatcher
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -2792,7 +2792,7 @@ module RubyVM::RJIT
|
|||||||
# @param asm [RubyVM::RJIT::Assembler]
|
# @param asm [RubyVM::RJIT::Assembler]
|
||||||
def jit_check_ints(jit, ctx, asm)
|
def jit_check_ints(jit, ctx, asm)
|
||||||
asm.comment('RUBY_VM_CHECK_INTS(ec)')
|
asm.comment('RUBY_VM_CHECK_INTS(ec)')
|
||||||
asm.mov(:eax, [EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
|
asm.mov(:eax, DwordPtr[EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
|
||||||
asm.test(:eax, :eax)
|
asm.test(:eax, :eax)
|
||||||
asm.jnz(side_exit(jit, ctx))
|
asm.jnz(side_exit(jit, ctx))
|
||||||
end
|
end
|
||||||
|
@ -111,9 +111,23 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def test_cmp
|
def test_cmp
|
||||||
asm = Assembler.new
|
asm = Assembler.new
|
||||||
asm.cmp(:rax, 0) # CMP r/m64, imm8 (Mod 11: reg)
|
asm.cmp(BytePtr[:rax, 8], 8) # CMP r/m8, imm8 (Mod 01: [reg]+disp8)
|
||||||
|
asm.cmp(DwordPtr[:rax, 8], 0x100) # CMP r/m32, imm32 (Mod 01: [reg]+disp8)
|
||||||
|
asm.cmp([:rax, 8], 8) # CMP r/m64, imm8 (Mod 01: [reg]+disp8)
|
||||||
|
asm.cmp([:rax, 0x100], 8) # CMP r/m64, imm8 (Mod 10: [reg]+disp32)
|
||||||
|
asm.cmp(:rax, 8) # CMP r/m64, imm8 (Mod 11: reg)
|
||||||
|
asm.cmp(:rax, 0x100) # CMP r/m64, imm32 (Mod 11: reg)
|
||||||
|
asm.cmp([:rax, 8], :rbx) # CMP r/m64, r64 (Mod 01: [reg]+disp8)
|
||||||
|
asm.cmp(:rax, :rbx) # CMP r/m64, r64 (Mod 11: reg)
|
||||||
assert_compile(asm, <<~EOS)
|
assert_compile(asm, <<~EOS)
|
||||||
0x0: cmp rax, 0
|
0x0: cmp byte ptr [rax + 8], 8
|
||||||
|
0x4: cmp dword ptr [rax + 8], 0x100
|
||||||
|
0xb: cmp qword ptr [rax + 8], 8
|
||||||
|
0x10: cmp qword ptr [rax + 0x100], 8
|
||||||
|
0x18: cmp rax, 8
|
||||||
|
0x1c: cmp rax, 0x100
|
||||||
|
0x23: cmp qword ptr [rax + 8], rbx
|
||||||
|
0x27: cmp rax, rbx
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -201,19 +215,45 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def test_mov
|
def test_mov
|
||||||
asm = Assembler.new
|
asm = Assembler.new
|
||||||
asm.mov(:rax, :rbx) # MOV r64, r/m64 (Mod 00: [reg])
|
asm.mov(:eax, DwordPtr[:rbx, 8]) # MOV r32 r/m32 (Mod 01: [reg]+disp8)
|
||||||
asm.mov(:rax, [:rbx, 8]) # MOV r64, r/m64 (Mod 01: [reg]+disp8)
|
asm.mov(:eax, 0x100) # MOV r32, imm32 (Mod 11: reg)
|
||||||
|
asm.mov(:rax, [:rbx]) # MOV r64, r/m64 (Mod 00: [reg])
|
||||||
|
asm.mov(:rax, [:rbx, 8]) # MOV r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
|
asm.mov(:rax, [:rbx, 0x100]) # MOV r64, r/m64 (Mod 10: [reg]+disp32)
|
||||||
|
asm.mov(:rax, :rbx) # MOV r64, r/m64 (Mod 11: reg)
|
||||||
|
asm.mov(:rax, 0x100) # MOV r/m64, imm32 (Mod 11: reg)
|
||||||
|
asm.mov(:rax, 0x100000000) # MOV r64, imm64
|
||||||
|
asm.mov(DwordPtr[:rax, 8], 0x100) # MOV r/m32, imm32 (Mod 01: [reg]+disp8)
|
||||||
|
asm.mov([:rax], 0x100) # MOV r/m64, imm32 (Mod 00: [reg])
|
||||||
|
asm.mov([:rax], :rbx) # MOV r/m64, r64 (Mod 00: [reg])
|
||||||
|
asm.mov([:rax, 8], 0x100) # MOV r/m64, imm32 (Mod 01: [reg]+disp8)
|
||||||
|
asm.mov([:rax, 8], :rbx) # MOV r/m64, r64 (Mod 01: [reg]+disp8)
|
||||||
|
asm.mov([:rax, 0x100], 0x100) # MOV r/m64, imm32 (Mod 10: [reg]+disp32)
|
||||||
|
asm.mov([:rax, 0x100], :rbx) # MOV r/m64, r64 (Mod 10: [reg]+disp32)
|
||||||
assert_compile(asm, <<~EOS)
|
assert_compile(asm, <<~EOS)
|
||||||
0x0: mov rax, rbx
|
0x0: mov eax, dword ptr [rbx + 8]
|
||||||
0x3: mov rax, qword ptr [rbx + 8]
|
0x3: mov eax, 0x100
|
||||||
|
0x8: mov rax, qword ptr [rbx]
|
||||||
|
0xb: mov rax, qword ptr [rbx + 8]
|
||||||
|
0xf: mov rax, qword ptr [rbx + 0x100]
|
||||||
|
0x16: mov rax, rbx
|
||||||
|
0x19: mov rax, 0x100
|
||||||
|
0x20: movabs rax, 0x100000000
|
||||||
|
0x2a: mov dword ptr [rax + 8], 0x100
|
||||||
|
0x31: mov qword ptr [rax], 0x100
|
||||||
|
0x38: mov qword ptr [rax], rbx
|
||||||
|
0x3b: mov qword ptr [rax + 8], 0x100
|
||||||
|
0x43: mov qword ptr [rax + 8], rbx
|
||||||
|
0x47: mov qword ptr [rax + 0x100], 0x100
|
||||||
|
0x52: mov qword ptr [rax + 0x100], rbx
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_or
|
def test_or
|
||||||
asm = Assembler.new
|
asm = Assembler.new
|
||||||
asm.or(:rax, 0) # OR r/m64, imm8 (Mod 11: reg)
|
asm.or(:rax, 0) # OR r/m64, imm8 (Mod 11: reg)
|
||||||
asm.or(:rax, 0xffff) # OR r/m64, imm32 (Mod 11: reg)
|
asm.or(:rax, 0xffff) # OR r/m64, imm32 (Mod 11: reg)
|
||||||
asm.or(:rax, [:rbx, 8]) # OR r64, r/m64 (Mod 01: [reg]+disp8)
|
asm.or(:rax, [:rbx, 8]) # OR r64, r/m64 (Mod 01: [reg]+disp8)
|
||||||
assert_compile(asm, <<~EOS)
|
assert_compile(asm, <<~EOS)
|
||||||
0x0: or rax, 0
|
0x0: or rax, 0
|
||||||
0x4: or rax, 0xffff
|
0x4: or rax, 0xffff
|
||||||
@ -245,7 +285,7 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def test_sar
|
def test_sar
|
||||||
asm = Assembler.new
|
asm = Assembler.new
|
||||||
asm.sar(:rax, 0) # SAR r/m64, imm8 (Mod 11: reg)
|
asm.sar(:rax, 0) # SAR r/m64, imm8 (Mod 11: reg)
|
||||||
assert_compile(asm, <<~EOS)
|
assert_compile(asm, <<~EOS)
|
||||||
0x0: sar rax, 0
|
0x0: sar rax, 0
|
||||||
EOS
|
EOS
|
||||||
@ -253,9 +293,11 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def test_sub
|
def test_sub
|
||||||
asm = Assembler.new
|
asm = Assembler.new
|
||||||
asm.sub(:rax, 0) # SUB r/m64, imm8 (Mod 11: reg)
|
asm.sub(:rax, 8) # SUB r/m64, imm8 (Mod 11: reg)
|
||||||
|
asm.sub(:rax, :rbx) # SUB r/m64, r64 (Mod 11: reg)
|
||||||
assert_compile(asm, <<~EOS)
|
assert_compile(asm, <<~EOS)
|
||||||
0x0: sub rax, 0
|
0x0: sub rax, 8
|
||||||
|
0x4: sub rax, rbx
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user