74 |
AMD64_RAX,8); |
AMD64_RAX,8); |
75 |
} |
} |
76 |
|
|
77 |
|
/* |
78 |
|
* Try to branch directly to the specified JIT block without returning to |
79 |
|
* main loop. |
80 |
|
*/ |
81 |
|
static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, |
82 |
|
m_uint64_t new_pc) |
83 |
|
{ |
84 |
|
m_uint64_t new_page; |
85 |
|
m_uint32_t pc_hash,pc_offset; |
86 |
|
u_char *test1,*test2,*test3; |
87 |
|
|
88 |
|
new_page = new_pc & MIPS_MIN_PAGE_MASK; |
89 |
|
pc_offset = (new_pc & MIPS_MIN_PAGE_IMASK) >> 2; |
90 |
|
pc_hash = mips64_jit_get_pc_hash(new_pc); |
91 |
|
|
92 |
|
/* Get JIT block info in %rdx */ |
93 |
|
amd64_mov_reg_membase(b->jit_ptr,AMD64_RBX, |
94 |
|
AMD64_R15,OFFSET(cpu_mips_t,exec_blk_map),8); |
95 |
|
amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, |
96 |
|
AMD64_RBX,pc_hash*sizeof(void *),8); |
97 |
|
|
98 |
|
/* no JIT block found ? */ |
99 |
|
amd64_test_reg_reg(b->jit_ptr,AMD64_RDX,AMD64_RDX); |
100 |
|
test1 = b->jit_ptr; |
101 |
|
amd64_branch8(b->jit_ptr, X86_CC_Z, 0, 1); |
102 |
|
|
103 |
|
/* Check block IA */ |
104 |
|
mips64_load_imm(b,AMD64_RAX,new_page); |
105 |
|
amd64_alu_reg_membase_size(b->jit_ptr,X86_CMP,X86_EAX,AMD64_RDX, |
106 |
|
OFFSET(mips64_jit_tcb_t,start_pc),4); |
107 |
|
test2 = b->jit_ptr; |
108 |
|
amd64_branch8(b->jit_ptr, X86_CC_NE, 0, 1); |
109 |
|
|
110 |
|
/* Jump to the code */ |
111 |
|
amd64_mov_reg_membase(b->jit_ptr,AMD64_RSI, |
112 |
|
AMD64_RDX,OFFSET(mips64_jit_tcb_t,jit_insn_ptr),8); |
113 |
|
amd64_mov_reg_membase(b->jit_ptr,AMD64_RBX, |
114 |
|
AMD64_RSI,pc_offset * sizeof(void *),8); |
115 |
|
|
116 |
|
amd64_test_reg_reg(b->jit_ptr,AMD64_RBX,AMD64_RBX); |
117 |
|
test3 = b->jit_ptr; |
118 |
|
amd64_branch8(b->jit_ptr, X86_CC_Z, 0, 1); |
119 |
|
amd64_jump_reg(b->jit_ptr,AMD64_RBX); |
120 |
|
|
121 |
|
/* Returns to caller... */ |
122 |
|
amd64_patch(test1,b->jit_ptr); |
123 |
|
amd64_patch(test2,b->jit_ptr); |
124 |
|
amd64_patch(test3,b->jit_ptr); |
125 |
|
|
126 |
|
mips64_set_pc(b,new_pc); |
127 |
|
mips64_jit_tcb_push_epilog(b); |
128 |
|
} |
129 |
|
|
130 |
/* Set Jump */ |
/* Set Jump */ |
131 |
static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, |
static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, |
132 |
m_uint64_t new_pc,int local_jump) |
m_uint64_t new_pc,int local_jump) |
141 |
if (jump_ptr) { |
if (jump_ptr) { |
142 |
amd64_jump_code(b->jit_ptr,jump_ptr); |
amd64_jump_code(b->jit_ptr,jump_ptr); |
143 |
} else { |
} else { |
144 |
|
/* Never jump directly to code in a delay slot */ |
145 |
|
if (mips64_jit_is_delay_slot(b,new_pc)) { |
146 |
|
mips64_set_pc(b,new_pc); |
147 |
|
mips64_jit_tcb_push_epilog(b); |
148 |
|
return; |
149 |
|
} |
150 |
|
|
151 |
mips64_jit_tcb_record_patch(b,b->jit_ptr,new_pc); |
mips64_jit_tcb_record_patch(b,b->jit_ptr,new_pc); |
152 |
amd64_jump32(b->jit_ptr,0); |
amd64_jump32(b->jit_ptr,0); |
153 |
} |
} |
154 |
} else { |
} else { |
155 |
/* save PC */ |
if (cpu->exec_blk_direct_jump) { |
156 |
mips64_set_pc(b,new_pc); |
/* Block lookup optimization */ |
157 |
|
mips64_try_direct_far_jump(cpu,b,new_pc); |
158 |
/* address is in another block, for now, returns to caller */ |
} else { |
159 |
mips64_jit_tcb_push_epilog(b); |
mips64_set_pc(b,new_pc); |
160 |
|
mips64_jit_tcb_push_epilog(b); |
161 |
|
} |
162 |
} |
} |
163 |
} |
} |
164 |
|
|
2757 |
{ mips64_emit_XOR , 0xfc0007ff , 0x00000026, 1 }, |
{ mips64_emit_XOR , 0xfc0007ff , 0x00000026, 1 }, |
2758 |
{ mips64_emit_XORI , 0xfc000000 , 0x38000000, 1 }, |
{ mips64_emit_XORI , 0xfc000000 , 0x38000000, 1 }, |
2759 |
{ mips64_emit_unknown , 0x00000000 , 0x00000000, 1 }, |
{ mips64_emit_unknown , 0x00000000 , 0x00000000, 1 }, |
2760 |
|
{ NULL , 0x00000000 , 0x00000000, 0 }, |
2761 |
}; |
}; |