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