Commit 4e9f853731f060236d9036663c12ca0594395d0d

Authored by ths
1 parent 0e21e12b

Fix [ls][wd][lr] instructions, by Aurelien Jarno.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3372 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -658,7 +658,7 @@ endif @@ -658,7 +658,7 @@ endif
658 ifeq ($(TARGET_BASE_ARCH), mips) 658 ifeq ($(TARGET_BASE_ARCH), mips)
659 helper.o: cpu.h exec-all.h 659 helper.o: cpu.h exec-all.h
660 op.o: op_template.c fop_template.c op_mem.c exec.h cpu.h 660 op.o: op_template.c fop_template.c op_mem.c exec.h cpu.h
661 -op_helper.o: op_helper_mem.c exec.h softmmu_template.h cpu.h 661 +op_helper.o: exec.h softmmu_template.h cpu.h
662 translate.o: translate_init.c exec-all.h disas.h 662 translate.o: translate_init.c exec-all.h disas.h
663 endif 663 endif
664 664
target-mips/exec.h
@@ -100,36 +100,6 @@ void fpu_dump_state(CPUState *env, FILE *f, @@ -100,36 +100,6 @@ void fpu_dump_state(CPUState *env, FILE *f,
100 int (*fpu_fprintf)(FILE *f, const char *fmt, ...), 100 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
101 int flags); 101 int flags);
102 void dump_sc (void); 102 void dump_sc (void);
103 -void do_lwl_raw (uint32_t);  
104 -void do_lwr_raw (uint32_t);  
105 -uint32_t do_swl_raw (uint32_t);  
106 -uint32_t do_swr_raw (uint32_t);  
107 -#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)  
108 -void do_ldl_raw (uint64_t);  
109 -void do_ldr_raw (uint64_t);  
110 -uint64_t do_sdl_raw (uint64_t);  
111 -uint64_t do_sdr_raw (uint64_t);  
112 -#endif  
113 -#if !defined(CONFIG_USER_ONLY)  
114 -void do_lwl_user (uint32_t);  
115 -void do_lwl_kernel (uint32_t);  
116 -void do_lwr_user (uint32_t);  
117 -void do_lwr_kernel (uint32_t);  
118 -uint32_t do_swl_user (uint32_t);  
119 -uint32_t do_swl_kernel (uint32_t);  
120 -uint32_t do_swr_user (uint32_t);  
121 -uint32_t do_swr_kernel (uint32_t);  
122 -#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)  
123 -void do_ldl_user (uint64_t);  
124 -void do_ldl_kernel (uint64_t);  
125 -void do_ldr_user (uint64_t);  
126 -void do_ldr_kernel (uint64_t);  
127 -uint64_t do_sdl_user (uint64_t);  
128 -uint64_t do_sdl_kernel (uint64_t);  
129 -uint64_t do_sdr_user (uint64_t);  
130 -uint64_t do_sdr_kernel (uint64_t);  
131 -#endif  
132 -#endif  
133 void do_pmon (int function); 103 void do_pmon (int function);
134 104
135 void dump_sc (void); 105 void dump_sc (void);
target-mips/op_helper.c
@@ -62,18 +62,6 @@ void do_raise_exception_direct (uint32_t exception) @@ -62,18 +62,6 @@ void do_raise_exception_direct (uint32_t exception)
62 do_raise_exception_direct_err (exception, 0); 62 do_raise_exception_direct_err (exception, 0);
63 } 63 }
64 64
65 -#define MEMSUFFIX _raw  
66 -#include "op_helper_mem.c"  
67 -#undef MEMSUFFIX  
68 -#if !defined(CONFIG_USER_ONLY)  
69 -#define MEMSUFFIX _user  
70 -#include "op_helper_mem.c"  
71 -#undef MEMSUFFIX  
72 -#define MEMSUFFIX _kernel  
73 -#include "op_helper_mem.c"  
74 -#undef MEMSUFFIX  
75 -#endif  
76 -  
77 #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) 65 #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
78 #if TARGET_LONG_BITS > HOST_LONG_BITS 66 #if TARGET_LONG_BITS > HOST_LONG_BITS
79 /* Those might call libgcc functions. */ 67 /* Those might call libgcc functions. */
target-mips/op_mem.c
@@ -75,34 +75,92 @@ void glue(op_sw, MEMSUFFIX) (void) @@ -75,34 +75,92 @@ void glue(op_sw, MEMSUFFIX) (void)
75 75
76 /* "half" load and stores. We must do the memory access inline, 76 /* "half" load and stores. We must do the memory access inline,
77 or fault handling won't work. */ 77 or fault handling won't work. */
78 -/* XXX: This is broken, CP0_BADVADDR has the wrong (aligned) value. */ 78 +
  79 +#ifdef TARGET_WORDS_BIGENDIAN
  80 +#define GET_LMASK(v) ((v) & 3)
  81 +#define GET_OFFSET(addr, offset) (addr + (offset))
  82 +#else
  83 +#define GET_LMASK(v) (((v) & 3) ^ 3)
  84 +#define GET_OFFSET(addr, offset) (addr - (offset))
  85 +#endif
  86 +
