diff --git a/qemu/aarch64.h b/qemu/aarch64.h index eb91e405..a8b26eb7 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_aarch64 #define gen_helper_wfe gen_helper_wfe_aarch64 #define gen_helper_wfi gen_helper_wfi_aarch64 +#define gen_helper_yield gen_helper_yield_aarch64 #define gen_hvc gen_hvc_aarch64 #define gen_intermediate_code_internal gen_intermediate_code_internal_aarch64 #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_aarch64 @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_aarch64 #define helper_wfe helper_wfe_aarch64 #define helper_wfi helper_wfi_aarch64 +#define helper_yield helper_yield_aarch64 #define hex2decimal hex2decimal_aarch64 #define hw_breakpoint_update hw_breakpoint_update_aarch64 #define hw_breakpoint_update_all hw_breakpoint_update_all_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index f8edd23b..9e25ad19 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_aarch64eb #define gen_helper_wfe gen_helper_wfe_aarch64eb #define gen_helper_wfi gen_helper_wfi_aarch64eb +#define gen_helper_yield gen_helper_yield_aarch64eb #define gen_hvc gen_hvc_aarch64eb #define gen_intermediate_code_internal gen_intermediate_code_internal_aarch64eb #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_aarch64eb @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_aarch64eb #define helper_wfe helper_wfe_aarch64eb #define helper_wfi helper_wfi_aarch64eb +#define helper_yield helper_yield_aarch64eb #define hex2decimal hex2decimal_aarch64eb #define hw_breakpoint_update hw_breakpoint_update_aarch64eb #define hw_breakpoint_update_all hw_breakpoint_update_all_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 8b442ff9..70c7eff9 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_arm #define gen_helper_wfe gen_helper_wfe_arm #define gen_helper_wfi gen_helper_wfi_arm +#define gen_helper_yield gen_helper_yield_arm #define gen_hvc gen_hvc_arm #define gen_intermediate_code_internal gen_intermediate_code_internal_arm #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_arm @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_arm #define helper_wfe helper_wfe_arm #define helper_wfi helper_wfi_arm +#define helper_yield helper_yield_arm #define hex2decimal hex2decimal_arm #define hw_breakpoint_update hw_breakpoint_update_arm #define hw_breakpoint_update_all hw_breakpoint_update_all_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index e8c306bb..10a72b31 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_armeb #define gen_helper_wfe gen_helper_wfe_armeb #define gen_helper_wfi gen_helper_wfi_armeb +#define gen_helper_yield gen_helper_yield_armeb #define gen_hvc gen_hvc_armeb #define gen_intermediate_code_internal gen_intermediate_code_internal_armeb #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_armeb @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_armeb #define helper_wfe helper_wfe_armeb #define helper_wfi helper_wfi_armeb +#define helper_yield helper_yield_armeb #define hex2decimal hex2decimal_armeb #define hw_breakpoint_update hw_breakpoint_update_armeb #define hw_breakpoint_update_all hw_breakpoint_update_all_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 20ae68d8..add19b32 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1143,6 +1143,7 @@ symbols = ( 'gen_helper_vfp_ultos', 'gen_helper_wfe', 'gen_helper_wfi', + 'gen_helper_yield', 'gen_hvc', 'gen_intermediate_code_internal', 'gen_intermediate_code_internal_a64', @@ -1929,6 +1930,7 @@ symbols = ( 'helper_vfp_uqtos', 'helper_wfe', 'helper_wfi', + 'helper_yield', 'hex2decimal', 'hw_breakpoint_update', 'hw_breakpoint_update_all', diff --git a/qemu/m68k.h b/qemu/m68k.h index 96e1254b..dc4f2711 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_m68k #define gen_helper_wfe gen_helper_wfe_m68k #define gen_helper_wfi gen_helper_wfi_m68k +#define gen_helper_yield gen_helper_yield_m68k #define gen_hvc gen_hvc_m68k #define gen_intermediate_code_internal gen_intermediate_code_internal_m68k #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_m68k @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_m68k #define helper_wfe helper_wfe_m68k #define helper_wfi helper_wfi_m68k +#define helper_yield helper_yield_m68k #define hex2decimal hex2decimal_m68k #define hw_breakpoint_update hw_breakpoint_update_m68k #define hw_breakpoint_update_all hw_breakpoint_update_all_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 9d61af1b..177078e0 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_mips #define gen_helper_wfe gen_helper_wfe_mips #define gen_helper_wfi gen_helper_wfi_mips +#define gen_helper_yield gen_helper_yield_mips #define gen_hvc gen_hvc_mips #define gen_intermediate_code_internal gen_intermediate_code_internal_mips #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_mips @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_mips #define helper_wfe helper_wfe_mips #define helper_wfi helper_wfi_mips +#define helper_yield helper_yield_mips #define hex2decimal hex2decimal_mips #define hw_breakpoint_update hw_breakpoint_update_mips #define hw_breakpoint_update_all hw_breakpoint_update_all_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 06302324..6036a496 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_mips64 #define gen_helper_wfe gen_helper_wfe_mips64 #define gen_helper_wfi gen_helper_wfi_mips64 +#define gen_helper_yield gen_helper_yield_mips64 #define gen_hvc gen_hvc_mips64 #define gen_intermediate_code_internal gen_intermediate_code_internal_mips64 #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_mips64 @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_mips64 #define helper_wfe helper_wfe_mips64 #define helper_wfi helper_wfi_mips64 +#define helper_yield helper_yield_mips64 #define hex2decimal hex2decimal_mips64 #define hw_breakpoint_update hw_breakpoint_update_mips64 #define hw_breakpoint_update_all hw_breakpoint_update_all_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index ce53005c..10e26bec 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_mips64el #define gen_helper_wfe gen_helper_wfe_mips64el #define gen_helper_wfi gen_helper_wfi_mips64el +#define gen_helper_yield gen_helper_yield_mips64el #define gen_hvc gen_hvc_mips64el #define gen_intermediate_code_internal gen_intermediate_code_internal_mips64el #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_mips64el @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_mips64el #define helper_wfe helper_wfe_mips64el #define helper_wfi helper_wfi_mips64el +#define helper_yield helper_yield_mips64el #define hex2decimal hex2decimal_mips64el #define hw_breakpoint_update hw_breakpoint_update_mips64el #define hw_breakpoint_update_all hw_breakpoint_update_all_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 0b9dac0c..e7ca951d 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_mipsel #define gen_helper_wfe gen_helper_wfe_mipsel #define gen_helper_wfi gen_helper_wfi_mipsel +#define gen_helper_yield gen_helper_yield_mipsel #define gen_hvc gen_hvc_mipsel #define gen_intermediate_code_internal gen_intermediate_code_internal_mipsel #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_mipsel @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_mipsel #define helper_wfe helper_wfe_mipsel #define helper_wfi helper_wfi_mipsel +#define helper_yield helper_yield_mipsel #define hex2decimal hex2decimal_mipsel #define hw_breakpoint_update hw_breakpoint_update_mipsel #define hw_breakpoint_update_all hw_breakpoint_update_all_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index fdb9d019..5c76755d 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_powerpc #define gen_helper_wfe gen_helper_wfe_powerpc #define gen_helper_wfi gen_helper_wfi_powerpc +#define gen_helper_yield gen_helper_yield_powerpc #define gen_hvc gen_hvc_powerpc #define gen_intermediate_code_internal gen_intermediate_code_internal_powerpc #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_powerpc @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_powerpc #define helper_wfe helper_wfe_powerpc #define helper_wfi helper_wfi_powerpc +#define helper_yield helper_yield_powerpc #define hex2decimal hex2decimal_powerpc #define hw_breakpoint_update hw_breakpoint_update_powerpc #define hw_breakpoint_update_all hw_breakpoint_update_all_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 45702778..28ad32b1 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_sparc #define gen_helper_wfe gen_helper_wfe_sparc #define gen_helper_wfi gen_helper_wfi_sparc +#define gen_helper_yield gen_helper_yield_sparc #define gen_hvc gen_hvc_sparc #define gen_intermediate_code_internal gen_intermediate_code_internal_sparc #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_sparc @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_sparc #define helper_wfe helper_wfe_sparc #define helper_wfi helper_wfi_sparc +#define helper_yield helper_yield_sparc #define hex2decimal hex2decimal_sparc #define hw_breakpoint_update hw_breakpoint_update_sparc #define hw_breakpoint_update_all hw_breakpoint_update_all_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index daeeab71..913c63b8 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_sparc64 #define gen_helper_wfe gen_helper_wfe_sparc64 #define gen_helper_wfi gen_helper_wfi_sparc64 +#define gen_helper_yield gen_helper_yield_sparc64 #define gen_hvc gen_hvc_sparc64 #define gen_intermediate_code_internal gen_intermediate_code_internal_sparc64 #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_sparc64 @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_sparc64 #define helper_wfe helper_wfe_sparc64 #define helper_wfi helper_wfi_sparc64 +#define helper_yield helper_yield_sparc64 #define hex2decimal hex2decimal_sparc64 #define hw_breakpoint_update hw_breakpoint_update_sparc64 #define hw_breakpoint_update_all hw_breakpoint_update_all_sparc64 diff --git a/qemu/target-arm/helper.h b/qemu/target-arm/helper.h index 7c1644ec..082bf980 100644 --- a/qemu/target-arm/helper.h +++ b/qemu/target-arm/helper.h @@ -53,6 +53,7 @@ DEF_HELPER_2(exception_internal, void, env, i32) DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32) DEF_HELPER_1(wfi, void, env) DEF_HELPER_1(wfe, void, env) +DEF_HELPER_1(yield, void, env) DEF_HELPER_1(pre_hvc, void, env) DEF_HELPER_2(pre_smc, void, env, i32) diff --git a/qemu/target-arm/op_helper.c b/qemu/target-arm/op_helper.c index e9556203..95538866 100644 --- a/qemu/target-arm/op_helper.c +++ b/qemu/target-arm/op_helper.c @@ -323,13 +323,25 @@ void HELPER(wfi)(CPUARMState *env) void HELPER(wfe)(CPUARMState *env) { - CPUState *cs = CPU(arm_env_get_cpu(env)); - - /* Don't actually halt the CPU, just yield back to top + /* This is a hint instruction that is semantically different + * from YIELD even though we currently implement it identically. + * Don't actually halt the CPU, just yield back to top * level loop. This is not going into a "low power state" * (ie halting until some event occurs), so we never take * a configurable trap to a different exception level. */ + HELPER(yield)(env); +} + +void HELPER(yield)(CPUARMState *env) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + CPUState *cs = CPU(cpu); + + /* This is a non-trappable hint instruction that generally indicates + * that the guest is currently busy-looping. Yield control back to the + * top level loop so that a more deserving VCPU has a chance to run. + */ cs->exception_index = EXCP_YIELD; cpu_loop_exit(cs); } diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 79cd761c..6d7f0fcd 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -1234,6 +1234,8 @@ static void handle_hint(DisasContext *s, uint32_t insn, s->is_jmp = DISAS_WFI; return; case 1: /* YIELD */ + s->is_jmp = DISAS_YIELD; + return; case 2: /* WFE */ s->is_jmp = DISAS_WFE; return; @@ -11400,6 +11402,10 @@ tb_end: gen_a64_set_pc_im(dc, dc->pc); gen_helper_wfe(tcg_ctx, tcg_ctx->cpu_env); break; + case DISAS_YIELD: + gen_a64_set_pc_im(dc, dc->pc); + gen_helper_yield(tcg_ctx, tcg_ctx->cpu_env); + break; case DISAS_WFI: /* This is a special case because we don't want to just halt the CPU * if trying to debug across a WFI. diff --git a/qemu/target-arm/translate.h b/qemu/target-arm/translate.h index 5a77471f..d0abef50 100644 --- a/qemu/target-arm/translate.h +++ b/qemu/target-arm/translate.h @@ -110,6 +110,7 @@ static inline int default_exception_el(DisasContext *s) #define DISAS_WFE 7 #define DISAS_HVC 8 #define DISAS_SMC 9 +#define DISAS_YIELD 10 #ifdef TARGET_AARCH64 void a64_translate_init(struct uc_struct *uc); diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 133617ce..5e7de80d 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1137,6 +1137,7 @@ #define gen_helper_vfp_ultos gen_helper_vfp_ultos_x86_64 #define gen_helper_wfe gen_helper_wfe_x86_64 #define gen_helper_wfi gen_helper_wfi_x86_64 +#define gen_helper_yield gen_helper_yield_x86_64 #define gen_hvc gen_hvc_x86_64 #define gen_intermediate_code_internal gen_intermediate_code_internal_x86_64 #define gen_intermediate_code_internal_a64 gen_intermediate_code_internal_a64_x86_64 @@ -1923,6 +1924,7 @@ #define helper_vfp_uqtos helper_vfp_uqtos_x86_64 #define helper_wfe helper_wfe_x86_64 #define helper_wfi helper_wfi_x86_64 +#define helper_yield helper_yield_x86_64 #define hex2decimal hex2decimal_x86_64 #define hw_breakpoint_update hw_breakpoint_update_x86_64 #define hw_breakpoint_update_all hw_breakpoint_update_all_x86_64