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);