@@ -1363,10 +1363,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
1363 | 1363 | case kLoong64Sub_d: |
1364 | 1364 | __ Sub_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
1365 | 1365 | break; |
1366 | | - case kLoong64SubOvf_d: |
| 1366 | + case kLoong64SubOvf_d: { |
| 1367 | + UseScratchRegisterScope temps(masm()); |
| 1368 | + DCHECK(temps.hasAvailable()); |
| 1369 | + temps.Exclude(t8); |
1367 | 1370 | __ SubOverflow_d(i.OutputRegister(), i.InputRegister(0), |
1368 | 1371 | i.InputOperand(1), t8); |
1369 | 1372 | break; |
| 1373 | + } |
1370 | 1374 | case kLoong64Mul_w: |
1371 | 1375 | __ Mul_w(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
1372 | 1376 | break; |
@@ -4591,7 +4595,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
4591 | 4595 | } |
4592 | 4596 | return; |
4593 | 4597 | } else { |
4594 | | - PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n", |
| 4598 | + PrintF("AssembleArchBoolean Unimplemented arch_opcode is : %d\n", |
4595 | 4599 | instr->arch_opcode()); |
4596 | 4600 | TRACE("UNIMPLEMENTED code_generator_loong64: %s at line %d\n", __FUNCTION__, |
4597 | 4601 | __LINE__); |
@@ -4646,56 +4650,49 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr, |
4646 | 4650 | size_t output_index = instr->OutputCount() - 1; |
4647 | 4651 | // We don't know how many inputs were consumed by the condition, so we have to |
4648 | 4652 | // calculate the indices of the last two inputs. |
4649 | | - DCHECK_GE(instr->InputCount(), 4); |
4650 | 4653 | size_t true_value_index = instr->InputCount() - 2; |
4651 | 4654 | size_t false_value_index = instr->InputCount() - 1; |
| 4655 | + Register result = i.OutputRegister(output_index); |
| 4656 | + Register v_true = i.InputOrZeroRegister(true_value_index); |
| 4657 | + Register v_false = i.InputOrZeroRegister(false_value_index); |
| 4658 | + |
| 4659 | + DCHECK( |
| 4660 | + LocationOperand::cast(instr->OutputAt(output_index))->representation() == |
| 4661 | + MachineRepresentation::kWord64); |
4652 | 4662 |
|
4653 | 4663 | if (instr->arch_opcode() == kLoong64Tst) { |
| 4664 | + DCHECK_GE(instr->InputCount(), 4); |
4654 | 4665 | Condition cc = FlagsConditionToConditionTst(condition); |
4655 | | - Register result = i.OutputRegister(output_index); |
4656 | | - Register v_true = i.InputOrZeroRegister(true_value_index); |
4657 | | - Register v_false = i.InputOrZeroRegister(false_value_index); |
4658 | | - if (v_true == zero_reg || v_false == zero_reg) { |
4659 | | - if (v_true == zero_reg) { |
4660 | | - v_true = v_false; |
4661 | | - cc = NegateCondition(cc); |
4662 | | - } |
4663 | | - if (cc == eq) |
4664 | | - __ masknez(result, v_true, t8); |
4665 | | - else |
4666 | | - __ maskeqz(result, v_true, t8); |
4667 | | - } else if (result == v_true || result == v_false) { |
4668 | | - if (result == v_false) { |
4669 | | - v_false = v_true; |
4670 | | - cc = NegateCondition(cc); |
4671 | | - } |
4672 | | - Label done; |
4673 | | - __ Branch(&done, cc, t8, Operand(0)); |
4674 | | - __ Move(result, v_false); |
4675 | | - __ bind(&done); |
4676 | | - } else { |
4677 | | - UseScratchRegisterScope temps(masm()); |
4678 | | - Register scratch = temps.Acquire(); |
4679 | | - if (cc == eq) { |
4680 | | - Register temp = v_true; |
4681 | | - v_true = v_false; |
4682 | | - v_false = temp; |
4683 | | - } |
4684 | | - __ maskeqz(scratch, v_true, t8); |
4685 | | - __ masknez(result, v_false, t8); |
4686 | | - __ or_(result, scratch, result); |
| 4666 | + if (cc == eq) { |
| 4667 | + Register temp = v_true; |
| 4668 | + v_true = v_false; |
| 4669 | + v_false = temp; |
4687 | 4670 | } |
| 4671 | + __ SelectWord(result, t8, v_true, v_false); |
4688 | 4672 | UseScratchRegisterScope temps(masm()); |
4689 | 4673 | temps.Include(t8); |
4690 | 4674 | return; |
4691 | 4675 | } else if (instr->arch_opcode() == kLoong64Cmp64 || |
4692 | | - instr->arch_opcode() == kLoong64Cmp32) { |
| 4676 | + instr->arch_opcode() == kLoong64Cmp32 || |
| 4677 | + instr->arch_opcode() == kArchStackPointerGreaterThan) { |
4693 | 4678 | Condition cc = FlagsConditionToConditionCmp(condition); |
4694 | | - Register left = i.InputRegister(0); |
4695 | | - Operand right = i.InputOperand(1); |
4696 | | - Register result = i.OutputRegister(output_index); |
4697 | | - Register v_true = i.InputOrZeroRegister(true_value_index); |
4698 | | - Register v_false = i.InputOrZeroRegister(false_value_index); |
| 4679 | + Register left = no_reg; |
| 4680 | + Operand right = Operand(0); |
| 4681 | + if (instr->arch_opcode() == kArchStackPointerGreaterThan) { |
| 4682 | + DCHECK_GE(instr->InputCount(), 3); |
| 4683 | + DCHECK((cc == ls) || (cc == hi)); |
| 4684 | + left = sp; |
| 4685 | + right = i.InputOperand(0); |
| 4686 | + uint32_t offset; |
| 4687 | + if (ShouldApplyOffsetToStackCheck(instr, &offset)) { |
| 4688 | + left = i.TempRegister(1); |
| 4689 | + __ Sub_d(left, sp, offset); |
| 4690 | + } |
| 4691 | + } else { |
| 4692 | + DCHECK_GE(instr->InputCount(), 4); |
| 4693 | + left = i.InputRegister(0); |
| 4694 | + right = i.InputOperand(1); |
| 4695 | + } |
4699 | 4696 | if (v_true == zero_reg || v_false == zero_reg) { |
4700 | 4697 | if (v_true == zero_reg) { |
4701 | 4698 | v_true = v_false; |
@@ -4725,6 +4722,108 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr, |
4725 | 4722 | __ bind(&done); |
4726 | 4723 | } |
4727 | 4724 | return; |
| 4725 | + } else if (instr->arch_opcode() == kLoong64Add_d || |
| 4726 | + instr->arch_opcode() == kLoong64Sub_d) { |
| 4727 | + DCHECK_GE(instr->InputCount(), 4); |
| 4728 | + Condition cc = FlagsConditionToConditionOvf(condition); |
| 4729 | + if (cc == eq) { |
| 4730 | + Register temp = v_true; |
| 4731 | + v_true = v_false; |
| 4732 | + v_false = temp; |
| 4733 | + } |
| 4734 | + UseScratchRegisterScope temps(masm()); |
| 4735 | + Register scratch1 = temps.Acquire(); |
| 4736 | + Register scratch2 = temps.Acquire(); |
| 4737 | + __ srai_d(scratch1, i.OutputRegister(), 32); |
| 4738 | + __ srai_w(scratch2, i.OutputRegister(), 31); |
| 4739 | + if (v_false == zero_reg) { |
| 4740 | + __ xor_(scratch1, scratch1, scratch2); |
| 4741 | + __ maskeqz(result, v_true, scratch1); |
| 4742 | + } else if (v_true == zero_reg) { |
| 4743 | + __ xor_(scratch1, scratch1, scratch2); |
| 4744 | + __ masknez(result, v_false, scratch1); |
| 4745 | + } else if (result == v_true || result == v_false) { |
| 4746 | + if (result == v_false) { |
| 4747 | + v_false = v_true; |
| 4748 | + cc = NegateCondition(cc); |
| 4749 | + } |
| 4750 | + Label done; |
| 4751 | + __ Branch(&done, cc, scratch2, Operand(scratch1)); |
| 4752 | + __ Move(result, v_false); |
| 4753 | + __ bind(&done); |
| 4754 | + } else { |
| 4755 | + Label true_label, done; |
| 4756 | + __ Branch(&true_label, cc, scratch2, Operand(scratch1)); |
| 4757 | + __ Move(result, v_false); |
| 4758 | + __ Branch(&done); |
| 4759 | + __ bind(&true_label); |
| 4760 | + __ Move(result, v_true); |
| 4761 | + __ bind(&done); |
| 4762 | + } |
| 4763 | + return; |
| 4764 | + } else if (instr->arch_opcode() == kLoong64AddOvf_d || |
| 4765 | + instr->arch_opcode() == kLoong64SubOvf_d) { |
| 4766 | + DCHECK_GE(instr->InputCount(), 4); |
| 4767 | + // Overflow occurs if overflow register is negative |
| 4768 | + Condition cc = lt; |
| 4769 | + if (condition == kNotOverflow) { |
| 4770 | + Register temp = v_true; |
| 4771 | + v_true = v_false; |
| 4772 | + v_false = temp; |
| 4773 | + } |
| 4774 | + if (v_false == zero_reg) { |
| 4775 | + __ slt(t8, t8, zero_reg); |
| 4776 | + __ maskeqz(result, v_true, t8); |
| 4777 | + } else if (v_true == zero_reg) { |
| 4778 | + __ slt(t8, t8, zero_reg); |
| 4779 | + __ masknez(result, v_false, t8); |
| 4780 | + } else if (result == v_true || result == v_false) { |
| 4781 | + if (result == v_false) { |
| 4782 | + v_false = v_true; |
| 4783 | + cc = NegateCondition(cc); |
| 4784 | + } |
| 4785 | + Label done; |
| 4786 | + __ Branch(&done, cc, t8, Operand(zero_reg)); |
| 4787 | + __ Move(result, v_false); |
| 4788 | + __ bind(&done); |
| 4789 | + } else { |
| 4790 | + Label true_label, done; |
| 4791 | + __ Branch(&true_label, cc, t8, Operand(zero_reg)); |
| 4792 | + __ Move(result, v_false); |
| 4793 | + __ Branch(&done); |
| 4794 | + __ bind(&true_label); |
| 4795 | + __ Move(result, v_true); |
| 4796 | + __ bind(&done); |
| 4797 | + } |
| 4798 | + UseScratchRegisterScope temps(masm()); |
| 4799 | + temps.Include(t8); |
| 4800 | + } else if (instr->arch_opcode() == kLoong64MulOvf_w || |
| 4801 | + instr->arch_opcode() == kLoong64MulOvf_d) { |
| 4802 | + DCHECK_GE(instr->InputCount(), 4); |
| 4803 | + Condition cc = FlagsConditionToConditionOvf(condition); |
| 4804 | + if (cc == eq) { |
| 4805 | + Register temp = v_true; |
| 4806 | + v_true = v_false; |
| 4807 | + v_false = temp; |
| 4808 | + } |
| 4809 | + __ SelectWord(result, t8, v_true, v_false); |
| 4810 | + UseScratchRegisterScope temps(masm()); |
| 4811 | + temps.Include(t8); |
| 4812 | + return; |
| 4813 | + } else if (instr->arch_opcode() == kLoong64Float32Cmp || |
| 4814 | + instr->arch_opcode() == kLoong64Float64Cmp) { |
| 4815 | + bool predicate; |
| 4816 | + FlagsConditionToConditionCmpFPU(&predicate, condition); |
| 4817 | + UseScratchRegisterScope temps(masm()); |
| 4818 | + Register scratch = temps.Acquire(); |
| 4819 | + if (!predicate) { |
| 4820 | + Register temp = v_true; |
| 4821 | + v_true = v_false; |
| 4822 | + v_false = temp; |
| 4823 | + } |
| 4824 | + __ movcf2gr(scratch, FCC0); |
| 4825 | + __ SelectWord(result, scratch, v_true, v_false); |
| 4826 | + return; |
4728 | 4827 | } else { |
4729 | 4828 | PrintF("AssembleArchSelect Unimplemented arch_opcode is : %d\n", |
4730 | 4829 | instr->arch_opcode()); |
|