]> git.proxmox.com Git - qemu.git/blobdiff - target-s390x/translate.c
qcow2: lock on prealloc
[qemu.git] / target-s390x / translate.c
index 141a72f0e8a98dd78a2e78bca46499457402bb1c..9bf8c38bb3b082dd62170bea1053e45b046cd2b0 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
 
 /* #define DEBUG_ILLEGAL_INSTRUCTIONS */
 /* #define DEBUG_INLINE_BRANCHES */
@@ -35,7 +30,6 @@
 #endif
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-log.h"
@@ -44,9 +38,9 @@
 static TCGv_ptr cpu_env;
 
 #include "gen-icount.h"
-#include "helpers.h"
+#include "helper.h"
 #define GEN_HELPER 1
-#include "helpers.h"
+#include "helper.h"
 
 typedef struct DisasContext DisasContext;
 struct DisasContext {
@@ -80,7 +74,7 @@ static inline uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
     return pc;
 }
 
-void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
+void cpu_dump_state(CPUS390XState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int i;
@@ -154,25 +148,25 @@ void s390x_translate_init(void)
     char *p;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-    psw_addr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, psw.addr),
+    psw_addr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, psw.addr),
                                       "psw_addr");
-    psw_mask = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, psw.mask),
+    psw_mask = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, psw.mask),
                                       "psw_mask");
 
-    cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op),
+    cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUS390XState, cc_op),
                                    "cc_op");
-    cc_src = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_src),
+    cc_src = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_src),
                                     "cc_src");
-    cc_dst = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_dst),
+    cc_dst = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_dst),
                                     "cc_dst");
-    cc_vr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_vr),
+    cc_vr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_vr),
                                    "cc_vr");
 
     p = cpu_reg_names;
     for (i = 0; i < 16; i++) {
         snprintf(p, cpu_reg_names_size, "r%d", i);
         regs[i] = tcg_global_mem_new(TCG_AREG0,
-                                     offsetof(CPUState, regs[i]), p);
+                                     offsetof(CPUS390XState, regs[i]), p);
         p += (i < 10) ? 3 : 4;
         cpu_reg_names_size -= (i < 10) ? 3 : 4;
     }
@@ -188,14 +182,14 @@ static inline TCGv_i64 load_reg(int reg)
 static inline TCGv_i64 load_freg(int reg)
 {
     TCGv_i64 r = tcg_temp_new_i64();
-    tcg_gen_ld_i64(r, cpu_env, offsetof(CPUState, fregs[reg].d));
+    tcg_gen_ld_i64(r, cpu_env, offsetof(CPUS390XState, fregs[reg].d));
     return r;
 }
 
 static inline TCGv_i32 load_freg32(int reg)
 {
     TCGv_i32 r = tcg_temp_new_i32();
-    tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, fregs[reg].l.upper));
+    tcg_gen_ld_i32(r, cpu_env, offsetof(CPUS390XState, fregs[reg].l.upper));
     return r;
 }
 
@@ -220,7 +214,7 @@ static inline void store_reg(int reg, TCGv_i64 v)
 
 static inline void store_freg(int reg, TCGv_i64 v)
 {
-    tcg_gen_st_i64(v, cpu_env, offsetof(CPUState, fregs[reg].d));
+    tcg_gen_st_i64(v, cpu_env, offsetof(CPUS390XState, fregs[reg].d));
 }
 
 static inline void store_reg32(int reg, TCGv_i32 v)
@@ -263,7 +257,7 @@ static inline void store_reg8(int reg, TCGv_i64 v)
 
 static inline void store_freg32(int reg, TCGv_i32 v)
 {
-    tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, fregs[reg].l.upper));
+    tcg_gen_st_i32(v, cpu_env, offsetof(CPUS390XState, fregs[reg].l.upper));
 }
 
 static inline void update_psw_addr(DisasContext *s)
@@ -367,11 +361,11 @@ static void gen_program_exception(DisasContext *s, int ilc, int code)
 
     /* remember what pgm exeption this was */
     tmp = tcg_const_i32(code);
-    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, int_pgm_code));
+    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_code));
     tcg_temp_free_i32(tmp);
 
     tmp = tcg_const_i32(ilc);
-    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, int_pgm_ilc));
+    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_ilc));
     tcg_temp_free_i32(tmp);
 
     /* advance past instruction */
@@ -831,7 +825,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc)
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         tcg_gen_movi_i64(psw_addr, pc);
-        tcg_gen_exit_tb((long)tb + tb_num);
+        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         tcg_gen_movi_i64(psw_addr, pc);
@@ -1078,9 +1072,12 @@ static void gen_jcc(DisasContext *s, uint32_t mask, int skip)
             tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip);
             break;
         default:
+            tcg_temp_free_i32(tmp);
+            tcg_temp_free_i32(tmp2);
             goto do_dynamic;
         }
         tcg_temp_free_i32(tmp);
+        tcg_temp_free_i32(tmp2);
         account_inline_branch(s);
         break;
     case CC_OP_TM_64:
