Fix indexed FP load/store instructions.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2837 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									cfc05abe4c
								
							
						
					
					
						commit
						93b12ccc62
					
				| @ -3,6 +3,7 @@ | ||||
|  *  | ||||
|  *  Copyright (c) 2004-2005 Jocelyn Mayer | ||||
|  *  Copyright (c) 2006 Marius Groeger (FPU operations) | ||||
|  *  Copyright (c) 2007 Thiemo Seufer (64-bit FPU support) | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  | ||||
| @ -220,35 +220,13 @@ void glue(op_sdc1, MEMSUFFIX) (void) | ||||
|     glue(stq, MEMSUFFIX)(T0, DT0); | ||||
|     RETURN(); | ||||
| } | ||||
| void glue(op_lwxc1, MEMSUFFIX) (void) | ||||
| { | ||||
|     WT0 = glue(ldl, MEMSUFFIX)(T0 + T1); | ||||
|     RETURN(); | ||||
| } | ||||
| void glue(op_swxc1, MEMSUFFIX) (void) | ||||
| { | ||||
|     glue(stl, MEMSUFFIX)(T0 + T1, WT0); | ||||
|     RETURN(); | ||||
| } | ||||
| void glue(op_ldxc1, MEMSUFFIX) (void) | ||||
| { | ||||
|     DT0 = glue(ldq, MEMSUFFIX)(T0 + T1); | ||||
|     RETURN(); | ||||
| } | ||||
| void glue(op_sdxc1, MEMSUFFIX) (void) | ||||
| { | ||||
|     glue(stq, MEMSUFFIX)(T0 + T1, DT0); | ||||
|     RETURN(); | ||||
| } | ||||
| void glue(op_luxc1, MEMSUFFIX) (void) | ||||
| { | ||||
|     /* XXX: is defined as unaligned */ | ||||
|     DT0 = glue(ldq, MEMSUFFIX)(T0 + T1); | ||||
|     DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7); | ||||
|     RETURN(); | ||||
| } | ||||
| void glue(op_suxc1, MEMSUFFIX) (void) | ||||
| { | ||||
|     /* XXX: is defined as unaligned */ | ||||
|     glue(stq, MEMSUFFIX)(T0 + T1, DT0); | ||||
|     glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0); | ||||
|     RETURN(); | ||||
| } | ||||
|  | ||||
| @ -711,10 +711,6 @@ OP_LD_TABLE(wc1); | ||||
| OP_ST_TABLE(wc1); | ||||
| OP_LD_TABLE(dc1); | ||||
| OP_ST_TABLE(dc1); | ||||
| OP_LD_TABLE(wxc1); | ||||
| OP_ST_TABLE(wxc1); | ||||
| OP_LD_TABLE(dxc1); | ||||
| OP_ST_TABLE(dxc1); | ||||
| OP_LD_TABLE(uxc1); | ||||
| OP_ST_TABLE(uxc1); | ||||
| 
 | ||||
| @ -1092,7 +1088,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, | ||||
|         return; | ||||
|     } | ||||
|     GEN_STORE_TN_REG(rt, T0); | ||||
|     MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm); | ||||
|     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); | ||||
| } | ||||
| 
 | ||||
| /* Arithmetic */ | ||||
| @ -5242,25 +5238,36 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, | ||||
| 
 | ||||
| /* Coprocessor 3 (FPU) */ | ||||
| static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd, | ||||
|                            int base, int index) | ||||
|                            int fs, int base, int index) | ||||
| { | ||||
|     const char *opn = "extended float load/store"; | ||||
|     int store = 0; | ||||
| 
 | ||||
|     /* All of those work only on 64bit FPUs. */ | ||||
|     gen_op_cp1_64bitmode(); | ||||
|     GEN_LOAD_REG_TN(T0, base); | ||||
|     GEN_LOAD_REG_TN(T1, index); | ||||
|     if (base == 0) { | ||||
|         if (index == 0) | ||||
|             gen_op_reset_T0(); | ||||
|         else | ||||
|             GEN_LOAD_REG_TN(T0, index); | ||||
|     } else if (index == 0) { | ||||
|         GEN_LOAD_REG_TN(T0, base); | ||||
|     } else { | ||||
|         GEN_LOAD_REG_TN(T0, base); | ||||
|         GEN_LOAD_REG_TN(T1, index); | ||||
|         gen_op_addr_add(); | ||||
|     } | ||||
|     /* Don't do NOP if destination is zero: we must perform the actual
 | ||||
|      * memory access | ||||
|      */ | ||||
|     switch (opc) { | ||||
|     case OPC_LWXC1: | ||||
|         op_ldst(lwxc1); | ||||
|         op_ldst(lwc1); | ||||
|         GEN_STORE_FTN_FREG(fd, WT0); | ||||
|         opn = "lwxc1"; | ||||
|         break; | ||||
|     case OPC_LDXC1: | ||||
|         op_ldst(ldxc1); | ||||
|         op_ldst(ldc1); | ||||
|         GEN_STORE_FTN_FREG(fd, DT0); | ||||
|         opn = "ldxc1"; | ||||
|         break; | ||||
| @ -5270,26 +5277,30 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd, | ||||
|         opn = "luxc1"; | ||||
|         break; | ||||
|     case OPC_SWXC1: | ||||
|         GEN_LOAD_FREG_FTN(WT0, fd); | ||||
|         op_ldst(swxc1); | ||||
|         GEN_LOAD_FREG_FTN(WT0, fs); | ||||
|         op_ldst(swc1); | ||||
|         opn = "swxc1"; | ||||
|         store = 1; | ||||
|         break; | ||||
|     case OPC_SDXC1: | ||||
|         GEN_LOAD_FREG_FTN(DT0, fd); | ||||
|         op_ldst(sdxc1); | ||||
|         GEN_LOAD_FREG_FTN(DT0, fs); | ||||
|         op_ldst(sdc1); | ||||
|         opn = "sdxc1"; | ||||
|         store = 1; | ||||
|         break; | ||||
|     case OPC_SUXC1: | ||||
|         GEN_LOAD_FREG_FTN(DT0, fd); | ||||
|         GEN_LOAD_FREG_FTN(DT0, fs); | ||||
|         op_ldst(suxc1); | ||||
|         opn = "suxc1"; | ||||
|         store = 1; | ||||
|         break; | ||||
|     default: | ||||
|         MIPS_INVAL(opn); | ||||
|         generate_exception(ctx, EXCP_RI); | ||||
|         return; | ||||
|     } | ||||
|     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[fd],regnames[index], regnames[base]); | ||||
|     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd], | ||||
|                regnames[index], regnames[base]); | ||||
| } | ||||
| 
 | ||||
| static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd, | ||||
| @ -5882,7 +5893,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||||
|             case OPC_SWXC1: | ||||
|             case OPC_SDXC1: | ||||
|             case OPC_SUXC1: | ||||
|                 gen_flt3_ldst(ctx, op1, sa, rs, rt); | ||||
|                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); | ||||
|                 break; | ||||
|             case OPC_PREFX: | ||||
|                 /* treat as noop */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 ths
						ths