~ubuntu-branches/ubuntu/saucy/libv8/saucy

« back to all changes in this revision

Viewing changes to src/arm/lithium-arm.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2012-04-07 16:26:13 UTC
  • mfrom: (15.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120407162613-dqo1m6w9r3fh8tst
Tags: 3.8.9.16-3
* mipsel build fixes :
  + v8_use_mips_abi_hardfloat=false, this lowers EABI requirements.
  + v8_can_use_fpu_instructions=false, detect if FPU is present.
  + set -Wno-unused-but-set-variable only on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
1005
1005
  LEnvironment* outer =
1006
1006
      CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
1007
1007
  int ast_id = hydrogen_env->ast_id();
1008
 
  ASSERT(ast_id != AstNode::kNoNumber);
 
1008
  ASSERT(ast_id != AstNode::kNoNumber || hydrogen_env->is_arguments_adaptor());
1009
1009
  int value_count = hydrogen_env->length();
1010
1010
  LEnvironment* result = new LEnvironment(hydrogen_env->closure(),
 
1011
                                          hydrogen_env->is_arguments_adaptor(),
1011
1012
                                          ast_id,
1012
1013
                                          hydrogen_env->parameter_count(),
1013
1014
                                          argument_count_,
1014
1015
                                          value_count,
1015
1016
                                          outer);
 
1017
  int argument_index = *argument_index_accumulator;
1016
1018
  for (int i = 0; i < value_count; ++i) {
1017
1019
    if (hydrogen_env->is_special_index(i)) continue;
1018
1020
 
1021
1023
    if (value->IsArgumentsObject()) {
1022
1024
      op = NULL;
1023
1025
    } else if (value->IsPushArgument()) {
1024
 
      op = new LArgument((*argument_index_accumulator)++);
 
1026
      op = new LArgument(argument_index++);
1025
1027
    } else {
1026
1028
      op = UseAny(value);
1027
1029
    }
1028
1030
    result->AddValue(op, value->representation());
1029
1031
  }
1030
1032
 
 
1033
  if (!hydrogen_env->is_arguments_adaptor()) {
 
1034
    *argument_index_accumulator = argument_index;
 
1035
  }
 
1036
 
1031
1037
  return result;
1032
1038
}
1033
1039
 
1038
1044
 
1039
1045
 
1040
1046
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1041
 
  HValue* v = instr->value();
1042
 
  if (v->EmitAtUses()) {
1043
 
    HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
 
1047
  HValue* value = instr->value();
 
1048
  if (value->EmitAtUses()) {
 
1049
    HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
1044
1050
        ? instr->FirstSuccessor()
1045
1051
        : instr->SecondSuccessor();
1046
1052
    return new LGoto(successor->block_id());
1047
1053
  }
1048
 
  return AssignEnvironment(new LBranch(UseRegister(v)));
 
1054
 
 
1055
  LBranch* result = new LBranch(UseRegister(value));
 
1056
  // Tagged values that are not known smis or booleans require a
 
1057
  // deoptimization environment.
 
1058
  Representation rep = value->representation();
 
1059
  HType type = value->type();
 
1060
  if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean()) {
 
1061
    return AssignEnvironment(result);
 
1062
  }
 
1063
  return result;
1049
1064
}
1050
1065
 
1051
1066
 
1153
1168
    LOperand* input = UseFixedDouble(instr->value(), d2);
1154
1169
    LUnaryMathOperation* result = new LUnaryMathOperation(input, NULL);
1155
1170
    return MarkAsCall(DefineFixedDouble(result, d2), instr);
 
1171
  } else if (op == kMathPowHalf) {
 
1172
    LOperand* input = UseFixedDouble(instr->value(), d2);
 
1173
    LOperand* temp = FixedTemp(d3);
 
1174
    LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
 
1175
    return DefineFixedDouble(result, d2);
1156
1176
  } else {
1157
1177
    LOperand* input = UseRegisterAtStart(instr->value());
1158
1178
    LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
1166
1186
        return DefineAsRegister(result);
1167
1187
      case kMathRound:
1168
1188
        return AssignEnvironment(DefineAsRegister(result));
1169
 
      case kMathPowHalf:
1170
 
        return DefineAsRegister(result);
1171
1189
      default:
1172
1190
        UNREACHABLE();
1173
1191
        return NULL;
1341
1359
    } else {
1342
1360
      left = UseRegisterAtStart(instr->LeastConstantOperand());
1343
1361
    }
1344
 
    return AssignEnvironment(DefineAsRegister(new LMulI(left, right, temp)));
 
1362
    LMulI* mul = new LMulI(left, right, temp);
 
1363
    if (instr->CheckFlag(HValue::kCanOverflow) ||
 
1364
        instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
 
1365
      AssignEnvironment(mul);
 
1366
    }
 
1367
    return DefineAsRegister(mul);
1345
1368
 
1346
1369
  } else if (instr->representation().IsDouble()) {
1347
1370
    return DoArithmeticD(Token::MUL, instr);
1402
1425
  LOperand* left = UseFixedDouble(instr->left(), d1);
1403
1426
  LOperand* right = exponent_type.IsDouble() ?
1404
1427
      UseFixedDouble(instr->right(), d2) :
1405
 
      UseFixed(instr->right(), r0);
 
1428
      UseFixed(instr->right(), r2);
1406
1429
  LPower* result = new LPower(left, right);
1407
1430
  return MarkAsCall(DefineFixedDouble(result, d3),
1408
1431
                    instr,
1410
1433
}
1411
1434
 
1412
1435
 
 
1436
LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
 
1437
  ASSERT(instr->representation().IsDouble());
 
1438
  ASSERT(instr->global_object()->representation().IsTagged());
 
1439
  LOperand* global_object = UseFixed(instr->global_object(), r0);
 
1440
  LRandom* result = new LRandom(global_object);
 
1441
  return MarkAsCall(DefineFixedDouble(result, d7), instr);
 
1442
}
 
