Commit 93b12ccc62debf438f0881898e6be0eeb51e1bdd

Authored by ths
1 parent cfc05abe

Fix indexed FP load/store instructions.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2837 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/op.c
... ... @@ -3,6 +3,7 @@
3 3 *
4 4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
  6 + * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
6 7 *
7 8 * This library is free software; you can redistribute it and/or
8 9 * modify it under the terms of the GNU Lesser General Public
... ...
target-mips/op_mem.c
... ... @@ -220,35 +220,13 @@ void glue(op_sdc1, MEMSUFFIX) (void)
220 220 glue(stq, MEMSUFFIX)(T0, DT0);
221 221 RETURN();
222 222 }
223   -void glue(op_lwxc1, MEMSUFFIX) (void)
224   -{
225   - WT0 = glue(ldl, MEMSUFFIX)(T0 + T1);
226   - RETURN();
227   -}
228   -void glue(op_swxc1, MEMSUFFIX) (void)
229   -{
230   - glue(stl, MEMSUFFIX)(T0 + T1, WT0);
231   - RETURN();
232   -}
233   -void glue(op_ldxc1, MEMSUFFIX) (void)
234   -{
235   - DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
236   - RETURN();
237   -}
238   -void glue(op_sdxc1, MEMSUFFIX) (void)
239   -{
240   - glue(stq, MEMSUFFIX)(T0 + T1, DT0);
241   - RETURN();
242   -}
243 223 void glue(op_luxc1, MEMSUFFIX) (void)
244 224 {
245   - /* XXX: is defined as unaligned */
246   - DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
  225 + DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7);
247 226 RETURN();
248 227 }
249 228 void glue(op_suxc1, MEMSUFFIX) (void)
250 229 {
251   - /* XXX: is defined as unaligned */
252   - glue(stq, MEMSUFFIX)(T0 + T1, DT0);
  230 + glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0);
253 231 RETURN();
254 232 }
... ...
target-mips/translate.c
... ... @@ -711,10 +711,6 @@ OP_LD_TABLE(wc1);
711 711 OP_ST_TABLE(wc1);
712 712 OP_LD_TABLE(dc1);
713 713 OP_ST_TABLE(dc1);
714   -OP_LD_TABLE(wxc1);
715   -OP_ST_TABLE(wxc1);
716   -OP_LD_TABLE(dxc1);
717   -OP_ST_TABLE(dxc1);
718 714 OP_LD_TABLE(uxc1);
719 715 OP_ST_TABLE(uxc1);
720 716  
... ... @@ -1092,7 +1088,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1092 1088 return;
1093 1089 }
1094 1090 GEN_STORE_TN_REG(rt, T0);
1095   - MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
  1091 + MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1096 1092 }
1097 1093  
1098 1094 /* Arithmetic */
... ... @@ -5242,25 +5238,36 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5242 5238  
5243 5239 /* Coprocessor 3 (FPU) */
5244 5240 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5245   - int base, int index)
  5241 + int fs, int base, int index)
5246 5242 {
5247 5243 const char *opn = "extended float load/store";
  5244 + int store = 0;
5248 5245  
5249 5246 /* All of those work only on 64bit FPUs. */
5250 5247 gen_op_cp1_64bitmode();
5251   - GEN_LOAD_REG_TN(T0, base);
5252   - GEN_LOAD_REG_TN(T1, index);
  5248 + if (base == 0) {
  5249 + if (index == 0)
  5250 + gen_op_reset_T0();
  5251 + else
  5252 + GEN_LOAD_REG_TN(T0, index);
  5253 + } else if (index == 0) {
  5254 + GEN_LOAD_REG_TN(T0, base);
  5255 + } else {
  5256 + GEN_LOAD_REG_TN(T0, base);
  5257 + GEN_LOAD_REG_TN(T1, index);
  5258 + gen_op_addr_add();
  5259 + }
5253 5260 /* Don't do NOP if destination is zero: we must perform the actual
5254 5261 * memory access
5255 5262 */
5256 5263 switch (opc) {
5257 5264 case OPC_LWXC1:
5258   - op_ldst(lwxc1);
  5265 + op_ldst(lwc1);
5259 5266 GEN_STORE_FTN_FREG(fd, WT0);
5260 5267 opn = "lwxc1";
5261 5268 break;
5262 5269 case OPC_LDXC1:
5263   - op_ldst(ldxc1);
  5270 + op_ldst(ldc1);
5264 5271 GEN_STORE_FTN_FREG(fd, DT0);
5265 5272 opn = "ldxc1";
5266 5273 break;
... ... @@ -5270,26 +5277,30 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5270 5277 opn = "luxc1";
5271 5278 break;
5272 5279 case OPC_SWXC1:
5273   - GEN_LOAD_FREG_FTN(WT0, fd);
5274   - op_ldst(swxc1);
  5280 + GEN_LOAD_FREG_FTN(WT0, fs);
  5281 + op_ldst(swc1);
5275 5282 opn = "swxc1";
  5283 + store = 1;
5276 5284 break;
5277 5285 case OPC_SDXC1:
5278   - GEN_LOAD_FREG_FTN(DT0, fd);
5279   - op_ldst(sdxc1);
  5286 + GEN_LOAD_FREG_FTN(DT0, fs);
  5287 + op_ldst(sdc1);
5280 5288 opn = "sdxc1";
  5289 + store = 1;
5281 5290 break;
5282 5291 case OPC_SUXC1:
5283   - GEN_LOAD_FREG_FTN(DT0, fd);
  5292 + GEN_LOAD_FREG_FTN(DT0, fs);
5284 5293 op_ldst(suxc1);
5285 5294 opn = "suxc1";
  5295 + store = 1;
5286 5296 break;
5287 5297 default:
5288 5298 MIPS_INVAL(opn);
5289 5299 generate_exception(ctx, EXCP_RI);
5290 5300 return;
5291 5301 }
5292   - MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[fd],regnames[index], regnames[base]);
  5302 + MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
  5303 + regnames[index], regnames[base]);
5293 5304 }
5294 5305  
5295 5306 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
... ... @@ -5882,7 +5893,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5882 5893 case OPC_SWXC1:
5883 5894 case OPC_SDXC1:
5884 5895 case OPC_SUXC1:
5885   - gen_flt3_ldst(ctx, op1, sa, rs, rt);
  5896 + gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5886 5897 break;
5887 5898 case OPC_PREFX:
5888 5899 /* treat as noop */
... ...