79 void glue(op_lwl, MEMSUFFIX) (void) 87 void glue(op_lwl, MEMSUFFIX) (void)
80 { 88 {
81 - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3);  
82 - CALL_FROM_TB1(glue(do_lwl, MEMSUFFIX), tmp); 89 + target_ulong tmp;
  90 +
  91 + tmp = glue(ldub, MEMSUFFIX)(T0);
  92 + T1 = (int32_t)((T1 & 0x00FFFFFF) | (tmp << 24));
  93 +
  94 + if (GET_LMASK(T0) <= 2) {
  95 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
  96 + T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
  97 + }
  98 +
  99 + if (GET_LMASK(T0) <= 1) {
  100 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
  101 + T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
  102 + }
  103 +
  104 + if (GET_LMASK(T0) == 0) {
  105 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
  106 + T1 = (T1 & 0xFFFFFF00) | tmp;
  107 + }
83 RETURN(); 108 RETURN();
84 } 109 }
85 110
86 void glue(op_lwr, MEMSUFFIX) (void) 111 void glue(op_lwr, MEMSUFFIX) (void)
87 { 112 {
88 - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3);  
89 - CALL_FROM_TB1(glue(do_lwr, MEMSUFFIX), tmp); 113 + target_ulong tmp;
  114 +
  115 + tmp = glue(ldub, MEMSUFFIX)(T0);
  116 + T1 = (T1 & 0xFFFFFF00) | tmp;
  117 +
  118 + if (GET_LMASK(T0) >= 1) {
  119 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
  120 + T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
  121 + }
  122 +
  123 + if (GET_LMASK(T0) >= 2) {
  124 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
  125 + T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
  126 + }
  127 +
  128 + if (GET_LMASK(T0) == 3) {
  129 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
  130 + T1 = (T1 & 0x00FFFFFF) | (tmp << 24);
  131 + }
90 RETURN(); 132 RETURN();
91 } 133 }
92 134
93 void glue(op_swl, MEMSUFFIX) (void) 135 void glue(op_swl, MEMSUFFIX) (void)
94 { 136 {
95 - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3);  
96 - tmp = CALL_FROM_TB1(glue(do_swl, MEMSUFFIX), tmp);  
97 - glue(stl, MEMSUFFIX)(T0 & ~3, tmp); 137 + glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 24));
  138 +
  139 + if (GET_LMASK(T0) <= 2)
  140 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16));
  141 +
  142 + if (GET_LMASK(T0) <= 1)
  143 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8));
  144 +
  145 + if (GET_LMASK(T0) == 0)
  146 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)T1);
  147 +
