cgmodule_ppc.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "cgstd.h"
  2. #include "cgdebug.h"
  3. #include "cgmodule_ppc.h"
  4. CGModule_PPC::CGModule_PPC( ostream &o ):CGModule(o),fp_const(0){
  5. }
  6. void CGModule_PPC::setSeg( string t ){
  7. if( t==seg ) return;
  8. seg=t;
  9. out<<"\t."<<seg<<'\n';
  10. }
  11. CGFrame *CGModule_PPC::frame( CGFun *f ){
  12. return new CGFrame_PPC( f,this );
  13. }
  14. void CGModule_PPC::emitHeader(){
  15. }
  16. void CGModule_PPC::emitImport( string t ){
  17. out<<"\t.non_lazy_symbol_pointer\n";
  18. out<<""<<t<<"$non_lazy_ptr:\n";
  19. out<<"\t.indirect_symbol\t"<<t<<"\n";
  20. out<<"\t.long\t0\n";
  21. }
  22. void CGModule_PPC::emitExport( string t ){
  23. out<<"\t.globl\t"<<t<<'\n';
  24. }
  25. void CGModule_PPC::emitFrame( CGFrame *f ){
  26. CGFrame_PPC *frame=dynamic_cast<CGFrame_PPC*>(f);
  27. assert(frame);
  28. setSeg( "text" );
  29. //find callee-save regs
  30. int k,max_int=12,max_flt=13;
  31. for( k=64;k<frame->regs.size();++k ){
  32. CGReg *r=frame->regs[k];
  33. if( r->isfloat() ){
  34. if( r->color>=14 && r->color<=31 && r->color>max_flt ) max_flt=r->color;
  35. }else{
  36. if( r->color>=13 && r->color<=31 && r->color>max_int ) max_int=r->color;
  37. }
  38. }
  39. int int_save=max_int-12;
  40. int flt_save=max_flt-13;
  41. int save_sz=int_save*4+flt_save*8;
  42. int stack_sz=24+frame->param_sz+frame->local_sz+save_sz;
  43. stack_sz=(stack_sz+15)&~15;
  44. //emit label
  45. out<<frame->fun->sym->value<<":\n";
  46. //setup frames
  47. out<<"__LOCAL="<<(24+frame->param_sz)<<'\n';
  48. out<<"__FRAME="<<stack_sz<<'\n';
  49. //get link register
  50. out<<"\tmflr\tr0\n";
  51. //save float regs
  52. for( k=0;k<flt_save;++k ){
  53. out<<"\tstfd\tf"<<(k+14)<<","<<(-save_sz+int_save*4+k*8)<<"(r1)\n";
  54. }
  55. //save int regs
  56. if( int_save ){
  57. out<<"\tstmw\tr"<<(32-int_save)<<","<<(-save_sz)<<"(r1)\n";
  58. }
  59. //save link register
  60. out<<"\tstw\tr0,8(r1)\n";
  61. //allocate frame
  62. out<<"\tstwu\tr1,"<<-stack_sz<<"(r1)\n";
  63. CGAsm *as;
  64. for( as=frame->assem.begin;as!=frame->assem.end;as=as->succ ){
  65. if( as->stm->ret() ){
  66. out<<"\tlwz\tr1,0(r1)\n";
  67. out<<"\tlwz\tr0,8(r1)\n";
  68. out<<"\tmtlr\tr0\n";
  69. //restore int regs
  70. if( int_save ){
  71. out<<"\tlmw\tr"<<(32-int_save)<<","<<(-save_sz)<<"(r1)\n";
  72. }
  73. //restore float regs
  74. for( int k=flt_save-1;k>=0;--k ){
  75. out<<"\tlfd\tf"<<(k+14)<<","<<(-save_sz+int_save*4+k*8)<<"(r1)\n";
  76. }
  77. }
  78. const char *p=as->assem;
  79. if( !p ) continue;
  80. out<<p;
  81. }
  82. }
  83. void CGModule_PPC::emitData( CGDat *d ){
  84. setSeg( "data" );
  85. out<<"\t.align\t2\n";
  86. out<<d->value<<":\n";
  87. for( int k=0;k<d->exps.size();++k ){
  88. CGExp *e=d->exps[k];
  89. if( CGLit *t=e->lit() ){
  90. if( t->type==CG_INT8 ){
  91. out<<"\t.byte\t"<<unsigned(t->int_value)<<'\n';
  92. }else if( t->type==CG_INT16 ){
  93. out<<"\t.short\t"<<unsigned(t->int_value)<<'\n';
  94. }else if( t->type==CG_INT32 ){
  95. out<<"\t.long\t"<<int(t->int_value)<<'\n';
  96. }else if( t->type==CG_INT64 ){
  97. out<<"\t.long\t"<<int(t->int_value>>int64(32))<<','<<int(t->int_value)<<'\n';
  98. }else if( t->type==CG_FLOAT32 ){
  99. float f=t->float_value;
  100. out<<"\t.long\t0x"<<hex<<*((int*)&f)<<dec<<'\n';
  101. }else if( t->type==CG_FLOAT64 ){
  102. double f=t->float_value;
  103. out<<"\t.long\t0x"<<hex<<*((int*)&f+0)<<",0x"<<*((int*)&f+1)<<dec<<'\n';
  104. }else if( t->type==CG_CSTRING ){
  105. bstring s=t->string_value;
  106. out<<"\t.asciz\t\"";
  107. for( int k=0;k<s.size();++k ){
  108. if( s[k]==34 ){
  109. out<<"\\\"";
  110. }else{
  111. out<<(char)s[k];
  112. }
  113. }
  114. out<<"\"\n";
  115. }else if( t->type==CG_BSTRING ){
  116. bstring s=t->string_value;
  117. out<<"\t.long\t"<<s.size();
  118. for( int k=0;k<s.size();++k ){
  119. if( k%16 ) out<<','<<(unsigned)(unsigned short)s[k];
  120. else out<<"\n\t.short\t"<<(unsigned)(unsigned short)s[k];
  121. }
  122. out<<"\n";
  123. }else if( t->type==CG_BINFILE ){
  124. string file=tostring(t->string_value);
  125. ifstream is( file.c_str() );
  126. if( !is.good() ) fail( "Unable to read from file '%s'",file.c_str() );
  127. for(;;){
  128. char buf[16];
  129. is.read( buf,16 );
  130. int n=is.gcount();
  131. if( !n ) break;
  132. out<<"\t.byte\t";
  133. for( int k=0;k<n;++k ){
  134. if( k ) out<<',';
  135. out<<(unsigned)(unsigned char)buf[k];
  136. }
  137. out<<'\n';
  138. }
  139. is.close();
  140. }else if( t->type==CG_LABEL ){
  141. out<<tostring(t->string_value)<<":\n";
  142. }else{
  143. assert(0);
  144. }
  145. }else if( CGSym *t=e->sym() ){
  146. out<<"\t.long\t"<<t->value<<'\n';
  147. }else if( CGLea *t=e->lea() ){
  148. CGMem *m=t->exp->mem();
  149. assert(m);
  150. if( m->flags==1 ){ //PARAM
  151. }else if( m->flags==2 ){ //LOCAL
  152. out<<"\t.long\t"<<m->offset<<'\n';
  153. }else if( CGSym *t=m->exp->sym() ){
  154. assert(t);
  155. if( m->offset ){
  156. out<<"\t.long\t"<<t->value<<'+'<<m->offset<<'\n';
  157. }else{
  158. out<<"\t.long\t"<<t->value<<'\n';
  159. }
  160. }else{
  161. assert(0);
  162. }
  163. }else{
  164. cout<<e<<endl;
  165. assert(0);
  166. }
  167. }
  168. }
  169. void CGModule_PPC::emitFooter(){
  170. //emit fp_const
  171. if( fp_const ){
  172. setSeg( "data" );
  173. out<<fp_const->value<<":\n";
  174. out<<"\t.double\t0r4.50360177485414400000e15\n";
  175. }
  176. }