diff --git a/qemu/aarch64.h b/qemu/aarch64.h index c56b7aeb..60c58623 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_aarch64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_aarch64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_aarch64 +#define tcg_gen_mb tcg_gen_mb_aarch64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_aarch64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_aarch64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 7fbae051..100348f7 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_aarch64eb #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_aarch64eb #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_aarch64eb +#define tcg_gen_mb tcg_gen_mb_aarch64eb #define tcg_gen_mov_i32 tcg_gen_mov_i32_aarch64eb #define tcg_gen_mov_i64 tcg_gen_mov_i64_aarch64eb #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 26612074..d34835e9 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_arm #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_arm #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_arm +#define tcg_gen_mb tcg_gen_mb_arm #define tcg_gen_mov_i32 tcg_gen_mov_i32_arm #define tcg_gen_mov_i64 tcg_gen_mov_i64_arm #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 01c17f69..42a0370d 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_armeb #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_armeb #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_armeb +#define tcg_gen_mb tcg_gen_mb_armeb #define tcg_gen_mov_i32 tcg_gen_mov_i32_armeb #define tcg_gen_mov_i64 tcg_gen_mov_i64_armeb #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 61273a3a..187416d1 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2810,6 +2810,7 @@ symbols = ( 'tcg_gen_ld_i64', 'tcg_gen_ldst_op_i32', 'tcg_gen_ldst_op_i64', + 'tcg_gen_mb', 'tcg_gen_mov_i32', 'tcg_gen_mov_i64', 'tcg_gen_movcond_i32', diff --git a/qemu/m68k.h b/qemu/m68k.h index 9def456c..01837d15 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_m68k #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_m68k #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_m68k +#define tcg_gen_mb tcg_gen_mb_m68k #define tcg_gen_mov_i32 tcg_gen_mov_i32_m68k #define tcg_gen_mov_i64 tcg_gen_mov_i64_m68k #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index d665d6d6..2d34093b 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mips #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mips #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mips +#define tcg_gen_mb tcg_gen_mb_mips #define tcg_gen_mov_i32 tcg_gen_mov_i32_mips #define tcg_gen_mov_i64 tcg_gen_mov_i64_mips #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index f3228165..d58b44cc 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mips64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mips64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mips64 +#define tcg_gen_mb tcg_gen_mb_mips64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_mips64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_mips64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 72a465dd..0bb68a19 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mips64el #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mips64el #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mips64el +#define tcg_gen_mb tcg_gen_mb_mips64el #define tcg_gen_mov_i32 tcg_gen_mov_i32_mips64el #define tcg_gen_mov_i64 tcg_gen_mov_i64_mips64el #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index b69a8ee0..4f054c02 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_mipsel #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_mipsel #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_mipsel +#define tcg_gen_mb tcg_gen_mb_mipsel #define tcg_gen_mov_i32 tcg_gen_mov_i32_mipsel #define tcg_gen_mov_i64 tcg_gen_mov_i64_mipsel #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 401107c6..ad1a143e 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_powerpc #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_powerpc #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_powerpc +#define tcg_gen_mb tcg_gen_mb_powerpc #define tcg_gen_mov_i32 tcg_gen_mov_i32_powerpc #define tcg_gen_mov_i64 tcg_gen_mov_i64_powerpc #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index bb708220..67a357d5 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_sparc #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_sparc #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_sparc +#define tcg_gen_mb tcg_gen_mb_sparc #define tcg_gen_mov_i32 tcg_gen_mov_i32_sparc #define tcg_gen_mov_i64 tcg_gen_mov_i64_sparc #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 2f952b70..ca2f6044 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_sparc64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_sparc64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_sparc64 +#define tcg_gen_mb tcg_gen_mb_sparc64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_sparc64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_sparc64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_sparc64 diff --git a/qemu/tcg/README b/qemu/tcg/README index 34c0775c..908e9704 100644 --- a/qemu/tcg/README +++ b/qemu/tcg/README @@ -402,6 +402,23 @@ double-word product T0. The later is returned in two single-word outputs. Similar to mulu2, except the two inputs T1 and T2 are signed. +********* Memory Barrier support + +* mb <$arg> + +Generate a target memory barrier instruction to ensure memory ordering as being +enforced by a corresponding guest memory barrier instruction. The ordering +enforced by the backend may be stricter than the ordering required by the guest. +It cannot be weaker. This opcode takes a constant argument which is required to +generate the appropriate barrier instruction. The backend should take care to +emit the target barrier instruction only when necessary i.e., for SMP guests and +when MTTCG is enabled. + +The guest translators should generate this opcode for all guest instructions +which have ordering side effects. + +Please see docs/atomics.txt for more information on memory barriers. + ********* 64-bit guest on 32-bit host support The following opcodes are internal to TCG. Thus they are to be implemented by diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index 19fd5f5d..4a74c24c 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -147,6 +147,23 @@ void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2, tcg_emit_op(ctx, opc, pi); } +void tcg_gen_mb(TCGContext *ctx, TCGBar mb_type) +{ + bool emit_barriers = true; + +#ifndef CONFIG_USER_ONLY + /* TODO: When MTTCG is available for system mode, we will check + * the following condition and enable emit_barriers + * (qemu_tcg_mttcg_enabled() && smp_cpus > 1) + */ + emit_barriers = false; +#endif + + if (emit_barriers) { + tcg_gen_op1(ctx, INDEX_op_mb, mb_type); + } +} + /* 32 bit ops */ void tcg_gen_addi_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index 7beb1c7c..e360caf4 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -269,6 +269,8 @@ static inline void tcg_gen_br(TCGContext *s, TCGLabel *l) tcg_gen_op1(s, INDEX_op_br, label_arg(s, l)); } +void tcg_gen_mb(TCGContext *, TCGBar); + /* Helper calls. */ /* 32 bit ops */ diff --git a/qemu/tcg/tcg-opc.h b/qemu/tcg/tcg-opc.h index 4d52b5c3..850d71ff 100644 --- a/qemu/tcg/tcg-opc.h +++ b/qemu/tcg/tcg-opc.h @@ -47,6 +47,8 @@ DEF(br, 0, 0, 1, TCG_OPF_BB_END) # define IMPL64 TCG_OPF_64BIT #endif +DEF(mb, 0, 0, 1, 0) + DEF(mov_i32, 1, 1, 0, TCG_OPF_NOT_PRESENT) DEF(movi_i32, 1, 0, 1, TCG_OPF_NOT_PRESENT) DEF(setcond_i32, 1, 2, 1, 0) diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h index 8014bf02..b69412a3 100644 --- a/qemu/tcg/tcg.h +++ b/qemu/tcg/tcg.h @@ -468,6 +468,23 @@ static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_PTR(TCGv_ptr t) #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1) #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1)) +typedef enum { + /* Used to indicate the type of accesses on which ordering + is to be ensured. Modeled after SPARC barriers. */ + TCG_MO_LD_LD = 0x01, + TCG_MO_ST_LD = 0x02, + TCG_MO_LD_ST = 0x04, + TCG_MO_ST_ST = 0x08, + TCG_MO_ALL = 0x0F, /* OR of the above */ + + /* Used to indicate the kind of ordering which is to be ensured by the + instruction. These types are derived from x86/aarch64 instructions. + It should be noted that these are different from C11 semantics. */ + TCG_BAR_LDAQ = 0x10, /* Following ops will not come forward */ + TCG_BAR_STRL = 0x20, /* Previous ops will not be delayed */ + TCG_BAR_SC = 0x30, /* No ops cross barrier; OR of the above */ +} TCGBar; + /* Conditions. Note that these are laid out for easy manipulation by the functions below: bit 0 is used for inverting; @@ -963,7 +980,7 @@ static inline bool tcg_op_buf_full(TCGContext *tcg_ctx) } // UNICORN: Added -#define TCG_OP_DEFS_TABLE_SIZE 124 +#define TCG_OP_DEFS_TABLE_SIZE 125 extern const TCGOpDef tcg_op_defs_org[TCG_OP_DEFS_TABLE_SIZE]; typedef struct TCGTargetOpDef { diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 2cf5e716..5ef96f5d 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2804,6 +2804,7 @@ #define tcg_gen_ld_i64 tcg_gen_ld_i64_x86_64 #define tcg_gen_ldst_op_i32 tcg_gen_ldst_op_i32_x86_64 #define tcg_gen_ldst_op_i64 tcg_gen_ldst_op_i64_x86_64 +#define tcg_gen_mb tcg_gen_mb_x86_64 #define tcg_gen_mov_i32 tcg_gen_mov_i32_x86_64 #define tcg_gen_mov_i64 tcg_gen_mov_i64_x86_64 #define tcg_gen_movcond_i32 tcg_gen_movcond_i32_x86_64