47
47
refmask &= RC_MASK_XYZW;
49
for(unsigned int chan = 0; chan < 4; ++chan) {
50
if (GET_BIT(refmask, chan)) {
51
cb(userdata, fullinst, inst->SrcReg[src].File, inst->SrcReg[src].Index, chan);
50
cb(userdata, fullinst, inst->SrcReg[src].File, inst->SrcReg[src].Index, refmask);
55
52
if (refmask && inst->SrcReg[src].RelAddr)
56
53
cb(userdata, fullinst, RC_FILE_ADDRESS, 0, RC_MASK_X);
60
static void reads_pair(struct rc_instruction * fullinst, rc_read_write_fn cb, void * userdata)
57
static void reads_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata)
62
59
struct rc_pair_instruction * inst = &fullinst->U.P;
63
60
unsigned int refmasks[3] = { 0, 0, 0 };
86
83
for(unsigned int src = 0; src < 3; ++src) {
87
if (inst->RGB.Src[src].Used) {
88
for(unsigned int chan = 0; chan < 3; ++chan) {
89
if (GET_BIT(refmasks[src], chan))
90
cb(userdata, fullinst, inst->RGB.Src[src].File, inst->RGB.Src[src].Index, chan);
84
if (inst->RGB.Src[src].Used && (refmasks[src] & RC_MASK_XYZ))
85
cb(userdata, fullinst, inst->RGB.Src[src].File, inst->RGB.Src[src].Index,
86
refmasks[src] & RC_MASK_XYZ);
94
if (inst->Alpha.Src[src].Used) {
95
if (GET_BIT(refmasks[src], 3))
96
cb(userdata, fullinst, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, 3);
88
if (inst->Alpha.Src[src].Used && (refmasks[src] & RC_MASK_W))
89
cb(userdata, fullinst, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, RC_MASK_W);
102
* Calls a callback function for all sourced register channels.
94
* Calls a callback function for all register reads.
104
* This is conservative, i.e. channels may be called multiple times,
105
* and the writemask of the instruction is not taken into account.
96
* This is conservative, i.e. if the same register is referenced multiple times,
97
* the callback may also be called multiple times.
98
* Also, the writemask of the instruction is not taken into account.
107
void rc_for_all_reads(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata)
100
void rc_for_all_reads_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata)
109
102
if (inst->Type == RC_INSTRUCTION_NORMAL) {
110
103
reads_normal(inst, cb, userdata);
118
static void writes_normal(struct rc_instruction * fullinst, rc_read_write_fn cb, void * userdata)
111
static void writes_normal(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata)
120
113
struct rc_sub_instruction * inst = &fullinst->U.I;
121
114
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
123
if (opcode->HasDstReg) {
124
for(unsigned int chan = 0; chan < 4; ++chan) {
125
if (GET_BIT(inst->DstReg.WriteMask, chan))
126
cb(userdata, fullinst, inst->DstReg.File, inst->DstReg.Index, chan);
116
if (opcode->HasDstReg && inst->DstReg.WriteMask)
117
cb(userdata, fullinst, inst->DstReg.File, inst->DstReg.Index, inst->DstReg.WriteMask);
130
119
if (inst->WriteALUResult)
131
cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, 0);
120
cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X);
134
static void writes_pair(struct rc_instruction * fullinst, rc_read_write_fn cb, void * userdata)
123
static void writes_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata)
136
125
struct rc_pair_instruction * inst = &fullinst->U.P;
138
for(unsigned int chan = 0; chan < 3; ++chan) {
139
if (GET_BIT(inst->RGB.WriteMask, chan))
140
cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->RGB.DestIndex, chan);
127
if (inst->RGB.WriteMask)
128
cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->RGB.DestIndex, inst->RGB.WriteMask);
143
130
if (inst->Alpha.WriteMask)
144
cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->Alpha.DestIndex, 3);
131
cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->Alpha.DestIndex, RC_MASK_W);
146
133
if (inst->WriteALUResult)
147
cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, 0);
134
cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X);
151
* Calls a callback function for all written register channels.
138
* Calls a callback function for all register writes in the instruction,
139
* reporting writemasks to the callback function.
153
141
* \warning Does not report output registers for paired instructions!
155
void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata)
143
void rc_for_all_writes_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata)
157
145
if (inst->Type == RC_INSTRUCTION_NORMAL) {
158
146
writes_normal(inst, cb, userdata);
160
148
writes_pair(inst, cb, userdata);
153
struct mask_to_chan_data {
155
rc_read_write_chan_fn Fn;
158
static void mask_to_chan_cb(void * data, struct rc_instruction * inst,
159
rc_register_file file, unsigned int index, unsigned int mask)
161
struct mask_to_chan_data * d = data;
162
for(unsigned int chan = 0; chan < 4; ++chan) {
163
if (GET_BIT(mask, chan))
164
d->Fn(d->UserData, inst, file, index, chan);
169
* Calls a callback function for all sourced register channels.
171
* This is conservative, i.e. channels may be called multiple times,
172
* and the writemask of the instruction is not taken into account.
174
void rc_for_all_reads_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata)
176
struct mask_to_chan_data d;
177
d.UserData = userdata;
179
rc_for_all_reads_mask(inst, &mask_to_chan_cb, &d);
183
* Calls a callback function for all written register channels.
185
* \warning Does not report output registers for paired instructions!
187
void rc_for_all_writes_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata)
189
struct mask_to_chan_data d;
190
d.UserData = userdata;
192
rc_for_all_writes_mask(inst, &mask_to_chan_cb, &d);
195
static void remap_normal_instruction(struct rc_instruction * fullinst,
196
rc_remap_register_fn cb, void * userdata)
198
struct rc_sub_instruction * inst = &fullinst->U.I;
199
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
201
if (opcode->HasDstReg) {
202
rc_register_file file = inst->DstReg.File;
203
unsigned int index = inst->DstReg.Index;
205
cb(userdata, fullinst, &file, &index);
207
inst->DstReg.File = file;
208
inst->DstReg.Index = index;
211
for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
212
rc_register_file file = inst->SrcReg[src].File;
213
unsigned int index = inst->SrcReg[src].Index;
215
cb(userdata, fullinst, &file, &index);
217
inst->SrcReg[src].File = file;
218
inst->SrcReg[src].Index = index;
222
static void remap_pair_instruction(struct rc_instruction * fullinst,
223
rc_remap_register_fn cb, void * userdata)
225
struct rc_pair_instruction * inst = &fullinst->U.P;
227
if (inst->RGB.WriteMask) {
228
rc_register_file file = RC_FILE_TEMPORARY;
229
unsigned int index = inst->RGB.DestIndex;
231
cb(userdata, fullinst, &file, &index);
233
inst->RGB.DestIndex = index;
236
if (inst->Alpha.WriteMask) {
237
rc_register_file file = RC_FILE_TEMPORARY;
238
unsigned int index = inst->Alpha.DestIndex;
240
cb(userdata, fullinst, &file, &index);
242
inst->Alpha.DestIndex = index;
245
for(unsigned int src = 0; src < 3; ++src) {
246
if (inst->RGB.Src[src].Used) {
247
rc_register_file file = inst->RGB.Src[src].File;
248
unsigned int index = inst->RGB.Src[src].Index;
250
cb(userdata, fullinst, &file, &index);
252
inst->RGB.Src[src].File = file;
253
inst->RGB.Src[src].Index = index;
256
if (inst->Alpha.Src[src].Used) {
257
rc_register_file file = inst->Alpha.Src[src].File;
258
unsigned int index = inst->Alpha.Src[src].Index;
260
cb(userdata, fullinst, &file, &index);
262
inst->Alpha.Src[src].File = file;
263
inst->Alpha.Src[src].Index = index;
270
* Remap all register accesses according to the given function.
271
* That is, call the function \p cb for each referenced register (both read and written)
272
* and update the given instruction \p inst accordingly
273
* if it modifies its \ref pfile and \ref pindex contents.
275
void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata)
277
if (inst->Type == RC_INSTRUCTION_NORMAL)
278
remap_normal_instruction(inst, cb, userdata);
280
remap_pair_instruction(inst, cb, userdata);