]>
git.wh0rd.org - ICEs.git/blob - 555418/mips.c
714373a6d18141c927c83e2fe3858c2b5f5a87af
3 uint32_t pc_exec
, pc
, r
[32];
5 static uint32_t engine_getbits(uint32_t fetched
, int base
, int width
)
7 return (fetched
>> base
) & ((((uint32_t) 0x1) << width
) - 1);
9 static void *engine_decode(void **ijops
, void **rops
, uint32_t fetched
)
11 int ijcode
= engine_getbits(fetched
, 26, 6);
12 void *ij
= ijops
[ijcode
], *r
= rops
[engine_getbits(fetched
, 0, 6)];
18 static int32_t engine_sign(uint32_t u
, int width
)
20 uint32_t msb
= ((uint32_t) 0x1) << (width
- 1);
21 return (u
^ msb
) - msb
;
23 static void engine_monitor(uint32_t pc_done
, uint32_t pc_exec
, uint32_t pc
,
28 //printf("%08x:%x-%x-%x\n", inst, pc_done * 4, pc_exec * 4, pc * 4);
31 http://www.d.umn.edu/~gshute/mips/instruction-types.xhtml
32 https://www.student.cs.uwaterloo.ca/~isg/res/mips/opcodes
33 http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
35 int engine(engine_state
* statep
, uint32_t * memory
)
39 void *ijops
[64], *rops
[64];
40 register uint32_t inst
asm("edx");
41 register uint32_t pc_exec
asm("ebx") = statep
->pc_exec
;
42 register uint32_t pc
asm("ecx") = statep
->pc
;
43 uint32_t *r
= statep
->r
;
45 #define COME(name) op_##name: { uint32_t ninst = memory[pc], pc_done = pc_exec; void *nlabel = engine_decode(ijops, rops, ninst); pc_exec = pc++
46 #define JUMP(name) engine_monitor(pc_done, pc_exec, pc, inst); r[0] = 0; inst = ninst; asm volatile ("#" #name); goto *nlabel; } while (0)
48 #define REG_S (r[engine_getbits(inst, 21, 5)])
49 #define REG_T (r[engine_getbits(inst, 16, 5)])
50 #define REG_D (r[engine_getbits(inst, 11, 5)])
51 #define IMM_A (engine_getbits(inst, 6, 5))
52 #define IMM_I ((uint16_t) inst)
53 #define IMM_SI ((int16_t) inst)
54 #define IMM_J (engine_getbits(inst, 0, 26))
56 for (i
= 0; i
< 64; i
++)
57 ijops
[i
] = rops
[i
] = &&op_undef
;
58 #define OP(code,mnemonic) ijops[code] = &&op_##mnemonic
68 #define OP(code,mnemonic) rops[code] = &&op_##mnemonic
76 inst
= memory
[pc_exec
];
78 goto *engine_decode(ijops
, rops
, inst
);
93 pc
= (pc_exec
& 0xfc000000) | IMM_J
;
97 pc
= (pc_exec
& 0xfc000000) | IMM_J
;
103 #define STEM_BRANCH(op,name) \
104 COME(name); { uint32_t leap = pc_exec + IMM_SI; if (REG_S op REG_T) pc = leap; } JUMP(name)
105 STEM_BRANCH( ==, beq
);
106 STEM_BRANCH(!=, bne
);
107 /* register to register */
109 REG_T
= REG_S
+ IMM_SI
;
112 REG_D
= REG_S
+ REG_T
;
115 REG_T
= REG_S
& IMM_I
;
121 REG_T
= REG_S
| IMM_I
;
124 REG_D
= REG_T
<< IMM_A
;
127 REG_D
= REG_T
>> IMM_A
;
130 REG_D
= REG_S
^ REG_T
;
134 statep
->pc_exec
= pc_exec
;