Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#define Extern extern
#include "mips.h"

void    Snor(ulong);
void    Ssll(ulong);
void    Ssra(ulong);
void    Sslt(ulong);
void    Ssltu(ulong);
void    Sand(ulong);
void    Saddu(ulong);
void    Sadd(ulong);
void    Sjr(ulong);
void    Sor(ulong);
void    Ssubu(ulong);
void    Sjalr(ulong);
void    Sdivu(ulong);
void    Smfhi(ulong);
void    Smflo(ulong);
void    Sxor(ulong);
void    Smult(ulong);
void    Smultu(ulong);
void    Sdiv(ulong);
void    Ssrl(ulong);
void    Ssllv(ulong);
void    Ssrlv(ulong);
void    Ssrav(ulong);

Inst ispec[] = 
{
        { Ssll,         "sll",  Iarith },
        { undef,                "" },
        { Ssrl,         "srl",  Iarith },
        { Ssra,         "sra",  Iarith },
        { Ssllv,        "sllv", Iarith },
        { undef,        "" },
        { Ssrlv,        "srlv", Iarith },
        { Ssrav,        "srav", Iarith },
        { Sjr,          "jr",   Ibranch },
        { Sjalr,        "jalr", Ibranch },
        { undef,        "" },
        { undef,        "" },
        { Ssyscall,     "sysc", Isyscall },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { Smfhi,        "mfhi", Ireg },
        { undef,        "" },
        { Smflo,        "mflo", Ireg },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { Smult,        "mult", Iarith },
        { Smultu,       "multu" },
        { Sdiv,         "div",  Iarith },
        { Sdivu,        "divu", Iarith },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { Sadd,         "add",  Iarith },
        { Saddu,        "addu", Iarith },
        { undef,        "" },
        { Ssubu,        "subu", Iarith },
        { Sand,         "and",  Iarith },
        { Sor,          "or",   Iarith },
        { Sxor,         "xor",  Iarith },
        { Snor,         "nor",  Iarith },
        { undef,        "" },
        { undef,        "" },
        { Sslt,         "slt",  Iarith },
        { Ssltu,        "sltu", Iarith },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { undef,        "" },
        { 0 }
};

void
Ispecial(ulong inst)
{
        Inst *i;

        i = &ispec[inst&0x3f];
        reg.ip = i;
        i->count++;
        (*i->func)(inst);
}

void
Snor(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("nor\tr%d,r%d,r%d", rd, rs, rt);

        if(inst == INOP)
                nopcount++;
        else
                reg.r[rd] = ~(reg.r[rt]|reg.r[rs]);
}

void
Ssll(ulong inst)
{
        int rd, rt, shamt;

        SpecialGetrtrd(rt, rd, inst);
        shamt = (inst>>6)&0x1f;
        if(trace)
                itrace("sll\tr%d,r%d,%d", rd, rt, shamt);

        reg.r[rd] = reg.r[rt]<<shamt;
}

void
Ssllv(ulong inst)
{
        int rd, rt, rs;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("sllv\tr%d,r%d,r%d", rd, rt, rs);

        reg.r[rd] = reg.r[rt]<<(reg.r[rs]&0x1f);
}

void
Ssrlv(ulong inst)
{
        int rd, rt, rs;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("srlv\tr%d,r%d,r%d", rd, rt, rs);

        reg.r[rd] = (ulong)reg.r[rt] >> (reg.r[rs]&0x1f);
}

void
Ssrav(ulong inst)
{
        int rd, rt, rs, shamt;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("srav\tr%d,r%d,r%d", rd, rt, rs);

        shamt = reg.r[rs]&0x1f;
        if(shamt != 0 && (reg.r[rt] & SIGNBIT))
                reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1);
        else
                reg.r[rd] = reg.r[rt]>>shamt;
}

void
Ssrl(ulong inst)
{
        int rd, rt, shamt;

        SpecialGetrtrd(rt, rd, inst);
        shamt = (inst>>6)&0x1f;
        if(trace)
                itrace("srl\tr%d,r%d,%d", rd, rt, shamt);

        reg.r[rd] = (ulong)reg.r[rt] >> shamt;
}

void
Ssra(ulong inst)
{
        int rd, rt, shamt;

        SpecialGetrtrd(rt, rd, inst);
        shamt = (inst>>6)&0x1f;
        if(trace)
                itrace("sra\tr%d,r%d,%d", rd, rt, shamt);

        if(shamt != 0 && (reg.r[rt] & SIGNBIT))
                reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1);
        else
                reg.r[rd] = reg.r[rt]>>shamt;
}

