2 /**********************************************************************
8 Copyright (C) 2004-2007 Koichi Sasada
10 **********************************************************************/
14 #if USE_YJIT || USE_RJIT
15 // The number of instructions executed on vm_exec_core. --yjit-stats uses this.
16 uint64_t rb_vm_insns_count
= 0;
19 #if VM_COLLECT_USAGE_DETAILS
20 static void vm_analysis_insn(int insn
);
24 #define DECL_SC_REG(type, r, reg) register type reg_##r
26 #elif defined(__GNUC__) && defined(__x86_64__)
27 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
29 #elif defined(__GNUC__) && defined(__i386__)
30 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg)
32 #elif defined(__GNUC__) && (defined(__powerpc64__) || defined(__POWERPC__))
33 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
35 #elif defined(__GNUC__) && defined(__aarch64__)
36 #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("x" reg)
39 #define DECL_SC_REG(type, r, reg) register type reg_##r
41 /* #define DECL_SC_REG(r, reg) VALUE reg_##r */
43 #if !OPT_CALL_THREADED_CODE
45 vm_exec_core(rb_execution_context_t
*ec
)
47 #if defined(__GNUC__) && defined(__i386__)
48 DECL_SC_REG(const VALUE
*, pc
, "di");
49 DECL_SC_REG(rb_control_frame_t
*, cfp
, "si");
50 #define USE_MACHINE_REGS 1
52 #elif defined(__GNUC__) && defined(__x86_64__)
53 DECL_SC_REG(const VALUE
*, pc
, "14");
54 DECL_SC_REG(rb_control_frame_t
*, cfp
, "15");
55 #define USE_MACHINE_REGS 1
57 #elif defined(__GNUC__) && (defined(__powerpc64__) || defined(__POWERPC__))
58 DECL_SC_REG(const VALUE
*, pc
, "14");
59 DECL_SC_REG(rb_control_frame_t
*, cfp
, "15");
60 #define USE_MACHINE_REGS 1
62 #elif defined(__GNUC__) && defined(__aarch64__)
63 DECL_SC_REG(const VALUE
*, pc
, "19");
64 DECL_SC_REG(rb_control_frame_t
*, cfp
, "20");
65 #define USE_MACHINE_REGS 1
68 register rb_control_frame_t
*reg_cfp
;
70 #define USE_MACHINE_REGS 0
77 #define RESTORE_REGS() \
79 VM_REG_CFP = ec->cfp; \
80 reg_pc = reg_cfp->pc; \
84 #define VM_REG_PC reg_pc
86 #define GET_PC() (reg_pc)
88 #define SET_PC(x) (reg_cfp->pc = VM_REG_PC = (x))
91 #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
93 if (UNLIKELY(ec
== 0)) {
94 return (VALUE
)insns_address_table
;
105 END_INSNS_DISPATCH();
108 rb_bug("vm_eval: unreachable");
113 rb_vm_get_insns_address_table(void)
115 return (const void **)vm_exec_core(0);
118 #else /* OPT_CALL_THREADED_CODE */
124 rb_vm_get_insns_address_table(void)
126 return (const void **)insns_address_table
;
130 vm_exec_core(rb_execution_context_t
*ec
)
132 register rb_control_frame_t
*reg_cfp
= ec
->cfp
;
136 reg_cfp
= ((rb_insn_func_t
) (*GET_PC()))(ec
, reg_cfp
);
138 if (UNLIKELY(reg_cfp
== 0)) {
143 if (!UNDEF_P((th
= rb_ec_thread_ptr(ec
))->retval
)) {
144 VALUE ret
= th
->retval
;
149 VALUE err
= ec
->errinfo
;