home *** CD-ROM | disk | FTP | other *** search
- #include "register.h"
- #include "symtab.h"
- #include "diblock.h"
- #include "instrn.h"
- #include "process.h"
-
- extern double fabs();
-
- dinstrn *
- i_absfmt(dipc, fmt, ft, fs, fd)
- dinstrn *dipc;
- int fmt;
- int ft;
- int fs;
- int fd;
- {
- float singles;
- float singled;
- double doubles;
- double doubled;
-
- switch (fmt)
- {
- case FMT_SINGLE:
- procsget(CP1G(fs), *(unsigned long *)&singles);
-
- singled = (float)fabs(singles);
-
- procsput(CP1G(fd), *(unsigned long *)&singled);
-
- break;
-
- case FMT_DOUBLE:
- /*
- * Note apparent reversal of words within
- * doubles here -- no idea why.
- */
- procsget(CP1G(fs), *((unsigned long *)&doubles + 1));
-
- procsget(CP1G(fs) + 1, *(unsigned long *)&doubles);
-
- doubled = fabs(doubles);
-
- procsput(CP1G(fd), *((unsigned long *)&doubled + 1));
-
- procsput(CP1G(fd) + 1, *(unsigned long *)&doubled);
- break;
-
- default:
- unrecognised(dipc);
- break;
- }
-
- return dipc;
- }
-
- dinstrn *
- i_add(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- unsigned long s;
- unsigned long t;
-
- procsget(rs, s);
-
- procsget(rt, t);
-
- /*
- * TODO -- overflow exception.
- */
- procsput(rd, s + t);
-
- return dipc;
- }
-
- dinstrn *
- i_addfmt(dipc, fmt, ft, fs, fd)
- dinstrn *dipc;
- int fmt;
- int ft;
- int fs;
- int fd;
- {
- float singles;
- float singlet;
- float singled;
- double doubles;
- double doublet;
- double doubled;
- unsigned long l[2];
-
- switch (fmt)
- {
- case FMT_SINGLE:
- procsget(CP1G(fs), *(unsigned long *)&singles);
-
- procsget(CP1G(ft), *(unsigned long *)&singlet);
-
- singled = singles + singlet;
-
- procsput(CP1G(fd), *(unsigned long *)&singled);
-
- break;
-
- case FMT_DOUBLE:
- /*
- * Note apparent reversal of words within
- * doubles here -- no idea why.
- */
- procsget(CP1G(fs), *((unsigned long *)&doubles + 1));
-
- procsget(CP1G(fs) + 1, *(unsigned long *)&doubles);
-
- procsget(CP1G(ft), *((unsigned long *)&doublet + 1));
-
- procsget(CP1G(ft) + 1, *(unsigned long *)&doublet);
-
- doubled = doubles + doublet;
-
- procsput(CP1G(fd), *((unsigned long *)&doubled + 1));
-
- procsput(CP1G(fd) + 1, *(unsigned long *)&doubled);
- break;
-
- default:
- unrecognised(dipc);
- break;
- }
-
- return dipc;
- }
-
- static
- dinstrn *
- c_addi_li(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = (long)dipc->di_2;
-
- return dipc;
- }
-
- static
- dinstrn *
- c_addi(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_1 + (long)dipc->di_2;
-
- return dipc;
- }
-
- dinstrn *
- i_addi(dipc, rs, rt, immediate)
- dinstrn *dipc;
- int rs;
- int rt;
- short immediate;
- {
- unsigned long r;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- if (rs == R_0)
- dipc->di_handler = c_addi_li;
- else
- dipc->di_handler = c_addi;
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = &P.p_state[rs];
- dipc->di_2 = (unsigned long *)(long)immediate;
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(rs, r);
-
- procsput(rt, r + immediate);
-
- /*
- * Overflow exception?
- */
-
- return dipc;
- }
-
- static
- dinstrn *
- c_addiu_li(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = (long)dipc->di_2;
-
- return dipc;
- }
-
- static
- dinstrn *
- c_addiu(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_1 + (long)dipc->di_2;
-
- return dipc;
- }
-
- dinstrn *
- i_addiu(dipc, rs, rt, immediate)
- dinstrn *dipc;
- int rs;
- int rt;
- short immediate;
- {
- unsigned long s;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- if (rs == R_0)
- dipc->di_handler = c_addiu_li;
- else
- dipc->di_handler = c_addiu;
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = &P.p_state[rs];
- dipc->di_2 = (unsigned long *)(long)immediate;
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(rs, s);
-
- procsput(rt, s + (long)immediate);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_addu_move(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_2;
-
- return dipc;
- }
-
- static
- dinstrn *
- c_addu_move2(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_1;
-
- return dipc;
- }
-
- static
- dinstrn *
- c_addu(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_1 + *dipc->di_2;
-
- return dipc;
- }
-
- dinstrn *
- i_addu(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- unsigned long s;
- unsigned long t;
-
- if (compile_ok)
- {
- if (rd == R_0)
- dipc->di_handler = c_noop;
- else
- {
- if (rs == R_0)
- dipc->di_handler = c_addu_move;
- else if (rt == R_0)
- dipc->di_handler = c_addu_move2;
- else
- dipc->di_handler = c_addu;
- dipc->di_0 = &P.p_state[rd];
- dipc->di_1 = &P.p_state[rs];
- dipc->di_2 = &P.p_state[rt];
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(rs, s);
-
- procsget(rt, t);
-
- procsput(rd, s + t);
-
- return dipc;
- }
-
- dinstrn *
- i_and(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- unsigned long s;
- unsigned long t;
-
- procsget(rs, s);
-
- procsget(rt, t);
-
- procsput(rd, s & t);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_andi(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_1 & (unsigned long)dipc->di_2;
-
- return dipc;
- }
-
- dinstrn *
- i_andi(dipc, rs, rt, immediate)
- dinstrn *dipc;
- int rs;
- int rt;
- short immediate;
- {
- unsigned long s;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_andi;
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = &P.p_state[rs];
- dipc->di_2 = (unsigned long *)(((unsigned long)immediate) & 0xFFFF);
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(rs, s);
-
- procsput(rt, s & (((unsigned long)immediate) & 0xFFFF));
-
- return dipc;
- }
-