@@ -1095,6 +1092,7 @@ static void gen_jcc(DisasContext *s, uint32_t mask, int skip)
             tcg_gen_brcondi_i64(TCG_COND_EQ, tmp64, 0, skip);
             break;
         default:
+            tcg_temp_free_i64(tmp64);
             goto do_dynamic;
         }
         tcg_temp_free_i64(tmp64);
@@ -2093,6 +2091,7 @@ do_mh:
             tcg_gen_add_i64(tmp, tmp, tmp3);
         }
         tcg_temp_free_i64(tmp);
+        tcg_temp_free_i64(tmp3);
         tcg_temp_free_i64(tmp4);
         break;
     case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */
@@ -2210,6 +2209,10 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
     addr = get_address(s, x2, b2, d2);
     tmp_r1 = tcg_const_i32(r1);
     switch (op) {
+    case 0x4: /* LDEB R1,D2(X2,B2) [RXE] */
+        potential_page_fault(s);
+        gen_helper_ldeb(tmp_r1, addr);
+        break;
     case 0x5: /* LXDB R1,D2(X2,B2) [RXE] */
         potential_page_fault(s);
         gen_helper_lxdb(tmp_r1, addr);
@@ -2329,18 +2332,22 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
     case 0x0: /* IIHH     R1,I2     [RI] */
         tmp = tcg_const_i64(i2);
         tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16);
+        tcg_temp_free_i64(tmp);
         break;
     case 0x1: /* IIHL     R1,I2     [RI] */
         tmp = tcg_const_i64(i2);
         tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16);
+        tcg_temp_free_i64(tmp);
         break;
     case 0x2: /* IILH     R1,I2     [RI] */
         tmp = tcg_const_i64(i2);
         tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16);
+        tcg_temp_free_i64(tmp);
         break;
     case 0x3: /* IILL     R1,I2     [RI] */
         tmp = tcg_const_i64(i2);
         tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16);
+        tcg_temp_free_i64(tmp);
         break;
     case 0x4: /* NIHH     R1,I2     [RI] */
     case 0x8: /* OIHH     R1,I2     [RI] */
@@ -2365,6 +2372,7 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
         set_cc_nz_u32(s, tmp32);
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32);
+        tcg_temp_free_i64(tmp);
         break;
     case 0x5: /* NIHL     R1,I2     [RI] */
     case 0x9: /* OIHL     R1,I2     [RI] */
@@ -2390,6 +2398,7 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
         set_cc_nz_u32(s, tmp32);
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32);
+        tcg_temp_free_i64(tmp);
         break;
     case 0x6: /* NILH     R1,I2     [RI] */
     case 0xa: /* OILH     R1,I2     [RI] */
@@ -2415,6 +2424,7 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
         set_cc_nz_u32(s, tmp32);
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32);
+        tcg_temp_free_i64(tmp);
         break;
     case 0x7: /* NILL     R1,I2     [RI] */
     case 0xb: /* OILL     R1,I2     [RI] */
@@ -2438,29 +2448,33 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
         set_cc_nz_u32(s, tmp32);        /* signedness should not matter here */
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32);
+        tcg_temp_free_i64(tmp);
         break;
     case 0xc: /* LLIHH     R1,I2     [RI] */
         tmp = tcg_const_i64( ((uint64_t)i2) << 48 );
         store_reg(r1, tmp);
+        tcg_temp_free_i64(tmp);
         break;
     case 0xd: /* LLIHL     R1,I2     [RI] */
         tmp = tcg_const_i64( ((uint64_t)i2) << 32 );
         store_reg(r1, tmp);
+        tcg_temp_free_i64(tmp);
         break;
     case 0xe: /* LLILH     R1,I2     [RI] */
         tmp = tcg_const_i64( ((uint64_t)i2) << 16 );
         store_reg(r1, tmp);
+        tcg_temp_free_i64(tmp);
         break;
     case 0xf: /* LLILL     R1,I2     [RI] */
         tmp = tcg_const_i64(i2);
         store_reg(r1, tmp);
+        tcg_temp_free_i64(tmp);
         break;
     default:
         LOG_DISAS("illegal a5 operation 0x%x\n", op);
         gen_illegal_opcode(s, 2);
         return;
     }
-    tcg_temp_free_i64(tmp);
 }
 
 static void disas_a7(DisasContext *s, int op, int r1, int i2)
@@ -2633,12 +2647,12 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
         break;
     case 0x4e: /* SAR     R1,R2     [RRE] */
         tmp32_1 = load_reg32(r2);
-        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, aregs[r1]));
+        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, aregs[r1]));
         tcg_temp_free_i32(tmp32_1);
         break;
     case 0x4f: /* EAR     R1,R2     [RRE] */
         tmp32_1 = tcg_temp_new_i32();
-        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, aregs[r2]));
+        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, aregs[r2]));
         store_reg32(r1, tmp32_1);
         tcg_temp_free_i32(tmp32_1);
         break;
@@ -2793,7 +2807,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
         decode_rs(s, insn, &r1, &r3, &b2, &d2);
         tmp = get_address(s, 0, b2, d2);
         tmp2 = tcg_temp_new_i64();
