Index: src/compiler/mips/code-generator-mips.cc |
diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc |
index 26074af6275f76c43b0b8924235e6075f07776d6..d1f54e59b04db6b0a41711100f566abf9e1b4597 100644 |
--- a/src/compiler/mips/code-generator-mips.cc |
+++ b/src/compiler/mips/code-generator-mips.cc |
@@ -830,6 +830,210 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ sra(i.OutputRegister(), i.InputRegister(0), imm); |
} |
break; |
+ case kMipsShlPair: { |
+ if (instr->InputAt(2)->IsRegister()) { |
akos.palfi.imgtec
2016/03/24 12:10:19
Please move this code into the macro-assembler.
F
Marija Antic
2016/03/24 15:40:34
Done.
|
+ Label less_than_32; |
+ Label zero_shift; |
+ Label word_shift; |
+ Label done; |
+ __ Branch(&less_than_32, lt, i.InputRegister(2), Operand(32)); |
+ |
+ __ Branch(&word_shift, eq, i.InputRegister(2), Operand(32)); |
+ |
+ // Shift more than 32 |
+ __ li(kScratchReg, 0x20); |
balazs.kilvady
2016/03/24 11:52:46
Using Operand(32) in the above 2 Branches causes 2
Marija Antic
2016/03/24 15:40:34
Done.
|
+ __ Subu(kScratchReg, i.InputRegister(2), kScratchReg); |
+ __ mov(i.OutputRegister(0), zero_reg); |
+ __ sllv(i.OutputRegister(1), i.InputRegister(0), kScratchReg); |
+ __ Branch(&done); |
+ |
+ // Word shift |
+ __ bind(&word_shift); |
+ __ mov(i.OutputRegister(0), zero_reg); |
+ __ mov(i.OutputRegister(1), i.InputRegister(0)); |
+ __ Branch(&done); |
+ |
+ __ bind(&less_than_32); |
+ |
+ // Check if zero shift |
+ __ Branch(&zero_shift, eq, i.InputRegister(2), Operand(zero_reg)); |
+ |
+ // Shift less than 32 |
+ __ li(kScratchReg, 0x20); |
+ __ Subu(kScratchReg, kScratchReg, i.InputRegister(2)); |
+ __ sllv(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(2)); |
+ __ sllv(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); |
+ __ srlv(kScratchReg, i.InputRegister(0), kScratchReg); |
+ __ Or(i.OutputRegister(1), i.OutputRegister(1), kScratchReg); |
+ __ Branch(&done); |
+ |
+ // Zero shift |
+ __ bind(&zero_shift); |
+ __ mov(i.OutputRegister(0), i.InputRegister(0)); |
+ __ mov(i.OutputRegister(1), i.InputRegister(1)); |
+ __ bind(&done); |
+ } else { |
+ int32_t imm = i.InputOperand(2).immediate(); |
+ if (imm < 32) { |
+ if (imm == 0) { |
+ __ mov(i.OutputRegister(0), i.InputRegister(0)); |
+ __ mov(i.OutputRegister(1), i.InputRegister(1)); |
+ } else { |
+ __ sll(i.OutputRegister(1), i.InputRegister(1), imm); |
+ __ sll(i.OutputRegister(0), i.InputRegister(0), imm); |
+ imm = 32 - imm; |
+ __ srl(kScratchReg, i.InputRegister(0), imm); |
+ __ Or(i.OutputRegister(1), i.OutputRegister(1), kScratchReg); |
+ } |
+ } else { |
+ if (imm == 32) { |
+ __ mov(i.OutputRegister(0), zero_reg); |
+ __ mov(i.OutputRegister(1), i.InputRegister(0)); |
+ } else { |
+ imm = imm - 32; |
+ __ mov(i.OutputRegister(0), zero_reg); |
+ __ sll(i.OutputRegister(1), i.InputRegister(0), imm); |
+ } |
+ } |
+ } |
+ } break; |
+ case kMipsShrPair: { |
+ if (instr->InputAt(2)->IsRegister()) { |
akos.palfi.imgtec
2016/03/24 12:10:19
Same here, please move to the macro-asm.
Marija Antic
2016/03/24 15:40:34
Done.
|
+ Label less_than_32; |
+ Label zero_shift; |
+ Label word_shift; |
+ Label done; |
+ __ Branch(&less_than_32, lt, i.InputRegister(2), Operand(32)); |
+ |
+ __ Branch(&word_shift, eq, i.InputRegister(2), Operand(32)); |
+ |
+ // Shift more than 32 |
+ __ li(kScratchReg, 0x20); |
+ __ Subu(kScratchReg, i.InputRegister(2), kScratchReg); |
+ __ mov(i.OutputRegister(1), zero_reg); |
+ __ srlv(i.OutputRegister(0), i.InputRegister(1), kScratchReg); |
+ __ Branch(&done); |
+ |
+ // Word shift |
+ __ bind(&word_shift); |
+ __ mov(i.OutputRegister(1), zero_reg); |
+ __ mov(i.OutputRegister(0), i.InputRegister(1)); |
+ __ Branch(&done); |
+ |
+ __ bind(&less_than_32); |
+ |
+ // Check if zero shift |
+ __ Branch(&zero_shift, eq, i.InputRegister(2), Operand(zero_reg)); |
+ |
+ // Shift less than 32 |
+ __ li(kScratchReg, 0x20); |
+ __ Subu(kScratchReg, kScratchReg, i.InputRegister(2)); |
+ __ srlv(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(2)); |
+ __ srlv(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); |
+ __ sllv(kScratchReg, i.InputRegister(1), kScratchReg); |
+ __ Or(i.OutputRegister(0), i.OutputRegister(0), kScratchReg); |
+ __ Branch(&done); |
+ |
+ // Zero shift |
+ __ bind(&zero_shift); |
+ __ mov(i.OutputRegister(0), i.InputRegister(0)); |
+ __ mov(i.OutputRegister(1), i.InputRegister(1)); |
+ |
+ __ bind(&done); |
+ } else { |
+ int32_t imm = i.InputOperand(2).immediate(); |
+ if (imm < 32) { |
+ if (imm == 0) { |
+ __ mov(i.OutputRegister(0), i.InputRegister(0)); |
+ __ mov(i.OutputRegister(1), i.InputRegister(1)); |
+ } else { |
+ __ srl(i.OutputRegister(1), i.InputRegister(1), imm); |
+ __ srl(i.OutputRegister(0), i.InputRegister(0), imm); |
+ imm = 32 - imm; |
+ __ sll(kScratchReg, i.InputRegister(1), imm); |
+ __ Or(i.OutputRegister(0), i.OutputRegister(0), kScratchReg); |
+ } |
+ } else { |
+ if (imm == 32) { |
+ __ mov(i.OutputRegister(1), zero_reg); |
+ __ mov(i.OutputRegister(0), i.InputRegister(1)); |
+ } else { |
+ imm = imm - 32; |
+ __ mov(i.OutputRegister(1), zero_reg); |
+ __ srl(i.OutputRegister(0), i.InputRegister(1), imm); |
+ } |
+ } |
+ } |
+ } break; |
+ case kMipsSarPair: { |
+ if (instr->InputAt(2)->IsRegister()) { |
akos.palfi.imgtec
2016/03/24 12:10:19
Same here, please move to the macro-asm.
Marija Antic
2016/03/24 15:40:34
Done.
|
+ Label less_than_32; |
+ Label zero_shift; |
+ Label word_shift; |
+ Label done; |
+ __ Branch(&less_than_32, lt, i.InputRegister(2), Operand(32)); |
+ |
+ __ Branch(&word_shift, eq, i.InputRegister(2), Operand(32)); |
+ |
+ // Shift more than 32 |
+ __ li(kScratchReg, 0x20); |
+ __ li(kScratchReg2, 0x1F); |
+ __ Subu(kScratchReg, i.InputRegister(2), kScratchReg); |
+ __ srav(i.OutputRegister(1), i.InputRegister(1), kScratchReg2); |
+ __ srav(i.OutputRegister(0), i.InputRegister(1), kScratchReg); |
+ __ Branch(&done); |
+ |
+ // Word shift |
+ __ bind(&word_shift); |
+ __ li(kScratchReg2, 0x1F); |
+ __ srav(i.OutputRegister(1), i.InputRegister(1), kScratchReg2); |
+ __ mov(i.OutputRegister(0), i.InputRegister(1)); |
+ __ Branch(&done); |
+ |
+ __ bind(&less_than_32); |
+ // Check if zero shift |
+ __ Branch(&zero_shift, eq, i.InputRegister(2), Operand(zero_reg)); |
+ |
+ // Shift less than 32 |
+ __ li(kScratchReg, 0x20); |
+ __ Subu(kScratchReg, kScratchReg, i.InputRegister(2)); |
+ __ srav(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(2)); |
+ __ srlv(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); |
+ __ sllv(kScratchReg, i.InputRegister(1), kScratchReg); |
+ __ Or(i.OutputRegister(0), i.OutputRegister(0), kScratchReg); |
+ __ Branch(&done); |
+ |
+ // Zero shift |
+ __ bind(&zero_shift); |
+ __ mov(i.OutputRegister(0), i.InputRegister(0)); |
+ __ mov(i.OutputRegister(1), i.InputRegister(1)); |
+ |
+ __ bind(&done); |
+ } else { |
+ int32_t imm = i.InputOperand(2).immediate(); |
+ if (imm < 32) { |
+ if (imm == 0) { |
+ __ mov(i.OutputRegister(0), i.InputRegister(0)); |
+ __ mov(i.OutputRegister(1), i.InputRegister(1)); |
+ } else { |
+ __ sra(i.OutputRegister(1), i.InputRegister(1), imm); |
+ __ srl(i.OutputRegister(0), i.InputRegister(0), imm); |
+ imm = 32 - imm; |
+ __ sll(kScratchReg, i.InputRegister(1), imm); |
+ __ Or(i.OutputRegister(0), i.OutputRegister(0), kScratchReg); |
+ } |
+ } else { |
+ if (imm == 32) { |
+ __ sra(i.OutputRegister(1), i.InputRegister(1), 31); |
+ __ mov(i.OutputRegister(0), i.InputRegister(1)); |
+ } else { |
+ imm = imm - 32; |
+ __ sra(i.OutputRegister(1), i.InputRegister(1), 31); |
+ __ sra(i.OutputRegister(0), i.InputRegister(1), imm); |
+ } |
+ } |
+ } |
+ } break; |
case kMipsExt: |
__ Ext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1), |
i.InputInt8(2)); |
@@ -914,6 +1118,32 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kMipsCmpD: |
// Psuedo-instruction used for FP cmp/branch. No opcode emitted here. |
break; |
+ case kMipsAddPair: { |
+ Label no_overflow; |
+ // Add lower word |
+ __ Addu(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); |
+ __ Addu(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(3)); |
+ // Check for lower word overflow |
akos.palfi.imgtec
2016/03/24 12:10:19
Instead of manual overflow checking here, can you
Marija Antic
2016/03/25 11:17:58
Simple switching to AddBranchOvf() causes test fai
|
+ __ Sltu(kScratchReg, i.OutputRegister(0), i.InputRegister(0)); |
+ __ Sltu(kScratchReg2, i.OutputRegister(0), i.InputRegister(2)); |
+ __ Or(kScratchReg, kScratchReg2, kScratchReg); |
+ __ Branch(&no_overflow, eq, kScratchReg, Operand(zero_reg)); |
+ // Increment higher word if there was overflow |
+ __ Addu(i.OutputRegister(1), i.OutputRegister(1), 0x1); |
+ __ bind(&no_overflow); |
+ } break; |
+ case kMipsSubPair: { |
+ Label no_overflow; |
+ // Subtract lower word |
+ __ Subu(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); |
+ __ Subu(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(3)); |
+ // Check for lower word underflow |
akos.palfi.imgtec
2016/03/24 12:10:19
Same question here with SubBranchOvf().
|
+ __ Sltu(kScratchReg, i.InputRegister(0), i.OutputRegister(0)); |
+ __ Branch(&no_overflow, eq, kScratchReg, Operand(zero_reg)); |
+ // Decrement higher word if there was underflow |
+ __ Subu(i.OutputRegister(1), i.OutputRegister(1), 0x1); |
+ __ bind(&no_overflow); |
+ } break; |
case kMipsAddD: |
// TODO(plind): add special case: combine mult & add. |
__ add_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |