diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/optimizing/block_builder.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 54 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 116 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_builder.cc | 26 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_builder.h | 4 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 2 | ||||
| -rw-r--r-- | compiler/optimizing/load_store_elimination.cc | 38 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.cc | 1 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 4 | ||||
| -rw-r--r-- | compiler/optimizing/ssa_builder.cc | 4 | ||||
| -rw-r--r-- | compiler/utils/mips/assembler_mips.cc | 1394 | ||||
| -rw-r--r-- | compiler/utils/mips/assembler_mips.h | 127 |
12 files changed, 699 insertions, 1073 deletions
diff --git a/compiler/optimizing/block_builder.cc b/compiler/optimizing/block_builder.cc index a6687fe258..ed000327ff 100644 --- a/compiler/optimizing/block_builder.cc +++ b/compiler/optimizing/block_builder.cc @@ -58,6 +58,7 @@ bool HBasicBlockBuilder::CreateBranchTargets() { // cannot have any code afterwards. } else { // The TryItem spans beyond the end of the CodeItem. This is invalid code. + VLOG(compiler) << "Not compiled: TryItem spans beyond the end of the CodeItem"; return false; } } @@ -110,6 +111,7 @@ bool HBasicBlockBuilder::CreateBranchTargets() { if (next == instructions.end()) { // In the normal case we should never hit this but someone can artificially forge a dex // file to fall-through out the method code. In this case we bail out compilation. + VLOG(compiler) << "Not compiled: Fall-through beyond the CodeItem"; return false; } MaybeCreateBlockAt(next.DexPc()); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 6376f03b26..1f6b214f11 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -1941,6 +1941,7 @@ void LocationsBuilderMIPS::HandleBinaryOp(HBinaryOperation* instruction) { DCHECK_EQ(instruction->InputCount(), 2U); LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction); DataType::Type type = instruction->GetResultType(); + bool isR6 = codegen_->GetInstructionSetFeatures().IsR6(); switch (type) { case DataType::Type::kInt32: { locations->SetInAt(0, Location::RequiresRegister()); @@ -1950,11 +1951,22 @@ void LocationsBuilderMIPS::HandleBinaryOp(HBinaryOperation* instruction) { int32_t imm = CodeGenerator::GetInt32ValueOf(right->AsConstant()); if (instruction->IsAnd() || instruction->IsOr() || instruction->IsXor()) { can_use_imm = IsUint<16>(imm); - } else if (instruction->IsAdd()) { - can_use_imm = IsInt<16>(imm); } else { - DCHECK(instruction->IsSub()); - can_use_imm = IsInt<16>(-imm); + DCHECK(instruction->IsSub() || instruction->IsAdd()); + if (instruction->IsSub()) { + imm = -imm; + } + if (isR6) { + bool single_use = right->GetUses().HasExactlyOneElement(); + int16_t imm_high = High16Bits(imm); + int16_t imm_low = Low16Bits(imm); + if (imm_low < 0) { + imm_high += 1; + } + can_use_imm = !((imm_high != 0) && (imm_low != 0)) || single_use; + } else { + can_use_imm = IsInt<16>(imm); + } } } if (can_use_imm) @@ -1988,6 +2000,7 @@ void LocationsBuilderMIPS::HandleBinaryOp(HBinaryOperation* instruction) { void InstructionCodeGeneratorMIPS::HandleBinaryOp(HBinaryOperation* instruction) { DataType::Type type = instruction->GetType(); LocationSummary* locations = instruction->GetLocations(); + bool isR6 = codegen_->GetInstructionSetFeatures().IsR6(); switch (type) { case DataType::Type::kInt32: { @@ -2019,17 +2032,32 @@ void InstructionCodeGeneratorMIPS::HandleBinaryOp(HBinaryOperation* instruction) __ Xori(dst, lhs, rhs_imm); else __ Xor(dst, lhs, rhs_reg); - } else if (instruction->IsAdd()) { - if (use_imm) - __ Addiu(dst, lhs, rhs_imm); - else - __ Addu(dst, lhs, rhs_reg); } else { - DCHECK(instruction->IsSub()); - if (use_imm) - __ Addiu(dst, lhs, -rhs_imm); - else + DCHECK(instruction->IsAdd() || instruction->IsSub()); + if (use_imm) { + if (instruction->IsSub()) { + rhs_imm = -rhs_imm; + } + if (IsInt<16>(rhs_imm)) { + __ Addiu(dst, lhs, rhs_imm); + } else { + DCHECK(isR6); + int16_t rhs_imm_high = High16Bits(rhs_imm); + int16_t rhs_imm_low = Low16Bits(rhs_imm); + if (rhs_imm_low < 0) { + rhs_imm_high += 1; + } + __ Aui(dst, lhs, rhs_imm_high); + if (rhs_imm_low != 0) { + __ Addiu(dst, dst, rhs_imm_low); + } + } + } else if (instruction->IsAdd()) { + __ Addu(dst, lhs, rhs_reg); + } else { + DCHECK(instruction->IsSub()); __ Subu(dst, lhs, rhs_reg); + } } break; } diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 03a719f445..22989c8283 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -1793,11 +1793,19 @@ void LocationsBuilderMIPS64::HandleBinaryOp(HBinaryOperation* instruction) { int64_t imm = CodeGenerator::GetInt64ValueOf(right->AsConstant()); if (instruction->IsAnd() || instruction->IsOr() || instruction->IsXor()) { can_use_imm = IsUint<16>(imm); - } else if (instruction->IsAdd()) { - can_use_imm = IsInt<16>(imm); } else { - DCHECK(instruction->IsSub()); - can_use_imm = IsInt<16>(-imm); + DCHECK(instruction->IsAdd() || instruction->IsSub()); + bool single_use = right->GetUses().HasExactlyOneElement(); + if (instruction->IsSub()) { + if (!(type == DataType::Type::kInt32 && imm == INT32_MIN)) { + imm = -imm; + } + } + if (type == DataType::Type::kInt32) { + can_use_imm = IsInt<16>(imm) || (Low16Bits(imm) == 0) || single_use; + } else { + can_use_imm = IsInt<16>(imm) || (IsInt<32>(imm) && (Low16Bits(imm) == 0)) || single_use; + } } } if (can_use_imm) @@ -1855,30 +1863,90 @@ void InstructionCodeGeneratorMIPS64::HandleBinaryOp(HBinaryOperation* instructio __ Xori(dst, lhs, rhs_imm); else __ Xor(dst, lhs, rhs_reg); - } else if (instruction->IsAdd()) { - if (type == DataType::Type::kInt32) { - if (use_imm) - __ Addiu(dst, lhs, rhs_imm); - else - __ Addu(dst, lhs, rhs_reg); - } else { - if (use_imm) - __ Daddiu(dst, lhs, rhs_imm); - else - __ Daddu(dst, lhs, rhs_reg); + } else if (instruction->IsAdd() || instruction->IsSub()) { + if (instruction->IsSub()) { + rhs_imm = -rhs_imm; } - } else { - DCHECK(instruction->IsSub()); if (type == DataType::Type::kInt32) { - if (use_imm) - __ Addiu(dst, lhs, -rhs_imm); - else - __ Subu(dst, lhs, rhs_reg); + if (use_imm) { + if (IsInt<16>(rhs_imm)) { + __ Addiu(dst, lhs, rhs_imm); + } else { + int16_t rhs_imm_high = High16Bits(rhs_imm); + int16_t rhs_imm_low = Low16Bits(rhs_imm); + if (rhs_imm_low < 0) { + rhs_imm_high += 1; + } + __ Aui(dst, lhs, rhs_imm_high); + if (rhs_imm_low != 0) { + __ Addiu(dst, dst, rhs_imm_low); + } + } + } else { + if (instruction->IsAdd()) { + __ Addu(dst, lhs, rhs_reg); + } else { + DCHECK(instruction->IsSub()); + __ Subu(dst, lhs, rhs_reg); + } + } } else { - if (use_imm) - __ Daddiu(dst, lhs, -rhs_imm); - else + if (use_imm) { + if (IsInt<16>(rhs_imm)) { + __ Daddiu(dst, lhs, rhs_imm); + } else if (IsInt<32>(rhs_imm)) { + int16_t rhs_imm_high = High16Bits(rhs_imm); + int16_t rhs_imm_low = Low16Bits(rhs_imm); + bool overflow_hi16 = false; + if (rhs_imm_low < 0) { + rhs_imm_high += 1; + overflow_hi16 = (rhs_imm_high == -32768); + } + __ Daui(dst, lhs, rhs_imm_high); + if (rhs_imm_low != 0) { + __ Daddiu(dst, dst, rhs_imm_low); + } + if (overflow_hi16) { + __ Dahi(dst, 1); + } + } else { + int16_t rhs_imm_low = Low16Bits(Low32Bits(rhs_imm)); + if (rhs_imm_low < 0) { + rhs_imm += (INT64_C(1) << 16); + } + int16_t rhs_imm_upper = High16Bits(Low32Bits(rhs_imm)); + if (rhs_imm_upper < 0) { + rhs_imm += (INT64_C(1) << 32); + } + int16_t rhs_imm_high = Low16Bits(High32Bits(rhs_imm)); + if (rhs_imm_high < 0) { + rhs_imm += (INT64_C(1) << 48); + } + int16_t rhs_imm_top = High16Bits(High32Bits(rhs_imm)); + GpuRegister tmp = lhs; + if (rhs_imm_low != 0) { + __ Daddiu(dst, tmp, rhs_imm_low); + tmp = dst; + } + // Dahi and Dati must use the same input and output register, so we have to initialize + // the dst register using Daddiu or Daui, even when the intermediate value is zero: + // Daui(dst, lhs, 0). + if ((rhs_imm_upper != 0) || (rhs_imm_low == 0)) { + __ Daui(dst, tmp, rhs_imm_upper); + } + if (rhs_imm_high != 0) { + __ Dahi(dst, rhs_imm_high); + } + if (rhs_imm_top != 0) { + __ Dati(dst, rhs_imm_top); + } + } + } else if (instruction->IsAdd()) { + __ Daddu(dst, lhs, rhs_reg); + } else { + DCHECK(instruction->IsSub()); __ Dsubu(dst, lhs, rhs_reg); + } } } break; diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 978d0c2225..782546c9d8 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1351,6 +1351,8 @@ bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instructio uint16_t field_index; if (instruction.IsQuickened()) { if (!CanDecodeQuickenedInfo()) { + VLOG(compiler) << "Not compiled: Could not decode quickened instruction " + << instruction.Opcode(); return false; } field_index = LookupQuickenedInfo(quicken_index); @@ -1487,7 +1489,6 @@ ArtField* HInstructionBuilder::ResolveField(uint16_t field_idx, bool is_static, dex_compilation_unit_->GetDexCache(), class_loader, is_static); - if (UNLIKELY(resolved_field == nullptr)) { // Clean up any exception left by type resolution. soa.Self()->ClearException(); @@ -1523,7 +1524,7 @@ ArtField* HInstructionBuilder::ResolveField(uint16_t field_idx, bool is_static, return resolved_field; } -bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, +void HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put) { uint32_t source_or_dest_reg = instruction.VRegA_21c(); @@ -1537,7 +1538,7 @@ bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, MethodCompilationStat::kUnresolvedField); DataType::Type field_type = GetFieldAccessType(*dex_file_, field_index); BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type); - return true; + return; } DataType::Type field_type = GetFieldAccessType(*dex_file_, field_index); @@ -1555,7 +1556,7 @@ bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, MaybeRecordStat(compilation_stats_, MethodCompilationStat::kUnresolvedFieldNotAFastAccess); BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type); - return true; + return; } HInstruction* cls = constant; @@ -1591,7 +1592,6 @@ bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, dex_pc)); UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); } - return true; } void HInstructionBuilder::BuildCheckedDivRem(uint16_t out_vreg, @@ -2058,6 +2058,8 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, uint16_t method_idx; if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_QUICK) { if (!CanDecodeQuickenedInfo()) { + VLOG(compiler) << "Not compiled: Could not decode quickened instruction " + << instruction.Opcode(); return false; } method_idx = LookupQuickenedInfo(quicken_index); @@ -2083,6 +2085,8 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, uint16_t method_idx; if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK) { if (!CanDecodeQuickenedInfo()) { + VLOG(compiler) << "Not compiled: Could not decode quickened instruction " + << instruction.Opcode(); return false; } method_idx = LookupQuickenedInfo(quicken_index); @@ -2758,7 +2762,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::IGET_CHAR_QUICK: case Instruction::IGET_SHORT: case Instruction::IGET_SHORT_QUICK: { - if (!BuildInstanceFieldAccess(instruction, dex_pc, false, quicken_index)) { + if (!BuildInstanceFieldAccess(instruction, dex_pc, /* is_put */ false, quicken_index)) { return false; } break; @@ -2778,7 +2782,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::IPUT_CHAR_QUICK: case Instruction::IPUT_SHORT: case Instruction::IPUT_SHORT_QUICK: { - if (!BuildInstanceFieldAccess(instruction, dex_pc, true, quicken_index)) { + if (!BuildInstanceFieldAccess(instruction, dex_pc, /* is_put */ true, quicken_index)) { return false; } break; @@ -2791,9 +2795,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::SGET_BYTE: case Instruction::SGET_CHAR: case Instruction::SGET_SHORT: { - if (!BuildStaticFieldAccess(instruction, dex_pc, false)) { - return false; - } + BuildStaticFieldAccess(instruction, dex_pc, /* is_put */ false); break; } @@ -2804,9 +2806,7 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::SPUT_BYTE: case Instruction::SPUT_CHAR: case Instruction::SPUT_SHORT: { - if (!BuildStaticFieldAccess(instruction, dex_pc, true)) { - return false; - } + BuildStaticFieldAccess(instruction, dex_pc, /* is_put */ true); break; } diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index f551ac4280..2446ddb86a 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -175,8 +175,8 @@ class HInstructionBuilder : public ValueObject { uint32_t dex_pc, bool is_put, DataType::Type field_type); - // Builds a static field access node and returns whether the instruction is supported. - bool BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put); + // Builds a static field access node. + void BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put); void BuildArrayAccess(const Instruction& instruction, uint32_t dex_pc, diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 089e41b4f4..a65d7b1984 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -2268,7 +2268,7 @@ void InstructionSimplifierVisitor::SimplifyStringCharAt(HInvoke* invoke) { HArrayLength* length = new (allocator) HArrayLength(str, dex_pc, /* is_string_length */ true); invoke->GetBlock()->InsertInstructionBefore(length, invoke); HBoundsCheck* bounds_check = new (allocator) HBoundsCheck( - index, length, dex_pc, invoke->GetDexMethodIndex()); + index, length, dex_pc, /* is_string_char_at */ true); invoke->GetBlock()->InsertInstructionBefore(bounds_check, invoke); HArrayGet* array_get = new (allocator) HArrayGet(str, bounds_check, diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index 89ad85e0b4..f03fffabe2 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -74,6 +74,18 @@ class LSEVisitor : public HGraphDelegateVisitor { HGraphVisitor::VisitBasicBlock(block); } + // Find an instruction's substitute if it should be removed. + // Return the same instruction if it should not be removed. + HInstruction* FindSubstitute(HInstruction* instruction) { + size_t size = removed_loads_.size(); + for (size_t i = 0; i < size; i++) { + if (removed_loads_[i] == instruction) { + return substitute_instructions_for_loads_[i]; + } + } + return instruction; + } + // Remove recorded instructions that should be eliminated. void RemoveInstructions() { size_t size = removed_loads_.size(); @@ -86,12 +98,10 @@ class LSEVisitor : public HGraphDelegateVisitor { load->IsArrayGet()); HInstruction* substitute = substitute_instructions_for_loads_[i]; DCHECK(substitute != nullptr); - // Keep tracing substitute till one that's not removed. - HInstruction* sub_sub = FindSubstitute(substitute); - while (sub_sub != substitute) { - substitute = sub_sub; - sub_sub = FindSubstitute(substitute); - } + // We proactively retrieve the substitute for a removed load, so + // a load that has a substitute should not be observed as a heap + // location value. + DCHECK_EQ(FindSubstitute(substitute), substitute); load->ReplaceWith(substitute); load->GetBlock()->RemoveInstruction(load); } @@ -342,6 +352,8 @@ class LSEVisitor : public HGraphDelegateVisitor { DCHECK(ref_info->IsSingleton()); // Get the real heap value of the store. heap_value = heap_value->IsInstanceFieldSet() ? store->InputAt(1) : store->InputAt(2); + // heap_value may already have a substitute. + heap_value = FindSubstitute(heap_value); } } if (heap_value == kUnknownHeapValue) { @@ -385,6 +397,8 @@ class LSEVisitor : public HGraphDelegateVisitor { size_t vector_length, int16_t declaring_class_def_index, HInstruction* value) { + // value may already have a substitute. + value = FindSubstitute(value); HInstruction* original_ref = heap_location_collector_.HuntForOriginalReference(ref); ReferenceInfo* ref_info = heap_location_collector_.FindReferenceInfoOf(original_ref); size_t idx = heap_location_collector_.FindHeapLocationIndex( @@ -679,18 +693,6 @@ class LSEVisitor : public HGraphDelegateVisitor { } } - // Find an instruction's substitute if it should be removed. - // Return the same instruction if it should not be removed. - HInstruction* FindSubstitute(HInstruction* instruction) { - size_t size = removed_loads_.size(); - for (size_t i = 0; i < size; i++) { - if (removed_loads_[i] == instruction) { - return substitute_instructions_for_loads_[i]; - } - } - return instruction; - } - const HeapLocationCollector& heap_location_collector_; const SideEffectsAnalysis& side_effects_; diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 4a9da7ece1..d117bfb67d 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -507,6 +507,7 @@ GraphAnalysisResult HGraph::AnalyzeLoops() const { if (block->IsCatchBlock()) { // TODO: Dealing with exceptional back edges could be tricky because // they only approximate the real control flow. Bail out for now. + VLOG(compiler) << "Not compiled: Exceptional back edges"; return kAnalysisFailThrowCatchLoop; } block->GetLoopInformation()->Populate(); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 66d5bfea32..58030df9d4 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -5787,10 +5787,10 @@ class HBoundsCheck FINAL : public HExpression<2> { HBoundsCheck(HInstruction* index, HInstruction* length, uint32_t dex_pc, - bool string_char_at = false) + bool is_string_char_at = false) : HExpression(index->GetType(), SideEffects::CanTriggerGC(), dex_pc) { DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(index->GetType())); - SetPackedFlag<kFlagIsStringCharAt>(string_char_at); + SetPackedFlag<kFlagIsStringCharAt>(is_string_char_at); SetRawInputAt(0, index); SetRawInputAt(1, length); } diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index e4edbfdc24..cb384768b7 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -328,6 +328,8 @@ bool SsaBuilder::FixAmbiguousArrayOps() { HInstruction* array = aget_int->GetArray(); if (!array->GetReferenceTypeInfo().IsPrimitiveArrayClass()) { // RTP did not type the input array. Bail. + VLOG(compiler) << "Not compiled: Could not infer an array type for array operation at " + << aget_int->GetDexPc(); return false; } @@ -368,6 +370,8 @@ bool SsaBuilder::FixAmbiguousArrayOps() { HInstruction* array = aset->GetArray(); if (!array->GetReferenceTypeInfo().IsPrimitiveArrayClass()) { // RTP did not type the input array. Bail. + VLOG(compiler) << "Not compiled: Could not infer an array type for array operation at " + << aset->GetDexPc(); return false; } diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc index eb75f8b67c..2218ef9af2 100644 --- a/compiler/utils/mips/assembler_mips.cc +++ b/compiler/utils/mips/assembler_mips.cc @@ -42,26 +42,13 @@ std::ostream& operator<<(std::ostream& os, const DRegister& rhs) { MipsAssembler::DelaySlot::DelaySlot() : instruction_(0), - gpr_outs_mask_(0), - gpr_ins_mask_(0), - fpr_outs_mask_(0), - fpr_ins_mask_(0), - cc_outs_mask_(0), - cc_ins_mask_(0), patcher_label_(nullptr) {} -void MipsAssembler::DsFsmInstr(uint32_t instruction, - uint32_t gpr_outs_mask, - uint32_t gpr_ins_mask, - uint32_t fpr_outs_mask, - uint32_t fpr_ins_mask, - uint32_t cc_outs_mask, - uint32_t cc_ins_mask, - MipsLabel* patcher_label) { +InOutRegMasks& MipsAssembler::DsFsmInstr(uint32_t instruction, MipsLabel* patcher_label) { if (!reordering_) { CHECK_EQ(ds_fsm_state_, kExpectingLabel); CHECK_EQ(delay_slot_.instruction_, 0u); - return; + return delay_slot_.masks_; } switch (ds_fsm_state_) { case kExpectingLabel: @@ -92,13 +79,9 @@ void MipsAssembler::DsFsmInstr(uint32_t instruction, break; } delay_slot_.instruction_ = instruction; - delay_slot_.gpr_outs_mask_ = gpr_outs_mask & ~1u; // Ignore register ZERO. - delay_slot_.gpr_ins_mask_ = gpr_ins_mask & ~1u; // Ignore register ZERO. - delay_slot_.fpr_outs_mask_ = fpr_outs_mask; - delay_slot_.fpr_ins_mask_ = fpr_ins_mask; - delay_slot_.cc_outs_mask_ = cc_outs_mask; - delay_slot_.cc_ins_mask_ = cc_ins_mask; + delay_slot_.masks_ = InOutRegMasks(); delay_slot_.patcher_label_ = patcher_label; + return delay_slot_.masks_; } void MipsAssembler::DsFsmLabel() { @@ -167,73 +150,7 @@ size_t MipsAssembler::CodePosition() { } void MipsAssembler::DsFsmInstrNop(uint32_t instruction ATTRIBUTE_UNUSED) { - DsFsmInstr(0, 0, 0, 0, 0, 0, 0); -} - -void MipsAssembler::DsFsmInstrRrr(uint32_t instruction, - Register out, - Register in1, - Register in2, - MipsLabel* patcher_label) { - DsFsmInstr(instruction, (1u << out), (1u << in1) | (1u << in2), 0, 0, 0, 0, patcher_label); -} - -void MipsAssembler::DsFsmInstrRrrr(uint32_t instruction, - Register in1_out, - Register in2, - Register in3) { - DsFsmInstr(instruction, (1u << in1_out), (1u << in1_out) | (1u << in2) | (1u << in3), 0, 0, 0, 0); -} - -void MipsAssembler::DsFsmInstrFff(uint32_t instruction, - FRegister out, - FRegister in1, - FRegister in2) { - DsFsmInstr(instruction, 0, 0, (1u << out), (1u << in1) | (1u << in2), 0, 0); -} - -void MipsAssembler::DsFsmInstrFfff(uint32_t instruction, - FRegister in1_out, - FRegister in2, - FRegister in3) { - DsFsmInstr(instruction, 0, 0, (1u << in1_out), (1u << in1_out) | (1u << in2) | (1u << in3), 0, 0); -} - -void MipsAssembler::DsFsmInstrFffr(uint32_t instruction, - FRegister in1_out, - FRegister in2, - Register in3) { - DsFsmInstr(instruction, 0, (1u << in3), (1u << in1_out), (1u << in1_out) | (1u << in2), 0, 0); -} - -void MipsAssembler::DsFsmInstrRf(uint32_t instruction, Register out, FRegister in) { - DsFsmInstr(instruction, (1u << out), 0, 0, (1u << in), 0, 0); -} - -void MipsAssembler::DsFsmInstrFr(uint32_t instruction, FRegister out, Register in) { - DsFsmInstr(instruction, 0, (1u << in), (1u << out), 0, 0, 0); -} - -void MipsAssembler::DsFsmInstrFR(uint32_t instruction, FRegister in1, Register in2) { - DsFsmInstr(instruction, 0, (1u << in2), 0, (1u << in1), 0, 0); -} - -void MipsAssembler::DsFsmInstrCff(uint32_t instruction, int cc_out, FRegister in1, FRegister in2) { - DsFsmInstr(instruction, 0, 0, 0, (1u << in1) | (1u << in2), (1 << cc_out), 0); -} - -void MipsAssembler::DsFsmInstrRrrc(uint32_t instruction, - Register in1_out, - Register in2, - int cc_in) { - DsFsmInstr(instruction, (1u << in1_out), (1u << in1_out) | (1u << in2), 0, 0, 0, (1 << cc_in)); -} - -void MipsAssembler::DsFsmInstrFffc(uint32_t instruction, - FRegister in1_out, - FRegister in2, - int cc_in) { - DsFsmInstr(instruction, 0, 0, (1u << in1_out), (1u << in1_out) | (1u << in2), 0, (1 << cc_in)); + DsFsmInstr(0); } void MipsAssembler::FinalizeCode() { @@ -535,14 +452,14 @@ uint32_t MipsAssembler::EmitMsa2RF(int operation, } void MipsAssembler::Addu(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x21), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x21)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Addiu(Register rt, Register rs, uint16_t imm16, MipsLabel* patcher_label) { if (patcher_label != nullptr) { Bind(patcher_label); } - DsFsmInstrRrr(EmitI(0x9, rs, rt, imm16), rt, rs, rs, patcher_label); + DsFsmInstr(EmitI(0x9, rs, rt, imm16), patcher_label).GprOuts(rt).GprIns(rs); } void MipsAssembler::Addiu(Register rt, Register rs, uint16_t imm16) { @@ -550,32 +467,32 @@ void MipsAssembler::Addiu(Register rt, Register rs, uint16_t imm16) { } void MipsAssembler::Subu(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x23), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x23)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::MultR2(Register rs, Register rt) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x18), ZERO, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x18)).GprIns(rs, rt); } void MipsAssembler::MultuR2(Register rs, Register rt) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x19), ZERO, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x19)).GprIns(rs, rt); } void MipsAssembler::DivR2(Register rs, Register rt) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x1a), ZERO, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x1a)).GprIns(rs, rt); } void MipsAssembler::DivuR2(Register rs, Register rt) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x1b), ZERO, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, static_cast<Register>(0), 0, 0x1b)).GprIns(rs, rt); } void MipsAssembler::MulR2(Register rd, Register rs, Register rt) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0x1c, rs, rt, rd, 0, 2), rd, rs, rt); + DsFsmInstr(EmitR(0x1c, rs, rt, rd, 0, 2)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::DivR2(Register rd, Register rs, Register rt) { @@ -604,179 +521,181 @@ void MipsAssembler::ModuR2(Register rd, Register rs, Register rt) { void MipsAssembler::MulR6(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 2, 0x18), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 2, 0x18)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::MuhR6(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 3, 0x18), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 3, 0x18)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::MuhuR6(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 3, 0x19), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 3, 0x19)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::DivR6(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 2, 0x1a), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 2, 0x1a)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::ModR6(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 3, 0x1a), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 3, 0x1a)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::DivuR6(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 2, 0x1b), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 2, 0x1b)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::ModuR6(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 3, 0x1b), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 3, 0x1b)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::And(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x24), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x24)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Andi(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0xc, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0xc, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Or(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x25), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x25)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Ori(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0xd, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0xd, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Xor(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x26), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x26)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Xori(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0xe, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0xe, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Nor(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x27), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x27)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Movz(Register rd, Register rs, Register rt) { CHECK(!IsR6()); - DsFsmInstrRrrr(EmitR(0, rs, rt, rd, 0, 0x0A), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x0A)).GprInOuts(rd).GprIns(rs, rt); } void MipsAssembler::Movn(Register rd, Register rs, Register rt) { CHECK(!IsR6()); - DsFsmInstrRrrr(EmitR(0, rs, rt, rd, 0, 0x0B), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x0B)).GprInOuts(rd).GprIns(rs, rt); } void MipsAssembler::Seleqz(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x35), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x35)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Selnez(Register rd, Register rs, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x37), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x37)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::ClzR6(Register rd, Register rs) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, static_cast<Register>(0), rd, 0x01, 0x10), rd, rs, rs); + DsFsmInstr(EmitR(0, rs, static_cast<Register>(0), rd, 0x01, 0x10)).GprOuts(rd).GprIns(rs); } void MipsAssembler::ClzR2(Register rd, Register rs) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0x1C, rs, rd, rd, 0, 0x20), rd, rs, rs); + DsFsmInstr(EmitR(0x1C, rs, rd, rd, 0, 0x20)).GprOuts(rd).GprIns(rs); } void MipsAssembler::CloR6(Register rd, Register rs) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0, rs, static_cast<Register>(0), rd, 0x01, 0x11), rd, rs, rs); + DsFsmInstr(EmitR(0, rs, static_cast<Register>(0), rd, 0x01, 0x11)).GprOuts(rd).GprIns(rs); } void MipsAssembler::CloR2(Register rd, Register rs) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0x1C, rs, rd, rd, 0, 0x21), rd, rs, rs); + DsFsmInstr(EmitR(0x1C, rs, rd, rd, 0, 0x21)).GprOuts(rd).GprIns(rs); } void MipsAssembler::Seb(Register rd, Register rt) { - DsFsmInstrRrr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 0x10, 0x20), rd, rt, rt); + DsFsmInstr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 0x10, 0x20)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Seh(Register rd, Register rt) { - DsFsmInstrRrr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 0x18, 0x20), rd, rt, rt); + DsFsmInstr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 0x18, 0x20)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Wsbh(Register rd, Register rt) { - DsFsmInstrRrr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 2, 0x20), rd, rt, rt); + DsFsmInstr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 2, 0x20)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Bitswap(Register rd, Register rt) { CHECK(IsR6()); - DsFsmInstrRrr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 0x0, 0x20), rd, rt, rt); + DsFsmInstr(EmitR(0x1f, static_cast<Register>(0), rt, rd, 0x0, 0x20)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Sll(Register rd, Register rt, int shamt) { CHECK(IsUint<5>(shamt)) << shamt; - DsFsmInstrRrr(EmitR(0, static_cast<Register>(0), rt, rd, shamt, 0x00), rd, rt, rt); + DsFsmInstr(EmitR(0, static_cast<Register>(0), rt, rd, shamt, 0x00)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Srl(Register rd, Register rt, int shamt) { CHECK(IsUint<5>(shamt)) << shamt; - DsFsmInstrRrr(EmitR(0, static_cast<Register>(0), rt, rd, shamt, 0x02), rd, rt, rt); + DsFsmInstr(EmitR(0, static_cast<Register>(0), rt, rd, shamt, 0x02)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Rotr(Register rd, Register rt, int shamt) { CHECK(IsUint<5>(shamt)) << shamt; - DsFsmInstrRrr(EmitR(0, static_cast<Register>(1), rt, rd, shamt, 0x02), rd, rt, rt); + DsFsmInstr(EmitR(0, static_cast<Register>(1), rt, rd, shamt, 0x02)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Sra(Register rd, Register rt, int shamt) { CHECK(IsUint<5>(shamt)) << shamt; - DsFsmInstrRrr(EmitR(0, static_cast<Register>(0), rt, rd, shamt, 0x03), rd, rt, rt); + DsFsmInstr(EmitR(0, static_cast<Register>(0), rt, rd, shamt, 0x03)).GprOuts(rd).GprIns(rt); } void MipsAssembler::Sllv(Register rd, Register rt, Register rs) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x04), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x04)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Srlv(Register rd, Register rt, Register rs) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x06), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x06)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Rotrv(Register rd, Register rt, Register rs) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 1, 0x06), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 1, 0x06)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Srav(Register rd, Register rt, Register rs) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x07), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x07)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Ext(Register rd, Register rt, int pos, int size) { CHECK(IsUint<5>(pos)) << pos; CHECK(0 < size && size <= 32) << size; CHECK(0 < pos + size && pos + size <= 32) << pos << " + " << size; - DsFsmInstrRrr(EmitR(0x1f, rt, rd, static_cast<Register>(size - 1), pos, 0x00), rd, rt, rt); + DsFsmInstr(EmitR(0x1f, rt, rd, static_cast<Register>(size - 1), pos, 0x00)) + .GprOuts(rd).GprIns(rt); } void MipsAssembler::Ins(Register rd, Register rt, int pos, int size) { CHECK(IsUint<5>(pos)) << pos; CHECK(0 < size && size <= 32) << size; CHECK(0 < pos + size && pos + size <= 32) << pos << " + " << size; - DsFsmInstrRrr(EmitR(0x1f, rt, rd, static_cast<Register>(pos + size - 1), pos, 0x04), rd, rd, rt); + DsFsmInstr(EmitR(0x1f, rt, rd, static_cast<Register>(pos + size - 1), pos, 0x04)) + .GprInOuts(rd).GprIns(rt); } void MipsAssembler::Lsa(Register rd, Register rs, Register rt, int saPlusOne) { CHECK(IsR6() || HasMsa()); CHECK(1 <= saPlusOne && saPlusOne <= 4) << saPlusOne; int sa = saPlusOne - 1; - DsFsmInstrRrr(EmitR(0x0, rs, rt, rd, sa, 0x05), rd, rs, rt); + DsFsmInstr(EmitR(0x0, rs, rt, rd, sa, 0x05)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::ShiftAndAdd(Register dst, @@ -798,18 +717,18 @@ void MipsAssembler::ShiftAndAdd(Register dst, } void MipsAssembler::Lb(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0x20, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0x20, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Lh(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0x21, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0x21, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Lw(Register rt, Register rs, uint16_t imm16, MipsLabel* patcher_label) { if (patcher_label != nullptr) { Bind(patcher_label); } - DsFsmInstrRrr(EmitI(0x23, rs, rt, imm16), rt, rs, rs, patcher_label); + DsFsmInstr(EmitI(0x23, rs, rt, imm16), patcher_label).GprOuts(rt).GprIns(rs); } void MipsAssembler::Lw(Register rt, Register rs, uint16_t imm16) { @@ -818,20 +737,20 @@ void MipsAssembler::Lw(Register rt, Register rs, uint16_t imm16) { void MipsAssembler::Lwl(Register rt, Register rs, uint16_t imm16) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitI(0x22, rs, rt, imm16), rt, rt, rs); + DsFsmInstr(EmitI(0x22, rs, rt, imm16)).GprInOuts(rt).GprIns(rs); } void MipsAssembler::Lwr(Register rt, Register rs, uint16_t imm16) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitI(0x26, rs, rt, imm16), rt, rt, rs); + DsFsmInstr(EmitI(0x26, rs, rt, imm16)).GprInOuts(rt).GprIns(rs); } void MipsAssembler::Lbu(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0x24, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0x24, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Lhu(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0x25, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0x25, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Lwpc(Register rs, uint32_t imm19) { @@ -841,12 +760,12 @@ void MipsAssembler::Lwpc(Register rs, uint32_t imm19) { } void MipsAssembler::Lui(Register rt, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0xf, static_cast<Register>(0), rt, imm16), rt, ZERO, ZERO); + DsFsmInstr(EmitI(0xf, static_cast<Register>(0), rt, imm16)).GprOuts(rt); } void MipsAssembler::Aui(Register rt, Register rs, uint16_t imm16) { CHECK(IsR6()); - DsFsmInstrRrr(EmitI(0xf, rs, rt, imm16), rt, rt, rs); + DsFsmInstr(EmitI(0xf, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::AddUpper(Register rt, Register rs, uint16_t imm16, Register tmp) { @@ -871,27 +790,27 @@ void MipsAssembler::Sync(uint32_t stype) { void MipsAssembler::Mfhi(Register rd) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0, ZERO, ZERO, rd, 0, 0x10), rd, ZERO, ZERO); + DsFsmInstr(EmitR(0, ZERO, ZERO, rd, 0, 0x10)).GprOuts(rd); } void MipsAssembler::Mflo(Register rd) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitR(0, ZERO, ZERO, rd, 0, 0x12), rd, ZERO, ZERO); + DsFsmInstr(EmitR(0, ZERO, ZERO, rd, 0, 0x12)).GprOuts(rd); } void MipsAssembler::Sb(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0x28, rs, rt, imm16), ZERO, rt, rs); + DsFsmInstr(EmitI(0x28, rs, rt, imm16)).GprIns(rt, rs); } void MipsAssembler::Sh(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0x29, rs, rt, imm16), ZERO, rt, rs); + DsFsmInstr(EmitI(0x29, rs, rt, imm16)).GprIns(rt, rs); } void MipsAssembler::Sw(Register rt, Register rs, uint16_t imm16, MipsLabel* patcher_label) { if (patcher_label != nullptr) { Bind(patcher_label); } - DsFsmInstrRrr(EmitI(0x2b, rs, rt, imm16), ZERO, rt, rs, patcher_label); + DsFsmInstr(EmitI(0x2b, rs, rt, imm16), patcher_label).GprIns(rt, rs); } void MipsAssembler::Sw(Register rt, Register rs, uint16_t imm16) { @@ -900,50 +819,50 @@ void MipsAssembler::Sw(Register rt, Register rs, uint16_t imm16) { void MipsAssembler::Swl(Register rt, Register rs, uint16_t imm16) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitI(0x2a, rs, rt, imm16), ZERO, rt, rs); + DsFsmInstr(EmitI(0x2a, rs, rt, imm16)).GprIns(rt, rs); } void MipsAssembler::Swr(Register rt, Register rs, uint16_t imm16) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitI(0x2e, rs, rt, imm16), ZERO, rt, rs); + DsFsmInstr(EmitI(0x2e, rs, rt, imm16)).GprIns(rt, rs); } void MipsAssembler::LlR2(Register rt, Register base, int16_t imm16) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitI(0x30, base, rt, imm16), rt, base, base); + DsFsmInstr(EmitI(0x30, base, rt, imm16)).GprOuts(rt).GprIns(base); } void MipsAssembler::ScR2(Register rt, Register base, int16_t imm16) { CHECK(!IsR6()); - DsFsmInstrRrr(EmitI(0x38, base, rt, imm16), rt, rt, base); + DsFsmInstr(EmitI(0x38, base, rt, imm16)).GprInOuts(rt).GprIns(base); } void MipsAssembler::LlR6(Register rt, Register base, int16_t imm9) { CHECK(IsR6()); CHECK(IsInt<9>(imm9)); - DsFsmInstrRrr(EmitI(0x1f, base, rt, ((imm9 & 0x1ff) << 7) | 0x36), rt, base, base); + DsFsmInstr(EmitI(0x1f, base, rt, ((imm9 & 0x1ff) << 7) | 0x36)).GprOuts(rt).GprIns(base); } void MipsAssembler::ScR6(Register rt, Register base, int16_t imm9) { CHECK(IsR6()); CHECK(IsInt<9>(imm9)); - DsFsmInstrRrr(EmitI(0x1f, base, rt, ((imm9 & 0x1ff) << 7) | 0x26), rt, rt, base); + DsFsmInstr(EmitI(0x1f, base, rt, ((imm9 & 0x1ff) << 7) | 0x26)).GprInOuts(rt).GprIns(base); } void MipsAssembler::Slt(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x2a), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x2a)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Sltu(Register rd, Register rs, Register rt) { - DsFsmInstrRrr(EmitR(0, rs, rt, rd, 0, 0x2b), rd, rs, rt); + DsFsmInstr(EmitR(0, rs, rt, rd, 0, 0x2b)).GprOuts(rd).GprIns(rs, rt); } void MipsAssembler::Slti(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0xa, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0xa, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::Sltiu(Register rt, Register rs, uint16_t imm16) { - DsFsmInstrRrr(EmitI(0xb, rs, rt, imm16), rt, rs, rs); + DsFsmInstr(EmitI(0xb, rs, rt, imm16)).GprOuts(rt).GprIns(rs); } void MipsAssembler::B(uint16_t imm16) { @@ -1021,8 +940,8 @@ void MipsAssembler::Jalr(Register rd, Register rs) { uint32_t last_instruction = delay_slot_.instruction_; MipsLabel* patcher_label = delay_slot_.patcher_label_; bool exchange = (last_instruction != 0 && - (delay_slot_.gpr_outs_mask_ & (1u << rs)) == 0 && - ((delay_slot_.gpr_ins_mask_ | delay_slot_.gpr_outs_mask_) & (1u << rd)) == 0); + (delay_slot_.masks_.gpr_outs_ & (1u << rs)) == 0 && + ((delay_slot_.masks_.gpr_ins_ | delay_slot_.masks_.gpr_outs_) & (1u << rd)) == 0); if (exchange) { // The last instruction cannot be used in a different delay slot, // do not commit the label before it (if any). @@ -1305,67 +1224,67 @@ void MipsAssembler::EmitBcondR6(BranchCondition cond, Register rs, Register rt, } void MipsAssembler::AddS(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x0), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x0)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::SubS(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x1), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x1)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::MulS(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x2), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x2)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::DivS(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x3), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x3)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::AddD(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x0), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x0)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::SubD(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x1), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x1)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::MulD(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x2), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x2)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::DivD(FRegister fd, FRegister fs, FRegister ft) { - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x3), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x3)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::SqrtS(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x4), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x4)).FprOuts(fd).FprIns(fs); } void MipsAssembler::SqrtD(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x4), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x4)).FprOuts(fd).FprIns(fs); } void MipsAssembler::AbsS(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x5), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x5)).FprOuts(fd).FprIns(fs); } void MipsAssembler::AbsD(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x5), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x5)).FprOuts(fd).FprIns(fs); } void MipsAssembler::MovS(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x6), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x6)).FprOuts(fd).FprIns(fs); } void MipsAssembler::MovD(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x6), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x6)).FprOuts(fd).FprIns(fs); } void MipsAssembler::NegS(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x7), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x7)).FprOuts(fd).FprIns(fs); } void MipsAssembler::NegD(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x7), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x7)).FprOuts(fd).FprIns(fs); } void MipsAssembler::CunS(FRegister fs, FRegister ft) { @@ -1375,7 +1294,8 @@ void MipsAssembler::CunS(FRegister fs, FRegister ft) { void MipsAssembler::CunS(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x31), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x31)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CeqS(FRegister fs, FRegister ft) { @@ -1385,7 +1305,8 @@ void MipsAssembler::CeqS(FRegister fs, FRegister ft) { void MipsAssembler::CeqS(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x32), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x32)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CueqS(FRegister fs, FRegister ft) { @@ -1395,7 +1316,8 @@ void MipsAssembler::CueqS(FRegister fs, FRegister ft) { void MipsAssembler::CueqS(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x33), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x33)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::ColtS(FRegister fs, FRegister ft) { @@ -1405,7 +1327,8 @@ void MipsAssembler::ColtS(FRegister fs, FRegister ft) { void MipsAssembler::ColtS(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x34), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x34)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CultS(FRegister fs, FRegister ft) { @@ -1415,7 +1338,8 @@ void MipsAssembler::CultS(FRegister fs, FRegister ft) { void MipsAssembler::CultS(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x35), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x35)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::ColeS(FRegister fs, FRegister ft) { @@ -1425,7 +1349,8 @@ void MipsAssembler::ColeS(FRegister fs, FRegister ft) { void MipsAssembler::ColeS(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x36), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x36)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CuleS(FRegister fs, FRegister ft) { @@ -1435,7 +1360,8 @@ void MipsAssembler::CuleS(FRegister fs, FRegister ft) { void MipsAssembler::CuleS(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x37), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, static_cast<FRegister>(cc << 2), 0x37)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CunD(FRegister fs, FRegister ft) { @@ -1445,7 +1371,8 @@ void MipsAssembler::CunD(FRegister fs, FRegister ft) { void MipsAssembler::CunD(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x31), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x31)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CeqD(FRegister fs, FRegister ft) { @@ -1455,7 +1382,8 @@ void MipsAssembler::CeqD(FRegister fs, FRegister ft) { void MipsAssembler::CeqD(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x32), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x32)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CueqD(FRegister fs, FRegister ft) { @@ -1465,7 +1393,8 @@ void MipsAssembler::CueqD(FRegister fs, FRegister ft) { void MipsAssembler::CueqD(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x33), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x33)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::ColtD(FRegister fs, FRegister ft) { @@ -1475,7 +1404,8 @@ void MipsAssembler::ColtD(FRegister fs, FRegister ft) { void MipsAssembler::ColtD(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x34), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x34)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CultD(FRegister fs, FRegister ft) { @@ -1485,7 +1415,8 @@ void MipsAssembler::CultD(FRegister fs, FRegister ft) { void MipsAssembler::CultD(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x35), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x35)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::ColeD(FRegister fs, FRegister ft) { @@ -1495,7 +1426,8 @@ void MipsAssembler::ColeD(FRegister fs, FRegister ft) { void MipsAssembler::ColeD(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x36), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x36)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CuleD(FRegister fs, FRegister ft) { @@ -1505,301 +1437,323 @@ void MipsAssembler::CuleD(FRegister fs, FRegister ft) { void MipsAssembler::CuleD(int cc, FRegister fs, FRegister ft) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrCff(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x37), cc, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, static_cast<FRegister>(cc << 2), 0x37)) + .CcOuts(cc).FprIns(fs, ft); } void MipsAssembler::CmpUnS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x01), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x01)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpEqS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x02), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x02)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUeqS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x03), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x03)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpLtS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x04), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x04)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUltS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x05), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x05)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpLeS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x06), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x06)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUleS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x07), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x07)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpOrS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x11), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x11)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUneS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x12), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x12)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpNeS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x14, ft, fs, fd, 0x13), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x14, ft, fs, fd, 0x13)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUnD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x01), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x01)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpEqD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x02), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x02)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUeqD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x03), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x03)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpLtD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x04), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x04)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUltD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x05), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x05)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpLeD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x06), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x06)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUleD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x07), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x07)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpOrD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x11), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x11)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpUneD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x12), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x12)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::CmpNeD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x15, ft, fs, fd, 0x13), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x15, ft, fs, fd, 0x13)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::Movf(Register rd, Register rs, int cc) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrRrrc(EmitR(0, rs, static_cast<Register>(cc << 2), rd, 0, 0x01), rd, rs, cc); + DsFsmInstr(EmitR(0, rs, static_cast<Register>(cc << 2), rd, 0, 0x01)) + .GprInOuts(rd).GprIns(rs).CcIns(cc); } void MipsAssembler::Movt(Register rd, Register rs, int cc) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrRrrc(EmitR(0, rs, static_cast<Register>((cc << 2) | 1), rd, 0, 0x01), rd, rs, cc); + DsFsmInstr(EmitR(0, rs, static_cast<Register>((cc << 2) | 1), rd, 0, 0x01)) + .GprInOuts(rd).GprIns(rs).CcIns(cc); } void MipsAssembler::MovfS(FRegister fd, FRegister fs, int cc) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrFffc(EmitFR(0x11, 0x10, static_cast<FRegister>(cc << 2), fs, fd, 0x11), fd, fs, cc); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(cc << 2), fs, fd, 0x11)) + .FprInOuts(fd).FprIns(fs).CcIns(cc); } void MipsAssembler::MovfD(FRegister fd, FRegister fs, int cc) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrFffc(EmitFR(0x11, 0x11, static_cast<FRegister>(cc << 2), fs, fd, 0x11), fd, fs, cc); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(cc << 2), fs, fd, 0x11)) + .FprInOuts(fd).FprIns(fs).CcIns(cc); } void MipsAssembler::MovtS(FRegister fd, FRegister fs, int cc) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrFffc(EmitFR(0x11, 0x10, static_cast<FRegister>((cc << 2) | 1), fs, fd, 0x11), - fd, - fs, - cc); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>((cc << 2) | 1), fs, fd, 0x11)) + .FprInOuts(fd).FprIns(fs).CcIns(cc); } void MipsAssembler::MovtD(FRegister fd, FRegister fs, int cc) { CHECK(!IsR6()); CHECK(IsUint<3>(cc)) << cc; - DsFsmInstrFffc(EmitFR(0x11, 0x11, static_cast<FRegister>((cc << 2) | 1), fs, fd, 0x11), - fd, - fs, - cc); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>((cc << 2) | 1), fs, fd, 0x11)) + .FprInOuts(fd).FprIns(fs).CcIns(cc); } void MipsAssembler::MovzS(FRegister fd, FRegister fs, Register rt) { CHECK(!IsR6()); - DsFsmInstrFffr(EmitFR(0x11, 0x10, static_cast<FRegister>(rt), fs, fd, 0x12), fd, fs, rt); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(rt), fs, fd, 0x12)) + .FprInOuts(fd).FprIns(fs).GprIns(rt); } void MipsAssembler::MovzD(FRegister fd, FRegister fs, Register rt) { CHECK(!IsR6()); - DsFsmInstrFffr(EmitFR(0x11, 0x11, static_cast<FRegister>(rt), fs, fd, 0x12), fd, fs, rt); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(rt), fs, fd, 0x12)) + .FprInOuts(fd).FprIns(fs).GprIns(rt); } void MipsAssembler::MovnS(FRegister fd, FRegister fs, Register rt) { CHECK(!IsR6()); - DsFsmInstrFffr(EmitFR(0x11, 0x10, static_cast<FRegister>(rt), fs, fd, 0x13), fd, fs, rt); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(rt), fs, fd, 0x13)) + .FprInOuts(fd).FprIns(fs).GprIns(rt); } void MipsAssembler::MovnD(FRegister fd, FRegister fs, Register rt) { CHECK(!IsR6()); - DsFsmInstrFffr(EmitFR(0x11, 0x11, static_cast<FRegister>(rt), fs, fd, 0x13), fd, fs, rt); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(rt), fs, fd, 0x13)) + .FprInOuts(fd).FprIns(fs).GprIns(rt); } void MipsAssembler::SelS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFfff(EmitFR(0x11, 0x10, ft, fs, fd, 0x10), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x10)).FprInOuts(fd).FprIns(fs, ft); } void MipsAssembler::SelD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFfff(EmitFR(0x11, 0x11, ft, fs, fd, 0x10), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x10)).FprInOuts(fd).FprIns(fs, ft); } void MipsAssembler::SeleqzS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x14), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x14)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::SeleqzD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x14), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x14)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::SelnezS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x17), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x17)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::SelnezD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x17), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x17)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::ClassS(FRegister fd, FRegister fs) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x1b), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x1b)).FprOuts(fd).FprIns(fs); } void MipsAssembler::ClassD(FRegister fd, FRegister fs) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x1b), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x1b)).FprOuts(fd).FprIns(fs); } void MipsAssembler::MinS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x1c), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x1c)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::MinD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x1c), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x1c)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::MaxS(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x10, ft, fs, fd, 0x1e), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x10, ft, fs, fd, 0x1e)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::MaxD(FRegister fd, FRegister fs, FRegister ft) { CHECK(IsR6()); - DsFsmInstrFff(EmitFR(0x11, 0x11, ft, fs, fd, 0x1e), fd, fs, ft); + DsFsmInstr(EmitFR(0x11, 0x11, ft, fs, fd, 0x1e)).FprOuts(fd).FprIns(fs, ft); } void MipsAssembler::TruncLS(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x09), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x09)).FprOuts(fd).FprIns(fs); } void MipsAssembler::TruncLD(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x09), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x09)).FprOuts(fd).FprIns(fs); } void MipsAssembler::TruncWS(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x0D), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x0D)).FprOuts(fd).FprIns(fs); } void MipsAssembler::TruncWD(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x0D), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x0D)).FprOuts(fd).FprIns(fs); } void MipsAssembler::Cvtsw(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x14, static_cast<FRegister>(0), fs, fd, 0x20), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x14, static_cast<FRegister>(0), fs, fd, 0x20)).FprOuts(fd).FprIns(fs); } void MipsAssembler::Cvtdw(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x14, static_cast<FRegister>(0), fs, fd, 0x21), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x14, static_cast<FRegister>(0), fs, fd, 0x21)).FprOuts(fd).FprIns(fs); } void MipsAssembler::Cvtsd(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x20), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0x20)).FprOuts(fd).FprIns(fs); } void MipsAssembler::Cvtds(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x21), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0x21)).FprOuts(fd).FprIns(fs); } void MipsAssembler::Cvtsl(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x15, static_cast<FRegister>(0), fs, fd, 0x20), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x15, static_cast<FRegister>(0), fs, fd, 0x20)).FprOuts(fd).FprIns(fs); } void MipsAssembler::Cvtdl(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x15, static_cast<FRegister>(0), fs, fd, 0x21), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x15, static_cast<FRegister>(0), fs, fd, 0x21)).FprOuts(fd).FprIns(fs); } void MipsAssembler::FloorWS(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0xf), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x10, static_cast<FRegister>(0), fs, fd, 0xf)).FprOuts(fd).FprIns(fs); } void MipsAssembler::FloorWD(FRegister fd, FRegister fs) { - DsFsmInstrFff(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0xf), fd, fs, fs); + DsFsmInstr(EmitFR(0x11, 0x11, static_cast<FRegister>(0), fs, fd, 0xf)).FprOuts(fd).FprIns(fs); +} + +FRegister MipsAssembler::GetFpuRegLow(FRegister reg) { + // If FPRs are 32-bit (and get paired to hold 64-bit values), accesses to + // odd-numbered FPRs are reattributed to even-numbered FPRs. This lets us + // use only even-numbered FPRs irrespective of whether we're doing single- + // or double-precision arithmetic. (We don't use odd-numbered 32-bit FPRs + // to hold single-precision values). + return Is32BitFPU() ? static_cast<FRegister>(reg & ~1u) : reg; } void MipsAssembler::Mfc1(Register rt, FRegister fs) { - DsFsmInstrRf(EmitFR(0x11, 0x00, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0), - rt, - fs); + DsFsmInstr(EmitFR(0x11, 0x00, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0)) + .GprOuts(rt).FprIns(GetFpuRegLow(fs)); } +// Note, the 32 LSBs of a 64-bit value must be loaded into an FPR before the 32 MSBs +// when loading the value as 32-bit halves. void MipsAssembler::Mtc1(Register rt, FRegister fs) { - DsFsmInstrFr(EmitFR(0x11, 0x04, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0), - fs, - rt); + uint32_t encoding = + EmitFR(0x11, 0x04, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0); + if (Is32BitFPU() && (fs % 2 != 0)) { + // If mtc1 is used to simulate mthc1 by writing to the odd-numbered FPR in + // a pair of 32-bit FPRs, the associated even-numbered FPR is an in/out. + DsFsmInstr(encoding).FprInOuts(GetFpuRegLow(fs)).GprIns(rt); + } else { + // Otherwise (the FPR is 64-bit or even-numbered), the FPR is an out. + DsFsmInstr(encoding).FprOuts(fs).GprIns(rt); + } } void MipsAssembler::Mfhc1(Register rt, FRegister fs) { - DsFsmInstrRf(EmitFR(0x11, 0x03, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0), - rt, - fs); + DsFsmInstr(EmitFR(0x11, 0x03, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0)) + .GprOuts(rt).FprIns(fs); } +// Note, the 32 LSBs of a 64-bit value must be loaded into an FPR before the 32 MSBs +// when loading the value as 32-bit halves. void MipsAssembler::Mthc1(Register rt, FRegister fs) { - DsFsmInstrFr(EmitFR(0x11, 0x07, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0), - fs, - rt); + DsFsmInstr(EmitFR(0x11, 0x07, static_cast<FRegister>(rt), fs, static_cast<FRegister>(0), 0x0)) + .FprInOuts(fs).GprIns(rt); } void MipsAssembler::MoveFromFpuHigh(Register rt, FRegister fs) { @@ -1820,20 +1774,30 @@ void MipsAssembler::MoveToFpuHigh(Register rt, FRegister fs) { } } +// Note, the 32 LSBs of a 64-bit value must be loaded into an FPR before the 32 MSBs +// when loading the value as 32-bit halves. void MipsAssembler::Lwc1(FRegister ft, Register rs, uint16_t imm16) { - DsFsmInstrFr(EmitI(0x31, rs, static_cast<Register>(ft), imm16), ft, rs); + uint32_t encoding = EmitI(0x31, rs, static_cast<Register>(ft), imm16); + if (Is32BitFPU() && (ft % 2 != 0)) { + // If lwc1 is used to load the odd-numbered FPR in a pair of 32-bit FPRs, + // the associated even-numbered FPR is an in/out. + DsFsmInstr(encoding).FprInOuts(GetFpuRegLow(ft)).GprIns(rs); + } else { + // Otherwise (the FPR is 64-bit or even-numbered), the FPR is an out. + DsFsmInstr(encoding).FprOuts(ft).GprIns(rs); + } } void MipsAssembler::Ldc1(FRegister ft, Register rs, uint16_t imm16) { - DsFsmInstrFr(EmitI(0x35, rs, static_cast<Register>(ft), imm16), ft, rs); + DsFsmInstr(EmitI(0x35, rs, static_cast<Register>(ft), imm16)).FprOuts(ft).GprIns(rs); } void MipsAssembler::Swc1(FRegister ft, Register rs, uint16_t imm16) { - DsFsmInstrFR(EmitI(0x39, rs, static_cast<Register>(ft), imm16), ft, rs); + DsFsmInstr(EmitI(0x39, rs, static_cast<Register>(ft), imm16)).FprIns(GetFpuRegLow(ft)).GprIns(rs); } void MipsAssembler::Sdc1(FRegister ft, Register rs, uint16_t imm16) { - DsFsmInstrFR(EmitI(0x3d, rs, static_cast<Register>(ft), imm16), ft, rs); + DsFsmInstr(EmitI(0x3d, rs, static_cast<Register>(ft), imm16)).FprIns(ft).GprIns(rs); } void MipsAssembler::Break() { @@ -1882,1447 +1846,951 @@ void MipsAssembler::PopAndReturn(Register rd, Register rt) { void MipsAssembler::AndV(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::OrV(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::NorV(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::XorV(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::AddvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::AddvH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::AddvW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::AddvD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SubvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SubvH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SubvW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SubvD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::MulvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::MulvH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::MulvW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::MulvD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Div_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Mod_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x12)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Add_aB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Add_aH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Add_aW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Add_aD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ave_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Aver_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x10), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x10)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x3, 0x0, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x3, 0x0, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x3, 0x1, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x3, 0x1, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x3, 0x2, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x3, 0x2, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Max_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x3, 0x3, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x3, 0x3, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Min_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0xe), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0xe)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FaddW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FaddD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FsubW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FsubD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmulW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmulD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FdivW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FdivD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmaxW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmaxD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FminW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FminD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x1b)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Ffint_sW(VectorRegister wd, VectorRegister ws) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa2RF(0x19e, 0x0, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsa2RF(0x19e, 0x0, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); } void MipsAssembler::Ffint_sD(VectorRegister wd, VectorRegister ws) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa2RF(0x19e, 0x1, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsa2RF(0x19e, 0x1, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); } void MipsAssembler::Ftint_sW(VectorRegister wd, VectorRegister ws) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa2RF(0x19c, 0x0, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsa2RF(0x19c, 0x0, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); } void MipsAssembler::Ftint_sD(VectorRegister wd, VectorRegister ws) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa2RF(0x19c, 0x1, ws, wd, 0x1e), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsa2RF(0x19c, 0x1, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SllB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x0, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SllH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x1, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SllW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x2, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SllD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x0, 0x3, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SraB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SraH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SraW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SraD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SrlB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SrlH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SrlW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SrlD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0xd), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0xd)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::SlliB(VectorRegister wd, VectorRegister ws, int shamt3) { CHECK(HasMsa()); CHECK(IsUint<3>(shamt3)) << shamt3; - DsFsmInstrFff(EmitMsaBIT(0x0, shamt3 | kMsaDfMByteMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x0, shamt3 | kMsaDfMByteMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SlliH(VectorRegister wd, VectorRegister ws, int shamt4) { CHECK(HasMsa()); CHECK(IsUint<4>(shamt4)) << shamt4; - DsFsmInstrFff(EmitMsaBIT(0x0, shamt4 | kMsaDfMHalfwordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x0, shamt4 | kMsaDfMHalfwordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SlliW(VectorRegister wd, VectorRegister ws, int shamt5) { CHECK(HasMsa()); CHECK(IsUint<5>(shamt5)) << shamt5; - DsFsmInstrFff(EmitMsaBIT(0x0, shamt5 | kMsaDfMWordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x0, shamt5 | kMsaDfMWordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SlliD(VectorRegister wd, VectorRegister ws, int shamt6) { CHECK(HasMsa()); CHECK(IsUint<6>(shamt6)) << shamt6; - DsFsmInstrFff(EmitMsaBIT(0x0, shamt6 | kMsaDfMDoublewordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x0, shamt6 | kMsaDfMDoublewordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SraiB(VectorRegister wd, VectorRegister ws, int shamt3) { CHECK(HasMsa()); CHECK(IsUint<3>(shamt3)) << shamt3; - DsFsmInstrFff(EmitMsaBIT(0x1, shamt3 | kMsaDfMByteMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x1, shamt3 | kMsaDfMByteMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SraiH(VectorRegister wd, VectorRegister ws, int shamt4) { CHECK(HasMsa()); CHECK(IsUint<4>(shamt4)) << shamt4; - DsFsmInstrFff(EmitMsaBIT(0x1, shamt4 | kMsaDfMHalfwordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x1, shamt4 | kMsaDfMHalfwordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SraiW(VectorRegister wd, VectorRegister ws, int shamt5) { CHECK(HasMsa()); CHECK(IsUint<5>(shamt5)) << shamt5; - DsFsmInstrFff(EmitMsaBIT(0x1, shamt5 | kMsaDfMWordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x1, shamt5 | kMsaDfMWordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SraiD(VectorRegister wd, VectorRegister ws, int shamt6) { CHECK(HasMsa()); CHECK(IsUint<6>(shamt6)) << shamt6; - DsFsmInstrFff(EmitMsaBIT(0x1, shamt6 | kMsaDfMDoublewordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x1, shamt6 | kMsaDfMDoublewordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SrliB(VectorRegister wd, VectorRegister ws, int shamt3) { CHECK(HasMsa()); CHECK(IsUint<3>(shamt3)) << shamt3; - DsFsmInstrFff(EmitMsaBIT(0x2, shamt3 | kMsaDfMByteMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x2, shamt3 | kMsaDfMByteMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SrliH(VectorRegister wd, VectorRegister ws, int shamt4) { CHECK(HasMsa()); CHECK(IsUint<4>(shamt4)) << shamt4; - DsFsmInstrFff(EmitMsaBIT(0x2, shamt4 | kMsaDfMHalfwordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x2, shamt4 | kMsaDfMHalfwordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SrliW(VectorRegister wd, VectorRegister ws, int shamt5) { CHECK(HasMsa()); CHECK(IsUint<5>(shamt5)) << shamt5; - DsFsmInstrFff(EmitMsaBIT(0x2, shamt5 | kMsaDfMWordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x2, shamt5 | kMsaDfMWordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SrliD(VectorRegister wd, VectorRegister ws, int shamt6) { CHECK(HasMsa()); CHECK(IsUint<6>(shamt6)) << shamt6; - DsFsmInstrFff(EmitMsaBIT(0x2, shamt6 | kMsaDfMDoublewordMask, ws, wd, 0x9), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x2, shamt6 | kMsaDfMDoublewordMask, ws, wd, 0x9)).FprOuts(wd).FprIns(ws); } void MipsAssembler::MoveV(VectorRegister wd, VectorRegister ws) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsaBIT(0x1, 0x3e, ws, wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaBIT(0x1, 0x3e, ws, wd, 0x19)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SplatiB(VectorRegister wd, VectorRegister ws, int n4) { CHECK(HasMsa()); CHECK(IsUint<4>(n4)) << n4; - DsFsmInstrFff(EmitMsaELM(0x1, n4 | kMsaDfNByteMask, ws, wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x1, n4 | kMsaDfNByteMask, ws, wd, 0x19)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SplatiH(VectorRegister wd, VectorRegister ws, int n3) { CHECK(HasMsa()); CHECK(IsUint<3>(n3)) << n3; - DsFsmInstrFff(EmitMsaELM(0x1, n3 | kMsaDfNHalfwordMask, ws, wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x1, n3 | kMsaDfNHalfwordMask, ws, wd, 0x19)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SplatiW(VectorRegister wd, VectorRegister ws, int n2) { CHECK(HasMsa()); CHECK(IsUint<2>(n2)) << n2; - DsFsmInstrFff(EmitMsaELM(0x1, n2 | kMsaDfNWordMask, ws, wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x1, n2 | kMsaDfNWordMask, ws, wd, 0x19)).FprOuts(wd).FprIns(ws); } void MipsAssembler::SplatiD(VectorRegister wd, VectorRegister ws, int n1) { CHECK(HasMsa()); CHECK(IsUint<1>(n1)) << n1; - DsFsmInstrFff(EmitMsaELM(0x1, n1 | kMsaDfNDoublewordMask, ws, wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x1, n1 | kMsaDfNDoublewordMask, ws, wd, 0x19)).FprOuts(wd).FprIns(ws); } void MipsAssembler::Copy_sB(Register rd, VectorRegister ws, int n4) { CHECK(HasMsa()); CHECK(IsUint<4>(n4)) << n4; - DsFsmInstrRf(EmitMsaELM(0x2, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19), - rd, - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x2, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19)) + .GprOuts(rd).FprIns(ws); } void MipsAssembler::Copy_sH(Register rd, VectorRegister ws, int n3) { CHECK(HasMsa()); CHECK(IsUint<3>(n3)) << n3; - DsFsmInstrRf(EmitMsaELM(0x2, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19), - rd, - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x2, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19)) + .GprOuts(rd).FprIns(ws); } void MipsAssembler::Copy_sW(Register rd, VectorRegister ws, int n2) { CHECK(HasMsa()); CHECK(IsUint<2>(n2)) << n2; - DsFsmInstrRf(EmitMsaELM(0x2, n2 | kMsaDfNWordMask, ws, static_cast<VectorRegister>(rd), 0x19), - rd, - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x2, n2 | kMsaDfNWordMask, ws, static_cast<VectorRegister>(rd), 0x19)) + .GprOuts(rd).FprIns(ws); } void MipsAssembler::Copy_uB(Register rd, VectorRegister ws, int n4) { CHECK(HasMsa()); CHECK(IsUint<4>(n4)) << n4; - DsFsmInstrRf(EmitMsaELM(0x3, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19), - rd, - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x3, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19)) + .GprOuts(rd).FprIns(ws); } void MipsAssembler::Copy_uH(Register rd, VectorRegister ws, int n3) { CHECK(HasMsa()); CHECK(IsUint<3>(n3)) << n3; - DsFsmInstrRf(EmitMsaELM(0x3, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19), - rd, - static_cast<FRegister>(ws)); + DsFsmInstr(EmitMsaELM(0x3, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19)) + .GprOuts(rd).FprIns(ws); } void MipsAssembler::InsertB(VectorRegister wd, Register rs, int n4) { CHECK(HasMsa()); CHECK(IsUint<4>(n4)) << n4; - DsFsmInstrFffr(EmitMsaELM(0x4, n4 | kMsaDfNByteMask, static_cast<VectorRegister>(rs), wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaELM(0x4, n4 | kMsaDfNByteMask, static_cast<VectorRegister>(rs), wd, 0x19)) + .FprInOuts(wd).GprIns(rs); } void MipsAssembler::InsertH(VectorRegister wd, Register rs, int n3) { CHECK(HasMsa()); CHECK(IsUint<3>(n3)) << n3; - DsFsmInstrFffr( - EmitMsaELM(0x4, n3 | kMsaDfNHalfwordMask, static_cast<VectorRegister>(rs), wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaELM(0x4, n3 | kMsaDfNHalfwordMask, static_cast<VectorRegister>(rs), wd, 0x19)) + .FprInOuts(wd).GprIns(rs); } void MipsAssembler::InsertW(VectorRegister wd, Register rs, int n2) { CHECK(HasMsa()); CHECK(IsUint<2>(n2)) << n2; - DsFsmInstrFffr(EmitMsaELM(0x4, n2 | kMsaDfNWordMask, static_cast<VectorRegister>(rs), wd, 0x19), - static_cast<FRegister>(wd), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaELM(0x4, n2 | kMsaDfNWordMask, static_cast<VectorRegister>(rs), wd, 0x19)) + .FprInOuts(wd).GprIns(rs); } void MipsAssembler::FillB(VectorRegister wd, Register rs) { CHECK(HasMsa()); - DsFsmInstrFr(EmitMsa2R(0xc0, 0x0, static_cast<VectorRegister>(rs), wd, 0x1e), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsa2R(0xc0, 0x0, static_cast<VectorRegister>(rs), wd, 0x1e)) + .FprOuts(wd).GprIns(rs); } void MipsAssembler::FillH(VectorRegister wd, Register rs) { CHECK(HasMsa()); - DsFsmInstrFr(EmitMsa2R(0xc0, 0x1, static_cast<VectorRegister>(rs), wd, 0x1e), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsa2R(0xc0, 0x1, static_cast<VectorRegister>(rs), wd, 0x1e)) + .FprOuts(wd).GprIns(rs); } void MipsAssembler::FillW(VectorRegister wd, Register rs) { CHECK(HasMsa()); - DsFsmInstrFr(EmitMsa2R(0xc0, 0x2, static_cast<VectorRegister>(rs), wd, 0x1e), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsa2R(0xc0, 0x2, static_cast<VectorRegister>(rs), wd, 0x1e)) + .FprOuts(wd).GprIns(rs); } void MipsAssembler::LdiB(VectorRegister wd, int imm8) { CHECK(HasMsa()); CHECK(IsInt<8>(imm8)) << imm8; - DsFsmInstrFr(EmitMsaI10(0x6, 0x0, imm8 & kMsaS10Mask, wd, 0x7), - static_cast<FRegister>(wd), - ZERO); + DsFsmInstr(EmitMsaI10(0x6, 0x0, imm8 & kMsaS10Mask, wd, 0x7)).FprOuts(wd); } void MipsAssembler::LdiH(VectorRegister wd, int imm10) { CHECK(HasMsa()); CHECK(IsInt<10>(imm10)) << imm10; - DsFsmInstrFr(EmitMsaI10(0x6, 0x1, imm10 & kMsaS10Mask, wd, 0x7), - static_cast<FRegister>(wd), - ZERO); + DsFsmInstr(EmitMsaI10(0x6, 0x1, imm10 & kMsaS10Mask, wd, 0x7)).FprOuts(wd); } void MipsAssembler::LdiW(VectorRegister wd, int imm10) { CHECK(HasMsa()); CHECK(IsInt<10>(imm10)) << imm10; - DsFsmInstrFr(EmitMsaI10(0x6, 0x2, imm10 & kMsaS10Mask, wd, 0x7), - static_cast<FRegister>(wd), - ZERO); + DsFsmInstr(EmitMsaI10(0x6, 0x2, imm10 & kMsaS10Mask, wd, 0x7)).FprOuts(wd); } void MipsAssembler::LdiD(VectorRegister wd, int imm10) { CHECK(HasMsa()); CHECK(IsInt<10>(imm10)) << imm10; - DsFsmInstrFr(EmitMsaI10(0x6, 0x3, imm10 & kMsaS10Mask, wd, 0x7), - static_cast<FRegister>(wd), - ZERO); + DsFsmInstr(EmitMsaI10(0x6, 0x3, imm10 & kMsaS10Mask, wd, 0x7)).FprOuts(wd); } void MipsAssembler::LdB(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<10>(offset)) << offset; - DsFsmInstrFr(EmitMsaMI10(offset & kMsaS10Mask, rs, wd, 0x8, 0x0), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaMI10(offset & kMsaS10Mask, rs, wd, 0x8, 0x0)).FprOuts(wd).GprIns(rs); } void MipsAssembler::LdH(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<11>(offset)) << offset; CHECK_ALIGNED(offset, kMipsHalfwordSize); - DsFsmInstrFr(EmitMsaMI10((offset >> TIMES_2) & kMsaS10Mask, rs, wd, 0x8, 0x1), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaMI10((offset >> TIMES_2) & kMsaS10Mask, rs, wd, 0x8, 0x1)) + .FprOuts(wd).GprIns(rs); } void MipsAssembler::LdW(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<12>(offset)) << offset; CHECK_ALIGNED(offset, kMipsWordSize); - DsFsmInstrFr(EmitMsaMI10((offset >> TIMES_4) & kMsaS10Mask, rs, wd, 0x8, 0x2), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaMI10((offset >> TIMES_4) & kMsaS10Mask, rs, wd, 0x8, 0x2)) + .FprOuts(wd).GprIns(rs); } void MipsAssembler::LdD(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<13>(offset)) << offset; CHECK_ALIGNED(offset, kMipsDoublewordSize); - DsFsmInstrFr(EmitMsaMI10((offset >> TIMES_8) & kMsaS10Mask, rs, wd, 0x8, 0x3), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaMI10((offset >> TIMES_8) & kMsaS10Mask, rs, wd, 0x8, 0x3)) + .FprOuts(wd).GprIns(rs); } void MipsAssembler::StB(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<10>(offset)) << offset; - DsFsmInstrFR(EmitMsaMI10(offset & kMsaS10Mask, rs, wd, 0x9, 0x0), static_cast<FRegister>(wd), rs); + DsFsmInstr(EmitMsaMI10(offset & kMsaS10Mask, rs, wd, 0x9, 0x0)).FprIns(wd).GprIns(rs); } void MipsAssembler::StH(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<11>(offset)) << offset; CHECK_ALIGNED(offset, kMipsHalfwordSize); - DsFsmInstrFR(EmitMsaMI10((offset >> TIMES_2) & kMsaS10Mask, rs, wd, 0x9, 0x1), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaMI10((offset >> TIMES_2) & kMsaS10Mask, rs, wd, 0x9, 0x1)) + .FprIns(wd).GprIns(rs); } void MipsAssembler::StW(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<12>(offset)) << offset; CHECK_ALIGNED(offset, kMipsWordSize); - DsFsmInstrFR(EmitMsaMI10((offset >> TIMES_4) & kMsaS10Mask, rs, wd, 0x9, 0x2), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaMI10((offset >> TIMES_4) & kMsaS10Mask, rs, wd, 0x9, 0x2)) + .FprIns(wd).GprIns(rs); } void MipsAssembler::StD(VectorRegister wd, Register rs, int offset) { CHECK(HasMsa()); CHECK(IsInt<13>(offset)) << offset; CHECK_ALIGNED(offset, kMipsDoublewordSize); - DsFsmInstrFR(EmitMsaMI10((offset >> TIMES_8) & kMsaS10Mask, rs, wd, 0x9, 0x3), - static_cast<FRegister>(wd), - rs); + DsFsmInstr(EmitMsaMI10((offset >> TIMES_8) & kMsaS10Mask, rs, wd, 0x9, 0x3)) + .FprIns(wd).GprIns(rs); } void MipsAssembler::IlvlB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvlH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvlW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvlD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvrB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvrH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvrW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvrD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvevB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvevH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvevW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvevD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvodB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvodH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvodW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::IlvodD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x14), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x14)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::MaddvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::MaddvH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x1, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::MaddvW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x2, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::MaddvD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x1, 0x3, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::MsubvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::MsubvH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::MsubvW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::MsubvD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0x12), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0x12)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Asub_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x11), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x11)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmaddW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x0, wt, ws, wd, 0x1b)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmaddD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x1, wt, ws, wd, 0x1b)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmsubW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x2, wt, ws, wd, 0x1b)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::FmsubD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0x1b), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x2, 0x3, wt, ws, wd, 0x1b)).FprInOuts(wd).FprIns(ws, wt); } void MipsAssembler::Hadd_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x15), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x15)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Hadd_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x15), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x15)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Hadd_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x15), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x15)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Hadd_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x15), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x15)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Hadd_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x15), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x15)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); - DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x15), - static_cast<FRegister>(wd), - static_cast<FRegister>(ws), - static_cast<FRegister>(wt)); + DsFsmInstr(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x15)).FprOuts(wd).FprIns(ws, wt); } void MipsAssembler::ReplicateFPToVectorRegister(VectorRegister dst, @@ -4144,7 +3612,7 @@ bool MipsAssembler::Branch::CanHaveDelayedInstruction(const DelaySlot& delay_slo case kLongCall: // Instructions depending on or modifying RA should not be moved into delay slots // of branches modifying RA. - return ((delay_slot.gpr_ins_mask_ | delay_slot.gpr_outs_mask_) & (1u << RA)) == 0; + return ((delay_slot.masks_.gpr_ins_ | delay_slot.masks_.gpr_outs_) & (1u << RA)) == 0; // R2 conditional branches. case kCondBranch: @@ -4157,17 +3625,17 @@ bool MipsAssembler::Branch::CanHaveDelayedInstruction(const DelaySlot& delay_slo case kCondGTZ: case kCondEQZ: case kCondNEZ: - return (delay_slot.gpr_outs_mask_ & (1u << lhs_reg_)) == 0; + return (delay_slot.masks_.gpr_outs_ & (1u << lhs_reg_)) == 0; // Branches with two GPR sources. case kCondEQ: case kCondNE: - return (delay_slot.gpr_outs_mask_ & ((1u << lhs_reg_) | (1u << rhs_reg_))) == 0; + return (delay_slot.masks_.gpr_outs_ & ((1u << lhs_reg_) | (1u << rhs_reg_))) == 0; // Branches with one FPU condition code source. case kCondF: case kCondT: - return (delay_slot.cc_outs_mask_ & (1u << lhs_reg_)) == 0; + return (delay_slot.masks_.cc_outs_ & (1u << lhs_reg_)) == 0; default: // We don't support synthetic R2 branches (preceded with slt[u]) at this level @@ -4192,7 +3660,7 @@ bool MipsAssembler::Branch::CanHaveDelayedInstruction(const DelaySlot& delay_slo // Branches with one FPU register source. case kCondF: case kCondT: - return (delay_slot.fpr_outs_mask_ & (1u << lhs_reg_)) == 0; + return (delay_slot.masks_.fpr_outs_ & (1u << lhs_reg_)) == 0; // Others have a forbidden slot instead of a delay slot. default: return false; @@ -4858,8 +4326,8 @@ bool MipsAssembler::CanExchangeWithSlt(Register rs, Register rt) const { // Likewise, if the instruction depends on AT, it can't be exchanged with slt[u] // because slt[u] changes AT. return (delay_slot_.instruction_ != 0 && - (delay_slot_.gpr_outs_mask_ & ((1u << AT) | (1u << rs) | (1u << rt))) == 0 && - (delay_slot_.gpr_ins_mask_ & (1u << AT)) == 0); + (delay_slot_.masks_.gpr_outs_ & ((1u << AT) | (1u << rs) | (1u << rt))) == 0 && + (delay_slot_.masks_.gpr_ins_ & (1u << AT)) == 0); } void MipsAssembler::ExchangeWithSlt(const DelaySlot& forwarded_slot) { diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h index 1c3097ac58..7de8e2e366 100644 --- a/compiler/utils/mips/assembler_mips.h +++ b/compiler/utils/mips/assembler_mips.h @@ -74,6 +74,81 @@ enum FPClassMaskType { kPositiveZero = 0x200, }; +// Instruction description in terms of input and output registers. +// Used for instruction reordering. +struct InOutRegMasks { + InOutRegMasks() + : gpr_outs_(0), gpr_ins_(0), fpr_outs_(0), fpr_ins_(0), cc_outs_(0), cc_ins_(0) {} + + inline InOutRegMasks& GprOuts(Register reg) { + gpr_outs_ |= (1u << reg); + gpr_outs_ &= ~1u; // Ignore register ZERO. + return *this; + } + template<typename T, typename... Ts> + inline InOutRegMasks& GprOuts(T one, Ts... more) { GprOuts(one); GprOuts(more...); return *this; } + + inline InOutRegMasks& GprIns(Register reg) { + gpr_ins_ |= (1u << reg); + gpr_ins_ &= ~1u; // Ignore register ZERO. + return *this; + } + template<typename T, typename... Ts> + inline InOutRegMasks& GprIns(T one, Ts... more) { GprIns(one); GprIns(more...); return *this; } + + inline InOutRegMasks& GprInOuts(Register reg) { GprIns(reg); GprOuts(reg); return *this; } + template<typename T, typename... Ts> + inline InOutRegMasks& GprInOuts(T one, Ts... more) { + GprInOuts(one); + GprInOuts(more...); + return *this; + } + + inline InOutRegMasks& FprOuts(FRegister reg) { fpr_outs_ |= (1u << reg); return *this; } + inline InOutRegMasks& FprOuts(VectorRegister reg) { return FprOuts(static_cast<FRegister>(reg)); } + template<typename T, typename... Ts> + inline InOutRegMasks& FprOuts(T one, Ts... more) { FprOuts(one); FprOuts(more...); return *this; } + + inline InOutRegMasks& FprIns(FRegister reg) { fpr_ins_ |= (1u << reg); return *this; } + inline InOutRegMasks& FprIns(VectorRegister reg) { return FprIns(static_cast<FRegister>(reg)); } + template<typename T, typename... Ts> + inline InOutRegMasks& FprIns(T one, Ts... more) { FprIns(one); FprIns(more...); return *this; } + + inline InOutRegMasks& FprInOuts(FRegister reg) { FprIns(reg); FprOuts(reg); return *this; } + inline InOutRegMasks& FprInOuts(VectorRegister reg) { + return FprInOuts(static_cast<FRegister>(reg)); + } + template<typename T, typename... Ts> + inline InOutRegMasks& FprInOuts(T one, Ts... more) { + FprInOuts(one); + FprInOuts(more...); + return *this; + } + + inline InOutRegMasks& CcOuts(int cc) { cc_outs_ |= (1u << cc); return *this; } + template<typename T, typename... Ts> + inline InOutRegMasks& CcOuts(T one, Ts... more) { CcOuts(one); CcOuts(more...); return *this; } + + inline InOutRegMasks& CcIns(int cc) { cc_ins_ |= (1u << cc); return *this; } + template<typename T, typename... Ts> + inline InOutRegMasks& CcIns(T one, Ts... more) { CcIns(one); CcIns(more...); return *this; } + + // Mask of output GPRs for the instruction. + uint32_t gpr_outs_; + // Mask of input GPRs for the instruction. + uint32_t gpr_ins_; + // Mask of output FPRs for the instruction. + uint32_t fpr_outs_; + // Mask of input FPRs for the instruction. + uint32_t fpr_ins_; + // Mask of output FPU condition code flags for the instruction. + uint32_t cc_outs_; + // Mask of input FPU condition code flags for the instruction. + uint32_t cc_ins_; + + // TODO: add LO and HI. +}; + class MipsLabel : public Label { public: MipsLabel() : prev_branch_id_plus_one_(0) {} @@ -462,6 +537,16 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi void FloorWS(FRegister fd, FRegister fs); void FloorWD(FRegister fd, FRegister fs); + // Note, the 32 LSBs of a 64-bit value must be loaded into an FPR before the 32 MSBs + // when loading the value as 32-bit halves. This applies to all 32-bit FPR loads: + // Mtc1(), Mthc1(), MoveToFpuHigh(), Lwc1(). Even if you need two Mtc1()'s or two + // Lwc1()'s to load a pair of 32-bit FPRs and these loads do not interfere with one + // another (unlike Mtc1() and Mthc1() with 64-bit FPRs), maintain the order: + // low then high. + // + // Also, prefer MoveFromFpuHigh()/MoveToFpuHigh() over Mfhc1()/Mthc1() and Mfc1()/Mtc1(). + // This will save you some if statements. + FRegister GetFpuRegLow(FRegister reg); void Mfc1(Register rt, FRegister fs); void Mtc1(Register rt, FRegister fs); void Mfhc1(Register rt, FRegister fs); @@ -1337,23 +1422,13 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi // Used to make the decision of moving the instruction into a delay slot. struct DelaySlot { DelaySlot(); + // Encoded instruction that may be used to fill the delay slot or 0 // (0 conveniently represents NOP). uint32_t instruction_; - // Mask of output GPRs for the instruction. - uint32_t gpr_outs_mask_; - // Mask of input GPRs for the instruction. - uint32_t gpr_ins_mask_; - // Mask of output FPRs for the instruction. - uint32_t fpr_outs_mask_; - // Mask of input FPRs for the instruction. - uint32_t fpr_ins_mask_; - // Mask of output FPU condition code flags for the instruction. - uint32_t cc_outs_mask_; - // Mask of input FPU condition code flags for the instruction. - uint32_t cc_ins_mask_; - // Branches never operate on the LO and HI registers, hence there's - // no mask for LO and HI. + + // Input/output register masks. + InOutRegMasks masks_; // Label for patchable instructions to allow moving them into delay slots. MipsLabel* patcher_label_; @@ -1646,30 +1721,8 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi void FinalizeLabeledBranch(MipsLabel* label); // Various helpers for branch delay slot management. - void DsFsmInstr(uint32_t instruction, - uint32_t gpr_outs_mask, - uint32_t gpr_ins_mask, - uint32_t fpr_outs_mask, - uint32_t fpr_ins_mask, - uint32_t cc_outs_mask, - uint32_t cc_ins_mask, - MipsLabel* patcher_label = nullptr); + InOutRegMasks& DsFsmInstr(uint32_t instruction, MipsLabel* patcher_label = nullptr); void DsFsmInstrNop(uint32_t instruction); - void DsFsmInstrRrr(uint32_t instruction, - Register out, - Register in1, - Register in2, - MipsLabel* patcher_label = nullptr); - void DsFsmInstrRrrr(uint32_t instruction, Register in1_out, Register in2, Register in3); - void DsFsmInstrFff(uint32_t instruction, FRegister out, FRegister in1, FRegister in2); - void DsFsmInstrFfff(uint32_t instruction, FRegister in1_out, FRegister in2, FRegister in3); - void DsFsmInstrFffr(uint32_t instruction, FRegister in1_out, FRegister in2, Register in3); - void DsFsmInstrRf(uint32_t instruction, Register out, FRegister in); - void DsFsmInstrFr(uint32_t instruction, FRegister out, Register in); - void DsFsmInstrFR(uint32_t instruction, FRegister in1, Register in2); - void DsFsmInstrCff(uint32_t instruction, int cc_out, FRegister in1, FRegister in2); - void DsFsmInstrRrrc(uint32_t instruction, Register in1_out, Register in2, int cc_in); - void DsFsmInstrFffc(uint32_t instruction, FRegister in1_out, FRegister in2, int cc_in); void DsFsmLabel(); void DsFsmCommitLabel(); void DsFsmDropLabel(); |