Index: src/x64/macro-assembler-x64.cc |
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
index eb3f7c19e3d00ae16c41a6a3576f1886cbf86480..835f861d4dc5777e10e4f525190577225aa1f801 100644 |
--- a/src/x64/macro-assembler-x64.cc |
+++ b/src/x64/macro-assembler-x64.cc |
@@ -2570,6 +2570,51 @@ void MacroAssembler::CheckMap(Register obj, |
} |
+void MacroAssembler::ClampUint8(Register reg) { |
+ Label done; |
+ testl(reg, Immediate(0xFFFFFF00)); |
+ j(zero, &done, Label::kNear); |
+ setcc(negative, reg); // 1 if negative, 0 if positive. |
+ decb(reg); // 0 if negative, 255 if positive. |
+ bind(&done); |
+} |
+ |
+ |
+void MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, |
+ XMMRegister temp_xmm_reg, |
+ Register result_reg, |
+ Register temp_reg) { |
+ Label above_zero; |
+ Label done; |
+ Label in_bounds; |
+ xorps(temp_xmm_reg, temp_xmm_reg); |
+ ucomisd(input_reg, temp_xmm_reg); |
+ j(above, &above_zero, Label::kNear); |
Lasse Reichstein
2011/05/14 09:34:38
I believe NaN should also be converted to zero (i.
danno
2011/05/15 05:50:27
NaN does get set to zero, there is an explicit tes
Lasse Reichstein
2011/05/15 10:18:50
Ack, yes. I didn't consider that "above" would als
|
+ Set(result_reg, 0); |
Lasse Reichstein
2011/05/13 13:17:24
How about setting result to 0 prior to the compare
danno
2011/05/15 05:50:27
Done.
|
+ jmp(&done, Label::kNear); |
+ bind(&above_zero); |
+ uint64_t max_clamp = BitCast<uint64_t, double>(255.0); |
Lasse Reichstein
2011/05/13 13:17:24
How about not capping at 255 until after you have
danno
2011/05/15 05:50:27
Done.
|
+ Set(temp_reg, max_clamp); |
+ movq(temp_xmm_reg, temp_reg); |
Lasse Reichstein
2011/05/13 13:17:24
Use movsd here. Movq makes the CPU think the XMM r
danno
2011/05/15 05:50:27
Done.
|
+ ucomisd(input_reg, temp_xmm_reg); |
+ j(below_equal, &in_bounds, Label::kNear); |
+ Set(result_reg, 255); |
+ jmp(&done, Label::kNear); |
+ bind(&in_bounds); |
+ if (CpuFeatures::IsSupported(SSE4_1)) { |
+ CpuFeatures::Scope scope(SSE4_1); |
+ roundsd(temp_xmm_reg, input_reg, kRoundToNearest); |
Lasse Reichstein
2011/05/13 13:17:24
Roundsd's round-to-nearest rounds to even numbers
Lasse Reichstein
2011/05/14 09:34:38
I tried to look up a spec for typed arrays, and if
danno
2011/05/15 05:50:27
Done.
danno
2011/05/15 05:50:27
This code is specifically for CanvasPixelArrays (w
Lasse Reichstein
2011/05/15 10:18:50
I read that as clamping positions to the edge of t
|
+ } else { |
+ uint64_t one_half = BitCast<uint64_t, double>(0.5); |
+ Set(temp_reg, one_half); |
+ movq(temp_xmm_reg, temp_reg); |
Lasse Reichstein
2011/05/13 13:17:24
Movsd.
danno
2011/05/15 05:50:27
Done.
|
+ addsd(temp_xmm_reg, input_reg); |
Lasse Reichstein
2011/05/13 13:17:24
Adding 0.5 and truncating doesn't work perfectly a
danno
2011/05/15 05:50:27
I am aware of this imprecision, but this is exactl
Lasse Reichstein
2011/05/15 10:18:51
Good :)
|
+ } |
+ cvttsd2si(result_reg, temp_xmm_reg); |
+ bind(&done); |
+} |
+ |
+ |
void MacroAssembler::AbortIfNotNumber(Register object) { |
Label ok; |
Condition is_smi = CheckSmi(object); |