98 RETURN(); 148 RETURN();
99 } 149 }
100 150
101 void glue(op_swr, MEMSUFFIX) (void) 151 void glue(op_swr, MEMSUFFIX) (void)
102 { 152 {
103 - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3);  
104 - tmp = CALL_FROM_TB1(glue(do_swr, MEMSUFFIX), tmp);  
105 - glue(stl, MEMSUFFIX)(T0 & ~3, tmp); 153 + glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
  154 +
  155 + if (GET_LMASK(T0) >= 1)
  156 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
  157 +
  158 + if (GET_LMASK(T0) >= 2)
  159 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
  160 +
  161 + if (GET_LMASK(T0) == 3)
  162 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
  163 +
106 RETURN(); 164 RETURN();
107 } 165 }
108 166
@@ -145,33 +203,156 @@ void glue(op_sd, MEMSUFFIX) (void) @@ -145,33 +203,156 @@ void glue(op_sd, MEMSUFFIX) (void)
145 203
146 /* "half" load and stores. We must do the memory access inline, 204 /* "half" load and stores. We must do the memory access inline,
147 or fault handling won't work. */ 205 or fault handling won't work. */
  206 +
  207 +#ifdef TARGET_WORDS_BIGENDIAN
  208 +#define GET_LMASK64(v) ((v) & 7)
  209 +#else
  210 +#define GET_LMASK64(v) (((v) & 7) ^ 7)
  211 +#endif
  212 +
148 void glue(op_ldl, MEMSUFFIX) (void) 213 void glue(op_ldl, MEMSUFFIX) (void)
149 { 214 {
150 - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);  
151 - CALL_FROM_TB1(glue(do_ldl, MEMSUFFIX), tmp); 215 + uint64_t tmp;
  216 +
  217 + tmp = glue(ldub, MEMSUFFIX)(T0);
  218 + T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
  219 +
  220 + if (GET_LMASK64(T0) <= 6) {
  221 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
  222 + T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
  223 + }
  224 +
  225 + if (GET_LMASK64(T0) <= 5) {
  226 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
  227 + T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
  228 + }
  229 +
  230 + if (GET_LMASK64(T0) <= 4) {
  231 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
  232 + T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
  233 + }
  234 +
  235 + if (GET_LMASK64(T0) <= 3) {
  236 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 4));
  237 + T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
  238 + }
  239 +
  240 + if (GET_LMASK64(T0) <= 2) {
  241 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 5));
  242 + T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
  243 + }
  244 +
  245 + if (GET_LMASK64(T0) <= 1) {
  246 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 6));
  247 + T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
  248 + }
  249 +
  250 + if (GET_LMASK64(T0) == 0) {
  251 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 7));
  252 + T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
  253 + }
  254 +
152 RETURN(); 255 RETURN();
153 } 256 }
154 257
155 void glue(op_ldr, MEMSUFFIX) (void) 258 void glue(op_ldr, MEMSUFFIX) (void)
156 { 259 {
157 - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);  
158 - CALL_FROM_TB1(glue(do_ldr, MEMSUFFIX), tmp); 260 + uint64_t tmp;
  261 +
  262 + tmp = glue(ldub, MEMSUFFIX)(T0);
  263 + T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
  264 +
  265 + if (GET_LMASK64(T0) >= 1) {
  266 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
  267 + T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
  268 + }
  269 +
  270 + if (GET_LMASK64(T0) >= 2) {
  271 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
  272 + T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
  273 + }
  274 +
  275 + if (GET_LMASK64(T0) >= 3) {
  276 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
  277 + T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
  278 + }
  279 +
  280 + if (GET_LMASK64(T0) >= 4) {
  281 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -4));
  282 + T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
  283 + }
  284 +
  285 + if (GET_LMASK64(T0) >= 5) {
  286 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -5));
  287 + T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
  288 + }
  289 +
  290 + if (GET_LMASK64(T0) >= 6) {
  291 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -6));
  292 + T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
  293 + }
  294 +
  295 + if (GET_LMASK64(T0) == 7) {
  296 + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -7));
  297 + T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
  298 + }
  299 +
