Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index 02f7bee24811f9280148137a2df53782e9508855..864011211192c46feedec1bf318df2463a2261df 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -1327,6 +1327,211 @@ void MacroAssembler::MultiPopReversedFPU(RegList regs) { |
addiu(sp, sp, stack_offset); |
} |
+void MacroAssembler::ShlPair(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ Register shift) { |
+ Label less_than_32; |
+ Label zero_shift; |
+ Label word_shift; |
+ Label done; |
+ Register kScratchReg = s3; |
+ li(kScratchReg, 0x20); |
+ Branch(&less_than_32, lt, shift, Operand(kScratchReg)); |
+ |
+ Branch(&word_shift, eq, shift, Operand(kScratchReg)); |
+ // Shift more than 32 |
+ Subu(kScratchReg, shift, kScratchReg); |
+ mov(dst_low, zero_reg); |
+ sllv(dst_high, src_low, kScratchReg); |
+ Branch(&done); |
+ // Word shift |
+ bind(&word_shift); |
+ mov(dst_low, zero_reg); |
+ mov(dst_high, src_low); |
+ Branch(&done); |
+ |
+ bind(&less_than_32); |
+ // Check if zero shift |
+ Branch(&zero_shift, eq, shift, Operand(zero_reg)); |
+ // Shift less than 32 |
+ Subu(kScratchReg, kScratchReg, shift); |
+ sllv(dst_high, src_high, shift); |
+ sllv(dst_low, src_low, shift); |
+ srlv(kScratchReg, src_low, kScratchReg); |
+ Or(dst_high, dst_high, kScratchReg); |
+ Branch(&done); |
+ // Zero shift |
+ bind(&zero_shift); |
+ mov(dst_low, src_low); |
+ mov(dst_high, src_high); |
+ bind(&done); |
+} |
+ |
+void MacroAssembler::ShlPair(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ uint32_t shift) { |
+ Register kScratchReg = s3; |
+ if (shift < 32) { |
+ if (shift == 0) { |
+ mov(dst_low, src_low); |
+ mov(dst_high, src_high); |
+ } else { |
+ sll(dst_high, src_high, shift); |
+ sll(dst_low, src_low, shift); |
+ shift = 32 - shift; |
+ srl(kScratchReg, src_low, shift); |
+ Or(dst_high, dst_high, kScratchReg); |
+ } |
+ } else { |
+ if (shift == 32) { |
+ mov(dst_low, zero_reg); |
+ mov(dst_high, src_low); |
+ } else { |
+ shift = shift - 32; |
+ mov(dst_low, zero_reg); |
+ sll(dst_high, src_low, shift); |
+ } |
+ } |
+} |
+ |
+void MacroAssembler::ShrPair(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ Register shift) { |
+ Label less_than_32; |
+ Label zero_shift; |
+ Label word_shift; |
+ Label done; |
+ Register kScratchReg = s3; |
+ li(kScratchReg, 0x20); |
+ Branch(&less_than_32, lt, shift, Operand(kScratchReg)); |
+ |
+ Branch(&word_shift, eq, shift, Operand(kScratchReg)); |
+ // Shift more than 32 |
+ Subu(kScratchReg, shift, kScratchReg); |
+ mov(dst_high, zero_reg); |
+ srlv(dst_low, src_high, kScratchReg); |
+ Branch(&done); |
+ // Word shift |
+ bind(&word_shift); |
+ mov(dst_high, zero_reg); |
+ mov(dst_low, src_high); |
+ Branch(&done); |
+ |
+ bind(&less_than_32); |
+ // Check if zero shift |
+ Branch(&zero_shift, eq, shift, Operand(zero_reg)); |
+ // Shift less than 32 |
+ Subu(kScratchReg, kScratchReg, shift); |
+ srlv(dst_high, src_high, shift); |
+ srlv(dst_low, src_low, shift); |
+ sllv(kScratchReg, src_high, kScratchReg); |
+ Or(dst_low, dst_low, kScratchReg); |
+ Branch(&done); |
+ // Zero shift |
+ bind(&zero_shift); |
+ mov(dst_low, src_low); |
+ mov(dst_high, src_high); |
+ bind(&done); |
+} |
+ |
+void MacroAssembler::ShrPair(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ uint32_t shift) { |
+ Register kScratchReg = s3; |
+ if (shift < 32) { |
+ if (shift == 0) { |
+ mov(dst_low, src_low); |
+ mov(dst_high, src_high); |
+ } else { |
+ srl(dst_high, src_high, shift); |
+ srl(dst_low, src_low, shift); |
+ shift = 32 - shift; |
+ sll(kScratchReg, src_high, shift); |
+ Or(dst_low, dst_low, kScratchReg); |
+ } |
+ } else { |
+ if (shift == 32) { |
+ mov(dst_high, zero_reg); |
+ mov(dst_low, src_high); |
+ } else { |
+ shift = shift - 32; |
+ mov(dst_high, zero_reg); |
+ srl(dst_low, src_high, shift); |
+ } |
+ } |
+} |
+ |
+void MacroAssembler::SarPair(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ Register shift) { |
+ Label less_than_32; |
+ Label zero_shift; |
+ Label word_shift; |
+ Label done; |
+ Register kScratchReg = s3; |
+ Register kScratchReg2 = s4; |
+ li(kScratchReg, 0x20); |
+ Branch(&less_than_32, lt, shift, Operand(kScratchReg)); |
+ |
+ Branch(&word_shift, eq, shift, Operand(kScratchReg)); |
+ |
+ // Shift more than 32 |
+ li(kScratchReg2, 0x1F); |
+ Subu(kScratchReg, shift, kScratchReg); |
+ srav(dst_high, src_high, kScratchReg2); |
+ srav(dst_low, src_high, kScratchReg); |
+ Branch(&done); |
+ // Word shift |
+ bind(&word_shift); |
+ li(kScratchReg2, 0x1F); |
+ srav(dst_high, src_high, kScratchReg2); |
+ mov(dst_low, src_high); |
+ Branch(&done); |
+ |
+ bind(&less_than_32); |
+ // Check if zero shift |
+ Branch(&zero_shift, eq, shift, Operand(zero_reg)); |
+ |
+ // Shift less than 32 |
+ Subu(kScratchReg, kScratchReg, shift); |
+ srav(dst_high, src_high, shift); |
+ srlv(dst_low, src_low, shift); |
+ sllv(kScratchReg, src_high, kScratchReg); |
+ Or(dst_low, dst_low, kScratchReg); |
+ Branch(&done); |
+ // Zero shift |
+ bind(&zero_shift); |
+ mov(dst_low, src_low); |
+ mov(dst_high, src_high); |
+ bind(&done); |
+} |
+ |
+void MacroAssembler::SarPair(Register dst_low, Register dst_high, |
+ Register src_low, Register src_high, |
+ uint32_t shift) { |
+ Register kScratchReg = s3; |
+ if (shift < 32) { |
+ if (shift == 0) { |
+ mov(dst_low, src_low); |
+ mov(dst_high, src_high); |
+ } else { |
+ sra(dst_high, src_high, shift); |
+ srl(dst_low, src_low, shift); |
+ shift = 32 - shift; |
+ sll(kScratchReg, src_high, shift); |
+ Or(dst_low, dst_low, kScratchReg); |
+ } |
+ } else { |
+ if (shift == 32) { |
+ sra(dst_high, src_high, 31); |
+ mov(dst_low, src_high); |
+ } else { |
+ shift = shift - 32; |
+ sra(dst_high, src_high, 31); |
+ sra(dst_low, src_high, shift); |
+ } |
+ } |
+} |
void MacroAssembler::Ext(Register rt, |
Register rs, |