Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes847downloads
BackLib.txt710 linesDownload Raw Back to Compiler
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