#include "radeon_program.h"
-#include "shader/prog_print.h"
+#include <stdio.h>
+
+#include "radeon_compiler.h"
/**
* one instruction at a time.
*/
void radeonLocalTransform(
- struct gl_program *program,
+ struct radeon_compiler * c,
int num_transformations,
struct radeon_program_transformation* transformations)
{
- struct radeon_transform_context ctx;
- int ip;
-
- ctx.Program = program;
- ctx.OldInstructions = program->Instructions;
- ctx.OldNumInstructions = program->NumInstructions;
-
- program->Instructions = 0;
- program->NumInstructions = 0;
+ struct rc_instruction * inst = c->Program.Instructions.Next;
- for(ip = 0; ip < ctx.OldNumInstructions; ++ip) {
- struct prog_instruction *instr = ctx.OldInstructions + ip;
+ while(inst != &c->Program.Instructions) {
+ struct rc_instruction * current = inst;
int i;
+ inst = inst->Next;
+
for(i = 0; i < num_transformations; ++i) {
struct radeon_program_transformation* t = transformations + i;
- if (t->function(&ctx, instr, t->userData))
+ if (t->function(c, current, t->userData))
break;
}
-
- if (i >= num_transformations) {
- struct prog_instruction* dest = radeonAppendInstructions(program, 1);
- _mesa_copy_instructions(dest, instr, 1);
- }
}
-
- _mesa_free_instructions(ctx.OldInstructions, ctx.OldNumInstructions);
}
-
-static void scan_instructions(GLboolean* used, const struct prog_instruction* insts, GLuint count)
+/**
+ * Left multiplication of a register with a swizzle
+ */
+struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg)
{
- GLuint i;
- for (i = 0; i < count; i++) {
- const struct prog_instruction *inst = insts + i;
- const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
- GLuint k;
-
- for (k = 0; k < n; k++) {
- if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
- used[inst->SrcReg[k].Index] = GL_TRUE;
+ struct rc_src_register tmp = srcreg;
+ int i;
+ tmp.Swizzle = 0;
+ tmp.Negate = 0;
+ for(i = 0; i < 4; ++i) {
+ rc_swizzle swz = GET_SWZ(swizzle, i);
+ if (swz < 4) {
+ tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3);
+ tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i;
+ } else {
+ tmp.Swizzle |= swz << (i*3);
}
}
+ return tmp;
}
-GLint radeonFindFreeTemporary(struct radeon_transform_context *t)
+unsigned int rc_find_free_temporary(struct radeon_compiler * c)
{
- GLboolean used[MAX_PROGRAM_TEMPS];
- GLuint i;
+ char used[RC_REGISTER_MAX_INDEX];
+ unsigned int i;
+
+ memset(used, 0, sizeof(used));
- _mesa_memset(used, 0, sizeof(used));
- scan_instructions(used, t->Program->Instructions, t->Program->NumInstructions);
- scan_instructions(used, t->OldInstructions, t->OldNumInstructions);
+ for (struct rc_instruction * rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
+ const struct rc_sub_instruction *inst = &rcinst->I;
+ const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->Opcode);
+ unsigned int k;
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+ for (k = 0; k < opcode->NumSrcRegs; k++) {
+ if (inst->SrcReg[k].File == RC_FILE_TEMPORARY)
+ used[inst->SrcReg[k].Index] = 1;
+ }
+
+ if (opcode->HasDstReg) {
+ if (inst->DstReg.File == RC_FILE_TEMPORARY)
+ used[inst->DstReg.Index] = 1;
+ }
+ }
+
+ for (i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
if (!used[i])
return i;
}
- return -1;
+ rc_error(c, "Ran out of temporary registers\n");
+ return 0;
+}
+
+
+struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c)
+{
+ struct rc_instruction * inst = memory_pool_malloc(&c->Pool, sizeof(struct rc_instruction));
+
+ memset(inst, 0, sizeof(struct rc_instruction));
+
+ inst->I.Opcode = RC_OPCODE_ILLEGAL_OPCODE;
+ inst->I.DstReg.WriteMask = RC_MASK_XYZW;
+ inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
+ inst->I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZW;
+ inst->I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZW;
+
+ return inst;
+}
+
+
+struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after)
+{
+ struct rc_instruction * inst = rc_alloc_instruction(c);
+
+ inst->Prev = after;
+ inst->Next = after->Next;
+
+ inst->Prev->Next = inst;
+ inst->Next->Prev = inst;
+
+ return inst;
}
+void rc_remove_instruction(struct rc_instruction * inst)
+{
+ inst->Prev->Next = inst->Next;
+ inst->Next->Prev = inst->Prev;
+}
/**
- * Append the given number of instructions to the program and return a
- * pointer to the first new instruction.
+ * Return the number of instructions in the program.
*/
-struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count)
+unsigned int rc_recompute_ips(struct radeon_compiler * c)
{
- int oldnum = program->NumInstructions;
- _mesa_insert_instructions(program, oldnum, count);
- return program->Instructions + oldnum;
+ unsigned int ip = 0;
+
+ for(struct rc_instruction * inst = c->Program.Instructions.Next;
+ inst != &c->Program.Instructions;
+ inst = inst->Next) {
+ inst->IP = ip++;
+ }
+
+ c->Program.Instructions.IP = 0xcafedead;
+
+ return ip;
}