comparison m68k_to_x86.c @ 14:2bdad0f52f42

x86 code gen, initial work on translator
author Mike Pavone <pavone@retrodev.com>
date Tue, 27 Nov 2012 09:28:13 -0800
parents
children 3e7bfde7606e
comparison
equal deleted inserted replaced
13:168b1a873895 14:2bdad0f52f42
1 #include "gen_x86.h"
2 #include "m68k_to_x86.h"
3
4
5 #define BUS 4
6 #define CYCLES RAX
7 #define LIMIT RBP
8 #define SCRATCH RCX
9 #define CONTEXT RSI
10
11 #define FLAG_N RBX
12 #define FLAG_V BH
13 #define FLAG_Z RDX
14 #define FLAG_C DH
15
16 typedef struct {
17 int32_t disp;
18 uint8_t mode;
19 uint8_t base;
20 uint8_t index;
21 uint8_t cycles;
22 } x86_ea;
23
24 void handle_cycle_limit();
25
26 uint8_t * cycles(uint8_t * dst, uint32_t num)
27 {
28 dst = add_i32r(dst, num, CYCLES);
29 }
30
31 uint8_t * check_cycles(uint8_t * dst) Ivds
32 {
33 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
34 dst = jcc(dst, CC_G, 5);
35 dst = call(dst, (char *)handle_cycle_limit);
36 }
37
38 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts)
39 {
40 if (op->addr_mode == MODE_REG) {
41 return opts->dregs[op->params.regs.pri];
42 }
43 if (op->addr_mode == MODE_AREG) {
44 return opts->aregs[op->params.regs.pri];
45 }
46 return -1;
47 }
48
49 uint8_t * translate_m68k_ea(m68k_op_info * op, x86_ea * dst, uint8_t * out, x86_68k_options * opts)
50 {
51 int8_t reg = native_reg(op, opts);
52 if (reg >= 0) {
53 dst->mode = MODE_REG_DIRECT;
54 dst->base = reg;
55 return;
56 }
57 switch (op->addr_mode)
58 {
59 case MODE_REG:
60 case MODE_AREG:
61 dst->mode = MODE_DISPLACE8;
62 dst->base = CONTEXT;
63 dst->disp = (op->addr_mode = MODE_REG ? offsetof(m68k_context, dregs) : offsetof(m68k_context, aregs)) + 4 * op->params.regs.pri;
64 break;
65 case MODE_AREG_INDIRECT:
66
67 break;
68 }
69 }
70
71 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
72 {
73 int8_t reg_a, reg_b, flags_reg;
74 uint8_t dir = 0;
75 int32_t offset;
76 switch(inst->op)
77 {
78 case M68K_ABCD:
79 case M68K_ADD:
80 case M68K_ADDX:
81 case M68K_AND:
82 case M68K_ANDI_CCR:
83 case M68K_ANDI_SR:
84 case M68K_ASL:
85 case M68K_ASR:
86 case M68K_BCC:
87 case M68K_BCHG:
88 case M68K_BCLR:
89 case M68K_BSET:
90 case M68K_BSR:
91 case M68K_BTST:
92 case M68K_CHK:
93 case M68K_CLR:
94 case M68K_CMP:
95 case M68K_DBCC:
96 case M68K_DIVS:
97 case M68K_DIVU:
98 case M68K_EOR:
99 case M68K_EORI_CCR:
100 case M68K_EORI_SR:
101 case M68K_EXG:
102 case M68K_EXT:
103 case M68K_ILLEGAL:
104 case M68K_JMP:
105 case M68K_JSR:
106 case M68K_LEA:
107 case M68K_LINK:
108 case M68K_LSL:
109 case M68K_LSR:
110 case M68K_MOVE:
111
112 if ((inst->src.addr_mode == MODE_REG || inst->src.addr_mode == MODE_AREG || (inst->src.addr_mode == MODE_IMMEDIATE && inst->src.variant == VAR_QUICK)) && (inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)) {
113 dst = cycles(dst, BUS);
114 reg_a = native_reg(&(inst->src), opts);
115 reg_b = native_reg(&(inst->dst), opts);
116 dst = cycles(dst, BUS);
117 if (reg_a >= 0 && reg_b >= 0) {
118 dst = mov_rr(dst, reg_a, reg_b, inst->extra.size);
119 flags_reg = reg_b;
120 } else if(reg_a >= 0) {
121 offset = inst->dst.addr_mode == MODE_REG ? offsetof(m68k_context, dregs) : offsetof(m68k_context, aregs);
122 dst = mov_rrdisp8(dst, reg_a, CONTEXT, offset + 4 * inst->dst.params.regs.pri, inst->extra.size);
123 flags_reg = reg_a;
124 } else if(reg_b >= 0) {
125 if (inst->src.addr_mode == MODE_REG) {
126 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->src.params.regs.pri, reg_b, inst->extra.size);
127 } else if(inst->src.addr_mode == MODE_AREG) {
128 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, reg_b, inst->extra.size);
129 } else {
130 dst = mov_i32r(dst, inst->src.params.u32, reg_b);
131 }
132 flags_reg = reg_b;
133 } else {
134
135 }
136 dst = mov_i8r(dst, 0, FLAG_V);
137 dst = mov_i8r(dst, 0, FLAG_C);
138 switch (inst->extra.size)
139 {
140 case OPSIZE_BYTE:
141 dst = cmp_i8r(dst, 0, reg_b, SZ_B);
142 break;
143 case OPSIZE_WORD:
144 dst = cmp_i8r(dst, 0, reg_b, SZ_W);
145 break;
146 case OPSIZE_LONG:
147 dst = cmp_i8r(dst, 0, reg_b, SZ_D);
148 break;
149 }
150 dst = setcc_r(dst, CC_Z, FLAG_Z);
151 dst = setcc_r(dst, CC_S, FLAG_N);
152 dst = check_cycles(dst);
153 }
154
155 if (reg_a >= 0 && reg_b >= 0) {
156 dst = cycles(dst, BUS);
157 dst = mov_rr(dst, reg_a, reg_b, inst->extra.size);
158 dst = mov_i8r(dst, 0, FLAG_V);
159 dst = mov_i8r(dst, 0, FLAG_C);
160 switch (inst->extra.size)
161 {
162 case OPSIZE_BYTE:
163 dst = cmp_i8r(dst, 0, reg_b, SZ_B);
164 break;
165 case OPSIZE_WORD:
166 dst = cmp_i8r(dst, 0, reg_b, SZ_W);
167 break;
168 case OPSIZE_LONG:
169 dst = cmp_i8r(dst, 0, reg_b, SZ_D);
170 break;
171 }
172 dst = setcc_r(dst, CC_Z, FLAG_Z);
173 dst = setcc_r(dst, CC_S, FLAG_N);
174 dst = check_cycles(dst);
175 } else if(reg_a >= 0 || reg_b >= 0) {
176 if (reg_a >= 0) {
177 switch (inst->dst.addr_mode)
178 {
179 case MODE_REG:
180 dst = cycles(dst, BUS);
181 dst = mov_rr(dst, reg_a, reg_b, inst->extra.size);
182 dst = check_cycles(dst);
183 break;
184 case MODE_AREG:
185 break;
186 }
187 } else {
188 }
189 }
190 break;
191 case M68K_MOVE_CCR:
192 case M68K_MOVE_FROM_SR:
193 case M68K_MOVE_SR:
194 case M68K_MOVE_USP:
195 case M68K_MOVEM:
196 case M68K_MOVEP:
197 case M68K_MULS:
198 case M68K_MULU:
199 case M68K_NBCD:
200 case M68K_NEG:
201 case M68K_NEGX:
202 case M68K_NOP:
203 case M68K_NOT:
204 case M68K_OR:
205 case M68K_ORI_CCR:
206 case M68K_ORI_SR:
207 case M68K_PEA:
208 case M68K_RESET:
209 case M68K_ROL:
210 case M68K_ROR:
211 case M68K_ROXL:
212 case M68K_ROXR:
213 case M68K_RTE:
214 case M68K_RTR:
215 case M68K_RTS:
216 case M68K_SBCD:
217 case M68K_SCC:
218 case M68K_STOP:
219 case M68K_SUB:
220 case M68K_SUBX:
221 case M68K_SWAP:
222 case M68K_TAS:
223 case M68K_TRAP:
224 case M68K_TRAPV:
225 case M68K_TST:
226 case M68K_UNLK:
227 case M68K_INVALID:
228 break;
229 }
230 }
231