7979 break ; \
8080 }
8181
82- #define PROT_ASMJIT_S_OP (OP, DATA_TYPE ) \
83- case k##OP : { \
84- loadReg (rs1, insn.rs1 ()); \
85- cc.add (rs1, insn.imm ()); \
86- loadReg (rs2, insn.rs2 ()); \
87- asmjit::InvokeNode *invoke{}; \
88- cc.invoke (&invoke, reinterpret_cast <size_t >(storeHelper<DATA_TYPE >), \
89- asmjit::FuncSignature::build<void , CPUState &, isa::Addr, \
90- DATA_TYPE >()); \
91- invoke->setArg (0 , state_ptr); \
92- invoke->setArg (1 , rs1); \
93- invoke->setArg (2 , rs2); \
94- break ; \
95- }
96-
97- #define PROT_ASMJIT_L_OP (OP, DATA_TYPE ) \
98- case k##OP : { \
99- loadReg (rs1, insn.rs1 ()); \
100- cc.add (rs1, insn.imm ()); \
101- asmjit::InvokeNode *invoke = nullptr ; \
102- cc.invoke ( \
103- &invoke, reinterpret_cast <size_t >(loadHelper<DATA_TYPE >), \
104- asmjit::FuncSignature::build<DATA_TYPE , CPUState &, isa::Addr>()); \
105- invoke->setArg (0 , state_ptr); \
106- invoke->setArg (1 , rs1); \
107- invoke->setRet (0 , rd); \
108- switch (insn.opcode ()) { \
109- case kLB : \
110- cc.movsx (rd, rd.r8 ()); \
111- break ; \
112- case kLH : \
113- cc.movsx (rd, rd.r16 ()); \
114- break ; \
115- default : \
116- break ; \
117- } \
118- setDst (insn.rd (), rd); \
119- break ; \
120- }
121-
12282namespace prot ::engine {
12383namespace {
12484
@@ -134,14 +94,6 @@ class AsmJit : public Translator {
13494 asmjit::JitRuntime runtime;
13595};
13696
137- template <typename T> void storeHelper (CPUState &state, isa::Addr addr, T val) {
138- state.memory ->write (addr, val);
139- }
140-
141- template <typename T> T loadHelper (CPUState &state, isa::Addr addr) {
142- return state.memory ->read <T>(addr);
143- }
144-
14597void syscallHelper (CPUState &state) { state.emulateSysCall (); }
14698
14799JitFunction AsmJit::translate (const BBInfo &info) {
@@ -155,6 +107,10 @@ JitFunction AsmJit::translate(const BBInfo &info) {
155107 auto state_ptr = cc.newUIntPtr ();
156108 func_node->setArg (0 , state_ptr);
157109
110+ auto mem_base = cc.newUInt64 ();
111+ cc.mov (mem_base,
112+ asmjit::x86::qword_ptr (state_ptr, offsetof (CPUState, mem_base)));
113+
158114 auto getReg = [&state_ptr](auto regId) {
159115 return asmjit::x86::dword_ptr (state_ptr, offsetof (CPUState, regs) +
160116 isa::kWordSize * regId);
@@ -181,6 +137,9 @@ JitFunction AsmJit::translate(const BBInfo &info) {
181137 auto rs2 = cc.newGpd ();
182138 auto rd = cc.newGpd ();
183139
140+ auto guest_addr = cc.newGpd ();
141+ auto host_addr = cc.newUInt64 ();
142+
184143 for (const auto &insn : info.insns ) {
185144 switch (insn.opcode ()) {
186145 using enum isa::Opcode;
@@ -209,17 +168,102 @@ JitFunction AsmJit::translate(const BBInfo &info) {
209168 PROT_ASMJIT_B_COND_OP (BLTU , kUnsignedLT )
210169 PROT_ASMJIT_B_COND_OP (BGEU , kUnsignedGE )
211170
212- PROT_ASMJIT_L_OP (LB , prot::isa::Byte)
213- PROT_ASMJIT_L_OP (LH , prot::isa::Half)
214- PROT_ASMJIT_L_OP (LBU , prot::isa::Byte)
215- PROT_ASMJIT_L_OP (LHU , prot::isa::Half)
216- PROT_ASMJIT_L_OP (LW , prot::isa::Word)
171+ case kLW : {
172+ loadReg (guest_addr, insn.rs1 ());
173+ cc.add (guest_addr, insn.imm ());
174+
175+ cc.mov (host_addr, mem_base);
176+ cc.add (host_addr, guest_addr.r64 ());
177+
178+ cc.mov (rd, asmjit::x86::dword_ptr (host_addr));
179+ setDst (insn.rd (), rd);
180+ break ;
181+ }
182+
183+ case kLH : {
184+ loadReg (guest_addr, insn.rs1 ());
185+ cc.add (guest_addr, insn.imm ());
186+
187+ cc.mov (host_addr, mem_base);
188+ cc.add (host_addr, guest_addr.r64 ());
189+
190+ cc.movsx (rd, asmjit::x86::word_ptr (host_addr));
191+ setDst (insn.rd (), rd);
192+ break ;
193+ }
194+
195+ case kLHU : {
196+ loadReg (guest_addr, insn.rs1 ());
197+ cc.add (guest_addr, insn.imm ());
198+
199+ cc.mov (host_addr, mem_base);
200+ cc.add (host_addr, guest_addr.r64 ());
217201
218- PROT_ASMJIT_S_OP (SB , prot::isa::Byte)
219- PROT_ASMJIT_S_OP (SH , prot::isa::Half)
220- PROT_ASMJIT_S_OP (SW , prot::isa::Word)
202+ cc.movzx (rd, asmjit::x86::word_ptr (host_addr));
203+ setDst (insn.rd (), rd);
204+ break ;
205+ }
206+
207+ case kLB : {
208+ loadReg (guest_addr, insn.rs1 ());
209+ cc.add (guest_addr, insn.imm ());
210+
211+ cc.mov (host_addr, mem_base);
212+ cc.add (host_addr, guest_addr.r64 ());
213+
214+ cc.movsx (rd, asmjit::x86::byte_ptr (host_addr));
215+ setDst (insn.rd (), rd);
216+ break ;
217+ }
218+
219+ case kLBU : {
220+ loadReg (guest_addr, insn.rs1 ());
221+ cc.add (guest_addr, insn.imm ());
222+
223+ cc.mov (host_addr, mem_base);
224+ cc.add (host_addr, guest_addr.r64 ());
225+
226+ cc.movzx (rd, asmjit::x86::byte_ptr (host_addr));
227+ setDst (insn.rd (), rd);
228+ break ;
229+ }
230+
231+ case kSW : {
232+ loadReg (guest_addr, insn.rs1 ());
233+ cc.add (guest_addr, insn.imm ());
234+ loadReg (rd, insn.rs2 ());
235+
236+ cc.mov (host_addr, mem_base);
237+ cc.add (host_addr, guest_addr.r64 ());
238+
239+ cc.mov (asmjit::x86::dword_ptr (host_addr), rd);
240+ break ;
241+ }
242+
243+ case kSH : {
244+ loadReg (guest_addr, insn.rs1 ());
245+ cc.add (guest_addr, insn.imm ());
246+ loadReg (rd, insn.rs2 ());
247+
248+ cc.mov (host_addr, mem_base);
249+ cc.add (host_addr, guest_addr.r64 ());
250+
251+ cc.mov (asmjit::x86::word_ptr (host_addr), rd.r16 ());
252+ break ;
253+ }
254+
255+ case kSB : {
256+ loadReg (guest_addr, insn.rs1 ());
257+ cc.add (guest_addr, insn.imm ());
258+ loadReg (rd, insn.rs2 ());
259+
260+ cc.mov (host_addr, mem_base);
261+ cc.add (host_addr, guest_addr.r64 ());
262+
263+ cc.mov (asmjit::x86::byte_ptr (host_addr), rd.r8 ());
264+ break ;
265+ }
221266
222- // PROT_ASMJIT_J_OP
223267 case kJAL : {
224268 cc.mov (rd, getPC ());
225269 cc.add (rd, isa::kWordSize );
@@ -229,6 +273,7 @@ JitFunction AsmJit::translate(const BBInfo &info) {
229273 cc.mov (getPC (), pc);
230274 break ;
231275 }
276+
232277 case kJALR : {
233278 cc.mov (rd, getPC ());
234279 cc.add (rd, isa::kWordSize );
@@ -243,7 +288,6 @@ JitFunction AsmJit::translate(const BBInfo &info) {
243288 break ;
244289 }
245290
246- // PROT_ASMJIT_U_OP
247291 case kLUI : {
248292 cc.mov (rs1, insn.imm ());
249293 setDst (insn.rd (), rs1);
0 commit comments