summaryrefslogtreecommitdiff
path: root/emulators/tme/patches/patch-bb
blob: 6d6a3d5eb9424914dc65aeea7c1905b22650832f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
$NetBSD: patch-bb,v 1.1 2007/03/17 13:44:20 tsutsui Exp $

--- ic/m68k/m68k-insns-auto.sh.orig	2005-03-23 11:09:33.000000000 +0900
+++ ic/m68k/m68k-insns-auto.sh	2007-03-15 01:11:22.000000000 +0900
@@ -51,8 +51,92 @@
 _TME_RCSID("\$Id: patch-bb,v 1.1 2007/03/17 13:44:20 tsutsui Exp $");
 
 EOF
-if $header; then :; else
+if $header; then
     cat <<EOF
+
+/* following are to fix the movel sp,-(sp) problem (of the value being pushed
+   on the stack being off by four) and to warn if there are other possible
+   problems that haven't been tested */
+
+#define PREDEC_POSTINC_CONCERN	(					\\
+									\\
+/* if source and destination register are the same number */		\\
+    (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,0,3) ==			\\
+     TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,9,3)) &&			\\
+									\\
+/* and both are address registers */					\\
+    (									\\
+     (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) >= 1) &&		\\
+     (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) <= 6) &&		\\
+     (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3) >= 1) &&		\\
+     (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3) <= 6)		\\
+    ) &&								\\
+									\\
+/* and there is a predec or postinc in the src, or a predec in dest */	\\
+    (									\\
+     (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) == 3) ||		\\
+     (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) == 4) ||		\\
+     (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3) == 4)		\\
+    )									\\
+  )
+
+
+#define DEST_IS_PREDEC_SRC_IS_REG_BOTH_SP (				\\
+    (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3) == 4) &&		\\
+    (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) == 1) &&		\\
+    (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,0,3) == 7) &&		\\
+    (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,9,3) == 7)			\\
+  )
+
+/* following modes test ok */
+#define MODE35_MODE24_OR_MODE54	(					\\
+									\\
+/* src/dest mode 3,5 : this is move.l (a5)+,(028,a5) */			\\
+    (									\\
+      (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) == 3) &&		\\
+      (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3) == 5)		\\
+    ) ||								\\
+									\\
+/* or src/dest mode 2,4 : this is move.l (a5),-(a5) */			\\
+    (									\\
+      (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) == 2) &&		\\
+      (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3) == 4)		\\
+    ) ||								\\
+									\\
+/* or src/dest mode 5,4 : this is move.l (028,a5),-(a5) */		\\
+    (									\\
+      (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3) == 5) &&		\\
+      (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3) == 4)		\\
+    )									\\
+  ) 
+
+
+#define PRINT_WEIRD_SRC_DST_REG_MODE(msg)				\\
+  printf("%s\nsrc reg: %x src mode: %x dest reg: %x dest mode %x at pc:%x\n", \\
+    msg,								\\
+    TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,0,3),			\\
+    TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,3),			\\
+    TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,9,3),			\\
+    TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,6,3),			\\
+    ic->tme_m68k_ireg_pc)
+
+
+#define HITRETURN(msg)	do {						\\
+  printf("%s, pc:0x%08x, insn:0x%08x: please",				\\
+    msg, ic->tme_m68k_ireg_pc, TME_M68K_INSN_OPCODE);			\\
+  printf("  analyze M68K instruction.\n");				\\
+  printf("  generate test case.\n");					\\
+  printf("  if TME emulation is incorrect, correct problem.\n");	\\
+  printf("  modify source to avoid this message in the future.\n");	\\
+  printf("press any to continue:");					\\
+  (void)getchar();							\\
+  printf("continuing\n");						\\
+} while (0)
+
+EOF
+else
+    cat <<EOF
+#include <stdio.h>
 #include "m68k-impl.h"
 
 EOF
@@ -162,16 +246,16 @@
 		    echo ""
 		    echo "  if (!TME_M68K_SEQUENCE_RESTARTING) {"
 		    echo "    ic->_tme_m68k_ea_function_code = function_code;"
