[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v3.5 2/8] target/s390x: Implement CONVERT UNICOD
From: |
Thomas Huth |
Subject: |
Re: [Qemu-devel] [PATCH v3.5 2/8] target/s390x: Implement CONVERT UNICODE insns |
Date: |
Wed, 12 Jul 2017 08:46:41 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.0 |
On 11.07.2017 20:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <address@hidden>
> ---
> v3.5: Added even register checks in the translator [thuth].
> ---
> target/s390x/helper.h | 6 +
> target/s390x/mem_helper.c | 310
> +++++++++++++++++++++++++++++++++++++++++++++
> target/s390x/translate.c | 51 ++++++++
> target/s390x/insn-data.def | 13 ++
> 4 files changed, 380 insertions(+)
>
> diff --git a/target/s390x/helper.h b/target/s390x/helper.h
> index 23e8d1d..2793cf3 100644
> --- a/target/s390x/helper.h
> +++ b/target/s390x/helper.h
> @@ -107,6 +107,12 @@ DEF_HELPER_2(stfle, i32, env, i64)
> DEF_HELPER_FLAGS_2(lpq, TCG_CALL_NO_WG, i64, env, i64)
> DEF_HELPER_FLAGS_4(stpq, TCG_CALL_NO_WG, void, env, i64, i64, i64)
> DEF_HELPER_4(mvcos, i32, env, i64, i64, i64)
> +DEF_HELPER_4(cu12, i32, env, i32, i32, i32)
> +DEF_HELPER_4(cu14, i32, env, i32, i32, i32)
> +DEF_HELPER_4(cu21, i32, env, i32, i32, i32)
> +DEF_HELPER_4(cu24, i32, env, i32, i32, i32)
> +DEF_HELPER_4(cu41, i32, env, i32, i32, i32)
> +DEF_HELPER_4(cu42, i32, env, i32, i32, i32)
>
> #ifndef CONFIG_USER_ONLY
> DEF_HELPER_3(servc, i32, env, i64, i64)
> diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
> index 513b402..0b18560 100644
> --- a/target/s390x/mem_helper.c
> +++ b/target/s390x/mem_helper.c
> @@ -2196,3 +2196,313 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t
> dest, uint64_t src,
>
> return cc;
> }
> +
> +/* Decode a Unicode character. A return value < 0 indicates success, storing
> + the UTF-32 result into OCHAR and the input length into OLEN. A return
> + value >= 0 indicates failure, and the CC value to be returned. */
> +typedef int (*decode_unicode_fn)(CPUS390XState *env, uint64_t addr,
> + uint64_t ilen, bool enh_check, uintptr_t ra,
> + uint32_t *ochar, uint32_t *olen);
> +
> +/* Encode a Unicode character. A return value < 0 indicates success, storing
> + the bytes into ADDR and the output length into OLEN. A return value >= 0
> + indicates failure, and the CC value to be returned. */
> +typedef int (*encode_unicode_fn)(CPUS390XState *env, uint64_t addr,
> + uint64_t ilen, uintptr_t ra, uint32_t c,
> + uint32_t *olen);
> +
> +static int decode_utf8(CPUS390XState *env, uint64_t addr, uint64_t ilen,
> + bool enh_check, uintptr_t ra,
> + uint32_t *ochar, uint32_t *olen)
> +{
> + uint8_t s0, s1, s2, s3;
> + uint32_t c, l;
> +
> + if (ilen < 1) {
> + return 0;
> + }
> + s0 = cpu_ldub_data_ra(env, addr, ra);
> + if (s0 <= 0x7f) {
> + /* one byte character */
> + l = 1;
> + c = s0;
> + } else if (s0 <= (enh_check ? 0xc1 : 0xbf)) {
> + /* invalid character */
> + return 2;
> + } else if (s0 <= 0xdf) {
> + /* two byte character */
> + l = 2;
> + if (ilen < 2) {
> + return 0;
> + }
> + s1 = cpu_ldub_data_ra(env, addr + 1, ra);
> + c = s0 & 0x1f;
> + c = (c << 6) | (s1 & 0x3f);
> + if (enh_check && (s1 & 0xc0) != 0x80) {
> + return 2;
> + }
> + } else if (s0 <= 0xef) {
> + /* three byte character */
> + l = 3;
> + if (ilen < 3) {
> + return 0;
> + }
> + s1 = cpu_ldub_data_ra(env, addr + 1, ra);
> + s2 = cpu_ldub_data_ra(env, addr + 2, ra);
> + c = s0 & 0x0f;
> + c = (c << 6) | (s1 & 0x3f);
> + c = (c << 6) | (s2 & 0x3f);
> + /* Fold the byte-by-byte range descriptions in the PoO into
> + tests against the complete value. It disallows encodings
> + that could be smaller, and the UTF-16 surrogates. */
> + if (enh_check
> + && ((s1 & 0xc0) != 0x80
> + || (s2 & 0xc0) != 0x80
> + || c < 0x1000
> + || (c >= 0xd800 && c <= 0xdfff))) {
> + return 2;
> + }
> + } else if (s0 <= (enh_check ? 0xf4 : 0xf7)) {
> + /* four byte character */
> + l = 4;
> + if (ilen < 4) {
> + return 0;
> + }
> + s1 = cpu_ldub_data_ra(env, addr + 1, ra);
> + s2 = cpu_ldub_data_ra(env, addr + 2, ra);
> + s3 = cpu_ldub_data_ra(env, addr + 3, ra);
> + c = s0 & 0x0f;
I think you could also use 0x07 instead of 0x0f here. Shouldn't matter
much due to the s0 <= 0xf7 check above, though.
> + c = (c << 6) | (s1 & 0x3f);
> + c = (c << 6) | (s2 & 0x3f);
> + c = (c << 6) | (s3 & 0x3f);
> + /* See above. */
> + if (enh_check
> + && ((s1 & 0xc0) != 0x80
> + || (s2 & 0xc0) != 0x80
> + || (s3 & 0xc0) != 0x80
> + || c < 0x010000
> + || c > 0x10ffff)) {
> + return 2;
> + }
> + } else {
> + /* invalid character */
> + return 2;
> + }
> +
> + *ochar = c;
> + *olen = l;
> + return -1;
> +}
[...]
Patch looks fine to me now!
Reviewed-by: Thomas Huth <address@hidden>
- [Qemu-devel] [PATCH v3 0/8] target/s390x tcg improvements, Richard Henderson, 2017/07/10
- [Qemu-devel] [PATCH v3 2/8] target/s390x: Implement CONVERT UNICODE insns, Richard Henderson, 2017/07/10
- Re: [Qemu-devel] [PATCH v3 2/8] target/s390x: Implement CONVERT UNICODE insns, Aurelien Jarno, 2017/07/14
- Re: [Qemu-devel] [PATCH v3 2/8] target/s390x: Implement CONVERT UNICODE insns, Richard Henderson, 2017/07/14
- Re: [Qemu-devel] [PATCH v3 2/8] target/s390x: Implement CONVERT UNICODE insns, Aurelien Jarno, 2017/07/15
- Re: [Qemu-devel] [PATCH v3 2/8] target/s390x: Implement CONVERT UNICODE insns, Richard Henderson, 2017/07/15
Re: [Qemu-devel] [PATCH v3 2/8] target/s390x: Implement CONVERT UNICODE insns, Aurelien Jarno, 2017/07/14
[Qemu-devel] [PATCH v3 6/8] target/s390x: Mark ETF3 and ETF3_ENH facilities as available, Richard Henderson, 2017/07/10
[Qemu-devel] [PATCH v3 7/8] target/s390x: Allow to enable "idtes" feature for TCG, Richard Henderson, 2017/07/10
[Qemu-devel] [PATCH v3 3/8] target/s390x: Tidy SRST, Richard Henderson, 2017/07/10