comparison m68k_to_x86.c @ 558:dc9f178085a0

Use a typedef code_ptr in place of uint8_t * in 68K core to better support host instruction sets with different instruction word sizes. Make x86_68k_options contain a cpu_options so that gen_mem_fun can eventually be shared with the Z80 core.
author Mike Pavone <pavone@retrodev.com>
date Mon, 24 Feb 2014 01:30:16 -0800
parents acec5464fa1e
children 6b248602ab84 8e395210f50f
comparison
equal deleted inserted replaced
557:acec5464fa1e 558:dc9f178085a0
41 41
42 void m68k_invalid(); 42 void m68k_invalid();
43 void bcd_add(); 43 void bcd_add();
44 void bcd_sub(); 44 void bcd_sub();
45 45
46 uint8_t * cycles(uint8_t * dst, uint32_t num) 46 code_ptr cycles(code_ptr dst, uint32_t num)
47 { 47 {
48 dst = add_ir(dst, num, CYCLES, SZ_D); 48 dst = add_ir(dst, num, CYCLES, SZ_D);
49 return dst; 49 return dst;
50 } 50 }
51 51
52 uint8_t * check_cycles_int(uint8_t * dst, uint32_t address, x86_68k_options * opts) 52 code_ptr check_cycles_int(code_ptr dst, uint32_t address, x86_68k_options * opts)
53 { 53 {
54 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); 54 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
55 uint8_t * jmp_off = dst+1; 55 code_ptr jmp_off = dst+1;
56 dst = jcc(dst, CC_NC, dst + 7); 56 dst = jcc(dst, CC_NC, dst + 7);
57 dst = mov_ir(dst, address, SCRATCH1, SZ_D); 57 dst = mov_ir(dst, address, SCRATCH1, SZ_D);
58 dst = call(dst, opts->handle_cycle_limit_int); 58 dst = call(dst, opts->gen.handle_cycle_limit_int);
59 *jmp_off = dst - (jmp_off+1); 59 *jmp_off = dst - (jmp_off+1);
60 return dst; 60 return dst;
61 } 61 }
62 62
63 uint8_t * check_cycles(uint8_t * dst, x86_68k_options * opts) 63 code_ptr check_cycles(code_ptr dst, cpu_options * opts)
64 { 64 {
65 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); 65 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
66 uint8_t * jmp_off = dst+1; 66 code_ptr jmp_off = dst+1;
67 dst = jcc(dst, CC_NC, dst + 7); 67 dst = jcc(dst, CC_NC, dst + 7);
68 dst = call(dst, opts->handle_cycle_limit); 68 dst = call(dst, opts->handle_cycle_limit);
69 *jmp_off = dst - (jmp_off+1); 69 *jmp_off = dst - (jmp_off+1);
70 return dst; 70 return dst;
71 } 71 }
72 72
73 uint8_t * set_flag(uint8_t * dst, uint8_t val, uint8_t flag, x86_68k_options * opts) 73 code_ptr set_flag(code_ptr dst, uint8_t val, uint8_t flag, x86_68k_options * opts)
74 { 74 {
75 if (opts->flag_regs[flag] >= 0) { 75 if (opts->flag_regs[flag] >= 0) {
76 dst = mov_ir(dst, val, opts->flag_regs[flag], SZ_B); 76 dst = mov_ir(dst, val, opts->flag_regs[flag], SZ_B);
77 } else { 77 } else {
78 int8_t offset = offsetof(m68k_context, flags) + flag; 78 int8_t offset = offsetof(m68k_context, flags) + flag;
84 } 84 }
85 85
86 return dst; 86 return dst;
87 } 87 }
88 88
89 uint8_t * set_flag_cond(uint8_t * dst, uint8_t cond, uint8_t flag, x86_68k_options *opts) 89 code_ptr set_flag_cond(code_ptr dst, uint8_t cond, uint8_t flag, x86_68k_options *opts)
90 { 90 {
91 if (opts->flag_regs[flag] >= 0) { 91 if (opts->flag_regs[flag] >= 0) {
92 dst = setcc_r(dst, cond, opts->flag_regs[flag]); 92 dst = setcc_r(dst, cond, opts->flag_regs[flag]);
93 } else { 93 } else {
94 int8_t offset = offsetof(m68k_context, flags) + flag; 94 int8_t offset = offsetof(m68k_context, flags) + flag;
100 } 100 }
101 101
102 return dst; 102 return dst;
103 } 103 }
104 104
105 uint8_t * check_flag(uint8_t *dst, uint8_t flag, x86_68k_options *opts) 105 code_ptr check_flag(code_ptr dst, uint8_t flag, x86_68k_options *opts)
106 { 106 {
107 if (opts->flag_regs[flag] >= 0) { 107 if (opts->flag_regs[flag] >= 0) {
108 dst = cmp_ir(dst, 0, opts->flag_regs[flag], SZ_B); 108 dst = cmp_ir(dst, 0, opts->flag_regs[flag], SZ_B);
109 } else { 109 } else {
110 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B); 110 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B);
111 } 111 }
112 return dst; 112 return dst;
113 } 113 }
114 114
115 uint8_t * flag_to_reg(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts) 115 code_ptr flag_to_reg(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
116 { 116 {
117 if (opts->flag_regs[flag] >= 0) { 117 if (opts->flag_regs[flag] >= 0) {
118 dst = mov_rr(dst, opts->flag_regs[flag], reg, SZ_B); 118 dst = mov_rr(dst, opts->flag_regs[flag], reg, SZ_B);
119 } else { 119 } else {
120 int8_t offset = offsetof(m68k_context, flags) + flag; 120 int8_t offset = offsetof(m68k_context, flags) + flag;
125 } 125 }
126 } 126 }
127 return dst; 127 return dst;
128 } 128 }
129 129
130 uint8_t * reg_to_flag(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts) 130 code_ptr reg_to_flag(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
131 { 131 {
132 if (opts->flag_regs[flag] >= 0) { 132 if (opts->flag_regs[flag] >= 0) {
133 dst = mov_rr(dst, reg, opts->flag_regs[flag], SZ_B); 133 dst = mov_rr(dst, reg, opts->flag_regs[flag], SZ_B);
134 } else { 134 } else {
135 int8_t offset = offsetof(m68k_context, flags) + flag; 135 int8_t offset = offsetof(m68k_context, flags) + flag;
140 } 140 }
141 } 141 }
142 return dst; 142 return dst;
143 } 143 }
144 144
145 uint8_t * flag_to_flag(uint8_t *dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts) 145 code_ptr flag_to_flag(code_ptr dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts)
146 { 146 {
147 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { 147 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) {
148 dst = mov_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); 148 dst = mov_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B);
149 } else if(opts->flag_regs[flag1] >= 0) { 149 } else if(opts->flag_regs[flag1] >= 0) {
150 dst = mov_rrdisp8(dst, opts->flag_regs[flag1], CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B); 150 dst = mov_rrdisp8(dst, opts->flag_regs[flag1], CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B);
157 dst = pop_r(dst, SCRATCH1); 157 dst = pop_r(dst, SCRATCH1);
158 } 158 }
159 return dst; 159 return dst;
160 } 160 }
161 161
162 uint8_t * flag_to_carry(uint8_t *dst, uint8_t flag, x86_68k_options * opts) 162 code_ptr flag_to_carry(code_ptr dst, uint8_t flag, x86_68k_options * opts)
163 { 163 {
164 if (opts->flag_regs[flag] >= 0) { 164 if (opts->flag_regs[flag] >= 0) {
165 dst = bt_ir(dst, 0, opts->flag_regs[flag], SZ_B); 165 dst = bt_ir(dst, 0, opts->flag_regs[flag], SZ_B);
166 } else { 166 } else {
167 dst = bt_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B); 167 dst = bt_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B);
168 } 168 }
169 return dst; 169 return dst;
170 } 170 }
171 171
172 uint8_t * or_flag_to_reg(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts) 172 code_ptr or_flag_to_reg(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
173 { 173 {
174 if (opts->flag_regs[flag] >= 0) { 174 if (opts->flag_regs[flag] >= 0) {
175 dst = or_rr(dst, opts->flag_regs[flag], reg, SZ_B); 175 dst = or_rr(dst, opts->flag_regs[flag], reg, SZ_B);
176 } else { 176 } else {
177 dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B); 177 dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B);
178 } 178 }
179 return dst; 179 return dst;
180 } 180 }
181 181
182 uint8_t * xor_flag_to_reg(uint8_t *dst, uint8_t flag, uint8_t reg, x86_68k_options *opts) 182 code_ptr xor_flag_to_reg(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
183 { 183 {
184 if (opts->flag_regs[flag] >= 0) { 184 if (opts->flag_regs[flag] >= 0) {
185 dst = xor_rr(dst, opts->flag_regs[flag], reg, SZ_B); 185 dst = xor_rr(dst, opts->flag_regs[flag], reg, SZ_B);
186 } else { 186 } else {
187 dst = xor_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B); 187 dst = xor_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B);
188 } 188 }
189 return dst; 189 return dst;
190 } 190 }
191 191
192 uint8_t * xor_flag(uint8_t *dst, uint8_t val, uint8_t flag, x86_68k_options *opts) 192 code_ptr xor_flag(code_ptr dst, uint8_t val, uint8_t flag, x86_68k_options *opts)
193 { 193 {
194 if (opts->flag_regs[flag] >= 0) { 194 if (opts->flag_regs[flag] >= 0) {
195 dst = xor_ir(dst, val, opts->flag_regs[flag], SZ_B); 195 dst = xor_ir(dst, val, opts->flag_regs[flag], SZ_B);
196 } else { 196 } else {
197 dst = xor_irdisp8(dst, val, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B); 197 dst = xor_irdisp8(dst, val, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B);
198 } 198 }
199 return dst; 199 return dst;
200 } 200 }
201 201
202 uint8_t * cmp_flags(uint8_t *dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts) 202 code_ptr cmp_flags(code_ptr dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts)
203 { 203 {
204 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { 204 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) {
205 dst = cmp_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); 205 dst = cmp_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B);
206 } else if(opts->flag_regs[flag1] >= 0 || opts->flag_regs[flag2] >= 0) { 206 } else if(opts->flag_regs[flag1] >= 0 || opts->flag_regs[flag2] >= 0) {
207 if (opts->flag_regs[flag2] >= 0) { 207 if (opts->flag_regs[flag2] >= 0) {
247 printf("a%d: %X\n", i, context->aregs[i]); 247 printf("a%d: %X\n", i, context->aregs[i]);
248 } 248 }
249 exit(0); 249 exit(0);
250 } 250 }
251 251
252 uint8_t * translate_m68k_src(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts) 252 code_ptr translate_m68k_src(m68kinst * inst, x86_ea * ea, code_ptr out, x86_68k_options * opts)
253 { 253 {
254 int8_t reg = native_reg(&(inst->src), opts); 254 int8_t reg = native_reg(&(inst->src), opts);
255 uint8_t sec_reg; 255 uint8_t sec_reg;
256 int32_t dec_amount,inc_amount; 256 int32_t dec_amount,inc_amount;
257 if (reg >= 0) { 257 if (reg >= 0) {
526 ea->base = SCRATCH1; 526 ea->base = SCRATCH1;
527 } 527 }
528 return out; 528 return out;
529 } 529 }
530 530
531 uint8_t * translate_m68k_dst(m68kinst * inst, x86_ea * ea, uint8_t * out, x86_68k_options * opts, uint8_t fake_read) 531 code_ptr translate_m68k_dst(m68kinst * inst, x86_ea * ea, code_ptr out, x86_68k_options * opts, uint8_t fake_read)
532 { 532 {
533 int8_t reg = native_reg(&(inst->dst), opts), sec_reg; 533 int8_t reg = native_reg(&(inst->dst), opts), sec_reg;
534 int32_t dec_amount, inc_amount; 534 int32_t dec_amount, inc_amount;
535 if (reg >= 0) { 535 if (reg >= 0) {
536 ea->mode = MODE_REG_DIRECT; 536 ea->mode = MODE_REG_DIRECT;
801 exit(1); 801 exit(1);
802 } 802 }
803 return out; 803 return out;
804 } 804 }
805 805
806 uint8_t * m68k_save_result(m68kinst * inst, uint8_t * out, x86_68k_options * opts) 806 code_ptr m68k_save_result(m68kinst * inst, code_ptr out, x86_68k_options * opts)
807 { 807 {
808 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) { 808 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) {
809 if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) { 809 if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) {
810 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 810 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
811 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 811 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D);
827 } 827 }
828 } 828 }
829 return out; 829 return out;
830 } 830 }
831 831
832 uint8_t * get_native_address(native_map_slot * native_code_map, uint32_t address) 832 code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
833 { 833 {
834 address &= 0xFFFFFF; 834 address &= 0xFFFFFF;
835 address /= 2; 835 address /= 2;
836 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 836 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
837 if (!native_code_map[chunk].base) { 837 if (!native_code_map[chunk].base) {
842 return NULL; 842 return NULL;
843 } 843 }
844 return native_code_map[chunk].base + native_code_map[chunk].offsets[offset]; 844 return native_code_map[chunk].base + native_code_map[chunk].offsets[offset];
845 } 845 }
846 846
847 uint8_t * get_native_from_context(m68k_context * context, uint32_t address) 847 code_ptr get_native_from_context(m68k_context * context, uint32_t address)
848 { 848 {
849 return get_native_address(context->native_code_map, address); 849 return get_native_address(context->native_code_map, address);
850 } 850 }
851 851
852 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address) 852 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
867 offset = address % NATIVE_CHUNK_SIZE; 867 offset = address % NATIVE_CHUNK_SIZE;
868 } 868 }
869 return address*2; 869 return address*2;
870 } 870 }
871 871
872 void map_native_address(m68k_context * context, uint32_t address, uint8_t * native_addr, uint8_t size, uint8_t native_size) 872 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size)
873 { 873 {
874 native_map_slot * native_code_map = context->native_code_map; 874 native_map_slot * native_code_map = context->native_code_map;
875 x86_68k_options * opts = context->options; 875 x86_68k_options * opts = context->options;
876 address &= 0xFFFFFF; 876 address &= 0xFFFFFF;
877 if (address > 0xE00000) { 877 if (address > 0xE00000) {
878 context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11); 878 context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11);
879 if (((address & 0x3FFF) + size) & 0xC000) { 879 if (((address & 0x3FFF) + size) & 0xC000) {
880 context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11); 880 context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11);
881 } 881 }
882 uint32_t slot = (address & 0xFFFF)/1024; 882 uint32_t slot = (address & 0xFFFF)/1024;
883 if (!opts->ram_inst_sizes[slot]) { 883 if (!opts->gen.ram_inst_sizes[slot]) {
884 opts->ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); 884 opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512);
885 } 885 }
886 opts->ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size; 886 opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size;
887 } 887 }
888 address/= 2; 888 address/= 2;
889 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 889 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
890 if (!native_code_map[chunk].base) { 890 if (!native_code_map[chunk].base) {
891 native_code_map[chunk].base = native_addr; 891 native_code_map[chunk].base = native_addr;
910 { 910 {
911 if (address < 0xE00000) { 911 if (address < 0xE00000) {
912 return 0; 912 return 0;
913 } 913 }
914 uint32_t slot = (address & 0xFFFF)/1024; 914 uint32_t slot = (address & 0xFFFF)/1024;
915 return opts->ram_inst_sizes[slot][((address & 0xFFFF)/2)%512]; 915 return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512];
916 } 916 }
917 917
918 uint8_t * translate_m68k_move(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 918 code_ptr translate_m68k_move(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
919 { 919 {
920 int8_t reg, flags_reg, sec_reg; 920 int8_t reg, flags_reg, sec_reg;
921 uint8_t dir = 0; 921 uint8_t dir = 0;
922 int32_t offset; 922 int32_t offset;
923 int32_t inc_amount, dec_amount; 923 int32_t inc_amount, dec_amount;
1274 //add cycles for prefetch 1274 //add cycles for prefetch
1275 dst = cycles(dst, BUS); 1275 dst = cycles(dst, BUS);
1276 return dst; 1276 return dst;
1277 } 1277 }
1278 1278
1279 uint8_t * translate_m68k_movem(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1279 code_ptr translate_m68k_movem(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1280 { 1280 {
1281 int8_t bit,reg,sec_reg; 1281 int8_t bit,reg,sec_reg;
1282 uint8_t early_cycles; 1282 uint8_t early_cycles;
1283 if(inst->src.addr_mode == MODE_REG) { 1283 if(inst->src.addr_mode == MODE_REG) {
1284 //reg to mem 1284 //reg to mem
1602 //prefetch 1602 //prefetch
1603 dst = cycles(dst, 4); 1603 dst = cycles(dst, 4);
1604 return dst; 1604 return dst;
1605 } 1605 }
1606 1606
1607 uint8_t * translate_m68k_clr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1607 code_ptr translate_m68k_clr(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1608 { 1608 {
1609 dst = set_flag(dst, 0, FLAG_N, opts); 1609 dst = set_flag(dst, 0, FLAG_N, opts);
1610 dst = set_flag(dst, 0, FLAG_V, opts); 1610 dst = set_flag(dst, 0, FLAG_V, opts);
1611 dst = set_flag(dst, 0, FLAG_C, opts); 1611 dst = set_flag(dst, 0, FLAG_C, opts);
1612 dst = set_flag(dst, 1, FLAG_Z, opts); 1612 dst = set_flag(dst, 1, FLAG_Z, opts);
1624 } 1624 }
1625 dst = m68k_save_result(inst, dst, opts); 1625 dst = m68k_save_result(inst, dst, opts);
1626 return dst; 1626 return dst;
1627 } 1627 }
1628 1628
1629 uint8_t * translate_m68k_ext(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1629 code_ptr translate_m68k_ext(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1630 { 1630 {
1631 x86_ea dst_op; 1631 x86_ea dst_op;
1632 uint8_t dst_size = inst->extra.size; 1632 uint8_t dst_size = inst->extra.size;
1633 inst->extra.size--; 1633 inst->extra.size--;
1634 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); 1634 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0);
1647 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 1647 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
1648 //M68K EXT only operates on registers so no need for a call to save result here 1648 //M68K EXT only operates on registers so no need for a call to save result here
1649 return dst; 1649 return dst;
1650 } 1650 }
1651 1651
1652 uint8_t * translate_m68k_lea(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1652 code_ptr translate_m68k_lea(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1653 { 1653 {
1654 int8_t dst_reg = native_reg(&(inst->dst), opts), sec_reg; 1654 int8_t dst_reg = native_reg(&(inst->dst), opts), sec_reg;
1655 switch(inst->src.addr_mode) 1655 switch(inst->src.addr_mode)
1656 { 1656 {
1657 case MODE_AREG_INDIRECT: 1657 case MODE_AREG_INDIRECT:
1807 exit(1); 1807 exit(1);
1808 } 1808 }
1809 return dst; 1809 return dst;
1810 } 1810 }
1811 1811
1812 uint8_t * translate_m68k_pea(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1812 code_ptr translate_m68k_pea(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1813 { 1813 {
1814 uint8_t sec_reg; 1814 uint8_t sec_reg;
1815 switch(inst->src.addr_mode) 1815 switch(inst->src.addr_mode)
1816 { 1816 {
1817 case MODE_AREG_INDIRECT: 1817 case MODE_AREG_INDIRECT:
1891 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1891 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1892 dst = call(dst, opts->write_32_lowfirst); 1892 dst = call(dst, opts->write_32_lowfirst);
1893 return dst; 1893 return dst;
1894 } 1894 }
1895 1895
1896 uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1896 code_ptr translate_m68k_bsr(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1897 { 1897 {
1898 int32_t disp = inst->src.params.immed; 1898 int32_t disp = inst->src.params.immed;
1899 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4); 1899 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4);
1900 //TODO: Add cycles in the right place relative to pushing the return address on the stack 1900 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1901 dst = cycles(dst, 10); 1901 dst = cycles(dst, 10);
1902 dst = mov_ir(dst, after, SCRATCH1, SZ_D); 1902 dst = mov_ir(dst, after, SCRATCH1, SZ_D);
1903 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1903 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1904 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1904 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1905 dst = call(dst, opts->write_32_highfirst); 1905 dst = call(dst, opts->write_32_highfirst);
1906 uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp); 1906 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, (inst->address+2) + disp);
1907 if (!dest_addr) { 1907 if (!dest_addr) {
1908 opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1); 1908 opts->gen.deferred = defer_address(opts->gen.deferred, (inst->address+2) + disp, dst + 1);
1909 //dummy address to be replaced later 1909 //dummy address to be replaced later
1910 dest_addr = dst + 256; 1910 dest_addr = dst + 256;
1911 } 1911 }
1912 dst = jmp(dst, (char *)dest_addr); 1912 dst = jmp(dst, (char *)dest_addr);
1913 return dst; 1913 return dst;
1914 } 1914 }
1915 1915
1916 uint8_t * translate_m68k_bcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1916 code_ptr translate_m68k_bcc(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1917 { 1917 {
1918 dst = cycles(dst, 10);//TODO: Adjust this for branch not taken case 1918 dst = cycles(dst, 10);//TODO: Adjust this for branch not taken case
1919 int32_t disp = inst->src.params.immed; 1919 int32_t disp = inst->src.params.immed;
1920 uint32_t after = inst->address + 2; 1920 uint32_t after = inst->address + 2;
1921 uint8_t * dest_addr = get_native_address(opts->native_code_map, after + disp); 1921 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + disp);
1922 if (inst->extra.cond == COND_TRUE) { 1922 if (inst->extra.cond == COND_TRUE) {
1923 if (!dest_addr) { 1923 if (!dest_addr) {
1924 opts->deferred = defer_address(opts->deferred, after + disp, dst + 1); 1924 opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, dst + 1);
1925 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1925 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1926 dest_addr = dst + 256; 1926 dest_addr = dst + 256;
1927 } 1927 }
1928 dst = jmp(dst, dest_addr); 1928 dst = jmp(dst, dest_addr);
1929 } else { 1929 } else {
1968 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts); 1968 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
1969 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts); 1969 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
1970 break; 1970 break;
1971 } 1971 }
1972 if (!dest_addr) { 1972 if (!dest_addr) {
1973 opts->deferred = defer_address(opts->deferred, after + disp, dst + 2); 1973 opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, dst + 2);
1974 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1974 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1975 dest_addr = dst + 256; 1975 dest_addr = dst + 256;
1976 } 1976 }
1977 dst = jcc(dst, cond, dest_addr); 1977 dst = jcc(dst, cond, dest_addr);
1978 } 1978 }
1979 return dst; 1979 return dst;
1980 } 1980 }
1981 1981
1982 uint8_t * translate_m68k_scc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1982 code_ptr translate_m68k_scc(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
1983 { 1983 {
1984 uint8_t cond = inst->extra.cond; 1984 uint8_t cond = inst->extra.cond;
1985 x86_ea dst_op; 1985 x86_ea dst_op;
1986 inst->extra.size = OPSIZE_BYTE; 1986 inst->extra.size = OPSIZE_BYTE;
1987 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 1); 1987 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 1);
2037 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts); 2037 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts);
2038 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts); 2038 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
2039 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts); 2039 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
2040 break; 2040 break;
2041 } 2041 }
2042 uint8_t *true_off = dst + 1; 2042 code_ptr true_off = dst + 1;
2043 dst = jcc(dst, cc, dst+2); 2043 dst = jcc(dst, cc, dst+2);
2044 dst = cycles(dst, BUS); 2044 dst = cycles(dst, BUS);
2045 if (dst_op.mode == MODE_REG_DIRECT) { 2045 if (dst_op.mode == MODE_REG_DIRECT) {
2046 dst = mov_ir(dst, 0, dst_op.base, SZ_B); 2046 dst = mov_ir(dst, 0, dst_op.base, SZ_B);
2047 } else { 2047 } else {
2048 dst = mov_irdisp8(dst, 0, dst_op.base, dst_op.disp, SZ_B); 2048 dst = mov_irdisp8(dst, 0, dst_op.base, dst_op.disp, SZ_B);
2049 } 2049 }
2050 uint8_t *end_off = dst+1; 2050 code_ptr end_off = dst+1;
2051 dst = jmp(dst, dst+2); 2051 dst = jmp(dst, dst+2);
2052 *true_off = dst - (true_off+1); 2052 *true_off = dst - (true_off+1);
2053 dst = cycles(dst, 6); 2053 dst = cycles(dst, 6);
2054 if (dst_op.mode == MODE_REG_DIRECT) { 2054 if (dst_op.mode == MODE_REG_DIRECT) {
2055 dst = mov_ir(dst, 0xFF, dst_op.base, SZ_B); 2055 dst = mov_ir(dst, 0xFF, dst_op.base, SZ_B);
2060 } 2060 }
2061 dst = m68k_save_result(inst, dst, opts); 2061 dst = m68k_save_result(inst, dst, opts);
2062 return dst; 2062 return dst;
2063 } 2063 }
2064 2064
2065 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2065 code_ptr translate_m68k_jmp(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2066 { 2066 {
2067 uint8_t * dest_addr, sec_reg; 2067 code_ptr dest_addr;
2068 uint8_t sec_reg;
2068 uint32_t m68k_addr; 2069 uint32_t m68k_addr;
2069 switch(inst->src.addr_mode) 2070 switch(inst->src.addr_mode)
2070 { 2071 {
2071 case MODE_AREG_INDIRECT: 2072 case MODE_AREG_INDIRECT:
2072 dst = cycles(dst, BUS*2); 2073 dst = cycles(dst, BUS*2);
2126 break; 2127 break;
2127 case MODE_PC_DISPLACE: 2128 case MODE_PC_DISPLACE:
2128 dst = cycles(dst, 10); 2129 dst = cycles(dst, 10);
2129 m68k_addr = inst->src.params.regs.displacement + inst->address + 2; 2130 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
2130 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2131 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2131 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 2132 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2132 if (!dest_addr) { 2133 if (!dest_addr) {
2133 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2134 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1);
2134 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2135 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2135 dest_addr = dst + 256; 2136 dest_addr = dst + 256;
2136 } 2137 }
2137 dst = jmp(dst, dest_addr); 2138 dst = jmp(dst, dest_addr);
2138 } else { 2139 } else {
2184 case MODE_ABSOLUTE: 2185 case MODE_ABSOLUTE:
2185 case MODE_ABSOLUTE_SHORT: 2186 case MODE_ABSOLUTE_SHORT:
2186 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); 2187 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
2187 m68k_addr = inst->src.params.immed; 2188 m68k_addr = inst->src.params.immed;
2188 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2189 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2189 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 2190 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2190 if (!dest_addr) { 2191 if (!dest_addr) {
2191 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2192 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1);
2192 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2193 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2193 dest_addr = dst + 256; 2194 dest_addr = dst + 256;
2194 } 2195 }
2195 dst = jmp(dst, dest_addr); 2196 dst = jmp(dst, dest_addr);
2196 } else { 2197 } else {
2205 exit(1); 2206 exit(1);
2206 } 2207 }
2207 return dst; 2208 return dst;
2208 } 2209 }
2209 2210
2210 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2211 code_ptr translate_m68k_jsr(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2211 { 2212 {
2212 uint8_t * dest_addr, sec_reg; 2213 code_ptr dest_addr;
2214 uint8_t sec_reg;
2213 uint32_t after; 2215 uint32_t after;
2214 uint32_t m68k_addr; 2216 uint32_t m68k_addr;
2215 switch(inst->src.addr_mode) 2217 switch(inst->src.addr_mode)
2216 { 2218 {
2217 case MODE_AREG_INDIRECT: 2219 case MODE_AREG_INDIRECT:
2298 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2300 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2299 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2301 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2300 dst = call(dst, opts->write_32_highfirst); 2302 dst = call(dst, opts->write_32_highfirst);
2301 m68k_addr = inst->src.params.regs.displacement + inst->address + 2; 2303 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
2302 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2304 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2303 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 2305 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2304 if (!dest_addr) { 2306 if (!dest_addr) {
2305 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2307 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1);
2306 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2308 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2307 dest_addr = dst + 256; 2309 dest_addr = dst + 256;
2308 } 2310 }
2309 dst = jmp(dst, dest_addr); 2311 dst = jmp(dst, dest_addr);
2310 } else { 2312 } else {
2365 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2367 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2366 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2368 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2367 dst = call(dst, opts->write_32_highfirst); 2369 dst = call(dst, opts->write_32_highfirst);
2368 m68k_addr = inst->src.params.immed; 2370 m68k_addr = inst->src.params.immed;
2369 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2371 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2370 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 2372 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2371 if (!dest_addr) { 2373 if (!dest_addr) {
2372 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 2374 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1);
2373 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2375 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2374 dest_addr = dst + 256; 2376 dest_addr = dst + 256;
2375 } 2377 }
2376 dst = jmp(dst, dest_addr); 2378 dst = jmp(dst, dest_addr);
2377 } else { 2379 } else {
2386 exit(1); 2388 exit(1);
2387 } 2389 }
2388 return dst; 2390 return dst;
2389 } 2391 }
2390 2392
2391 uint8_t * translate_m68k_rts(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2393 code_ptr translate_m68k_rts(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2392 { 2394 {
2393 //TODO: Add cycles 2395 //TODO: Add cycles
2394 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 2396 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
2395 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 2397 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
2396 dst = call(dst, opts->read_32); 2398 dst = call(dst, opts->read_32);
2397 dst = call(dst, opts->native_addr); 2399 dst = call(dst, opts->native_addr);
2398 dst = jmp_r(dst, SCRATCH1); 2400 dst = jmp_r(dst, SCRATCH1);
2399 return dst; 2401 return dst;
2400 } 2402 }
2401 2403
2402 uint8_t * translate_m68k_dbcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2404 code_ptr translate_m68k_dbcc(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2403 { 2405 {
2404 //best case duration 2406 //best case duration
2405 dst = cycles(dst, 10); 2407 dst = cycles(dst, 10);
2406 uint8_t * skip_loc = NULL; 2408 code_ptr skip_loc = NULL;
2407 //TODO: Check if COND_TRUE technically valid here even though 2409 //TODO: Check if COND_TRUE technically valid here even though
2408 //it's basically a slow NOP 2410 //it's basically a slow NOP
2409 if (inst->extra.cond != COND_FALSE) { 2411 if (inst->extra.cond != COND_FALSE) {
2410 uint8_t cond = CC_NZ; 2412 uint8_t cond = CC_NZ;
2411 switch (inst->extra.cond) 2413 switch (inst->extra.cond)
2457 dst = cmp_ir(dst, -1, opts->dregs[inst->dst.params.regs.pri], SZ_W); 2459 dst = cmp_ir(dst, -1, opts->dregs[inst->dst.params.regs.pri], SZ_W);
2458 } else { 2460 } else {
2459 dst = sub_irdisp8(dst, 1, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W); 2461 dst = sub_irdisp8(dst, 1, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W);
2460 dst = cmp_irdisp8(dst, -1, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W); 2462 dst = cmp_irdisp8(dst, -1, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W);
2461 } 2463 }
2462 uint8_t *loop_end_loc = dst+1; 2464 code_ptr loop_end_loc = dst+1;
2463 dst = jcc(dst, CC_Z, dst+2); 2465 dst = jcc(dst, CC_Z, dst+2);
2464 uint32_t after = inst->address + 2; 2466 uint32_t after = inst->address + 2;
2465 uint8_t * dest_addr = get_native_address(opts->native_code_map, after + inst->src.params.immed); 2467 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + inst->src.params.immed);
2466 if (!dest_addr) { 2468 if (!dest_addr) {
2467 opts->deferred = defer_address(opts->deferred, after + inst->src.params.immed, dst + 1); 2469 opts->gen.deferred = defer_address(opts->gen.deferred, after + inst->src.params.immed, dst + 1);
2468 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2470 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2469 dest_addr = dst + 256; 2471 dest_addr = dst + 256;
2470 } 2472 }
2471 dst = jmp(dst, dest_addr); 2473 dst = jmp(dst, dest_addr);
2472 *loop_end_loc = dst - (loop_end_loc+1); 2474 *loop_end_loc = dst - (loop_end_loc+1);
2478 dst = cycles(dst, 4); 2480 dst = cycles(dst, 4);
2479 } 2481 }
2480 return dst; 2482 return dst;
2481 } 2483 }
2482 2484
2483 uint8_t * translate_m68k_link(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2485 code_ptr translate_m68k_link(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2484 { 2486 {
2485 int8_t reg = native_reg(&(inst->src), opts); 2487 int8_t reg = native_reg(&(inst->src), opts);
2486 //compensate for displacement word 2488 //compensate for displacement word
2487 dst = cycles(dst, BUS); 2489 dst = cycles(dst, BUS);
2488 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2490 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2502 //prefetch 2504 //prefetch
2503 dst = cycles(dst, BUS); 2505 dst = cycles(dst, BUS);
2504 return dst; 2506 return dst;
2505 } 2507 }
2506 2508
2507 uint8_t * translate_m68k_movep(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2509 code_ptr translate_m68k_movep(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2508 { 2510 {
2509 int8_t reg; 2511 int8_t reg;
2510 dst = cycles(dst, BUS*2); 2512 dst = cycles(dst, BUS*2);
2511 if (inst->src.addr_mode == MODE_REG) { 2513 if (inst->src.addr_mode == MODE_REG) {
2512 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 2514 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
2611 } 2613 }
2612 } 2614 }
2613 return dst; 2615 return dst;
2614 } 2616 }
2615 2617
2616 uint8_t * translate_m68k_cmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2618 code_ptr translate_m68k_cmp(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2617 { 2619 {
2618 uint8_t size = inst->extra.size; 2620 uint8_t size = inst->extra.size;
2619 x86_ea src_op, dst_op; 2621 x86_ea src_op, dst_op;
2620 dst = translate_m68k_src(inst, &src_op, dst, opts); 2622 dst = translate_m68k_src(inst, &src_op, dst, opts);
2621 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 2623 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
2650 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2652 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2651 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 2653 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
2652 return dst; 2654 return dst;
2653 } 2655 }
2654 2656
2655 typedef uint8_t * (*shift_ir_t)(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size); 2657 typedef code_ptr (*shift_ir_t)(code_ptr out, uint8_t val, uint8_t dst, uint8_t size);
2656 typedef uint8_t * (*shift_irdisp8_t)(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size); 2658 typedef code_ptr (*shift_irdisp8_t)(code_ptr out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size);
2657 typedef uint8_t * (*shift_clr_t)(uint8_t * out, uint8_t dst, uint8_t size); 2659 typedef code_ptr (*shift_clr_t)(code_ptr out, uint8_t dst, uint8_t size);
2658 typedef uint8_t * (*shift_clrdisp8_t)(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size); 2660 typedef code_ptr (*shift_clrdisp8_t)(code_ptr out, uint8_t dst_base, int8_t disp, uint8_t size);
2659 2661
2660 uint8_t * translate_shift(uint8_t * dst, m68kinst * inst, x86_ea *src_op, x86_ea * dst_op, x86_68k_options * opts, shift_ir_t shift_ir, shift_irdisp8_t shift_irdisp8, shift_clr_t shift_clr, shift_clrdisp8_t shift_clrdisp8, shift_ir_t special, shift_irdisp8_t special_disp8) 2662 code_ptr translate_shift(code_ptr dst, m68kinst * inst, x86_ea *src_op, x86_ea * dst_op, x86_68k_options * opts, shift_ir_t shift_ir, shift_irdisp8_t shift_irdisp8, shift_clr_t shift_clr, shift_clrdisp8_t shift_clrdisp8, shift_ir_t special, shift_irdisp8_t special_disp8)
2661 { 2663 {
2662 uint8_t * end_off = NULL; 2664 code_ptr end_off = NULL;
2663 uint8_t * nz_off = NULL; 2665 code_ptr nz_off = NULL;
2664 uint8_t * z_off = NULL; 2666 code_ptr z_off = NULL;
2665 if (inst->src.addr_mode == MODE_UNUSED) { 2667 if (inst->src.addr_mode == MODE_UNUSED) {
2666 dst = cycles(dst, BUS); 2668 dst = cycles(dst, BUS);
2667 //Memory shift 2669 //Memory shift
2668 dst = shift_ir(dst, 1, dst_op->base, SZ_W); 2670 dst = shift_ir(dst, 1, dst_op->base, SZ_W);
2669 } else { 2671 } else {
2676 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); 2678 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size);
2677 } else { 2679 } else {
2678 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); 2680 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size);
2679 } 2681 }
2680 //dst = setcc_r(dst, CC_O, FLAG_V); 2682 //dst = setcc_r(dst, CC_O, FLAG_V);
2681 uint8_t *after_flag_set = dst+1; 2683 code_ptr after_flag_set = dst+1;
2682 dst = jcc(dst, CC_NO, dst+2); 2684 dst = jcc(dst, CC_NO, dst+2);
2683 dst = set_flag(dst, 1, FLAG_V, opts); 2685 dst = set_flag(dst, 1, FLAG_V, opts);
2684 *after_flag_set = dst - (after_flag_set+1); 2686 *after_flag_set = dst - (after_flag_set+1);
2685 } 2687 }
2686 } else { 2688 } else {
2724 dst = add_rr(dst, RCX, CYCLES, SZ_D); 2726 dst = add_rr(dst, RCX, CYCLES, SZ_D);
2725 if (inst->op == M68K_ASL) { 2727 if (inst->op == M68K_ASL) {
2726 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB 2728 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB
2727 //Easiest way to deal with this is to shift one bit at a time 2729 //Easiest way to deal with this is to shift one bit at a time
2728 dst = set_flag(dst, 0, FLAG_V, opts); 2730 dst = set_flag(dst, 0, FLAG_V, opts);
2729 uint8_t * loop_start = dst; 2731 code_ptr loop_start = dst;
2730 if (dst_op->mode == MODE_REG_DIRECT) { 2732 if (dst_op->mode == MODE_REG_DIRECT) {
2731 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); 2733 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size);
2732 } else { 2734 } else {
2733 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); 2735 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size);
2734 } 2736 }
2735 //dst = setcc_r(dst, CC_O, FLAG_V); 2737 //dst = setcc_r(dst, CC_O, FLAG_V);
2736 uint8_t *after_flag_set = dst+1; 2738 code_ptr after_flag_set = dst+1;
2737 dst = jcc(dst, CC_NO, dst+2); 2739 dst = jcc(dst, CC_NO, dst+2);
2738 dst = set_flag(dst, 1, FLAG_V, opts); 2740 dst = set_flag(dst, 1, FLAG_V, opts);
2739 *after_flag_set = dst - (after_flag_set+1); 2741 *after_flag_set = dst - (after_flag_set+1);
2740 dst = loop(dst, loop_start); 2742 dst = loop(dst, loop_start);
2741 } else { 2743 } else {
2742 //x86 shifts modulo 32 for operand sizes less than 64-bits 2744 //x86 shifts modulo 32 for operand sizes less than 64-bits
2743 //but M68K shifts modulo 64, so we need to check for large shifts here 2745 //but M68K shifts modulo 64, so we need to check for large shifts here
2744 dst = cmp_ir(dst, 32, RCX, SZ_B); 2746 dst = cmp_ir(dst, 32, RCX, SZ_B);
2745 uint8_t * norm_shift_off = dst + 1; 2747 code_ptr norm_shift_off = dst + 1;
2746 dst = jcc(dst, CC_L, dst+2); 2748 dst = jcc(dst, CC_L, dst+2);
2747 if (special) { 2749 if (special) {
2748 uint8_t *after_flag_set = NULL; 2750 code_ptr after_flag_set = NULL;
2749 if (inst->extra.size == OPSIZE_LONG) { 2751 if (inst->extra.size == OPSIZE_LONG) {
2750 uint8_t * neq_32_off = dst + 1; 2752 code_ptr neq_32_off = dst + 1;
2751 dst = jcc(dst, CC_NZ, dst+2); 2753 dst = jcc(dst, CC_NZ, dst+2);
2752 2754
2753 //set the carry bit to the lsb 2755 //set the carry bit to the lsb
2754 if (dst_op->mode == MODE_REG_DIRECT) { 2756 if (dst_op->mode == MODE_REG_DIRECT) {
2755 dst = special(dst, 1, dst_op->base, SZ_D); 2757 dst = special(dst, 1, dst_op->base, SZ_D);
2821 return dst; 2823 return dst;
2822 } 2824 }
2823 2825
2824 #define BIT_SUPERVISOR 5 2826 #define BIT_SUPERVISOR 5
2825 2827
2826 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 2828 code_ptr translate_m68k(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2827 { 2829 {
2828 uint8_t * end_off, *zero_off, *norm_off; 2830 code_ptr end_off, zero_off, norm_off;
2829 uint8_t dst_reg; 2831 uint8_t dst_reg;
2830 dst = check_cycles_int(dst, inst->address, opts); 2832 dst = check_cycles_int(dst, inst->address, opts);
2831 if (inst->op == M68K_MOVE) { 2833 if (inst->op == M68K_MOVE) {
2832 return translate_m68k_move(dst, inst, opts); 2834 return translate_m68k_move(dst, inst, opts);
2833 } else if(inst->op == M68K_LEA) { 2835 } else if(inst->op == M68K_LEA) {
2861 } else if(inst->op == M68K_INVALID) { 2863 } else if(inst->op == M68K_INVALID) {
2862 if (inst->src.params.immed == 0x7100) { 2864 if (inst->src.params.immed == 0x7100) {
2863 return retn(dst); 2865 return retn(dst);
2864 } 2866 }
2865 dst = mov_ir(dst, inst->address, SCRATCH1, SZ_D); 2867 dst = mov_ir(dst, inst->address, SCRATCH1, SZ_D);
2866 return call(dst, (uint8_t *)m68k_invalid); 2868 return call(dst, (code_ptr)m68k_invalid);
2867 } else if(inst->op == M68K_CMP) { 2869 } else if(inst->op == M68K_CMP) {
2868 return translate_m68k_cmp(dst, inst, opts); 2870 return translate_m68k_cmp(dst, inst, opts);
2869 } 2871 }
2870 x86_ea src_op, dst_op; 2872 x86_ea src_op, dst_op;
2871 if (inst->src.addr_mode != MODE_UNUSED) { 2873 if (inst->src.addr_mode != MODE_UNUSED) {
2893 } 2895 }
2894 } 2896 }
2895 dst = flag_to_carry(dst, FLAG_X, opts); 2897 dst = flag_to_carry(dst, FLAG_X, opts);
2896 dst = jcc(dst, CC_NC, dst+5); 2898 dst = jcc(dst, CC_NC, dst+5);
2897 dst = add_ir(dst, 1, SCRATCH1, SZ_B); 2899 dst = add_ir(dst, 1, SCRATCH1, SZ_B);
2898 dst = call(dst, (uint8_t *)bcd_add); 2900 dst = call(dst, (code_ptr)bcd_add);
2899 dst = reg_to_flag(dst, CH, FLAG_C, opts); 2901 dst = reg_to_flag(dst, CH, FLAG_C, opts);
2900 dst = reg_to_flag(dst, CH, FLAG_X, opts); 2902 dst = reg_to_flag(dst, CH, FLAG_X, opts);
2901 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B); 2903 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B);
2902 dst = jcc(dst, CC_Z, dst+4); 2904 dst = jcc(dst, CC_Z, dst+4);
2903 dst = set_flag(dst, 0, FLAG_Z, opts); 2905 dst = set_flag(dst, 0, FLAG_Z, opts);
2959 dst = adc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2961 dst = adc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
2960 } 2962 }
2961 } 2963 }
2962 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 2964 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
2963 2965
2964 uint8_t *after_flag_set = dst+1; 2966 code_ptr after_flag_set = dst+1;
2965 dst = jcc(dst, CC_Z, dst+2); 2967 dst = jcc(dst, CC_Z, dst+2);
2966 dst = set_flag(dst, 0, FLAG_Z, opts); 2968 dst = set_flag(dst, 0, FLAG_Z, opts);
2967 *after_flag_set = dst - (after_flag_set+1); 2969 *after_flag_set = dst - (after_flag_set+1);
2968 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2970 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
2969 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 2971 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
3176 isize = 6; 3178 isize = 6;
3177 break; 3179 break;
3178 default: 3180 default:
3179 isize = 2; 3181 isize = 2;
3180 } 3182 }
3181 uint8_t * passed = dst+1; 3183 code_ptr passed = dst+1;
3182 dst = jcc(dst, CC_GE, dst+2); 3184 dst = jcc(dst, CC_GE, dst+2);
3183 dst = set_flag(dst, 1, FLAG_N, opts); 3185 dst = set_flag(dst, 1, FLAG_N, opts);
3184 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); 3186 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D);
3185 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); 3187 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D);
3186 dst = jmp(dst, opts->trap); 3188 dst = jmp(dst, opts->trap);
3237 } else { 3239 } else {
3238 dst = movzx_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_W, SZ_D); 3240 dst = movzx_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_W, SZ_D);
3239 } 3241 }
3240 } 3242 }
3241 dst = cmp_ir(dst, 0, SCRATCH2, SZ_D); 3243 dst = cmp_ir(dst, 0, SCRATCH2, SZ_D);
3242 uint8_t * not_zero = dst+1; 3244 code_ptr not_zero = dst+1;
3243 dst = jcc(dst, CC_NZ, dst+2); 3245 dst = jcc(dst, CC_NZ, dst+2);
3244 dst = pop_r(dst, RAX); 3246 dst = pop_r(dst, RAX);
3245 dst = pop_r(dst, RDX); 3247 dst = pop_r(dst, RDX);
3246 dst = mov_ir(dst, VECTOR_INT_DIV_ZERO, SCRATCH2, SZ_D); 3248 dst = mov_ir(dst, VECTOR_INT_DIV_ZERO, SCRATCH2, SZ_D);
3247 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 3249 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
3255 if (inst->op == M68K_DIVS) { 3257 if (inst->op == M68K_DIVS) {
3256 dst = idiv_r(dst, SCRATCH2, SZ_D); 3258 dst = idiv_r(dst, SCRATCH2, SZ_D);
3257 } else { 3259 } else {
3258 dst = div_r(dst, SCRATCH2, SZ_D); 3260 dst = div_r(dst, SCRATCH2, SZ_D);
3259 } 3261 }
3260 uint8_t * skip_sec_check; 3262 code_ptr skip_sec_check;
3261 if (inst->op == M68K_DIVS) { 3263 if (inst->op == M68K_DIVS) {
3262 dst = cmp_ir(dst, 0x8000, RAX, SZ_D); 3264 dst = cmp_ir(dst, 0x8000, RAX, SZ_D);
3263 skip_sec_check = dst + 1; 3265 skip_sec_check = dst + 1;
3264 dst = jcc(dst, CC_GE, dst+2); 3266 dst = jcc(dst, CC_GE, dst+2);
3265 dst = cmp_ir(dst, -0x8000, RAX, SZ_D); 3267 dst = cmp_ir(dst, -0x8000, RAX, SZ_D);
3368 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D); 3370 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D);
3369 } 3371 }
3370 } 3372 }
3371 break; 3373 break;
3372 case M68K_ILLEGAL: 3374 case M68K_ILLEGAL:
3373 dst = call(dst, opts->save_context); 3375 dst = call(dst, opts->gen.save_context);
3374 #ifdef X86_64 3376 #ifdef X86_64
3375 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 3377 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR);
3376 #else 3378 #else
3377 dst = push_r(dst, CONTEXT); 3379 dst = push_r(dst, CONTEXT);
3378 #endif 3380 #endif
3379 dst = call(dst, (uint8_t *)print_regs_exit); 3381 dst = call(dst, (code_ptr)print_regs_exit);
3380 break; 3382 break;
3381 case M68K_MOVE_FROM_SR: 3383 case M68K_MOVE_FROM_SR:
3382 //TODO: Trap if not in system mode 3384 //TODO: Trap if not in system mode
3383 dst = call(dst, opts->get_sr); 3385 dst = call(dst, opts->get_sr);
3384 if (dst_op.mode == MODE_REG_DIRECT) { 3386 if (dst_op.mode == MODE_REG_DIRECT) {
3525 dst = flag_to_carry(dst, FLAG_X, opts); 3527 dst = flag_to_carry(dst, FLAG_X, opts);
3526 dst = sbb_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size); 3528 dst = sbb_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size);
3527 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, inst->extra.size); 3529 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, inst->extra.size);
3528 } 3530 }
3529 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3531 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3530 uint8_t *after_flag_set = dst+1; 3532 code_ptr after_flag_set = dst+1;
3531 dst = jcc(dst, CC_Z, dst+2); 3533 dst = jcc(dst, CC_Z, dst+2);
3532 dst = set_flag(dst, 0, FLAG_Z, opts); 3534 dst = set_flag(dst, 0, FLAG_Z, opts);
3533 *after_flag_set = dst - (after_flag_set+1); 3535 *after_flag_set = dst - (after_flag_set+1);
3534 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3536 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3535 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 3537 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
3607 dst = call(dst, opts->do_sync); 3609 dst = call(dst, opts->do_sync);
3608 } 3610 }
3609 } 3611 }
3610 break; 3612 break;
3611 case M68K_RESET: 3613 case M68K_RESET:
3612 dst = call(dst, opts->save_context); 3614 dst = call(dst, opts->gen.save_context);
3613 #ifdef X86_64 3615 #ifdef X86_64
3614 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 3616 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR);
3615 #else 3617 #else
3616 dst = push_r(dst, CONTEXT); 3618 dst = push_r(dst, CONTEXT);
3617 #endif 3619 #endif
3618 dst = call(dst, (uint8_t *)print_regs_exit); 3620 dst = call(dst, (code_ptr)print_regs_exit);
3619 break; 3621 break;
3620 case M68K_ROL: 3622 case M68K_ROL:
3621 case M68K_ROR: 3623 case M68K_ROR:
3622 dst = set_flag(dst, 0, FLAG_V, opts); 3624 dst = set_flag(dst, 0, FLAG_V, opts);
3623 if (inst->src.addr_mode == MODE_UNUSED) { 3625 if (inst->src.addr_mode == MODE_UNUSED) {
3886 } 3888 }
3887 } 3889 }
3888 dst = flag_to_carry(dst, FLAG_X, opts); 3890 dst = flag_to_carry(dst, FLAG_X, opts);
3889 dst = jcc(dst, CC_NC, dst+5); 3891 dst = jcc(dst, CC_NC, dst+5);
3890 dst = sub_ir(dst, 1, SCRATCH1, SZ_B); 3892 dst = sub_ir(dst, 1, SCRATCH1, SZ_B);
3891 dst = call(dst, (uint8_t *)bcd_sub); 3893 dst = call(dst, (code_ptr)bcd_sub);
3892 dst = reg_to_flag(dst, CH, FLAG_C, opts); 3894 dst = reg_to_flag(dst, CH, FLAG_C, opts);
3893 dst = reg_to_flag(dst, CH, FLAG_X, opts); 3895 dst = reg_to_flag(dst, CH, FLAG_X, opts);
3894 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B); 3896 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B);
3895 uint8_t *after_flag_set = dst+1; 3897 code_ptr after_flag_set = dst+1;
3896 dst = jcc(dst, CC_Z, dst+2); 3898 dst = jcc(dst, CC_Z, dst+2);
3897 dst = set_flag(dst, 0, FLAG_Z, opts); 3899 dst = set_flag(dst, 0, FLAG_Z, opts);
3898 *after_flag_set = dst - (after_flag_set+1); 3900 *after_flag_set = dst - (after_flag_set+1);
3899 if (dst_op.base != SCRATCH1) { 3901 if (dst_op.base != SCRATCH1) {
3900 if (dst_op.mode == MODE_REG_DIRECT) { 3902 if (dst_op.mode == MODE_REG_DIRECT) {
3921 //leave supervisor mode 3923 //leave supervisor mode
3922 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3924 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
3923 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); 3925 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3924 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3926 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3925 } 3927 }
3926 uint8_t * loop_top = dst; 3928 code_ptr loop_top = dst;
3927 dst = call(dst, opts->do_sync); 3929 dst = call(dst, opts->do_sync);
3928 dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D); 3930 dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D);
3929 uint8_t * normal_cycle_up = dst + 1; 3931 code_ptr normal_cycle_up = dst + 1;
3930 dst = jcc(dst, CC_A, dst+2); 3932 dst = jcc(dst, CC_A, dst+2);
3931 dst = cycles(dst, BUS); 3933 dst = cycles(dst, BUS);
3932 uint8_t * after_cycle_up = dst + 1; 3934 code_ptr after_cycle_up = dst + 1;
3933 dst = jmp(dst, dst+2); 3935 dst = jmp(dst, dst+2);
3934 *normal_cycle_up = dst - (normal_cycle_up + 1); 3936 *normal_cycle_up = dst - (normal_cycle_up + 1);
3935 dst = mov_rr(dst, LIMIT, CYCLES, SZ_D); 3937 dst = mov_rr(dst, LIMIT, CYCLES, SZ_D);
3936 *after_cycle_up = dst - (after_cycle_up+1); 3938 *after_cycle_up = dst - (after_cycle_up+1);
3937 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); 3939 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
3989 } 3991 }
3990 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3992 dst = set_flag_cond(dst, CC_C, FLAG_C, opts);
3991 if (opts->flag_regs[FLAG_C] < 0) { 3993 if (opts->flag_regs[FLAG_C] < 0) {
3992 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3994 dst = set_flag_cond(dst, CC_C, FLAG_X, opts);
3993 } 3995 }
3994 uint8_t *after_flag_set = dst+1; 3996 code_ptr after_flag_set = dst+1;
3995 dst = jcc(dst, CC_Z, dst+2); 3997 dst = jcc(dst, CC_Z, dst+2);
3996 dst = set_flag(dst, 0, FLAG_Z, opts); 3998 dst = set_flag(dst, 0, FLAG_Z, opts);
3997 *after_flag_set = dst - (after_flag_set+1); 3999 *after_flag_set = dst - (after_flag_set+1);
3998 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 4000 dst = set_flag_cond(dst, CC_S, FLAG_N, opts);
3999 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 4001 dst = set_flag_cond(dst, CC_O, FLAG_V, opts);
4069 } 4071 }
4070 4072
4071 void m68k_handle_deferred(m68k_context * context) 4073 void m68k_handle_deferred(m68k_context * context)
4072 { 4074 {
4073 x86_68k_options * opts = context->options; 4075 x86_68k_options * opts = context->options;
4074 process_deferred(&opts->deferred, context, (native_addr_func)get_native_from_context); 4076 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
4075 if (opts->deferred) { 4077 if (opts->gen.deferred) {
4076 translate_m68k_stream(opts->deferred->address, context); 4078 translate_m68k_stream(opts->gen.deferred->address, context);
4077 } 4079 }
4078 } 4080 }
4079 4081
4080 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context) 4082 code_ptr translate_m68k_stream(uint32_t address, m68k_context * context)
4081 { 4083 {
4082 m68kinst instbuf; 4084 m68kinst instbuf;
4083 x86_68k_options * opts = context->options; 4085 x86_68k_options * opts = context->options;
4084 uint8_t * dst = opts->cur_code; 4086 code_ptr dst = opts->gen.cur_code;
4085 uint8_t * dst_end = opts->code_end; 4087 code_ptr dst_end = opts->gen.code_end;
4086 address &= 0xFFFFFF; 4088 address &= 0xFFFFFF;
4087 if(get_native_address(opts->native_code_map, address)) { 4089 if(get_native_address(opts->gen.native_code_map, address)) {
4088 return dst; 4090 return dst;
4089 } 4091 }
4090 char disbuf[1024]; 4092 char disbuf[1024];
4091 uint16_t *encoded, *next; 4093 uint16_t *encoded, *next;
4092 if ((address & 0xFFFFFF) < 0x400000) { 4094 if ((address & 0xFFFFFF) < 0x400000) {
4106 if (dst_end-dst < 5) { 4108 if (dst_end-dst < 5) {
4107 puts("out of code memory, not enough space for jmp to next chunk"); 4109 puts("out of code memory, not enough space for jmp to next chunk");
4108 exit(1); 4110 exit(1);
4109 } 4111 }
4110 size_t size = 1024*1024; 4112 size_t size = 1024*1024;
4111 opts->cur_code = alloc_code(&size); 4113 opts->gen.cur_code = alloc_code(&size);
4112 opts->code_end = opts->cur_code + size; 4114 opts->gen.code_end = opts->gen.cur_code + size;
4113 jmp(dst, opts->cur_code); 4115 jmp(dst, opts->gen.cur_code);
4114 dst = opts->cur_code; 4116 dst = opts->gen.cur_code;
4115 dst_end = opts->code_end; 4117 dst_end = opts->gen.code_end;
4116 } 4118 }
4117 if (address >= 0x400000 && address < 0xE00000) { 4119 if (address >= 0x400000 && address < 0xE00000) {
4118 dst = xor_rr(dst, RDI, RDI, SZ_D); 4120 dst = xor_rr(dst, RDI, RDI, SZ_D);
4119 #ifdef X86_32 4121 #ifdef X86_32
4120 dst = push_r(dst, RDI); 4122 dst = push_r(dst, RDI);
4121 #endif 4123 #endif
4122 dst = call(dst, (uint8_t *)exit); 4124 dst = call(dst, (code_ptr)exit);
4123 break; 4125 break;
4124 } 4126 }
4125 uint8_t * existing = get_native_address(opts->native_code_map, address); 4127 code_ptr existing = get_native_address(opts->gen.native_code_map, address);
4126 if (existing) { 4128 if (existing) {
4127 dst = jmp(dst, existing); 4129 dst = jmp(dst, existing);
4128 break; 4130 break;
4129 } 4131 }
4130 next = m68k_decode(encoded, &instbuf, address); 4132 next = m68k_decode(encoded, &instbuf, address);
4134 uint16_t m68k_size = (next-encoded)*2; 4136 uint16_t m68k_size = (next-encoded)*2;
4135 address += m68k_size; 4137 address += m68k_size;
4136 encoded = next; 4138 encoded = next;
4137 //m68k_disasm(&instbuf, disbuf); 4139 //m68k_disasm(&instbuf, disbuf);
4138 //printf("%X: %s\n", instbuf.address, disbuf); 4140 //printf("%X: %s\n", instbuf.address, disbuf);
4139 uint8_t * after = translate_m68k(dst, &instbuf, opts); 4141 code_ptr after = translate_m68k(dst, &instbuf, opts);
4140 map_native_address(context, instbuf.address, dst, m68k_size, after-dst); 4142 map_native_address(context, instbuf.address, dst, m68k_size, after-dst);
4141 dst = after; 4143 dst = after;
4142 } while(!m68k_is_terminal(&instbuf)); 4144 } while(!m68k_is_terminal(&instbuf));
4143 process_deferred(&opts->deferred, context, (native_addr_func)get_native_from_context); 4145 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
4144 if (opts->deferred) { 4146 if (opts->gen.deferred) {
4145 address = opts->deferred->address; 4147 address = opts->gen.deferred->address;
4146 if ((address & 0xFFFFFF) < 0x400000) { 4148 if ((address & 0xFFFFFF) < 0x400000) {
4147 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; 4149 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2;
4148 } else if ((address & 0xFFFFFF) > 0xE00000) { 4150 } else if ((address & 0xFFFFFF) > 0xE00000) {
4149 encoded = context->mem_pointers[1] + (address & 0xFFFF)/2; 4151 encoded = context->mem_pointers[1] + (address & 0xFFFF)/2;
4150 } else { 4152 } else {
4153 } 4155 }
4154 } else { 4156 } else {
4155 encoded = NULL; 4157 encoded = NULL;
4156 } 4158 }
4157 } while(encoded != NULL); 4159 } while(encoded != NULL);
4158 opts->cur_code = dst; 4160 opts->gen.cur_code = dst;
4159 return dst; 4161 return dst;
4160 } 4162 }
4161 4163
4162 uint8_t * get_native_address_trans(m68k_context * context, uint32_t address) 4164 code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
4163 { 4165 {
4164 address &= 0xFFFFFF; 4166 address &= 0xFFFFFF;
4165 uint8_t * ret = get_native_address(context->native_code_map, address); 4167 code_ptr ret = get_native_address(context->native_code_map, address);
4166 if (!ret) { 4168 if (!ret) {
4167 translate_m68k_stream(address, context); 4169 translate_m68k_stream(address, context);
4168 ret = get_native_address(context->native_code_map, address); 4170 ret = get_native_address(context->native_code_map, address);
4169 } 4171 }
4170 return ret; 4172 return ret;
4172 4174
4173 void * m68k_retranslate_inst(uint32_t address, m68k_context * context) 4175 void * m68k_retranslate_inst(uint32_t address, m68k_context * context)
4174 { 4176 {
4175 x86_68k_options * opts = context->options; 4177 x86_68k_options * opts = context->options;
4176 uint8_t orig_size = get_native_inst_size(opts, address); 4178 uint8_t orig_size = get_native_inst_size(opts, address);
4177 uint8_t * orig_start = get_native_address(context->native_code_map, address); 4179 code_ptr orig_start = get_native_address(context->native_code_map, address);
4178 uint32_t orig = address; 4180 uint32_t orig = address;
4179 address &= 0xFFFF; 4181 address &= 0xFFFF;
4180 uint8_t * dst = opts->cur_code; 4182 code_ptr dst = opts->gen.cur_code;
4181 uint8_t * dst_end = opts->code_end; 4183 code_ptr dst_end = opts->gen.code_end;
4182 uint16_t *after, *inst = context->mem_pointers[1] + address/2; 4184 uint16_t *after, *inst = context->mem_pointers[1] + address/2;
4183 m68kinst instbuf; 4185 m68kinst instbuf;
4184 after = m68k_decode(inst, &instbuf, orig); 4186 after = m68k_decode(inst, &instbuf, orig);
4185 if (orig_size != MAX_NATIVE_SIZE) { 4187 if (orig_size != MAX_NATIVE_SIZE) {
4186 if (dst_end - dst < 128) { 4188 if (dst_end - dst < 128) {
4187 size_t size = 1024*1024; 4189 size_t size = 1024*1024;
4188 dst = alloc_code(&size); 4190 dst = alloc_code(&size);
4189 opts->code_end = dst_end = dst + size; 4191 opts->gen.code_end = dst_end = dst + size;
4190 opts->cur_code = dst; 4192 opts->gen.cur_code = dst;
4191 } 4193 }
4192 deferred_addr * orig_deferred = opts->deferred; 4194 deferred_addr * orig_deferred = opts->gen.deferred;
4193 uint8_t * native_end = translate_m68k(dst, &instbuf, opts); 4195 code_ptr native_end = translate_m68k(dst, &instbuf, opts);
4194 uint8_t is_terminal = m68k_is_terminal(&instbuf); 4196 uint8_t is_terminal = m68k_is_terminal(&instbuf);
4195 if ((native_end - dst) <= orig_size) { 4197 if ((native_end - dst) <= orig_size) {
4196 uint8_t * native_next; 4198 code_ptr native_next;
4197 if (!is_terminal) { 4199 if (!is_terminal) {
4198 native_next = get_native_address(context->native_code_map, orig + (after-inst)*2); 4200 native_next = get_native_address(context->native_code_map, orig + (after-inst)*2);
4199 } 4201 }
4200 if (is_terminal || (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - dst)) > 5))) { 4202 if (is_terminal || (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - dst)) > 5))) {
4201 remove_deferred_until(&opts->deferred, orig_deferred); 4203 remove_deferred_until(&opts->gen.deferred, orig_deferred);
4202 native_end = translate_m68k(orig_start, &instbuf, opts); 4204 native_end = translate_m68k(orig_start, &instbuf, opts);
4203 if (!is_terminal) { 4205 if (!is_terminal) {
4204 if (native_next == orig_start + orig_size && (native_next-native_end) < 2) { 4206 if (native_next == orig_start + orig_size && (native_next-native_end) < 2) {
4205 while (native_end < orig_start + orig_size) { 4207 while (native_end < orig_start + orig_size) {
4206 *(native_end++) = 0x90; //NOP 4208 *(native_end++) = 0x90; //NOP
4213 return orig_start; 4215 return orig_start;
4214 } 4216 }
4215 } 4217 }
4216 4218
4217 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE); 4219 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE);
4218 opts->cur_code = dst+MAX_NATIVE_SIZE; 4220 opts->gen.cur_code = dst+MAX_NATIVE_SIZE;
4219 jmp(orig_start, dst); 4221 jmp(orig_start, dst);
4220 if (!m68k_is_terminal(&instbuf)) { 4222 if (!m68k_is_terminal(&instbuf)) {
4221 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2)); 4223 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2));
4222 } 4224 }
4223 m68k_handle_deferred(context); 4225 m68k_handle_deferred(context);
4234 4236
4235 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) 4237 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context)
4236 { 4238 {
4237 uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000); 4239 uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000);
4238 if (inst_start) { 4240 if (inst_start) {
4239 uint8_t * dst = get_native_address(context->native_code_map, inst_start); 4241 code_ptr dst = get_native_address(context->native_code_map, inst_start);
4240 dst = mov_ir(dst, inst_start, SCRATCH2, SZ_D); 4242 dst = mov_ir(dst, inst_start, SCRATCH2, SZ_D);
4241 x86_68k_options * options = context->options; 4243 x86_68k_options * options = context->options;
4242 if (!options->retrans_stub) { 4244 if (!options->retrans_stub) {
4243 if (options->code_end - options->cur_code < 32) { 4245 if (options->gen.code_end - options->gen.cur_code < 32) {
4244 size_t size = 1024*1024; 4246 size_t size = 1024*1024;
4245 options->cur_code = alloc_code(&size); 4247 options->gen.cur_code = alloc_code(&size);
4246 options->code_end = options->cur_code + size; 4248 options->gen.code_end = options->gen.cur_code + size;
4247 } 4249 }
4248 uint8_t * rdst = options->retrans_stub = options->cur_code; 4250 code_ptr rdst = options->retrans_stub = options->gen.cur_code;
4249 rdst = call(rdst, options->save_context); 4251 rdst = call(rdst, options->gen.save_context);
4250 rdst = push_r(rdst, CONTEXT); 4252 rdst = push_r(rdst, CONTEXT);
4251 #ifdef X86_32 4253 #ifdef X86_32
4252 rdst = push_r(rdst, CONTEXT); 4254 rdst = push_r(rdst, CONTEXT);
4253 rdst = push_r(rdst, SCRATCH2); 4255 rdst = push_r(rdst, SCRATCH2);
4254 #endif 4256 #endif
4255 rdst = call(rdst, (uint8_t *)m68k_retranslate_inst); 4257 rdst = call(rdst, (code_ptr)m68k_retranslate_inst);
4256 #ifdef X86_32 4258 #ifdef X86_32
4257 rdst = add_ir(rdst, 8, RSP, SZ_D); 4259 rdst = add_ir(rdst, 8, RSP, SZ_D);
4258 #endif 4260 #endif
4259 rdst = pop_r(rdst, CONTEXT); 4261 rdst = pop_r(rdst, CONTEXT);
4260 rdst = mov_rr(rdst, RAX, SCRATCH1, SZ_PTR); 4262 rdst = mov_rr(rdst, RAX, SCRATCH1, SZ_PTR);
4261 rdst = call(rdst, options->load_context); 4263 rdst = call(rdst, options->gen.load_context);
4262 rdst = jmp_r(rdst, SCRATCH1); 4264 rdst = jmp_r(rdst, SCRATCH1);
4263 options->cur_code = rdst; 4265 options->gen.cur_code = rdst;
4264 } 4266 }
4265 dst = jmp(dst, options->retrans_stub); 4267 dst = jmp(dst, options->retrans_stub);
4266 } 4268 }
4267 return context; 4269 return context;
4268 } 4270 }
4269 4271
4270 void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler) 4272 void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_handler)
4271 { 4273 {
4272 static uint8_t * bp_stub = NULL; 4274 static code_ptr bp_stub = NULL;
4273 uint8_t * native = get_native_address_trans(context, address); 4275 code_ptr native = get_native_address_trans(context, address);
4274 uint8_t * start_native = native; 4276 code_ptr start_native = native;
4275 native = mov_ir(native, address, SCRATCH1, SZ_D); 4277 native = mov_ir(native, address, SCRATCH1, SZ_D);
4276 if (!bp_stub) { 4278 if (!bp_stub) {
4277 x86_68k_options * opts = context->options; 4279 x86_68k_options * opts = context->options;
4278 uint8_t * dst = opts->cur_code; 4280 code_ptr dst = opts->gen.cur_code;
4279 uint8_t * dst_end = opts->code_end; 4281 code_ptr dst_end = opts->gen.code_end;
4280 if (dst_end - dst < 128) { 4282 if (dst_end - dst < 128) {
4281 size_t size = 1024*1024; 4283 size_t size = 1024*1024;
4282 dst = alloc_code(&size); 4284 dst = alloc_code(&size);
4283 opts->code_end = dst_end = dst + size; 4285 opts->gen.code_end = dst_end = dst + size;
4284 } 4286 }
4285 bp_stub = dst; 4287 bp_stub = dst;
4286 native = call(native, bp_stub); 4288 native = call(native, bp_stub);
4287 4289
4288 //Calculate length of prologue 4290 //Calculate length of prologue
4289 dst = check_cycles_int(dst, address, opts); 4291 dst = check_cycles_int(dst, address, opts);
4290 int check_int_size = dst-bp_stub; 4292 int check_int_size = dst-bp_stub;
4291 dst = bp_stub; 4293 dst = bp_stub;
4292 4294
4293 //Save context and call breakpoint handler 4295 //Save context and call breakpoint handler
4294 dst = call(dst, opts->save_context); 4296 dst = call(dst, opts->gen.save_context);
4295 dst = push_r(dst, SCRATCH1); 4297 dst = push_r(dst, SCRATCH1);
4296 #ifdef X86_64 4298 #ifdef X86_64
4297 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 4299 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR);
4298 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); 4300 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
4299 #else 4301 #else
4304 #ifdef X86_32 4306 #ifdef X86_32
4305 dst = add_ir(dst, 8, RSP, SZ_D); 4307 dst = add_ir(dst, 8, RSP, SZ_D);
4306 #endif 4308 #endif
4307 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4309 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR);
4308 //Restore context 4310 //Restore context
4309 dst = call(dst, opts->load_context); 4311 dst = call(dst, opts->gen.load_context);
4310 dst = pop_r(dst, SCRATCH1); 4312 dst = pop_r(dst, SCRATCH1);
4311 //do prologue stuff 4313 //do prologue stuff
4312 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); 4314 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
4313 uint8_t * jmp_off = dst+1; 4315 code_ptr jmp_off = dst+1;
4314 dst = jcc(dst, CC_NC, dst + 7); 4316 dst = jcc(dst, CC_NC, dst + 7);
4315 dst = call(dst, opts->handle_cycle_limit_int); 4317 dst = call(dst, opts->gen.handle_cycle_limit_int);
4316 *jmp_off = dst - (jmp_off+1); 4318 *jmp_off = dst - (jmp_off+1);
4317 //jump back to body of translated instruction 4319 //jump back to body of translated instruction
4318 dst = pop_r(dst, SCRATCH1); 4320 dst = pop_r(dst, SCRATCH1);
4319 dst = add_ir(dst, check_int_size - (native-start_native), SCRATCH1, SZ_PTR); 4321 dst = add_ir(dst, check_int_size - (native-start_native), SCRATCH1, SZ_PTR);
4320 dst = jmp_r(dst, SCRATCH1); 4322 dst = jmp_r(dst, SCRATCH1);
4321 opts->cur_code = dst; 4323 opts->gen.cur_code = dst;
4322 } else { 4324 } else {
4323 native = call(native, bp_stub); 4325 native = call(native, bp_stub);
4324 } 4326 }
4325 } 4327 }
4326 4328
4327 void remove_breakpoint(m68k_context * context, uint32_t address) 4329 void remove_breakpoint(m68k_context * context, uint32_t address)
4328 { 4330 {
4329 uint8_t * native = get_native_address(context->native_code_map, address); 4331 code_ptr native = get_native_address(context->native_code_map, address);
4330 check_cycles_int(native, address, context->options); 4332 check_cycles_int(native, address, context->options);
4331 } 4333 }
4332 4334
4333 void start_68k_context(m68k_context * context, uint32_t address) 4335 void start_68k_context(m68k_context * context, uint32_t address)
4334 { 4336 {
4335 uint8_t * addr = get_native_address_trans(context, address); 4337 code_ptr addr = get_native_address_trans(context, address);
4336 x86_68k_options * options = context->options; 4338 x86_68k_options * options = context->options;
4337 options->start_context(addr, context); 4339 options->start_context(addr, context);
4338 } 4340 }
4339 4341
4340 void m68k_reset(m68k_context * context) 4342 void m68k_reset(m68k_context * context)
4343 context->aregs[7] = context->mem_pointers[0][0] << 16 | context->mem_pointers[0][1]; 4345 context->aregs[7] = context->mem_pointers[0][0] << 16 | context->mem_pointers[0][1];
4344 uint32_t address = context->mem_pointers[0][2] << 16 | context->mem_pointers[0][3]; 4346 uint32_t address = context->mem_pointers[0][2] << 16 | context->mem_pointers[0][3];
4345 start_68k_context(context, address); 4347 start_68k_context(context, address);
4346 } 4348 }
4347 4349
4348 uint8_t * gen_mem_fun(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type) 4350 code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type)
4349 { 4351 {
4350 uint8_t * dst = opts->cur_code; 4352 code_ptr dst = opts->cur_code;
4351 uint8_t * start = dst; 4353 code_ptr start = dst;
4352 dst = check_cycles(dst, opts); 4354 dst = check_cycles(dst, opts);
4353 dst = cycles(dst, BUS); 4355 dst = cycles(dst, BUS);
4354 dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); 4356 dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D);
4355 uint8_t *lb_jcc = NULL, *ub_jcc = NULL; 4357 code_ptr lb_jcc = NULL, ub_jcc = NULL;
4356 uint8_t is_write = fun_type == WRITE_16 || fun_type == WRITE_8; 4358 uint8_t is_write = fun_type == WRITE_16 || fun_type == WRITE_8;
4357 uint8_t adr_reg = is_write ? SCRATCH2 : SCRATCH1; 4359 uint8_t adr_reg = is_write ? SCRATCH2 : SCRATCH1;
4358 uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ; 4360 uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ;
4359 uint8_t size = (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B; 4361 uint8_t size = (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B;
4360 for (uint32_t chunk = 0; chunk < num_chunks; chunk++) 4362 for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
4393 } 4395 }
4394 if(memmap[chunk].buffer && memmap[chunk].flags & access_flag) { 4396 if(memmap[chunk].buffer && memmap[chunk].flags & access_flag) {
4395 if (memmap[chunk].flags & MMAP_PTR_IDX) { 4397 if (memmap[chunk].flags & MMAP_PTR_IDX) {
4396 if (memmap[chunk].flags & MMAP_FUNC_NULL) { 4398 if (memmap[chunk].flags & MMAP_FUNC_NULL) {
4397 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, SZ_PTR); 4399 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, SZ_PTR);
4398 uint8_t * not_null = dst+1; 4400 code_ptr not_null = dst+1;
4399 dst = jcc(dst, CC_NZ, dst+2); 4401 dst = jcc(dst, CC_NZ, dst+2);
4400 dst = call(dst, opts->save_context); 4402 dst = call(dst, opts->save_context);
4401 #ifdef X86_64 4403 #ifdef X86_64
4402 if (is_write) { 4404 if (is_write) {
4403 if (SCRATCH2 != RDI) { 4405 if (SCRATCH2 != RDI) {
4407 } else { 4409 } else {
4408 dst = push_r(dst, CONTEXT); 4410 dst = push_r(dst, CONTEXT);
4409 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); 4411 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
4410 } 4412 }
4411 dst = test_ir(dst, 8, RSP, SZ_D); 4413 dst = test_ir(dst, 8, RSP, SZ_D);
4412 uint8_t *adjust_rsp = dst+1; 4414 code_ptr adjust_rsp = dst+1;
4413 dst = jcc(dst, CC_NZ, dst+2); 4415 dst = jcc(dst, CC_NZ, dst+2);
4414 dst = call(dst, cfun); 4416 dst = call(dst, cfun);
4415 uint8_t *no_adjust = dst+1; 4417 code_ptr no_adjust = dst+1;
4416 dst = jmp(dst, dst+2); 4418 dst = jmp(dst, dst+2);
4417 *adjust_rsp = dst - (adjust_rsp + 1); 4419 *adjust_rsp = dst - (adjust_rsp + 1);
4418 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4420 dst = sub_ir(dst, 8, RSP, SZ_PTR);
4419 dst = call(dst, cfun); 4421 dst = call(dst, cfun);
4420 dst = add_ir(dst, 8, RSP, SZ_PTR); 4422 dst = add_ir(dst, 8, RSP, SZ_PTR);
4453 } else { 4455 } else {
4454 uint8_t tmp_size = size; 4456 uint8_t tmp_size = size;
4455 if (size == SZ_B) { 4457 if (size == SZ_B) {
4456 if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) { 4458 if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) {
4457 dst = bt_ir(dst, 0, adr_reg, SZ_D); 4459 dst = bt_ir(dst, 0, adr_reg, SZ_D);
4458 uint8_t * good_addr = dst + 1; 4460 code_ptr good_addr = dst + 1;
4459 dst = jcc(dst, (memmap[chunk].flags & MMAP_ONLY_ODD) ? CC_C : CC_NC, dst+2); 4461 dst = jcc(dst, (memmap[chunk].flags & MMAP_ONLY_ODD) ? CC_C : CC_NC, dst+2);
4460 if (!is_write) { 4462 if (!is_write) {
4461 dst = mov_ir(dst, 0xFF, SCRATCH1, SZ_B); 4463 dst = mov_ir(dst, 0xFF, SCRATCH1, SZ_B);
4462 } 4464 }
4463 dst = retn(dst); 4465 dst = retn(dst);
4502 } 4504 }
4503 if (is_write && (memmap[chunk].flags & MMAP_CODE)) { 4505 if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
4504 dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 4506 dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
4505 dst = shr_ir(dst, 11, SCRATCH1, SZ_D); 4507 dst = shr_ir(dst, 11, SCRATCH1, SZ_D);
4506 dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); 4508 dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D);
4507 uint8_t * not_code = dst+1; 4509 code_ptr not_code = dst+1;
4508 dst = jcc(dst, CC_NC, dst+2); 4510 dst = jcc(dst, CC_NC, dst+2);
4509 dst = call(dst, opts->save_context); 4511 dst = call(dst, opts->save_context);
4510 #ifdef X86_32 4512 #ifdef X86_32
4511 dst = push_r(dst, CONTEXT); 4513 dst = push_r(dst, CONTEXT);
4512 dst = push_r(dst, SCRATCH2); 4514 dst = push_r(dst, SCRATCH2);
4513 #endif 4515 #endif
4514 dst = call(dst, (uint8_t *)m68k_handle_code_write); 4516 dst = call(dst, (code_ptr)m68k_handle_code_write);
4515 #ifdef X86_32 4517 #ifdef X86_32
4516 dst = add_ir(dst, 8, RSP, SZ_D); 4518 dst = add_ir(dst, 8, RSP, SZ_D);
4517 #endif 4519 #endif
4518 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4520 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR);
4519 dst = call(dst, opts->load_context); 4521 dst = call(dst, opts->load_context);
4531 } else { 4533 } else {
4532 dst = push_r(dst, CONTEXT); 4534 dst = push_r(dst, CONTEXT);
4533 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); 4535 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
4534 } 4536 }
4535 dst = test_ir(dst, 8, RSP, SZ_D); 4537 dst = test_ir(dst, 8, RSP, SZ_D);
4536 uint8_t *adjust_rsp = dst+1; 4538 code_ptr adjust_rsp = dst+1;
4537 dst = jcc(dst, CC_NZ, dst+2); 4539 dst = jcc(dst, CC_NZ, dst+2);
4538 dst = call(dst, cfun); 4540 dst = call(dst, cfun);
4539 uint8_t *no_adjust = dst+1; 4541 code_ptr no_adjust = dst+1;
4540 dst = jmp(dst, dst+2); 4542 dst = jmp(dst, dst+2);
4541 *adjust_rsp = dst - (adjust_rsp + 1); 4543 *adjust_rsp = dst - (adjust_rsp + 1);
4542 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4544 dst = sub_ir(dst, 8, RSP, SZ_PTR);
4543 dst = call(dst, cfun); 4545 dst = call(dst, cfun);
4544 dst = add_ir(dst, 8, RSP, SZ_PTR); 4546 dst = add_ir(dst, 8, RSP, SZ_PTR);
4612 for (int i = 0; i < 5; i++) 4614 for (int i = 0; i < 5; i++)
4613 opts->flag_regs[i] = -1; 4615 opts->flag_regs[i] = -1;
4614 #endif 4616 #endif
4615 4617
4616 4618
4617 opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); 4619 opts->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
4618 memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); 4620 memset(opts->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
4619 opts->deferred = NULL; 4621 opts->gen.deferred = NULL;
4620 size_t size = 1024 * 1024; 4622 size_t size = 1024 * 1024;
4621 opts->cur_code = alloc_code(&size); 4623 opts->gen.cur_code = alloc_code(&size);
4622 opts->code_end = opts->cur_code + size; 4624 opts->gen.code_end = opts->gen.cur_code + size;
4623 opts->ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); 4625 opts->gen.ram_inst_sizes = malloc(sizeof(code_ptr) * 64);
4624 memset(opts->ram_inst_sizes, 0, sizeof(uint8_t *) * 64); 4626 memset(opts->gen.ram_inst_sizes, 0, sizeof(code_ptr) * 64);
4625 4627
4626 uint8_t * dst = opts->cur_code; 4628 code_ptr dst = opts->gen.cur_code;
4627 4629
4628 opts->save_context = dst; 4630 opts->gen.save_context = dst;
4629 for (int i = 0; i < 5; i++) 4631 for (int i = 0; i < 5; i++)
4630 if (opts->flag_regs[i] >= 0) { 4632 if (opts->flag_regs[i] >= 0) {
4631 dst = mov_rrdisp8(dst, opts->flag_regs[i], CONTEXT, offsetof(m68k_context, flags) + i, SZ_B); 4633 dst = mov_rrdisp8(dst, opts->flag_regs[i], CONTEXT, offsetof(m68k_context, flags) + i, SZ_B);
4632 } 4634 }
4633 for (int i = 0; i < 8; i++) 4635 for (int i = 0; i < 8; i++)
4640 } 4642 }
4641 } 4643 }
4642 dst = mov_rrdisp8(dst, CYCLES, CONTEXT, offsetof(m68k_context, current_cycle), SZ_D); 4644 dst = mov_rrdisp8(dst, CYCLES, CONTEXT, offsetof(m68k_context, current_cycle), SZ_D);
4643 dst = retn(dst); 4645 dst = retn(dst);
4644 4646
4645 opts->load_context = dst; 4647 opts->gen.load_context = dst;
4646 for (int i = 0; i < 5; i++) 4648 for (int i = 0; i < 5; i++)
4647 if (opts->flag_regs[i] >= 0) { 4649 if (opts->flag_regs[i] >= 0) {
4648 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B); 4650 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B);
4649 } 4651 }
4650 for (int i = 0; i < 8; i++) 4652 for (int i = 0; i < 8; i++)
4679 dst = push_r(dst, RDI); 4681 dst = push_r(dst, RDI);
4680 4682
4681 dst = mov_rdisp8r(dst, RSP, 20, SCRATCH2, SZ_D); 4683 dst = mov_rdisp8r(dst, RSP, 20, SCRATCH2, SZ_D);
4682 dst = mov_rdisp8r(dst, RSP, 24, CONTEXT, SZ_D); 4684 dst = mov_rdisp8r(dst, RSP, 24, CONTEXT, SZ_D);
4683 #endif 4685 #endif
4684 dst = call(dst, opts->load_context); 4686 dst = call(dst, opts->gen.load_context);
4685 dst = call_r(dst, SCRATCH2); 4687 dst = call_r(dst, SCRATCH2);
4686 dst = call(dst, opts->save_context); 4688 dst = call(dst, opts->gen.save_context);
4687 #ifdef X86_64 4689 #ifdef X86_64
4688 //restore callee save registers 4690 //restore callee save registers
4689 dst = pop_r(dst, R15); 4691 dst = pop_r(dst, R15);
4690 dst = pop_r(dst, R14); 4692 dst = pop_r(dst, R14);
4691 dst = pop_r(dst, R13); 4693 dst = pop_r(dst, R13);
4698 dst = pop_r(dst, RBP); 4700 dst = pop_r(dst, RBP);
4699 #endif 4701 #endif
4700 dst = retn(dst); 4702 dst = retn(dst);
4701 4703
4702 opts->native_addr = dst; 4704 opts->native_addr = dst;
4703 dst = call(dst, opts->save_context); 4705 dst = call(dst, opts->gen.save_context);
4704 dst = push_r(dst, CONTEXT); 4706 dst = push_r(dst, CONTEXT);
4705 #ifdef X86_64 4707 #ifdef X86_64
4706 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); //move context to 1st arg reg 4708 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); //move context to 1st arg reg
4707 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); //move address to 2nd arg reg 4709 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); //move address to 2nd arg reg
4708 #else 4710 #else
4709 dst = push_r(dst, SCRATCH1); 4711 dst = push_r(dst, SCRATCH1);
4710 dst = push_r(dst, CONTEXT); 4712 dst = push_r(dst, CONTEXT);
4711 #endif 4713 #endif
4712 dst = call(dst, (uint8_t *)get_native_address_trans); 4714 dst = call(dst, (code_ptr)get_native_address_trans);
4713 #ifdef X86_32 4715 #ifdef X86_32
4714 dst = add_ir(dst, 8, RSP, SZ_D); 4716 dst = add_ir(dst, 8, RSP, SZ_D);
4715 #endif 4717 #endif
4716 dst = mov_rr(dst, RAX, SCRATCH1, SZ_PTR); //move result to scratch reg 4718 dst = mov_rr(dst, RAX, SCRATCH1, SZ_PTR); //move result to scratch reg
4717 dst = pop_r(dst, CONTEXT); 4719 dst = pop_r(dst, CONTEXT);
4718 dst = call(dst, opts->load_context); 4720 dst = call(dst, opts->gen.load_context);
4719 dst = retn(dst); 4721 dst = retn(dst);
4720 4722
4721 opts->native_addr_and_sync = dst; 4723 opts->native_addr_and_sync = dst;
4722 dst = call(dst, opts->save_context); 4724 dst = call(dst, opts->gen.save_context);
4723 dst = push_r(dst, SCRATCH1); 4725 dst = push_r(dst, SCRATCH1);
4724 #ifdef X86_64 4726 #ifdef X86_64
4725 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 4727 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR);
4726 dst = xor_rr(dst, RSI, RSI, SZ_D); 4728 dst = xor_rr(dst, RSI, RSI, SZ_D);
4727 dst = test_ir(dst, 8, RSP, SZ_PTR); //check stack alignment 4729 dst = test_ir(dst, 8, RSP, SZ_PTR); //check stack alignment
4728 uint8_t * do_adjust_rsp = dst+1; 4730 code_ptr do_adjust_rsp = dst+1;
4729 dst = jcc(dst, CC_NZ, dst+2); 4731 dst = jcc(dst, CC_NZ, dst+2);
4730 dst = call(dst, (uint8_t *)sync_components); 4732 dst = call(dst, (code_ptr)sync_components);
4731 uint8_t * no_adjust_rsp = dst+1; 4733 code_ptr no_adjust_rsp = dst+1;
4732 dst = jmp(dst, dst+2); 4734 dst = jmp(dst, dst+2);
4733 *do_adjust_rsp = dst - (do_adjust_rsp+1); 4735 *do_adjust_rsp = dst - (do_adjust_rsp+1);
4734 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4736 dst = sub_ir(dst, 8, RSP, SZ_PTR);
4735 dst = call(dst, (uint8_t *)sync_components); 4737 dst = call(dst, (code_ptr)sync_components);
4736 dst = add_ir(dst, 8, RSP, SZ_PTR); 4738 dst = add_ir(dst, 8, RSP, SZ_PTR);
4737 *no_adjust_rsp = dst - (no_adjust_rsp+1); 4739 *no_adjust_rsp = dst - (no_adjust_rsp+1);
4738 dst = pop_r(dst, RSI); 4740 dst = pop_r(dst, RSI);
4739 dst = push_r(dst, RAX); 4741 dst = push_r(dst, RAX);
4740 dst = mov_rr(dst, RAX, RDI, SZ_PTR); 4742 dst = mov_rr(dst, RAX, RDI, SZ_PTR);
4741 dst = call(dst, (uint8_t *)get_native_address_trans); 4743 dst = call(dst, (code_ptr)get_native_address_trans);
4742 #else 4744 #else
4743 //TODO: Add support for pushing a constant in gen_x86 4745 //TODO: Add support for pushing a constant in gen_x86
4744 dst = xor_rr(dst, RAX, RAX, SZ_D); 4746 dst = xor_rr(dst, RAX, RAX, SZ_D);
4745 dst = push_r(dst, RAX); 4747 dst = push_r(dst, RAX);
4746 dst = push_r(dst, CONTEXT); 4748 dst = push_r(dst, CONTEXT);
4747 dst = call(dst, (uint8_t *)sync_components); 4749 dst = call(dst, (code_ptr)sync_components);
4748 dst = add_ir(dst, 8, RSP, SZ_D); 4750 dst = add_ir(dst, 8, RSP, SZ_D);
4749 dst = pop_r(dst, RSI); //restore saved address from SCRATCH1 4751 dst = pop_r(dst, RSI); //restore saved address from SCRATCH1
4750 dst = push_r(dst, RAX); //save context pointer for later 4752 dst = push_r(dst, RAX); //save context pointer for later
4751 dst = push_r(dst, RSI); //2nd arg -- address 4753 dst = push_r(dst, RSI); //2nd arg -- address
4752 dst = push_r(dst, RAX); //1st arg -- context pointer 4754 dst = push_r(dst, RAX); //1st arg -- context pointer
4753 dst = call(dst, (uint8_t *)get_native_address_trans); 4755 dst = call(dst, (code_ptr)get_native_address_trans);
4754 dst = add_ir(dst, 8, RSP, SZ_D); 4756 dst = add_ir(dst, 8, RSP, SZ_D);
4755 #endif 4757 #endif
4756 4758
4757 dst = mov_rr(dst, RAX, SCRATCH1, SZ_PTR); //move result to scratch reg 4759 dst = mov_rr(dst, RAX, SCRATCH1, SZ_PTR); //move result to scratch reg
4758 dst = pop_r(dst, CONTEXT); 4760 dst = pop_r(dst, CONTEXT);
4759 dst = call(dst, opts->load_context); 4761 dst = call(dst, opts->gen.load_context);
4760 dst = retn(dst); 4762 dst = retn(dst);
4761 4763
4762 opts->handle_cycle_limit = dst; 4764 opts->gen.handle_cycle_limit = dst;
4763 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); 4765 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
4764 uint8_t * skip_sync = dst+1; 4766 code_ptr skip_sync = dst+1;
4765 dst = jcc(dst, CC_C, dst+2); 4767 dst = jcc(dst, CC_C, dst+2);
4766 opts->do_sync = dst; 4768 opts->do_sync = dst;
4767 dst = push_r(dst, SCRATCH1); 4769 dst = push_r(dst, SCRATCH1);
4768 dst = push_r(dst, SCRATCH2); 4770 dst = push_r(dst, SCRATCH2);
4769 dst = call(dst, opts->save_context); 4771 dst = call(dst, opts->gen.save_context);
4770 #ifdef X86_64 4772 #ifdef X86_64
4771 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 4773 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR);
4772 dst = xor_rr(dst, RSI, RSI, SZ_D); 4774 dst = xor_rr(dst, RSI, RSI, SZ_D);
4773 dst = test_ir(dst, 8, RSP, SZ_D); 4775 dst = test_ir(dst, 8, RSP, SZ_D);
4774 uint8_t *adjust_rsp = dst+1; 4776 code_ptr adjust_rsp = dst+1;
4775 dst = jcc(dst, CC_NZ, dst+2); 4777 dst = jcc(dst, CC_NZ, dst+2);
4776 dst = call(dst, (uint8_t *)sync_components); 4778 dst = call(dst, (code_ptr)sync_components);
4777 uint8_t *no_adjust = dst+1; 4779 code_ptr no_adjust = dst+1;
4778 dst = jmp(dst, dst+2); 4780 dst = jmp(dst, dst+2);
4779 *adjust_rsp = dst - (adjust_rsp + 1); 4781 *adjust_rsp = dst - (adjust_rsp + 1);
4780 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4782 dst = sub_ir(dst, 8, RSP, SZ_PTR);
4781 dst = call(dst, (uint8_t *)sync_components); 4783 dst = call(dst, (code_ptr)sync_components);
4782 dst = add_ir(dst, 8, RSP, SZ_PTR); 4784 dst = add_ir(dst, 8, RSP, SZ_PTR);
4783 *no_adjust = dst - (no_adjust+1); 4785 *no_adjust = dst - (no_adjust+1);
4784 #else 4786 #else
4785 //TODO: Add support for pushing a constant in gen_x86 4787 //TODO: Add support for pushing a constant in gen_x86
4786 dst = xor_rr(dst, RAX, RAX, SZ_D); 4788 dst = xor_rr(dst, RAX, RAX, SZ_D);
4787 dst = push_r(dst, RAX); 4789 dst = push_r(dst, RAX);
4788 dst = push_r(dst, CONTEXT); 4790 dst = push_r(dst, CONTEXT);
4789 dst = call(dst, (uint8_t *)sync_components); 4791 dst = call(dst, (code_ptr)sync_components);
4790 dst = add_ir(dst, 8, RSP, SZ_D); 4792 dst = add_ir(dst, 8, RSP, SZ_D);
4791 #endif 4793 #endif
4792 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4794 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR);
4793 dst = call(dst, opts->load_context); 4795 dst = call(dst, opts->gen.load_context);
4794 dst = pop_r(dst, SCRATCH2); 4796 dst = pop_r(dst, SCRATCH2);
4795 dst = pop_r(dst, SCRATCH1); 4797 dst = pop_r(dst, SCRATCH1);
4796 *skip_sync = dst - (skip_sync+1); 4798 *skip_sync = dst - (skip_sync+1);
4797 dst = retn(dst); 4799 dst = retn(dst);
4798 4800
4799 opts->cur_code = dst; 4801 opts->gen.cur_code = dst;
4800 4802
4801 opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); 4803 opts->read_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_16);
4802 opts->read_8 = gen_mem_fun(opts, memmap, num_chunks, READ_8); 4804 opts->read_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_8);
4803 opts->write_16 = gen_mem_fun(opts, memmap, num_chunks, WRITE_16); 4805 opts->write_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_16);
4804 opts->write_8 = gen_mem_fun(opts, memmap, num_chunks, WRITE_8); 4806 opts->write_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_8);
4805 4807
4806 dst = opts->cur_code; 4808 dst = opts->gen.cur_code;
4807 4809
4808 opts->read_32 = dst; 4810 opts->read_32 = dst;
4809 dst = push_r(dst, SCRATCH1); 4811 dst = push_r(dst, SCRATCH1);
4810 dst = call(dst, opts->read_16); 4812 dst = call(dst, opts->read_16);
4811 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); 4813 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W);
4897 } 4899 }
4898 } 4900 }
4899 } 4901 }
4900 dst = retn(dst); 4902 dst = retn(dst);
4901 4903
4902 opts->handle_cycle_limit_int = dst; 4904 opts->gen.handle_cycle_limit_int = dst;
4903 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); 4905 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
4904 uint8_t * do_int = dst+1; 4906 code_ptr do_int = dst+1;
4905 dst = jcc(dst, CC_NC, dst+2); 4907 dst = jcc(dst, CC_NC, dst+2);
4906 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); 4908 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
4907 skip_sync = dst+1; 4909 skip_sync = dst+1;
4908 dst = jcc(dst, CC_C, dst+2); 4910 dst = jcc(dst, CC_C, dst+2);
4909 dst = call(dst, opts->save_context); 4911 dst = call(dst, opts->gen.save_context);
4910 #ifdef X86_64 4912 #ifdef X86_64
4911 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 4913 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR);
4912 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); 4914 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
4913 dst = test_ir(dst, 8, RSP, SZ_D); 4915 dst = test_ir(dst, 8, RSP, SZ_D);
4914 adjust_rsp = dst+1; 4916 adjust_rsp = dst+1;
4915 dst = jcc(dst, CC_NZ, dst+2); 4917 dst = jcc(dst, CC_NZ, dst+2);
4916 dst = call(dst, (uint8_t *)sync_components); 4918 dst = call(dst, (code_ptr)sync_components);
4917 no_adjust = dst+1; 4919 no_adjust = dst+1;
4918 dst = jmp(dst, dst+2); 4920 dst = jmp(dst, dst+2);
4919 *adjust_rsp = dst - (adjust_rsp + 1); 4921 *adjust_rsp = dst - (adjust_rsp + 1);
4920 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4922 dst = sub_ir(dst, 8, RSP, SZ_PTR);
4921 dst = call(dst, (uint8_t *)sync_components); 4923 dst = call(dst, (code_ptr)sync_components);
4922 dst = add_ir(dst, 8, RSP, SZ_PTR); 4924 dst = add_ir(dst, 8, RSP, SZ_PTR);
4923 *no_adjust = dst - (no_adjust+1); 4925 *no_adjust = dst - (no_adjust+1);
4924 #else 4926 #else
4925 dst = push_r(dst, SCRATCH1); 4927 dst = push_r(dst, SCRATCH1);
4926 dst = push_r(dst, CONTEXT); 4928 dst = push_r(dst, CONTEXT);
4927 dst = call(dst, (uint8_t *)sync_components); 4929 dst = call(dst, (code_ptr)sync_components);
4928 dst = add_ir(dst, 8, RSP, SZ_D); 4930 dst = add_ir(dst, 8, RSP, SZ_D);
4929 #endif 4931 #endif
4930 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4932 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR);
4931 dst = jmp(dst, opts->load_context); 4933 dst = jmp(dst, opts->gen.load_context);
4932 *skip_sync = dst - (skip_sync+1); 4934 *skip_sync = dst - (skip_sync+1);
4933 dst = retn(dst); 4935 dst = retn(dst);
4934 *do_int = dst - (do_int+1); 4936 *do_int = dst - (do_int+1);
4935 //set target cycle to sync cycle 4937 //set target cycle to sync cycle
4936 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D); 4938 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D);
4937 //swap USP and SSP if not already in supervisor mode 4939 //swap USP and SSP if not already in supervisor mode
4938 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); 4940 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B);
4939 uint8_t *already_supervisor = dst+1; 4941 code_ptr already_supervisor = dst+1;
4940 dst = jcc(dst, CC_C, dst+2); 4942 dst = jcc(dst, CC_C, dst+2);
4941 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH2, SZ_D); 4943 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH2, SZ_D);
4942 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 4944 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
4943 dst = mov_rr(dst, SCRATCH2, opts->aregs[7], SZ_D); 4945 dst = mov_rr(dst, SCRATCH2, opts->aregs[7], SZ_D);
4944 *already_supervisor = dst - (already_supervisor+1); 4946 *already_supervisor = dst - (already_supervisor+1);
4995 dst = call(dst, opts->read_32); 4997 dst = call(dst, opts->read_32);
4996 dst = call(dst, opts->native_addr_and_sync); 4998 dst = call(dst, opts->native_addr_and_sync);
4997 dst = cycles(dst, 18); 4999 dst = cycles(dst, 18);
4998 dst = jmp_r(dst, SCRATCH1); 5000 dst = jmp_r(dst, SCRATCH1);
4999 5001
5000 opts->cur_code = dst; 5002 opts->gen.cur_code = dst;
5001 } 5003 }
5002 5004
5003 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) 5005 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
5004 { 5006 {
5005 memset(context, 0, sizeof(m68k_context)); 5007 memset(context, 0, sizeof(m68k_context));