hschumann2/TempleOS-Source-Code
0847
1 2/*Intermediate Code to Machine Code3 4RAX,RBX,RCX and RDX can be clobbered by5each intermediate code's output code.6However, intermediate codes must be7coupled together based on the arg and8res type specifications in the9CICArg. RAX is the most common reg10for coupling intermediate codes.11 12Internal calculations take place on1364-bit vals, so anything which has14found it's way into a reg has been15sign or zero extended to 64-bits.16*/17 18U0 ICU8(CIntermediateCode *tmpi,U8 b)19{20 tmpi->ic_body[tmpi->ic_cnt++]=b;21}22 23U0 ICRex(CIntermediateCode *tmpi,U8 b)24{25 if (b)26 tmpi->ic_body[tmpi->ic_cnt++]=b;27}28 29U0 ICOpSizeRex(CIntermediateCode *tmpi,U8 b)30{31 tmpi->ic_body[tmpi->ic_cnt++]=OC_OP_SIZE_PREFIX;32 if (b)33 tmpi->ic_body[tmpi->ic_cnt++]=b;34}35 36U0 ICU16(CIntermediateCode *tmpi,U16 w)37{38 *(&tmpi->ic_body[tmpi->ic_cnt])(U16)=w;39 tmpi->ic_cnt+=2;40}41 42U0 ICU24(CIntermediateCode *tmpi,U32 d)43{//Writes extra harmless overhanging byte.44 *(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;45 tmpi->ic_cnt+=3;46}47 48U0 ICU32(CIntermediateCode *tmpi,U32 d)49{50 *(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;51 tmpi->ic_cnt+=4;52}53 54U0 ICU64(CIntermediateCode *tmpi,U64 q)55{56 *(&tmpi->ic_body[tmpi->ic_cnt])(U64)=q;57 tmpi->ic_cnt+=8;58}59 60U0 ICAddRSP(CIntermediateCode *tmpi,I64 i,Bool optimize=TRUE)61{62 I64 j,last_start;63 CIntermediateCode *tmpil1;64 if (optimize) {65 tmpil1=tmpi;66 if (tmpi->ic_last_start<0 && !tmpi->ic_cnt &&67 (tmpil1=OptLag1(tmpi)) && tmpil1->ic_last_start<0)68 tmpil1=NULL;69 if (tmpil1) {70 j=tmpil1->ic_cnt;71 if (tmpil1->ic_last_start==j-4 && tmpil1->ic_body[j-3]==0x83 &&72 tmpil1->ic_body[j-4]==0x48) {73 if (tmpil1->ic_body[j-2]==0xEC)74 j=-tmpil1->ic_body[j-1](I8);75 else if (tmpil1->ic_body[j-2]==0xC4)76 j=tmpil1->ic_body[j-1](I8);77 else78 j=0;79 } else if (tmpil1->ic_last_start==j-7 && tmpil1->ic_body[j-6]==0x81 &&80 tmpil1->ic_body[j-7]==0x48) {81 if (tmpil1->ic_body[j-5]==0xEC)82 j=-tmpil1->ic_body[j-4](I32);83 else if (tmpil1->ic_body[j-5]==0xC4)84 j=tmpil1->ic_body[j-4](I32);85 else86 j=0;87 } else88 j=0;89 if (j) {90 if (tmpi==tmpil1) {91 tmpi->ic_cnt=tmpi->ic_last_start;92 i+=j;93 } else if (!(tmpi->ic_flags&ICF_PREV_DELETED)) {94 tmpil1->ic_flags|=ICF_DEL_PREV_INS;95 tmpi->ic_flags=tmpi->ic_flags&~ICF_CODE_FINAL|ICF_PREV_DELETED;96 i+=j;97 }98 }99 }100 }101 last_start=tmpi->ic_cnt;102 if (i>0) {103 if (i<=I8_MAX)104 ICU32(tmpi,0xC48348+i<<24);105 else if (i<=I32_MAX) {106 ICU24(tmpi,0xC48148);107 ICU32(tmpi,i);108 } else109 throw('Compiler');110 } else if (i<0) {111 i=-i;112 if (i<=I8_MAX)113 ICU32(tmpi,0xEC8348+i<<24);114 else if (i<=I32_MAX) {115 ICU24(tmpi,0xEC8148);116 ICU32(tmpi,i);117 } else118 throw('Compiler');119 }120 if (optimize && tmpi->ic_cnt>last_start)121 tmpi->ic_last_start=last_start;122}123 124extern U0 ICMov(CIntermediateCode *tmpi,125 CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip);126 127#define MODR_REG 0128#define MODR_INDIRECT_REG 1129#define MODR_D8_INDIRECT_REG 2130#define MODR_D32_INDIRECT_REG 3131#define MODR_SIB_INDIRECT_REG 4132#define MODR_SIB_D8_INDIRECT_REG 5133#define MODR_SIB_D32_INDIRECT_REG 6134#define MODR_RIP_REL 7135#define MODR_RIP_REL_IMM_U32 8136 137I64 ICModr1(I64 r,CICType t2,I64 r2,I64 d2)138{//res.u8[0] is type139//res.u8[1] is REX140 //res.u8[2] is ModR141 //res.u8[3] is SIB142 I64 res=0;143 if (t2.raw_type<RT_I64)144 res.u8[1]=0x40;145 else146 res.u8[1]=0x48;147 if (r>7) {148 res.u8[1]+=4;149 r&=7;150 }151 switch (Bsr(t2)) {152 case MDf_REG:153 if (r2>7) {154 res.u8[1]++;155 r2&=7;156 }157 res.u8[2]=0xC0+r<<3+r2;158 res.u8[0]=MODR_REG;159 if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4 && r2<4))160 res.u8[1]=0;161 break;162 case MDf_DISP:163 if (r2>7) {164 res.u8[1]++;165 r2&=7;166 }167 if (!d2 && r2!=REG_RBP) {168 res.u8[2]=r<<3+r2;169 res.u8[0]=MODR_INDIRECT_REG;170 } else if (I8_MIN<=d2<=I8_MAX) {171 res.u8[2]=0x40+r<<3+r2;172 res.u8[0]=MODR_D8_INDIRECT_REG;173 } else {174 res.u8[2]=0x80+r<<3+r2;175 res.u8[0]=MODR_D32_INDIRECT_REG;176 }177 if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))178 res.u8[1]=0;179 break;180 case MDf_SIB:181 if (7<r2.u8[0]<REG_NONE)182 res.u8[1]++;183 if (r2.u8[1]&15>7)184 res.u8[1]+=2;185 if (r2.u8[0]==REG_NONE) {186 res.u8[3]=5+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;187 res.u8[2]=4+r<<3;188 res.u8[0]=MODR_SIB_D32_INDIRECT_REG;189 } else {190 res.u8[3]=r2.u8[0]&7+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;191 if (!d2 && r2.u8[0]&7!=REG_RBP) {192 res.u8[2]=4+r<<3;193 res.u8[0]=MODR_SIB_INDIRECT_REG;194 } else if (I8_MIN<=d2<=I8_MAX) {195 res.u8[2]=0x44+r<<3;196 res.u8[0]=MODR_SIB_D8_INDIRECT_REG;197 } else {198 res.u8[2]=0x84+r<<3;199 res.u8[0]=MODR_SIB_D32_INDIRECT_REG;200 }201 }202 if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))203 res.u8[1]=0;204 break;205 case MDf_RIP_DISP32:206 res.u8[2]=0x05+r<<3;207 res.u8[0]=MODR_RIP_REL;208 if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))209 res.u8[1]=0;210 break;211 }212 return res;213}214 215U0 ICModr2(CIntermediateCode *tmpi,I64 i,CICType t=0,I64 d,I64 rip=0)216{217 switch [i.u8[0]] {218 case MODR_REG:219 break;220 case MODR_INDIRECT_REG:221 break;222 case MODR_D8_INDIRECT_REG:223 ICU8(tmpi,d);224 break;225 case MODR_D32_INDIRECT_REG:226 ICU32(tmpi,d);227 break;228 case MODR_SIB_INDIRECT_REG:229 ICU8(tmpi,i.u8[3]);230 break;231 case MODR_SIB_D8_INDIRECT_REG:232 ICU8(tmpi,i.u8[3]);233 ICU8(tmpi,d);234 break;235 case MODR_SIB_D32_INDIRECT_REG:236 ICU8(tmpi,i.u8[3]);237 ICU32(tmpi,d);238 break;239 case MODR_RIP_REL_IMM_U32:240 switch (t.raw_type) {241 case RT_I8:242 case RT_U8:243 d--;244 break;245 case RT_I16:246 case RT_U16:247 d-=2;248 break;249 default:250 d-=4;251 }252 case MODR_RIP_REL:253 ICU32(tmpi,d-(rip+4+tmpi->ic_cnt));254 tmpi->ic_flags&=~ICF_CODE_FINAL;255 break;256 }257}258 259#define SLASH_OP_INC 0x0003000000FFFE00260#define SLASH_OP_DEC 0x052B000000FFFE01261#define SLASH_OP_NOT 0x0000000000F7F602262#define SLASH_OP_NEG 0x0000000000F7F603263#define SLASH_OP_IMM_U8 0x0000000000838000264#define SLASH_OP_IMM_U32 0x0000000000818300265#define SLASH_OP_MUL 0x0000000000F7F604266#define SLASH_OP_IMUL 0x0000000000F7F605267#define SLASH_OP_DIV 0x0000000000F7F606268#define SLASH_OP_MOV 0x0000000000898800269#define SLASH_OP_MOV_IMM 0x0000000000C7C600270#define SLASH_OP_PUSH 0x0000000000FFFF06271#define SLASH_OP_POP 0x00000000008F8F00272#define SLASH_OP_FADD 0x0000C1DE01DCDC00273#define SLASH_OP_FSUB 0x0000E9DE01DCDC04274#define SLASH_OP_FSUBR 0x0000E1DE01DCDC05275#define SLASH_OP_FMUL 0x0000C9DE01DCDC01276#define SLASH_OP_FDIV 0x0000F9DE01DCDC06277#define SLASH_OP_FDIVR 0x0000F1DE01DCDC07278#define SLASH_OP_FLD 0x0000000001DDDD00279#define SLASH_OP_FSTP 0x0000000001DDDD03280#define SLASH_OP_FISTTP 0x0000000001DDDD01281#define SLASH_OP_FILD 0x0000000001DFDF05282 283U0 ICSlashOp(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 op,I64 rip)284{285 I64 i;286 if (t1&MDF_REG && !op.u8[3])287 t1=t1&(MDG_MASK|RTF_UNSIGNED)+RT_I64; //Set to 64 bit,preserving unsigned288 i=ICModr1(op.u8[0],t1,r1,d1);289 if (tmpi->ic_flags&ICF_LOCK && !(t1&MDF_REG) &&290 op&~7!=SLASH_OP_MOV && op!=SLASH_OP_MOV_IMM)291 ICU8(tmpi,OC_LOCK_PREFIX);292 switch (t1.raw_type) {293 case RT_I8:294 case RT_U8:295 ICRex(tmpi,i.u8[1]);296 ICU16(tmpi,i.u8[2]<<8+op.u8[1]);297 break;298 case RT_I16:299 case RT_U16:300 ICOpSizeRex(tmpi,i.u8[1]);301 ICU16(tmpi,i.u8[2]<<8+op.u8[2]);302 break;303 default:304 if (i.u8[1]!=0x48 || !op.u8[3])305 ICRex(tmpi,i.u8[1]);306 ICU16(tmpi,i.u8[2]<<8+op.u8[2]);307 }308 if (i.u8[0]==MODR_RIP_REL&& (op==SLASH_OP_MOV_IMM || op&~7==SLASH_OP_IMM_U32))309 i.u8[0]=MODR_RIP_REL_IMM_U32;310 ICModr2(tmpi,i,t1,d1,rip);311}312 313U0 ICPush(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)314{315 switch (Bsr(t1)) {316 case MDf_REG:317 if (r1>7)318 ICU16(tmpi,0x5049+(r1&7)<<8);319 else320 ICU8(tmpi,0x50+r1);321 return;322 case MDf_IMM:323 if (I8_MIN<=d1<=I8_MAX)324 ICU16(tmpi,0x6A+d1<<8);325 else if (I32_MIN<=d1<=I32_MAX) {326 ICU8(tmpi,0x68);327 ICU32(tmpi,d1);328 } else {329 ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);330 ICU8(tmpi,0x50+REG_RBX);331 }332 return;333 case MDf_STK:334 return;335 case MDf_DISP:336 case MDf_SIB:337 case MDf_RIP_DISP32:338 switch (t1.raw_type) {339 case RT_I64:340 case RT_U64:341 case RT_F64:342 ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_PUSH,rip);343 return;344 }345 break;346 }347 ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);348 ICU16(tmpi,0x5048+REG_RBX<<8);349}350 351U0 ICPushRegs(CIntermediateCode *tmpi,I64 mask)352{353 I64 i;354 for (i=0;i<REG_REGS_NUM;i++) {355 if (Bt(&mask,i)) {356 if (i>7)357 ICU16(tmpi,0x5049+(i&7)<<8);358 else359 ICU8(tmpi,0x50+i);360 }361 }362}363 364U0 ICPop(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)365{366 switch (Bsr(t1)) {367 case MDf_REG:368 if (r1>7)369 ICU16(tmpi,0x5849+(r1&7)<<8);370 else371 ICU8(tmpi,0x58+r1);372 break;373 case MDf_DISP:374 case MDf_RIP_DISP32:375 case MDf_SIB:376 if (t1.raw_type<RT_I64) {377 ICU8(tmpi,0x58+REG_RBX);378 ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);379 } else380 ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_POP,rip);381 break;382 case MDf_STK:383 case MDf_IMM:384 ICU8(tmpi,0x58+REG_RBX);385 ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);386 break;387 default:388 ICAddRSP(tmpi,8);389 }390}391 392U0 ICPopRegs(CIntermediateCode *tmpi,I64 mask)393{394 I64 i;395 for (i=REG_REGS_NUM-1;i>=0;i--) {396 if (Bt(&mask,i)) {397 if (i>7)398 ICU16(tmpi,0x5849+(i&7)<<8);399 else400 ICU8(tmpi,0x58+i);401 }402 }403}404 405U0 ICZero(CIntermediateCode *tmpi,I64 r)406{407 if (r>7) {408 r&=7;409 ICU24(tmpi,0xC0334D+r<<16+r<<19);410 } else411 ICU16(tmpi,0xC033+r<<8+r<<11);412}413 414U0 ICTest(CIntermediateCode *tmpi,I64 r)415{416 I64 i=0xC08548; //TEST R,R417 if (r>7) {418 i+=5;419 r&=7;420 }421 ICU24(tmpi,i+r<<16+r<<19);422}423 424I64 ICBuiltInFloatConst(F64 d)425{//Returns 2-byte opcode for FLD const or zero426 if (!d)427 return 0xEED9;428 else if (d==1.0)429 return 0xE8D9;430 else if (GetOption(OPTf_NO_BUILTIN_CONST))431 return 0;432 else if (d==pi)433 return 0xEBD9;434 else if (d==log2_10)435 return 0xE9D9;436 else if (d==log2_e)437 return 0xEAD9;438 else if (d==log10_2)439 return 0xECD9;440 else if (d==loge_2)441 return 0xEDD9;442 else443 return 0;444}445 446U0 ICMov(CIntermediateCode *tmpi,447 CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip)448{449 I64 i,cnt1,cnt2,b1_rex,b2_rex,b1,b2,b1_modr,b2_modr,450 b1_r1,b1_r2,b2_r1,b2_r2,last_start=tmpi->ic_cnt;451 CIntermediateCode *tmpil1;452 Bool old_lock=Btr(&tmpi->ic_flags,ICf_LOCK);453 switch (Bsr(t1)) {454 case MDf_REG:455 if (t2&MDF_IMM) {456 if (!d2)457 ICZero(tmpi,r1);458 else if (0<=d2<=U8_MAX) {459 ICZero(tmpi,r1);460 if (r1>7)461 ICU24(tmpi,d2<<16+(0xB0+r1&7)<<8+0x41);462 else if (r1>3)463 ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);464 else465 ICU16(tmpi,d2<<8+0xB0+r1);466 } else if (I8_MIN<=d2<0) {467 if (r1>7) {468 r1&=7;469 ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x41);470 ICU32(tmpi,0xC0BE0F4D+r1<<24+r1<<27);471 } else {472 if (r1>3)473 ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);474 else475 ICU16(tmpi,d2<<8+0xB0+r1);476 ICU32(tmpi,0xC0BE0F48+r1<<24+r1<<27);477 }478 } else if (0<=d2<=U32_MAX) {479 if (r1>7) {480 r1&=7;481 ICU16(tmpi,(0xB8+r1)<<8+0x41);482 ICU32(tmpi,d2);483 } else {484 ICU8(tmpi,0xB8+r1);485 ICU32(tmpi,d2);486 }487 } else if (I32_MIN<=d2<0) {488 if (r1>7) {489 r1&=7;490 ICU16(tmpi,(0xB8+r1)<<8+0x41);491 ICU32(tmpi,d2);492 ICU24(tmpi,0xC0634D+r1<<16+r1<<19);493 } else {494 ICU8(tmpi,0xB8+r1);495 ICU32(tmpi,d2);496 ICU24(tmpi,0xC06348+r1<<16+r1<<19);497 }498 } else {499 i=0xB848;500 if (r1>7) {501 i++;502 r1&=7;503 }504 ICU16(tmpi,i+r1<<8);505 ICU64(tmpi,d2);506 }507 } else if (t2&MDF_STK)508 ICPop(tmpi,t1,r1,d1,rip);509 else {510 if (r1==r2 && t2&MDF_REG)511 goto move_done;512 if (t2&MDF_REG)513 t2=MDF_REG+RT_I64;514 i=ICModr1(r1,t2,r2,d2);515 if (t2.raw_type!=RT_U32)516 i|=0x4800;517 ICRex(tmpi,i.u8[1]);518 switch (t2.raw_type) {519 case RT_I8:520 ICU24(tmpi,i.u8[2]<<16+0xBE0F);521 break;522 case RT_I16:523 ICU24(tmpi,i.u8[2]<<16+0xBF0F);524 break;525 case RT_I32:526 ICU16(tmpi,i.u8[2]<<8+0x63);527 break;528 529 case RT_U8:530 ICU24(tmpi,i.u8[2]<<16+0xB60F);531 break;532 case RT_U16:533 ICU24(tmpi,i.u8[2]<<16+0xB70F);534 break;535 default:536 ICU16(tmpi,i.u8[2]<<8+0x8B);537 }538 ICModr2(tmpi,i,,d2,rip);539 }540 break;541 case MDf_STK:542 if (tmpi->ic_flags&ICF_PUSH_CMP)543 ICPopRegs(tmpi,1<<REG_RBX);544 if (t1.raw_type<t2.raw_type)545 ICPush(tmpi,t2&MDG_MASK+t1.raw_type,r2,d2,rip);546 else547 ICPush(tmpi,t2,r2,d2,rip);548 if (tmpi->ic_flags&ICF_PUSH_CMP)549 ICPushRegs(tmpi,1<<REG_RBX);550 break;551 case MDf_DISP:552 case MDf_RIP_DISP32:553 case MDf_SIB:554 if (t2&MDF_IMM && (t1.raw_type<RT_I64 || (I32_MIN<=d2<=I32_MAX))) {555 ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_MOV_IMM,rip);556 switch (t1.raw_type) {557 case RT_I8:558 case RT_U8:559 ICU8(tmpi,d2);560 break;561 case RT_I16:562 case RT_U16:563 ICU16(tmpi,d2);564 break;565 default:566 ICU32(tmpi,d2);567 }568 } else {569 if (t2&MDF_REG)570 ICSlashOp(tmpi,t1,r1,d1,r2+SLASH_OP_MOV,rip);571 else {572 ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t2,r2,d2,rip);573 ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);574 }575 }576 break;577 }578move_done:579 if (!((t1|t2)&(MDF_STK|MDF_RIP_DISP32))) {580 tmpil1=tmpi;581 if (tmpi->ic_last_start<0 && (tmpil1=OptLag1(tmpi)) &&582 tmpil1->ic_last_start<0)583 tmpil1=NULL;584 if (tmpil1) {585 if (tmpil1==tmpi)586 cnt1=last_start-tmpil1->ic_last_start;587 else {588 if (!(tmpil1->ic_flags&ICF_CODE_FINAL))589 tmpi->ic_flags&=~ICF_CODE_FINAL;590 if (last_start)591 cnt1=0;592 else593 cnt1=tmpil1->ic_cnt-tmpil1->ic_last_start;594 }595 cnt2=tmpi->ic_cnt-last_start;596 if (cnt1 && cnt1==cnt2) {597 b1_rex=tmpil1->ic_body[tmpil1->ic_last_start];598 b2_rex=tmpi->ic_body[last_start];599 if (b1_rex&0x48==0x48 && b2_rex&0x48==0x48) {600 for (i=1;i<cnt1;i++)601 if ((b1=tmpil1->ic_body[tmpil1->ic_last_start+i])==602 (b2=tmpi->ic_body[last_start+i])) {603 if (i==1 && (b2==0x89 || b2==0x8B)) {604 b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];605 b1_r1=b1_modr&7 +Bt(&b1_rex,0)<<3;606 b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;607 b2_modr=tmpi->ic_body[last_start+2];608 b2_r1=b2_modr&7 +Bt(&b2_rex,0)<<3;609 b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;610 if (cnt1==3 && b2_modr&0xC0==0xC0) {611 if (b2_r1==b2_r2)612 goto move_redundant;613 if (b1_modr&0xC0==0xC0) {614 if (b1_r1==b2_r2 && b2_r1==b1_r2)615 goto move_redundant;616 }617 } else if (b1_rex!=b2_rex || b1_r1==b1_r2 || (t1|t2)&MDF_SIB)618 break;619 } else if (b1_rex!=b2_rex)620 break;621 } else if (i!=1)622 break;623 else if (b2!=0x89 && b2!=0x8B)624 break;625 else {626 b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];627 b1_r1=b1_modr&7 +Bt(&b1_rex,0)<<3;628 b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;629 b2_modr=tmpi->ic_body[last_start+2];630 b2_r1=b2_modr&7 +Bt(&b2_rex,0)<<3;631 b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;632 if (cnt1==3 && b2_modr&0xC0==0xC0) {633 if (b2_r1==b2_r2)634 goto move_redundant;635 if (b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89) {636 if (b1_modr&0xC0==0xC0) {637 if (b1_r1==b2_r1 && b1_r2==b2_r2 ||638 b1_r1==b2_r2 && b2_r1==b1_r2)639 goto move_redundant;640 }641 if (b1_rex!=b2_rex)642 break;643 } else644 break;645 } else if (b1_r1==b1_r2 || (t1|t2)&MDF_SIB || b1_rex!=b2_rex ||646 !(b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89))647 break;648 }649 if (i==cnt1) {650move_redundant:651 tmpi->ic_cnt=last_start;652 }653 }654 }655 }656 }657 if (tmpi->ic_cnt>last_start>tmpi->ic_last_start)658 tmpi->ic_last_start=last_start;659 BEqu(&tmpi->ic_flags,ICf_LOCK,old_lock);660}661 662U0 ICLea(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,663 CICType t2,I64 r2,I64 d2,CCmpCtrl *cc,U8 *buf,I64 rip)664{665 I64 i;666 CAOTAbsAddr *tmpa;667 switch (Bsr(t1)) {668 case MDf_REG:669 i=ICModr1(r1,t2,r2,d2);670 i.u8[1]|=0x48;671 ICU24(tmpi,i.u8[2]<<16+0x8D00+i.u8[1]);672 ICModr2(tmpi,i,,d2,rip);673 break;674 case MDf_STK:675 if (t2&MDF_RIP_DISP32) {676 ICU8(tmpi,0x68);677 ICU32(tmpi,d2);678 if (cc->flags&CCF_AOT_COMPILE && buf && !(cc->flags&CCF_NO_ABSS)) {679 tmpa=CAlloc(sizeof(CAOTAbsAddr));680 tmpa->next=cc->aotc->abss;681 tmpa->type=AAT_ADD_U32;682 cc->aotc->abss=tmpa;683 tmpa->rip=rip+tmpi->ic_cnt-4;684 }685 tmpi->ic_flags&=~ICF_CODE_FINAL;686 break;687 } // Fall thru688 default:689 ICLea(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,cc,buf,rip);690 ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RCX,0,rip);691 }692}693 694U0 ICDeref(CIntermediateCode *tmpi,I64 rip)695{696 CICType t;697 t=tmpi->res.type.raw_type;698 if (t>tmpi->arg1_type_pointed_to)699 t=tmpi->arg1_type_pointed_to;700 if (tmpi->arg1.type&MDF_REG)701 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,702 MDF_DISP+t,tmpi->arg1.reg,tmpi->arg1.disp,rip);703 else {704 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,705 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);706 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,707 MDF_DISP+t,REG_RCX,0,rip);708 }709}710 