CoolFace
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes838downloads
Asm.txt1116 linesDownload Raw Back to Compiler
1 2Bool PrsAsmImm(CCmpCtrl *cc,CAsmArg *arg)3{4  if (arg->imm_or_off_present)5    LexExcept(cc,"Already one immediate at ");6  arg->imm_or_off_present=TRUE;7  arg->num.local_asm_undef_hash=NULL;8  arg->num.glbl_asm_undef_hash=NULL;9  cc->asm_undef_hash=NULL;10  cc->abs_cnts=0;11  cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);12  if (!IsLexExpression2Bin(cc,&arg->num.machine_code))13    LexSkipEol(cc);14  else {15    if (cc->abs_cnts.externs)16      LexExcept(cc,"Extern Not Allowed at ");17    if (cc->flags & CCF_UNRESOLVED) {18      if (cc->flags & CCF_LOCAL) {19        arg->num.local_asm_undef_hash=cc->asm_undef_hash;20        cc->asm_undef_hash=NULL;21      } else {22        arg->num.glbl_asm_undef_hash=cc->asm_undef_hash;23        cc->asm_undef_hash=NULL;24      }25    } else {26      arg->num.i=Call(arg->num.machine_code);27      arg->num.glbl_asm_undef_hash=cc->asm_undef_hash;28      cc->asm_undef_hash=NULL;29      Free(arg->num.machine_code);30      arg->num.machine_code=NULL;31    }32  }33  return TRUE;34}35 36U0 PrsAsmArg(CCmpCtrl *cc,CAsmArg *arg,Bool rel)37{38  CHashGeneric *tmph,*tmph1;39  CHashReg *tmpr;40  MemSet(arg,0,sizeof(CAsmArg));41  arg->seg =REG_NONE;42  arg->reg1=REG_NONE;43  arg->reg2=REG_NONE;44  arg->scale=1;45  while (TRUE) {46    if (cc->token==TK_IDENT) {47      if (tmph=cc->hash_entry) {48        if (tmph->type&HTG_TYPE_MASK==HTT_REG) {49          tmpr=tmph;50          arg->reg1_type=tmpr->reg_type;51          switch (tmpr->reg_type) {52            start:53              case REGT_R8:54                arg->size=1;55                break;56              case REGT_R16:57                arg->size=2;58                break;59              case REGT_R32:60                arg->size=4;61                break;62              case REGT_R64:63                arg->size=8;64                break;65            end:66              arg->reg1=tmpr->reg_num;67              Lex(cc);68              return;69            case REGT_SEG:70              arg->seg=tmpr->reg_num;71              if (Lex(cc)!=':') {72                arg->just_seg=TRUE;73                return;74              } else75                Lex(cc); //skip ":"76              break;77            case REGT_FSTK:78            case REGT_MM:79            case REGT_XMM:80              arg->size=8;81              arg->reg1=tmpr->reg_num;82              Lex(cc);83              return;84          }85        } else {86          if ((tmph->type&HTG_TYPE_MASK==HTT_CLASS||87                tmph->type&HTG_TYPE_MASK==HTT_INTERNAL_TYPE) &&88                (tmph1=HashFind(cc->cur_str,cmp.asm_hash,HTT_ASM_KEYWORD)))89            tmph=tmph1;90          if (tmph->type&HTG_TYPE_MASK==HTT_ASM_KEYWORD) {91            switch (tmph->user_data0) {92              case AKW_I8:93              case AKW_U8:94                arg->size=1;95                break;96              case AKW_I16:97              case AKW_U16:98                arg->size=2;99                break;100              case AKW_I32:101              case AKW_U32:102                arg->size=4;103                break;104              case AKW_I64:105              case AKW_U64:106                arg->size=8;107                break;108              default:109                LexExcept(cc,"syntax error at ");110            }111            Lex(cc); //skip keyword112          } else113            goto pa_asm_direct_imm;114        }115      } else {116pa_asm_direct_imm:117        PrsAsmImm(cc,arg);118        arg->num.abs_cnts=cc->abs_cnts;119        if (arg->size<=1 && !rel && arg->num.abs_cnts&1) {120          if (cc->aotc->seg_size==16)121            arg->size=2;122          else123            arg->size=4;124        }125        if (cc->token!='[')126          return;127      }128    } else if (cc->token=='[') {129      arg->indirect=TRUE;130      Lex(cc); // skip [131      while (cc->token && cc->token!=']') {132        if (cc->token==TK_IDENT) {133          if (tmph=cc->hash_entry) {134            if (tmph->type&HTG_TYPE_MASK==HTT_REG &&135                  REGT_R16<=tmph(CHashReg *)->reg_type<=REGT_R64) {136              tmpr=tmph;137              arg->reg2_type=tmpr->reg_type;138              if (arg->reg1==REG_NONE) {139                if (tmpr->reg_num&7==REG_RSP) {140                  arg->reg1=4;141                  arg->reg2=tmpr->reg_num;142                } else143                  arg->reg1=tmpr->reg_num;144              } else145                arg->reg2=tmpr->reg_num;146              Lex(cc);147            } else148              goto pa_asm_indirect_imm;149          } else150            goto pa_asm_indirect_imm;151        } else if (cc->token=='*') {152          Lex(cc);153          if (cc->token!=TK_I64)154            LexExcept(cc,"Expecting scale factor at ");155          arg->scale=cc->cur_i64;156          Lex(cc); //skip scale157          if (arg->reg2!=REG_NONE) {158            SwapI64(&arg->reg1,&arg->reg2);159            SwapI64(&arg->reg1_type,&arg->reg2_type);160          }161        } else if (cc->token=='+') {162          Lex(cc); //skip '+'163        } else {164pa_asm_indirect_imm:165          PrsAsmImm(cc,arg);166          arg->num.abs_cnts=cc->abs_cnts;167        }168      }169      if (cc->token!=']')170        LexExcept(cc,"Missing ']' at ");171      Lex(cc); //skip ]172      return;173    } else174      goto pa_asm_direct_imm;175  }176}177 178I64 AsmMakeArgMask(CCmpCtrl *cc,CAsmArg *arg)179{180  CAOTCtrl *aotc=cc->aotc;181  I64 res;182  if (arg->just_seg) {183    switch (arg->seg) {184      case 0: res=1<<ARGT_ES|1<<ARGT_SREG; break;185      case 1: res=1<<ARGT_CS|1<<ARGT_SREG; break;186      case 2: res=1<<ARGT_SS|1<<ARGT_SREG; break;187      case 3: res=1<<ARGT_DS|1<<ARGT_SREG; break;188      case 4: res=1<<ARGT_FS|1<<ARGT_SREG; break;189      case 5: res=1<<ARGT_GS|1<<ARGT_SREG; break;190    }191    goto mm_done;192  }193  if (arg->reg1_type==REGT_FSTK) {194    if (arg->reg1)195      res=1<<ARGT_STI;196    else197      res=1<<ARGT_ST0|1<<ARGT_STI;198    goto mm_done;199  }200  res=cmp.size_arg_mask[arg->size];201  if (aotc->seg_size==64)202    res&=0xFF0FFFFFFF;203 204  if (arg->reg1!=REG_NONE && arg->imm_or_off_present && !arg->num.i &&205        !arg->num.glbl_asm_undef_hash && !arg->num.local_asm_undef_hash)206    arg->imm_or_off_present=FALSE;  //Zero displacement207 208  if (arg->reg2!=REG_NONE || arg->scale!=1) {209    res&=0x0000FF0000;210    goto mm_done;211  }212 213  if (arg->indirect) {214    if (arg->imm_or_off_present)215      res&=0x00FFFF0000;216    else217      res&=0x000FFF0000;218  } else {219    if (arg->imm_or_off_present)220      res&=0x000F000FFE;221    else222      res&=0x3F0FFFF000;223  }224  if (arg->seg!=REG_NONE)225    res&=0x00FFFF0000;226  if (arg->reg1==REG_NONE) {227    if (arg->indirect)228      res&=0x00FFFF0000;229    else if (arg->num.i<0) {230      if (arg->num.i>=I8_MIN)231        res&=0x8FE;232      else if (arg->num.i>=I16_MIN)233        res&=0x8EE;234      else if (arg->num.i>=I32_MIN)235        res&=0x8CE;236      else237        res&=0x88E;238    } else {239      if (arg->num.i<=I8_MAX)240        res&=0xFFE;241      else if (arg->num.i<=U8_MAX)242        res&=0xFEE;243      else if (arg->num.i<=I16_MAX)244        res&=0xEEE;245      else if (arg->num.i<=U16_MAX)246        res&=0xECE;247      else if (arg->num.i<=I32_MAX)248        res&=0xCCE;249      else if (arg->num.i<=U32_MAX)250        res&=0xC8E;251      else252        res&=0x88E;253    }254  } else {255    res&=  0x3F00FFF000;256    if (!arg->indirect) //M8-M64257      res&=0xFFFF0FFFFF;258  }259  switch (arg->reg1) {260    case REG_RAX: res&=~0x3000000000; break;261    case REG_RCX: res&=~0x2F00000000; break;262    case REG_RDX: res&=~0x1F00000000; break;263    default:      res&=~0x3F00000000;264  }265mm_done:266  return res;267}268 269Bool AsmStoreNum(CCmpCtrl *cc,CAsmNum2 *num2,I64 cnt,Bool U8_avail)270{271  CAOTCtrl *aotc=cc->aotc;272  I64 i;273  CAOTAbsAddr *tmpa;274 275  if (!num2->imm_flag)276    num2->num.i-=num2->rel;277  for (i=0;i<cnt;i++) {278    if (num2->U8_cnt==1) {279      if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)280        AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I8+num2->imm_flag,281              aotc->rip,num2->rel,num2->num.local_asm_undef_hash,282              num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,283              U8_avail);284      else if (!num2->imm_flag && !(I8_MIN<=num2->num.i<=I8_MAX))285        LexExcept(cc,"Branch out of range at ");286      if (num2->imm_flag) {287        if (num2->num.abs_cnts.abs_addres&1) {288          tmpa=CAlloc(sizeof(CAOTAbsAddr));289          tmpa->next=aotc->abss;290          aotc->abss=tmpa;291          tmpa->rip=aotc->rip;292          tmpa->type=AAT_ADD_U8;293        }294      } else {295        if (num2->num.abs_cnts.c_addres&1) {296          tmpa=CAlloc(sizeof(CAOTAbsAddr));297          tmpa->next=aotc->abss;298          aotc->abss=tmpa;299          tmpa->rip=aotc->rip;300          tmpa->type=AAT_SUB_U8;301        }302      }303      AOTStoreCodeU8(cc,num2->num.i);304    } else {305      if (num2->U8_cnt==2) {306        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)307          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I16+num2->imm_flag,308                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,309                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,310                U8_avail);311        else if (!num2->imm_flag && !(I16_MIN<=num2->num.i<=I16_MAX))312          LexExcept(cc,"Branch out of range at ");313        if (num2->imm_flag) {314          if (num2->num.abs_cnts.abs_addres&1) {315            tmpa=CAlloc(sizeof(CAOTAbsAddr));316            tmpa->next=aotc->abss;317            aotc->abss=tmpa;318            tmpa->rip=aotc->rip;319            tmpa->type=AAT_ADD_U16;320          }321        } else {322          if (num2->num.abs_cnts.c_addres&1) {323            tmpa=CAlloc(sizeof(CAOTAbsAddr));324            tmpa->next=aotc->abss;325            aotc->abss=tmpa;326            tmpa->rip=aotc->rip;327            tmpa->type=AAT_SUB_U16;328          }329        }330        AOTStoreCodeU8(cc,num2->num.i.u8[0]);331        AOTStoreCodeU8(cc,num2->num.i.u8[1]);332      } else if (num2->U8_cnt==4) {333        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)334          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I32+num2->imm_flag,335                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,336                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,337                U8_avail);338        else if (!num2->imm_flag && !(I32_MIN<=num2->num.i<=I32_MAX))339          LexExcept(cc,"Branch out of range at ");340        if (num2->imm_flag) {341          if (num2->num.abs_cnts.abs_addres&1) {342            tmpa=CAlloc(sizeof(CAOTAbsAddr));343            tmpa->next=aotc->abss;344            aotc->abss=tmpa;345            tmpa->rip=aotc->rip;346            tmpa->type=AAT_ADD_U32;347          }348        } else {349          if (num2->num.abs_cnts.c_addres&1) {350            tmpa=CAlloc(sizeof(CAOTAbsAddr));351            tmpa->next=aotc->abss;352            aotc->abss=tmpa;353            tmpa->rip=aotc->rip;354            tmpa->type=AAT_SUB_U32;355          }356        }357        AOTStoreCodeU32(cc,num2->num.i);358      } else if (num2->U8_cnt==8) {359        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)360          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I64+num2->imm_flag,361                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,362                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,363                U8_avail);364        if (num2->imm_flag) {365          if (num2->num.abs_cnts.abs_addres&1) {366            tmpa=CAlloc(sizeof(CAOTAbsAddr));367            tmpa->next=aotc->abss;368            aotc->abss=tmpa;369            tmpa->rip=aotc->rip;370            tmpa->type=AAT_ADD_U64;371          }372        } else {373          if (num2->num.abs_cnts.c_addres&1) {374            tmpa=CAlloc(sizeof(CAOTAbsAddr));375            tmpa->next=aotc->abss;376            aotc->abss=tmpa;377            tmpa->rip=aotc->rip;378            tmpa->type=AAT_SUB_U64;379          }380        }381        AOTStoreCodeU64(cc,num2->num.i);382      }383      if (U8_avail && !num2->num.local_asm_undef_hash &&384            !num2->num.glbl_asm_undef_hash &&385            !num2->imm_flag && -124<=num2->num.i<=123) {386        LexWarn(cc,"could use I8 displacement at ");387        return FALSE;388      }389    }390  }391  return TRUE;392}393 394U8 asm_seg_prefixes[6]={0x26,0x2E,0x36,0x3E,0x64,0x65};395 396Bool PrsAsmInst(CCmpCtrl *cc,CHashOpcode *tmpo,I64 argcnt)397{398  CAOTCtrl *aotc=cc->aotc;399  I64 i,j,arg1,arg2,om,seg,arg1mask,arg2mask;400  CAsmArg *tmpa1,*tmpa2;401  Bool ModrM_complete,U8_avail=FALSE,found_second_possible=FALSE;402  CInst *tmpins;403  CAsmIns cur,best;404 405  best.U8_cnt=255;406  if (argcnt>0)407    arg1mask=AsmMakeArgMask(cc,&aotc->arg1);408  else409    arg1mask=1;410  if (argcnt>1)411    arg2mask=AsmMakeArgMask(cc,&aotc->arg2);412  else413    arg2mask=1;414  for (i=0;i<tmpo->inst_entry_cnt;i++) {415    tmpins=&tmpo->ins[i];416    if (tmpins->arg1==ARGT_REL8 || tmpins->arg2==ARGT_REL8)417      U8_avail=TRUE;418    if (Bt(&arg1mask,tmpins->arg1) && Bt(&arg2mask,tmpins->arg2) &&419          (!(tmpins->flags&IEF_NOT_IN_64_BIT) || aotc->seg_size!=64)) {420      MemSet(&cur,0,sizeof(CAsmIns));421      cur.tmpins=tmpins;422      ModrM_complete=FALSE;423      cur.is_dft=ToBool(tmpins->flags & IEF_DFT);424      if (aotc->seg_size==64) {425        if (tmpins->flags & IEF_48_REX)426          cur.REX=0x48;427        else428          cur.REX=0x40;429      }430      cur.disp.imm_flag=TRUE;431      cur.imm.imm_flag=TRUE;432      om=tmpins->opcode_modifier;433      arg1=tmpins->arg1;434      arg2=tmpins->arg2;435      tmpa1=&aotc->arg1;436      tmpa2=&aotc->arg2;437      cur.last_opcode_U8=tmpins->opcode[tmpins->opcode_cnt-1];438 439      if (tmpins->slash_val<8) {440        cur.ModrM|=tmpins->slash_val<<3;441        cur.has_ModrM=TRUE;442      }443 444      if (aotc->seg_size==16 && tmpins->flags & IEF_OP_SIZE32 ||445            aotc->seg_size!=16 && tmpins->flags & IEF_OP_SIZE16)446        cur.has_operand_prefix=TRUE;447 448      if (om==OM_IB)      cur.imm.U8_cnt=1;449      else if (om==OM_IW) cur.imm.U8_cnt=2;450      else if (om==OM_ID) cur.imm.U8_cnt=4;451 452      if (om==OM_CB) {453        cur.imm.U8_cnt=1;454        cur.imm.imm_flag=FALSE;455      } else if (om==OM_CW) {456        cur.imm.U8_cnt=2;457        cur.imm.imm_flag=FALSE;458      } else if (om==OM_CD) {459        cur.imm.U8_cnt=4;460        cur.imm.imm_flag=FALSE;461      }462 463      if (argcnt==1) {464        if (best.U8_cnt!=255 && !found_second_possible && !best.is_dft) {465          found_second_possible=TRUE;466          if (!aotc->arg1.size)467            PrintWarn("no size specified at %s,%04d\n",468                  cc->lex_include_stk->full_name,469                  cc->lex_include_stk->line_num-1);470        }471        if (tmpins->flags & IEF_PLUS_OPCODE) {472          if (tmpins->slash_val==SV_R_REG) {473            cur.last_opcode_U8|=tmpa1->reg1&7;474            if (tmpa1->reg1&15>7)475              cur.REX|=1;476            if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?477              cur.has_REX=TRUE;478          } else {//SV_I_REG479            if (tmpa1->reg1_type==REGT_FSTK)480              cur.last_opcode_U8+=tmpa1->reg1;481          }482        }483        if (arg1==ARGT_R64 || arg1==ARGT_RM64 || arg1==ARGT_M64)484          cur.REX|=8;485        if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_M8<=arg1<=ARGT_M64) {486          if (aotc->seg_size==16)487            cur.has_addr_prefix=TRUE;488 489          cur.has_ModrM=TRUE;490          if (tmpa1->imm_or_off_present && tmpa1->indirect &&491                tmpa1->reg1==REG_NONE) {492            cur.ModrM=cur.ModrM+5;493            MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));494            cur.disp.U8_cnt=4;495            if (aotc->seg_size==64)496              cur.disp.imm_flag=FALSE;497          } else {498            if (tmpa1->reg2==REG_NONE && tmpa1->scale==1) {499              cur.ModrM|=tmpa1->reg1&7;500              if (tmpa1->reg1&15>7)501                cur.REX|=1;502              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?503                cur.has_REX=TRUE;504            } else {505              cur.ModrM|=4;506              cur.has_SIB=TRUE;507              if (tmpa1->scale==1)508                cur.SIB=0;509              else if (tmpa1->scale==2)510                cur.SIB=0x40;511              else if (tmpa1->scale==4)512                cur.SIB=0x80;513              else if (tmpa1->scale==8)514                cur.SIB=0xC0;515              if (tmpa1->reg2==REG_NONE) {516                ModrM_complete=TRUE;517                cur.SIB|=(tmpa1->reg1&7)<<3+REG_RBP;518                if (tmpa1->reg1&15>7)519                  cur.REX|=2;520                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?521                  cur.has_REX=TRUE;522                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));523                cur.disp.U8_cnt=4;524              } else {525                cur.SIB|=(tmpa1->reg1&7)<<3+tmpa1->reg2&7;526                if (tmpa1->reg1&15>7)527                  cur.REX|=2;528                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?529                  cur.has_REX=TRUE;530                if (tmpa1->reg2&15>7)531                  cur.REX|=1;532                if (tmpa1->reg2>=20) //RBPu8,RSPu8,RSIu8,RDIu8?533                  cur.has_REX=TRUE;534                if (tmpa1->reg2&7==REG_RBP &&535                      !tmpa1->imm_or_off_present && tmpa1->indirect) {536                  cur.ModrM|=0x40;537                  cur.disp.U8_cnt=1;538                  ModrM_complete=TRUE;539                }540              }541            }542            if (!ModrM_complete) {543              if (tmpa1->imm_or_off_present) {544                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));545                if (!cur.disp.num.machine_code &&546                      I8_MIN<=cur.disp.num.i<=I8_MAX) {547                  cur.ModrM|=0x40;548                  cur.disp.U8_cnt=1;549                } else if (aotc->seg_size==16) {550                  cur.ModrM|=0x80;551                  cur.disp.U8_cnt=2;552                } else {553                  cur.ModrM|=0x80;554                  cur.disp.U8_cnt=4;555                }556              } else if (!tmpa1->indirect) {557                cur.has_addr_prefix=FALSE;558                cur.ModrM|=0xC0;559              } else {560                if (tmpa1->reg1&7==REG_RBP) {561                  cur.ModrM|=0x40;562                  cur.disp.U8_cnt=1;563                }564              }565            }566          }567        } else if (ARGT_REL8<=arg1<=ARGT_REL32 || ARGT_IMM8<=arg1<=ARGT_IMM64 ||568              ARGT_UIMM8<=arg1<=ARGT_UIMM64) {569          if (arg1==ARGT_IMM64 || arg2==ARGT_UIMM64)570            cur.REX|=8;571          MemCpy(&cur.imm.num,&tmpa1->num,sizeof(CAsmNum));572        }573      } else if (argcnt==2) {574        if (best.U8_cnt!=255 && !found_second_possible && !best.is_dft) {575          found_second_possible=TRUE;576          if (!aotc->arg1.size && !aotc->arg2.size)577            PrintWarn("no size specified at %s,%04d\n",578                  cc->lex_include_stk->full_name,579                  cc->lex_include_stk->line_num-1);580        }581        if (tmpins->flags & IEF_PLUS_OPCODE) {582          if (tmpins->slash_val==SV_R_REG) {583            if (ARGT_AL<=arg1<=ARGT_RAX) {584              cur.last_opcode_U8|=tmpa2->reg1&7;585              if (tmpa2->reg1&15>7)586                cur.REX|=1;587              if (tmpa2->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?588                cur.has_REX=TRUE;589            } else {590              cur.last_opcode_U8|=tmpa1->reg1&7;591              if (tmpa1->reg1&15>7)592                cur.REX|=1;593              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?594                cur.has_REX=TRUE;595            }596          } else {//SV_I_REG597            if (tmpa1->reg1_type==REGT_FSTK)598              cur.last_opcode_U8|=tmpa1->reg1;599            if (tmpa2->reg1_type==REGT_FSTK)600              cur.last_opcode_U8|=tmpa2->reg1;601          }602        }603        if (arg1==ARGT_RM64 || arg2==ARGT_RM64 ||604              arg1==ARGT_M64 || arg2==ARGT_M64 ||605              arg1==ARGT_R64 || arg2==ARGT_R64)606          cur.REX|=8;607        if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_RM8<=arg2<=ARGT_RM64 ||608              ARGT_M8<=arg1<=ARGT_M64  || ARGT_M8<=arg2<=ARGT_M64) {609          if (aotc->seg_size==16)610            cur.has_addr_prefix=TRUE;611          cur.has_ModrM=TRUE;612          if (ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {613            tmpa1=&aotc->arg2;614            tmpa2=&aotc->arg1;615          }616          if (tmpins->slash_val==SV_R_REG) {617            if (tmpa2->just_seg)618              cur.ModrM|=tmpa2->seg<<3;619            else {620              if (tmpa2->reg1==REG_NONE) {621                cur.ModrM|=(tmpa1->reg1&7)<<3;622                if (tmpa1->reg1&15>7)623                  cur.REX|=4;624                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?625                  cur.has_REX=TRUE;626              } else {627                cur.ModrM|=(tmpa2->reg1&7)<<3;628                if (tmpa2->reg1&15>7)629                  cur.REX|=4;630                if (tmpa2->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?631                  cur.has_REX=TRUE;632              }633            }634          }635          if (tmpa1->reg2==REG_NONE && tmpa1->scale==1) {636            if (tmpa1->reg1!=REG_NONE) {637              cur.ModrM|=tmpa1->reg1&7;638              if (tmpa1->reg1&15>7)639                cur.REX|=1;640              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?641                cur.has_REX=TRUE;642            }643          } else {644            cur.ModrM|=4;645            cur.has_SIB=TRUE;646            if (tmpa1->scale==1)647              cur.SIB=0;648            else if (tmpa1->scale==2)649              cur.SIB=0x40;650            else if (tmpa1->scale==4)651              cur.SIB=0x80;652            else if (tmpa1->scale==8)653              cur.SIB=0xC0;654            if (tmpa1->reg2==REG_NONE) {655              ModrM_complete=TRUE;656              cur.SIB|=(tmpa1->reg1&7)<<3+5;657              if (tmpa1->reg1&15>7)658                cur.REX|=2;659              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?660                cur.has_REX=TRUE;661              MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));662              cur.disp.U8_cnt=4;663            } else {664              cur.SIB|=(tmpa1->reg1&7)<<3+tmpa1->reg2&7;665              if (tmpa1->reg1&15>7)666                cur.REX|=2;667              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?668                cur.has_REX=TRUE;669              if (tmpa1->reg2&15>7)670                cur.REX|=1;671              if (tmpa1->reg2>=20) //RBPu8,RSPu8,RSIu8,RDIu8?672                cur.has_REX=TRUE;673              if (tmpa1->reg2&7==REG_RBP &&674                    !tmpa1->imm_or_off_present && tmpa1->indirect) {675                cur.ModrM|=0x40;676                cur.disp.U8_cnt=1;677                ModrM_complete=TRUE;678              }679            }680          }681          if (!ModrM_complete) {682            if (tmpa1->imm_or_off_present &&683                  tmpa1->indirect && tmpa1->reg1==REG_NONE) {684              cur.ModrM=cur.ModrM&0xF8+5;685              MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));686              cur.disp.U8_cnt=4;687              if (aotc->seg_size==64)688                cur.disp.imm_flag=FALSE;689            } else {690              if (tmpa1->imm_or_off_present) {691                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));692                if (!cur.disp.num.machine_code &&693                      I8_MIN<=cur.disp.num.i<=I8_MAX) {694                  cur.ModrM|=0x40;695                  cur.disp.U8_cnt=1;696                } else if (aotc->seg_size==16) {697                  cur.ModrM|=0x80;698                  cur.disp.U8_cnt=2;699                } else {700                  cur.ModrM|=0x80;701                  cur.disp.U8_cnt=4;702                }703              } else if (!tmpa1->indirect) {704                cur.has_addr_prefix=FALSE;705                cur.ModrM|=0xC0;706              } else {707                if (tmpa1->reg1&7==REG_RBP) {708                  cur.ModrM|=0x40;709                  cur.disp.U8_cnt=1;710                }711              }712            }713          }714        } else if (ARGT_MOFFS8<=arg1<=ARGT_MOFFS64) {715          MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));716          if (aotc->seg_size==16)717            cur.disp.U8_cnt=2;718          else719            cur.disp.U8_cnt=4;720          cur.has_addr_prefix=FALSE;721        } else if (ARGT_MOFFS8<=arg2<=ARGT_MOFFS64) {722          MemCpy(&cur.disp.num,&tmpa2->num,sizeof(CAsmNum));723          if (aotc->seg_size==16)724            cur.disp.U8_cnt=2;725          else726            cur.disp.U8_cnt=4;727          cur.has_addr_prefix=FALSE;728        } else if (ARGT_IMM8<=arg1<=ARGT_IMM64 ||729              ARGT_UIMM8<=arg1<=ARGT_UIMM64) {730          MemCpy(&cur.imm.num,&tmpa1->num,sizeof(CAsmNum));731          if (arg1==ARGT_IMM8 || arg1==ARGT_UIMM8) cur.imm.U8_cnt=1;732          else if (arg1==ARGT_IMM16 || arg1==ARGT_UIMM16) cur.imm.U8_cnt=2;733          else if (arg1==ARGT_IMM32 || arg1==ARGT_UIMM32) cur.imm.U8_cnt=4;734          else {735            cur.imm.U8_cnt=8;736            cur.REX|=8;737          }738        }739        if (ARGT_IMM8<=arg2<=ARGT_IMM64 ||740              ARGT_UIMM8<=arg2<=ARGT_UIMM64) {741          MemCpy(&cur.imm.num,&tmpa2->num,sizeof(CAsmNum));742          if (arg2==ARGT_IMM8 || arg2==ARGT_UIMM8) cur.imm.U8_cnt=1;743          else if (arg2==ARGT_IMM16 || arg2==ARGT_UIMM16) cur.imm.U8_cnt=2;744          else if (arg2==ARGT_IMM32 || arg2==ARGT_UIMM32) {745            cur.imm.U8_cnt=4;746            if (tmpins->flags&IEF_REX_ONLY_R8_R15 && arg2==ARGT_UIMM32)747              cur.REX&=~8;748          } else {749            cur.imm.U8_cnt=8;750            cur.REX|=8;751          }752        }753      }754      cur.U8_cnt=tmpins->opcode_cnt+cur.disp.U8_cnt+cur.imm.U8_cnt;755      if (cur.has_ModrM) cur.U8_cnt++;756      if (cur.has_SIB) cur.U8_cnt++;757      if (aotc->seg_size==64 && cur.REX&0x40==0x40 &&758            (cur.REX!=0x40 || cur.has_REX) &&759            (cur.REX&7 || !(tmpins->flags&IEF_REX_ONLY_R8_R15 ||760            tmpins->flags&IEF_REX_XOR_LIKE && tmpa1->reg1==tmpa2->reg1 &&761            cur.ModrM&0xC0==0xC0)))762        cur.U8_cnt++;763      if (cur.U8_cnt<best.U8_cnt &&764            !(tmpins->flags & IEF_DONT_SWITCH_MODES &&765            (cur.has_addr_prefix || cur.has_operand_prefix)))766        MemCpy(&best,&cur,sizeof(CAsmIns));767    }768  }769  if (best.U8_cnt<255) {770    tmpins=best.tmpins;771    seg=REG_NONE;772    if (argcnt>1 && aotc->arg2.seg!=REG_NONE && !aotc->arg2.just_seg)773      seg=aotc->arg2.seg;774    else if (argcnt>0 && aotc->arg1.seg!=REG_NONE && !aotc->arg1.just_seg)775      seg=aotc->arg1.seg;776    if (seg!=REG_NONE)777      AOTStoreCodeU8(cc,asm_seg_prefixes[seg]);778    if (best.has_operand_prefix)779      AOTStoreCodeU8(cc,OC_OP_SIZE_PREFIX); //Operand size override780    if (best.has_addr_prefix  || aotc->seg_size==16 && cur.has_SIB)781      AOTStoreCodeU8(cc,OC_ADDR_SIZE_PREFIX); //Operand size override782    if (aotc->seg_size==64 && best.REX&0x40==0x40 &&783          (best.REX!=0x40 || best.has_REX) &&784          (best.REX&7||!(tmpins->flags&IEF_REX_ONLY_R8_R15 ||785          tmpins->flags&IEF_REX_XOR_LIKE && tmpa1->reg1==tmpa2->reg1 &&786          best.ModrM&0xC0==0xC0)))787      AOTStoreCodeU8(cc,best.REX);788    for (j=0;j<tmpins->opcode_cnt-1;j++)789      AOTStoreCodeU8(cc,tmpins->opcode[j]);790    AOTStoreCodeU8(cc,best.last_opcode_U8);791 792    if (best.has_ModrM)793      AOTStoreCodeU8(cc,best.ModrM);794    if (best.has_SIB)795      AOTStoreCodeU8(cc,best.SIB);796 797    if (best.disp.U8_cnt) {798      best.disp.rel=aotc->rip+best.disp.U8_cnt+best.imm.U8_cnt;799      if (!AsmStoreNum(cc,&best.disp,1,U8_avail))800        return FALSE;801    }802 803    if (best.imm.U8_cnt) {804      best.imm.rel=aotc->rip+best.imm.U8_cnt;805      if (!AsmStoreNum(cc,&best.imm,1,U8_avail))806        return FALSE;807    }808    if (tmpins->flags&IEF_ENDING_ZERO) //ENTER inst809      AOTStoreCodeU8(cc,0);810    return TRUE;811  }812  LexExcept(cc,"Invalid inst at ");813}814 815U0 PrsAsmDefine(CCmpCtrl *cc,I64 U8_cnt)816{817  Bool is_dup;818  I64 i,dup_val;819  U8 *ptr;820  CAsmNum2 num2;821  num2.U8_cnt=U8_cnt;822 823  while (cc->token && cc->token!=';') {824    num2.num.local_asm_undef_hash=NULL;825    num2.num.glbl_asm_undef_hash=NULL;826    if (cc->token==TK_STR) {827      ptr=cc->cur_str;828      i=cc->cur_str_len-1;829      while (i--)830        AOTStoreCodeU8(cc,*ptr++);831      Lex(cc);  //Skip Str832    } else {833      is_dup=FALSE;834      cc->abs_cnts=0;835      cc->asm_undef_hash=NULL;836      cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);837      if (!IsLexExpression2Bin(cc,&num2.num.machine_code))838        LexSkipEol(cc);839      else {840        if (cc->abs_cnts.externs)841          LexExcept(cc,"Extern Not Allowed at ");842        if (cc->flags & CCF_UNRESOLVED) {843          if (cc->flags & CCF_LOCAL) {844            num2.num.local_asm_undef_hash=cc->asm_undef_hash;845            cc->asm_undef_hash=NULL;846          } else {847            num2.num.glbl_asm_undef_hash=cc->asm_undef_hash;848            cc->asm_undef_hash=NULL;849          }850        } else {851          i=Call(num2.num.machine_code);852          Free(num2.num.machine_code);853        }854      }855      if (cc->token==TK_IDENT && cc->hash_entry) {856        if (cc->hash_entry->type & HTT_ASM_KEYWORD &&857              cc->hash_entry->user_data0==AKW_DUP) {858          is_dup=TRUE;859          if (Lex(cc)!='(')860            LexExcept(cc,"Expecting '(' at ");861          Lex(cc); //skip (862          dup_val=AsmLexExpression(cc);863          if (cc->token!=')')864            LexExcept(cc,"Expecting ')' at ");865          Lex(cc); //SKIP )866        }867      }868      num2.rel=0;869      num2.imm_flag=TRUE;870      num2.num.abs_cnts=cc->abs_cnts;871      if (is_dup) {872        if (num2.num.local_asm_undef_hash || num2.num.glbl_asm_undef_hash)873          LexExcept(cc,"Undefined DUP cnt at ");874        num2.num.i=dup_val;875        AsmStoreNum(cc,&num2,i,FALSE);876      } else {877        num2.num.i=i;878        AsmStoreNum(cc,&num2,1,FALSE);879      }880    }881    if (cc->token==',')882      Lex(cc);883  }884  if (cc->token!=';')885    LexExcept(cc,"Missing ';' at");886  Lex(cc);887}888 889U0 PrsBinFile(CCmpCtrl *cc)890{891  I64 i,size;892  U8 *buf,*st;893  if (cc->token!=TK_STR)894    LexExcept(cc,"Expecting string at ");895  st=ExtDft(cc->cur_str,"BIN");896  buf=FileRead(st,&size);897  Free(st);898  for (i=0;i<size;i++)899    AOTStoreCodeU8(cc,buf[i]);900  if (Lex(cc)!=';')901    LexExcept(cc,"Missing ';' at");902  Lex(cc);903}904 905U0 PrsAsmBlk(CCmpCtrl *cc,I64 cmp_flags)906{907  CAOTCtrl *aotc=cc->aotc;908  I64 i,j,k,argcnt,909        old_flags=cc->flags & CCF_ASM_EXPRESSIONS;910  CHashOpcode *tmpo;911  CHashExport *tmpex;912  U8 *next_last_label;913  CCodeMisc *g_lb;914 915  aotc->seg_size=64;916  cc->flags|=CCF_ASM_EXPRESSIONS;917  if (!(cmp_flags&CMPF_ONE_ASM_INS)) {918    if (cc->token!='{')919      LexExcept(cc,"Expecting '{' at ");920    Lex(cc);921  }922  while (cc->token && cc->token!='}') {923    AsmLineLst(cc);924    if (cc->token==TK_IDENT && cc->hash_entry) {925      if (cc->hash_entry->type&HTT_ASM_KEYWORD) {926        i=cc->hash_entry->user_data0;927        Lex(cc); //skip keyword928        switch (i) {929          case AKW_IMPORT:930            while (cc->token && cc->token!=';') {931              if (cc->token!=TK_IDENT)932                LexExcept(cc,"Expecting identifier at ");933              else {934                tmpex=NULL;935                tmpex=CAlloc(sizeof(CHashExport));936                tmpex->str=cc->cur_str;937                cc->cur_str=0;938                tmpex->type=HTT_EXPORT_SYS_SYM|HTF_UNRESOLVED;939                HashAdd(tmpex,cc->htc.glbl_hash_table);940                tmpex->type|=HTF_IMPORT;941                if (Lex(cc)==',')942                  Lex(cc); //skip ','943              }944            }945            if (cc->token!=';')946              LexExcept(cc,"Missing ';' at");947            Lex(cc); //skip ';';948            break;949          case AKW_ORG:950            if (cc->htc.local_var_lst)951              LexExcept(cc,"ORG not allowed in fun asm blk ");952            if (aotc->org!=INVALID_PTR)953              LexExcept(cc,"Just one org allowed ");954            if (aotc->rip)955              LexExcept(cc,"ORG must be at beginning ");956            aotc->org=AsmLexExpression(cc);957            break;958          case AKW_ALIGN:959            if (cc->htc.local_var_lst)960              LexExcept(cc,"ALIGN not allowed in fun asm blk ");961            i=AsmLexExpression(cc);962            j=Bsf(i);963            if (!i || j!=Bsr(i))964              LexExcept(cc,"ALIGN must be power of two at ");965            if (!(cc->flags&CCF_AOT_COMPILE) && i>8)966              LexExcept(cc,"In JIT mode, max ALIGN is 8 ");967            if (j>aotc->max_align_bits) aotc->max_align_bits=j;968            i=CeilU64(aotc->rip,i);969            if (cc->token!=',')970              LexExcept(cc,"Expecting ',' at ");971            Lex(cc);972            k=AsmLexExpression(cc);973            for (j=aotc->rip;j<i;j++)974              AOTStoreCodeU8(cc,k);975            break;976          case AKW_DU8:977            PrsAsmDefine(cc,1);978            break;979          case AKW_DU16:980            PrsAsmDefine(cc,2);981            break;982          case AKW_DU32:983            PrsAsmDefine(cc,4);984            break;985          case AKW_DU64:986            PrsAsmDefine(cc,8);987            break;988          case AKW_BINFILE:989            PrsBinFile(cc);990            break;991          case AKW_LIST:992            aotc->lst=TRUE;993            break;994          case AKW_NOLIST:995            aotc->lst=FALSE;996            break;997          case AKW_USE16:998            aotc->seg_size=16;999            break;1000          case AKW_USE32:1001            aotc->seg_size=32;1002            break;1003          case AKW_USE64:1004            aotc->seg_size=64;1005            break;1006          default:1007            LexExcept(cc,"Syntax error at ");1008        }1009      } else if (cc->hash_entry->type & HTT_OPCODE) {1010        tmpo=cc->hash_entry;1011        Lex(cc); //skip opcode1012        argcnt=0;1013        if (tmpo->ins[0].arg1) {1014          argcnt++;1015          if (ARGT_REL8<=tmpo->ins[0].arg1<=ARGT_REL32)1016            PrsAsmArg(cc,&aotc->arg1,TRUE);1017          else1018            PrsAsmArg(cc,&aotc->arg1,FALSE);1019          if (tmpo->ins[0].arg2) {1020            argcnt++;1021            if (cc->token!=',')1022              LexExcept(cc,"Expecting ',' at ");1023            else {1024              Lex(cc); //skip ','1025              if (ARGT_REL8<=tmpo->ins[0].arg2<=ARGT_REL32)1026                PrsAsmArg(cc,&aotc->arg2,TRUE);1027              else1028                PrsAsmArg(cc,&aotc->arg2,FALSE);1029            }1030          }1031        }1032        PrsAsmInst(cc,tmpo,argcnt);1033      } else if (cc->hash_entry->type & HTT_EXPORT_SYS_SYM) {1034        if (Btr(&cc->hash_entry->type,HTf_UNRESOLVED)) {1035          if (cc->hash_entry->type & HTF_LOCAL) {1036            cc->hash_entry(CHashExport *)->val=aotc->rip;1037            if (Lex(cc)!=':')1038              LexExcept(cc,"Expecting ':' at ");1039            Lex(cc);1040          } else {1041            if (cc->hash_entry->type & HTF_IMPORT)1042              LexExcept(cc,"attempt to define import at ");1043            cc->hash_entry(CHashExport *)->val=aotc->rip;1044            next_last_label=cc->hash_entry->str;1045            Lex(cc); //Skip cur_str1046            if (cc->token!=':' && cc->token!=TK_DBL_COLON)1047              LexExcept(cc,"Expecting ':' at ");1048            if (cc->token==TK_DBL_COLON) {1049              cc->hash_entry->type|=HTF_EXPORT;1050              HashSrcFileSet(cc,cc->hash_entry);1051 1052              AOTLocalsResolve(cc);1053              aotc->last_label=next_last_label;1054            }1055            Lex(cc);1056          }1057        } else if (cc->hash_entry(CHashExport *)->val==aotc->rip) {1058          Lex(cc); //Skip cur_str1059          if (cc->token!=':' && cc->token!=TK_DBL_COLON)1060            LexExcept(cc,"Expecting ':' at ");1061          Lex(cc);1062        } else1063          LexExcept(cc,"Redefinition at ");1064      } else1065        LexExcept(cc,"Syntax error at ");1066    } else if (cc->token==TK_IDENT) {1067      tmpex=CAlloc(sizeof(CHashExport));1068      tmpex->str=cc->cur_str;1069      cc->cur_str=0;1070      tmpex->type=HTT_EXPORT_SYS_SYM;1071      tmpex->val=aotc->rip;1072      Lex(cc);  //Skip cur_str1073      if (cc->token!=':' && cc->token!=TK_DBL_COLON)1074        LexExcept(cc,"Expecting ':' at ");1075      else {1076        if (*tmpex->str=='@' && tmpex->str[1]=='@') {1077          if (cc->token==TK_DBL_COLON)1078            LexExcept(cc,"No local glbl exports at ");1079          HashAdd(tmpex,cc->htc.local_hash_table);1080        } else1081          HashAdd(tmpex,cc->htc.glbl_hash_table);1082        if (cc->htc.local_var_lst) {//AsmBlk in fun? Also add goto-like label.1083          if (!(g_lb=COCGoToLabelFind(cc,tmpex->str))) {1084            g_lb=COCMiscNew(cc,CMT_ASM_LABEL);1085            g_lb->str=StrNew(tmpex->str);1086          } else if (g_lb->flags&CMF_DEFINED)1087            LexExcept(cc,"Duplicate goto label at ");1088          g_lb->type=CMT_ASM_LABEL;1089          g_lb->flags|=CMF_DEFINED;1090          g_lb->rip=aotc->rip;1091          g_lb->use_cnt++; //Disable warning on unused labels.1092          ICAdd(cc,IC_LABEL,g_lb,0);1093        }1094        if (cc->token==TK_DBL_COLON) {1095          tmpex->type|=HTF_EXPORT;1096          HashSrcFileSet(cc,tmpex);1097 1098          AOTLocalsResolve(cc);1099          aotc->last_label=tmpex->str;1100        }1101        Lex(cc);1102      }1103    } else if (cc->token==';')1104      Lex(cc);1105    else1106      LexExcept(cc,"Syntax error at ");1107    if (cmp_flags&CMPF_ONE_ASM_INS && (cc->token!=TK_IDENT ||1108          !(tmpo=cc->hash_entry) ||1109          !(tmpo->type&(HTT_OPCODE|HTT_ASM_KEYWORD))))1110      break;1111  }1112  AOTLocalsResolve(cc);1113  aotc->lst=FALSE;1114  cc->flags&=cc->flags&~CCF_ASM_EXPRESSIONS|old_flags;1115}1116