Chromium Code Reviews| 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); |