CoolFace
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes838downloads
BackC.txt773 linesDownload Raw Back to Compiler
1 2U0 ICAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)3{4  U64 i;5  I64 it,t1,r1,d1,r2;6  Bool short_jmp,swap,override;7  CCodeMisc *lb;8  CICArg *arg1,*arg2;9 10  if (tmpi->arg1.type&MDF_IMM) {11    swap=TRUE;12    arg1=&tmpi->arg2;13    arg2=&tmpi->arg1;14  } else {15    swap=FALSE;16    arg1=&tmpi->arg1;17    arg2=&tmpi->arg2;18  }19 20  if (arg2->type&MDF_IMM && arg2->disp>U32_MAX)21    override=TRUE;22  else23    override=FALSE;24 25  if (arg1->type.raw_type<arg2->type.raw_type)26    it=arg1->type.raw_type;27  else28    it=arg2->type.raw_type;29 30  i=arg2->disp;31  if (arg2->type&MDF_IMM && i<=U32_MAX) {32    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,arg1->reg,arg1->disp,rip2);33    if (i<=U8_MAX)34      ICU16(tmpi,i<<8+0xA8);35    else if (i<=U16_MAX)36      ICU32(tmpi,i<<16+0xA900+OC_OP_SIZE_PREFIX);37    else {38      ICU8(tmpi,0xA9);39      ICU32(tmpi,i);40    }41  } else {42    t1=MDF_REG+it;43    d1=0;44    if (swap && !override) {45      if (arg1->type&MDF_REG) {46        r1=arg1->reg;47        swap=TRUE;48      } else {49        r1=REG_RCX;50        swap=FALSE;51      }52      if (arg2->type&MDF_REG) {53        r2=arg2->reg;54        swap=FALSE;55      } else56        r2=REG_RDX;57      if (swap) {58        if (!(arg1->type&MDF_REG) || r1!=arg1->reg)59          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);60        if (arg2->type&MDG_REG_DISP_SIB_RIP) {61          t1=arg2->type&MDG_MASK+it;62          r2=arg2->reg;63          d1=arg2->disp;64        } else65          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);66        i=ICModr1(r1,t1,r2,d1);67      } else {68        if (arg1->type&MDG_REG_DISP_SIB_RIP) {69          t1=arg1->type&MDG_MASK+it;70          r1=arg1->reg;71          d1=arg1->disp;72        } else73          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);74        if (!(arg2->type&MDF_REG) || r2!=arg2->reg)75          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);76        i=ICModr1(r2,t1,r1,d1);77      }78    } else {79      if (arg2->type&MDF_REG) {80        r2=arg2->reg;81        swap=FALSE;82      } else {83        r2=REG_RDX;84        swap=TRUE;85      }86      if (arg1->type&MDF_REG) {87        r1=arg1->reg;88        swap=TRUE;89      } else90        r1=REG_RCX;91      if (override)92        swap=FALSE;93      if (swap) {94        if (arg2->type&MDG_REG_DISP_SIB_RIP) {95          t1=arg2->type&MDG_MASK+it;96          r2=arg2->reg;97          d1=arg2->disp;98        } else99          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);100        if (!(arg1->type&MDF_REG) || r1!=arg1->reg)101          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);102        i=ICModr1(r1,t1,r2,d1);103      } else {104        if (!(arg2->type&MDF_REG) || r2!=arg2->reg)105          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);106        if (arg1->type&MDG_REG_DISP_SIB_RIP) {107          t1=arg1->type&MDG_MASK+it;108          r1=arg1->reg;109          d1=arg1->disp;110        } else111          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);112        i=ICModr1(r2,t1,r1,d1);113      }114    }115    switch (it) {116      case RT_I8:117      case RT_U8:118        ICRex(tmpi,i.u8[1]);119        ICU16(tmpi,i.u8[2]<<8+0x84);120        break;121      case RT_U16:122      case RT_I16:123        ICOpSizeRex(tmpi,i.u8[1]);124        ICU16(tmpi,i.u8[2]<<8+0x85);125        break;126      default:127        ICRex(tmpi,i.u8[1]);128        ICU16(tmpi,i.u8[2]<<8+0x85);129    }130    ICModr2(tmpi,i,,d1,rip2);131  }132 133  rip+=tmpi->ic_cnt;134  lb=OptLabelFwd(tmpi->ic_data);135  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);136  if (!buf && lb->addr!=INVALID_PTR) {137    i=lb->addr-(rip+2);138    if (lb->flags&CMF_POP_CMP)139      i+=8;140    if (I8_MIN<=i<=I8_MAX)141      short_jmp=TRUE;142  }143 144  if (short_jmp) {145    tmpi->ic_flags|=ICF_SHORT_JMP;146    i=lb->addr-(rip+2);147    if (lb->flags&CMF_POP_CMP)148      i+=8;149    ICU16(tmpi,i<<8+is.u8[2]);150  } else {151    tmpi->ic_flags&=~ICF_SHORT_JMP;152    i=lb->addr-(rip+6);153    if (lb->flags&CMF_POP_CMP)154      i+=8;155    ICU16(tmpi,is.u16[0]);156    ICU32(tmpi,i);157  }158}159 160U0 ICAssign(CIntermediateCode *tmpi,I64 rip)161{162  CIntermediateCode *tmpi1;163  if (tmpi->ic_flags & ICF_BY_VAL) {164    ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,165          tmpi->arg1.reg,tmpi->arg1.disp,166          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);167    if (tmpi->res.type.mode)168      ICMov(tmpi,tmpi->res.type&MDG_MASK+tmpi->arg1_type_pointed_to,169            tmpi->res.reg,tmpi->res.disp,170            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,171            tmpi->arg1.reg,tmpi->arg1.disp,rip);172  } else {173    if (tmpi->arg1.type&MDF_REG) {174      if (!(tmpi1=OptLag1(tmpi)) || tmpi1->ic_code!=IC_ADD_CONST ||175            tmpi1->res.type!=MDF_REG+RT_I64 || tmpi1->res.reg!=tmpi->arg1.reg ||176            tmpi1->arg1.type!=MDF_REG+RT_I64 ||177            tmpi1->arg1.reg!=tmpi->arg1.reg ||178            (tmpi->arg2.type&MDF_REG || tmpi->arg2.type&MDF_DISP) &&179            tmpi->arg2.reg==tmpi->arg1.reg ||180            tmpi->res.type.mode || tmpi1->ic_flags&~ICG_NO_CVT_MASK) {181        ICMov(tmpi,182              MDF_DISP+tmpi->arg1_type_pointed_to,183              tmpi->arg1.reg,tmpi->arg1.disp,184              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);185        if (tmpi->res.type.mode)186          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,187                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);188      } else {189        tmpi->ic_flags=(tmpi->ic_flags|tmpi1->ic_flags)&190              ~ICF_CODE_FINAL|ICF_DONT_RESTORE;191        tmpi->arg1.disp=tmpi1->ic_data;192        OptSetNOP1(tmpi1); //This better not be last pass!193        ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,194              tmpi->arg1.reg,tmpi->arg1.disp,195              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);196      }197    } else {198      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,199            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);200      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,201            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);202      if (tmpi->res.type.mode)203        ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,204              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);205    }206  }207}208 209U0 ICBrBitOps(CIntermediateCode *tmpi,I64 rip,210        I64 op,I64 op_imm,I64 is,U8 *buf,I64 rip2)211{212  I64 i,t,r1,r2,d1,d2,t1,t2;213  CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;214  Bool short_jmp;215  CCodeMisc *lb;216 217  if (tmpi->ic_flags & ICF_BY_VAL) {218    if (tmpi->ic_flags&ICF_SWAP && !(arg2->type&MDF_REG) &&219          (!(arg2->type&MDF_IMM) ||arg2->disp>63)||220          !(tmpi->ic_flags&ICF_SWAP) && arg2->type&MDF_IMM &&221          arg2->disp<64 || arg2->type&MDF_STK) {222      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);223      t2=MDF_REG+RT_I64;224      r2=REG_RCX;225      d2=0;226    } else {227      t2=arg2->type;228      if (t2&MDF_IMM && arg2->disp<64)229        r2=0;230      else231        r2=arg2->reg;232      d2=arg2->disp;233    }234    if (!(tmpi->ic_flags&ICF_SWAP) && !(arg1->type&MDF_REG) &&235          (!(arg1->type&MDF_IMM) || arg1->disp>63) ||236          tmpi->ic_flags&ICF_SWAP && arg1->type&MDF_IMM &&237          arg1->disp<64 || arg1->type&MDF_STK) {238      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);239      t1=MDF_REG+RT_I64;240      r1=REG_RDX;241      d1=0;242    } else {243      t1=arg1->type;244      if (t1&MDF_IMM && arg1->disp<64)245        r1=0;246      else247        r1=arg1->reg;248      d1=arg1->disp;249    }250  } else {251    t1=MDF_DISP+RT_I64;252    t2=MDF_DISP+RT_I64;253    d1=0;254    d2=0;255    if (arg2->type&MDF_REG)256      r2=arg2->reg;257    else if (!(tmpi->ic_flags&ICF_SWAP) || !(arg2->type&MDF_IMM) ||258          arg2->disp>63) {259      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);260      r2=REG_RCX;261    } else262      r2=0;263    if (arg1->type&MDF_REG)264      r1=arg1->reg;265    else if (tmpi->ic_flags&ICF_SWAP ||266          !(arg1->type&MDF_IMM) || arg1->disp>63) {267      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);268      r1=REG_RDX;269    } else270      r1=0;271  }272  if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)273    ICU8(tmpi,OC_LOCK_PREFIX);274  if (tmpi->ic_flags&ICF_SWAP) {275    if (arg2->type&MDF_IMM && arg2->disp<32) {276      if (op==0xA30F && arg2->disp<8) {277        t=t1&MDG_MASK+RT_U8;278        op_imm=0xF6; //TEST279      } else280        t=t1&MDG_MASK+RT_U32;281    } else282      t=t1;283    i=ICModr1(r2,t,r1,d1);284    SwapI64(&arg1,&arg2);285  } else {286    if (arg1->type&MDF_IMM && arg1->disp<32) {287      if (op==0xA30F && arg1->disp<8) {288        t=t2&MDG_MASK+RT_U8;289        op_imm=0xF6; //TEST290      } else291        t=t2&MDG_MASK+RT_U32;292    } else293      t=t2;294    i=ICModr1(r1,t,r2,d2);295  }296  ICRex(tmpi,i.u8[1]);297  if (op_imm==0xF6) {//TEST298    ICU16(tmpi,i.u8[2]<<8+op_imm);299    ICModr2(tmpi,i,,arg2->disp,rip2+1);300    ICU8(tmpi,1<<arg1->disp);301    if (is==0x72820F)302      is=0x75850F;303    else304      is=0x74840F;305  } else if (arg1->type&MDF_IMM && arg1->disp<64) {306    ICU24(tmpi,i.u8[2]<<16+op_imm);307    ICModr2(tmpi,i,,arg2->disp,rip2+1);308    ICU8(tmpi,arg1->disp);309  } else {310    ICU24(tmpi,i.u8[2]<<16+op);311    ICModr2(tmpi,i,,arg2->disp,rip2);312  }313 314  rip+=tmpi->ic_cnt;315  lb=OptLabelFwd(tmpi->ic_data);316  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);317  if (!buf && lb->addr!=INVALID_PTR) {318    i=lb->addr-(rip+2);319    if (lb->flags&CMF_POP_CMP)320      i+=8;321    if (I8_MIN<=i<=I8_MAX)322      short_jmp=TRUE;323  }324 325  if (short_jmp) {326    tmpi->ic_flags|=ICF_SHORT_JMP;327    i=lb->addr-(rip+2);328    if (lb->flags&CMF_POP_CMP)329      i+=8;330    ICU16(tmpi,i<<8+is.u8[2]);331  } else {332    tmpi->ic_flags&=~ICF_SHORT_JMP;333    i=lb->addr-(rip+6);334    if (lb->flags&CMF_POP_CMP)335      i+=8;336    ICU16(tmpi,is.u16[0]);337    ICU32(tmpi,i);338  }339}340 341U0 ICQueInit(CIntermediateCode *tmpi,I64 rip2)342{343  I64 r1;344  if (tmpi->arg1.type==MDF_REG+RT_I64)345    r1=tmpi->arg1.reg;346  else {347    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,348          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);349    r1=REG_RAX;350  }351  ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r1,0,rip2);352  ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);353}354 355U0 ICQueIns(CIntermediateCode *tmpi,I64 rip2)356{357  I64 r1,r2;358  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)359    r2=tmpi->arg2.reg;360  else {361    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,362          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);363    r2=REG_RAX;364  }365  if (tmpi->arg1.type==MDF_REG+RT_I64)366    r1=tmpi->arg1.reg;367  else {368    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,369          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);370    r1=REG_RDX;371  }372  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);373  ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r2,0,rip2);374  ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,REG_RBX,0,rip2);375  ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);376  ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);377}378 379U0 ICQueInsRev(CIntermediateCode *tmpi,I64 rip2)380{381  I64 r1,r2;382  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)383    r2=tmpi->arg2.reg;384  else {385    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,386          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);387    r2=REG_RAX;388  }389  if (tmpi->arg1.type==MDF_REG+RT_I64)390    r1=tmpi->arg1.reg;391  else {392    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,393          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);394    r1=REG_RDX;395  }396  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);397  ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,0,MDF_REG+RT_I64,r2,0,rip2);398  ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,r1,0,rip2);399  ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,REG_RBX,0,rip2);400  ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);401}402 403U0 ICQueRem(CIntermediateCode *tmpi,I64 rip2)404{405  I64 r1;406  if (tmpi->arg1.type==MDF_REG+RT_I64)407    r1=tmpi->arg1.reg;408  else {409    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,410          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);411    r1=REG_RAX;412  }413  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);414  ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);415  ICU24(tmpi,0x1A8948);416  ICU32(tmpi,sizeof(U8 *)<<24+0x538948);417}418 419U0 ICMinMax(CIntermediateCode *tmpi,I64 op,I64 rip2)420{421  I64 r1,i1=0x48;422  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RAX) {423    r1=tmpi->arg2.reg;424    if (r1>7) {425      i1++;426      r1&=7;427    }428    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,429          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);430  } else {431    if (tmpi->arg1.reg==REG_RAX && tmpi->arg1.type&MDG_REG_DISP_SIB) {432      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,433            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);434      r1=REG_RDX;435      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,436            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);437    } else {438      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,439            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);440      if (tmpi->arg1.type==MDF_REG+RT_I64) {441        r1=tmpi->arg1.reg;442        if (r1>7) {443          i1++;444          r1&=7;445        }446      } else {447        r1=REG_RDX;448        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,449              tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);450      }451    }452  }453  ICU24(tmpi,0xC03B00+r1<<16+i1);454  ICU32(tmpi,0xC0000F00+op<<16+r1<<24+i1);455}456 457U0 ICSqr(CIntermediateCode *tmpi,I64 op,I64 rip2)458{459  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,460        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);461  ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip2);462}463 464U0 ICModU64(CIntermediateCode *tmpi,I64 rip2)465{466  CICType t1;467  I64 r1,d1;468  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,469        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);470  if (tmpi->arg1.reg!=REG_RAX && tmpi->arg1.reg!=REG_RDX &&471        tmpi->arg1.type&MDG_REG_DISP_SIB &&472        tmpi->arg1.type.raw_type>=RT_I64) {473    t1=tmpi->arg1.type;474    r1=tmpi->arg1.reg;475    d1=tmpi->arg1.disp;476  } else {477    t1=MDF_REG+RT_I64;478    r1=REG_RBX;479    d1=0;480    ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,481          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);482  }483  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip2);484  ICZero(tmpi,REG_RDX);485  ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_DIV,rip2);486  ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip2);487  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,488        MDF_REG+RT_I64,REG_RDX,0,rip2);489}490 491U0 ICSwap(CIntermediateCode *tmpi,I64 rip2)492{493  I64 r1,r2;494  if (tmpi->arg1.type&MDF_REG)495    r1=tmpi->arg1.reg;496  else497    r1=REG_RAX;498  if (tmpi->arg2.type&MDF_REG)499    r2=tmpi->arg2.reg;500  else501    r2=REG_RAX;502  if (r1==r2) {503    if (r1==REG_RAX)504      r1=REG_RBX;505    else506      r2=REG_RAX;507  }508  ICMov(tmpi,MDF_REG+RT_I64,r2,0,509        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);510  ICMov(tmpi,MDF_REG+RT_I64,r1,0,511        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);512  switch (tmpi->ic_code) {513    case IC_SWAP_U8:514      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U8,r1,0,rip2);515      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U8,r2,0,rip2);516      ICMov(tmpi,MDF_DISP+RT_U8,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);517      ICMov(tmpi,MDF_DISP+RT_U8,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);518      break;519    case IC_SWAP_U16:520      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U16,r1,0,rip2);521      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U16,r2,0,rip2);522      ICMov(tmpi,MDF_DISP+RT_U16,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);523      ICMov(tmpi,MDF_DISP+RT_U16,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);524      break;525    case IC_SWAP_U32:526      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U32,r1,0,rip2);527      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U32,r2,0,rip2);528      ICMov(tmpi,MDF_DISP+RT_U32,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);529      ICMov(tmpi,MDF_DISP+RT_U32,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);530      break;531    case IC_SWAP_I64:532      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U64,r1,0,rip2);533      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U64,r2,0,rip2);534      ICMov(tmpi,MDF_DISP+RT_U64,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);535      ICMov(tmpi,MDF_DISP+RT_U64,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);536      break;537  }538}539 540U0 ICAndEqu(CIntermediateCode *tmpi,I64 rip2)541{542  I64 i,bit;543  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&544        tmpi->ic_flags&ICF_RES_NOT_USED) {545    i=~tmpi->arg2.disp;546    bit=Bsf(i);547    if (0<=bit==Bsr(i)) {548      tmpi->arg2.disp=bit;549      tmpi->arg2.reg=0;550      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;551      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xB30F,0x30BA0F,rip2);552      return;553    }554  }555  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,556        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,557        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,558        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x210425240423,rip2);559}560 561U0 ICOrEqu(CIntermediateCode *tmpi,I64 rip2)562{563  I64 i,bit;564  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&565        tmpi->ic_flags&ICF_RES_NOT_USED) {566    i=tmpi->arg2.disp;567    bit=Bsf(i);568    if (0<=bit==Bsr(i) && i>I8_MAX) {569      tmpi->arg2.disp=bit;570      tmpi->arg2.reg=0;571      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;572      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xAB0F,0x28BA0F,rip2);573      return;574    }575  }576  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,577        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,578        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,579        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x09010D0C010B,rip2);580}581 582U0 ICXorEqu(CIntermediateCode *tmpi,I64 rip2)583{584  I64 i,bit;585  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&586        tmpi->ic_flags&ICF_RES_NOT_USED) {587    i=tmpi->arg2.disp;588    bit=Bsf(i);589    if (0<=bit==Bsr(i)) {590      tmpi->arg2.disp=bit;591      tmpi->arg2.reg=0;592      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;593      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xBB0F,0x38BA0F,rip2);594      return;595    }596  }597  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,598        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,599        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,600        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x310635340633,rip2);601}602 603U0 ICSwitch(CIntermediateCode *tmpi,I64 rip,604        Bool nobound,CCmpCtrl *cc,U8 *buf,I64 rip2)605{606  I64 i,j,cnt,min,max,begin,r;607  CCodeMisc *lb;608  Bool short_jmp;609  CAOTAbsAddr *tmpa;610  if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg&7==REG_RSP)611    r=REG_RDX;612  else613    r=tmpi->arg1.reg;614  if (nobound)615    ICMov(tmpi,MDF_REG+RT_I64,r,0,616          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);617  else {618    if (tmpi->arg2.type&MDF_IMM) {619      j=tmpi->arg2.disp;620      ICMov(tmpi,MDF_REG+RT_I64,r,0,621            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);622      if (I8_MIN<=j<=I8_MAX) {623        i=0xF88348+(r&7)<<16;624        if (r>7) i++;625        ICU24(tmpi,i);626        ICU8(tmpi,j);627      } else if (I32_MIN<=j<=I32_MAX) {628        i=0xF88148+(r&7)<<16;629        if (r>7) i++;630        ICU24(tmpi,i);631        ICU32(tmpi,j);632      } else {633        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,634              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);635        i=0xC13B48+(r&7)<<19;636        if (r>7) i+=4;637        ICU24(tmpi,i);638      }639    } else {640      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,641            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);642      ICMov(tmpi,MDF_REG+RT_I64,r,0,643            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);644      i=0xC13B48+(r&7)<<19;645      if (r>7) i+=4;646      ICU24(tmpi,i);647    }648 649    rip+=tmpi->ic_cnt;650    lb=tmpi->ic_data(CCodeMisc *)->dft;651    short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);652    if (!buf && lb->addr!=INVALID_PTR) {653      i=lb->addr-(rip+2);654      if (I8_MIN<=i<=I8_MAX)655        short_jmp=TRUE;656    }657    if (short_jmp) {658      tmpi->ic_flags|=ICF_SHORT_JMP;659      ICU16(tmpi,(lb->addr-(rip+2))<<8+0x73);660    } else {661      tmpi->ic_flags&=~ICF_SHORT_JMP;662      ICU16(tmpi,0x830F);663      ICU32(tmpi,lb->addr-(rip+6));664    }665  }666 667  lb=tmpi->ic_data;668  begin=lb->begin->addr;669  if (!buf && begin!=INVALID_PTR) {670    min=I64_MAX;671    max=I64_MIN;672    for (i=0;i<lb->range;i++) {673      if (lb->jmp_table[i]->addr==INVALID_PTR) {674        min=I64_MIN;675        max=I64_MAX;676        break;677      } else {678        j=lb->jmp_table[i]->addr-begin;679        min=MinI64(min,j);680        max=MaxI64(max,j);681      }682    }683    if (I8_MIN<=min<=max<=I8_MAX)684      lb->flags|=CMF_I8_JMP_TABLE;685    else if (U8_MIN<=min<=max<=U8_MAX)686      lb->flags|=CMF_U8_JMP_TABLE;687    else if (I16_MIN<=min<=max<=I16_MAX)688      lb->flags|=CMF_I16_JMP_TABLE;689    else if (U16_MIN<=min<=max<=U16_MAX)690      lb->flags|=CMF_U16_JMP_TABLE;691  }692 693  if (lb->flags&CMF_I8_JMP_TABLE) {694    if (r<8)695      ICU8(tmpi,0x48);696    else697      ICU8(tmpi,0x49);698    ICU24(tmpi,0x98BE0F+(r&7)<<16);699    cnt=1;700  } else if (lb->flags&CMF_U8_JMP_TABLE) {701    if (r<8)702      cnt=2;703    else {704      ICU8(tmpi,0x49);705      cnt=1;706    }707    ICU24(tmpi,0x98B60F+(r&7)<<16);708  } else if (lb->flags&CMF_I16_JMP_TABLE) {709    if (r<8)710      ICU8(tmpi,0x48);711    else712      ICU8(tmpi,0x4A);713    ICU32(tmpi,0x451CBF0F+(r&7)<<27);714    cnt=0;715  } else if (lb->flags&CMF_U16_JMP_TABLE) {716    if (r<8)717      cnt=1;718    else {719      ICU8(tmpi,0x4A);720      cnt=0;721    }722    ICU32(tmpi,0x451CB70F+(r&7)<<27);723  } else {724    if (r<8)725      cnt=2;726    else {727      ICU8(tmpi,0x42);728      cnt=1;729    }730    ICU24(tmpi,0x851C8B+(r&7)<<19);731  }732  if (buf && cc->flags&CCF_AOT_COMPILE) {733    tmpa=CAlloc(sizeof(CAOTAbsAddr));734    tmpa->next=cc->aotc->abss;735    tmpa->type=AAT_ADD_U32;736    cc->aotc->abss=tmpa;737    tmpa->rip=rip2+tmpi->ic_cnt;738    ICU32(tmpi,lb->addr+cc->aotc->rip);739  } else740    ICU32(tmpi,lb->addr+buf);741 742  if (lb->flags&(CMF_I8_JMP_TABLE|CMF_U8_JMP_TABLE|743        CMF_I16_JMP_TABLE|CMF_U16_JMP_TABLE)) {744    ICU16(tmpi,0xC381); //ADD EBX,0x12345678745    if (buf && cc->flags&CCF_AOT_COMPILE) {746      tmpa=CAlloc(sizeof(CAOTAbsAddr));747      tmpa->next=cc->aotc->abss;748      tmpa->type=AAT_ADD_U32;749      cc->aotc->abss=tmpa;750      tmpa->rip=rip2+tmpi->ic_cnt;751      ICU32(tmpi,begin+cc->aotc->rip);752    } else753      ICU32(tmpi,begin+buf);754  } else755    cnt+=6;756  ICU16(tmpi,0xE3FF); //JMP EBX757  for (i=0;i<cnt;i++) //Code must always shrink, not expand758    ICU8(tmpi,OC_NOP);759  tmpi->ic_flags&=~ICF_CODE_FINAL;760}761 762U0 ICLocalVarInit(CIntermediateCode *tmpi)763{764  ICU24(tmpi,0xC48B48);765  ICU16(tmpi,0x5748);766  ICU24(tmpi,0xF88B48);767  ICU24(tmpi,0xC1C748);768  ICU32(tmpi,tmpi->ic_data);769  ICU16(tmpi,sys_var_init_val<<8+0xB0);770  ICU24(tmpi,0xAA48F3);771  ICU16(tmpi,0x5F48);772}773