Split branches for mov src and dst

This commit is contained in:
Takashi Kokubun 2022-12-28 13:16:02 -08:00
parent 5760f7fd3c
commit e9535a439b
2 changed files with 83 additions and 70 deletions

View File

@ -19,14 +19,14 @@ module RubyVM::MJIT
def leave(jit, ctx, asm) def leave(jit, ctx, asm)
assert_eq!(ctx.stack_size, 1) assert_eq!(ctx.stack_size, 1)
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, [EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
asm.test(:eax, :eax) asm.test(:eax, :eax)
asm.jz(not_interrupted = asm.new_label(:not_interrupted)) asm.jz(not_interrupted = asm.new_label(:not_interrupted))
Compiler.compile_exit(jit, ctx, asm) # TODO: use ocb Compiler.compile_exit(jit, ctx, asm) # TODO: use ocb
asm.write_label(not_interrupted) asm.write_label(not_interrupted)
asm.comment("pop stack frame") asm.comment('pop stack frame')
asm.add(CFP, C.rb_control_frame_t.size) # cfp = cfp + 1 asm.add(CFP, C.rb_control_frame_t.size) # cfp = cfp + 1
asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], CFP) # ec->cfp = cfp asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], CFP) # ec->cfp = cfp

View File

@ -68,74 +68,87 @@ module RubyVM::MJIT
end end
def mov(dst, src) def mov(dst, src)
case [dst, src] case dst
# MOV r32 r/m32 (Mod 01) in Symbol => dst_reg
in [Symbol => dst_reg, [Symbol => src_reg, Integer => src_disp]] if r32?(dst_reg) && imm8?(src_disp) case src
# 8B /r # MOV r64, r/m64 (Mod 00)
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r) in [Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg)
insn( # REX.W + 8B /r
opcode: 0x8b, # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
mod_rm: mod_rm(mod: 0b01, reg: reg_code(dst_reg), rm: reg_code(src_reg)), # Mod 01: [reg]+disp8 insn(
disp: src_disp, prefix: REX_W,
) opcode: 0x8b,
# MOV r/m64, imm32 (Mod 00) mod_rm: mod_rm(mod: 0b00, reg: reg_code(dst_reg), rm: reg_code(src_reg)), # Mod 00: [reg]
in [[Symbol => dst_reg], Integer => src_imm] if r64?(dst_reg) )
# REX.W + C7 /0 id # MOV r32 r/m32 (Mod 01)
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64 in [Symbol => src_reg, Integer => src_disp] if r32?(dst_reg) && imm8?(src_disp)
insn( # 8B /r
prefix: REX_W, # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
opcode: 0xc7, insn(
mod_rm: mod_rm(mod: 0b00, rm: reg_code(dst_reg)), # Mod 00: [reg] opcode: 0x8b,
imm: imm32(src_imm), mod_rm: mod_rm(mod: 0b01, reg: reg_code(dst_reg), rm: reg_code(src_reg)), # Mod 01: [reg]+disp8
) disp: src_disp,
# MOV r/m64, imm32 (Mod 11) )
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm32?(src_imm) # MOV r64, r/m64 (Mod 01)
# REX.W + C7 /0 id in [Symbol => src_reg, Integer => src_disp] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_disp)
# MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64 # REX.W + 8B /r
insn( # RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r)
prefix: REX_W, insn(
opcode: 0xc7, prefix: REX_W,
mod_rm: mod_rm(mod: 0b11, rm: reg_code(dst_reg)), # Mod 11: reg opcode: 0x8b,
imm: imm32(src_imm), mod_rm: mod_rm(mod: 0b01, reg: reg_code(dst_reg), rm: reg_code(src_reg)), # Mod 01: [reg]+disp8
) disp: src_disp,
# MOV r64, imm64 )
in [Symbol => dst_reg, Integer => src_imm] if r64?(dst_reg) && imm64?(src_imm) # MOV r/m64, imm32 (Mod 11)
# REX.W + B8+ rd io in Integer => src_imm if r64?(dst_reg) && imm32?(src_imm)
# OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64 # REX.W + C7 /0 id
insn( # MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
prefix: REX_W, insn(
opcode: 0xb8 + reg_code(dst_reg), prefix: REX_W,
imm: imm64(src_imm), opcode: 0xc7,
) mod_rm: mod_rm(mod: 0b11, rm: reg_code(dst_reg)), # Mod 11: reg
# MOV r/m64, r64 imm: imm32(src_imm),
in [[Symbol => dst_reg, Integer => dst_disp], Symbol => src_reg] if r64?(dst_reg) && r64?(src_reg) && imm8?(dst_disp) )
# REX.W + 89 /r # MOV r64, imm64
# MR: Operand 1: ModRM:r/m (w), Operand 2: ModRM:reg (r) in Integer => src_imm if r64?(dst_reg) && imm64?(src_imm)
insn( # REX.W + B8+ rd io
prefix: REX_W, # OI: Operand 1: opcode + rd (w), Operand 2: imm8/16/32/64
opcode: 0x89, insn(
mod_rm: mod_rm(mod: 0b01, reg: reg_code(src_reg), rm: reg_code(dst_reg)), # Mod 01: [reg]+disp8 prefix: REX_W,
disp: dst_disp, opcode: 0xb8 + reg_code(dst_reg),
) imm: imm64(src_imm),
# MOV r64, r/m64 (Mod 00) )
in [Symbol => dst_reg, [Symbol => src_reg]] if r64?(dst_reg) && r64?(src_reg) else
# REX.W + 8B /r raise NotImplementedError, "mov: not-implemented operands: #{dst.inspect}, #{src.inspect}"
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r) end
insn( in [Symbol => dst_reg]
prefix: REX_W, case src
opcode: 0x8b, # MOV r/m64, imm32 (Mod 00)
mod_rm: mod_rm(mod: 0b00, reg: reg_code(dst_reg), rm: reg_code(src_reg)), # Mod 00: [reg] in Integer => src_imm if r64?(dst_reg) && imm32?(src_imm)
) # REX.W + C7 /0 id
# MOV r64, r/m64 (Mod 01) # MI: Operand 1: ModRM:r/m (w), Operand 2: imm8/16/32/64
in [Symbol => dst_reg, [Symbol => src_reg, Integer => src_offset]] if r64?(dst_reg) && r64?(src_reg) && imm8?(src_offset) insn(
# REX.W + 8B /r prefix: REX_W,
# RM: Operand 1: ModRM:reg (w), Operand 2: ModRM:r/m (r) opcode: 0xc7,
insn( mod_rm: mod_rm(mod: 0b00, rm: reg_code(dst_reg)), # Mod 00: [reg]
prefix: REX_W, imm: imm32(src_imm),
opcode: 0x8b, )
mod_rm: mod_rm(mod: 0b01, reg: reg_code(dst_reg), rm: reg_code(src_reg)), # Mod 01: [reg]+disp8 end
disp: src_offset, in [Symbol => dst_reg, Integer => dst_disp]
) # MOV r/m64, r64 (Mod 01)
case src
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: mod_rm(mod: 0b01, reg: reg_code(src_reg), rm: reg_code(dst_reg)), # Mod 01: [reg]+disp8
disp: dst_disp,
)
else
raise NotImplementedError, "mov: not-implemented operands: #{dst.inspect}, #{src.inspect}"
end
else else
raise NotImplementedError, "mov: not-implemented operands: #{dst.inspect}, #{src.inspect}" raise NotImplementedError, "mov: not-implemented operands: #{dst.inspect}, #{src.inspect}"
end end