예제 #1
0
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();
}
예제 #2
0
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;
}