home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "register.h"
- #include "symtab.h"
- #include "diblock.h"
- #include "instrn.h"
- #include "process.h"
- #include "wcache.h"
- #include "talloc.h"
- #include "nels.h"
-
- #define char_to_signed_long(C) (long)(((C) & 0x80) ? ((C) | 0xFFFFFF80) : (C))
-
- #define quiet_procmget_word(dipc,offset,ip,n,S,T) \
- { \
- 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]; \
- *ip = *wp; \
- S; \
- T; \
- return dipc; \
- } \
- } \
- else if (n == sizeof(short)) \
- { \
- if (offset <= P.p_data_region_limit + 1 - n) \
- { \
- *ip = *(unsigned short *)&P.p_data_region[i]; \
- S; \
- T; \
- return dipc; \
- } \
- } \
- else \
- { \
- if (offset <= P.p_data_region_limit) \
- { \
- *ip = *(unsigned char *)&P.p_data_region[i]; \
- S; \
- T; \
- 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]; \
- *ip = *wp; \
- } \
- else if (n == sizeof(short)) \
- *ip = *(unsigned short *)&P.p_stack_region[i]; \
- else \
- *ip = *(unsigned char *)&P.p_stack_region[i]; \
- \
- S; \
- T; \
- return dipc; \
- } \
- } \
- \
- (void)quiet_procmget(dipc, offset, (unsigned char *)ip, n); \
- S; \
- return dipc; \
- }
-
- static
- dinstrn *
- c_lb0(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned char c;
- unsigned long *lp;
-
- addr = *dipc->di_1;
- lp = dipc->di_0;
-
- quiet_procmget_word(dipc, addr, &c, sizeof(c), *lp = (unsigned long)char_to_signed_long(c), ;);
- }
-
- static
- dinstrn *
- c_lb(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned char c;
- unsigned long *lp;
-
- addr = *dipc->di_1 + (long)dipc->di_2;
- lp = dipc->di_0;
-
- quiet_procmget_word(dipc, addr, &c, sizeof(c), *lp = (unsigned long)char_to_signed_long(c), ;);
- }
-
- dinstrn *
- i_lb(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned char c;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- if (offset == (short)0)
- dipc->di_handler = c_lb0;
- else
- dipc->di_handler = c_lb;
- 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);
-
- if (procmget(dipc, b + (long)offset, (char *)&c, sizeof(c)) != -1)
- procsput(rt, char_to_signed_long(c));
-
- return dipc;
- }
-
- static
- dinstrn *
- c_lbu(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned char c;
- unsigned long *lp;
-
- addr = *dipc->di_1 + (long)dipc->di_2;
- lp = dipc->di_0;
-
- quiet_procmget_word(dipc, addr, &c, sizeof(c), *lp = (unsigned long)c, ;);
- }
-
- dinstrn *
- i_lbu(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned char c;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_lbu;
- 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);
-
- if (procmget(dipc, b + (long)offset, (char *)&c, sizeof(c)) != -1)
- procsput(rt, (unsigned long)c);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_lh(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long *lp;
- short m;
-
- addr = *dipc->di_1 + (long)dipc->di_2;
- lp = dipc->di_0;
-
- check_halfword_align(dipc, addr);
-
- quiet_procmget_word(dipc, addr, &m, sizeof(m), *lp = (unsigned long)(long)m, ;);
- }
-
- dinstrn *
- i_lh(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- short m;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_lh;
- 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_halfword_align(dipc, addr);
-
- if (procmget(dipc, addr, (char *)&m, sizeof(m)) != -1)
- procsput(rt, (long)m);
-
- return dipc;
- }
-
- dinstrn *
- i_lhu(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- unsigned short m;
-
- procsget(base, b);
-
- addr = b + (long)offset;
-
- check_halfword_align(dipc, addr);
-
- if (procmget(dipc, addr, (char *)&m, sizeof(m)) != -1)
- procsput(rt, (unsigned long)m);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_lui(dipc)
- dinstrn *dipc;
- {
- *dipc->di_0 = (unsigned long)dipc->di_1;
-
- return dipc;
- }
-
- dinstrn *
- i_lui(dipc, rs, rt, immediate)
- dinstrn *dipc;
- int rs;
- int rt;
- short immediate;
- {
- unsigned long t;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- dipc->di_handler = c_lui;
- dipc->di_0 = &P.p_state[rt];
- dipc->di_1 = (unsigned long *)((immediate << 16) & 0xFFFF0000);
- }
-
- return (*dipc->di_handler)(dipc);
- }
-
- t = (immediate << 16) & 0xFFFF0000;
-
- procsput(rt, t);
-
- return dipc;
- }
-
- static
- dinstrn *
- c_lw0(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long *lp;
- cent *cap;
-
- addr = *dipc->di_1;
- lp = dipc->di_0;
-
- if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
- {
- *lp = *cap->c_ptr;
- return dipc;
- }
-
- check_word_align(dipc, addr);
-
- quiet_procmget_word(dipc, addr, lp, sizeof(*lp), ;, cap->c_ptr = wp; cap->c_addr = addr);
- }
-
- static
- dinstrn *
- c_lw4(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long *lp;
- cent *cap;
-
- addr = *dipc->di_1 + 4;
- lp = dipc->di_0;
-
- if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
- {
- *lp = *cap->c_ptr;
- return dipc;
- }
-
- check_word_align(dipc, addr);
-
- quiet_procmget_word(dipc, addr, lp, sizeof(*lp), ;, cap->c_ptr = wp; cap->c_addr = addr);
- }
-
- static
- dinstrn *
- c_lw8(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long *lp;
- cent *cap;
-
- addr = *dipc->di_1 + 8;
- lp = dipc->di_0;
-
- if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
- {
- *lp = *cap->c_ptr;
- return dipc;
- }
-
- check_word_align(dipc, addr);
-
- quiet_procmget_word(dipc, addr, lp, sizeof(*lp), ;, cap->c_ptr = wp; cap->c_addr = addr);
- }
-
- static
- dinstrn *
- c_lw(dipc)
- dinstrn *dipc;
- {
- unsigned long addr;
- unsigned long *lp;
- cent *cap;
-
- addr = *dipc->di_1 + (long)dipc->di_2;
- lp = dipc->di_0;
-
- if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
- {
- *lp = *cap->c_ptr;
- return dipc;
- }
-
- check_word_align(dipc, addr);
-
- quiet_procmget_word(dipc, addr, lp, sizeof(*lp), ;, cap->c_ptr = wp; cap->c_addr = addr);
- }
-
- dinstrn *
- i_lw(dipc, base, rt, offset)
- dinstrn *dipc;
- int base;
- int rt;
- short offset;
- {
- unsigned long b;
- unsigned long addr;
- unsigned long t;
-
- if (compile_ok)
- {
- if (rt == R_0)
- dipc->di_handler = c_noop;
- else
- {
- switch (offset)
- {
- case 0:
- dipc->di_handler = c_lw0;
- break;
-
- case 4:
- dipc->di_handler = c_lw4;
- break;
-
- case 8:
- dipc->di_handler = c_lw8;
- break;
-
- default:
- dipc->di_handler = c_lw;
- 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);
-
- if (procmget(dipc, addr, (char *)&t, sizeof(t)) != -1)
- procsput(rt, t);
-
- return dipc;
- }
-
- dinstrn *
- i_lwc1(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);
-
- if (procmget(dipc, addr, (char *)&t, sizeof(t)) != -1)
- procsput(CP1G(rt), t);
-
- return dipc;
- }
-
- dinstrn *
- i_lwl(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 + offset;
-
- procsget(rt, t);
-
- length = sizeof(t) - (addr - (addr & ~0x3));
-
- if (procmget(dipc, addr, (unsigned char *)&t, length) != -1)
- procsput(rt, t);
-
- return dipc;
- }
-
- dinstrn *
- i_lwr(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 + offset;
-
- procsget(rt, t);
-
- length = (addr - (addr & ~0x3)) + 1;
-
- if (procmget(dipc, addr & ~0x3, ((unsigned char *)&t) + (sizeof(t) - length), length) != -1)
- procsput(rt, t);
-
- return dipc;
- }
-