cgint64.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #include "cgstd.h"
  2. #include "cgframe.h"
  3. #include "cgallocregs.h"
  4. #include "cgutil.h"
  5. #include "cgdebug.h"
  6. using namespace CG;
  7. static CGFun *func;
  8. static CGFrame *frame;
  9. static CGMem *i64_dummy;
  10. static void int32ToInt64( CGMem *m,CGExp *exp ){
  11. func->stms.push_back( mov(frame->int64lo(m),exp) );
  12. func->stms.push_back( mov(frame->int64hi(m),lit0) );
  13. }
  14. static CGExp *int64ToInt32( CGExp *exp ){
  15. if( CGLit *t=exp->lit() ){
  16. return lit((int)(t->int_value));
  17. }else if( CGMem *t=exp->mem() ){
  18. return frame->int64lo(t);
  19. }
  20. assert(0);
  21. return 0;
  22. }
  23. static void genInt64Stms( CGMem *m,CGExp *exp ){
  24. if( CGLit *t=exp->lit() ){
  25. //mov i64,lit
  26. CGLit *lo=lit( (int)(t->int_value) );
  27. CGLit *hi=lit( (int)(t->int_value>>int64(32)) );
  28. func->stms.push_back( mov(frame->int64lo(m),lo) );
  29. func->stms.push_back( mov(frame->int64hi(m),hi) );
  30. }else if( CGMem *t=exp->mem() ){
  31. func->stms.push_back( mov(frame->int64lo(m),frame->int64lo(t)) );
  32. func->stms.push_back( mov(frame->int64hi(m),frame->int64hi(t)) );
  33. }else if( CGJsr *t=exp->jsr() ){
  34. CGJsr *e=jsr(CG_INT32,t->call_conv,t->exp );
  35. e->args.push_back( lea(m) );
  36. for( int k=0;k<t->args.size();++k ) e->args.push_back( t->args[k] );
  37. func->stms.push_back( eva(e) );
  38. }else if( CGUop *t=exp->uop() ){
  39. string f;
  40. switch( t->op ){
  41. case CG_NEG:f="bbLongNeg";break;
  42. case CG_NOT:f="bbLongNot";break;
  43. case CG_ABS:f="bbLongAbs";break;
  44. case CG_SGN:f="bbLongSgn";break;
  45. default:assert(0);
  46. }
  47. CGJsr *e=jsr(CG_INT32,f);
  48. e->args.push_back( lea(m) );
  49. e->args.push_back( t->exp );
  50. func->stms.push_back( eva(e) );
  51. }else if( CGBop *t=exp->bop() ){
  52. string f;
  53. switch( t->op ){
  54. case CG_ADD:f="bbLongAdd";break;
  55. case CG_SUB:f="bbLongSub";break;
  56. case CG_MUL:f="bbLongMul";break;
  57. case CG_DIV:f="bbLongDiv";break;
  58. case CG_MOD:f="bbLongMod";break;
  59. case CG_AND:f="bbLongAnd";break;
  60. case CG_ORL:f="bbLongOrl";break;
  61. case CG_XOR:f="bbLongXor";break;
  62. case CG_SHL:f="bbLongShl";break;
  63. case CG_SHR:f="bbLongShr";break;
  64. case CG_SAR:f="bbLongSar";break;
  65. case CG_MIN:f="bbLongMin";break;
  66. case CG_MAX:f="bbLongMax";break;
  67. default:assert(0);
  68. }
  69. CGJsr *e=jsr(CG_INT32,f);
  70. e->args.push_back( lea(m) );
  71. e->args.push_back( t->lhs );
  72. e->args.push_back( t->rhs );
  73. func->stms.push_back( eva(e) );
  74. }else if( CGCvt *t=exp->cvt() ){
  75. CGExp *e=t->exp;
  76. switch( e->type ){
  77. case CG_INT8: //int8 to int64
  78. int32ToInt64(m,cvt(CG_INT32,e));
  79. break;
  80. case CG_INT16: //int16 to int64
  81. int32ToInt64(m,cvt(CG_INT32,e));
  82. break;
  83. case CG_PTR: //ptr to int64
  84. int32ToInt64(m,e);
  85. break;
  86. case CG_INT32: //int32 to int64
  87. func->stms.push_back( eva(jsr(CG_INT32,"bbIntToLong",lea(m),e)) );
  88. break;
  89. case CG_INT64:
  90. break;
  91. case CG_FLOAT32://float32 to int64
  92. func->stms.push_back( eva(jsr(CG_INT32,"bbFloatToLong",lea(m),cvt(CG_FLOAT64,e))) );
  93. break;
  94. case CG_FLOAT64://float64 to int64
  95. func->stms.push_back( eva(jsr(CG_INT32,"bbFloatToLong",lea(m),e)) );
  96. break;
  97. default:
  98. assert(0);
  99. }
  100. }else{
  101. cout<<exp<<endl;
  102. assert(0);
  103. }
  104. }
  105. struct CGInt64StmFixer : public CGVisitor{
  106. CGFrame *frame;
  107. CGInt64StmFixer( CGFrame *f ):frame(f){}
  108. CGStm *visit( CGStm *stm ){
  109. if( CGMov *t=stm->mov() ){
  110. if( t->lhs->type==CG_INT64 ){
  111. CGMem *lhs=t->lhs->mem();
  112. assert( lhs );
  113. genInt64Stms( lhs,t->rhs );
  114. return stm;
  115. }
  116. }else if( CGEva *t=stm->eva() ){
  117. if( t->exp->type==CG_INT64 ){
  118. if( !i64_dummy ) i64_dummy=frame->allocLocal( CG_INT64 );
  119. genInt64Stms( i64_dummy,t->exp );
  120. return stm;
  121. }
  122. }else if( CGRet *t=stm->ret() ){
  123. if( frame->int64ret ){
  124. CGMem *lhs=mem(CG_INT64,frame->int64ret,0);
  125. genInt64Stms( lhs,t->exp );
  126. func->stms.push_back( ret(0) );
  127. return stm;
  128. }
  129. }else if( CGBcc *t=stm->bcc() ){
  130. if( t->lhs->type==CG_INT64 ){
  131. func->stms.push_back( bcc(CG_NE,scc(t->cc,t->lhs,t->rhs),lit0,t->sym) );
  132. return stm;
  133. }
  134. }
  135. func->stms.push_back( stm );
  136. return stm;
  137. }
  138. };
  139. struct CGInt64ExpFixer : public CGVisitor{
  140. CGFrame *frame;
  141. CGFun *fun;
  142. CGInt64ExpFixer( CGFrame *f ):frame(f),fun(frame->fun){}
  143. CGStm *visit( CGStm *stm ){
  144. func->stms.push_back( stm );
  145. return stm;
  146. }
  147. CGExp *visit( CGExp *exp ){
  148. if( CGScc *t=exp->scc() ){
  149. if( t->lhs->type!=CG_INT64 ) return exp;
  150. string f;
  151. switch( t->cc ){
  152. case CG_LT:f="bbLongSlt";break;
  153. case CG_GT:f="bbLongSgt";break;
  154. case CG_LE:f="bbLongSle";break;
  155. case CG_GE:f="bbLongSge";break;
  156. case CG_EQ:f="bbLongSeq";break;
  157. case CG_NE:f="bbLongSne";break;
  158. default:assert(0);
  159. }
  160. CGJsr *e=jsr(CG_INT32,f,t->lhs,t->rhs);
  161. return e;
  162. }else if( CGCvt *t=exp->cvt() ){
  163. CGExp *e=t->exp;
  164. if( e->type==CG_INT64 ){
  165. switch( t->type ){
  166. case CG_INT8: //int64 to int8
  167. return cvt(CG_INT8,int64ToInt32(e));
  168. case CG_INT16: //int64 to int16
  169. return cvt(CG_INT16,int64ToInt32(e));
  170. case CG_INT32: //int64 to int32
  171. return int64ToInt32(e);
  172. case CG_INT64:
  173. return e;
  174. case CG_FLOAT32://int64 to float32
  175. return cvt(CG_FLOAT32,jsr(CG_FLOAT64,"bbLongToFloat",e));
  176. case CG_FLOAT64://int64 to float64
  177. return jsr(CG_FLOAT64,"bbLongToFloat",e);
  178. }
  179. assert(0);
  180. }
  181. }
  182. if( exp->type!=CG_INT64 ) return exp;
  183. if( exp->uop() || exp->bop() || exp->jsr() || exp->cvt() ){
  184. CGMem *m=frame->allocLocal( CG_INT64 );
  185. genInt64Stms( m,exp );
  186. return m;
  187. }
  188. return exp;
  189. }
  190. };
  191. struct CGInt64ArgFixer : public CGVisitor{
  192. CGFrame *frame;
  193. CGInt64ArgFixer( CGFrame *f ):frame(f){}
  194. CGExp *visit( CGExp *exp ){
  195. if( CGJsr *t=exp->jsr() ){
  196. int k;
  197. for( k=0;k<t->args.size();++k ){
  198. if( t->args[k]->type==CG_INT64 ) break;
  199. }
  200. if( k==t->args.size() ) return exp;
  201. CGJsr *e=jsr( t->type,t->call_conv,t->exp );
  202. for( k=0;k<t->args.size();++k ){
  203. CGExp *arg=t->args[k];
  204. if( arg->type!=CG_INT64 ){
  205. e->args.push_back( arg );
  206. continue;
  207. }
  208. if( CGMem *t=arg->mem() ){
  209. e->args.push_back( frame->int64el(t,0) );
  210. e->args.push_back( frame->int64el(t,4) );
  211. }else if( CGLit *t=arg->lit() ){
  212. assert( t->type==CG_INT64 );
  213. int *p=(int*)&t->int_value;
  214. e->args.push_back( lit(p[0]) );
  215. e->args.push_back( lit(p[1]) );
  216. }else{
  217. cout<<arg<<endl;
  218. assert(0);
  219. }
  220. }
  221. return e;
  222. }
  223. return exp;
  224. }
  225. };
  226. void CGFrame::fixInt64(){
  227. ::func=fun;
  228. ::frame=this;
  229. ::i64_dummy=0;
  230. int k;
  231. vector<CGStm*> stms;
  232. stms.clear();
  233. stms.swap( func->stms );
  234. CGInt64StmFixer stm_vis( this );
  235. for( k=0;k<stms.size();++k ) stms[k]->visit( stm_vis );
  236. stms.clear();
  237. stms.swap( func->stms );
  238. CGInt64ExpFixer exp_vis( this );
  239. for( k=0;k<stms.size();++k ) stms[k]->visit( exp_vis );
  240. CGInt64ArgFixer arg_vis( this );
  241. func=visitFun( func,arg_vis );
  242. fun=func;
  243. }