I hacked at the simulator some more. I'm postponing decisions about
which instructions to keep and not and just setting up a skeleton. I
wonder if our SVN is online again. Anyone know?
// A "decoded" instruction
struct Instruction {
unsigned char opcode;
unsigned char rs, rd, rt;
int immed;
opfunc func;
};
// A shader engine vertical pipeline, functional model
class Pipeline {
public:
Instruction *program;
int PC;
int regfile[256];
Pipeline();
~Pipeline();
void advanceClock(); // Execute another instruction
};
// Operations / opcodes
enum {
ADD, SUB, MULU, MULS, AND, OR, XOR, CMP,
SHL, ASR, LSR, NEG, NOT,
FADD, FSUB, FMUL, FNEG, FCMP,
RDREQ, RDGETI, RDGETP, WRREQ, WRPUTI, WRPUTP,
JSR, JMP, JZERO, JNZERO, JNEG, JNNEG, JPOS, JNPOS};
#define TO_FLOAT(x) ( *(float *)&(x) )
#define TO_INT(x) ( *(int *)&(x) )
void func_add(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] + pipe->regfile[ins->rt];
}
void func_sub(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] - pipe->regfile[ins->rt];
// Like MIPS, use sub to do int cmp
}
void func_muls(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] * pipe->regfile[ins->rt];
}
void func_mulu(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = (unsigned int)pipe->regfile[ins->rs] *
(unsigned int)pipe->regfile[ins->rt];
}
void func_and(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] & pipe->regfile[ins->rt];
}
void func_or(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] | pipe->regfile[ins->rt];
}
void func_xor(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] ^ pipe->regfile[ins->rt];
}
void func_shl(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] << pipe->regfile[ins->rt];
}
void func_asr(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->regfile[ins->rs] >> pipe->regfile[ins->rt];
}
void func_lsr(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = (unsigned)pipe->regfile[ins->rs] >>
pipe->regfile[ins->rt];
}
void func_neg(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = -pipe->regfile[ins->rs];
}
void func_not(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = ~pipe->regfile[ins->rs];
}
void func_fadd(Instruction *ins, Pipeline *pipe) {
float a, b, c;
a = TO_FLOAT(pipe->regfile[ins->rs]);
b = TO_FLOAT(pipe->regfile[ins->rd]);
c = a + b;
pipe->regfile[ins->rt] = TO_INT(c);
}
void func_fsub(Instruction *ins, Pipeline *pipe) {
float a, b, c;
a = TO_FLOAT(pipe->regfile[ins->rs]);
b = TO_FLOAT(pipe->regfile[ins->rd]);
c = a - b;
pipe->regfile[ins->rt] = TO_INT(c);
}
void func_fmul(Instruction *ins, Pipeline *pipe) {
float a, b, c;
a = TO_FLOAT(pipe->regfile[ins->rs]);
b = TO_FLOAT(pipe->regfile[ins->rd]);
c = a * b;
pipe->regfile[ins->rt] = TO_INT(c);
}
void func_fneg(Instruction *ins, Pipeline *pipe) {
float a, c;
a = TO_FLOAT(pipe->regfile[ins->rs]);
c = -a;
pipe->regfile[ins->rt] = TO_INT(c);
}
void func_fcmp(Instruction *ins, Pipeline *pipe) {
float a, b, c;
int d;
a = TO_FLOAT(pipe->regfile[ins->rs]);
b = TO_FLOAT(pipe->regfile[ins->rd]);
c = a - b;
if (c < 0) {
d = -1;
} else if (c > 0) {
d = 1;
} else {
d = 0;
}
pipe->regfile[ins->rt] = d;
}
void func_rdreq(Instruction *ins, Pipeline *pipe) {
int addr = pipe->regfile[ins->rs];
int num = pipe->regfile[ins->rd];
// Request to read num 32-bit words starting at addr
}
void func_rdgeti(Instruction *ins, Pipeline *pipe) {
// Get one 32-bit word from memory read pipe and
// put it in rt
}
void func_rdgetp(Instruction *ins, Pipeline *pipe) {
// Grab next 8 bits from pipe, convert to float, and
// put it in rt
}
void func_wrreq(Instruction *ins, Pipeline *pipe) {
int addr = pipe->regfile[ins->rs];
int num = pipe->regfile[ins->rd];
// Indicate that num 32-bit words will be written starting at addr
}
void func_wrputi(Instruction *ins, Pipeline *pipe) {
int data = pipe->regfile[ins->rs];
// Put one 32-bit word of data into write pipe
}
void func_wrputp(Instruction *ins, Pipeline *pipe) {
int data = pipe->regfile[ins->rs];
// Convert data from float to 8-bit and put into write pipe
}
void func_jsr(Instruction *ins, Pipeline *pipe) {
pipe->regfile[ins->rt] = pipe->PC;
pipe->PC = ins->immed;
// Maybe support jumps to addr in reg?
}
void func_jmp(Instruction *ins, Pipeline *pipe) {
pipe->PC = ins->immed;
}
typedef void (*opfunc)(Instruction *ins, Pipeline *pipe);
opfunc funcs[] = {
func_add, func_sub, func_mulu, func_muls, func_and, func_or, func_xor,
func_cmp, func_shl, func_asr, func_lsr, func_neg, func_not,
func_fadd, func->fsub, func_fmul, func_fneg, func_fcmp,
func_rdreq, func_rdgeti, func_rdgetp,
func_wrreq, func_wrputi, func_wrputp,
func_jsr, func_jmp};
void Pipeline::advanceClock()
{
Instruction *i = program[PC];
PC++;
i->func(i, this);
}
--
Timothy Normand Miller
http://www.cse.ohio-state.edu/~millerti
Open Graphics Project
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)