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)

Reply via email to