Ref makeAsmCoercedZero(AsmType type) { switch (type) { case ASM_INT: return ValueBuilder::makeNum(0); break; case ASM_DOUBLE: return ValueBuilder::makeUnary(PLUS, ValueBuilder::makeNum(0)); break; case ASM_FLOAT: { if (!ASM_FLOAT_ZERO.isNull()) { return ValueBuilder::makeName(ASM_FLOAT_ZERO); } else { return ValueBuilder::makeCall(MATH_FROUND, ValueBuilder::makeNum(0)); } break; } case ASM_FLOAT32X4: { return ValueBuilder::makeCall(SIMD_FLOAT32X4, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); break; } case ASM_FLOAT64X2: { return ValueBuilder::makeCall(SIMD_FLOAT64X2, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); break; } case ASM_INT8X16: { return ValueBuilder::makeCall(SIMD_INT8X16, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); break; } case ASM_INT16X8: { return ValueBuilder::makeCall(SIMD_INT16X8, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); break; } case ASM_INT32X4: { return ValueBuilder::makeCall(SIMD_INT32X4, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); break; } default: assert(0); } abort(); }
AsmType detectType(Ref node, AsmData *asmData, bool inVarDef, IString minifiedFround) { switch (node[0]->getCString()[0]) { case 'n': { if (node[0] == NUM) { if (!isInteger(node[1]->getNumber())) return ASM_DOUBLE; return ASM_INT; } else if (node[0] == NAME) { if (asmData) { AsmType ret = asmData->getType(node[1]->getCString()); if (ret != ASM_NONE) return ret; } if (!inVarDef) { if (node[1] == INF || node[1] == NaN) return ASM_DOUBLE; if (node[1] == TEMP_RET0) return ASM_INT; return ASM_NONE; } // We are in a variable definition, where Math_fround(0) optimized into a global constant becomes f0 = Math_fround(0) if (ASM_FLOAT_ZERO.isNull()) ASM_FLOAT_ZERO = node[1]->getIString(); else assert(node[1] == ASM_FLOAT_ZERO); return ASM_FLOAT; } break; } case 'u': { if (node[0] == UNARY_PREFIX) { switch (node[1]->getCString()[0]) { case '+': return ASM_DOUBLE; case '-': return detectType(node[2], asmData, inVarDef, minifiedFround); case '!': case '~': return ASM_INT; } break; } break; } case 'c': { if (node[0] == CALL) { if (node[1][0] == NAME) { IString name = node[1][1]->getIString(); if (name == MATH_FROUND || name == minifiedFround) return ASM_FLOAT; else if (name == SIMD_FLOAT32X4 || name == SIMD_FLOAT32X4_CHECK) return ASM_FLOAT32X4; else if (name == SIMD_FLOAT64X2 || name == SIMD_FLOAT64X2_CHECK) return ASM_FLOAT64X2; else if (name == SIMD_INT8X16 || name == SIMD_INT8X16_CHECK) return ASM_INT8X16; else if (name == SIMD_INT16X8 || name == SIMD_INT16X8_CHECK) return ASM_INT16X8; else if (name == SIMD_INT32X4 || name == SIMD_INT32X4_CHECK) return ASM_INT32X4; } return ASM_NONE; } else if (node[0] == CONDITIONAL) { return detectType(node[2], asmData, inVarDef, minifiedFround); } break; } case 'b': { if (node[0] == BINARY) { switch (node[1]->getCString()[0]) { case '+': case '-': case '*': case '/': case '%': return detectType(node[2], asmData, inVarDef, minifiedFround); case '|': case '&': case '^': case '<': case '>': // handles <<, >>, >>=, <=, >= case '=': case '!': { // handles ==, != return ASM_INT; } } } break; } case 's': { if (node[0] == SEQ) { return detectType(node[2], asmData, inVarDef, minifiedFround); } else if (node[0] == SUB) { assert(node[1][0] == NAME); HeapInfo info = parseHeap(node[1][1]->getCString()); if (info.valid) return ASM_NONE; return info.floaty ? ASM_DOUBLE : ASM_INT; // XXX ASM_FLOAT? } break; } } //dump("horrible", node); //assert(0); return ASM_NONE; }