Mercurial > repos > blastem
comparison m68k_core.c @ 581:9f40aa5243c2
Combine implementations of lea and pea. Update bit instructions to use the op_ family of functions to simplify their implementation a bit.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 05 Mar 2014 19:26:53 -0800 |
parents | 1594525e2157 |
children | c05fcbfe1b1a |
comparison
equal
deleted
inserted
replaced
580:5157bc966c1a | 581:9f40aa5243c2 |
---|---|
84 call(&opts->gen.code, opts->write_32_highfirst); | 84 call(&opts->gen.code, opts->write_32_highfirst); |
85 break; | 85 break; |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
89 void translate_m68k_lea(m68k_options * opts, m68kinst * inst) | 89 void translate_m68k_lea_pea(m68k_options * opts, m68kinst * inst) |
90 { | 90 { |
91 code_info *code = &opts->gen.code; | 91 code_info *code = &opts->gen.code; |
92 int8_t dst_reg = native_reg(&(inst->dst), opts); | 92 int8_t dst_reg = inst->op == M68K_PEA ? opts->gen.scratch1 : native_reg(&(inst->dst), opts); |
93 switch(inst->src.addr_mode) | 93 switch(inst->src.addr_mode) |
94 { | 94 { |
95 case MODE_AREG_INDIRECT: | 95 case MODE_AREG_INDIRECT: |
96 cycles(&opts->gen, BUS); | 96 cycles(&opts->gen, BUS); |
97 if (dst_reg >= 0) { | 97 if (dst_reg >= 0) { |
116 cycles(&opts->gen, 12); | 116 cycles(&opts->gen, 12); |
117 if (dst_reg < 0 || inst->dst.params.regs.pri == inst->src.params.regs.pri || inst->dst.params.regs.pri == (inst->src.params.regs.sec >> 1 & 0x7)) { | 117 if (dst_reg < 0 || inst->dst.params.regs.pri == inst->src.params.regs.pri || inst->dst.params.regs.pri == (inst->src.params.regs.sec >> 1 & 0x7)) { |
118 dst_reg = opts->gen.scratch1; | 118 dst_reg = opts->gen.scratch1; |
119 } | 119 } |
120 calc_areg_index_disp8(opts, &inst->src, dst_reg); | 120 calc_areg_index_disp8(opts, &inst->src, dst_reg); |
121 if (dst_reg == opts->gen.scratch1) { | 121 if (dst_reg == opts->gen.scratch1 && inst->op != M68K_PEA) { |
122 native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri); | 122 native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri); |
123 } | 123 } |
124 break; | 124 break; |
125 case MODE_PC_DISPLACE: | 125 case MODE_PC_DISPLACE: |
126 cycles(&opts->gen, 8); | 126 cycles(&opts->gen, 8); |
127 ldi_areg(opts, inst->src.params.regs.displacement + inst->address+2, inst->dst.params.regs.pri); | 127 if (inst->op == M68K_PEA) { |
128 ldi_native(opts, inst->src.params.regs.displacement + inst->address+2, dst_reg); | |
129 } else { | |
130 ldi_areg(opts, inst->src.params.regs.displacement + inst->address+2, inst->dst.params.regs.pri); | |
131 } | |
128 break; | 132 break; |
129 case MODE_PC_INDEX_DISP8: | 133 case MODE_PC_INDEX_DISP8: |
130 cycles(&opts->gen, BUS*3); | 134 cycles(&opts->gen, BUS*3); |
131 if (dst_reg < 0 || inst->dst.params.regs.pri == (inst->src.params.regs.sec >> 1 & 0x7)) { | 135 if (dst_reg < 0 || inst->dst.params.regs.pri == (inst->src.params.regs.sec >> 1 & 0x7)) { |
132 dst_reg = opts->gen.scratch1; | 136 dst_reg = opts->gen.scratch1; |
133 } | 137 } |
134 ldi_native(opts, inst->address+2, dst_reg); | 138 ldi_native(opts, inst->address+2, dst_reg); |
135 calc_index_disp8(opts, &inst->src, dst_reg); | 139 calc_index_disp8(opts, &inst->src, dst_reg); |
136 if (dst_reg == opts->gen.scratch1) { | 140 if (dst_reg == opts->gen.scratch1 && inst->op != M68K_PEA) { |
137 native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri); | 141 native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri); |
138 } | 142 } |
139 break; | 143 break; |
140 case MODE_ABSOLUTE: | 144 case MODE_ABSOLUTE: |
141 case MODE_ABSOLUTE_SHORT: | 145 case MODE_ABSOLUTE_SHORT: |
142 cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); | 146 cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); |
143 ldi_areg(opts, inst->src.params.immed, inst->dst.params.regs.pri); | 147 if (inst->op == M68K_PEA) { |
148 ldi_native(opts, inst->src.params.immed, dst_reg); | |
149 } else { | |
150 ldi_areg(opts, inst->src.params.immed, inst->dst.params.regs.pri); | |
151 } | |
144 break; | 152 break; |
145 default: | 153 default: |
146 m68k_disasm(inst, disasm_buf); | 154 m68k_disasm(inst, disasm_buf); |
147 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); | 155 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); |
148 exit(1); | 156 exit(1); |
149 } | 157 } |
150 } | 158 if (inst->op == M68K_PEA) { |
151 | 159 subi_areg(opts, 4, 7); |
152 void translate_m68k_pea(m68k_options * opts, m68kinst * inst) | 160 areg_to_native(opts, 7, opts->gen.scratch2); |
153 { | 161 call(code, opts->write_32_lowfirst); |
154 code_info *code = &opts->gen.code; | 162 } |
155 switch(inst->src.addr_mode) | |
156 { | |
157 case MODE_AREG_INDIRECT: | |
158 cycles(&opts->gen, BUS); | |
159 areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1); | |
160 break; | |
161 case MODE_AREG_DISPLACE: | |
162 cycles(&opts->gen, 8); | |
163 calc_areg_displace(opts, &inst->src, opts->gen.scratch1); | |
164 break; | |
165 case MODE_AREG_INDEX_DISP8: | |
166 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct | |
167 calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1); | |
168 break; | |
169 case MODE_PC_DISPLACE: | |
170 cycles(&opts->gen, 8); | |
171 ldi_native(opts, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1); | |
172 break; | |
173 case MODE_PC_INDEX_DISP8: | |
174 cycles(&opts->gen, BUS*3);//TODO: Check to make sure this is correct | |
175 ldi_native(opts, inst->address+2, opts->gen.scratch1); | |
176 calc_index_disp8(opts, &inst->src, opts->gen.scratch1); | |
177 break; | |
178 case MODE_ABSOLUTE: | |
179 case MODE_ABSOLUTE_SHORT: | |
180 cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); | |
181 ldi_native(opts, inst->src.params.immed, opts->gen.scratch1); | |
182 break; | |
183 default: | |
184 m68k_disasm(inst, disasm_buf); | |
185 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); | |
186 exit(1); | |
187 } | |
188 subi_areg(opts, 4, 7); | |
189 areg_to_native(opts, 7, opts->gen.scratch2); | |
190 call(code, opts->write_32_lowfirst); | |
191 } | 163 } |
192 | 164 |
193 void push_const(m68k_options *opts, int32_t value) | 165 void push_const(m68k_options *opts, int32_t value) |
194 { | 166 { |
195 ldi_native(opts, value, opts->gen.scratch1); | 167 ldi_native(opts, value, opts->gen.scratch1); |