-        tcg_gen_ld_i64(tmp2, cpu_env, offsetof(CPUState, psa));
+        tcg_gen_ld_i64(tmp2, cpu_env, offsetof(CPUS390XState, psa));
         tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
         tcg_temp_free_i64(tmp);
         tcg_temp_free_i64(tmp2);
@@ -2805,7 +2819,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
         tmp = get_address(s, 0, b2, d2);
         tmp2 = tcg_temp_new_i64();
         tmp32_1 = tcg_temp_new_i32();
-        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, cpu_num));
+        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, cpu_num));
         tcg_gen_extu_i32_i64(tmp2, tmp32_1);
         tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
         tcg_temp_free_i64(tmp);
@@ -2934,7 +2948,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
         tmp32_1 = tcg_temp_new_i32();
         tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
         tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
-        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
+        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, fpc));
         tcg_temp_free_i64(tmp);
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32_1);
@@ -2962,6 +2976,8 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
         /* we need to keep cc_op intact */
         s->is_jmp = DISAS_JUMP;
         tcg_temp_free_i64(tmp);
+        tcg_temp_free_i64(tmp2);
+        tcg_temp_free_i64(tmp3);
         break;
     case 0x20: /* SERVC     R1,R2     [RRE] */
         /* SCLP Service call (PV hypercall) */
@@ -3142,12 +3158,12 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
         break;
     case 0x84: /* SFPC        R1                [RRE] */
         tmp32_1 = load_reg32(r1);
-        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
+        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, fpc));
         tcg_temp_free_i32(tmp32_1);
         break;
     case 0x8c: /* EFPC        R1                [RRE] */
         tmp32_1 = tcg_temp_new_i32();
-        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
+        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, fpc));
         store_reg32(r1, tmp32_1);
         tcg_temp_free_i32(tmp32_1);
         break;
@@ -3455,6 +3471,9 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i64(tmp3);
         break;
+    case 0x0f: /* LRVGR    R1,R2     [RRE] */
+        tcg_gen_bswap64_i64(regs[r1], regs[r2]);
+        break;
     case 0x1f: /* LRVR     R1,R2     [RRE] */
         tmp32_1 = load_reg32(r2);
         tcg_gen_bswap32_i32(tmp32_1, tmp32_1);
@@ -3910,8 +3929,8 @@ static void disas_s390_insn(DisasContext *s)
         tmp32_1 = tcg_const_i32(i);
         tmp32_2 = tcg_const_i32(ilc * 2);
         tmp32_3 = tcg_const_i32(EXCP_SVC);
-        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, int_svc_code));
-        tcg_gen_st_i32(tmp32_2, cpu_env, offsetof(CPUState, int_svc_ilc));
+        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, int_svc_code));
+        tcg_gen_st_i32(tmp32_2, cpu_env, offsetof(CPUS390XState, int_svc_ilc));
         gen_helper_exception(tmp32_3);
         s->is_jmp = DISAS_EXCP;
         tcg_temp_free_i32(tmp32_1);
@@ -4592,6 +4611,8 @@ static void disas_s390_insn(DisasContext *s)
         store_reg32(r1, tmp32_1);
         tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
         store_reg32(r1 + 1, tmp32_2);
+        tcg_temp_free_i64(tmp);
+        tcg_temp_free_i64(tmp2);
         break;
     case 0x98: /* LM     R1,R3,D2(B2)     [RS] */
     case 0x90: /* STM    R1,R3,D2(B2)     [RS] */
@@ -4615,6 +4636,7 @@ static void disas_s390_insn(DisasContext *s)
             }
             tcg_gen_add_i64(tmp, tmp, tmp3);
         }
+        tcg_temp_free_i64(tmp);
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i64(tmp3);
         tcg_temp_free_i64(tmp4);
@@ -4788,7 +4810,7 @@ static void disas_s390_insn(DisasContext *s)
             tmp32_1 = tcg_temp_new_i32();
             tmp = tcg_temp_new_i64();
             tmp2 = get_address(s, 0, b2, d2);
-            tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
+            tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, fpc));
             tcg_gen_extu_i32_i64(tmp, tmp32_1);
             tcg_gen_qemu_st32(tmp, tmp2, get_mem_index(s));
             tcg_temp_free_i32(tmp32_1);
@@ -5085,7 +5107,7 @@ static void disas_s390_insn(DisasContext *s)
     s->pc += (ilc * 2);
 }
 
-static inline void gen_intermediate_code_internal(CPUState *env,
+static inline void gen_intermediate_code_internal(CPUS390XState *env,
                                                   TranslationBlock *tb,
                                                   int search_pc)
 {
@@ -5201,17 +5223,17 @@ static inline void gen_intermediate_code_internal(CPUState *env,
 #endif
 }
 
-void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
+void gen_intermediate_code (CPUS390XState *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 0);
 }
 
-void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
+void gen_intermediate_code_pc (CPUS390XState *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
+void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, int pc_pos)
 {
     int cc_op;
     env->psw.addr = gen_opc_pc[pc_pos];