From ba5b388c134f9e8213412f7ac4e88fb858551983 Mon Sep 17 00:00:00 2001 From: ageay Date: Tue, 21 Sep 2010 08:41:19 +0000 Subject: [PATCH] *** empty log message *** --- .../ExprEval/InterpKernelAsmX86.cxx | 477 ++++++++++++++++++ .../ExprEval/InterpKernelAsmX86.hxx | 67 +++ .../ExprEval/InterpKernelExprParser.cxx | 181 ++++++- .../ExprEval/InterpKernelExprParser.hxx | 19 +- .../ExprEval/InterpKernelFunction.cxx | 85 +++- .../ExprEval/InterpKernelFunction.hxx | 18 + src/INTERP_KERNEL/ExprEval/Makefile.am | 7 +- 7 files changed, 839 insertions(+), 15 deletions(-) create mode 100644 src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx create mode 100644 src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx new file mode 100644 index 000000000..ee7116fd2 --- /dev/null +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx @@ -0,0 +1,477 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "InterpKernelAsmX86.hxx" + +#include +#include +#include + +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"}; + +std::vector INTERP_KERNEL::AsmX86::convertIntoMachineLangage(const std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + std::vector ret; + for(std::vector::const_iterator iter=asmb.begin();iter!=asmb.end();iter++) + convertOneInstructionInML(*iter,ret); + return ret; +} + +char *INTERP_KERNEL::AsmX86::convertMachineLangageInBasic(const std::vector& ml, int& lgth) const +{ + lgth=ml.size(); + char *ret=new char[lgth]; + std::copy(ml.begin(),ml.end(),ret); + return ret; +} + +void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector& ml) const throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string op; + std::string param; + if(pos!=std::string::npos) + { + op=inst.substr(0,pos); + param=inst.substr(pos+1); + } + else + op=inst; + int id=0; + for(const char **it=OPS;it!=OPS+NB_OF_OPS;it++,id++) + { + std::string tmp(*it); + if(op==tmp) + break; + } + switch(id) + { + case 0: + convertMov(param,ml); + break; + case 1: + convertPush(param,ml); + break; + case 2: + convertPop(param,ml); + break; + case 3: + convertFld(param,ml); + break; + case 4: + convertFaddp(param,ml); + break; + case 5: + convertFsubp(param,ml); + break; + case 6: + convertFmulp(param,ml); + break; + case 7: + convertFdivp(param,ml); + break; + case 8: + convertFcos(param,ml); + break; + case 9: + convertFsin(param,ml); + break; + case 10: + convertFabs(param,ml); + break; + case 11: + convertFchs(param,ml); + break; + case 12: + convertFsqrt(param,ml); + break; + case 13: + convertSub(param,ml); + break; + case 14: + convertAdd(param,ml); + break; + case 15: + convertRet(param,ml); + break; + case 16: + convertLeave(param,ml); + break; + case 17: + convertMovsd(param,ml); + break; + case 18: + convertFst(param,ml); + break; + default: + { + std::ostringstream oss; oss << "Unrecognized op : " << op << " in assembly line : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +#include + +void INTERP_KERNEL::AsmX86::convertMov(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ASM1[]="ebp,esp"; + const char ML1[2]={0x89,0xe5}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="rbp,rsp"; + const char ML2[3]={0x48,0x89,0xe5}; + if(inst==ASM2) + { + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + std::string::size_type pos=inst.find_first_of(' '); + if(pos==std::string::npos) + { + std::ostringstream oss; oss << "not recognized instruction mov : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string inst2=inst.substr(pos+1); + pos=inst2.find_first_of(','); + if(pos==std::string::npos) + { + std::ostringstream oss; oss << "not recognized instruction mov : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string inst3=inst2.substr(0,pos); + std::string inst4=inst2.substr(pos+1); + convertMovToEsp(inst3,inst4,ml); +} + +void INTERP_KERNEL::AsmX86::convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + if(inst1[0]!='[' || inst1[inst1.length()-1]!=']') + throw INTERP_KERNEL::Exception("not recognized convertMovToEsp exp !"); + std::string inst1bis=inst1.substr(1,inst1.length()-2); + const char ASM1[]="esp"; + const char ML1[3]={0xc7,0x04,0x24}; + if(inst1bis==ASM1) + {//mov dword [esp],0x3ff3c0ca + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + appendAddress(inst2,4,ml); + return ; + } + if(inst1bis.substr(0,3)==ASM1) + { + if(inst1bis[3]=='+') + {//mov dword [esp+4],0x3ff3c0ca + const char ML2[3]={0xc7,0x44,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string::size_type pos=inst1bis.find_first_of(']'); + std::string inst1_1=inst1bis.substr(4,pos-4-1); + appendAddress(inst1_1,1,ml); + appendAddress(inst2,4,ml); + return; + } + else + throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); + } + const char ASM3[]="rsp"; + const char ML3[3]={0xc7,0x04,0x24}; + if(inst1bis==ASM3) + {//mov dword [rsp],0x3ff3c0ca + ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); + appendAddress(inst2,4,ml); + return ; + } + if(inst1bis.substr(0,3)==ASM3) + { + if(inst1bis[3]=='+') + {//mov dword [rsp+4],0x3ff3c0ca + const char ML2[3]={0xc7,0x44,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string::size_type pos=inst1bis.find_first_of(']'); + std::string inst1_1=inst1bis.substr(4,pos-4-1); + appendAddress(inst1_1,1,ml); + appendAddress(inst2,4,ml); + return; + } + else + throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); + } + throw INTERP_KERNEL::Exception("Not recognized exp : mov"); +} + +void INTERP_KERNEL::AsmX86::convertPush(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string inst2=inst.substr(pos+1); + const char ASM1[]="ebp"; + const char ML1[1]={0x55}; + if(inst2==ASM1) + {//push ebp + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="ebx"; + const char ML2[1]={0x53}; + if(inst2==ASM2) + {//push ebx + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + const char ASM3[]="rbp"; + const char ML3[1]={0x55}; + if(inst2==ASM3) + {//push rbp + ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized push instruction"); +} + +void INTERP_KERNEL::AsmX86::convertPop(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string inst2=inst.substr(pos+1); + const char ASM1[]="ebp"; + const char ML1[1]={0x5d}; + if(inst2==ASM1) + {//push ebp + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="ebx"; + const char ML2[1]={0x5b}; + if(inst2==ASM2) + {//push ebx + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized pop instruction"); +} + +void INTERP_KERNEL::AsmX86::convertFld(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string params=inst.substr(pos+1); + std::string params2=params.substr(1,params.length()-2); + if(params2.substr(0,3)=="esp") + { + const char ML1[3]={0xdd,0x04,0x24}; + if(params2.length()==3) + {//fld qword [esp] + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + pos=params2.find_first_of('+'); + if(pos!=std::string::npos) + {//fld qword [esp+@] + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + std::string params3=params2.substr(pos+1); + appendAddress(params3,1,ml); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld esp..."); + } + if(params2.substr(0,3)=="ebp") + { + const char ML2[2]={0xdd,0x45}; + if(params2.length()==3) + {//fld qword [ebp] + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + ml.push_back(0); + return ; + } + pos=params2.find_first_of('+'); + if(pos!=std::string::npos) + {//fld qword [esp+@] + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string params3=params2.substr(pos+1); + appendAddress(params3,1,ml); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld ebp..."); + } + if(params2.substr(0,3)=="rsp") + { + const char ML2[3]={0xdd,0x04,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2));// to improve ! no fully managed ! + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld instruction"); +} + +void INTERP_KERNEL::AsmX86::convertFaddp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xc1}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFsubp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xe9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFmulp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xc9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFdivp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xf9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFcos(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xff}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFsin(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xfe}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFabs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xe1}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFchs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xe0}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFsqrt(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xfa}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertSub(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + if(inst.substr(0,4)=="esp,") + { + const char ML[2]={0x81,0xec}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); + std::string inst2=inst.substr(4); + appendAddress(inst2,4,ml); + return; + } + if(inst.substr(0,4)=="rsp,") + { + const char ML[4]={0x48,0x83,0xec,0x08}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! + return; + } + throw INTERP_KERNEL::Exception("Not recognized sub instruction."); +} + +void INTERP_KERNEL::AsmX86::convertAdd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + if(inst.substr(0,4)=="esp,") + { + const char ML[2]={0x81,0xc4}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); + std::string inst2=inst.substr(4); + appendAddress(inst2,4,ml); + return; + } + if(inst.substr(0,4)=="rsp,") + { + const char ML[4]={0x48,0x83,0xc4,0x08}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! + return; + } + throw INTERP_KERNEL::Exception("Not recognized add instruction."); +} + +void INTERP_KERNEL::AsmX86::convertRet(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[1]={0xc3}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertLeave(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[1]={0xc9}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertMovsd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ASM1[]="[rsp],xmm0"; + const char ML1[5]={0xf2,0x0f,0x11,0x04,0x24}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="xmm0,[rsp]"; + const char ML2[5]={0xf2,0x0f,0x10,0x04,0x24}; + if(inst==ASM2) + { + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + std::ostringstream oss; oss << "not recognized instruction movsd : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +void INTERP_KERNEL::AsmX86::convertFst(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ASM1[]="qword [rsp]"; + const char ML1[3]={0xdd,0x14,0x24}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + std::ostringstream oss; oss << "not recognized instruction fst : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + //tony +} + + +void INTERP_KERNEL::AsmX86::appendAddress(const std::string& addr, int nbOfByte, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + int i,j; + char v; + std::istringstream iss(addr); + if(addr.length()>2) + { + if(addr[0]=='0' && addr[1]=='x') + iss >> std::hex; + } + iss >> i; + for(int k=0;k>=8; + } +} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx new file mode 100644 index 000000000..11b8733e5 --- /dev/null +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __INTERPKERNELASMX86_HXX__ +#define __INTERPKERNELASMX86_HXX__ + +#include "INTERPKERNELEXPREVALDefines.hxx" +#include "InterpKernelException.hxx" + +#include +#include + +namespace INTERP_KERNEL +{ + class AsmX86 + { + public: + std::vector convertIntoMachineLangage(const std::vector& asmb) const throw(INTERP_KERNEL::Exception); + char *convertMachineLangageInBasic(const std::vector& ml, int& lgth) const; + private: + void convertOneInstructionInML(const std::string& inst, std::vector& ml) const throw(INTERP_KERNEL::Exception); + private: + static void convertMov(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertPush(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertPop(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFld(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFaddp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFsubp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFmulp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFdivp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFcos(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFsin(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFabs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFchs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFsqrt(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertSub(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertAdd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertRet(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertLeave(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertMovsd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFst(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + // + static void convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void appendAddress(const std::string& addr, int nbOfByte, std::vector& ml) throw(INTERP_KERNEL::Exception); + private: + static const int NB_OF_OPS=19; + static const char *OPS[NB_OF_OPS]; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx index 90bd5e2c8..704b6afc8 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx @@ -19,13 +19,20 @@ #include "InterpKernelExprParser.hxx" #include "InterpKernelValue.hxx" +#include "InterpKernelAsmX86.hxx" #include #include #include #include +#include #include +#ifdef _POSIX_MAPPED_FILES +#include +#else +#endif + using namespace INTERP_KERNEL; const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec"; @@ -120,12 +127,12 @@ LeafExprVar::~LeafExprVar() { } -ExprParser::ExprParser(const char *expr):_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr) +ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr) { } //! For \b NOT null terminated strings coming from FORTRAN. -ExprParser::ExprParser(const char *expr, int lgth):_is_parsed(false),_leaf(0),_is_parsing_ok(false) +ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false) { _expr=buildStringFromFortran(expr,lgth); } @@ -404,7 +411,7 @@ void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception) if(pos5!=std::string::npos) len=pos5-pos6; std::string newExp3=newExp2.substr(pos6,len); - _sub_expr.push_back(ExprParser(newExp3.c_str())); + _sub_expr.push_back(ExprParser(newExp3.c_str(),this)); pos6=pos5+1; } _is_parsing_ok=true; @@ -456,7 +463,7 @@ void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception) if(*accessor!='*' && *accessor!='/' && *accessor!='^') { isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); curPart.clear(); _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); } @@ -483,7 +490,7 @@ void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception) { if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); _is_parsing_ok=true; } else @@ -515,7 +522,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception) isParsingSucceed=true; if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); curPart.clear(); _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); } @@ -546,7 +553,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception) { if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); _is_parsing_ok=true; } else @@ -576,7 +583,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception) if(!curPart.empty()) { isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); curPart.clear(); _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); } @@ -606,7 +613,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception) { if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); _is_parsing_ok=true; } else @@ -691,3 +698,159 @@ void ExprParser::locateError(std::ostream& stringToDisp, const std::string& srcO { stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl; } + +char *ExprParser::compileX86() const +{ + std::vector ass; + //need in stack + ass.push_back("push ebp"); + ass.push_back("mov ebp,esp"); + compileX86LowLev(ass); + ass.push_back("pop ebp"); + ass.push_back("ret"); + std::cout << std::endl; + for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) + std::cout << " " << *iter << std::endl; + AsmX86 asmb; + std::vector output=asmb.convertIntoMachineLangage(ass); + for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) + std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; + std::cout << std::endl; + int lgth; + char *lm=asmb.convertMachineLangageInBasic(output,lgth); + char *ret=0; +#ifdef _POSIX_MAPPED_FILES + ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0); + std::copy(lm,lm+lgth,ret); +#else +#endif + delete [] lm; + return ret; +} + +char *ExprParser::compileX86_64() const +{ + std::vector ass; + //need in stack + ass.push_back("push rbp"); + ass.push_back("mov rbp,rsp"); + compileX86_64LowLev(ass); + ass.push_back("sub rsp,8"); + ass.push_back("fst qword [rsp]"); + ass.push_back("movsd xmm0,[rsp]"); + ass.push_back("add rsp,8"); + ass.push_back("leave"); + ass.push_back("ret"); + std::cout << std::endl; + for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) + std::cout << " " << *iter << std::endl; + AsmX86 asmb; + std::vector output=asmb.convertIntoMachineLangage(ass); + for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) + std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; + std::cout << std::endl; + int lgth; + char *lm=asmb.convertMachineLangageInBasic(output,lgth); + char *ret=0; +#ifdef _POSIX_MAPPED_FILES + ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0); + std::copy(lm,lm+lgth,ret); +#else +#endif + delete [] lm; + return ret; +} + +void ExprParser::compileX86LowLev(std::vector& ass) const +{ + if(_leaf) + _leaf->compileX86(ass); + else + { + for(std::list::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).compileX86LowLev(ass); + for(std::list::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) + (*iter2)->operateX86(ass); + } +} + +void ExprParser::compileX86_64LowLev(std::vector& ass) const +{ + if(_leaf) + _leaf->compileX86_64(ass); + else + { + for(std::list::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).compileX86_64LowLev(ass); + for(std::list::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) + (*iter2)->operateX86(ass); + } +} + +void LeafExprVal::compileX86(std::vector& ass) const +{ + ass.push_back("sub esp,8"); + int *b=(int *)&_value,*c=(int *)&_value; + c++; + std::ostringstream oss; + oss << std::hex; + oss << "mov dword [esp+4],0x" << *c; + ass.push_back(oss.str()); + oss.str(""); + oss << "mov dword [esp],0x" << *b; + ass.push_back(oss.str()); + ass.push_back("fld qword [esp]"); + ass.push_back("add esp,8"); +} + +void LeafExprVal::compileX86_64(std::vector& ass) const +{ + ass.push_back("sub rsp,8"); + int *b=(int *)&_value,*c=(int *)&_value; + c++; + std::ostringstream oss; + oss << std::hex; + oss << "mov dword [rsp+4],0x" << *c; + ass.push_back(oss.str()); + oss.str(""); + oss << "mov dword [rsp],0x" << *b; + ass.push_back(oss.str()); + ass.push_back("fld qword [rsp]"); + ass.push_back("add rsp,8"); +} + +void LeafExprVar::compileX86(std::vector& ass) const +{ + ass.push_back("fld qword [ebp+8]"); +} + +void LeafExprVar::compileX86_64(std::vector& ass) const +{ + ass.push_back("sub rsp,8"); + ass.push_back("movsd [rsp],xmm0"); + ass.push_back("fld qword [rsp]"); + ass.push_back("add rsp,8"); +} + +int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const +{ + if(asker) + { + int sz=_father->getStackSizeToPlayX86(this); + int i=0; + for(std::list::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++) + { + const ExprParser& obj=(*iter); + const ExprParser *pt=&obj; + if(pt==asker) + return sz-i; + } + throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !"); + } + else + { + if(!_father) + return MAX_X86_FP_ST; + return _father->getStackSizeToPlayX86(this); + } +} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx index eceee0ad3..7ff8babb5 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx @@ -39,6 +39,8 @@ namespace INTERP_KERNEL public: virtual ~LeafExpr(); virtual void fillValue(Value *val) const throw(INTERP_KERNEL::Exception) = 0; + virtual void compileX86(std::vector& ass) const = 0; + virtual void compileX86_64(std::vector& ass) const = 0; static LeafExpr *buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception); }; @@ -47,6 +49,8 @@ namespace INTERP_KERNEL public: LeafExprVal(double value); ~LeafExprVal(); + void compileX86(std::vector& ass) const; + void compileX86_64(std::vector& ass) const; void fillValue(Value *val) const throw(INTERP_KERNEL::Exception); private: double _value; @@ -57,6 +61,8 @@ namespace INTERP_KERNEL public: LeafExprVar(const std::string& var); ~LeafExprVar(); + void compileX86(std::vector& ass) const; + void compileX86_64(std::vector& ass) const; void fillValue(Value *val) const throw(INTERP_KERNEL::Exception); std::string getVar() const { return _var_name; } void prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception); @@ -72,8 +78,8 @@ namespace INTERP_KERNEL class INTERPKERNELEXPREVAL_EXPORT ExprParser { public: - ExprParser(const char *expr); - ExprParser(const char *expr, int lgth); + ExprParser(const char *expr, ExprParser *father=0); + ExprParser(const char *expr, int lgth, ExprParser *father=0); ~ExprParser(); void parse() throw(INTERP_KERNEL::Exception); bool isParsingSuccessfull() const { return _is_parsing_ok; } @@ -84,6 +90,13 @@ namespace INTERP_KERNEL void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception); void getSetOfVars(std::set& vars) const; void getTrueSetOfVars(std::set& vars) const; + // + char *compileX86() const; + char *compileX86_64() const; + void compileX86LowLev(std::vector& ass) const; + void compileX86_64LowLev(std::vector& ass) const; + int getStackSizeToPlayX86(const ExprParser *asker) const; + // static std::string buildStringFromFortran(const char *expr, int lgth); static std::string deleteWhiteSpaces(const std::string& expr); private: @@ -102,6 +115,7 @@ namespace INTERP_KERNEL static std::size_t findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket); static void locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr); private: + ExprParser *_father; bool _is_parsed; LeafExpr *_leaf; bool _is_parsing_ok; @@ -109,6 +123,7 @@ namespace INTERP_KERNEL std::list _sub_expr; std::list _func_btw_sub_expr; private: + static const int MAX_X86_FP_ST=8; static const char WHITE_SPACES[]; static const char EXPR_PARSE_ERR_MSG[]; }; diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx index 6e8316526..dd16329f6 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx @@ -140,6 +140,10 @@ void IdentityFunction::operate(std::vector& stack) const throw(INTERP_K { } +void IdentityFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ +} + const char *IdentityFunction::getRepr() const { return REPR; @@ -163,6 +167,10 @@ void PositiveFunction::operate(std::vector& stack) const throw(INTERP_K { } +void PositiveFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ +} + const char *PositiveFunction::getRepr() const { return REPR; @@ -183,6 +191,11 @@ void NegateFunction::operate(std::vector& stack) const throw(INTERP_KER val->negate(); } +void NegateFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fchs"); +} + const char *NegateFunction::getRepr() const { return REPR; @@ -203,6 +216,11 @@ void CosFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->cos(); } +void CosFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fcos"); +} + const char *CosFunction::getRepr() const { return REPR; @@ -223,6 +241,11 @@ void SinFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->sin(); } +void SinFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fsin"); +} + const char *SinFunction::getRepr() const { return REPR; @@ -243,6 +266,11 @@ void TanFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->tan(); } +void TanFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *TanFunction::getRepr() const { return REPR; @@ -263,6 +291,11 @@ void SqrtFunction::operate(std::vector& stack) const throw(INTERP_KERNE val->sqrt(); } +void SqrtFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fsqrt"); +} + const char *SqrtFunction::getRepr() const { return REPR; @@ -283,6 +316,11 @@ void AbsFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->abs(); } +void AbsFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fabs"); +} + const char *AbsFunction::getRepr() const { return REPR; @@ -298,7 +336,12 @@ void ExpFunction::operate(std::vector& stack) const throw(INTERP_KERNEL Value *val=stack.back(); val->exp(); } - + +void ExpFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *ExpFunction::getRepr() const { return REPR; @@ -319,6 +362,11 @@ void LnFunction::operate(std::vector& stack) const throw(INTERP_KERNEL: val->ln(); } +void LnFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *LnFunction::getRepr() const { return REPR; @@ -358,6 +406,11 @@ void PlusFunction::operate(std::vector& stack) const throw(INTERP_KERNE val2=val3; } +void PlusFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("faddp st1"); +} + const char *PlusFunction::getRepr() const { return REPR; @@ -392,6 +445,11 @@ void MinusFunction::operate(std::vector& stack) const throw(INTERP_KERN val2=val3; } +void MinusFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fsubp st1"); +} + const char *MinusFunction::getRepr() const { return REPR; @@ -417,6 +475,11 @@ void MultFunction::operate(std::vector& stack) const throw(INTERP_KERNE val2=val3; } +void MultFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fmulp st1"); +} + const char *MultFunction::getRepr() const { return REPR; @@ -451,6 +514,11 @@ void DivFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void DivFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fdivp st1"); +} + const char *DivFunction::getRepr() const { return REPR; @@ -485,6 +553,11 @@ void PowFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void PowFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *PowFunction::getRepr() const { return REPR; @@ -523,6 +596,11 @@ void MaxFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void MaxFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *MaxFunction::getRepr() const { return REPR; @@ -557,6 +635,11 @@ void MinFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void MinFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *MinFunction::getRepr() const { return REPR; diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx index 548a09f1e..160e15ba9 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx @@ -46,6 +46,7 @@ namespace INTERP_KERNEL virtual ~Function(); virtual int getNbInputParams() const = 0; virtual void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception) = 0; + virtual void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) = 0; virtual const char *getRepr() const = 0; virtual bool isACall() const = 0; }; @@ -61,6 +62,7 @@ namespace INTERP_KERNEL public: ~IdentityFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -72,6 +74,7 @@ namespace INTERP_KERNEL public: ~PositiveFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -83,6 +86,7 @@ namespace INTERP_KERNEL public: ~NegateFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -94,6 +98,7 @@ namespace INTERP_KERNEL public: ~CosFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -105,6 +110,7 @@ namespace INTERP_KERNEL public: ~SinFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -116,6 +122,7 @@ namespace INTERP_KERNEL public: ~TanFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -127,6 +134,7 @@ namespace INTERP_KERNEL public: ~SqrtFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -138,6 +146,7 @@ namespace INTERP_KERNEL public: ~AbsFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -149,6 +158,7 @@ namespace INTERP_KERNEL public: ~ExpFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -160,6 +170,7 @@ namespace INTERP_KERNEL public: ~LnFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -177,6 +188,7 @@ namespace INTERP_KERNEL public: ~PlusFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -188,6 +200,7 @@ namespace INTERP_KERNEL public: ~MinusFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -199,6 +212,7 @@ namespace INTERP_KERNEL public: ~MultFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -210,6 +224,7 @@ namespace INTERP_KERNEL public: ~DivFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -221,6 +236,7 @@ namespace INTERP_KERNEL public: ~PowFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -232,6 +248,7 @@ namespace INTERP_KERNEL public: ~MaxFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -243,6 +260,7 @@ namespace INTERP_KERNEL public: ~MinFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: diff --git a/src/INTERP_KERNEL/ExprEval/Makefile.am b/src/INTERP_KERNEL/ExprEval/Makefile.am index 4a67afba5..28f5e9124 100644 --- a/src/INTERP_KERNEL/ExprEval/Makefile.am +++ b/src/INTERP_KERNEL/ExprEval/Makefile.am @@ -30,8 +30,8 @@ INTERPKERNELEXPREVALDefines.hxx \ InterpKernelExprParser.hxx \ InterpKernelFunction.hxx \ InterpKernelUnit.hxx \ -InterpKernelValue.hxx - +InterpKernelValue.hxx \ +InterpKernelAsmX86.hxx EXTRA_DIST += \ INTERPKERNELEXPREVALDefines.hxx \ @@ -44,7 +44,8 @@ dist_libinterpkernelexpreval_la_SOURCES = \ InterpKernelExprParser.cxx \ InterpKernelFunction.cxx \ InterpKernelUnit.cxx \ - InterpKernelValue.cxx + InterpKernelValue.cxx \ + InterpKernelAsmX86.cxx libinterpkernelexpreval_la_CPPFLAGS=-I$(srcdir)/../Bases -- 2.39.2