Index: src/arm/macro-assembler-arm.cc |
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
index 80aef0c4ffefa253069de6ac66473a4ac116b2a4..936839e4eaf08cb2220d85db526d30bc17122bb7 100644 |
--- a/src/arm/macro-assembler-arm.cc |
+++ b/src/arm/macro-assembler-arm.cc |
@@ -1056,7 +1056,45 @@ void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { |
vmov(dst, VmovIndexLo, src); |
} |
} |
+void MacroAssembler::PairLsl(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ Register scratch, Register shift) { |
+ Label less_than_32; |
martyn.capewell
2016/03/04 18:54:57
Add some register alias assertions: perhaps !AreAl
ahaas
2016/03/07 13:40:49
I enforced src_low == dst_low now in the register
|
+ Label done; |
+ cmp_raw_immediate(shift, 32); |
+ b(lt, &less_than_32); |
+ eor(dst_low, dst_low, Operand(dst_low)); |
martyn.capewell
2016/03/04 18:54:57
mov(dst_low, Operand(0))
martyn.capewell
2016/03/04 18:54:57
Switching zero and shift operations here would all
ahaas
2016/03/07 13:40:48
Done.
|
+ and_(scratch, shift, Operand(0x1f)); |
+ lsl(dst_high, src_low, Operand(scratch)); |
+ jmp(&done); |
+ bind(&less_than_32); |
+ rsb(scratch, shift, Operand(32)); |
+ lsr(dst_low, src_low, Operand(scratch)); |
+ lsl(dst_high, src_high, Operand(shift)); |
+ orr(dst_high, dst_high, dst_low); |
+ lsl(dst_low, src_low, Operand(shift)); |
martyn.capewell
2016/03/04 18:54:57
You can combine shift with orr here:
lsl(dst_hig
ahaas
2016/03/07 13:40:48
Thanks, that's really helpful.
|
+ bind(&done); |
+} |
+void MacroAssembler::PairLsl(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ Register scratch, uint32_t shift) { |
martyn.capewell
2016/03/04 18:54:57
scratch isn't used.
ahaas
2016/03/07 13:40:49
I removed it.
|
+ Label less_than_32; |
martyn.capewell
2016/03/04 18:54:57
Add some register alias assertions. At the top lev
ahaas
2016/03/07 13:40:49
Done.
|
+ Label done; |
+ if (shift >= 32) { |
martyn.capewell
2016/03/04 18:54:57
Switch the zero and shift instructions here, so ds
ahaas
2016/03/07 13:40:49
Done.
|
+ eor(dst_low, dst_low, Operand(dst_low)); |
martyn.capewell
2016/03/04 18:54:57
mov(dst_low, Operand(0))
ahaas
2016/03/07 13:40:48
Done.
|
+ shift &= 0x1f; |
+ lsl(dst_high, src_low, Operand(shift)); |
+ } else if (shift == 0) { |
martyn.capewell
2016/03/04 18:54:57
Assert dst_low != src_high.
|
+ mov(dst_low, src_low); |
martyn.capewell
2016/03/04 18:54:57
Use Move() here to eliminate redundant instruction
ahaas
2016/03/07 13:40:49
Aha, that's useful. Thanks.
|
+ mov(dst_high, src_high); |
+ } else { |
+ lsr(dst_low, src_low, Operand(32 - shift)); |
+ lsl(dst_high, src_high, Operand(shift)); |
+ orr(dst_high, dst_high, dst_low); |
+ lsl(dst_low, src_low, Operand(shift)); |
martyn.capewell
2016/03/04 18:54:57
Combine shift with orr:
lsl(dst_high, src_high,
ahaas
2016/03/07 13:40:48
Done.
|
+ } |
+} |
void MacroAssembler::LoadConstantPoolPointerRegisterFromCodeTargetAddress( |
Register code_target_address) { |