Commit 585ca904 authored by Hao Xu's avatar Hao Xu Committed by V8 LUCI CQ

[x64][compiler] Optimize SmiTag/SmiUntag

... by selecting better instructions and avoiding sign-extend unsigned
smi.

Change-Id: I60b47f88dd34bfcda189716ac55d1fab13f3d4a1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3819112
Commit-Queue: Hao A Xu <hao.a.xu@intel.com>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82463}
parent 5d13fc53
...@@ -355,6 +355,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -355,6 +355,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
__ ldr(output, FieldMemOperand(source, offset)); __ ldr(output, FieldMemOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ ldr(output, FieldMemOperand(source, offset)); __ ldr(output, FieldMemOperand(source, offset));
......
...@@ -406,6 +406,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -406,6 +406,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
__ LoadTaggedSignedField(output, FieldMemOperand(source, offset)); __ LoadTaggedSignedField(output, FieldMemOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ LoadAnyTaggedField(output, FieldMemOperand(source, offset)); __ LoadAnyTaggedField(output, FieldMemOperand(source, offset));
......
...@@ -158,6 +158,8 @@ class BaselineAssembler { ...@@ -158,6 +158,8 @@ class BaselineAssembler {
int offset); int offset);
inline void LoadTaggedSignedField(Register output, Register source, inline void LoadTaggedSignedField(Register output, Register source,
int offset); int offset);
inline void LoadTaggedSignedFieldAndUntag(Register output, Register source,
int offset);
inline void LoadTaggedAnyField(Register output, Register source, int offset); inline void LoadTaggedAnyField(Register output, Register source, int offset);
inline void LoadWord16FieldZeroExtend(Register output, Register source, inline void LoadWord16FieldZeroExtend(Register output, Register source,
int offset); int offset);
......
...@@ -2198,8 +2198,8 @@ void BaselineCompiler::VisitSwitchOnGeneratorState() { ...@@ -2198,8 +2198,8 @@ void BaselineCompiler::VisitSwitchOnGeneratorState() {
__ JumpIfRoot(generator_object, RootIndex::kUndefinedValue, &fallthrough); __ JumpIfRoot(generator_object, RootIndex::kUndefinedValue, &fallthrough);
Register continuation = scratch_scope.AcquireScratch(); Register continuation = scratch_scope.AcquireScratch();
__ LoadTaggedAnyField(continuation, generator_object, __ LoadTaggedSignedFieldAndUntag(continuation, generator_object,
JSGeneratorObject::kContinuationOffset); JSGeneratorObject::kContinuationOffset);
__ StoreTaggedSignedField( __ StoreTaggedSignedField(
generator_object, JSGeneratorObject::kContinuationOffset, generator_object, JSGeneratorObject::kContinuationOffset,
Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
...@@ -2220,7 +2220,6 @@ void BaselineCompiler::VisitSwitchOnGeneratorState() { ...@@ -2220,7 +2220,6 @@ void BaselineCompiler::VisitSwitchOnGeneratorState() {
for (interpreter::JumpTableTargetOffset offset : offsets) { for (interpreter::JumpTableTargetOffset offset : offsets) {
labels[offset.case_value] = EnsureLabel(offset.target_offset); labels[offset.case_value] = EnsureLabel(offset.target_offset);
} }
__ SmiUntag(continuation);
__ Switch(continuation, 0, labels.get(), offsets.size()); __ Switch(continuation, 0, labels.get(), offsets.size());
// We should never fall through this switch. // We should never fall through this switch.
// TODO(v8:11429,leszeks): Maybe remove the fallthrough check in the Switch? // TODO(v8:11429,leszeks): Maybe remove the fallthrough check in the Switch?
......
...@@ -337,6 +337,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -337,6 +337,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
__ mov(output, FieldOperand(source, offset)); __ mov(output, FieldOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ mov(output, FieldOperand(source, offset)); __ mov(output, FieldOperand(source, offset));
......
...@@ -353,6 +353,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -353,6 +353,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
int offset) { int offset) {
__ Ld_d(output, FieldMemOperand(source, offset)); __ Ld_d(output, FieldMemOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ Ld_d(output, FieldMemOperand(source, offset)); __ Ld_d(output, FieldMemOperand(source, offset));
......
...@@ -363,6 +363,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -363,6 +363,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
int offset) { int offset) {
__ Lw(output, FieldMemOperand(source, offset)); __ Lw(output, FieldMemOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ Lw(output, FieldMemOperand(source, offset)); __ Lw(output, FieldMemOperand(source, offset));
......
...@@ -361,6 +361,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -361,6 +361,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
int offset) { int offset) {
__ Ld(output, FieldMemOperand(source, offset)); __ Ld(output, FieldMemOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ Ld(output, FieldMemOperand(source, offset)); __ Ld(output, FieldMemOperand(source, offset));
......
...@@ -507,6 +507,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -507,6 +507,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
__ LoadTaggedSignedField(output, FieldMemOperand(source, offset), r0); __ LoadTaggedSignedField(output, FieldMemOperand(source, offset), r0);
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
ASM_CODE_COMMENT(masm_); ASM_CODE_COMMENT(masm_);
......
...@@ -337,6 +337,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -337,6 +337,12 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
int offset) { int offset) {
__ LoadTaggedSignedField(output, FieldMemOperand(source, offset)); __ LoadTaggedSignedField(output, FieldMemOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ LoadAnyTaggedField(output, FieldMemOperand(source, offset)); __ LoadAnyTaggedField(output, FieldMemOperand(source, offset));
......
...@@ -505,6 +505,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -505,6 +505,13 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
__ LoadTaggedSignedField(output, FieldMemOperand(source, offset)); __ LoadTaggedSignedField(output, FieldMemOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
LoadTaggedSignedField(output, source, offset);
SmiUntag(output);
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
ASM_CODE_COMMENT(masm_); ASM_CODE_COMMENT(masm_);
......
...@@ -338,6 +338,11 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source, ...@@ -338,6 +338,11 @@ void BaselineAssembler::LoadTaggedSignedField(Register output, Register source,
int offset) { int offset) {
__ LoadTaggedSignedField(output, FieldOperand(source, offset)); __ LoadTaggedSignedField(output, FieldOperand(source, offset));
} }
void BaselineAssembler::LoadTaggedSignedFieldAndUntag(Register output,
Register source,
int offset) {
__ SmiUntagField(output, FieldOperand(source, offset));
}
void BaselineAssembler::LoadTaggedAnyField(Register output, Register source, void BaselineAssembler::LoadTaggedAnyField(Register output, Register source,
int offset) { int offset) {
__ LoadAnyTaggedField(output, FieldOperand(source, offset)); __ LoadAnyTaggedField(output, FieldOperand(source, offset));
...@@ -630,7 +635,7 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) { ...@@ -630,7 +635,7 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt, 1); __ CallRuntime(Runtime::kBytecodeBudgetInterrupt, 1);
__ Pop(kInterpreterAccumulatorRegister, params_size); __ Pop(kInterpreterAccumulatorRegister, params_size);
__ masm()->SmiUntag(params_size); __ masm()->SmiUntagUnsigned(params_size);
} }
__ Bind(&skip_interrupt_label); __ Bind(&skip_interrupt_label);
} }
......
...@@ -222,7 +222,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -222,7 +222,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// Restore constructor function and argument count. // Restore constructor function and argument count.
__ movq(rdi, Operand(rbp, ConstructFrameConstants::kConstructorOffset)); __ movq(rdi, Operand(rbp, ConstructFrameConstants::kConstructorOffset));
__ SmiUntag(rax, Operand(rbp, ConstructFrameConstants::kLengthOffset)); __ SmiUntagUnsigned(rax,
Operand(rbp, ConstructFrameConstants::kLengthOffset));
// Check if we have enough stack space to push all arguments. // Check if we have enough stack space to push all arguments.
// Argument count in rax. // Argument count in rax.
...@@ -1152,8 +1153,9 @@ void Builtins::Generate_InterpreterEntryTrampoline( ...@@ -1152,8 +1153,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(
// Get bytecode array and bytecode offset from the stack frame. // Get bytecode array and bytecode offset from the stack frame.
__ movq(kInterpreterBytecodeArrayRegister, __ movq(kInterpreterBytecodeArrayRegister,
Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp));
__ SmiUntag(kInterpreterBytecodeOffsetRegister, __ SmiUntagUnsigned(
Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); kInterpreterBytecodeOffsetRegister,
Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
// Either return, or advance to the next bytecode and dispatch. // Either return, or advance to the next bytecode and dispatch.
Label do_return; Label do_return;
...@@ -1449,8 +1451,9 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1449,8 +1451,9 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
} }
// Get the target bytecode offset from the frame. // Get the target bytecode offset from the frame.
__ SmiUntag(kInterpreterBytecodeOffsetRegister, __ SmiUntagUnsigned(
Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); kInterpreterBytecodeOffsetRegister,
Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
if (FLAG_debug_code) { if (FLAG_debug_code) {
Label okay; Label okay;
...@@ -1475,8 +1478,9 @@ void Builtins::Generate_InterpreterEnterAtNextBytecode(MacroAssembler* masm) { ...@@ -1475,8 +1478,9 @@ void Builtins::Generate_InterpreterEnterAtNextBytecode(MacroAssembler* masm) {
// Get bytecode array and bytecode offset from the stack frame. // Get bytecode array and bytecode offset from the stack frame.
__ movq(kInterpreterBytecodeArrayRegister, __ movq(kInterpreterBytecodeArrayRegister,
Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp));
__ SmiUntag(kInterpreterBytecodeOffsetRegister, __ SmiUntagUnsigned(
Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); kInterpreterBytecodeOffsetRegister,
Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
Label enter_bytecode, function_entry_bytecode; Label enter_bytecode, function_entry_bytecode;
__ cmpq(kInterpreterBytecodeOffsetRegister, __ cmpq(kInterpreterBytecodeOffsetRegister,
...@@ -1679,7 +1683,7 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, ...@@ -1679,7 +1683,7 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
int code = config->GetAllocatableGeneralCode(i); int code = config->GetAllocatableGeneralCode(i);
__ popq(Register::from_code(code)); __ popq(Register::from_code(code));
if (java_script_builtin && code == kJavaScriptCallArgCountRegister.code()) { if (java_script_builtin && code == kJavaScriptCallArgCountRegister.code()) {
__ SmiUntag(Register::from_code(code)); __ SmiUntagUnsigned(Register::from_code(code));
} }
} }
if (with_result && java_script_builtin) { if (with_result && java_script_builtin) {
...@@ -2238,7 +2242,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2238,7 +2242,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ movq(rcx, rax); __ movq(rcx, rax);
__ Pop(rdi); __ Pop(rdi);
__ Pop(rax); __ Pop(rax);
__ SmiUntag(rax); __ SmiUntagUnsigned(rax);
} }
__ LoadTaggedPointerField( __ LoadTaggedPointerField(
rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
...@@ -2273,7 +2277,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { ...@@ -2273,7 +2277,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) {
Label no_bound_arguments; Label no_bound_arguments;
__ LoadTaggedPointerField( __ LoadTaggedPointerField(
rcx, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset)); rcx, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset));
__ SmiUntagField(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); __ SmiUntagFieldUnsigned(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
__ testl(rbx, rbx); __ testl(rbx, rbx);
__ j(zero, &no_bound_arguments); __ j(zero, &no_bound_arguments);
{ {
...@@ -2315,7 +2319,8 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { ...@@ -2315,7 +2319,8 @@ void Generate_PushBoundArguments(MacroAssembler* masm) {
Label loop; Label loop;
__ LoadTaggedPointerField( __ LoadTaggedPointerField(
rcx, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset)); rcx, FieldOperand(rdi, JSBoundFunction::kBoundArgumentsOffset));
__ SmiUntagField(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); __ SmiUntagFieldUnsigned(rbx,
FieldOperand(rcx, FixedArray::kLengthOffset));
__ addq(rax, rbx); // Adjust effective number of arguments. __ addq(rax, rbx); // Adjust effective number of arguments.
__ bind(&loop); __ bind(&loop);
// Instead of doing decl(rbx) here subtract kTaggedSize from the header // Instead of doing decl(rbx) here subtract kTaggedSize from the header
...@@ -2707,7 +2712,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) { ...@@ -2707,7 +2712,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
__ CallRuntime(Runtime::kWasmCompileLazy, 3); __ CallRuntime(Runtime::kWasmCompileLazy, 3);
// The runtime function returns the jump table slot offset as a Smi. Use // The runtime function returns the jump table slot offset as a Smi. Use
// that to compute the jump target in r15. // that to compute the jump target in r15.
__ SmiUntag(kReturnRegister0); __ SmiUntagUnsigned(kReturnRegister0);
__ movq(r15, kReturnRegister0); __ movq(r15, kReturnRegister0);
// Restore registers. // Restore registers.
...@@ -3315,10 +3320,8 @@ void GenericJSToWasmWrapperHelper(MacroAssembler* masm, bool stack_switch) { ...@@ -3315,10 +3320,8 @@ void GenericJSToWasmWrapperHelper(MacroAssembler* masm, bool stack_switch) {
__ cmpq(valuetype, Immediate(wasm::kWasmI32.raw_bit_field())); __ cmpq(valuetype, Immediate(wasm::kWasmI32.raw_bit_field()));
__ j(not_equal, &convert_param); __ j(not_equal, &convert_param);
__ JumpIfNotSmi(param, &convert_param); __ JumpIfNotSmi(param, &convert_param);
// Change the param from Smi to int32. // Change the param from Smi to int32 (zero extend).
__ SmiUntag(param); __ SmiToInt32(param);
// Zero extend.
__ movl(param, param);
// Place the param into the proper slot in Integer section. // Place the param into the proper slot in Integer section.
__ movq(MemOperand(current_int_param_slot, 0), param); __ movq(MemOperand(current_int_param_slot, 0), param);
__ subq(current_int_param_slot, Immediate(kSystemPointerSize)); __ subq(current_int_param_slot, Immediate(kSystemPointerSize));
...@@ -5044,7 +5047,7 @@ void Generate_BaselineOrInterpreterEntry(MacroAssembler* masm, ...@@ -5044,7 +5047,7 @@ void Generate_BaselineOrInterpreterEntry(MacroAssembler* masm,
__ j(not_equal, &install_baseline_code); __ j(not_equal, &install_baseline_code);
// Save BytecodeOffset from the stack frame. // Save BytecodeOffset from the stack frame.
__ SmiUntag( __ SmiUntagUnsigned(
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeOffsetRegister,
MemOperand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); MemOperand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
// Replace BytecodeOffset with the feedback vector. // Replace BytecodeOffset with the feedback vector.
......
This diff is collapsed.
...@@ -295,6 +295,10 @@ void TurboAssembler::SmiUntagField(Register dst, Operand src) { ...@@ -295,6 +295,10 @@ void TurboAssembler::SmiUntagField(Register dst, Operand src) {
SmiUntag(dst, src); SmiUntag(dst, src);
} }
void TurboAssembler::SmiUntagFieldUnsigned(Register dst, Operand src) {
SmiUntagUnsigned(dst, src);
}
void TurboAssembler::StoreTaggedField(Operand dst_field_operand, void TurboAssembler::StoreTaggedField(Operand dst_field_operand,
Immediate value) { Immediate value) {
if (COMPRESS_POINTERS_BOOL) { if (COMPRESS_POINTERS_BOOL) {
...@@ -868,7 +872,7 @@ void MacroAssembler::GenerateTailCallToReturnedCode( ...@@ -868,7 +872,7 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
// Restore target function, new target and actual argument count. // Restore target function, new target and actual argument count.
Pop(kJavaScriptCallArgCountRegister); Pop(kJavaScriptCallArgCountRegister);
SmiUntag(kJavaScriptCallArgCountRegister); SmiUntagUnsigned(kJavaScriptCallArgCountRegister);
Pop(kJavaScriptCallNewTargetRegister); Pop(kJavaScriptCallNewTargetRegister);
Pop(kJavaScriptCallTargetRegister); Pop(kJavaScriptCallTargetRegister);
} }
...@@ -1457,7 +1461,8 @@ void TurboAssembler::SmiTag(Register reg) { ...@@ -1457,7 +1461,8 @@ void TurboAssembler::SmiTag(Register reg) {
static_assert(kSmiTag == 0); static_assert(kSmiTag == 0);
DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits()); DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
if (COMPRESS_POINTERS_BOOL) { if (COMPRESS_POINTERS_BOOL) {
shll(reg, Immediate(kSmiShift)); DCHECK_EQ(kSmiShift, 1);
addl(reg, reg);
} else { } else {
shlq(reg, Immediate(kSmiShift)); shlq(reg, Immediate(kSmiShift));
} }
...@@ -1484,6 +1489,17 @@ void TurboAssembler::SmiUntag(Register reg) { ...@@ -1484,6 +1489,17 @@ void TurboAssembler::SmiUntag(Register reg) {
sarq(reg, Immediate(kSmiShift)); sarq(reg, Immediate(kSmiShift));
} }
void TurboAssembler::SmiUntagUnsigned(Register reg) {
static_assert(kSmiTag == 0);
DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
if (COMPRESS_POINTERS_BOOL) {
AssertSignedBitOfSmiIsZero(reg);
shrl(reg, Immediate(kSmiShift));
} else {
shrq(reg, Immediate(kSmiShift));
}
}
void TurboAssembler::SmiUntag(Register dst, Register src) { void TurboAssembler::SmiUntag(Register dst, Register src) {
DCHECK(dst != src); DCHECK(dst != src);
if (COMPRESS_POINTERS_BOOL) { if (COMPRESS_POINTERS_BOOL) {
...@@ -1500,9 +1516,8 @@ void TurboAssembler::SmiUntag(Register dst, Register src) { ...@@ -1500,9 +1516,8 @@ void TurboAssembler::SmiUntag(Register dst, Register src) {
void TurboAssembler::SmiUntag(Register dst, Operand src) { void TurboAssembler::SmiUntag(Register dst, Operand src) {
if (SmiValuesAre32Bits()) { if (SmiValuesAre32Bits()) {
movl(dst, Operand(src, kSmiShift / kBitsPerByte));
// Sign extend to 64-bit. // Sign extend to 64-bit.
movsxlq(dst, dst); movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
} else { } else {
DCHECK(SmiValuesAre31Bits()); DCHECK(SmiValuesAre31Bits());
if (COMPRESS_POINTERS_BOOL) { if (COMPRESS_POINTERS_BOOL) {
...@@ -1514,6 +1529,23 @@ void TurboAssembler::SmiUntag(Register dst, Operand src) { ...@@ -1514,6 +1529,23 @@ void TurboAssembler::SmiUntag(Register dst, Operand src) {
} }
} }
void TurboAssembler::SmiUntagUnsigned(Register dst, Operand src) {
if (SmiValuesAre32Bits()) {
// Zero extend to 64-bit.
movl(dst, Operand(src, kSmiShift / kBitsPerByte));
} else {
DCHECK(SmiValuesAre31Bits());
if (COMPRESS_POINTERS_BOOL) {
movl(dst, src);
AssertSignedBitOfSmiIsZero(dst);
shrl(dst, Immediate(kSmiShift));
} else {
movq(dst, src);
shrq(dst, Immediate(kSmiShift));
}
}
}
void TurboAssembler::SmiToInt32(Register reg) { void TurboAssembler::SmiToInt32(Register reg) {
static_assert(kSmiTag == 0); static_assert(kSmiTag == 0);
DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits()); DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits());
...@@ -2126,7 +2158,7 @@ Operand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { ...@@ -2126,7 +2158,7 @@ Operand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) {
Operand TurboAssembler::EntryFromBuiltinIndexAsOperand(Register builtin_index) { Operand TurboAssembler::EntryFromBuiltinIndexAsOperand(Register builtin_index) {
if (SmiValuesAre32Bits()) { if (SmiValuesAre32Bits()) {
// The builtin_index register contains the builtin index as a Smi. // The builtin_index register contains the builtin index as a Smi.
SmiUntag(builtin_index); SmiUntagUnsigned(builtin_index);
return Operand(kRootRegister, builtin_index, times_system_pointer_size, return Operand(kRootRegister, builtin_index, times_system_pointer_size,
IsolateData::builtin_entry_table_offset()); IsolateData::builtin_entry_table_offset());
} else { } else {
...@@ -2652,6 +2684,14 @@ void TurboAssembler::AssertZeroExtended(Register int32_register) { ...@@ -2652,6 +2684,14 @@ void TurboAssembler::AssertZeroExtended(Register int32_register) {
Check(above, AbortReason::k32BitValueInRegisterIsNotZeroExtended); Check(above, AbortReason::k32BitValueInRegisterIsNotZeroExtended);
} }
void TurboAssembler::AssertSignedBitOfSmiIsZero(Register smi_register) {
if (!FLAG_debug_code) return;
ASM_CODE_COMMENT(this);
DCHECK(COMPRESS_POINTERS_BOOL);
testl(smi_register, Immediate(int32_t{0x10000000}));
Check(zero, AbortReason::kSignedBitOfSmiIsNotZero);
}
void MacroAssembler::AssertCodeT(Register object) { void MacroAssembler::AssertCodeT(Register object) {
if (!FLAG_debug_code) return; if (!FLAG_debug_code) return;
ASM_CODE_COMMENT(this); ASM_CODE_COMMENT(this);
......
...@@ -353,9 +353,11 @@ class V8_EXPORT_PRIVATE TurboAssembler ...@@ -353,9 +353,11 @@ class V8_EXPORT_PRIVATE TurboAssembler
// Convert smi to word-size sign-extended value. // Convert smi to word-size sign-extended value.
void SmiUntag(Register reg); void SmiUntag(Register reg);
void SmiUntagUnsigned(Register reg);
// Requires dst != src // Requires dst != src
void SmiUntag(Register dst, Register src); void SmiUntag(Register dst, Register src);
void SmiUntag(Register dst, Operand src); void SmiUntag(Register dst, Operand src);
void SmiUntagUnsigned(Register dst, Operand src);
// Convert smi to 32-bit value. // Convert smi to 32-bit value.
void SmiToInt32(Register reg); void SmiToInt32(Register reg);
...@@ -462,6 +464,10 @@ class V8_EXPORT_PRIVATE TurboAssembler ...@@ -462,6 +464,10 @@ class V8_EXPORT_PRIVATE TurboAssembler
// have zeros in the top 32 bits, enabled via --debug-code. // have zeros in the top 32 bits, enabled via --debug-code.
void AssertZeroExtended(Register reg) NOOP_UNLESS_DEBUG_CODE; void AssertZeroExtended(Register reg) NOOP_UNLESS_DEBUG_CODE;
// Abort execution if the signed bit of smi register with pointer compression
// is not zero, enabled via --debug-code.
void AssertSignedBitOfSmiIsZero(Register smi) NOOP_UNLESS_DEBUG_CODE;
// Like Assert(), but always enabled. // Like Assert(), but always enabled.
void Check(Condition cc, AbortReason reason); void Check(Condition cc, AbortReason reason);
...@@ -600,6 +606,7 @@ class V8_EXPORT_PRIVATE TurboAssembler ...@@ -600,6 +606,7 @@ class V8_EXPORT_PRIVATE TurboAssembler
// Loads a field containing smi value and untags it. // Loads a field containing smi value and untags it.
void SmiUntagField(Register dst, Operand src); void SmiUntagField(Register dst, Operand src);
void SmiUntagFieldUnsigned(Register dst, Operand src);
// Compresses tagged value if necessary and stores it to given on-heap // Compresses tagged value if necessary and stores it to given on-heap
// location. // location.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment