tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0
authorAurelien Jarno <aurelien@aurel32.net>
Sat, 8 Sep 2012 03:45:43 +0000 (03:45 +0000)
committerAlexander Graf <agraf@suse.de>
Mon, 10 Sep 2012 11:38:33 +0000 (13:38 +0200)
The load/store slow path has been broken in e141ab52d:
- We need to move 4 registers for store functions and 3 registers for
  load functions and not the reverse.
- According to the s390x calling convention the arguments of a function
  should be zero extended. This means that the register shift should be
  done with TCG_TYPE_I64 to ensure the higher word is correctly zero
  extended when needed.

I am aware that CONFIG_TCG_PASS_AREG0 is being removed and thus that
this patch can be improved, but doing so means it can also be applied to
the 1.1 and 1.2 stable branches.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
tcg/s390/tcg-target.c

index 04662c15fd70623629d42d8850a04b0286a7906c..99b53390c5b783417a2aed3666eacd3af4586f08 100644 (file)
@@ -1509,11 +1509,13 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
 #ifdef CONFIG_TCG_PASS_AREG0
         /* XXX/FIXME: suboptimal */
-        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
+                    tcg_target_call_iarg_regs[2]);
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
                     tcg_target_call_iarg_regs[1]);
-        tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
                     tcg_target_call_iarg_regs[0]);
-        tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
                     TCG_AREG0);
 #endif
         tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
@@ -1521,13 +1523,11 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
         tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
 #ifdef CONFIG_TCG_PASS_AREG0
         /* XXX/FIXME: suboptimal */
-        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
-                    tcg_target_call_iarg_regs[2]);
         tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
                     tcg_target_call_iarg_regs[1]);
-        tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
                     tcg_target_call_iarg_regs[0]);
-        tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
                     TCG_AREG0);
 #endif
         tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);