home *** CD-ROM | disk | FTP | other *** search
- #include "register.h"
- #include "symtab.h"
- #include "diblock.h"
- #include "instrn.h"
- #include "process.h"
- #include "wcache.h"
-
- /*
- * TODO -- big-endian v. little-endian.
- */
-
- #define quiet_procmput_word(dipc,offset,w,n,S) \
- { \
- int i; \
- unsigned long *wp; \
- \
- if ((i = offset - P.p_data_region_min) >= 0) \
- { \
- if (n == sizeof(int)) \
- { \
- if (offset <= P.p_data_region_wlimit) \
- { \
- wp = (unsigned long *)&P.p_data_region[i]; \
- *wp = w; \
- S; \
- return dipc; \
- } \
- } \
- else if (n == sizeof(short)) \
- { \
- if (offset <= P.p_data_region_limit + 1 - n) \
- { \
- *(unsigned short *)&P.p_data_region[i] = w; \
- return dipc; \
- } \
- } \
- else \
- { \
- if (offset <= P.p_data_region_limit) \
- { \
- *(unsigned char *)&P.p_data_region[i] = w; \
- return dipc; \
- } \
- } \
- \
- if (offset <= STACK_WMAX) \
- { \
- if ((i = offset - P.p_stack_region_min) < 0) \
- { \
- (void)proc_grow_stack(dipc, offset); \
- \
- i = offset - P.p_stack_region_min; \
- } \
- \
- if (n == sizeof(int)) \
- { \
- wp = (unsigned long *)&P.p_stack_region[i]; \
- *wp = w; \
- S; \
- } \
- else if (n == sizeof(short)) \
- *(unsigned short *)&P.p_stack_region[i] = w; \
- else \
- *(unsigned char *)&P.p_stack_region[i] = w; \
- \
- return dipc; \
- } \
- } \
- \
- (void)quiet_procmput(dipc, offset, (unsigned char *)&w, n); \
- return dipc; \
- }
-
- static
- dinstrn *
- c_sb(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned char c;
-
- addr = *dipc->di_1 + (long)dipc->di_2;
- c = *dipc->di_0;
-
- quiet_procmput_word(dipc, addr, c, sizeof(c), ;);
- }
-
- dinstrn *
- i_sb(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long t;
- unsigned char c;
-
- if (compile_ok)
- {
- dipc->di_handler = c_sb;
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = &P.p_state[base];
- dipc->di_2 = (unsigned long *)(long)offset;
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(base, b);
-
- procsget(rt, t);
-
- c = t;
-
- (void)procmput(dipc, b + (long)offset, (char *)&c, sizeof(c));
-
- return dipc;
- }
-
- static
- dinstrn *
- c_sh(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned short h;
-
- addr = *dipc->di_1 + (long)dipc->di_2;
- h = *dipc->di_0;
-
- check_halfword_align(dipc, addr);
-
- quiet_procmput_word(dipc, addr, h, sizeof(h), ;);
- }
-
- dinstrn *
- i_sh(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- unsigned long t;
- unsigned short h;
-
- if (compile_ok)
- {
- dipc->di_handler = c_sh;
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = &P.p_state[base];
- dipc->di_2 = (unsigned long *)(long)offset;
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(base, b);
-
- addr = b + offset;
-
- check_halfword_align(dipc, addr);
-
- procsget(rt, t);
-
- h = t;
-
- (void)procmput(dipc, addr, (char *)&h, sizeof(h));
-
- return dipc;
- }
-
- static
- dinstrn *
- c_sll(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_1 << (int)dipc->di_2;
-
- return dipc;
- }
-
- dinstrn *
- i_sll(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- unsigned long t;
-
- if (compile_ok)
- {
- if (rd == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_sll;
- dipc->di_0 = &P.p_state[rd];
- dipc->di_1 = &P.p_state[rt];
- dipc->di_2 = (unsigned long *)shamt;
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(rt, t);
-
- procsput(rd, t << shamt);
-
- return dipc;
- }
-
- dinstrn *
- i_sllv(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- unsigned long t;
- unsigned long s;
-
- procsget(rt, t);
-
- procsget(rs, s);
-
- procsput(rd, t << (s & 0x1F));
-
- return dipc;
- }
-
- static
- dinstrn *
- c_slt(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = ((long)*dipc->di_1 < (long)*dipc->di_2) ? 1 : 0;
-
- return dipc;
- }
-
- dinstrn *
- i_slt(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- long s;
- long t;
-
- if (compile_ok)
- {
- if (rd == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_slt;
- 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, *(unsigned long *)&s);
-
- procsget(rt, *(unsigned long *)&t);
-
- procsput(rd, (s < t) ? 1 : 0);
-
- return dipc;
- }
-
- dinstrn *
- i_slti(dipc, rs, rt, immediate)
- dinstrn *dipc;
- int rs;
- int rt;
- short immediate;
- {
- long s;
-
- procsget(rs, *(unsigned long *)&s);
-
- procsput(rt, (s < (long)immediate) ? 1 : 0);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_sltiu(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = (*dipc->di_1 < (unsigned long)dipc->di_2) ? 1 : 0;
-
- return dipc;
- }
-
- dinstrn *
- i_sltiu(dipc, rs, rt, immediate)
- dinstrn *dipc;
- int rs;
- int rt;
- short immediate;
- {
- unsigned long s;
- long i;
- unsigned long ui;
-
- i = immediate;
- ui = i;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_sltiu;
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = &P.p_state[rs];
- dipc->di_2 = (unsigned long *)ui;
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(rs, s);
-
- procsput(rt, (s < ui) ? 1 : 0);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_sltu(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = (*dipc->di_1 < *dipc->di_2) ? 1 : 0;
-
- return dipc;
- }
-
- dinstrn *
- i_sltu(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
- {
- dipc->di_handler = c_sltu;
- 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) ? 1 : 0);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_sra(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = (unsigned long)(((long)*dipc->di_2) >> (int)dipc->di_1);
-
- return dipc;
- }
-
- dinstrn *
- i_sra(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- long t;
-
- if (compile_ok)
- {
- if (rd == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_sra;
- dipc->di_0 = &P.p_state[rd];
- dipc->di_1 = (unsigned long *)shamt;
- dipc->di_2 = &P.p_state[rt];
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(rt, *(unsigned long *)&t);
-
- procsput(rd, t >> shamt);
-
- return dipc;
- }
-
- dinstrn *
- i_srav(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- long t;
- unsigned long s;
-
- procsget(rt, *(unsigned long *)&t);
-
- procsget(rs, s);
-
- procsput(rd, t >> (s & 0x1F));
-
- return dipc;
- }
-
- dinstrn *
- i_srl(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- unsigned long t;
-
- procsget(rt, t);
-
- procsput(rd, t >> shamt);
-
- return dipc;
- }
-
- dinstrn *
- i_srlv(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- unsigned long t;
- unsigned long s;
-
- procsget(rt, t);
-
- procsget(rs, s);
-
- procsput(rd, t >> (s & 0x1F));
-
- return dipc;
- }
-
- dinstrn *
- i_sub(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_subfmt(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_subu(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = *dipc->di_1 - *dipc->di_2;
-
- return dipc;
- }
-
- dinstrn *
- i_subu(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
- {
- dipc->di_handler = c_subu;
- 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;
- }
-
- static
- dinstrn *
- c_sw0(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long l;
- cent *cap;
-
- addr = *dipc->di_1;
- l = *dipc->di_0;
-
- if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
- {
- *cap->c_ptr = l;
- return dipc;
- }
-
- check_word_align(dipc, addr);
-
- quiet_procmput_word(dipc, addr, l, sizeof(l), cap->c_ptr = wp; cap->c_addr = addr);
- }
-
- static
- dinstrn *
- c_sw4(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long l;
- cent *cap;
-
- addr = *dipc->di_1 + 4;
- l = *dipc->di_0;
-
- if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
- {
- *cap->c_ptr = l;
- return dipc;
- }
-
- check_word_align(dipc, addr);
-
- quiet_procmput_word(dipc, addr, l, sizeof(l), cap->c_ptr = wp; cap->c_addr = addr);
- }
-
- static
- dinstrn *
- c_sw(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long l;
- cent *cap;
-
- addr = *dipc->di_1 + (long)dipc->di_2;
- l = *dipc->di_0;
-
- if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
- {
- *cap->c_ptr = l;
- return dipc;
- }
-
- check_word_align(dipc, addr);
-
- quiet_procmput_word(dipc, addr, l, sizeof(l), cap->c_ptr = wp; cap->c_addr = addr);
- }
-
- dinstrn *
- i_sw(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- unsigned long t;
-
- if (compile_ok)
- {
- switch (offset)
- {
- case 0:
- dipc->di_handler = c_sw0;
- break;
-
- case 4:
- dipc->di_handler = c_sw4;
- break;
-
- default:
- dipc->di_handler = c_sw;
- break;
- }
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = &P.p_state[base];
- dipc->di_2 = (unsigned long *)(long)offset;
-
- return (*dipc->di_handler)(dipc);
- }
-
- procsget(base, b);
-
- addr = b + (long)offset;
-
- check_word_align(dipc, addr);
-
- procsget(rt, t);
-
- (void)procmput(dipc, addr, (char *)&t, sizeof(t));
-
- return dipc;
- }
-
- dinstrn *
- i_swc1(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- unsigned long t;
-
- procsget(base, b);
-
- addr = b + (long)offset;
-
- check_word_align(dipc, addr);
-
- procsget(CP1G(rt), t);
-
- (void)procmput(dipc, addr, (char *)&t, sizeof(t));
-
- return dipc;
- }
-
- dinstrn *
- i_swl(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- unsigned long t;
- int length;
-
- procsget(base, b);
-
- addr = b + (long)offset;
-
- procsget(rt, t);
-
- length = sizeof(t) - (addr - (addr & ~0x3));
-
- (void)procmput(dipc, addr, (char *)&t, length);
-
- return dipc;
- }
-
- dinstrn *
- i_swr(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- unsigned long t;
- int length;
-
- procsget(base, b);
-
- addr = b + (long)offset;
-
- procsget(rt, t);
-
- length = (addr - (addr & ~0x3)) + 1;
-
- (void)procmput(dipc, addr & ~0x3, ((char *)&t) + (sizeof(t) - length), length);
-
- return dipc;
- }
-