1443
 
 
1444
 
1413
1445
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1414
1446
  ASSERT(instr->left()->representation().IsTagged());
1415
1447
  ASSERT(instr->right()->representation().IsTagged());
1526
1558
LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
1527
1559
    HClassOfTestAndBranch* instr) {
1528
1560
  ASSERT(instr->value()->representation().IsTagged());
1529
 
  return new LClassOfTestAndBranch(UseTempRegister(instr->value()),
 
1561
  return new LClassOfTestAndBranch(UseRegister(instr->value()),
1530
1562
                                   TempRegister());
1531
1563
}
1532
1564
 
1553
1585
LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1554
1586
  LOperand* object = UseRegister(instr->value());
1555
1587
  LValueOf* result = new LValueOf(object, TempRegister());
1556
 
  return AssignEnvironment(DefineAsRegister(result));
 
1588
  return DefineAsRegister(result);
1557
1589
}
1558
1590
 
1559
1591
 
1776
1808
 
1777
1809
 
1778
1810
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
1779
 
  LOperand* temp = TempRegister();
1780
 
  LOperand* value = UseTempRegister(instr->value());
1781
 
  LInstruction* result = new LStoreGlobalCell(value, temp);
1782
 
  if (instr->RequiresHoleCheck()) result = AssignEnvironment(result);
1783
 
  return result;
 
1811
  LOperand* value = UseRegister(instr->value());
 
1812
  // Use a temp to check the value in the cell in the case where we perform
 
1813
  // a hole check.
 
1814
  return instr->RequiresHoleCheck()
 
1815
      ? AssignEnvironment(new LStoreGlobalCell(value, TempRegister()))
 
1816
      : new LStoreGlobalCell(value, NULL);
1784
1817
}
1785
1818
 
1786
1819
 
1795
1828
 
1796
1829
LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1797
1830
  LOperand* context = UseRegisterAtStart(instr->value());
1798
 
  return DefineAsRegister(new LLoadContextSlot(context));
 
1831
  LInstruction* result = DefineAsRegister(new LLoadContextSlot(context));
 
1832
  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
1799
1833
}
1800
1834
 
1801
1835
 
1809
1843
    context = UseRegister(instr->context());
1810
1844
    value = UseRegister(instr->value());
1811
1845
  }
1812
 
  return new LStoreContextSlot(context, value);
 
1846
  LInstruction* result = new LStoreContextSlot(context, value);
 
1847
  return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
1813
1848
}
1814
1849
 
1815
1850
 
1868
1903
  LOperand* obj = UseRegisterAtStart(instr->object());
1869
1904
  LOperand* key = UseRegisterAtStart(instr->key());
1870
1905
  LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1871
 
  return AssignEnvironment(DefineAsRegister(result));
 
1906
  if (instr->RequiresHoleCheck()) AssignEnvironment(result);
 
1907
  return DefineAsRegister(result);
1872
1908
}
1873
1909
 
1874
1910
 
1887
1923
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1888
1924
    HLoadKeyedSpecializedArrayElement* instr) {
1889
1925
  ElementsKind elements_kind = instr->elements_kind();
1890
 
  Representation representation(instr->representation());
1891
1926
  ASSERT(
1892
 
      (representation.IsInteger32() &&
 
1927
      (instr->representation().IsInteger32() &&
1893
1928
       (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
1894
1929
       (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
1895
 
      (representation.IsDouble() &&
 
1930
      (instr->representation().IsDouble() &&
1896
1931
       ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
1897
1932
       (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
1898
1933
  ASSERT(instr->key()->representation().IsInteger32());
1932
1967
  LOperand* key = needs_write_barrier
1933
1968
      ? UseTempRegister(instr->key())
1934
1969
      : UseRegisterOrConstantAtStart(instr->key());
1935
 
 
1936
 
  return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
 
1970
  return new LStoreKeyedFastElement(obj, key, val);
1937
1971
}
1938
1972
 
1939
1973
 
1953
1987
 
1954
1988
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
1955
1989
    HStoreKeyedSpecializedArrayElement* instr) {
1956
 
  Representation representation(instr->value()->representation());
1957
1990
  ElementsKind elements_kind = instr->elements_kind();
1958
1991
  ASSERT(
1959
 
      (representation.IsInteger32() &&
 
1992
      (instr->value()->representation().IsInteger32() &&
1960
1993
       (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
1961
1994
       (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
1962
 
      (representation.IsDouble() &&
 
1995
      (instr->value()->representation().IsDouble() &&
1963
1996
       ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
1964
1997
       (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
1965
1998
  ASSERT(instr->external_pointer()->representation().IsExternal());
2215
2248
  HEnvironment* outer = current_block_->last_environment();
2216
2249
  HConstant* undefined = graph()->GetConstantUndefined();
2217
2250
  HEnvironment* inner = outer->CopyForInlining(instr->closure(),
 
2251
                                               instr->arguments_count(),
2218
2252
                                               instr->function(),
2219
2253
                                               undefined,
2220
2254
                                               instr->call_kind());
2225
2259
 
2226
2260
 
2227
2261
LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2228
 
  HEnvironment* outer = current_block_->last_environment()->outer();
 
2262
  HEnvironment* outer = current_block_->last_environment()->
 
2263
      DiscardInlined(false);
2229
2264
  current_block_->UpdateEnvironment(outer);
2230
2265
  return NULL;
2231
2266
}