diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/alpha/machine.c | 2 | ||||
-rw-r--r-- | target/arm/helper.c | 6 | ||||
-rw-r--r-- | target/arm/machine.c | 6 | ||||
-rw-r--r-- | target/arm/monitor.c | 13 | ||||
-rw-r--r-- | target/avr/machine.c | 4 | ||||
-rw-r--r-- | target/hppa/machine.c | 4 | ||||
-rw-r--r-- | target/i386/cpu.c | 6 | ||||
-rw-r--r-- | target/i386/tcg/translate.c | 7 | ||||
-rw-r--r-- | target/microblaze/machine.c | 2 | ||||
-rw-r--r-- | target/mips/cpu.c | 6 | ||||
-rw-r--r-- | target/mips/cpu.h | 1 | ||||
-rw-r--r-- | target/mips/machine.c | 4 | ||||
-rw-r--r-- | target/openrisc/machine.c | 2 | ||||
-rw-r--r-- | target/ppc/machine.c | 10 | ||||
-rw-r--r-- | target/ppc/translate_init.c.inc | 12 | ||||
-rw-r--r-- | target/s390x/cc_helper.c | 123 | ||||
-rw-r--r-- | target/s390x/cpu_features.c | 39 | ||||
-rw-r--r-- | target/s390x/cpu_models.c | 37 | ||||
-rw-r--r-- | target/s390x/helper.c | 10 | ||||
-rw-r--r-- | target/s390x/insn-data.def | 76 | ||||
-rw-r--r-- | target/s390x/internal.h | 11 | ||||
-rw-r--r-- | target/s390x/translate.c | 287 | ||||
-rw-r--r-- | target/sparc/cpu.h | 28 | ||||
-rw-r--r-- | target/sparc/int64_helper.c | 5 | ||||
-rw-r--r-- | target/sparc/machine.c | 2 | ||||
-rw-r--r-- | target/sparc/translate.c | 2 | ||||
-rw-r--r-- | target/sparc/win_helper.c | 2 | ||||
-rw-r--r-- | target/unicore32/translate.c | 2 |
28 files changed, 337 insertions, 372 deletions
diff --git a/target/alpha/machine.c b/target/alpha/machine.c index 9d20169..2b7c814 100644 --- a/target/alpha/machine.c +++ b/target/alpha/machine.c @@ -11,7 +11,7 @@ static int get_fpcr(QEMUFile *f, void *opaque, size_t size, } static int put_fpcr(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { CPUAlphaState *env = opaque; qemu_put_be64(f, cpu_alpha_load_fpcr(env)); diff --git a/target/arm/helper.c b/target/arm/helper.c index 7b8bcd6..2d0d4cd 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8283,7 +8283,6 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data) { ObjectClass *oc = data; CpuDefinitionInfoList **cpu_list = user_data; - CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; const char *typename; @@ -8293,10 +8292,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data) strlen(typename) - strlen("-" TYPE_ARM_CPU)); info->q_typename = g_strdup(typename); - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = *cpu_list; - *cpu_list = entry; + QAPI_LIST_PREPEND(*cpu_list, info); } CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) diff --git a/target/arm/machine.c b/target/arm/machine.c index c5a2114..581852b 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -27,7 +27,7 @@ static int get_fpscr(QEMUFile *f, void *opaque, size_t size, } static int put_fpscr(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; @@ -573,7 +573,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size, } static int put_cpsr(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; @@ -608,7 +608,7 @@ static int get_power(QEMUFile *f, void *opaque, size_t size, } static int put_power(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { ARMCPU *cpu = opaque; diff --git a/target/arm/monitor.c b/target/arm/monitor.c index 169d8a6..198b14e 100644 --- a/target/arm/monitor.c +++ b/target/arm/monitor.c @@ -42,15 +42,6 @@ static GICCapability *gic_cap_new(int version) return cap; } -static GICCapabilityList *gic_cap_list_add(GICCapabilityList *head, - GICCapability *cap) -{ - GICCapabilityList *item = g_new0(GICCapabilityList, 1); - item->value = cap; - item->next = head; - return item; -} - static inline void gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3) { #ifdef CONFIG_KVM @@ -84,8 +75,8 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp) gic_cap_kvm_probe(v2, v3); - head = gic_cap_list_add(head, v2); - head = gic_cap_list_add(head, v3); + QAPI_LIST_PREPEND(head, v2); + QAPI_LIST_PREPEND(head, v3); return head; } diff --git a/target/avr/machine.c b/target/avr/machine.c index e315442..de264f5 100644 --- a/target/avr/machine.c +++ b/target/avr/machine.c @@ -34,7 +34,7 @@ static int get_sreg(QEMUFile *f, void *opaque, size_t size, } static int put_sreg(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { CPUAVRState *env = opaque; uint8_t sreg = cpu_get_sreg(env); @@ -61,7 +61,7 @@ static int get_segment(QEMUFile *f, void *opaque, size_t size, } static int put_segment(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { uint32_t *ramp = opaque; uint8_t temp = *ramp >> 16; diff --git a/target/hppa/machine.c b/target/hppa/machine.c index b60b654..905991d 100644 --- a/target/hppa/machine.c +++ b/target/hppa/machine.c @@ -52,7 +52,7 @@ static int get_psw(QEMUFile *f, void *opaque, size_t size, } static int put_psw(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { CPUHPPAState *env = opaque; qemu_put_betr(f, cpu_hppa_get_psw(env)); @@ -93,7 +93,7 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size, } static int put_tlb(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { hppa_tlb_entry *ent = opaque; uint32_t val = 0; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 0d20e15..35459a3 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5014,7 +5014,6 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data) ObjectClass *oc = data; X86CPUClass *cc = X86_CPU_CLASS(oc); CpuDefinitionInfoList **cpu_list = user_data; - CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; info = g_malloc0(sizeof(*info)); @@ -5039,10 +5038,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data) info->has_alias_of = !!info->alias_of; } - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = *cpu_list; - *cpu_list = entry; + QAPI_LIST_PREPEND(*cpu_list, info); } CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 750f75c..11db2f3 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -1778,9 +1778,12 @@ static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1, } else { tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); } - /* FALLTHRU */ -#ifdef TARGET_X86_64 + /* + * If TARGET_X86_64 defined then fall through into MO_32 case, + * otherwise fall through default case. + */ case MO_32: +#ifdef TARGET_X86_64 /* Concatenate the two 32-bit values and use a 64-bit shift. */ tcg_gen_subi_tl(s->tmp0, count, 1); if (is_right) { diff --git a/target/microblaze/machine.c b/target/microblaze/machine.c index c2074bb..d24def3 100644 --- a/target/microblaze/machine.c +++ b/target/microblaze/machine.c @@ -46,7 +46,7 @@ static int get_msr(QEMUFile *f, void *opaque, size_t size, } static int put_msr(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { CPUMBState *env = container_of(opaque, CPUMBState, msr); diff --git a/target/mips/cpu.c b/target/mips/cpu.c index aadc6f8..b2cd69f 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -543,7 +543,6 @@ static void mips_cpu_add_definition(gpointer data, gpointer user_data) { ObjectClass *oc = data; CpuDefinitionInfoList **cpu_list = user_data; - CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; const char *typename; @@ -553,10 +552,7 @@ static void mips_cpu_add_definition(gpointer data, gpointer user_data) strlen(typename) - strlen("-" TYPE_MIPS_CPU)); info->q_typename = g_strdup(typename); - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = *cpu_list; - *cpu_list = entry; + QAPI_LIST_PREPEND(*cpu_list, info); } CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 3ac21d0..4cbc31c 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -844,6 +844,7 @@ struct CPUMIPSState { #define CP0C0_MT 7 /* 9..7 */ #define CP0C0_VI 3 #define CP0C0_K0 0 /* 2..0 */ +#define CP0C0_AR_LENGTH 3 int32_t CP0_Config1; #define CP0C1_M 31 #define CP0C1_MMU 25 /* 30..25 */ diff --git a/target/mips/machine.c b/target/mips/machine.c index 5b23e3e..77afe65 100644 --- a/target/mips/machine.c +++ b/target/mips/machine.c @@ -31,7 +31,7 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size, } static int put_fpr(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { int i; fpr_t *v = pv; @@ -156,7 +156,7 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size, } static int put_tlb(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { r4k_tlb_t *v = pv; diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c index b92985d..6239725 100644 --- a/target/openrisc/machine.c +++ b/target/openrisc/machine.c @@ -55,7 +55,7 @@ static int get_sr(QEMUFile *f, void *opaque, size_t size, } static int put_sr(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { CPUOpenRISCState *env = opaque; qemu_put_be32(f, cpu_get_sr(env)); diff --git a/target/ppc/machine.c b/target/ppc/machine.c index d9d911b..283db1d 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -134,7 +134,7 @@ static int get_avr(QEMUFile *f, void *pv, size_t size, } static int put_avr(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { ppc_avr_t *v = pv; @@ -166,7 +166,7 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size, } static int put_fpr(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { ppc_vsr_t *v = pv; @@ -197,7 +197,7 @@ static int get_vsr(QEMUFile *f, void *pv, size_t size, } static int put_vsr(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { ppc_vsr_t *v = pv; @@ -455,7 +455,7 @@ static int get_vscr(QEMUFile *f, void *opaque, size_t size, } static int put_vscr(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { PowerPCCPU *cpu = opaque; qemu_put_be32(f, helper_mfvscr(&cpu->env)); @@ -580,7 +580,7 @@ static int get_slbe(QEMUFile *f, void *pv, size_t size, } static int put_slbe(QEMUFile *f, void *pv, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { ppc_slb_t *v = pv; diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index a4d0038..3c05a17 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -10566,7 +10566,6 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) ObjectClass *oc = data; CpuDefinitionInfoList **first = user_data; const char *typename; - CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; typename = object_class_get_name(oc); @@ -10574,10 +10573,7 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) info->name = g_strndup(typename, strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX)); - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = *first; - *first = entry; + QAPI_LIST_PREPEND(*first, info); } CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) @@ -10593,7 +10589,6 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { PowerPCCPUAlias *alias = &ppc_cpu_aliases[i]; ObjectClass *oc; - CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; oc = ppc_cpu_class_by_name(alias->model); @@ -10605,10 +10600,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) info->name = g_strdup(alias->alias); info->q_typename = g_strdup(object_class_get_name(oc)); - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = cpu_list; - cpu_list = entry; + QAPI_LIST_PREPEND(cpu_list, info); } return cpu_list; diff --git a/target/s390x/cc_helper.c b/target/s390x/cc_helper.c index 5432aee..e7039d0 100644 --- a/target/s390x/cc_helper.c +++ b/target/s390x/cc_helper.c @@ -123,6 +123,17 @@ static uint32_t cc_calc_nz(uint64_t dst) return !!dst; } +static uint32_t cc_calc_addu(uint64_t carry_out, uint64_t result) +{ + g_assert(carry_out <= 1); + return (result != 0) + 2 * carry_out; +} + +static uint32_t cc_calc_subu(uint64_t borrow_out, uint64_t result) +{ + return cc_calc_addu(borrow_out + 1, result); +} + static uint32_t cc_calc_add_64(int64_t a1, int64_t a2, int64_t ar) { if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) { @@ -138,21 +149,6 @@ static uint32_t cc_calc_add_64(int64_t a1, int64_t a2, int64_t ar) } } -static uint32_t cc_calc_addu_64(uint64_t a1, uint64_t a2, uint64_t ar) -{ - return (ar != 0) + 2 * (ar < a1); -} - -static uint32_t cc_calc_addc_64(uint64_t a1, uint64_t a2, uint64_t ar) -{ - /* Recover a2 + carry_in. */ - uint64_t a2c = ar - a1; - /* Check for a2+carry_in overflow, then a1+a2c overflow. */ - int carry_out = (a2c < a2) || (ar < a1); - - return (ar != 0) + 2 * carry_out; -} - static uint32_t cc_calc_sub_64(int64_t a1, int64_t a2, int64_t ar) { if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) { @@ -168,32 +164,6 @@ static uint32_t cc_calc_sub_64(int64_t a1, int64_t a2, int64_t ar) } } -static uint32_t cc_calc_subu_64(uint64_t a1, uint64_t a2, uint64_t ar) -{ - if (ar == 0) { - return 2; - } else { - if (a2 > a1) { - return 1; - } else { - return 3; - } - } -} - -static uint32_t cc_calc_subb_64(uint64_t a1, uint64_t a2, uint64_t ar) -{ - int borrow_out; - - if (ar != a1 - a2) { /* difference means borrow-in */ - borrow_out = (a2 >= a1); - } else { - borrow_out = (a2 > a1); - } - - return (ar != 0) + 2 * !borrow_out; -} - static uint32_t cc_calc_abs_64(int64_t dst) { if ((uint64_t)dst == 0x8000000000000000ULL) { @@ -239,21 +209,6 @@ static uint32_t cc_calc_add_32(int32_t a1, int32_t a2, int32_t ar) } } -static uint32_t cc_calc_addu_32(uint32_t a1, uint32_t a2, uint32_t ar) -{ - return (ar != 0) + 2 * (ar < a1); -} - -static uint32_t cc_calc_addc_32(uint32_t a1, uint32_t a2, uint32_t ar) -{ - /* Recover a2 + carry_in. */ - uint32_t a2c = ar - a1; - /* Check for a2+carry_in overflow, then a1+a2c overflow. */ - int carry_out = (a2c < a2) || (ar < a1); - - return (ar != 0) + 2 * carry_out; -} - static uint32_t cc_calc_sub_32(int32_t a1, int32_t a2, int32_t ar) { if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) { @@ -269,32 +224,6 @@ static uint32_t cc_calc_sub_32(int32_t a1, int32_t a2, int32_t ar) } } -static uint32_t cc_calc_subu_32(uint32_t a1, uint32_t a2, uint32_t ar) -{ - if (ar == 0) { - return 2; - } else { - if (a2 > a1) { - return 1; - } else { - return 3; - } - } -} - -static uint32_t cc_calc_subb_32(uint32_t a1, uint32_t a2, uint32_t ar) -{ - int borrow_out; - - if (ar != a1 - a2) { /* difference means borrow-in */ - borrow_out = (a2 >= a1); - } else { - borrow_out = (a2 > a1); - } - - return (ar != 0) + 2 * !borrow_out; -} - static uint32_t cc_calc_abs_32(int32_t dst) { if ((uint32_t)dst == 0x80000000UL) { @@ -483,24 +412,18 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, case CC_OP_NZ: r = cc_calc_nz(dst); break; - case CC_OP_ADD_64: - r = cc_calc_add_64(src, dst, vr); + case CC_OP_ADDU: + r = cc_calc_addu(src, dst); break; - case CC_OP_ADDU_64: - r = cc_calc_addu_64(src, dst, vr); + case CC_OP_SUBU: + r = cc_calc_subu(src, dst); break; - case CC_OP_ADDC_64: - r = cc_calc_addc_64(src, dst, vr); + case CC_OP_ADD_64: + r = cc_calc_add_64(src, dst, vr); break; case CC_OP_SUB_64: r = cc_calc_sub_64(src, dst, vr); break; - case CC_OP_SUBU_64: - r = cc_calc_subu_64(src, dst, vr); - break; - case CC_OP_SUBB_64: - r = cc_calc_subb_64(src, dst, vr); - break; case CC_OP_ABS_64: r = cc_calc_abs_64(dst); break; @@ -517,21 +440,9 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, case CC_OP_ADD_32: r = cc_calc_add_32(src, dst, vr); break; - case CC_OP_ADDU_32: - r = cc_calc_addu_32(src, dst, vr); - break; - case CC_OP_ADDC_32: - r = cc_calc_addc_32(src, dst, vr); - break; case CC_OP_SUB_32: r = cc_calc_sub_32(src, dst, vr); break; - case CC_OP_SUBU_32: - r = cc_calc_subu_32(src, dst, vr); - break; - case CC_OP_SUBB_32: - r = cc_calc_subb_32(src, dst, vr); - break; case CC_OP_ABS_32: r = cc_calc_abs_32(dst); break; diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c index 42fe0bf..5528acd 100644 --- a/target/s390x/cpu_features.c +++ b/target/s390x/cpu_features.c @@ -107,8 +107,45 @@ void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type, feat = find_next_bit(features, S390_FEAT_MAX, feat + 1); } - if (type == S390_FEAT_TYPE_SCLP_FAC134 && s390_is_pv()) { + if (!s390_is_pv()) { + return; + } + + /* + * Some facilities are not available for CPUs in protected mode: + * - All SIE facilities because SIE is not available + * - DIAG318 + * + * As VMs can move in and out of protected mode the CPU model + * doesn't protect us from that problem because it is only + * validated at the start of the VM. + */ + switch (type) { + case S390_FEAT_TYPE_SCLP_CPU: + clear_be_bit(s390_feat_def(S390_FEAT_SIE_F2)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_SKEY)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_GPERE)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_SIIF)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_SIGPIF)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_IB)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_CEI)->bit, data); + break; + case S390_FEAT_TYPE_SCLP_CONF_CHAR: + clear_be_bit(s390_feat_def(S390_FEAT_SIE_GSLS)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_HPMA2)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_KSS)->bit, data); + break; + case S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT: + clear_be_bit(s390_feat_def(S390_FEAT_SIE_64BSCAO)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_CMMA)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_PFMFI)->bit, data); + clear_be_bit(s390_feat_def(S390_FEAT_SIE_IBS)->bit, data); + break; + case S390_FEAT_TYPE_SCLP_FAC134: clear_be_bit(s390_feat_def(S390_FEAT_DIAG_318)->bit, data); + break; + default: + return; } } diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index b5abff8..35179f9 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -239,8 +239,29 @@ bool s390_has_feat(S390Feat feat) } return 0; } - if (feat == S390_FEAT_DIAG_318 && s390_is_pv()) { - return false; + + if (s390_is_pv()) { + switch (feat) { + case S390_FEAT_DIAG_318: + case S390_FEAT_HPMA2: + case S390_FEAT_SIE_F2: + case S390_FEAT_SIE_SKEY: + case S390_FEAT_SIE_GPERE: + case S390_FEAT_SIE_SIIF: + case S390_FEAT_SIE_SIGPIF: + case S390_FEAT_SIE_IB: + case S390_FEAT_SIE_CEI: + case S390_FEAT_SIE_KSS: + case S390_FEAT_SIE_GSLS: + case S390_FEAT_SIE_64BSCAO: + case S390_FEAT_SIE_CMMA: + case S390_FEAT_SIE_PFMFI: + case S390_FEAT_SIE_IBS: + return false; + break; + default: + break; + } } return test_bit(feat, cpu->model->features); } @@ -427,7 +448,6 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) { struct CpuDefinitionInfoListData *cpu_list_data = opaque; CpuDefinitionInfoList **cpu_list = &cpu_list_data->list; - CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; char *name = g_strdup(object_class_get_name(klass)); S390CPUClass *scc = S390_CPU_CLASS(klass); @@ -454,10 +474,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) object_unref(obj); } - entry = g_new0(CpuDefinitionInfoList, 1); - entry->value = info; - entry->next = *cpu_list; - *cpu_list = entry; + QAPI_LIST_PREPEND(*cpu_list, info); } CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) @@ -624,12 +641,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, static void list_add_feat(const char *name, void *opaque) { strList **last = (strList **) opaque; - strList *entry; - entry = g_new0(strList, 1); - entry->value = g_strdup(name); - entry->next = *last; - *last = entry; + QAPI_LIST_PREPEND(*last, g_strdup(name)); } CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa, diff --git a/target/s390x/helper.c b/target/s390x/helper.c index b877690..7678994 100644 --- a/target/s390x/helper.c +++ b/target/s390x/helper.c @@ -395,6 +395,8 @@ const char *cc_name(enum cc_op cc_op) [CC_OP_DYNAMIC] = "CC_OP_DYNAMIC", [CC_OP_STATIC] = "CC_OP_STATIC", [CC_OP_NZ] = "CC_OP_NZ", + [CC_OP_ADDU] = "CC_OP_ADDU", + [CC_OP_SUBU] = "CC_OP_SUBU", [CC_OP_LTGT_32] = "CC_OP_LTGT_32", [CC_OP_LTGT_64] = "CC_OP_LTGT_64", [CC_OP_LTUGTU_32] = "CC_OP_LTUGTU_32", @@ -402,19 +404,11 @@ const char *cc_name(enum cc_op cc_op) [CC_OP_LTGT0_32] = "CC_OP_LTGT0_32", [CC_OP_LTGT0_64] = "CC_OP_LTGT0_64", [CC_OP_ADD_64] = "CC_OP_ADD_64", - [CC_OP_ADDU_64] = "CC_OP_ADDU_64", - [CC_OP_ADDC_64] = "CC_OP_ADDC_64", [CC_OP_SUB_64] = "CC_OP_SUB_64", - [CC_OP_SUBU_64] = "CC_OP_SUBU_64", - [CC_OP_SUBB_64] = "CC_OP_SUBB_64", [CC_OP_ABS_64] = "CC_OP_ABS_64", [CC_OP_NABS_64] = "CC_OP_NABS_64", [CC_OP_ADD_32] = "CC_OP_ADD_32", - [CC_OP_ADDU_32] = "CC_OP_ADDU_32", - [CC_OP_ADDC_32] = "CC_OP_ADDC_32", [CC_OP_SUB_32] = "CC_OP_SUB_32", - [CC_OP_SUBU_32] = "CC_OP_SUBU_32", - [CC_OP_SUBB_32] = "CC_OP_SUBB_32", [CC_OP_ABS_32] = "CC_OP_ABS_32", [CC_OP_NABS_32] = "CC_OP_NABS_32", [CC_OP_COMP_32] = "CC_OP_COMP_32", diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index b95bc98..26badb6 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -58,34 +58,34 @@ C(0xa70b, AGHI, RI_a, Z, r1, i2, r1, 0, add, adds64) /* ADD LOGICAL */ - C(0x1e00, ALR, RR_a, Z, r1, r2, new, r1_32, add, addu32) - C(0xb9fa, ALRK, RRF_a, DO, r2, r3, new, r1_32, add, addu32) - C(0x5e00, AL, RX_a, Z, r1, m2_32u, new, r1_32, add, addu32) - C(0xe35e, ALY, RXY_a, LD, r1, m2_32u, new, r1_32, add, addu32) - C(0xb90a, ALGR, RRE, Z, r1, r2, r1, 0, add, addu64) - C(0xb91a, ALGFR, RRE, Z, r1, r2_32u, r1, 0, add, addu64) - C(0xb9ea, ALGRK, RRF_a, DO, r2, r3, r1, 0, add, addu64) - C(0xe30a, ALG, RXY_a, Z, r1, m2_64, r1, 0, add, addu64) - C(0xe31a, ALGF, RXY_a, Z, r1, m2_32u, r1, 0, add, addu64) + C(0x1e00, ALR, RR_a, Z, r1_32u, r2_32u, new, r1_32, add, addu32) + C(0xb9fa, ALRK, RRF_a, DO, r2_32u, r3_32u, new, r1_32, add, addu32) + C(0x5e00, AL, RX_a, Z, r1_32u, m2_32u, new, r1_32, add, addu32) + C(0xe35e, ALY, RXY_a, LD, r1_32u, m2_32u, new, r1_32, add, addu32) + C(0xb90a, ALGR, RRE, Z, r1, r2, r1, 0, addu64, addu64) + C(0xb91a, ALGFR, RRE, Z, r1, r2_32u, r1, 0, addu64, addu64) + C(0xb9ea, ALGRK, RRF_a, DO, r2, r3, r1, 0, addu64, addu64) + C(0xe30a, ALG, RXY_a, Z, r1, m2_64, r1, 0, addu64, addu64) + C(0xe31a, ALGF, RXY_a, Z, r1, m2_32u, r1, 0, addu64, addu64) /* ADD LOGICAL HIGH */ C(0xb9ca, ALHHHR, RRF_a, HW, r2_sr32, r3_sr32, new, r1_32h, add, addu32) - C(0xb9da, ALHHLR, RRF_a, HW, r2_sr32, r3, new, r1_32h, add, addu32) + C(0xb9da, ALHHLR, RRF_a, HW, r2_sr32, r3_32u, new, r1_32h, add, addu32) /* ADD LOGICAL IMMEDIATE */ - C(0xc20b, ALFI, RIL_a, EI, r1, i2_32u, new, r1_32, add, addu32) - C(0xc20a, ALGFI, RIL_a, EI, r1, i2_32u, r1, 0, add, addu64) + C(0xc20b, ALFI, RIL_a, EI, r1_32u, i2_32u, new, r1_32, add, addu32) + C(0xc20a, ALGFI, RIL_a, EI, r1, i2_32u, r1, 0, addu64, addu64) /* ADD LOGICAL WITH SIGNED IMMEDIATE */ - D(0xeb6e, ALSI, SIY, GIE, la1, i2, new, 0, asi, addu32, MO_TEUL) - C(0xecda, ALHSIK, RIE_d, DO, r3, i2, new, r1_32, add, addu32) - D(0xeb7e, ALGSI, SIY, GIE, la1, i2, new, 0, asi, addu64, MO_TEQ) - C(0xecdb, ALGHSIK, RIE_d, DO, r3, i2, r1, 0, add, addu64) + D(0xeb6e, ALSI, SIY, GIE, la1, i2_32u, new, 0, asi, addu32, MO_TEUL) + C(0xecda, ALHSIK, RIE_d, DO, r3_32u, i2_32u, new, r1_32, add, addu32) + C(0xeb7e, ALGSI, SIY, GIE, la1, i2, r1, 0, asiu64, addu64) + C(0xecdb, ALGHSIK, RIE_d, DO, r3, i2, r1, 0, addu64, addu64) /* ADD LOGICAL WITH SIGNED IMMEDIATE HIGH */ - C(0xcc0a, ALSIH, RIL_a, HW, r1_sr32, i2, new, r1_32h, add, addu32) - C(0xcc0b, ALSIHN, RIL_a, HW, r1_sr32, i2, new, r1_32h, add, 0) + C(0xcc0a, ALSIH, RIL_a, HW, r1_sr32, i2_32u, new, r1_32h, add, addu32) + C(0xcc0b, ALSIHN, RIL_a, HW, r1_sr32, i2_32u, new, r1_32h, add, 0) /* ADD LOGICAL WITH CARRY */ - C(0xb998, ALCR, RRE, Z, r1, r2, new, r1_32, addc, addc32) - C(0xb988, ALCGR, RRE, Z, r1, r2, r1, 0, addc, addc64) - C(0xe398, ALC, RXY_a, Z, r1, m2_32u, new, r1_32, addc, addc32) - C(0xe388, ALCG, RXY_a, Z, r1, m2_64, r1, 0, addc, addc64) + C(0xb998, ALCR, RRE, Z, r1_32u, r2_32u, new, r1_32, addc32, addu32) + C(0xb988, ALCGR, RRE, Z, r1, r2, r1, 0, addc64, addu64) + C(0xe398, ALC, RXY_a, Z, r1_32u, m2_32u, new, r1_32, addc32, addu32) + C(0xe388, ALCG, RXY_a, Z, r1, m2_64, r1, 0, addc64, addu64) /* AND */ C(0x1400, NR, RR_a, Z, r1, r2, new, r1_32, and, nz32) @@ -900,26 +900,26 @@ C(0xb9c9, SHHHR, RRF_a, HW, r2_sr32, r3_sr32, new, r1_32h, sub, subs32) C(0xb9d9, SHHLR, RRF_a, HW, r2_sr32, r3, new, r1_32h, sub, subs32) /* SUBTRACT LOGICAL */ - C(0x1f00, SLR, RR_a, Z, r1, r2, new, r1_32, sub, subu32) - C(0xb9fb, SLRK, RRF_a, DO, r2, r3, new, r1_32, sub, subu32) - C(0x5f00, SL, RX_a, Z, r1, m2_32u, new, r1_32, sub, subu32) - C(0xe35f, SLY, RXY_a, LD, r1, m2_32u, new, r1_32, sub, subu32) - C(0xb90b, SLGR, RRE, Z, r1, r2, r1, 0, sub, subu64) - C(0xb91b, SLGFR, RRE, Z, r1, r2_32u, r1, 0, sub, subu64) - C(0xb9eb, SLGRK, RRF_a, DO, r2, r3, r1, 0, sub, subu64) - C(0xe30b, SLG, RXY_a, Z, r1, m2_64, r1, 0, sub, subu64) - C(0xe31b, SLGF, RXY_a, Z, r1, m2_32u, r1, 0, sub, subu64) + C(0x1f00, SLR, RR_a, Z, r1_32u, r2_32u, new, r1_32, sub, subu32) + C(0xb9fb, SLRK, RRF_a, DO, r2_32u, r3_32u, new, r1_32, sub, subu32) + C(0x5f00, SL, RX_a, Z, r1_32u, m2_32u, new, r1_32, sub, subu32) + C(0xe35f, SLY, RXY_a, LD, r1_32u, m2_32u, new, r1_32, sub, subu32) + C(0xb90b, SLGR, RRE, Z, r1, r2, r1, 0, subu64, subu64) + C(0xb91b, SLGFR, RRE, Z, r1, r2_32u, r1, 0, subu64, subu64) + C(0xb9eb, SLGRK, RRF_a, DO, r2, r3, r1, 0, subu64, subu64) + C(0xe30b, SLG, RXY_a, Z, r1, m2_64, r1, 0, subu64, subu64) + C(0xe31b, SLGF, RXY_a, Z, r1, m2_32u, r1, 0, subu64, subu64) /* SUBTRACT LOCICAL HIGH */ C(0xb9cb, SLHHHR, RRF_a, HW, r2_sr32, r3_sr32, new, r1_32h, sub, subu32) - C(0xb9db, SLHHLR, RRF_a, HW, r2_sr32, r3, new, r1_32h, sub, subu32) + C(0xb9db, SLHHLR, RRF_a, HW, r2_sr32, r3_32u, new, r1_32h, sub, subu32) /* SUBTRACT LOGICAL IMMEDIATE */ - C(0xc205, SLFI, RIL_a, EI, r1, i2_32u, new, r1_32, sub, subu32) - C(0xc204, SLGFI, RIL_a, EI, r1, i2_32u, r1, 0, sub, subu64) + C(0xc205, SLFI, RIL_a, EI, r1_32u, i2_32u, new, r1_32, sub, subu32) + C(0xc204, SLGFI, RIL_a, EI, r1, i2_32u, r1, 0, subu64, subu64) /* SUBTRACT LOGICAL WITH BORROW */ - C(0xb999, SLBR, RRE, Z, r1, r2, new, r1_32, subb, subb32) - C(0xb989, SLBGR, RRE, Z, r1, r2, r1, 0, subb, subb64) - C(0xe399, SLB, RXY_a, Z, r1, m2_32u, new, r1_32, subb, subb32) - C(0xe389, SLBG, RXY_a, Z, r1, m2_64, r1, 0, subb, subb64) + C(0xb999, SLBR, RRE, Z, r1_32u, r2_32u, new, r1_32, subb32, subu32) + C(0xb989, SLBGR, RRE, Z, r1, r2, r1, 0, subb64, subu64) + C(0xe399, SLB, RXY_a, Z, r1_32u, m2_32u, new, r1_32, subb32, subu32) + C(0xe389, SLBG, RXY_a, Z, r1, m2_64, r1, 0, subb64, subu64) /* SUPERVISOR CALL */ C(0x0a00, SVC, I, Z, 0, 0, 0, 0, svc, 0) diff --git a/target/s390x/internal.h b/target/s390x/internal.h index 6460266..11515bb 100644 --- a/target/s390x/internal.h +++ b/target/s390x/internal.h @@ -160,6 +160,9 @@ enum cc_op { CC_OP_STATIC, /* CC value is env->cc_op */ CC_OP_NZ, /* env->cc_dst != 0 */ + CC_OP_ADDU, /* dst != 0, src = carry out (0,1) */ + CC_OP_SUBU, /* dst != 0, src = borrow out (0,-1) */ + CC_OP_LTGT_32, /* signed less/greater than (32bit) */ CC_OP_LTGT_64, /* signed less/greater than (64bit) */ CC_OP_LTUGTU_32, /* unsigned less/greater than (32bit) */ @@ -168,21 +171,13 @@ enum cc_op { CC_OP_LTGT0_64, /* signed less/greater than 0 (64bit) */ CC_OP_ADD_64, /* overflow on add (64bit) */ - CC_OP_ADDU_64, /* overflow on unsigned add (64bit) */ - CC_OP_ADDC_64, /* overflow on unsigned add-carry (64bit) */ CC_OP_SUB_64, /* overflow on subtraction (64bit) */ - CC_OP_SUBU_64, /* overflow on unsigned subtraction (64bit) */ - CC_OP_SUBB_64, /* overflow on unsigned sub-borrow (64bit) */ CC_OP_ABS_64, /* sign eval on abs (64bit) */ CC_OP_NABS_64, /* sign eval on nabs (64bit) */ CC_OP_MULS_64, /* overflow on signed multiply (64bit) */ CC_OP_ADD_32, /* overflow on add (32bit) */ - CC_OP_ADDU_32, /* overflow on unsigned add (32bit) */ - CC_OP_ADDC_32, /* overflow on unsigned add-carry (32bit) */ CC_OP_SUB_32, /* overflow on subtraction (32bit) */ - CC_OP_SUBU_32, /* overflow on unsigned subtraction (32bit) */ - CC_OP_SUBB_32, /* overflow on unsigned sub-borrow (32bit) */ CC_OP_ABS_32, /* sign eval on abs (64bit) */ CC_OP_NABS_32, /* sign eval on nabs (64bit) */ CC_OP_MULS_32, /* overflow on signed multiply (32bit) */ diff --git a/target/s390x/translate.c b/target/s390x/translate.c index be32938..3d5c0d6 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -600,17 +600,9 @@ static void gen_op_calc_cc(DisasContext *s) dummy = tcg_const_i64(0); /* FALLTHRU */ case CC_OP_ADD_64: - case CC_OP_ADDU_64: - case CC_OP_ADDC_64: case CC_OP_SUB_64: - case CC_OP_SUBU_64: - case CC_OP_SUBB_64: case CC_OP_ADD_32: - case CC_OP_ADDU_32: - case CC_OP_ADDC_32: case CC_OP_SUB_32: - case CC_OP_SUBU_32: - case CC_OP_SUBB_32: local_cc_op = tcg_const_i32(s->cc_op); break; case CC_OP_CONST0: @@ -650,6 +642,7 @@ static void gen_op_calc_cc(DisasContext *s) /* 1 argument */ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy); break; + case CC_OP_ADDU: case CC_OP_ICM: case CC_OP_LTGT_32: case CC_OP_LTGT_64: @@ -659,6 +652,7 @@ static void gen_op_calc_cc(DisasContext *s) case CC_OP_TM_64: case CC_OP_SLA_32: case CC_OP_SLA_64: + case CC_OP_SUBU: case CC_OP_NZ_F128: case CC_OP_VC: case CC_OP_MULS_64: @@ -666,17 +660,9 @@ static void gen_op_calc_cc(DisasContext *s) gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy); break; case CC_OP_ADD_64: - case CC_OP_ADDU_64: - case CC_OP_ADDC_64: case CC_OP_SUB_64: - case CC_OP_SUBU_64: - case CC_OP_SUBB_64: case CC_OP_ADD_32: - case CC_OP_ADDU_32: - case CC_OP_ADDC_32: case CC_OP_SUB_32: - case CC_OP_SUBU_32: - case CC_OP_SUBB_32: /* 3 arguments */ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr); break; @@ -849,42 +835,20 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask) account_inline_branch(s, old_cc_op); break; - case CC_OP_ADDU_32: - case CC_OP_ADDU_64: + case CC_OP_ADDU: + case CC_OP_SUBU: switch (mask) { - case 8 | 2: /* vr == 0 */ + case 8 | 2: /* result == 0 */ cond = TCG_COND_EQ; break; - case 4 | 1: /* vr != 0 */ + case 4 | 1: /* result != 0 */ cond = TCG_COND_NE; break; - case 8 | 4: /* no carry -> vr >= src */ - cond = TCG_COND_GEU; + case 8 | 4: /* !carry (borrow) */ + cond = old_cc_op == CC_OP_ADDU ? TCG_COND_EQ : TCG_COND_NE; break; - case 2 | 1: /* carry -> vr < src */ - cond = TCG_COND_LTU; - break; - default: - goto do_dynamic; - } - account_inline_branch(s, old_cc_op); - break; - - case CC_OP_SUBU_32: - case CC_OP_SUBU_64: - /* Note that CC=0 is impossible; treat it as dont-care. */ - switch (mask & 7) { - case 2: /* zero -> op1 == op2 */ - cond = TCG_COND_EQ; - break; - case 4 | 1: /* !zero -> op1 != op2 */ - cond = TCG_COND_NE; - break; - case 4: /* borrow (!carry) -> op1 < op2 */ - cond = TCG_COND_LTU; - break; - case 2 | 1: /* !borrow (carry) -> op1 >= op2 */ - cond = TCG_COND_GEU; + case 2 | 1: /* carry (!borrow) */ + cond = old_cc_op == CC_OP_ADDU ? TCG_COND_NE : TCG_COND_EQ; break; default: goto do_dynamic; @@ -919,7 +883,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask) break; case CC_OP_LTGT_32: case CC_OP_LTUGTU_32: - case CC_OP_SUBU_32: c->is_64 = false; c->u.s32.a = tcg_temp_new_i32(); tcg_gen_extrl_i64_i32(c->u.s32.a, cc_src); @@ -936,7 +899,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask) break; case CC_OP_LTGT_64: case CC_OP_LTUGTU_64: - case CC_OP_SUBU_64: c->u.s64.a = cc_src; c->u.s64.b = cc_dst; c->g1 = c->g2 = true; @@ -950,26 +912,22 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask) tcg_gen_and_i64(c->u.s64.a, cc_src, cc_dst); break; - case CC_OP_ADDU_32: - c->is_64 = false; - c->u.s32.a = tcg_temp_new_i32(); - c->u.s32.b = tcg_temp_new_i32(); - tcg_gen_extrl_i64_i32(c->u.s32.a, cc_vr); - if (cond == TCG_COND_EQ || cond == TCG_COND_NE) { - tcg_gen_movi_i32(c->u.s32.b, 0); - } else { - tcg_gen_extrl_i64_i32(c->u.s32.b, cc_src); - } - break; - - case CC_OP_ADDU_64: - c->u.s64.a = cc_vr; + case CC_OP_ADDU: + case CC_OP_SUBU: + c->is_64 = true; + c->u.s64.b = tcg_const_i64(0); c->g1 = true; - if (cond == TCG_COND_EQ || cond == TCG_COND_NE) { - c->u.s64.b = tcg_const_i64(0); - } else { - c->u.s64.b = cc_src; - c->g2 = true; + switch (mask) { + case 8 | 2: + case 4 | 1: /* result */ + c->u.s64.a = cc_dst; + break; + case 8 | 4: + case 2 | 1: /* carry */ + c->u.s64.a = cc_src; + break; + default: + g_assert_not_reached(); } break; @@ -1445,38 +1403,60 @@ static DisasJumpType op_add(DisasContext *s, DisasOps *o) return DISAS_NEXT; } -static DisasJumpType op_addc(DisasContext *s, DisasOps *o) +static DisasJumpType op_addu64(DisasContext *s, DisasOps *o) { - DisasCompare cmp; - TCGv_i64 carry; + tcg_gen_movi_i64(cc_src, 0); + tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src); + return DISAS_NEXT; +} + +/* Compute carry into cc_src. */ +static void compute_carry(DisasContext *s) +{ + switch (s->cc_op) { + case CC_OP_ADDU: + /* The carry value is already in cc_src (1,0). */ + break; + case CC_OP_SUBU: + tcg_gen_addi_i64(cc_src, cc_src, 1); + break; + default: + gen_op_calc_cc(s); + /* fall through */ + case CC_OP_STATIC: + /* The carry flag is the msb of CC; compute into cc_src. */ + tcg_gen_extu_i32_i64(cc_src, cc_op); + tcg_gen_shri_i64(cc_src, cc_src, 1); + break; + } +} +static DisasJumpType op_addc32(DisasContext *s, DisasOps *o) +{ + compute_carry(s); tcg_gen_add_i64(o->out, o->in1, o->in2); + tcg_gen_add_i64(o->out, o->out, cc_src); + return DISAS_NEXT; +} - /* The carry flag is the msb of CC, therefore the branch mask that would - create that comparison is 3. Feeding the generated comparison to - setcond produces the carry flag that we desire. */ - disas_jcc(s, &cmp, 3); - carry = tcg_temp_new_i64(); - if (cmp.is_64) { - tcg_gen_setcond_i64(cmp.cond, carry, cmp.u.s64.a, cmp.u.s64.b); - } else { - TCGv_i32 t = tcg_temp_new_i32(); - tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b); - tcg_gen_extu_i32_i64(carry, t); - tcg_temp_free_i32(t); - } - free_compare(&cmp); +static DisasJumpType op_addc64(DisasContext *s, DisasOps *o) +{ + compute_carry(s); + + TCGv_i64 zero = tcg_const_i64(0); + tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, zero); + tcg_gen_add2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero); + tcg_temp_free_i64(zero); - tcg_gen_add_i64(o->out, o->out, carry); - tcg_temp_free_i64(carry); return DISAS_NEXT; } static DisasJumpType op_asi(DisasContext *s, DisasOps *o) { - o->in1 = tcg_temp_new_i64(); + bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45); - if (!s390_has_feat(S390_FEAT_STFLE_45)) { + o->in1 = tcg_temp_new_i64(); + if (non_atomic) { tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); } else { /* Perform the atomic addition in memory. */ @@ -1487,7 +1467,30 @@ static DisasJumpType op_asi(DisasContext *s, DisasOps *o) /* Recompute also for atomic case: needed for setting CC. */ tcg_gen_add_i64(o->out, o->in1, o->in2); - if (!s390_has_feat(S390_FEAT_STFLE_45)) { + if (non_atomic) { + tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); + } + return DISAS_NEXT; +} + +static DisasJumpType op_asiu64(DisasContext *s, DisasOps *o) +{ + bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45); + + o->in1 = tcg_temp_new_i64(); + if (non_atomic) { + tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data); + } else { + /* Perform the atomic addition in memory. */ + tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s), + s->insn->data); + } + + /* Recompute also for atomic case: needed for setting CC. */ + tcg_gen_movi_i64(cc_src, 0); + tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src); + + if (non_atomic) { tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data); } return DISAS_NEXT; @@ -4732,29 +4735,58 @@ static DisasJumpType op_sub(DisasContext *s, DisasOps *o) return DISAS_NEXT; } -static DisasJumpType op_subb(DisasContext *s, DisasOps *o) +static DisasJumpType op_subu64(DisasContext *s, DisasOps *o) { - DisasCompare cmp; - TCGv_i64 borrow; - - tcg_gen_sub_i64(o->out, o->in1, o->in2); + tcg_gen_movi_i64(cc_src, 0); + tcg_gen_sub2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src); + return DISAS_NEXT; +} - /* The !borrow flag is the msb of CC. Since we want the inverse of - that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4. */ - disas_jcc(s, &cmp, 8 | 4); - borrow = tcg_temp_new_i64(); - if (cmp.is_64) { - tcg_gen_setcond_i64(cmp.cond, borrow, cmp.u.s64.a, cmp.u.s64.b); - } else { - TCGv_i32 t = tcg_temp_new_i32(); - tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b); - tcg_gen_extu_i32_i64(borrow, t); - tcg_temp_free_i32(t); +/* Compute borrow (0, -1) into cc_src. */ +static void compute_borrow(DisasContext *s) +{ + switch (s->cc_op) { + case CC_OP_SUBU: + /* The borrow value is already in cc_src (0,-1). */ + break; + default: + gen_op_calc_cc(s); + /* fall through */ + case CC_OP_STATIC: + /* The carry flag is the msb of CC; compute into cc_src. */ + tcg_gen_extu_i32_i64(cc_src, cc_op); + tcg_gen_shri_i64(cc_src, cc_src, 1); + /* fall through */ + case CC_OP_ADDU: + /* Convert carry (1,0) to borrow (0,-1). */ + tcg_gen_subi_i64(cc_src, cc_src, 1); + break; } - free_compare(&cmp); +} + +static DisasJumpType op_subb32(DisasContext *s, DisasOps *o) +{ + compute_borrow(s); + + /* Borrow is {0, -1}, so add to subtract. */ + tcg_gen_add_i64(o->out, o->in1, cc_src); + tcg_gen_sub_i64(o->out, o->out, o->in2); + return DISAS_NEXT; +} + +static DisasJumpType op_subb64(DisasContext *s, DisasOps *o) +{ + compute_borrow(s); + + /* + * Borrow is {0, -1}, so add to subtract; replicate the + * borrow input to produce 128-bit -1 for the addition. + */ + TCGv_i64 zero = tcg_const_i64(0); + tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, cc_src); + tcg_gen_sub2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero); + tcg_temp_free_i64(zero); - tcg_gen_sub_i64(o->out, o->out, borrow); - tcg_temp_free_i64(borrow); return DISAS_NEXT; } @@ -5185,22 +5217,14 @@ static void cout_adds64(DisasContext *s, DisasOps *o) static void cout_addu32(DisasContext *s, DisasOps *o) { - gen_op_update3_cc_i64(s, CC_OP_ADDU_32, o->in1, o->in2, o->out); + tcg_gen_shri_i64(cc_src, o->out, 32); + tcg_gen_ext32u_i64(cc_dst, o->out); + gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, cc_dst); } static void cout_addu64(DisasContext *s, DisasOps *o) { - gen_op_update3_cc_i64(s, CC_OP_ADDU_64, o->in1, o->in2, o->out); -} - -static void cout_addc32(DisasContext *s, DisasOps *o) -{ - gen_op_update3_cc_i64(s, CC_OP_ADDC_32, o->in1, o->in2, o->out); -} - -static void cout_addc64(DisasContext *s, DisasOps *o) -{ - gen_op_update3_cc_i64(s, CC_OP_ADDC_64, o->in1, o->in2, o->out); + gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, o->out); } static void cout_cmps32(DisasContext *s, DisasOps *o) @@ -5291,22 +5315,14 @@ static void cout_subs64(DisasContext *s, DisasOps *o) static void cout_subu32(DisasContext *s, DisasOps *o) { - gen_op_update3_cc_i64(s, CC_OP_SUBU_32, o->in1, o->in2, o->out); + tcg_gen_sari_i64(cc_src, o->out, 32); + tcg_gen_ext32u_i64(cc_dst, o->out); + gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, cc_dst); } static void cout_subu64(DisasContext *s, DisasOps *o) { - gen_op_update3_cc_i64(s, CC_OP_SUBU_64, o->in1, o->in2, o->out); -} - -static void cout_subb32(DisasContext *s, DisasOps *o) -{ - gen_op_update3_cc_i64(s, CC_OP_SUBB_32, o->in1, o->in2, o->out); -} - -static void cout_subb64(DisasContext *s, DisasOps *o) -{ - gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out); + gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, o->out); } static void cout_tm32(DisasContext *s, DisasOps *o) @@ -5637,6 +5653,13 @@ static void in1_r2_sr32(DisasContext *s, DisasOps *o) } #define SPEC_in1_r2_sr32 0 +static void in1_r2_32u(DisasContext *s, DisasOps *o) +{ + o->in1 = tcg_temp_new_i64(); + tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r2)]); +} +#define SPEC_in1_r2_32u 0 + static void in1_r3(DisasContext *s, DisasOps *o) { o->in1 = load_reg(get_field(s, r3)); diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index b936939..4b22906 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -156,7 +156,9 @@ enum { #define PS_IE (1<<1) #define PS_AG (1<<0) /* v9, zero on UA2007 */ -#define FPRS_FEF (1<<2) +#define FPRS_DL (1 << 0) +#define FPRS_DU (1 << 1) +#define FPRS_FEF (1 << 2) #define HS_PRIV (1<<2) #endif @@ -606,10 +608,6 @@ target_ulong cpu_get_psr(CPUSPARCState *env1); void cpu_put_psr(CPUSPARCState *env1, target_ulong val); void cpu_put_psr_raw(CPUSPARCState *env1, target_ulong val); #ifdef TARGET_SPARC64 -target_ulong cpu_get_ccr(CPUSPARCState *env1); -void cpu_put_ccr(CPUSPARCState *env1, target_ulong val); -target_ulong cpu_get_cwp64(CPUSPARCState *env1); -void cpu_put_cwp64(CPUSPARCState *env1, int cwp); void cpu_change_pstate(CPUSPARCState *env1, uint32_t new_pstate); void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl); #endif @@ -827,4 +825,24 @@ static inline bool tb_am_enabled(int tb_flags) #endif } +#ifdef TARGET_SPARC64 +/* win_helper.c */ +target_ulong cpu_get_ccr(CPUSPARCState *env1); +void cpu_put_ccr(CPUSPARCState *env1, target_ulong val); +target_ulong cpu_get_cwp64(CPUSPARCState *env1); +void cpu_put_cwp64(CPUSPARCState *env1, int cwp); + +static inline uint64_t sparc64_tstate(CPUSPARCState *env) +{ + uint64_t tstate = (cpu_get_ccr(env) << 32) | + ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) | + cpu_get_cwp64(env); + + if (env->def.features & CPU_FEATURE_GL) { + tstate |= (env->gl & 7ULL) << 40; + } + return tstate; +} +#endif + #endif diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c index ba95bf2..7fb8ab2 100644 --- a/target/sparc/int64_helper.c +++ b/target/sparc/int64_helper.c @@ -131,9 +131,7 @@ void sparc_cpu_do_interrupt(CPUState *cs) } tsptr = cpu_tsptr(env); - tsptr->tstate = (cpu_get_ccr(env) << 32) | - ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) | - cpu_get_cwp64(env); + tsptr->tstate = sparc64_tstate(env); tsptr->tpc = env->pc; tsptr->tnpc = env->npc; tsptr->tt = intno; @@ -148,7 +146,6 @@ void sparc_cpu_do_interrupt(CPUState *cs) } if (env->def.features & CPU_FEATURE_GL) { - tsptr->tstate |= (env->gl & 7ULL) << 40; cpu_gl_switch_gregs(env, env->gl + 1); env->gl++; } diff --git a/target/sparc/machine.c b/target/sparc/machine.c index f38cf22..917375c 100644 --- a/target/sparc/machine.c +++ b/target/sparc/machine.c @@ -68,7 +68,7 @@ static int get_psr(QEMUFile *f, void *opaque, size_t size, } static int put_psr(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) + const VMStateField *field, JSONWriter *vmdesc) { SPARCCPU *cpu = opaque; CPUSPARCState *env = &cpu->env; diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 30c73f8..4bfa317 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -2324,8 +2324,8 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, } /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions * are ST_BLKINIT_ ASIs */ - /* fall through */ #endif + /* fall through */ case GET_ASI_DIRECT: gen_address_mask(dc, addr); tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop); diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c index 5b57892..3a7c0ff 100644 --- a/target/sparc/win_helper.c +++ b/target/sparc/win_helper.c @@ -302,7 +302,7 @@ static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) switch (pstate) { default: trace_win_helper_gregset_error(pstate); - /* pass through to normal set of global registers */ + /* fall through to normal set of global registers */ case 0: return env->bgregs; case PS_AG: diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c index d4b06df..962f987 100644 --- a/target/unicore32/translate.c +++ b/target/unicore32/translate.c @@ -1801,6 +1801,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s) do_misc(env, s, insn); break; } + /* fallthrough */ case 0x1: if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) { do_misc(env, s, insn); @@ -1817,6 +1818,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s) if (UCOP_SET(8) || UCOP_SET(5)) { ILLEGAL; } + /* fallthrough */ case 0x3: do_ldst_ir(env, s, insn); break; |