void
Sslt(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("slt\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = reg.r[rs] < reg.r[rt] ? 1 : 0;
}

void
Ssltu(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("sltu\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = (unsigned)reg.r[rs] < (unsigned)reg.r[rt] ? 1 : 0;
}

void
Sand(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("and\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = reg.r[rs] & reg.r[rt];
}

void
Saddu(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("addu\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = reg.r[rs] + reg.r[rt];
}

void
Sadd(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("add\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = reg.r[rs] + reg.r[rt];
}

void
Ssubu(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("subu\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = reg.r[rs] - reg.r[rt];
}

void
Sor(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("or\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = reg.r[rs] | reg.r[rt];
}

void
Sxor(ulong inst)
{
        int rs, rt, rd;

        Get3(rs, rt, rd, inst);
        if(trace)
                itrace("or\tr%d,r%d,r%d", rd, rs, rt);

        reg.r[rd] = reg.r[rs] ^ reg.r[rt];
}

void
Sjr(ulong inst)
{
        ulong npc;
        int rs;
        Symbol s;

        rs = (inst>>21)&0x1f;
        npc = reg.r[rs];

        if(trace)
                itrace("jr\t0x%lux", npc);

        /* Do the delay slot */
        reg.ir = ifetch(reg.pc+4);
        Statbra();
        Iexec(reg.ir);
        if(calltree) {
                if(rs == 31 || rs == 2) {
                        findsym(npc, CTEXT, &s);
                        Bprint(bioout, "%8lux return to %lux %s r1=%lux\n",
                                                reg.pc, npc, s.name, reg.r[1]);
                }
        }
        reg.pc = npc-4;
}

void
Sjalr(ulong inst)
{
        ulong npc;
        int rs, rd;
        Symbol s;

        rs = (inst>>21)&0x1f;
        rd = (inst>>11)&0x1f;
        npc = reg.r[rs];

        if(trace)
                itrace("jalr\tr%d,r%d", rd, rs);

        reg.r[rd] = reg.pc+8;
        /* Do the delay slot */
        reg.ir = ifetch(reg.pc+4);
        Statbra();
        Iexec(reg.ir);

        if(calltree) {
                findsym(npc, CTEXT, &s);
                if(rs == 31)
                        Bprint(bioout, "%8lux return to %8lux %s\n",
                                                reg.pc, npc, s.name);
                else {
                        printparams(&s, reg.r[29]);
                        Bputc(bioout, '\n');
                }
        }

        reg.pc = npc-4;
}

void
Sdivu(ulong inst)
{
        int rs, rt;

        Getrsrt(rs,rt,inst);
        if(trace)
                itrace("divu\tr%d,r%d", rs, rt);

        reg.mlo = (ulong)reg.r[rs]/(ulong)reg.r[rt];
        reg.mhi = (ulong)reg.r[rs]%(ulong)reg.r[rt];
}

void
Sdiv(ulong inst)
{
        int rs, rt;

        Getrsrt(rs,rt,inst);
        if(trace)
                itrace("div\tr%d,r%d", rs, rt);

        reg.mlo = reg.r[rs]/reg.r[rt];
        reg.mhi = reg.r[rs]%reg.r[rt];
}

void
Smfhi(ulong inst)
{
        int rd;

        rd = (inst>>11)&0x1ff;
        if(trace)
                itrace("mfhi\tr%d", rd);

        reg.r[rd] = reg.mhi;
}

void
Smflo(ulong inst)
{
        int rd;

        rd = (inst>>11)&0x1ff;
        if(trace)
                itrace("mflo\tr%d", rd);

        reg.r[rd] = reg.mlo;
}

void
Smult(ulong inst)
{
        int rs, rt;
        Mul m;

        Getrsrt(rs,rt,inst);
        if(trace)
                itrace("mult\tr%d,r%d", rs,rt);

        m = mul(reg.r[rs], reg.r[rt]);
        reg.mlo = m.lo;
        reg.mhi = m.hi;
}

void
Smultu(ulong inst)
{
        int rs, rt;
        Mulu m;

        Getrsrt(rs,rt,inst);
        if(trace)
                itrace("multu\tr%d,r%d", rs,rt);

        m = mulu(reg.r[rs], reg.r[rt]);
        reg.mlo = m.lo;
        reg.mhi = m.hi;
}