static int feature_full_extension_format = 0;
static int feature_test_rounds = 2;
static int feature_flag_mode = 0;
-static int feature_odd_usp = 0;
+static int feature_usp = 0;
static TCHAR *feature_instruction_size = NULL;
static uae_u32 feature_addressing_modes[2];
static int ad8r[2], pc8r[2];
cpu_bus_error |= 2;
cpu_bus_error_fake |= 2;
}
+ if (!write && (fc & 2) && feature_usp == 3) {
+ out_of_test_space = true;
+ out_of_test_space_addr = addr;
+ }
}
}
static uae_u32 generate_stack_return(int cnt)
{
uae_u32 v;
- if (target_ea[0] != 0xffffffff) {
+ // if targer sp mode: generate random return address
+ if (target_ea[0] != 0xffffffff && feature_usp < 3) {
v = target_ea[0];
} else {
v = rand32();
int offset = 0;
if (dp->mnemo == i_RTE || dp->mnemo == i_RTD || dp->mnemo == i_RTS || dp->mnemo == i_RTR || dp->mnemo == i_UNLK) {
uae_u32 v;
- uaecptr addr = regs.regs[8 + 7];
+ uaecptr addr = regs.regs[15];
// RTE, RTD, RTS and RTR
- if (dp->mnemo == i_RTR) {
+ if (dp->mnemo == i_RTR) {
// RTR
v = imm_special++;
uae_u16 ccr = v & 31;
}
}
+// instruction that reads or writes stack
+static int stackinst(struct instr *dp)
+{
+ switch (dp->mnemo)
+ {
+ case i_RTS:
+ case i_RTR:
+ case i_RTD:
+ case i_RTE:
+ case i_UNLK:
+ return 1;
+ case i_BSR:
+ case i_JSR:
+ case i_LINK:
+ case i_PEA:
+ return 2;
+ }
+ return 0;
+}
+
// any instruction that can branch execution
static int isbranchinst(struct instr *dp)
{
int count = 0;
registers[8 + 6] = opcode_memory_start - 0x100;
- registers[8 + 7] = user_stack_memory_use;
+ registers[15] = user_stack_memory_use;
uae_u32 target_address = 0xffffffff;
uae_u32 target_opcode_address = 0xffffffff;
+ uae_u32 target_usp_address = 0xffffffff;
target_ea[0] = 0xffffffff;
target_ea[1] = 0xffffffff;
target_ea[2] = 0xffffffff;
if (feature_target_ea[0][2] && feature_target_ea[0][2] != 0xffffffff) {
- target_opcode_address = feature_target_ea[0][2];
- target_ea[2] = target_opcode_address;
+ if (feature_usp == 3) {
+ target_usp_address = feature_target_ea[0][2];
+ target_ea[2] = target_usp_address;
+ target_usp_address += opcode_memory_start;
+ } else {
+ target_opcode_address = feature_target_ea[0][2];
+ target_ea[2] = target_opcode_address;
+ }
}
if (feature_target_ea[0][0] != 0xffffffff) {
target_address = feature_target_ea[0][0];
target_address = target_address_bak;
target_opcode_address = target_opcode_address_bak;
+ if (target_usp_address != 0xffffffff) {
+ cur_registers[15] = target_usp_address;
+ regs.regs[15] = target_usp_address;
+ }
+
if (opc == 0x4a53)
printf("");
if (subtest_count >= 700)
}
// requested target address but no EA? skip
- if (target_address != 0xffffffff && isbranchinst(dp) != 2) {
+ if (target_address != 0xffffffff && isbranchinst(dp) != 2 && (feature_usp < 3 || !stackinst(dp))) {
if (srcea != target_address && dstea != target_address) {
memcpy(opcode_memory, oldcodebytes, sizeof(oldcodebytes));
continue;
for (int i = 0; i < 8; i++) {
regs.fp[i].fpx = cur_fpuregisters[i];
}
+
uaecptr nextpc;
srcaddr = 0xffffffff;
dstaddr = 0xffffffff;
constant_loops++;
quick = 0;
}
- srcaddr = get_long_test(regs.regs[8 + 7] + stackoffset);
+ srcaddr = get_long_test(regs.regs[15] + stackoffset);
}
// branch target is not accessible? skip.
- if ((srcaddr >= cur_registers[15] - 16 && srcaddr <= cur_registers[15] + 16) || ((srcaddr & 1) && !feature_exception3_instruction && feature_odd_usp < 2)) {
+ if ((srcaddr >= cur_registers[15] - 16 && srcaddr <= cur_registers[15] + 16) || ((srcaddr & 1) && !feature_exception3_instruction && feature_usp < 2)) {
// lets not jump directly to stack..
if (verbose) {
if (srcaddr & 1)
*dst++ = branch_target_swap_mode;
}
+ if (feature_usp >= 3) {
+ dst = store_reg(dst, CT_AREG + 7, 0, target_usp_address, sz_long);
+ }
+
// pre-test data end
*dst++ = CT_END_INIT;
regs.sr = ((ccr & 1) ? 31 : 0) | sr_mask;
}
regs.sr |= feature_min_interrupt_mask << 8;
- regs.usp = regs.regs[8 + 7];
+ regs.usp = regs.regs[15];
regs.isp = super_stack_memory - 0x80;
// copy user stack to super stack, for RTE etc support
memcpy(test_memory + (regs.isp - test_memory_start), test_memory + (regs.usp - test_memory_start), 0x20);
((cpu_bus_error & 2) && !(safe_memory_mode & 2))) {
skipped = 1;
}
+
// skip if feature_target_opcode_offset mode and non-prefetch bus error
if (target_opcode_address != 0xffffffff && (cpu_bus_error & 3)) {
skipped = 1;
if (feature_exception3_instruction == 2) {
skipped = 1;
}
- if (feature_odd_usp > 1) {
+ if (feature_usp == 2) {
skipped = 1;
}
}
}
// got exception 3 but didn't want them?
if (test_exception == 3) {
- if (!feature_odd_usp && !feature_exception3_data && !(test_exception_3_fc & 2)) {
+ if ((feature_usp != 1 && feature_usp != 2) && !feature_exception3_data && !(test_exception_3_fc & 2)) {
skipped = 1;
}
- if (!feature_odd_usp && !feature_exception3_instruction && (test_exception_3_fc & 2)) {
+ if ((feature_usp != 1 && feature_usp != 2) && !feature_exception3_instruction && (test_exception_3_fc & 2)) {
skipped = 1;
}
}
}
dst = storage_buffer;
- if (opcodecnt == 1 && target_address == 0xffffffff && target_opcode_address == 0xffffffff)
+ if (opcodecnt == 1 && target_address == 0xffffffff && target_opcode_address == 0xffffffff && target_usp_address == 0xffffffff)
break;
if (lookup->mnemo == i_ILLG)
break;
nextround = true;
}
- if (target_opcode_address != 0xffffffff) {
+ if (target_opcode_address != 0xffffffff || target_usp_address != 0xffffffff) {
nextround = false;
target_ea_opcode_cnt++;
if (target_ea_opcode_cnt >= target_ea_opcode_max) {
} else {
quick = 0;
}
- target_opcode_address = feature_target_ea[target_ea_opcode_cnt][2];
- target_ea[2] = opcode_memory_address + target_opcode_address;
+ if (feature_usp == 3) {
+ target_usp_address = feature_target_ea[target_ea_opcode_cnt][2];
+ target_usp_address += opcode_memory_start;
+ target_ea[2] = target_usp_address;
+ } else {
+ target_opcode_address = feature_target_ea[target_ea_opcode_cnt][2];
+ target_ea[2] = opcode_memory_address + target_opcode_address;
+ }
}
if (nextround) {
cur_registers[0] &= 0xffff;
cur_registers[8] &= 0xffff;
cur_registers[8 + 6]--;
- cur_registers[8 + 7] -= 2;
+ cur_registers[15] -= 2;
if (fpumode) {
for (int i = 0; i < 8; i++) {
}
feature_flag_mode = 0;
ini_getval(ini, INISECTION, _T("feature_flags_mode"), &feature_flag_mode);
- feature_odd_usp = 0;
- ini_getval(ini, INISECTION, _T("feature_odd_usp"), &feature_odd_usp);
+ feature_usp = 0;
+ ini_getval(ini, INISECTION, _T("feature_usp"), &feature_usp);
feature_full_extension_format = 0;
if (currprefs.cpu_model >= 68020) {
user_stack_memory = test_memory_start + RESERVED_SUPERSTACK;
}
user_stack_memory_use = user_stack_memory;
- if (feature_odd_usp) {
+ if (feature_usp == 1 || feature_usp == 2) {
user_stack_memory_use |= 1;
}
if (using_prefetch) {
irc2ir();
if (using_bus_error) {
- printf("\topcode = regs.ir;\n");
+ copy_opcode();
strcat(bus_error_code, "\t\tif (regs.t1) opcode |= 0x10000;\n");
}
fill_prefetch_1(m68k_pc_offset + 2);
if (using_bus_error) {
if (cond)
printf("\t%s\n\t", cond);
- printf("\topcode = regs.ir;\n");
+ copy_opcode();
bus_error_code[0] = 0;
if (format) {
va_list parms;
break;
case 2:
case -2:
- printf("\t\tm68k_areg(regs, %s) += 2 + %d;\n", bus_error_reg, offset);
+ if (g_instr->mnemo == i_RTR) {
+ ;
+ } else {
+ printf("\t\tm68k_areg(regs, %s) += 2 + %d;\n", bus_error_reg, offset);
+ }
break;
case 3:
case -3:
if ((g_instr->mnemo == i_ADDX || g_instr->mnemo == i_SUBX) && g_instr->size == sz_long) {
// ADDX.L/SUBX.L -(an),-(an) source: stack frame decreased by 2, not 4.
offset += 2;
+ } else if (g_instr->mnemo == i_RTR) {
+ if (offset) {
+ printf("\t\tm68k_areg(regs, %s) += 4;\n", bus_error_reg);
+ printf("\t\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
+ printf("\t\tregs.sr |= sr;\n");
+ printf("\t\tMakeFromSR();\n");
+ } else {
+ printf("\t\tm68k_areg(regs, %s) -= 2;\n", bus_error_reg);
+ }
} else {
printf("\t\tm68k_areg(regs, %s) = %sa;\n", bus_error_reg, name);
}
if (mnemo == i_LINK) {
// a7 -> a0 copy done before A7 address error check
- printf("\tm68k_areg(regs, srcreg) = olda;\n");
+ if (write) {
+ printf("\t\tm68k_areg(regs, 7) += 4;\n");
+ }
+ printf("\t\tm68k_areg(regs, srcreg) = olda;\n");
+ }
+ if (mnemo == i_PEA && write && offset && g_instr->smode != absw && g_instr->smode != absl) {
+ printf("\t\tif (regs.t1) opcode |= 0x10000;\n"); // I/N set
}
if (cpu_level == 1 && g_instr->mnemo == i_MVSR2 && !write) {
// write causing bus error and trace: set I/N
if (write && g_instr->size <= sz_word &&
mnemo != i_MOVE &&
+ mnemo != i_BSR &&
+ mnemo != i_LINK &&
mnemo != i_MVMEL && mnemo != i_MVMLE &&
- mnemo != i_MVPRM && mnemo != i_MVPMR) {
+ mnemo != i_MVPRM && mnemo != i_MVPMR) {
printf("\t\tif (regs.t1) opcode |= 0x10000;\n"); // I/N set
}
printf("\tuaecptr oldpc = %s;\n", getpc);
printf("\tMakeSR();\n");
genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, 0);
- genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
+ genamode(NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
if (cpu_level >= 4) {
printf("\tif (pc & 1) {\n");
printf("\t\tm68k_areg(regs, 7) -= 6;\n");
}
printf("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
printf("\tregs.sr |= sr;\n");
- setpc ("pc");
makefromsr();
+ setpc ("pc");
if (cpu_level < 4) {
printf("\tif (%s & 1) {\n", getpc);
printf("\t\tuaecptr faultpc = %s;\n", getpc);
if (using_prefetch || using_ce) {
int sp = (curi->smode == Ad16 || curi->smode == absw || curi->smode == absl || curi->smode == PC16 || curi->smode == Ad8r || curi->smode == PC8r) ? -1 : 0;
irc2ir();
- printf("\topcode = regs.ir;\n");
+ copy_opcode();
if (sp < 0)
printf("\tif(regs.t1) opcode |= 0x10000;\n");
printf("\t%s(%d);\n", prefetch_word, 2);
irc2ir();
printf("\t%s(%d);\n", prefetch_word, 2);
int sp = (curi->smode == Ad16 || curi->smode == absw || curi->smode == absl || curi->smode == PC16 || curi->smode == Ad8r || curi->smode == PC8r) ? -1 : 0;
- printf("\topcode = regs.ir;\n");
+ copy_opcode();
if (sp < 0)
printf("\tif(regs.t1) opcode |= 0x10000;\n");
check_prefetch_bus_error(-2, sp);
genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
genamode (NULL, Apdi, "7", sz_long, "dst", 2, 0, GF_AA);
if (!(curi->smode == absw || curi->smode == absl))
- fill_prefetch_next_after(1, "m68k_areg(regs, 7) += 4;\n");
+ fill_prefetch_next_after(0, "m68k_areg(regs, 7) += 4;\n");
if (curi->smode == Ad8r || curi->smode == PC8r)
addcycles000 (2);
genastore ("srca", Apdi, "7", sz_long, "dst");
add_head_cycs (6);
if (using_prefetch || using_ce) {
- printf("\topcode = regs.ir;\n");
+ copy_opcode();
printf("\tif(regs.t1) opcode |= 0x10000;\n");
printf("\t%s(%d);\n", prefetch_word, 2);
check_prefetch_bus_error(-2, -1);