-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathdemo_code.c
More file actions
115 lines (102 loc) · 2.74 KB
/
demo_code.c
File metadata and controls
115 lines (102 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
static void gen_exception(DisasContext *s, uint32_t where, int nr)
{
gen_flush_cc_op(s);
gen_jmp_im(s, where);
gen_helper_raise_exception(tcg_const_i32(nr));
}
static inline void gen_addr_fault(DisasContext *s)
{
gen_exception(s, s->insn_pc, EXCP_ADDRESS);
}
#define SRC_EA(result, opsize, op_sign, addrp) do { \
result = gen_ea(s, insn, opsize, NULL_QREG, addrp, op_sign ? EA_LOADS : EA_LOADU); \
if (IS_NULL_QREG(result)) { \
gen_addr_fault(s); \
return; \
} \
} while (0)
#define DEST_EA(insn, opsize, val, addrp) do { \
TCGv ea_result = gen_ea(s, insn, opsize, val, addrp, EA_STORE); \
if (IS_NULL_QREG(ea_result)) { \
gen_addr_fault(s); \
return; \
} \
} while (0)
/* Generate a jump to an immediate address. */
static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
{
TranslationBlock *tb;
tb = s->tb;
if (unlikely(s->singlestep_enabled)) {
gen_exception(s, dest, EXCP_DEBUG);
} else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
(s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
tcg_gen_goto_tb(n);
tcg_gen_movi_i32(QREG_PC, dest);
tcg_gen_exit_tb((long)tb + n);
} else {
gen_jmp_im(s, dest);
tcg_gen_exit_tb(0);
}
s->is_jmp = DISAS_TB_JUMP;
}
DISAS_INSN(undef_mac)
{
gen_exception(s, s->pc - 2, EXCP_LINEA);
}
DISAS_INSN(undef_fpu)
{
gen_exception(s, s->pc - 2, EXCP_LINEF);
}
DISAS_INSN(undef)
{
gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
insn, s->pc - 2);
}
DISAS_INSN(mulw)
{
TCGv reg;
TCGv tmp;
TCGv src;
int sign;
sign = (insn & 0x100) != 0;
reg = DREG(insn, 9);
tmp = tcg_temp_new();
if (sign)
tcg_gen_ext16s_i32(tmp, reg);
else
tcg_gen_ext16u_i32(tmp, reg);
SRC_EA(src, OS_WORD, sign, NULL);
tcg_gen_mul_i32(tmp, tmp, src);
tcg_gen_mov_i32(reg, tmp);
/* Unlike m68k, coldfire always clears the overflow bit. */
gen_logic_cc(s, tmp);
}
DISAS_INSN(divw)
{
TCGv reg;
TCGv tmp;
TCGv src;
int sign;
sign = (insn & 0x100) != 0;
reg = DREG(insn, 9);
if (sign) {
tcg_gen_ext16s_i32(QREG_DIV1, reg);
} else {
tcg_gen_ext16u_i32(QREG_DIV1, reg);
}
SRC_EA(src, OS_WORD, sign, NULL);
tcg_gen_mov_i32(QREG_DIV2, src);
if (sign) {
gen_helper_divs(cpu_env, tcg_const_i32(1));
} else {
gen_helper_divu(cpu_env, tcg_const_i32(1));
}
tmp = tcg_temp_new();
src = tcg_temp_new();
tcg_gen_ext16u_i32(tmp, QREG_DIV1);
tcg_gen_shli_i32(src, QREG_DIV2, 16);
tcg_gen_or_i32(reg, tmp, src);
s->cc_op = CC_OP_FLAGS;
}