void PPCXEmitter::MOVI2F (PPCReg dest, float imm, bool negate) { u32 tmp; union convert { unsigned int i; float f; } fc; fc.f = imm; MOVI2R(R6, fc.i); // R7 = imm MOVI2R(R7, (u32)&tmp); STW(R6, R7); // dest = R7 LFS(dest, R7, 0); if (negate == true) { FNEG(dest, dest); } }
/* * dooper() will execute a constant operation in a node and return * the node to be the result of the operation. */ static EXPR *dooper P1 (EXPR *, ep) { EXPRTYPE type = ep->nodetype; ep->nodetype = ep->v.p[0]->nodetype; switch (ep->v.p[0]->nodetype) { #ifdef FLOAT_SUPPORT #ifndef FLOAT_BOOTSTRAP RVAL f; #endif /* FLOAT_BOOTSTRAP */ case en_fcon: #ifndef FLOAT_BOOTSTRAP FASSIGN (f, ep->v.p[0]->v.f); switch (type) { case en_uminus: FASSIGN (ep->v.f, f); FNEG (ep->v.f); break; case en_test: ep->v.i = FTST (f) ? (IVAL) 1 : (IVAL) 0; ep->nodetype = en_icon; break; case en_not: ep->v.i = FTST (f) ? (IVAL) 0 : (IVAL) 1; ep->nodetype = en_icon; break; case en_cast: if (is_real_floating_type (ep->etp)) { ep->v.f = f; } else if (is_bool (ep->etp)) { ep->v.u = (UVAL) (f ? 1 : 0); ep->nodetype = en_icon; } else { FTOL (ep->v.i, f); ep->v.i = strip_icon (ep->v.i, ep->etp); ep->nodetype = en_icon; } break; case en_add: FADD3 (ep->v.f, f, ep->v.p[1]->v.f); break; case en_sub: FSUB3 (ep->v.f, f, ep->v.p[1]->v.f); break; case en_mul: FMUL3 (ep->v.f, f, ep->v.p[1]->v.f); break; case en_div: if (FTST (ep->v.p[1]->v.f)) { FDIV3 (ep->v.f, f, ep->v.p[1]->v.f); } else { ep->nodetype = en_div; } break; case en_eq: ep->v.i = (IVAL) FEQ (f, ep->v.p[1]->v.f); ep->nodetype = en_icon; break; case en_ne: ep->v.i = (IVAL) FNE (f, ep->v.p[1]->v.f); ep->nodetype = en_icon; break; case en_land: ep->v.i = (IVAL) (FTST (f) && FTST (ep->v.p[1]->v.f)); ep->nodetype = en_icon; break; case en_lor: ep->v.i = (IVAL) (FTST (f) || FTST (ep->v.p[1]->v.f)); ep->nodetype = en_icon; break; case en_lt: ep->v.i = (IVAL) FLT (f, ep->v.p[1]->v.f); ep->nodetype = en_icon; break; case en_le: ep->v.i = (IVAL) FLE (f, ep->v.p[1]->v.f); ep->nodetype = en_icon; break; case en_gt: ep->v.i = (IVAL) FGT (f, ep->v.p[1]->v.f); ep->nodetype = en_icon; break; case en_ge: ep->v.i = (IVAL) FGE (f, ep->v.p[1]->v.f); ep->nodetype = en_icon; break; default: CANNOT_REACH_HERE (); break; } break; #endif /* FLOAT_BOOTSTRAP */ #endif /* FLOAT_SUPPORT */ case en_icon: if (is_unsigned_type (ep->v.p[0]->etp)) { UVAL u = ep->v.p[0]->v.u; switch (type) { case en_uminus: /* * unary minus on an unsigned is normally a mistake so we must * fool the compiler into not giving a warning. */ ep->v.u = (UVAL) (-(IVAL) u); break; case en_test: ep->v.u = (u ? (UVAL) 1 : (UVAL) 0); break; case en_not: ep->v.u = (u ? (UVAL) 0 : (UVAL) 1); break; case en_compl: ep->v.u = (UVAL) strip_icon ((IVAL) ~u, ep->etp); break; case en_cast: if (is_bool (ep->etp)) { ep->v.u = (UVAL) (u ? 1 : 0); #ifdef FLOAT_SUPPORT } else if (is_real_floating_type (ep->etp)) { ep->nodetype = en_fcon; UTOF (ep->v.f, u); break; #endif /* FLOAT_SUPPORT */ } else { ep->v.u = (UVAL) strip_icon ((IVAL) u, ep->etp); } break; case en_add: ep->v.u = u + ep->v.p[1]->v.u; break; case en_sub: ep->v.u = u - ep->v.p[1]->v.u; break; case en_mul: ep->v.u = u * ep->v.p[1]->v.u; break; case en_div: if (ep->v.p[1]->v.u == (UVAL) 0) { ep->nodetype = en_div; } else { ep->v.u = u / ep->v.p[1]->v.u; } break; case en_mod: if (ep->v.p[1]->v.u == (UVAL) 0) { ep->nodetype = en_mod; } else { ep->v.u = u % ep->v.p[1]->v.u; } break; case en_and: ep->v.u = u & ep->v.p[1]->v.u; break; case en_or: ep->v.u = u | ep->v.p[1]->v.u; break; case en_xor: ep->v.u = u ^ ep->v.p[1]->v.u; break; case en_eq: ep->v.u = (UVAL) (u == ep->v.p[1]->v.u); break; case en_ne: ep->v.u = (UVAL) (u != ep->v.p[1]->v.u); break; case en_land: ep->v.u = (UVAL) (u && ep->v.p[1]->v.u); break; case en_lor: ep->v.u = (UVAL) (u || ep->v.p[1]->v.u); break; case en_lt: ep->v.u = (UVAL) (u < ep->v.p[1]->v.u); break; case en_le: ep->v.u = (UVAL) (u <= ep->v.p[1]->v.u); break; case en_gt: ep->v.u = (UVAL) (u > ep->v.p[1]->v.u); break; case en_ge: ep->v.u = (UVAL) (u >= ep->v.p[1]->v.u); break; case en_lsh: ep->v.u = u << ep->v.p[1]->v.u; break; case en_rsh: ep->v.u = u >> ep->v.p[1]->v.u; break; default: CANNOT_REACH_HERE (); break; } } else {