159 RETURN(); 300 RETURN();
160 } 301 }
161 302
162 void glue(op_sdl, MEMSUFFIX) (void) 303 void glue(op_sdl, MEMSUFFIX) (void)
163 { 304 {
164 - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);  
165 - tmp = CALL_FROM_TB1(glue(do_sdl, MEMSUFFIX), tmp);  
166 - glue(stq, MEMSUFFIX)(T0 & ~7, tmp); 305 + glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 56));
  306 +
  307 + if (GET_LMASK64(T0) <= 6)
  308 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48));
  309 +
  310 + if (GET_LMASK64(T0) <= 5)
  311 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40));
  312 +
  313 + if (GET_LMASK64(T0) <= 4)
  314 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32));
  315 +
  316 + if (GET_LMASK64(T0) <= 3)
  317 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24));
  318 +
  319 + if (GET_LMASK64(T0) <= 2)
  320 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16));
  321 +
  322 + if (GET_LMASK64(T0) <= 1)
  323 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8));
  324 +
  325 + if (GET_LMASK64(T0) <= 0)
  326 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 7), (uint8_t)T1);
  327 +
167 RETURN(); 328 RETURN();
168 } 329 }
169 330
170 void glue(op_sdr, MEMSUFFIX) (void) 331 void glue(op_sdr, MEMSUFFIX) (void)
171 { 332 {
172 - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);  
173 - tmp = CALL_FROM_TB1(glue(do_sdr, MEMSUFFIX), tmp);  
174 - glue(stq, MEMSUFFIX)(T0 & ~7, tmp); 333 + glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
  334 +
  335 + if (GET_LMASK64(T0) >= 1)
  336 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
  337 +
  338 + if (GET_LMASK64(T0) >= 2)
  339 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
  340 +
  341 + if (GET_LMASK64(T0) >= 3)
  342 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
  343 +
  344 + if (GET_LMASK64(T0) >= 4)
  345 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32));
  346 +
  347 + if (GET_LMASK64(T0) >= 5)
  348 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40));
  349 +
  350 + if (GET_LMASK64(T0) >= 6)
  351 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48));
  352 +
  353 + if (GET_LMASK64(T0) == 7)
  354 + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56));
  355 +
175 RETURN(); 356 RETURN();
176 } 357 }
177 358
target-mips/translate.c
@@ -889,7 +889,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -889,7 +889,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
889 case OPC_LDL: 889 case OPC_LDL:
890 GEN_LOAD_REG_TN(T1, rt); 890 GEN_LOAD_REG_TN(T1, rt);
891 op_ldst(ldl); 891 op_ldst(ldl);
892 - GEN_STORE_TN_REG(rt, T0); 892 + GEN_STORE_TN_REG(rt, T1);
893 opn = "ldl"; 893 opn = "ldl";
894 break; 894 break;
895 case OPC_SDL: 895 case OPC_SDL:
@@ -900,7 +900,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -900,7 +900,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
900 case OPC_LDR: 900 case OPC_LDR:
901 GEN_LOAD_REG_TN(T1, rt); 901 GEN_LOAD_REG_TN(T1, rt);
902 op_ldst(ldr); 902 op_ldst(ldr);
903 - GEN_STORE_TN_REG(rt, T0); 903 + GEN_STORE_TN_REG(rt, T1);
904 opn = "ldr"; 904 opn = "ldr";
905 break; 905 break;
906 case OPC_SDR: 906 case OPC_SDR:
@@ -952,7 +952,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -952,7 +952,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
952 case OPC_LWL: 952 case OPC_LWL:
953 GEN_LOAD_REG_TN(T1, rt); 953 GEN_LOAD_REG_TN(T1, rt);
954 op_ldst(lwl); 954 op_ldst(lwl);
955 - GEN_STORE_TN_REG(rt, T0); 955 + GEN_STORE_TN_REG(rt, T1);
956 opn = "lwl"; 956 opn = "lwl";
957 break; 957 break;
958 case OPC_SWL: 958 case OPC_SWL:
@@ -963,7 +963,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -963,7 +963,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
963 case OPC_LWR: 963 case OPC_LWR:
964 GEN_LOAD_REG_TN(T1, rt); 964 GEN_LOAD_REG_TN(T1, rt);
965 op_ldst(lwr); 965 op_ldst(lwr);
966 - GEN_STORE_TN_REG(rt, T0); 966 + GEN_STORE_TN_REG(rt, T1);
967 opn = "lwr"; 967 opn = "lwr";
968 break; 968 break;
969 case OPC_SWR: 969 case OPC_SWR: