diff options
| author | 2021-04-17 00:48:35 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:28 -0400 | |
| commit | be431f5ed080955cce358e9750347229b2bc9a04 (patch) | |
| tree | 6980191ce828379c3a0a16418539be676722de67 /src/shader_recompiler/frontend/maxwell | |
| parent | shader: Implement SampleMask (diff) | |
| download | yuzu-be431f5ed080955cce358e9750347229b2bc9a04.tar.gz yuzu-be431f5ed080955cce358e9750347229b2bc9a04.tar.xz yuzu-be431f5ed080955cce358e9750347229b2bc9a04.zip | |
shader: Implement BFE and BFI CC
Fix two bugs in BFI.
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp | 11 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp | 17 |
2 files changed, 16 insertions, 12 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp index 0738ae7a6..9d5a87e52 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_extract.cpp | |||
| @@ -18,10 +18,6 @@ void BFE(TranslatorVisitor& v, u64 insn, const IR::U32& src) { | |||
| 18 | BitField<48, 1, u64> is_signed; | 18 | BitField<48, 1, u64> is_signed; |
| 19 | } const bfe{insn}; | 19 | } const bfe{insn}; |
| 20 | 20 | ||
| 21 | if (bfe.cc != 0) { | ||
| 22 | throw NotImplementedException("BFE CC"); | ||
| 23 | } | ||
| 24 | |||
| 25 | const IR::U32 offset{v.ir.BitFieldExtract(src, v.ir.Imm32(0), v.ir.Imm32(8), false)}; | 21 | const IR::U32 offset{v.ir.BitFieldExtract(src, v.ir.Imm32(0), v.ir.Imm32(8), false)}; |
| 26 | const IR::U32 count{v.ir.BitFieldExtract(src, v.ir.Imm32(8), v.ir.Imm32(8), false)}; | 22 | const IR::U32 count{v.ir.BitFieldExtract(src, v.ir.Imm32(8), v.ir.Imm32(8), false)}; |
| 27 | 23 | ||
| @@ -53,6 +49,13 @@ void BFE(TranslatorVisitor& v, u64 insn, const IR::U32& src) { | |||
| 53 | result = IR::U32{v.ir.Select(zero_count, zero, result)}; | 49 | result = IR::U32{v.ir.Select(zero_count, zero, result)}; |
| 54 | 50 | ||
| 55 | v.X(bfe.dest_reg, result); | 51 | v.X(bfe.dest_reg, result); |
| 52 | |||
| 53 | if (bfe.cc != 0) { | ||
| 54 | v.SetZFlag(v.ir.IEqual(result, zero)); | ||
| 55 | v.SetSFlag(v.ir.ILessThan(result, zero, true)); | ||
| 56 | v.ResetCFlag(); | ||
| 57 | v.ResetOFlag(); | ||
| 58 | } | ||
| 56 | } | 59 | } |
| 57 | } // Anonymous namespace | 60 | } // Anonymous namespace |
| 58 | 61 | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp index fb7f821e6..1e1ec2119 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/bitfield_insert.cpp | |||
| @@ -16,18 +16,14 @@ void BFI(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& ba | |||
| 16 | BitField<47, 1, u64> cc; | 16 | BitField<47, 1, u64> cc; |
| 17 | } const bfi{insn}; | 17 | } const bfi{insn}; |
| 18 | 18 | ||
| 19 | if (bfi.cc != 0) { | 19 | const IR::U32 zero{v.ir.Imm32(0)}; |
| 20 | throw NotImplementedException("BFI CC"); | 20 | const IR::U32 offset{v.ir.BitFieldExtract(src_a, zero, v.ir.Imm32(8), false)}; |
| 21 | } | ||
| 22 | |||
| 23 | const IR::U32 offset{v.ir.BitFieldExtract(src_a, v.ir.Imm32(0), v.ir.Imm32(8), false)}; | ||
| 24 | const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)}; | 21 | const IR::U32 unsafe_count{v.ir.BitFieldExtract(src_a, v.ir.Imm32(8), v.ir.Imm32(8), false)}; |
| 25 | const IR::U32 max_size{v.ir.Imm32(32)}; | 22 | const IR::U32 max_size{v.ir.Imm32(32)}; |
| 26 | 23 | ||
| 27 | // Edge case conditions | 24 | // Edge case conditions |
| 28 | const IR::U1 zero_offset{v.ir.IEqual(offset, v.ir.Imm32(0))}; | ||
| 29 | const IR::U1 exceed_offset{v.ir.IGreaterThanEqual(offset, max_size, false)}; | 25 | const IR::U1 exceed_offset{v.ir.IGreaterThanEqual(offset, max_size, false)}; |
| 30 | const IR::U1 exceed_count{v.ir.IGreaterThanEqual(unsafe_count, max_size, false)}; | 26 | const IR::U1 exceed_count{v.ir.IGreaterThan(unsafe_count, max_size, false)}; |
| 31 | 27 | ||
| 32 | const IR::U32 remaining_size{v.ir.ISub(max_size, offset)}; | 28 | const IR::U32 remaining_size{v.ir.ISub(max_size, offset)}; |
| 33 | const IR::U32 safe_count{v.ir.Select(exceed_count, remaining_size, unsafe_count)}; | 29 | const IR::U32 safe_count{v.ir.Select(exceed_count, remaining_size, unsafe_count)}; |
| @@ -36,9 +32,14 @@ void BFI(TranslatorVisitor& v, u64 insn, const IR::U32& src_a, const IR::U32& ba | |||
| 36 | IR::U32 result{v.ir.BitFieldInsert(base, insert, offset, safe_count)}; | 32 | IR::U32 result{v.ir.BitFieldInsert(base, insert, offset, safe_count)}; |
| 37 | 33 | ||
| 38 | result = IR::U32{v.ir.Select(exceed_offset, base, result)}; | 34 | result = IR::U32{v.ir.Select(exceed_offset, base, result)}; |
| 39 | result = IR::U32{v.ir.Select(zero_offset, base, result)}; | ||
| 40 | 35 | ||
| 41 | v.X(bfi.dest_reg, result); | 36 | v.X(bfi.dest_reg, result); |
| 37 | if (bfi.cc != 0) { | ||
| 38 | v.SetZFlag(v.ir.IEqual(result, zero)); | ||
| 39 | v.SetSFlag(v.ir.ILessThan(result, zero, true)); | ||
| 40 | v.ResetCFlag(); | ||
| 41 | v.ResetOFlag(); | ||
| 42 | } | ||
| 42 | } | 43 | } |
| 43 | } // Anonymous namespace | 44 | } // Anonymous namespace |
| 44 | 45 | ||