summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/macro_interpreter.cpp29
-rw-r--r--src/video_core/macro_interpreter.h4
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() {
35 // The next parameter index starts at 1, because $r1 already has the value of the first 35 // The next parameter index starts at 1, because $r1 already has the value of the first
36 // parameter. 36 // parameter.
37 next_parameter_index = 1; 37 next_parameter_index = 1;
38 carry_flag = false;
38} 39}
39 40
40bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) { 41bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) {
@@ -135,14 +136,28 @@ MacroInterpreter::Opcode MacroInterpreter::GetOpcode(u32 offset) const {
135 return {macro_memory[offset + pc / sizeof(u32)]}; 136 return {macro_memory[offset + pc / sizeof(u32)]};
136} 137}
137 138
138u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const { 139u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) {
139 switch (operation) { 140 switch (operation) {
140 case ALUOperation::Add: 141 case ALUOperation::Add: {
141 return src_a + src_b; 142 const u64 result{static_cast<u64>(src_a) + src_b};
142 // TODO(Subv): Implement AddWithCarry 143 carry_flag = result > 0xffffffff;
143 case ALUOperation::Subtract: 144 return static_cast<u32>(result);
144 return src_a - src_b; 145 }
145 // TODO(Subv): Implement SubtractWithBorrow 146 case ALUOperation::AddWithCarry: {
147 const u64 result{static_cast<u64>(src_a) + src_b + (carry_flag ? 1ULL : 0ULL)};
148 carry_flag = result > 0xffffffff;
149 return static_cast<u32>(result);
150 }
151 case ALUOperation::Subtract: {
152 const u64 result{static_cast<u64>(src_a) - src_b};
153 carry_flag = result < 0x100000000;
154 return static_cast<u32>(result);
155 }
156 case ALUOperation::SubtractWithBorrow: {
157 const u64 result{static_cast<u64>(src_a) - src_b - (carry_flag ? 0ULL : 1ULL)};
158 carry_flag = result < 0x100000000;
159 return static_cast<u32>(result);
160 }
146 case ALUOperation::Xor: 161 case ALUOperation::Xor:
147 return src_a ^ src_b; 162 return src_a ^ src_b;
148 case ALUOperation::Or: 163 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:
117 bool Step(u32 offset, bool is_delay_slot); 117 bool Step(u32 offset, bool is_delay_slot);
118 118
119 /// Calculates the result of an ALU operation. src_a OP src_b; 119 /// Calculates the result of an ALU operation. src_a OP src_b;
120 u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const; 120 u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b);
121 121
122 /// Performs the result operation on the input result and stores it in the specified register 122 /// Performs the result operation on the input result and stores it in the specified register
123 /// (if necessary). 123 /// (if necessary).
@@ -165,5 +165,7 @@ private:
165 std::vector<u32> parameters; 165 std::vector<u32> parameters;
166 /// Index of the next parameter that will be fetched by the 'parm' instruction. 166 /// Index of the next parameter that will be fetched by the 'parm' instruction.
167 u32 next_parameter_index = 0; 167 u32 next_parameter_index = 0;
168
169 bool carry_flag{};
168}; 170};
169} // namespace Tegra 171} // namespace Tegra