Commit 93b12ccc62debf438f0881898e6be0eeb51e1bdd
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
Showing
3 changed files
with
31 additions
and
41 deletions
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 */ |