diff options
| author | bunnei <bunneidev@gmail.com> | 2018-11-22 08:43:29 -0800 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-22 08:43:29 -0800 | 
| commit | e633021532262d47284edc3a3c4626ce72360d3a (patch) | |
| tree | 49352b6ce62e05b6bae63f255d32227eef8ea64f /src/video_core | |
| parent | b84f4cfb6261ac8b2cce4ba773f0ddfd73606fac (diff) | |
| parent | 033b46253e6c7de33c5f8b51adb9d96ca606669d (diff) | |
Merge pull request #1764 from bunnei/macrointerpreter
macro_interpreter: Implement AddWithCarry and SubtractWithBorrow.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/macro_interpreter.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/macro_interpreter.h | 4 | 
2 files changed, 25 insertions, 8 deletions
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp index 335a8d407..2b0dea5cd 100644 --- a/src/video_core/macro_interpreter.cpp +++ b/src/video_core/macro_interpreter.cpp @@ -35,6 +35,7 @@ void MacroInterpreter::Reset() {      // The next parameter index starts at 1, because $r1 already has the value of the first      // parameter.      next_parameter_index = 1; +    carry_flag = false;  }  bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) { @@ -135,14 +136,28 @@ MacroInterpreter::Opcode MacroInterpreter::GetOpcode(u32 offset) const {      return {macro_memory[offset + pc / sizeof(u32)]};  } -u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const { +u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) {      switch (operation) { -    case ALUOperation::Add: -        return src_a + src_b; -    // TODO(Subv): Implement AddWithCarry -    case ALUOperation::Subtract: -        return src_a - src_b; -    // TODO(Subv): Implement SubtractWithBorrow +    case ALUOperation::Add: { +        const u64 result{static_cast<u64>(src_a) + src_b}; +        carry_flag = result > 0xffffffff; +        return static_cast<u32>(result); +    } +    case ALUOperation::AddWithCarry: { +        const u64 result{static_cast<u64>(src_a) + src_b + (carry_flag ? 1ULL : 0ULL)}; +        carry_flag = result > 0xffffffff; +        return static_cast<u32>(result); +    } +    case ALUOperation::Subtract: { +        const u64 result{static_cast<u64>(src_a) - src_b}; +        carry_flag = result < 0x100000000; +        return static_cast<u32>(result); +    } +    case ALUOperation::SubtractWithBorrow: { +        const u64 result{static_cast<u64>(src_a) - src_b - (carry_flag ? 0ULL : 1ULL)}; +        carry_flag = result < 0x100000000; +        return static_cast<u32>(result); +    }      case ALUOperation::Xor:          return src_a ^ src_b;      case ALUOperation::Or: diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h index 62d1ce289..cde360288 100644 --- a/src/video_core/macro_interpreter.h +++ b/src/video_core/macro_interpreter.h @@ -117,7 +117,7 @@ private:      bool Step(u32 offset, bool is_delay_slot);      /// Calculates the result of an ALU operation. src_a OP src_b; -    u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const; +    u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b);      /// Performs the result operation on the input result and stores it in the specified register      /// (if necessary). @@ -165,5 +165,7 @@ private:      std::vector<u32> parameters;      /// Index of the next parameter that will be fetched by the 'parm' instruction.      u32 next_parameter_index = 0; + +    bool carry_flag{};  };  } // namespace Tegra  | 
