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