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 | 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 */ | ... | ... |