cgframe_ppc.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. #include "cgstd.h"
  2. #include "cgframe_ppc.h"
  3. #include "cgmodule_ppc.h"
  4. #include "cgutil.h"
  5. #include "cgdebug.h"
  6. using namespace CG;
  7. enum{
  8. MEM_PARAM=1,
  9. MEM_LOCAL=2
  10. };
  11. CGMem *CGFrame_PPC::genMem( CGMem *m,char *buf ){
  12. CGReg *r=genExp(m->exp);
  13. const char *q="";
  14. switch( m->flags ){
  15. case MEM_PARAM:q="__FRAME+";break;
  16. case MEM_LOCAL:q="__LOCAL+";break;
  17. }
  18. sprintf( buf,"%s%i('%i)",q,m->offset,r->id );
  19. CGMem *t=mem(m->type,r,m->offset);
  20. t->flags=m->flags;
  21. return t;
  22. }
  23. CGReg *CGFrame_PPC::genLoad( CGMem *m ){
  24. CGReg *r=reg(m->type);
  25. const char *op=0;
  26. switch( m->type ){
  27. case CG_INT8:op="lbz";break;
  28. case CG_INT16:op="lhz";break;
  29. case CG_FLOAT32:op="lfs";break;
  30. case CG_FLOAT64:op="lfd";break;
  31. default:op="lwz";
  32. }
  33. char buf[256];
  34. m=genMem(m,buf);
  35. gen( mov(r,m),
  36. "\t%s\t'%i,%s\n",op,r->id,buf );
  37. return r;
  38. }
  39. void CGFrame_PPC::genStore( CGMem *m,CGExp *e ){
  40. CGReg *r=genExp(e);
  41. const char *op=0;
  42. switch( m->type ){
  43. case CG_INT8:op="stb";break;
  44. case CG_INT16:op="sth";break;
  45. case CG_FLOAT32:op="stfs";break;
  46. case CG_FLOAT64:op="stfd";break;
  47. default:op="stw";
  48. }
  49. char buf[256];
  50. m=genMem(m,buf);
  51. gen( mov( m,r ),"\t%s\t'%i,%s\n",op,r->id,buf );
  52. }
  53. void CGFrame_PPC::genCopy( CGReg *d,CGReg *r ){
  54. const char *op=d->isint() ? "mr" : "fmr";
  55. gen( mov(d,r),"\t%s\t'%i,'%i\n",op,d->id,r->id );
  56. }
  57. void CGFrame_PPC::genMov( CGExp *lhs,CGExp *rhs ){
  58. if( lhs->equals(rhs) ) return;
  59. if( CGMem *t=lhs->mem() ){
  60. genStore( t,rhs );
  61. }else if( CGReg *t=lhs->reg() ){
  62. genCopy( t,genExp( rhs ) );
  63. }else{
  64. assert(0);
  65. }
  66. }
  67. CGReg *CGFrame_PPC::genExp( CGExp *e ){
  68. if( CGReg *t=e->reg() ){
  69. return t;
  70. }else if( CGMem *t=e->mem() ){
  71. return genLoad( t );
  72. }else if( CGLea *t=e->lea() ){
  73. return genLea( t );
  74. }else if( CGCvt *t=e->cvt() ){
  75. return genCvt( t );
  76. }else if( CGUop *t=e->uop() ){
  77. return genUop( t );
  78. }else if( CGBop *t=e->bop() ){
  79. return genBop( t );
  80. }else if( CGScc *t=e->scc() ){
  81. return genScc( t );
  82. }else if( CGJsr *t=e->jsr() ){
  83. return genJsr( t );
  84. }else if( CGLit *t=e->lit() ){
  85. return genLit( t );
  86. }else if( CGSym *t=e->sym() ){
  87. return genSym( t );
  88. }else if( CGFrm *t=e->frm() ){
  89. return genFrm( t );
  90. }
  91. cout<<e<<endl;
  92. assert(0);
  93. return 0;
  94. }
  95. CGExp *CGFrame_PPC::genExp( CGExp *e,char *buf,int &mask ){
  96. if( mask & (EA_SIMM|EA_UIMM) ){
  97. if( CGLit *t=e->lit() ){
  98. if( t->isint() ){
  99. int n=t->int_value;
  100. if( (mask & EA_SIMM) && n>=-32768 && n<32768 ){
  101. sprintf( buf,"%i",n );
  102. mask=EA_SIMM;
  103. return e;
  104. }
  105. if( (mask & EA_UIMM) && n>=0 && n<65536 ){
  106. sprintf( buf,"%i",n );
  107. mask=EA_UIMM;
  108. return e;
  109. }
  110. }
  111. }
  112. }
  113. CGReg *r=genExp( e );
  114. sprintf( buf,"'%i",r->id );
  115. mask=0;
  116. return r;
  117. }
  118. CGReg *CGFrame_PPC::genLea( CGLea *e ){
  119. CGReg *r=reg(e->type);
  120. CGMem *m=e->exp->mem();
  121. assert( m );
  122. char buf[256];
  123. m=genMem(m,buf);
  124. gen( mov(r,lea(m)),"\tla\t'%i,%s\n",r->id,buf );
  125. return r;
  126. }
  127. CGReg *CGFrame_PPC::genCvt( CGCvt *e ){
  128. CGReg *r=reg(e->type);
  129. if( r->isint() && e->exp->isint() ){
  130. //int to int
  131. CGReg *t=genExp(e->exp);
  132. if( r->type==CG_INT8 && e->exp->type!=CG_INT8 ){
  133. gen( mov(r,cvt(r->type,t)),
  134. "\tandi.\t'%i,'%i,0xff\n",
  135. r->id,t->id );
  136. }else if( r->type==CG_INT16 && e->exp->type==CG_INT32 ){
  137. gen( mov(r,cvt(r->type,t)),
  138. "\tandi.\t'%i,'%i,0xffff\n",
  139. r->id,t->id );
  140. }else{
  141. gen( mov(r,cvt(r->type,t)),
  142. "\tmr\t'%i,'%i\n",
  143. r->id,t->id );
  144. }
  145. }else if( r->isfloat() && e->exp->isfloat() ){
  146. //float to float
  147. CGReg *t=genExp(e->exp);
  148. gen( mov(r,cvt(r->type,t)),
  149. "\tfmr\t'%i,'%i\n",
  150. r->id,t->id );
  151. }else if( r->isint() && e->exp->isfloat() ){
  152. //float to int
  153. if( tmp_disp8<0 ){
  154. tmp_disp8=local_sz;
  155. local_sz+=8;
  156. }
  157. int off;
  158. const char *op;
  159. switch( r->type ){
  160. case CG_INT8:off=7;op="lbz";break;
  161. case CG_INT16:off=6;op="lhz";break;
  162. case CG_INT32:case CG_PTR:off=4;op="lwz";break;
  163. default:assert(0);
  164. }
  165. CGReg *t=genExp(e->exp),*f=F[0];
  166. CGAsm *as=gen( mov(r,cvt(e->type,t)),
  167. "\tfctiwz\t'%i,'%i\n"
  168. "\tstfd\t'%i,__LOCAL+%i(r1)\n"
  169. "\t%s\t'%i,__LOCAL+%i+%i(r1)\n",
  170. f->id,t->id,
  171. f->id,tmp_disp8,
  172. op,r->id,tmp_disp8,off );
  173. as->def.insert(f->id);
  174. }else if( r->isfloat() && e->exp->isint() ){
  175. //int to float
  176. if( tmp_disp8<0 ){
  177. tmp_disp8=local_sz;
  178. local_sz+=8;
  179. }
  180. if( !mod_ppc->fp_const ){
  181. mod_ppc->fp_const=sym();
  182. }
  183. CGReg *t=reg(CG_INT32),*f=F[0];
  184. string p=mod_ppc->fp_const->value;
  185. genMov( t,genExp(e->exp) );
  186. CGAsm *as=gen( mov(r,cvt(e->type,t)),
  187. "\tlis\tr0,0x4330\n"
  188. "\tstw\tr0,__LOCAL+%i(r1)\n"
  189. "\txoris\t'%i,'%i,0x8000\n"
  190. "\tstw\t'%i,__LOCAL+%i+4(r1)\n"
  191. "\tlis\t'%i,ha16(%s)\n"
  192. "\tlfd\t'%i,lo16(%s)('%i)\n"
  193. "\tlfd\t'%i,__LOCAL+%i(r1)\n"
  194. "\tfsub\t'%i,'%i,'%i\n",
  195. tmp_disp8,
  196. t->id,t->id,
  197. t->id,tmp_disp8,
  198. t->id,p.c_str(),
  199. f->id,p.c_str(),t->id,
  200. r->id,tmp_disp8,
  201. r->id,r->id,f->id );
  202. as->use.insert(t->id);
  203. as->def.insert(t->id);
  204. as->def.insert(f->id);
  205. }else{
  206. assert(0);
  207. }
  208. return r;
  209. /* int r3 to float f1
  210. addis R0,R0,0x4330 # R0 = 0x43300000
  211. stw R0,disp(R1) # store upper half
  212. xoris R3,R3,0x8000 # flip sign bit
  213. stw R3,disp+4(R1) # store lower half
  214. lfd FR1,disp(R1) # float load double of value
  215. fsub FR1,FR1,FR2 # subtract 0x4330000080000000
  216. */
  217. /* float f1 to int r3
  218. fctiw[z] FR2,FR1 # convert to integer
  219. stfd FR2,disp(R1) # copy unmodified to memory
  220. lwz R3,disp+4(R1) # load the low-order 32 bits
  221. */
  222. }
  223. CGReg *CGFrame_PPC::genUop( CGUop *e ){
  224. const char *op=0;
  225. switch( e->op ){
  226. case CG_NOT:assert(e->isint());op="not";break;
  227. case CG_NEG:op=e->isfloat() ? "fneg" : "neg";break;
  228. default:assert(0);
  229. }
  230. CGReg *r=reg(e->type);
  231. CGReg *s=genExp(e->exp);
  232. gen( mov(r,uop(e->op,s)),"\t%s\t'%i,'%i\n",op,r->id,s->id );
  233. return r;
  234. }
  235. static int shifter( int n ){
  236. int k;
  237. for( k=0;k<32;++k ) if( (1<<k)==n ) return k;
  238. return -1;
  239. }
  240. CGReg *CGFrame_PPC::genBop( CGBop *e ){
  241. if( e->isint() && (e->op==CG_MUL || e->op==CG_DIV) ){
  242. if( CGLit *c=e->rhs->lit() ){
  243. int i=c->int_value;
  244. if( e->op==CG_MUL ){
  245. int n=shifter(i);
  246. if( n!=-1 ){
  247. CGReg *r=reg(e->type);
  248. CGReg *t=genExp(e->lhs);
  249. gen( mov(r,bop(e->op,t,c)),
  250. "\tslwi\t'%i,'%i,%i\n",
  251. r->id,t->id,n );
  252. return r;
  253. }
  254. }else if( e->op==CG_DIV ){
  255. int n=shifter(i);
  256. if( n!=-1 ){
  257. CGReg *r=reg(e->type);
  258. CGReg *t=genExp(e->lhs);
  259. gen( mov(r,bop(e->op,t,c)),
  260. "\tsrawi\t'%i,'%i,%i\n"
  261. "\taddze\t'%i,'%i\n",
  262. r->id,t->id,n,r->id,r->id );
  263. return r;
  264. }
  265. }
  266. }
  267. }
  268. CGReg *r=reg(e->type);
  269. const char *op=0;
  270. int mask=0;
  271. if( e->isfloat() ){
  272. switch( e->op ){
  273. case CG_ADD:op="fadd";break;
  274. case CG_SUB:op="fsub";break;
  275. case CG_MUL:op="fmul";break;
  276. case CG_DIV:op="fdiv";break;
  277. }
  278. }else{
  279. switch( e->op ){
  280. case CG_ADD:op="add";mask=EA_SIMM;break;
  281. case CG_SUB:op="sub";mask=EA_SIMM;break;
  282. case CG_MUL:op="mullw";mask=EA_SIMM;break;
  283. case CG_DIV:op="divw";break;
  284. case CG_AND:op="and";mask=EA_UIMM;break;
  285. case CG_ORL:op="or";mask=EA_UIMM;break;
  286. case CG_XOR:op="xor";mask=EA_UIMM;break;
  287. case CG_SHL:op="slw";break;
  288. case CG_SHR:op="srw";break;
  289. case CG_SAR:op="sraw";break;
  290. }
  291. }
  292. if( op ){
  293. char buf[256];
  294. CGReg *lhs=genExp(e->lhs);
  295. CGExp *rhs=genExp(e->rhs,buf,mask);
  296. const char *ext="";
  297. if( mask ){
  298. ext="i";
  299. switch( e->op ){
  300. case CG_AND:ext="i.";break;
  301. case CG_MUL:op="mull";break;
  302. }
  303. }
  304. gen( mov(r,bop(e->op,lhs,rhs)),
  305. "\t%s%s\t'%i,'%i,%s\n",op,ext,r->id,lhs->id,buf );
  306. return r;
  307. }
  308. if( e->op==CG_MOD && e->isint() ){
  309. CGReg *lhs=genExp(e->lhs);
  310. CGReg *rhs=genExp(e->rhs);
  311. //divw Rt,Ra,Rb # quotient = (int)(Ra / Rb)
  312. //mullw Rt,Rt,Rb # quotient * Rb
  313. //subf Rt,Rt,Ra # remainder = Ra - quotient * Rb
  314. gen( mov(r,bop(e->op,lhs,rhs)),
  315. "\tdivw\tr0,'%i,'%i\n"
  316. "\tmullw\tr0,r0,'%i\n"
  317. "\tsubf\t'%i,r0,'%i\n",
  318. lhs->id,rhs->id,rhs->id,r->id,lhs->id );
  319. return r;
  320. }
  321. assert(0);
  322. return 0;
  323. }
  324. CGReg *CGFrame_PPC::genScc( CGScc *e ){
  325. CGReg *r=reg(CG_INT32);
  326. CGReg *lhs=genExp(e->lhs);
  327. CGReg *rhs=genExp(e->rhs);
  328. int bit=0;
  329. char cror[256];cror[0]=0;
  330. char exor[256];exor[0]=0;
  331. const char *op=lhs->isfloat() ? "fcmpu" : "cmpw";
  332. switch( e->cc ){
  333. case CG_LT:bit=29;break;
  334. case CG_GT:bit=30;break;
  335. case CG_EQ:bit=31;break;
  336. case CG_LE:bit=0;sprintf(cror,"\tcror\t31,30,28\n");break;
  337. case CG_GE:bit=0;sprintf(cror,"\tcror\t31,30,29\n");break;
  338. case CG_NE:bit=31;sprintf(exor,"\txori\t'%i,'%i,1\n",r->id,r->id);break;
  339. case CG_LTU:bit=29;op="cmplw";break;
  340. default:assert(0);
  341. }
  342. gen( mov(r,scc(e->cc,lhs,rhs)),
  343. "\t%s\tcr7,'%i,'%i\n%s"
  344. "\tmfcr\t'%i\n"
  345. "\trlwinm\t'%i,'%i,%i,31,31\n%s",
  346. op,lhs->id,rhs->id,cror,r->id,r->id,r->id,bit,exor );
  347. return r;
  348. }
  349. CGReg *CGFrame_PPC::genJsr( CGJsr *e ){
  350. vector<CGExp*> args;
  351. int k;
  352. for( k=e->args.size()-1;k>=0;--k ){
  353. CGExp *arg=e->args[k];
  354. args.push_back( genExp(e->args[k]) );
  355. }
  356. CGExp *ea=e->exp;
  357. if( CGVfn *t=ea->vfn() ){
  358. args.push_back( genExp(t->self) );
  359. ea=t->exp;
  360. }
  361. ea=genExp(ea);
  362. int arg_sz=0,fp_id=1;
  363. for( k=args.size()-1;k>=0;--k ){
  364. CGExp *t=args[k],*p;
  365. if( t->isfloat() && fp_id<14 ){
  366. p=F[fp_id++];
  367. }else if( t->isfloat() || arg_sz>=32 ){
  368. p=mem(t->type,R[1],arg_sz+24 );
  369. }else{
  370. p=R[arg_sz/4+3];
  371. }
  372. arg_sz+=(t->type==CG_FLOAT64) ? 8 : 4;
  373. genMov( p,t );
  374. args[k]=p;
  375. }
  376. if( arg_sz>param_sz ) param_sz=arg_sz;
  377. CGExp *dst=e->isfloat() ? F[1] : R[3];
  378. CGAsm *as=gen( mov(dst,jsr(e->type,e->call_conv,ea,args)),
  379. "\tmtctr\t'%i\n"
  380. "\tbctrl\n",ea->reg()->id );
  381. for( k=3;k<13;++k ) as->def.insert( R[k]->id );
  382. for( k=1;k<14;++k ) as->def.insert( F[k]->id );
  383. CGReg *r=reg( e->type );
  384. genMov( r,dst );
  385. return r;
  386. }
  387. CGReg *CGFrame_PPC::genLit( CGLit *e ){
  388. CGReg *r=reg(e->type);
  389. if( e->isfloat() ){
  390. CGDat *d=dat();
  391. d->push_back(e);
  392. genMov( r,mem(e->type,d,0) );
  393. return r;
  394. }
  395. CGStm *m=mov(r,e);
  396. int n=e->int_value;
  397. if( n>=-32768 && n<32768 ){
  398. //16 bit signed
  399. gen( m,
  400. "\tli\t'%i,%i\n",r->id,n );
  401. }else if( !(n&65535) ){
  402. //32 bit - 0 low word
  403. gen( m,
  404. "\tlis\t'%i,%i\n",r->id,(n>>16) );
  405. }else{
  406. //32 bit
  407. gen( m,
  408. "\tlis\t'%i,%i\n"
  409. "\tori\t'%i,'%i,%i\n",r->id,(n>>16),r->id,r->id,(n&65535) );
  410. }
  411. return r;
  412. }
  413. CGReg *CGFrame_PPC::genSym( CGSym *e ){
  414. CGReg *r=reg(e->type);
  415. if( e->linkage==CG_IMPORT ){
  416. string t=""+e->value+"$non_lazy_ptr";
  417. gen( mov(r,e),
  418. "\tlis\t'%i,ha16(%s)\n"
  419. "\tlwz\t'%i,lo16(%s)('%i)\n",r->id,t.c_str(),r->id,t.c_str(),r->id );
  420. }else{
  421. gen( mov(r,e),
  422. "\tlis\t'%i,hi16(%s)\n"
  423. "\tori\t'%i,'%i,lo16(%s)\n",r->id,e->value.c_str(),r->id,r->id,e->value.c_str() );
  424. }
  425. return r;
  426. }
  427. CGReg *CGFrame_PPC::genFrm( CGFrm *e ){
  428. CGReg *r=reg(CG_PTR);
  429. gen( mov(r,e),
  430. "\tla\t'%i,__LOCAL(r1)\n",r->id );
  431. return r;
  432. }
  433. void CGFrame_PPC::genBcc( int cc,CGExp *lhs,CGExp *rhs,CGSym *sym ){
  434. if( cc==CG_LTU ){
  435. genBcc( CG_NE,scc(cc,lhs,rhs),lit0,sym );
  436. return;
  437. }
  438. int tcc=cc;
  439. if( bigFun ) cc=CG::swapcc(cc);
  440. const char *p;
  441. switch( cc ){
  442. case CG_LT:p="lt";break;
  443. case CG_GT:p="gt";break;
  444. case CG_EQ:p="eq";break;
  445. case CG_LE:p="le";break;
  446. case CG_GE:p="ge";break;
  447. case CG_NE:p="ne";break;
  448. default:assert(0);
  449. }
  450. if( lhs->isfloat() ){
  451. CGReg *x=genExp(lhs);
  452. CGReg *y=genExp(rhs);
  453. if( bigFun ){
  454. CGSym *t=CG::sym();
  455. gen( bcc(tcc,x,y,sym),
  456. "\tfcmpu\tcr0,'%i,'%i\n"
  457. "\tb%s\t%s\n\tb\t%s\n%s:\n",x->id,y->id,p,t->value.c_str(),sym->value.c_str(),t->value.c_str() );
  458. }else{
  459. gen( bcc(cc,x,y,sym),
  460. "\tfcmpu\tcr0,'%i,'%i\n"
  461. "\tb%s\t%s\n",x->id,y->id,p,sym->value.c_str() );
  462. }
  463. return;
  464. }
  465. char buf[256];
  466. int mask=EA_SIMM;
  467. CGReg *x=genExp(lhs);
  468. CGExp *y=genExp(rhs,buf,mask);
  469. const char *ext=mask ? "i" : "";
  470. if( bigFun ){
  471. CGSym *t=CG::sym();
  472. gen( bcc(tcc,x,y,sym),
  473. "\tcmpw%s\t'%i,%s\n"
  474. "\tb%s\t%s\n\tb\t%s\n%s:\n",ext,x->id,buf,p,t->value.c_str(),sym->value.c_str(),t->value.c_str() );
  475. }else{
  476. gen( bcc(cc,x,y,sym),
  477. "\tcmpw%s\t'%i,%s\n"
  478. "\tb%s\t%s\n",ext,x->id,buf,p,sym->value.c_str() );
  479. }
  480. }
  481. void CGFrame_PPC::genRet( CGExp *e ){
  482. CGReg *r=0;
  483. if( e ){
  484. r=e->isfloat() ? F[1] : R[3];
  485. genMov(r,e);
  486. }
  487. CGAsm *as=gen( ret(r),"\tblr\n" );
  488. as->use.insert( R[1]->id );
  489. }
  490. string CGFrame_PPC::fixSym( string id ){
  491. return "_"+id;
  492. }
  493. void CGFrame_PPC::genStm( CGStm *s ){
  494. if( CGAti *t=s->ati() ){
  495. char buf[256];
  496. CGMem *m=genMem( t->mem,buf );
  497. CGAsm *as=gen( ati(m),
  498. "\tlwz\tr2,%s\n"
  499. "\taddi\tr2,r2,1\n"
  500. "\tstw\tr2,%s\n",
  501. buf,buf );
  502. /*
  503. CGReg *r=genLea( lea(t->mem) );
  504. CGAsm *as=gen( ati(mem(CG_INT32,r,0)),
  505. "1:\n"
  506. "\tlwarx\tr2,0,'%i\n"
  507. "\taddi\tr2,r2,1\n"
  508. "\tstwcx.\tr2,0,'%i\n"
  509. "\tbne\t1b\n",
  510. r->id,r->id );
  511. */
  512. }else if( CGAtd *t=s->atd() ){
  513. char buf[256];
  514. CGMem *m=genMem( t->mem,buf );
  515. CGAsm *as=gen( atd(m,t->sym),
  516. "\tlwz\tr2,%s\n"
  517. "\taddi\tr2,r2,-1\n"
  518. "\tstw\tr2,%s\n"
  519. "\tcmpwi\tr2,0\n"
  520. "\tbne\t%s\n",
  521. buf,buf,t->sym->value.c_str() );
  522. /*
  523. CGReg *r=genLea( lea(t->mem) );
  524. CGAsm *as=gen( atd(mem(CG_INT32,r,0),t->sym),
  525. "1:\n"
  526. "\tlwarx\tr2,0,'%i\n"
  527. "\taddi\tr2,r2,-1\n"
  528. "\tstwcx.\tr2,0,'%i\n"
  529. "\tbne\t1b\n"
  530. "\tor.\tr2,r2,r2\n"
  531. "\tbne\t%s\n",
  532. r->id,r->id,t->sym->value.c_str() );
  533. */
  534. }else if( CGMov *t=s->mov() ){
  535. genMov( t->lhs,t->rhs );
  536. }else if( CGLab *t=s->lab() ){
  537. gen( t,"%s:\n",t->sym->value.c_str() );
  538. }else if( CGBra *t=s->bra() ){
  539. gen( t,"\tb\t%s\n",t->sym->value.c_str() );
  540. }else if( CGBcc *t=s->bcc() ){
  541. genBcc( t->cc,t->lhs,t->rhs,t->sym );
  542. }else if( CGEva *t=s->eva() ){
  543. if( t->exp->dat() ){
  544. gen( t,"" );
  545. }else{
  546. genExp( t->exp );
  547. }
  548. }else if( CGRem *t=s->rem() ){
  549. gen( t,"\t;%s\n",t->comment.c_str() );
  550. }else if( CGRet *t=s->ret() ){
  551. genRet( t->exp );
  552. }else if( CGXop *t=s->xop() ){
  553. assert(0);
  554. }else{
  555. assert(0);
  556. }
  557. }
  558. void CGFrame_PPC::genFun(){
  559. param_sz=32;
  560. tmp_disp8=-1;
  561. int k,arg_sz=0,fp_id=1;
  562. //move self to tmp
  563. if( CGExp *t=fun->self ){
  564. //get 'this' from stack
  565. genMov( t,R[3] );
  566. arg_sz+=4;
  567. }
  568. //move args to tmps
  569. for( k=0;k<fun->args.size();++k ){
  570. CGExp *t=fun->args[k],*p;
  571. if( t->isfloat() && fp_id<14 ){
  572. p=F[fp_id++];
  573. }else if( t->isfloat() || arg_sz>=32 ){
  574. CGMem *m=mem(t->type,R[1],arg_sz+24 );
  575. m->flags=MEM_PARAM;
  576. p=m;
  577. }else{
  578. p=R[arg_sz/4+3];
  579. }
  580. arg_sz+=(t->type==CG_FLOAT64) ? 8 : 4;
  581. genMov( t,p );
  582. }
  583. //genAsm for statements
  584. for( k=0;k<fun->stms.size();++k ){
  585. genStm( fun->stms[k] );
  586. }
  587. }
  588. CGMem *CGFrame_PPC::allocLocal( int type ){
  589. CGMem *m=mem(type,R[1],local_sz);
  590. m->flags=MEM_LOCAL;
  591. int sz=(type==CG_INT64 || type==CG_FLOAT64) ? 8 : 4;
  592. local_sz+=sz;
  593. return m;
  594. }
  595. CGExp *CGFrame_PPC::allocSpill( CGReg *r ){
  596. return allocLocal( r->type );
  597. }
  598. void CGFrame_PPC::finish(){
  599. }
  600. CGFrame_PPC::CGFrame_PPC( CGFun *fun,CGModule_PPC *mod ):CGFrame(fun),
  601. mod_ppc(mod),local_sz(0){
  602. bigFun=fun->stms.size()>300;
  603. /*
  604. if( bigFun ){
  605. printf( "Big function:%i stms\n",fun->stms.size() );
  606. fflush( stdout );
  607. }else{
  608. printf( "Small function:%i stms\n",fun->stms.size() );
  609. fflush( stdout );
  610. }
  611. */
  612. //int types map to reg bank 0
  613. reg_banks[CG_INT8]=0;
  614. reg_banks[CG_INT16]=0;
  615. reg_banks[CG_INT32]=0;
  616. reg_banks[CG_PTR]=0;
  617. //float types map to bank 1
  618. reg_banks[CG_FLOAT32]=1;
  619. reg_banks[CG_FLOAT64]=1;
  620. //available reg masks
  621. reg_masks[0]=0xfffffff8; //R0/R1/R2 unavailable!
  622. reg_masks[1]=0xfffffffe; //F0 unavailable!
  623. char *buf;
  624. for( int k=0;k<32;++k ){
  625. R[k]=reg( CG_INT32,0,k );
  626. F[k]=reg( CG_FLOAT64,0,k );
  627. buf=new char[4];
  628. sprintf( buf,"r%i",k<13 ? k : 31+13-k );
  629. reg_names[0].push_back( buf );
  630. buf=new char[4];
  631. sprintf( buf,"f%i",k );
  632. reg_names[1].push_back( buf );
  633. }
  634. }