ReXGlue SDK
Loading...
Searching...
No Matches
ucode.h
1
11
12#pragma once
13
14#include <cstdint>
15
16#include <rex/types.h>
17#include <rex/assert.h>
18#include <rex/xenos/fetch.h>
19#include <rex/xenos/format.h>
20#include <rex/xenos/state.h>
21#include <rex/math.h>
22#include <rex/platform.h>
23
24/*
25 * Parts of this code come from the freedreno project:
26 * https://github.com/freedreno/freedreno/blob/master/includes/instr-a2xx.h
27 *
28 * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
29 *
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
36 *
37 * The above copyright notice and this permission notice (including the next
38 * paragraph) shall be included in all copies or substantial portions of the
39 * Software.
40 *
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
47 * SOFTWARE.
48 */
49
55
56// NOLINTNEXTLINE(performance-enum-size): Xenos bit field, MSVC packs per type
57enum class ControlFlowOpcode : u32 {
58 kNop = 0,
59 kExec = 1,
91 kReturn = 10,
92 kCondJmp = 11,
93 kAlloc = 12,
104};
105
108 return opcode == ControlFlowOpcode::kExec || opcode == ControlFlowOpcode::kExecEnd ||
114}
115
122
131
133// NOLINTNEXTLINE(performance-enum-size): Xenos bit field, MSVC packs per type
134enum class AddressingMode : u32 {
139};
140
141// NOLINTNEXTLINE(performance-enum-size): Xenos bit field, MSVC packs per type
142enum class AllocType : u32 {
144 kNone = 0,
145 kVsPosition = 1,
146 kVsInterpolators = 2,
147 kPsColors = 2,
148 kMemory = 3,
149};
150
153 ControlFlowOpcode GetOpcode() const { return opcode_; }
154 AddressingMode GetAddressingMode() const { return address_mode_; }
155 u32 GetAddress() const { return address_; }
156 u32 GetCount() const { return count_; }
158 u32 GetSequence() const { return sequence_; }
165 bool IsPredicateClean() const { return is_predicate_clean_ == 1; }
166 bool IsYield() const { return is_yield_ == 1; }
167
168 private:
169 u32 address_ : 12;
170 u32 count_ : 3;
171 u32 is_yield_ : 1;
172 u32 sequence_ : 12;
173 [[maybe_unused]] u32 vc_hi_ : 4;
174
175 [[maybe_unused]] u32 vc_lo_ : 2;
176 u32 : 7;
177 u32 is_predicate_clean_ : 1;
178 u32 : 1;
179 AddressingMode address_mode_ : 1;
180 ControlFlowOpcode opcode_ : 4;
181};
182REX_STATIC_ASSERT_SIZE(ControlFlowExecInstruction, sizeof(u32) * 2);
183
189 ControlFlowOpcode GetOpcode() const { return opcode_; }
190 AddressingMode GetAddressingMode() const { return address_mode_; }
191 u32 GetAddress() const { return address_; }
192 u32 GetCount() const { return count_; }
194 u32 GetSequence() const { return sequence_; }
195 u32 GetBoolAddress() const { return bool_address_; }
197 bool GetCondition() const { return condition_ == 1; }
198 bool IsYield() const { return is_yield_ == 1; }
199
200 private:
201 u32 address_ : 12;
202 u32 count_ : 3;
203 u32 is_yield_ : 1;
204 u32 sequence_ : 12;
205 [[maybe_unused]] u32 vc_hi_ : 4;
206
207 [[maybe_unused]] u32 vc_lo_ : 2;
208 u32 bool_address_ : 8;
209 u32 condition_ : 1;
210 AddressingMode address_mode_ : 1;
211 ControlFlowOpcode opcode_ : 4;
212};
213REX_STATIC_ASSERT_SIZE(ControlFlowCondExecInstruction, sizeof(u32) * 2);
214
217 ControlFlowOpcode GetOpcode() const { return opcode_; }
218 AddressingMode GetAddressingMode() const { return address_mode_; }
219 u32 GetAddress() const { return address_; }
220 u32 GetCount() const { return count_; }
222 u32 GetSequence() const { return sequence_; }
224 bool IsPredicateClean() const { return is_predicate_clean_ == 1; }
226 bool GetCondition() const { return condition_ == 1; }
227 bool IsYield() const { return is_yield_ == 1; }
228
229 private:
230 u32 address_ : 12;
231 u32 count_ : 3;
232 u32 is_yield_ : 1;
233 u32 sequence_ : 12;
234 [[maybe_unused]] u32 vc_hi_ : 4;
235
236 [[maybe_unused]] u32 vc_lo_ : 2;
237 u32 : 7;
238 u32 is_predicate_clean_ : 1;
239 u32 condition_ : 1;
240 AddressingMode address_mode_ : 1;
241 ControlFlowOpcode opcode_ : 4;
242};
243REX_STATIC_ASSERT_SIZE(ControlFlowCondExecPredInstruction, sizeof(u32) * 2);
244
247 ControlFlowOpcode GetOpcode() const { return opcode_; }
248 AddressingMode GetAddressingMode() const { return address_mode_; }
250 u32 GetAddress() const { return address_; }
252 bool IsRepeat() const { return is_repeat_; }
254 u32 GetLoopID() const { return loop_id_; }
255
256 private:
257 u32 address_ : 13;
258 u32 is_repeat_ : 1;
259 u32 : 2;
260 u32 loop_id_ : 5;
261 u32 : 11;
262
263 u32 : 11;
264 AddressingMode address_mode_ : 1;
265 ControlFlowOpcode opcode_ : 4;
266};
267REX_STATIC_ASSERT_SIZE(ControlFlowLoopStartInstruction, sizeof(u32) * 2);
268
271 ControlFlowOpcode GetOpcode() const { return opcode_; }
272 AddressingMode GetAddressingMode() const { return address_mode_; }
274 u32 GetAddress() const { return address_; }
276 u32 GetLoopID() const { return loop_id_; }
278 bool IsPredicatedBreak() const { return is_predicated_break_; }
280 bool GetCondition() const { return condition_ == 1; }
281
282 private:
283 u32 address_ : 13;
284 u32 : 3;
285 u32 loop_id_ : 5;
286 u32 is_predicated_break_ : 1;
287 u32 : 10;
288
289 u32 : 10;
290 u32 condition_ : 1;
291 AddressingMode address_mode_ : 1;
292 ControlFlowOpcode opcode_ : 4;
293};
294REX_STATIC_ASSERT_SIZE(ControlFlowLoopEndInstruction, sizeof(u32) * 2);
295
298 ControlFlowOpcode GetOpcode() const { return opcode_; }
299 AddressingMode GetAddressingMode() const { return address_mode_; }
300 u32 GetAddress() const { return address_; }
301 bool IsUnconditional() const { return is_unconditional_; }
303 bool IsPredicated() const { return is_predicated_; }
304 u32 GetBoolAddress() const { return bool_address_; }
306 bool GetCondition() const { return condition_ == 1; }
307
308 private:
309 u32 address_ : 13;
310 u32 is_unconditional_ : 1;
311 u32 is_predicated_ : 1;
312 u32 : 17;
313
314 u32 : 2;
315 u32 bool_address_ : 8;
316 u32 condition_ : 1;
317 AddressingMode address_mode_ : 1;
318 ControlFlowOpcode opcode_ : 4;
319};
320REX_STATIC_ASSERT_SIZE(ControlFlowCondCallInstruction, sizeof(u32) * 2);
321
324 ControlFlowOpcode GetOpcode() const { return opcode_; }
325 AddressingMode GetAddressingMode() const { return address_mode_; }
326
327 private:
328 u32 : 32;
329
330 u32 : 11;
331 AddressingMode address_mode_ : 1;
332 ControlFlowOpcode opcode_ : 4;
333};
334REX_STATIC_ASSERT_SIZE(ControlFlowReturnInstruction, sizeof(u32) * 2);
335
338 ControlFlowOpcode GetOpcode() const { return opcode_; }
339 AddressingMode GetAddressingMode() const { return address_mode_; }
340 u32 GetAddress() const { return address_; }
341 bool IsUnconditional() const { return is_unconditional_; }
343 bool IsPredicated() const { return is_predicated_; }
344 u32 GetBoolAddress() const { return bool_address_; }
346 bool GetCondition() const { return condition_ == 1; }
347
348 private:
349 u32 address_ : 13;
350 u32 is_unconditional_ : 1;
351 u32 is_predicated_ : 1;
352 u32 : 17;
353
354 u32 : 1;
355 [[maybe_unused]] u32 direction_ : 1;
356 u32 bool_address_ : 8;
357 u32 condition_ : 1;
358 AddressingMode address_mode_ : 1;
359 ControlFlowOpcode opcode_ : 4;
360};
361REX_STATIC_ASSERT_SIZE(ControlFlowCondJmpInstruction, sizeof(u32) * 2);
362
365 ControlFlowOpcode GetOpcode() const { return opcode_; }
366 u32 GetSize() const { return size_; }
367 AllocType GetAllocType() const { return alloc_type_; }
368
369 private:
370 u32 size_ : 3;
371 u32 : 29;
372
373 u32 : 8;
374 u32 : 1;
375 AllocType alloc_type_ : 2;
376 u32 : 1;
377 ControlFlowOpcode opcode_ : 4;
378};
379REX_STATIC_ASSERT_SIZE(ControlFlowAllocInstruction, sizeof(u32) * 2);
380
405REX_STATIC_ASSERT_SIZE(ControlFlowInstruction, sizeof(u32) * 2);
406
413inline void UnpackControlFlowInstructions(const u32* dwords, ControlFlowInstruction* out_ab) {
414 u32 dword_0 = dwords[0];
415 u32 dword_1 = dwords[1];
416 u32 dword_2 = dwords[2];
417 out_ab[0].dword_0 = dword_0;
418 out_ab[0].dword_1 = dword_1 & 0xFFFF;
419 out_ab[1].dword_0 = (dword_1 >> 16) | (dword_2 << 16);
420 out_ab[1].dword_1 = dword_2 >> 16;
421}
422
423// NOLINTNEXTLINE(performance-enum-size): Xenos bit field, MSVC packs per type
488
490enum class FetchDestinationSwizzle : u8 {
491 kX = 0,
492 kY = 1,
493 kZ = 2,
494 kW = 3,
495 k0 = 4,
496 k1 = 5,
498 kKeep = 7,
499};
500
508 return static_cast<FetchDestinationSwizzle>((swizzle >> (3 * component)) & 0b111);
509}
510
512struct alignas(u32) VertexFetchInstruction {
513 FetchOpcode GetOpcode() const { return data_.opcode_value; }
514
515 bool IsPredicated() const { return data_.is_predicated; }
517 bool GetPredicateCondition() const { return data_.pred_condition == 1; }
519 u32 GetFetchConstantIndex() const { return data_.const_index * 3 + data_.const_index_sel; }
520
521 u32 GetDest() const { return data_.dst_reg; }
522 u32 GetDestSwizzle() const { return data_.dst_swiz; }
523 bool IsDestRelative() const { return data_.dst_reg_am; }
525 u32 GetSrcReg() const { return data_.src_reg; }
526 u32 GetSrcSwizzle() const { return data_.src_swiz; }
527 bool IsSrcRelative() const { return data_.src_reg_am; }
528
530 u32 GetPrefetchCount() const { return data_.prefetch_count; }
532 bool IsMiniFetch() const { return data_.is_mini_fetch == 1; }
533
534 xenos::VertexFormat GetDataFormat() const { return data_.format; }
536 int GetExpAdjust() const { return data_.exp_adjust; }
537 bool IsSigned() const { return data_.format_comp_all == 1; }
539 bool IsNormalized() const { return data_.num_format_all == 0; }
540 xenos::SignedRepeatingFractionMode GetSignedRFMode() const { return data_.signed_rf_mode_all; }
542 bool IsIndexRounded() const { return data_.is_index_rounded == 1; }
544 u32 GetStride() const { return data_.stride; }
546 i32 GetOffset() const { return data_.offset; }
547
548 private:
549 struct Data {
550 struct {
551 FetchOpcode opcode_value : 5;
552 u32 src_reg : 6;
553 u32 src_reg_am : 1;
554 u32 dst_reg : 6;
555 u32 dst_reg_am : 1;
556 u32 must_be_one : 1;
557 u32 const_index : 5;
558 u32 const_index_sel : 2;
559 u32 prefetch_count : 3;
560 u32 src_swiz : 2;
561 };
562 struct {
563 u32 dst_swiz : 12;
564 u32 format_comp_all : 1;
565 u32 num_format_all : 1;
566 xenos::SignedRepeatingFractionMode signed_rf_mode_all : 1;
567 u32 is_index_rounded : 1;
568 xenos::VertexFormat format : 6;
569 u32 reserved2 : 2;
570 i32 exp_adjust : 6;
571 u32 is_mini_fetch : 1;
572 u32 is_predicated : 1;
573 };
574 struct {
575 u32 stride : 8;
576 i32 offset : 23;
577 u32 pred_condition : 1;
578 };
579 };
580 Data data_;
581};
582REX_STATIC_ASSERT_SIZE(VertexFetchInstruction, sizeof(u32) * 3);
583
585struct alignas(u32) TextureFetchInstruction {
586 FetchOpcode GetOpcode() const { return data_.opcode_value; }
587
588 bool IsPredicated() const { return data_.is_predicated; }
590 bool GetPredicateCondition() const { return data_.pred_condition == 1; }
592 u32 GetFetchConstantIndex() const { return data_.const_index; }
593
594 u32 GetDest() const { return data_.dst_reg; }
595 u32 GetDestSwizzle() const { return data_.dst_swiz; }
596 bool IsDestRelative() const { return data_.dst_reg_am; }
597 u32 GetSrcReg() const { return data_.src_reg; }
598 u32 GetSrcSwizzle() const { return data_.src_swiz; }
599 bool IsSrcRelative() const { return data_.src_reg_am; }
600
601 xenos::FetchOpDimension GetDimension() const { return data_.dimension; }
603 bool IsFetchValidOnly() const { return data_.fetch_valid_only == 1; }
604 bool HasUnnormalizedCoordinates() const { return data_.tx_coord_denorm == 1; }
606 bool HasMagFilter() const { return data_.mag_filter != xenos::TextureFilter::kUseFetchConst; }
607 xenos::TextureFilter GetMagFilter() const { return data_.mag_filter; }
609 bool HasMinFilter() const { return data_.min_filter != xenos::TextureFilter::kUseFetchConst; }
610 xenos::TextureFilter GetMinFilter() const { return data_.min_filter; }
612 bool HasMipFilter() const { return data_.mip_filter != xenos::TextureFilter::kUseFetchConst; }
613 xenos::TextureFilter GetMipFilter() const { return data_.mip_filter; }
615 bool HasAnisoFilter() const { return data_.aniso_filter != xenos::AnisoFilter::kUseFetchConst; }
616 xenos::AnisoFilter GetAnisoFilter() const { return data_.aniso_filter; }
618 bool HasVolMagFilter() const {
619 return data_.vol_mag_filter != xenos::TextureFilter::kUseFetchConst;
620 }
621 xenos::TextureFilter GetVolMagFilter() const { return data_.vol_mag_filter; }
623 bool HasVolMinFilter() const {
624 return data_.vol_min_filter != xenos::TextureFilter::kUseFetchConst;
625 }
626 xenos::TextureFilter GetVolMinFilter() const { return data_.vol_min_filter; }
627 bool IsComputedLODUsed() const { return data_.use_comp_lod == 1; }
628 bool IsRegisterLODUsed() const { return data_.use_reg_lod == 1; }
629 bool HasRegisterGradients() const { return data_.use_reg_gradients == 1; }
630 xenos::SampleLocation GetSampleLocation() const { return data_.sample_location; }
631 f32 GetLODBias() const { return static_cast<f32>(data_.lod_bias) * (1.0f / 16.0f); }
632 f32 GetOffsetX() const { return static_cast<f32>(data_.offset_x) * 0.5f; }
633 f32 GetOffsetY() const { return static_cast<f32>(data_.offset_y) * 0.5f; }
634 f32 GetOffsetZ() const { return static_cast<f32>(data_.offset_z) * 0.5f; }
635
636 private:
637 struct Data {
638 struct {
639 FetchOpcode opcode_value : 5;
640 u32 src_reg : 6;
641 u32 src_reg_am : 1;
642 u32 dst_reg : 6;
643 u32 dst_reg_am : 1;
644 u32 fetch_valid_only : 1;
645 u32 const_index : 5;
646 u32 tx_coord_denorm : 1;
647 u32 src_swiz : 6;
648 };
649 struct {
650 u32 dst_swiz : 12;
651 xenos::TextureFilter mag_filter : 2;
652 xenos::TextureFilter min_filter : 2;
653 xenos::TextureFilter mip_filter : 2;
654 xenos::AnisoFilter aniso_filter : 3;
655 xenos::ArbitraryFilter arbitrary_filter : 3;
656 xenos::TextureFilter vol_mag_filter : 2;
657 xenos::TextureFilter vol_min_filter : 2;
658 u32 use_comp_lod : 1;
659 u32 use_reg_lod : 1;
660 u32 unknown : 1;
661 u32 is_predicated : 1;
662 };
663 struct {
664 u32 use_reg_gradients : 1;
665 xenos::SampleLocation sample_location : 1;
666 i32 lod_bias : 7;
667 u32 unused : 5;
668 xenos::FetchOpDimension dimension : 2;
669 i32 offset_x : 5;
670 i32 offset_y : 5;
671 i32 offset_z : 5;
672 u32 pred_condition : 1;
673 };
674 };
675 Data data_;
676};
677REX_STATIC_ASSERT_SIZE(TextureFetchInstruction, sizeof(u32) * 3);
678
680union alignas(u32) FetchInstruction {
681 public:
682 FetchOpcode GetOpcode() const { return data_.opcode_value; }
683
684 bool IsPredicated() const { return data_.is_predicated; }
686 bool GetPredicateCondition() const { return data_.pred_condition == 1; }
687
688 u32 GetDest() const { return data_.dst_reg; }
689 u32 GetDestSwizzle() const { return data_.dst_swiz; }
690 bool IsDestRelative() const { return data_.dst_reg_am; }
691 u32 GetSrcReg() const { return data_.src_reg; }
692 bool IsSrcRelative() const { return data_.src_reg_am; }
693
695 const VertexFetchInstruction& GetVertexFetch() const { return vertex_fetch_; }
697 const TextureFetchInstruction& GetTextureFetch() const { return texture_fetch_; }
698
699 private:
700 struct Data {
701 struct {
702 FetchOpcode opcode_value : 5;
703 u32 src_reg : 6;
704 u32 src_reg_am : 1;
705 u32 dst_reg : 6;
706 u32 dst_reg_am : 1;
707 u32 : 1;
708 u32 const_index : 5;
709 u32 : 7;
710 };
711 struct {
712 u32 dst_swiz : 12;
713 u32 : 19;
714 u32 is_predicated : 1;
715 };
716 struct {
717 u32 : 31;
718 u32 pred_condition : 1;
719 };
720 };
721 Data data_;
722 VertexFetchInstruction vertex_fetch_;
723 TextureFetchInstruction texture_fetch_;
724};
725REX_STATIC_ASSERT_SIZE(FetchInstruction, sizeof(u32) * 3);
726
732 kAluOpChangedStateNone = 0,
739};
740
759// NOLINTNEXTLINE(performance-enum-size): Xenos bit field, MSVC packs per type
760enum class AluScalarOpcode : u32 {
769 kAdds = 0,
770
780
789 kMuls = 2,
790
800
812
821 kMaxs = 5,
822
831 kMins = 6,
832
841 kSeqs = 7,
842
851 kSgts = 8,
852
861 kSges = 9,
862
871 kSnes = 10,
872
881 kFrcs = 11,
882
892
902
911 kExp = 14,
912
922 kLogc = 15,
923
932 kLog = 16,
933
945 kRcpc = 17,
946
960 kRcpf = 18,
961
970 kRcp = 19,
971
983 kRsqc = 20,
984
996 kRsqf = 21,
997
1006 kRsq = 22,
1007
1019
1031
1040 kSubs = 25,
1041
1051
1067
1083
1099
1115
1135
1151
1162
1178
1193
1208
1223
1238
1253
1262 kSqrt = 40,
1263
1276
1285 kSin = 48,
1286
1295 kCos = 49,
1296
1305};
1306
1316
1319
1322 REX_ASSERT(static_cast<u32>(opcode) < rex::CountOf(kAluScalarOpcodeTraits));
1323 return kAluScalarOpcodeTraits[static_cast<u32>(opcode)];
1324}
1325
1326// NOLINTNEXTLINE(performance-enum-size): Xenos bit field, MSVC packs per type
1327enum class AluVectorOpcode : u32 {
1339 kAdd = 0,
1340
1352 kMul = 1,
1353
1365 kMax = 2,
1366
1378 kMin = 3,
1379
1391 kSeq = 4,
1392
1404 kSgt = 5,
1405
1417 kSge = 6,
1418
1430 kSne = 7,
1431
1443 kFrc = 8,
1444
1457
1470
1482 kMad = 11,
1483
1496
1509
1522
1532 kDp4 = 15,
1533
1542 kDp3 = 16,
1543
1553
1596 kCube = 18,
1597
1614 kMax4 = 19,
1615
1634
1653
1672
1691
1709
1727
1745
1763
1774 kDst = 28,
1775
1789 kMaxA = 29,
1790};
1791
1793 const char* name;
1798
1802 u32 GetOperandCount() const {
1803 if (!operand_components_used[2]) {
1804 if (!operand_components_used[1]) {
1805 if (!operand_components_used[0]) {
1806 return 0;
1807 }
1808 return 1;
1809 }
1810 return 2;
1811 }
1812 return 3;
1813 }
1814};
1815
1817extern const AluVectorOpcodeTraits kAluVectorOpcodeTraits[32];
1818
1821 REX_ASSERT(static_cast<u32>(opcode) < rex::CountOf(kAluVectorOpcodeTraits));
1822 return kAluVectorOpcodeTraits[static_cast<u32>(opcode)];
1823}
1824
1831inline u32 GetAluVectorOpNeededSourceComponents(AluVectorOpcode vector_opcode, u32 src_index,
1832 u32 used_result_components) {
1833 REX_ASSERT(src_index != 0);
1834 REX_ASSERT((used_result_components & ~static_cast<u32>(0b1111)) == 0);
1835 u32 components = used_result_components;
1836 switch (vector_opcode) {
1839 components = used_result_components ? 0b1111 : 0;
1840 break;
1842 components = used_result_components ? 0b0111 : 0;
1843 break;
1845 components = used_result_components ? (src_index == 3 ? 0b0001 : 0b0011) : 0;
1846 break;
1848 components = used_result_components ? 0b1111 : 0;
1849 break;
1854 components = used_result_components ? 0b1001 : 0b1000;
1855 break;
1860 components = 0b1111;
1861 break;
1863 if (src_index == 1) {
1864 components |= 0b1000;
1865 }
1866 break;
1867 default:
1868 break;
1869 }
1870 return components &
1871 GetAluVectorOpcodeTraits(vector_opcode).operand_components_used[src_index - 1];
1872}
1873
1876
1933
1935struct alignas(u32) AluInstruction {
1937 bool IsExport() const { return data_.export_data == 1; }
1938
1939 bool IsPredicated() const { return data_.is_predicated; }
1941 bool GetPredicateCondition() const { return data_.pred_condition == 1; }
1942
1944 bool HasAbsConstants() const { return data_.abs_constants == 1; }
1946 bool IsConst0Addressed() const { return data_.const_0_rel_abs == 1; }
1948 bool IsConst1Addressed() const { return data_.const_1_rel_abs == 1; }
1953 bool IsConstAddressRegisterRelative() const { return data_.const_address_register_relative == 1; }
1954
1955 AluVectorOpcode GetVectorOpcode() const { return data_.vector_opc; }
1957 u32 GetVectorWriteMask() const { return data_.vector_write_mask; }
1958 u32 GetVectorDest() const { return data_.vector_dest; }
1959 bool IsVectorDestRelative() const { return data_.vector_dest_rel == 1; }
1960 bool IsVectorClamped() const { return data_.vector_clamp == 1; }
1961
1962 AluScalarOpcode GetScalarOpcode() const { return data_.scalar_opc; }
1964 u32 GetScalarWriteMask() const { return data_.scalar_write_mask; }
1965 u32 GetScalarDest() const { return data_.scalar_dest; }
1966 bool IsScalarDestRelative() const { return data_.scalar_dest_rel == 1; }
1967 bool IsScalarClamped() const { return data_.scalar_clamp == 1; }
1968
1974 static constexpr u32 GetSrcTempReg(u32 src_reg) { return src_reg & 0x3F; }
1980 static constexpr bool IsSrcTempRelative(u32 src_reg) { return (src_reg & 0x40) != 0; }
1986 static constexpr bool IsSrcTempValueAbsolute(u32 src_reg) { return (src_reg & 0x80) != 0; }
1993 u32 GetSrcReg(size_t i) const {
1994 switch (i) {
1995 case 1:
1996 return data_.src1_reg;
1997 case 2:
1998 return data_.src2_reg;
1999 case 3:
2000 return data_.src3_reg;
2001 default:
2003 return 0;
2004 }
2005 }
2006
2011 bool IsSrcTemp(size_t i) const {
2012 switch (i) {
2013 case 1:
2014 return static_cast<bool>(data_.src1_sel);
2015 case 2:
2016 return static_cast<bool>(data_.src2_sel);
2017 case 3:
2018 return static_cast<bool>(data_.src3_sel);
2019 default:
2021 return 0;
2022 }
2023 }
2024
2034 bool IsSrcConstAddressed(size_t i) const {
2035 switch (i) {
2036 case 1:
2037 return static_cast<bool>(data_.const_0_rel_abs);
2038 case 2:
2039 return static_cast<bool>(IsSrcTemp(1) ? data_.const_0_rel_abs : data_.const_1_rel_abs);
2040 case 3:
2041 return static_cast<bool>((IsSrcTemp(1) && IsSrcTemp(2)) ? data_.const_0_rel_abs
2042 : data_.const_1_rel_abs);
2043 default:
2045 return false;
2046 }
2047 }
2048
2053 u32 GetSrcSwizzle(size_t i) const {
2054 switch (i) {
2055 case 1:
2056 return data_.src1_swiz;
2057 case 2:
2058 return data_.src2_swiz;
2059 case 3:
2060 return data_.src3_swiz;
2061 default:
2063 return 0;
2064 }
2065 }
2066
2071 bool IsSrcNegated(size_t i) const {
2072 switch (i) {
2073 case 1:
2074 return data_.src1_reg_negate == 1;
2075 case 2:
2076 return data_.src2_reg_negate == 1;
2077 case 3:
2078 return data_.src3_reg_negate == 1;
2079 default:
2081 return 0;
2082 }
2083 }
2084
2087 return (static_cast<u32>(data_.scalar_opc) & 1) | (data_.src3_sel << 1) |
2088 (data_.src3_swiz & 0x3C);
2089 }
2090
2092 static constexpr u32 GetSwizzledComponentIndex(u32 swizzle, u32 component_index) {
2093 return ((swizzle >> (2 * component_index)) + component_index) & 3;
2094 }
2095
2101 u32 mask = GetVectorWriteMask();
2102 if (IsExport()) {
2103 mask &= ~GetScalarWriteMask();
2104 }
2105 return mask;
2106 }
2107
2112 u32 mask = GetScalarWriteMask();
2113 if (IsExport()) {
2114 mask &= ~GetVectorWriteMask();
2115 }
2116 return mask;
2117 }
2118
2123 if (!IsExport() || !IsScalarDestRelative()) {
2124 return 0b0000;
2125 }
2126 return 0b1111 & ~(GetVectorWriteMask() | GetScalarWriteMask());
2127 }
2128
2133 if (!IsExport()) {
2134 return 0b0000;
2135 }
2137 }
2138
2139 private:
2140 struct Data {
2141 struct {
2143 u32 vector_dest : 6;
2144 u32 vector_dest_rel : 1;
2145 u32 abs_constants : 1;
2146 u32 scalar_dest : 6;
2147 u32 scalar_dest_rel : 1;
2156 u32 export_data : 1;
2157 u32 vector_write_mask : 4;
2158 u32 scalar_write_mask : 4;
2159 u32 vector_clamp : 1;
2160 u32 scalar_clamp : 1;
2161 AluScalarOpcode scalar_opc : 6;
2162 };
2163 struct {
2164 u32 src3_swiz : 8;
2165 u32 src2_swiz : 8;
2166 u32 src1_swiz : 8;
2167 u32 src3_reg_negate : 1;
2168 u32 src2_reg_negate : 1;
2169 u32 src1_reg_negate : 1;
2170 u32 pred_condition : 1;
2171 u32 is_predicated : 1;
2174 u32 const_1_rel_abs : 1;
2175 u32 const_0_rel_abs : 1;
2176 };
2177 struct {
2178 u32 src3_reg : 8;
2179 u32 src2_reg : 8;
2180 u32 src1_reg : 8;
2181 AluVectorOpcode vector_opc : 5;
2182 u32 src3_sel : 1;
2183 u32 src2_sel : 1;
2184 u32 src1_sel : 1;
2185 };
2186 };
2187 Data data_;
2188};
2189REX_STATIC_ASSERT_SIZE(AluInstruction, sizeof(u32) * 3);
2190
2191} // namespace rex::xenos::ucode
#define REX_UNHANDLED_CASE(var)
Definition assert.h:119
#define REX_ASSERT(cond,...)
Definition assert.h:84
Fetch constant layouts, texture sampling enums and limits.
AnisoFilter
Definition fetch.h:73
@ kUseFetchConst
Definition fetch.h:80
TextureFilter
Definition fetch.h:65
@ kUseFetchConst
Definition fetch.h:69
FetchOpDimension
Definition fetch.h:93
Data, texture, vertex and render target formats and conversions.
Definition ucode.h:54
const AluVectorOpcodeTraits kAluVectorOpcodeTraits[32]
const AluVectorOpcodeTraits & GetAluVectorOpcodeTraits(AluVectorOpcode opcode)
Definition ucode.h:1820
AddressingMode
Definition ucode.h:134
@ kAbsolute
Definition ucode.h:138
@ kRelative
Definition ucode.h:136
const AluScalarOpcodeTraits & GetAluScalarOpcodeTraits(AluScalarOpcode opcode)
Definition ucode.h:1321
constexpr bool HasControlFlowCondExecCleanPredicate(ControlFlowOpcode opcode)
Definition ucode.h:127
ControlFlowOpcode
Definition ucode.h:57
@ kCondCall
Definition ucode.h:89
@ kLoopStart
Definition ucode.h:85
@ kMarkVSFetchDone
Definition ucode.h:103
@ kCondExec
Definition ucode.h:63
@ kCondExecPred
Definition ucode.h:76
@ kCondExecEnd
Definition ucode.h:69
@ kCondExecPredCleanEnd
Definition ucode.h:101
@ kExecEnd
Definition ucode.h:61
@ kCondExecPredClean
Definition ucode.h:99
@ kCondExecPredEnd
Definition ucode.h:83
@ kLoopEnd
Definition ucode.h:87
FetchOpcode
Definition ucode.h:424
@ kGetTextureGradients
Definition ucode.h:466
@ kGetTextureBorderColorFrac
Definition ucode.h:449
@ kGetTextureComputedLOD
Definition ucode.h:459
@ kTextureFetch
Definition ucode.h:442
@ kSetTextureLOD
Definition ucode.h:482
@ kSetTextureGradientsVert
Definition ucode.h:486
@ kGetTextureWeights
Definition ucode.h:479
@ kSetTextureGradientsHorz
Definition ucode.h:484
constexpr bool IsControlFlowOpcodeExec(ControlFlowOpcode opcode)
Definition ucode.h:107
AluScalarOpcode
Definition ucode.h:760
@ kMulsc0
Definition ucode.h:1265
@ kMulsPrev2
Definition ucode.h:811
@ kRsqf
Definition ucode.h:996
@ kTruncs
Definition ucode.h:891
@ kAddsc0
Definition ucode.h:1269
@ kSubsPrev
Definition ucode.h:1050
@ kKillsOne
Definition ucode.h:1252
@ kSetpRstr
Definition ucode.h:1177
@ kMuls
Definition ucode.h:789
@ kCos
Definition ucode.h:1295
@ kSubsc1
Definition ucode.h:1275
@ kSetpNe
Definition ucode.h:1082
@ kFrcs
Definition ucode.h:881
@ kSetpEq
Definition ucode.h:1066
@ kRcpf
Definition ucode.h:960
@ kSeqs
Definition ucode.h:841
@ kSetpGe
Definition ucode.h:1114
@ kSetpClr
Definition ucode.h:1161
@ kRcpc
Definition ucode.h:945
@ kMaxs
Definition ucode.h:821
@ kSges
Definition ucode.h:861
@ kMulsPrev
Definition ucode.h:799
@ kSnes
Definition ucode.h:871
@ kKillsGe
Definition ucode.h:1222
@ kKillsGt
Definition ucode.h:1207
@ kAdds
Definition ucode.h:769
@ kLogc
Definition ucode.h:922
@ kSetpGt
Definition ucode.h:1098
@ kSubsc0
Definition ucode.h:1273
@ kMaxAs
Definition ucode.h:1018
@ kSetpInv
Definition ucode.h:1134
@ kAddsc1
Definition ucode.h:1271
@ kAddsPrev
Definition ucode.h:779
@ kRcp
Definition ucode.h:970
@ kSgts
Definition ucode.h:851
@ kSqrt
Definition ucode.h:1262
@ kSubs
Definition ucode.h:1040
@ kMaxAsf
Definition ucode.h:1030
@ kFloors
Definition ucode.h:901
@ kMulsc1
Definition ucode.h:1267
@ kRsq
Definition ucode.h:1006
@ kKillsNe
Definition ucode.h:1237
@ kKillsEq
Definition ucode.h:1192
@ kExp
Definition ucode.h:911
@ kSetpPop
Definition ucode.h:1150
@ kMins
Definition ucode.h:831
@ kRsqc
Definition ucode.h:983
@ kLog
Definition ucode.h:932
@ kSin
Definition ucode.h:1285
@ kRetainPrev
Definition ucode.h:1304
constexpr FetchDestinationSwizzle GetFetchDestinationComponentSwizzle(u32 swizzle, u32 component)
Definition ucode.h:507
AluVectorOpcode
Definition ucode.h:1327
@ kDp3
Definition ucode.h:1542
@ kSetpGtPush
Definition ucode.h:1671
@ kKillEq
Definition ucode.h:1708
@ kSetpEqPush
Definition ucode.h:1633
@ kFloor
Definition ucode.h:1469
@ kFrc
Definition ucode.h:1443
@ kKillGt
Definition ucode.h:1726
@ kDst
Definition ucode.h:1774
@ kSeq
Definition ucode.h:1391
@ kMad
Definition ucode.h:1482
@ kSgt
Definition ucode.h:1404
@ kCndGe
Definition ucode.h:1508
@ kMul
Definition ucode.h:1352
@ kSne
Definition ucode.h:1430
@ kSge
Definition ucode.h:1417
@ kCndEq
Definition ucode.h:1495
@ kMax4
Definition ucode.h:1614
@ kKillNe
Definition ucode.h:1762
@ kTrunc
Definition ucode.h:1456
@ kMaxA
Definition ucode.h:1789
@ kKillGe
Definition ucode.h:1744
@ kDp4
Definition ucode.h:1532
@ kDp2Add
Definition ucode.h:1552
@ kSetpNePush
Definition ucode.h:1652
@ kCndGt
Definition ucode.h:1521
@ kSetpGePush
Definition ucode.h:1690
@ kCube
Definition ucode.h:1596
ExportRegister
Definition ucode.h:1878
@ kPSColor1
Definition ucode.h:1915
@ kVSInterpolator9
Definition ucode.h:1890
@ kVSInterpolator0
Definition ucode.h:1881
@ kVSInterpolator6
Definition ucode.h:1887
@ kVSInterpolator13
Definition ucode.h:1894
@ kVSInterpolator2
Definition ucode.h:1883
@ kVSInterpolator3
Definition ucode.h:1884
@ kVSPosition
Definition ucode.h:1900
@ kPSColor2
Definition ucode.h:1916
@ kVSInterpolator5
Definition ucode.h:1886
@ kVSInterpolator14
Definition ucode.h:1895
@ kVSInterpolator8
Definition ucode.h:1889
@ kPSColor0
Definition ucode.h:1914
@ kPSDepth
Definition ucode.h:1921
@ kVSInterpolator10
Definition ucode.h:1891
@ kVSInterpolator11
Definition ucode.h:1892
@ kVSInterpolator1
Definition ucode.h:1882
@ kVSPointSizeEdgeFlagKillVertex
Definition ucode.h:1910
@ kVSInterpolator4
Definition ucode.h:1885
@ kPSColor3
Definition ucode.h:1917
@ kVSInterpolator7
Definition ucode.h:1888
@ kVSInterpolator12
Definition ucode.h:1893
@ kVSInterpolator15
Definition ucode.h:1896
u32 GetAluVectorOpNeededSourceComponents(AluVectorOpcode vector_opcode, u32 src_index, u32 used_result_components)
Definition ucode.h:1831
FetchDestinationSwizzle
Definition ucode.h:490
void UnpackControlFlowInstructions(const u32 *dwords, ControlFlowInstruction *out_ab)
Definition ucode.h:413
constexpr u32 kMaxMemExportElementCount
Definition ucode.h:1875
AluOpChangedState
Definition ucode.h:731
@ kAluOpChangedStatePixelKill
Definition ucode.h:738
@ kAluOpChangedStateAddressRegister
Definition ucode.h:734
@ kAluOpChangedStatePredicate
Definition ucode.h:736
AllocType
Definition ucode.h:142
const AluScalarOpcodeTraits kAluScalarOpcodeTraits[64]
constexpr bool IsControlFlowOpcodeEnd(ControlFlowOpcode opcode)
Definition ucode.h:117
@ kAdd
Definition input_keys.h:155
Platform flags, packing macros and export markers.
Xenos pipeline state, shader and EDRAM enums.
ArbitraryFilter
Definition state.h:209
SignedRepeatingFractionMode
Definition state.h:202
Definition ucode.h:1935
u32 GetScalarConstRegOpSrcTempReg() const
Definition ucode.h:2086
static constexpr bool IsSrcTempValueAbsolute(u32 src_reg)
Definition ucode.h:1986
bool IsConst1Addressed() const
Definition ucode.h:1948
u32 GetScalarOpResultWriteMask() const
Definition ucode.h:2111
bool IsConstAddressRegisterRelative() const
Definition ucode.h:1953
u32 GetSrcSwizzle(size_t i) const
Definition ucode.h:2053
u32 GetConstant0WriteMask() const
Definition ucode.h:2122
static constexpr bool IsSrcTempRelative(u32 src_reg)
Definition ucode.h:1980
static constexpr u32 GetSwizzledComponentIndex(u32 swizzle, u32 component_index)
Definition ucode.h:2092
bool IsSrcTemp(size_t i) const
Definition ucode.h:2011
bool IsSrcNegated(size_t i) const
Definition ucode.h:2071
bool IsSrcConstAddressed(size_t i) const
Definition ucode.h:2034
bool HasAbsConstants() const
Definition ucode.h:1944
u32 GetSrcReg(size_t i) const
Definition ucode.h:1993
static constexpr u32 GetSrcTempReg(u32 src_reg)
Definition ucode.h:1974
bool IsExport() const
Definition ucode.h:1937
bool IsConst0Addressed() const
Definition ucode.h:1946
u32 GetConstant1WriteMask() const
Definition ucode.h:2132
u32 GetVectorOpResultWriteMask() const
Definition ucode.h:2100
u32 GetScalarWriteMask() const
Definition ucode.h:1964
bool GetPredicateCondition() const
Definition ucode.h:1941
u32 GetVectorWriteMask() const
Definition ucode.h:1957
AluOpChangedState changed_state
Definition ucode.h:1314
u32 operand_count
Definition ucode.h:1310
const char * name
Definition ucode.h:1308
bool single_operand_is_two_component
Definition ucode.h:1312
const char * name
Definition ucode.h:1793
u32 operand_components_used[3]
Definition ucode.h:1795
u32 GetOperandCount() const
Definition ucode.h:1802
AluOpChangedState changed_state
Definition ucode.h:1797
bool GetCondition() const
Definition ucode.h:306
bool IsPredicated() const
Definition ucode.h:303
bool GetCondition() const
Definition ucode.h:197
u32 GetSequence() const
Definition ucode.h:194
bool GetCondition() const
Definition ucode.h:226
bool IsPredicateClean() const
Definition ucode.h:224
u32 GetSequence() const
Definition ucode.h:222
bool GetCondition() const
Definition ucode.h:346
bool IsPredicated() const
Definition ucode.h:343
u32 GetSequence() const
Definition ucode.h:158
bool IsPredicateClean() const
Definition ucode.h:165
u32 GetAddress() const
Definition ucode.h:274
bool GetCondition() const
Definition ucode.h:280
u32 GetLoopID() const
Definition ucode.h:276
bool IsPredicatedBreak() const
Definition ucode.h:278
u32 GetAddress() const
Definition ucode.h:250
u32 GetLoopID() const
Definition ucode.h:254
bool IsRepeat() const
Definition ucode.h:252
u32 GetFetchConstantIndex() const
Definition ucode.h:592
bool HasMipFilter() const
Definition ucode.h:612
bool HasAnisoFilter() const
Definition ucode.h:615
bool HasMagFilter() const
Definition ucode.h:606
bool HasVolMinFilter() const
Definition ucode.h:623
bool GetPredicateCondition() const
Definition ucode.h:590
bool HasVolMagFilter() const
Definition ucode.h:618
bool HasMinFilter() const
Definition ucode.h:609
bool IsFetchValidOnly() const
Definition ucode.h:603
u32 GetFetchConstantIndex() const
Definition ucode.h:519
bool IsMiniFetch() const
Definition ucode.h:532
int GetExpAdjust() const
Definition ucode.h:536
u32 GetSrcReg() const
Definition ucode.h:525
u32 GetPrefetchCount() const
Definition ucode.h:530
bool IsIndexRounded() const
Definition ucode.h:542
u32 GetStride() const
Definition ucode.h:544
bool GetPredicateCondition() const
Definition ucode.h:517
bool IsNormalized() const
Definition ucode.h:539
i32 GetOffset() const
Definition ucode.h:546
Integer types, byte order wrappers and size literals.
ControlFlowLoopEndInstruction loop_end
Definition ucode.h:389
ControlFlowLoopStartInstruction loop_start
Definition ucode.h:388
ControlFlowCondExecInstruction cond_exec
Definition ucode.h:386
ControlFlowExecInstruction exec
Definition ucode.h:385
ControlFlowReturnInstruction ret
Definition ucode.h:391
ControlFlowCondCallInstruction cond_call
Definition ucode.h:390
ControlFlowCondJmpInstruction cond_jmp
Definition ucode.h:392
ControlFlowAllocInstruction alloc
Definition ucode.h:393
ControlFlowCondExecPredInstruction cond_exec_pred
Definition ucode.h:387
bool GetPredicateCondition() const
Definition ucode.h:686
const TextureFetchInstruction & GetTextureFetch() const
Definition ucode.h:697
const VertexFetchInstruction & GetVertexFetch() const
Definition ucode.h:695