cgutil.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #include "cgstd.h"
  2. #include "cgutil.h"
  3. static string _id(){
  4. char buf[32];
  5. static int n_id;
  6. sprintf( buf,"_%i",++n_id );
  7. return buf;
  8. }
  9. CGNop *CG::nop(){
  10. return new CGNop;
  11. }
  12. CGXop *CG::xop( int op,CGReg *r,CGExp *exp ){
  13. CGXop *t=new CGXop;
  14. t->op=op;t->def=r;t->exp=exp;
  15. return t;
  16. }
  17. CGRem *CG::rem( string comment ){
  18. CGRem *t=new CGRem;
  19. t->comment=comment;
  20. return t;
  21. }
  22. CGAti *CG::ati( CGMem *mem ){
  23. CGAti *t=new CGAti;
  24. t->mem=mem;
  25. return t;
  26. }
  27. CGAtd *CG::atd( CGMem *mem,CGSym *sym ){
  28. CGAtd *t=new CGAtd;
  29. t->mem=mem;t->sym=sym;
  30. return t;
  31. }
  32. CGMov *CG::mov( CGExp *lhs,CGExp *rhs ){
  33. CGMov *t=new CGMov;
  34. t->lhs=lhs;t->rhs=rhs;
  35. return t;
  36. }
  37. CGLab *CG::lab( CGSym *sym ){
  38. CGLab *t=new CGLab;
  39. t->sym=sym ? sym : CG::sym();
  40. return t;
  41. }
  42. CGBra *CG::bra( CGSym *sym ){
  43. CGBra *t=new CGBra;
  44. t->sym=sym;
  45. return t;
  46. }
  47. CGBcc *CG::bcc( int cc,CGExp *lhs,CGExp *rhs,CGSym *sym ){
  48. CGBcc *t=new CGBcc;
  49. t->cc=cc;t->lhs=lhs;t->rhs=rhs;t->sym=sym;
  50. return t;
  51. }
  52. CGRet *CG::ret( CGExp *exp ){
  53. CGRet *t=new CGRet;
  54. t->exp=exp;
  55. return t;
  56. }
  57. CGEva *CG::eva( CGExp *exp ){
  58. CGEva *t=new CGEva;
  59. t->exp=exp;
  60. return t;
  61. }
  62. CGSeq *CG::seq( const std::vector<CGStm*> &stms ){
  63. CGSeq *t=new CGSeq;
  64. t->stms=stms;
  65. return t;
  66. }
  67. CGSeq *CG::seq( CGStm *stm0,... ){
  68. CGSeq *t=new CGSeq;
  69. if( !stm0 ) return t;
  70. t->stms.push_back( stm0 );
  71. va_list args;
  72. va_start( args,stm0 );
  73. while( CGStm *p=va_arg(args,CGStm*) ) t->stms.push_back(p);
  74. return t;
  75. }
  76. CGMem *CG::mem( int type,CGExp *exp,int offset ){
  77. CGMem *t=new CGMem;
  78. t->type=type;t->exp=exp;t->offset=offset;t->flags=0;
  79. return t;
  80. }
  81. CGLea *CG::lea( CGExp *exp ){
  82. CGLea *t=new CGLea;
  83. t->type=CG_INT32;t->exp=exp;
  84. return t;
  85. }
  86. CGCvt *CG::cvt( int type,CGExp *exp ){
  87. CGCvt *t=new CGCvt;
  88. t->type=type;t->exp=exp;
  89. return t;
  90. }
  91. CGUop *CG::uop( int op,CGExp *exp ){
  92. CGUop *t=new CGUop;
  93. t->type=exp->type;t->op=op;t->exp=exp;
  94. return t;
  95. }
  96. CGBop *CG::bop( int op,CGExp *lhs,CGExp *rhs ){
  97. CGBop *t=new CGBop;
  98. t->type=lhs->type;t->op=op;t->lhs=lhs;t->rhs=rhs;
  99. return t;
  100. }
  101. CGJsr *CG::jsr( int type,int call_conv,CGExp *exp,const vector<CGExp*> &args ){
  102. CGJsr *t=new CGJsr;
  103. t->type=type;t->call_conv=call_conv;t->exp=exp;t->args=args;
  104. return t;
  105. }
  106. CGJsr *CG::jsr( int type,int call_conv,CGExp *exp,CGExp *a0,CGExp *a1,CGExp *a2,CGExp *a3 ){
  107. vector<CGExp*> args;
  108. if( a0 ) args.push_back(a0);
  109. if( a1 ) args.push_back(a1);
  110. if( a2 ) args.push_back(a2);
  111. if( a3 ) args.push_back(a3);
  112. return jsr( type,call_conv,exp,args );
  113. }
  114. CGJsr *CG::jsr( int type,string t_sym,const vector<CGExp*> &args ){
  115. return jsr( type,CG_CDECL,sym(t_sym,CG_IMPORT),args );
  116. }
  117. CGJsr *CG::jsr( int type,string t_sym,CGExp *a0,CGExp *a1,CGExp *a2,CGExp *a3 ){
  118. vector<CGExp*> args;
  119. if( a0 ) args.push_back(a0);
  120. if( a1 ) args.push_back(a1);
  121. if( a2 ) args.push_back(a2);
  122. if( a3 ) args.push_back(a3);
  123. return jsr( type,t_sym,args );
  124. }
  125. CGVfn *CG::vfn( CGExp *exp,CGExp *self ){
  126. CGVfn *t=new CGVfn;
  127. t->type=exp->type;t->exp=exp;t->self=self;
  128. return t;
  129. }
  130. CGScc *CG::scc( int cc,CGExp *lhs,CGExp *rhs ){
  131. CGScc *t=new CGScc;
  132. t->type=CG_INT32;t->cc=cc;t->lhs=lhs;t->rhs=rhs;
  133. return t;
  134. }
  135. CGEsq *CG::esq( CGStm *lhs,CGExp *rhs ){
  136. CGEsq *t=new CGEsq;
  137. t->type=rhs->type;t->lhs=lhs;t->rhs=rhs;
  138. return t;
  139. }
  140. CGFrm *CG::frm(){
  141. CGFrm *t=new CGFrm;
  142. t->type=CG_PTR;
  143. return t;
  144. }
  145. CGLit *CG::lit( int val ){
  146. CGLit *t=new CGLit;
  147. t->type=CG_INT32;t->int_value=val;
  148. return t;
  149. }
  150. CGLit *CG::lit( int64 val ){
  151. CGLit *t=new CGLit;
  152. t->type=CG_INT64;t->int_value=val;
  153. return t;
  154. }
  155. CGLit *CG::lit( float val ){
  156. CGLit *t=new CGLit;
  157. t->type=CG_FLOAT32;t->float_value=val;
  158. return t;
  159. }
  160. CGLit *CG::lit( double val ){
  161. CGLit *t=new CGLit;
  162. t->type=CG_FLOAT64;t->float_value=val;
  163. return t;
  164. }
  165. CGLit *CG::lit( bstring val,int type ){
  166. CGLit *t=new CGLit;
  167. t->type=type;t->string_value=val;
  168. return t;
  169. }
  170. CGTmp *CG::tmp( int type,string id ){
  171. CGTmp *t=new CGTmp;
  172. t->type=type;t->ident=id.size() ? id : _id();t->owner=0;
  173. return t;
  174. }
  175. CGSym *CG::sym(){
  176. CGSym *t=new CGSym;
  177. t->type=CG_INT32;
  178. t->value=_id();
  179. t->linkage=CG_INTERNAL;
  180. return t;
  181. }
  182. CGSym *CG::sym( string id,int linkage ){
  183. CGSym *t=new CGSym;
  184. t->type=CG_INT32;
  185. t->value=id;
  186. t->linkage=linkage;
  187. return t;
  188. }
  189. CGDat *CG::dat(){
  190. CGDat *t=new CGDat;
  191. t->type=CG_INT32;
  192. t->value=_id();
  193. t->linkage=CG_INTERNAL;
  194. return t;
  195. }
  196. CGDat *CG::dat( string id ){
  197. CGDat *t=new CGDat;
  198. t->type=CG_INT32;
  199. t->value=id;
  200. t->linkage=CG_EXPORT;
  201. return t;
  202. }
  203. CGFun *CG::fun( int type,int call_conv,CGSym *sym,CGExp *self ){
  204. CGFun *t=new CGFun;
  205. t->type=type;t->call_conv=call_conv;t->sym=sym;t->self=self;
  206. return t;
  207. }
  208. CGFun *CG::visitFun( CGFun *fun,CGVisitor &vis ){
  209. int k;
  210. CGFun *out=0;
  211. bool copy=false;
  212. vector<CGExp*> args;
  213. CGSym *sym=fun->sym->visit( vis )->sym();
  214. CGExp *self=fun->self ? fun->self->visit( vis ) : 0;
  215. if( sym!=fun->sym || self!=fun->self ) copy=true;
  216. for( k=0;k<fun->args.size();++k ){
  217. args.push_back( fun->args[k]->visit( vis ) );
  218. if( args.back()!=fun->args[k] ) copy=true;
  219. }
  220. CGStm *stm=0;
  221. for( k=0;;++k ){
  222. if( copy ){
  223. out=CG::fun( fun->type,fun->call_conv,sym,self );
  224. out->args=args;
  225. out->stms.reserve( fun->stms.size() );
  226. for( int j=0;j<k;++j ) out->stms.push_back( fun->stms[j] );
  227. if( stm ) out->stms[out->stms.size()-1]=stm;
  228. copy=false;
  229. }
  230. if( k==fun->stms.size() ) break;
  231. stm=fun->stms[k]->visit( vis );
  232. if( out ){
  233. out->stms.push_back( stm );
  234. }else{
  235. if( stm!=fun->stms[k] ) copy=true;
  236. }
  237. }
  238. return out ? out : fun;
  239. }
  240. int CG::swapcc( int cg_cc ){
  241. switch( cg_cc ){
  242. case CG_EQ:return CG_NE;
  243. case CG_NE:return CG_EQ;
  244. case CG_LT:return CG_GE;
  245. case CG_GT:return CG_LE;
  246. case CG_LE:return CG_GT;
  247. case CG_GE:return CG_LT;
  248. case CG_LTU:return CG_GEU;
  249. case CG_GTU:return CG_LEU;
  250. case CG_LEU:return CG_GTU;
  251. case CG_GEU:return CG_LTU;
  252. }
  253. assert(0);
  254. return 0;
  255. }
  256. CGLit *CG::lit0=CG::lit(0);
  257. CGLit *CG::lit1=CG::lit(1);