1#include <stdlib.h> 2 3#if !defined(NO_LABEL_VALUES) && (!defined(STACK_SIZE) || STACK_SIZE >= 4000) && __INT_MAX__ >= 2147483647 4typedef unsigned int uint32; 5typedef signed int sint32; 6 7typedef uint32 reg_t; 8 9typedef unsigned long int host_addr_t; 10typedef uint32 target_addr_t; 11typedef sint32 target_saddr_t; 12 13typedef union 14{ 15 struct 16 { 17 unsigned int offset:18; 18 unsigned int ignore:4; 19 unsigned int s1:8; 20 int :2; 21 signed int simm:14; 22 unsigned int s3:8; 23 unsigned int s2:8; 24 int pad2:2; 25 } f1; 26 long long ll; 27 double d; 28} insn_t; 29 30typedef struct 31{ 32 target_addr_t vaddr_tag; 33 unsigned long int rigged_paddr; 34} tlb_entry_t; 35 36typedef struct 37{ 38 insn_t *pc; 39 reg_t registers[256]; 40 insn_t *program; 41 tlb_entry_t tlb_tab[0x100]; 42} environment_t; 43 44enum operations 45{ 46 LOAD32_RR, 47 METAOP_DONE 48}; 49 50host_addr_t 51f () 52{ 53 abort (); 54} 55 56reg_t 57simulator_kernel (int what, environment_t *env) 58{ 59 register insn_t *pc = env->pc; 60 register reg_t *regs = env->registers; 61 register insn_t insn; 62 register int s1; 63 register reg_t r2; 64 register void *base_addr = &&sim_base_addr; 65 register tlb_entry_t *tlb = env->tlb_tab; 66 67 if (what != 0) 68 { 69 int i; 70 static void *op_map[] = 71 { 72 &&L_LOAD32_RR, 73 &&L_METAOP_DONE, 74 }; 75 insn_t *program = env->program; 76 for (i = 0; i < what; i++) 77 program[i].f1.offset = op_map[program[i].f1.offset] - base_addr; 78 } 79 80 sim_base_addr:; 81 82 insn = *pc++; 83 r2 = (*(reg_t *) (((char *) regs) + (insn.f1.s2 << 2))); 84 s1 = (insn.f1.s1 << 2); 85 goto *(base_addr + insn.f1.offset); 86 87 L_LOAD32_RR: 88 { 89 target_addr_t vaddr_page = r2 / 4096; 90 unsigned int x = vaddr_page % 0x100; 91 insn = *pc++; 92 93 for (;;) 94 { 95 target_addr_t tag = tlb[x].vaddr_tag; 96 host_addr_t rigged_paddr = tlb[x].rigged_paddr; 97 98 if (tag == vaddr_page) 99 { 100 *(reg_t *) (((char *) regs) + s1) = *(uint32 *) (rigged_paddr + r2); 101 r2 = *(reg_t *) (((char *) regs) + (insn.f1.s2 << 2)); 102 s1 = insn.f1.s1 << 2; 103 goto *(base_addr + insn.f1.offset); 104 } 105 106 if (((target_saddr_t) tag < 0)) 107 { 108 *(reg_t *) (((char *) regs) + s1) = *(uint32 *) f (); 109 r2 = *(reg_t *) (((char *) regs) + (insn.f1.s2 << 2)); 110 s1 = insn.f1.s1 << 2; 111 goto *(base_addr + insn.f1.offset); 112 } 113 114 x = (x - 1) % 0x100; 115 } 116 117 L_METAOP_DONE: 118 return (*(reg_t *) (((char *) regs) + s1)); 119 } 120} 121 122insn_t program[2 + 1]; 123 124void *malloc (); 125 126int 127main () 128{ 129 environment_t env; 130 insn_t insn; 131 int i, res; 132 host_addr_t a_page = (host_addr_t) malloc (2 * 4096); 133 target_addr_t a_vaddr = 0x123450; 134 target_addr_t vaddr_page = a_vaddr / 4096; 135 a_page = (a_page + 4096 - 1) & -4096; 136 137 env.tlb_tab[((vaddr_page) % 0x100)].vaddr_tag = vaddr_page; 138 env.tlb_tab[((vaddr_page) % 0x100)].rigged_paddr = a_page - vaddr_page * 4096; 139 insn.f1.offset = LOAD32_RR; 140 env.registers[0] = 0; 141 env.registers[2] = a_vaddr; 142 *(sint32 *) (a_page + a_vaddr % 4096) = 88; 143 insn.f1.s1 = 0; 144 insn.f1.s2 = 2; 145 146 for (i = 0; i < 2; i++) 147 program[i] = insn; 148 149 insn.f1.offset = METAOP_DONE; 150 insn.f1.s1 = 0; 151 program[2] = insn; 152 153 env.pc = program; 154 env.program = program; 155 156 res = simulator_kernel (2 + 1, &env); 157 158 if (res != 88) 159 abort (); 160 exit (0); 161} 162#else 163main(){ exit (0); } 164#endif 165