void rewriteCopysign(Binary* curr) { Literal signBit, otherBits; UnaryOp int2float, float2int; BinaryOp bitAnd, bitOr; switch (curr->op) { case CopySignFloat32: float2int = ReinterpretFloat32; int2float = ReinterpretInt32; bitAnd = AndInt32; bitOr = OrInt32; signBit = Literal(uint32_t(1 << 31)); otherBits = Literal(uint32_t(1 << 31) - 1); break; case CopySignFloat64: float2int = ReinterpretFloat64; int2float = ReinterpretInt64; bitAnd = AndInt64; bitOr = OrInt64; signBit = Literal(uint64_t(1) << 63); otherBits = Literal((uint64_t(1) << 63) - 1); break; default: return; } replaceCurrent( builder->makeUnary( int2float, builder->makeBinary( bitOr, builder->makeBinary( bitAnd, builder->makeUnary( float2int, curr->left ), builder->makeConst(otherBits) ), builder->makeBinary( bitAnd, builder->makeUnary( float2int, curr->right ), builder->makeConst(signBit) ) ) ) ); }
void visitStore(Store* curr) { if (curr->align == 0 || curr->align >= curr->bytes) { return; } // Switch unaligned stores of floats to unaligned stores of integers (which // we can actually implement) and then use reinterpretation to store the // right value. switch (curr->valueType) { case f32: curr->valueType = i32; curr->value = builder->makeUnary(ReinterpretFloat32, curr->value); break; case f64: curr->valueType = i64; curr->value = builder->makeUnary(ReinterpretFloat64, curr->value); break; default: break; } }
void visitLoad(Load* curr) { if (curr->align == 0 || curr->align >= curr->bytes) { return; } // Switch unaligned loads of floats to unaligned loads of integers (which we // can actually implement) and then use reinterpretation to get the float // back out. switch (curr->type) { case f32: curr->type = i32; replaceCurrent(builder->makeUnary(ReinterpretInt32, curr)); break; case f64: curr->type = i64; replaceCurrent(builder->makeUnary(ReinterpretInt64, curr)); break; default: break; } }