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,31 +991,37 @@ static void _decode_opc(DisasContext * ctx) | ||
| 991 | return; | 991 | return; |
| 992 | case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ | 992 | case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ |
| 993 | if (ctx->fpscr & FPSCR_SZ) { | 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 | } else { | 1000 | } else { |
| 999 | tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], REG(B11_8), ctx->memidx); | 1001 | tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], REG(B11_8), ctx->memidx); |
| 1000 | } | 1002 | } |
| 1001 | return; | 1003 | return; |
| 1002 | case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ | 1004 | case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ |
| 1003 | if (ctx->fpscr & FPSCR_SZ) { | 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 | } else { | 1012 | } else { |
| 1009 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); | 1013 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); |
| 1010 | } | 1014 | } |
| 1011 | return; | 1015 | return; |
| 1012 | case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ | 1016 | case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ |
| 1013 | if (ctx->fpscr & FPSCR_SZ) { | 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 | } else { | 1025 | } else { |
| 1020 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); | 1026 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); |
| 1021 | tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4); | 1027 | tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4); |
| @@ -1023,16 +1029,14 @@ static void _decode_opc(DisasContext * ctx) | @@ -1023,16 +1029,14 @@ static void _decode_opc(DisasContext * ctx) | ||
| 1023 | return; | 1029 | return; |
| 1024 | case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ | 1030 | case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ |
| 1025 | if (ctx->fpscr & FPSCR_SZ) { | 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 | tcg_gen_subi_i32(addr, REG(B11_8), 8); | 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 | tcg_temp_free(addr); | 1039 | tcg_temp_free(addr); |
| 1035 | - tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8); | ||
| 1036 | } else { | 1040 | } else { |
| 1037 | TCGv addr; | 1041 | TCGv addr; |
| 1038 | addr = tcg_temp_new_i32(); | 1042 | addr = tcg_temp_new_i32(); |
| @@ -1047,10 +1051,10 @@ static void _decode_opc(DisasContext * ctx) | @@ -1047,10 +1051,10 @@ static void _decode_opc(DisasContext * ctx) | ||
| 1047 | TCGv addr = tcg_temp_new_i32(); | 1051 | TCGv addr = tcg_temp_new_i32(); |
| 1048 | tcg_gen_add_i32(addr, REG(B7_4), REG(0)); | 1052 | tcg_gen_add_i32(addr, REG(B7_4), REG(0)); |
| 1049 | if (ctx->fpscr & FPSCR_SZ) { | 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 | } else { | 1058 | } else { |
| 1055 | tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], addr, ctx->memidx); | 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,10 +1066,10 @@ static void _decode_opc(DisasContext * ctx) | ||
| 1062 | TCGv addr = tcg_temp_new(); | 1066 | TCGv addr = tcg_temp_new(); |
| 1063 | tcg_gen_add_i32(addr, REG(B11_8), REG(0)); | 1067 | tcg_gen_add_i32(addr, REG(B11_8), REG(0)); |
| 1064 | if (ctx->fpscr & FPSCR_SZ) { | 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 | } else { | 1073 | } else { |
| 1070 | tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx); | 1074 | tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx); |
| 1071 | } | 1075 | } |