Commit 11bb09f1be8e5157b21065e14efda7fd0c7221e7
1 parent
64adab3f
target-sh4: fix 64-bit fmov to/from memory
When loading/storing a register pair, the even-numbered register always maps to the low 32 bits of memory independently of target endian configuration. Signed-off-by: Mans Rullgard <mans@mansr.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5773 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
33 additions
and
29 deletions
target-sh4/translate.c
... | ... | @@ -991,31 +991,37 @@ static void _decode_opc(DisasContext * ctx) |
991 | 991 | return; |
992 | 992 | case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ |
993 | 993 | if (ctx->fpscr & FPSCR_SZ) { |
994 | - TCGv_i64 fp = tcg_temp_new_i64(); | |
995 | - gen_load_fpr64(fp, XREG(B7_4)); | |
996 | - tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx); | |
997 | - tcg_temp_free_i64(fp); | |
994 | + TCGv addr_hi = tcg_temp_new(); | |
995 | + int fr = XREG(B7_4); | |
996 | + tcg_gen_addi_i32(addr_hi, REG(B11_8), 4); | |
997 | + tcg_gen_qemu_st32(cpu_fregs[fr ], REG(B11_8), ctx->memidx); | |
998 | + tcg_gen_qemu_st32(cpu_fregs[fr+1], addr_hi, ctx->memidx); | |
999 | + tcg_temp_free(addr_hi); | |
998 | 1000 | } else { |
999 | 1001 | tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], REG(B11_8), ctx->memidx); |
1000 | 1002 | } |
1001 | 1003 | return; |
1002 | 1004 | case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ |
1003 | 1005 | if (ctx->fpscr & FPSCR_SZ) { |
1004 | - TCGv_i64 fp = tcg_temp_new_i64(); | |
1005 | - tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx); | |
1006 | - gen_store_fpr64(fp, XREG(B11_8)); | |
1007 | - tcg_temp_free_i64(fp); | |
1006 | + TCGv addr_hi = tcg_temp_new(); | |
1007 | + int fr = XREG(B11_8); | |
1008 | + tcg_gen_addi_i32(addr_hi, REG(B7_4), 4); | |
1009 | + tcg_gen_qemu_ld32u(cpu_fregs[fr ], REG(B7_4), ctx->memidx); | |
1010 | + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr_hi, ctx->memidx); | |
1011 | + tcg_temp_free(addr_hi); | |
1008 | 1012 | } else { |
1009 | 1013 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); |
1010 | 1014 | } |
1011 | 1015 | return; |
1012 | 1016 | case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ |
1013 | 1017 | if (ctx->fpscr & FPSCR_SZ) { |
1014 | - TCGv_i64 fp = tcg_temp_new_i64(); | |
1015 | - tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx); | |
1016 | - gen_store_fpr64(fp, XREG(B11_8)); | |
1017 | - tcg_temp_free_i64(fp); | |
1018 | - tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8); | |
1018 | + TCGv addr_hi = tcg_temp_new(); | |
1019 | + int fr = XREG(B11_8); | |
1020 | + tcg_gen_addi_i32(addr_hi, REG(B7_4), 4); | |
1021 | + tcg_gen_qemu_ld32u(cpu_fregs[fr ], REG(B7_4), ctx->memidx); | |
1022 | + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr_hi, ctx->memidx); | |
1023 | + tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8); | |
1024 | + tcg_temp_free(addr_hi); | |
1019 | 1025 | } else { |
1020 | 1026 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); |
1021 | 1027 | tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4); |
... | ... | @@ -1023,16 +1029,14 @@ static void _decode_opc(DisasContext * ctx) |
1023 | 1029 | return; |
1024 | 1030 | case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ |
1025 | 1031 | if (ctx->fpscr & FPSCR_SZ) { |
1026 | - TCGv addr; | |
1027 | - TCGv_i64 fp; | |
1028 | - addr = tcg_temp_new(); | |
1032 | + TCGv addr = tcg_temp_new_i32(); | |
1033 | + int fr = XREG(B7_4); | |
1034 | + tcg_gen_subi_i32(addr, REG(B11_8), 4); | |
1035 | + tcg_gen_qemu_st32(cpu_fregs[fr+1], addr, ctx->memidx); | |
1029 | 1036 | tcg_gen_subi_i32(addr, REG(B11_8), 8); |
1030 | - fp = tcg_temp_new_i64(); | |
1031 | - gen_load_fpr64(fp, XREG(B7_4)); | |
1032 | - tcg_gen_qemu_st64(fp, addr, ctx->memidx); | |
1033 | - tcg_temp_free_i64(fp); | |
1037 | + tcg_gen_qemu_st32(cpu_fregs[fr ], addr, ctx->memidx); | |
1038 | + tcg_gen_mov_i32(REG(B11_8), addr); | |
1034 | 1039 | tcg_temp_free(addr); |
1035 | - tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8); | |
1036 | 1040 | } else { |
1037 | 1041 | TCGv addr; |
1038 | 1042 | addr = tcg_temp_new_i32(); |
... | ... | @@ -1047,10 +1051,10 @@ static void _decode_opc(DisasContext * ctx) |
1047 | 1051 | TCGv addr = tcg_temp_new_i32(); |
1048 | 1052 | tcg_gen_add_i32(addr, REG(B7_4), REG(0)); |
1049 | 1053 | if (ctx->fpscr & FPSCR_SZ) { |
1050 | - TCGv_i64 fp = tcg_temp_new_i64(); | |
1051 | - tcg_gen_qemu_ld64(fp, addr, ctx->memidx); | |
1052 | - gen_store_fpr64(fp, XREG(B11_8)); | |
1053 | - tcg_temp_free_i64(fp); | |
1054 | + int fr = XREG(B11_8); | |
1055 | + tcg_gen_qemu_ld32u(cpu_fregs[fr ], addr, ctx->memidx); | |
1056 | + tcg_gen_addi_i32(addr, addr, 4); | |
1057 | + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr, ctx->memidx); | |
1054 | 1058 | } else { |
1055 | 1059 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], addr, ctx->memidx); |
1056 | 1060 | } |
... | ... | @@ -1062,10 +1066,10 @@ static void _decode_opc(DisasContext * ctx) |
1062 | 1066 | TCGv addr = tcg_temp_new(); |
1063 | 1067 | tcg_gen_add_i32(addr, REG(B11_8), REG(0)); |
1064 | 1068 | if (ctx->fpscr & FPSCR_SZ) { |
1065 | - TCGv_i64 fp = tcg_temp_new_i64(); | |
1066 | - gen_load_fpr64(fp, XREG(B7_4)); | |
1067 | - tcg_gen_qemu_st64(fp, addr, ctx->memidx); | |
1068 | - tcg_temp_free_i64(fp); | |
1069 | + int fr = XREG(B7_4); | |
1070 | + tcg_gen_qemu_ld32u(cpu_fregs[fr ], addr, ctx->memidx); | |
1071 | + tcg_gen_addi_i32(addr, addr, 4); | |
1072 | + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr, ctx->memidx); | |
1069 | 1073 | } else { |
1070 | 1074 | tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx); |
1071 | 1075 | } | ... | ... |