hschumann2/TempleOS-Source-Code
0838
1 2CCodeMisc *OptLabelFwd(CCodeMisc *lb)3{4 CCodeMisc *lb1;5 while (lb1=lb->fwd)6 lb=lb1;7 return lb;8}9 10CHashClass *OptClassFwd(CHashClass *tmpc)11{//Class forwarding for unions and subclasses.12 CHashClass *tmpc1;13 while (tmpc1=tmpc->fwd_class)14 tmpc=tmpc1;15 return tmpc;16}17 18U0 OptSetNOP1(CIntermediateCode *tmpi)19{20 tmpi->ic_code=IC_NOP1;21 tmpi->ic_flags=0;22 tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;23 tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;24}25 26U0 OptSetNOP2(CIntermediateCode *tmpi,I64 stk_delta=1)27{28 tmpi->ic_code=IC_NOP2;29 tmpi->ic_data=stk_delta;30 tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;31 tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;32}33 34CIntermediateCode *OptFree(CIntermediateCode *tmpi)35{//We might access freed entries in CICTreeLinks36 QueRem(tmpi);37 Free(tmpi);38 return NULL;39}40 41CIntermediateCode *OptLag(CIntermediateCode *tmpi)42{43 do {44 if (!tmpi->ic_code)45 return NULL;46 else47 tmpi=tmpi->last;48 } while (tmpi->ic_code<=IC_END_EXP);49 return tmpi;50}51 52CIntermediateCode *OptLag1(CIntermediateCode *tmpi)53{54 do {55 if (!tmpi->ic_code)56 return NULL;57 else58 tmpi=tmpi->last;59 } while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);60 return tmpi;61}62 63CIntermediateCode *OptLag2(CIntermediateCode *tmpi)64{65 do {66 if (!tmpi->ic_code)67 return NULL;68 else69 tmpi=tmpi->last;70 } while (tmpi->ic_code<IC_END_EXP);71 return tmpi;72}73 74CIntermediateCode *OptLead1(CIntermediateCode *tmpi)75{76 do {77 tmpi=tmpi->next;78 if (!tmpi->ic_code)79 return NULL;80 } while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);81 return tmpi;82}83 84I64 CmpOffset2Reg(I64 offset,COptReg *reg_offsets)85{86 I64 i;87 for (i=0;i<REG_REGS_NUM;i++)88 if (offset==reg_offsets[i].offset)89 return i;90 return -1;91}92 93#define FBO1_NOT_CONST 094#define FBO1_INT 195#define FBO1_F64 296 97Bool OptFixupBinaryOp1(CIntermediateCode *tmpi,98 CIntermediateCode *tmpi1,CIntermediateCode *tmpi2,99 Bool *is_unsigned)100{101 CIntermediateCode *tmpii;102 CHashClass *tmpc=tmpi->ic_class,*tmpc1,*tmpc2;103 104 if (tmpi1->ic_flags&ICF_RES_TO_INT)105 tmpc1=cmp.internal_types[RT_I64];106 else if (tmpi1->ic_flags&ICF_RES_TO_F64)107 tmpc1=cmp.internal_types[RT_F64];108 else {109 tmpc1=OptClassFwd(tmpi1->ic_class);110 }111 112 if (tmpi2->ic_flags&ICF_RES_TO_INT)113 tmpc2=cmp.internal_types[RT_I64];114 else if (tmpi2->ic_flags&ICF_RES_TO_F64)115 tmpc2=cmp.internal_types[RT_F64];116 else {117 tmpc2=OptClassFwd(tmpi2->ic_class);118 }119 120 if (tmpc1->raw_type>tmpc2->raw_type)121 tmpc=tmpi->ic_class=tmpc1;122 else123 tmpc=tmpi->ic_class=tmpc2;124 125 if (tmpc->raw_type==RT_F64) {126 if (tmpi1->ic_code==IC_IMM_I64) {127 tmpi1->ic_data(F64)=tmpi1->ic_data;128 tmpi1->ic_class=cmp.internal_types[RT_F64];129 tmpi1->ic_code=IC_IMM_F64;130 tmpi1->ic_flags&=~ICF_RES_TO_F64;131 } else132 if (tmpc1->raw_type!=RT_F64)133 tmpi1->ic_flags|=ICF_RES_TO_F64;134 if (tmpi2->ic_code==IC_IMM_I64) {135 tmpi2->ic_data(F64)=tmpi2->ic_data;136 tmpi2->ic_class=cmp.internal_types[RT_F64];137 tmpi2->ic_code=IC_IMM_F64;138 tmpi2->ic_flags&=~ICF_RES_TO_F64;139 } else140 if (tmpc2->raw_type!=RT_F64)141 tmpi2->ic_flags|=ICF_RES_TO_F64;142 if (IC_LESS<=tmpi->ic_code<=IC_GREATER_EQU && (tmpii=OptLead1(tmpi)) &&143 tmpii->ic_code!=IC_PUSH_CMP && tmpii->ic_code!=IC_AND_AND) {144//We are looking for float comparisons to zero to convert to int.145 if (tmpi1->ic_code==IC_IMM_F64 && !tmpi1->ic_data &&146 tmpi2->ic_code==IC_DEREF && tmpc2==cmp.internal_types[RT_F64]) {147 tmpi1->ic_code==IC_IMM_I64;148 goto fb_here1;149 } else if (tmpi2->ic_code==IC_IMM_F64 && !tmpi2->ic_data &&150 tmpi1->ic_code==IC_DEREF && tmpc1==cmp.internal_types[RT_F64]) {151 tmpi2->ic_code==IC_IMM_I64;152fb_here1:153 tmpi1->ic_flags&=~ICF_RES_TO_F64;154 tmpi->ic_class=tmpi1->ic_class=tmpi2->ic_class=155 cmp.internal_types[RT_I64];156 *is_unsigned=FALSE;157 return FBO1_NOT_CONST;158 }159 goto fb_here2;160 } else {161fb_here2:162 if (tmpi1->ic_code==IC_IMM_F64 && tmpi2->ic_code==IC_IMM_F64 &&163 !(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {164 tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;165 OptSetNOP1(tmpi1);166 OptSetNOP1(tmpi2);167 return FBO1_F64;168 } else169 return FBO1_NOT_CONST;170 }171 }172 *is_unsigned=tmpc1->raw_type&RTF_UNSIGNED || tmpc2->raw_type&RTF_UNSIGNED;173 if (tmpi1->ic_code==IC_IMM_I64 && tmpi2->ic_code==IC_IMM_I64 &&174 !(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {175 tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;176 OptSetNOP1(tmpi1);177 OptSetNOP1(tmpi2);178 return FBO1_INT;179 } else180 return FBO1_NOT_CONST;181}182 183Bool OptFixupBinaryOp2(CIntermediateCode **tmpi1,CIntermediateCode **tmpi2)184{185 CIntermediateCode *tmpii1=*tmpi1,186 *tmpii2=*tmpi2;187 if (tmpii1->ic_code==IC_IMM_I64 && !(tmpii1->ic_flags & ICF_RES_TO_F64))188 return TRUE;189 if (tmpii2->ic_code==IC_IMM_I64 && !(tmpii2->ic_flags & ICF_RES_TO_F64)) {190 *tmpi1=tmpii2;191 *tmpi2=tmpii1;192 return TRUE;193 }194 return FALSE;195}196 197Bool OptFixupUnaryOp(CIntermediateCode *tmpi, CIntermediateCode *tmpi1,198 Bool *is_unsigned)199{200 CHashClass *tmpc,*tmpc1;201 tmpc1=OptClassFwd(tmpi1->ic_class);202 tmpi->ic_class=tmpc1;203 tmpc=tmpi->ic_class;204 if (tmpc->raw_type==RT_F64) {205 if (tmpi1->ic_code==IC_IMM_I64) {206 tmpi1->ic_data(F64)=tmpi1->ic_data;207 tmpi1->ic_class=cmp.internal_types[RT_F64];208 tmpi1->ic_code=IC_IMM_F64;209 tmpi1->ic_flags&=~ICF_RES_TO_F64;210 } else211 if (tmpc1->raw_type!=RT_F64)212 tmpi1->ic_flags|=ICF_RES_TO_F64;213 if (tmpi1->ic_code==IC_IMM_F64) {214 tmpi->ic_flags|=tmpi1->ic_flags;215 OptSetNOP1(tmpi1);216 return FBO1_F64;217 } else218 return FBO1_NOT_CONST;219 }220 *is_unsigned=tmpc1->raw_type&RTF_UNSIGNED;221 if (tmpi1->ic_code==IC_IMM_I64) {222 tmpi->ic_flags|=tmpi1->ic_flags;223 OptSetNOP1(tmpi1);224 return FBO1_INT;225 } else226 return FBO1_NOT_CONST;227}228 229extern CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi);230 231CIntermediateCode *OptBrZero(CCmpCtrl *cc,CIntermediateCode *tmpi)232{233 CCodeMisc *lb_true,*lb_false;234 CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;235 switch (tmpii->ic_code) {236 case IC_NOT:237 tmpi->ic_code=IC_BR_NOT_ZERO;238 tmpi->ic_class=tmpii->ic_class;239 tmpi->ic_flags|=tmpii->ic_flags;240 tmpi->t.arg1_class=tmpii->t.arg1_class;241 tmpi->t.arg1_tree=tmpii->t.arg1_tree;242 OptFree(tmpii);243 return OptBrNotZero(cc,tmpi);244 case IC_EQU_EQU...IC_LESS_EQU:245 tmpi->ic_code=(tmpii->ic_code-IC_EQU_EQU)^1+IC_BR_EQU_EQU;246 break;247 case IC_OR_OR:248 tmpi->ic_code=IC_BR_OR_OR_ZERO;249 break;250 case IC_AND_AND:251 tmpi->ic_code=IC_BR_AND_AND_ZERO;252 break;253 case IC_AND:254 tmpi->ic_code=IC_BR_AND_ZERO;255 break;256 case IC_MM_:257 if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&258 tmpii->ic_class->raw_type!=RT_F64)259 tmpi->ic_code=IC_BR_MM_ZERO;260 break;261 case IC_CALL_END:262 tmpii2=OptLag(tmpii);263 switch (tmpii2->ic_code) {264 start:265 case IC_CARRY:266 tmpii2->ic_code=IC_BR_NOT_CARRY;267 break;268 case IC_BT:269 tmpii2->ic_code=IC_BR_NOT_BT;270 break;271 case IC_LBTS:272 tmpii2->ic_flags|=ICF_LOCK;273 case IC_BTS:274 tmpii2->ic_code=IC_BR_NOT_BTS;275 break;276 case IC_LBTR:277 tmpii2->ic_flags|=ICF_LOCK;278 case IC_BTR:279 tmpii2->ic_code=IC_BR_NOT_BTR;280 break;281 case IC_LBTC:282 tmpii2->ic_flags|=ICF_LOCK;283 case IC_BTC:284 tmpii2->ic_code=IC_BR_NOT_BTC;285 break;286 end:287 tmpii2->ic_data=tmpi->ic_data;288 tmpii->ic_code=IC_CALL_END2;289 OptSetNOP1(tmpi);290 return tmpii;291 }292 break;293 }294 if (tmpi->ic_code!=IC_BR_ZERO) {295 tmpi->ic_class=tmpii->ic_class;296 tmpi->ic_flags|=tmpii->ic_flags;297 tmpi->t.arg1_class=tmpii->t.arg1_class;298 tmpi->t.arg2_class=tmpii->t.arg2_class;299 tmpi->t.arg1_tree=tmpii->t.arg1_tree;300 tmpi->t.arg2_tree=tmpii->t.arg2_tree;301 OptFree(tmpii);302 303 if (tmpi->ic_flags&ICF_PUSH_CMP &&304 IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&305 !(tmpi->ic_flags&ICF_USE_F64)) {306 tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;307 tmpi->ic_flags&=~ICF_PUSH_CMP;308 tmpii=tmpi->next; //IC_PUSH_CMP inst309 while (tmpii->ic_code!=IC_PUSH_CMP)310 tmpii=tmpii->next;311 tmpii->t.arg1_tree=tmpi;312 OptSetNOP1(tmpii);313 }314 315 lb_true=tmpi->ic_data;316 if (tmpi->ic_code==IC_BR_AND_AND_ZERO) {317 tmpii=tmpi->t.arg1_tree->next;318 tmpii->ic_data=lb_true;319 tmpii->t.arg1_tree=tmpi->t.arg1_tree;320 tmpii->t.arg1_class=tmpi->t.arg1_class;321 tmpii->ic_code=IC_BR_ZERO;322 OptBrZero(cc,tmpii);323 tmpii=tmpi->t.arg2_tree->next;324 tmpii->t.arg1_tree=tmpi->t.arg2_tree;325 tmpii->t.arg1_class=tmpi->t.arg2_class;326 tmpii->ic_data=lb_true;327 tmpii->ic_code=IC_BR_ZERO;328 tmpii=OptBrZero(cc,tmpii);329 OptSetNOP1(tmpi);330 } else if (tmpi->ic_code==IC_BR_OR_OR_ZERO) {331 lb_false=COCMiscNew(cc,CMT_LABEL);332 tmpi->ic_code=IC_LABEL;333 tmpi->ic_flags=0;334 tmpi->ic_data=lb_false;335 tmpii=tmpi->t.arg1_tree->next;336 tmpii->t.arg1_tree=tmpi->t.arg1_tree;337 tmpii->t.arg1_class=tmpi->t.arg1_class;338 tmpii->ic_data=lb_false;339 tmpii->ic_code=IC_BR_NOT_ZERO;340 OptBrNotZero(cc,tmpii);341 tmpii=tmpi->t.arg2_tree->next;342 tmpii->t.arg1_tree=tmpi->t.arg2_tree;343 tmpii->t.arg1_class=tmpi->t.arg2_class;344 tmpii->ic_data=lb_true;345 tmpii->ic_code=IC_BR_ZERO;346 tmpii=OptBrZero(cc,tmpii);347 } else348 tmpii=tmpi;349 if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {350 tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;351 tmpi->ic_flags&=~ICF_POP_CMP;352 }353 return tmpii;354 }355 return tmpi;356}357 358CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi)359{360 CCodeMisc *lb_true,*lb_false;361 CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;362 switch (tmpii->ic_code) {363 case IC_NOT:364 tmpi->ic_code=IC_BR_ZERO;365 tmpi->ic_class=tmpii->ic_class;366 tmpi->ic_flags|=tmpii->ic_flags;367 tmpi->t.arg1_class=tmpii->t.arg1_class;368 tmpi->t.arg1_tree=tmpii->t.arg1_tree;369 OptFree(tmpii);370 return OptBrZero(cc,tmpi);371 case IC_EQU_EQU...IC_LESS_EQU:372 tmpi->ic_code=tmpii->ic_code+IC_BR_EQU_EQU-IC_EQU_EQU;373 break;374 case IC_OR_OR:375 tmpi->ic_code=IC_BR_OR_OR_NOT_ZERO;376 break;377 case IC_AND_AND:378 tmpi->ic_code=IC_BR_AND_AND_NOT_ZERO;379 break;380 case IC_AND:381 tmpi->ic_code=IC_BR_AND_NOT_ZERO;382 break;383 case IC_MM_:384 if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&385 tmpii->ic_class->raw_type!=RT_F64)386 tmpi->ic_code=IC_BR_MM_NOT_ZERO;387 break;388 case IC_CALL_END:389 tmpii2=OptLag(tmpii);390 switch (tmpii2->ic_code) {391 start:392 case IC_CARRY:393 tmpii2->ic_code=IC_BR_CARRY;394 break;395 case IC_BT:396 tmpii2->ic_code=IC_BR_BT;397 break;398 case IC_LBTS:399 tmpii2->ic_flags|=ICF_LOCK;400 case IC_BTS:401 tmpii2->ic_code=IC_BR_BTS;402 break;403 case IC_LBTR:404 tmpii2->ic_flags|=ICF_LOCK;405 case IC_BTR:406 tmpii2->ic_code=IC_BR_BTR;407 break;408 case IC_LBTC:409 tmpii2->ic_flags|=ICF_LOCK;410 case IC_BTC:411 tmpii2->ic_code=IC_BR_BTC;412 break;413 end:414 tmpii2->ic_data=tmpi->ic_data;415 tmpii->ic_code=IC_CALL_END2;416 OptSetNOP1(tmpi);417 return tmpii;418 }419 break;420 }421 if (tmpi->ic_code!=IC_BR_NOT_ZERO) {422 tmpi->ic_class=tmpii->ic_class;423 tmpi->ic_flags|=tmpii->ic_flags;424 tmpi->t.arg1_class=tmpii->t.arg1_class;425 tmpi->t.arg2_class=tmpii->t.arg2_class;426 tmpi->t.arg1_tree=tmpii->t.arg1_tree;427 tmpi->t.arg2_tree=tmpii->t.arg2_tree;428 OptFree(tmpii);429 430 if (tmpi->ic_flags&ICF_PUSH_CMP &&431 IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&432 !(tmpi->ic_flags&ICF_USE_F64)) {433 tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;434 tmpi->ic_flags&=~ICF_PUSH_CMP;435 tmpii=tmpi->next; //IC_PUSH_CMP inst436 while (tmpii->ic_code!=IC_PUSH_CMP)437 tmpii=tmpii->next;438 tmpii->t.arg1_tree=tmpi;439 OptSetNOP1(tmpii);440 }441 442 lb_true=tmpi->ic_data;443 if (tmpi->ic_code==IC_BR_OR_OR_NOT_ZERO) {444 tmpii=tmpi->t.arg1_tree->next;445 tmpii->t.arg1_tree=tmpi->t.arg1_tree;446 tmpii->t.arg1_class=tmpi->t.arg1_class;447 tmpii->ic_data=lb_true;448 tmpii->ic_code=IC_BR_NOT_ZERO;449 OptBrNotZero(cc,tmpii);450 tmpii=tmpi->t.arg2_tree->next;451 tmpii->t.arg1_tree=tmpi->t.arg2_tree;452 tmpii->t.arg1_class=tmpi->t.arg2_class;453 tmpii->ic_data=lb_true;454 tmpii->ic_code=IC_BR_NOT_ZERO;455 tmpii=OptBrNotZero(cc,tmpii);456 OptSetNOP1(tmpi);457 } else if (tmpi->ic_code==IC_BR_AND_AND_NOT_ZERO) {458 lb_false=COCMiscNew(cc,CMT_LABEL);459 tmpi->ic_code=IC_LABEL;460 tmpi->ic_flags=0;461 tmpi->ic_data=lb_false;462 tmpii=tmpi->t.arg1_tree->next;463 tmpii->t.arg1_tree=tmpi->t.arg1_tree;464 tmpii->t.arg1_class=tmpi->t.arg1_class;465 tmpii->ic_data=lb_false;466 tmpii->ic_code=IC_BR_ZERO;467 OptBrZero(cc,tmpii);468 tmpii=tmpi->t.arg2_tree->next;469 tmpii->t.arg1_tree=tmpi->t.arg2_tree;470 tmpii->t.arg1_class=tmpi->t.arg2_class;471 tmpii->ic_data=lb_true;472 tmpii->ic_code=IC_BR_NOT_ZERO;473 tmpii=OptBrNotZero(cc,tmpii);474 } else475 tmpii=tmpi;476 if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {477 tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;478 tmpi->ic_flags&=~ICF_POP_CMP;479 }480 return tmpii;481 }482 return tmpi;483}484 485U0 OptFixSizeOf(CIntermediateCode *tmpi1,486 CIntermediateCode *tmpi_push,CHashClass *tmpcc)487{488 if (tmpi1->ic_code==IC_MUL && tmpi1->t.arg2_tree->ic_code==IC_SIZEOF) {489 tmpi1->t.arg2_tree->ic_code=IC_IMM_I64;490 tmpi1->t.arg2_tree->ic_class=tmpcc;491 tmpi_push->ic_class=tmpcc;492 if (tmpcc->ptr_stars_cnt) {493 tmpcc--;494 if (tmpcc->size==1)495 goto here;496 tmpi1->t.arg2_tree->ic_data=tmpcc->size;497 } else {498here:499 if (tmpi_push==tmpi1)500 tmpi1->t.arg2_tree->ic_data=1;501 else {502 OptSetNOP1(tmpi1->t.arg2_tree);503 OptSetNOP1(tmpi1);504 }505 }506 }507}508 509I64 CmpRawType(CHashClass *tmpc)510{511 if (tmpc) {512 tmpc=OptClassFwd(tmpc);513 return tmpc->raw_type;514 }515 return 0;516}517 518I64 CmpRawTypePointed(CHashClass *tmpc)519{520 if (tmpc) {521 if (tmpc->ptr_stars_cnt)522 tmpc--;523 tmpc=OptClassFwd(tmpc);524 return tmpc->raw_type;525 }526 return 0;527}528 529U0 CmpMinTypePointed(CIntermediateCode *tmpi,I64 pt1)530{531 I64 pt;532 if ((pt=tmpi->arg1_type_pointed_to) && pt!=RT_F64 && 0<pt1<pt)533 tmpi->arg1_type_pointed_to=pt;534}535 536U0 CmpF1PushPop(CIntermediateCode *tmpi,CIntermediateCode *tmpi2)537{538 if (intermediate_code_table[tmpi2->ic_code].fpop||539 tmpi2->ic_flags&ICF_RES_TO_F64)540 Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);541}542 543U0 CmpF2PushPop(CIntermediateCode *tmpi,544 CIntermediateCode *tmpi1,CIntermediateCode *tmpi2)545{546 if ((tmpi2->ic_code==IC_MOV || tmpi2->ic_code==IC_IMM_F64) &&547 !(tmpi2->ic_flags&ICF_RES_TO_F64) &&548 (intermediate_code_table[tmpi1->ic_code].fpop ||549 tmpi1->ic_flags&ICF_RES_TO_F64))550 Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);551 else if ((intermediate_code_table[tmpi2->ic_code].fpop ||552 tmpi2->ic_flags&ICF_RES_TO_F64)&&553 !(tmpi1->ic_flags&ICF_RES_TO_F64))554 Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);555}556 557class COptMemberVar558{559 I64 score,offset_start,offset_end,lea_balance;560 CMemberLst *m;561};562 563I64 OptMVCompare(COptMemberVar *mv1,COptMemberVar *mv2)564{565 return mv2->score-mv1->score;566}567 