1 #pragma once
2 
3 #include <map>
4 #include "Types.h"
5 
6 class CVuAssembler
7 {
8 public:
9 	enum VF_REGISTER
10 	{
11 		VF0,
12 		VF1,
13 		VF2,
14 		VF3,
15 		VF4,
16 		VF5,
17 		VF6,
18 		VF7,
19 		VF8,
20 		VF9,
21 		VF10,
22 		VF11,
23 		VF12,
24 		VF13,
25 		VF14,
26 		VF15,
27 		VF16,
28 		VF17,
29 		VF18,
30 		VF19,
31 		VF20,
32 		VF21,
33 		VF22,
34 		VF23,
35 		VF24,
36 		VF25,
37 		VF26,
38 		VF27,
39 		VF28,
40 		VF29,
41 		VF30,
42 		VF31
43 	};
44 
45 	enum VI_REGISTER
46 	{
47 		VI0,
48 		VI1,
49 		VI2,
50 		VI3,
51 		VI4,
52 		VI5,
53 		VI6,
54 		VI7,
55 		VI8,
56 		VI9,
57 		VI10,
58 		VI11,
59 		VI12,
60 		VI13,
61 		VI14,
62 		VI15,
63 	};
64 
65 	enum DEST
66 	{
67 		DEST_NONE,
68 		DEST_W,
69 		DEST_Z,
70 		DEST_ZW,
71 		DEST_Y,
72 		DEST_YW,
73 		DEST_YZ,
74 		DEST_YZW,
75 		DEST_X,
76 		DEST_XW,
77 		DEST_XZ,
78 		DEST_XZW,
79 		DEST_XY,
80 		DEST_XYW,
81 		DEST_XYZ,
82 		DEST_XYZW,
83 	};
84 
85 	enum BROADCAST
86 	{
87 		BC_X,
88 		BC_Y,
89 		BC_Z,
90 		BC_W,
91 	};
92 
93 	enum FVF
94 	{
95 		FVF_X,
96 		FVF_Y,
97 		FVF_Z,
98 		FVF_W
99 	};
100 
101 	enum
102 	{
103 		INSTRUCTION_SIZE = 8,
104 	};
105 
106 	CVuAssembler(uint32*);
107 	virtual ~CVuAssembler();
108 
109 	typedef uint32 LABEL;
110 
111 	struct BRANCHOP
112 	{
113 		uint32 op = 0;
114 		LABEL label = 0;
115 	};
116 
117 	unsigned int GetProgramSize() const;
118 	LABEL CreateLabel();
119 	void MarkLabel(LABEL);
120 
121 	void Write(uint32, uint32);
122 	void Write(uint32, BRANCHOP);
123 
124 	class Upper
125 	{
126 	public:
127 		enum
128 		{
129 			I_BIT = 0x80000000,
130 			E_BIT = 0x40000000,
131 		};
132 
133 		static uint32 ADDbc(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER, BROADCAST);
134 		static uint32 ADDi(DEST, VF_REGISTER, VF_REGISTER);
135 		static uint32 CLIP(VF_REGISTER, VF_REGISTER);
136 		static uint32 FTOI4(DEST, VF_REGISTER, VF_REGISTER);
137 		static uint32 ITOF0(DEST, VF_REGISTER, VF_REGISTER);
138 		static uint32 ITOF12(DEST, VF_REGISTER, VF_REGISTER);
139 		static uint32 MADDbc(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER, BROADCAST);
140 		static uint32 MADDAbc(DEST, VF_REGISTER, VF_REGISTER, BROADCAST);
141 		static uint32 MULi(DEST, VF_REGISTER, VF_REGISTER);
142 		static uint32 MULq(DEST, VF_REGISTER, VF_REGISTER);
143 		static uint32 MULAbc(DEST, VF_REGISTER, VF_REGISTER, BROADCAST);
144 		static uint32 MAX(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER);
145 		static uint32 MINI(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER);
146 		static uint32 NOP();
147 		static uint32 OPMULA(VF_REGISTER, VF_REGISTER);
148 		static uint32 OPMSUB(VF_REGISTER, VF_REGISTER, VF_REGISTER);
149 		static uint32 SUB(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER);
150 		static uint32 SUBbc(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER, BROADCAST);
151 	};
152 
153 	class Lower
154 	{
155 	public:
156 		static BRANCHOP B(LABEL);
157 		static uint32 DIV(VF_REGISTER, FVF, VF_REGISTER, FVF);
158 		static uint32 FCAND(uint32);
159 		static uint32 FCGET(VI_REGISTER);
160 		static uint32 FMAND(VI_REGISTER, VI_REGISTER);
161 		static uint32 FSAND(VI_REGISTER, uint16);
162 		static uint32 IADDIU(VI_REGISTER, VI_REGISTER, uint16);
163 		static BRANCHOP IBEQ(VI_REGISTER, VI_REGISTER, LABEL);
164 		static uint32 LQ(DEST, VF_REGISTER, uint16, VI_REGISTER);
165 		static uint32 MFIR(DEST, VF_REGISTER, VI_REGISTER);
166 		static uint32 MTIR(VI_REGISTER, VF_REGISTER, FVF);
167 		static uint32 NOP();
168 		static uint32 SQ(DEST, VF_REGISTER, uint16, VI_REGISTER);
169 		static uint32 WAITQ();
170 	};
171 
172 private:
173 	void ResolveLabelReferences();
174 	void CreateLabelReference(LABEL);
175 
176 	struct LABELREF
177 	{
178 		size_t address;
179 	};
180 
181 	typedef std::map<LABEL, size_t> LabelMapType;
182 	typedef std::multimap<LABEL, LABELREF> LabelReferenceMapType;
183 
184 	uint32* m_ptr = nullptr;
185 	uint32* m_startPtr = nullptr;
186 	LabelMapType m_labels;
187 	LabelReferenceMapType m_labelReferences;
188 	uint32 m_nextLabelId = 1;
189 };
190