hschumann2/TempleOS-Source-Code
0838
1 2U0 ICFOpEqu(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,U8 *buf2,I64 rip)3{//for ADD,SUB,DIV,MUL4 CICArg *arg1=&tmpi->arg1,5 *arg2=&tmpi->arg2;6 Bool dont_push_float,dont_pop_float,p1_mem;7 I64 rsp_size=0,builtin2=0,8 t1,r1,d1,t2,r2,d2;9 10 if (cc->flags&CCF_AOT_COMPILE)11 buf2=cc->aotc->rip;12 13 CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);14 if (dont_pop_float)15 throw('Compiler');16 17 if (tmpi->ic_flags & ICF_BY_VAL) {18 p1_mem=FALSE;19 if (dont_push_float) {20 if (tmpi->arg1_type_pointed_to!=RT_F64) {21 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,22 arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,23 arg1->reg,arg1->disp,rip);24 ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);25 ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);26 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;27 rsp_size+=8;28 } else {29 if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {30 t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;31 r1=arg1->reg;32 d1=arg1->disp;33 p1_mem=TRUE;34 } else {35 ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,36 arg1->reg,arg1->disp,rip);37 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;38 rsp_size+=8;39 }40 }41 } else {42 if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {43 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,44 arg2->reg,arg2->disp,rip);45 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,46 arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,47 arg1->reg,arg1->disp,rip);48 if (tmpi->arg1_type_pointed_to!=RT_F64)49 ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);50 ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX51 rsp_size=16;52 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;53 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;54 } else {55 if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {56 t2=arg2->type;57 r2=arg2->reg;58 d2=arg2->disp;59 } else {60 if (arg2->type&MDF_IMM) {61 if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {62 t2=MDF_RIP_DISP32+RT_I64;63 r2=REG_RIP;64 d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;65 }66 } else {67 ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);68 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;69 rsp_size+=8;70 }71 }72 if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {73 t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;74 r1=arg1->reg;75 d1=arg1->disp;76 p1_mem=TRUE;77 } else {78 ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,79 arg1->reg,arg1->disp,rip);80 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;81 rsp_size+=8;82 if (r2==REG_RSP+REG_RSP<<8)83 d2+=8;84 }85 }86 }87 if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to==RT_F64)) {88 rsp_size=8;89 ICAddRSP(tmpi,-8);90 }91 if (!dont_push_float) {92 if (builtin2)93 ICU16(tmpi,builtin2);94 else95 ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);96 }97 switch (op.u8[0]) {98 case 4: op=SLASH_OP_FSUBR; break;99 case 6: op=SLASH_OP_FDIVR; break;100 }101 ICSlashOp(tmpi,t1,r1,d1,op,rip);102 CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);103 if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {104 ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FSTP,rip);105 if (rsp_size)106 ICAddRSP(tmpi,rsp_size);107 } else {108 if (rsp_size==8)109 ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);110 else if (rsp_size>8) {111 ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,112 SLASH_OP_FSTP,rip);113 ICAddRSP(tmpi,rsp_size-8);114 }115 if (tmpi->arg1_type_pointed_to!=RT_F64) {116 ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);117 ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);118 ICMov(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,arg1->reg,119 arg1->disp,MDF_REG+RT_I64,REG_RAX,0,rip);120 } else121 ICPop(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,122 arg1->reg,arg1->disp,rip);123 }124 if (tmpi->res.type.mode)125 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,126 arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,127 arg1->reg,arg1->disp,rip);128 } else {129 if (tmpi->arg1_type_pointed_to>=RT_I64)130 p1_mem=TRUE;131 else132 p1_mem=FALSE;133 if (dont_push_float) {134 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,arg1->reg,arg1->disp,rip);135 if (tmpi->arg1_type_pointed_to!=RT_F64) {136 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,137 MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);138 ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);139 ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);140 } else141 ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);142 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;143 rsp_size+=8;144 } else {145 if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {146 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,147 arg2->reg,arg2->disp,rip);148 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,149 arg1->reg,arg1->disp,rip);150 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,151 MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);152 if (tmpi->arg1_type_pointed_to!=RT_F64)153 ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);154 ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX155 rsp_size=16;156 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;157 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;158 } else {159 if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {160 t2=arg2->type;161 r2=arg2->reg;162 d2=arg2->disp;163 } else {164 if (arg2->type&MDF_IMM) {165 if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {166 t2=MDF_RIP_DISP32+RT_I64;167 r2=REG_RIP;168 d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;169 }170 } else {171 ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);172 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;173 rsp_size+=8;174 }175 }176 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,177 arg1->reg,arg1->disp,rip);178 ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);179 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;180 rsp_size+=8;181 if (r2==REG_RSP+REG_RSP<<8)182 d2+=8;183 }184 }185 if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to==RT_F64)) {186 rsp_size=8;187 ICAddRSP(tmpi,-8);188 }189 if (!dont_push_float) {190 if (builtin2)191 ICU16(tmpi,builtin2);192 else193 ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);194 }195 196 switch (op.u8[0]) {197 case 4: op=SLASH_OP_FSUBR; break;198 case 6: op=SLASH_OP_FDIVR; break;199 }200 ICSlashOp(tmpi,t1,r1,d1,op,rip);201 CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);202 if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {203 ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,204 REG_RCX,0,SLASH_OP_FSTP,rip);205 if (rsp_size)206 ICAddRSP(tmpi,rsp_size);207 } else {208 if (rsp_size==8)209 ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);210 else if (rsp_size>8) {211 ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,212 SLASH_OP_FSTP,rip);213 ICAddRSP(tmpi,rsp_size-8);214 }215 ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);216 if (tmpi->arg1_type_pointed_to!=RT_F64)217 ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);218 ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,219 MDF_REG+RT_I64,REG_RAX,0,rip);220 }221 if (tmpi->res.type.mode)222 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,223 MDF_REG+RT_I64,REG_RAX,0,rip);224 }225}226 227U0 ICFCmpAndBranch(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip,228 I64 us,I64 not_us,U8 *buf,I64 rip2)229{230 CICArg *arg1,*arg2;231 Bool dont_push_float,dont_pop_float,alt,short_jmp;232 I64 i,rsp_size=0,builtin1=0,builtin2=0,t1,r1,d1,t2,r2,d2;233 CCodeMisc *lb;234 U8 *buf2;235 236 if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {237 arg1=&tmpi->arg2;238 arg2=&tmpi->arg1;239 alt=TRUE;240 } else {241 arg1=&tmpi->arg1;242 arg2=&tmpi->arg2;243 alt=FALSE;244 }245 246 if (cc->flags&CCF_AOT_COMPILE)247 buf2=cc->aotc->rip;248 else249 buf2=buf;250 251 CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);252 if (dont_push_float) {253 if (tmpi->ic_flags&ICF_POP_CMP && alt) {254 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;255 rsp_size+=8;256 } else {257 if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {258 t2=arg2->type;259 r2=arg2->reg;260 d2=arg2->disp;261 } else {262 if (arg2->type&MDF_IMM) {263 if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||264 tmpi->ic_flags&ICF_PUSH_CMP) {265 t2=MDF_RIP_DISP32+RT_I64;266 r2=REG_RIP;267 d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;268 }269 } else {270 ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);271 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;272 rsp_size+=8;273 }274 }275 }276 } else {277 if (alt) {278 if (!(arg2->type&MDF_STK)) {279 if (tmpi->ic_flags&ICF_POP_CMP) {280 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;281 rsp_size+=8;282 } else {283 if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {284 t1=arg1->type;285 r1=arg1->reg;286 d1=arg1->disp;287 } else {288 if (arg1->type&MDF_IMM) {289 if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {290 t1=MDF_RIP_DISP32+RT_I64;291 r1=REG_RIP;292 d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;293 }294 } else {295 ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);296 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;297 rsp_size+=8;298 }299 }300 }301 if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {302 t2=arg2->type;303 r2=arg2->reg;304 d2=arg2->disp;305 } else {306 if (arg2->type&MDF_IMM) {307 if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||308 tmpi->ic_flags&ICF_PUSH_CMP) {309 t2=MDF_RIP_DISP32+RT_I64;310 r2=REG_RIP;311 d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;312 }313 } else {314 ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);315 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;316 rsp_size+=8;317 if (r1==REG_RSP+REG_RSP<<8)318 d1+=8;319 }320 }321 } else {322 if (tmpi->ic_flags&ICF_POP_CMP)323 ICPopRegs(tmpi,1<<REG_RDX);324 else325 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,326 arg1->reg,arg1->disp,rip2);327 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,328 arg2->reg,arg2->disp,rip2);329 ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX330 rsp_size=16;331 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;332 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;333 }334 } else {335 if (!(arg1->type&MDF_STK)) {336 if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {337 t2=arg2->type;338 r2=arg2->reg;339 d2=arg2->disp;340 } else {341 if (arg2->type&MDF_IMM) {342 if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||343 tmpi->ic_flags&ICF_PUSH_CMP) {344 t2=MDF_RIP_DISP32+RT_I64;345 r2=REG_RIP;346 d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;347 }348 } else {349 ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);350 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;351 rsp_size+=8;352 }353 }354 if (tmpi->ic_flags&ICF_POP_CMP) {355 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;356 rsp_size+=8;357 if (r2==REG_RSP+REG_RSP<<8)358 d1+=8;359 } else {360 if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {361 t1=arg1->type;362 r1=arg1->reg;363 d1=arg1->disp;364 } else {365 if (arg1->type&MDF_IMM) {366 if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {367 t1=MDF_RIP_DISP32+RT_I64;368 r1=REG_RIP;369 d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;370 }371 } else {372 ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);373 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;374 rsp_size+=8;375 if (r2==REG_RSP+REG_RSP<<8)376 d2+=8;377 }378 }379 }380 } else {381 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,382 arg2->reg,arg2->disp,rip2);383 if (tmpi->ic_flags&ICF_POP_CMP)384 ICPopRegs(tmpi,1<<REG_RDX);385 else386 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,387 arg1->reg,arg1->disp,rip2);388 ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX389 rsp_size=16;390 t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;391 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;392 }393 }394 }395 if (!dont_push_float) {396 if (builtin1)397 ICU16(tmpi,builtin1);398 else399 ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip2);400 }401 if (!alt)402 us=not_us;403 if (builtin2)404 ICU16(tmpi,builtin2);405 else406 ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip2);407 if (tmpi->ic_flags&ICF_PUSH_CMP) {408 t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;409 if (!rsp_size) {410 rsp_size=8;411 ICAddRSP(tmpi,-8);412 } else if (rsp_size==16)413 d2=8;414 415 if (alt) {416 ICU16(tmpi,0xF1DF); //FCOMIP417 ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);418 } else {419 ICU16(tmpi,0xF1DB); //FCOMI420 ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);421 ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP422 }423 } else {424 ICU16(tmpi,0xF1DF); //FCOMIP425 ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP426 }427 CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);428 429 if (tmpi->ic_flags&ICF_PUSH_CMP) {430 if (r2.u8[0]==REG_RSP) {431 while (d2 && rsp_size) {432 ICU8(tmpi,0x5B); //POP RBX (Dont change flags)433 rsp_size-=8;434 d2-=8;435 }436 } else {437 while (rsp_size) {438 ICU8(tmpi,0x5B); //POP RBX (Dont change flags)439 rsp_size-=8;440 }441 ICPush(tmpi,t2,r2,d2,rip2);442 }443 } else {444 while (rsp_size) {445 ICU8(tmpi,0x5B); //POP RBX (Dont change flags)446 rsp_size-=8;447 }448 }449 450 rip+=tmpi->ic_cnt;451 lb=OptLabelFwd(tmpi->ic_data);452 short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);453 if (!buf && lb->addr!=INVALID_PTR) {454 i=lb->addr-(rip+2);455 if (lb->flags&CMF_POP_CMP) {456 if(tmpi->ic_flags&ICF_PUSH_CMP)457 i+=4;458 else459 i+=8;460 }461 if (I8_MIN<=i<=I8_MAX)462 short_jmp=TRUE;463 }464 465 if (short_jmp) {466 tmpi->ic_flags|=ICF_SHORT_JMP;467 i=lb->addr-(rip+2);468 if (lb->flags&CMF_POP_CMP) {469 if(tmpi->ic_flags&ICF_PUSH_CMP)470 i+=4;471 else472 i+=8;473 }474 ICU16(tmpi,i<<8+us.u8[2]);475 } else {476 tmpi->ic_flags&=~ICF_SHORT_JMP;477 i=lb->addr-(rip+6);478 if (lb->flags&CMF_POP_CMP) {479 if(tmpi->ic_flags&ICF_PUSH_CMP)480 i+=4;481 else482 i+=8;483 }484 ICU16(tmpi,us.u16[0]);485 ICU32(tmpi,i);486 }487}488 489U0 ICFMul(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)490{491 if (tmpi->arg1.type&MDF_IMM && tmpi->arg1.type&RTG_MASK==RT_F64 &&492 tmpi->arg1.disp(F64)==1.0) {493 CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);494 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,495 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);496 } else if (tmpi->arg2.type&MDF_IMM &&497 tmpi->arg2.type&RTG_MASK==RT_F64&& tmpi->arg2.disp(F64)==1.0) {498 CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);499 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,500 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);501 } else502 ICFOp(cc,tmpi,SLASH_OP_FMUL,buf,rip);503}504 505U0 ICFDiv(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)506{507 if (tmpi->arg2.type&MDF_IMM && tmpi->arg2.type&RTG_MASK==RT_F64 &&508 tmpi->arg2.disp(F64)==1.0) {509 CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);510 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,511 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);512 } else513 ICFOp(cc,tmpi,SLASH_OP_FDIV,buf,rip);514}515 516U0 ICFAdd(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)517{518 Bool dont_push_float,dont_pop_float;519 CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);520 if (tmpi->arg1.type&MDF_IMM && !tmpi->arg1.disp) {521 if (dont_push_float) {522 ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);523 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,524 MDF_REG+RT_I64,REG_RAX,0,rip);525 } else if (dont_pop_float) {526 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,527 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);528 ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);529 } else {530 CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);531 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,532 tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);533 }534 } else if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {535 if (dont_push_float) {536 ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);537 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,538 MDF_REG+RT_I64,REG_RAX,0,rip);539 } else if (dont_pop_float) {540 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,541 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);542 ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);543 } else {544 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,545 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);546 CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);547 }548 } else549 ICFOp(cc,tmpi,SLASH_OP_FADD,buf,rip);550}551 552U0 ICFSub(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)553{554 Bool dont_push_float,dont_pop_float;555 if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {556 CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);557 if (dont_push_float) {558 ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);559 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,560 MDF_REG+RT_I64,REG_RAX,0,rip);561 } else if (dont_pop_float) {562 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,563 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);564 ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);565 } else {566 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,567 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);568 CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);569 }570 } else571 ICFOp(cc,tmpi,SLASH_OP_FSUB,buf,rip);572}573 574U0 ICFPreIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)575{576 if (tmpi->ic_flags & ICF_BY_VAL) {577 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,578 tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);579 ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);580 ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,581 MDF_REG+RT_I64,REG_RAX,0,rip);582 } else {583 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,584 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);585 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);586 ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);587 ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);588 }589 if (tmpi->res.type.mode)590 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,591 MDF_REG+RT_I64,REG_RAX,0,rip);592}593 594U0 ICFPostIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)595{596 if (tmpi->ic_flags & ICF_BY_VAL) {597 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,598 tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);599 if (tmpi->res.type.mode)600 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);601 ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);602 ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,603 MDF_REG+RT_I64,REG_RAX,0,rip);604 } else {605 ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,606 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);607 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);608 if (tmpi->res.type.mode)609 ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);610 ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);611 ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);612 }613 if (tmpi->res.type.mode)614 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,615 MDF_REG+RT_I64,REG_RDX,0,rip);616}617 618U0 ICFTemplateFun(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)619{620 Bool dont_push_float,dont_pop_float;621 622 CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);623 if (!dont_push_float)624 ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,625 tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);626 627 ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);628 if (tmpi->res.type.mode && !(tmpi->ic_flags & ICF_RES_TO_F64) &&629 !(tmpi->ic_flags & ICF_RES_TO_INT))630 ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,631 MDF_REG+RT_I64,REG_RAX,0,rip);632}633 