-		    echo "    ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);"
-		    echo "    ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;"
-		    echo "  }"
-		    echo "  tme_m68k_read_memx${size}(ic);"
-		    echo "  if (!TME_M68K_SEQUENCE_RESTARTING) {"
-		    echo "    ic->_tme_m68k_ea_function_code = function_code;"
 		    echo "    ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);"
 		    echo "    ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust;"
 		    echo "  }"
 		    echo "  tme_m68k_read_mem${size}(ic, TME_M68K_IREG_MEMY${size});"
+		    echo "  if (!TME_M68K_SEQUENCE_RESTARTING) {"
+		    echo "    ic->_tme_m68k_ea_function_code = function_code;"
+		    echo "    ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);"
+		    echo "    ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;"
+		    echo "  }"
+		    echo "  tme_m68k_read_memx${size}(ic);"
 		    echo "  ${dst} = ic->tme_m68k_ireg_memx${size};"
 		    echo "  ${src} = ic->tme_m68k_ireg_memy${size};"
 		    ;;
@@ -181,6 +265,12 @@
 		addx|subx)
 		    echo "  tme_uint16_t memory;"
 		    echo ""
+		    # sanity checks for addx/subx
+		    echo "  if ((ireg_src == ireg_dst) &&"
+		    echo "    (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,3,1) == 1)) {"
+		    echo "    HITRETURN(\"weird ${name}${size}\");"
+		    echo "  }"
+		    echo ""
 		    echo "  memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));"
 		    echo "  if (memory) {"
 		    echo "    TME_M68K_INSN_CANFAULT;"
@@ -239,6 +329,35 @@
 	    fi
 	    echo ";"
 
+	    # check "moveX sp,-(sp)" and adjust res
+	    if test ${name} = move; then
+		echo ""
+		echo "  if (PREDEC_POSTINC_CONCERN) {"
+		echo "    if (DEST_IS_PREDEC_SRC_IS_REG_BOTH_SP) {"
+		if test ${size} = 8; then
+		    echo "      printf(\"ERROR: ${name}${size}: how can addr/addr be 8 bits? at pc:%x\\n\","
+		    echo "        ic->tme_m68k_ireg_pc);"
+		else
+		    echo "#if 0"
+		    echo "      printf(\"${name}${size}: chg predec dest res from:%x to %x for register %d at pc %x\\n\","
+		    echo "         res, res + (${size} / 8), TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE,0,3), ic->tme_m68k_ireg_pc);"
+		    echo "#endif"
+		    echo "      res = res + (${size} / 8);"
+		fi
+		echo "      } else if (!(MODE35_MODE24_OR_MODE54)) {"
+		echo "        PRINT_WEIRD_SRC_DST_REG_MODE(\"WEIRD: ${name}${size}\");"
+		echo "    }"
+		echo "  }"
+	    fi
+
+	    # sanity check for cmpa16
+	    if test ${name} = cmpa; then
+		echo ""
+		echo "  if PREDEC_POSTINC_CONCERN {"
+		echo "    PRINT_WEIRD_SRC_DST_REG_MODE(\"weird ${name}${size}\");"
+		echo "  }"
+	    fi
+
 	    # store the result:
 	    if $store_res; then
 		echo ""
@@ -362,6 +481,10 @@
 	adda) op='+' ; src="_op0" ; dst="_op1" ;;
 	movea) op='' ; src="_op1" ; dst="_op0" ;;
 	esac
+	echo "  if (PREDEC_POSTINC_CONCERN) {"
+	echo "    PRINT_WEIRD_SRC_DST_REG_MODE(\"weird ${name}${size}\");"
+	echo "  }"
+	echo ""
 	echo "  *((tme_int32_t *) ${dst}) ${op}= *((tme_int${size}_t *) ${src});"
 	echo "  TME_M68K_INSN_OK;"
 	echo "}"
@@ -801,6 +924,10 @@
 		echo "  tme_uint16_t specopy = TME_M68K_INSN_OP0(tme_uint16_t);"
 		echo "  tme_uint32_t addrx;"
 		echo "  tme_uint32_t addry;"
+	    fi
+	    echo ""
+	    echo "  TME_M68K_INSN_CANFAULT;"
+	    if test $name = cas2_; then
 		echo ""
 		echo "  /* get the function code and addresses we'll be dealing with: */"
 		echo "  ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);"