1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "InterpKernelAsmX86.hxx"
27 #ifdef _POSIX_MAPPED_FILES
35 const char *INTERP_KERNEL::AsmX86::OPS[NB_OF_OPS]={"mov","push","pop","fld","faddp","fsubp","fmulp","fdivp","fcos","fsin","fabs","fchs","fsqrt","sub","add","ret","leave","movsd","fst"};
37 std::vector<char> INTERP_KERNEL::AsmX86::convertIntoMachineLangage(const std::vector<std::string>& asmb) const
39 std::vector<char> ret;
40 for(std::vector<std::string>::const_iterator iter=asmb.begin();iter!=asmb.end();iter++)
41 convertOneInstructionInML(*iter,ret);
45 char *INTERP_KERNEL::AsmX86::copyToExecMemZone(const std::vector<char>& ml, unsigned& offset) const
49 #ifdef _POSIX_MAPPED_FILES
50 ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0);
53 HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL);
54 ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth);
58 std::copy(ml.begin(),ml.end(),ret);
62 void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector<char>& ml) const
64 std::string::size_type pos=inst.find_first_of(' ');
67 if(pos!=std::string::npos)
69 op=inst.substr(0,pos);
70 param=inst.substr(pos+1);
75 for(const char **it=OPS;it!=OPS+NB_OF_OPS;it++,id++)
87 convertPush(param,ml);
96 convertFaddp(param,ml);
99 convertFsubp(param,ml);
102 convertFmulp(param,ml);
105 convertFdivp(param,ml);
108 convertFcos(param,ml);
111 convertFsin(param,ml);
114 convertFabs(param,ml);
117 convertFchs(param,ml);
120 convertFsqrt(param,ml);
123 convertSub(param,ml);
126 convertAdd(param,ml);
129 convertRet(param,ml);
132 convertLeave(param,ml);
135 convertMovsd(param,ml);
138 convertFst(param,ml);
142 std::ostringstream oss; oss << "Unrecognized op : " << op << " in assembly line : " << inst;
143 throw INTERP_KERNEL::Exception(oss.str().c_str());
150 void INTERP_KERNEL::AsmX86::convertMov(const std::string& inst, std::vector<char>& ml)
152 const char ASM1[]="ebp,esp";
153 const unsigned char ML1[2]={0x89,0xe5};
156 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
159 const char ASM2[]="rbp,rsp";
160 const unsigned char ML2[3]={0x48,0x89,0xe5};
163 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
166 std::string::size_type pos=inst.find_first_of(' ');
167 if(pos==std::string::npos)
169 std::ostringstream oss; oss << "not recognized instruction mov : " << inst;
170 throw INTERP_KERNEL::Exception(oss.str().c_str());
172 std::string inst2=inst.substr(pos+1);
173 pos=inst2.find_first_of(',');
174 if(pos==std::string::npos)
176 std::ostringstream oss; oss << "not recognized instruction mov : " << inst;
177 throw INTERP_KERNEL::Exception(oss.str().c_str());
179 std::string inst3=inst2.substr(0,pos);
180 std::string inst4=inst2.substr(pos+1);
181 convertMovToEsp(inst3,inst4,ml);
184 void INTERP_KERNEL::AsmX86::convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector<char>& ml)
186 if(inst1[0]!='[' || inst1[inst1.length()-1]!=']')
187 throw INTERP_KERNEL::Exception("not recognized convertMovToEsp exp !");
188 std::string inst1bis=inst1.substr(1,inst1.length()-2);
189 const char ASM1[]="esp";
190 const unsigned char ML1[3]={0xc7,0x04,0x24};
192 {//mov dword [esp],0x3ff3c0ca
193 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
194 appendAddress(inst2,4,ml);
197 if(inst1bis.substr(0,3)==ASM1)
200 {//mov dword [esp+4],0x3ff3c0ca
201 const unsigned char ML2[3]={0xc7,0x44,0x24};
202 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
203 std::string::size_type pos=inst1bis.find_first_of(']');
204 std::string inst1_1=inst1bis.substr(4,pos-4-1);
205 appendAddress(inst1_1,1,ml);
206 appendAddress(inst2,4,ml);
210 throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],...");
212 const char ASM3[]="rsp";
213 const unsigned char ML3[3]={0xc7,0x04,0x24};
215 {//mov dword [rsp],0x3ff3c0ca
216 ml.insert(ml.end(),ML3,ML3+sizeof(ML3));
217 appendAddress(inst2,4,ml);
220 if(inst1bis.substr(0,3)==ASM3)
223 {//mov dword [rsp+4],0x3ff3c0ca
224 const unsigned char ML2[3]={0xc7,0x44,0x24};
225 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
226 std::string::size_type pos=inst1bis.find_first_of(']');
227 std::string inst1_1=inst1bis.substr(4,pos-4-1);
228 appendAddress(inst1_1,1,ml);
229 appendAddress(inst2,4,ml);
233 throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],...");
235 throw INTERP_KERNEL::Exception("Not recognized exp : mov");
238 void INTERP_KERNEL::AsmX86::convertPush(const std::string& inst, std::vector<char>& ml)
240 std::string::size_type pos=inst.find_first_of(' ');
241 std::string inst2=inst.substr(pos+1);
242 const char ASM1[]="ebp";
243 const unsigned char ML1[1]={0x55};
246 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
249 const char ASM2[]="ebx";
250 const unsigned char ML2[1]={0x53};
253 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
256 const char ASM3[]="rbp";
257 const unsigned char ML3[1]={0x55};
260 ml.insert(ml.end(),ML3,ML3+sizeof(ML3));
263 throw INTERP_KERNEL::Exception("Unrecognized push instruction");
266 void INTERP_KERNEL::AsmX86::convertPop(const std::string& inst, std::vector<char>& ml)
268 std::string::size_type pos=inst.find_first_of(' ');
269 std::string inst2=inst.substr(pos+1);
270 const char ASM1[]="ebp";
271 const unsigned char ML1[1]={0x5d};
274 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
277 const char ASM2[]="ebx";
278 const unsigned char ML2[1]={0x5b};
281 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
284 throw INTERP_KERNEL::Exception("Unrecognized pop instruction");
287 void INTERP_KERNEL::AsmX86::convertFld(const std::string& inst, std::vector<char>& ml)
289 std::string::size_type pos=inst.find_first_of(' ');
290 std::string params=inst.substr(pos+1);
291 std::string params2=params.substr(1,params.length()-2);
292 if(params2.substr(0,3)=="esp")
294 const unsigned char ML1[3]={0xdd,0x04,0x24};
295 if(params2.length()==3)
297 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
300 pos=params2.find_first_of('+');
301 if(pos!=std::string::npos)
303 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
304 std::string params3=params2.substr(pos+1);
305 appendAddress(params3,1,ml);
308 throw INTERP_KERNEL::Exception("Unrecognized fld esp...");
310 if(params2.substr(0,3)=="ebp")
312 const unsigned char ML2[2]={0xdd,0x45};
313 if(params2.length()==3)
315 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
319 pos=params2.find_first_of('+');
320 if(pos!=std::string::npos)
322 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
323 std::string params3=params2.substr(pos+1);
324 appendAddress(params3,1,ml);
327 throw INTERP_KERNEL::Exception("Unrecognized fld ebp...");
329 if(params2.substr(0,3)=="rsp")
331 const unsigned char ML2[3]={0xdd,0x04,0x24};
332 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));// to improve ! no fully managed !
335 throw INTERP_KERNEL::Exception("Unrecognized fld instruction");
338 void INTERP_KERNEL::AsmX86::convertFaddp(const std::string& inst, std::vector<char>& ml)
340 const unsigned char ML1[2]={0xde,0xc1};
341 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
344 void INTERP_KERNEL::AsmX86::convertFsubp(const std::string& inst, std::vector<char>& ml)
346 const unsigned char ML1[2]={0xde,0xe9};
347 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
350 void INTERP_KERNEL::AsmX86::convertFmulp(const std::string& inst, std::vector<char>& ml)
352 const unsigned char ML1[2]={0xde,0xc9};
353 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
356 void INTERP_KERNEL::AsmX86::convertFdivp(const std::string& inst, std::vector<char>& ml)
358 const unsigned char ML1[2]={0xde,0xf9};
359 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
362 void INTERP_KERNEL::AsmX86::convertFcos(const std::string& inst, std::vector<char>& ml)
364 const unsigned char ML[2]={0xd9,0xff};
365 ml.insert(ml.end(),ML,ML+sizeof(ML));
368 void INTERP_KERNEL::AsmX86::convertFsin(const std::string& inst, std::vector<char>& ml)
370 const unsigned char ML[2]={0xd9,0xfe};
371 ml.insert(ml.end(),ML,ML+sizeof(ML));
374 void INTERP_KERNEL::AsmX86::convertFabs(const std::string& inst, std::vector<char>& ml)
376 const unsigned char ML[2]={0xd9,0xe1};
377 ml.insert(ml.end(),ML,ML+sizeof(ML));
380 void INTERP_KERNEL::AsmX86::convertFchs(const std::string& inst, std::vector<char>& ml)
382 const unsigned char ML[2]={0xd9,0xe0};
383 ml.insert(ml.end(),ML,ML+sizeof(ML));
386 void INTERP_KERNEL::AsmX86::convertFsqrt(const std::string& inst, std::vector<char>& ml)
388 const unsigned char ML[2]={0xd9,0xfa};
389 ml.insert(ml.end(),ML,ML+sizeof(ML));
392 void INTERP_KERNEL::AsmX86::convertSub(const std::string& inst, std::vector<char>& ml)
394 if(inst.substr(0,4)=="esp,")
396 const unsigned char ML[2]={0x81,0xec};
397 ml.insert(ml.end(),ML,ML+sizeof(ML));
398 std::string inst2=inst.substr(4);
399 appendAddress(inst2,4,ml);
402 if(inst.substr(0,4)=="rsp,")
404 const unsigned char ML[4]={0x48,0x83,0xec,0x08};
405 ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!!
408 throw INTERP_KERNEL::Exception("Not recognized sub instruction.");
411 void INTERP_KERNEL::AsmX86::convertAdd(const std::string& inst, std::vector<char>& ml)
413 if(inst.substr(0,4)=="esp,")
415 const unsigned char ML[2]={0x81,0xc4};
416 ml.insert(ml.end(),ML,ML+sizeof(ML));
417 std::string inst2=inst.substr(4);
418 appendAddress(inst2,4,ml);
421 if(inst.substr(0,4)=="rsp,")
423 const unsigned char ML[4]={0x48,0x83,0xc4,0x08};
424 ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!!
427 throw INTERP_KERNEL::Exception("Not recognized add instruction.");
430 void INTERP_KERNEL::AsmX86::convertRet(const std::string& inst, std::vector<char>& ml)
432 const unsigned char ML[1]={0xc3};
433 ml.insert(ml.end(),ML,ML+sizeof(ML));
436 void INTERP_KERNEL::AsmX86::convertLeave(const std::string& inst, std::vector<char>& ml)
438 const unsigned char ML[1]={0xc9};
439 ml.insert(ml.end(),ML,ML+sizeof(ML));
442 void INTERP_KERNEL::AsmX86::convertMovsd(const std::string& inst, std::vector<char>& ml)
444 const char ASM1[]="[rsp],xmm0";
445 const unsigned char ML1[5]={0xf2,0x0f,0x11,0x04,0x24};
448 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
451 const char ASM2[]="xmm0,[rsp]";
452 const unsigned char ML2[5]={0xf2,0x0f,0x10,0x04,0x24};
455 ml.insert(ml.end(),ML2,ML2+sizeof(ML2));
458 std::ostringstream oss; oss << "not recognized instruction movsd : " << inst;
459 throw INTERP_KERNEL::Exception(oss.str().c_str());
462 void INTERP_KERNEL::AsmX86::convertFst(const std::string& inst, std::vector<char>& ml)
464 const char ASM1[]="qword [rsp]";
465 const unsigned char ML1[3]={0xdd,0x14,0x24};
468 ml.insert(ml.end(),ML1,ML1+sizeof(ML1));
471 std::ostringstream oss; oss << "not recognized instruction fst : " << inst;
472 throw INTERP_KERNEL::Exception(oss.str().c_str());
477 void INTERP_KERNEL::AsmX86::appendAddress(const std::string& addr, int nbOfByte, std::vector<char>& ml)
481 std::istringstream iss(addr);
484 if(addr[0]=='0' && addr[1]=='x')
488 for(int k=0;k<nbOfByte;k++)