hschumann2/TempleOS-Source-Code
0838
1 2U0 ICUnaries(CIntermediateCode *tmpi,I64 op,I64 rip)3{4 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,5 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);6 ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip);7 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,8 MDF_REG+RT_I64,REG_RAX,0,rip);9}10 11U0 ICNot(CIntermediateCode *tmpi,I64 rip)12{13 I64 i;14 if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {15 i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);16 ICRex(tmpi,i.u8[1]);17 ICU16(tmpi,i.u8[2]<<8+0xF6); //TEST ?,0xFF18 ICModr2(tmpi,i,,tmpi->arg1.disp,rip+1);19 ICU8(tmpi,0xFF);20 } else {21 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,22 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);23 ICTest(tmpi,REG_RAX);24 }25 ICU24(tmpi,0xC0940F); //SETZ AL26 ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL27 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,28 MDF_REG+RT_U64,REG_RAX,0,rip);29}30 31U0 ICAndAnd(CIntermediateCode *tmpi,I64 rip)32{33 I64 r2;34 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,35 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);36 if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {37 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,38 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);39 r2=REG_RDX;40 } else41 r2=tmpi->arg1.reg;42 ICZero(tmpi,REG_RAX);43 ICTest(tmpi,r2);44 ICU16(tmpi,0x0874);45 ICTest(tmpi,REG_RCX);46 ICU16(tmpi,0x0374);47 ICU24(tmpi,0xC0FF48);48 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,49 MDF_REG+RT_I64,REG_RAX,0,rip);50}51 52U0 ICOrOr(CIntermediateCode *tmpi,I64 rip)53{54 I64 i=0x48,r2;55 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,56 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);57 if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {58 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,59 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);60 r2=REG_RDX;61 } else62 r2=tmpi->arg1.reg;63 64 if (r2>7) {65 i++;66 r2&=7;67 }68 ICZero(tmpi,REG_RAX);69 ICU24(tmpi,0xC80B00+i+r2<<16);70 ICU16(tmpi,0x0374);71 ICU24(tmpi,0xC0FF48);72 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,73 MDF_REG+RT_I64,REG_RAX,0,rip);74}75 76U0 ICXorXor(CIntermediateCode *tmpi,I64 rip)77{78 I64 r2;79 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,80 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);81 if (!(tmpi->arg1.type&MDF_REG)) {82 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,83 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);84 r2=REG_RDX;85 } else86 r2=tmpi->arg1.reg;87 ICZero(tmpi,REG_RBX);88 ICTest(tmpi,r2);89 ICU16(tmpi,0x0374);90 ICU24(tmpi,0xC3FF48);91 92 ICZero(tmpi,REG_RAX);93 ICTest(tmpi,REG_RCX);94 ICU16(tmpi,0x0374);95 ICU24(tmpi,0xC0FF48);96 97 ICU24(tmpi,0xC33348);98 99 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,100 MDF_REG+RT_I64,REG_RAX,0,rip);101}102 103U0 ICCmp(CIntermediateCode *tmpi,I64 us,I64 is,I64 rip)104{105 I64 r1,d1,r2,i=0x48,j=tmpi->arg2.disp;106 if (tmpi->arg2.type&MDF_IMM && I32_MIN<=j<=I32_MAX) {107 if (!(tmpi->ic_flags&(ICF_POP_CMP|ICF_PUSH_CMP)) &&108 tmpi->arg1.type&MDF_DISP && //TODO109 tmpi->arg1.type.raw_type>=RT_I64 && tmpi->arg1.reg!=REG_RAX) {110 r1=tmpi->arg1.reg;111 d1=tmpi->arg1.disp;112 ICZero(tmpi,REG_RAX);113 if (r1>7)114 i++;115 if (I8_MIN<=j<=I8_MAX)116 i+=0x388300;117 else118 i+=0x388100;119 if (!d1) {120 ICU24(tmpi,0x000000+i+(r1&7)<<16);121 } else if (I8_MIN<=d1<=I8_MAX) {122 ICU24(tmpi,0x400000+i+(r1&7)<<16);123 ICU8(tmpi,d1);124 } else {125 ICU24(tmpi,0x800000+i+(r1&7)<<16);126 ICU32(tmpi,d1);127 }128 if (I8_MIN<=j<=I8_MAX)129 ICU8(tmpi,j);130 else131 ICU32(tmpi,j);132 } else {133 if (tmpi->ic_flags & ICF_POP_CMP) {134 ICPopRegs(tmpi,1<<REG_RCX);135 r1=REG_RCX;136 } else {137 if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)138 r1=tmpi->arg1.reg;139 else {140 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,141 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);142 r1=REG_RCX;143 }144 }145 ICZero(tmpi,REG_RAX);146 if (r1>7)147 i++;148 if (I8_MIN<=j<=I8_MAX) {149 ICU24(tmpi,0xF88300+i+(r1&7)<<16);150 ICU8(tmpi,j);151 } else {152 ICU24(tmpi,0xF88100+i+(r1&7)<<16);153 ICU32(tmpi,j);154 }155 }156 if (tmpi->ic_flags & ICF_PUSH_CMP)157 ICPush(tmpi,MDF_IMM+RT_I64,0,j,rip);158 if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||159 tmpi->ic_flags & ICF_USE_UNSIGNED)160 is=us;161 ICU16(tmpi,0x300+is);162 ICU24(tmpi,0xC0FF48);163 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,164 MDF_REG+RT_I64,REG_RAX,0,rip);165 } else {166 if (tmpi->arg2.type&MDF_REG && tmpi->arg2.reg!=REG_RAX)167 r2=tmpi->arg2.reg;168 else {169 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,170 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);171 r2=REG_RCX;172 }173 if (tmpi->ic_flags & ICF_POP_CMP) {174 ICPopRegs(tmpi,1<<REG_RDX);175 r1=REG_RDX;176 } else {177 if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)178 r1=tmpi->arg1.reg;179 else {180 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,181 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);182 r1=REG_RDX;183 }184 }185 ICZero(tmpi,REG_RAX);186 if (r2>7)187 i++;188 if (r1>7)189 i+=4;190 if (tmpi->ic_flags & ICF_PUSH_CMP)191 ICPushRegs(tmpi,1<<r2);192 ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);193 if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||194 tmpi->ic_flags & ICF_USE_UNSIGNED)195 is=us;196 ICU16(tmpi,0x300+is);197 ICU24(tmpi,0xC0FF48);198 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,199 MDF_REG+RT_I64,REG_RAX,0,rip);200 }201}202 203U0 ICBitOps(CIntermediateCode *tmpi,CICArg *arg1,CICArg *arg2,204 CIntermediateCode *tmpi2,I64 op,I64 op_imm,I64 rip)205{//TODO:not fully utilizing Modr206 Bool res_not_used=ToBool(tmpi2->ic_flags&ICF_RES_NOT_USED);207 I64 r1,t2,r2,d2,i=0x48;208 if (tmpi->ic_flags & ICF_BY_VAL) {209 t2=arg2->type&MDG_MASK+RT_I64; //TODO: check overflow210 r2=arg2->reg;211 d2=arg2->disp;212 if (!(t2&MDG_REG_DISP_SIB_RIP) || !(r2.u8[0]!=REG_RAX&&(!(t2&MDF_SIB) ||213 r2.u8[1]&15!=REG_RAX) || res_not_used)) {214 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);215 t2=MDF_REG+RT_I64;216 r2=REG_RCX;217 d2=0;218 }219 if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))220 r1=arg1->reg;221 else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {222 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);223 r1=REG_RDX;224 } else225 r1=0;226 } else {227 t2=MDF_DISP+RT_I64;228 d2=0;229 if (arg2->type&MDF_REG && (arg2->reg!=REG_RAX||res_not_used))230 r2=arg2->reg;231 else {232 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip);233 r2=REG_RCX;234 }235 if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))236 r1=arg1->reg;237 else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {238 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);239 r1=REG_RDX;240 } else241 r1=0;242 }243 if (!res_not_used)244 ICZero(tmpi,REG_RAX);245 if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)246 ICU8(tmpi,OC_LOCK_PREFIX);247 if (arg1->type&MDF_IMM && arg1->disp<32)248 t2=t2&MDG_MASK+RT_U32;249 i=ICModr1(r1,t2,r2,d2);250 ICRex(tmpi,i.u8[1]);251 if (arg1->type&MDF_IMM && arg1->disp<64) {252 ICU24(tmpi,i.u8[2]<<16+op_imm);253 ICModr2(tmpi,i,,d2,rip+1);254 ICU8(tmpi,arg1->disp);255 } else {256 ICU24(tmpi,i.u8[2]<<16+op);257 ICModr2(tmpi,i,,d2,rip);258 }259 if (!res_not_used) {260 ICU24(tmpi,0xC0920F); //SETC AL261 if (tmpi->res.type.mode)262 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,263 MDF_REG+RT_I64,REG_RAX,0,rip);264 }265}266 267U0 ICToUpper(CIntermediateCode *tmpi,I64 rip)268{269 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,270 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);271 ICU32(tmpi,0x61F88348);272 ICU16(tmpi,0x0A7C);273 ICU32(tmpi,0x7AF88348);274 ICU16(tmpi,0x047F);275 ICU32(tmpi,0xE0C08348);276}277 278U0 ICToI64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)279{280 ICFCvt(cc,tmpi,REG_RAX,281 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,TRUE,CN_INST,rip);282}283 284U0 ICToF64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)285{286 ICFCvt(cc,tmpi,REG_RAX,287 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,FALSE,CN_INST,rip);288}289 290U0 ICToBool(CCmpCtrl *,CIntermediateCode *tmpi,I64 rip)291{292 I64 r;293 if (tmpi->arg1.type&MDF_REG)294 r=tmpi->arg1.reg;295 else {296 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,297 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);298 r=REG_RAX;299 }300 ICTest(tmpi,r);301 ICU24(tmpi,0xC0950F); //SETNZ AL302 ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL303}304 305U0 ICPreIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)306{307 I64 r;308 CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;309 if (tmpi->ic_flags & ICF_BY_VAL) {310 if (tmpc->ptr_stars_cnt && tmpc1->size!=1) {311 ICAddSubEctImm(tmpi,312 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,313 tmpi->arg1.reg,tmpi->arg1.disp,314 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,315 tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);316 } else317 ICSlashOp(tmpi,318 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,319 tmpi->arg1.reg,tmpi->arg1.disp,op,rip);320 if (tmpi->res.type.mode)321 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,322 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,323 tmpi->arg1.reg,tmpi->arg1.disp,rip);324 } else {325 if (tmpi->arg1.type&MDF_REG)326 r=tmpi->arg1.reg;327 else {328 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,329 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);330 r=REG_RCX;331 }332 if (tmpc->ptr_stars_cnt &&333 tmpc1->size!=1) {334 ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,335 MDF_DISP+tmpi->arg1_type_pointed_to,r,0,336 tmpc1->size,op.u16[3],rip);337 } else338 ICSlashOp(tmpi,339 MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);340 if (tmpi->res.type.mode)341 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,342 MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);343 }344}345 346U0 ICPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)347{348 I64 r;349 CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;350 if (tmpi->ic_flags & ICF_BY_VAL) {351 if (tmpi->res.type.mode)352 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,353 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,354 tmpi->arg1.reg,tmpi->arg1.disp,rip);355 if (tmpc->ptr_stars_cnt && tmpc1->size!=1)356 ICAddSubEctImm(tmpi,357 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,358 tmpi->arg1.reg,tmpi->arg1.disp,359 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,360 tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);361 else362 ICSlashOp(tmpi,363 tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,364 tmpi->arg1.reg,tmpi->arg1.disp,op,rip);365 } else {366 if (tmpi->arg1.type&MDF_REG &&367 !(tmpi->res.type&MDF_REG && tmpi->res.reg==tmpi->arg1.reg))368 r=tmpi->arg1.reg;369 else {370 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,371 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);372 r=REG_RCX;373 }374 if (tmpi->res.type.mode)375 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,376 MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);377 if (tmpc->ptr_stars_cnt && tmpc1->size!=1)378 ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,379 MDF_DISP+tmpi->arg1_type_pointed_to,r,0,tmpc1->size,op.u16[3],rip);380 else381 ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);382 }383}384 385U0 ICDerefPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)386{387 CICType t;388 I64 r;389 CHashClass *tmpc1=tmpi->ic_class;390 t=tmpi->res.type.raw_type;391 if (t>tmpi->arg1_type_pointed_to)392 t=tmpi->arg1_type_pointed_to;393 if (tmpi->ic_flags & ICF_BY_VAL) {394 if (tmpi->arg1.type&MDF_REG)395 r=tmpi->arg1.reg;396 else {397 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,398 tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);399 r=REG_RDX;400 }401 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,402 MDF_DISP+t,r,0,rip);403 if (tmpc1->size!=1)404 ICAddSubEctImm(tmpi,405 tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,406 tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,407 tmpc1->size,op.u16[3],rip);408 else409 ICSlashOp(tmpi,tmpi->arg1.type&MDG_MASK+RT_I64,410 tmpi->arg1.reg,tmpi->arg1.disp,op,rip);411 } else {412 if (tmpi->arg1.type&MDF_REG)413 r=tmpi->arg1.reg;414 else {415 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,416 tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);417 r=REG_RCX;418 }419 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r,0,rip);420 if (tmpc1->size!=1)421 ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,r,0,MDF_DISP+RT_I64,r,0,422 tmpc1->size,op.u16[3],rip);423 else424 ICSlashOp(tmpi,MDF_DISP+RT_I64,r,0,op,rip);425 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,426 MDF_DISP+t,REG_RDX,0,rip);427 }428}429 430U0 ICAssignPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)431{432 CHashClass *tmpc1=tmpi->ic_class2-1;433 I64 r;434 if (tmpi->ic_flags & ICF_BY_VAL) {435 if (tmpi->arg1.type&MDF_REG)436 r=tmpi->arg1.reg;437 else {438 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,439 tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);440 r=REG_RDX;441 }442 ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,443 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);444 if (tmpi->res.type.mode)445 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,446 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);447 if (tmpc1->size!=1 || tmpi->arg1.type&MDF_STK)448 ICAddSubEctImm(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,449 MDF_REG+RT_I64,r,0,tmpc1->size,op.u16[3],rip);450 else451 ICSlashOp(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,op,rip);452 } else {453 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,454 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);455 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_I64,REG_RDX,0,rip);456 ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,457 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);458 if (tmpi->res.type.mode)459 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,460 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);461 if (tmpc1->size!=1)462 ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,REG_RDX,0,463 MDF_REG+RT_I64,REG_RCX,0,tmpc1->size,op.u16[3],rip);464 else465 ICSlashOp(tmpi,MDF_DISP+RT_I64,REG_RDX,0,op,rip);466 }467}468 469U0 ICCmpAndBranch(CIntermediateCode *tmpi,Bool has_res,I64 rip,470 I64 us,I64 is,I64 not_us,I64 not_is,U8 *buf,I64 rip2)471{472 I64 r1,r2,i=0x48,j,res_reg;473 CICType t1,t2;474 Bool short_jmp,swap,done;475 CCodeMisc *lb;476 CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;477 478 j=arg1->disp;479 if (arg1->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {480 SwapI64(&arg1,&arg2);481 swap=TRUE;482 us=not_us;483 is=not_is;484 } else485 swap=FALSE;486 if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||487 tmpi->ic_flags & ICF_USE_UNSIGNED)488 is=us;489 490 j=arg2->disp;491 if (arg2->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {492 if (!has_res && arg1->type&MDG_REG_DISP_SIB_RIP)493 ICAddSubEctImm(tmpi,arg1->type,arg1->reg,arg1->disp,494 arg1->type,arg1->reg,arg1->disp,j,0x073B,rip2);495 else {496 if (arg1->type&MDF_REG)497 r1=arg1->reg;498 else {499 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,500 arg1->reg,arg1->disp,rip2);501 r1=REG_RDX;502 }503 if (!j) {504 if (is.u8[2]==0x7C) {505 ICTest(tmpi,r1);506 is=0x78880F;507 } else if (is.u8[2]==0x7D) {508 ICTest(tmpi,r1);509 is=0x79890F;510 } else if (is.u8[2]==0x74 || is.u8[2]==0x75)511 ICTest(tmpi,r1);512 else {513 if (r1>7)514 i++;515 ICU24(tmpi,0xF88300+i+(r1&7)<<16);516 ICU8(tmpi,j);517 }518 } else {519 if (r1>7)520 i++;521 if (I8_MIN<=j<=I8_MAX) {522 ICU24(tmpi,0xF88300+i+(r1&7)<<16);523 ICU8(tmpi,j);524 } else {525 ICU24(tmpi,0xF88100+i+(r1&7)<<16);526 ICU32(tmpi,j);527 }528 }529 }530 if (has_res) {531 if (!swap) {532 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_IMM+RT_I64,0,j,rip2);533 res_reg=REG_RCX;534 } else535 res_reg=r1;536 }537 } else {538 done=FALSE;539 t1=arg1->type;540 r1=arg1->reg;541 r2=arg2->reg;542 t2=arg2->type;543 if (t2.raw_type>=RT_I64 && !has_res && t2&MDG_DISP_SIB_RIP) {544 if (!(t1&MDF_REG) || t1.raw_type<RT_I64) {545 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,546 arg1->reg,arg1->disp,rip2);547 r1=REG_RAX;548 }549 i=ICModr1(r1,t2,r2,arg2->disp);550 ICRex(tmpi,i.u8[1]);551 ICU16(tmpi,i.u8[2]<<8+0x3B);552 ICModr2(tmpi,i,,arg2->disp,rip2);553 done=TRUE;554 } else if (t1.raw_type>=RT_I64 && t1&MDG_REG_DISP_SIB_RIP) {555 if (!(t2&MDF_REG) || t2.raw_type<RT_I64) {556 if (t1&MDF_REG && r1==REG_RAX) {557 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,558 arg2->reg,arg2->disp,rip2);559 r2=REG_RCX;560 } else {561 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,562 arg2->reg,arg2->disp,rip2);563 r2=REG_RAX;564 }565 }566 i=ICModr1(r2,t1,r1,arg1->disp);567 ICRex(tmpi,i.u8[1]);568 ICU16(tmpi,i.u8[2]<<8+0x39);569 ICModr2(tmpi,i,,arg1->disp,rip2);570 if (has_res)571 res_reg=r2;572 done=TRUE;573 }574 if (!done) {575 if (arg2->type&MDF_REG)576 r2=arg2->reg;577 else {578 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,579 arg2->reg,arg2->disp,rip2);580 r2=REG_RAX;581 }582 if (arg1->type&MDF_REG)583 r1=arg1->reg;584 else {585 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,586 arg1->reg,arg1->disp,rip2);587 r1=REG_RCX;588 }589 if (r2>7)590 i++;591 if (r1>7)592 i+=4;593 ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);594 if (has_res)595 res_reg=r2;596 }597 }598 599 rip+=tmpi->ic_cnt;600 lb=OptLabelFwd(tmpi->ic_data);601 short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);602 if (!buf && lb->addr!=INVALID_PTR) {603 i=lb->addr-(rip+2);604 if (lb->flags&CMF_POP_CMP) {605 if(tmpi->ic_flags&ICF_PUSH_CMP)606 i+=4;607 else608 i+=8;609 }610 if (I8_MIN<=i<=I8_MAX)611 short_jmp=TRUE;612 }613 614 if (short_jmp) {615 tmpi->ic_flags|=ICF_SHORT_JMP;616 i=lb->addr-(rip+2);617 if (lb->flags&CMF_POP_CMP) {618 if(tmpi->ic_flags&ICF_PUSH_CMP)619 i+=4;620 else621 i+=8;622 }623 ICU16(tmpi,i<<8+is.u8[2]);624 } else {625 tmpi->ic_flags&=~ICF_SHORT_JMP;626 i=lb->addr-(rip+6);627 if (lb->flags&CMF_POP_CMP) {628 if(tmpi->ic_flags&ICF_PUSH_CMP)629 i+=4;630 else631 i+=8;632 }633 ICU16(tmpi,is.u16[0]);634 ICU32(tmpi,i);635 }636 if (has_res)637 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,638 MDF_REG+RT_I64,res_reg,0,rip2);639}640 641U0 ICTestAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)642{643 I64 i;644 Bool short_jmp;645 CCodeMisc *lb;646 647 if (!(tmpi->arg1.type&MDF_REG)) {648 if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {649 i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);650 ICRex(tmpi,i.u8[1]);651 ICU16(tmpi,i.u8[2]<<8+0xF6);652 ICModr2(tmpi,i,,tmpi->arg1.disp,rip2+1);653 ICU8(tmpi,0xFF);654 } else {655 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,656 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);657 ICTest(tmpi,REG_RAX);658 }659 } else660 ICTest(tmpi,tmpi->arg1.reg);661 662 rip+=tmpi->ic_cnt;663 lb=OptLabelFwd(tmpi->ic_data);664 short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);665 if (!buf && lb->addr!=INVALID_PTR) {666 i=lb->addr-(rip+2);667 if (lb->flags&CMF_POP_CMP)668 i+=8;669 if (I8_MIN<=i<=I8_MAX)670 short_jmp=TRUE;671 }672 673 if (short_jmp) {674 tmpi->ic_flags|=ICF_SHORT_JMP;675 i=lb->addr-(rip+2);676 if (lb->flags&CMF_POP_CMP)677 i+=8;678 ICU16(tmpi,i<<8+is.u8[2]);679 } else {680 tmpi->ic_flags&=~ICF_SHORT_JMP;681 i=lb->addr-(rip+6);682 if (lb->flags&CMF_POP_CMP)683 i+=8;684 ICU16(tmpi,is.u16[0]);685 ICU32(tmpi,i);686 }687}688 689U0 ICFlagBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf)690{691 I64 i;692 Bool short_jmp;693 CCodeMisc *lb;694 695 rip+=tmpi->ic_cnt;696 lb=OptLabelFwd(tmpi->ic_data);697 short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);698 if (!buf && lb->addr!=INVALID_PTR) {699 i=lb->addr-(rip+2);700 if (lb->flags&CMF_POP_CMP)701 i+=8;702 if (I8_MIN<=i<=I8_MAX)703 short_jmp=TRUE;704 }705 706 if (short_jmp) {707 tmpi->ic_flags|=ICF_SHORT_JMP;708 i=lb->addr-(rip+2);709 if (lb->flags&CMF_POP_CMP)710 i+=8;711 ICU16(tmpi,i<<8+is.u8[2]);712 } else {713 tmpi->ic_flags&=~ICF_SHORT_JMP;714 i=lb->addr-(rip+6);715 if (lb->flags&CMF_POP_CMP)716 i+=8;717 ICU16(tmpi,is.u16[0]);718 ICU32(tmpi,i);719 }720}721 