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,6 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer 4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations) 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
  6 + * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
6 * 7 *
7 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 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,35 +220,13 @@ void glue(op_sdc1, MEMSUFFIX) (void)
220 glue(stq, MEMSUFFIX)(T0, DT0); 220 glue(stq, MEMSUFFIX)(T0, DT0);
221 RETURN(); 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 void glue(op_luxc1, MEMSUFFIX) (void) 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 RETURN(); 226 RETURN();
248 } 227 }
249 void glue(op_suxc1, MEMSUFFIX) (void) 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 RETURN(); 231 RETURN();
254 } 232 }
target-mips/translate.c
@@ -711,10 +711,6 @@ OP_LD_TABLE(wc1); @@ -711,10 +711,6 @@ OP_LD_TABLE(wc1);
711 OP_ST_TABLE(wc1); 711 OP_ST_TABLE(wc1);
712 OP_LD_TABLE(dc1); 712 OP_LD_TABLE(dc1);
713 OP_ST_TABLE(dc1); 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 OP_LD_TABLE(uxc1); 714 OP_LD_TABLE(uxc1);
719 OP_ST_TABLE(uxc1); 715 OP_ST_TABLE(uxc1);
720 716
@@ -1092,7 +1088,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, @@ -1092,7 +1088,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1092 return; 1088 return;
1093 } 1089 }
1094 GEN_STORE_TN_REG(rt, T0); 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 /* Arithmetic */ 1094 /* Arithmetic */
@@ -5242,25 +5238,36 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5242,25 +5238,36 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5242 5238
5243 /* Coprocessor 3 (FPU) */ 5239 /* Coprocessor 3 (FPU) */
5244 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd, 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 const char *opn = "extended float load/store"; 5243 const char *opn = "extended float load/store";
  5244 + int store = 0;
5248 5245
5249 /* All of those work only on 64bit FPUs. */ 5246 /* All of those work only on 64bit FPUs. */
5250 gen_op_cp1_64bitmode(); 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 /* Don't do NOP if destination is zero: we must perform the actual 5260 /* Don't do NOP if destination is zero: we must perform the actual
5254 * memory access 5261 * memory access
5255 */ 5262 */
5256 switch (opc) { 5263 switch (opc) {
5257 case OPC_LWXC1: 5264 case OPC_LWXC1:
5258 - op_ldst(lwxc1); 5265 + op_ldst(lwc1);
5259 GEN_STORE_FTN_FREG(fd, WT0); 5266 GEN_STORE_FTN_FREG(fd, WT0);
5260 opn = "lwxc1"; 5267 opn = "lwxc1";
5261 break; 5268 break;
5262 case OPC_LDXC1: 5269 case OPC_LDXC1:
5263 - op_ldst(ldxc1); 5270 + op_ldst(ldc1);
5264 GEN_STORE_FTN_FREG(fd, DT0); 5271 GEN_STORE_FTN_FREG(fd, DT0);
5265 opn = "ldxc1"; 5272 opn = "ldxc1";
5266 break; 5273 break;
@@ -5270,26 +5277,30 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd, @@ -5270,26 +5277,30 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5270 opn = "luxc1"; 5277 opn = "luxc1";
5271 break; 5278 break;
5272 case OPC_SWXC1: 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 opn = "swxc1"; 5282 opn = "swxc1";
  5283 + store = 1;
5276 break; 5284 break;
5277 case OPC_SDXC1: 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 opn = "sdxc1"; 5288 opn = "sdxc1";
  5289 + store = 1;
5281 break; 5290 break;
5282 case OPC_SUXC1: 5291 case OPC_SUXC1:
5283 - GEN_LOAD_FREG_FTN(DT0, fd); 5292 + GEN_LOAD_FREG_FTN(DT0, fs);
5284 op_ldst(suxc1); 5293 op_ldst(suxc1);
5285 opn = "suxc1"; 5294 opn = "suxc1";
  5295 + store = 1;
5286 break; 5296 break;
5287 default: 5297 default:
5288 MIPS_INVAL(opn); 5298 MIPS_INVAL(opn);
5289 generate_exception(ctx, EXCP_RI); 5299 generate_exception(ctx, EXCP_RI);
5290 return; 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 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd, 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,7 +5893,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5882 case OPC_SWXC1: 5893 case OPC_SWXC1:
5883 case OPC_SDXC1: 5894 case OPC_SDXC1:
5884 case OPC_SUXC1: 5895 case OPC_SUXC1:
5885 - gen_flt3_ldst(ctx, op1, sa, rs, rt); 5896 + gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5886 break; 5897 break;
5887 case OPC_PREFX: 5898 case OPC_PREFX:
5888 /* treat as noop */ 5899 /* treat as noop */