Add BitcastTaggedSignedToWord operator

R=jarin@chromium.org, tebbi@chromium.org

Change-Id: I3f23b48d4294722d056edb0ec30f834c0169b042
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1645331
Commit-Queue: Georg Schmid <gsps@google.com>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62028}
This commit is contained in:
Georg Schmid 2019-06-06 15:51:24 +02:00 committed by Commit Bot
parent 0e53739c39
commit 72b9d704d0
12 changed files with 83 additions and 52 deletions

View File

@ -567,7 +567,7 @@ TNode<Float64T> CodeStubAssembler::Float64Trunc(SloppyTNode<Float64T> x) {
TNode<BoolT> CodeStubAssembler::IsValidSmi(TNode<Smi> smi) {
if (SmiValuesAre31Bits() && kSystemPointerSize == kInt64Size) {
// Check that the Smi value is properly sign-extended.
TNode<IntPtrT> value = Signed(BitcastTaggedToWord(smi));
TNode<IntPtrT> value = Signed(BitcastTaggedSignedToWord(smi));
return WordEqual(value, ChangeInt32ToIntPtr(TruncateIntPtrToInt32(value)));
}
return Int32TrueConstant();
@ -611,7 +611,8 @@ TNode<IntPtrT> CodeStubAssembler::SmiUntag(SloppyTNode<Smi> value) {
if (ToIntPtrConstant(value, constant_value)) {
return IntPtrConstant(constant_value >> (kSmiShiftSize + kSmiTagSize));
}
return Signed(WordSar(BitcastTaggedToWord(value), SmiShiftBitsConstant()));
return Signed(
WordSar(BitcastTaggedSignedToWord(value), SmiShiftBitsConstant()));
}
TNode<Int32T> CodeStubAssembler::SmiToInt32(SloppyTNode<Smi> value) {
@ -660,13 +661,14 @@ TNode<Int32T> CodeStubAssembler::TryInt32Mul(TNode<Int32T> a, TNode<Int32T> b,
TNode<Smi> CodeStubAssembler::TrySmiAdd(TNode<Smi> lhs, TNode<Smi> rhs,
Label* if_overflow) {
if (SmiValuesAre32Bits()) {
return BitcastWordToTaggedSigned(TryIntPtrAdd(
BitcastTaggedToWord(lhs), BitcastTaggedToWord(rhs), if_overflow));
return BitcastWordToTaggedSigned(
TryIntPtrAdd(BitcastTaggedSignedToWord(lhs),
BitcastTaggedSignedToWord(rhs), if_overflow));
} else {
DCHECK(SmiValuesAre31Bits());
TNode<PairT<Int32T, BoolT>> pair =
Int32AddWithOverflow(TruncateIntPtrToInt32(BitcastTaggedToWord(lhs)),
TruncateIntPtrToInt32(BitcastTaggedToWord(rhs)));
TNode<PairT<Int32T, BoolT>> pair = Int32AddWithOverflow(
TruncateIntPtrToInt32(BitcastTaggedSignedToWord(lhs)),
TruncateIntPtrToInt32(BitcastTaggedSignedToWord(rhs)));
TNode<BoolT> overflow = Projection<1>(pair);
GotoIf(overflow, if_overflow);
TNode<Int32T> result = Projection<0>(pair);
@ -678,16 +680,16 @@ TNode<Smi> CodeStubAssembler::TrySmiSub(TNode<Smi> lhs, TNode<Smi> rhs,
Label* if_overflow) {
if (SmiValuesAre32Bits()) {
TNode<PairT<IntPtrT, BoolT>> pair = IntPtrSubWithOverflow(
BitcastTaggedToWord(lhs), BitcastTaggedToWord(rhs));
BitcastTaggedSignedToWord(lhs), BitcastTaggedSignedToWord(rhs));
TNode<BoolT> overflow = Projection<1>(pair);
GotoIf(overflow, if_overflow);
TNode<IntPtrT> result = Projection<0>(pair);
return BitcastWordToTaggedSigned(result);
} else {
DCHECK(SmiValuesAre31Bits());
TNode<PairT<Int32T, BoolT>> pair =
Int32SubWithOverflow(TruncateIntPtrToInt32(BitcastTaggedToWord(lhs)),
TruncateIntPtrToInt32(BitcastTaggedToWord(rhs)));
TNode<PairT<Int32T, BoolT>> pair = Int32SubWithOverflow(
TruncateIntPtrToInt32(BitcastTaggedSignedToWord(lhs)),
TruncateIntPtrToInt32(BitcastTaggedSignedToWord(rhs)));
TNode<BoolT> overflow = Projection<1>(pair);
GotoIf(overflow, if_overflow);
TNode<Int32T> result = Projection<0>(pair);
@ -7510,7 +7512,7 @@ TNode<String> CodeStubAssembler::NumberToString(TNode<Number> input) {
// contains two elements (number and string) for each cache entry.
// TODO(ishell): cleanup mask handling.
Node* mask =
BitcastTaggedToWord(LoadFixedArrayBaseLength(number_string_cache));
BitcastTaggedSignedToWord(LoadFixedArrayBaseLength(number_string_cache));
TNode<IntPtrT> one = IntPtrConstant(1);
mask = IntPtrSub(mask, one);
@ -7557,8 +7559,8 @@ TNode<String> CodeStubAssembler::NumberToString(TNode<Number> input) {
BIND(&if_smi);
{
// Load the smi key, make sure it matches the smi we're looking for.
Node* smi_index = BitcastWordToTagged(
WordAnd(WordShl(BitcastTaggedToWord(smi_input.value()), one), mask));
Node* smi_index = BitcastWordToTagged(WordAnd(
WordShl(BitcastTaggedSignedToWord(smi_input.value()), one), mask));
Node* smi_key = UnsafeLoadFixedArrayElement(CAST(number_string_cache),
smi_index, 0, SMI_PARAMETERS);
GotoIf(WordNotEqual(smi_key, smi_input.value()), &runtime);
@ -10046,7 +10048,7 @@ TNode<IntPtrT> CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
Smi smi_index;
constant_index = ToSmiConstant(index_node, &smi_index);
if (constant_index) index = smi_index.value();
index_node = BitcastTaggedToWord(index_node);
index_node = BitcastTaggedSignedToWord(index_node);
} else {
DCHECK(mode == INTPTR_PARAMETERS);
constant_index = ToIntPtrConstant(index_node, index);
@ -13491,8 +13493,9 @@ TNode<Code> CodeStubAssembler::LoadBuiltin(TNode<Smi> builtin_id) {
int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize;
int index_shift = kSystemPointerSizeLog2 - kSmiShiftBits;
TNode<WordT> table_index =
index_shift >= 0 ? WordShl(BitcastTaggedToWord(builtin_id), index_shift)
: WordSar(BitcastTaggedToWord(builtin_id), -index_shift);
index_shift >= 0
? WordShl(BitcastTaggedSignedToWord(builtin_id), index_shift)
: WordSar(BitcastTaggedSignedToWord(builtin_id), -index_shift);
return CAST(
Load(MachineType::TaggedPointer(),

View File

@ -490,21 +490,21 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Int32T> SmiToInt32(SloppyTNode<Smi> value);
// Smi operations.
#define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName, Int32OpName) \
TNode<Smi> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \
if (SmiValuesAre32Bits()) { \
return BitcastWordToTaggedSigned( \
IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); \
} else { \
DCHECK(SmiValuesAre31Bits()); \
if (kSystemPointerSize == kInt64Size) { \
CSA_ASSERT(this, IsValidSmi(a)); \
CSA_ASSERT(this, IsValidSmi(b)); \
} \
return BitcastWordToTaggedSigned(ChangeInt32ToIntPtr( \
Int32OpName(TruncateIntPtrToInt32(BitcastTaggedToWord(a)), \
TruncateIntPtrToInt32(BitcastTaggedToWord(b))))); \
} \
#define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName, Int32OpName) \
TNode<Smi> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \
if (SmiValuesAre32Bits()) { \
return BitcastWordToTaggedSigned(IntPtrOpName( \
BitcastTaggedSignedToWord(a), BitcastTaggedSignedToWord(b))); \
} else { \
DCHECK(SmiValuesAre31Bits()); \
if (kSystemPointerSize == kInt64Size) { \
CSA_ASSERT(this, IsValidSmi(a)); \
CSA_ASSERT(this, IsValidSmi(b)); \
} \
return BitcastWordToTaggedSigned(ChangeInt32ToIntPtr( \
Int32OpName(TruncateIntPtrToInt32(BitcastTaggedSignedToWord(a)), \
TruncateIntPtrToInt32(BitcastTaggedSignedToWord(b))))); \
} \
}
SMI_ARITHMETIC_BINOP(SmiAdd, IntPtrAdd, Int32Add)
SMI_ARITHMETIC_BINOP(SmiSub, IntPtrSub, Int32Sub)
@ -523,19 +523,20 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Smi> TrySmiSub(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
TNode<Smi> SmiShl(TNode<Smi> a, int shift) {
return BitcastWordToTaggedSigned(WordShl(BitcastTaggedToWord(a), shift));
return BitcastWordToTaggedSigned(
WordShl(BitcastTaggedSignedToWord(a), shift));
}
TNode<Smi> SmiShr(TNode<Smi> a, int shift) {
return BitcastWordToTaggedSigned(
WordAnd(WordShr(BitcastTaggedToWord(a), shift),
BitcastTaggedToWord(SmiConstant(-1))));
WordAnd(WordShr(BitcastTaggedSignedToWord(a), shift),
BitcastTaggedSignedToWord(SmiConstant(-1))));
}
TNode<Smi> SmiSar(TNode<Smi> a, int shift) {
return BitcastWordToTaggedSigned(
WordAnd(WordSar(BitcastTaggedToWord(a), shift),
BitcastTaggedToWord(SmiConstant(-1))));
WordAnd(WordSar(BitcastTaggedSignedToWord(a), shift),
BitcastTaggedSignedToWord(SmiConstant(-1))));
}
Node* WordOrSmiShl(Node* a, int shift, ParameterMode mode) {
@ -556,19 +557,20 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
}
}
#define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName, Int32OpName) \
TNode<BoolT> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \
if (SmiValuesAre32Bits()) { \
return IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); \
} else { \
DCHECK(SmiValuesAre31Bits()); \
if (kSystemPointerSize == kInt64Size) { \
CSA_ASSERT(this, IsValidSmi(a)); \
CSA_ASSERT(this, IsValidSmi(b)); \
} \
return Int32OpName(TruncateIntPtrToInt32(BitcastTaggedToWord(a)), \
TruncateIntPtrToInt32(BitcastTaggedToWord(b))); \
} \
#define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName, Int32OpName) \
TNode<BoolT> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \
if (SmiValuesAre32Bits()) { \
return IntPtrOpName(BitcastTaggedSignedToWord(a), \
BitcastTaggedSignedToWord(b)); \
} else { \
DCHECK(SmiValuesAre31Bits()); \
if (kSystemPointerSize == kInt64Size) { \
CSA_ASSERT(this, IsValidSmi(a)); \
CSA_ASSERT(this, IsValidSmi(b)); \
} \
return Int32OpName(TruncateIntPtrToInt32(BitcastTaggedSignedToWord(a)), \
TruncateIntPtrToInt32(BitcastTaggedSignedToWord(b))); \
} \
}
SMI_COMPARISON_OP(SmiEqual, WordEqual, Word32Equal)
SMI_COMPARISON_OP(SmiNotEqual, WordNotEqual, Word32NotEqual)
@ -2577,7 +2579,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsSetSmi(SloppyTNode<Smi> smi, int untagged_mask) {
intptr_t mask_word = bit_cast<intptr_t>(Smi::FromInt(untagged_mask));
return WordNotEqual(
WordAnd(BitcastTaggedToWord(smi), IntPtrConstant(mask_word)),
WordAnd(BitcastTaggedSignedToWord(smi), IntPtrConstant(mask_word)),
IntPtrConstant(0));
}

View File

@ -1476,6 +1476,7 @@ void InstructionSelector::VisitNode(Node* node) {
case IrOpcode::kUint64Mod:
return MarkAsWord64(node), VisitUint64Mod(node);
case IrOpcode::kBitcastTaggedToWord:
case IrOpcode::kBitcastTaggedSignedToWord:
return MarkAsRepresentation(MachineType::PointerRepresentation(), node),
VisitBitcastTaggedToWord(node);
case IrOpcode::kBitcastWordToTagged:

View File

@ -614,6 +614,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
V(Float64ExtractLowWord32, Word32T, Float64T) \
V(Float64ExtractHighWord32, Word32T, Float64T) \
V(BitcastTaggedToWord, IntPtrT, Object) \
V(BitcastTaggedSignedToWord, IntPtrT, Smi) \
V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject) \
V(BitcastWordToTagged, Object, WordT) \
V(BitcastWordToTaggedSigned, Smi, WordT) \
@ -1195,6 +1196,12 @@ class V8_EXPORT_PRIVATE CodeAssembler {
CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
#undef DECLARE_CODE_ASSEMBLER_UNARY_OP
template <class Dummy = void>
TNode<IntPtrT> BitcastTaggedToWord(TNode<Smi> node) {
static_assert(sizeof(Dummy) < 0,
"Should use BitcastTaggedSignedToWord instead.");
}
// Changes a double to an inptr_t for pointer arithmetic outside of Smi range.
// Assumes that the double can be exactly represented as an int.
TNode<UintPtrT> ChangeFloat64ToUintPtr(SloppyTNode<Float64T> value);

View File

@ -221,6 +221,12 @@ Node* GraphAssembler::BitcastTaggedToWord(Node* value) {
current_effect_, current_control_);
}
Node* GraphAssembler::BitcastTaggedSignedToWord(Node* value) {
return current_effect_ =
graph()->NewNode(machine()->BitcastTaggedSignedToWord(), value,
current_effect_, current_control_);
}
Node* GraphAssembler::Word32PoisonOnSpeculation(Node* value) {
return current_effect_ =
graph()->NewNode(machine()->Word32PoisonOnSpeculation(), value,

View File

@ -225,6 +225,7 @@ class GraphAssembler {
Node* ToNumber(Node* value);
Node* BitcastWordToTagged(Node* value);
Node* BitcastTaggedToWord(Node* value);
Node* BitcastTaggedSignedToWord(Node* value);
Node* Allocate(AllocationType allocation, Node* size);
Node* LoadField(FieldAccess const&, Node* object);
Node* LoadElement(ElementAccess const&, Node* object, Node* index);

View File

@ -240,6 +240,7 @@ class MachineRepresentationInferrer {
MachineType::PointerRepresentation();
break;
case IrOpcode::kBitcastTaggedToWord:
case IrOpcode::kBitcastTaggedSignedToWord:
representation_vector_[node->id()] =
MachineType::PointerRepresentation();
break;
@ -428,6 +429,7 @@ class MachineRepresentationChecker {
MachineRepresentation::kWord64);
break;
case IrOpcode::kBitcastTaggedToWord:
case IrOpcode::kBitcastTaggedSignedToWord:
case IrOpcode::kTaggedPoisonOnSpeculation:
CheckValueInputIsTagged(node, 0);
break;

View File

@ -140,6 +140,7 @@ MachineType AtomicOpType(Operator const* op) {
V(Word64Clz, Operator::kNoProperties, 1, 0, 1) \
V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
V(BitcastTaggedSignedToWord, Operator::kNoProperties, 1, 0, 1) \
V(BitcastWordToTaggedSigned, Operator::kNoProperties, 1, 0, 1) \
V(TruncateFloat64ToWord32, Operator::kNoProperties, 1, 0, 1) \
V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1) \

View File

@ -295,9 +295,12 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const Operator* Uint64LessThanOrEqual();
const Operator* Uint64Mod();
// This operator reinterprets the bits of a tagged pointer as word.
// This operator reinterprets the bits of a tagged pointer as a word.
const Operator* BitcastTaggedToWord();
// This operator reinterprets the bits of a Smi as a word.
const Operator* BitcastTaggedSignedToWord();
// This operator reinterprets the bits of a tagged MaybeObject pointer as
// word.
const Operator* BitcastMaybeObjectToWord();

View File

@ -632,6 +632,7 @@
V(Word64ReverseBytes) \
V(Int64AbsWithOverflow) \
V(BitcastTaggedToWord) \
V(BitcastTaggedSignedToWord) \
V(BitcastWordToTagged) \
V(BitcastWordToTaggedSigned) \
V(TruncateFloat64ToWord32) \

View File

@ -732,6 +732,9 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
Node* BitcastTaggedToWord(Node* a) {
return AddNode(machine()->BitcastTaggedToWord(), a);
}
Node* BitcastTaggedSignedToWord(Node* a) {
return AddNode(machine()->BitcastTaggedSignedToWord(), a);
}
Node* BitcastMaybeObjectToWord(Node* a) {
return AddNode(machine()->BitcastMaybeObjectToWord(), a);
}

View File

@ -1756,6 +1756,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
case IrOpcode::kBitcastInt32ToFloat32:
case IrOpcode::kBitcastInt64ToFloat64:
case IrOpcode::kBitcastTaggedToWord:
case IrOpcode::kBitcastTaggedSignedToWord:
case IrOpcode::kBitcastWordToTagged:
case IrOpcode::kBitcastWordToTaggedSigned:
case IrOpcode::kChangeInt32ToInt64: