1 | Finish the conversion of all aarch64 instructions to decodetree. | 1 | Finish the conversion of all aarch64 instructions to decodetree. |
---|---|---|---|
2 | 2 | ||
3 | Changes for v2: | 3 | Changes for v3: |
4 | - Apply review nits as appropriate. | 4 | - Fix decode for f16 fsqrt (vector) in patch 23, prior to conversion. |
5 | - Split out gen_gvec_fabs, gen_gvec_fneg and share with a32 neon. | 5 | This is the only patch without R-B. |
6 | |||
7 | Patches lacking review: | ||
8 | 23-target-arm-Fix-decode-of-fp16-vector-fabs-fneg.patch | ||
9 | 24-target-arm-Convert-FMOV-FABS-FNEG-scalar-to-decod.patch | ||
10 | 29-target-arm-Convert-BFCVT-to-decodetree.patch | ||
11 | 43-target-arm-Convert-handle_rev-to-decodetree.patch | ||
12 | 53-target-arm-Implement-gen_gvec_fabs-gen_gvec_fneg.patch | ||
13 | 57-target-arm-Convert-FCVT-vector-integer-scalar-to-.patch | ||
14 | 58-target-arm-Convert-FCVT-vector-fixed-point-scalar.patch | ||
15 | 60-target-arm-Convert-US-CVTF-vector-fixed-point-sca.patch | ||
16 | 62-target-arm-Convert-US-CVTF-vector-to-decodetree.patch | ||
17 | 63-target-arm-Convert-FCVTZ-SU-vector-fixed-point-to.patch | ||
18 | 64-target-arm-Convert-FCVT-vector-integer-to-decodet.patch | ||
19 | 67-target-arm-Introduce-gen_gvec_urecpe-gen_gvec_urs.patch | ||
20 | 68-target-arm-Convert-URECPE-and-URSQRTE-to-decodetr.patch | ||
21 | 6 | ||
22 | 7 | ||
23 | r~ | 8 | r~ |
24 | 9 | ||
25 | 10 | ||
... | ... | ||
44 | target/arm: Convert CCMP, CCMN to decodetree | 29 | target/arm: Convert CCMP, CCMN to decodetree |
45 | target/arm: Convert disas_cond_select to decodetree | 30 | target/arm: Convert disas_cond_select to decodetree |
46 | target/arm: Introduce fp_access_check_scalar_hsd | 31 | target/arm: Introduce fp_access_check_scalar_hsd |
47 | target/arm: Introduce fp_access_check_vector_hsd | 32 | target/arm: Introduce fp_access_check_vector_hsd |
48 | target/arm: Convert FCMP, FCMPE, FCCMP, FCCMPE to decodetree | 33 | target/arm: Convert FCMP, FCMPE, FCCMP, FCCMPE to decodetree |
49 | target/arm: Fix decode of fp16 vector fabs, fneg | 34 | target/arm: Fix decode of fp16 vector fabs, fneg, fsqrt |
50 | target/arm: Convert FMOV, FABS, FNEG (scalar) to decodetree | 35 | target/arm: Convert FMOV, FABS, FNEG (scalar) to decodetree |
51 | target/arm: Pass fpstatus to vfp_sqrt* | 36 | target/arm: Pass fpstatus to vfp_sqrt* |
52 | target/arm: Remove helper_sqrt_f16 | 37 | target/arm: Remove helper_sqrt_f16 |
53 | target/arm: Convert FSQRT (scalar) to decodetree | 38 | target/arm: Convert FSQRT (scalar) to decodetree |
54 | target/arm: Convert FRINT[NPMSAXI] (scalar) to decodetree | 39 | target/arm: Convert FRINT[NPMSAXI] (scalar) to decodetree |
... | ... | diff view generated by jsdifflib |
1 | At the same time, use ### to separate 3rd-level sections. | 1 | At the same time, use ### to separate 3rd-level sections. |
---|---|---|---|
2 | We already use ### for 4.1.92 Data Processing (immediate), | 2 | We already use ### for 4.1.92 Data Processing (immediate), |
3 | but not the two following two third-level sections: | 3 | but not the two following two third-level sections: |
4 | 4.1.93 Branches, and 4.1.94 Loads and stores. | 4 | 4.1.93 Branches, and 4.1.94 Loads and stores. |
5 | 5 | ||
6 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 6 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
7 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 7 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
8 | --- | 8 | --- |
9 | target/arm/tcg/a64.decode | 19 +++++++++++++++++-- | 9 | target/arm/tcg/a64.decode | 19 +++++++++++++++++-- |
10 | 1 file changed, 17 insertions(+), 2 deletions(-) | 10 | 1 file changed, 17 insertions(+), 2 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 12 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/tcg/a64.decode | 14 | --- a/target/arm/tcg/a64.decode |
15 | +++ b/target/arm/tcg/a64.decode | 15 | +++ b/target/arm/tcg/a64.decode |
16 | @@ -XXX,XX +XXX,XX @@ UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32 | 16 | @@ -XXX,XX +XXX,XX @@ UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32 |
17 | EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1 | 17 | EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1 |
18 | EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0 | 18 | EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0 |
19 | 19 | ||
20 | -# Branches | 20 | -# Branches |
21 | +### Branches | 21 | +### Branches |
22 | 22 | ||
23 | %imm26 0:s26 !function=times_4 | 23 | %imm26 0:s26 !function=times_4 |
24 | @branch . ..... .......................... &i imm=%imm26 | 24 | @branch . ..... .......................... &i imm=%imm26 |
25 | @@ -XXX,XX +XXX,XX @@ HLT 1101 0100 010 ................ 000 00 @i16 | 25 | @@ -XXX,XX +XXX,XX @@ HLT 1101 0100 010 ................ 000 00 @i16 |
26 | # DCPS2 1101 0100 101 ................ 000 10 @i16 | 26 | # DCPS2 1101 0100 101 ................ 000 10 @i16 |
27 | # DCPS3 1101 0100 101 ................ 000 11 @i16 | 27 | # DCPS3 1101 0100 101 ................ 000 11 @i16 |
28 | 28 | ||
29 | -# Loads and stores | 29 | -# Loads and stores |
30 | +### Loads and stores | 30 | +### Loads and stores |
31 | 31 | ||
32 | &stxr rn rt rt2 rs sz lasr | 32 | &stxr rn rt rt2 rs sz lasr |
33 | &stlr rn rt sz lasr | 33 | &stlr rn rt sz lasr |
34 | @@ -XXX,XX +XXX,XX @@ CPYP 00 011 1 01000 ..... .... 01 ..... ..... @cpy | 34 | @@ -XXX,XX +XXX,XX @@ CPYP 00 011 1 01000 ..... .... 01 ..... ..... @cpy |
35 | CPYM 00 011 1 01010 ..... .... 01 ..... ..... @cpy | 35 | CPYM 00 011 1 01010 ..... .... 01 ..... ..... @cpy |
36 | CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy | 36 | CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy |
37 | 37 | ||
38 | +### Data Processing (register) | 38 | +### Data Processing (register) |
39 | + | 39 | + |
40 | +# Data Processing (2-source) | 40 | +# Data Processing (2-source) |
41 | +# Data Processing (1-source) | 41 | +# Data Processing (1-source) |
42 | +# Logical (shifted reg) | 42 | +# Logical (shifted reg) |
43 | +# Add/subtract (shifted reg) | 43 | +# Add/subtract (shifted reg) |
44 | +# Add/subtract (extended reg) | 44 | +# Add/subtract (extended reg) |
45 | +# Add/subtract (carry) | 45 | +# Add/subtract (carry) |
46 | +# Rotate right into flags | 46 | +# Rotate right into flags |
47 | +# Evaluate into flags | 47 | +# Evaluate into flags |
48 | +# Conditional compare (regster) | 48 | +# Conditional compare (regster) |
49 | +# Conditional compare (immediate) | 49 | +# Conditional compare (immediate) |
50 | +# Conditional select | 50 | +# Conditional select |
51 | +# Data Processing (3-source) | 51 | +# Data Processing (3-source) |
52 | + | 52 | + |
53 | ### Cryptographic AES | 53 | ### Cryptographic AES |
54 | 54 | ||
55 | AESE 01001110 00 10100 00100 10 ..... ..... @r2r_q1e0 | 55 | AESE 01001110 00 10100 00100 10 ..... ..... @r2r_q1e0 |
56 | -- | 56 | -- |
57 | 2.43.0 | 57 | 2.43.0 |
58 | 58 | ||
59 | 59 | diff view generated by jsdifflib |
1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 64 +++++++++++++++++----------------- | 4 | target/arm/tcg/translate-a64.c | 64 +++++++++++++++++----------------- |
5 | target/arm/tcg/a64.decode | 7 ++++ | 5 | target/arm/tcg/a64.decode | 7 ++++ |
6 | 2 files changed, 39 insertions(+), 32 deletions(-) | 6 | 2 files changed, 39 insertions(+), 32 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ TRANS(UQRSHRN_si, do_scalar_shift_imm_narrow, a, uqrshrn_fns, 0, false) | 12 | @@ -XXX,XX +XXX,XX @@ TRANS(UQRSHRN_si, do_scalar_shift_imm_narrow, a, uqrshrn_fns, 0, false) |
13 | TRANS(SQSHRUN_si, do_scalar_shift_imm_narrow, a, sqshrun_fns, MO_SIGN, false) | 13 | TRANS(SQSHRUN_si, do_scalar_shift_imm_narrow, a, sqshrun_fns, MO_SIGN, false) |
14 | TRANS(SQRSHRUN_si, do_scalar_shift_imm_narrow, a, sqrshrun_fns, MO_SIGN, false) | 14 | TRANS(SQRSHRUN_si, do_scalar_shift_imm_narrow, a, sqrshrun_fns, MO_SIGN, false) |
15 | 15 | ||
16 | +static bool do_div(DisasContext *s, arg_rrr_sf *a, bool is_signed) | 16 | +static bool do_div(DisasContext *s, arg_rrr_sf *a, bool is_signed) |
17 | +{ | 17 | +{ |
18 | + TCGv_i64 tcg_n, tcg_m, tcg_rd; | 18 | + TCGv_i64 tcg_n, tcg_m, tcg_rd; |
19 | + tcg_rd = cpu_reg(s, a->rd); | 19 | + tcg_rd = cpu_reg(s, a->rd); |
20 | + | 20 | + |
21 | + if (!a->sf && is_signed) { | 21 | + if (!a->sf && is_signed) { |
22 | + tcg_n = tcg_temp_new_i64(); | 22 | + tcg_n = tcg_temp_new_i64(); |
23 | + tcg_m = tcg_temp_new_i64(); | 23 | + tcg_m = tcg_temp_new_i64(); |
24 | + tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, a->rn)); | 24 | + tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, a->rn)); |
25 | + tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, a->rm)); | 25 | + tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, a->rm)); |
26 | + } else { | 26 | + } else { |
27 | + tcg_n = read_cpu_reg(s, a->rn, a->sf); | 27 | + tcg_n = read_cpu_reg(s, a->rn, a->sf); |
28 | + tcg_m = read_cpu_reg(s, a->rm, a->sf); | 28 | + tcg_m = read_cpu_reg(s, a->rm, a->sf); |
29 | + } | 29 | + } |
30 | + | 30 | + |
31 | + if (is_signed) { | 31 | + if (is_signed) { |
32 | + gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m); | 32 | + gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m); |
33 | + } else { | 33 | + } else { |
34 | + gen_helper_udiv64(tcg_rd, tcg_n, tcg_m); | 34 | + gen_helper_udiv64(tcg_rd, tcg_n, tcg_m); |
35 | + } | 35 | + } |
36 | + | 36 | + |
37 | + if (!a->sf) { /* zero extend final result */ | 37 | + if (!a->sf) { /* zero extend final result */ |
38 | + tcg_gen_ext32u_i64(tcg_rd, tcg_rd); | 38 | + tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
39 | + } | 39 | + } |
40 | + return true; | 40 | + return true; |
41 | +} | 41 | +} |
42 | + | 42 | + |
43 | +TRANS(SDIV, do_div, a, true) | 43 | +TRANS(SDIV, do_div, a, true) |
44 | +TRANS(UDIV, do_div, a, false) | 44 | +TRANS(UDIV, do_div, a, false) |
45 | + | 45 | + |
46 | /* Shift a TCGv src by TCGv shift_amount, put result in dst. | 46 | /* Shift a TCGv src by TCGv shift_amount, put result in dst. |
47 | * Note that it is the caller's responsibility to ensure that the | 47 | * Note that it is the caller's responsibility to ensure that the |
48 | * shift amount is in range (ie 0..31 or 0..63) and provide the ARM | 48 | * shift amount is in range (ie 0..31 or 0..63) and provide the ARM |
49 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 49 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
50 | #undef MAP | 50 | #undef MAP |
51 | } | 51 | } |
52 | 52 | ||
53 | -static void handle_div(DisasContext *s, bool is_signed, unsigned int sf, | 53 | -static void handle_div(DisasContext *s, bool is_signed, unsigned int sf, |
54 | - unsigned int rm, unsigned int rn, unsigned int rd) | 54 | - unsigned int rm, unsigned int rn, unsigned int rd) |
55 | -{ | 55 | -{ |
56 | - TCGv_i64 tcg_n, tcg_m, tcg_rd; | 56 | - TCGv_i64 tcg_n, tcg_m, tcg_rd; |
57 | - tcg_rd = cpu_reg(s, rd); | 57 | - tcg_rd = cpu_reg(s, rd); |
58 | - | 58 | - |
59 | - if (!sf && is_signed) { | 59 | - if (!sf && is_signed) { |
60 | - tcg_n = tcg_temp_new_i64(); | 60 | - tcg_n = tcg_temp_new_i64(); |
61 | - tcg_m = tcg_temp_new_i64(); | 61 | - tcg_m = tcg_temp_new_i64(); |
62 | - tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, rn)); | 62 | - tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, rn)); |
63 | - tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, rm)); | 63 | - tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, rm)); |
64 | - } else { | 64 | - } else { |
65 | - tcg_n = read_cpu_reg(s, rn, sf); | 65 | - tcg_n = read_cpu_reg(s, rn, sf); |
66 | - tcg_m = read_cpu_reg(s, rm, sf); | 66 | - tcg_m = read_cpu_reg(s, rm, sf); |
67 | - } | 67 | - } |
68 | - | 68 | - |
69 | - if (is_signed) { | 69 | - if (is_signed) { |
70 | - gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m); | 70 | - gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m); |
71 | - } else { | 71 | - } else { |
72 | - gen_helper_udiv64(tcg_rd, tcg_n, tcg_m); | 72 | - gen_helper_udiv64(tcg_rd, tcg_n, tcg_m); |
73 | - } | 73 | - } |
74 | - | 74 | - |
75 | - if (!sf) { /* zero extend final result */ | 75 | - if (!sf) { /* zero extend final result */ |
76 | - tcg_gen_ext32u_i64(tcg_rd, tcg_rd); | 76 | - tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
77 | - } | 77 | - } |
78 | -} | 78 | -} |
79 | 79 | ||
80 | /* LSLV, LSRV, ASRV, RORV */ | 80 | /* LSLV, LSRV, ASRV, RORV */ |
81 | static void handle_shift_reg(DisasContext *s, | 81 | static void handle_shift_reg(DisasContext *s, |
82 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 82 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
83 | } | 83 | } |
84 | } | 84 | } |
85 | break; | 85 | break; |
86 | - case 2: /* UDIV */ | 86 | - case 2: /* UDIV */ |
87 | - handle_div(s, false, sf, rm, rn, rd); | 87 | - handle_div(s, false, sf, rm, rn, rd); |
88 | - break; | 88 | - break; |
89 | - case 3: /* SDIV */ | 89 | - case 3: /* SDIV */ |
90 | - handle_div(s, true, sf, rm, rn, rd); | 90 | - handle_div(s, true, sf, rm, rn, rd); |
91 | - break; | 91 | - break; |
92 | case 4: /* IRG */ | 92 | case 4: /* IRG */ |
93 | if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { | 93 | if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { |
94 | goto do_unallocated; | 94 | goto do_unallocated; |
95 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 95 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
96 | } | 96 | } |
97 | default: | 97 | default: |
98 | do_unallocated: | 98 | do_unallocated: |
99 | + case 2: /* UDIV */ | 99 | + case 2: /* UDIV */ |
100 | + case 3: /* SDIV */ | 100 | + case 3: /* SDIV */ |
101 | unallocated_encoding(s); | 101 | unallocated_encoding(s); |
102 | break; | 102 | break; |
103 | } | 103 | } |
104 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 104 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
105 | index XXXXXXX..XXXXXXX 100644 | 105 | index XXXXXXX..XXXXXXX 100644 |
106 | --- a/target/arm/tcg/a64.decode | 106 | --- a/target/arm/tcg/a64.decode |
107 | +++ b/target/arm/tcg/a64.decode | 107 | +++ b/target/arm/tcg/a64.decode |
108 | @@ -XXX,XX +XXX,XX @@ | 108 | @@ -XXX,XX +XXX,XX @@ |
109 | &r rn | 109 | &r rn |
110 | &ri rd imm | 110 | &ri rd imm |
111 | &rri_sf rd rn imm sf | 111 | &rri_sf rd rn imm sf |
112 | +&rrr_sf rd rn rm sf | 112 | +&rrr_sf rd rn rm sf |
113 | &i imm | 113 | &i imm |
114 | &rr_e rd rn esz | 114 | &rr_e rd rn esz |
115 | &rri_e rd rn imm esz | 115 | &rri_e rd rn imm esz |
116 | @@ -XXX,XX +XXX,XX @@ CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy | 116 | @@ -XXX,XX +XXX,XX @@ CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy |
117 | ### Data Processing (register) | 117 | ### Data Processing (register) |
118 | 118 | ||
119 | # Data Processing (2-source) | 119 | # Data Processing (2-source) |
120 | + | 120 | + |
121 | +@rrr_sf sf:1 .......... rm:5 ...... rn:5 rd:5 &rrr_sf | 121 | +@rrr_sf sf:1 .......... rm:5 ...... rn:5 rd:5 &rrr_sf |
122 | + | 122 | + |
123 | +UDIV . 00 11010110 ..... 00001 0 ..... ..... @rrr_sf | 123 | +UDIV . 00 11010110 ..... 00001 0 ..... ..... @rrr_sf |
124 | +SDIV . 00 11010110 ..... 00001 1 ..... ..... @rrr_sf | 124 | +SDIV . 00 11010110 ..... 00001 1 ..... ..... @rrr_sf |
125 | + | 125 | + |
126 | # Data Processing (1-source) | 126 | # Data Processing (1-source) |
127 | # Logical (shifted reg) | 127 | # Logical (shifted reg) |
128 | # Add/subtract (shifted reg) | 128 | # Add/subtract (shifted reg) |
129 | -- | 129 | -- |
130 | 2.43.0 | 130 | 2.43.0 |
131 | 131 | ||
132 | 132 | diff view generated by jsdifflib |
1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 46 ++++++++++++++++------------------ | 4 | target/arm/tcg/translate-a64.c | 46 ++++++++++++++++------------------ |
5 | target/arm/tcg/a64.decode | 4 +++ | 5 | target/arm/tcg/a64.decode | 4 +++ |
6 | 2 files changed, 25 insertions(+), 25 deletions(-) | 6 | 2 files changed, 25 insertions(+), 25 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf, | 12 | @@ -XXX,XX +XXX,XX @@ static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf, |
13 | } | 13 | } |
14 | } | 14 | } |
15 | 15 | ||
16 | +static bool do_shift_reg(DisasContext *s, arg_rrr_sf *a, | 16 | +static bool do_shift_reg(DisasContext *s, arg_rrr_sf *a, |
17 | + enum a64_shift_type shift_type) | 17 | + enum a64_shift_type shift_type) |
18 | +{ | 18 | +{ |
19 | + TCGv_i64 tcg_shift = tcg_temp_new_i64(); | 19 | + TCGv_i64 tcg_shift = tcg_temp_new_i64(); |
20 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 20 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
21 | + TCGv_i64 tcg_rn = read_cpu_reg(s, a->rn, a->sf); | 21 | + TCGv_i64 tcg_rn = read_cpu_reg(s, a->rn, a->sf); |
22 | + | 22 | + |
23 | + tcg_gen_andi_i64(tcg_shift, cpu_reg(s, a->rm), a->sf ? 63 : 31); | 23 | + tcg_gen_andi_i64(tcg_shift, cpu_reg(s, a->rm), a->sf ? 63 : 31); |
24 | + shift_reg(tcg_rd, tcg_rn, a->sf, shift_type, tcg_shift); | 24 | + shift_reg(tcg_rd, tcg_rn, a->sf, shift_type, tcg_shift); |
25 | + return true; | 25 | + return true; |
26 | +} | 26 | +} |
27 | + | 27 | + |
28 | +TRANS(LSLV, do_shift_reg, a, A64_SHIFT_TYPE_LSL) | 28 | +TRANS(LSLV, do_shift_reg, a, A64_SHIFT_TYPE_LSL) |
29 | +TRANS(LSRV, do_shift_reg, a, A64_SHIFT_TYPE_LSR) | 29 | +TRANS(LSRV, do_shift_reg, a, A64_SHIFT_TYPE_LSR) |
30 | +TRANS(ASRV, do_shift_reg, a, A64_SHIFT_TYPE_ASR) | 30 | +TRANS(ASRV, do_shift_reg, a, A64_SHIFT_TYPE_ASR) |
31 | +TRANS(RORV, do_shift_reg, a, A64_SHIFT_TYPE_ROR) | 31 | +TRANS(RORV, do_shift_reg, a, A64_SHIFT_TYPE_ROR) |
32 | + | 32 | + |
33 | /* Logical (shifted register) | 33 | /* Logical (shifted register) |
34 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 34 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
35 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 35 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
36 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 36 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
37 | } | 37 | } |
38 | 38 | ||
39 | 39 | ||
40 | -/* LSLV, LSRV, ASRV, RORV */ | 40 | -/* LSLV, LSRV, ASRV, RORV */ |
41 | -static void handle_shift_reg(DisasContext *s, | 41 | -static void handle_shift_reg(DisasContext *s, |
42 | - enum a64_shift_type shift_type, unsigned int sf, | 42 | - enum a64_shift_type shift_type, unsigned int sf, |
43 | - unsigned int rm, unsigned int rn, unsigned int rd) | 43 | - unsigned int rm, unsigned int rn, unsigned int rd) |
44 | -{ | 44 | -{ |
45 | - TCGv_i64 tcg_shift = tcg_temp_new_i64(); | 45 | - TCGv_i64 tcg_shift = tcg_temp_new_i64(); |
46 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); | 46 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); |
47 | - TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf); | 47 | - TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf); |
48 | - | 48 | - |
49 | - tcg_gen_andi_i64(tcg_shift, cpu_reg(s, rm), sf ? 63 : 31); | 49 | - tcg_gen_andi_i64(tcg_shift, cpu_reg(s, rm), sf ? 63 : 31); |
50 | - shift_reg(tcg_rd, tcg_rn, sf, shift_type, tcg_shift); | 50 | - shift_reg(tcg_rd, tcg_rn, sf, shift_type, tcg_shift); |
51 | -} | 51 | -} |
52 | - | 52 | - |
53 | /* CRC32[BHWX], CRC32C[BHWX] */ | 53 | /* CRC32[BHWX], CRC32C[BHWX] */ |
54 | static void handle_crc32(DisasContext *s, | 54 | static void handle_crc32(DisasContext *s, |
55 | unsigned int sf, unsigned int sz, bool crc32c, | 55 | unsigned int sf, unsigned int sz, bool crc32c, |
56 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 56 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
57 | tcg_gen_or_i64(cpu_reg(s, rd), cpu_reg(s, rm), t); | 57 | tcg_gen_or_i64(cpu_reg(s, rd), cpu_reg(s, rm), t); |
58 | } | 58 | } |
59 | break; | 59 | break; |
60 | - case 8: /* LSLV */ | 60 | - case 8: /* LSLV */ |
61 | - handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd); | 61 | - handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd); |
62 | - break; | 62 | - break; |
63 | - case 9: /* LSRV */ | 63 | - case 9: /* LSRV */ |
64 | - handle_shift_reg(s, A64_SHIFT_TYPE_LSR, sf, rm, rn, rd); | 64 | - handle_shift_reg(s, A64_SHIFT_TYPE_LSR, sf, rm, rn, rd); |
65 | - break; | 65 | - break; |
66 | - case 10: /* ASRV */ | 66 | - case 10: /* ASRV */ |
67 | - handle_shift_reg(s, A64_SHIFT_TYPE_ASR, sf, rm, rn, rd); | 67 | - handle_shift_reg(s, A64_SHIFT_TYPE_ASR, sf, rm, rn, rd); |
68 | - break; | 68 | - break; |
69 | - case 11: /* RORV */ | 69 | - case 11: /* RORV */ |
70 | - handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd); | 70 | - handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd); |
71 | - break; | 71 | - break; |
72 | case 12: /* PACGA */ | 72 | case 12: /* PACGA */ |
73 | if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) { | 73 | if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) { |
74 | goto do_unallocated; | 74 | goto do_unallocated; |
75 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 75 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
76 | do_unallocated: | 76 | do_unallocated: |
77 | case 2: /* UDIV */ | 77 | case 2: /* UDIV */ |
78 | case 3: /* SDIV */ | 78 | case 3: /* SDIV */ |
79 | + case 8: /* LSLV */ | 79 | + case 8: /* LSLV */ |
80 | + case 9: /* LSRV */ | 80 | + case 9: /* LSRV */ |
81 | + case 10: /* ASRV */ | 81 | + case 10: /* ASRV */ |
82 | + case 11: /* RORV */ | 82 | + case 11: /* RORV */ |
83 | unallocated_encoding(s); | 83 | unallocated_encoding(s); |
84 | break; | 84 | break; |
85 | } | 85 | } |
86 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 86 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
87 | index XXXXXXX..XXXXXXX 100644 | 87 | index XXXXXXX..XXXXXXX 100644 |
88 | --- a/target/arm/tcg/a64.decode | 88 | --- a/target/arm/tcg/a64.decode |
89 | +++ b/target/arm/tcg/a64.decode | 89 | +++ b/target/arm/tcg/a64.decode |
90 | @@ -XXX,XX +XXX,XX @@ CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy | 90 | @@ -XXX,XX +XXX,XX @@ CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy |
91 | 91 | ||
92 | UDIV . 00 11010110 ..... 00001 0 ..... ..... @rrr_sf | 92 | UDIV . 00 11010110 ..... 00001 0 ..... ..... @rrr_sf |
93 | SDIV . 00 11010110 ..... 00001 1 ..... ..... @rrr_sf | 93 | SDIV . 00 11010110 ..... 00001 1 ..... ..... @rrr_sf |
94 | +LSLV . 00 11010110 ..... 00100 0 ..... ..... @rrr_sf | 94 | +LSLV . 00 11010110 ..... 00100 0 ..... ..... @rrr_sf |
95 | +LSRV . 00 11010110 ..... 00100 1 ..... ..... @rrr_sf | 95 | +LSRV . 00 11010110 ..... 00100 1 ..... ..... @rrr_sf |
96 | +ASRV . 00 11010110 ..... 00101 0 ..... ..... @rrr_sf | 96 | +ASRV . 00 11010110 ..... 00101 0 ..... ..... @rrr_sf |
97 | +RORV . 00 11010110 ..... 00101 1 ..... ..... @rrr_sf | 97 | +RORV . 00 11010110 ..... 00101 1 ..... ..... @rrr_sf |
98 | 98 | ||
99 | # Data Processing (1-source) | 99 | # Data Processing (1-source) |
100 | # Logical (shifted reg) | 100 | # Logical (shifted reg) |
101 | -- | 101 | -- |
102 | 2.43.0 | 102 | 2.43.0 |
103 | 103 | ||
104 | 104 | diff view generated by jsdifflib |
1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 101 +++++++++++++-------------------- | 4 | target/arm/tcg/translate-a64.c | 101 +++++++++++++-------------------- |
5 | target/arm/tcg/a64.decode | 12 ++++ | 5 | target/arm/tcg/a64.decode | 12 ++++ |
6 | 2 files changed, 53 insertions(+), 60 deletions(-) | 6 | 2 files changed, 53 insertions(+), 60 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ TRANS(LSRV, do_shift_reg, a, A64_SHIFT_TYPE_LSR) | 12 | @@ -XXX,XX +XXX,XX @@ TRANS(LSRV, do_shift_reg, a, A64_SHIFT_TYPE_LSR) |
13 | TRANS(ASRV, do_shift_reg, a, A64_SHIFT_TYPE_ASR) | 13 | TRANS(ASRV, do_shift_reg, a, A64_SHIFT_TYPE_ASR) |
14 | TRANS(RORV, do_shift_reg, a, A64_SHIFT_TYPE_ROR) | 14 | TRANS(RORV, do_shift_reg, a, A64_SHIFT_TYPE_ROR) |
15 | 15 | ||
16 | +static bool do_crc32(DisasContext *s, arg_rrr_e *a, bool crc32c) | 16 | +static bool do_crc32(DisasContext *s, arg_rrr_e *a, bool crc32c) |
17 | +{ | 17 | +{ |
18 | + TCGv_i64 tcg_acc, tcg_val, tcg_rd; | 18 | + TCGv_i64 tcg_acc, tcg_val, tcg_rd; |
19 | + TCGv_i32 tcg_bytes; | 19 | + TCGv_i32 tcg_bytes; |
20 | + | 20 | + |
21 | + switch (a->esz) { | 21 | + switch (a->esz) { |
22 | + case MO_8: | 22 | + case MO_8: |
23 | + case MO_16: | 23 | + case MO_16: |
24 | + case MO_32: | 24 | + case MO_32: |
25 | + tcg_val = tcg_temp_new_i64(); | 25 | + tcg_val = tcg_temp_new_i64(); |
26 | + tcg_gen_extract_i64(tcg_val, cpu_reg(s, a->rm), 0, 8 << a->esz); | 26 | + tcg_gen_extract_i64(tcg_val, cpu_reg(s, a->rm), 0, 8 << a->esz); |
27 | + break; | 27 | + break; |
28 | + case MO_64: | 28 | + case MO_64: |
29 | + tcg_val = cpu_reg(s, a->rm); | 29 | + tcg_val = cpu_reg(s, a->rm); |
30 | + break; | 30 | + break; |
31 | + default: | 31 | + default: |
32 | + g_assert_not_reached(); | 32 | + g_assert_not_reached(); |
33 | + } | 33 | + } |
34 | + tcg_acc = cpu_reg(s, a->rn); | 34 | + tcg_acc = cpu_reg(s, a->rn); |
35 | + tcg_bytes = tcg_constant_i32(1 << a->esz); | 35 | + tcg_bytes = tcg_constant_i32(1 << a->esz); |
36 | + tcg_rd = cpu_reg(s, a->rd); | 36 | + tcg_rd = cpu_reg(s, a->rd); |
37 | + | 37 | + |
38 | + if (crc32c) { | 38 | + if (crc32c) { |
39 | + gen_helper_crc32c_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes); | 39 | + gen_helper_crc32c_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes); |
40 | + } else { | 40 | + } else { |
41 | + gen_helper_crc32_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes); | 41 | + gen_helper_crc32_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes); |
42 | + } | 42 | + } |
43 | + return true; | 43 | + return true; |
44 | +} | 44 | +} |
45 | + | 45 | + |
46 | +TRANS_FEAT(CRC32, aa64_crc32, do_crc32, a, false) | 46 | +TRANS_FEAT(CRC32, aa64_crc32, do_crc32, a, false) |
47 | +TRANS_FEAT(CRC32C, aa64_crc32, do_crc32, a, true) | 47 | +TRANS_FEAT(CRC32C, aa64_crc32, do_crc32, a, true) |
48 | + | 48 | + |
49 | /* Logical (shifted register) | 49 | /* Logical (shifted register) |
50 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 50 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
51 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 51 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
52 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 52 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
53 | } | 53 | } |
54 | 54 | ||
55 | 55 | ||
56 | -/* CRC32[BHWX], CRC32C[BHWX] */ | 56 | -/* CRC32[BHWX], CRC32C[BHWX] */ |
57 | -static void handle_crc32(DisasContext *s, | 57 | -static void handle_crc32(DisasContext *s, |
58 | - unsigned int sf, unsigned int sz, bool crc32c, | 58 | - unsigned int sf, unsigned int sz, bool crc32c, |
59 | - unsigned int rm, unsigned int rn, unsigned int rd) | 59 | - unsigned int rm, unsigned int rn, unsigned int rd) |
60 | -{ | 60 | -{ |
61 | - TCGv_i64 tcg_acc, tcg_val; | 61 | - TCGv_i64 tcg_acc, tcg_val; |
62 | - TCGv_i32 tcg_bytes; | 62 | - TCGv_i32 tcg_bytes; |
63 | - | 63 | - |
64 | - if (!dc_isar_feature(aa64_crc32, s) | 64 | - if (!dc_isar_feature(aa64_crc32, s) |
65 | - || (sf == 1 && sz != 3) | 65 | - || (sf == 1 && sz != 3) |
66 | - || (sf == 0 && sz == 3)) { | 66 | - || (sf == 0 && sz == 3)) { |
67 | - unallocated_encoding(s); | 67 | - unallocated_encoding(s); |
68 | - return; | 68 | - return; |
69 | - } | 69 | - } |
70 | - | 70 | - |
71 | - if (sz == 3) { | 71 | - if (sz == 3) { |
72 | - tcg_val = cpu_reg(s, rm); | 72 | - tcg_val = cpu_reg(s, rm); |
73 | - } else { | 73 | - } else { |
74 | - uint64_t mask; | 74 | - uint64_t mask; |
75 | - switch (sz) { | 75 | - switch (sz) { |
76 | - case 0: | 76 | - case 0: |
77 | - mask = 0xFF; | 77 | - mask = 0xFF; |
78 | - break; | 78 | - break; |
79 | - case 1: | 79 | - case 1: |
80 | - mask = 0xFFFF; | 80 | - mask = 0xFFFF; |
81 | - break; | 81 | - break; |
82 | - case 2: | 82 | - case 2: |
83 | - mask = 0xFFFFFFFF; | 83 | - mask = 0xFFFFFFFF; |
84 | - break; | 84 | - break; |
85 | - default: | 85 | - default: |
86 | - g_assert_not_reached(); | 86 | - g_assert_not_reached(); |
87 | - } | 87 | - } |
88 | - tcg_val = tcg_temp_new_i64(); | 88 | - tcg_val = tcg_temp_new_i64(); |
89 | - tcg_gen_andi_i64(tcg_val, cpu_reg(s, rm), mask); | 89 | - tcg_gen_andi_i64(tcg_val, cpu_reg(s, rm), mask); |
90 | - } | 90 | - } |
91 | - | 91 | - |
92 | - tcg_acc = cpu_reg(s, rn); | 92 | - tcg_acc = cpu_reg(s, rn); |
93 | - tcg_bytes = tcg_constant_i32(1 << sz); | 93 | - tcg_bytes = tcg_constant_i32(1 << sz); |
94 | - | 94 | - |
95 | - if (crc32c) { | 95 | - if (crc32c) { |
96 | - gen_helper_crc32c_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes); | 96 | - gen_helper_crc32c_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes); |
97 | - } else { | 97 | - } else { |
98 | - gen_helper_crc32_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes); | 98 | - gen_helper_crc32_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes); |
99 | - } | 99 | - } |
100 | -} | 100 | -} |
101 | - | 101 | - |
102 | /* Data-processing (2 source) | 102 | /* Data-processing (2 source) |
103 | * 31 30 29 28 21 20 16 15 10 9 5 4 0 | 103 | * 31 30 29 28 21 20 16 15 10 9 5 4 0 |
104 | * +----+---+---+-----------------+------+--------+------+------+ | 104 | * +----+---+---+-----------------+------+--------+------+------+ |
105 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 105 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
106 | gen_helper_pacga(cpu_reg(s, rd), tcg_env, | 106 | gen_helper_pacga(cpu_reg(s, rd), tcg_env, |
107 | cpu_reg(s, rn), cpu_reg_sp(s, rm)); | 107 | cpu_reg(s, rn), cpu_reg_sp(s, rm)); |
108 | break; | 108 | break; |
109 | - case 16: | 109 | - case 16: |
110 | - case 17: | 110 | - case 17: |
111 | - case 18: | 111 | - case 18: |
112 | - case 19: | 112 | - case 19: |
113 | - case 20: | 113 | - case 20: |
114 | - case 21: | 114 | - case 21: |
115 | - case 22: | 115 | - case 22: |
116 | - case 23: /* CRC32 */ | 116 | - case 23: /* CRC32 */ |
117 | - { | 117 | - { |
118 | - int sz = extract32(opcode, 0, 2); | 118 | - int sz = extract32(opcode, 0, 2); |
119 | - bool crc32c = extract32(opcode, 2, 1); | 119 | - bool crc32c = extract32(opcode, 2, 1); |
120 | - handle_crc32(s, sf, sz, crc32c, rm, rn, rd); | 120 | - handle_crc32(s, sf, sz, crc32c, rm, rn, rd); |
121 | - break; | 121 | - break; |
122 | - } | 122 | - } |
123 | default: | 123 | default: |
124 | do_unallocated: | 124 | do_unallocated: |
125 | case 2: /* UDIV */ | 125 | case 2: /* UDIV */ |
126 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 126 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
127 | case 9: /* LSRV */ | 127 | case 9: /* LSRV */ |
128 | case 10: /* ASRV */ | 128 | case 10: /* ASRV */ |
129 | case 11: /* RORV */ | 129 | case 11: /* RORV */ |
130 | + case 16: | 130 | + case 16: |
131 | + case 17: | 131 | + case 17: |
132 | + case 18: | 132 | + case 18: |
133 | + case 19: | 133 | + case 19: |
134 | + case 20: | 134 | + case 20: |
135 | + case 21: | 135 | + case 21: |
136 | + case 22: | 136 | + case 22: |
137 | + case 23: /* CRC32 */ | 137 | + case 23: /* CRC32 */ |
138 | unallocated_encoding(s); | 138 | unallocated_encoding(s); |
139 | break; | 139 | break; |
140 | } | 140 | } |
141 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 141 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
142 | index XXXXXXX..XXXXXXX 100644 | 142 | index XXXXXXX..XXXXXXX 100644 |
143 | --- a/target/arm/tcg/a64.decode | 143 | --- a/target/arm/tcg/a64.decode |
144 | +++ b/target/arm/tcg/a64.decode | 144 | +++ b/target/arm/tcg/a64.decode |
145 | @@ -XXX,XX +XXX,XX @@ | 145 | @@ -XXX,XX +XXX,XX @@ |
146 | @rr_d ........ ... ..... ...... rn:5 rd:5 &rr_e esz=3 | 146 | @rr_d ........ ... ..... ...... rn:5 rd:5 &rr_e esz=3 |
147 | @rr_sd ........ ... ..... ...... rn:5 rd:5 &rr_e esz=%esz_sd | 147 | @rr_sd ........ ... ..... ...... rn:5 rd:5 &rr_e esz=%esz_sd |
148 | 148 | ||
149 | +@rrr_b ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=0 | 149 | +@rrr_b ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=0 |
150 | @rrr_h ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=1 | 150 | @rrr_h ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=1 |
151 | +@rrr_s ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=2 | 151 | +@rrr_s ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=2 |
152 | @rrr_d ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=3 | 152 | @rrr_d ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=3 |
153 | @rrr_sd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_sd | 153 | @rrr_sd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_sd |
154 | @rrr_hsd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_hsd | 154 | @rrr_hsd ........ ... rm:5 ...... rn:5 rd:5 &rrr_e esz=%esz_hsd |
155 | @@ -XXX,XX +XXX,XX @@ LSRV . 00 11010110 ..... 00100 1 ..... ..... @rrr_sf | 155 | @@ -XXX,XX +XXX,XX @@ LSRV . 00 11010110 ..... 00100 1 ..... ..... @rrr_sf |
156 | ASRV . 00 11010110 ..... 00101 0 ..... ..... @rrr_sf | 156 | ASRV . 00 11010110 ..... 00101 0 ..... ..... @rrr_sf |
157 | RORV . 00 11010110 ..... 00101 1 ..... ..... @rrr_sf | 157 | RORV . 00 11010110 ..... 00101 1 ..... ..... @rrr_sf |
158 | 158 | ||
159 | +CRC32 0 00 11010110 ..... 0100 00 ..... ..... @rrr_b | 159 | +CRC32 0 00 11010110 ..... 0100 00 ..... ..... @rrr_b |
160 | +CRC32 0 00 11010110 ..... 0100 01 ..... ..... @rrr_h | 160 | +CRC32 0 00 11010110 ..... 0100 01 ..... ..... @rrr_h |
161 | +CRC32 0 00 11010110 ..... 0100 10 ..... ..... @rrr_s | 161 | +CRC32 0 00 11010110 ..... 0100 10 ..... ..... @rrr_s |
162 | +CRC32 1 00 11010110 ..... 0100 11 ..... ..... @rrr_d | 162 | +CRC32 1 00 11010110 ..... 0100 11 ..... ..... @rrr_d |
163 | + | 163 | + |
164 | +CRC32C 0 00 11010110 ..... 0101 00 ..... ..... @rrr_b | 164 | +CRC32C 0 00 11010110 ..... 0101 00 ..... ..... @rrr_b |
165 | +CRC32C 0 00 11010110 ..... 0101 01 ..... ..... @rrr_h | 165 | +CRC32C 0 00 11010110 ..... 0101 01 ..... ..... @rrr_h |
166 | +CRC32C 0 00 11010110 ..... 0101 10 ..... ..... @rrr_s | 166 | +CRC32C 0 00 11010110 ..... 0101 10 ..... ..... @rrr_s |
167 | +CRC32C 1 00 11010110 ..... 0101 11 ..... ..... @rrr_d | 167 | +CRC32C 1 00 11010110 ..... 0101 11 ..... ..... @rrr_d |
168 | + | 168 | + |
169 | # Data Processing (1-source) | 169 | # Data Processing (1-source) |
170 | # Logical (shifted reg) | 170 | # Logical (shifted reg) |
171 | # Add/subtract (shifted reg) | 171 | # Add/subtract (shifted reg) |
172 | -- | 172 | -- |
173 | 2.43.0 | 173 | 2.43.0 |
174 | 174 | ||
175 | 175 | diff view generated by jsdifflib |
1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 94 +++++++++++++++++++--------------- | 4 | target/arm/tcg/translate-a64.c | 94 +++++++++++++++++++--------------- |
5 | target/arm/tcg/a64.decode | 7 +++ | 5 | target/arm/tcg/a64.decode | 7 +++ |
6 | 2 files changed, 59 insertions(+), 42 deletions(-) | 6 | 2 files changed, 59 insertions(+), 42 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool do_crc32(DisasContext *s, arg_rrr_e *a, bool crc32c) | 12 | @@ -XXX,XX +XXX,XX @@ static bool do_crc32(DisasContext *s, arg_rrr_e *a, bool crc32c) |
13 | TRANS_FEAT(CRC32, aa64_crc32, do_crc32, a, false) | 13 | TRANS_FEAT(CRC32, aa64_crc32, do_crc32, a, false) |
14 | TRANS_FEAT(CRC32C, aa64_crc32, do_crc32, a, true) | 14 | TRANS_FEAT(CRC32C, aa64_crc32, do_crc32, a, true) |
15 | 15 | ||
16 | +static bool do_subp(DisasContext *s, arg_rrr *a, bool setflag) | 16 | +static bool do_subp(DisasContext *s, arg_rrr *a, bool setflag) |
17 | +{ | 17 | +{ |
18 | + TCGv_i64 tcg_n = read_cpu_reg_sp(s, a->rn, true); | 18 | + TCGv_i64 tcg_n = read_cpu_reg_sp(s, a->rn, true); |
19 | + TCGv_i64 tcg_m = read_cpu_reg_sp(s, a->rm, true); | 19 | + TCGv_i64 tcg_m = read_cpu_reg_sp(s, a->rm, true); |
20 | + TCGv_i64 tcg_d = cpu_reg(s, a->rd); | 20 | + TCGv_i64 tcg_d = cpu_reg(s, a->rd); |
21 | + | 21 | + |
22 | + tcg_gen_sextract_i64(tcg_n, tcg_n, 0, 56); | 22 | + tcg_gen_sextract_i64(tcg_n, tcg_n, 0, 56); |
23 | + tcg_gen_sextract_i64(tcg_m, tcg_m, 0, 56); | 23 | + tcg_gen_sextract_i64(tcg_m, tcg_m, 0, 56); |
24 | + | 24 | + |
25 | + if (setflag) { | 25 | + if (setflag) { |
26 | + gen_sub_CC(true, tcg_d, tcg_n, tcg_m); | 26 | + gen_sub_CC(true, tcg_d, tcg_n, tcg_m); |
27 | + } else { | 27 | + } else { |
28 | + tcg_gen_sub_i64(tcg_d, tcg_n, tcg_m); | 28 | + tcg_gen_sub_i64(tcg_d, tcg_n, tcg_m); |
29 | + } | 29 | + } |
30 | + return true; | 30 | + return true; |
31 | +} | 31 | +} |
32 | + | 32 | + |
33 | +TRANS_FEAT(SUBP, aa64_mte_insn_reg, do_subp, a, false) | 33 | +TRANS_FEAT(SUBP, aa64_mte_insn_reg, do_subp, a, false) |
34 | +TRANS_FEAT(SUBPS, aa64_mte_insn_reg, do_subp, a, true) | 34 | +TRANS_FEAT(SUBPS, aa64_mte_insn_reg, do_subp, a, true) |
35 | + | 35 | + |
36 | +static bool trans_IRG(DisasContext *s, arg_rrr *a) | 36 | +static bool trans_IRG(DisasContext *s, arg_rrr *a) |
37 | +{ | 37 | +{ |
38 | + if (dc_isar_feature(aa64_mte_insn_reg, s)) { | 38 | + if (dc_isar_feature(aa64_mte_insn_reg, s)) { |
39 | + TCGv_i64 tcg_rd = cpu_reg_sp(s, a->rd); | 39 | + TCGv_i64 tcg_rd = cpu_reg_sp(s, a->rd); |
40 | + TCGv_i64 tcg_rn = cpu_reg_sp(s, a->rn); | 40 | + TCGv_i64 tcg_rn = cpu_reg_sp(s, a->rn); |
41 | + | 41 | + |
42 | + if (s->ata[0]) { | 42 | + if (s->ata[0]) { |
43 | + gen_helper_irg(tcg_rd, tcg_env, tcg_rn, cpu_reg(s, a->rm)); | 43 | + gen_helper_irg(tcg_rd, tcg_env, tcg_rn, cpu_reg(s, a->rm)); |
44 | + } else { | 44 | + } else { |
45 | + gen_address_with_allocation_tag0(tcg_rd, tcg_rn); | 45 | + gen_address_with_allocation_tag0(tcg_rd, tcg_rn); |
46 | + } | 46 | + } |
47 | + return true; | 47 | + return true; |
48 | + } | 48 | + } |
49 | + return false; | 49 | + return false; |
50 | +} | 50 | +} |
51 | + | 51 | + |
52 | +static bool trans_GMI(DisasContext *s, arg_rrr *a) | 52 | +static bool trans_GMI(DisasContext *s, arg_rrr *a) |
53 | +{ | 53 | +{ |
54 | + if (dc_isar_feature(aa64_mte_insn_reg, s)) { | 54 | + if (dc_isar_feature(aa64_mte_insn_reg, s)) { |
55 | + TCGv_i64 t = tcg_temp_new_i64(); | 55 | + TCGv_i64 t = tcg_temp_new_i64(); |
56 | + | 56 | + |
57 | + tcg_gen_extract_i64(t, cpu_reg_sp(s, a->rn), 56, 4); | 57 | + tcg_gen_extract_i64(t, cpu_reg_sp(s, a->rn), 56, 4); |
58 | + tcg_gen_shl_i64(t, tcg_constant_i64(1), t); | 58 | + tcg_gen_shl_i64(t, tcg_constant_i64(1), t); |
59 | + tcg_gen_or_i64(cpu_reg(s, a->rd), cpu_reg(s, a->rm), t); | 59 | + tcg_gen_or_i64(cpu_reg(s, a->rd), cpu_reg(s, a->rm), t); |
60 | + return true; | 60 | + return true; |
61 | + } | 61 | + } |
62 | + return false; | 62 | + return false; |
63 | +} | 63 | +} |
64 | + | 64 | + |
65 | /* Logical (shifted register) | 65 | /* Logical (shifted register) |
66 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 66 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
67 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 67 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
68 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 68 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
69 | } | 69 | } |
70 | 70 | ||
71 | switch (opcode) { | 71 | switch (opcode) { |
72 | - case 0: /* SUBP(S) */ | 72 | - case 0: /* SUBP(S) */ |
73 | - if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { | 73 | - if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { |
74 | - goto do_unallocated; | 74 | - goto do_unallocated; |
75 | - } else { | 75 | - } else { |
76 | - TCGv_i64 tcg_n, tcg_m, tcg_d; | 76 | - TCGv_i64 tcg_n, tcg_m, tcg_d; |
77 | - | 77 | - |
78 | - tcg_n = read_cpu_reg_sp(s, rn, true); | 78 | - tcg_n = read_cpu_reg_sp(s, rn, true); |
79 | - tcg_m = read_cpu_reg_sp(s, rm, true); | 79 | - tcg_m = read_cpu_reg_sp(s, rm, true); |
80 | - tcg_gen_sextract_i64(tcg_n, tcg_n, 0, 56); | 80 | - tcg_gen_sextract_i64(tcg_n, tcg_n, 0, 56); |
81 | - tcg_gen_sextract_i64(tcg_m, tcg_m, 0, 56); | 81 | - tcg_gen_sextract_i64(tcg_m, tcg_m, 0, 56); |
82 | - tcg_d = cpu_reg(s, rd); | 82 | - tcg_d = cpu_reg(s, rd); |
83 | - | 83 | - |
84 | - if (setflag) { | 84 | - if (setflag) { |
85 | - gen_sub_CC(true, tcg_d, tcg_n, tcg_m); | 85 | - gen_sub_CC(true, tcg_d, tcg_n, tcg_m); |
86 | - } else { | 86 | - } else { |
87 | - tcg_gen_sub_i64(tcg_d, tcg_n, tcg_m); | 87 | - tcg_gen_sub_i64(tcg_d, tcg_n, tcg_m); |
88 | - } | 88 | - } |
89 | - } | 89 | - } |
90 | - break; | 90 | - break; |
91 | - case 4: /* IRG */ | 91 | - case 4: /* IRG */ |
92 | - if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { | 92 | - if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { |
93 | - goto do_unallocated; | 93 | - goto do_unallocated; |
94 | - } | 94 | - } |
95 | - if (s->ata[0]) { | 95 | - if (s->ata[0]) { |
96 | - gen_helper_irg(cpu_reg_sp(s, rd), tcg_env, | 96 | - gen_helper_irg(cpu_reg_sp(s, rd), tcg_env, |
97 | - cpu_reg_sp(s, rn), cpu_reg(s, rm)); | 97 | - cpu_reg_sp(s, rn), cpu_reg(s, rm)); |
98 | - } else { | 98 | - } else { |
99 | - gen_address_with_allocation_tag0(cpu_reg_sp(s, rd), | 99 | - gen_address_with_allocation_tag0(cpu_reg_sp(s, rd), |
100 | - cpu_reg_sp(s, rn)); | 100 | - cpu_reg_sp(s, rn)); |
101 | - } | 101 | - } |
102 | - break; | 102 | - break; |
103 | - case 5: /* GMI */ | 103 | - case 5: /* GMI */ |
104 | - if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { | 104 | - if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { |
105 | - goto do_unallocated; | 105 | - goto do_unallocated; |
106 | - } else { | 106 | - } else { |
107 | - TCGv_i64 t = tcg_temp_new_i64(); | 107 | - TCGv_i64 t = tcg_temp_new_i64(); |
108 | - | 108 | - |
109 | - tcg_gen_extract_i64(t, cpu_reg_sp(s, rn), 56, 4); | 109 | - tcg_gen_extract_i64(t, cpu_reg_sp(s, rn), 56, 4); |
110 | - tcg_gen_shl_i64(t, tcg_constant_i64(1), t); | 110 | - tcg_gen_shl_i64(t, tcg_constant_i64(1), t); |
111 | - tcg_gen_or_i64(cpu_reg(s, rd), cpu_reg(s, rm), t); | 111 | - tcg_gen_or_i64(cpu_reg(s, rd), cpu_reg(s, rm), t); |
112 | - } | 112 | - } |
113 | - break; | 113 | - break; |
114 | case 12: /* PACGA */ | 114 | case 12: /* PACGA */ |
115 | if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) { | 115 | if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) { |
116 | goto do_unallocated; | 116 | goto do_unallocated; |
117 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 117 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
118 | break; | 118 | break; |
119 | default: | 119 | default: |
120 | do_unallocated: | 120 | do_unallocated: |
121 | + case 0: /* SUBP(S) */ | 121 | + case 0: /* SUBP(S) */ |
122 | case 2: /* UDIV */ | 122 | case 2: /* UDIV */ |
123 | case 3: /* SDIV */ | 123 | case 3: /* SDIV */ |
124 | + case 4: /* IRG */ | 124 | + case 4: /* IRG */ |
125 | + case 5: /* GMI */ | 125 | + case 5: /* GMI */ |
126 | case 8: /* LSLV */ | 126 | case 8: /* LSLV */ |
127 | case 9: /* LSRV */ | 127 | case 9: /* LSRV */ |
128 | case 10: /* ASRV */ | 128 | case 10: /* ASRV */ |
129 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 129 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
130 | index XXXXXXX..XXXXXXX 100644 | 130 | index XXXXXXX..XXXXXXX 100644 |
131 | --- a/target/arm/tcg/a64.decode | 131 | --- a/target/arm/tcg/a64.decode |
132 | +++ b/target/arm/tcg/a64.decode | 132 | +++ b/target/arm/tcg/a64.decode |
133 | @@ -XXX,XX +XXX,XX @@ | 133 | @@ -XXX,XX +XXX,XX @@ |
134 | %hlm 11:1 20:2 | 134 | %hlm 11:1 20:2 |
135 | 135 | ||
136 | &r rn | 136 | &r rn |
137 | +&rrr rd rn rm | 137 | +&rrr rd rn rm |
138 | &ri rd imm | 138 | &ri rd imm |
139 | &rri_sf rd rn imm sf | 139 | &rri_sf rd rn imm sf |
140 | &rrr_sf rd rn rm sf | 140 | &rrr_sf rd rn rm sf |
141 | @@ -XXX,XX +XXX,XX @@ CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy | 141 | @@ -XXX,XX +XXX,XX @@ CPYE 00 011 1 01100 ..... .... 01 ..... ..... @cpy |
142 | 142 | ||
143 | # Data Processing (2-source) | 143 | # Data Processing (2-source) |
144 | 144 | ||
145 | +@rrr . .......... rm:5 ...... rn:5 rd:5 &rrr | 145 | +@rrr . .......... rm:5 ...... rn:5 rd:5 &rrr |
146 | @rrr_sf sf:1 .......... rm:5 ...... rn:5 rd:5 &rrr_sf | 146 | @rrr_sf sf:1 .......... rm:5 ...... rn:5 rd:5 &rrr_sf |
147 | 147 | ||
148 | UDIV . 00 11010110 ..... 00001 0 ..... ..... @rrr_sf | 148 | UDIV . 00 11010110 ..... 00001 0 ..... ..... @rrr_sf |
149 | @@ -XXX,XX +XXX,XX @@ CRC32C 0 00 11010110 ..... 0101 01 ..... ..... @rrr_h | 149 | @@ -XXX,XX +XXX,XX @@ CRC32C 0 00 11010110 ..... 0101 01 ..... ..... @rrr_h |
150 | CRC32C 0 00 11010110 ..... 0101 10 ..... ..... @rrr_s | 150 | CRC32C 0 00 11010110 ..... 0101 10 ..... ..... @rrr_s |
151 | CRC32C 1 00 11010110 ..... 0101 11 ..... ..... @rrr_d | 151 | CRC32C 1 00 11010110 ..... 0101 11 ..... ..... @rrr_d |
152 | 152 | ||
153 | +SUBP 1 00 11010110 ..... 000000 ..... ..... @rrr | 153 | +SUBP 1 00 11010110 ..... 000000 ..... ..... @rrr |
154 | +SUBPS 1 01 11010110 ..... 000000 ..... ..... @rrr | 154 | +SUBPS 1 01 11010110 ..... 000000 ..... ..... @rrr |
155 | +IRG 1 00 11010110 ..... 000100 ..... ..... @rrr | 155 | +IRG 1 00 11010110 ..... 000100 ..... ..... @rrr |
156 | +GMI 1 00 11010110 ..... 000101 ..... ..... @rrr | 156 | +GMI 1 00 11010110 ..... 000101 ..... ..... @rrr |
157 | + | 157 | + |
158 | # Data Processing (1-source) | 158 | # Data Processing (1-source) |
159 | # Logical (shifted reg) | 159 | # Logical (shifted reg) |
160 | # Add/subtract (shifted reg) | 160 | # Add/subtract (shifted reg) |
161 | -- | 161 | -- |
162 | 2.43.0 | 162 | 2.43.0 |
163 | 163 | ||
164 | 164 | diff view generated by jsdifflib |
1 | Remove disas_data_proc_2src, as this was the last insn | 1 | Remove disas_data_proc_2src, as this was the last insn |
---|---|---|---|
2 | decoded by that function. | 2 | decoded by that function. |
3 | 3 | ||
4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 65 ++++++---------------------------- | 7 | target/arm/tcg/translate-a64.c | 65 ++++++---------------------------- |
8 | target/arm/tcg/a64.decode | 2 ++ | 8 | target/arm/tcg/a64.decode | 2 ++ |
9 | 2 files changed, 13 insertions(+), 54 deletions(-) | 9 | 2 files changed, 13 insertions(+), 54 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ static bool trans_GMI(DisasContext *s, arg_rrr *a) | 15 | @@ -XXX,XX +XXX,XX @@ static bool trans_GMI(DisasContext *s, arg_rrr *a) |
16 | return false; | 16 | return false; |
17 | } | 17 | } |
18 | 18 | ||
19 | +static bool trans_PACGA(DisasContext *s, arg_rrr *a) | 19 | +static bool trans_PACGA(DisasContext *s, arg_rrr *a) |
20 | +{ | 20 | +{ |
21 | + if (dc_isar_feature(aa64_pauth, s)) { | 21 | + if (dc_isar_feature(aa64_pauth, s)) { |
22 | + gen_helper_pacga(cpu_reg(s, a->rd), tcg_env, | 22 | + gen_helper_pacga(cpu_reg(s, a->rd), tcg_env, |
23 | + cpu_reg(s, a->rn), cpu_reg_sp(s, a->rm)); | 23 | + cpu_reg(s, a->rn), cpu_reg_sp(s, a->rm)); |
24 | + return true; | 24 | + return true; |
25 | + } | 25 | + } |
26 | + return false; | 26 | + return false; |
27 | +} | 27 | +} |
28 | + | 28 | + |
29 | /* Logical (shifted register) | 29 | /* Logical (shifted register) |
30 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 30 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
31 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 31 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
32 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 32 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
33 | } | 33 | } |
34 | 34 | ||
35 | 35 | ||
36 | -/* Data-processing (2 source) | 36 | -/* Data-processing (2 source) |
37 | - * 31 30 29 28 21 20 16 15 10 9 5 4 0 | 37 | - * 31 30 29 28 21 20 16 15 10 9 5 4 0 |
38 | - * +----+---+---+-----------------+------+--------+------+------+ | 38 | - * +----+---+---+-----------------+------+--------+------+------+ |
39 | - * | sf | 0 | S | 1 1 0 1 0 1 1 0 | Rm | opcode | Rn | Rd | | 39 | - * | sf | 0 | S | 1 1 0 1 0 1 1 0 | Rm | opcode | Rn | Rd | |
40 | - * +----+---+---+-----------------+------+--------+------+------+ | 40 | - * +----+---+---+-----------------+------+--------+------+------+ |
41 | - */ | 41 | - */ |
42 | -static void disas_data_proc_2src(DisasContext *s, uint32_t insn) | 42 | -static void disas_data_proc_2src(DisasContext *s, uint32_t insn) |
43 | -{ | 43 | -{ |
44 | - unsigned int sf, rm, opcode, rn, rd, setflag; | 44 | - unsigned int sf, rm, opcode, rn, rd, setflag; |
45 | - sf = extract32(insn, 31, 1); | 45 | - sf = extract32(insn, 31, 1); |
46 | - setflag = extract32(insn, 29, 1); | 46 | - setflag = extract32(insn, 29, 1); |
47 | - rm = extract32(insn, 16, 5); | 47 | - rm = extract32(insn, 16, 5); |
48 | - opcode = extract32(insn, 10, 6); | 48 | - opcode = extract32(insn, 10, 6); |
49 | - rn = extract32(insn, 5, 5); | 49 | - rn = extract32(insn, 5, 5); |
50 | - rd = extract32(insn, 0, 5); | 50 | - rd = extract32(insn, 0, 5); |
51 | - | 51 | - |
52 | - if (setflag && opcode != 0) { | 52 | - if (setflag && opcode != 0) { |
53 | - unallocated_encoding(s); | 53 | - unallocated_encoding(s); |
54 | - return; | 54 | - return; |
55 | - } | 55 | - } |
56 | - | 56 | - |
57 | - switch (opcode) { | 57 | - switch (opcode) { |
58 | - case 12: /* PACGA */ | 58 | - case 12: /* PACGA */ |
59 | - if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) { | 59 | - if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) { |
60 | - goto do_unallocated; | 60 | - goto do_unallocated; |
61 | - } | 61 | - } |
62 | - gen_helper_pacga(cpu_reg(s, rd), tcg_env, | 62 | - gen_helper_pacga(cpu_reg(s, rd), tcg_env, |
63 | - cpu_reg(s, rn), cpu_reg_sp(s, rm)); | 63 | - cpu_reg(s, rn), cpu_reg_sp(s, rm)); |
64 | - break; | 64 | - break; |
65 | - default: | 65 | - default: |
66 | - do_unallocated: | 66 | - do_unallocated: |
67 | - case 0: /* SUBP(S) */ | 67 | - case 0: /* SUBP(S) */ |
68 | - case 2: /* UDIV */ | 68 | - case 2: /* UDIV */ |
69 | - case 3: /* SDIV */ | 69 | - case 3: /* SDIV */ |
70 | - case 4: /* IRG */ | 70 | - case 4: /* IRG */ |
71 | - case 5: /* GMI */ | 71 | - case 5: /* GMI */ |
72 | - case 8: /* LSLV */ | 72 | - case 8: /* LSLV */ |
73 | - case 9: /* LSRV */ | 73 | - case 9: /* LSRV */ |
74 | - case 10: /* ASRV */ | 74 | - case 10: /* ASRV */ |
75 | - case 11: /* RORV */ | 75 | - case 11: /* RORV */ |
76 | - case 16: | 76 | - case 16: |
77 | - case 17: | 77 | - case 17: |
78 | - case 18: | 78 | - case 18: |
79 | - case 19: | 79 | - case 19: |
80 | - case 20: | 80 | - case 20: |
81 | - case 21: | 81 | - case 21: |
82 | - case 22: | 82 | - case 22: |
83 | - case 23: /* CRC32 */ | 83 | - case 23: /* CRC32 */ |
84 | - unallocated_encoding(s); | 84 | - unallocated_encoding(s); |
85 | - break; | 85 | - break; |
86 | - } | 86 | - } |
87 | -} | 87 | -} |
88 | - | 88 | - |
89 | /* | 89 | /* |
90 | * Data processing - register | 90 | * Data processing - register |
91 | * 31 30 29 28 25 21 20 16 10 0 | 91 | * 31 30 29 28 25 21 20 16 10 0 |
92 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 92 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
93 | if (op0) { /* (1 source) */ | 93 | if (op0) { /* (1 source) */ |
94 | disas_data_proc_1src(s, insn); | 94 | disas_data_proc_1src(s, insn); |
95 | } else { /* (2 source) */ | 95 | } else { /* (2 source) */ |
96 | - disas_data_proc_2src(s, insn); | 96 | - disas_data_proc_2src(s, insn); |
97 | + goto do_unallocated; | 97 | + goto do_unallocated; |
98 | } | 98 | } |
99 | break; | 99 | break; |
100 | case 0x8 ... 0xf: /* (3 source) */ | 100 | case 0x8 ... 0xf: /* (3 source) */ |
101 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 101 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
102 | index XXXXXXX..XXXXXXX 100644 | 102 | index XXXXXXX..XXXXXXX 100644 |
103 | --- a/target/arm/tcg/a64.decode | 103 | --- a/target/arm/tcg/a64.decode |
104 | +++ b/target/arm/tcg/a64.decode | 104 | +++ b/target/arm/tcg/a64.decode |
105 | @@ -XXX,XX +XXX,XX @@ SUBPS 1 01 11010110 ..... 000000 ..... ..... @rrr | 105 | @@ -XXX,XX +XXX,XX @@ SUBPS 1 01 11010110 ..... 000000 ..... ..... @rrr |
106 | IRG 1 00 11010110 ..... 000100 ..... ..... @rrr | 106 | IRG 1 00 11010110 ..... 000100 ..... ..... @rrr |
107 | GMI 1 00 11010110 ..... 000101 ..... ..... @rrr | 107 | GMI 1 00 11010110 ..... 000101 ..... ..... @rrr |
108 | 108 | ||
109 | +PACGA 1 00 11010110 ..... 001100 ..... ..... @rrr | 109 | +PACGA 1 00 11010110 ..... 001100 ..... ..... @rrr |
110 | + | 110 | + |
111 | # Data Processing (1-source) | 111 | # Data Processing (1-source) |
112 | # Logical (shifted reg) | 112 | # Logical (shifted reg) |
113 | # Add/subtract (shifted reg) | 113 | # Add/subtract (shifted reg) |
114 | -- | 114 | -- |
115 | 2.43.0 | 115 | 2.43.0 |
116 | 116 | ||
117 | 117 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 137 +++++++++++++++------------------ | 4 | target/arm/tcg/translate-a64.c | 137 +++++++++++++++------------------ |
5 | target/arm/tcg/a64.decode | 11 +++ | 5 | target/arm/tcg/a64.decode | 11 +++ |
6 | 2 files changed, 72 insertions(+), 76 deletions(-) | 6 | 2 files changed, 72 insertions(+), 76 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool trans_PACGA(DisasContext *s, arg_rrr *a) | 12 | @@ -XXX,XX +XXX,XX @@ static bool trans_PACGA(DisasContext *s, arg_rrr *a) |
13 | return false; | 13 | return false; |
14 | } | 14 | } |
15 | 15 | ||
16 | +typedef void ArithOneOp(TCGv_i64, TCGv_i64); | 16 | +typedef void ArithOneOp(TCGv_i64, TCGv_i64); |
17 | + | 17 | + |
18 | +static bool gen_rr(DisasContext *s, int rd, int rn, ArithOneOp fn) | 18 | +static bool gen_rr(DisasContext *s, int rd, int rn, ArithOneOp fn) |
19 | +{ | 19 | +{ |
20 | + fn(cpu_reg(s, rd), cpu_reg(s, rn)); | 20 | + fn(cpu_reg(s, rd), cpu_reg(s, rn)); |
21 | + return true; | 21 | + return true; |
22 | +} | 22 | +} |
23 | + | 23 | + |
24 | +static void gen_rbit32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 24 | +static void gen_rbit32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
25 | +{ | 25 | +{ |
26 | + TCGv_i32 t32 = tcg_temp_new_i32(); | 26 | + TCGv_i32 t32 = tcg_temp_new_i32(); |
27 | + | 27 | + |
28 | + tcg_gen_extrl_i64_i32(t32, tcg_rn); | 28 | + tcg_gen_extrl_i64_i32(t32, tcg_rn); |
29 | + gen_helper_rbit(t32, t32); | 29 | + gen_helper_rbit(t32, t32); |
30 | + tcg_gen_extu_i32_i64(tcg_rd, t32); | 30 | + tcg_gen_extu_i32_i64(tcg_rd, t32); |
31 | +} | 31 | +} |
32 | + | 32 | + |
33 | +static void gen_rev16_xx(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 mask) | 33 | +static void gen_rev16_xx(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 mask) |
34 | +{ | 34 | +{ |
35 | + TCGv_i64 tcg_tmp = tcg_temp_new_i64(); | 35 | + TCGv_i64 tcg_tmp = tcg_temp_new_i64(); |
36 | + | 36 | + |
37 | + tcg_gen_shri_i64(tcg_tmp, tcg_rn, 8); | 37 | + tcg_gen_shri_i64(tcg_tmp, tcg_rn, 8); |
38 | + tcg_gen_and_i64(tcg_rd, tcg_rn, mask); | 38 | + tcg_gen_and_i64(tcg_rd, tcg_rn, mask); |
39 | + tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); | 39 | + tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); |
40 | + tcg_gen_shli_i64(tcg_rd, tcg_rd, 8); | 40 | + tcg_gen_shli_i64(tcg_rd, tcg_rd, 8); |
41 | + tcg_gen_or_i64(tcg_rd, tcg_rd, tcg_tmp); | 41 | + tcg_gen_or_i64(tcg_rd, tcg_rd, tcg_tmp); |
42 | +} | 42 | +} |
43 | + | 43 | + |
44 | +static void gen_rev16_32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 44 | +static void gen_rev16_32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
45 | +{ | 45 | +{ |
46 | + gen_rev16_xx(tcg_rd, tcg_rn, tcg_constant_i64(0x00ff00ff)); | 46 | + gen_rev16_xx(tcg_rd, tcg_rn, tcg_constant_i64(0x00ff00ff)); |
47 | +} | 47 | +} |
48 | + | 48 | + |
49 | +static void gen_rev16_64(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 49 | +static void gen_rev16_64(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
50 | +{ | 50 | +{ |
51 | + gen_rev16_xx(tcg_rd, tcg_rn, tcg_constant_i64(0x00ff00ff00ff00ffull)); | 51 | + gen_rev16_xx(tcg_rd, tcg_rn, tcg_constant_i64(0x00ff00ff00ff00ffull)); |
52 | +} | 52 | +} |
53 | + | 53 | + |
54 | +static void gen_rev_32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 54 | +static void gen_rev_32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
55 | +{ | 55 | +{ |
56 | + tcg_gen_bswap32_i64(tcg_rd, tcg_rn, TCG_BSWAP_OZ); | 56 | + tcg_gen_bswap32_i64(tcg_rd, tcg_rn, TCG_BSWAP_OZ); |
57 | +} | 57 | +} |
58 | + | 58 | + |
59 | +static void gen_rev32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 59 | +static void gen_rev32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
60 | +{ | 60 | +{ |
61 | + tcg_gen_bswap64_i64(tcg_rd, tcg_rn); | 61 | + tcg_gen_bswap64_i64(tcg_rd, tcg_rn); |
62 | + tcg_gen_rotri_i64(tcg_rd, tcg_rd, 32); | 62 | + tcg_gen_rotri_i64(tcg_rd, tcg_rd, 32); |
63 | +} | 63 | +} |
64 | + | 64 | + |
65 | +TRANS(RBIT, gen_rr, a->rd, a->rn, a->sf ? gen_helper_rbit64 : gen_rbit32) | 65 | +TRANS(RBIT, gen_rr, a->rd, a->rn, a->sf ? gen_helper_rbit64 : gen_rbit32) |
66 | +TRANS(REV16, gen_rr, a->rd, a->rn, a->sf ? gen_rev16_64 : gen_rev16_32) | 66 | +TRANS(REV16, gen_rr, a->rd, a->rn, a->sf ? gen_rev16_64 : gen_rev16_32) |
67 | +TRANS(REV32, gen_rr, a->rd, a->rn, a->sf ? gen_rev32 : gen_rev_32) | 67 | +TRANS(REV32, gen_rr, a->rd, a->rn, a->sf ? gen_rev32 : gen_rev_32) |
68 | +TRANS(REV64, gen_rr, a->rd, a->rn, tcg_gen_bswap64_i64) | 68 | +TRANS(REV64, gen_rr, a->rd, a->rn, tcg_gen_bswap64_i64) |
69 | + | 69 | + |
70 | /* Logical (shifted register) | 70 | /* Logical (shifted register) |
71 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 71 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
72 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 72 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
73 | @@ -XXX,XX +XXX,XX @@ static void handle_cls(DisasContext *s, unsigned int sf, | 73 | @@ -XXX,XX +XXX,XX @@ static void handle_cls(DisasContext *s, unsigned int sf, |
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | -static void handle_rbit(DisasContext *s, unsigned int sf, | 77 | -static void handle_rbit(DisasContext *s, unsigned int sf, |
78 | - unsigned int rn, unsigned int rd) | 78 | - unsigned int rn, unsigned int rd) |
79 | -{ | 79 | -{ |
80 | - TCGv_i64 tcg_rd, tcg_rn; | 80 | - TCGv_i64 tcg_rd, tcg_rn; |
81 | - tcg_rd = cpu_reg(s, rd); | 81 | - tcg_rd = cpu_reg(s, rd); |
82 | - tcg_rn = cpu_reg(s, rn); | 82 | - tcg_rn = cpu_reg(s, rn); |
83 | - | 83 | - |
84 | - if (sf) { | 84 | - if (sf) { |
85 | - gen_helper_rbit64(tcg_rd, tcg_rn); | 85 | - gen_helper_rbit64(tcg_rd, tcg_rn); |
86 | - } else { | 86 | - } else { |
87 | - TCGv_i32 tcg_tmp32 = tcg_temp_new_i32(); | 87 | - TCGv_i32 tcg_tmp32 = tcg_temp_new_i32(); |
88 | - tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn); | 88 | - tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn); |
89 | - gen_helper_rbit(tcg_tmp32, tcg_tmp32); | 89 | - gen_helper_rbit(tcg_tmp32, tcg_tmp32); |
90 | - tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32); | 90 | - tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32); |
91 | - } | 91 | - } |
92 | -} | 92 | -} |
93 | - | 93 | - |
94 | -/* REV with sf==1, opcode==3 ("REV64") */ | 94 | -/* REV with sf==1, opcode==3 ("REV64") */ |
95 | -static void handle_rev64(DisasContext *s, unsigned int sf, | 95 | -static void handle_rev64(DisasContext *s, unsigned int sf, |
96 | - unsigned int rn, unsigned int rd) | 96 | - unsigned int rn, unsigned int rd) |
97 | -{ | 97 | -{ |
98 | - if (!sf) { | 98 | - if (!sf) { |
99 | - unallocated_encoding(s); | 99 | - unallocated_encoding(s); |
100 | - return; | 100 | - return; |
101 | - } | 101 | - } |
102 | - tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn)); | 102 | - tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn)); |
103 | -} | 103 | -} |
104 | - | 104 | - |
105 | -/* REV with sf==0, opcode==2 | 105 | -/* REV with sf==0, opcode==2 |
106 | - * REV32 (sf==1, opcode==2) | 106 | - * REV32 (sf==1, opcode==2) |
107 | - */ | 107 | - */ |
108 | -static void handle_rev32(DisasContext *s, unsigned int sf, | 108 | -static void handle_rev32(DisasContext *s, unsigned int sf, |
109 | - unsigned int rn, unsigned int rd) | 109 | - unsigned int rn, unsigned int rd) |
110 | -{ | 110 | -{ |
111 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); | 111 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); |
112 | - TCGv_i64 tcg_rn = cpu_reg(s, rn); | 112 | - TCGv_i64 tcg_rn = cpu_reg(s, rn); |
113 | - | 113 | - |
114 | - if (sf) { | 114 | - if (sf) { |
115 | - tcg_gen_bswap64_i64(tcg_rd, tcg_rn); | 115 | - tcg_gen_bswap64_i64(tcg_rd, tcg_rn); |
116 | - tcg_gen_rotri_i64(tcg_rd, tcg_rd, 32); | 116 | - tcg_gen_rotri_i64(tcg_rd, tcg_rd, 32); |
117 | - } else { | 117 | - } else { |
118 | - tcg_gen_bswap32_i64(tcg_rd, tcg_rn, TCG_BSWAP_OZ); | 118 | - tcg_gen_bswap32_i64(tcg_rd, tcg_rn, TCG_BSWAP_OZ); |
119 | - } | 119 | - } |
120 | -} | 120 | -} |
121 | - | 121 | - |
122 | -/* REV16 (opcode==1) */ | 122 | -/* REV16 (opcode==1) */ |
123 | -static void handle_rev16(DisasContext *s, unsigned int sf, | 123 | -static void handle_rev16(DisasContext *s, unsigned int sf, |
124 | - unsigned int rn, unsigned int rd) | 124 | - unsigned int rn, unsigned int rd) |
125 | -{ | 125 | -{ |
126 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); | 126 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); |
127 | - TCGv_i64 tcg_tmp = tcg_temp_new_i64(); | 127 | - TCGv_i64 tcg_tmp = tcg_temp_new_i64(); |
128 | - TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf); | 128 | - TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf); |
129 | - TCGv_i64 mask = tcg_constant_i64(sf ? 0x00ff00ff00ff00ffull : 0x00ff00ff); | 129 | - TCGv_i64 mask = tcg_constant_i64(sf ? 0x00ff00ff00ff00ffull : 0x00ff00ff); |
130 | - | 130 | - |
131 | - tcg_gen_shri_i64(tcg_tmp, tcg_rn, 8); | 131 | - tcg_gen_shri_i64(tcg_tmp, tcg_rn, 8); |
132 | - tcg_gen_and_i64(tcg_rd, tcg_rn, mask); | 132 | - tcg_gen_and_i64(tcg_rd, tcg_rn, mask); |
133 | - tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); | 133 | - tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); |
134 | - tcg_gen_shli_i64(tcg_rd, tcg_rd, 8); | 134 | - tcg_gen_shli_i64(tcg_rd, tcg_rd, 8); |
135 | - tcg_gen_or_i64(tcg_rd, tcg_rd, tcg_tmp); | 135 | - tcg_gen_or_i64(tcg_rd, tcg_rd, tcg_tmp); |
136 | -} | 136 | -} |
137 | - | 137 | - |
138 | /* Data-processing (1 source) | 138 | /* Data-processing (1 source) |
139 | * 31 30 29 28 21 20 16 15 10 9 5 4 0 | 139 | * 31 30 29 28 21 20 16 15 10 9 5 4 0 |
140 | * +----+---+---+-----------------+---------+--------+------+------+ | 140 | * +----+---+---+-----------------+---------+--------+------+------+ |
141 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 141 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
142 | #define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) | 142 | #define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) |
143 | 143 | ||
144 | switch (MAP(sf, opcode2, opcode)) { | 144 | switch (MAP(sf, opcode2, opcode)) { |
145 | - case MAP(0, 0x00, 0x00): /* RBIT */ | 145 | - case MAP(0, 0x00, 0x00): /* RBIT */ |
146 | - case MAP(1, 0x00, 0x00): | 146 | - case MAP(1, 0x00, 0x00): |
147 | - handle_rbit(s, sf, rn, rd); | 147 | - handle_rbit(s, sf, rn, rd); |
148 | - break; | 148 | - break; |
149 | - case MAP(0, 0x00, 0x01): /* REV16 */ | 149 | - case MAP(0, 0x00, 0x01): /* REV16 */ |
150 | - case MAP(1, 0x00, 0x01): | 150 | - case MAP(1, 0x00, 0x01): |
151 | - handle_rev16(s, sf, rn, rd); | 151 | - handle_rev16(s, sf, rn, rd); |
152 | - break; | 152 | - break; |
153 | - case MAP(0, 0x00, 0x02): /* REV/REV32 */ | 153 | - case MAP(0, 0x00, 0x02): /* REV/REV32 */ |
154 | - case MAP(1, 0x00, 0x02): | 154 | - case MAP(1, 0x00, 0x02): |
155 | - handle_rev32(s, sf, rn, rd); | 155 | - handle_rev32(s, sf, rn, rd); |
156 | - break; | 156 | - break; |
157 | - case MAP(1, 0x00, 0x03): /* REV64 */ | 157 | - case MAP(1, 0x00, 0x03): /* REV64 */ |
158 | - handle_rev64(s, sf, rn, rd); | 158 | - handle_rev64(s, sf, rn, rd); |
159 | - break; | 159 | - break; |
160 | case MAP(0, 0x00, 0x04): /* CLZ */ | 160 | case MAP(0, 0x00, 0x04): /* CLZ */ |
161 | case MAP(1, 0x00, 0x04): | 161 | case MAP(1, 0x00, 0x04): |
162 | handle_clz(s, sf, rn, rd); | 162 | handle_clz(s, sf, rn, rd); |
163 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 163 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
164 | break; | 164 | break; |
165 | default: | 165 | default: |
166 | do_unallocated: | 166 | do_unallocated: |
167 | + case MAP(0, 0x00, 0x00): /* RBIT */ | 167 | + case MAP(0, 0x00, 0x00): /* RBIT */ |
168 | + case MAP(1, 0x00, 0x00): | 168 | + case MAP(1, 0x00, 0x00): |
169 | + case MAP(0, 0x00, 0x01): /* REV16 */ | 169 | + case MAP(0, 0x00, 0x01): /* REV16 */ |
170 | + case MAP(1, 0x00, 0x01): | 170 | + case MAP(1, 0x00, 0x01): |
171 | + case MAP(0, 0x00, 0x02): /* REV/REV32 */ | 171 | + case MAP(0, 0x00, 0x02): /* REV/REV32 */ |
172 | + case MAP(1, 0x00, 0x02): | 172 | + case MAP(1, 0x00, 0x02): |
173 | + case MAP(1, 0x00, 0x03): /* REV64 */ | 173 | + case MAP(1, 0x00, 0x03): /* REV64 */ |
174 | unallocated_encoding(s); | 174 | unallocated_encoding(s); |
175 | break; | 175 | break; |
176 | } | 176 | } |
177 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 177 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
178 | index XXXXXXX..XXXXXXX 100644 | 178 | index XXXXXXX..XXXXXXX 100644 |
179 | --- a/target/arm/tcg/a64.decode | 179 | --- a/target/arm/tcg/a64.decode |
180 | +++ b/target/arm/tcg/a64.decode | 180 | +++ b/target/arm/tcg/a64.decode |
181 | @@ -XXX,XX +XXX,XX @@ | 181 | @@ -XXX,XX +XXX,XX @@ |
182 | &r rn | 182 | &r rn |
183 | &rrr rd rn rm | 183 | &rrr rd rn rm |
184 | &ri rd imm | 184 | &ri rd imm |
185 | +&rr rd rn | 185 | +&rr rd rn |
186 | +&rr_sf rd rn sf | 186 | +&rr_sf rd rn sf |
187 | &rri_sf rd rn imm sf | 187 | &rri_sf rd rn imm sf |
188 | &rrr_sf rd rn rm sf | 188 | &rrr_sf rd rn rm sf |
189 | &i imm | 189 | &i imm |
190 | @@ -XXX,XX +XXX,XX @@ GMI 1 00 11010110 ..... 000101 ..... ..... @rrr | 190 | @@ -XXX,XX +XXX,XX @@ GMI 1 00 11010110 ..... 000101 ..... ..... @rrr |
191 | PACGA 1 00 11010110 ..... 001100 ..... ..... @rrr | 191 | PACGA 1 00 11010110 ..... 001100 ..... ..... @rrr |
192 | 192 | ||
193 | # Data Processing (1-source) | 193 | # Data Processing (1-source) |
194 | + | 194 | + |
195 | +@rr . .......... ..... ...... rn:5 rd:5 &rr | 195 | +@rr . .......... ..... ...... rn:5 rd:5 &rr |
196 | +@rr_sf sf:1 .......... ..... ...... rn:5 rd:5 &rr_sf | 196 | +@rr_sf sf:1 .......... ..... ...... rn:5 rd:5 &rr_sf |
197 | + | 197 | + |
198 | +RBIT . 10 11010110 00000 000000 ..... ..... @rr_sf | 198 | +RBIT . 10 11010110 00000 000000 ..... ..... @rr_sf |
199 | +REV16 . 10 11010110 00000 000001 ..... ..... @rr_sf | 199 | +REV16 . 10 11010110 00000 000001 ..... ..... @rr_sf |
200 | +REV32 . 10 11010110 00000 000010 ..... ..... @rr_sf | 200 | +REV32 . 10 11010110 00000 000010 ..... ..... @rr_sf |
201 | +REV64 1 10 11010110 00000 000011 ..... ..... @rr | 201 | +REV64 1 10 11010110 00000 000011 ..... ..... @rr |
202 | + | 202 | + |
203 | # Logical (shifted reg) | 203 | # Logical (shifted reg) |
204 | # Add/subtract (shifted reg) | 204 | # Add/subtract (shifted reg) |
205 | # Add/subtract (extended reg) | 205 | # Add/subtract (extended reg) |
206 | -- | 206 | -- |
207 | 2.43.0 | 207 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 72 ++++++++++++++-------------------- | 4 | target/arm/tcg/translate-a64.c | 72 ++++++++++++++-------------------- |
5 | target/arm/tcg/a64.decode | 3 ++ | 5 | target/arm/tcg/a64.decode | 3 ++ |
6 | 2 files changed, 33 insertions(+), 42 deletions(-) | 6 | 2 files changed, 33 insertions(+), 42 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ TRANS(REV16, gen_rr, a->rd, a->rn, a->sf ? gen_rev16_64 : gen_rev16_32) | 12 | @@ -XXX,XX +XXX,XX @@ TRANS(REV16, gen_rr, a->rd, a->rn, a->sf ? gen_rev16_64 : gen_rev16_32) |
13 | TRANS(REV32, gen_rr, a->rd, a->rn, a->sf ? gen_rev32 : gen_rev_32) | 13 | TRANS(REV32, gen_rr, a->rd, a->rn, a->sf ? gen_rev32 : gen_rev_32) |
14 | TRANS(REV64, gen_rr, a->rd, a->rn, tcg_gen_bswap64_i64) | 14 | TRANS(REV64, gen_rr, a->rd, a->rn, tcg_gen_bswap64_i64) |
15 | 15 | ||
16 | +static void gen_clz32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 16 | +static void gen_clz32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
17 | +{ | 17 | +{ |
18 | + TCGv_i32 t32 = tcg_temp_new_i32(); | 18 | + TCGv_i32 t32 = tcg_temp_new_i32(); |
19 | + | 19 | + |
20 | + tcg_gen_extrl_i64_i32(t32, tcg_rn); | 20 | + tcg_gen_extrl_i64_i32(t32, tcg_rn); |
21 | + tcg_gen_clzi_i32(t32, t32, 32); | 21 | + tcg_gen_clzi_i32(t32, t32, 32); |
22 | + tcg_gen_extu_i32_i64(tcg_rd, t32); | 22 | + tcg_gen_extu_i32_i64(tcg_rd, t32); |
23 | +} | 23 | +} |
24 | + | 24 | + |
25 | +static void gen_clz64(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 25 | +static void gen_clz64(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
26 | +{ | 26 | +{ |
27 | + tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64); | 27 | + tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64); |
28 | +} | 28 | +} |
29 | + | 29 | + |
30 | +static void gen_cls32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 30 | +static void gen_cls32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
31 | +{ | 31 | +{ |
32 | + TCGv_i32 t32 = tcg_temp_new_i32(); | 32 | + TCGv_i32 t32 = tcg_temp_new_i32(); |
33 | + | 33 | + |
34 | + tcg_gen_extrl_i64_i32(t32, tcg_rn); | 34 | + tcg_gen_extrl_i64_i32(t32, tcg_rn); |
35 | + tcg_gen_clrsb_i32(t32, t32); | 35 | + tcg_gen_clrsb_i32(t32, t32); |
36 | + tcg_gen_extu_i32_i64(tcg_rd, t32); | 36 | + tcg_gen_extu_i32_i64(tcg_rd, t32); |
37 | +} | 37 | +} |
38 | + | 38 | + |
39 | +TRANS(CLZ, gen_rr, a->rd, a->rn, a->sf ? gen_clz64 : gen_clz32) | 39 | +TRANS(CLZ, gen_rr, a->rd, a->rn, a->sf ? gen_clz64 : gen_clz32) |
40 | +TRANS(CLS, gen_rr, a->rd, a->rn, a->sf ? tcg_gen_clrsb_i64 : gen_cls32) | 40 | +TRANS(CLS, gen_rr, a->rd, a->rn, a->sf ? tcg_gen_clrsb_i64 : gen_cls32) |
41 | + | 41 | + |
42 | /* Logical (shifted register) | 42 | /* Logical (shifted register) |
43 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 43 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
44 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 44 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
45 | @@ -XXX,XX +XXX,XX @@ static void disas_cond_select(DisasContext *s, uint32_t insn) | 45 | @@ -XXX,XX +XXX,XX @@ static void disas_cond_select(DisasContext *s, uint32_t insn) |
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | -static void handle_clz(DisasContext *s, unsigned int sf, | 49 | -static void handle_clz(DisasContext *s, unsigned int sf, |
50 | - unsigned int rn, unsigned int rd) | 50 | - unsigned int rn, unsigned int rd) |
51 | -{ | 51 | -{ |
52 | - TCGv_i64 tcg_rd, tcg_rn; | 52 | - TCGv_i64 tcg_rd, tcg_rn; |
53 | - tcg_rd = cpu_reg(s, rd); | 53 | - tcg_rd = cpu_reg(s, rd); |
54 | - tcg_rn = cpu_reg(s, rn); | 54 | - tcg_rn = cpu_reg(s, rn); |
55 | - | 55 | - |
56 | - if (sf) { | 56 | - if (sf) { |
57 | - tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64); | 57 | - tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64); |
58 | - } else { | 58 | - } else { |
59 | - TCGv_i32 tcg_tmp32 = tcg_temp_new_i32(); | 59 | - TCGv_i32 tcg_tmp32 = tcg_temp_new_i32(); |
60 | - tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn); | 60 | - tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn); |
61 | - tcg_gen_clzi_i32(tcg_tmp32, tcg_tmp32, 32); | 61 | - tcg_gen_clzi_i32(tcg_tmp32, tcg_tmp32, 32); |
62 | - tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32); | 62 | - tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32); |
63 | - } | 63 | - } |
64 | -} | 64 | -} |
65 | - | 65 | - |
66 | -static void handle_cls(DisasContext *s, unsigned int sf, | 66 | -static void handle_cls(DisasContext *s, unsigned int sf, |
67 | - unsigned int rn, unsigned int rd) | 67 | - unsigned int rn, unsigned int rd) |
68 | -{ | 68 | -{ |
69 | - TCGv_i64 tcg_rd, tcg_rn; | 69 | - TCGv_i64 tcg_rd, tcg_rn; |
70 | - tcg_rd = cpu_reg(s, rd); | 70 | - tcg_rd = cpu_reg(s, rd); |
71 | - tcg_rn = cpu_reg(s, rn); | 71 | - tcg_rn = cpu_reg(s, rn); |
72 | - | 72 | - |
73 | - if (sf) { | 73 | - if (sf) { |
74 | - tcg_gen_clrsb_i64(tcg_rd, tcg_rn); | 74 | - tcg_gen_clrsb_i64(tcg_rd, tcg_rn); |
75 | - } else { | 75 | - } else { |
76 | - TCGv_i32 tcg_tmp32 = tcg_temp_new_i32(); | 76 | - TCGv_i32 tcg_tmp32 = tcg_temp_new_i32(); |
77 | - tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn); | 77 | - tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn); |
78 | - tcg_gen_clrsb_i32(tcg_tmp32, tcg_tmp32); | 78 | - tcg_gen_clrsb_i32(tcg_tmp32, tcg_tmp32); |
79 | - tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32); | 79 | - tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32); |
80 | - } | 80 | - } |
81 | -} | 81 | -} |
82 | - | 82 | - |
83 | /* Data-processing (1 source) | 83 | /* Data-processing (1 source) |
84 | * 31 30 29 28 21 20 16 15 10 9 5 4 0 | 84 | * 31 30 29 28 21 20 16 15 10 9 5 4 0 |
85 | * +----+---+---+-----------------+---------+--------+------+------+ | 85 | * +----+---+---+-----------------+---------+--------+------+------+ |
86 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 86 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
87 | #define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) | 87 | #define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) |
88 | 88 | ||
89 | switch (MAP(sf, opcode2, opcode)) { | 89 | switch (MAP(sf, opcode2, opcode)) { |
90 | - case MAP(0, 0x00, 0x04): /* CLZ */ | 90 | - case MAP(0, 0x00, 0x04): /* CLZ */ |
91 | - case MAP(1, 0x00, 0x04): | 91 | - case MAP(1, 0x00, 0x04): |
92 | - handle_clz(s, sf, rn, rd); | 92 | - handle_clz(s, sf, rn, rd); |
93 | - break; | 93 | - break; |
94 | - case MAP(0, 0x00, 0x05): /* CLS */ | 94 | - case MAP(0, 0x00, 0x05): /* CLS */ |
95 | - case MAP(1, 0x00, 0x05): | 95 | - case MAP(1, 0x00, 0x05): |
96 | - handle_cls(s, sf, rn, rd); | 96 | - handle_cls(s, sf, rn, rd); |
97 | - break; | 97 | - break; |
98 | case MAP(1, 0x01, 0x00): /* PACIA */ | 98 | case MAP(1, 0x01, 0x00): /* PACIA */ |
99 | if (s->pauth_active) { | 99 | if (s->pauth_active) { |
100 | tcg_rd = cpu_reg(s, rd); | 100 | tcg_rd = cpu_reg(s, rd); |
101 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 101 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
102 | case MAP(0, 0x00, 0x02): /* REV/REV32 */ | 102 | case MAP(0, 0x00, 0x02): /* REV/REV32 */ |
103 | case MAP(1, 0x00, 0x02): | 103 | case MAP(1, 0x00, 0x02): |
104 | case MAP(1, 0x00, 0x03): /* REV64 */ | 104 | case MAP(1, 0x00, 0x03): /* REV64 */ |
105 | + case MAP(0, 0x00, 0x04): /* CLZ */ | 105 | + case MAP(0, 0x00, 0x04): /* CLZ */ |
106 | + case MAP(1, 0x00, 0x04): | 106 | + case MAP(1, 0x00, 0x04): |
107 | + case MAP(0, 0x00, 0x05): /* CLS */ | 107 | + case MAP(0, 0x00, 0x05): /* CLS */ |
108 | + case MAP(1, 0x00, 0x05): | 108 | + case MAP(1, 0x00, 0x05): |
109 | unallocated_encoding(s); | 109 | unallocated_encoding(s); |
110 | break; | 110 | break; |
111 | } | 111 | } |
112 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 112 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
113 | index XXXXXXX..XXXXXXX 100644 | 113 | index XXXXXXX..XXXXXXX 100644 |
114 | --- a/target/arm/tcg/a64.decode | 114 | --- a/target/arm/tcg/a64.decode |
115 | +++ b/target/arm/tcg/a64.decode | 115 | +++ b/target/arm/tcg/a64.decode |
116 | @@ -XXX,XX +XXX,XX @@ REV16 . 10 11010110 00000 000001 ..... ..... @rr_sf | 116 | @@ -XXX,XX +XXX,XX @@ REV16 . 10 11010110 00000 000001 ..... ..... @rr_sf |
117 | REV32 . 10 11010110 00000 000010 ..... ..... @rr_sf | 117 | REV32 . 10 11010110 00000 000010 ..... ..... @rr_sf |
118 | REV64 1 10 11010110 00000 000011 ..... ..... @rr | 118 | REV64 1 10 11010110 00000 000011 ..... ..... @rr |
119 | 119 | ||
120 | +CLZ . 10 11010110 00000 000100 ..... ..... @rr_sf | 120 | +CLZ . 10 11010110 00000 000100 ..... ..... @rr_sf |
121 | +CLS . 10 11010110 00000 000101 ..... ..... @rr_sf | 121 | +CLS . 10 11010110 00000 000101 ..... ..... @rr_sf |
122 | + | 122 | + |
123 | # Logical (shifted reg) | 123 | # Logical (shifted reg) |
124 | # Add/subtract (shifted reg) | 124 | # Add/subtract (shifted reg) |
125 | # Add/subtract (extended reg) | 125 | # Add/subtract (extended reg) |
126 | -- | 126 | -- |
127 | 2.43.0 | 127 | 2.43.0 |
128 | 128 | ||
129 | 129 | diff view generated by jsdifflib |
1 | This includes PACIA, PACIZA, PACIB, PACIZB, PACDA, PACDZA, PACDB, | 1 | This includes PACIA, PACIZA, PACIB, PACIZB, PACDA, PACDZA, PACDB, |
---|---|---|---|
2 | PACDZB, AUTIA, AUTIZA, AUTIB, AUTIZB, AUTDA, AUTDZA, AUTDB, AUTDZB. | 2 | PACDZB, AUTIA, AUTIZA, AUTIB, AUTIZB, AUTDA, AUTDZA, AUTDB, AUTDZB. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 173 +++++++++------------------------ | 7 | target/arm/tcg/translate-a64.c | 173 +++++++++------------------------ |
8 | target/arm/tcg/a64.decode | 13 +++ | 8 | target/arm/tcg/a64.decode | 13 +++ |
9 | 2 files changed, 58 insertions(+), 128 deletions(-) | 9 | 2 files changed, 58 insertions(+), 128 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ static void gen_cls32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) | 15 | @@ -XXX,XX +XXX,XX @@ static void gen_cls32(TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) |
16 | TRANS(CLZ, gen_rr, a->rd, a->rn, a->sf ? gen_clz64 : gen_clz32) | 16 | TRANS(CLZ, gen_rr, a->rd, a->rn, a->sf ? gen_clz64 : gen_clz32) |
17 | TRANS(CLS, gen_rr, a->rd, a->rn, a->sf ? tcg_gen_clrsb_i64 : gen_cls32) | 17 | TRANS(CLS, gen_rr, a->rd, a->rn, a->sf ? tcg_gen_clrsb_i64 : gen_cls32) |
18 | 18 | ||
19 | +static bool gen_pacaut(DisasContext *s, arg_pacaut *a, NeonGenTwo64OpEnvFn fn) | 19 | +static bool gen_pacaut(DisasContext *s, arg_pacaut *a, NeonGenTwo64OpEnvFn fn) |
20 | +{ | 20 | +{ |
21 | + TCGv_i64 tcg_rd, tcg_rn; | 21 | + TCGv_i64 tcg_rd, tcg_rn; |
22 | + | 22 | + |
23 | + if (a->z) { | 23 | + if (a->z) { |
24 | + if (a->rn != 31) { | 24 | + if (a->rn != 31) { |
25 | + return false; | 25 | + return false; |
26 | + } | 26 | + } |
27 | + tcg_rn = tcg_constant_i64(0); | 27 | + tcg_rn = tcg_constant_i64(0); |
28 | + } else { | 28 | + } else { |
29 | + tcg_rn = cpu_reg_sp(s, a->rn); | 29 | + tcg_rn = cpu_reg_sp(s, a->rn); |
30 | + } | 30 | + } |
31 | + if (s->pauth_active) { | 31 | + if (s->pauth_active) { |
32 | + tcg_rd = cpu_reg(s, a->rd); | 32 | + tcg_rd = cpu_reg(s, a->rd); |
33 | + fn(tcg_rd, tcg_env, tcg_rd, tcg_rn); | 33 | + fn(tcg_rd, tcg_env, tcg_rd, tcg_rn); |
34 | + } | 34 | + } |
35 | + return true; | 35 | + return true; |
36 | +} | 36 | +} |
37 | + | 37 | + |
38 | +TRANS_FEAT(PACIA, aa64_pauth, gen_pacaut, a, gen_helper_pacia) | 38 | +TRANS_FEAT(PACIA, aa64_pauth, gen_pacaut, a, gen_helper_pacia) |
39 | +TRANS_FEAT(PACIB, aa64_pauth, gen_pacaut, a, gen_helper_pacib) | 39 | +TRANS_FEAT(PACIB, aa64_pauth, gen_pacaut, a, gen_helper_pacib) |
40 | +TRANS_FEAT(PACDA, aa64_pauth, gen_pacaut, a, gen_helper_pacda) | 40 | +TRANS_FEAT(PACDA, aa64_pauth, gen_pacaut, a, gen_helper_pacda) |
41 | +TRANS_FEAT(PACDB, aa64_pauth, gen_pacaut, a, gen_helper_pacdb) | 41 | +TRANS_FEAT(PACDB, aa64_pauth, gen_pacaut, a, gen_helper_pacdb) |
42 | + | 42 | + |
43 | +TRANS_FEAT(AUTIA, aa64_pauth, gen_pacaut, a, gen_helper_autia) | 43 | +TRANS_FEAT(AUTIA, aa64_pauth, gen_pacaut, a, gen_helper_autia) |
44 | +TRANS_FEAT(AUTIB, aa64_pauth, gen_pacaut, a, gen_helper_autib) | 44 | +TRANS_FEAT(AUTIB, aa64_pauth, gen_pacaut, a, gen_helper_autib) |
45 | +TRANS_FEAT(AUTDA, aa64_pauth, gen_pacaut, a, gen_helper_autda) | 45 | +TRANS_FEAT(AUTDA, aa64_pauth, gen_pacaut, a, gen_helper_autda) |
46 | +TRANS_FEAT(AUTDB, aa64_pauth, gen_pacaut, a, gen_helper_autdb) | 46 | +TRANS_FEAT(AUTDB, aa64_pauth, gen_pacaut, a, gen_helper_autdb) |
47 | + | 47 | + |
48 | /* Logical (shifted register) | 48 | /* Logical (shifted register) |
49 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 49 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
50 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 50 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
51 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 51 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
52 | #define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) | 52 | #define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) |
53 | 53 | ||
54 | switch (MAP(sf, opcode2, opcode)) { | 54 | switch (MAP(sf, opcode2, opcode)) { |
55 | - case MAP(1, 0x01, 0x00): /* PACIA */ | 55 | - case MAP(1, 0x01, 0x00): /* PACIA */ |
56 | - if (s->pauth_active) { | 56 | - if (s->pauth_active) { |
57 | - tcg_rd = cpu_reg(s, rd); | 57 | - tcg_rd = cpu_reg(s, rd); |
58 | - gen_helper_pacia(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 58 | - gen_helper_pacia(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
59 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 59 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
60 | - goto do_unallocated; | 60 | - goto do_unallocated; |
61 | - } | 61 | - } |
62 | - break; | 62 | - break; |
63 | - case MAP(1, 0x01, 0x01): /* PACIB */ | 63 | - case MAP(1, 0x01, 0x01): /* PACIB */ |
64 | - if (s->pauth_active) { | 64 | - if (s->pauth_active) { |
65 | - tcg_rd = cpu_reg(s, rd); | 65 | - tcg_rd = cpu_reg(s, rd); |
66 | - gen_helper_pacib(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 66 | - gen_helper_pacib(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
67 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 67 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
68 | - goto do_unallocated; | 68 | - goto do_unallocated; |
69 | - } | 69 | - } |
70 | - break; | 70 | - break; |
71 | - case MAP(1, 0x01, 0x02): /* PACDA */ | 71 | - case MAP(1, 0x01, 0x02): /* PACDA */ |
72 | - if (s->pauth_active) { | 72 | - if (s->pauth_active) { |
73 | - tcg_rd = cpu_reg(s, rd); | 73 | - tcg_rd = cpu_reg(s, rd); |
74 | - gen_helper_pacda(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 74 | - gen_helper_pacda(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
75 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 75 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
76 | - goto do_unallocated; | 76 | - goto do_unallocated; |
77 | - } | 77 | - } |
78 | - break; | 78 | - break; |
79 | - case MAP(1, 0x01, 0x03): /* PACDB */ | 79 | - case MAP(1, 0x01, 0x03): /* PACDB */ |
80 | - if (s->pauth_active) { | 80 | - if (s->pauth_active) { |
81 | - tcg_rd = cpu_reg(s, rd); | 81 | - tcg_rd = cpu_reg(s, rd); |
82 | - gen_helper_pacdb(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 82 | - gen_helper_pacdb(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
83 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 83 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
84 | - goto do_unallocated; | 84 | - goto do_unallocated; |
85 | - } | 85 | - } |
86 | - break; | 86 | - break; |
87 | - case MAP(1, 0x01, 0x04): /* AUTIA */ | 87 | - case MAP(1, 0x01, 0x04): /* AUTIA */ |
88 | - if (s->pauth_active) { | 88 | - if (s->pauth_active) { |
89 | - tcg_rd = cpu_reg(s, rd); | 89 | - tcg_rd = cpu_reg(s, rd); |
90 | - gen_helper_autia(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 90 | - gen_helper_autia(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
91 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 91 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
92 | - goto do_unallocated; | 92 | - goto do_unallocated; |
93 | - } | 93 | - } |
94 | - break; | 94 | - break; |
95 | - case MAP(1, 0x01, 0x05): /* AUTIB */ | 95 | - case MAP(1, 0x01, 0x05): /* AUTIB */ |
96 | - if (s->pauth_active) { | 96 | - if (s->pauth_active) { |
97 | - tcg_rd = cpu_reg(s, rd); | 97 | - tcg_rd = cpu_reg(s, rd); |
98 | - gen_helper_autib(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 98 | - gen_helper_autib(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
99 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 99 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
100 | - goto do_unallocated; | 100 | - goto do_unallocated; |
101 | - } | 101 | - } |
102 | - break; | 102 | - break; |
103 | - case MAP(1, 0x01, 0x06): /* AUTDA */ | 103 | - case MAP(1, 0x01, 0x06): /* AUTDA */ |
104 | - if (s->pauth_active) { | 104 | - if (s->pauth_active) { |
105 | - tcg_rd = cpu_reg(s, rd); | 105 | - tcg_rd = cpu_reg(s, rd); |
106 | - gen_helper_autda(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 106 | - gen_helper_autda(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
107 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 107 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
108 | - goto do_unallocated; | 108 | - goto do_unallocated; |
109 | - } | 109 | - } |
110 | - break; | 110 | - break; |
111 | - case MAP(1, 0x01, 0x07): /* AUTDB */ | 111 | - case MAP(1, 0x01, 0x07): /* AUTDB */ |
112 | - if (s->pauth_active) { | 112 | - if (s->pauth_active) { |
113 | - tcg_rd = cpu_reg(s, rd); | 113 | - tcg_rd = cpu_reg(s, rd); |
114 | - gen_helper_autdb(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); | 114 | - gen_helper_autdb(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn)); |
115 | - } else if (!dc_isar_feature(aa64_pauth, s)) { | 115 | - } else if (!dc_isar_feature(aa64_pauth, s)) { |
116 | - goto do_unallocated; | 116 | - goto do_unallocated; |
117 | - } | 117 | - } |
118 | - break; | 118 | - break; |
119 | - case MAP(1, 0x01, 0x08): /* PACIZA */ | 119 | - case MAP(1, 0x01, 0x08): /* PACIZA */ |
120 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 120 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
121 | - goto do_unallocated; | 121 | - goto do_unallocated; |
122 | - } else if (s->pauth_active) { | 122 | - } else if (s->pauth_active) { |
123 | - tcg_rd = cpu_reg(s, rd); | 123 | - tcg_rd = cpu_reg(s, rd); |
124 | - gen_helper_pacia(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 124 | - gen_helper_pacia(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
125 | - } | 125 | - } |
126 | - break; | 126 | - break; |
127 | - case MAP(1, 0x01, 0x09): /* PACIZB */ | 127 | - case MAP(1, 0x01, 0x09): /* PACIZB */ |
128 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 128 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
129 | - goto do_unallocated; | 129 | - goto do_unallocated; |
130 | - } else if (s->pauth_active) { | 130 | - } else if (s->pauth_active) { |
131 | - tcg_rd = cpu_reg(s, rd); | 131 | - tcg_rd = cpu_reg(s, rd); |
132 | - gen_helper_pacib(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 132 | - gen_helper_pacib(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
133 | - } | 133 | - } |
134 | - break; | 134 | - break; |
135 | - case MAP(1, 0x01, 0x0a): /* PACDZA */ | 135 | - case MAP(1, 0x01, 0x0a): /* PACDZA */ |
136 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 136 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
137 | - goto do_unallocated; | 137 | - goto do_unallocated; |
138 | - } else if (s->pauth_active) { | 138 | - } else if (s->pauth_active) { |
139 | - tcg_rd = cpu_reg(s, rd); | 139 | - tcg_rd = cpu_reg(s, rd); |
140 | - gen_helper_pacda(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 140 | - gen_helper_pacda(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
141 | - } | 141 | - } |
142 | - break; | 142 | - break; |
143 | - case MAP(1, 0x01, 0x0b): /* PACDZB */ | 143 | - case MAP(1, 0x01, 0x0b): /* PACDZB */ |
144 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 144 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
145 | - goto do_unallocated; | 145 | - goto do_unallocated; |
146 | - } else if (s->pauth_active) { | 146 | - } else if (s->pauth_active) { |
147 | - tcg_rd = cpu_reg(s, rd); | 147 | - tcg_rd = cpu_reg(s, rd); |
148 | - gen_helper_pacdb(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 148 | - gen_helper_pacdb(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
149 | - } | 149 | - } |
150 | - break; | 150 | - break; |
151 | - case MAP(1, 0x01, 0x0c): /* AUTIZA */ | 151 | - case MAP(1, 0x01, 0x0c): /* AUTIZA */ |
152 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 152 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
153 | - goto do_unallocated; | 153 | - goto do_unallocated; |
154 | - } else if (s->pauth_active) { | 154 | - } else if (s->pauth_active) { |
155 | - tcg_rd = cpu_reg(s, rd); | 155 | - tcg_rd = cpu_reg(s, rd); |
156 | - gen_helper_autia(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 156 | - gen_helper_autia(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
157 | - } | 157 | - } |
158 | - break; | 158 | - break; |
159 | - case MAP(1, 0x01, 0x0d): /* AUTIZB */ | 159 | - case MAP(1, 0x01, 0x0d): /* AUTIZB */ |
160 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 160 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
161 | - goto do_unallocated; | 161 | - goto do_unallocated; |
162 | - } else if (s->pauth_active) { | 162 | - } else if (s->pauth_active) { |
163 | - tcg_rd = cpu_reg(s, rd); | 163 | - tcg_rd = cpu_reg(s, rd); |
164 | - gen_helper_autib(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 164 | - gen_helper_autib(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
165 | - } | 165 | - } |
166 | - break; | 166 | - break; |
167 | - case MAP(1, 0x01, 0x0e): /* AUTDZA */ | 167 | - case MAP(1, 0x01, 0x0e): /* AUTDZA */ |
168 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 168 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
169 | - goto do_unallocated; | 169 | - goto do_unallocated; |
170 | - } else if (s->pauth_active) { | 170 | - } else if (s->pauth_active) { |
171 | - tcg_rd = cpu_reg(s, rd); | 171 | - tcg_rd = cpu_reg(s, rd); |
172 | - gen_helper_autda(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 172 | - gen_helper_autda(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
173 | - } | 173 | - } |
174 | - break; | 174 | - break; |
175 | - case MAP(1, 0x01, 0x0f): /* AUTDZB */ | 175 | - case MAP(1, 0x01, 0x0f): /* AUTDZB */ |
176 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 176 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
177 | - goto do_unallocated; | 177 | - goto do_unallocated; |
178 | - } else if (s->pauth_active) { | 178 | - } else if (s->pauth_active) { |
179 | - tcg_rd = cpu_reg(s, rd); | 179 | - tcg_rd = cpu_reg(s, rd); |
180 | - gen_helper_autdb(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); | 180 | - gen_helper_autdb(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0)); |
181 | - } | 181 | - } |
182 | - break; | 182 | - break; |
183 | case MAP(1, 0x01, 0x10): /* XPACI */ | 183 | case MAP(1, 0x01, 0x10): /* XPACI */ |
184 | if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 184 | if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
185 | goto do_unallocated; | 185 | goto do_unallocated; |
186 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 186 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
187 | case MAP(1, 0x00, 0x04): | 187 | case MAP(1, 0x00, 0x04): |
188 | case MAP(0, 0x00, 0x05): /* CLS */ | 188 | case MAP(0, 0x00, 0x05): /* CLS */ |
189 | case MAP(1, 0x00, 0x05): | 189 | case MAP(1, 0x00, 0x05): |
190 | + case MAP(1, 0x01, 0x00): /* PACIA */ | 190 | + case MAP(1, 0x01, 0x00): /* PACIA */ |
191 | + case MAP(1, 0x01, 0x01): /* PACIB */ | 191 | + case MAP(1, 0x01, 0x01): /* PACIB */ |
192 | + case MAP(1, 0x01, 0x02): /* PACDA */ | 192 | + case MAP(1, 0x01, 0x02): /* PACDA */ |
193 | + case MAP(1, 0x01, 0x03): /* PACDB */ | 193 | + case MAP(1, 0x01, 0x03): /* PACDB */ |
194 | + case MAP(1, 0x01, 0x04): /* AUTIA */ | 194 | + case MAP(1, 0x01, 0x04): /* AUTIA */ |
195 | + case MAP(1, 0x01, 0x05): /* AUTIB */ | 195 | + case MAP(1, 0x01, 0x05): /* AUTIB */ |
196 | + case MAP(1, 0x01, 0x06): /* AUTDA */ | 196 | + case MAP(1, 0x01, 0x06): /* AUTDA */ |
197 | + case MAP(1, 0x01, 0x07): /* AUTDB */ | 197 | + case MAP(1, 0x01, 0x07): /* AUTDB */ |
198 | + case MAP(1, 0x01, 0x08): /* PACIZA */ | 198 | + case MAP(1, 0x01, 0x08): /* PACIZA */ |
199 | + case MAP(1, 0x01, 0x09): /* PACIZB */ | 199 | + case MAP(1, 0x01, 0x09): /* PACIZB */ |
200 | + case MAP(1, 0x01, 0x0a): /* PACDZA */ | 200 | + case MAP(1, 0x01, 0x0a): /* PACDZA */ |
201 | + case MAP(1, 0x01, 0x0b): /* PACDZB */ | 201 | + case MAP(1, 0x01, 0x0b): /* PACDZB */ |
202 | + case MAP(1, 0x01, 0x0c): /* AUTIZA */ | 202 | + case MAP(1, 0x01, 0x0c): /* AUTIZA */ |
203 | + case MAP(1, 0x01, 0x0d): /* AUTIZB */ | 203 | + case MAP(1, 0x01, 0x0d): /* AUTIZB */ |
204 | + case MAP(1, 0x01, 0x0e): /* AUTDZA */ | 204 | + case MAP(1, 0x01, 0x0e): /* AUTDZA */ |
205 | + case MAP(1, 0x01, 0x0f): /* AUTDZB */ | 205 | + case MAP(1, 0x01, 0x0f): /* AUTDZB */ |
206 | unallocated_encoding(s); | 206 | unallocated_encoding(s); |
207 | break; | 207 | break; |
208 | } | 208 | } |
209 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 209 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
210 | index XXXXXXX..XXXXXXX 100644 | 210 | index XXXXXXX..XXXXXXX 100644 |
211 | --- a/target/arm/tcg/a64.decode | 211 | --- a/target/arm/tcg/a64.decode |
212 | +++ b/target/arm/tcg/a64.decode | 212 | +++ b/target/arm/tcg/a64.decode |
213 | @@ -XXX,XX +XXX,XX @@ REV64 1 10 11010110 00000 000011 ..... ..... @rr | 213 | @@ -XXX,XX +XXX,XX @@ REV64 1 10 11010110 00000 000011 ..... ..... @rr |
214 | CLZ . 10 11010110 00000 000100 ..... ..... @rr_sf | 214 | CLZ . 10 11010110 00000 000100 ..... ..... @rr_sf |
215 | CLS . 10 11010110 00000 000101 ..... ..... @rr_sf | 215 | CLS . 10 11010110 00000 000101 ..... ..... @rr_sf |
216 | 216 | ||
217 | +&pacaut rd rn z | 217 | +&pacaut rd rn z |
218 | +@pacaut . .. ........ ..... .. z:1 ... rn:5 rd:5 &pacaut | 218 | +@pacaut . .. ........ ..... .. z:1 ... rn:5 rd:5 &pacaut |
219 | + | 219 | + |
220 | +PACIA 1 10 11010110 00001 00.000 ..... ..... @pacaut | 220 | +PACIA 1 10 11010110 00001 00.000 ..... ..... @pacaut |
221 | +PACIB 1 10 11010110 00001 00.001 ..... ..... @pacaut | 221 | +PACIB 1 10 11010110 00001 00.001 ..... ..... @pacaut |
222 | +PACDA 1 10 11010110 00001 00.010 ..... ..... @pacaut | 222 | +PACDA 1 10 11010110 00001 00.010 ..... ..... @pacaut |
223 | +PACDB 1 10 11010110 00001 00.011 ..... ..... @pacaut | 223 | +PACDB 1 10 11010110 00001 00.011 ..... ..... @pacaut |
224 | + | 224 | + |
225 | +AUTIA 1 10 11010110 00001 00.100 ..... ..... @pacaut | 225 | +AUTIA 1 10 11010110 00001 00.100 ..... ..... @pacaut |
226 | +AUTIB 1 10 11010110 00001 00.101 ..... ..... @pacaut | 226 | +AUTIB 1 10 11010110 00001 00.101 ..... ..... @pacaut |
227 | +AUTDA 1 10 11010110 00001 00.110 ..... ..... @pacaut | 227 | +AUTDA 1 10 11010110 00001 00.110 ..... ..... @pacaut |
228 | +AUTDB 1 10 11010110 00001 00.111 ..... ..... @pacaut | 228 | +AUTDB 1 10 11010110 00001 00.111 ..... ..... @pacaut |
229 | + | 229 | + |
230 | # Logical (shifted reg) | 230 | # Logical (shifted reg) |
231 | # Add/subtract (shifted reg) | 231 | # Add/subtract (shifted reg) |
232 | # Add/subtract (extended reg) | 232 | # Add/subtract (extended reg) |
233 | -- | 233 | -- |
234 | 2.43.0 | 234 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove disas_data_proc_1src, as these were the last insns | 1 | Remove disas_data_proc_1src, as these were the last insns |
---|---|---|---|
2 | decoded by that function. | 2 | decoded by that function. |
3 | 3 | ||
4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 99 +++++----------------------------- | 7 | target/arm/tcg/translate-a64.c | 99 +++++----------------------------- |
8 | target/arm/tcg/a64.decode | 3 ++ | 8 | target/arm/tcg/a64.decode | 3 ++ |
9 | 2 files changed, 16 insertions(+), 86 deletions(-) | 9 | 2 files changed, 16 insertions(+), 86 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(AUTIB, aa64_pauth, gen_pacaut, a, gen_helper_autib) | 15 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(AUTIB, aa64_pauth, gen_pacaut, a, gen_helper_autib) |
16 | TRANS_FEAT(AUTDA, aa64_pauth, gen_pacaut, a, gen_helper_autda) | 16 | TRANS_FEAT(AUTDA, aa64_pauth, gen_pacaut, a, gen_helper_autda) |
17 | TRANS_FEAT(AUTDB, aa64_pauth, gen_pacaut, a, gen_helper_autdb) | 17 | TRANS_FEAT(AUTDB, aa64_pauth, gen_pacaut, a, gen_helper_autdb) |
18 | 18 | ||
19 | +static bool do_xpac(DisasContext *s, int rd, NeonGenOne64OpEnvFn *fn) | 19 | +static bool do_xpac(DisasContext *s, int rd, NeonGenOne64OpEnvFn *fn) |
20 | +{ | 20 | +{ |
21 | + if (s->pauth_active) { | 21 | + if (s->pauth_active) { |
22 | + TCGv_i64 tcg_rd = cpu_reg(s, rd); | 22 | + TCGv_i64 tcg_rd = cpu_reg(s, rd); |
23 | + fn(tcg_rd, tcg_env, tcg_rd); | 23 | + fn(tcg_rd, tcg_env, tcg_rd); |
24 | + } | 24 | + } |
25 | + return true; | 25 | + return true; |
26 | +} | 26 | +} |
27 | + | 27 | + |
28 | +TRANS_FEAT(XPACI, aa64_pauth, do_xpac, a->rd, gen_helper_xpaci) | 28 | +TRANS_FEAT(XPACI, aa64_pauth, do_xpac, a->rd, gen_helper_xpaci) |
29 | +TRANS_FEAT(XPACD, aa64_pauth, do_xpac, a->rd, gen_helper_xpacd) | 29 | +TRANS_FEAT(XPACD, aa64_pauth, do_xpac, a->rd, gen_helper_xpacd) |
30 | + | 30 | + |
31 | /* Logical (shifted register) | 31 | /* Logical (shifted register) |
32 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 32 | * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
33 | * +----+-----+-----------+-------+---+------+--------+------+------+ | 33 | * +----+-----+-----------+-------+---+------+--------+------+------+ |
34 | @@ -XXX,XX +XXX,XX @@ static void disas_cond_select(DisasContext *s, uint32_t insn) | 34 | @@ -XXX,XX +XXX,XX @@ static void disas_cond_select(DisasContext *s, uint32_t insn) |
35 | } | 35 | } |
36 | } | 36 | } |
37 | 37 | ||
38 | -/* Data-processing (1 source) | 38 | -/* Data-processing (1 source) |
39 | - * 31 30 29 28 21 20 16 15 10 9 5 4 0 | 39 | - * 31 30 29 28 21 20 16 15 10 9 5 4 0 |
40 | - * +----+---+---+-----------------+---------+--------+------+------+ | 40 | - * +----+---+---+-----------------+---------+--------+------+------+ |
41 | - * | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode | Rn | Rd | | 41 | - * | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode | Rn | Rd | |
42 | - * +----+---+---+-----------------+---------+--------+------+------+ | 42 | - * +----+---+---+-----------------+---------+--------+------+------+ |
43 | - */ | 43 | - */ |
44 | -static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 44 | -static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
45 | -{ | 45 | -{ |
46 | - unsigned int sf, opcode, opcode2, rn, rd; | 46 | - unsigned int sf, opcode, opcode2, rn, rd; |
47 | - TCGv_i64 tcg_rd; | 47 | - TCGv_i64 tcg_rd; |
48 | - | 48 | - |
49 | - if (extract32(insn, 29, 1)) { | 49 | - if (extract32(insn, 29, 1)) { |
50 | - unallocated_encoding(s); | 50 | - unallocated_encoding(s); |
51 | - return; | 51 | - return; |
52 | - } | 52 | - } |
53 | - | 53 | - |
54 | - sf = extract32(insn, 31, 1); | 54 | - sf = extract32(insn, 31, 1); |
55 | - opcode = extract32(insn, 10, 6); | 55 | - opcode = extract32(insn, 10, 6); |
56 | - opcode2 = extract32(insn, 16, 5); | 56 | - opcode2 = extract32(insn, 16, 5); |
57 | - rn = extract32(insn, 5, 5); | 57 | - rn = extract32(insn, 5, 5); |
58 | - rd = extract32(insn, 0, 5); | 58 | - rd = extract32(insn, 0, 5); |
59 | - | 59 | - |
60 | -#define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) | 60 | -#define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7)) |
61 | - | 61 | - |
62 | - switch (MAP(sf, opcode2, opcode)) { | 62 | - switch (MAP(sf, opcode2, opcode)) { |
63 | - case MAP(1, 0x01, 0x10): /* XPACI */ | 63 | - case MAP(1, 0x01, 0x10): /* XPACI */ |
64 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 64 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
65 | - goto do_unallocated; | 65 | - goto do_unallocated; |
66 | - } else if (s->pauth_active) { | 66 | - } else if (s->pauth_active) { |
67 | - tcg_rd = cpu_reg(s, rd); | 67 | - tcg_rd = cpu_reg(s, rd); |
68 | - gen_helper_xpaci(tcg_rd, tcg_env, tcg_rd); | 68 | - gen_helper_xpaci(tcg_rd, tcg_env, tcg_rd); |
69 | - } | 69 | - } |
70 | - break; | 70 | - break; |
71 | - case MAP(1, 0x01, 0x11): /* XPACD */ | 71 | - case MAP(1, 0x01, 0x11): /* XPACD */ |
72 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { | 72 | - if (!dc_isar_feature(aa64_pauth, s) || rn != 31) { |
73 | - goto do_unallocated; | 73 | - goto do_unallocated; |
74 | - } else if (s->pauth_active) { | 74 | - } else if (s->pauth_active) { |
75 | - tcg_rd = cpu_reg(s, rd); | 75 | - tcg_rd = cpu_reg(s, rd); |
76 | - gen_helper_xpacd(tcg_rd, tcg_env, tcg_rd); | 76 | - gen_helper_xpacd(tcg_rd, tcg_env, tcg_rd); |
77 | - } | 77 | - } |
78 | - break; | 78 | - break; |
79 | - default: | 79 | - default: |
80 | - do_unallocated: | 80 | - do_unallocated: |
81 | - case MAP(0, 0x00, 0x00): /* RBIT */ | 81 | - case MAP(0, 0x00, 0x00): /* RBIT */ |
82 | - case MAP(1, 0x00, 0x00): | 82 | - case MAP(1, 0x00, 0x00): |
83 | - case MAP(0, 0x00, 0x01): /* REV16 */ | 83 | - case MAP(0, 0x00, 0x01): /* REV16 */ |
84 | - case MAP(1, 0x00, 0x01): | 84 | - case MAP(1, 0x00, 0x01): |
85 | - case MAP(0, 0x00, 0x02): /* REV/REV32 */ | 85 | - case MAP(0, 0x00, 0x02): /* REV/REV32 */ |
86 | - case MAP(1, 0x00, 0x02): | 86 | - case MAP(1, 0x00, 0x02): |
87 | - case MAP(1, 0x00, 0x03): /* REV64 */ | 87 | - case MAP(1, 0x00, 0x03): /* REV64 */ |
88 | - case MAP(0, 0x00, 0x04): /* CLZ */ | 88 | - case MAP(0, 0x00, 0x04): /* CLZ */ |
89 | - case MAP(1, 0x00, 0x04): | 89 | - case MAP(1, 0x00, 0x04): |
90 | - case MAP(0, 0x00, 0x05): /* CLS */ | 90 | - case MAP(0, 0x00, 0x05): /* CLS */ |
91 | - case MAP(1, 0x00, 0x05): | 91 | - case MAP(1, 0x00, 0x05): |
92 | - case MAP(1, 0x01, 0x00): /* PACIA */ | 92 | - case MAP(1, 0x01, 0x00): /* PACIA */ |
93 | - case MAP(1, 0x01, 0x01): /* PACIB */ | 93 | - case MAP(1, 0x01, 0x01): /* PACIB */ |
94 | - case MAP(1, 0x01, 0x02): /* PACDA */ | 94 | - case MAP(1, 0x01, 0x02): /* PACDA */ |
95 | - case MAP(1, 0x01, 0x03): /* PACDB */ | 95 | - case MAP(1, 0x01, 0x03): /* PACDB */ |
96 | - case MAP(1, 0x01, 0x04): /* AUTIA */ | 96 | - case MAP(1, 0x01, 0x04): /* AUTIA */ |
97 | - case MAP(1, 0x01, 0x05): /* AUTIB */ | 97 | - case MAP(1, 0x01, 0x05): /* AUTIB */ |
98 | - case MAP(1, 0x01, 0x06): /* AUTDA */ | 98 | - case MAP(1, 0x01, 0x06): /* AUTDA */ |
99 | - case MAP(1, 0x01, 0x07): /* AUTDB */ | 99 | - case MAP(1, 0x01, 0x07): /* AUTDB */ |
100 | - case MAP(1, 0x01, 0x08): /* PACIZA */ | 100 | - case MAP(1, 0x01, 0x08): /* PACIZA */ |
101 | - case MAP(1, 0x01, 0x09): /* PACIZB */ | 101 | - case MAP(1, 0x01, 0x09): /* PACIZB */ |
102 | - case MAP(1, 0x01, 0x0a): /* PACDZA */ | 102 | - case MAP(1, 0x01, 0x0a): /* PACDZA */ |
103 | - case MAP(1, 0x01, 0x0b): /* PACDZB */ | 103 | - case MAP(1, 0x01, 0x0b): /* PACDZB */ |
104 | - case MAP(1, 0x01, 0x0c): /* AUTIZA */ | 104 | - case MAP(1, 0x01, 0x0c): /* AUTIZA */ |
105 | - case MAP(1, 0x01, 0x0d): /* AUTIZB */ | 105 | - case MAP(1, 0x01, 0x0d): /* AUTIZB */ |
106 | - case MAP(1, 0x01, 0x0e): /* AUTDZA */ | 106 | - case MAP(1, 0x01, 0x0e): /* AUTDZA */ |
107 | - case MAP(1, 0x01, 0x0f): /* AUTDZB */ | 107 | - case MAP(1, 0x01, 0x0f): /* AUTDZB */ |
108 | - unallocated_encoding(s); | 108 | - unallocated_encoding(s); |
109 | - break; | 109 | - break; |
110 | - } | 110 | - } |
111 | - | 111 | - |
112 | -#undef MAP | 112 | -#undef MAP |
113 | -} | 113 | -} |
114 | - | 114 | - |
115 | - | 115 | - |
116 | /* | 116 | /* |
117 | * Data processing - register | 117 | * Data processing - register |
118 | * 31 30 29 28 25 21 20 16 10 0 | 118 | * 31 30 29 28 25 21 20 16 10 0 |
119 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) | 119 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn) |
120 | */ | 120 | */ |
121 | static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 121 | static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
122 | { | 122 | { |
123 | - int op0 = extract32(insn, 30, 1); | 123 | - int op0 = extract32(insn, 30, 1); |
124 | int op1 = extract32(insn, 28, 1); | 124 | int op1 = extract32(insn, 28, 1); |
125 | int op2 = extract32(insn, 21, 4); | 125 | int op2 = extract32(insn, 21, 4); |
126 | int op3 = extract32(insn, 10, 6); | 126 | int op3 = extract32(insn, 10, 6); |
127 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 127 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
128 | disas_cond_select(s, insn); | 128 | disas_cond_select(s, insn); |
129 | break; | 129 | break; |
130 | 130 | ||
131 | - case 0x6: /* Data-processing */ | 131 | - case 0x6: /* Data-processing */ |
132 | - if (op0) { /* (1 source) */ | 132 | - if (op0) { /* (1 source) */ |
133 | - disas_data_proc_1src(s, insn); | 133 | - disas_data_proc_1src(s, insn); |
134 | - } else { /* (2 source) */ | 134 | - } else { /* (2 source) */ |
135 | - goto do_unallocated; | 135 | - goto do_unallocated; |
136 | - } | 136 | - } |
137 | - break; | 137 | - break; |
138 | case 0x8 ... 0xf: /* (3 source) */ | 138 | case 0x8 ... 0xf: /* (3 source) */ |
139 | disas_data_proc_3src(s, insn); | 139 | disas_data_proc_3src(s, insn); |
140 | break; | 140 | break; |
141 | 141 | ||
142 | default: | 142 | default: |
143 | do_unallocated: | 143 | do_unallocated: |
144 | + case 0x6: /* Data-processing */ | 144 | + case 0x6: /* Data-processing */ |
145 | unallocated_encoding(s); | 145 | unallocated_encoding(s); |
146 | break; | 146 | break; |
147 | } | 147 | } |
148 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 148 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
149 | index XXXXXXX..XXXXXXX 100644 | 149 | index XXXXXXX..XXXXXXX 100644 |
150 | --- a/target/arm/tcg/a64.decode | 150 | --- a/target/arm/tcg/a64.decode |
151 | +++ b/target/arm/tcg/a64.decode | 151 | +++ b/target/arm/tcg/a64.decode |
152 | @@ -XXX,XX +XXX,XX @@ AUTIB 1 10 11010110 00001 00.101 ..... ..... @pacaut | 152 | @@ -XXX,XX +XXX,XX @@ AUTIB 1 10 11010110 00001 00.101 ..... ..... @pacaut |
153 | AUTDA 1 10 11010110 00001 00.110 ..... ..... @pacaut | 153 | AUTDA 1 10 11010110 00001 00.110 ..... ..... @pacaut |
154 | AUTDB 1 10 11010110 00001 00.111 ..... ..... @pacaut | 154 | AUTDB 1 10 11010110 00001 00.111 ..... ..... @pacaut |
155 | 155 | ||
156 | +XPACI 1 10 11010110 00001 010000 11111 rd:5 | 156 | +XPACI 1 10 11010110 00001 010000 11111 rd:5 |
157 | +XPACD 1 10 11010110 00001 010001 11111 rd:5 | 157 | +XPACD 1 10 11010110 00001 010001 11111 rd:5 |
158 | + | 158 | + |
159 | # Logical (shifted reg) | 159 | # Logical (shifted reg) |
160 | # Add/subtract (shifted reg) | 160 | # Add/subtract (shifted reg) |
161 | # Add/subtract (extended reg) | 161 | # Add/subtract (extended reg) |
162 | -- | 162 | -- |
163 | 2.43.0 | 163 | 2.43.0 |
164 | 164 | ||
165 | 165 | diff view generated by jsdifflib |
1 | This includes AND, BIC, ORR, ORN, EOR, EON, ANDS, BICS (shifted reg). | 1 | This includes AND, BIC, ORR, ORN, EOR, EON, ANDS, BICS (shifted reg). |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/tcg/translate-a64.c | 117 ++++++++++++--------------------- | 6 | target/arm/tcg/translate-a64.c | 117 ++++++++++++--------------------- |
7 | target/arm/tcg/a64.decode | 9 +++ | 7 | target/arm/tcg/a64.decode | 9 +++ |
8 | 2 files changed, 51 insertions(+), 75 deletions(-) | 8 | 2 files changed, 51 insertions(+), 75 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ static bool do_xpac(DisasContext *s, int rd, NeonGenOne64OpEnvFn *fn) | 14 | @@ -XXX,XX +XXX,XX @@ static bool do_xpac(DisasContext *s, int rd, NeonGenOne64OpEnvFn *fn) |
15 | TRANS_FEAT(XPACI, aa64_pauth, do_xpac, a->rd, gen_helper_xpaci) | 15 | TRANS_FEAT(XPACI, aa64_pauth, do_xpac, a->rd, gen_helper_xpaci) |
16 | TRANS_FEAT(XPACD, aa64_pauth, do_xpac, a->rd, gen_helper_xpacd) | 16 | TRANS_FEAT(XPACD, aa64_pauth, do_xpac, a->rd, gen_helper_xpacd) |
17 | 17 | ||
18 | -/* Logical (shifted register) | 18 | -/* Logical (shifted register) |
19 | - * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 19 | - * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
20 | - * +----+-----+-----------+-------+---+------+--------+------+------+ | 20 | - * +----+-----+-----------+-------+---+------+--------+------+------+ |
21 | - * | sf | opc | 0 1 0 1 0 | shift | N | Rm | imm6 | Rn | Rd | | 21 | - * | sf | opc | 0 1 0 1 0 | shift | N | Rm | imm6 | Rn | Rd | |
22 | - * +----+-----+-----------+-------+---+------+--------+------+------+ | 22 | - * +----+-----+-----------+-------+---+------+--------+------+------+ |
23 | - */ | 23 | - */ |
24 | -static void disas_logic_reg(DisasContext *s, uint32_t insn) | 24 | -static void disas_logic_reg(DisasContext *s, uint32_t insn) |
25 | +static bool do_logic_reg(DisasContext *s, arg_logic_shift *a, | 25 | +static bool do_logic_reg(DisasContext *s, arg_logic_shift *a, |
26 | + ArithTwoOp *fn, ArithTwoOp *inv_fn, bool setflags) | 26 | + ArithTwoOp *fn, ArithTwoOp *inv_fn, bool setflags) |
27 | { | 27 | { |
28 | TCGv_i64 tcg_rd, tcg_rn, tcg_rm; | 28 | TCGv_i64 tcg_rd, tcg_rn, tcg_rm; |
29 | - unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd; | 29 | - unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd; |
30 | 30 | ||
31 | - sf = extract32(insn, 31, 1); | 31 | - sf = extract32(insn, 31, 1); |
32 | - opc = extract32(insn, 29, 2); | 32 | - opc = extract32(insn, 29, 2); |
33 | - shift_type = extract32(insn, 22, 2); | 33 | - shift_type = extract32(insn, 22, 2); |
34 | - invert = extract32(insn, 21, 1); | 34 | - invert = extract32(insn, 21, 1); |
35 | - rm = extract32(insn, 16, 5); | 35 | - rm = extract32(insn, 16, 5); |
36 | - shift_amount = extract32(insn, 10, 6); | 36 | - shift_amount = extract32(insn, 10, 6); |
37 | - rn = extract32(insn, 5, 5); | 37 | - rn = extract32(insn, 5, 5); |
38 | - rd = extract32(insn, 0, 5); | 38 | - rd = extract32(insn, 0, 5); |
39 | - | 39 | - |
40 | - if (!sf && (shift_amount & (1 << 5))) { | 40 | - if (!sf && (shift_amount & (1 << 5))) { |
41 | - unallocated_encoding(s); | 41 | - unallocated_encoding(s); |
42 | - return; | 42 | - return; |
43 | + if (!a->sf && (a->sa & (1 << 5))) { | 43 | + if (!a->sf && (a->sa & (1 << 5))) { |
44 | + return false; | 44 | + return false; |
45 | } | 45 | } |
46 | 46 | ||
47 | - tcg_rd = cpu_reg(s, rd); | 47 | - tcg_rd = cpu_reg(s, rd); |
48 | + tcg_rd = cpu_reg(s, a->rd); | 48 | + tcg_rd = cpu_reg(s, a->rd); |
49 | + tcg_rn = cpu_reg(s, a->rn); | 49 | + tcg_rn = cpu_reg(s, a->rn); |
50 | 50 | ||
51 | - if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) { | 51 | - if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) { |
52 | - /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for | 52 | - /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for |
53 | - * register-register MOV and MVN, so it is worth special casing. | 53 | - * register-register MOV and MVN, so it is worth special casing. |
54 | - */ | 54 | - */ |
55 | - tcg_rm = cpu_reg(s, rm); | 55 | - tcg_rm = cpu_reg(s, rm); |
56 | - if (invert) { | 56 | - if (invert) { |
57 | + tcg_rm = read_cpu_reg(s, a->rm, a->sf); | 57 | + tcg_rm = read_cpu_reg(s, a->rm, a->sf); |
58 | + if (a->sa) { | 58 | + if (a->sa) { |
59 | + shift_reg_imm(tcg_rm, tcg_rm, a->sf, a->st, a->sa); | 59 | + shift_reg_imm(tcg_rm, tcg_rm, a->sf, a->st, a->sa); |
60 | + } | 60 | + } |
61 | + | 61 | + |
62 | + (a->n ? inv_fn : fn)(tcg_rd, tcg_rn, tcg_rm); | 62 | + (a->n ? inv_fn : fn)(tcg_rd, tcg_rn, tcg_rm); |
63 | + if (!a->sf) { | 63 | + if (!a->sf) { |
64 | + tcg_gen_ext32u_i64(tcg_rd, tcg_rd); | 64 | + tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
65 | + } | 65 | + } |
66 | + if (setflags) { | 66 | + if (setflags) { |
67 | + gen_logic_CC(a->sf, tcg_rd); | 67 | + gen_logic_CC(a->sf, tcg_rd); |
68 | + } | 68 | + } |
69 | + return true; | 69 | + return true; |
70 | +} | 70 | +} |
71 | + | 71 | + |
72 | +static bool trans_ORR_r(DisasContext *s, arg_logic_shift *a) | 72 | +static bool trans_ORR_r(DisasContext *s, arg_logic_shift *a) |
73 | +{ | 73 | +{ |
74 | + /* | 74 | + /* |
75 | + * Unshifted ORR and ORN with WZR/XZR is the standard encoding for | 75 | + * Unshifted ORR and ORN with WZR/XZR is the standard encoding for |
76 | + * register-register MOV and MVN, so it is worth special casing. | 76 | + * register-register MOV and MVN, so it is worth special casing. |
77 | + */ | 77 | + */ |
78 | + if (a->sa == 0 && a->st == 0 && a->rn == 31) { | 78 | + if (a->sa == 0 && a->st == 0 && a->rn == 31) { |
79 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 79 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
80 | + TCGv_i64 tcg_rm = cpu_reg(s, a->rm); | 80 | + TCGv_i64 tcg_rm = cpu_reg(s, a->rm); |
81 | + | 81 | + |
82 | + if (a->n) { | 82 | + if (a->n) { |
83 | tcg_gen_not_i64(tcg_rd, tcg_rm); | 83 | tcg_gen_not_i64(tcg_rd, tcg_rm); |
84 | - if (!sf) { | 84 | - if (!sf) { |
85 | + if (!a->sf) { | 85 | + if (!a->sf) { |
86 | tcg_gen_ext32u_i64(tcg_rd, tcg_rd); | 86 | tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
87 | } | 87 | } |
88 | } else { | 88 | } else { |
89 | - if (sf) { | 89 | - if (sf) { |
90 | + if (a->sf) { | 90 | + if (a->sf) { |
91 | tcg_gen_mov_i64(tcg_rd, tcg_rm); | 91 | tcg_gen_mov_i64(tcg_rd, tcg_rm); |
92 | } else { | 92 | } else { |
93 | tcg_gen_ext32u_i64(tcg_rd, tcg_rm); | 93 | tcg_gen_ext32u_i64(tcg_rd, tcg_rm); |
94 | } | 94 | } |
95 | } | 95 | } |
96 | - return; | 96 | - return; |
97 | + return true; | 97 | + return true; |
98 | } | 98 | } |
99 | 99 | ||
100 | - tcg_rm = read_cpu_reg(s, rm, sf); | 100 | - tcg_rm = read_cpu_reg(s, rm, sf); |
101 | - | 101 | - |
102 | - if (shift_amount) { | 102 | - if (shift_amount) { |
103 | - shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount); | 103 | - shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount); |
104 | - } | 104 | - } |
105 | - | 105 | - |
106 | - tcg_rn = cpu_reg(s, rn); | 106 | - tcg_rn = cpu_reg(s, rn); |
107 | - | 107 | - |
108 | - switch (opc | (invert << 2)) { | 108 | - switch (opc | (invert << 2)) { |
109 | - case 0: /* AND */ | 109 | - case 0: /* AND */ |
110 | - case 3: /* ANDS */ | 110 | - case 3: /* ANDS */ |
111 | - tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm); | 111 | - tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm); |
112 | - break; | 112 | - break; |
113 | - case 1: /* ORR */ | 113 | - case 1: /* ORR */ |
114 | - tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm); | 114 | - tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm); |
115 | - break; | 115 | - break; |
116 | - case 2: /* EOR */ | 116 | - case 2: /* EOR */ |
117 | - tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm); | 117 | - tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm); |
118 | - break; | 118 | - break; |
119 | - case 4: /* BIC */ | 119 | - case 4: /* BIC */ |
120 | - case 7: /* BICS */ | 120 | - case 7: /* BICS */ |
121 | - tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm); | 121 | - tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm); |
122 | - break; | 122 | - break; |
123 | - case 5: /* ORN */ | 123 | - case 5: /* ORN */ |
124 | - tcg_gen_orc_i64(tcg_rd, tcg_rn, tcg_rm); | 124 | - tcg_gen_orc_i64(tcg_rd, tcg_rn, tcg_rm); |
125 | - break; | 125 | - break; |
126 | - case 6: /* EON */ | 126 | - case 6: /* EON */ |
127 | - tcg_gen_eqv_i64(tcg_rd, tcg_rn, tcg_rm); | 127 | - tcg_gen_eqv_i64(tcg_rd, tcg_rn, tcg_rm); |
128 | - break; | 128 | - break; |
129 | - default: | 129 | - default: |
130 | - assert(FALSE); | 130 | - assert(FALSE); |
131 | - break; | 131 | - break; |
132 | - } | 132 | - } |
133 | - | 133 | - |
134 | - if (!sf) { | 134 | - if (!sf) { |
135 | - tcg_gen_ext32u_i64(tcg_rd, tcg_rd); | 135 | - tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
136 | - } | 136 | - } |
137 | - | 137 | - |
138 | - if (opc == 3) { | 138 | - if (opc == 3) { |
139 | - gen_logic_CC(sf, tcg_rd); | 139 | - gen_logic_CC(sf, tcg_rd); |
140 | - } | 140 | - } |
141 | + return do_logic_reg(s, a, tcg_gen_or_i64, tcg_gen_orc_i64, false); | 141 | + return do_logic_reg(s, a, tcg_gen_or_i64, tcg_gen_orc_i64, false); |
142 | } | 142 | } |
143 | 143 | ||
144 | +TRANS(AND_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, false) | 144 | +TRANS(AND_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, false) |
145 | +TRANS(ANDS_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, true) | 145 | +TRANS(ANDS_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, true) |
146 | +TRANS(EOR_r, do_logic_reg, a, tcg_gen_xor_i64, tcg_gen_eqv_i64, false) | 146 | +TRANS(EOR_r, do_logic_reg, a, tcg_gen_xor_i64, tcg_gen_eqv_i64, false) |
147 | + | 147 | + |
148 | /* | 148 | /* |
149 | * Add/subtract (extended register) | 149 | * Add/subtract (extended register) |
150 | * | 150 | * |
151 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 151 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
152 | /* Add/sub (shifted register) */ | 152 | /* Add/sub (shifted register) */ |
153 | disas_add_sub_reg(s, insn); | 153 | disas_add_sub_reg(s, insn); |
154 | } | 154 | } |
155 | - } else { | 155 | - } else { |
156 | - /* Logical (shifted register) */ | 156 | - /* Logical (shifted register) */ |
157 | - disas_logic_reg(s, insn); | 157 | - disas_logic_reg(s, insn); |
158 | + return; | 158 | + return; |
159 | } | 159 | } |
160 | - return; | 160 | - return; |
161 | + goto do_unallocated; | 161 | + goto do_unallocated; |
162 | } | 162 | } |
163 | 163 | ||
164 | switch (op2) { | 164 | switch (op2) { |
165 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 165 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
166 | index XXXXXXX..XXXXXXX 100644 | 166 | index XXXXXXX..XXXXXXX 100644 |
167 | --- a/target/arm/tcg/a64.decode | 167 | --- a/target/arm/tcg/a64.decode |
168 | +++ b/target/arm/tcg/a64.decode | 168 | +++ b/target/arm/tcg/a64.decode |
169 | @@ -XXX,XX +XXX,XX @@ XPACI 1 10 11010110 00001 010000 11111 rd:5 | 169 | @@ -XXX,XX +XXX,XX @@ XPACI 1 10 11010110 00001 010000 11111 rd:5 |
170 | XPACD 1 10 11010110 00001 010001 11111 rd:5 | 170 | XPACD 1 10 11010110 00001 010001 11111 rd:5 |
171 | 171 | ||
172 | # Logical (shifted reg) | 172 | # Logical (shifted reg) |
173 | + | 173 | + |
174 | +&logic_shift rd rn rm sf sa st n | 174 | +&logic_shift rd rn rm sf sa st n |
175 | +@logic_shift sf:1 .. ..... st:2 n:1 rm:5 sa:6 rn:5 rd:5 &logic_shift | 175 | +@logic_shift sf:1 .. ..... st:2 n:1 rm:5 sa:6 rn:5 rd:5 &logic_shift |
176 | + | 176 | + |
177 | +AND_r . 00 01010 .. . ..... ...... ..... ..... @logic_shift | 177 | +AND_r . 00 01010 .. . ..... ...... ..... ..... @logic_shift |
178 | +ORR_r . 01 01010 .. . ..... ...... ..... ..... @logic_shift | 178 | +ORR_r . 01 01010 .. . ..... ...... ..... ..... @logic_shift |
179 | +EOR_r . 10 01010 .. . ..... ...... ..... ..... @logic_shift | 179 | +EOR_r . 10 01010 .. . ..... ...... ..... ..... @logic_shift |
180 | +ANDS_r . 11 01010 .. . ..... ...... ..... ..... @logic_shift | 180 | +ANDS_r . 11 01010 .. . ..... ...... ..... ..... @logic_shift |
181 | + | 181 | + |
182 | # Add/subtract (shifted reg) | 182 | # Add/subtract (shifted reg) |
183 | # Add/subtract (extended reg) | 183 | # Add/subtract (extended reg) |
184 | # Add/subtract (carry) | 184 | # Add/subtract (carry) |
185 | -- | 185 | -- |
186 | 2.43.0 | 186 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes ADD, SUB, ADDS, SUBS (extended register). | 1 | This includes ADD, SUB, ADDS, SUBS (extended register). |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/tcg/translate-a64.c | 65 +++++++++++----------------------- | 6 | target/arm/tcg/translate-a64.c | 65 +++++++++++----------------------- |
7 | target/arm/tcg/a64.decode | 9 +++++ | 7 | target/arm/tcg/a64.decode | 9 +++++ |
8 | 2 files changed, 29 insertions(+), 45 deletions(-) | 8 | 2 files changed, 29 insertions(+), 45 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ TRANS(AND_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, false) | 14 | @@ -XXX,XX +XXX,XX @@ TRANS(AND_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, false) |
15 | TRANS(ANDS_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, true) | 15 | TRANS(ANDS_r, do_logic_reg, a, tcg_gen_and_i64, tcg_gen_andc_i64, true) |
16 | TRANS(EOR_r, do_logic_reg, a, tcg_gen_xor_i64, tcg_gen_eqv_i64, false) | 16 | TRANS(EOR_r, do_logic_reg, a, tcg_gen_xor_i64, tcg_gen_eqv_i64, false) |
17 | 17 | ||
18 | -/* | 18 | -/* |
19 | - * Add/subtract (extended register) | 19 | - * Add/subtract (extended register) |
20 | - * | 20 | - * |
21 | - * 31|30|29|28 24|23 22|21|20 16|15 13|12 10|9 5|4 0| | 21 | - * 31|30|29|28 24|23 22|21|20 16|15 13|12 10|9 5|4 0| |
22 | - * +--+--+--+-----------+-----+--+-------+------+------+----+----+ | 22 | - * +--+--+--+-----------+-----+--+-------+------+------+----+----+ |
23 | - * |sf|op| S| 0 1 0 1 1 | opt | 1| Rm |option| imm3 | Rn | Rd | | 23 | - * |sf|op| S| 0 1 0 1 1 | opt | 1| Rm |option| imm3 | Rn | Rd | |
24 | - * +--+--+--+-----------+-----+--+-------+------+------+----+----+ | 24 | - * +--+--+--+-----------+-----+--+-------+------+------+----+----+ |
25 | - * | 25 | - * |
26 | - * sf: 0 -> 32bit, 1 -> 64bit | 26 | - * sf: 0 -> 32bit, 1 -> 64bit |
27 | - * op: 0 -> add , 1 -> sub | 27 | - * op: 0 -> add , 1 -> sub |
28 | - * S: 1 -> set flags | 28 | - * S: 1 -> set flags |
29 | - * opt: 00 | 29 | - * opt: 00 |
30 | - * option: extension type (see DecodeRegExtend) | 30 | - * option: extension type (see DecodeRegExtend) |
31 | - * imm3: optional shift to Rm | 31 | - * imm3: optional shift to Rm |
32 | - * | 32 | - * |
33 | - * Rd = Rn + LSL(extend(Rm), amount) | 33 | - * Rd = Rn + LSL(extend(Rm), amount) |
34 | - */ | 34 | - */ |
35 | -static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) | 35 | -static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) |
36 | +static bool do_addsub_ext(DisasContext *s, arg_addsub_ext *a, | 36 | +static bool do_addsub_ext(DisasContext *s, arg_addsub_ext *a, |
37 | + bool sub_op, bool setflags) | 37 | + bool sub_op, bool setflags) |
38 | { | 38 | { |
39 | - int rd = extract32(insn, 0, 5); | 39 | - int rd = extract32(insn, 0, 5); |
40 | - int rn = extract32(insn, 5, 5); | 40 | - int rn = extract32(insn, 5, 5); |
41 | - int imm3 = extract32(insn, 10, 3); | 41 | - int imm3 = extract32(insn, 10, 3); |
42 | - int option = extract32(insn, 13, 3); | 42 | - int option = extract32(insn, 13, 3); |
43 | - int rm = extract32(insn, 16, 5); | 43 | - int rm = extract32(insn, 16, 5); |
44 | - int opt = extract32(insn, 22, 2); | 44 | - int opt = extract32(insn, 22, 2); |
45 | - bool setflags = extract32(insn, 29, 1); | 45 | - bool setflags = extract32(insn, 29, 1); |
46 | - bool sub_op = extract32(insn, 30, 1); | 46 | - bool sub_op = extract32(insn, 30, 1); |
47 | - bool sf = extract32(insn, 31, 1); | 47 | - bool sf = extract32(insn, 31, 1); |
48 | + TCGv_i64 tcg_rm, tcg_rn, tcg_rd, tcg_result; | 48 | + TCGv_i64 tcg_rm, tcg_rn, tcg_rd, tcg_result; |
49 | 49 | ||
50 | - TCGv_i64 tcg_rm, tcg_rn; /* temps */ | 50 | - TCGv_i64 tcg_rm, tcg_rn; /* temps */ |
51 | - TCGv_i64 tcg_rd; | 51 | - TCGv_i64 tcg_rd; |
52 | - TCGv_i64 tcg_result; | 52 | - TCGv_i64 tcg_result; |
53 | - | 53 | - |
54 | - if (imm3 > 4 || opt != 0) { | 54 | - if (imm3 > 4 || opt != 0) { |
55 | - unallocated_encoding(s); | 55 | - unallocated_encoding(s); |
56 | - return; | 56 | - return; |
57 | + if (a->sa > 4) { | 57 | + if (a->sa > 4) { |
58 | + return false; | 58 | + return false; |
59 | } | 59 | } |
60 | 60 | ||
61 | /* non-flag setting ops may use SP */ | 61 | /* non-flag setting ops may use SP */ |
62 | if (!setflags) { | 62 | if (!setflags) { |
63 | - tcg_rd = cpu_reg_sp(s, rd); | 63 | - tcg_rd = cpu_reg_sp(s, rd); |
64 | + tcg_rd = cpu_reg_sp(s, a->rd); | 64 | + tcg_rd = cpu_reg_sp(s, a->rd); |
65 | } else { | 65 | } else { |
66 | - tcg_rd = cpu_reg(s, rd); | 66 | - tcg_rd = cpu_reg(s, rd); |
67 | + tcg_rd = cpu_reg(s, a->rd); | 67 | + tcg_rd = cpu_reg(s, a->rd); |
68 | } | 68 | } |
69 | - tcg_rn = read_cpu_reg_sp(s, rn, sf); | 69 | - tcg_rn = read_cpu_reg_sp(s, rn, sf); |
70 | + tcg_rn = read_cpu_reg_sp(s, a->rn, a->sf); | 70 | + tcg_rn = read_cpu_reg_sp(s, a->rn, a->sf); |
71 | 71 | ||
72 | - tcg_rm = read_cpu_reg(s, rm, sf); | 72 | - tcg_rm = read_cpu_reg(s, rm, sf); |
73 | - ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3); | 73 | - ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3); |
74 | + tcg_rm = read_cpu_reg(s, a->rm, a->sf); | 74 | + tcg_rm = read_cpu_reg(s, a->rm, a->sf); |
75 | + ext_and_shift_reg(tcg_rm, tcg_rm, a->st, a->sa); | 75 | + ext_and_shift_reg(tcg_rm, tcg_rm, a->st, a->sa); |
76 | 76 | ||
77 | tcg_result = tcg_temp_new_i64(); | 77 | tcg_result = tcg_temp_new_i64(); |
78 | - | 78 | - |
79 | if (!setflags) { | 79 | if (!setflags) { |
80 | if (sub_op) { | 80 | if (sub_op) { |
81 | tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm); | 81 | tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm); |
82 | @@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) | 82 | @@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) |
83 | } | 83 | } |
84 | } else { | 84 | } else { |
85 | if (sub_op) { | 85 | if (sub_op) { |
86 | - gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm); | 86 | - gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm); |
87 | + gen_sub_CC(a->sf, tcg_result, tcg_rn, tcg_rm); | 87 | + gen_sub_CC(a->sf, tcg_result, tcg_rn, tcg_rm); |
88 | } else { | 88 | } else { |
89 | - gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm); | 89 | - gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm); |
90 | + gen_add_CC(a->sf, tcg_result, tcg_rn, tcg_rm); | 90 | + gen_add_CC(a->sf, tcg_result, tcg_rn, tcg_rm); |
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | - if (sf) { | 94 | - if (sf) { |
95 | + if (a->sf) { | 95 | + if (a->sf) { |
96 | tcg_gen_mov_i64(tcg_rd, tcg_result); | 96 | tcg_gen_mov_i64(tcg_rd, tcg_result); |
97 | } else { | 97 | } else { |
98 | tcg_gen_ext32u_i64(tcg_rd, tcg_result); | 98 | tcg_gen_ext32u_i64(tcg_rd, tcg_result); |
99 | } | 99 | } |
100 | + return true; | 100 | + return true; |
101 | } | 101 | } |
102 | 102 | ||
103 | +TRANS(ADD_ext, do_addsub_ext, a, false, false) | 103 | +TRANS(ADD_ext, do_addsub_ext, a, false, false) |
104 | +TRANS(SUB_ext, do_addsub_ext, a, true, false) | 104 | +TRANS(SUB_ext, do_addsub_ext, a, true, false) |
105 | +TRANS(ADDS_ext, do_addsub_ext, a, false, true) | 105 | +TRANS(ADDS_ext, do_addsub_ext, a, false, true) |
106 | +TRANS(SUBS_ext, do_addsub_ext, a, true, true) | 106 | +TRANS(SUBS_ext, do_addsub_ext, a, true, true) |
107 | + | 107 | + |
108 | /* | 108 | /* |
109 | * Add/subtract (shifted register) | 109 | * Add/subtract (shifted register) |
110 | * | 110 | * |
111 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 111 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
112 | if (!op1) { | 112 | if (!op1) { |
113 | if (op2 & 8) { | 113 | if (op2 & 8) { |
114 | if (op2 & 1) { | 114 | if (op2 & 1) { |
115 | - /* Add/sub (extended register) */ | 115 | - /* Add/sub (extended register) */ |
116 | - disas_add_sub_ext_reg(s, insn); | 116 | - disas_add_sub_ext_reg(s, insn); |
117 | + goto do_unallocated; | 117 | + goto do_unallocated; |
118 | } else { | 118 | } else { |
119 | /* Add/sub (shifted register) */ | 119 | /* Add/sub (shifted register) */ |
120 | disas_add_sub_reg(s, insn); | 120 | disas_add_sub_reg(s, insn); |
121 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 121 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
122 | index XXXXXXX..XXXXXXX 100644 | 122 | index XXXXXXX..XXXXXXX 100644 |
123 | --- a/target/arm/tcg/a64.decode | 123 | --- a/target/arm/tcg/a64.decode |
124 | +++ b/target/arm/tcg/a64.decode | 124 | +++ b/target/arm/tcg/a64.decode |
125 | @@ -XXX,XX +XXX,XX @@ ANDS_r . 11 01010 .. . ..... ...... ..... ..... @logic_shift | 125 | @@ -XXX,XX +XXX,XX @@ ANDS_r . 11 01010 .. . ..... ...... ..... ..... @logic_shift |
126 | 126 | ||
127 | # Add/subtract (shifted reg) | 127 | # Add/subtract (shifted reg) |
128 | # Add/subtract (extended reg) | 128 | # Add/subtract (extended reg) |
129 | + | 129 | + |
130 | +&addsub_ext rd rn rm sf sa st | 130 | +&addsub_ext rd rn rm sf sa st |
131 | +@addsub_ext sf:1 .. ........ rm:5 st:3 sa:3 rn:5 rd:5 &addsub_ext | 131 | +@addsub_ext sf:1 .. ........ rm:5 st:3 sa:3 rn:5 rd:5 &addsub_ext |
132 | + | 132 | + |
133 | +ADD_ext . 00 01011001 ..... ... ... ..... ..... @addsub_ext | 133 | +ADD_ext . 00 01011001 ..... ... ... ..... ..... @addsub_ext |
134 | +SUB_ext . 10 01011001 ..... ... ... ..... ..... @addsub_ext | 134 | +SUB_ext . 10 01011001 ..... ... ... ..... ..... @addsub_ext |
135 | +ADDS_ext . 01 01011001 ..... ... ... ..... ..... @addsub_ext | 135 | +ADDS_ext . 01 01011001 ..... ... ... ..... ..... @addsub_ext |
136 | +SUBS_ext . 11 01011001 ..... ... ... ..... ..... @addsub_ext | 136 | +SUBS_ext . 11 01011001 ..... ... ... ..... ..... @addsub_ext |
137 | + | 137 | + |
138 | # Add/subtract (carry) | 138 | # Add/subtract (carry) |
139 | # Rotate right into flags | 139 | # Rotate right into flags |
140 | # Evaluate into flags | 140 | # Evaluate into flags |
141 | -- | 141 | -- |
142 | 2.43.0 | 142 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes ADD, SUB, ADDS, SUBS (shifted register). | 1 | This includes ADD, SUB, ADDS, SUBS (shifted register). |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/tcg/translate-a64.c | 64 ++++++++++------------------------ | 6 | target/arm/tcg/translate-a64.c | 64 ++++++++++------------------------ |
7 | target/arm/tcg/a64.decode | 9 +++++ | 7 | target/arm/tcg/a64.decode | 9 +++++ |
8 | 2 files changed, 27 insertions(+), 46 deletions(-) | 8 | 2 files changed, 27 insertions(+), 46 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ TRANS(SUB_ext, do_addsub_ext, a, true, false) | 14 | @@ -XXX,XX +XXX,XX @@ TRANS(SUB_ext, do_addsub_ext, a, true, false) |
15 | TRANS(ADDS_ext, do_addsub_ext, a, false, true) | 15 | TRANS(ADDS_ext, do_addsub_ext, a, false, true) |
16 | TRANS(SUBS_ext, do_addsub_ext, a, true, true) | 16 | TRANS(SUBS_ext, do_addsub_ext, a, true, true) |
17 | 17 | ||
18 | -/* | 18 | -/* |
19 | - * Add/subtract (shifted register) | 19 | - * Add/subtract (shifted register) |
20 | - * | 20 | - * |
21 | - * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 | 21 | - * 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0 |
22 | - * +--+--+--+-----------+-----+--+-------+---------+------+------+ | 22 | - * +--+--+--+-----------+-----+--+-------+---------+------+------+ |
23 | - * |sf|op| S| 0 1 0 1 1 |shift| 0| Rm | imm6 | Rn | Rd | | 23 | - * |sf|op| S| 0 1 0 1 1 |shift| 0| Rm | imm6 | Rn | Rd | |
24 | - * +--+--+--+-----------+-----+--+-------+---------+------+------+ | 24 | - * +--+--+--+-----------+-----+--+-------+---------+------+------+ |
25 | - * | 25 | - * |
26 | - * sf: 0 -> 32bit, 1 -> 64bit | 26 | - * sf: 0 -> 32bit, 1 -> 64bit |
27 | - * op: 0 -> add , 1 -> sub | 27 | - * op: 0 -> add , 1 -> sub |
28 | - * S: 1 -> set flags | 28 | - * S: 1 -> set flags |
29 | - * shift: 00 -> LSL, 01 -> LSR, 10 -> ASR, 11 -> RESERVED | 29 | - * shift: 00 -> LSL, 01 -> LSR, 10 -> ASR, 11 -> RESERVED |
30 | - * imm6: Shift amount to apply to Rm before the add/sub | 30 | - * imm6: Shift amount to apply to Rm before the add/sub |
31 | - */ | 31 | - */ |
32 | -static void disas_add_sub_reg(DisasContext *s, uint32_t insn) | 32 | -static void disas_add_sub_reg(DisasContext *s, uint32_t insn) |
33 | +static bool do_addsub_reg(DisasContext *s, arg_addsub_shift *a, | 33 | +static bool do_addsub_reg(DisasContext *s, arg_addsub_shift *a, |
34 | + bool sub_op, bool setflags) | 34 | + bool sub_op, bool setflags) |
35 | { | 35 | { |
36 | - int rd = extract32(insn, 0, 5); | 36 | - int rd = extract32(insn, 0, 5); |
37 | - int rn = extract32(insn, 5, 5); | 37 | - int rn = extract32(insn, 5, 5); |
38 | - int imm6 = extract32(insn, 10, 6); | 38 | - int imm6 = extract32(insn, 10, 6); |
39 | - int rm = extract32(insn, 16, 5); | 39 | - int rm = extract32(insn, 16, 5); |
40 | - int shift_type = extract32(insn, 22, 2); | 40 | - int shift_type = extract32(insn, 22, 2); |
41 | - bool setflags = extract32(insn, 29, 1); | 41 | - bool setflags = extract32(insn, 29, 1); |
42 | - bool sub_op = extract32(insn, 30, 1); | 42 | - bool sub_op = extract32(insn, 30, 1); |
43 | - bool sf = extract32(insn, 31, 1); | 43 | - bool sf = extract32(insn, 31, 1); |
44 | + TCGv_i64 tcg_rd, tcg_rn, tcg_rm, tcg_result; | 44 | + TCGv_i64 tcg_rd, tcg_rn, tcg_rm, tcg_result; |
45 | 45 | ||
46 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); | 46 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); |
47 | - TCGv_i64 tcg_rn, tcg_rm; | 47 | - TCGv_i64 tcg_rn, tcg_rm; |
48 | - TCGv_i64 tcg_result; | 48 | - TCGv_i64 tcg_result; |
49 | - | 49 | - |
50 | - if ((shift_type == 3) || (!sf && (imm6 > 31))) { | 50 | - if ((shift_type == 3) || (!sf && (imm6 > 31))) { |
51 | - unallocated_encoding(s); | 51 | - unallocated_encoding(s); |
52 | - return; | 52 | - return; |
53 | + if (a->st == 3 || (!a->sf && (a->sa & 32))) { | 53 | + if (a->st == 3 || (!a->sf && (a->sa & 32))) { |
54 | + return false; | 54 | + return false; |
55 | } | 55 | } |
56 | 56 | ||
57 | - tcg_rn = read_cpu_reg(s, rn, sf); | 57 | - tcg_rn = read_cpu_reg(s, rn, sf); |
58 | - tcg_rm = read_cpu_reg(s, rm, sf); | 58 | - tcg_rm = read_cpu_reg(s, rm, sf); |
59 | + tcg_rd = cpu_reg(s, a->rd); | 59 | + tcg_rd = cpu_reg(s, a->rd); |
60 | + tcg_rn = read_cpu_reg(s, a->rn, a->sf); | 60 | + tcg_rn = read_cpu_reg(s, a->rn, a->sf); |
61 | + tcg_rm = read_cpu_reg(s, a->rm, a->sf); | 61 | + tcg_rm = read_cpu_reg(s, a->rm, a->sf); |
62 | 62 | ||
63 | - shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6); | 63 | - shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6); |
64 | + shift_reg_imm(tcg_rm, tcg_rm, a->sf, a->st, a->sa); | 64 | + shift_reg_imm(tcg_rm, tcg_rm, a->sf, a->st, a->sa); |
65 | 65 | ||
66 | tcg_result = tcg_temp_new_i64(); | 66 | tcg_result = tcg_temp_new_i64(); |
67 | - | 67 | - |
68 | if (!setflags) { | 68 | if (!setflags) { |
69 | if (sub_op) { | 69 | if (sub_op) { |
70 | tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm); | 70 | tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm); |
71 | @@ -XXX,XX +XXX,XX @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn) | 71 | @@ -XXX,XX +XXX,XX @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn) |
72 | } | 72 | } |
73 | } else { | 73 | } else { |
74 | if (sub_op) { | 74 | if (sub_op) { |
75 | - gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm); | 75 | - gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm); |
76 | + gen_sub_CC(a->sf, tcg_result, tcg_rn, tcg_rm); | 76 | + gen_sub_CC(a->sf, tcg_result, tcg_rn, tcg_rm); |
77 | } else { | 77 | } else { |
78 | - gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm); | 78 | - gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm); |
79 | + gen_add_CC(a->sf, tcg_result, tcg_rn, tcg_rm); | 79 | + gen_add_CC(a->sf, tcg_result, tcg_rn, tcg_rm); |
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | - if (sf) { | 83 | - if (sf) { |
84 | + if (a->sf) { | 84 | + if (a->sf) { |
85 | tcg_gen_mov_i64(tcg_rd, tcg_result); | 85 | tcg_gen_mov_i64(tcg_rd, tcg_result); |
86 | } else { | 86 | } else { |
87 | tcg_gen_ext32u_i64(tcg_rd, tcg_result); | 87 | tcg_gen_ext32u_i64(tcg_rd, tcg_result); |
88 | } | 88 | } |
89 | + return true; | 89 | + return true; |
90 | } | 90 | } |
91 | 91 | ||
92 | +TRANS(ADD_r, do_addsub_reg, a, false, false) | 92 | +TRANS(ADD_r, do_addsub_reg, a, false, false) |
93 | +TRANS(SUB_r, do_addsub_reg, a, true, false) | 93 | +TRANS(SUB_r, do_addsub_reg, a, true, false) |
94 | +TRANS(ADDS_r, do_addsub_reg, a, false, true) | 94 | +TRANS(ADDS_r, do_addsub_reg, a, false, true) |
95 | +TRANS(SUBS_r, do_addsub_reg, a, true, true) | 95 | +TRANS(SUBS_r, do_addsub_reg, a, true, true) |
96 | + | 96 | + |
97 | /* Data-processing (3 source) | 97 | /* Data-processing (3 source) |
98 | * | 98 | * |
99 | * 31 30 29 28 24 23 21 20 16 15 14 10 9 5 4 0 | 99 | * 31 30 29 28 24 23 21 20 16 15 14 10 9 5 4 0 |
100 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 100 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
101 | int op3 = extract32(insn, 10, 6); | 101 | int op3 = extract32(insn, 10, 6); |
102 | 102 | ||
103 | if (!op1) { | 103 | if (!op1) { |
104 | - if (op2 & 8) { | 104 | - if (op2 & 8) { |
105 | - if (op2 & 1) { | 105 | - if (op2 & 1) { |
106 | - goto do_unallocated; | 106 | - goto do_unallocated; |
107 | - } else { | 107 | - } else { |
108 | - /* Add/sub (shifted register) */ | 108 | - /* Add/sub (shifted register) */ |
109 | - disas_add_sub_reg(s, insn); | 109 | - disas_add_sub_reg(s, insn); |
110 | - } | 110 | - } |
111 | - return; | 111 | - return; |
112 | - } | 112 | - } |
113 | goto do_unallocated; | 113 | goto do_unallocated; |
114 | } | 114 | } |
115 | 115 | ||
116 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 116 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
117 | index XXXXXXX..XXXXXXX 100644 | 117 | index XXXXXXX..XXXXXXX 100644 |
118 | --- a/target/arm/tcg/a64.decode | 118 | --- a/target/arm/tcg/a64.decode |
119 | +++ b/target/arm/tcg/a64.decode | 119 | +++ b/target/arm/tcg/a64.decode |
120 | @@ -XXX,XX +XXX,XX @@ EOR_r . 10 01010 .. . ..... ...... ..... ..... @logic_shift | 120 | @@ -XXX,XX +XXX,XX @@ EOR_r . 10 01010 .. . ..... ...... ..... ..... @logic_shift |
121 | ANDS_r . 11 01010 .. . ..... ...... ..... ..... @logic_shift | 121 | ANDS_r . 11 01010 .. . ..... ...... ..... ..... @logic_shift |
122 | 122 | ||
123 | # Add/subtract (shifted reg) | 123 | # Add/subtract (shifted reg) |
124 | + | 124 | + |
125 | +&addsub_shift rd rn rm sf sa st | 125 | +&addsub_shift rd rn rm sf sa st |
126 | +@addsub_shift sf:1 .. ..... st:2 . rm:5 sa:6 rn:5 rd:5 &addsub_shift | 126 | +@addsub_shift sf:1 .. ..... st:2 . rm:5 sa:6 rn:5 rd:5 &addsub_shift |
127 | + | 127 | + |
128 | +ADD_r . 00 01011 .. 0 ..... ...... ..... ..... @addsub_shift | 128 | +ADD_r . 00 01011 .. 0 ..... ...... ..... ..... @addsub_shift |
129 | +SUB_r . 10 01011 .. 0 ..... ...... ..... ..... @addsub_shift | 129 | +SUB_r . 10 01011 .. 0 ..... ...... ..... ..... @addsub_shift |
130 | +ADDS_r . 01 01011 .. 0 ..... ...... ..... ..... @addsub_shift | 130 | +ADDS_r . 01 01011 .. 0 ..... ...... ..... ..... @addsub_shift |
131 | +SUBS_r . 11 01011 .. 0 ..... ...... ..... ..... @addsub_shift | 131 | +SUBS_r . 11 01011 .. 0 ..... ...... ..... ..... @addsub_shift |
132 | + | 132 | + |
133 | # Add/subtract (extended reg) | 133 | # Add/subtract (extended reg) |
134 | 134 | ||
135 | &addsub_ext rd rn rm sf sa st | 135 | &addsub_ext rd rn rm sf sa st |
136 | -- | 136 | -- |
137 | 2.43.0 | 137 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes MADD, MSUB, SMADDL, SMSUBL, UMADDL, UMSUBL, SMULH, UMULH. | 1 | This includes MADD, MSUB, SMADDL, SMSUBL, UMADDL, UMSUBL, SMULH, UMULH. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/tcg/translate-a64.c | 119 ++++++++++++--------------------- | 6 | target/arm/tcg/translate-a64.c | 119 ++++++++++++--------------------- |
7 | target/arm/tcg/a64.decode | 16 +++++ | 7 | target/arm/tcg/a64.decode | 16 +++++ |
8 | 2 files changed, 59 insertions(+), 76 deletions(-) | 8 | 2 files changed, 59 insertions(+), 76 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ TRANS(SUB_r, do_addsub_reg, a, true, false) | 14 | @@ -XXX,XX +XXX,XX @@ TRANS(SUB_r, do_addsub_reg, a, true, false) |
15 | TRANS(ADDS_r, do_addsub_reg, a, false, true) | 15 | TRANS(ADDS_r, do_addsub_reg, a, false, true) |
16 | TRANS(SUBS_r, do_addsub_reg, a, true, true) | 16 | TRANS(SUBS_r, do_addsub_reg, a, true, true) |
17 | 17 | ||
18 | -/* Data-processing (3 source) | 18 | -/* Data-processing (3 source) |
19 | - * | 19 | - * |
20 | - * 31 30 29 28 24 23 21 20 16 15 14 10 9 5 4 0 | 20 | - * 31 30 29 28 24 23 21 20 16 15 14 10 9 5 4 0 |
21 | - * +--+------+-----------+------+------+----+------+------+------+ | 21 | - * +--+------+-----------+------+------+----+------+------+------+ |
22 | - * |sf| op54 | 1 1 0 1 1 | op31 | Rm | o0 | Ra | Rn | Rd | | 22 | - * |sf| op54 | 1 1 0 1 1 | op31 | Rm | o0 | Ra | Rn | Rd | |
23 | - * +--+------+-----------+------+------+----+------+------+------+ | 23 | - * +--+------+-----------+------+------+----+------+------+------+ |
24 | - */ | 24 | - */ |
25 | -static void disas_data_proc_3src(DisasContext *s, uint32_t insn) | 25 | -static void disas_data_proc_3src(DisasContext *s, uint32_t insn) |
26 | +static bool do_mulh(DisasContext *s, arg_rrr *a, | 26 | +static bool do_mulh(DisasContext *s, arg_rrr *a, |
27 | + void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) | 27 | + void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) |
28 | { | 28 | { |
29 | - int rd = extract32(insn, 0, 5); | 29 | - int rd = extract32(insn, 0, 5); |
30 | - int rn = extract32(insn, 5, 5); | 30 | - int rn = extract32(insn, 5, 5); |
31 | - int ra = extract32(insn, 10, 5); | 31 | - int ra = extract32(insn, 10, 5); |
32 | - int rm = extract32(insn, 16, 5); | 32 | - int rm = extract32(insn, 16, 5); |
33 | - int op_id = (extract32(insn, 29, 3) << 4) | | 33 | - int op_id = (extract32(insn, 29, 3) << 4) | |
34 | - (extract32(insn, 21, 3) << 1) | | 34 | - (extract32(insn, 21, 3) << 1) | |
35 | - extract32(insn, 15, 1); | 35 | - extract32(insn, 15, 1); |
36 | - bool sf = extract32(insn, 31, 1); | 36 | - bool sf = extract32(insn, 31, 1); |
37 | - bool is_sub = extract32(op_id, 0, 1); | 37 | - bool is_sub = extract32(op_id, 0, 1); |
38 | - bool is_high = extract32(op_id, 2, 1); | 38 | - bool is_high = extract32(op_id, 2, 1); |
39 | - bool is_signed = false; | 39 | - bool is_signed = false; |
40 | - TCGv_i64 tcg_op1; | 40 | - TCGv_i64 tcg_op1; |
41 | - TCGv_i64 tcg_op2; | 41 | - TCGv_i64 tcg_op2; |
42 | - TCGv_i64 tcg_tmp; | 42 | - TCGv_i64 tcg_tmp; |
43 | + TCGv_i64 discard = tcg_temp_new_i64(); | 43 | + TCGv_i64 discard = tcg_temp_new_i64(); |
44 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 44 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
45 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); | 45 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); |
46 | + TCGv_i64 tcg_rm = cpu_reg(s, a->rm); | 46 | + TCGv_i64 tcg_rm = cpu_reg(s, a->rm); |
47 | 47 | ||
48 | - /* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */ | 48 | - /* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */ |
49 | - switch (op_id) { | 49 | - switch (op_id) { |
50 | - case 0x42: /* SMADDL */ | 50 | - case 0x42: /* SMADDL */ |
51 | - case 0x43: /* SMSUBL */ | 51 | - case 0x43: /* SMSUBL */ |
52 | - case 0x44: /* SMULH */ | 52 | - case 0x44: /* SMULH */ |
53 | - is_signed = true; | 53 | - is_signed = true; |
54 | - break; | 54 | - break; |
55 | - case 0x0: /* MADD (32bit) */ | 55 | - case 0x0: /* MADD (32bit) */ |
56 | - case 0x1: /* MSUB (32bit) */ | 56 | - case 0x1: /* MSUB (32bit) */ |
57 | - case 0x40: /* MADD (64bit) */ | 57 | - case 0x40: /* MADD (64bit) */ |
58 | - case 0x41: /* MSUB (64bit) */ | 58 | - case 0x41: /* MSUB (64bit) */ |
59 | - case 0x4a: /* UMADDL */ | 59 | - case 0x4a: /* UMADDL */ |
60 | - case 0x4b: /* UMSUBL */ | 60 | - case 0x4b: /* UMSUBL */ |
61 | - case 0x4c: /* UMULH */ | 61 | - case 0x4c: /* UMULH */ |
62 | - break; | 62 | - break; |
63 | - default: | 63 | - default: |
64 | - unallocated_encoding(s); | 64 | - unallocated_encoding(s); |
65 | - return; | 65 | - return; |
66 | - } | 66 | - } |
67 | + fn(discard, tcg_rd, tcg_rn, tcg_rm); | 67 | + fn(discard, tcg_rd, tcg_rn, tcg_rm); |
68 | + return true; | 68 | + return true; |
69 | +} | 69 | +} |
70 | 70 | ||
71 | - if (is_high) { | 71 | - if (is_high) { |
72 | - TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */ | 72 | - TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */ |
73 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); | 73 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); |
74 | - TCGv_i64 tcg_rn = cpu_reg(s, rn); | 74 | - TCGv_i64 tcg_rn = cpu_reg(s, rn); |
75 | - TCGv_i64 tcg_rm = cpu_reg(s, rm); | 75 | - TCGv_i64 tcg_rm = cpu_reg(s, rm); |
76 | +TRANS(SMULH, do_mulh, a, tcg_gen_muls2_i64) | 76 | +TRANS(SMULH, do_mulh, a, tcg_gen_muls2_i64) |
77 | +TRANS(UMULH, do_mulh, a, tcg_gen_mulu2_i64) | 77 | +TRANS(UMULH, do_mulh, a, tcg_gen_mulu2_i64) |
78 | 78 | ||
79 | - if (is_signed) { | 79 | - if (is_signed) { |
80 | - tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm); | 80 | - tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm); |
81 | - } else { | 81 | - } else { |
82 | - tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm); | 82 | - tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm); |
83 | - } | 83 | - } |
84 | - return; | 84 | - return; |
85 | - } | 85 | - } |
86 | +static bool do_muladd(DisasContext *s, arg_rrrr *a, | 86 | +static bool do_muladd(DisasContext *s, arg_rrrr *a, |
87 | + bool sf, bool is_sub, MemOp mop) | 87 | + bool sf, bool is_sub, MemOp mop) |
88 | +{ | 88 | +{ |
89 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 89 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
90 | + TCGv_i64 tcg_op1, tcg_op2; | 90 | + TCGv_i64 tcg_op1, tcg_op2; |
91 | 91 | ||
92 | - tcg_op1 = tcg_temp_new_i64(); | 92 | - tcg_op1 = tcg_temp_new_i64(); |
93 | - tcg_op2 = tcg_temp_new_i64(); | 93 | - tcg_op2 = tcg_temp_new_i64(); |
94 | - tcg_tmp = tcg_temp_new_i64(); | 94 | - tcg_tmp = tcg_temp_new_i64(); |
95 | - | 95 | - |
96 | - if (op_id < 0x42) { | 96 | - if (op_id < 0x42) { |
97 | - tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn)); | 97 | - tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn)); |
98 | - tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm)); | 98 | - tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm)); |
99 | + if (mop == MO_64) { | 99 | + if (mop == MO_64) { |
100 | + tcg_op1 = cpu_reg(s, a->rn); | 100 | + tcg_op1 = cpu_reg(s, a->rn); |
101 | + tcg_op2 = cpu_reg(s, a->rm); | 101 | + tcg_op2 = cpu_reg(s, a->rm); |
102 | } else { | 102 | } else { |
103 | - if (is_signed) { | 103 | - if (is_signed) { |
104 | - tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn)); | 104 | - tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn)); |
105 | - tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm)); | 105 | - tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm)); |
106 | - } else { | 106 | - } else { |
107 | - tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn)); | 107 | - tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn)); |
108 | - tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm)); | 108 | - tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm)); |
109 | - } | 109 | - } |
110 | + tcg_op1 = tcg_temp_new_i64(); | 110 | + tcg_op1 = tcg_temp_new_i64(); |
111 | + tcg_op2 = tcg_temp_new_i64(); | 111 | + tcg_op2 = tcg_temp_new_i64(); |
112 | + tcg_gen_ext_i64(tcg_op1, cpu_reg(s, a->rn), mop); | 112 | + tcg_gen_ext_i64(tcg_op1, cpu_reg(s, a->rn), mop); |
113 | + tcg_gen_ext_i64(tcg_op2, cpu_reg(s, a->rm), mop); | 113 | + tcg_gen_ext_i64(tcg_op2, cpu_reg(s, a->rm), mop); |
114 | } | 114 | } |
115 | 115 | ||
116 | - if (ra == 31 && !is_sub) { | 116 | - if (ra == 31 && !is_sub) { |
117 | + if (a->ra == 31 && !is_sub) { | 117 | + if (a->ra == 31 && !is_sub) { |
118 | /* Special-case MADD with rA == XZR; it is the standard MUL alias */ | 118 | /* Special-case MADD with rA == XZR; it is the standard MUL alias */ |
119 | - tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2); | 119 | - tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2); |
120 | + tcg_gen_mul_i64(tcg_rd, tcg_op1, tcg_op2); | 120 | + tcg_gen_mul_i64(tcg_rd, tcg_op1, tcg_op2); |
121 | } else { | 121 | } else { |
122 | + TCGv_i64 tcg_tmp = tcg_temp_new_i64(); | 122 | + TCGv_i64 tcg_tmp = tcg_temp_new_i64(); |
123 | + TCGv_i64 tcg_ra = cpu_reg(s, a->ra); | 123 | + TCGv_i64 tcg_ra = cpu_reg(s, a->ra); |
124 | + | 124 | + |
125 | tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2); | 125 | tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2); |
126 | if (is_sub) { | 126 | if (is_sub) { |
127 | - tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp); | 127 | - tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp); |
128 | + tcg_gen_sub_i64(tcg_rd, tcg_ra, tcg_tmp); | 128 | + tcg_gen_sub_i64(tcg_rd, tcg_ra, tcg_tmp); |
129 | } else { | 129 | } else { |
130 | - tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp); | 130 | - tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp); |
131 | + tcg_gen_add_i64(tcg_rd, tcg_ra, tcg_tmp); | 131 | + tcg_gen_add_i64(tcg_rd, tcg_ra, tcg_tmp); |
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | if (!sf) { | 135 | if (!sf) { |
136 | - tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd)); | 136 | - tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd)); |
137 | + tcg_gen_ext32u_i64(tcg_rd, tcg_rd); | 137 | + tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
138 | } | 138 | } |
139 | + return true; | 139 | + return true; |
140 | } | 140 | } |
141 | 141 | ||
142 | +TRANS(MADD_w, do_muladd, a, false, false, MO_64) | 142 | +TRANS(MADD_w, do_muladd, a, false, false, MO_64) |
143 | +TRANS(MSUB_w, do_muladd, a, false, true, MO_64) | 143 | +TRANS(MSUB_w, do_muladd, a, false, true, MO_64) |
144 | +TRANS(MADD_x, do_muladd, a, true, false, MO_64) | 144 | +TRANS(MADD_x, do_muladd, a, true, false, MO_64) |
145 | +TRANS(MSUB_x, do_muladd, a, true, true, MO_64) | 145 | +TRANS(MSUB_x, do_muladd, a, true, true, MO_64) |
146 | + | 146 | + |
147 | +TRANS(SMADDL, do_muladd, a, true, false, MO_SL) | 147 | +TRANS(SMADDL, do_muladd, a, true, false, MO_SL) |
148 | +TRANS(SMSUBL, do_muladd, a, true, true, MO_SL) | 148 | +TRANS(SMSUBL, do_muladd, a, true, true, MO_SL) |
149 | +TRANS(UMADDL, do_muladd, a, true, false, MO_UL) | 149 | +TRANS(UMADDL, do_muladd, a, true, false, MO_UL) |
150 | +TRANS(UMSUBL, do_muladd, a, true, true, MO_UL) | 150 | +TRANS(UMSUBL, do_muladd, a, true, true, MO_UL) |
151 | + | 151 | + |
152 | /* Add/subtract (with carry) | 152 | /* Add/subtract (with carry) |
153 | * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0 | 153 | * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0 |
154 | * +--+--+--+------------------------+------+-------------+------+-----+ | 154 | * +--+--+--+------------------------+------+-------------+------+-----+ |
155 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 155 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
156 | disas_cond_select(s, insn); | 156 | disas_cond_select(s, insn); |
157 | break; | 157 | break; |
158 | 158 | ||
159 | - case 0x8 ... 0xf: /* (3 source) */ | 159 | - case 0x8 ... 0xf: /* (3 source) */ |
160 | - disas_data_proc_3src(s, insn); | 160 | - disas_data_proc_3src(s, insn); |
161 | - break; | 161 | - break; |
162 | - | 162 | - |
163 | default: | 163 | default: |
164 | do_unallocated: | 164 | do_unallocated: |
165 | case 0x6: /* Data-processing */ | 165 | case 0x6: /* Data-processing */ |
166 | + case 0x8 ... 0xf: /* (3 source) */ | 166 | + case 0x8 ... 0xf: /* (3 source) */ |
167 | unallocated_encoding(s); | 167 | unallocated_encoding(s); |
168 | break; | 168 | break; |
169 | } | 169 | } |
170 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 170 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
171 | index XXXXXXX..XXXXXXX 100644 | 171 | index XXXXXXX..XXXXXXX 100644 |
172 | --- a/target/arm/tcg/a64.decode | 172 | --- a/target/arm/tcg/a64.decode |
173 | +++ b/target/arm/tcg/a64.decode | 173 | +++ b/target/arm/tcg/a64.decode |
174 | @@ -XXX,XX +XXX,XX @@ SUBS_ext . 11 01011001 ..... ... ... ..... ..... @addsub_ext | 174 | @@ -XXX,XX +XXX,XX @@ SUBS_ext . 11 01011001 ..... ... ... ..... ..... @addsub_ext |
175 | # Conditional select | 175 | # Conditional select |
176 | # Data Processing (3-source) | 176 | # Data Processing (3-source) |
177 | 177 | ||
178 | +&rrrr rd rn rm ra | 178 | +&rrrr rd rn rm ra |
179 | +@rrrr . .. ........ rm:5 . ra:5 rn:5 rd:5 &rrrr | 179 | +@rrrr . .. ........ rm:5 . ra:5 rn:5 rd:5 &rrrr |
180 | + | 180 | + |
181 | +MADD_w 0 00 11011000 ..... 0 ..... ..... ..... @rrrr | 181 | +MADD_w 0 00 11011000 ..... 0 ..... ..... ..... @rrrr |
182 | +MSUB_w 0 00 11011000 ..... 1 ..... ..... ..... @rrrr | 182 | +MSUB_w 0 00 11011000 ..... 1 ..... ..... ..... @rrrr |
183 | +MADD_x 1 00 11011000 ..... 0 ..... ..... ..... @rrrr | 183 | +MADD_x 1 00 11011000 ..... 0 ..... ..... ..... @rrrr |
184 | +MSUB_x 1 00 11011000 ..... 1 ..... ..... ..... @rrrr | 184 | +MSUB_x 1 00 11011000 ..... 1 ..... ..... ..... @rrrr |
185 | + | 185 | + |
186 | +SMADDL 1 00 11011001 ..... 0 ..... ..... ..... @rrrr | 186 | +SMADDL 1 00 11011001 ..... 0 ..... ..... ..... @rrrr |
187 | +SMSUBL 1 00 11011001 ..... 1 ..... ..... ..... @rrrr | 187 | +SMSUBL 1 00 11011001 ..... 1 ..... ..... ..... @rrrr |
188 | +UMADDL 1 00 11011101 ..... 0 ..... ..... ..... @rrrr | 188 | +UMADDL 1 00 11011101 ..... 0 ..... ..... ..... @rrrr |
189 | +UMSUBL 1 00 11011101 ..... 1 ..... ..... ..... @rrrr | 189 | +UMSUBL 1 00 11011101 ..... 1 ..... ..... ..... @rrrr |
190 | + | 190 | + |
191 | +SMULH 1 00 11011010 ..... 0 11111 ..... ..... @rrr | 191 | +SMULH 1 00 11011010 ..... 0 11111 ..... ..... @rrr |
192 | +UMULH 1 00 11011110 ..... 0 11111 ..... ..... @rrr | 192 | +UMULH 1 00 11011110 ..... 0 11111 ..... ..... @rrr |
193 | + | 193 | + |
194 | ### Cryptographic AES | 194 | ### Cryptographic AES |
195 | 195 | ||
196 | AESE 01001110 00 10100 00100 10 ..... ..... @r2r_q1e0 | 196 | AESE 01001110 00 10100 00100 10 ..... ..... @r2r_q1e0 |
197 | -- | 197 | -- |
198 | 2.43.0 | 198 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes ADC, SBC, ADCS, SBCS. | 1 | This includes ADC, SBC, ADCS, SBCS. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/tcg/translate-a64.c | 43 +++++++++++++--------------------- | 6 | target/arm/tcg/translate-a64.c | 43 +++++++++++++--------------------- |
7 | target/arm/tcg/a64.decode | 6 +++++ | 7 | target/arm/tcg/a64.decode | 6 +++++ |
8 | 2 files changed, 22 insertions(+), 27 deletions(-) | 8 | 2 files changed, 22 insertions(+), 27 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ TRANS(SMSUBL, do_muladd, a, true, true, MO_SL) | 14 | @@ -XXX,XX +XXX,XX @@ TRANS(SMSUBL, do_muladd, a, true, true, MO_SL) |
15 | TRANS(UMADDL, do_muladd, a, true, false, MO_UL) | 15 | TRANS(UMADDL, do_muladd, a, true, false, MO_UL) |
16 | TRANS(UMSUBL, do_muladd, a, true, true, MO_UL) | 16 | TRANS(UMSUBL, do_muladd, a, true, true, MO_UL) |
17 | 17 | ||
18 | -/* Add/subtract (with carry) | 18 | -/* Add/subtract (with carry) |
19 | - * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0 | 19 | - * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0 |
20 | - * +--+--+--+------------------------+------+-------------+------+-----+ | 20 | - * +--+--+--+------------------------+------+-------------+------+-----+ |
21 | - * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | 0 0 0 0 0 0 | Rn | Rd | | 21 | - * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | 0 0 0 0 0 0 | Rn | Rd | |
22 | - * +--+--+--+------------------------+------+-------------+------+-----+ | 22 | - * +--+--+--+------------------------+------+-------------+------+-----+ |
23 | - */ | 23 | - */ |
24 | - | 24 | - |
25 | -static void disas_adc_sbc(DisasContext *s, uint32_t insn) | 25 | -static void disas_adc_sbc(DisasContext *s, uint32_t insn) |
26 | +static bool do_adc_sbc(DisasContext *s, arg_rrr_sf *a, | 26 | +static bool do_adc_sbc(DisasContext *s, arg_rrr_sf *a, |
27 | + bool is_sub, bool setflags) | 27 | + bool is_sub, bool setflags) |
28 | { | 28 | { |
29 | - unsigned int sf, op, setflags, rm, rn, rd; | 29 | - unsigned int sf, op, setflags, rm, rn, rd; |
30 | TCGv_i64 tcg_y, tcg_rn, tcg_rd; | 30 | TCGv_i64 tcg_y, tcg_rn, tcg_rd; |
31 | 31 | ||
32 | - sf = extract32(insn, 31, 1); | 32 | - sf = extract32(insn, 31, 1); |
33 | - op = extract32(insn, 30, 1); | 33 | - op = extract32(insn, 30, 1); |
34 | - setflags = extract32(insn, 29, 1); | 34 | - setflags = extract32(insn, 29, 1); |
35 | - rm = extract32(insn, 16, 5); | 35 | - rm = extract32(insn, 16, 5); |
36 | - rn = extract32(insn, 5, 5); | 36 | - rn = extract32(insn, 5, 5); |
37 | - rd = extract32(insn, 0, 5); | 37 | - rd = extract32(insn, 0, 5); |
38 | + tcg_rd = cpu_reg(s, a->rd); | 38 | + tcg_rd = cpu_reg(s, a->rd); |
39 | + tcg_rn = cpu_reg(s, a->rn); | 39 | + tcg_rn = cpu_reg(s, a->rn); |
40 | 40 | ||
41 | - tcg_rd = cpu_reg(s, rd); | 41 | - tcg_rd = cpu_reg(s, rd); |
42 | - tcg_rn = cpu_reg(s, rn); | 42 | - tcg_rn = cpu_reg(s, rn); |
43 | - | 43 | - |
44 | - if (op) { | 44 | - if (op) { |
45 | + if (is_sub) { | 45 | + if (is_sub) { |
46 | tcg_y = tcg_temp_new_i64(); | 46 | tcg_y = tcg_temp_new_i64(); |
47 | - tcg_gen_not_i64(tcg_y, cpu_reg(s, rm)); | 47 | - tcg_gen_not_i64(tcg_y, cpu_reg(s, rm)); |
48 | + tcg_gen_not_i64(tcg_y, cpu_reg(s, a->rm)); | 48 | + tcg_gen_not_i64(tcg_y, cpu_reg(s, a->rm)); |
49 | } else { | 49 | } else { |
50 | - tcg_y = cpu_reg(s, rm); | 50 | - tcg_y = cpu_reg(s, rm); |
51 | + tcg_y = cpu_reg(s, a->rm); | 51 | + tcg_y = cpu_reg(s, a->rm); |
52 | } | 52 | } |
53 | 53 | ||
54 | if (setflags) { | 54 | if (setflags) { |
55 | - gen_adc_CC(sf, tcg_rd, tcg_rn, tcg_y); | 55 | - gen_adc_CC(sf, tcg_rd, tcg_rn, tcg_y); |
56 | + gen_adc_CC(a->sf, tcg_rd, tcg_rn, tcg_y); | 56 | + gen_adc_CC(a->sf, tcg_rd, tcg_rn, tcg_y); |
57 | } else { | 57 | } else { |
58 | - gen_adc(sf, tcg_rd, tcg_rn, tcg_y); | 58 | - gen_adc(sf, tcg_rd, tcg_rn, tcg_y); |
59 | + gen_adc(a->sf, tcg_rd, tcg_rn, tcg_y); | 59 | + gen_adc(a->sf, tcg_rd, tcg_rn, tcg_y); |
60 | } | 60 | } |
61 | + return true; | 61 | + return true; |
62 | } | 62 | } |
63 | 63 | ||
64 | +TRANS(ADC, do_adc_sbc, a, false, false) | 64 | +TRANS(ADC, do_adc_sbc, a, false, false) |
65 | +TRANS(SBC, do_adc_sbc, a, true, false) | 65 | +TRANS(SBC, do_adc_sbc, a, true, false) |
66 | +TRANS(ADCS, do_adc_sbc, a, false, true) | 66 | +TRANS(ADCS, do_adc_sbc, a, false, true) |
67 | +TRANS(SBCS, do_adc_sbc, a, true, true) | 67 | +TRANS(SBCS, do_adc_sbc, a, true, true) |
68 | + | 68 | + |
69 | /* | 69 | /* |
70 | * Rotate right into flags | 70 | * Rotate right into flags |
71 | * 31 30 29 21 15 10 5 4 0 | 71 | * 31 30 29 21 15 10 5 4 0 |
72 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 72 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
73 | switch (op2) { | 73 | switch (op2) { |
74 | case 0x0: | 74 | case 0x0: |
75 | switch (op3) { | 75 | switch (op3) { |
76 | - case 0x00: /* Add/subtract (with carry) */ | 76 | - case 0x00: /* Add/subtract (with carry) */ |
77 | - disas_adc_sbc(s, insn); | 77 | - disas_adc_sbc(s, insn); |
78 | - break; | 78 | - break; |
79 | - | 79 | - |
80 | case 0x01: /* Rotate right into flags */ | 80 | case 0x01: /* Rotate right into flags */ |
81 | case 0x21: | 81 | case 0x21: |
82 | disas_rotate_right_into_flags(s, insn); | 82 | disas_rotate_right_into_flags(s, insn); |
83 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 83 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
84 | break; | 84 | break; |
85 | 85 | ||
86 | default: | 86 | default: |
87 | + case 0x00: /* Add/subtract (with carry) */ | 87 | + case 0x00: /* Add/subtract (with carry) */ |
88 | goto do_unallocated; | 88 | goto do_unallocated; |
89 | } | 89 | } |
90 | break; | 90 | break; |
91 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 91 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
92 | index XXXXXXX..XXXXXXX 100644 | 92 | index XXXXXXX..XXXXXXX 100644 |
93 | --- a/target/arm/tcg/a64.decode | 93 | --- a/target/arm/tcg/a64.decode |
94 | +++ b/target/arm/tcg/a64.decode | 94 | +++ b/target/arm/tcg/a64.decode |
95 | @@ -XXX,XX +XXX,XX @@ ADDS_ext . 01 01011001 ..... ... ... ..... ..... @addsub_ext | 95 | @@ -XXX,XX +XXX,XX @@ ADDS_ext . 01 01011001 ..... ... ... ..... ..... @addsub_ext |
96 | SUBS_ext . 11 01011001 ..... ... ... ..... ..... @addsub_ext | 96 | SUBS_ext . 11 01011001 ..... ... ... ..... ..... @addsub_ext |
97 | 97 | ||
98 | # Add/subtract (carry) | 98 | # Add/subtract (carry) |
99 | + | 99 | + |
100 | +ADC . 00 11010000 ..... 000000 ..... ..... @rrr_sf | 100 | +ADC . 00 11010000 ..... 000000 ..... ..... @rrr_sf |
101 | +ADCS . 01 11010000 ..... 000000 ..... ..... @rrr_sf | 101 | +ADCS . 01 11010000 ..... 000000 ..... ..... @rrr_sf |
102 | +SBC . 10 11010000 ..... 000000 ..... ..... @rrr_sf | 102 | +SBC . 10 11010000 ..... 000000 ..... ..... @rrr_sf |
103 | +SBCS . 11 11010000 ..... 000000 ..... ..... @rrr_sf | 103 | +SBCS . 11 11010000 ..... 000000 ..... ..... @rrr_sf |
104 | + | 104 | + |
105 | # Rotate right into flags | 105 | # Rotate right into flags |
106 | # Evaluate into flags | 106 | # Evaluate into flags |
107 | # Conditional compare (regster) | 107 | # Conditional compare (regster) |
108 | -- | 108 | -- |
109 | 2.43.0 | 109 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 1 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 32 +++++++++----------------------- | 4 | target/arm/tcg/translate-a64.c | 32 +++++++++----------------------- |
5 | target/arm/tcg/a64.decode | 3 +++ | 5 | target/arm/tcg/a64.decode | 3 +++ |
6 | 2 files changed, 12 insertions(+), 23 deletions(-) | 6 | 2 files changed, 12 insertions(+), 23 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ TRANS(SBC, do_adc_sbc, a, true, false) | 12 | @@ -XXX,XX +XXX,XX @@ TRANS(SBC, do_adc_sbc, a, true, false) |
13 | TRANS(ADCS, do_adc_sbc, a, false, true) | 13 | TRANS(ADCS, do_adc_sbc, a, false, true) |
14 | TRANS(SBCS, do_adc_sbc, a, true, true) | 14 | TRANS(SBCS, do_adc_sbc, a, true, true) |
15 | 15 | ||
16 | -/* | 16 | -/* |
17 | - * Rotate right into flags | 17 | - * Rotate right into flags |
18 | - * 31 30 29 21 15 10 5 4 0 | 18 | - * 31 30 29 21 15 10 5 4 0 |
19 | - * +--+--+--+-----------------+--------+-----------+------+--+------+ | 19 | - * +--+--+--+-----------------+--------+-----------+------+--+------+ |
20 | - * |sf|op| S| 1 1 0 1 0 0 0 0 | imm6 | 0 0 0 0 1 | Rn |o2| mask | | 20 | - * |sf|op| S| 1 1 0 1 0 0 0 0 | imm6 | 0 0 0 0 1 | Rn |o2| mask | |
21 | - * +--+--+--+-----------------+--------+-----------+------+--+------+ | 21 | - * +--+--+--+-----------------+--------+-----------+------+--+------+ |
22 | - */ | 22 | - */ |
23 | -static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn) | 23 | -static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn) |
24 | +static bool trans_RMIF(DisasContext *s, arg_RMIF *a) | 24 | +static bool trans_RMIF(DisasContext *s, arg_RMIF *a) |
25 | { | 25 | { |
26 | - int mask = extract32(insn, 0, 4); | 26 | - int mask = extract32(insn, 0, 4); |
27 | - int o2 = extract32(insn, 4, 1); | 27 | - int o2 = extract32(insn, 4, 1); |
28 | - int rn = extract32(insn, 5, 5); | 28 | - int rn = extract32(insn, 5, 5); |
29 | - int imm6 = extract32(insn, 15, 6); | 29 | - int imm6 = extract32(insn, 15, 6); |
30 | - int sf_op_s = extract32(insn, 29, 3); | 30 | - int sf_op_s = extract32(insn, 29, 3); |
31 | + int mask = a->mask; | 31 | + int mask = a->mask; |
32 | TCGv_i64 tcg_rn; | 32 | TCGv_i64 tcg_rn; |
33 | TCGv_i32 nzcv; | 33 | TCGv_i32 nzcv; |
34 | 34 | ||
35 | - if (sf_op_s != 5 || o2 != 0 || !dc_isar_feature(aa64_condm_4, s)) { | 35 | - if (sf_op_s != 5 || o2 != 0 || !dc_isar_feature(aa64_condm_4, s)) { |
36 | - unallocated_encoding(s); | 36 | - unallocated_encoding(s); |
37 | - return; | 37 | - return; |
38 | + if (!dc_isar_feature(aa64_condm_4, s)) { | 38 | + if (!dc_isar_feature(aa64_condm_4, s)) { |
39 | + return false; | 39 | + return false; |
40 | } | 40 | } |
41 | 41 | ||
42 | - tcg_rn = read_cpu_reg(s, rn, 1); | 42 | - tcg_rn = read_cpu_reg(s, rn, 1); |
43 | - tcg_gen_rotri_i64(tcg_rn, tcg_rn, imm6); | 43 | - tcg_gen_rotri_i64(tcg_rn, tcg_rn, imm6); |
44 | + tcg_rn = read_cpu_reg(s, a->rn, 1); | 44 | + tcg_rn = read_cpu_reg(s, a->rn, 1); |
45 | + tcg_gen_rotri_i64(tcg_rn, tcg_rn, a->imm); | 45 | + tcg_gen_rotri_i64(tcg_rn, tcg_rn, a->imm); |
46 | 46 | ||
47 | nzcv = tcg_temp_new_i32(); | 47 | nzcv = tcg_temp_new_i32(); |
48 | tcg_gen_extrl_i64_i32(nzcv, tcg_rn); | 48 | tcg_gen_extrl_i64_i32(nzcv, tcg_rn); |
49 | @@ -XXX,XX +XXX,XX @@ static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn) | 49 | @@ -XXX,XX +XXX,XX @@ static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn) |
50 | if (mask & 1) { /* V */ | 50 | if (mask & 1) { /* V */ |
51 | tcg_gen_shli_i32(cpu_VF, nzcv, 31 - 0); | 51 | tcg_gen_shli_i32(cpu_VF, nzcv, 31 - 0); |
52 | } | 52 | } |
53 | + return true; | 53 | + return true; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* | 56 | /* |
57 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 57 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
58 | switch (op2) { | 58 | switch (op2) { |
59 | case 0x0: | 59 | case 0x0: |
60 | switch (op3) { | 60 | switch (op3) { |
61 | - case 0x01: /* Rotate right into flags */ | 61 | - case 0x01: /* Rotate right into flags */ |
62 | - case 0x21: | 62 | - case 0x21: |
63 | - disas_rotate_right_into_flags(s, insn); | 63 | - disas_rotate_right_into_flags(s, insn); |
64 | - break; | 64 | - break; |
65 | - | 65 | - |
66 | case 0x02: /* Evaluate into flags */ | 66 | case 0x02: /* Evaluate into flags */ |
67 | case 0x12: | 67 | case 0x12: |
68 | case 0x22: | 68 | case 0x22: |
69 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 69 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
70 | 70 | ||
71 | default: | 71 | default: |
72 | case 0x00: /* Add/subtract (with carry) */ | 72 | case 0x00: /* Add/subtract (with carry) */ |
73 | + case 0x01: /* Rotate right into flags */ | 73 | + case 0x01: /* Rotate right into flags */ |
74 | + case 0x21: | 74 | + case 0x21: |
75 | goto do_unallocated; | 75 | goto do_unallocated; |
76 | } | 76 | } |
77 | break; | 77 | break; |
78 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 78 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
79 | index XXXXXXX..XXXXXXX 100644 | 79 | index XXXXXXX..XXXXXXX 100644 |
80 | --- a/target/arm/tcg/a64.decode | 80 | --- a/target/arm/tcg/a64.decode |
81 | +++ b/target/arm/tcg/a64.decode | 81 | +++ b/target/arm/tcg/a64.decode |
82 | @@ -XXX,XX +XXX,XX @@ SBC . 10 11010000 ..... 000000 ..... ..... @rrr_sf | 82 | @@ -XXX,XX +XXX,XX @@ SBC . 10 11010000 ..... 000000 ..... ..... @rrr_sf |
83 | SBCS . 11 11010000 ..... 000000 ..... ..... @rrr_sf | 83 | SBCS . 11 11010000 ..... 000000 ..... ..... @rrr_sf |
84 | 84 | ||
85 | # Rotate right into flags | 85 | # Rotate right into flags |
86 | + | 86 | + |
87 | +RMIF 1 01 11010000 imm:6 00001 rn:5 0 mask:4 | 87 | +RMIF 1 01 11010000 imm:6 00001 rn:5 0 mask:4 |
88 | + | 88 | + |
89 | # Evaluate into flags | 89 | # Evaluate into flags |
90 | # Conditional compare (regster) | 90 | # Conditional compare (regster) |
91 | # Conditional compare (immediate) | 91 | # Conditional compare (immediate) |
92 | -- | 92 | -- |
93 | 2.43.0 | 93 | 2.43.0 |
94 | 94 | ||
95 | 95 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 48 +++++----------------------------- | 4 | target/arm/tcg/translate-a64.c | 48 +++++----------------------------- |
5 | target/arm/tcg/a64.decode | 4 +++ | 5 | target/arm/tcg/a64.decode | 4 +++ |
6 | 2 files changed, 11 insertions(+), 41 deletions(-) | 6 | 2 files changed, 11 insertions(+), 41 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool trans_RMIF(DisasContext *s, arg_RMIF *a) | 12 | @@ -XXX,XX +XXX,XX @@ static bool trans_RMIF(DisasContext *s, arg_RMIF *a) |
13 | return true; | 13 | return true; |
14 | } | 14 | } |
15 | 15 | ||
16 | -/* | 16 | -/* |
17 | - * Evaluate into flags | 17 | - * Evaluate into flags |
18 | - * 31 30 29 21 15 14 10 5 4 0 | 18 | - * 31 30 29 21 15 14 10 5 4 0 |
19 | - * +--+--+--+-----------------+---------+----+---------+------+--+------+ | 19 | - * +--+--+--+-----------------+---------+----+---------+------+--+------+ |
20 | - * |sf|op| S| 1 1 0 1 0 0 0 0 | opcode2 | sz | 0 0 1 0 | Rn |o3| mask | | 20 | - * |sf|op| S| 1 1 0 1 0 0 0 0 | opcode2 | sz | 0 0 1 0 | Rn |o3| mask | |
21 | - * +--+--+--+-----------------+---------+----+---------+------+--+------+ | 21 | - * +--+--+--+-----------------+---------+----+---------+------+--+------+ |
22 | - */ | 22 | - */ |
23 | -static void disas_evaluate_into_flags(DisasContext *s, uint32_t insn) | 23 | -static void disas_evaluate_into_flags(DisasContext *s, uint32_t insn) |
24 | +static bool do_setf(DisasContext *s, int rn, int shift) | 24 | +static bool do_setf(DisasContext *s, int rn, int shift) |
25 | { | 25 | { |
26 | - int o3_mask = extract32(insn, 0, 5); | 26 | - int o3_mask = extract32(insn, 0, 5); |
27 | - int rn = extract32(insn, 5, 5); | 27 | - int rn = extract32(insn, 5, 5); |
28 | - int o2 = extract32(insn, 15, 6); | 28 | - int o2 = extract32(insn, 15, 6); |
29 | - int sz = extract32(insn, 14, 1); | 29 | - int sz = extract32(insn, 14, 1); |
30 | - int sf_op_s = extract32(insn, 29, 3); | 30 | - int sf_op_s = extract32(insn, 29, 3); |
31 | - TCGv_i32 tmp; | 31 | - TCGv_i32 tmp; |
32 | - int shift; | 32 | - int shift; |
33 | + TCGv_i32 tmp = tcg_temp_new_i32(); | 33 | + TCGv_i32 tmp = tcg_temp_new_i32(); |
34 | 34 | ||
35 | - if (sf_op_s != 1 || o2 != 0 || o3_mask != 0xd || | 35 | - if (sf_op_s != 1 || o2 != 0 || o3_mask != 0xd || |
36 | - !dc_isar_feature(aa64_condm_4, s)) { | 36 | - !dc_isar_feature(aa64_condm_4, s)) { |
37 | - unallocated_encoding(s); | 37 | - unallocated_encoding(s); |
38 | - return; | 38 | - return; |
39 | - } | 39 | - } |
40 | - shift = sz ? 16 : 24; /* SETF16 or SETF8 */ | 40 | - shift = sz ? 16 : 24; /* SETF16 or SETF8 */ |
41 | - | 41 | - |
42 | - tmp = tcg_temp_new_i32(); | 42 | - tmp = tcg_temp_new_i32(); |
43 | tcg_gen_extrl_i64_i32(tmp, cpu_reg(s, rn)); | 43 | tcg_gen_extrl_i64_i32(tmp, cpu_reg(s, rn)); |
44 | tcg_gen_shli_i32(cpu_NF, tmp, shift); | 44 | tcg_gen_shli_i32(cpu_NF, tmp, shift); |
45 | tcg_gen_shli_i32(cpu_VF, tmp, shift - 1); | 45 | tcg_gen_shli_i32(cpu_VF, tmp, shift - 1); |
46 | tcg_gen_mov_i32(cpu_ZF, cpu_NF); | 46 | tcg_gen_mov_i32(cpu_ZF, cpu_NF); |
47 | tcg_gen_xor_i32(cpu_VF, cpu_VF, cpu_NF); | 47 | tcg_gen_xor_i32(cpu_VF, cpu_VF, cpu_NF); |
48 | + return true; | 48 | + return true; |
49 | } | 49 | } |
50 | 50 | ||
51 | +TRANS_FEAT(SETF8, aa64_condm_4, do_setf, a->rn, 24) | 51 | +TRANS_FEAT(SETF8, aa64_condm_4, do_setf, a->rn, 24) |
52 | +TRANS_FEAT(SETF16, aa64_condm_4, do_setf, a->rn, 16) | 52 | +TRANS_FEAT(SETF16, aa64_condm_4, do_setf, a->rn, 16) |
53 | + | 53 | + |
54 | /* Conditional compare (immediate / register) | 54 | /* Conditional compare (immediate / register) |
55 | * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0 | 55 | * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0 |
56 | * +--+--+--+------------------------+--------+------+----+--+------+--+-----+ | 56 | * +--+--+--+------------------------+--------+------+----+--+------+--+-----+ |
57 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 57 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
58 | { | 58 | { |
59 | int op1 = extract32(insn, 28, 1); | 59 | int op1 = extract32(insn, 28, 1); |
60 | int op2 = extract32(insn, 21, 4); | 60 | int op2 = extract32(insn, 21, 4); |
61 | - int op3 = extract32(insn, 10, 6); | 61 | - int op3 = extract32(insn, 10, 6); |
62 | 62 | ||
63 | if (!op1) { | 63 | if (!op1) { |
64 | goto do_unallocated; | 64 | goto do_unallocated; |
65 | } | 65 | } |
66 | 66 | ||
67 | switch (op2) { | 67 | switch (op2) { |
68 | - case 0x0: | 68 | - case 0x0: |
69 | - switch (op3) { | 69 | - switch (op3) { |
70 | - case 0x02: /* Evaluate into flags */ | 70 | - case 0x02: /* Evaluate into flags */ |
71 | - case 0x12: | 71 | - case 0x12: |
72 | - case 0x22: | 72 | - case 0x22: |
73 | - case 0x32: | 73 | - case 0x32: |
74 | - disas_evaluate_into_flags(s, insn); | 74 | - disas_evaluate_into_flags(s, insn); |
75 | - break; | 75 | - break; |
76 | - | 76 | - |
77 | - default: | 77 | - default: |
78 | - case 0x00: /* Add/subtract (with carry) */ | 78 | - case 0x00: /* Add/subtract (with carry) */ |
79 | - case 0x01: /* Rotate right into flags */ | 79 | - case 0x01: /* Rotate right into flags */ |
80 | - case 0x21: | 80 | - case 0x21: |
81 | - goto do_unallocated; | 81 | - goto do_unallocated; |
82 | - } | 82 | - } |
83 | - break; | 83 | - break; |
84 | - | 84 | - |
85 | case 0x2: /* Conditional compare */ | 85 | case 0x2: /* Conditional compare */ |
86 | disas_cc(s, insn); /* both imm and reg forms */ | 86 | disas_cc(s, insn); /* both imm and reg forms */ |
87 | break; | 87 | break; |
88 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 88 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
89 | 89 | ||
90 | default: | 90 | default: |
91 | do_unallocated: | 91 | do_unallocated: |
92 | + case 0x0: | 92 | + case 0x0: |
93 | case 0x6: /* Data-processing */ | 93 | case 0x6: /* Data-processing */ |
94 | case 0x8 ... 0xf: /* (3 source) */ | 94 | case 0x8 ... 0xf: /* (3 source) */ |
95 | unallocated_encoding(s); | 95 | unallocated_encoding(s); |
96 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 96 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
97 | index XXXXXXX..XXXXXXX 100644 | 97 | index XXXXXXX..XXXXXXX 100644 |
98 | --- a/target/arm/tcg/a64.decode | 98 | --- a/target/arm/tcg/a64.decode |
99 | +++ b/target/arm/tcg/a64.decode | 99 | +++ b/target/arm/tcg/a64.decode |
100 | @@ -XXX,XX +XXX,XX @@ SBCS . 11 11010000 ..... 000000 ..... ..... @rrr_sf | 100 | @@ -XXX,XX +XXX,XX @@ SBCS . 11 11010000 ..... 000000 ..... ..... @rrr_sf |
101 | RMIF 1 01 11010000 imm:6 00001 rn:5 0 mask:4 | 101 | RMIF 1 01 11010000 imm:6 00001 rn:5 0 mask:4 |
102 | 102 | ||
103 | # Evaluate into flags | 103 | # Evaluate into flags |
104 | + | 104 | + |
105 | +SETF8 0 01 11010000 00000 000010 rn:5 01101 | 105 | +SETF8 0 01 11010000 00000 000010 rn:5 01101 |
106 | +SETF16 0 01 11010000 00000 010010 rn:5 01101 | 106 | +SETF16 0 01 11010000 00000 010010 rn:5 01101 |
107 | + | 107 | + |
108 | # Conditional compare (regster) | 108 | # Conditional compare (regster) |
109 | # Conditional compare (immediate) | 109 | # Conditional compare (immediate) |
110 | # Conditional select | 110 | # Conditional select |
111 | -- | 111 | -- |
112 | 2.43.0 | 112 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 66 +++++++++++----------------------- | 4 | target/arm/tcg/translate-a64.c | 66 +++++++++++----------------------- |
5 | target/arm/tcg/a64.decode | 6 ++-- | 5 | target/arm/tcg/a64.decode | 6 ++-- |
6 | 2 files changed, 25 insertions(+), 47 deletions(-) | 6 | 2 files changed, 25 insertions(+), 47 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool do_setf(DisasContext *s, int rn, int shift) | 12 | @@ -XXX,XX +XXX,XX @@ static bool do_setf(DisasContext *s, int rn, int shift) |
13 | TRANS_FEAT(SETF8, aa64_condm_4, do_setf, a->rn, 24) | 13 | TRANS_FEAT(SETF8, aa64_condm_4, do_setf, a->rn, 24) |
14 | TRANS_FEAT(SETF16, aa64_condm_4, do_setf, a->rn, 16) | 14 | TRANS_FEAT(SETF16, aa64_condm_4, do_setf, a->rn, 16) |
15 | 15 | ||
16 | -/* Conditional compare (immediate / register) | 16 | -/* Conditional compare (immediate / register) |
17 | - * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0 | 17 | - * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0 |
18 | - * +--+--+--+------------------------+--------+------+----+--+------+--+-----+ | 18 | - * +--+--+--+------------------------+--------+------+----+--+------+--+-----+ |
19 | - * |sf|op| S| 1 1 0 1 0 0 1 0 |imm5/rm | cond |i/r |o2| Rn |o3|nzcv | | 19 | - * |sf|op| S| 1 1 0 1 0 0 1 0 |imm5/rm | cond |i/r |o2| Rn |o3|nzcv | |
20 | - * +--+--+--+------------------------+--------+------+----+--+------+--+-----+ | 20 | - * +--+--+--+------------------------+--------+------+----+--+------+--+-----+ |
21 | - * [1] y [0] [0] | 21 | - * [1] y [0] [0] |
22 | - */ | 22 | - */ |
23 | -static void disas_cc(DisasContext *s, uint32_t insn) | 23 | -static void disas_cc(DisasContext *s, uint32_t insn) |
24 | +/* CCMP, CCMN */ | 24 | +/* CCMP, CCMN */ |
25 | +static bool trans_CCMP(DisasContext *s, arg_CCMP *a) | 25 | +static bool trans_CCMP(DisasContext *s, arg_CCMP *a) |
26 | { | 26 | { |
27 | - unsigned int sf, op, y, cond, rn, nzcv, is_imm; | 27 | - unsigned int sf, op, y, cond, rn, nzcv, is_imm; |
28 | - TCGv_i32 tcg_t0, tcg_t1, tcg_t2; | 28 | - TCGv_i32 tcg_t0, tcg_t1, tcg_t2; |
29 | - TCGv_i64 tcg_tmp, tcg_y, tcg_rn; | 29 | - TCGv_i64 tcg_tmp, tcg_y, tcg_rn; |
30 | + TCGv_i32 tcg_t0 = tcg_temp_new_i32(); | 30 | + TCGv_i32 tcg_t0 = tcg_temp_new_i32(); |
31 | + TCGv_i32 tcg_t1 = tcg_temp_new_i32(); | 31 | + TCGv_i32 tcg_t1 = tcg_temp_new_i32(); |
32 | + TCGv_i32 tcg_t2 = tcg_temp_new_i32(); | 32 | + TCGv_i32 tcg_t2 = tcg_temp_new_i32(); |
33 | + TCGv_i64 tcg_tmp = tcg_temp_new_i64(); | 33 | + TCGv_i64 tcg_tmp = tcg_temp_new_i64(); |
34 | + TCGv_i64 tcg_rn, tcg_y; | 34 | + TCGv_i64 tcg_rn, tcg_y; |
35 | DisasCompare c; | 35 | DisasCompare c; |
36 | - | 36 | - |
37 | - if (!extract32(insn, 29, 1)) { | 37 | - if (!extract32(insn, 29, 1)) { |
38 | - unallocated_encoding(s); | 38 | - unallocated_encoding(s); |
39 | - return; | 39 | - return; |
40 | - } | 40 | - } |
41 | - if (insn & (1 << 10 | 1 << 4)) { | 41 | - if (insn & (1 << 10 | 1 << 4)) { |
42 | - unallocated_encoding(s); | 42 | - unallocated_encoding(s); |
43 | - return; | 43 | - return; |
44 | - } | 44 | - } |
45 | - sf = extract32(insn, 31, 1); | 45 | - sf = extract32(insn, 31, 1); |
46 | - op = extract32(insn, 30, 1); | 46 | - op = extract32(insn, 30, 1); |
47 | - is_imm = extract32(insn, 11, 1); | 47 | - is_imm = extract32(insn, 11, 1); |
48 | - y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */ | 48 | - y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */ |
49 | - cond = extract32(insn, 12, 4); | 49 | - cond = extract32(insn, 12, 4); |
50 | - rn = extract32(insn, 5, 5); | 50 | - rn = extract32(insn, 5, 5); |
51 | - nzcv = extract32(insn, 0, 4); | 51 | - nzcv = extract32(insn, 0, 4); |
52 | + unsigned nzcv; | 52 | + unsigned nzcv; |
53 | 53 | ||
54 | /* Set T0 = !COND. */ | 54 | /* Set T0 = !COND. */ |
55 | - tcg_t0 = tcg_temp_new_i32(); | 55 | - tcg_t0 = tcg_temp_new_i32(); |
56 | - arm_test_cc(&c, cond); | 56 | - arm_test_cc(&c, cond); |
57 | + arm_test_cc(&c, a->cond); | 57 | + arm_test_cc(&c, a->cond); |
58 | tcg_gen_setcondi_i32(tcg_invert_cond(c.cond), tcg_t0, c.value, 0); | 58 | tcg_gen_setcondi_i32(tcg_invert_cond(c.cond), tcg_t0, c.value, 0); |
59 | 59 | ||
60 | /* Load the arguments for the new comparison. */ | 60 | /* Load the arguments for the new comparison. */ |
61 | - if (is_imm) { | 61 | - if (is_imm) { |
62 | - tcg_y = tcg_temp_new_i64(); | 62 | - tcg_y = tcg_temp_new_i64(); |
63 | - tcg_gen_movi_i64(tcg_y, y); | 63 | - tcg_gen_movi_i64(tcg_y, y); |
64 | + if (a->imm) { | 64 | + if (a->imm) { |
65 | + tcg_y = tcg_constant_i64(a->y); | 65 | + tcg_y = tcg_constant_i64(a->y); |
66 | } else { | 66 | } else { |
67 | - tcg_y = cpu_reg(s, y); | 67 | - tcg_y = cpu_reg(s, y); |
68 | + tcg_y = cpu_reg(s, a->y); | 68 | + tcg_y = cpu_reg(s, a->y); |
69 | } | 69 | } |
70 | - tcg_rn = cpu_reg(s, rn); | 70 | - tcg_rn = cpu_reg(s, rn); |
71 | + tcg_rn = cpu_reg(s, a->rn); | 71 | + tcg_rn = cpu_reg(s, a->rn); |
72 | 72 | ||
73 | /* Set the flags for the new comparison. */ | 73 | /* Set the flags for the new comparison. */ |
74 | - tcg_tmp = tcg_temp_new_i64(); | 74 | - tcg_tmp = tcg_temp_new_i64(); |
75 | - if (op) { | 75 | - if (op) { |
76 | - gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y); | 76 | - gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y); |
77 | + if (a->op) { | 77 | + if (a->op) { |
78 | + gen_sub_CC(a->sf, tcg_tmp, tcg_rn, tcg_y); | 78 | + gen_sub_CC(a->sf, tcg_tmp, tcg_rn, tcg_y); |
79 | } else { | 79 | } else { |
80 | - gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y); | 80 | - gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y); |
81 | + gen_add_CC(a->sf, tcg_tmp, tcg_rn, tcg_y); | 81 | + gen_add_CC(a->sf, tcg_tmp, tcg_rn, tcg_y); |
82 | } | 82 | } |
83 | 83 | ||
84 | - /* If COND was false, force the flags to #nzcv. Compute two masks | 84 | - /* If COND was false, force the flags to #nzcv. Compute two masks |
85 | + /* | 85 | + /* |
86 | + * If COND was false, force the flags to #nzcv. Compute two masks | 86 | + * If COND was false, force the flags to #nzcv. Compute two masks |
87 | * to help with this: T1 = (COND ? 0 : -1), T2 = (COND ? -1 : 0). | 87 | * to help with this: T1 = (COND ? 0 : -1), T2 = (COND ? -1 : 0). |
88 | * For tcg hosts that support ANDC, we can make do with just T1. | 88 | * For tcg hosts that support ANDC, we can make do with just T1. |
89 | * In either case, allow the tcg optimizer to delete any unused mask. | 89 | * In either case, allow the tcg optimizer to delete any unused mask. |
90 | */ | 90 | */ |
91 | - tcg_t1 = tcg_temp_new_i32(); | 91 | - tcg_t1 = tcg_temp_new_i32(); |
92 | - tcg_t2 = tcg_temp_new_i32(); | 92 | - tcg_t2 = tcg_temp_new_i32(); |
93 | tcg_gen_neg_i32(tcg_t1, tcg_t0); | 93 | tcg_gen_neg_i32(tcg_t1, tcg_t0); |
94 | tcg_gen_subi_i32(tcg_t2, tcg_t0, 1); | 94 | tcg_gen_subi_i32(tcg_t2, tcg_t0, 1); |
95 | 95 | ||
96 | + nzcv = a->nzcv; | 96 | + nzcv = a->nzcv; |
97 | if (nzcv & 8) { /* N */ | 97 | if (nzcv & 8) { /* N */ |
98 | tcg_gen_or_i32(cpu_NF, cpu_NF, tcg_t1); | 98 | tcg_gen_or_i32(cpu_NF, cpu_NF, tcg_t1); |
99 | } else { | 99 | } else { |
100 | @@ -XXX,XX +XXX,XX @@ static void disas_cc(DisasContext *s, uint32_t insn) | 100 | @@ -XXX,XX +XXX,XX @@ static void disas_cc(DisasContext *s, uint32_t insn) |
101 | tcg_gen_and_i32(cpu_VF, cpu_VF, tcg_t2); | 101 | tcg_gen_and_i32(cpu_VF, cpu_VF, tcg_t2); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | + return true; | 104 | + return true; |
105 | } | 105 | } |
106 | 106 | ||
107 | /* Conditional select | 107 | /* Conditional select |
108 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 108 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
109 | } | 109 | } |
110 | 110 | ||
111 | switch (op2) { | 111 | switch (op2) { |
112 | - case 0x2: /* Conditional compare */ | 112 | - case 0x2: /* Conditional compare */ |
113 | - disas_cc(s, insn); /* both imm and reg forms */ | 113 | - disas_cc(s, insn); /* both imm and reg forms */ |
114 | - break; | 114 | - break; |
115 | - | 115 | - |
116 | case 0x4: /* Conditional select */ | 116 | case 0x4: /* Conditional select */ |
117 | disas_cond_select(s, insn); | 117 | disas_cond_select(s, insn); |
118 | break; | 118 | break; |
119 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 119 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
120 | default: | 120 | default: |
121 | do_unallocated: | 121 | do_unallocated: |
122 | case 0x0: | 122 | case 0x0: |
123 | + case 0x2: /* Conditional compare */ | 123 | + case 0x2: /* Conditional compare */ |
124 | case 0x6: /* Data-processing */ | 124 | case 0x6: /* Data-processing */ |
125 | case 0x8 ... 0xf: /* (3 source) */ | 125 | case 0x8 ... 0xf: /* (3 source) */ |
126 | unallocated_encoding(s); | 126 | unallocated_encoding(s); |
127 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 127 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
128 | index XXXXXXX..XXXXXXX 100644 | 128 | index XXXXXXX..XXXXXXX 100644 |
129 | --- a/target/arm/tcg/a64.decode | 129 | --- a/target/arm/tcg/a64.decode |
130 | +++ b/target/arm/tcg/a64.decode | 130 | +++ b/target/arm/tcg/a64.decode |
131 | @@ -XXX,XX +XXX,XX @@ RMIF 1 01 11010000 imm:6 00001 rn:5 0 mask:4 | 131 | @@ -XXX,XX +XXX,XX @@ RMIF 1 01 11010000 imm:6 00001 rn:5 0 mask:4 |
132 | SETF8 0 01 11010000 00000 000010 rn:5 01101 | 132 | SETF8 0 01 11010000 00000 000010 rn:5 01101 |
133 | SETF16 0 01 11010000 00000 010010 rn:5 01101 | 133 | SETF16 0 01 11010000 00000 010010 rn:5 01101 |
134 | 134 | ||
135 | -# Conditional compare (regster) | 135 | -# Conditional compare (regster) |
136 | -# Conditional compare (immediate) | 136 | -# Conditional compare (immediate) |
137 | +# Conditional compare | 137 | +# Conditional compare |
138 | + | 138 | + |
139 | +CCMP sf:1 op:1 1 11010010 y:5 cond:4 imm:1 0 rn:5 0 nzcv:4 | 139 | +CCMP sf:1 op:1 1 11010010 y:5 cond:4 imm:1 0 rn:5 0 nzcv:4 |
140 | + | 140 | + |
141 | # Conditional select | 141 | # Conditional select |
142 | # Data Processing (3-source) | 142 | # Data Processing (3-source) |
143 | 143 | ||
144 | -- | 144 | -- |
145 | 2.43.0 | 145 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes CSEL, CSINC, CSINV, CSNEG. Remove disas_data_proc_reg, | 1 | This includes CSEL, CSINC, CSINV, CSNEG. Remove disas_data_proc_reg, |
---|---|---|---|
2 | as these were the last insns decoded by that function. | 2 | as these were the last insns decoded by that function. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 84 ++++++---------------------------- | 7 | target/arm/tcg/translate-a64.c | 84 ++++++---------------------------- |
8 | target/arm/tcg/a64.decode | 3 ++ | 8 | target/arm/tcg/a64.decode | 3 ++ |
9 | 2 files changed, 17 insertions(+), 70 deletions(-) | 9 | 2 files changed, 17 insertions(+), 70 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ static bool trans_CCMP(DisasContext *s, arg_CCMP *a) | 15 | @@ -XXX,XX +XXX,XX @@ static bool trans_CCMP(DisasContext *s, arg_CCMP *a) |
16 | return true; | 16 | return true; |
17 | } | 17 | } |
18 | 18 | ||
19 | -/* Conditional select | 19 | -/* Conditional select |
20 | - * 31 30 29 28 21 20 16 15 12 11 10 9 5 4 0 | 20 | - * 31 30 29 28 21 20 16 15 12 11 10 9 5 4 0 |
21 | - * +----+----+---+-----------------+------+------+-----+------+------+ | 21 | - * +----+----+---+-----------------+------+------+-----+------+------+ |
22 | - * | sf | op | S | 1 1 0 1 0 1 0 0 | Rm | cond | op2 | Rn | Rd | | 22 | - * | sf | op | S | 1 1 0 1 0 1 0 0 | Rm | cond | op2 | Rn | Rd | |
23 | - * +----+----+---+-----------------+------+------+-----+------+------+ | 23 | - * +----+----+---+-----------------+------+------+-----+------+------+ |
24 | - */ | 24 | - */ |
25 | -static void disas_cond_select(DisasContext *s, uint32_t insn) | 25 | -static void disas_cond_select(DisasContext *s, uint32_t insn) |
26 | +static bool trans_CSEL(DisasContext *s, arg_CSEL *a) | 26 | +static bool trans_CSEL(DisasContext *s, arg_CSEL *a) |
27 | { | 27 | { |
28 | - unsigned int sf, else_inv, rm, cond, else_inc, rn, rd; | 28 | - unsigned int sf, else_inv, rm, cond, else_inc, rn, rd; |
29 | - TCGv_i64 tcg_rd, zero; | 29 | - TCGv_i64 tcg_rd, zero; |
30 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 30 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
31 | + TCGv_i64 zero = tcg_constant_i64(0); | 31 | + TCGv_i64 zero = tcg_constant_i64(0); |
32 | DisasCompare64 c; | 32 | DisasCompare64 c; |
33 | 33 | ||
34 | - if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) { | 34 | - if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) { |
35 | - /* S == 1 or op2<1> == 1 */ | 35 | - /* S == 1 or op2<1> == 1 */ |
36 | - unallocated_encoding(s); | 36 | - unallocated_encoding(s); |
37 | - return; | 37 | - return; |
38 | - } | 38 | - } |
39 | - sf = extract32(insn, 31, 1); | 39 | - sf = extract32(insn, 31, 1); |
40 | - else_inv = extract32(insn, 30, 1); | 40 | - else_inv = extract32(insn, 30, 1); |
41 | - rm = extract32(insn, 16, 5); | 41 | - rm = extract32(insn, 16, 5); |
42 | - cond = extract32(insn, 12, 4); | 42 | - cond = extract32(insn, 12, 4); |
43 | - else_inc = extract32(insn, 10, 1); | 43 | - else_inc = extract32(insn, 10, 1); |
44 | - rn = extract32(insn, 5, 5); | 44 | - rn = extract32(insn, 5, 5); |
45 | - rd = extract32(insn, 0, 5); | 45 | - rd = extract32(insn, 0, 5); |
46 | + a64_test_cc(&c, a->cond); | 46 | + a64_test_cc(&c, a->cond); |
47 | 47 | ||
48 | - tcg_rd = cpu_reg(s, rd); | 48 | - tcg_rd = cpu_reg(s, rd); |
49 | - | 49 | - |
50 | - a64_test_cc(&c, cond); | 50 | - a64_test_cc(&c, cond); |
51 | - zero = tcg_constant_i64(0); | 51 | - zero = tcg_constant_i64(0); |
52 | - | 52 | - |
53 | - if (rn == 31 && rm == 31 && (else_inc ^ else_inv)) { | 53 | - if (rn == 31 && rm == 31 && (else_inc ^ else_inv)) { |
54 | + if (a->rn == 31 && a->rm == 31 && (a->else_inc ^ a->else_inv)) { | 54 | + if (a->rn == 31 && a->rm == 31 && (a->else_inc ^ a->else_inv)) { |
55 | /* CSET & CSETM. */ | 55 | /* CSET & CSETM. */ |
56 | - if (else_inv) { | 56 | - if (else_inv) { |
57 | + if (a->else_inv) { | 57 | + if (a->else_inv) { |
58 | tcg_gen_negsetcond_i64(tcg_invert_cond(c.cond), | 58 | tcg_gen_negsetcond_i64(tcg_invert_cond(c.cond), |
59 | tcg_rd, c.value, zero); | 59 | tcg_rd, c.value, zero); |
60 | } else { | 60 | } else { |
61 | @@ -XXX,XX +XXX,XX @@ static void disas_cond_select(DisasContext *s, uint32_t insn) | 61 | @@ -XXX,XX +XXX,XX @@ static void disas_cond_select(DisasContext *s, uint32_t insn) |
62 | tcg_rd, c.value, zero); | 62 | tcg_rd, c.value, zero); |
63 | } | 63 | } |
64 | } else { | 64 | } else { |
65 | - TCGv_i64 t_true = cpu_reg(s, rn); | 65 | - TCGv_i64 t_true = cpu_reg(s, rn); |
66 | - TCGv_i64 t_false = read_cpu_reg(s, rm, 1); | 66 | - TCGv_i64 t_false = read_cpu_reg(s, rm, 1); |
67 | - if (else_inv && else_inc) { | 67 | - if (else_inv && else_inc) { |
68 | + TCGv_i64 t_true = cpu_reg(s, a->rn); | 68 | + TCGv_i64 t_true = cpu_reg(s, a->rn); |
69 | + TCGv_i64 t_false = read_cpu_reg(s, a->rm, 1); | 69 | + TCGv_i64 t_false = read_cpu_reg(s, a->rm, 1); |
70 | + | 70 | + |
71 | + if (a->else_inv && a->else_inc) { | 71 | + if (a->else_inv && a->else_inc) { |
72 | tcg_gen_neg_i64(t_false, t_false); | 72 | tcg_gen_neg_i64(t_false, t_false); |
73 | - } else if (else_inv) { | 73 | - } else if (else_inv) { |
74 | + } else if (a->else_inv) { | 74 | + } else if (a->else_inv) { |
75 | tcg_gen_not_i64(t_false, t_false); | 75 | tcg_gen_not_i64(t_false, t_false); |
76 | - } else if (else_inc) { | 76 | - } else if (else_inc) { |
77 | + } else if (a->else_inc) { | 77 | + } else if (a->else_inc) { |
78 | tcg_gen_addi_i64(t_false, t_false, 1); | 78 | tcg_gen_addi_i64(t_false, t_false, 1); |
79 | } | 79 | } |
80 | tcg_gen_movcond_i64(c.cond, tcg_rd, c.value, zero, t_true, t_false); | 80 | tcg_gen_movcond_i64(c.cond, tcg_rd, c.value, zero, t_true, t_false); |
81 | } | 81 | } |
82 | 82 | ||
83 | - if (!sf) { | 83 | - if (!sf) { |
84 | + if (!a->sf) { | 84 | + if (!a->sf) { |
85 | tcg_gen_ext32u_i64(tcg_rd, tcg_rd); | 85 | tcg_gen_ext32u_i64(tcg_rd, tcg_rd); |
86 | } | 86 | } |
87 | -} | 87 | -} |
88 | - | 88 | - |
89 | -/* | 89 | -/* |
90 | - * Data processing - register | 90 | - * Data processing - register |
91 | - * 31 30 29 28 25 21 20 16 10 0 | 91 | - * 31 30 29 28 25 21 20 16 10 0 |
92 | - * +--+---+--+---+-------+-----+-------+-------+---------+ | 92 | - * +--+---+--+---+-------+-----+-------+-------+---------+ |
93 | - * | |op0| |op1| 1 0 1 | op2 | | op3 | | | 93 | - * | |op0| |op1| 1 0 1 | op2 | | op3 | | |
94 | - * +--+---+--+---+-------+-----+-------+-------+---------+ | 94 | - * +--+---+--+---+-------+-----+-------+-------+---------+ |
95 | - */ | 95 | - */ |
96 | -static void disas_data_proc_reg(DisasContext *s, uint32_t insn) | 96 | -static void disas_data_proc_reg(DisasContext *s, uint32_t insn) |
97 | -{ | 97 | -{ |
98 | - int op1 = extract32(insn, 28, 1); | 98 | - int op1 = extract32(insn, 28, 1); |
99 | - int op2 = extract32(insn, 21, 4); | 99 | - int op2 = extract32(insn, 21, 4); |
100 | - | 100 | - |
101 | - if (!op1) { | 101 | - if (!op1) { |
102 | - goto do_unallocated; | 102 | - goto do_unallocated; |
103 | - } | 103 | - } |
104 | - | 104 | - |
105 | - switch (op2) { | 105 | - switch (op2) { |
106 | - case 0x4: /* Conditional select */ | 106 | - case 0x4: /* Conditional select */ |
107 | - disas_cond_select(s, insn); | 107 | - disas_cond_select(s, insn); |
108 | - break; | 108 | - break; |
109 | - | 109 | - |
110 | - default: | 110 | - default: |
111 | - do_unallocated: | 111 | - do_unallocated: |
112 | - case 0x0: | 112 | - case 0x0: |
113 | - case 0x2: /* Conditional compare */ | 113 | - case 0x2: /* Conditional compare */ |
114 | - case 0x6: /* Data-processing */ | 114 | - case 0x6: /* Data-processing */ |
115 | - case 0x8 ... 0xf: /* (3 source) */ | 115 | - case 0x8 ... 0xf: /* (3 source) */ |
116 | - unallocated_encoding(s); | 116 | - unallocated_encoding(s); |
117 | - break; | 117 | - break; |
118 | - } | 118 | - } |
119 | + return true; | 119 | + return true; |
120 | } | 120 | } |
121 | 121 | ||
122 | static void handle_fp_compare(DisasContext *s, int size, | 122 | static void handle_fp_compare(DisasContext *s, int size, |
123 | @@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype) | 123 | @@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype) |
124 | static void disas_a64_legacy(DisasContext *s, uint32_t insn) | 124 | static void disas_a64_legacy(DisasContext *s, uint32_t insn) |
125 | { | 125 | { |
126 | switch (extract32(insn, 25, 4)) { | 126 | switch (extract32(insn, 25, 4)) { |
127 | - case 0x5: | 127 | - case 0x5: |
128 | - case 0xd: /* Data processing - register */ | 128 | - case 0xd: /* Data processing - register */ |
129 | - disas_data_proc_reg(s, insn); | 129 | - disas_data_proc_reg(s, insn); |
130 | - break; | 130 | - break; |
131 | case 0x7: | 131 | case 0x7: |
132 | case 0xf: /* Data processing - SIMD and floating point */ | 132 | case 0xf: /* Data processing - SIMD and floating point */ |
133 | disas_data_proc_simd_fp(s, insn); | 133 | disas_data_proc_simd_fp(s, insn); |
134 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 134 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
135 | index XXXXXXX..XXXXXXX 100644 | 135 | index XXXXXXX..XXXXXXX 100644 |
136 | --- a/target/arm/tcg/a64.decode | 136 | --- a/target/arm/tcg/a64.decode |
137 | +++ b/target/arm/tcg/a64.decode | 137 | +++ b/target/arm/tcg/a64.decode |
138 | @@ -XXX,XX +XXX,XX @@ SETF16 0 01 11010000 00000 010010 rn:5 01101 | 138 | @@ -XXX,XX +XXX,XX @@ SETF16 0 01 11010000 00000 010010 rn:5 01101 |
139 | CCMP sf:1 op:1 1 11010010 y:5 cond:4 imm:1 0 rn:5 0 nzcv:4 | 139 | CCMP sf:1 op:1 1 11010010 y:5 cond:4 imm:1 0 rn:5 0 nzcv:4 |
140 | 140 | ||
141 | # Conditional select | 141 | # Conditional select |
142 | + | 142 | + |
143 | +CSEL sf:1 else_inv:1 011010100 rm:5 cond:4 0 else_inc:1 rn:5 rd:5 | 143 | +CSEL sf:1 else_inv:1 011010100 rm:5 cond:4 0 else_inc:1 rn:5 rd:5 |
144 | + | 144 | + |
145 | # Data Processing (3-source) | 145 | # Data Processing (3-source) |
146 | 146 | ||
147 | &rrrr rd rn rm ra | 147 | &rrrr rd rn rm ra |
148 | -- | 148 | -- |
149 | 2.43.0 | 149 | 2.43.0 | diff view generated by jsdifflib |
1 | Provide a simple way to check for float64, float32, | 1 | Provide a simple way to check for float64, float32, |
---|---|---|---|
2 | and float16 support, as well as the fpu enabled. | 2 | and float16 support, as well as the fpu enabled. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 62 ++++++++++++++++++---------------- | 7 | target/arm/tcg/translate-a64.c | 62 ++++++++++++++++++---------------- |
8 | 1 file changed, 32 insertions(+), 30 deletions(-) | 8 | 1 file changed, 32 insertions(+), 30 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ static bool fp_access_check(DisasContext *s) | 14 | @@ -XXX,XX +XXX,XX @@ static bool fp_access_check(DisasContext *s) |
15 | return true; | 15 | return true; |
16 | } | 16 | } |
17 | 17 | ||
18 | +/* | 18 | +/* |
19 | + * Return <0 for non-supported element sizes, with MO_16 controlled by | 19 | + * Return <0 for non-supported element sizes, with MO_16 controlled by |
20 | + * FEAT_FP16; return 0 for fp disabled; otherwise return >0 for success. | 20 | + * FEAT_FP16; return 0 for fp disabled; otherwise return >0 for success. |
21 | + */ | 21 | + */ |
22 | +static int fp_access_check_scalar_hsd(DisasContext *s, MemOp esz) | 22 | +static int fp_access_check_scalar_hsd(DisasContext *s, MemOp esz) |
23 | +{ | 23 | +{ |
24 | + switch (esz) { | 24 | + switch (esz) { |
25 | + case MO_64: | 25 | + case MO_64: |
26 | + case MO_32: | 26 | + case MO_32: |
27 | + break; | 27 | + break; |
28 | + case MO_16: | 28 | + case MO_16: |
29 | + if (!dc_isar_feature(aa64_fp16, s)) { | 29 | + if (!dc_isar_feature(aa64_fp16, s)) { |
30 | + return -1; | 30 | + return -1; |
31 | + } | 31 | + } |
32 | + break; | 32 | + break; |
33 | + default: | 33 | + default: |
34 | + return -1; | 34 | + return -1; |
35 | + } | 35 | + } |
36 | + return fp_access_check(s); | 36 | + return fp_access_check(s); |
37 | +} | 37 | +} |
38 | + | 38 | + |
39 | /* | 39 | /* |
40 | * Check that SVE access is enabled. If it is, return true. | 40 | * Check that SVE access is enabled. If it is, return true. |
41 | * If not, emit code to generate an appropriate exception and return false. | 41 | * If not, emit code to generate an appropriate exception and return false. |
42 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCSEL(DisasContext *s, arg_FCSEL *a) | 42 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCSEL(DisasContext *s, arg_FCSEL *a) |
43 | { | 43 | { |
44 | TCGv_i64 t_true, t_false; | 44 | TCGv_i64 t_true, t_false; |
45 | DisasCompare64 c; | 45 | DisasCompare64 c; |
46 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 46 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
47 | 47 | ||
48 | - switch (a->esz) { | 48 | - switch (a->esz) { |
49 | - case MO_32: | 49 | - case MO_32: |
50 | - case MO_64: | 50 | - case MO_64: |
51 | - break; | 51 | - break; |
52 | - case MO_16: | 52 | - case MO_16: |
53 | - if (!dc_isar_feature(aa64_fp16, s)) { | 53 | - if (!dc_isar_feature(aa64_fp16, s)) { |
54 | - return false; | 54 | - return false; |
55 | - } | 55 | - } |
56 | - break; | 56 | - break; |
57 | - default: | 57 | - default: |
58 | - return false; | 58 | - return false; |
59 | - } | 59 | - } |
60 | - | 60 | - |
61 | - if (!fp_access_check(s)) { | 61 | - if (!fp_access_check(s)) { |
62 | - return true; | 62 | - return true; |
63 | + if (check <= 0) { | 63 | + if (check <= 0) { |
64 | + return check == 0; | 64 | + return check == 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | /* Zero extend sreg & hreg inputs to 64 bits now. */ | 67 | /* Zero extend sreg & hreg inputs to 64 bits now. */ |
68 | @@ -XXX,XX +XXX,XX @@ TRANS(FMINV_s, do_fp_reduction, a, gen_helper_vfp_mins) | 68 | @@ -XXX,XX +XXX,XX @@ TRANS(FMINV_s, do_fp_reduction, a, gen_helper_vfp_mins) |
69 | 69 | ||
70 | static bool trans_FMOVI_s(DisasContext *s, arg_FMOVI_s *a) | 70 | static bool trans_FMOVI_s(DisasContext *s, arg_FMOVI_s *a) |
71 | { | 71 | { |
72 | - switch (a->esz) { | 72 | - switch (a->esz) { |
73 | - case MO_32: | 73 | - case MO_32: |
74 | - case MO_64: | 74 | - case MO_64: |
75 | - break; | 75 | - break; |
76 | - case MO_16: | 76 | - case MO_16: |
77 | - if (!dc_isar_feature(aa64_fp16, s)) { | 77 | - if (!dc_isar_feature(aa64_fp16, s)) { |
78 | - return false; | 78 | - return false; |
79 | - } | 79 | - } |
80 | - break; | 80 | - break; |
81 | - default: | 81 | - default: |
82 | - return false; | 82 | - return false; |
83 | - } | 83 | - } |
84 | - if (fp_access_check(s)) { | 84 | - if (fp_access_check(s)) { |
85 | - uint64_t imm = vfp_expand_imm(a->esz, a->imm); | 85 | - uint64_t imm = vfp_expand_imm(a->esz, a->imm); |
86 | - write_fp_dreg(s, a->rd, tcg_constant_i64(imm)); | 86 | - write_fp_dreg(s, a->rd, tcg_constant_i64(imm)); |
87 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 87 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
88 | + uint64_t imm; | 88 | + uint64_t imm; |
89 | + | 89 | + |
90 | + if (check <= 0) { | 90 | + if (check <= 0) { |
91 | + return check == 0; | 91 | + return check == 0; |
92 | } | 92 | } |
93 | + | 93 | + |
94 | + imm = vfp_expand_imm(a->esz, a->imm); | 94 | + imm = vfp_expand_imm(a->esz, a->imm); |
95 | + write_fp_dreg(s, a->rd, tcg_constant_i64(imm)); | 95 | + write_fp_dreg(s, a->rd, tcg_constant_i64(imm)); |
96 | return true; | 96 | return true; |
97 | } | 97 | } |
98 | 98 | ||
99 | -- | 99 | -- |
100 | 2.43.0 | 100 | 2.43.0 | diff view generated by jsdifflib |
1 | Provide a simple way to check for float64, float32, and float16 | 1 | Provide a simple way to check for float64, float32, and float16 |
---|---|---|---|
2 | support vs vector width, as well as the fpu enabled. | 2 | support vs vector width, as well as the fpu enabled. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 135 +++++++++++++-------------------- | 7 | target/arm/tcg/translate-a64.c | 135 +++++++++++++-------------------- |
8 | 1 file changed, 54 insertions(+), 81 deletions(-) | 8 | 1 file changed, 54 insertions(+), 81 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ static int fp_access_check_scalar_hsd(DisasContext *s, MemOp esz) | 14 | @@ -XXX,XX +XXX,XX @@ static int fp_access_check_scalar_hsd(DisasContext *s, MemOp esz) |
15 | return fp_access_check(s); | 15 | return fp_access_check(s); |
16 | } | 16 | } |
17 | 17 | ||
18 | +/* Likewise, but vector MO_64 must have two elements. */ | 18 | +/* Likewise, but vector MO_64 must have two elements. */ |
19 | +static int fp_access_check_vector_hsd(DisasContext *s, bool is_q, MemOp esz) | 19 | +static int fp_access_check_vector_hsd(DisasContext *s, bool is_q, MemOp esz) |
20 | +{ | 20 | +{ |
21 | + switch (esz) { | 21 | + switch (esz) { |
22 | + case MO_64: | 22 | + case MO_64: |
23 | + if (!is_q) { | 23 | + if (!is_q) { |
24 | + return -1; | 24 | + return -1; |
25 | + } | 25 | + } |
26 | + break; | 26 | + break; |
27 | + case MO_32: | 27 | + case MO_32: |
28 | + break; | 28 | + break; |
29 | + case MO_16: | 29 | + case MO_16: |
30 | + if (!dc_isar_feature(aa64_fp16, s)) { | 30 | + if (!dc_isar_feature(aa64_fp16, s)) { |
31 | + return -1; | 31 | + return -1; |
32 | + } | 32 | + } |
33 | + break; | 33 | + break; |
34 | + default: | 34 | + default: |
35 | + return -1; | 35 | + return -1; |
36 | + } | 36 | + } |
37 | + return fp_access_check(s); | 37 | + return fp_access_check(s); |
38 | +} | 38 | +} |
39 | + | 39 | + |
40 | /* | 40 | /* |
41 | * Check that SVE access is enabled. If it is, return true. | 41 | * Check that SVE access is enabled. If it is, return true. |
42 | * If not, emit code to generate an appropriate exception and return false. | 42 | * If not, emit code to generate an appropriate exception and return false. |
43 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a, int data, | 43 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a, int data, |
44 | gen_helper_gvec_3_ptr * const fns[3]) | 44 | gen_helper_gvec_3_ptr * const fns[3]) |
45 | { | 45 | { |
46 | MemOp esz = a->esz; | 46 | MemOp esz = a->esz; |
47 | + int check = fp_access_check_vector_hsd(s, a->q, esz); | 47 | + int check = fp_access_check_vector_hsd(s, a->q, esz); |
48 | 48 | ||
49 | - switch (esz) { | 49 | - switch (esz) { |
50 | - case MO_64: | 50 | - case MO_64: |
51 | - if (!a->q) { | 51 | - if (!a->q) { |
52 | - return false; | 52 | - return false; |
53 | - } | 53 | - } |
54 | - break; | 54 | - break; |
55 | - case MO_32: | 55 | - case MO_32: |
56 | - break; | 56 | - break; |
57 | - case MO_16: | 57 | - case MO_16: |
58 | - if (!dc_isar_feature(aa64_fp16, s)) { | 58 | - if (!dc_isar_feature(aa64_fp16, s)) { |
59 | - return false; | 59 | - return false; |
60 | - } | 60 | - } |
61 | - break; | 61 | - break; |
62 | - default: | 62 | - default: |
63 | - return false; | 63 | - return false; |
64 | - } | 64 | - } |
65 | - if (fp_access_check(s)) { | 65 | - if (fp_access_check(s)) { |
66 | - gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, | 66 | - gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, |
67 | - esz == MO_16, data, fns[esz - 1]); | 67 | - esz == MO_16, data, fns[esz - 1]); |
68 | + if (check <= 0) { | 68 | + if (check <= 0) { |
69 | + return check == 0; | 69 | + return check == 0; |
70 | } | 70 | } |
71 | + | 71 | + |
72 | + gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, | 72 | + gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, |
73 | + esz == MO_16, data, fns[esz - 1]); | 73 | + esz == MO_16, data, fns[esz - 1]); |
74 | return true; | 74 | return true; |
75 | } | 75 | } |
76 | 76 | ||
77 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FCADD_270, aa64_fcma, do_fp3_vector, a, 1, f_vector_fcadd) | 77 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FCADD_270, aa64_fcma, do_fp3_vector, a, 1, f_vector_fcadd) |
78 | 78 | ||
79 | static bool trans_FCMLA_v(DisasContext *s, arg_FCMLA_v *a) | 79 | static bool trans_FCMLA_v(DisasContext *s, arg_FCMLA_v *a) |
80 | { | 80 | { |
81 | - gen_helper_gvec_4_ptr *fn; | 81 | - gen_helper_gvec_4_ptr *fn; |
82 | + static gen_helper_gvec_4_ptr * const fn[] = { | 82 | + static gen_helper_gvec_4_ptr * const fn[] = { |
83 | + [MO_16] = gen_helper_gvec_fcmlah, | 83 | + [MO_16] = gen_helper_gvec_fcmlah, |
84 | + [MO_32] = gen_helper_gvec_fcmlas, | 84 | + [MO_32] = gen_helper_gvec_fcmlas, |
85 | + [MO_64] = gen_helper_gvec_fcmlad, | 85 | + [MO_64] = gen_helper_gvec_fcmlad, |
86 | + }; | 86 | + }; |
87 | + int check; | 87 | + int check; |
88 | 88 | ||
89 | if (!dc_isar_feature(aa64_fcma, s)) { | 89 | if (!dc_isar_feature(aa64_fcma, s)) { |
90 | return false; | 90 | return false; |
91 | } | 91 | } |
92 | - switch (a->esz) { | 92 | - switch (a->esz) { |
93 | - case MO_64: | 93 | - case MO_64: |
94 | - if (!a->q) { | 94 | - if (!a->q) { |
95 | - return false; | 95 | - return false; |
96 | - } | 96 | - } |
97 | - fn = gen_helper_gvec_fcmlad; | 97 | - fn = gen_helper_gvec_fcmlad; |
98 | - break; | 98 | - break; |
99 | - case MO_32: | 99 | - case MO_32: |
100 | - fn = gen_helper_gvec_fcmlas; | 100 | - fn = gen_helper_gvec_fcmlas; |
101 | - break; | 101 | - break; |
102 | - case MO_16: | 102 | - case MO_16: |
103 | - if (!dc_isar_feature(aa64_fp16, s)) { | 103 | - if (!dc_isar_feature(aa64_fp16, s)) { |
104 | - return false; | 104 | - return false; |
105 | - } | 105 | - } |
106 | - fn = gen_helper_gvec_fcmlah; | 106 | - fn = gen_helper_gvec_fcmlah; |
107 | - break; | 107 | - break; |
108 | - default: | 108 | - default: |
109 | - return false; | 109 | - return false; |
110 | - } | 110 | - } |
111 | - if (fp_access_check(s)) { | 111 | - if (fp_access_check(s)) { |
112 | - gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, | 112 | - gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, |
113 | - a->esz == MO_16, a->rot, fn); | 113 | - a->esz == MO_16, a->rot, fn); |
114 | + | 114 | + |
115 | + check = fp_access_check_vector_hsd(s, a->q, a->esz); | 115 | + check = fp_access_check_vector_hsd(s, a->q, a->esz); |
116 | + if (check <= 0) { | 116 | + if (check <= 0) { |
117 | + return check == 0; | 117 | + return check == 0; |
118 | } | 118 | } |
119 | + | 119 | + |
120 | + gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, | 120 | + gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, |
121 | + a->esz == MO_16, a->rot, fn[a->esz]); | 121 | + a->esz == MO_16, a->rot, fn[a->esz]); |
122 | return true; | 122 | return true; |
123 | } | 123 | } |
124 | 124 | ||
125 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_vector_idx(DisasContext *s, arg_qrrx_e *a, | 125 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_vector_idx(DisasContext *s, arg_qrrx_e *a, |
126 | gen_helper_gvec_3_ptr * const fns[3]) | 126 | gen_helper_gvec_3_ptr * const fns[3]) |
127 | { | 127 | { |
128 | MemOp esz = a->esz; | 128 | MemOp esz = a->esz; |
129 | + int check = fp_access_check_vector_hsd(s, a->q, esz); | 129 | + int check = fp_access_check_vector_hsd(s, a->q, esz); |
130 | 130 | ||
131 | - switch (esz) { | 131 | - switch (esz) { |
132 | - case MO_64: | 132 | - case MO_64: |
133 | - if (!a->q) { | 133 | - if (!a->q) { |
134 | - return false; | 134 | - return false; |
135 | - } | 135 | - } |
136 | - break; | 136 | - break; |
137 | - case MO_32: | 137 | - case MO_32: |
138 | - break; | 138 | - break; |
139 | - case MO_16: | 139 | - case MO_16: |
140 | - if (!dc_isar_feature(aa64_fp16, s)) { | 140 | - if (!dc_isar_feature(aa64_fp16, s)) { |
141 | - return false; | 141 | - return false; |
142 | - } | 142 | - } |
143 | - break; | 143 | - break; |
144 | - default: | 144 | - default: |
145 | - g_assert_not_reached(); | 145 | - g_assert_not_reached(); |
146 | - } | 146 | - } |
147 | - if (fp_access_check(s)) { | 147 | - if (fp_access_check(s)) { |
148 | - gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, | 148 | - gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, |
149 | - esz == MO_16, a->idx, fns[esz - 1]); | 149 | - esz == MO_16, a->idx, fns[esz - 1]); |
150 | + if (check <= 0) { | 150 | + if (check <= 0) { |
151 | + return check == 0; | 151 | + return check == 0; |
152 | } | 152 | } |
153 | + | 153 | + |
154 | + gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, | 154 | + gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm, |
155 | + esz == MO_16, a->idx, fns[esz - 1]); | 155 | + esz == MO_16, a->idx, fns[esz - 1]); |
156 | return true; | 156 | return true; |
157 | } | 157 | } |
158 | 158 | ||
159 | @@ -XXX,XX +XXX,XX @@ static bool do_fmla_vector_idx(DisasContext *s, arg_qrrx_e *a, bool neg) | 159 | @@ -XXX,XX +XXX,XX @@ static bool do_fmla_vector_idx(DisasContext *s, arg_qrrx_e *a, bool neg) |
160 | gen_helper_gvec_fmla_idx_d, | 160 | gen_helper_gvec_fmla_idx_d, |
161 | }; | 161 | }; |
162 | MemOp esz = a->esz; | 162 | MemOp esz = a->esz; |
163 | + int check = fp_access_check_vector_hsd(s, a->q, esz); | 163 | + int check = fp_access_check_vector_hsd(s, a->q, esz); |
164 | 164 | ||
165 | - switch (esz) { | 165 | - switch (esz) { |
166 | - case MO_64: | 166 | - case MO_64: |
167 | - if (!a->q) { | 167 | - if (!a->q) { |
168 | - return false; | 168 | - return false; |
169 | - } | 169 | - } |
170 | - break; | 170 | - break; |
171 | - case MO_32: | 171 | - case MO_32: |
172 | - break; | 172 | - break; |
173 | - case MO_16: | 173 | - case MO_16: |
174 | - if (!dc_isar_feature(aa64_fp16, s)) { | 174 | - if (!dc_isar_feature(aa64_fp16, s)) { |
175 | - return false; | 175 | - return false; |
176 | - } | 176 | - } |
177 | - break; | 177 | - break; |
178 | - default: | 178 | - default: |
179 | - g_assert_not_reached(); | 179 | - g_assert_not_reached(); |
180 | - } | 180 | - } |
181 | - if (fp_access_check(s)) { | 181 | - if (fp_access_check(s)) { |
182 | - gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, | 182 | - gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, |
183 | - esz == MO_16, (a->idx << 1) | neg, | 183 | - esz == MO_16, (a->idx << 1) | neg, |
184 | - fns[esz - 1]); | 184 | - fns[esz - 1]); |
185 | + if (check <= 0) { | 185 | + if (check <= 0) { |
186 | + return check == 0; | 186 | + return check == 0; |
187 | } | 187 | } |
188 | + | 188 | + |
189 | + gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, | 189 | + gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd, |
190 | + esz == MO_16, (a->idx << 1) | neg, | 190 | + esz == MO_16, (a->idx << 1) | neg, |
191 | + fns[esz - 1]); | 191 | + fns[esz - 1]); |
192 | return true; | 192 | return true; |
193 | } | 193 | } |
194 | 194 | ||
195 | -- | 195 | -- |
196 | 2.43.0 | 196 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 283 ++++++++++++--------------------- | 4 | target/arm/tcg/translate-a64.c | 283 ++++++++++++--------------------- |
5 | target/arm/tcg/a64.decode | 8 + | 5 | target/arm/tcg/a64.decode | 8 + |
6 | 2 files changed, 112 insertions(+), 179 deletions(-) | 6 | 2 files changed, 112 insertions(+), 179 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool trans_FMOVI_s(DisasContext *s, arg_FMOVI_s *a) | 12 | @@ -XXX,XX +XXX,XX @@ static bool trans_FMOVI_s(DisasContext *s, arg_FMOVI_s *a) |
13 | return true; | 13 | return true; |
14 | } | 14 | } |
15 | 15 | ||
16 | +/* | 16 | +/* |
17 | + * Floating point compare, conditional compare | 17 | + * Floating point compare, conditional compare |
18 | + */ | 18 | + */ |
19 | + | 19 | + |
20 | +static void handle_fp_compare(DisasContext *s, int size, | 20 | +static void handle_fp_compare(DisasContext *s, int size, |
21 | + unsigned int rn, unsigned int rm, | 21 | + unsigned int rn, unsigned int rm, |
22 | + bool cmp_with_zero, bool signal_all_nans) | 22 | + bool cmp_with_zero, bool signal_all_nans) |
23 | +{ | 23 | +{ |
24 | + TCGv_i64 tcg_flags = tcg_temp_new_i64(); | 24 | + TCGv_i64 tcg_flags = tcg_temp_new_i64(); |
25 | + TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | 25 | + TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); |
26 | + | 26 | + |
27 | + if (size == MO_64) { | 27 | + if (size == MO_64) { |
28 | + TCGv_i64 tcg_vn, tcg_vm; | 28 | + TCGv_i64 tcg_vn, tcg_vm; |
29 | + | 29 | + |
30 | + tcg_vn = read_fp_dreg(s, rn); | 30 | + tcg_vn = read_fp_dreg(s, rn); |
31 | + if (cmp_with_zero) { | 31 | + if (cmp_with_zero) { |
32 | + tcg_vm = tcg_constant_i64(0); | 32 | + tcg_vm = tcg_constant_i64(0); |
33 | + } else { | 33 | + } else { |
34 | + tcg_vm = read_fp_dreg(s, rm); | 34 | + tcg_vm = read_fp_dreg(s, rm); |
35 | + } | 35 | + } |
36 | + if (signal_all_nans) { | 36 | + if (signal_all_nans) { |
37 | + gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 37 | + gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
38 | + } else { | 38 | + } else { |
39 | + gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 39 | + gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
40 | + } | 40 | + } |
41 | + } else { | 41 | + } else { |
42 | + TCGv_i32 tcg_vn = tcg_temp_new_i32(); | 42 | + TCGv_i32 tcg_vn = tcg_temp_new_i32(); |
43 | + TCGv_i32 tcg_vm = tcg_temp_new_i32(); | 43 | + TCGv_i32 tcg_vm = tcg_temp_new_i32(); |
44 | + | 44 | + |
45 | + read_vec_element_i32(s, tcg_vn, rn, 0, size); | 45 | + read_vec_element_i32(s, tcg_vn, rn, 0, size); |
46 | + if (cmp_with_zero) { | 46 | + if (cmp_with_zero) { |
47 | + tcg_gen_movi_i32(tcg_vm, 0); | 47 | + tcg_gen_movi_i32(tcg_vm, 0); |
48 | + } else { | 48 | + } else { |
49 | + read_vec_element_i32(s, tcg_vm, rm, 0, size); | 49 | + read_vec_element_i32(s, tcg_vm, rm, 0, size); |
50 | + } | 50 | + } |
51 | + | 51 | + |
52 | + switch (size) { | 52 | + switch (size) { |
53 | + case MO_32: | 53 | + case MO_32: |
54 | + if (signal_all_nans) { | 54 | + if (signal_all_nans) { |
55 | + gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 55 | + gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
56 | + } else { | 56 | + } else { |
57 | + gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 57 | + gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
58 | + } | 58 | + } |
59 | + break; | 59 | + break; |
60 | + case MO_16: | 60 | + case MO_16: |
61 | + if (signal_all_nans) { | 61 | + if (signal_all_nans) { |
62 | + gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 62 | + gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
63 | + } else { | 63 | + } else { |
64 | + gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 64 | + gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
65 | + } | 65 | + } |
66 | + break; | 66 | + break; |
67 | + default: | 67 | + default: |
68 | + g_assert_not_reached(); | 68 | + g_assert_not_reached(); |
69 | + } | 69 | + } |
70 | + } | 70 | + } |
71 | + | 71 | + |
72 | + gen_set_nzcv(tcg_flags); | 72 | + gen_set_nzcv(tcg_flags); |
73 | +} | 73 | +} |
74 | + | 74 | + |
75 | +/* FCMP, FCMPE */ | 75 | +/* FCMP, FCMPE */ |
76 | +static bool trans_FCMP(DisasContext *s, arg_FCMP *a) | 76 | +static bool trans_FCMP(DisasContext *s, arg_FCMP *a) |
77 | +{ | 77 | +{ |
78 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 78 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
79 | + | 79 | + |
80 | + if (check <= 0) { | 80 | + if (check <= 0) { |
81 | + return check == 0; | 81 | + return check == 0; |
82 | + } | 82 | + } |
83 | + | 83 | + |
84 | + handle_fp_compare(s, a->esz, a->rn, a->rm, a->z, a->e); | 84 | + handle_fp_compare(s, a->esz, a->rn, a->rm, a->z, a->e); |
85 | + return true; | 85 | + return true; |
86 | +} | 86 | +} |
87 | + | 87 | + |
88 | +/* FCCMP, FCCMPE */ | 88 | +/* FCCMP, FCCMPE */ |
89 | +static bool trans_FCCMP(DisasContext *s, arg_FCCMP *a) | 89 | +static bool trans_FCCMP(DisasContext *s, arg_FCCMP *a) |
90 | +{ | 90 | +{ |
91 | + TCGLabel *label_continue = NULL; | 91 | + TCGLabel *label_continue = NULL; |
92 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 92 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
93 | + | 93 | + |
94 | + if (check <= 0) { | 94 | + if (check <= 0) { |
95 | + return check == 0; | 95 | + return check == 0; |
96 | + } | 96 | + } |
97 | + | 97 | + |
98 | + if (a->cond < 0x0e) { /* not always */ | 98 | + if (a->cond < 0x0e) { /* not always */ |
99 | + TCGLabel *label_match = gen_new_label(); | 99 | + TCGLabel *label_match = gen_new_label(); |
100 | + label_continue = gen_new_label(); | 100 | + label_continue = gen_new_label(); |
101 | + arm_gen_test_cc(a->cond, label_match); | 101 | + arm_gen_test_cc(a->cond, label_match); |
102 | + /* nomatch: */ | 102 | + /* nomatch: */ |
103 | + gen_set_nzcv(tcg_constant_i64(a->nzcv << 28)); | 103 | + gen_set_nzcv(tcg_constant_i64(a->nzcv << 28)); |
104 | + tcg_gen_br(label_continue); | 104 | + tcg_gen_br(label_continue); |
105 | + gen_set_label(label_match); | 105 | + gen_set_label(label_match); |
106 | + } | 106 | + } |
107 | + | 107 | + |
108 | + handle_fp_compare(s, a->esz, a->rn, a->rm, false, a->e); | 108 | + handle_fp_compare(s, a->esz, a->rn, a->rm, false, a->e); |
109 | + | 109 | + |
110 | + if (label_continue) { | 110 | + if (label_continue) { |
111 | + gen_set_label(label_continue); | 111 | + gen_set_label(label_continue); |
112 | + } | 112 | + } |
113 | + return true; | 113 | + return true; |
114 | +} | 114 | +} |
115 | + | 115 | + |
116 | /* | 116 | /* |
117 | * Advanced SIMD Modified Immediate | 117 | * Advanced SIMD Modified Immediate |
118 | */ | 118 | */ |
119 | @@ -XXX,XX +XXX,XX @@ static bool trans_CSEL(DisasContext *s, arg_CSEL *a) | 119 | @@ -XXX,XX +XXX,XX @@ static bool trans_CSEL(DisasContext *s, arg_CSEL *a) |
120 | return true; | 120 | return true; |
121 | } | 121 | } |
122 | 122 | ||
123 | -static void handle_fp_compare(DisasContext *s, int size, | 123 | -static void handle_fp_compare(DisasContext *s, int size, |
124 | - unsigned int rn, unsigned int rm, | 124 | - unsigned int rn, unsigned int rm, |
125 | - bool cmp_with_zero, bool signal_all_nans) | 125 | - bool cmp_with_zero, bool signal_all_nans) |
126 | -{ | 126 | -{ |
127 | - TCGv_i64 tcg_flags = tcg_temp_new_i64(); | 127 | - TCGv_i64 tcg_flags = tcg_temp_new_i64(); |
128 | - TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | 128 | - TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); |
129 | - | 129 | - |
130 | - if (size == MO_64) { | 130 | - if (size == MO_64) { |
131 | - TCGv_i64 tcg_vn, tcg_vm; | 131 | - TCGv_i64 tcg_vn, tcg_vm; |
132 | - | 132 | - |
133 | - tcg_vn = read_fp_dreg(s, rn); | 133 | - tcg_vn = read_fp_dreg(s, rn); |
134 | - if (cmp_with_zero) { | 134 | - if (cmp_with_zero) { |
135 | - tcg_vm = tcg_constant_i64(0); | 135 | - tcg_vm = tcg_constant_i64(0); |
136 | - } else { | 136 | - } else { |
137 | - tcg_vm = read_fp_dreg(s, rm); | 137 | - tcg_vm = read_fp_dreg(s, rm); |
138 | - } | 138 | - } |
139 | - if (signal_all_nans) { | 139 | - if (signal_all_nans) { |
140 | - gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 140 | - gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
141 | - } else { | 141 | - } else { |
142 | - gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 142 | - gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
143 | - } | 143 | - } |
144 | - } else { | 144 | - } else { |
145 | - TCGv_i32 tcg_vn = tcg_temp_new_i32(); | 145 | - TCGv_i32 tcg_vn = tcg_temp_new_i32(); |
146 | - TCGv_i32 tcg_vm = tcg_temp_new_i32(); | 146 | - TCGv_i32 tcg_vm = tcg_temp_new_i32(); |
147 | - | 147 | - |
148 | - read_vec_element_i32(s, tcg_vn, rn, 0, size); | 148 | - read_vec_element_i32(s, tcg_vn, rn, 0, size); |
149 | - if (cmp_with_zero) { | 149 | - if (cmp_with_zero) { |
150 | - tcg_gen_movi_i32(tcg_vm, 0); | 150 | - tcg_gen_movi_i32(tcg_vm, 0); |
151 | - } else { | 151 | - } else { |
152 | - read_vec_element_i32(s, tcg_vm, rm, 0, size); | 152 | - read_vec_element_i32(s, tcg_vm, rm, 0, size); |
153 | - } | 153 | - } |
154 | - | 154 | - |
155 | - switch (size) { | 155 | - switch (size) { |
156 | - case MO_32: | 156 | - case MO_32: |
157 | - if (signal_all_nans) { | 157 | - if (signal_all_nans) { |
158 | - gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 158 | - gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
159 | - } else { | 159 | - } else { |
160 | - gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 160 | - gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
161 | - } | 161 | - } |
162 | - break; | 162 | - break; |
163 | - case MO_16: | 163 | - case MO_16: |
164 | - if (signal_all_nans) { | 164 | - if (signal_all_nans) { |
165 | - gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 165 | - gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
166 | - } else { | 166 | - } else { |
167 | - gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst); | 167 | - gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst); |
168 | - } | 168 | - } |
169 | - break; | 169 | - break; |
170 | - default: | 170 | - default: |
171 | - g_assert_not_reached(); | 171 | - g_assert_not_reached(); |
172 | - } | 172 | - } |
173 | - } | 173 | - } |
174 | - | 174 | - |
175 | - gen_set_nzcv(tcg_flags); | 175 | - gen_set_nzcv(tcg_flags); |
176 | -} | 176 | -} |
177 | - | 177 | - |
178 | -/* Floating point compare | 178 | -/* Floating point compare |
179 | - * 31 30 29 28 24 23 22 21 20 16 15 14 13 10 9 5 4 0 | 179 | - * 31 30 29 28 24 23 22 21 20 16 15 14 13 10 9 5 4 0 |
180 | - * +---+---+---+-----------+------+---+------+-----+---------+------+-------+ | 180 | - * +---+---+---+-----------+------+---+------+-----+---------+------+-------+ |
181 | - * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | op | 1 0 0 0 | Rn | op2 | | 181 | - * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | op | 1 0 0 0 | Rn | op2 | |
182 | - * +---+---+---+-----------+------+---+------+-----+---------+------+-------+ | 182 | - * +---+---+---+-----------+------+---+------+-----+---------+------+-------+ |
183 | - */ | 183 | - */ |
184 | -static void disas_fp_compare(DisasContext *s, uint32_t insn) | 184 | -static void disas_fp_compare(DisasContext *s, uint32_t insn) |
185 | -{ | 185 | -{ |
186 | - unsigned int mos, type, rm, op, rn, opc, op2r; | 186 | - unsigned int mos, type, rm, op, rn, opc, op2r; |
187 | - int size; | 187 | - int size; |
188 | - | 188 | - |
189 | - mos = extract32(insn, 29, 3); | 189 | - mos = extract32(insn, 29, 3); |
190 | - type = extract32(insn, 22, 2); | 190 | - type = extract32(insn, 22, 2); |
191 | - rm = extract32(insn, 16, 5); | 191 | - rm = extract32(insn, 16, 5); |
192 | - op = extract32(insn, 14, 2); | 192 | - op = extract32(insn, 14, 2); |
193 | - rn = extract32(insn, 5, 5); | 193 | - rn = extract32(insn, 5, 5); |
194 | - opc = extract32(insn, 3, 2); | 194 | - opc = extract32(insn, 3, 2); |
195 | - op2r = extract32(insn, 0, 3); | 195 | - op2r = extract32(insn, 0, 3); |
196 | - | 196 | - |
197 | - if (mos || op || op2r) { | 197 | - if (mos || op || op2r) { |
198 | - unallocated_encoding(s); | 198 | - unallocated_encoding(s); |
199 | - return; | 199 | - return; |
200 | - } | 200 | - } |
201 | - | 201 | - |
202 | - switch (type) { | 202 | - switch (type) { |
203 | - case 0: | 203 | - case 0: |
204 | - size = MO_32; | 204 | - size = MO_32; |
205 | - break; | 205 | - break; |
206 | - case 1: | 206 | - case 1: |
207 | - size = MO_64; | 207 | - size = MO_64; |
208 | - break; | 208 | - break; |
209 | - case 3: | 209 | - case 3: |
210 | - size = MO_16; | 210 | - size = MO_16; |
211 | - if (dc_isar_feature(aa64_fp16, s)) { | 211 | - if (dc_isar_feature(aa64_fp16, s)) { |
212 | - break; | 212 | - break; |
213 | - } | 213 | - } |
214 | - /* fallthru */ | 214 | - /* fallthru */ |
215 | - default: | 215 | - default: |
216 | - unallocated_encoding(s); | 216 | - unallocated_encoding(s); |
217 | - return; | 217 | - return; |
218 | - } | 218 | - } |
219 | - | 219 | - |
220 | - if (!fp_access_check(s)) { | 220 | - if (!fp_access_check(s)) { |
221 | - return; | 221 | - return; |
222 | - } | 222 | - } |
223 | - | 223 | - |
224 | - handle_fp_compare(s, size, rn, rm, opc & 1, opc & 2); | 224 | - handle_fp_compare(s, size, rn, rm, opc & 1, opc & 2); |
225 | -} | 225 | -} |
226 | - | 226 | - |
227 | -/* Floating point conditional compare | 227 | -/* Floating point conditional compare |
228 | - * 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0 | 228 | - * 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0 |
229 | - * +---+---+---+-----------+------+---+------+------+-----+------+----+------+ | 229 | - * +---+---+---+-----------+------+---+------+------+-----+------+----+------+ |
230 | - * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | cond | 0 1 | Rn | op | nzcv | | 230 | - * | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | cond | 0 1 | Rn | op | nzcv | |
231 | - * +---+---+---+-----------+------+---+------+------+-----+------+----+------+ | 231 | - * +---+---+---+-----------+------+---+------+------+-----+------+----+------+ |
232 | - */ | 232 | - */ |
233 | -static void disas_fp_ccomp(DisasContext *s, uint32_t insn) | 233 | -static void disas_fp_ccomp(DisasContext *s, uint32_t insn) |
234 | -{ | 234 | -{ |
235 | - unsigned int mos, type, rm, cond, rn, op, nzcv; | 235 | - unsigned int mos, type, rm, cond, rn, op, nzcv; |
236 | - TCGLabel *label_continue = NULL; | 236 | - TCGLabel *label_continue = NULL; |
237 | - int size; | 237 | - int size; |
238 | - | 238 | - |
239 | - mos = extract32(insn, 29, 3); | 239 | - mos = extract32(insn, 29, 3); |
240 | - type = extract32(insn, 22, 2); | 240 | - type = extract32(insn, 22, 2); |
241 | - rm = extract32(insn, 16, 5); | 241 | - rm = extract32(insn, 16, 5); |
242 | - cond = extract32(insn, 12, 4); | 242 | - cond = extract32(insn, 12, 4); |
243 | - rn = extract32(insn, 5, 5); | 243 | - rn = extract32(insn, 5, 5); |
244 | - op = extract32(insn, 4, 1); | 244 | - op = extract32(insn, 4, 1); |
245 | - nzcv = extract32(insn, 0, 4); | 245 | - nzcv = extract32(insn, 0, 4); |
246 | - | 246 | - |
247 | - if (mos) { | 247 | - if (mos) { |
248 | - unallocated_encoding(s); | 248 | - unallocated_encoding(s); |
249 | - return; | 249 | - return; |
250 | - } | 250 | - } |
251 | - | 251 | - |
252 | - switch (type) { | 252 | - switch (type) { |
253 | - case 0: | 253 | - case 0: |
254 | - size = MO_32; | 254 | - size = MO_32; |
255 | - break; | 255 | - break; |
256 | - case 1: | 256 | - case 1: |
257 | - size = MO_64; | 257 | - size = MO_64; |
258 | - break; | 258 | - break; |
259 | - case 3: | 259 | - case 3: |
260 | - size = MO_16; | 260 | - size = MO_16; |
261 | - if (dc_isar_feature(aa64_fp16, s)) { | 261 | - if (dc_isar_feature(aa64_fp16, s)) { |
262 | - break; | 262 | - break; |
263 | - } | 263 | - } |
264 | - /* fallthru */ | 264 | - /* fallthru */ |
265 | - default: | 265 | - default: |
266 | - unallocated_encoding(s); | 266 | - unallocated_encoding(s); |
267 | - return; | 267 | - return; |
268 | - } | 268 | - } |
269 | - | 269 | - |
270 | - if (!fp_access_check(s)) { | 270 | - if (!fp_access_check(s)) { |
271 | - return; | 271 | - return; |
272 | - } | 272 | - } |
273 | - | 273 | - |
274 | - if (cond < 0x0e) { /* not always */ | 274 | - if (cond < 0x0e) { /* not always */ |
275 | - TCGLabel *label_match = gen_new_label(); | 275 | - TCGLabel *label_match = gen_new_label(); |
276 | - label_continue = gen_new_label(); | 276 | - label_continue = gen_new_label(); |
277 | - arm_gen_test_cc(cond, label_match); | 277 | - arm_gen_test_cc(cond, label_match); |
278 | - /* nomatch: */ | 278 | - /* nomatch: */ |
279 | - gen_set_nzcv(tcg_constant_i64(nzcv << 28)); | 279 | - gen_set_nzcv(tcg_constant_i64(nzcv << 28)); |
280 | - tcg_gen_br(label_continue); | 280 | - tcg_gen_br(label_continue); |
281 | - gen_set_label(label_match); | 281 | - gen_set_label(label_match); |
282 | - } | 282 | - } |
283 | - | 283 | - |
284 | - handle_fp_compare(s, size, rn, rm, false, op); | 284 | - handle_fp_compare(s, size, rn, rm, false, op); |
285 | - | 285 | - |
286 | - if (cond < 0x0e) { | 286 | - if (cond < 0x0e) { |
287 | - gen_set_label(label_continue); | 287 | - gen_set_label(label_continue); |
288 | - } | 288 | - } |
289 | -} | 289 | -} |
290 | - | 290 | - |
291 | /* Floating-point data-processing (1 source) - half precision */ | 291 | /* Floating-point data-processing (1 source) - half precision */ |
292 | static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) | 292 | static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) |
293 | { | 293 | { |
294 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) | 294 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) |
295 | disas_fp_fixed_conv(s, insn); | 295 | disas_fp_fixed_conv(s, insn); |
296 | } else { | 296 | } else { |
297 | switch (extract32(insn, 10, 2)) { | 297 | switch (extract32(insn, 10, 2)) { |
298 | - case 1: | 298 | - case 1: |
299 | - /* Floating point conditional compare */ | 299 | - /* Floating point conditional compare */ |
300 | - disas_fp_ccomp(s, insn); | 300 | - disas_fp_ccomp(s, insn); |
301 | - break; | 301 | - break; |
302 | - case 2: | 302 | - case 2: |
303 | - /* Floating point data-processing (2 source) */ | 303 | - /* Floating point data-processing (2 source) */ |
304 | - unallocated_encoding(s); /* in decodetree */ | 304 | - unallocated_encoding(s); /* in decodetree */ |
305 | - break; | 305 | - break; |
306 | - case 3: | 306 | - case 3: |
307 | - /* Floating point conditional select */ | 307 | - /* Floating point conditional select */ |
308 | + case 1: /* Floating point conditional compare */ | 308 | + case 1: /* Floating point conditional compare */ |
309 | + case 2: /* Floating point data-processing (2 source) */ | 309 | + case 2: /* Floating point data-processing (2 source) */ |
310 | + case 3: /* Floating point conditional select */ | 310 | + case 3: /* Floating point conditional select */ |
311 | unallocated_encoding(s); /* in decodetree */ | 311 | unallocated_encoding(s); /* in decodetree */ |
312 | break; | 312 | break; |
313 | case 0: | 313 | case 0: |
314 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) | 314 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) |
315 | break; | 315 | break; |
316 | case 1: /* [15:12] == xx10 */ | 316 | case 1: /* [15:12] == xx10 */ |
317 | /* Floating point compare */ | 317 | /* Floating point compare */ |
318 | - disas_fp_compare(s, insn); | 318 | - disas_fp_compare(s, insn); |
319 | + unallocated_encoding(s); /* in decodetree */ | 319 | + unallocated_encoding(s); /* in decodetree */ |
320 | break; | 320 | break; |
321 | case 2: /* [15:12] == x100 */ | 321 | case 2: /* [15:12] == x100 */ |
322 | /* Floating point data-processing (1 source) */ | 322 | /* Floating point data-processing (1 source) */ |
323 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 323 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
324 | index XXXXXXX..XXXXXXX 100644 | 324 | index XXXXXXX..XXXXXXX 100644 |
325 | --- a/target/arm/tcg/a64.decode | 325 | --- a/target/arm/tcg/a64.decode |
326 | +++ b/target/arm/tcg/a64.decode | 326 | +++ b/target/arm/tcg/a64.decode |
327 | @@ -XXX,XX +XXX,XX @@ FMINV_s 0110 1110 10 11000 01111 10 ..... ..... @rr_q1e2 | 327 | @@ -XXX,XX +XXX,XX @@ FMINV_s 0110 1110 10 11000 01111 10 ..... ..... @rr_q1e2 |
328 | 328 | ||
329 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd | 329 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd |
330 | 330 | ||
331 | +# Floating-point Compare | 331 | +# Floating-point Compare |
332 | + | 332 | + |
333 | +FCMP 00011110 .. 1 rm:5 001000 rn:5 e:1 z:1 000 esz=%esz_hsd | 333 | +FCMP 00011110 .. 1 rm:5 001000 rn:5 e:1 z:1 000 esz=%esz_hsd |
334 | + | 334 | + |
335 | +# Floating-point Conditional Compare | 335 | +# Floating-point Conditional Compare |
336 | + | 336 | + |
337 | +FCCMP 00011110 .. 1 rm:5 cond:4 01 rn:5 e:1 nzcv:4 esz=%esz_hsd | 337 | +FCCMP 00011110 .. 1 rm:5 cond:4 01 rn:5 e:1 nzcv:4 esz=%esz_hsd |
338 | + | 338 | + |
339 | # Advanced SIMD Modified Immediate / Shift by Immediate | 339 | # Advanced SIMD Modified Immediate / Shift by Immediate |
340 | 340 | ||
341 | %abcdefgh 16:3 5:5 | 341 | %abcdefgh 16:3 5:5 |
342 | -- | 342 | -- |
343 | 2.43.0 | 343 | 2.43.0 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
3 | the unreachable implementation of scalar fneg. | 3 | the unreachable implementation of scalar fneg. |
4 | 4 | ||
5 | Reported-by: Peter Maydell <peter.maydell@linaro.org> | 5 | Reported-by: Peter Maydell <peter.maydell@linaro.org> |
6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
7 | --- | 7 | --- |
8 | target/arm/tcg/translate-a64.c | 4 +--- | 8 | target/arm/tcg/translate-a64.c | 6 +++--- |
9 | 1 file changed, 1 insertion(+), 3 deletions(-) | 9 | 1 file changed, 3 insertions(+), 3 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
... | ... | ||
18 | case 0x6f: /* FNEG */ | 18 | case 0x6f: /* FNEG */ |
19 | + only_in_vector = true; | 19 | + only_in_vector = true; |
20 | need_fpst = false; | 20 | need_fpst = false; |
21 | break; | 21 | break; |
22 | case 0x7d: /* FRSQRTE */ | 22 | case 0x7d: /* FRSQRTE */ |
23 | + break; | ||
24 | case 0x7f: /* FSQRT (vector) */ | ||
25 | + only_in_vector = true; | ||
26 | break; | ||
27 | default: | ||
28 | unallocated_encoding(s); | ||
23 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 29 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
24 | case 0x7b: /* FCVTZU */ | 30 | case 0x7b: /* FCVTZU */ |
25 | gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus); | 31 | gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus); |
26 | break; | 32 | break; |
27 | - case 0x6f: /* FNEG */ | 33 | - case 0x6f: /* FNEG */ |
... | ... | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
---|---|---|---|
1 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
2 | --- | 3 | --- |
3 | target/arm/tcg/translate-a64.c | 105 +++++++++++++++++++++++---------- | 4 | target/arm/tcg/translate-a64.c | 105 +++++++++++++++++++++++---------- |
4 | target/arm/tcg/a64.decode | 7 +++ | 5 | target/arm/tcg/a64.decode | 7 +++ |
5 | 2 files changed, 81 insertions(+), 31 deletions(-) | 6 | 2 files changed, 81 insertions(+), 31 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Pass fpstatus not env, like most other fp helpers. | 1 | Pass fpstatus not env, like most other fp helpers. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/helper.h | 6 +++--- | 6 | target/arm/helper.h | 6 +++--- |
7 | target/arm/tcg/translate-a64.c | 15 +++++++-------- | 7 | target/arm/tcg/translate-a64.c | 15 +++++++-------- |
8 | target/arm/tcg/translate-vfp.c | 6 +++--- | 8 | target/arm/tcg/translate-vfp.c | 6 +++--- |
9 | target/arm/vfp_helper.c | 12 ++++++------ | 9 | target/arm/vfp_helper.c | 12 ++++++------ |
10 | 4 files changed, 19 insertions(+), 20 deletions(-) | 10 | 4 files changed, 19 insertions(+), 20 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/helper.h b/target/arm/helper.h | 12 | diff --git a/target/arm/helper.h b/target/arm/helper.h |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/helper.h | 14 | --- a/target/arm/helper.h |
15 | +++ b/target/arm/helper.h | 15 | +++ b/target/arm/helper.h |
16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_maxnumd, f64, f64, f64, ptr) | 16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_maxnumd, f64, f64, f64, ptr) |
17 | DEF_HELPER_3(vfp_minnumh, f16, f16, f16, ptr) | 17 | DEF_HELPER_3(vfp_minnumh, f16, f16, f16, ptr) |
18 | DEF_HELPER_3(vfp_minnums, f32, f32, f32, ptr) | 18 | DEF_HELPER_3(vfp_minnums, f32, f32, f32, ptr) |
19 | DEF_HELPER_3(vfp_minnumd, f64, f64, f64, ptr) | 19 | DEF_HELPER_3(vfp_minnumd, f64, f64, f64, ptr) |
20 | -DEF_HELPER_2(vfp_sqrth, f16, f16, env) | 20 | -DEF_HELPER_2(vfp_sqrth, f16, f16, env) |
21 | -DEF_HELPER_2(vfp_sqrts, f32, f32, env) | 21 | -DEF_HELPER_2(vfp_sqrts, f32, f32, env) |
22 | -DEF_HELPER_2(vfp_sqrtd, f64, f64, env) | 22 | -DEF_HELPER_2(vfp_sqrtd, f64, f64, env) |
23 | +DEF_HELPER_2(vfp_sqrth, f16, f16, ptr) | 23 | +DEF_HELPER_2(vfp_sqrth, f16, f16, ptr) |
24 | +DEF_HELPER_2(vfp_sqrts, f32, f32, ptr) | 24 | +DEF_HELPER_2(vfp_sqrts, f32, f32, ptr) |
25 | +DEF_HELPER_2(vfp_sqrtd, f64, f64, ptr) | 25 | +DEF_HELPER_2(vfp_sqrtd, f64, f64, ptr) |
26 | DEF_HELPER_3(vfp_cmph, void, f16, f16, env) | 26 | DEF_HELPER_3(vfp_cmph, void, f16, f16, env) |
27 | DEF_HELPER_3(vfp_cmps, void, f32, f32, env) | 27 | DEF_HELPER_3(vfp_cmps, void, f32, f32, env) |
28 | DEF_HELPER_3(vfp_cmpd, void, f64, f64, env) | 28 | DEF_HELPER_3(vfp_cmpd, void, f64, f64, env) |
29 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 29 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
30 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
31 | --- a/target/arm/tcg/translate-a64.c | 31 | --- a/target/arm/tcg/translate-a64.c |
32 | +++ b/target/arm/tcg/translate-a64.c | 32 | +++ b/target/arm/tcg/translate-a64.c |
33 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 33 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
34 | 34 | ||
35 | switch (opcode) { | 35 | switch (opcode) { |
36 | case 0x3: /* FSQRT */ | 36 | case 0x3: /* FSQRT */ |
37 | - gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_env); | 37 | - gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_env); |
38 | - goto done; | 38 | - goto done; |
39 | + gen_fpst = gen_helper_vfp_sqrts; | 39 | + gen_fpst = gen_helper_vfp_sqrts; |
40 | + break; | 40 | + break; |
41 | case 0x6: /* BFCVT */ | 41 | case 0x6: /* BFCVT */ |
42 | gen_fpst = gen_helper_bfcvt; | 42 | gen_fpst = gen_helper_bfcvt; |
43 | break; | 43 | break; |
44 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 44 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
45 | gen_fpst(tcg_res, tcg_op, fpst); | 45 | gen_fpst(tcg_res, tcg_op, fpst); |
46 | } | 46 | } |
47 | 47 | ||
48 | - done: | 48 | - done: |
49 | write_fp_sreg(s, rd, tcg_res); | 49 | write_fp_sreg(s, rd, tcg_res); |
50 | } | 50 | } |
51 | 51 | ||
52 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) | 52 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) |
53 | 53 | ||
54 | switch (opcode) { | 54 | switch (opcode) { |
55 | case 0x3: /* FSQRT */ | 55 | case 0x3: /* FSQRT */ |
56 | - gen_helper_vfp_sqrtd(tcg_res, tcg_op, tcg_env); | 56 | - gen_helper_vfp_sqrtd(tcg_res, tcg_op, tcg_env); |
57 | - goto done; | 57 | - goto done; |
58 | + gen_fpst = gen_helper_vfp_sqrtd; | 58 | + gen_fpst = gen_helper_vfp_sqrtd; |
59 | + break; | 59 | + break; |
60 | case 0x8: /* FRINTN */ | 60 | case 0x8: /* FRINTN */ |
61 | case 0x9: /* FRINTP */ | 61 | case 0x9: /* FRINTP */ |
62 | case 0xa: /* FRINTM */ | 62 | case 0xa: /* FRINTM */ |
63 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) | 63 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) |
64 | gen_fpst(tcg_res, tcg_op, fpst); | 64 | gen_fpst(tcg_res, tcg_op, fpst); |
65 | } | 65 | } |
66 | 66 | ||
67 | - done: | 67 | - done: |
68 | write_fp_dreg(s, rd, tcg_res); | 68 | write_fp_dreg(s, rd, tcg_res); |
69 | } | 69 | } |
70 | 70 | ||
71 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 71 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
72 | gen_vfp_negd(tcg_rd, tcg_rn); | 72 | gen_vfp_negd(tcg_rd, tcg_rn); |
73 | break; | 73 | break; |
74 | case 0x7f: /* FSQRT */ | 74 | case 0x7f: /* FSQRT */ |
75 | - gen_helper_vfp_sqrtd(tcg_rd, tcg_rn, tcg_env); | 75 | - gen_helper_vfp_sqrtd(tcg_rd, tcg_rn, tcg_env); |
76 | + gen_helper_vfp_sqrtd(tcg_rd, tcg_rn, tcg_fpstatus); | 76 | + gen_helper_vfp_sqrtd(tcg_rd, tcg_rn, tcg_fpstatus); |
77 | break; | 77 | break; |
78 | case 0x1a: /* FCVTNS */ | 78 | case 0x1a: /* FCVTNS */ |
79 | case 0x1b: /* FCVTMS */ | 79 | case 0x1b: /* FCVTMS */ |
80 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 80 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
81 | handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd); | 81 | handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd); |
82 | return; | 82 | return; |
83 | case 0x7f: /* FSQRT */ | 83 | case 0x7f: /* FSQRT */ |
84 | + need_fpstatus = true; | 84 | + need_fpstatus = true; |
85 | if (size == 3 && !is_q) { | 85 | if (size == 3 && !is_q) { |
86 | unallocated_encoding(s); | 86 | unallocated_encoding(s); |
87 | return; | 87 | return; |
88 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 88 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
89 | gen_vfp_negs(tcg_res, tcg_op); | 89 | gen_vfp_negs(tcg_res, tcg_op); |
90 | break; | 90 | break; |
91 | case 0x7f: /* FSQRT */ | 91 | case 0x7f: /* FSQRT */ |
92 | - gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_env); | 92 | - gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_env); |
93 | + gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_fpstatus); | 93 | + gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_fpstatus); |
94 | break; | 94 | break; |
95 | case 0x1a: /* FCVTNS */ | 95 | case 0x1a: /* FCVTNS */ |
96 | case 0x1b: /* FCVTMS */ | 96 | case 0x1b: /* FCVTMS */ |
97 | diff --git a/target/arm/tcg/translate-vfp.c b/target/arm/tcg/translate-vfp.c | 97 | diff --git a/target/arm/tcg/translate-vfp.c b/target/arm/tcg/translate-vfp.c |
98 | index XXXXXXX..XXXXXXX 100644 | 98 | index XXXXXXX..XXXXXXX 100644 |
99 | --- a/target/arm/tcg/translate-vfp.c | 99 | --- a/target/arm/tcg/translate-vfp.c |
100 | +++ b/target/arm/tcg/translate-vfp.c | 100 | +++ b/target/arm/tcg/translate-vfp.c |
101 | @@ -XXX,XX +XXX,XX @@ DO_VFP_2OP(VNEG, dp, gen_vfp_negd, aa32_fpdp_v2) | 101 | @@ -XXX,XX +XXX,XX @@ DO_VFP_2OP(VNEG, dp, gen_vfp_negd, aa32_fpdp_v2) |
102 | 102 | ||
103 | static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm) | 103 | static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm) |
104 | { | 104 | { |
105 | - gen_helper_vfp_sqrth(vd, vm, tcg_env); | 105 | - gen_helper_vfp_sqrth(vd, vm, tcg_env); |
106 | + gen_helper_vfp_sqrth(vd, vm, fpstatus_ptr(FPST_FPCR_F16)); | 106 | + gen_helper_vfp_sqrth(vd, vm, fpstatus_ptr(FPST_FPCR_F16)); |
107 | } | 107 | } |
108 | 108 | ||
109 | static void gen_VSQRT_sp(TCGv_i32 vd, TCGv_i32 vm) | 109 | static void gen_VSQRT_sp(TCGv_i32 vd, TCGv_i32 vm) |
110 | { | 110 | { |
111 | - gen_helper_vfp_sqrts(vd, vm, tcg_env); | 111 | - gen_helper_vfp_sqrts(vd, vm, tcg_env); |
112 | + gen_helper_vfp_sqrts(vd, vm, fpstatus_ptr(FPST_FPCR)); | 112 | + gen_helper_vfp_sqrts(vd, vm, fpstatus_ptr(FPST_FPCR)); |
113 | } | 113 | } |
114 | 114 | ||
115 | static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm) | 115 | static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm) |
116 | { | 116 | { |
117 | - gen_helper_vfp_sqrtd(vd, vm, tcg_env); | 117 | - gen_helper_vfp_sqrtd(vd, vm, tcg_env); |
118 | + gen_helper_vfp_sqrtd(vd, vm, fpstatus_ptr(FPST_FPCR)); | 118 | + gen_helper_vfp_sqrtd(vd, vm, fpstatus_ptr(FPST_FPCR)); |
119 | } | 119 | } |
120 | 120 | ||
121 | DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith) | 121 | DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith) |
122 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | 122 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c |
123 | index XXXXXXX..XXXXXXX 100644 | 123 | index XXXXXXX..XXXXXXX 100644 |
124 | --- a/target/arm/vfp_helper.c | 124 | --- a/target/arm/vfp_helper.c |
125 | +++ b/target/arm/vfp_helper.c | 125 | +++ b/target/arm/vfp_helper.c |
126 | @@ -XXX,XX +XXX,XX @@ VFP_BINOP(minnum) | 126 | @@ -XXX,XX +XXX,XX @@ VFP_BINOP(minnum) |
127 | VFP_BINOP(maxnum) | 127 | VFP_BINOP(maxnum) |
128 | #undef VFP_BINOP | 128 | #undef VFP_BINOP |
129 | 129 | ||
130 | -dh_ctype_f16 VFP_HELPER(sqrt, h)(dh_ctype_f16 a, CPUARMState *env) | 130 | -dh_ctype_f16 VFP_HELPER(sqrt, h)(dh_ctype_f16 a, CPUARMState *env) |
131 | +dh_ctype_f16 VFP_HELPER(sqrt, h)(dh_ctype_f16 a, void *fpstp) | 131 | +dh_ctype_f16 VFP_HELPER(sqrt, h)(dh_ctype_f16 a, void *fpstp) |
132 | { | 132 | { |
133 | - return float16_sqrt(a, &env->vfp.fp_status_f16); | 133 | - return float16_sqrt(a, &env->vfp.fp_status_f16); |
134 | + return float16_sqrt(a, fpstp); | 134 | + return float16_sqrt(a, fpstp); |
135 | } | 135 | } |
136 | 136 | ||
137 | -float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env) | 137 | -float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env) |
138 | +float32 VFP_HELPER(sqrt, s)(float32 a, void *fpstp) | 138 | +float32 VFP_HELPER(sqrt, s)(float32 a, void *fpstp) |
139 | { | 139 | { |
140 | - return float32_sqrt(a, &env->vfp.fp_status); | 140 | - return float32_sqrt(a, &env->vfp.fp_status); |
141 | + return float32_sqrt(a, fpstp); | 141 | + return float32_sqrt(a, fpstp); |
142 | } | 142 | } |
143 | 143 | ||
144 | -float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env) | 144 | -float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env) |
145 | +float64 VFP_HELPER(sqrt, d)(float64 a, void *fpstp) | 145 | +float64 VFP_HELPER(sqrt, d)(float64 a, void *fpstp) |
146 | { | 146 | { |
147 | - return float64_sqrt(a, &env->vfp.fp_status); | 147 | - return float64_sqrt(a, &env->vfp.fp_status); |
148 | + return float64_sqrt(a, fpstp); | 148 | + return float64_sqrt(a, fpstp); |
149 | } | 149 | } |
150 | 150 | ||
151 | static void softfloat_to_vfp_compare(CPUARMState *env, FloatRelation cmp) | 151 | static void softfloat_to_vfp_compare(CPUARMState *env, FloatRelation cmp) |
152 | -- | 152 | -- |
153 | 2.43.0 | 153 | 2.43.0 | diff view generated by jsdifflib |
1 | This function is identical with helper_vfp_sqrth. | 1 | This function is identical with helper_vfp_sqrth. |
---|---|---|---|
2 | Replace all uses. | 2 | Replace all uses. |
3 | 3 | ||
4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/helper-a64.h | 1 - | 7 | target/arm/tcg/helper-a64.h | 1 - |
8 | target/arm/tcg/helper-a64.c | 11 ----------- | 8 | target/arm/tcg/helper-a64.c | 11 ----------- |
9 | target/arm/tcg/translate-a64.c | 4 ++-- | 9 | target/arm/tcg/translate-a64.c | 4 ++-- |
10 | 3 files changed, 2 insertions(+), 14 deletions(-) | 10 | 3 files changed, 2 insertions(+), 14 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h | 12 | diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/tcg/helper-a64.h | 14 | --- a/target/arm/tcg/helper-a64.h |
15 | +++ b/target/arm/tcg/helper-a64.h | 15 | +++ b/target/arm/tcg/helper-a64.h |
16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr) | 16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr) |
17 | DEF_HELPER_2(advsimd_rinth, f16, f16, ptr) | 17 | DEF_HELPER_2(advsimd_rinth, f16, f16, ptr) |
18 | DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr) | 18 | DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr) |
19 | DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr) | 19 | DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr) |
20 | -DEF_HELPER_2(sqrt_f16, f16, f16, ptr) | 20 | -DEF_HELPER_2(sqrt_f16, f16, f16, ptr) |
21 | 21 | ||
22 | DEF_HELPER_2(exception_return, void, env, i64) | 22 | DEF_HELPER_2(exception_return, void, env, i64) |
23 | DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64) | 23 | DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64) |
24 | diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c | 24 | diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c |
25 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/target/arm/tcg/helper-a64.c | 26 | --- a/target/arm/tcg/helper-a64.c |
27 | +++ b/target/arm/tcg/helper-a64.c | 27 | +++ b/target/arm/tcg/helper-a64.c |
28 | @@ -XXX,XX +XXX,XX @@ illegal_return: | 28 | @@ -XXX,XX +XXX,XX @@ illegal_return: |
29 | "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc); | 29 | "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc); |
30 | } | 30 | } |
31 | 31 | ||
32 | -/* | 32 | -/* |
33 | - * Square Root and Reciprocal square root | 33 | - * Square Root and Reciprocal square root |
34 | - */ | 34 | - */ |
35 | - | 35 | - |
36 | -uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp) | 36 | -uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp) |
37 | -{ | 37 | -{ |
38 | - float_status *s = fpstp; | 38 | - float_status *s = fpstp; |
39 | - | 39 | - |
40 | - return float16_sqrt(a, s); | 40 | - return float16_sqrt(a, s); |
41 | -} | 41 | -} |
42 | - | 42 | - |
43 | void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) | 43 | void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in) |
44 | { | 44 | { |
45 | uintptr_t ra = GETPC(); | 45 | uintptr_t ra = GETPC(); |
46 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 46 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
47 | index XXXXXXX..XXXXXXX 100644 | 47 | index XXXXXXX..XXXXXXX 100644 |
48 | --- a/target/arm/tcg/translate-a64.c | 48 | --- a/target/arm/tcg/translate-a64.c |
49 | +++ b/target/arm/tcg/translate-a64.c | 49 | +++ b/target/arm/tcg/translate-a64.c |
50 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) | 50 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) |
51 | switch (opcode) { | 51 | switch (opcode) { |
52 | case 0x3: /* FSQRT */ | 52 | case 0x3: /* FSQRT */ |
53 | fpst = fpstatus_ptr(FPST_FPCR_F16); | 53 | fpst = fpstatus_ptr(FPST_FPCR_F16); |
54 | - gen_helper_sqrt_f16(tcg_res, tcg_op, fpst); | 54 | - gen_helper_sqrt_f16(tcg_res, tcg_op, fpst); |
55 | + gen_helper_vfp_sqrth(tcg_res, tcg_op, fpst); | 55 | + gen_helper_vfp_sqrth(tcg_res, tcg_op, fpst); |
56 | break; | 56 | break; |
57 | case 0x8: /* FRINTN */ | 57 | case 0x8: /* FRINTN */ |
58 | case 0x9: /* FRINTP */ | 58 | case 0x9: /* FRINTP */ |
59 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 59 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
60 | gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); | 60 | gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); |
61 | break; | 61 | break; |
62 | case 0x7f: /* FSQRT */ | 62 | case 0x7f: /* FSQRT */ |
63 | - gen_helper_sqrt_f16(tcg_res, tcg_op, tcg_fpstatus); | 63 | - gen_helper_sqrt_f16(tcg_res, tcg_op, tcg_fpstatus); |
64 | + gen_helper_vfp_sqrth(tcg_res, tcg_op, tcg_fpstatus); | 64 | + gen_helper_vfp_sqrth(tcg_res, tcg_op, tcg_fpstatus); |
65 | break; | 65 | break; |
66 | default: | 66 | default: |
67 | g_assert_not_reached(); | 67 | g_assert_not_reached(); |
68 | -- | 68 | -- |
69 | 2.43.0 | 69 | 2.43.0 |
70 | 70 | ||
71 | 71 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 72 ++++++++++++++++++++++++++++------ | 4 | target/arm/tcg/translate-a64.c | 72 ++++++++++++++++++++++++++++------ |
5 | target/arm/tcg/a64.decode | 1 + | 5 | target/arm/tcg/a64.decode | 1 + |
6 | 2 files changed, 62 insertions(+), 11 deletions(-) | 6 | 2 files changed, 62 insertions(+), 11 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static const FPScalar1Int f_scalar_fneg = { | 12 | @@ -XXX,XX +XXX,XX @@ static const FPScalar1Int f_scalar_fneg = { |
13 | }; | 13 | }; |
14 | TRANS(FNEG_s, do_fp1_scalar_int, a, &f_scalar_fneg) | 14 | TRANS(FNEG_s, do_fp1_scalar_int, a, &f_scalar_fneg) |
15 | 15 | ||
16 | +typedef struct FPScalar1 { | 16 | +typedef struct FPScalar1 { |
17 | + void (*gen_h)(TCGv_i32, TCGv_i32, TCGv_ptr); | 17 | + void (*gen_h)(TCGv_i32, TCGv_i32, TCGv_ptr); |
18 | + void (*gen_s)(TCGv_i32, TCGv_i32, TCGv_ptr); | 18 | + void (*gen_s)(TCGv_i32, TCGv_i32, TCGv_ptr); |
19 | + void (*gen_d)(TCGv_i64, TCGv_i64, TCGv_ptr); | 19 | + void (*gen_d)(TCGv_i64, TCGv_i64, TCGv_ptr); |
20 | +} FPScalar1; | 20 | +} FPScalar1; |
21 | + | 21 | + |
22 | +static bool do_fp1_scalar(DisasContext *s, arg_rr_e *a, | 22 | +static bool do_fp1_scalar(DisasContext *s, arg_rr_e *a, |
23 | + const FPScalar1 *f, int rmode) | 23 | + const FPScalar1 *f, int rmode) |
24 | +{ | 24 | +{ |
25 | + TCGv_i32 tcg_rmode = NULL; | 25 | + TCGv_i32 tcg_rmode = NULL; |
26 | + TCGv_ptr fpst; | 26 | + TCGv_ptr fpst; |
27 | + TCGv_i64 t64; | 27 | + TCGv_i64 t64; |
28 | + TCGv_i32 t32; | 28 | + TCGv_i32 t32; |
29 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 29 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
30 | + | 30 | + |
31 | + if (check <= 0) { | 31 | + if (check <= 0) { |
32 | + return check == 0; | 32 | + return check == 0; |
33 | + } | 33 | + } |
34 | + | 34 | + |
35 | + fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | 35 | + fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); |
36 | + if (rmode >= 0) { | 36 | + if (rmode >= 0) { |
37 | + tcg_rmode = gen_set_rmode(rmode, fpst); | 37 | + tcg_rmode = gen_set_rmode(rmode, fpst); |
38 | + } | 38 | + } |
39 | + | 39 | + |
40 | + switch (a->esz) { | 40 | + switch (a->esz) { |
41 | + case MO_64: | 41 | + case MO_64: |
42 | + t64 = read_fp_dreg(s, a->rn); | 42 | + t64 = read_fp_dreg(s, a->rn); |
43 | + f->gen_d(t64, t64, fpst); | 43 | + f->gen_d(t64, t64, fpst); |
44 | + write_fp_dreg(s, a->rd, t64); | 44 | + write_fp_dreg(s, a->rd, t64); |
45 | + break; | 45 | + break; |
46 | + case MO_32: | 46 | + case MO_32: |
47 | + t32 = read_fp_sreg(s, a->rn); | 47 | + t32 = read_fp_sreg(s, a->rn); |
48 | + f->gen_s(t32, t32, fpst); | 48 | + f->gen_s(t32, t32, fpst); |
49 | + write_fp_sreg(s, a->rd, t32); | 49 | + write_fp_sreg(s, a->rd, t32); |
50 | + break; | 50 | + break; |
51 | + case MO_16: | 51 | + case MO_16: |
52 | + t32 = read_fp_hreg(s, a->rn); | 52 | + t32 = read_fp_hreg(s, a->rn); |
53 | + f->gen_h(t32, t32, fpst); | 53 | + f->gen_h(t32, t32, fpst); |
54 | + write_fp_sreg(s, a->rd, t32); | 54 | + write_fp_sreg(s, a->rd, t32); |
55 | + break; | 55 | + break; |
56 | + default: | 56 | + default: |
57 | + g_assert_not_reached(); | 57 | + g_assert_not_reached(); |
58 | + } | 58 | + } |
59 | + | 59 | + |
60 | + if (rmode >= 0) { | 60 | + if (rmode >= 0) { |
61 | + gen_restore_rmode(tcg_rmode, fpst); | 61 | + gen_restore_rmode(tcg_rmode, fpst); |
62 | + } | 62 | + } |
63 | + return true; | 63 | + return true; |
64 | +} | 64 | +} |
65 | + | 65 | + |
66 | +static const FPScalar1 f_scalar_fsqrt = { | 66 | +static const FPScalar1 f_scalar_fsqrt = { |
67 | + gen_helper_vfp_sqrth, | 67 | + gen_helper_vfp_sqrth, |
68 | + gen_helper_vfp_sqrts, | 68 | + gen_helper_vfp_sqrts, |
69 | + gen_helper_vfp_sqrtd, | 69 | + gen_helper_vfp_sqrtd, |
70 | +}; | 70 | +}; |
71 | +TRANS(FSQRT_s, do_fp1_scalar, a, &f_scalar_fsqrt, -1) | 71 | +TRANS(FSQRT_s, do_fp1_scalar, a, &f_scalar_fsqrt, -1) |
72 | + | 72 | + |
73 | /* Floating-point data-processing (1 source) - half precision */ | 73 | /* Floating-point data-processing (1 source) - half precision */ |
74 | static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) | 74 | static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) |
75 | { | 75 | { |
76 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) | 76 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) |
77 | TCGv_i32 tcg_res = tcg_temp_new_i32(); | 77 | TCGv_i32 tcg_res = tcg_temp_new_i32(); |
78 | 78 | ||
79 | switch (opcode) { | 79 | switch (opcode) { |
80 | - case 0x3: /* FSQRT */ | 80 | - case 0x3: /* FSQRT */ |
81 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | 81 | - fpst = fpstatus_ptr(FPST_FPCR_F16); |
82 | - gen_helper_vfp_sqrth(tcg_res, tcg_op, fpst); | 82 | - gen_helper_vfp_sqrth(tcg_res, tcg_op, fpst); |
83 | - break; | 83 | - break; |
84 | case 0x8: /* FRINTN */ | 84 | case 0x8: /* FRINTN */ |
85 | case 0x9: /* FRINTP */ | 85 | case 0x9: /* FRINTP */ |
86 | case 0xa: /* FRINTM */ | 86 | case 0xa: /* FRINTM */ |
87 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) | 87 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) |
88 | case 0x0: /* FMOV */ | 88 | case 0x0: /* FMOV */ |
89 | case 0x1: /* FABS */ | 89 | case 0x1: /* FABS */ |
90 | case 0x2: /* FNEG */ | 90 | case 0x2: /* FNEG */ |
91 | + case 0x3: /* FSQRT */ | 91 | + case 0x3: /* FSQRT */ |
92 | g_assert_not_reached(); | 92 | g_assert_not_reached(); |
93 | } | 93 | } |
94 | 94 | ||
95 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 95 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
96 | tcg_res = tcg_temp_new_i32(); | 96 | tcg_res = tcg_temp_new_i32(); |
97 | 97 | ||
98 | switch (opcode) { | 98 | switch (opcode) { |
99 | - case 0x3: /* FSQRT */ | 99 | - case 0x3: /* FSQRT */ |
100 | - gen_fpst = gen_helper_vfp_sqrts; | 100 | - gen_fpst = gen_helper_vfp_sqrts; |
101 | - break; | 101 | - break; |
102 | case 0x6: /* BFCVT */ | 102 | case 0x6: /* BFCVT */ |
103 | gen_fpst = gen_helper_bfcvt; | 103 | gen_fpst = gen_helper_bfcvt; |
104 | break; | 104 | break; |
105 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 105 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
106 | case 0x0: /* FMOV */ | 106 | case 0x0: /* FMOV */ |
107 | case 0x1: /* FABS */ | 107 | case 0x1: /* FABS */ |
108 | case 0x2: /* FNEG */ | 108 | case 0x2: /* FNEG */ |
109 | + case 0x3: /* FSQRT */ | 109 | + case 0x3: /* FSQRT */ |
110 | g_assert_not_reached(); | 110 | g_assert_not_reached(); |
111 | } | 111 | } |
112 | 112 | ||
113 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) | 113 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) |
114 | tcg_res = tcg_temp_new_i64(); | 114 | tcg_res = tcg_temp_new_i64(); |
115 | 115 | ||
116 | switch (opcode) { | 116 | switch (opcode) { |
117 | - case 0x3: /* FSQRT */ | 117 | - case 0x3: /* FSQRT */ |
118 | - gen_fpst = gen_helper_vfp_sqrtd; | 118 | - gen_fpst = gen_helper_vfp_sqrtd; |
119 | - break; | 119 | - break; |
120 | case 0x8: /* FRINTN */ | 120 | case 0x8: /* FRINTN */ |
121 | case 0x9: /* FRINTP */ | 121 | case 0x9: /* FRINTP */ |
122 | case 0xa: /* FRINTM */ | 122 | case 0xa: /* FRINTM */ |
123 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) | 123 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) |
124 | case 0x0: /* FMOV */ | 124 | case 0x0: /* FMOV */ |
125 | case 0x1: /* FABS */ | 125 | case 0x1: /* FABS */ |
126 | case 0x2: /* FNEG */ | 126 | case 0x2: /* FNEG */ |
127 | + case 0x3: /* FSQRT */ | 127 | + case 0x3: /* FSQRT */ |
128 | g_assert_not_reached(); | 128 | g_assert_not_reached(); |
129 | } | 129 | } |
130 | 130 | ||
131 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) | 131 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) |
132 | goto do_unallocated; | 132 | goto do_unallocated; |
133 | } | 133 | } |
134 | /* fall through */ | 134 | /* fall through */ |
135 | - case 0x3: | 135 | - case 0x3: |
136 | case 0x8 ... 0xc: | 136 | case 0x8 ... 0xc: |
137 | case 0xe ... 0xf: | 137 | case 0xe ... 0xf: |
138 | /* 32-to-32 and 64-to-64 ops */ | 138 | /* 32-to-32 and 64-to-64 ops */ |
139 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) | 139 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) |
140 | case 0x0: /* FMOV */ | 140 | case 0x0: /* FMOV */ |
141 | case 0x1: /* FABS */ | 141 | case 0x1: /* FABS */ |
142 | case 0x2: /* FNEG */ | 142 | case 0x2: /* FNEG */ |
143 | + case 0x3: /* FSQRT */ | 143 | + case 0x3: /* FSQRT */ |
144 | unallocated_encoding(s); | 144 | unallocated_encoding(s); |
145 | break; | 145 | break; |
146 | } | 146 | } |
147 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 147 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
148 | index XXXXXXX..XXXXXXX 100644 | 148 | index XXXXXXX..XXXXXXX 100644 |
149 | --- a/target/arm/tcg/a64.decode | 149 | --- a/target/arm/tcg/a64.decode |
150 | +++ b/target/arm/tcg/a64.decode | 150 | +++ b/target/arm/tcg/a64.decode |
151 | @@ -XXX,XX +XXX,XX @@ FMINV_s 0110 1110 10 11000 01111 10 ..... ..... @rr_q1e2 | 151 | @@ -XXX,XX +XXX,XX @@ FMINV_s 0110 1110 10 11000 01111 10 ..... ..... @rr_q1e2 |
152 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd | 152 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd |
153 | FABS_s 00011110 .. 1 000001 10000 ..... ..... @rr_hsd | 153 | FABS_s 00011110 .. 1 000001 10000 ..... ..... @rr_hsd |
154 | FNEG_s 00011110 .. 1 000010 10000 ..... ..... @rr_hsd | 154 | FNEG_s 00011110 .. 1 000010 10000 ..... ..... @rr_hsd |
155 | +FSQRT_s 00011110 .. 1 000011 10000 ..... ..... @rr_hsd | 155 | +FSQRT_s 00011110 .. 1 000011 10000 ..... ..... @rr_hsd |
156 | 156 | ||
157 | # Floating-point Immediate | 157 | # Floating-point Immediate |
158 | 158 | ||
159 | -- | 159 | -- |
160 | 2.43.0 | 160 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove handle_fp_1src_half as these were the last insns | 1 | Remove handle_fp_1src_half as these were the last insns |
---|---|---|---|
2 | decoded by that function. | 2 | decoded by that function. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 117 +++++++++++---------------------- | 7 | target/arm/tcg/translate-a64.c | 117 +++++++++++---------------------- |
8 | target/arm/tcg/a64.decode | 8 +++ | 8 | target/arm/tcg/a64.decode | 8 +++ |
9 | 2 files changed, 46 insertions(+), 79 deletions(-) | 9 | 2 files changed, 46 insertions(+), 79 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ static const FPScalar1 f_scalar_fsqrt = { | 15 | @@ -XXX,XX +XXX,XX @@ static const FPScalar1 f_scalar_fsqrt = { |
16 | }; | 16 | }; |
17 | TRANS(FSQRT_s, do_fp1_scalar, a, &f_scalar_fsqrt, -1) | 17 | TRANS(FSQRT_s, do_fp1_scalar, a, &f_scalar_fsqrt, -1) |
18 | 18 | ||
19 | -/* Floating-point data-processing (1 source) - half precision */ | 19 | -/* Floating-point data-processing (1 source) - half precision */ |
20 | -static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) | 20 | -static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn) |
21 | -{ | 21 | -{ |
22 | - TCGv_ptr fpst = NULL; | 22 | - TCGv_ptr fpst = NULL; |
23 | - TCGv_i32 tcg_op = read_fp_hreg(s, rn); | 23 | - TCGv_i32 tcg_op = read_fp_hreg(s, rn); |
24 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); | 24 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); |
25 | +static const FPScalar1 f_scalar_frint = { | 25 | +static const FPScalar1 f_scalar_frint = { |
26 | + gen_helper_advsimd_rinth, | 26 | + gen_helper_advsimd_rinth, |
27 | + gen_helper_rints, | 27 | + gen_helper_rints, |
28 | + gen_helper_rintd, | 28 | + gen_helper_rintd, |
29 | +}; | 29 | +}; |
30 | +TRANS(FRINTN_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_TIEEVEN) | 30 | +TRANS(FRINTN_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_TIEEVEN) |
31 | +TRANS(FRINTP_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_POSINF) | 31 | +TRANS(FRINTP_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_POSINF) |
32 | +TRANS(FRINTM_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_NEGINF) | 32 | +TRANS(FRINTM_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_NEGINF) |
33 | +TRANS(FRINTZ_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_ZERO) | 33 | +TRANS(FRINTZ_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_ZERO) |
34 | +TRANS(FRINTA_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_TIEAWAY) | 34 | +TRANS(FRINTA_s, do_fp1_scalar, a, &f_scalar_frint, FPROUNDING_TIEAWAY) |
35 | +TRANS(FRINTI_s, do_fp1_scalar, a, &f_scalar_frint, -1) | 35 | +TRANS(FRINTI_s, do_fp1_scalar, a, &f_scalar_frint, -1) |
36 | 36 | ||
37 | - switch (opcode) { | 37 | - switch (opcode) { |
38 | - case 0x8: /* FRINTN */ | 38 | - case 0x8: /* FRINTN */ |
39 | - case 0x9: /* FRINTP */ | 39 | - case 0x9: /* FRINTP */ |
40 | - case 0xa: /* FRINTM */ | 40 | - case 0xa: /* FRINTM */ |
41 | - case 0xb: /* FRINTZ */ | 41 | - case 0xb: /* FRINTZ */ |
42 | - case 0xc: /* FRINTA */ | 42 | - case 0xc: /* FRINTA */ |
43 | - { | 43 | - { |
44 | - TCGv_i32 tcg_rmode; | 44 | - TCGv_i32 tcg_rmode; |
45 | - | 45 | - |
46 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | 46 | - fpst = fpstatus_ptr(FPST_FPCR_F16); |
47 | - tcg_rmode = gen_set_rmode(opcode & 7, fpst); | 47 | - tcg_rmode = gen_set_rmode(opcode & 7, fpst); |
48 | - gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst); | 48 | - gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst); |
49 | - gen_restore_rmode(tcg_rmode, fpst); | 49 | - gen_restore_rmode(tcg_rmode, fpst); |
50 | - break; | 50 | - break; |
51 | - } | 51 | - } |
52 | - case 0xe: /* FRINTX */ | 52 | - case 0xe: /* FRINTX */ |
53 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | 53 | - fpst = fpstatus_ptr(FPST_FPCR_F16); |
54 | - gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, fpst); | 54 | - gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, fpst); |
55 | - break; | 55 | - break; |
56 | - case 0xf: /* FRINTI */ | 56 | - case 0xf: /* FRINTI */ |
57 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | 57 | - fpst = fpstatus_ptr(FPST_FPCR_F16); |
58 | - gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst); | 58 | - gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst); |
59 | - break; | 59 | - break; |
60 | - default: | 60 | - default: |
61 | - case 0x0: /* FMOV */ | 61 | - case 0x0: /* FMOV */ |
62 | - case 0x1: /* FABS */ | 62 | - case 0x1: /* FABS */ |
63 | - case 0x2: /* FNEG */ | 63 | - case 0x2: /* FNEG */ |
64 | - case 0x3: /* FSQRT */ | 64 | - case 0x3: /* FSQRT */ |
65 | - g_assert_not_reached(); | 65 | - g_assert_not_reached(); |
66 | - } | 66 | - } |
67 | - | 67 | - |
68 | - write_fp_sreg(s, rd, tcg_res); | 68 | - write_fp_sreg(s, rd, tcg_res); |
69 | -} | 69 | -} |
70 | +static const FPScalar1 f_scalar_frintx = { | 70 | +static const FPScalar1 f_scalar_frintx = { |
71 | + gen_helper_advsimd_rinth_exact, | 71 | + gen_helper_advsimd_rinth_exact, |
72 | + gen_helper_rints_exact, | 72 | + gen_helper_rints_exact, |
73 | + gen_helper_rintd_exact, | 73 | + gen_helper_rintd_exact, |
74 | +}; | 74 | +}; |
75 | +TRANS(FRINTX_s, do_fp1_scalar, a, &f_scalar_frintx, -1) | 75 | +TRANS(FRINTX_s, do_fp1_scalar, a, &f_scalar_frintx, -1) |
76 | 76 | ||
77 | /* Floating-point data-processing (1 source) - single precision */ | 77 | /* Floating-point data-processing (1 source) - single precision */ |
78 | static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 78 | static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
79 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 79 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
80 | case 0x6: /* BFCVT */ | 80 | case 0x6: /* BFCVT */ |
81 | gen_fpst = gen_helper_bfcvt; | 81 | gen_fpst = gen_helper_bfcvt; |
82 | break; | 82 | break; |
83 | - case 0x8: /* FRINTN */ | 83 | - case 0x8: /* FRINTN */ |
84 | - case 0x9: /* FRINTP */ | 84 | - case 0x9: /* FRINTP */ |
85 | - case 0xa: /* FRINTM */ | 85 | - case 0xa: /* FRINTM */ |
86 | - case 0xb: /* FRINTZ */ | 86 | - case 0xb: /* FRINTZ */ |
87 | - case 0xc: /* FRINTA */ | 87 | - case 0xc: /* FRINTA */ |
88 | - rmode = opcode & 7; | 88 | - rmode = opcode & 7; |
89 | - gen_fpst = gen_helper_rints; | 89 | - gen_fpst = gen_helper_rints; |
90 | - break; | 90 | - break; |
91 | - case 0xe: /* FRINTX */ | 91 | - case 0xe: /* FRINTX */ |
92 | - gen_fpst = gen_helper_rints_exact; | 92 | - gen_fpst = gen_helper_rints_exact; |
93 | - break; | 93 | - break; |
94 | - case 0xf: /* FRINTI */ | 94 | - case 0xf: /* FRINTI */ |
95 | - gen_fpst = gen_helper_rints; | 95 | - gen_fpst = gen_helper_rints; |
96 | - break; | 96 | - break; |
97 | case 0x10: /* FRINT32Z */ | 97 | case 0x10: /* FRINT32Z */ |
98 | rmode = FPROUNDING_ZERO; | 98 | rmode = FPROUNDING_ZERO; |
99 | gen_fpst = gen_helper_frint32_s; | 99 | gen_fpst = gen_helper_frint32_s; |
100 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 100 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
101 | case 0x1: /* FABS */ | 101 | case 0x1: /* FABS */ |
102 | case 0x2: /* FNEG */ | 102 | case 0x2: /* FNEG */ |
103 | case 0x3: /* FSQRT */ | 103 | case 0x3: /* FSQRT */ |
104 | + case 0x8: /* FRINTN */ | 104 | + case 0x8: /* FRINTN */ |
105 | + case 0x9: /* FRINTP */ | 105 | + case 0x9: /* FRINTP */ |
106 | + case 0xa: /* FRINTM */ | 106 | + case 0xa: /* FRINTM */ |
107 | + case 0xb: /* FRINTZ */ | 107 | + case 0xb: /* FRINTZ */ |
108 | + case 0xc: /* FRINTA */ | 108 | + case 0xc: /* FRINTA */ |
109 | + case 0xe: /* FRINTX */ | 109 | + case 0xe: /* FRINTX */ |
110 | + case 0xf: /* FRINTI */ | 110 | + case 0xf: /* FRINTI */ |
111 | g_assert_not_reached(); | 111 | g_assert_not_reached(); |
112 | } | 112 | } |
113 | 113 | ||
114 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) | 114 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) |
115 | tcg_res = tcg_temp_new_i64(); | 115 | tcg_res = tcg_temp_new_i64(); |
116 | 116 | ||
117 | switch (opcode) { | 117 | switch (opcode) { |
118 | - case 0x8: /* FRINTN */ | 118 | - case 0x8: /* FRINTN */ |
119 | - case 0x9: /* FRINTP */ | 119 | - case 0x9: /* FRINTP */ |
120 | - case 0xa: /* FRINTM */ | 120 | - case 0xa: /* FRINTM */ |
121 | - case 0xb: /* FRINTZ */ | 121 | - case 0xb: /* FRINTZ */ |
122 | - case 0xc: /* FRINTA */ | 122 | - case 0xc: /* FRINTA */ |
123 | - rmode = opcode & 7; | 123 | - rmode = opcode & 7; |
124 | - gen_fpst = gen_helper_rintd; | 124 | - gen_fpst = gen_helper_rintd; |
125 | - break; | 125 | - break; |
126 | - case 0xe: /* FRINTX */ | 126 | - case 0xe: /* FRINTX */ |
127 | - gen_fpst = gen_helper_rintd_exact; | 127 | - gen_fpst = gen_helper_rintd_exact; |
128 | - break; | 128 | - break; |
129 | - case 0xf: /* FRINTI */ | 129 | - case 0xf: /* FRINTI */ |
130 | - gen_fpst = gen_helper_rintd; | 130 | - gen_fpst = gen_helper_rintd; |
131 | - break; | 131 | - break; |
132 | case 0x10: /* FRINT32Z */ | 132 | case 0x10: /* FRINT32Z */ |
133 | rmode = FPROUNDING_ZERO; | 133 | rmode = FPROUNDING_ZERO; |
134 | gen_fpst = gen_helper_frint32_d; | 134 | gen_fpst = gen_helper_frint32_d; |
135 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) | 135 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) |
136 | case 0x1: /* FABS */ | 136 | case 0x1: /* FABS */ |
137 | case 0x2: /* FNEG */ | 137 | case 0x2: /* FNEG */ |
138 | case 0x3: /* FSQRT */ | 138 | case 0x3: /* FSQRT */ |
139 | + case 0x8: /* FRINTN */ | 139 | + case 0x8: /* FRINTN */ |
140 | + case 0x9: /* FRINTP */ | 140 | + case 0x9: /* FRINTP */ |
141 | + case 0xa: /* FRINTM */ | 141 | + case 0xa: /* FRINTM */ |
142 | + case 0xb: /* FRINTZ */ | 142 | + case 0xb: /* FRINTZ */ |
143 | + case 0xc: /* FRINTA */ | 143 | + case 0xc: /* FRINTA */ |
144 | + case 0xe: /* FRINTX */ | 144 | + case 0xe: /* FRINTX */ |
145 | + case 0xf: /* FRINTI */ | 145 | + case 0xf: /* FRINTI */ |
146 | g_assert_not_reached(); | 146 | g_assert_not_reached(); |
147 | } | 147 | } |
148 | 148 | ||
149 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) | 149 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) |
150 | if (type > 1 || !dc_isar_feature(aa64_frint, s)) { | 150 | if (type > 1 || !dc_isar_feature(aa64_frint, s)) { |
151 | goto do_unallocated; | 151 | goto do_unallocated; |
152 | } | 152 | } |
153 | - /* fall through */ | 153 | - /* fall through */ |
154 | - case 0x8 ... 0xc: | 154 | - case 0x8 ... 0xc: |
155 | - case 0xe ... 0xf: | 155 | - case 0xe ... 0xf: |
156 | /* 32-to-32 and 64-to-64 ops */ | 156 | /* 32-to-32 and 64-to-64 ops */ |
157 | switch (type) { | 157 | switch (type) { |
158 | case 0: | 158 | case 0: |
159 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) | 159 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) |
160 | handle_fp_1src_double(s, opcode, rd, rn); | 160 | handle_fp_1src_double(s, opcode, rd, rn); |
161 | break; | 161 | break; |
162 | case 3: | 162 | case 3: |
163 | - if (!dc_isar_feature(aa64_fp16, s)) { | 163 | - if (!dc_isar_feature(aa64_fp16, s)) { |
164 | - goto do_unallocated; | 164 | - goto do_unallocated; |
165 | - } | 165 | - } |
166 | - | 166 | - |
167 | - if (!fp_access_check(s)) { | 167 | - if (!fp_access_check(s)) { |
168 | - return; | 168 | - return; |
169 | - } | 169 | - } |
170 | - handle_fp_1src_half(s, opcode, rd, rn); | 170 | - handle_fp_1src_half(s, opcode, rd, rn); |
171 | - break; | 171 | - break; |
172 | default: | 172 | default: |
173 | goto do_unallocated; | 173 | goto do_unallocated; |
174 | } | 174 | } |
175 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) | 175 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) |
176 | case 0x1: /* FABS */ | 176 | case 0x1: /* FABS */ |
177 | case 0x2: /* FNEG */ | 177 | case 0x2: /* FNEG */ |
178 | case 0x3: /* FSQRT */ | 178 | case 0x3: /* FSQRT */ |
179 | + case 0x8: /* FRINTN */ | 179 | + case 0x8: /* FRINTN */ |
180 | + case 0x9: /* FRINTP */ | 180 | + case 0x9: /* FRINTP */ |
181 | + case 0xa: /* FRINTM */ | 181 | + case 0xa: /* FRINTM */ |
182 | + case 0xb: /* FRINTZ */ | 182 | + case 0xb: /* FRINTZ */ |
183 | + case 0xc: /* FRINTA */ | 183 | + case 0xc: /* FRINTA */ |
184 | + case 0xe: /* FRINTX */ | 184 | + case 0xe: /* FRINTX */ |
185 | + case 0xf: /* FRINTI */ | 185 | + case 0xf: /* FRINTI */ |
186 | unallocated_encoding(s); | 186 | unallocated_encoding(s); |
187 | break; | 187 | break; |
188 | } | 188 | } |
189 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 189 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
190 | index XXXXXXX..XXXXXXX 100644 | 190 | index XXXXXXX..XXXXXXX 100644 |
191 | --- a/target/arm/tcg/a64.decode | 191 | --- a/target/arm/tcg/a64.decode |
192 | +++ b/target/arm/tcg/a64.decode | 192 | +++ b/target/arm/tcg/a64.decode |
193 | @@ -XXX,XX +XXX,XX @@ FABS_s 00011110 .. 1 000001 10000 ..... ..... @rr_hsd | 193 | @@ -XXX,XX +XXX,XX @@ FABS_s 00011110 .. 1 000001 10000 ..... ..... @rr_hsd |
194 | FNEG_s 00011110 .. 1 000010 10000 ..... ..... @rr_hsd | 194 | FNEG_s 00011110 .. 1 000010 10000 ..... ..... @rr_hsd |
195 | FSQRT_s 00011110 .. 1 000011 10000 ..... ..... @rr_hsd | 195 | FSQRT_s 00011110 .. 1 000011 10000 ..... ..... @rr_hsd |
196 | 196 | ||
197 | +FRINTN_s 00011110 .. 1 001000 10000 ..... ..... @rr_hsd | 197 | +FRINTN_s 00011110 .. 1 001000 10000 ..... ..... @rr_hsd |
198 | +FRINTP_s 00011110 .. 1 001001 10000 ..... ..... @rr_hsd | 198 | +FRINTP_s 00011110 .. 1 001001 10000 ..... ..... @rr_hsd |
199 | +FRINTM_s 00011110 .. 1 001010 10000 ..... ..... @rr_hsd | 199 | +FRINTM_s 00011110 .. 1 001010 10000 ..... ..... @rr_hsd |
200 | +FRINTZ_s 00011110 .. 1 001011 10000 ..... ..... @rr_hsd | 200 | +FRINTZ_s 00011110 .. 1 001011 10000 ..... ..... @rr_hsd |
201 | +FRINTA_s 00011110 .. 1 001100 10000 ..... ..... @rr_hsd | 201 | +FRINTA_s 00011110 .. 1 001100 10000 ..... ..... @rr_hsd |
202 | +FRINTX_s 00011110 .. 1 001110 10000 ..... ..... @rr_hsd | 202 | +FRINTX_s 00011110 .. 1 001110 10000 ..... ..... @rr_hsd |
203 | +FRINTI_s 00011110 .. 1 001111 10000 ..... ..... @rr_hsd | 203 | +FRINTI_s 00011110 .. 1 001111 10000 ..... ..... @rr_hsd |
204 | + | 204 | + |
205 | # Floating-point Immediate | 205 | # Floating-point Immediate |
206 | 206 | ||
207 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd | 207 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd |
208 | -- | 208 | -- |
209 | 2.43.0 | 209 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
---|---|---|---|
1 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
2 | --- | 3 | --- |
3 | target/arm/tcg/translate-a64.c | 26 +++++++------------------- | 4 | target/arm/tcg/translate-a64.c | 26 +++++++------------------- |
4 | target/arm/tcg/a64.decode | 3 +++ | 5 | target/arm/tcg/a64.decode | 3 +++ |
5 | 2 files changed, 10 insertions(+), 19 deletions(-) | 6 | 2 files changed, 10 insertions(+), 19 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Remove handle_fp_1src_single and handle_fp_1src_double as | 1 | Remove handle_fp_1src_single and handle_fp_1src_double as |
---|---|---|---|
2 | these were the last insns decoded by those functions. | 2 | these were the last insns decoded by those functions. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 146 ++++----------------------------- | 7 | target/arm/tcg/translate-a64.c | 146 ++++----------------------------- |
8 | target/arm/tcg/a64.decode | 5 ++ | 8 | target/arm/tcg/a64.decode | 5 ++ |
9 | 2 files changed, 22 insertions(+), 129 deletions(-) | 9 | 2 files changed, 22 insertions(+), 129 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ static const FPScalar1 f_scalar_bfcvt = { | 15 | @@ -XXX,XX +XXX,XX @@ static const FPScalar1 f_scalar_bfcvt = { |
16 | }; | 16 | }; |
17 | TRANS_FEAT(BFCVT_s, aa64_bf16, do_fp1_scalar, a, &f_scalar_bfcvt, -1) | 17 | TRANS_FEAT(BFCVT_s, aa64_bf16, do_fp1_scalar, a, &f_scalar_bfcvt, -1) |
18 | 18 | ||
19 | -/* Floating-point data-processing (1 source) - single precision */ | 19 | -/* Floating-point data-processing (1 source) - single precision */ |
20 | -static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) | 20 | -static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn) |
21 | -{ | 21 | -{ |
22 | - void (*gen_fpst)(TCGv_i32, TCGv_i32, TCGv_ptr); | 22 | - void (*gen_fpst)(TCGv_i32, TCGv_i32, TCGv_ptr); |
23 | - TCGv_i32 tcg_op, tcg_res; | 23 | - TCGv_i32 tcg_op, tcg_res; |
24 | - TCGv_ptr fpst; | 24 | - TCGv_ptr fpst; |
25 | - int rmode = -1; | 25 | - int rmode = -1; |
26 | +static const FPScalar1 f_scalar_frint32 = { | 26 | +static const FPScalar1 f_scalar_frint32 = { |
27 | + NULL, | 27 | + NULL, |
28 | + gen_helper_frint32_s, | 28 | + gen_helper_frint32_s, |
29 | + gen_helper_frint32_d, | 29 | + gen_helper_frint32_d, |
30 | +}; | 30 | +}; |
31 | +TRANS_FEAT(FRINT32Z_s, aa64_frint, do_fp1_scalar, a, | 31 | +TRANS_FEAT(FRINT32Z_s, aa64_frint, do_fp1_scalar, a, |
32 | + &f_scalar_frint32, FPROUNDING_ZERO) | 32 | + &f_scalar_frint32, FPROUNDING_ZERO) |
33 | +TRANS_FEAT(FRINT32X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint32, -1) | 33 | +TRANS_FEAT(FRINT32X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint32, -1) |
34 | 34 | ||
35 | - tcg_op = read_fp_sreg(s, rn); | 35 | - tcg_op = read_fp_sreg(s, rn); |
36 | - tcg_res = tcg_temp_new_i32(); | 36 | - tcg_res = tcg_temp_new_i32(); |
37 | - | 37 | - |
38 | - switch (opcode) { | 38 | - switch (opcode) { |
39 | - case 0x10: /* FRINT32Z */ | 39 | - case 0x10: /* FRINT32Z */ |
40 | - rmode = FPROUNDING_ZERO; | 40 | - rmode = FPROUNDING_ZERO; |
41 | - gen_fpst = gen_helper_frint32_s; | 41 | - gen_fpst = gen_helper_frint32_s; |
42 | - break; | 42 | - break; |
43 | - case 0x11: /* FRINT32X */ | 43 | - case 0x11: /* FRINT32X */ |
44 | - gen_fpst = gen_helper_frint32_s; | 44 | - gen_fpst = gen_helper_frint32_s; |
45 | - break; | 45 | - break; |
46 | - case 0x12: /* FRINT64Z */ | 46 | - case 0x12: /* FRINT64Z */ |
47 | - rmode = FPROUNDING_ZERO; | 47 | - rmode = FPROUNDING_ZERO; |
48 | - gen_fpst = gen_helper_frint64_s; | 48 | - gen_fpst = gen_helper_frint64_s; |
49 | - break; | 49 | - break; |
50 | - case 0x13: /* FRINT64X */ | 50 | - case 0x13: /* FRINT64X */ |
51 | - gen_fpst = gen_helper_frint64_s; | 51 | - gen_fpst = gen_helper_frint64_s; |
52 | - break; | 52 | - break; |
53 | - default: | 53 | - default: |
54 | - case 0x0: /* FMOV */ | 54 | - case 0x0: /* FMOV */ |
55 | - case 0x1: /* FABS */ | 55 | - case 0x1: /* FABS */ |
56 | - case 0x2: /* FNEG */ | 56 | - case 0x2: /* FNEG */ |
57 | - case 0x3: /* FSQRT */ | 57 | - case 0x3: /* FSQRT */ |
58 | - case 0x6: /* BFCVT */ | 58 | - case 0x6: /* BFCVT */ |
59 | - case 0x8: /* FRINTN */ | 59 | - case 0x8: /* FRINTN */ |
60 | - case 0x9: /* FRINTP */ | 60 | - case 0x9: /* FRINTP */ |
61 | - case 0xa: /* FRINTM */ | 61 | - case 0xa: /* FRINTM */ |
62 | - case 0xb: /* FRINTZ */ | 62 | - case 0xb: /* FRINTZ */ |
63 | - case 0xc: /* FRINTA */ | 63 | - case 0xc: /* FRINTA */ |
64 | - case 0xe: /* FRINTX */ | 64 | - case 0xe: /* FRINTX */ |
65 | - case 0xf: /* FRINTI */ | 65 | - case 0xf: /* FRINTI */ |
66 | - g_assert_not_reached(); | 66 | - g_assert_not_reached(); |
67 | - } | 67 | - } |
68 | - | 68 | - |
69 | - fpst = fpstatus_ptr(FPST_FPCR); | 69 | - fpst = fpstatus_ptr(FPST_FPCR); |
70 | - if (rmode >= 0) { | 70 | - if (rmode >= 0) { |
71 | - TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst); | 71 | - TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst); |
72 | - gen_fpst(tcg_res, tcg_op, fpst); | 72 | - gen_fpst(tcg_res, tcg_op, fpst); |
73 | - gen_restore_rmode(tcg_rmode, fpst); | 73 | - gen_restore_rmode(tcg_rmode, fpst); |
74 | - } else { | 74 | - } else { |
75 | - gen_fpst(tcg_res, tcg_op, fpst); | 75 | - gen_fpst(tcg_res, tcg_op, fpst); |
76 | - } | 76 | - } |
77 | - | 77 | - |
78 | - write_fp_sreg(s, rd, tcg_res); | 78 | - write_fp_sreg(s, rd, tcg_res); |
79 | -} | 79 | -} |
80 | - | 80 | - |
81 | -/* Floating-point data-processing (1 source) - double precision */ | 81 | -/* Floating-point data-processing (1 source) - double precision */ |
82 | -static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) | 82 | -static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) |
83 | -{ | 83 | -{ |
84 | - void (*gen_fpst)(TCGv_i64, TCGv_i64, TCGv_ptr); | 84 | - void (*gen_fpst)(TCGv_i64, TCGv_i64, TCGv_ptr); |
85 | - TCGv_i64 tcg_op, tcg_res; | 85 | - TCGv_i64 tcg_op, tcg_res; |
86 | - TCGv_ptr fpst; | 86 | - TCGv_ptr fpst; |
87 | - int rmode = -1; | 87 | - int rmode = -1; |
88 | - | 88 | - |
89 | - tcg_op = read_fp_dreg(s, rn); | 89 | - tcg_op = read_fp_dreg(s, rn); |
90 | - tcg_res = tcg_temp_new_i64(); | 90 | - tcg_res = tcg_temp_new_i64(); |
91 | - | 91 | - |
92 | - switch (opcode) { | 92 | - switch (opcode) { |
93 | - case 0x10: /* FRINT32Z */ | 93 | - case 0x10: /* FRINT32Z */ |
94 | - rmode = FPROUNDING_ZERO; | 94 | - rmode = FPROUNDING_ZERO; |
95 | - gen_fpst = gen_helper_frint32_d; | 95 | - gen_fpst = gen_helper_frint32_d; |
96 | - break; | 96 | - break; |
97 | - case 0x11: /* FRINT32X */ | 97 | - case 0x11: /* FRINT32X */ |
98 | - gen_fpst = gen_helper_frint32_d; | 98 | - gen_fpst = gen_helper_frint32_d; |
99 | - break; | 99 | - break; |
100 | - case 0x12: /* FRINT64Z */ | 100 | - case 0x12: /* FRINT64Z */ |
101 | - rmode = FPROUNDING_ZERO; | 101 | - rmode = FPROUNDING_ZERO; |
102 | - gen_fpst = gen_helper_frint64_d; | 102 | - gen_fpst = gen_helper_frint64_d; |
103 | - break; | 103 | - break; |
104 | - case 0x13: /* FRINT64X */ | 104 | - case 0x13: /* FRINT64X */ |
105 | - gen_fpst = gen_helper_frint64_d; | 105 | - gen_fpst = gen_helper_frint64_d; |
106 | - break; | 106 | - break; |
107 | - default: | 107 | - default: |
108 | - case 0x0: /* FMOV */ | 108 | - case 0x0: /* FMOV */ |
109 | - case 0x1: /* FABS */ | 109 | - case 0x1: /* FABS */ |
110 | - case 0x2: /* FNEG */ | 110 | - case 0x2: /* FNEG */ |
111 | - case 0x3: /* FSQRT */ | 111 | - case 0x3: /* FSQRT */ |
112 | - case 0x8: /* FRINTN */ | 112 | - case 0x8: /* FRINTN */ |
113 | - case 0x9: /* FRINTP */ | 113 | - case 0x9: /* FRINTP */ |
114 | - case 0xa: /* FRINTM */ | 114 | - case 0xa: /* FRINTM */ |
115 | - case 0xb: /* FRINTZ */ | 115 | - case 0xb: /* FRINTZ */ |
116 | - case 0xc: /* FRINTA */ | 116 | - case 0xc: /* FRINTA */ |
117 | - case 0xe: /* FRINTX */ | 117 | - case 0xe: /* FRINTX */ |
118 | - case 0xf: /* FRINTI */ | 118 | - case 0xf: /* FRINTI */ |
119 | - g_assert_not_reached(); | 119 | - g_assert_not_reached(); |
120 | - } | 120 | - } |
121 | - | 121 | - |
122 | - fpst = fpstatus_ptr(FPST_FPCR); | 122 | - fpst = fpstatus_ptr(FPST_FPCR); |
123 | - if (rmode >= 0) { | 123 | - if (rmode >= 0) { |
124 | - TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst); | 124 | - TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst); |
125 | - gen_fpst(tcg_res, tcg_op, fpst); | 125 | - gen_fpst(tcg_res, tcg_op, fpst); |
126 | - gen_restore_rmode(tcg_rmode, fpst); | 126 | - gen_restore_rmode(tcg_rmode, fpst); |
127 | - } else { | 127 | - } else { |
128 | - gen_fpst(tcg_res, tcg_op, fpst); | 128 | - gen_fpst(tcg_res, tcg_op, fpst); |
129 | - } | 129 | - } |
130 | - | 130 | - |
131 | - write_fp_dreg(s, rd, tcg_res); | 131 | - write_fp_dreg(s, rd, tcg_res); |
132 | -} | 132 | -} |
133 | +static const FPScalar1 f_scalar_frint64 = { | 133 | +static const FPScalar1 f_scalar_frint64 = { |
134 | + NULL, | 134 | + NULL, |
135 | + gen_helper_frint64_s, | 135 | + gen_helper_frint64_s, |
136 | + gen_helper_frint64_d, | 136 | + gen_helper_frint64_d, |
137 | +}; | 137 | +}; |
138 | +TRANS_FEAT(FRINT64Z_s, aa64_frint, do_fp1_scalar, a, | 138 | +TRANS_FEAT(FRINT64Z_s, aa64_frint, do_fp1_scalar, a, |
139 | + &f_scalar_frint64, FPROUNDING_ZERO) | 139 | + &f_scalar_frint64, FPROUNDING_ZERO) |
140 | +TRANS_FEAT(FRINT64X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint64, -1) | 140 | +TRANS_FEAT(FRINT64X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint64, -1) |
141 | 141 | ||
142 | static void handle_fp_fcvt(DisasContext *s, int opcode, | 142 | static void handle_fp_fcvt(DisasContext *s, int opcode, |
143 | int rd, int rn, int dtype, int ntype) | 143 | int rd, int rn, int dtype, int ntype) |
144 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) | 144 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) |
145 | break; | 145 | break; |
146 | } | 146 | } |
147 | 147 | ||
148 | - case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */ | 148 | - case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */ |
149 | - if (type > 1 || !dc_isar_feature(aa64_frint, s)) { | 149 | - if (type > 1 || !dc_isar_feature(aa64_frint, s)) { |
150 | - goto do_unallocated; | 150 | - goto do_unallocated; |
151 | - } | 151 | - } |
152 | - /* 32-to-32 and 64-to-64 ops */ | 152 | - /* 32-to-32 and 64-to-64 ops */ |
153 | - switch (type) { | 153 | - switch (type) { |
154 | - case 0: | 154 | - case 0: |
155 | - if (!fp_access_check(s)) { | 155 | - if (!fp_access_check(s)) { |
156 | - return; | 156 | - return; |
157 | - } | 157 | - } |
158 | - handle_fp_1src_single(s, opcode, rd, rn); | 158 | - handle_fp_1src_single(s, opcode, rd, rn); |
159 | - break; | 159 | - break; |
160 | - case 1: | 160 | - case 1: |
161 | - if (!fp_access_check(s)) { | 161 | - if (!fp_access_check(s)) { |
162 | - return; | 162 | - return; |
163 | - } | 163 | - } |
164 | - handle_fp_1src_double(s, opcode, rd, rn); | 164 | - handle_fp_1src_double(s, opcode, rd, rn); |
165 | - break; | 165 | - break; |
166 | - case 3: | 166 | - case 3: |
167 | - default: | 167 | - default: |
168 | - goto do_unallocated; | 168 | - goto do_unallocated; |
169 | - } | 169 | - } |
170 | - break; | 170 | - break; |
171 | - | 171 | - |
172 | default: | 172 | default: |
173 | do_unallocated: | 173 | do_unallocated: |
174 | case 0x0: /* FMOV */ | 174 | case 0x0: /* FMOV */ |
175 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) | 175 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) |
176 | case 0xc: /* FRINTA */ | 176 | case 0xc: /* FRINTA */ |
177 | case 0xe: /* FRINTX */ | 177 | case 0xe: /* FRINTX */ |
178 | case 0xf: /* FRINTI */ | 178 | case 0xf: /* FRINTI */ |
179 | + case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */ | 179 | + case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */ |
180 | unallocated_encoding(s); | 180 | unallocated_encoding(s); |
181 | break; | 181 | break; |
182 | } | 182 | } |
183 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 183 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
184 | index XXXXXXX..XXXXXXX 100644 | 184 | index XXXXXXX..XXXXXXX 100644 |
185 | --- a/target/arm/tcg/a64.decode | 185 | --- a/target/arm/tcg/a64.decode |
186 | +++ b/target/arm/tcg/a64.decode | 186 | +++ b/target/arm/tcg/a64.decode |
187 | @@ -XXX,XX +XXX,XX @@ FRINTI_s 00011110 .. 1 001111 10000 ..... ..... @rr_hsd | 187 | @@ -XXX,XX +XXX,XX @@ FRINTI_s 00011110 .. 1 001111 10000 ..... ..... @rr_hsd |
188 | 188 | ||
189 | BFCVT_s 00011110 01 1 000110 10000 ..... ..... @rr_s | 189 | BFCVT_s 00011110 01 1 000110 10000 ..... ..... @rr_s |
190 | 190 | ||
191 | +FRINT32Z_s 00011110 0. 1 010000 10000 ..... ..... @rr_sd | 191 | +FRINT32Z_s 00011110 0. 1 010000 10000 ..... ..... @rr_sd |
192 | +FRINT32X_s 00011110 0. 1 010001 10000 ..... ..... @rr_sd | 192 | +FRINT32X_s 00011110 0. 1 010001 10000 ..... ..... @rr_sd |
193 | +FRINT64Z_s 00011110 0. 1 010010 10000 ..... ..... @rr_sd | 193 | +FRINT64Z_s 00011110 0. 1 010010 10000 ..... ..... @rr_sd |
194 | +FRINT64X_s 00011110 0. 1 010011 10000 ..... ..... @rr_sd | 194 | +FRINT64X_s 00011110 0. 1 010011 10000 ..... ..... @rr_sd |
195 | + | 195 | + |
196 | # Floating-point Immediate | 196 | # Floating-point Immediate |
197 | 197 | ||
198 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd | 198 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd |
199 | -- | 199 | -- |
200 | 2.43.0 | 200 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove handle_fp_fcvt and disas_fp_1src as these were | 1 | Remove handle_fp_fcvt and disas_fp_1src as these were |
---|---|---|---|
2 | the last insns decoded by those functions. | 2 | the last insns decoded by those functions. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 172 +++++++++++++-------------------- | 7 | target/arm/tcg/translate-a64.c | 172 +++++++++++++-------------------- |
8 | target/arm/tcg/a64.decode | 7 ++ | 8 | target/arm/tcg/a64.decode | 7 ++ |
9 | 2 files changed, 74 insertions(+), 105 deletions(-) | 9 | 2 files changed, 74 insertions(+), 105 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FRINT64Z_s, aa64_frint, do_fp1_scalar, a, | 15 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FRINT64Z_s, aa64_frint, do_fp1_scalar, a, |
16 | &f_scalar_frint64, FPROUNDING_ZERO) | 16 | &f_scalar_frint64, FPROUNDING_ZERO) |
17 | TRANS_FEAT(FRINT64X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint64, -1) | 17 | TRANS_FEAT(FRINT64X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint64, -1) |
18 | 18 | ||
19 | -static void handle_fp_fcvt(DisasContext *s, int opcode, | 19 | -static void handle_fp_fcvt(DisasContext *s, int opcode, |
20 | - int rd, int rn, int dtype, int ntype) | 20 | - int rd, int rn, int dtype, int ntype) |
21 | +static bool trans_FCVT_s_ds(DisasContext *s, arg_rr *a) | 21 | +static bool trans_FCVT_s_ds(DisasContext *s, arg_rr *a) |
22 | { | 22 | { |
23 | - switch (ntype) { | 23 | - switch (ntype) { |
24 | - case 0x0: | 24 | - case 0x0: |
25 | - { | 25 | - { |
26 | - TCGv_i32 tcg_rn = read_fp_sreg(s, rn); | 26 | - TCGv_i32 tcg_rn = read_fp_sreg(s, rn); |
27 | - if (dtype == 1) { | 27 | - if (dtype == 1) { |
28 | - /* Single to double */ | 28 | - /* Single to double */ |
29 | - TCGv_i64 tcg_rd = tcg_temp_new_i64(); | 29 | - TCGv_i64 tcg_rd = tcg_temp_new_i64(); |
30 | - gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, tcg_env); | 30 | - gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, tcg_env); |
31 | - write_fp_dreg(s, rd, tcg_rd); | 31 | - write_fp_dreg(s, rd, tcg_rd); |
32 | - } else { | 32 | - } else { |
33 | - /* Single to half */ | 33 | - /* Single to half */ |
34 | - TCGv_i32 tcg_rd = tcg_temp_new_i32(); | 34 | - TCGv_i32 tcg_rd = tcg_temp_new_i32(); |
35 | - TCGv_i32 ahp = get_ahp_flag(); | 35 | - TCGv_i32 ahp = get_ahp_flag(); |
36 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 36 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
37 | + if (fp_access_check(s)) { | 37 | + if (fp_access_check(s)) { |
38 | + TCGv_i32 tcg_rn = read_fp_sreg(s, a->rn); | 38 | + TCGv_i32 tcg_rn = read_fp_sreg(s, a->rn); |
39 | + TCGv_i64 tcg_rd = tcg_temp_new_i64(); | 39 | + TCGv_i64 tcg_rd = tcg_temp_new_i64(); |
40 | 40 | ||
41 | - gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, fpst, ahp); | 41 | - gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, fpst, ahp); |
42 | - /* write_fp_sreg is OK here because top half of tcg_rd is zero */ | 42 | - /* write_fp_sreg is OK here because top half of tcg_rd is zero */ |
43 | - write_fp_sreg(s, rd, tcg_rd); | 43 | - write_fp_sreg(s, rd, tcg_rd); |
44 | - } | 44 | - } |
45 | - break; | 45 | - break; |
46 | - } | 46 | - } |
47 | - case 0x1: | 47 | - case 0x1: |
48 | - { | 48 | - { |
49 | - TCGv_i64 tcg_rn = read_fp_dreg(s, rn); | 49 | - TCGv_i64 tcg_rn = read_fp_dreg(s, rn); |
50 | - TCGv_i32 tcg_rd = tcg_temp_new_i32(); | 50 | - TCGv_i32 tcg_rd = tcg_temp_new_i32(); |
51 | - if (dtype == 0) { | 51 | - if (dtype == 0) { |
52 | - /* Double to single */ | 52 | - /* Double to single */ |
53 | - gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, tcg_env); | 53 | - gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, tcg_env); |
54 | - } else { | 54 | - } else { |
55 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 55 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
56 | - TCGv_i32 ahp = get_ahp_flag(); | 56 | - TCGv_i32 ahp = get_ahp_flag(); |
57 | - /* Double to half */ | 57 | - /* Double to half */ |
58 | - gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp); | 58 | - gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp); |
59 | - /* write_fp_sreg is OK here because top half of tcg_rd is zero */ | 59 | - /* write_fp_sreg is OK here because top half of tcg_rd is zero */ |
60 | - } | 60 | - } |
61 | - write_fp_sreg(s, rd, tcg_rd); | 61 | - write_fp_sreg(s, rd, tcg_rd); |
62 | - break; | 62 | - break; |
63 | - } | 63 | - } |
64 | - case 0x3: | 64 | - case 0x3: |
65 | - { | 65 | - { |
66 | - TCGv_i32 tcg_rn = read_fp_sreg(s, rn); | 66 | - TCGv_i32 tcg_rn = read_fp_sreg(s, rn); |
67 | - TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); | 67 | - TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); |
68 | - TCGv_i32 tcg_ahp = get_ahp_flag(); | 68 | - TCGv_i32 tcg_ahp = get_ahp_flag(); |
69 | - tcg_gen_ext16u_i32(tcg_rn, tcg_rn); | 69 | - tcg_gen_ext16u_i32(tcg_rn, tcg_rn); |
70 | - if (dtype == 0) { | 70 | - if (dtype == 0) { |
71 | - /* Half to single */ | 71 | - /* Half to single */ |
72 | - TCGv_i32 tcg_rd = tcg_temp_new_i32(); | 72 | - TCGv_i32 tcg_rd = tcg_temp_new_i32(); |
73 | - gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); | 73 | - gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); |
74 | - write_fp_sreg(s, rd, tcg_rd); | 74 | - write_fp_sreg(s, rd, tcg_rd); |
75 | - } else { | 75 | - } else { |
76 | - /* Half to double */ | 76 | - /* Half to double */ |
77 | - TCGv_i64 tcg_rd = tcg_temp_new_i64(); | 77 | - TCGv_i64 tcg_rd = tcg_temp_new_i64(); |
78 | - gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); | 78 | - gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); |
79 | - write_fp_dreg(s, rd, tcg_rd); | 79 | - write_fp_dreg(s, rd, tcg_rd); |
80 | - } | 80 | - } |
81 | - break; | 81 | - break; |
82 | - } | 82 | - } |
83 | - default: | 83 | - default: |
84 | - g_assert_not_reached(); | 84 | - g_assert_not_reached(); |
85 | + gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, tcg_env); | 85 | + gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, tcg_env); |
86 | + write_fp_dreg(s, a->rd, tcg_rd); | 86 | + write_fp_dreg(s, a->rd, tcg_rd); |
87 | } | 87 | } |
88 | + return true; | 88 | + return true; |
89 | } | 89 | } |
90 | 90 | ||
91 | -/* Floating point data-processing (1 source) | 91 | -/* Floating point data-processing (1 source) |
92 | - * 31 30 29 28 24 23 22 21 20 15 14 10 9 5 4 0 | 92 | - * 31 30 29 28 24 23 22 21 20 15 14 10 9 5 4 0 |
93 | - * +---+---+---+-----------+------+---+--------+-----------+------+------+ | 93 | - * +---+---+---+-----------+------+---+--------+-----------+------+------+ |
94 | - * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 | Rn | Rd | | 94 | - * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 | Rn | Rd | |
95 | - * +---+---+---+-----------+------+---+--------+-----------+------+------+ | 95 | - * +---+---+---+-----------+------+---+--------+-----------+------+------+ |
96 | - */ | 96 | - */ |
97 | -static void disas_fp_1src(DisasContext *s, uint32_t insn) | 97 | -static void disas_fp_1src(DisasContext *s, uint32_t insn) |
98 | +static bool trans_FCVT_s_hs(DisasContext *s, arg_rr *a) | 98 | +static bool trans_FCVT_s_hs(DisasContext *s, arg_rr *a) |
99 | { | 99 | { |
100 | - int mos = extract32(insn, 29, 3); | 100 | - int mos = extract32(insn, 29, 3); |
101 | - int type = extract32(insn, 22, 2); | 101 | - int type = extract32(insn, 22, 2); |
102 | - int opcode = extract32(insn, 15, 6); | 102 | - int opcode = extract32(insn, 15, 6); |
103 | - int rn = extract32(insn, 5, 5); | 103 | - int rn = extract32(insn, 5, 5); |
104 | - int rd = extract32(insn, 0, 5); | 104 | - int rd = extract32(insn, 0, 5); |
105 | + if (fp_access_check(s)) { | 105 | + if (fp_access_check(s)) { |
106 | + TCGv_i32 tmp = read_fp_sreg(s, a->rn); | 106 | + TCGv_i32 tmp = read_fp_sreg(s, a->rn); |
107 | + TCGv_i32 ahp = get_ahp_flag(); | 107 | + TCGv_i32 ahp = get_ahp_flag(); |
108 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 108 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
109 | 109 | ||
110 | - if (mos) { | 110 | - if (mos) { |
111 | - goto do_unallocated; | 111 | - goto do_unallocated; |
112 | + gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp); | 112 | + gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp); |
113 | + /* write_fp_sreg is OK here because top half of result is zero */ | 113 | + /* write_fp_sreg is OK here because top half of result is zero */ |
114 | + write_fp_sreg(s, a->rd, tmp); | 114 | + write_fp_sreg(s, a->rd, tmp); |
115 | } | 115 | } |
116 | + return true; | 116 | + return true; |
117 | +} | 117 | +} |
118 | 118 | ||
119 | - switch (opcode) { | 119 | - switch (opcode) { |
120 | - case 0x4: case 0x5: case 0x7: | 120 | - case 0x4: case 0x5: case 0x7: |
121 | - { | 121 | - { |
122 | - /* FCVT between half, single and double precision */ | 122 | - /* FCVT between half, single and double precision */ |
123 | - int dtype = extract32(opcode, 0, 2); | 123 | - int dtype = extract32(opcode, 0, 2); |
124 | - if (type == 2 || dtype == type) { | 124 | - if (type == 2 || dtype == type) { |
125 | - goto do_unallocated; | 125 | - goto do_unallocated; |
126 | - } | 126 | - } |
127 | - if (!fp_access_check(s)) { | 127 | - if (!fp_access_check(s)) { |
128 | - return; | 128 | - return; |
129 | - } | 129 | - } |
130 | +static bool trans_FCVT_s_sd(DisasContext *s, arg_rr *a) | 130 | +static bool trans_FCVT_s_sd(DisasContext *s, arg_rr *a) |
131 | +{ | 131 | +{ |
132 | + if (fp_access_check(s)) { | 132 | + if (fp_access_check(s)) { |
133 | + TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); | 133 | + TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); |
134 | + TCGv_i32 tcg_rd = tcg_temp_new_i32(); | 134 | + TCGv_i32 tcg_rd = tcg_temp_new_i32(); |
135 | 135 | ||
136 | - handle_fp_fcvt(s, opcode, rd, rn, dtype, type); | 136 | - handle_fp_fcvt(s, opcode, rd, rn, dtype, type); |
137 | - break; | 137 | - break; |
138 | + gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, tcg_env); | 138 | + gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, tcg_env); |
139 | + write_fp_sreg(s, a->rd, tcg_rd); | 139 | + write_fp_sreg(s, a->rd, tcg_rd); |
140 | } | 140 | } |
141 | + return true; | 141 | + return true; |
142 | +} | 142 | +} |
143 | 143 | ||
144 | - default: | 144 | - default: |
145 | - do_unallocated: | 145 | - do_unallocated: |
146 | - case 0x0: /* FMOV */ | 146 | - case 0x0: /* FMOV */ |
147 | - case 0x1: /* FABS */ | 147 | - case 0x1: /* FABS */ |
148 | - case 0x2: /* FNEG */ | 148 | - case 0x2: /* FNEG */ |
149 | - case 0x3: /* FSQRT */ | 149 | - case 0x3: /* FSQRT */ |
150 | - case 0x6: /* BFCVT */ | 150 | - case 0x6: /* BFCVT */ |
151 | - case 0x8: /* FRINTN */ | 151 | - case 0x8: /* FRINTN */ |
152 | - case 0x9: /* FRINTP */ | 152 | - case 0x9: /* FRINTP */ |
153 | - case 0xa: /* FRINTM */ | 153 | - case 0xa: /* FRINTM */ |
154 | - case 0xb: /* FRINTZ */ | 154 | - case 0xb: /* FRINTZ */ |
155 | - case 0xc: /* FRINTA */ | 155 | - case 0xc: /* FRINTA */ |
156 | - case 0xe: /* FRINTX */ | 156 | - case 0xe: /* FRINTX */ |
157 | - case 0xf: /* FRINTI */ | 157 | - case 0xf: /* FRINTI */ |
158 | - case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */ | 158 | - case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */ |
159 | - unallocated_encoding(s); | 159 | - unallocated_encoding(s); |
160 | - break; | 160 | - break; |
161 | +static bool trans_FCVT_s_hd(DisasContext *s, arg_rr *a) | 161 | +static bool trans_FCVT_s_hd(DisasContext *s, arg_rr *a) |
162 | +{ | 162 | +{ |
163 | + if (fp_access_check(s)) { | 163 | + if (fp_access_check(s)) { |
164 | + TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); | 164 | + TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); |
165 | + TCGv_i32 tcg_rd = tcg_temp_new_i32(); | 165 | + TCGv_i32 tcg_rd = tcg_temp_new_i32(); |
166 | + TCGv_i32 ahp = get_ahp_flag(); | 166 | + TCGv_i32 ahp = get_ahp_flag(); |
167 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 167 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
168 | + | 168 | + |
169 | + gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp); | 169 | + gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp); |
170 | + /* write_fp_sreg is OK here because top half of tcg_rd is zero */ | 170 | + /* write_fp_sreg is OK here because top half of tcg_rd is zero */ |
171 | + write_fp_sreg(s, a->rd, tcg_rd); | 171 | + write_fp_sreg(s, a->rd, tcg_rd); |
172 | } | 172 | } |
173 | + return true; | 173 | + return true; |
174 | +} | 174 | +} |
175 | + | 175 | + |
176 | +static bool trans_FCVT_s_sh(DisasContext *s, arg_rr *a) | 176 | +static bool trans_FCVT_s_sh(DisasContext *s, arg_rr *a) |
177 | +{ | 177 | +{ |
178 | + if (fp_access_check(s)) { | 178 | + if (fp_access_check(s)) { |
179 | + TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); | 179 | + TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); |
180 | + TCGv_i32 tcg_rd = tcg_temp_new_i32(); | 180 | + TCGv_i32 tcg_rd = tcg_temp_new_i32(); |
181 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); | 181 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); |
182 | + TCGv_i32 tcg_ahp = get_ahp_flag(); | 182 | + TCGv_i32 tcg_ahp = get_ahp_flag(); |
183 | + | 183 | + |
184 | + gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); | 184 | + gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); |
185 | + write_fp_sreg(s, a->rd, tcg_rd); | 185 | + write_fp_sreg(s, a->rd, tcg_rd); |
186 | + } | 186 | + } |
187 | + return true; | 187 | + return true; |
188 | +} | 188 | +} |
189 | + | 189 | + |
190 | +static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a) | 190 | +static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a) |
191 | +{ | 191 | +{ |
192 | + if (fp_access_check(s)) { | 192 | + if (fp_access_check(s)) { |
193 | + TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); | 193 | + TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); |
194 | + TCGv_i64 tcg_rd = tcg_temp_new_i64(); | 194 | + TCGv_i64 tcg_rd = tcg_temp_new_i64(); |
195 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); | 195 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); |
196 | + TCGv_i32 tcg_ahp = get_ahp_flag(); | 196 | + TCGv_i32 tcg_ahp = get_ahp_flag(); |
197 | + | 197 | + |
198 | + gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); | 198 | + gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); |
199 | + write_fp_dreg(s, a->rd, tcg_rd); | 199 | + write_fp_dreg(s, a->rd, tcg_rd); |
200 | + } | 200 | + } |
201 | + return true; | 201 | + return true; |
202 | } | 202 | } |
203 | 203 | ||
204 | /* Handle floating point <=> fixed point conversions. Note that we can | 204 | /* Handle floating point <=> fixed point conversions. Note that we can |
205 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) | 205 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) |
206 | break; | 206 | break; |
207 | case 2: /* [15:12] == x100 */ | 207 | case 2: /* [15:12] == x100 */ |
208 | /* Floating point data-processing (1 source) */ | 208 | /* Floating point data-processing (1 source) */ |
209 | - disas_fp_1src(s, insn); | 209 | - disas_fp_1src(s, insn); |
210 | + unallocated_encoding(s); /* in decodetree */ | 210 | + unallocated_encoding(s); /* in decodetree */ |
211 | break; | 211 | break; |
212 | case 3: /* [15:12] == 1000 */ | 212 | case 3: /* [15:12] == 1000 */ |
213 | unallocated_encoding(s); | 213 | unallocated_encoding(s); |
214 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 214 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
215 | index XXXXXXX..XXXXXXX 100644 | 215 | index XXXXXXX..XXXXXXX 100644 |
216 | --- a/target/arm/tcg/a64.decode | 216 | --- a/target/arm/tcg/a64.decode |
217 | +++ b/target/arm/tcg/a64.decode | 217 | +++ b/target/arm/tcg/a64.decode |
218 | @@ -XXX,XX +XXX,XX @@ FRINT32X_s 00011110 0. 1 010001 10000 ..... ..... @rr_sd | 218 | @@ -XXX,XX +XXX,XX @@ FRINT32X_s 00011110 0. 1 010001 10000 ..... ..... @rr_sd |
219 | FRINT64Z_s 00011110 0. 1 010010 10000 ..... ..... @rr_sd | 219 | FRINT64Z_s 00011110 0. 1 010010 10000 ..... ..... @rr_sd |
220 | FRINT64X_s 00011110 0. 1 010011 10000 ..... ..... @rr_sd | 220 | FRINT64X_s 00011110 0. 1 010011 10000 ..... ..... @rr_sd |
221 | 221 | ||
222 | +FCVT_s_ds 00011110 00 1 000101 10000 ..... ..... @rr | 222 | +FCVT_s_ds 00011110 00 1 000101 10000 ..... ..... @rr |
223 | +FCVT_s_hs 00011110 00 1 000111 10000 ..... ..... @rr | 223 | +FCVT_s_hs 00011110 00 1 000111 10000 ..... ..... @rr |
224 | +FCVT_s_sd 00011110 01 1 000100 10000 ..... ..... @rr | 224 | +FCVT_s_sd 00011110 01 1 000100 10000 ..... ..... @rr |
225 | +FCVT_s_hd 00011110 01 1 000111 10000 ..... ..... @rr | 225 | +FCVT_s_hd 00011110 01 1 000111 10000 ..... ..... @rr |
226 | +FCVT_s_sh 00011110 11 1 000100 10000 ..... ..... @rr | 226 | +FCVT_s_sh 00011110 11 1 000100 10000 ..... ..... @rr |
227 | +FCVT_s_dh 00011110 11 1 000101 10000 ..... ..... @rr | 227 | +FCVT_s_dh 00011110 11 1 000101 10000 ..... ..... @rr |
228 | + | 228 | + |
229 | # Floating-point Immediate | 229 | # Floating-point Immediate |
230 | 230 | ||
231 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd | 231 | FMOVI_s 0001 1110 .. 1 imm:8 100 00000 rd:5 esz=%esz_hsd |
232 | -- | 232 | -- |
233 | 2.43.0 | 233 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes SCVTF, UCVTF, FCVT{N,P,M,Z,A}{S,U}. | 1 | This includes SCVTF, UCVTF, FCVT{N,P,M,Z,A}{S,U}. |
---|---|---|---|
2 | Remove disas_fp_fixed_conv as those were the last insns | 2 | Remove disas_fp_fixed_conv as those were the last insns |
3 | decoded by that function. | 3 | decoded by that function. |
4 | 4 | ||
5 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 5 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
7 | --- | 7 | --- |
8 | target/arm/tcg/translate-a64.c | 391 ++++++++++++++------------------- | 8 | target/arm/tcg/translate-a64.c | 391 ++++++++++++++------------------- |
9 | target/arm/tcg/a64.decode | 40 ++++ | 9 | target/arm/tcg/a64.decode | 40 ++++ |
10 | 2 files changed, 209 insertions(+), 222 deletions(-) | 10 | 2 files changed, 209 insertions(+), 222 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 12 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/tcg/translate-a64.c | 14 | --- a/target/arm/tcg/translate-a64.c |
15 | +++ b/target/arm/tcg/translate-a64.c | 15 | +++ b/target/arm/tcg/translate-a64.c |
16 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a) | 16 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a) |
17 | return true; | 17 | return true; |
18 | } | 18 | } |
19 | 19 | ||
20 | -/* Handle floating point <=> fixed point conversions. Note that we can | 20 | -/* Handle floating point <=> fixed point conversions. Note that we can |
21 | - * also deal with fp <=> integer conversions as a special case (scale == 64) | 21 | - * also deal with fp <=> integer conversions as a special case (scale == 64) |
22 | - * OPTME: consider handling that special case specially or at least skipping | 22 | - * OPTME: consider handling that special case specially or at least skipping |
23 | - * the call to scalbn in the helpers for zero shifts. | 23 | - * the call to scalbn in the helpers for zero shifts. |
24 | - */ | 24 | - */ |
25 | -static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, | 25 | -static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode, |
26 | - bool itof, int rmode, int scale, int sf, int type) | 26 | - bool itof, int rmode, int scale, int sf, int type) |
27 | +static bool do_cvtf_scalar(DisasContext *s, MemOp esz, int rd, int shift, | 27 | +static bool do_cvtf_scalar(DisasContext *s, MemOp esz, int rd, int shift, |
28 | + TCGv_i64 tcg_int, bool is_signed) | 28 | + TCGv_i64 tcg_int, bool is_signed) |
29 | { | 29 | { |
30 | - bool is_signed = !(opcode & 1); | 30 | - bool is_signed = !(opcode & 1); |
31 | TCGv_ptr tcg_fpstatus; | 31 | TCGv_ptr tcg_fpstatus; |
32 | TCGv_i32 tcg_shift, tcg_single; | 32 | TCGv_i32 tcg_shift, tcg_single; |
33 | TCGv_i64 tcg_double; | 33 | TCGv_i64 tcg_double; |
34 | 34 | ||
35 | - tcg_fpstatus = fpstatus_ptr(type == 3 ? FPST_FPCR_F16 : FPST_FPCR); | 35 | - tcg_fpstatus = fpstatus_ptr(type == 3 ? FPST_FPCR_F16 : FPST_FPCR); |
36 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | 36 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); |
37 | + tcg_shift = tcg_constant_i32(shift); | 37 | + tcg_shift = tcg_constant_i32(shift); |
38 | 38 | ||
39 | - tcg_shift = tcg_constant_i32(64 - scale); | 39 | - tcg_shift = tcg_constant_i32(64 - scale); |
40 | - | 40 | - |
41 | - if (itof) { | 41 | - if (itof) { |
42 | - TCGv_i64 tcg_int = cpu_reg(s, rn); | 42 | - TCGv_i64 tcg_int = cpu_reg(s, rn); |
43 | - if (!sf) { | 43 | - if (!sf) { |
44 | - TCGv_i64 tcg_extend = tcg_temp_new_i64(); | 44 | - TCGv_i64 tcg_extend = tcg_temp_new_i64(); |
45 | - | 45 | - |
46 | - if (is_signed) { | 46 | - if (is_signed) { |
47 | - tcg_gen_ext32s_i64(tcg_extend, tcg_int); | 47 | - tcg_gen_ext32s_i64(tcg_extend, tcg_int); |
48 | - } else { | 48 | - } else { |
49 | - tcg_gen_ext32u_i64(tcg_extend, tcg_int); | 49 | - tcg_gen_ext32u_i64(tcg_extend, tcg_int); |
50 | - } | 50 | - } |
51 | - | 51 | - |
52 | - tcg_int = tcg_extend; | 52 | - tcg_int = tcg_extend; |
53 | + switch (esz) { | 53 | + switch (esz) { |
54 | + case MO_64: | 54 | + case MO_64: |
55 | + tcg_double = tcg_temp_new_i64(); | 55 | + tcg_double = tcg_temp_new_i64(); |
56 | + if (is_signed) { | 56 | + if (is_signed) { |
57 | + gen_helper_vfp_sqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus); | 57 | + gen_helper_vfp_sqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus); |
58 | + } else { | 58 | + } else { |
59 | + gen_helper_vfp_uqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus); | 59 | + gen_helper_vfp_uqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus); |
60 | } | 60 | } |
61 | + write_fp_dreg(s, rd, tcg_double); | 61 | + write_fp_dreg(s, rd, tcg_double); |
62 | + break; | 62 | + break; |
63 | 63 | ||
64 | - switch (type) { | 64 | - switch (type) { |
65 | - case 1: /* float64 */ | 65 | - case 1: /* float64 */ |
66 | - tcg_double = tcg_temp_new_i64(); | 66 | - tcg_double = tcg_temp_new_i64(); |
67 | - if (is_signed) { | 67 | - if (is_signed) { |
68 | - gen_helper_vfp_sqtod(tcg_double, tcg_int, | 68 | - gen_helper_vfp_sqtod(tcg_double, tcg_int, |
69 | - tcg_shift, tcg_fpstatus); | 69 | - tcg_shift, tcg_fpstatus); |
70 | - } else { | 70 | - } else { |
71 | - gen_helper_vfp_uqtod(tcg_double, tcg_int, | 71 | - gen_helper_vfp_uqtod(tcg_double, tcg_int, |
72 | - tcg_shift, tcg_fpstatus); | 72 | - tcg_shift, tcg_fpstatus); |
73 | - } | 73 | - } |
74 | - write_fp_dreg(s, rd, tcg_double); | 74 | - write_fp_dreg(s, rd, tcg_double); |
75 | - break; | 75 | - break; |
76 | - | 76 | - |
77 | - case 0: /* float32 */ | 77 | - case 0: /* float32 */ |
78 | - tcg_single = tcg_temp_new_i32(); | 78 | - tcg_single = tcg_temp_new_i32(); |
79 | - if (is_signed) { | 79 | - if (is_signed) { |
80 | - gen_helper_vfp_sqtos(tcg_single, tcg_int, | 80 | - gen_helper_vfp_sqtos(tcg_single, tcg_int, |
81 | - tcg_shift, tcg_fpstatus); | 81 | - tcg_shift, tcg_fpstatus); |
82 | - } else { | 82 | - } else { |
83 | - gen_helper_vfp_uqtos(tcg_single, tcg_int, | 83 | - gen_helper_vfp_uqtos(tcg_single, tcg_int, |
84 | - tcg_shift, tcg_fpstatus); | 84 | - tcg_shift, tcg_fpstatus); |
85 | - } | 85 | - } |
86 | - write_fp_sreg(s, rd, tcg_single); | 86 | - write_fp_sreg(s, rd, tcg_single); |
87 | - break; | 87 | - break; |
88 | - | 88 | - |
89 | - case 3: /* float16 */ | 89 | - case 3: /* float16 */ |
90 | - tcg_single = tcg_temp_new_i32(); | 90 | - tcg_single = tcg_temp_new_i32(); |
91 | - if (is_signed) { | 91 | - if (is_signed) { |
92 | - gen_helper_vfp_sqtoh(tcg_single, tcg_int, | 92 | - gen_helper_vfp_sqtoh(tcg_single, tcg_int, |
93 | - tcg_shift, tcg_fpstatus); | 93 | - tcg_shift, tcg_fpstatus); |
94 | - } else { | 94 | - } else { |
95 | - gen_helper_vfp_uqtoh(tcg_single, tcg_int, | 95 | - gen_helper_vfp_uqtoh(tcg_single, tcg_int, |
96 | - tcg_shift, tcg_fpstatus); | 96 | - tcg_shift, tcg_fpstatus); |
97 | - } | 97 | - } |
98 | - write_fp_sreg(s, rd, tcg_single); | 98 | - write_fp_sreg(s, rd, tcg_single); |
99 | - break; | 99 | - break; |
100 | - | 100 | - |
101 | - default: | 101 | - default: |
102 | - g_assert_not_reached(); | 102 | - g_assert_not_reached(); |
103 | + case MO_32: | 103 | + case MO_32: |
104 | + tcg_single = tcg_temp_new_i32(); | 104 | + tcg_single = tcg_temp_new_i32(); |
105 | + if (is_signed) { | 105 | + if (is_signed) { |
106 | + gen_helper_vfp_sqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); | 106 | + gen_helper_vfp_sqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); |
107 | + } else { | 107 | + } else { |
108 | + gen_helper_vfp_uqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); | 108 | + gen_helper_vfp_uqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); |
109 | } | 109 | } |
110 | - } else { | 110 | - } else { |
111 | - TCGv_i64 tcg_int = cpu_reg(s, rd); | 111 | - TCGv_i64 tcg_int = cpu_reg(s, rd); |
112 | - TCGv_i32 tcg_rmode; | 112 | - TCGv_i32 tcg_rmode; |
113 | + write_fp_sreg(s, rd, tcg_single); | 113 | + write_fp_sreg(s, rd, tcg_single); |
114 | + break; | 114 | + break; |
115 | 115 | ||
116 | - if (extract32(opcode, 2, 1)) { | 116 | - if (extract32(opcode, 2, 1)) { |
117 | - /* There are too many rounding modes to all fit into rmode, | 117 | - /* There are too many rounding modes to all fit into rmode, |
118 | - * so FCVTA[US] is a special case. | 118 | - * so FCVTA[US] is a special case. |
119 | - */ | 119 | - */ |
120 | - rmode = FPROUNDING_TIEAWAY; | 120 | - rmode = FPROUNDING_TIEAWAY; |
121 | + case MO_16: | 121 | + case MO_16: |
122 | + tcg_single = tcg_temp_new_i32(); | 122 | + tcg_single = tcg_temp_new_i32(); |
123 | + if (is_signed) { | 123 | + if (is_signed) { |
124 | + gen_helper_vfp_sqtoh(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); | 124 | + gen_helper_vfp_sqtoh(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); |
125 | + } else { | 125 | + } else { |
126 | + gen_helper_vfp_uqtoh(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); | 126 | + gen_helper_vfp_uqtoh(tcg_single, tcg_int, tcg_shift, tcg_fpstatus); |
127 | } | 127 | } |
128 | + write_fp_sreg(s, rd, tcg_single); | 128 | + write_fp_sreg(s, rd, tcg_single); |
129 | + break; | 129 | + break; |
130 | 130 | ||
131 | - tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); | 131 | - tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); |
132 | - | 132 | - |
133 | - switch (type) { | 133 | - switch (type) { |
134 | - case 1: /* float64 */ | 134 | - case 1: /* float64 */ |
135 | - tcg_double = read_fp_dreg(s, rn); | 135 | - tcg_double = read_fp_dreg(s, rn); |
136 | - if (is_signed) { | 136 | - if (is_signed) { |
137 | - if (!sf) { | 137 | - if (!sf) { |
138 | - gen_helper_vfp_tosld(tcg_int, tcg_double, | 138 | - gen_helper_vfp_tosld(tcg_int, tcg_double, |
139 | - tcg_shift, tcg_fpstatus); | 139 | - tcg_shift, tcg_fpstatus); |
140 | - } else { | 140 | - } else { |
141 | - gen_helper_vfp_tosqd(tcg_int, tcg_double, | 141 | - gen_helper_vfp_tosqd(tcg_int, tcg_double, |
142 | - tcg_shift, tcg_fpstatus); | 142 | - tcg_shift, tcg_fpstatus); |
143 | - } | 143 | - } |
144 | - } else { | 144 | - } else { |
145 | - if (!sf) { | 145 | - if (!sf) { |
146 | - gen_helper_vfp_tould(tcg_int, tcg_double, | 146 | - gen_helper_vfp_tould(tcg_int, tcg_double, |
147 | - tcg_shift, tcg_fpstatus); | 147 | - tcg_shift, tcg_fpstatus); |
148 | - } else { | 148 | - } else { |
149 | - gen_helper_vfp_touqd(tcg_int, tcg_double, | 149 | - gen_helper_vfp_touqd(tcg_int, tcg_double, |
150 | - tcg_shift, tcg_fpstatus); | 150 | - tcg_shift, tcg_fpstatus); |
151 | - } | 151 | - } |
152 | - } | 152 | - } |
153 | - if (!sf) { | 153 | - if (!sf) { |
154 | - tcg_gen_ext32u_i64(tcg_int, tcg_int); | 154 | - tcg_gen_ext32u_i64(tcg_int, tcg_int); |
155 | - } | 155 | - } |
156 | - break; | 156 | - break; |
157 | - | 157 | - |
158 | - case 0: /* float32 */ | 158 | - case 0: /* float32 */ |
159 | - tcg_single = read_fp_sreg(s, rn); | 159 | - tcg_single = read_fp_sreg(s, rn); |
160 | - if (sf) { | 160 | - if (sf) { |
161 | - if (is_signed) { | 161 | - if (is_signed) { |
162 | - gen_helper_vfp_tosqs(tcg_int, tcg_single, | 162 | - gen_helper_vfp_tosqs(tcg_int, tcg_single, |
163 | - tcg_shift, tcg_fpstatus); | 163 | - tcg_shift, tcg_fpstatus); |
164 | - } else { | 164 | - } else { |
165 | - gen_helper_vfp_touqs(tcg_int, tcg_single, | 165 | - gen_helper_vfp_touqs(tcg_int, tcg_single, |
166 | - tcg_shift, tcg_fpstatus); | 166 | - tcg_shift, tcg_fpstatus); |
167 | - } | 167 | - } |
168 | - } else { | 168 | - } else { |
169 | - TCGv_i32 tcg_dest = tcg_temp_new_i32(); | 169 | - TCGv_i32 tcg_dest = tcg_temp_new_i32(); |
170 | - if (is_signed) { | 170 | - if (is_signed) { |
171 | - gen_helper_vfp_tosls(tcg_dest, tcg_single, | 171 | - gen_helper_vfp_tosls(tcg_dest, tcg_single, |
172 | - tcg_shift, tcg_fpstatus); | 172 | - tcg_shift, tcg_fpstatus); |
173 | - } else { | 173 | - } else { |
174 | - gen_helper_vfp_touls(tcg_dest, tcg_single, | 174 | - gen_helper_vfp_touls(tcg_dest, tcg_single, |
175 | - tcg_shift, tcg_fpstatus); | 175 | - tcg_shift, tcg_fpstatus); |
176 | - } | 176 | - } |
177 | - tcg_gen_extu_i32_i64(tcg_int, tcg_dest); | 177 | - tcg_gen_extu_i32_i64(tcg_int, tcg_dest); |
178 | - } | 178 | - } |
179 | - break; | 179 | - break; |
180 | - | 180 | - |
181 | - case 3: /* float16 */ | 181 | - case 3: /* float16 */ |
182 | - tcg_single = read_fp_sreg(s, rn); | 182 | - tcg_single = read_fp_sreg(s, rn); |
183 | - if (sf) { | 183 | - if (sf) { |
184 | - if (is_signed) { | 184 | - if (is_signed) { |
185 | - gen_helper_vfp_tosqh(tcg_int, tcg_single, | 185 | - gen_helper_vfp_tosqh(tcg_int, tcg_single, |
186 | - tcg_shift, tcg_fpstatus); | 186 | - tcg_shift, tcg_fpstatus); |
187 | - } else { | 187 | - } else { |
188 | - gen_helper_vfp_touqh(tcg_int, tcg_single, | 188 | - gen_helper_vfp_touqh(tcg_int, tcg_single, |
189 | - tcg_shift, tcg_fpstatus); | 189 | - tcg_shift, tcg_fpstatus); |
190 | - } | 190 | - } |
191 | - } else { | 191 | - } else { |
192 | - TCGv_i32 tcg_dest = tcg_temp_new_i32(); | 192 | - TCGv_i32 tcg_dest = tcg_temp_new_i32(); |
193 | - if (is_signed) { | 193 | - if (is_signed) { |
194 | - gen_helper_vfp_toslh(tcg_dest, tcg_single, | 194 | - gen_helper_vfp_toslh(tcg_dest, tcg_single, |
195 | - tcg_shift, tcg_fpstatus); | 195 | - tcg_shift, tcg_fpstatus); |
196 | - } else { | 196 | - } else { |
197 | - gen_helper_vfp_toulh(tcg_dest, tcg_single, | 197 | - gen_helper_vfp_toulh(tcg_dest, tcg_single, |
198 | - tcg_shift, tcg_fpstatus); | 198 | - tcg_shift, tcg_fpstatus); |
199 | - } | 199 | - } |
200 | - tcg_gen_extu_i32_i64(tcg_int, tcg_dest); | 200 | - tcg_gen_extu_i32_i64(tcg_int, tcg_dest); |
201 | - } | 201 | - } |
202 | - break; | 202 | - break; |
203 | - | 203 | - |
204 | - default: | 204 | - default: |
205 | - g_assert_not_reached(); | 205 | - g_assert_not_reached(); |
206 | - } | 206 | - } |
207 | - | 207 | - |
208 | - gen_restore_rmode(tcg_rmode, tcg_fpstatus); | 208 | - gen_restore_rmode(tcg_rmode, tcg_fpstatus); |
209 | + default: | 209 | + default: |
210 | + g_assert_not_reached(); | 210 | + g_assert_not_reached(); |
211 | } | 211 | } |
212 | + return true; | 212 | + return true; |
213 | } | 213 | } |
214 | 214 | ||
215 | -/* Floating point <-> fixed point conversions | 215 | -/* Floating point <-> fixed point conversions |
216 | - * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 | 216 | - * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 |
217 | - * +----+---+---+-----------+------+---+-------+--------+-------+------+------+ | 217 | - * +----+---+---+-----------+------+---+-------+--------+-------+------+------+ |
218 | - * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale | Rn | Rd | | 218 | - * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale | Rn | Rd | |
219 | - * +----+---+---+-----------+------+---+-------+--------+-------+------+------+ | 219 | - * +----+---+---+-----------+------+---+-------+--------+-------+------+------+ |
220 | - */ | 220 | - */ |
221 | -static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn) | 221 | -static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn) |
222 | +static bool do_cvtf_g(DisasContext *s, arg_fcvt *a, bool is_signed) | 222 | +static bool do_cvtf_g(DisasContext *s, arg_fcvt *a, bool is_signed) |
223 | { | 223 | { |
224 | - int rd = extract32(insn, 0, 5); | 224 | - int rd = extract32(insn, 0, 5); |
225 | - int rn = extract32(insn, 5, 5); | 225 | - int rn = extract32(insn, 5, 5); |
226 | - int scale = extract32(insn, 10, 6); | 226 | - int scale = extract32(insn, 10, 6); |
227 | - int opcode = extract32(insn, 16, 3); | 227 | - int opcode = extract32(insn, 16, 3); |
228 | - int rmode = extract32(insn, 19, 2); | 228 | - int rmode = extract32(insn, 19, 2); |
229 | - int type = extract32(insn, 22, 2); | 229 | - int type = extract32(insn, 22, 2); |
230 | - bool sbit = extract32(insn, 29, 1); | 230 | - bool sbit = extract32(insn, 29, 1); |
231 | - bool sf = extract32(insn, 31, 1); | 231 | - bool sf = extract32(insn, 31, 1); |
232 | - bool itof; | 232 | - bool itof; |
233 | + TCGv_i64 tcg_int; | 233 | + TCGv_i64 tcg_int; |
234 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 234 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
235 | 235 | ||
236 | - if (sbit || (!sf && scale < 32)) { | 236 | - if (sbit || (!sf && scale < 32)) { |
237 | - unallocated_encoding(s); | 237 | - unallocated_encoding(s); |
238 | - return; | 238 | - return; |
239 | + if (check <= 0) { | 239 | + if (check <= 0) { |
240 | + return check == 0; | 240 | + return check == 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | - switch (type) { | 243 | - switch (type) { |
244 | - case 0: /* float32 */ | 244 | - case 0: /* float32 */ |
245 | - case 1: /* float64 */ | 245 | - case 1: /* float64 */ |
246 | - break; | 246 | - break; |
247 | - case 3: /* float16 */ | 247 | - case 3: /* float16 */ |
248 | - if (dc_isar_feature(aa64_fp16, s)) { | 248 | - if (dc_isar_feature(aa64_fp16, s)) { |
249 | - break; | 249 | - break; |
250 | + if (a->sf) { | 250 | + if (a->sf) { |
251 | + tcg_int = cpu_reg(s, a->rn); | 251 | + tcg_int = cpu_reg(s, a->rn); |
252 | + } else { | 252 | + } else { |
253 | + tcg_int = read_cpu_reg(s, a->rn, true); | 253 | + tcg_int = read_cpu_reg(s, a->rn, true); |
254 | + if (is_signed) { | 254 | + if (is_signed) { |
255 | + tcg_gen_ext32s_i64(tcg_int, tcg_int); | 255 | + tcg_gen_ext32s_i64(tcg_int, tcg_int); |
256 | + } else { | 256 | + } else { |
257 | + tcg_gen_ext32u_i64(tcg_int, tcg_int); | 257 | + tcg_gen_ext32u_i64(tcg_int, tcg_int); |
258 | } | 258 | } |
259 | - /* fallthru */ | 259 | - /* fallthru */ |
260 | - default: | 260 | - default: |
261 | - unallocated_encoding(s); | 261 | - unallocated_encoding(s); |
262 | - return; | 262 | - return; |
263 | } | 263 | } |
264 | - | 264 | - |
265 | - switch ((rmode << 3) | opcode) { | 265 | - switch ((rmode << 3) | opcode) { |
266 | - case 0x2: /* SCVTF */ | 266 | - case 0x2: /* SCVTF */ |
267 | - case 0x3: /* UCVTF */ | 267 | - case 0x3: /* UCVTF */ |
268 | - itof = true; | 268 | - itof = true; |
269 | - break; | 269 | - break; |
270 | - case 0x18: /* FCVTZS */ | 270 | - case 0x18: /* FCVTZS */ |
271 | - case 0x19: /* FCVTZU */ | 271 | - case 0x19: /* FCVTZU */ |
272 | - itof = false; | 272 | - itof = false; |
273 | - break; | 273 | - break; |
274 | - default: | 274 | - default: |
275 | - unallocated_encoding(s); | 275 | - unallocated_encoding(s); |
276 | - return; | 276 | - return; |
277 | - } | 277 | - } |
278 | - | 278 | - |
279 | - if (!fp_access_check(s)) { | 279 | - if (!fp_access_check(s)) { |
280 | - return; | 280 | - return; |
281 | - } | 281 | - } |
282 | - | 282 | - |
283 | - handle_fpfpcvt(s, rd, rn, opcode, itof, FPROUNDING_ZERO, scale, sf, type); | 283 | - handle_fpfpcvt(s, rd, rn, opcode, itof, FPROUNDING_ZERO, scale, sf, type); |
284 | + return do_cvtf_scalar(s, a->esz, a->rd, a->shift, tcg_int, is_signed); | 284 | + return do_cvtf_scalar(s, a->esz, a->rd, a->shift, tcg_int, is_signed); |
285 | } | 285 | } |
286 | 286 | ||
287 | +TRANS(SCVTF_g, do_cvtf_g, a, true) | 287 | +TRANS(SCVTF_g, do_cvtf_g, a, true) |
288 | +TRANS(UCVTF_g, do_cvtf_g, a, false) | 288 | +TRANS(UCVTF_g, do_cvtf_g, a, false) |
289 | + | 289 | + |
290 | +static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz, | 290 | +static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz, |
291 | + TCGv_i64 tcg_out, int shift, int rn, | 291 | + TCGv_i64 tcg_out, int shift, int rn, |
292 | + ARMFPRounding rmode) | 292 | + ARMFPRounding rmode) |
293 | +{ | 293 | +{ |
294 | + TCGv_ptr tcg_fpstatus; | 294 | + TCGv_ptr tcg_fpstatus; |
295 | + TCGv_i32 tcg_shift, tcg_rmode, tcg_single; | 295 | + TCGv_i32 tcg_shift, tcg_rmode, tcg_single; |
296 | + | 296 | + |
297 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | 297 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); |
298 | + tcg_shift = tcg_constant_i32(shift); | 298 | + tcg_shift = tcg_constant_i32(shift); |
299 | + tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); | 299 | + tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); |
300 | + | 300 | + |
301 | + switch (esz) { | 301 | + switch (esz) { |
302 | + case MO_64: | 302 | + case MO_64: |
303 | + read_vec_element(s, tcg_out, rn, 0, MO_64); | 303 | + read_vec_element(s, tcg_out, rn, 0, MO_64); |
304 | + switch (out) { | 304 | + switch (out) { |
305 | + case MO_64 | MO_SIGN: | 305 | + case MO_64 | MO_SIGN: |
306 | + gen_helper_vfp_tosqd(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); | 306 | + gen_helper_vfp_tosqd(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); |
307 | + break; | 307 | + break; |
308 | + case MO_64: | 308 | + case MO_64: |
309 | + gen_helper_vfp_touqd(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); | 309 | + gen_helper_vfp_touqd(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); |
310 | + break; | 310 | + break; |
311 | + case MO_32 | MO_SIGN: | 311 | + case MO_32 | MO_SIGN: |
312 | + gen_helper_vfp_tosld(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); | 312 | + gen_helper_vfp_tosld(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); |
313 | + break; | 313 | + break; |
314 | + case MO_32: | 314 | + case MO_32: |
315 | + gen_helper_vfp_tould(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); | 315 | + gen_helper_vfp_tould(tcg_out, tcg_out, tcg_shift, tcg_fpstatus); |
316 | + break; | 316 | + break; |
317 | + default: | 317 | + default: |
318 | + g_assert_not_reached(); | 318 | + g_assert_not_reached(); |
319 | + } | 319 | + } |
320 | + break; | 320 | + break; |
321 | + | 321 | + |
322 | + case MO_32: | 322 | + case MO_32: |
323 | + tcg_single = read_fp_sreg(s, rn); | 323 | + tcg_single = read_fp_sreg(s, rn); |
324 | + switch (out) { | 324 | + switch (out) { |
325 | + case MO_64 | MO_SIGN: | 325 | + case MO_64 | MO_SIGN: |
326 | + gen_helper_vfp_tosqs(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); | 326 | + gen_helper_vfp_tosqs(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); |
327 | + break; | 327 | + break; |
328 | + case MO_64: | 328 | + case MO_64: |
329 | + gen_helper_vfp_touqs(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); | 329 | + gen_helper_vfp_touqs(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); |
330 | + break; | 330 | + break; |
331 | + case MO_32 | MO_SIGN: | 331 | + case MO_32 | MO_SIGN: |
332 | + gen_helper_vfp_tosls(tcg_single, tcg_single, | 332 | + gen_helper_vfp_tosls(tcg_single, tcg_single, |
333 | + tcg_shift, tcg_fpstatus); | 333 | + tcg_shift, tcg_fpstatus); |
334 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); | 334 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); |
335 | + break; | 335 | + break; |
336 | + case MO_32: | 336 | + case MO_32: |
337 | + gen_helper_vfp_touls(tcg_single, tcg_single, | 337 | + gen_helper_vfp_touls(tcg_single, tcg_single, |
338 | + tcg_shift, tcg_fpstatus); | 338 | + tcg_shift, tcg_fpstatus); |
339 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); | 339 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); |
340 | + break; | 340 | + break; |
341 | + default: | 341 | + default: |
342 | + g_assert_not_reached(); | 342 | + g_assert_not_reached(); |
343 | + } | 343 | + } |
344 | + break; | 344 | + break; |
345 | + | 345 | + |
346 | + case MO_16: | 346 | + case MO_16: |
347 | + tcg_single = read_fp_hreg(s, rn); | 347 | + tcg_single = read_fp_hreg(s, rn); |
348 | + switch (out) { | 348 | + switch (out) { |
349 | + case MO_64 | MO_SIGN: | 349 | + case MO_64 | MO_SIGN: |
350 | + gen_helper_vfp_tosqh(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); | 350 | + gen_helper_vfp_tosqh(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); |
351 | + break; | 351 | + break; |
352 | + case MO_64: | 352 | + case MO_64: |
353 | + gen_helper_vfp_touqh(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); | 353 | + gen_helper_vfp_touqh(tcg_out, tcg_single, tcg_shift, tcg_fpstatus); |
354 | + break; | 354 | + break; |
355 | + case MO_32 | MO_SIGN: | 355 | + case MO_32 | MO_SIGN: |
356 | + gen_helper_vfp_toslh(tcg_single, tcg_single, | 356 | + gen_helper_vfp_toslh(tcg_single, tcg_single, |
357 | + tcg_shift, tcg_fpstatus); | 357 | + tcg_shift, tcg_fpstatus); |
358 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); | 358 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); |
359 | + break; | 359 | + break; |
360 | + case MO_32: | 360 | + case MO_32: |
361 | + gen_helper_vfp_toulh(tcg_single, tcg_single, | 361 | + gen_helper_vfp_toulh(tcg_single, tcg_single, |
362 | + tcg_shift, tcg_fpstatus); | 362 | + tcg_shift, tcg_fpstatus); |
363 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); | 363 | + tcg_gen_extu_i32_i64(tcg_out, tcg_single); |
364 | + break; | 364 | + break; |
365 | + default: | 365 | + default: |
366 | + g_assert_not_reached(); | 366 | + g_assert_not_reached(); |
367 | + } | 367 | + } |
368 | + break; | 368 | + break; |
369 | + | 369 | + |
370 | + default: | 370 | + default: |
371 | + g_assert_not_reached(); | 371 | + g_assert_not_reached(); |
372 | + } | 372 | + } |
373 | + | 373 | + |
374 | + gen_restore_rmode(tcg_rmode, tcg_fpstatus); | 374 | + gen_restore_rmode(tcg_rmode, tcg_fpstatus); |
375 | +} | 375 | +} |
376 | + | 376 | + |
377 | +static bool do_fcvt_g(DisasContext *s, arg_fcvt *a, | 377 | +static bool do_fcvt_g(DisasContext *s, arg_fcvt *a, |
378 | + ARMFPRounding rmode, bool is_signed) | 378 | + ARMFPRounding rmode, bool is_signed) |
379 | +{ | 379 | +{ |
380 | + TCGv_i64 tcg_int; | 380 | + TCGv_i64 tcg_int; |
381 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 381 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
382 | + | 382 | + |
383 | + if (check <= 0) { | 383 | + if (check <= 0) { |
384 | + return check == 0; | 384 | + return check == 0; |
385 | + } | 385 | + } |
386 | + | 386 | + |
387 | + tcg_int = cpu_reg(s, a->rd); | 387 | + tcg_int = cpu_reg(s, a->rd); |
388 | + do_fcvt_scalar(s, (a->sf ? MO_64 : MO_32) | (is_signed ? MO_SIGN : 0), | 388 | + do_fcvt_scalar(s, (a->sf ? MO_64 : MO_32) | (is_signed ? MO_SIGN : 0), |
389 | + a->esz, tcg_int, a->shift, a->rn, rmode); | 389 | + a->esz, tcg_int, a->shift, a->rn, rmode); |
390 | + | 390 | + |
391 | + if (!a->sf) { | 391 | + if (!a->sf) { |
392 | + tcg_gen_ext32u_i64(tcg_int, tcg_int); | 392 | + tcg_gen_ext32u_i64(tcg_int, tcg_int); |
393 | + } | 393 | + } |
394 | + return true; | 394 | + return true; |
395 | +} | 395 | +} |
396 | + | 396 | + |
397 | +TRANS(FCVTNS_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, true) | 397 | +TRANS(FCVTNS_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, true) |
398 | +TRANS(FCVTNU_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, false) | 398 | +TRANS(FCVTNU_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, false) |
399 | +TRANS(FCVTPS_g, do_fcvt_g, a, FPROUNDING_POSINF, true) | 399 | +TRANS(FCVTPS_g, do_fcvt_g, a, FPROUNDING_POSINF, true) |
400 | +TRANS(FCVTPU_g, do_fcvt_g, a, FPROUNDING_POSINF, false) | 400 | +TRANS(FCVTPU_g, do_fcvt_g, a, FPROUNDING_POSINF, false) |
401 | +TRANS(FCVTMS_g, do_fcvt_g, a, FPROUNDING_NEGINF, true) | 401 | +TRANS(FCVTMS_g, do_fcvt_g, a, FPROUNDING_NEGINF, true) |
402 | +TRANS(FCVTMU_g, do_fcvt_g, a, FPROUNDING_NEGINF, false) | 402 | +TRANS(FCVTMU_g, do_fcvt_g, a, FPROUNDING_NEGINF, false) |
403 | +TRANS(FCVTZS_g, do_fcvt_g, a, FPROUNDING_ZERO, true) | 403 | +TRANS(FCVTZS_g, do_fcvt_g, a, FPROUNDING_ZERO, true) |
404 | +TRANS(FCVTZU_g, do_fcvt_g, a, FPROUNDING_ZERO, false) | 404 | +TRANS(FCVTZU_g, do_fcvt_g, a, FPROUNDING_ZERO, false) |
405 | +TRANS(FCVTAS_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, true) | 405 | +TRANS(FCVTAS_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, true) |
406 | +TRANS(FCVTAU_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, false) | 406 | +TRANS(FCVTAU_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, false) |
407 | + | 407 | + |
408 | static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) | 408 | static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) |
409 | { | 409 | { |
410 | /* FMOV: gpr to or from float, double, or top half of quad fp reg, | 410 | /* FMOV: gpr to or from float, double, or top half of quad fp reg, |
411 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) | 411 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) |
412 | switch (opcode) { | 412 | switch (opcode) { |
413 | case 2: /* SCVTF */ | 413 | case 2: /* SCVTF */ |
414 | case 3: /* UCVTF */ | 414 | case 3: /* UCVTF */ |
415 | - itof = true; | 415 | - itof = true; |
416 | - /* fallthru */ | 416 | - /* fallthru */ |
417 | case 4: /* FCVTAS */ | 417 | case 4: /* FCVTAS */ |
418 | case 5: /* FCVTAU */ | 418 | case 5: /* FCVTAU */ |
419 | - if (rmode != 0) { | 419 | - if (rmode != 0) { |
420 | - goto do_unallocated; | 420 | - goto do_unallocated; |
421 | - } | 421 | - } |
422 | - /* fallthru */ | 422 | - /* fallthru */ |
423 | case 0: /* FCVT[NPMZ]S */ | 423 | case 0: /* FCVT[NPMZ]S */ |
424 | case 1: /* FCVT[NPMZ]U */ | 424 | case 1: /* FCVT[NPMZ]U */ |
425 | - switch (type) { | 425 | - switch (type) { |
426 | - case 0: /* float32 */ | 426 | - case 0: /* float32 */ |
427 | - case 1: /* float64 */ | 427 | - case 1: /* float64 */ |
428 | - break; | 428 | - break; |
429 | - case 3: /* float16 */ | 429 | - case 3: /* float16 */ |
430 | - if (!dc_isar_feature(aa64_fp16, s)) { | 430 | - if (!dc_isar_feature(aa64_fp16, s)) { |
431 | - goto do_unallocated; | 431 | - goto do_unallocated; |
432 | - } | 432 | - } |
433 | - break; | 433 | - break; |
434 | - default: | 434 | - default: |
435 | - goto do_unallocated; | 435 | - goto do_unallocated; |
436 | - } | 436 | - } |
437 | - if (!fp_access_check(s)) { | 437 | - if (!fp_access_check(s)) { |
438 | - return; | 438 | - return; |
439 | - } | 439 | - } |
440 | - handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type); | 440 | - handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type); |
441 | - break; | 441 | - break; |
442 | + goto do_unallocated; | 442 | + goto do_unallocated; |
443 | 443 | ||
444 | default: | 444 | default: |
445 | switch (sf << 7 | type << 5 | rmode << 3 | opcode) { | 445 | switch (sf << 7 | type << 5 | rmode << 3 | opcode) { |
446 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) | 446 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) |
447 | unallocated_encoding(s); /* in decodetree */ | 447 | unallocated_encoding(s); /* in decodetree */ |
448 | } else if (extract32(insn, 21, 1) == 0) { | 448 | } else if (extract32(insn, 21, 1) == 0) { |
449 | /* Floating point to fixed point conversions */ | 449 | /* Floating point to fixed point conversions */ |
450 | - disas_fp_fixed_conv(s, insn); | 450 | - disas_fp_fixed_conv(s, insn); |
451 | + unallocated_encoding(s); /* in decodetree */ | 451 | + unallocated_encoding(s); /* in decodetree */ |
452 | } else { | 452 | } else { |
453 | switch (extract32(insn, 10, 2)) { | 453 | switch (extract32(insn, 10, 2)) { |
454 | case 1: /* Floating point conditional compare */ | 454 | case 1: /* Floating point conditional compare */ |
455 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 455 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
456 | index XXXXXXX..XXXXXXX 100644 | 456 | index XXXXXXX..XXXXXXX 100644 |
457 | --- a/target/arm/tcg/a64.decode | 457 | --- a/target/arm/tcg/a64.decode |
458 | +++ b/target/arm/tcg/a64.decode | 458 | +++ b/target/arm/tcg/a64.decode |
459 | @@ -XXX,XX +XXX,XX @@ FMAXV_s 0110 1110 00 11000 01111 10 ..... ..... @rr_q1e2 | 459 | @@ -XXX,XX +XXX,XX @@ FMAXV_s 0110 1110 00 11000 01111 10 ..... ..... @rr_q1e2 |
460 | FMINV_h 0.00 1110 10 11000 01111 10 ..... ..... @qrr_h | 460 | FMINV_h 0.00 1110 10 11000 01111 10 ..... ..... @qrr_h |
461 | FMINV_s 0110 1110 10 11000 01111 10 ..... ..... @rr_q1e2 | 461 | FMINV_s 0110 1110 10 11000 01111 10 ..... ..... @rr_q1e2 |
462 | 462 | ||
463 | +# Conversion between floating-point and fixed-point (general register) | 463 | +# Conversion between floating-point and fixed-point (general register) |
464 | + | 464 | + |
465 | +&fcvt rd rn esz sf shift | 465 | +&fcvt rd rn esz sf shift |
466 | +%fcvt_shift32 10:5 !function=rsub_32 | 466 | +%fcvt_shift32 10:5 !function=rsub_32 |
467 | +%fcvt_shift64 10:6 !function=rsub_64 | 467 | +%fcvt_shift64 10:6 !function=rsub_64 |
468 | + | 468 | + |
469 | +@fcvt32 0 ....... .. ...... 1..... rn:5 rd:5 \ | 469 | +@fcvt32 0 ....... .. ...... 1..... rn:5 rd:5 \ |
470 | + &fcvt sf=0 esz=%esz_hsd shift=%fcvt_shift32 | 470 | + &fcvt sf=0 esz=%esz_hsd shift=%fcvt_shift32 |
471 | +@fcvt64 1 ....... .. ...... ...... rn:5 rd:5 \ | 471 | +@fcvt64 1 ....... .. ...... ...... rn:5 rd:5 \ |
472 | + &fcvt sf=1 esz=%esz_hsd shift=%fcvt_shift64 | 472 | + &fcvt sf=1 esz=%esz_hsd shift=%fcvt_shift64 |
473 | + | 473 | + |
474 | +SCVTF_g . 0011110 .. 000010 ...... ..... ..... @fcvt32 | 474 | +SCVTF_g . 0011110 .. 000010 ...... ..... ..... @fcvt32 |
475 | +SCVTF_g . 0011110 .. 000010 ...... ..... ..... @fcvt64 | 475 | +SCVTF_g . 0011110 .. 000010 ...... ..... ..... @fcvt64 |
476 | +UCVTF_g . 0011110 .. 000011 ...... ..... ..... @fcvt32 | 476 | +UCVTF_g . 0011110 .. 000011 ...... ..... ..... @fcvt32 |
477 | +UCVTF_g . 0011110 .. 000011 ...... ..... ..... @fcvt64 | 477 | +UCVTF_g . 0011110 .. 000011 ...... ..... ..... @fcvt64 |
478 | + | 478 | + |
479 | +FCVTZS_g . 0011110 .. 011000 ...... ..... ..... @fcvt32 | 479 | +FCVTZS_g . 0011110 .. 011000 ...... ..... ..... @fcvt32 |
480 | +FCVTZS_g . 0011110 .. 011000 ...... ..... ..... @fcvt64 | 480 | +FCVTZS_g . 0011110 .. 011000 ...... ..... ..... @fcvt64 |
481 | +FCVTZU_g . 0011110 .. 011001 ...... ..... ..... @fcvt32 | 481 | +FCVTZU_g . 0011110 .. 011001 ...... ..... ..... @fcvt32 |
482 | +FCVTZU_g . 0011110 .. 011001 ...... ..... ..... @fcvt64 | 482 | +FCVTZU_g . 0011110 .. 011001 ...... ..... ..... @fcvt64 |
483 | + | 483 | + |
484 | +# Conversion between floating-point and integer (general register) | 484 | +# Conversion between floating-point and integer (general register) |
485 | + | 485 | + |
486 | +@icvt sf:1 ....... .. ...... ...... rn:5 rd:5 \ | 486 | +@icvt sf:1 ....... .. ...... ...... rn:5 rd:5 \ |
487 | + &fcvt esz=%esz_hsd shift=0 | 487 | + &fcvt esz=%esz_hsd shift=0 |
488 | + | 488 | + |
489 | +SCVTF_g . 0011110 .. 100010 000000 ..... ..... @icvt | 489 | +SCVTF_g . 0011110 .. 100010 000000 ..... ..... @icvt |
490 | +UCVTF_g . 0011110 .. 100011 000000 ..... ..... @icvt | 490 | +UCVTF_g . 0011110 .. 100011 000000 ..... ..... @icvt |
491 | + | 491 | + |
492 | +FCVTNS_g . 0011110 .. 100000 000000 ..... ..... @icvt | 492 | +FCVTNS_g . 0011110 .. 100000 000000 ..... ..... @icvt |
493 | +FCVTNU_g . 0011110 .. 100001 000000 ..... ..... @icvt | 493 | +FCVTNU_g . 0011110 .. 100001 000000 ..... ..... @icvt |
494 | +FCVTPS_g . 0011110 .. 101000 000000 ..... ..... @icvt | 494 | +FCVTPS_g . 0011110 .. 101000 000000 ..... ..... @icvt |
495 | +FCVTPU_g . 0011110 .. 101001 000000 ..... ..... @icvt | 495 | +FCVTPU_g . 0011110 .. 101001 000000 ..... ..... @icvt |
496 | +FCVTMS_g . 0011110 .. 110000 000000 ..... ..... @icvt | 496 | +FCVTMS_g . 0011110 .. 110000 000000 ..... ..... @icvt |
497 | +FCVTMU_g . 0011110 .. 110001 000000 ..... ..... @icvt | 497 | +FCVTMU_g . 0011110 .. 110001 000000 ..... ..... @icvt |
498 | +FCVTZS_g . 0011110 .. 111000 000000 ..... ..... @icvt | 498 | +FCVTZS_g . 0011110 .. 111000 000000 ..... ..... @icvt |
499 | +FCVTZU_g . 0011110 .. 111001 000000 ..... ..... @icvt | 499 | +FCVTZU_g . 0011110 .. 111001 000000 ..... ..... @icvt |
500 | +FCVTAS_g . 0011110 .. 100100 000000 ..... ..... @icvt | 500 | +FCVTAS_g . 0011110 .. 100100 000000 ..... ..... @icvt |
501 | +FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt | 501 | +FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt |
502 | + | 502 | + |
503 | # Floating-point data processing (1 source) | 503 | # Floating-point data processing (1 source) |
504 | 504 | ||
505 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd | 505 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd |
506 | -- | 506 | -- |
507 | 2.43.0 | 507 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 41 +++++++++++++++++----------------- | 4 | target/arm/tcg/translate-a64.c | 41 +++++++++++++++++----------------- |
5 | target/arm/tcg/a64.decode | 2 ++ | 5 | target/arm/tcg/a64.decode | 2 ++ |
6 | 2 files changed, 22 insertions(+), 21 deletions(-) | 6 | 2 files changed, 22 insertions(+), 21 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ TRANS(FCVTZU_g, do_fcvt_g, a, FPROUNDING_ZERO, false) | 12 | @@ -XXX,XX +XXX,XX @@ TRANS(FCVTZU_g, do_fcvt_g, a, FPROUNDING_ZERO, false) |
13 | TRANS(FCVTAS_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, true) | 13 | TRANS(FCVTAS_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, true) |
14 | TRANS(FCVTAU_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, false) | 14 | TRANS(FCVTAU_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, false) |
15 | 15 | ||
16 | +static bool trans_FJCVTZS(DisasContext *s, arg_FJCVTZS *a) | 16 | +static bool trans_FJCVTZS(DisasContext *s, arg_FJCVTZS *a) |
17 | +{ | 17 | +{ |
18 | + if (!dc_isar_feature(aa64_jscvt, s)) { | 18 | + if (!dc_isar_feature(aa64_jscvt, s)) { |
19 | + return false; | 19 | + return false; |
20 | + } | 20 | + } |
21 | + if (fp_access_check(s)) { | 21 | + if (fp_access_check(s)) { |
22 | + TCGv_i64 t = read_fp_dreg(s, a->rn); | 22 | + TCGv_i64 t = read_fp_dreg(s, a->rn); |
23 | + TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR); | 23 | + TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR); |
24 | + | 24 | + |
25 | + gen_helper_fjcvtzs(t, t, fpstatus); | 25 | + gen_helper_fjcvtzs(t, t, fpstatus); |
26 | + | 26 | + |
27 | + tcg_gen_ext32u_i64(cpu_reg(s, a->rd), t); | 27 | + tcg_gen_ext32u_i64(cpu_reg(s, a->rd), t); |
28 | + tcg_gen_extrh_i64_i32(cpu_ZF, t); | 28 | + tcg_gen_extrh_i64_i32(cpu_ZF, t); |
29 | + tcg_gen_movi_i32(cpu_CF, 0); | 29 | + tcg_gen_movi_i32(cpu_CF, 0); |
30 | + tcg_gen_movi_i32(cpu_NF, 0); | 30 | + tcg_gen_movi_i32(cpu_NF, 0); |
31 | + tcg_gen_movi_i32(cpu_VF, 0); | 31 | + tcg_gen_movi_i32(cpu_VF, 0); |
32 | + } | 32 | + } |
33 | + return true; | 33 | + return true; |
34 | +} | 34 | +} |
35 | + | 35 | + |
36 | static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) | 36 | static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) |
37 | { | 37 | { |
38 | /* FMOV: gpr to or from float, double, or top half of quad fp reg, | 38 | /* FMOV: gpr to or from float, double, or top half of quad fp reg, |
39 | @@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) | 39 | @@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) |
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
43 | -static void handle_fjcvtzs(DisasContext *s, int rd, int rn) | 43 | -static void handle_fjcvtzs(DisasContext *s, int rd, int rn) |
44 | -{ | 44 | -{ |
45 | - TCGv_i64 t = read_fp_dreg(s, rn); | 45 | - TCGv_i64 t = read_fp_dreg(s, rn); |
46 | - TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR); | 46 | - TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR); |
47 | - | 47 | - |
48 | - gen_helper_fjcvtzs(t, t, fpstatus); | 48 | - gen_helper_fjcvtzs(t, t, fpstatus); |
49 | - | 49 | - |
50 | - tcg_gen_ext32u_i64(cpu_reg(s, rd), t); | 50 | - tcg_gen_ext32u_i64(cpu_reg(s, rd), t); |
51 | - tcg_gen_extrh_i64_i32(cpu_ZF, t); | 51 | - tcg_gen_extrh_i64_i32(cpu_ZF, t); |
52 | - tcg_gen_movi_i32(cpu_CF, 0); | 52 | - tcg_gen_movi_i32(cpu_CF, 0); |
53 | - tcg_gen_movi_i32(cpu_NF, 0); | 53 | - tcg_gen_movi_i32(cpu_NF, 0); |
54 | - tcg_gen_movi_i32(cpu_VF, 0); | 54 | - tcg_gen_movi_i32(cpu_VF, 0); |
55 | -} | 55 | -} |
56 | - | 56 | - |
57 | /* Floating point <-> integer conversions | 57 | /* Floating point <-> integer conversions |
58 | * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 | 58 | * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 |
59 | * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ | 59 | * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ |
60 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) | 60 | @@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn) |
61 | break; | 61 | break; |
62 | 62 | ||
63 | case 0b00111110: /* FJCVTZS */ | 63 | case 0b00111110: /* FJCVTZS */ |
64 | - if (!dc_isar_feature(aa64_jscvt, s)) { | 64 | - if (!dc_isar_feature(aa64_jscvt, s)) { |
65 | - goto do_unallocated; | 65 | - goto do_unallocated; |
66 | - } else if (fp_access_check(s)) { | 66 | - } else if (fp_access_check(s)) { |
67 | - handle_fjcvtzs(s, rd, rn); | 67 | - handle_fjcvtzs(s, rd, rn); |
68 | - } | 68 | - } |
69 | - break; | 69 | - break; |
70 | - | 70 | - |
71 | default: | 71 | default: |
72 | do_unallocated: | 72 | do_unallocated: |
73 | unallocated_encoding(s); | 73 | unallocated_encoding(s); |
74 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 74 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
75 | index XXXXXXX..XXXXXXX 100644 | 75 | index XXXXXXX..XXXXXXX 100644 |
76 | --- a/target/arm/tcg/a64.decode | 76 | --- a/target/arm/tcg/a64.decode |
77 | +++ b/target/arm/tcg/a64.decode | 77 | +++ b/target/arm/tcg/a64.decode |
78 | @@ -XXX,XX +XXX,XX @@ FCVTZU_g . 0011110 .. 111001 000000 ..... ..... @icvt | 78 | @@ -XXX,XX +XXX,XX @@ FCVTZU_g . 0011110 .. 111001 000000 ..... ..... @icvt |
79 | FCVTAS_g . 0011110 .. 100100 000000 ..... ..... @icvt | 79 | FCVTAS_g . 0011110 .. 100100 000000 ..... ..... @icvt |
80 | FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt | 80 | FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt |
81 | 81 | ||
82 | +FJCVTZS 0 0011110 01 111110 000000 ..... ..... @rr | 82 | +FJCVTZS 0 0011110 01 111110 000000 ..... ..... @rr |
83 | + | 83 | + |
84 | # Floating-point data processing (1 source) | 84 | # Floating-point data processing (1 source) |
85 | 85 | ||
86 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd | 86 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd |
87 | -- | 87 | -- |
88 | 2.43.0 | 88 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove disas_fp_int_conv and disas_data_proc_fp as these | 1 | Remove disas_fp_int_conv and disas_data_proc_fp as these |
---|---|---|---|
2 | were the last insns decoded by those functions. | 2 | were the last insns decoded by those functions. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 232 ++++++++++----------------------- | 7 | target/arm/tcg/translate-a64.c | 232 ++++++++++----------------------- |
8 | target/arm/tcg/a64.decode | 14 ++ | 8 | target/arm/tcg/a64.decode | 14 ++ |
9 | 2 files changed, 86 insertions(+), 160 deletions(-) | 9 | 2 files changed, 86 insertions(+), 160 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ static bool trans_FJCVTZS(DisasContext *s, arg_FJCVTZS *a) | 15 | @@ -XXX,XX +XXX,XX @@ static bool trans_FJCVTZS(DisasContext *s, arg_FJCVTZS *a) |
16 | return true; | 16 | return true; |
17 | } | 17 | } |
18 | 18 | ||
19 | -static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) | 19 | -static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof) |
20 | +static bool trans_FMOV_hx(DisasContext *s, arg_rr *a) | 20 | +static bool trans_FMOV_hx(DisasContext *s, arg_rr *a) |
21 | { | 21 | { |
22 | - /* FMOV: gpr to or from float, double, or top half of quad fp reg, | 22 | - /* FMOV: gpr to or from float, double, or top half of quad fp reg, |
23 | - * without conversion. | 23 | - * without conversion. |
24 | - */ | 24 | - */ |
25 | - | 25 | - |
26 | - if (itof) { | 26 | - if (itof) { |
27 | - TCGv_i64 tcg_rn = cpu_reg(s, rn); | 27 | - TCGv_i64 tcg_rn = cpu_reg(s, rn); |
28 | - TCGv_i64 tmp; | 28 | - TCGv_i64 tmp; |
29 | - | 29 | - |
30 | - switch (type) { | 30 | - switch (type) { |
31 | - case 0: | 31 | - case 0: |
32 | - /* 32 bit */ | 32 | - /* 32 bit */ |
33 | - tmp = tcg_temp_new_i64(); | 33 | - tmp = tcg_temp_new_i64(); |
34 | - tcg_gen_ext32u_i64(tmp, tcg_rn); | 34 | - tcg_gen_ext32u_i64(tmp, tcg_rn); |
35 | - write_fp_dreg(s, rd, tmp); | 35 | - write_fp_dreg(s, rd, tmp); |
36 | - break; | 36 | - break; |
37 | - case 1: | 37 | - case 1: |
38 | - /* 64 bit */ | 38 | - /* 64 bit */ |
39 | - write_fp_dreg(s, rd, tcg_rn); | 39 | - write_fp_dreg(s, rd, tcg_rn); |
40 | - break; | 40 | - break; |
41 | - case 2: | 41 | - case 2: |
42 | - /* 64 bit to top half. */ | 42 | - /* 64 bit to top half. */ |
43 | - tcg_gen_st_i64(tcg_rn, tcg_env, fp_reg_hi_offset(s, rd)); | 43 | - tcg_gen_st_i64(tcg_rn, tcg_env, fp_reg_hi_offset(s, rd)); |
44 | - clear_vec_high(s, true, rd); | 44 | - clear_vec_high(s, true, rd); |
45 | - break; | 45 | - break; |
46 | - case 3: | 46 | - case 3: |
47 | - /* 16 bit */ | 47 | - /* 16 bit */ |
48 | - tmp = tcg_temp_new_i64(); | 48 | - tmp = tcg_temp_new_i64(); |
49 | - tcg_gen_ext16u_i64(tmp, tcg_rn); | 49 | - tcg_gen_ext16u_i64(tmp, tcg_rn); |
50 | - write_fp_dreg(s, rd, tmp); | 50 | - write_fp_dreg(s, rd, tmp); |
51 | - break; | 51 | - break; |
52 | - default: | 52 | - default: |
53 | - g_assert_not_reached(); | 53 | - g_assert_not_reached(); |
54 | - } | 54 | - } |
55 | - } else { | 55 | - } else { |
56 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); | 56 | - TCGv_i64 tcg_rd = cpu_reg(s, rd); |
57 | - | 57 | - |
58 | - switch (type) { | 58 | - switch (type) { |
59 | - case 0: | 59 | - case 0: |
60 | - /* 32 bit */ | 60 | - /* 32 bit */ |
61 | - tcg_gen_ld32u_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_32)); | 61 | - tcg_gen_ld32u_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_32)); |
62 | - break; | 62 | - break; |
63 | - case 1: | 63 | - case 1: |
64 | - /* 64 bit */ | 64 | - /* 64 bit */ |
65 | - tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_64)); | 65 | - tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_64)); |
66 | - break; | 66 | - break; |
67 | - case 2: | 67 | - case 2: |
68 | - /* 64 bits from top half */ | 68 | - /* 64 bits from top half */ |
69 | - tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_hi_offset(s, rn)); | 69 | - tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_hi_offset(s, rn)); |
70 | - break; | 70 | - break; |
71 | - case 3: | 71 | - case 3: |
72 | - /* 16 bit */ | 72 | - /* 16 bit */ |
73 | - tcg_gen_ld16u_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_16)); | 73 | - tcg_gen_ld16u_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_16)); |
74 | - break; | 74 | - break; |
75 | - default: | 75 | - default: |
76 | - g_assert_not_reached(); | 76 | - g_assert_not_reached(); |
77 | - } | 77 | - } |
78 | + if (!dc_isar_feature(aa64_fp16, s)) { | 78 | + if (!dc_isar_feature(aa64_fp16, s)) { |
79 | + return false; | 79 | + return false; |
80 | } | 80 | } |
81 | + if (fp_access_check(s)) { | 81 | + if (fp_access_check(s)) { |
82 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); | 82 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); |
83 | + TCGv_i64 tmp = tcg_temp_new_i64(); | 83 | + TCGv_i64 tmp = tcg_temp_new_i64(); |
84 | + tcg_gen_ext16u_i64(tmp, tcg_rn); | 84 | + tcg_gen_ext16u_i64(tmp, tcg_rn); |
85 | + write_fp_dreg(s, a->rd, tmp); | 85 | + write_fp_dreg(s, a->rd, tmp); |
86 | + } | 86 | + } |
87 | + return true; | 87 | + return true; |
88 | } | 88 | } |
89 | 89 | ||
90 | -/* Floating point <-> integer conversions | 90 | -/* Floating point <-> integer conversions |
91 | - * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 | 91 | - * 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0 |
92 | - * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ | 92 | - * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ |
93 | - * | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd | | 93 | - * | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd | |
94 | - * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ | 94 | - * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+ |
95 | - */ | 95 | - */ |
96 | -static void disas_fp_int_conv(DisasContext *s, uint32_t insn) | 96 | -static void disas_fp_int_conv(DisasContext *s, uint32_t insn) |
97 | +static bool trans_FMOV_sw(DisasContext *s, arg_rr *a) | 97 | +static bool trans_FMOV_sw(DisasContext *s, arg_rr *a) |
98 | { | 98 | { |
99 | - int rd = extract32(insn, 0, 5); | 99 | - int rd = extract32(insn, 0, 5); |
100 | - int rn = extract32(insn, 5, 5); | 100 | - int rn = extract32(insn, 5, 5); |
101 | - int opcode = extract32(insn, 16, 3); | 101 | - int opcode = extract32(insn, 16, 3); |
102 | - int rmode = extract32(insn, 19, 2); | 102 | - int rmode = extract32(insn, 19, 2); |
103 | - int type = extract32(insn, 22, 2); | 103 | - int type = extract32(insn, 22, 2); |
104 | - bool sbit = extract32(insn, 29, 1); | 104 | - bool sbit = extract32(insn, 29, 1); |
105 | - bool sf = extract32(insn, 31, 1); | 105 | - bool sf = extract32(insn, 31, 1); |
106 | - bool itof = false; | 106 | - bool itof = false; |
107 | - | 107 | - |
108 | - if (sbit) { | 108 | - if (sbit) { |
109 | - goto do_unallocated; | 109 | - goto do_unallocated; |
110 | - } | 110 | - } |
111 | - | 111 | - |
112 | - switch (opcode) { | 112 | - switch (opcode) { |
113 | - case 2: /* SCVTF */ | 113 | - case 2: /* SCVTF */ |
114 | - case 3: /* UCVTF */ | 114 | - case 3: /* UCVTF */ |
115 | - case 4: /* FCVTAS */ | 115 | - case 4: /* FCVTAS */ |
116 | - case 5: /* FCVTAU */ | 116 | - case 5: /* FCVTAU */ |
117 | - case 0: /* FCVT[NPMZ]S */ | 117 | - case 0: /* FCVT[NPMZ]S */ |
118 | - case 1: /* FCVT[NPMZ]U */ | 118 | - case 1: /* FCVT[NPMZ]U */ |
119 | - goto do_unallocated; | 119 | - goto do_unallocated; |
120 | - | 120 | - |
121 | - default: | 121 | - default: |
122 | - switch (sf << 7 | type << 5 | rmode << 3 | opcode) { | 122 | - switch (sf << 7 | type << 5 | rmode << 3 | opcode) { |
123 | - case 0b01100110: /* FMOV half <-> 32-bit int */ | 123 | - case 0b01100110: /* FMOV half <-> 32-bit int */ |
124 | - case 0b01100111: | 124 | - case 0b01100111: |
125 | - case 0b11100110: /* FMOV half <-> 64-bit int */ | 125 | - case 0b11100110: /* FMOV half <-> 64-bit int */ |
126 | - case 0b11100111: | 126 | - case 0b11100111: |
127 | - if (!dc_isar_feature(aa64_fp16, s)) { | 127 | - if (!dc_isar_feature(aa64_fp16, s)) { |
128 | - goto do_unallocated; | 128 | - goto do_unallocated; |
129 | - } | 129 | - } |
130 | - /* fallthru */ | 130 | - /* fallthru */ |
131 | - case 0b00000110: /* FMOV 32-bit */ | 131 | - case 0b00000110: /* FMOV 32-bit */ |
132 | - case 0b00000111: | 132 | - case 0b00000111: |
133 | - case 0b10100110: /* FMOV 64-bit */ | 133 | - case 0b10100110: /* FMOV 64-bit */ |
134 | - case 0b10100111: | 134 | - case 0b10100111: |
135 | - case 0b11001110: /* FMOV top half of 128-bit */ | 135 | - case 0b11001110: /* FMOV top half of 128-bit */ |
136 | - case 0b11001111: | 136 | - case 0b11001111: |
137 | - if (!fp_access_check(s)) { | 137 | - if (!fp_access_check(s)) { |
138 | - return; | 138 | - return; |
139 | - } | 139 | - } |
140 | - itof = opcode & 1; | 140 | - itof = opcode & 1; |
141 | - handle_fmov(s, rd, rn, type, itof); | 141 | - handle_fmov(s, rd, rn, type, itof); |
142 | - break; | 142 | - break; |
143 | - | 143 | - |
144 | - case 0b00111110: /* FJCVTZS */ | 144 | - case 0b00111110: /* FJCVTZS */ |
145 | - default: | 145 | - default: |
146 | - do_unallocated: | 146 | - do_unallocated: |
147 | - unallocated_encoding(s); | 147 | - unallocated_encoding(s); |
148 | - return; | 148 | - return; |
149 | - } | 149 | - } |
150 | - break; | 150 | - break; |
151 | + if (fp_access_check(s)) { | 151 | + if (fp_access_check(s)) { |
152 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); | 152 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); |
153 | + TCGv_i64 tmp = tcg_temp_new_i64(); | 153 | + TCGv_i64 tmp = tcg_temp_new_i64(); |
154 | + tcg_gen_ext32u_i64(tmp, tcg_rn); | 154 | + tcg_gen_ext32u_i64(tmp, tcg_rn); |
155 | + write_fp_dreg(s, a->rd, tmp); | 155 | + write_fp_dreg(s, a->rd, tmp); |
156 | } | 156 | } |
157 | + return true; | 157 | + return true; |
158 | } | 158 | } |
159 | 159 | ||
160 | -/* FP-specific subcases of table C3-6 (SIMD and FP data processing) | 160 | -/* FP-specific subcases of table C3-6 (SIMD and FP data processing) |
161 | - * 31 30 29 28 25 24 0 | 161 | - * 31 30 29 28 25 24 0 |
162 | - * +---+---+---+---------+-----------------------------+ | 162 | - * +---+---+---+---------+-----------------------------+ |
163 | - * | | 0 | | 1 1 1 1 | | | 163 | - * | | 0 | | 1 1 1 1 | | |
164 | - * +---+---+---+---------+-----------------------------+ | 164 | - * +---+---+---+---------+-----------------------------+ |
165 | - */ | 165 | - */ |
166 | -static void disas_data_proc_fp(DisasContext *s, uint32_t insn) | 166 | -static void disas_data_proc_fp(DisasContext *s, uint32_t insn) |
167 | +static bool trans_FMOV_dx(DisasContext *s, arg_rr *a) | 167 | +static bool trans_FMOV_dx(DisasContext *s, arg_rr *a) |
168 | { | 168 | { |
169 | - if (extract32(insn, 24, 1)) { | 169 | - if (extract32(insn, 24, 1)) { |
170 | - unallocated_encoding(s); /* in decodetree */ | 170 | - unallocated_encoding(s); /* in decodetree */ |
171 | - } else if (extract32(insn, 21, 1) == 0) { | 171 | - } else if (extract32(insn, 21, 1) == 0) { |
172 | - /* Floating point to fixed point conversions */ | 172 | - /* Floating point to fixed point conversions */ |
173 | - unallocated_encoding(s); /* in decodetree */ | 173 | - unallocated_encoding(s); /* in decodetree */ |
174 | - } else { | 174 | - } else { |
175 | - switch (extract32(insn, 10, 2)) { | 175 | - switch (extract32(insn, 10, 2)) { |
176 | - case 1: /* Floating point conditional compare */ | 176 | - case 1: /* Floating point conditional compare */ |
177 | - case 2: /* Floating point data-processing (2 source) */ | 177 | - case 2: /* Floating point data-processing (2 source) */ |
178 | - case 3: /* Floating point conditional select */ | 178 | - case 3: /* Floating point conditional select */ |
179 | - unallocated_encoding(s); /* in decodetree */ | 179 | - unallocated_encoding(s); /* in decodetree */ |
180 | - break; | 180 | - break; |
181 | - case 0: | 181 | - case 0: |
182 | - switch (ctz32(extract32(insn, 12, 4))) { | 182 | - switch (ctz32(extract32(insn, 12, 4))) { |
183 | - case 0: /* [15:12] == xxx1 */ | 183 | - case 0: /* [15:12] == xxx1 */ |
184 | - /* Floating point immediate */ | 184 | - /* Floating point immediate */ |
185 | - unallocated_encoding(s); /* in decodetree */ | 185 | - unallocated_encoding(s); /* in decodetree */ |
186 | - break; | 186 | - break; |
187 | - case 1: /* [15:12] == xx10 */ | 187 | - case 1: /* [15:12] == xx10 */ |
188 | - /* Floating point compare */ | 188 | - /* Floating point compare */ |
189 | - unallocated_encoding(s); /* in decodetree */ | 189 | - unallocated_encoding(s); /* in decodetree */ |
190 | - break; | 190 | - break; |
191 | - case 2: /* [15:12] == x100 */ | 191 | - case 2: /* [15:12] == x100 */ |
192 | - /* Floating point data-processing (1 source) */ | 192 | - /* Floating point data-processing (1 source) */ |
193 | - unallocated_encoding(s); /* in decodetree */ | 193 | - unallocated_encoding(s); /* in decodetree */ |
194 | - break; | 194 | - break; |
195 | - case 3: /* [15:12] == 1000 */ | 195 | - case 3: /* [15:12] == 1000 */ |
196 | - unallocated_encoding(s); | 196 | - unallocated_encoding(s); |
197 | - break; | 197 | - break; |
198 | - default: /* [15:12] == 0000 */ | 198 | - default: /* [15:12] == 0000 */ |
199 | - /* Floating point <-> integer conversions */ | 199 | - /* Floating point <-> integer conversions */ |
200 | - disas_fp_int_conv(s, insn); | 200 | - disas_fp_int_conv(s, insn); |
201 | - break; | 201 | - break; |
202 | - } | 202 | - } |
203 | - break; | 203 | - break; |
204 | - } | 204 | - } |
205 | + if (fp_access_check(s)) { | 205 | + if (fp_access_check(s)) { |
206 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); | 206 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); |
207 | + write_fp_dreg(s, a->rd, tcg_rn); | 207 | + write_fp_dreg(s, a->rd, tcg_rn); |
208 | } | 208 | } |
209 | + return true; | 209 | + return true; |
210 | +} | 210 | +} |
211 | + | 211 | + |
212 | +static bool trans_FMOV_ux(DisasContext *s, arg_rr *a) | 212 | +static bool trans_FMOV_ux(DisasContext *s, arg_rr *a) |
213 | +{ | 213 | +{ |
214 | + if (fp_access_check(s)) { | 214 | + if (fp_access_check(s)) { |
215 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); | 215 | + TCGv_i64 tcg_rn = cpu_reg(s, a->rn); |
216 | + tcg_gen_st_i64(tcg_rn, tcg_env, fp_reg_hi_offset(s, a->rd)); | 216 | + tcg_gen_st_i64(tcg_rn, tcg_env, fp_reg_hi_offset(s, a->rd)); |
217 | + clear_vec_high(s, true, a->rd); | 217 | + clear_vec_high(s, true, a->rd); |
218 | + } | 218 | + } |
219 | + return true; | 219 | + return true; |
220 | +} | 220 | +} |
221 | + | 221 | + |
222 | +static bool trans_FMOV_xh(DisasContext *s, arg_rr *a) | 222 | +static bool trans_FMOV_xh(DisasContext *s, arg_rr *a) |
223 | +{ | 223 | +{ |
224 | + if (!dc_isar_feature(aa64_fp16, s)) { | 224 | + if (!dc_isar_feature(aa64_fp16, s)) { |
225 | + return false; | 225 | + return false; |
226 | + } | 226 | + } |
227 | + if (fp_access_check(s)) { | 227 | + if (fp_access_check(s)) { |
228 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 228 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
229 | + tcg_gen_ld16u_i64(tcg_rd, tcg_env, fp_reg_offset(s, a->rn, MO_16)); | 229 | + tcg_gen_ld16u_i64(tcg_rd, tcg_env, fp_reg_offset(s, a->rn, MO_16)); |
230 | + } | 230 | + } |
231 | + return true; | 231 | + return true; |
232 | +} | 232 | +} |
233 | + | 233 | + |
234 | +static bool trans_FMOV_ws(DisasContext *s, arg_rr *a) | 234 | +static bool trans_FMOV_ws(DisasContext *s, arg_rr *a) |
235 | +{ | 235 | +{ |
236 | + if (fp_access_check(s)) { | 236 | + if (fp_access_check(s)) { |
237 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 237 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
238 | + tcg_gen_ld32u_i64(tcg_rd, tcg_env, fp_reg_offset(s, a->rn, MO_32)); | 238 | + tcg_gen_ld32u_i64(tcg_rd, tcg_env, fp_reg_offset(s, a->rn, MO_32)); |
239 | + } | 239 | + } |
240 | + return true; | 240 | + return true; |
241 | +} | 241 | +} |
242 | + | 242 | + |
243 | +static bool trans_FMOV_xd(DisasContext *s, arg_rr *a) | 243 | +static bool trans_FMOV_xd(DisasContext *s, arg_rr *a) |
244 | +{ | 244 | +{ |
245 | + if (fp_access_check(s)) { | 245 | + if (fp_access_check(s)) { |
246 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 246 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
247 | + tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_offset(s, a->rn, MO_64)); | 247 | + tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_offset(s, a->rn, MO_64)); |
248 | + } | 248 | + } |
249 | + return true; | 249 | + return true; |
250 | +} | 250 | +} |
251 | + | 251 | + |
252 | +static bool trans_FMOV_xu(DisasContext *s, arg_rr *a) | 252 | +static bool trans_FMOV_xu(DisasContext *s, arg_rr *a) |
253 | +{ | 253 | +{ |
254 | + if (fp_access_check(s)) { | 254 | + if (fp_access_check(s)) { |
255 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); | 255 | + TCGv_i64 tcg_rd = cpu_reg(s, a->rd); |
256 | + tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_hi_offset(s, a->rn)); | 256 | + tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_hi_offset(s, a->rn)); |
257 | + } | 257 | + } |
258 | + return true; | 258 | + return true; |
259 | } | 259 | } |
260 | 260 | ||
261 | /* Common vector code for handling integer to FP conversion */ | 261 | /* Common vector code for handling integer to FP conversion */ |
262 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd(DisasContext *s, uint32_t insn) | 262 | @@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd(DisasContext *s, uint32_t insn) |
263 | static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) | 263 | static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) |
264 | { | 264 | { |
265 | if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) { | 265 | if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) { |
266 | - disas_data_proc_fp(s, insn); | 266 | - disas_data_proc_fp(s, insn); |
267 | + unallocated_encoding(s); /* in decodetree */ | 267 | + unallocated_encoding(s); /* in decodetree */ |
268 | } else { | 268 | } else { |
269 | /* SIMD, including crypto */ | 269 | /* SIMD, including crypto */ |
270 | disas_data_proc_simd(s, insn); | 270 | disas_data_proc_simd(s, insn); |
271 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 271 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
272 | index XXXXXXX..XXXXXXX 100644 | 272 | index XXXXXXX..XXXXXXX 100644 |
273 | --- a/target/arm/tcg/a64.decode | 273 | --- a/target/arm/tcg/a64.decode |
274 | +++ b/target/arm/tcg/a64.decode | 274 | +++ b/target/arm/tcg/a64.decode |
275 | @@ -XXX,XX +XXX,XX @@ FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt | 275 | @@ -XXX,XX +XXX,XX @@ FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt |
276 | 276 | ||
277 | FJCVTZS 0 0011110 01 111110 000000 ..... ..... @rr | 277 | FJCVTZS 0 0011110 01 111110 000000 ..... ..... @rr |
278 | 278 | ||
279 | +FMOV_ws 0 0011110 00 100110 000000 ..... ..... @rr | 279 | +FMOV_ws 0 0011110 00 100110 000000 ..... ..... @rr |
280 | +FMOV_sw 0 0011110 00 100111 000000 ..... ..... @rr | 280 | +FMOV_sw 0 0011110 00 100111 000000 ..... ..... @rr |
281 | + | 281 | + |
282 | +FMOV_xd 1 0011110 01 100110 000000 ..... ..... @rr | 282 | +FMOV_xd 1 0011110 01 100110 000000 ..... ..... @rr |
283 | +FMOV_dx 1 0011110 01 100111 000000 ..... ..... @rr | 283 | +FMOV_dx 1 0011110 01 100111 000000 ..... ..... @rr |
284 | + | 284 | + |
285 | +# Move to/from upper half of 128-bit | 285 | +# Move to/from upper half of 128-bit |
286 | +FMOV_xu 1 0011110 10 101110 000000 ..... ..... @rr | 286 | +FMOV_xu 1 0011110 10 101110 000000 ..... ..... @rr |
287 | +FMOV_ux 1 0011110 10 101111 000000 ..... ..... @rr | 287 | +FMOV_ux 1 0011110 10 101111 000000 ..... ..... @rr |
288 | + | 288 | + |
289 | +# Half-precision allows both sf=0 and sf=1 with identical results | 289 | +# Half-precision allows both sf=0 and sf=1 with identical results |
290 | +FMOV_xh - 0011110 11 100110 000000 ..... ..... @rr | 290 | +FMOV_xh - 0011110 11 100110 000000 ..... ..... @rr |
291 | +FMOV_hx - 0011110 11 100111 000000 ..... ..... @rr | 291 | +FMOV_hx - 0011110 11 100111 000000 ..... ..... @rr |
292 | + | 292 | + |
293 | # Floating-point data processing (1 source) | 293 | # Floating-point data processing (1 source) |
294 | 294 | ||
295 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd | 295 | FMOV_s 00011110 .. 1 000000 10000 ..... ..... @rr_hsd |
296 | -- | 296 | -- |
297 | 2.43.0 | 297 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 123 +++++++++++++++++++++------------ | 4 | target/arm/tcg/translate-a64.c | 123 +++++++++++++++++++++------------ |
5 | target/arm/tcg/a64.decode | 11 +++ | 5 | target/arm/tcg/a64.decode | 11 +++ |
6 | 2 files changed, 89 insertions(+), 45 deletions(-) | 6 | 2 files changed, 89 insertions(+), 45 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool trans_FMOV_xu(DisasContext *s, arg_rr *a) | 12 | @@ -XXX,XX +XXX,XX @@ static bool trans_FMOV_xu(DisasContext *s, arg_rr *a) |
13 | return true; | 13 | return true; |
14 | } | 14 | } |
15 | 15 | ||
16 | +typedef struct ENVScalar1 { | 16 | +typedef struct ENVScalar1 { |
17 | + NeonGenOneOpEnvFn *gen_bhs[3]; | 17 | + NeonGenOneOpEnvFn *gen_bhs[3]; |
18 | + NeonGenOne64OpEnvFn *gen_d; | 18 | + NeonGenOne64OpEnvFn *gen_d; |
19 | +} ENVScalar1; | 19 | +} ENVScalar1; |
20 | + | 20 | + |
21 | +static bool do_env_scalar1(DisasContext *s, arg_rr_e *a, const ENVScalar1 *f) | 21 | +static bool do_env_scalar1(DisasContext *s, arg_rr_e *a, const ENVScalar1 *f) |
22 | +{ | 22 | +{ |
23 | + if (!fp_access_check(s)) { | 23 | + if (!fp_access_check(s)) { |
24 | + return true; | 24 | + return true; |
25 | + } | 25 | + } |
26 | + if (a->esz == MO_64) { | 26 | + if (a->esz == MO_64) { |
27 | + TCGv_i64 t = read_fp_dreg(s, a->rn); | 27 | + TCGv_i64 t = read_fp_dreg(s, a->rn); |
28 | + f->gen_d(t, tcg_env, t); | 28 | + f->gen_d(t, tcg_env, t); |
29 | + write_fp_dreg(s, a->rd, t); | 29 | + write_fp_dreg(s, a->rd, t); |
30 | + } else { | 30 | + } else { |
31 | + TCGv_i32 t = tcg_temp_new_i32(); | 31 | + TCGv_i32 t = tcg_temp_new_i32(); |
32 | + | 32 | + |
33 | + read_vec_element_i32(s, t, a->rn, 0, a->esz); | 33 | + read_vec_element_i32(s, t, a->rn, 0, a->esz); |
34 | + f->gen_bhs[a->esz](t, tcg_env, t); | 34 | + f->gen_bhs[a->esz](t, tcg_env, t); |
35 | + write_fp_sreg(s, a->rd, t); | 35 | + write_fp_sreg(s, a->rd, t); |
36 | + } | 36 | + } |
37 | + return true; | 37 | + return true; |
38 | +} | 38 | +} |
39 | + | 39 | + |
40 | +static bool do_env_vector1(DisasContext *s, arg_qrr_e *a, const ENVScalar1 *f) | 40 | +static bool do_env_vector1(DisasContext *s, arg_qrr_e *a, const ENVScalar1 *f) |
41 | +{ | 41 | +{ |
42 | + if (a->esz == MO_64 && !a->q) { | 42 | + if (a->esz == MO_64 && !a->q) { |
43 | + return false; | 43 | + return false; |
44 | + } | 44 | + } |
45 | + if (!fp_access_check(s)) { | 45 | + if (!fp_access_check(s)) { |
46 | + return true; | 46 | + return true; |
47 | + } | 47 | + } |
48 | + if (a->esz == MO_64) { | 48 | + if (a->esz == MO_64) { |
49 | + TCGv_i64 t = tcg_temp_new_i64(); | 49 | + TCGv_i64 t = tcg_temp_new_i64(); |
50 | + | 50 | + |
51 | + for (int i = 0; i < 2; ++i) { | 51 | + for (int i = 0; i < 2; ++i) { |
52 | + read_vec_element(s, t, a->rn, i, MO_64); | 52 | + read_vec_element(s, t, a->rn, i, MO_64); |
53 | + f->gen_d(t, tcg_env, t); | 53 | + f->gen_d(t, tcg_env, t); |
54 | + write_vec_element(s, t, a->rd, i, MO_64); | 54 | + write_vec_element(s, t, a->rd, i, MO_64); |
55 | + } | 55 | + } |
56 | + } else { | 56 | + } else { |
57 | + TCGv_i32 t = tcg_temp_new_i32(); | 57 | + TCGv_i32 t = tcg_temp_new_i32(); |
58 | + int n = (a->q ? 16 : 8) >> a->esz; | 58 | + int n = (a->q ? 16 : 8) >> a->esz; |
59 | + | 59 | + |
60 | + for (int i = 0; i < n; ++i) { | 60 | + for (int i = 0; i < n; ++i) { |
61 | + read_vec_element_i32(s, t, a->rn, i, a->esz); | 61 | + read_vec_element_i32(s, t, a->rn, i, a->esz); |
62 | + f->gen_bhs[a->esz](t, tcg_env, t); | 62 | + f->gen_bhs[a->esz](t, tcg_env, t); |
63 | + write_vec_element_i32(s, t, a->rd, i, a->esz); | 63 | + write_vec_element_i32(s, t, a->rd, i, a->esz); |
64 | + } | 64 | + } |
65 | + } | 65 | + } |
66 | + clear_vec_high(s, a->q, a->rd); | 66 | + clear_vec_high(s, a->q, a->rd); |
67 | + return true; | 67 | + return true; |
68 | +} | 68 | +} |
69 | + | 69 | + |
70 | +static const ENVScalar1 f_scalar_sqabs = { | 70 | +static const ENVScalar1 f_scalar_sqabs = { |
71 | + { gen_helper_neon_qabs_s8, | 71 | + { gen_helper_neon_qabs_s8, |
72 | + gen_helper_neon_qabs_s16, | 72 | + gen_helper_neon_qabs_s16, |
73 | + gen_helper_neon_qabs_s32 }, | 73 | + gen_helper_neon_qabs_s32 }, |
74 | + gen_helper_neon_qabs_s64, | 74 | + gen_helper_neon_qabs_s64, |
75 | +}; | 75 | +}; |
76 | +TRANS(SQABS_s, do_env_scalar1, a, &f_scalar_sqabs) | 76 | +TRANS(SQABS_s, do_env_scalar1, a, &f_scalar_sqabs) |
77 | +TRANS(SQABS_v, do_env_vector1, a, &f_scalar_sqabs) | 77 | +TRANS(SQABS_v, do_env_vector1, a, &f_scalar_sqabs) |
78 | + | 78 | + |
79 | +static const ENVScalar1 f_scalar_sqneg = { | 79 | +static const ENVScalar1 f_scalar_sqneg = { |
80 | + { gen_helper_neon_qneg_s8, | 80 | + { gen_helper_neon_qneg_s8, |
81 | + gen_helper_neon_qneg_s16, | 81 | + gen_helper_neon_qneg_s16, |
82 | + gen_helper_neon_qneg_s32 }, | 82 | + gen_helper_neon_qneg_s32 }, |
83 | + gen_helper_neon_qneg_s64, | 83 | + gen_helper_neon_qneg_s64, |
84 | +}; | 84 | +}; |
85 | +TRANS(SQNEG_s, do_env_scalar1, a, &f_scalar_sqneg) | 85 | +TRANS(SQNEG_s, do_env_scalar1, a, &f_scalar_sqneg) |
86 | +TRANS(SQNEG_v, do_env_vector1, a, &f_scalar_sqneg) | 86 | +TRANS(SQNEG_v, do_env_vector1, a, &f_scalar_sqneg) |
87 | + | 87 | + |
88 | /* Common vector code for handling integer to FP conversion */ | 88 | /* Common vector code for handling integer to FP conversion */ |
89 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 89 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
90 | int elements, int is_signed, | 90 | int elements, int is_signed, |
91 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 91 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
92 | */ | 92 | */ |
93 | tcg_gen_not_i64(tcg_rd, tcg_rn); | 93 | tcg_gen_not_i64(tcg_rd, tcg_rn); |
94 | break; | 94 | break; |
95 | - case 0x7: /* SQABS, SQNEG */ | 95 | - case 0x7: /* SQABS, SQNEG */ |
96 | - if (u) { | 96 | - if (u) { |
97 | - gen_helper_neon_qneg_s64(tcg_rd, tcg_env, tcg_rn); | 97 | - gen_helper_neon_qneg_s64(tcg_rd, tcg_env, tcg_rn); |
98 | - } else { | 98 | - } else { |
99 | - gen_helper_neon_qabs_s64(tcg_rd, tcg_env, tcg_rn); | 99 | - gen_helper_neon_qabs_s64(tcg_rd, tcg_env, tcg_rn); |
100 | - } | 100 | - } |
101 | - break; | 101 | - break; |
102 | case 0xa: /* CMLT */ | 102 | case 0xa: /* CMLT */ |
103 | cond = TCG_COND_LT; | 103 | cond = TCG_COND_LT; |
104 | do_cmop: | 104 | do_cmop: |
105 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 105 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
106 | gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus); | 106 | gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus); |
107 | break; | 107 | break; |
108 | default: | 108 | default: |
109 | + case 0x7: /* SQABS, SQNEG */ | 109 | + case 0x7: /* SQABS, SQNEG */ |
110 | g_assert_not_reached(); | 110 | g_assert_not_reached(); |
111 | } | 111 | } |
112 | } | 112 | } |
113 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 113 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
114 | TCGv_ptr tcg_fpstatus; | 114 | TCGv_ptr tcg_fpstatus; |
115 | 115 | ||
116 | switch (opcode) { | 116 | switch (opcode) { |
117 | - case 0x7: /* SQABS / SQNEG */ | 117 | - case 0x7: /* SQABS / SQNEG */ |
118 | - break; | 118 | - break; |
119 | case 0xa: /* CMLT */ | 119 | case 0xa: /* CMLT */ |
120 | if (u) { | 120 | if (u) { |
121 | unallocated_encoding(s); | 121 | unallocated_encoding(s); |
122 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 122 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
123 | break; | 123 | break; |
124 | default: | 124 | default: |
125 | case 0x3: /* USQADD / SUQADD */ | 125 | case 0x3: /* USQADD / SUQADD */ |
126 | + case 0x7: /* SQABS / SQNEG */ | 126 | + case 0x7: /* SQABS / SQNEG */ |
127 | unallocated_encoding(s); | 127 | unallocated_encoding(s); |
128 | return; | 128 | return; |
129 | } | 129 | } |
130 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 130 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
131 | read_vec_element_i32(s, tcg_rn, rn, 0, size); | 131 | read_vec_element_i32(s, tcg_rn, rn, 0, size); |
132 | 132 | ||
133 | switch (opcode) { | 133 | switch (opcode) { |
134 | - case 0x7: /* SQABS, SQNEG */ | 134 | - case 0x7: /* SQABS, SQNEG */ |
135 | - { | 135 | - { |
136 | - NeonGenOneOpEnvFn *genfn; | 136 | - NeonGenOneOpEnvFn *genfn; |
137 | - static NeonGenOneOpEnvFn * const fns[3][2] = { | 137 | - static NeonGenOneOpEnvFn * const fns[3][2] = { |
138 | - { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 }, | 138 | - { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 }, |
139 | - { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 }, | 139 | - { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 }, |
140 | - { gen_helper_neon_qabs_s32, gen_helper_neon_qneg_s32 }, | 140 | - { gen_helper_neon_qabs_s32, gen_helper_neon_qneg_s32 }, |
141 | - }; | 141 | - }; |
142 | - genfn = fns[size][u]; | 142 | - genfn = fns[size][u]; |
143 | - genfn(tcg_rd, tcg_env, tcg_rn); | 143 | - genfn(tcg_rd, tcg_env, tcg_rn); |
144 | - break; | 144 | - break; |
145 | - } | 145 | - } |
146 | case 0x1a: /* FCVTNS */ | 146 | case 0x1a: /* FCVTNS */ |
147 | case 0x1b: /* FCVTMS */ | 147 | case 0x1b: /* FCVTMS */ |
148 | case 0x1c: /* FCVTAS */ | 148 | case 0x1c: /* FCVTAS */ |
149 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 149 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
150 | tcg_fpstatus); | 150 | tcg_fpstatus); |
151 | break; | 151 | break; |
152 | default: | 152 | default: |
153 | + case 0x7: /* SQABS, SQNEG */ | 153 | + case 0x7: /* SQABS, SQNEG */ |
154 | g_assert_not_reached(); | 154 | g_assert_not_reached(); |
155 | } | 155 | } |
156 | 156 | ||
157 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 157 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
158 | return; | 158 | return; |
159 | } | 159 | } |
160 | break; | 160 | break; |
161 | - case 0x7: /* SQABS, SQNEG */ | 161 | - case 0x7: /* SQABS, SQNEG */ |
162 | - if (size == 3 && !is_q) { | 162 | - if (size == 3 && !is_q) { |
163 | - unallocated_encoding(s); | 163 | - unallocated_encoding(s); |
164 | - return; | 164 | - return; |
165 | - } | 165 | - } |
166 | - break; | 166 | - break; |
167 | case 0xc ... 0xf: | 167 | case 0xc ... 0xf: |
168 | case 0x16 ... 0x1f: | 168 | case 0x16 ... 0x1f: |
169 | { | 169 | { |
170 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 170 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
171 | } | 171 | } |
172 | default: | 172 | default: |
173 | case 0x3: /* SUQADD, USQADD */ | 173 | case 0x3: /* SUQADD, USQADD */ |
174 | + case 0x7: /* SQABS, SQNEG */ | 174 | + case 0x7: /* SQABS, SQNEG */ |
175 | unallocated_encoding(s); | 175 | unallocated_encoding(s); |
176 | return; | 176 | return; |
177 | } | 177 | } |
178 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 178 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
179 | tcg_gen_clrsb_i32(tcg_res, tcg_op); | 179 | tcg_gen_clrsb_i32(tcg_res, tcg_op); |
180 | } | 180 | } |
181 | break; | 181 | break; |
182 | - case 0x7: /* SQABS, SQNEG */ | 182 | - case 0x7: /* SQABS, SQNEG */ |
183 | - if (u) { | 183 | - if (u) { |
184 | - gen_helper_neon_qneg_s32(tcg_res, tcg_env, tcg_op); | 184 | - gen_helper_neon_qneg_s32(tcg_res, tcg_env, tcg_op); |
185 | - } else { | 185 | - } else { |
186 | - gen_helper_neon_qabs_s32(tcg_res, tcg_env, tcg_op); | 186 | - gen_helper_neon_qabs_s32(tcg_res, tcg_env, tcg_op); |
187 | - } | 187 | - } |
188 | - break; | 188 | - break; |
189 | case 0x2f: /* FABS */ | 189 | case 0x2f: /* FABS */ |
190 | gen_vfp_abss(tcg_res, tcg_op); | 190 | gen_vfp_abss(tcg_res, tcg_op); |
191 | break; | 191 | break; |
192 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 192 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
193 | gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus); | 193 | gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus); |
194 | break; | 194 | break; |
195 | default: | 195 | default: |
196 | + case 0x7: /* SQABS, SQNEG */ | 196 | + case 0x7: /* SQABS, SQNEG */ |
197 | g_assert_not_reached(); | 197 | g_assert_not_reached(); |
198 | } | 198 | } |
199 | } else { | 199 | } else { |
200 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 200 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
201 | gen_helper_neon_cnt_u8(tcg_res, tcg_op); | 201 | gen_helper_neon_cnt_u8(tcg_res, tcg_op); |
202 | } | 202 | } |
203 | break; | 203 | break; |
204 | - case 0x7: /* SQABS, SQNEG */ | 204 | - case 0x7: /* SQABS, SQNEG */ |
205 | - { | 205 | - { |
206 | - NeonGenOneOpEnvFn *genfn; | 206 | - NeonGenOneOpEnvFn *genfn; |
207 | - static NeonGenOneOpEnvFn * const fns[2][2] = { | 207 | - static NeonGenOneOpEnvFn * const fns[2][2] = { |
208 | - { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 }, | 208 | - { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 }, |
209 | - { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 }, | 209 | - { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 }, |
210 | - }; | 210 | - }; |
211 | - genfn = fns[size][u]; | 211 | - genfn = fns[size][u]; |
212 | - genfn(tcg_res, tcg_env, tcg_op); | 212 | - genfn(tcg_res, tcg_env, tcg_op); |
213 | - break; | 213 | - break; |
214 | - } | 214 | - } |
215 | case 0x4: /* CLS, CLZ */ | 215 | case 0x4: /* CLS, CLZ */ |
216 | if (u) { | 216 | if (u) { |
217 | if (size == 0) { | 217 | if (size == 0) { |
218 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 218 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
219 | } | 219 | } |
220 | break; | 220 | break; |
221 | default: | 221 | default: |
222 | + case 0x7: /* SQABS, SQNEG */ | 222 | + case 0x7: /* SQABS, SQNEG */ |
223 | g_assert_not_reached(); | 223 | g_assert_not_reached(); |
224 | } | 224 | } |
225 | } | 225 | } |
226 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 226 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
227 | index XXXXXXX..XXXXXXX 100644 | 227 | index XXXXXXX..XXXXXXX 100644 |
228 | --- a/target/arm/tcg/a64.decode | 228 | --- a/target/arm/tcg/a64.decode |
229 | +++ b/target/arm/tcg/a64.decode | 229 | +++ b/target/arm/tcg/a64.decode |
230 | @@ -XXX,XX +XXX,XX @@ | 230 | @@ -XXX,XX +XXX,XX @@ |
231 | @rr_h ........ ... ..... ...... rn:5 rd:5 &rr_e esz=1 | 231 | @rr_h ........ ... ..... ...... rn:5 rd:5 &rr_e esz=1 |
232 | @rr_s ........ ... ..... ...... rn:5 rd:5 &rr_e esz=2 | 232 | @rr_s ........ ... ..... ...... rn:5 rd:5 &rr_e esz=2 |
233 | @rr_d ........ ... ..... ...... rn:5 rd:5 &rr_e esz=3 | 233 | @rr_d ........ ... ..... ...... rn:5 rd:5 &rr_e esz=3 |
234 | +@rr_e ........ esz:2 . ..... ...... rn:5 rd:5 &rr_e | 234 | +@rr_e ........ esz:2 . ..... ...... rn:5 rd:5 &rr_e |
235 | @rr_sd ........ ... ..... ...... rn:5 rd:5 &rr_e esz=%esz_sd | 235 | @rr_sd ........ ... ..... ...... rn:5 rd:5 &rr_e esz=%esz_sd |
236 | @rr_hsd ........ ... ..... ...... rn:5 rd:5 &rr_e esz=%esz_hsd | 236 | @rr_hsd ........ ... ..... ...... rn:5 rd:5 &rr_e esz=%esz_hsd |
237 | 237 | ||
238 | @@ -XXX,XX +XXX,XX @@ UQRSHRN_si 0111 11110 .... ... 10011 1 ..... ..... @shri_s | 238 | @@ -XXX,XX +XXX,XX @@ UQRSHRN_si 0111 11110 .... ... 10011 1 ..... ..... @shri_s |
239 | SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_b | 239 | SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_b |
240 | SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_h | 240 | SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_h |
241 | SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_s | 241 | SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_s |
242 | + | 242 | + |
243 | +# Advanced SIMD scalar two-register miscellaneous | 243 | +# Advanced SIMD scalar two-register miscellaneous |
244 | + | 244 | + |
245 | +SQABS_s 0101 1110 ..1 00000 01111 0 ..... ..... @rr_e | 245 | +SQABS_s 0101 1110 ..1 00000 01111 0 ..... ..... @rr_e |
246 | +SQNEG_s 0111 1110 ..1 00000 01111 0 ..... ..... @rr_e | 246 | +SQNEG_s 0111 1110 ..1 00000 01111 0 ..... ..... @rr_e |
247 | + | 247 | + |
248 | +# Advanced SIMD two-register miscellaneous | 248 | +# Advanced SIMD two-register miscellaneous |
249 | + | 249 | + |
250 | +SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 250 | +SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
251 | +SQNEG_v 0.10 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 251 | +SQNEG_v 0.10 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
252 | -- | 252 | -- |
253 | 2.43.0 | 253 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 46 +++++++++++++++++++++++----------- | 4 | target/arm/tcg/translate-a64.c | 46 +++++++++++++++++++++++----------- |
5 | target/arm/tcg/a64.decode | 4 +++ | 5 | target/arm/tcg/a64.decode | 4 +++ |
6 | 2 files changed, 35 insertions(+), 15 deletions(-) | 6 | 2 files changed, 35 insertions(+), 15 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static const ENVScalar1 f_scalar_sqneg = { | 12 | @@ -XXX,XX +XXX,XX @@ static const ENVScalar1 f_scalar_sqneg = { |
13 | TRANS(SQNEG_s, do_env_scalar1, a, &f_scalar_sqneg) | 13 | TRANS(SQNEG_s, do_env_scalar1, a, &f_scalar_sqneg) |
14 | TRANS(SQNEG_v, do_env_vector1, a, &f_scalar_sqneg) | 14 | TRANS(SQNEG_v, do_env_vector1, a, &f_scalar_sqneg) |
15 | 15 | ||
16 | +static bool do_scalar1_d(DisasContext *s, arg_rr *a, ArithOneOp *f) | 16 | +static bool do_scalar1_d(DisasContext *s, arg_rr *a, ArithOneOp *f) |
17 | +{ | 17 | +{ |
18 | + if (fp_access_check(s)) { | 18 | + if (fp_access_check(s)) { |
19 | + TCGv_i64 t = read_fp_dreg(s, a->rn); | 19 | + TCGv_i64 t = read_fp_dreg(s, a->rn); |
20 | + f(t, t); | 20 | + f(t, t); |
21 | + write_fp_dreg(s, a->rd, t); | 21 | + write_fp_dreg(s, a->rd, t); |
22 | + } | 22 | + } |
23 | + return true; | 23 | + return true; |
24 | +} | 24 | +} |
25 | + | 25 | + |
26 | +TRANS(ABS_s, do_scalar1_d, a, tcg_gen_abs_i64) | 26 | +TRANS(ABS_s, do_scalar1_d, a, tcg_gen_abs_i64) |
27 | +TRANS(NEG_s, do_scalar1_d, a, tcg_gen_neg_i64) | 27 | +TRANS(NEG_s, do_scalar1_d, a, tcg_gen_neg_i64) |
28 | + | 28 | + |
29 | +static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 29 | +static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
30 | +{ | 30 | +{ |
31 | + if (!a->q && a->esz == MO_64) { | 31 | + if (!a->q && a->esz == MO_64) { |
32 | + return false; | 32 | + return false; |
33 | + } | 33 | + } |
34 | + if (fp_access_check(s)) { | 34 | + if (fp_access_check(s)) { |
35 | + gen_gvec_fn2(s, a->q, a->rd, a->rn, fn, a->esz); | 35 | + gen_gvec_fn2(s, a->q, a->rd, a->rn, fn, a->esz); |
36 | + } | 36 | + } |
37 | + return true; | 37 | + return true; |
38 | +} | 38 | +} |
39 | + | 39 | + |
40 | +TRANS(ABS_v, do_gvec_fn2, a, tcg_gen_gvec_abs) | 40 | +TRANS(ABS_v, do_gvec_fn2, a, tcg_gen_gvec_abs) |
41 | +TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) | 41 | +TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) |
42 | + | 42 | + |
43 | /* Common vector code for handling integer to FP conversion */ | 43 | /* Common vector code for handling integer to FP conversion */ |
44 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 44 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
45 | int elements, int is_signed, | 45 | int elements, int is_signed, |
46 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 46 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
47 | case 0x9: /* CMEQ, CMLE */ | 47 | case 0x9: /* CMEQ, CMLE */ |
48 | cond = u ? TCG_COND_LE : TCG_COND_EQ; | 48 | cond = u ? TCG_COND_LE : TCG_COND_EQ; |
49 | goto do_cmop; | 49 | goto do_cmop; |
50 | - case 0xb: /* ABS, NEG */ | 50 | - case 0xb: /* ABS, NEG */ |
51 | - if (u) { | 51 | - if (u) { |
52 | - tcg_gen_neg_i64(tcg_rd, tcg_rn); | 52 | - tcg_gen_neg_i64(tcg_rd, tcg_rn); |
53 | - } else { | 53 | - } else { |
54 | - tcg_gen_abs_i64(tcg_rd, tcg_rn); | 54 | - tcg_gen_abs_i64(tcg_rd, tcg_rn); |
55 | - } | 55 | - } |
56 | - break; | 56 | - break; |
57 | case 0x2f: /* FABS */ | 57 | case 0x2f: /* FABS */ |
58 | gen_vfp_absd(tcg_rd, tcg_rn); | 58 | gen_vfp_absd(tcg_rd, tcg_rn); |
59 | break; | 59 | break; |
60 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 60 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
61 | break; | 61 | break; |
62 | default: | 62 | default: |
63 | case 0x7: /* SQABS, SQNEG */ | 63 | case 0x7: /* SQABS, SQNEG */ |
64 | + case 0xb: /* ABS, NEG */ | 64 | + case 0xb: /* ABS, NEG */ |
65 | g_assert_not_reached(); | 65 | g_assert_not_reached(); |
66 | } | 66 | } |
67 | } | 67 | } |
68 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 68 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
69 | /* fall through */ | 69 | /* fall through */ |
70 | case 0x8: /* CMGT, CMGE */ | 70 | case 0x8: /* CMGT, CMGE */ |
71 | case 0x9: /* CMEQ, CMLE */ | 71 | case 0x9: /* CMEQ, CMLE */ |
72 | - case 0xb: /* ABS, NEG */ | 72 | - case 0xb: /* ABS, NEG */ |
73 | if (size != 3) { | 73 | if (size != 3) { |
74 | unallocated_encoding(s); | 74 | unallocated_encoding(s); |
75 | return; | 75 | return; |
76 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 76 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
77 | default: | 77 | default: |
78 | case 0x3: /* USQADD / SUQADD */ | 78 | case 0x3: /* USQADD / SUQADD */ |
79 | case 0x7: /* SQABS / SQNEG */ | 79 | case 0x7: /* SQABS / SQNEG */ |
80 | + case 0xb: /* ABS, NEG */ | 80 | + case 0xb: /* ABS, NEG */ |
81 | unallocated_encoding(s); | 81 | unallocated_encoding(s); |
82 | return; | 82 | return; |
83 | } | 83 | } |
84 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 84 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
85 | /* fall through */ | 85 | /* fall through */ |
86 | case 0x8: /* CMGT, CMGE */ | 86 | case 0x8: /* CMGT, CMGE */ |
87 | case 0x9: /* CMEQ, CMLE */ | 87 | case 0x9: /* CMEQ, CMLE */ |
88 | - case 0xb: /* ABS, NEG */ | 88 | - case 0xb: /* ABS, NEG */ |
89 | if (size == 3 && !is_q) { | 89 | if (size == 3 && !is_q) { |
90 | unallocated_encoding(s); | 90 | unallocated_encoding(s); |
91 | return; | 91 | return; |
92 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 92 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
93 | default: | 93 | default: |
94 | case 0x3: /* SUQADD, USQADD */ | 94 | case 0x3: /* SUQADD, USQADD */ |
95 | case 0x7: /* SQABS, SQNEG */ | 95 | case 0x7: /* SQABS, SQNEG */ |
96 | + case 0xb: /* ABS, NEG */ | 96 | + case 0xb: /* ABS, NEG */ |
97 | unallocated_encoding(s); | 97 | unallocated_encoding(s); |
98 | return; | 98 | return; |
99 | } | 99 | } |
100 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 100 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
101 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); | 101 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); |
102 | return; | 102 | return; |
103 | case 0xb: | 103 | case 0xb: |
104 | - if (u) { /* ABS, NEG */ | 104 | - if (u) { /* ABS, NEG */ |
105 | - gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size); | 105 | - gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size); |
106 | - } else { | 106 | - } else { |
107 | - gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_abs, size); | 107 | - gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_abs, size); |
108 | - } | 108 | - } |
109 | - return; | 109 | - return; |
110 | + g_assert_not_reached(); | 110 | + g_assert_not_reached(); |
111 | } | 111 | } |
112 | 112 | ||
113 | if (size == 3) { | 113 | if (size == 3) { |
114 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 114 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
115 | index XXXXXXX..XXXXXXX 100644 | 115 | index XXXXXXX..XXXXXXX 100644 |
116 | --- a/target/arm/tcg/a64.decode | 116 | --- a/target/arm/tcg/a64.decode |
117 | +++ b/target/arm/tcg/a64.decode | 117 | +++ b/target/arm/tcg/a64.decode |
118 | @@ -XXX,XX +XXX,XX @@ SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_s | 118 | @@ -XXX,XX +XXX,XX @@ SQRSHRUN_si 0111 11110 .... ... 10001 1 ..... ..... @shri_s |
119 | 119 | ||
120 | SQABS_s 0101 1110 ..1 00000 01111 0 ..... ..... @rr_e | 120 | SQABS_s 0101 1110 ..1 00000 01111 0 ..... ..... @rr_e |
121 | SQNEG_s 0111 1110 ..1 00000 01111 0 ..... ..... @rr_e | 121 | SQNEG_s 0111 1110 ..1 00000 01111 0 ..... ..... @rr_e |
122 | +ABS_s 0101 1110 111 00000 10111 0 ..... ..... @rr | 122 | +ABS_s 0101 1110 111 00000 10111 0 ..... ..... @rr |
123 | +NEG_s 0111 1110 111 00000 10111 0 ..... ..... @rr | 123 | +NEG_s 0111 1110 111 00000 10111 0 ..... ..... @rr |
124 | 124 | ||
125 | # Advanced SIMD two-register miscellaneous | 125 | # Advanced SIMD two-register miscellaneous |
126 | 126 | ||
127 | SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 127 | SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
128 | SQNEG_v 0.10 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 128 | SQNEG_v 0.10 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
129 | +ABS_v 0.00 1110 ..1 00000 10111 0 ..... ..... @qrr_e | 129 | +ABS_v 0.00 1110 ..1 00000 10111 0 ..... ..... @qrr_e |
130 | +NEG_v 0.10 1110 ..1 00000 10111 0 ..... ..... @qrr_e | 130 | +NEG_v 0.10 1110 ..1 00000 10111 0 ..... ..... @qrr_e |
131 | -- | 131 | -- |
132 | 2.43.0 | 132 | 2.43.0 | diff view generated by jsdifflib |
1 | Add gvec interfaces for CLS and CLZ operations. | 1 | Add gvec interfaces for CLS and CLZ operations. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 3 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/tcg/translate.h | 5 +++++ | 6 | target/arm/tcg/translate.h | 5 +++++ |
7 | target/arm/tcg/gengvec.c | 35 +++++++++++++++++++++++++++++++++ | 7 | target/arm/tcg/gengvec.c | 35 +++++++++++++++++++++++++++++++++ |
8 | target/arm/tcg/translate-a64.c | 29 +++++++-------------------- | 8 | target/arm/tcg/translate-a64.c | 29 +++++++-------------------- |
9 | target/arm/tcg/translate-neon.c | 29 ++------------------------- | 9 | target/arm/tcg/translate-neon.c | 29 ++------------------------- |
10 | 4 files changed, 49 insertions(+), 49 deletions(-) | 10 | 4 files changed, 49 insertions(+), 49 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h | 12 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/tcg/translate.h | 14 | --- a/target/arm/tcg/translate.h |
15 | +++ b/target/arm/tcg/translate.h | 15 | +++ b/target/arm/tcg/translate.h |
16 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_umaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 16 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_umaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
17 | void gen_gvec_uminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 17 | void gen_gvec_uminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
18 | uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz); | 18 | uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz); |
19 | 19 | ||
20 | +void gen_gvec_cls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 20 | +void gen_gvec_cls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
21 | + uint32_t opr_sz, uint32_t max_sz); | 21 | + uint32_t opr_sz, uint32_t max_sz); |
22 | +void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 22 | +void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
23 | + uint32_t opr_sz, uint32_t max_sz); | 23 | + uint32_t opr_sz, uint32_t max_sz); |
24 | + | 24 | + |
25 | /* | 25 | /* |
26 | * Forward to the isar_feature_* tests given a DisasContext pointer. | 26 | * Forward to the isar_feature_* tests given a DisasContext pointer. |
27 | */ | 27 | */ |
28 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c | 28 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c |
29 | index XXXXXXX..XXXXXXX 100644 | 29 | index XXXXXXX..XXXXXXX 100644 |
30 | --- a/target/arm/tcg/gengvec.c | 30 | --- a/target/arm/tcg/gengvec.c |
31 | +++ b/target/arm/tcg/gengvec.c | 31 | +++ b/target/arm/tcg/gengvec.c |
32 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_urhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 32 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_urhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
33 | assert(vece <= MO_32); | 33 | assert(vece <= MO_32); |
34 | tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &g[vece]); | 34 | tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &g[vece]); |
35 | } | 35 | } |
36 | + | 36 | + |
37 | +void gen_gvec_cls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 37 | +void gen_gvec_cls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
38 | + uint32_t opr_sz, uint32_t max_sz) | 38 | + uint32_t opr_sz, uint32_t max_sz) |
39 | +{ | 39 | +{ |
40 | + static const GVecGen2 g[] = { | 40 | + static const GVecGen2 g[] = { |
41 | + { .fni4 = gen_helper_neon_cls_s8, | 41 | + { .fni4 = gen_helper_neon_cls_s8, |
42 | + .vece = MO_8 }, | 42 | + .vece = MO_8 }, |
43 | + { .fni4 = gen_helper_neon_cls_s16, | 43 | + { .fni4 = gen_helper_neon_cls_s16, |
44 | + .vece = MO_16 }, | 44 | + .vece = MO_16 }, |
45 | + { .fni4 = tcg_gen_clrsb_i32, | 45 | + { .fni4 = tcg_gen_clrsb_i32, |
46 | + .vece = MO_32 }, | 46 | + .vece = MO_32 }, |
47 | + }; | 47 | + }; |
48 | + assert(vece <= MO_32); | 48 | + assert(vece <= MO_32); |
49 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 49 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
50 | +} | 50 | +} |
51 | + | 51 | + |
52 | +static void gen_clz32_i32(TCGv_i32 d, TCGv_i32 n) | 52 | +static void gen_clz32_i32(TCGv_i32 d, TCGv_i32 n) |
53 | +{ | 53 | +{ |
54 | + tcg_gen_clzi_i32(d, n, 32); | 54 | + tcg_gen_clzi_i32(d, n, 32); |
55 | +} | 55 | +} |
56 | + | 56 | + |
57 | +void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 57 | +void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
58 | + uint32_t opr_sz, uint32_t max_sz) | 58 | + uint32_t opr_sz, uint32_t max_sz) |
59 | +{ | 59 | +{ |
60 | + static const GVecGen2 g[] = { | 60 | + static const GVecGen2 g[] = { |
61 | + { .fni4 = gen_helper_neon_clz_u8, | 61 | + { .fni4 = gen_helper_neon_clz_u8, |
62 | + .vece = MO_8 }, | 62 | + .vece = MO_8 }, |
63 | + { .fni4 = gen_helper_neon_clz_u16, | 63 | + { .fni4 = gen_helper_neon_clz_u16, |
64 | + .vece = MO_16 }, | 64 | + .vece = MO_16 }, |
65 | + { .fni4 = gen_clz32_i32, | 65 | + { .fni4 = gen_clz32_i32, |
66 | + .vece = MO_32 }, | 66 | + .vece = MO_32 }, |
67 | + }; | 67 | + }; |
68 | + assert(vece <= MO_32); | 68 | + assert(vece <= MO_32); |
69 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 69 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
70 | +} | 70 | +} |
71 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 71 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
72 | index XXXXXXX..XXXXXXX 100644 | 72 | index XXXXXXX..XXXXXXX 100644 |
73 | --- a/target/arm/tcg/translate-a64.c | 73 | --- a/target/arm/tcg/translate-a64.c |
74 | +++ b/target/arm/tcg/translate-a64.c | 74 | +++ b/target/arm/tcg/translate-a64.c |
75 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 75 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
76 | } | 76 | } |
77 | 77 | ||
78 | switch (opcode) { | 78 | switch (opcode) { |
79 | + case 0x4: /* CLZ, CLS */ | 79 | + case 0x4: /* CLZ, CLS */ |
80 | + if (u) { | 80 | + if (u) { |
81 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clz, size); | 81 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clz, size); |
82 | + } else { | 82 | + } else { |
83 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cls, size); | 83 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cls, size); |
84 | + } | 84 | + } |
85 | + return; | 85 | + return; |
86 | case 0x5: | 86 | case 0x5: |
87 | if (u && size == 0) { /* NOT */ | 87 | if (u && size == 0) { /* NOT */ |
88 | gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); | 88 | gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); |
89 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 89 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
90 | if (size == 2) { | 90 | if (size == 2) { |
91 | /* Special cases for 32 bit elements */ | 91 | /* Special cases for 32 bit elements */ |
92 | switch (opcode) { | 92 | switch (opcode) { |
93 | - case 0x4: /* CLS */ | 93 | - case 0x4: /* CLS */ |
94 | - if (u) { | 94 | - if (u) { |
95 | - tcg_gen_clzi_i32(tcg_res, tcg_op, 32); | 95 | - tcg_gen_clzi_i32(tcg_res, tcg_op, 32); |
96 | - } else { | 96 | - } else { |
97 | - tcg_gen_clrsb_i32(tcg_res, tcg_op); | 97 | - tcg_gen_clrsb_i32(tcg_res, tcg_op); |
98 | - } | 98 | - } |
99 | - break; | 99 | - break; |
100 | case 0x2f: /* FABS */ | 100 | case 0x2f: /* FABS */ |
101 | gen_vfp_abss(tcg_res, tcg_op); | 101 | gen_vfp_abss(tcg_res, tcg_op); |
102 | break; | 102 | break; |
103 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 103 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
104 | gen_helper_neon_cnt_u8(tcg_res, tcg_op); | 104 | gen_helper_neon_cnt_u8(tcg_res, tcg_op); |
105 | } | 105 | } |
106 | break; | 106 | break; |
107 | - case 0x4: /* CLS, CLZ */ | 107 | - case 0x4: /* CLS, CLZ */ |
108 | - if (u) { | 108 | - if (u) { |
109 | - if (size == 0) { | 109 | - if (size == 0) { |
110 | - gen_helper_neon_clz_u8(tcg_res, tcg_op); | 110 | - gen_helper_neon_clz_u8(tcg_res, tcg_op); |
111 | - } else { | 111 | - } else { |
112 | - gen_helper_neon_clz_u16(tcg_res, tcg_op); | 112 | - gen_helper_neon_clz_u16(tcg_res, tcg_op); |
113 | - } | 113 | - } |
114 | - } else { | 114 | - } else { |
115 | - if (size == 0) { | 115 | - if (size == 0) { |
116 | - gen_helper_neon_cls_s8(tcg_res, tcg_op); | 116 | - gen_helper_neon_cls_s8(tcg_res, tcg_op); |
117 | - } else { | 117 | - } else { |
118 | - gen_helper_neon_cls_s16(tcg_res, tcg_op); | 118 | - gen_helper_neon_cls_s16(tcg_res, tcg_op); |
119 | - } | 119 | - } |
120 | - } | 120 | - } |
121 | - break; | 121 | - break; |
122 | default: | 122 | default: |
123 | case 0x7: /* SQABS, SQNEG */ | 123 | case 0x7: /* SQABS, SQNEG */ |
124 | g_assert_not_reached(); | 124 | g_assert_not_reached(); |
125 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c | 125 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c |
126 | index XXXXXXX..XXXXXXX 100644 | 126 | index XXXXXXX..XXXXXXX 100644 |
127 | --- a/target/arm/tcg/translate-neon.c | 127 | --- a/target/arm/tcg/translate-neon.c |
128 | +++ b/target/arm/tcg/translate-neon.c | 128 | +++ b/target/arm/tcg/translate-neon.c |
129 | @@ -XXX,XX +XXX,XX @@ DO_2MISC_VEC(VCGT0, gen_gvec_cgt0) | 129 | @@ -XXX,XX +XXX,XX @@ DO_2MISC_VEC(VCGT0, gen_gvec_cgt0) |
130 | DO_2MISC_VEC(VCLE0, gen_gvec_cle0) | 130 | DO_2MISC_VEC(VCLE0, gen_gvec_cle0) |
131 | DO_2MISC_VEC(VCGE0, gen_gvec_cge0) | 131 | DO_2MISC_VEC(VCGE0, gen_gvec_cge0) |
132 | DO_2MISC_VEC(VCLT0, gen_gvec_clt0) | 132 | DO_2MISC_VEC(VCLT0, gen_gvec_clt0) |
133 | +DO_2MISC_VEC(VCLS, gen_gvec_cls) | 133 | +DO_2MISC_VEC(VCLS, gen_gvec_cls) |
134 | +DO_2MISC_VEC(VCLZ, gen_gvec_clz) | 134 | +DO_2MISC_VEC(VCLZ, gen_gvec_clz) |
135 | 135 | ||
136 | static bool trans_VMVN(DisasContext *s, arg_2misc *a) | 136 | static bool trans_VMVN(DisasContext *s, arg_2misc *a) |
137 | { | 137 | { |
138 | @@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a) | 138 | @@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a) |
139 | return do_2misc(s, a, gen_rev16); | 139 | return do_2misc(s, a, gen_rev16); |
140 | } | 140 | } |
141 | 141 | ||
142 | -static bool trans_VCLS(DisasContext *s, arg_2misc *a) | 142 | -static bool trans_VCLS(DisasContext *s, arg_2misc *a) |
143 | -{ | 143 | -{ |
144 | - static NeonGenOneOpFn * const fn[] = { | 144 | - static NeonGenOneOpFn * const fn[] = { |
145 | - gen_helper_neon_cls_s8, | 145 | - gen_helper_neon_cls_s8, |
146 | - gen_helper_neon_cls_s16, | 146 | - gen_helper_neon_cls_s16, |
147 | - gen_helper_neon_cls_s32, | 147 | - gen_helper_neon_cls_s32, |
148 | - NULL, | 148 | - NULL, |
149 | - }; | 149 | - }; |
150 | - return do_2misc(s, a, fn[a->size]); | 150 | - return do_2misc(s, a, fn[a->size]); |
151 | -} | 151 | -} |
152 | - | 152 | - |
153 | -static void do_VCLZ_32(TCGv_i32 rd, TCGv_i32 rm) | 153 | -static void do_VCLZ_32(TCGv_i32 rd, TCGv_i32 rm) |
154 | -{ | 154 | -{ |
155 | - tcg_gen_clzi_i32(rd, rm, 32); | 155 | - tcg_gen_clzi_i32(rd, rm, 32); |
156 | -} | 156 | -} |
157 | - | 157 | - |
158 | -static bool trans_VCLZ(DisasContext *s, arg_2misc *a) | 158 | -static bool trans_VCLZ(DisasContext *s, arg_2misc *a) |
159 | -{ | 159 | -{ |
160 | - static NeonGenOneOpFn * const fn[] = { | 160 | - static NeonGenOneOpFn * const fn[] = { |
161 | - gen_helper_neon_clz_u8, | 161 | - gen_helper_neon_clz_u8, |
162 | - gen_helper_neon_clz_u16, | 162 | - gen_helper_neon_clz_u16, |
163 | - do_VCLZ_32, | 163 | - do_VCLZ_32, |
164 | - NULL, | 164 | - NULL, |
165 | - }; | 165 | - }; |
166 | - return do_2misc(s, a, fn[a->size]); | 166 | - return do_2misc(s, a, fn[a->size]); |
167 | -} | 167 | -} |
168 | - | 168 | - |
169 | static bool trans_VCNT(DisasContext *s, arg_2misc *a) | 169 | static bool trans_VCNT(DisasContext *s, arg_2misc *a) |
170 | { | 170 | { |
171 | if (a->size != 0) { | 171 | if (a->size != 0) { |
172 | -- | 172 | -- |
173 | 2.43.0 | 173 | 2.43.0 |
174 | 174 | ||
175 | 175 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 37 ++++++++++++++++------------------ | 4 | target/arm/tcg/translate-a64.c | 37 ++++++++++++++++------------------ |
5 | target/arm/tcg/a64.decode | 2 ++ | 5 | target/arm/tcg/a64.decode | 2 ++ |
6 | 2 files changed, 19 insertions(+), 20 deletions(-) | 6 | 2 files changed, 19 insertions(+), 20 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 12 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
13 | TRANS(ABS_v, do_gvec_fn2, a, tcg_gen_gvec_abs) | 13 | TRANS(ABS_v, do_gvec_fn2, a, tcg_gen_gvec_abs) |
14 | TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) | 14 | TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) |
15 | 15 | ||
16 | +static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 16 | +static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
17 | +{ | 17 | +{ |
18 | + if (a->esz == MO_64) { | 18 | + if (a->esz == MO_64) { |
19 | + return false; | 19 | + return false; |
20 | + } | 20 | + } |
21 | + if (fp_access_check(s)) { | 21 | + if (fp_access_check(s)) { |
22 | + gen_gvec_fn2(s, a->q, a->rd, a->rn, fn, a->esz); | 22 | + gen_gvec_fn2(s, a->q, a->rd, a->rn, fn, a->esz); |
23 | + } | 23 | + } |
24 | + return true; | 24 | + return true; |
25 | +} | 25 | +} |
26 | + | 26 | + |
27 | +TRANS(CLS_v, do_gvec_fn2_bhs, a, gen_gvec_cls) | 27 | +TRANS(CLS_v, do_gvec_fn2_bhs, a, gen_gvec_cls) |
28 | +TRANS(CLZ_v, do_gvec_fn2_bhs, a, gen_gvec_clz) | 28 | +TRANS(CLZ_v, do_gvec_fn2_bhs, a, gen_gvec_clz) |
29 | + | 29 | + |
30 | /* Common vector code for handling integer to FP conversion */ | 30 | /* Common vector code for handling integer to FP conversion */ |
31 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 31 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
32 | int elements, int is_signed, | 32 | int elements, int is_signed, |
33 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 33 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
34 | TCGCond cond; | 34 | TCGCond cond; |
35 | 35 | ||
36 | switch (opcode) { | 36 | switch (opcode) { |
37 | - case 0x4: /* CLS, CLZ */ | 37 | - case 0x4: /* CLS, CLZ */ |
38 | - if (u) { | 38 | - if (u) { |
39 | - tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64); | 39 | - tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64); |
40 | - } else { | 40 | - } else { |
41 | - tcg_gen_clrsb_i64(tcg_rd, tcg_rn); | 41 | - tcg_gen_clrsb_i64(tcg_rd, tcg_rn); |
42 | - } | 42 | - } |
43 | - break; | 43 | - break; |
44 | case 0x5: /* NOT */ | 44 | case 0x5: /* NOT */ |
45 | /* This opcode is shared with CNT and RBIT but we have earlier | 45 | /* This opcode is shared with CNT and RBIT but we have earlier |
46 | * enforced that size == 3 if and only if this is the NOT insn. | 46 | * enforced that size == 3 if and only if this is the NOT insn. |
47 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 47 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
48 | gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus); | 48 | gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus); |
49 | break; | 49 | break; |
50 | default: | 50 | default: |
51 | + case 0x4: /* CLS, CLZ */ | 51 | + case 0x4: /* CLS, CLZ */ |
52 | case 0x7: /* SQABS, SQNEG */ | 52 | case 0x7: /* SQABS, SQNEG */ |
53 | case 0xb: /* ABS, NEG */ | 53 | case 0xb: /* ABS, NEG */ |
54 | g_assert_not_reached(); | 54 | g_assert_not_reached(); |
55 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 55 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
56 | 56 | ||
57 | handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd); | 57 | handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd); |
58 | return; | 58 | return; |
59 | - case 0x4: /* CLS, CLZ */ | 59 | - case 0x4: /* CLS, CLZ */ |
60 | - if (size == 3) { | 60 | - if (size == 3) { |
61 | - unallocated_encoding(s); | 61 | - unallocated_encoding(s); |
62 | - return; | 62 | - return; |
63 | - } | 63 | - } |
64 | - break; | 64 | - break; |
65 | case 0x2: /* SADDLP, UADDLP */ | 65 | case 0x2: /* SADDLP, UADDLP */ |
66 | case 0x6: /* SADALP, UADALP */ | 66 | case 0x6: /* SADALP, UADALP */ |
67 | if (size == 3) { | 67 | if (size == 3) { |
68 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 68 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
69 | } | 69 | } |
70 | default: | 70 | default: |
71 | case 0x3: /* SUQADD, USQADD */ | 71 | case 0x3: /* SUQADD, USQADD */ |
72 | + case 0x4: /* CLS, CLZ */ | 72 | + case 0x4: /* CLS, CLZ */ |
73 | case 0x7: /* SQABS, SQNEG */ | 73 | case 0x7: /* SQABS, SQNEG */ |
74 | case 0xb: /* ABS, NEG */ | 74 | case 0xb: /* ABS, NEG */ |
75 | unallocated_encoding(s); | 75 | unallocated_encoding(s); |
76 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 76 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
77 | } | 77 | } |
78 | 78 | ||
79 | switch (opcode) { | 79 | switch (opcode) { |
80 | - case 0x4: /* CLZ, CLS */ | 80 | - case 0x4: /* CLZ, CLS */ |
81 | - if (u) { | 81 | - if (u) { |
82 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clz, size); | 82 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clz, size); |
83 | - } else { | 83 | - } else { |
84 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cls, size); | 84 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cls, size); |
85 | - } | 85 | - } |
86 | - return; | 86 | - return; |
87 | case 0x5: | 87 | case 0x5: |
88 | if (u && size == 0) { /* NOT */ | 88 | if (u && size == 0) { /* NOT */ |
89 | gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); | 89 | gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); |
90 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 90 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
91 | case 0xa: /* CMLT */ | 91 | case 0xa: /* CMLT */ |
92 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); | 92 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); |
93 | return; | 93 | return; |
94 | + case 0x4: /* CLZ, CLS */ | 94 | + case 0x4: /* CLZ, CLS */ |
95 | case 0xb: | 95 | case 0xb: |
96 | g_assert_not_reached(); | 96 | g_assert_not_reached(); |
97 | } | 97 | } |
98 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 98 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
99 | index XXXXXXX..XXXXXXX 100644 | 99 | index XXXXXXX..XXXXXXX 100644 |
100 | --- a/target/arm/tcg/a64.decode | 100 | --- a/target/arm/tcg/a64.decode |
101 | +++ b/target/arm/tcg/a64.decode | 101 | +++ b/target/arm/tcg/a64.decode |
102 | @@ -XXX,XX +XXX,XX @@ SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 102 | @@ -XXX,XX +XXX,XX @@ SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
103 | SQNEG_v 0.10 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 103 | SQNEG_v 0.10 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
104 | ABS_v 0.00 1110 ..1 00000 10111 0 ..... ..... @qrr_e | 104 | ABS_v 0.00 1110 ..1 00000 10111 0 ..... ..... @qrr_e |
105 | NEG_v 0.10 1110 ..1 00000 10111 0 ..... ..... @qrr_e | 105 | NEG_v 0.10 1110 ..1 00000 10111 0 ..... ..... @qrr_e |
106 | +CLS_v 0.00 1110 ..1 00000 01001 0 ..... ..... @qrr_e | 106 | +CLS_v 0.00 1110 ..1 00000 01001 0 ..... ..... @qrr_e |
107 | +CLZ_v 0.10 1110 ..1 00000 01001 0 ..... ..... @qrr_e | 107 | +CLZ_v 0.10 1110 ..1 00000 01001 0 ..... ..... @qrr_e |
108 | -- | 108 | -- |
109 | 2.43.0 | 109 | 2.43.0 | diff view generated by jsdifflib |
1 | Add gvec interfaces for CNT and RBIT operations. | 1 | Add gvec interfaces for CNT and RBIT operations. |
---|---|---|---|
2 | Use ctpop8 for CNT and revbit+bswap for RBIT. | 2 | Use ctpop8 for CNT and revbit+bswap for RBIT. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/helper.h | 4 ++-- | 7 | target/arm/helper.h | 4 ++-- |
8 | target/arm/tcg/translate.h | 4 ++++ | 8 | target/arm/tcg/translate.h | 4 ++++ |
9 | target/arm/tcg/gengvec.c | 16 ++++++++++++++++ | 9 | target/arm/tcg/gengvec.c | 16 ++++++++++++++++ |
10 | target/arm/tcg/neon_helper.c | 21 --------------------- | 10 | target/arm/tcg/neon_helper.c | 21 --------------------- |
11 | target/arm/tcg/translate-a64.c | 32 +++++++++----------------------- | 11 | target/arm/tcg/translate-a64.c | 32 +++++++++----------------------- |
12 | target/arm/tcg/translate-neon.c | 16 ++++++++-------- | 12 | target/arm/tcg/translate-neon.c | 16 ++++++++-------- |
13 | target/arm/tcg/vec_helper.c | 24 ++++++++++++++++++++++++ | 13 | target/arm/tcg/vec_helper.c | 24 ++++++++++++++++++++++++ |
14 | 7 files changed, 63 insertions(+), 54 deletions(-) | 14 | 7 files changed, 63 insertions(+), 54 deletions(-) |
15 | 15 | ||
16 | diff --git a/target/arm/helper.h b/target/arm/helper.h | 16 | diff --git a/target/arm/helper.h b/target/arm/helper.h |
17 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/arm/helper.h | 18 | --- a/target/arm/helper.h |
19 | +++ b/target/arm/helper.h | 19 | +++ b/target/arm/helper.h |
20 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(neon_clz_u16, i32, i32) | 20 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(neon_clz_u16, i32, i32) |
21 | DEF_HELPER_1(neon_cls_s8, i32, i32) | 21 | DEF_HELPER_1(neon_cls_s8, i32, i32) |
22 | DEF_HELPER_1(neon_cls_s16, i32, i32) | 22 | DEF_HELPER_1(neon_cls_s16, i32, i32) |
23 | DEF_HELPER_1(neon_cls_s32, i32, i32) | 23 | DEF_HELPER_1(neon_cls_s32, i32, i32) |
24 | -DEF_HELPER_1(neon_cnt_u8, i32, i32) | 24 | -DEF_HELPER_1(neon_cnt_u8, i32, i32) |
25 | -DEF_HELPER_FLAGS_1(neon_rbit_u8, TCG_CALL_NO_RWG_SE, i32, i32) | 25 | -DEF_HELPER_FLAGS_1(neon_rbit_u8, TCG_CALL_NO_RWG_SE, i32, i32) |
26 | +DEF_HELPER_FLAGS_3(gvec_cnt_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32) | 26 | +DEF_HELPER_FLAGS_3(gvec_cnt_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32) |
27 | +DEF_HELPER_FLAGS_3(gvec_rbit_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32) | 27 | +DEF_HELPER_FLAGS_3(gvec_rbit_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32) |
28 | 28 | ||
29 | DEF_HELPER_3(neon_qdmulh_s16, i32, env, i32, i32) | 29 | DEF_HELPER_3(neon_qdmulh_s16, i32, env, i32, i32) |
30 | DEF_HELPER_3(neon_qrdmulh_s16, i32, env, i32, i32) | 30 | DEF_HELPER_3(neon_qrdmulh_s16, i32, env, i32, i32) |
31 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h | 31 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h |
32 | index XXXXXXX..XXXXXXX 100644 | 32 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/target/arm/tcg/translate.h | 33 | --- a/target/arm/tcg/translate.h |
34 | +++ b/target/arm/tcg/translate.h | 34 | +++ b/target/arm/tcg/translate.h |
35 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_cls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 35 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_cls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
36 | uint32_t opr_sz, uint32_t max_sz); | 36 | uint32_t opr_sz, uint32_t max_sz); |
37 | void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 37 | void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
38 | uint32_t opr_sz, uint32_t max_sz); | 38 | uint32_t opr_sz, uint32_t max_sz); |
39 | +void gen_gvec_cnt(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 39 | +void gen_gvec_cnt(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
40 | + uint32_t opr_sz, uint32_t max_sz); | 40 | + uint32_t opr_sz, uint32_t max_sz); |
41 | +void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 41 | +void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
42 | + uint32_t opr_sz, uint32_t max_sz); | 42 | + uint32_t opr_sz, uint32_t max_sz); |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * Forward to the isar_feature_* tests given a DisasContext pointer. | 45 | * Forward to the isar_feature_* tests given a DisasContext pointer. |
46 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c | 46 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c |
47 | index XXXXXXX..XXXXXXX 100644 | 47 | index XXXXXXX..XXXXXXX 100644 |
48 | --- a/target/arm/tcg/gengvec.c | 48 | --- a/target/arm/tcg/gengvec.c |
49 | +++ b/target/arm/tcg/gengvec.c | 49 | +++ b/target/arm/tcg/gengvec.c |
50 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 50 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_clz(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
51 | assert(vece <= MO_32); | 51 | assert(vece <= MO_32); |
52 | tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 52 | tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
53 | } | 53 | } |
54 | + | 54 | + |
55 | +void gen_gvec_cnt(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 55 | +void gen_gvec_cnt(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
56 | + uint32_t opr_sz, uint32_t max_sz) | 56 | + uint32_t opr_sz, uint32_t max_sz) |
57 | +{ | 57 | +{ |
58 | + assert(vece == MO_8); | 58 | + assert(vece == MO_8); |
59 | + tcg_gen_gvec_2_ool(rd_ofs, rn_ofs, opr_sz, max_sz, 0, | 59 | + tcg_gen_gvec_2_ool(rd_ofs, rn_ofs, opr_sz, max_sz, 0, |
60 | + gen_helper_gvec_cnt_b); | 60 | + gen_helper_gvec_cnt_b); |
61 | +} | 61 | +} |
62 | + | 62 | + |
63 | +void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 63 | +void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
64 | + uint32_t opr_sz, uint32_t max_sz) | 64 | + uint32_t opr_sz, uint32_t max_sz) |
65 | +{ | 65 | +{ |
66 | + assert(vece == MO_8); | 66 | + assert(vece == MO_8); |
67 | + tcg_gen_gvec_2_ool(rd_ofs, rn_ofs, opr_sz, max_sz, 0, | 67 | + tcg_gen_gvec_2_ool(rd_ofs, rn_ofs, opr_sz, max_sz, 0, |
68 | + gen_helper_gvec_rbit_b); | 68 | + gen_helper_gvec_rbit_b); |
69 | +} | 69 | +} |
70 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c | 70 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c |
71 | index XXXXXXX..XXXXXXX 100644 | 71 | index XXXXXXX..XXXXXXX 100644 |
72 | --- a/target/arm/tcg/neon_helper.c | 72 | --- a/target/arm/tcg/neon_helper.c |
73 | +++ b/target/arm/tcg/neon_helper.c | 73 | +++ b/target/arm/tcg/neon_helper.c |
74 | @@ -XXX,XX +XXX,XX @@ uint32_t HELPER(neon_cls_s32)(uint32_t x) | 74 | @@ -XXX,XX +XXX,XX @@ uint32_t HELPER(neon_cls_s32)(uint32_t x) |
75 | return count - 1; | 75 | return count - 1; |
76 | } | 76 | } |
77 | 77 | ||
78 | -/* Bit count. */ | 78 | -/* Bit count. */ |
79 | -uint32_t HELPER(neon_cnt_u8)(uint32_t x) | 79 | -uint32_t HELPER(neon_cnt_u8)(uint32_t x) |
80 | -{ | 80 | -{ |
81 | - x = (x & 0x55555555) + ((x >> 1) & 0x55555555); | 81 | - x = (x & 0x55555555) + ((x >> 1) & 0x55555555); |
82 | - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); | 82 | - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); |
83 | - x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f); | 83 | - x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f); |
84 | - return x; | 84 | - return x; |
85 | -} | 85 | -} |
86 | - | 86 | - |
87 | -/* Reverse bits in each 8 bit word */ | 87 | -/* Reverse bits in each 8 bit word */ |
88 | -uint32_t HELPER(neon_rbit_u8)(uint32_t x) | 88 | -uint32_t HELPER(neon_rbit_u8)(uint32_t x) |
89 | -{ | 89 | -{ |
90 | - x = ((x & 0xf0f0f0f0) >> 4) | 90 | - x = ((x & 0xf0f0f0f0) >> 4) |
91 | - | ((x & 0x0f0f0f0f) << 4); | 91 | - | ((x & 0x0f0f0f0f) << 4); |
92 | - x = ((x & 0x88888888) >> 3) | 92 | - x = ((x & 0x88888888) >> 3) |
93 | - | ((x & 0x44444444) >> 1) | 93 | - | ((x & 0x44444444) >> 1) |
94 | - | ((x & 0x22222222) << 1) | 94 | - | ((x & 0x22222222) << 1) |
95 | - | ((x & 0x11111111) << 3); | 95 | - | ((x & 0x11111111) << 3); |
96 | - return x; | 96 | - return x; |
97 | -} | 97 | -} |
98 | - | 98 | - |
99 | #define NEON_QDMULH16(dest, src1, src2, round) do { \ | 99 | #define NEON_QDMULH16(dest, src1, src2, round) do { \ |
100 | uint32_t tmp = (int32_t)(int16_t) src1 * (int16_t) src2; \ | 100 | uint32_t tmp = (int32_t)(int16_t) src1 * (int16_t) src2; \ |
101 | if ((tmp ^ (tmp << 1)) & SIGNBIT) { \ | 101 | if ((tmp ^ (tmp << 1)) & SIGNBIT) { \ |
102 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 102 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
103 | index XXXXXXX..XXXXXXX 100644 | 103 | index XXXXXXX..XXXXXXX 100644 |
104 | --- a/target/arm/tcg/translate-a64.c | 104 | --- a/target/arm/tcg/translate-a64.c |
105 | +++ b/target/arm/tcg/translate-a64.c | 105 | +++ b/target/arm/tcg/translate-a64.c |
106 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 106 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
107 | } | 107 | } |
108 | 108 | ||
109 | switch (opcode) { | 109 | switch (opcode) { |
110 | - case 0x5: | 110 | - case 0x5: |
111 | - if (u && size == 0) { /* NOT */ | 111 | - if (u && size == 0) { /* NOT */ |
112 | + case 0x5: /* CNT, NOT, RBIT */ | 112 | + case 0x5: /* CNT, NOT, RBIT */ |
113 | + if (!u) { | 113 | + if (!u) { |
114 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cnt, 0); | 114 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cnt, 0); |
115 | + } else if (size) { | 115 | + } else if (size) { |
116 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_rbit, 0); | 116 | + gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_rbit, 0); |
117 | + } else { | 117 | + } else { |
118 | gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); | 118 | gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); |
119 | - return; | 119 | - return; |
120 | } | 120 | } |
121 | - break; | 121 | - break; |
122 | + return; | 122 | + return; |
123 | case 0x8: /* CMGT, CMGE */ | 123 | case 0x8: /* CMGT, CMGE */ |
124 | if (u) { | 124 | if (u) { |
125 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size); | 125 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size); |
126 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 126 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
127 | } else { | 127 | } else { |
128 | int pass; | 128 | int pass; |
129 | 129 | ||
130 | + assert(size == 2); | 130 | + assert(size == 2); |
131 | for (pass = 0; pass < (is_q ? 4 : 2); pass++) { | 131 | for (pass = 0; pass < (is_q ? 4 : 2); pass++) { |
132 | TCGv_i32 tcg_op = tcg_temp_new_i32(); | 132 | TCGv_i32 tcg_op = tcg_temp_new_i32(); |
133 | TCGv_i32 tcg_res = tcg_temp_new_i32(); | 133 | TCGv_i32 tcg_res = tcg_temp_new_i32(); |
134 | 134 | ||
135 | read_vec_element_i32(s, tcg_op, rn, pass, MO_32); | 135 | read_vec_element_i32(s, tcg_op, rn, pass, MO_32); |
136 | 136 | ||
137 | - if (size == 2) { | 137 | - if (size == 2) { |
138 | + { | 138 | + { |
139 | /* Special cases for 32 bit elements */ | 139 | /* Special cases for 32 bit elements */ |
140 | switch (opcode) { | 140 | switch (opcode) { |
141 | case 0x2f: /* FABS */ | 141 | case 0x2f: /* FABS */ |
142 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 142 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
143 | case 0x7: /* SQABS, SQNEG */ | 143 | case 0x7: /* SQABS, SQNEG */ |
144 | g_assert_not_reached(); | 144 | g_assert_not_reached(); |
145 | } | 145 | } |
146 | - } else { | 146 | - } else { |
147 | - /* Use helpers for 8 and 16 bit elements */ | 147 | - /* Use helpers for 8 and 16 bit elements */ |
148 | - switch (opcode) { | 148 | - switch (opcode) { |
149 | - case 0x5: /* CNT, RBIT */ | 149 | - case 0x5: /* CNT, RBIT */ |
150 | - /* For these two insns size is part of the opcode specifier | 150 | - /* For these two insns size is part of the opcode specifier |
151 | - * (handled earlier); they always operate on byte elements. | 151 | - * (handled earlier); they always operate on byte elements. |
152 | - */ | 152 | - */ |
153 | - if (u) { | 153 | - if (u) { |
154 | - gen_helper_neon_rbit_u8(tcg_res, tcg_op); | 154 | - gen_helper_neon_rbit_u8(tcg_res, tcg_op); |
155 | - } else { | 155 | - } else { |
156 | - gen_helper_neon_cnt_u8(tcg_res, tcg_op); | 156 | - gen_helper_neon_cnt_u8(tcg_res, tcg_op); |
157 | - } | 157 | - } |
158 | - break; | 158 | - break; |
159 | - default: | 159 | - default: |
160 | - case 0x7: /* SQABS, SQNEG */ | 160 | - case 0x7: /* SQABS, SQNEG */ |
161 | - g_assert_not_reached(); | 161 | - g_assert_not_reached(); |
162 | - } | 162 | - } |
163 | } | 163 | } |
164 | - | 164 | - |
165 | write_vec_element_i32(s, tcg_res, rd, pass, MO_32); | 165 | write_vec_element_i32(s, tcg_res, rd, pass, MO_32); |
166 | } | 166 | } |
167 | } | 167 | } |
168 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c | 168 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c |
169 | index XXXXXXX..XXXXXXX 100644 | 169 | index XXXXXXX..XXXXXXX 100644 |
170 | --- a/target/arm/tcg/translate-neon.c | 170 | --- a/target/arm/tcg/translate-neon.c |
171 | +++ b/target/arm/tcg/translate-neon.c | 171 | +++ b/target/arm/tcg/translate-neon.c |
172 | @@ -XXX,XX +XXX,XX @@ static bool trans_VMVN(DisasContext *s, arg_2misc *a) | 172 | @@ -XXX,XX +XXX,XX @@ static bool trans_VMVN(DisasContext *s, arg_2misc *a) |
173 | return do_2misc_vec(s, a, tcg_gen_gvec_not); | 173 | return do_2misc_vec(s, a, tcg_gen_gvec_not); |
174 | } | 174 | } |
175 | 175 | ||
176 | +static bool trans_VCNT(DisasContext *s, arg_2misc *a) | 176 | +static bool trans_VCNT(DisasContext *s, arg_2misc *a) |
177 | +{ | 177 | +{ |
178 | + if (a->size != 0) { | 178 | + if (a->size != 0) { |
179 | + return false; | 179 | + return false; |
180 | + } | 180 | + } |
181 | + return do_2misc_vec(s, a, gen_gvec_cnt); | 181 | + return do_2misc_vec(s, a, gen_gvec_cnt); |
182 | +} | 182 | +} |
183 | + | 183 | + |
184 | #define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \ | 184 | #define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \ |
185 | static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \ | 185 | static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \ |
186 | uint32_t rm_ofs, uint32_t oprsz, \ | 186 | uint32_t rm_ofs, uint32_t oprsz, \ |
187 | @@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a) | 187 | @@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a) |
188 | return do_2misc(s, a, gen_rev16); | 188 | return do_2misc(s, a, gen_rev16); |
189 | } | 189 | } |
190 | 190 | ||
191 | -static bool trans_VCNT(DisasContext *s, arg_2misc *a) | 191 | -static bool trans_VCNT(DisasContext *s, arg_2misc *a) |
192 | -{ | 192 | -{ |
193 | - if (a->size != 0) { | 193 | - if (a->size != 0) { |
194 | - return false; | 194 | - return false; |
195 | - } | 195 | - } |
196 | - return do_2misc(s, a, gen_helper_neon_cnt_u8); | 196 | - return do_2misc(s, a, gen_helper_neon_cnt_u8); |
197 | -} | 197 | -} |
198 | - | 198 | - |
199 | static void gen_VABS_F(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs, | 199 | static void gen_VABS_F(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs, |
200 | uint32_t oprsz, uint32_t maxsz) | 200 | uint32_t oprsz, uint32_t maxsz) |
201 | { | 201 | { |
202 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c | 202 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c |
203 | index XXXXXXX..XXXXXXX 100644 | 203 | index XXXXXXX..XXXXXXX 100644 |
204 | --- a/target/arm/tcg/vec_helper.c | 204 | --- a/target/arm/tcg/vec_helper.c |
205 | +++ b/target/arm/tcg/vec_helper.c | 205 | +++ b/target/arm/tcg/vec_helper.c |
206 | @@ -XXX,XX +XXX,XX @@ DO_CLAMP(gvec_uclamp_b, uint8_t) | 206 | @@ -XXX,XX +XXX,XX @@ DO_CLAMP(gvec_uclamp_b, uint8_t) |
207 | DO_CLAMP(gvec_uclamp_h, uint16_t) | 207 | DO_CLAMP(gvec_uclamp_h, uint16_t) |
208 | DO_CLAMP(gvec_uclamp_s, uint32_t) | 208 | DO_CLAMP(gvec_uclamp_s, uint32_t) |
209 | DO_CLAMP(gvec_uclamp_d, uint64_t) | 209 | DO_CLAMP(gvec_uclamp_d, uint64_t) |
210 | + | 210 | + |
211 | +/* Bit count in each 8-bit word. */ | 211 | +/* Bit count in each 8-bit word. */ |
212 | +void HELPER(gvec_cnt_b)(void *vd, void *vn, uint32_t desc) | 212 | +void HELPER(gvec_cnt_b)(void *vd, void *vn, uint32_t desc) |
213 | +{ | 213 | +{ |
214 | + intptr_t i, opr_sz = simd_oprsz(desc); | 214 | + intptr_t i, opr_sz = simd_oprsz(desc); |
215 | + uint8_t *d = vd, *n = vn; | 215 | + uint8_t *d = vd, *n = vn; |
216 | + | 216 | + |
217 | + for (i = 0; i < opr_sz; ++i) { | 217 | + for (i = 0; i < opr_sz; ++i) { |
218 | + d[i] = ctpop8(n[i]); | 218 | + d[i] = ctpop8(n[i]); |
219 | + } | 219 | + } |
220 | + clear_tail(d, opr_sz, simd_maxsz(desc)); | 220 | + clear_tail(d, opr_sz, simd_maxsz(desc)); |
221 | +} | 221 | +} |
222 | + | 222 | + |
223 | +/* Reverse bits in each 8 bit word */ | 223 | +/* Reverse bits in each 8 bit word */ |
224 | +void HELPER(gvec_rbit_b)(void *vd, void *vn, uint32_t desc) | 224 | +void HELPER(gvec_rbit_b)(void *vd, void *vn, uint32_t desc) |
225 | +{ | 225 | +{ |
226 | + intptr_t i, opr_sz = simd_oprsz(desc); | 226 | + intptr_t i, opr_sz = simd_oprsz(desc); |
227 | + uint64_t *d = vd, *n = vn; | 227 | + uint64_t *d = vd, *n = vn; |
228 | + | 228 | + |
229 | + for (i = 0; i < opr_sz / 8; ++i) { | 229 | + for (i = 0; i < opr_sz / 8; ++i) { |
230 | + d[i] = revbit64(bswap64(n[i])); | 230 | + d[i] = revbit64(bswap64(n[i])); |
231 | + } | 231 | + } |
232 | + clear_tail(d, opr_sz, simd_maxsz(desc)); | 232 | + clear_tail(d, opr_sz, simd_maxsz(desc)); |
233 | +} | 233 | +} |
234 | -- | 234 | -- |
235 | 2.43.0 | 235 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 34 ++++++---------------------------- | 4 | target/arm/tcg/translate-a64.c | 34 ++++++---------------------------- |
5 | target/arm/tcg/a64.decode | 4 ++++ | 5 | target/arm/tcg/a64.decode | 4 ++++ |
6 | 2 files changed, 10 insertions(+), 28 deletions(-) | 6 | 2 files changed, 10 insertions(+), 28 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 12 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
13 | 13 | ||
14 | TRANS(ABS_v, do_gvec_fn2, a, tcg_gen_gvec_abs) | 14 | TRANS(ABS_v, do_gvec_fn2, a, tcg_gen_gvec_abs) |
15 | TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) | 15 | TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) |
16 | +TRANS(NOT_v, do_gvec_fn2, a, tcg_gen_gvec_not) | 16 | +TRANS(NOT_v, do_gvec_fn2, a, tcg_gen_gvec_not) |
17 | +TRANS(CNT_v, do_gvec_fn2, a, gen_gvec_cnt) | 17 | +TRANS(CNT_v, do_gvec_fn2, a, gen_gvec_cnt) |
18 | +TRANS(RBIT_v, do_gvec_fn2, a, gen_gvec_rbit) | 18 | +TRANS(RBIT_v, do_gvec_fn2, a, gen_gvec_rbit) |
19 | 19 | ||
20 | static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 20 | static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
21 | { | 21 | { |
22 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 22 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
23 | TCGCond cond; | 23 | TCGCond cond; |
24 | 24 | ||
25 | switch (opcode) { | 25 | switch (opcode) { |
26 | - case 0x5: /* NOT */ | 26 | - case 0x5: /* NOT */ |
27 | - /* This opcode is shared with CNT and RBIT but we have earlier | 27 | - /* This opcode is shared with CNT and RBIT but we have earlier |
28 | - * enforced that size == 3 if and only if this is the NOT insn. | 28 | - * enforced that size == 3 if and only if this is the NOT insn. |
29 | - */ | 29 | - */ |
30 | - tcg_gen_not_i64(tcg_rd, tcg_rn); | 30 | - tcg_gen_not_i64(tcg_rd, tcg_rn); |
31 | - break; | 31 | - break; |
32 | case 0xa: /* CMLT */ | 32 | case 0xa: /* CMLT */ |
33 | cond = TCG_COND_LT; | 33 | cond = TCG_COND_LT; |
34 | do_cmop: | 34 | do_cmop: |
35 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 35 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
36 | break; | 36 | break; |
37 | default: | 37 | default: |
38 | case 0x4: /* CLS, CLZ */ | 38 | case 0x4: /* CLS, CLZ */ |
39 | + case 0x5: /* NOT */ | 39 | + case 0x5: /* NOT */ |
40 | case 0x7: /* SQABS, SQNEG */ | 40 | case 0x7: /* SQABS, SQNEG */ |
41 | case 0xb: /* ABS, NEG */ | 41 | case 0xb: /* ABS, NEG */ |
42 | g_assert_not_reached(); | 42 | g_assert_not_reached(); |
43 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 43 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
44 | case 0x1: /* REV16 */ | 44 | case 0x1: /* REV16 */ |
45 | handle_rev(s, opcode, u, is_q, size, rn, rd); | 45 | handle_rev(s, opcode, u, is_q, size, rn, rd); |
46 | return; | 46 | return; |
47 | - case 0x5: /* CNT, NOT, RBIT */ | 47 | - case 0x5: /* CNT, NOT, RBIT */ |
48 | - if (u && size == 0) { | 48 | - if (u && size == 0) { |
49 | - /* NOT */ | 49 | - /* NOT */ |
50 | - break; | 50 | - break; |
51 | - } else if (u && size == 1) { | 51 | - } else if (u && size == 1) { |
52 | - /* RBIT */ | 52 | - /* RBIT */ |
53 | - break; | 53 | - break; |
54 | - } else if (!u && size == 0) { | 54 | - } else if (!u && size == 0) { |
55 | - /* CNT */ | 55 | - /* CNT */ |
56 | - break; | 56 | - break; |
57 | - } | 57 | - } |
58 | - unallocated_encoding(s); | 58 | - unallocated_encoding(s); |
59 | - return; | 59 | - return; |
60 | case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ | 60 | case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ |
61 | case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ | 61 | case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ |
62 | if (size == 3) { | 62 | if (size == 3) { |
63 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 63 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
64 | default: | 64 | default: |
65 | case 0x3: /* SUQADD, USQADD */ | 65 | case 0x3: /* SUQADD, USQADD */ |
66 | case 0x4: /* CLS, CLZ */ | 66 | case 0x4: /* CLS, CLZ */ |
67 | + case 0x5: /* CNT, NOT, RBIT */ | 67 | + case 0x5: /* CNT, NOT, RBIT */ |
68 | case 0x7: /* SQABS, SQNEG */ | 68 | case 0x7: /* SQABS, SQNEG */ |
69 | case 0xb: /* ABS, NEG */ | 69 | case 0xb: /* ABS, NEG */ |
70 | unallocated_encoding(s); | 70 | unallocated_encoding(s); |
71 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 71 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
72 | } | 72 | } |
73 | 73 | ||
74 | switch (opcode) { | 74 | switch (opcode) { |
75 | - case 0x5: /* CNT, NOT, RBIT */ | 75 | - case 0x5: /* CNT, NOT, RBIT */ |
76 | - if (!u) { | 76 | - if (!u) { |
77 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cnt, 0); | 77 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cnt, 0); |
78 | - } else if (size) { | 78 | - } else if (size) { |
79 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_rbit, 0); | 79 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_rbit, 0); |
80 | - } else { | 80 | - } else { |
81 | - gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); | 81 | - gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0); |
82 | - } | 82 | - } |
83 | - return; | 83 | - return; |
84 | case 0x8: /* CMGT, CMGE */ | 84 | case 0x8: /* CMGT, CMGE */ |
85 | if (u) { | 85 | if (u) { |
86 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size); | 86 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size); |
87 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 87 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
88 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); | 88 | gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); |
89 | return; | 89 | return; |
90 | case 0x4: /* CLZ, CLS */ | 90 | case 0x4: /* CLZ, CLS */ |
91 | + case 0x5: /* CNT, NOT, RBIT */ | 91 | + case 0x5: /* CNT, NOT, RBIT */ |
92 | case 0xb: | 92 | case 0xb: |
93 | g_assert_not_reached(); | 93 | g_assert_not_reached(); |
94 | } | 94 | } |
95 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 95 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
96 | index XXXXXXX..XXXXXXX 100644 | 96 | index XXXXXXX..XXXXXXX 100644 |
97 | --- a/target/arm/tcg/a64.decode | 97 | --- a/target/arm/tcg/a64.decode |
98 | +++ b/target/arm/tcg/a64.decode | 98 | +++ b/target/arm/tcg/a64.decode |
99 | @@ -XXX,XX +XXX,XX @@ | 99 | @@ -XXX,XX +XXX,XX @@ |
100 | @rrr_q1e3 ........ ... rm:5 ...... rn:5 rd:5 &qrrr_e q=1 esz=3 | 100 | @rrr_q1e3 ........ ... rm:5 ...... rn:5 rd:5 &qrrr_e q=1 esz=3 |
101 | @rrrr_q1e3 ........ ... rm:5 . ra:5 rn:5 rd:5 &qrrrr_e q=1 esz=3 | 101 | @rrrr_q1e3 ........ ... rm:5 . ra:5 rn:5 rd:5 &qrrrr_e q=1 esz=3 |
102 | 102 | ||
103 | +@qrr_b . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=0 | 103 | +@qrr_b . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=0 |
104 | @qrr_h . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=1 | 104 | @qrr_h . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=1 |
105 | @qrr_e . q:1 ...... esz:2 ...... ...... rn:5 rd:5 &qrr_e | 105 | @qrr_e . q:1 ...... esz:2 ...... ...... rn:5 rd:5 &qrr_e |
106 | 106 | ||
107 | @@ -XXX,XX +XXX,XX @@ ABS_v 0.00 1110 ..1 00000 10111 0 ..... ..... @qrr_e | 107 | @@ -XXX,XX +XXX,XX @@ ABS_v 0.00 1110 ..1 00000 10111 0 ..... ..... @qrr_e |
108 | NEG_v 0.10 1110 ..1 00000 10111 0 ..... ..... @qrr_e | 108 | NEG_v 0.10 1110 ..1 00000 10111 0 ..... ..... @qrr_e |
109 | CLS_v 0.00 1110 ..1 00000 01001 0 ..... ..... @qrr_e | 109 | CLS_v 0.00 1110 ..1 00000 01001 0 ..... ..... @qrr_e |
110 | CLZ_v 0.10 1110 ..1 00000 01001 0 ..... ..... @qrr_e | 110 | CLZ_v 0.10 1110 ..1 00000 01001 0 ..... ..... @qrr_e |
111 | +CNT_v 0.00 1110 001 00000 01011 0 ..... ..... @qrr_b | 111 | +CNT_v 0.00 1110 001 00000 01011 0 ..... ..... @qrr_b |
112 | +NOT_v 0.10 1110 001 00000 01011 0 ..... ..... @qrr_b | 112 | +NOT_v 0.10 1110 001 00000 01011 0 ..... ..... @qrr_b |
113 | +RBIT_v 0.10 1110 011 00000 01011 0 ..... ..... @qrr_b | 113 | +RBIT_v 0.10 1110 011 00000 01011 0 ..... ..... @qrr_b |
114 | -- | 114 | -- |
115 | 2.43.0 | 115 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 94 +++++++++++----------------------- | 4 | target/arm/tcg/translate-a64.c | 94 +++++++++++----------------------- |
5 | target/arm/tcg/a64.decode | 10 ++++ | 5 | target/arm/tcg/a64.decode | 10 ++++ |
6 | 2 files changed, 40 insertions(+), 64 deletions(-) | 6 | 2 files changed, 40 insertions(+), 64 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool do_scalar1_d(DisasContext *s, arg_rr *a, ArithOneOp *f) | 12 | @@ -XXX,XX +XXX,XX @@ static bool do_scalar1_d(DisasContext *s, arg_rr *a, ArithOneOp *f) |
13 | TRANS(ABS_s, do_scalar1_d, a, tcg_gen_abs_i64) | 13 | TRANS(ABS_s, do_scalar1_d, a, tcg_gen_abs_i64) |
14 | TRANS(NEG_s, do_scalar1_d, a, tcg_gen_neg_i64) | 14 | TRANS(NEG_s, do_scalar1_d, a, tcg_gen_neg_i64) |
15 | 15 | ||
16 | +static bool do_cmop0_d(DisasContext *s, arg_rr *a, TCGCond cond) | 16 | +static bool do_cmop0_d(DisasContext *s, arg_rr *a, TCGCond cond) |
17 | +{ | 17 | +{ |
18 | + if (fp_access_check(s)) { | 18 | + if (fp_access_check(s)) { |
19 | + TCGv_i64 t = read_fp_dreg(s, a->rn); | 19 | + TCGv_i64 t = read_fp_dreg(s, a->rn); |
20 | + tcg_gen_negsetcond_i64(cond, t, t, tcg_constant_i64(0)); | 20 | + tcg_gen_negsetcond_i64(cond, t, t, tcg_constant_i64(0)); |
21 | + write_fp_dreg(s, a->rd, t); | 21 | + write_fp_dreg(s, a->rd, t); |
22 | + } | 22 | + } |
23 | + return true; | 23 | + return true; |
24 | +} | 24 | +} |
25 | + | 25 | + |
26 | +TRANS(CMGT0_s, do_cmop0_d, a, TCG_COND_GT) | 26 | +TRANS(CMGT0_s, do_cmop0_d, a, TCG_COND_GT) |
27 | +TRANS(CMGE0_s, do_cmop0_d, a, TCG_COND_GE) | 27 | +TRANS(CMGE0_s, do_cmop0_d, a, TCG_COND_GE) |
28 | +TRANS(CMLE0_s, do_cmop0_d, a, TCG_COND_LE) | 28 | +TRANS(CMLE0_s, do_cmop0_d, a, TCG_COND_LE) |
29 | +TRANS(CMLT0_s, do_cmop0_d, a, TCG_COND_LT) | 29 | +TRANS(CMLT0_s, do_cmop0_d, a, TCG_COND_LT) |
30 | +TRANS(CMEQ0_s, do_cmop0_d, a, TCG_COND_EQ) | 30 | +TRANS(CMEQ0_s, do_cmop0_d, a, TCG_COND_EQ) |
31 | + | 31 | + |
32 | static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 32 | static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
33 | { | 33 | { |
34 | if (!a->q && a->esz == MO_64) { | 34 | if (!a->q && a->esz == MO_64) { |
35 | @@ -XXX,XX +XXX,XX @@ TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) | 35 | @@ -XXX,XX +XXX,XX @@ TRANS(NEG_v, do_gvec_fn2, a, tcg_gen_gvec_neg) |
36 | TRANS(NOT_v, do_gvec_fn2, a, tcg_gen_gvec_not) | 36 | TRANS(NOT_v, do_gvec_fn2, a, tcg_gen_gvec_not) |
37 | TRANS(CNT_v, do_gvec_fn2, a, gen_gvec_cnt) | 37 | TRANS(CNT_v, do_gvec_fn2, a, gen_gvec_cnt) |
38 | TRANS(RBIT_v, do_gvec_fn2, a, gen_gvec_rbit) | 38 | TRANS(RBIT_v, do_gvec_fn2, a, gen_gvec_rbit) |
39 | +TRANS(CMGT0_v, do_gvec_fn2, a, gen_gvec_cgt0) | 39 | +TRANS(CMGT0_v, do_gvec_fn2, a, gen_gvec_cgt0) |
40 | +TRANS(CMGE0_v, do_gvec_fn2, a, gen_gvec_cge0) | 40 | +TRANS(CMGE0_v, do_gvec_fn2, a, gen_gvec_cge0) |
41 | +TRANS(CMLT0_v, do_gvec_fn2, a, gen_gvec_clt0) | 41 | +TRANS(CMLT0_v, do_gvec_fn2, a, gen_gvec_clt0) |
42 | +TRANS(CMLE0_v, do_gvec_fn2, a, gen_gvec_cle0) | 42 | +TRANS(CMLE0_v, do_gvec_fn2, a, gen_gvec_cle0) |
43 | +TRANS(CMEQ0_v, do_gvec_fn2, a, gen_gvec_ceq0) | 43 | +TRANS(CMEQ0_v, do_gvec_fn2, a, gen_gvec_ceq0) |
44 | 44 | ||
45 | static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 45 | static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
46 | { | 46 | { |
47 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 47 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
48 | * The caller only need provide tcg_rmode and tcg_fpstatus if the op | 48 | * The caller only need provide tcg_rmode and tcg_fpstatus if the op |
49 | * requires them. | 49 | * requires them. |
50 | */ | 50 | */ |
51 | - TCGCond cond; | 51 | - TCGCond cond; |
52 | - | 52 | - |
53 | switch (opcode) { | 53 | switch (opcode) { |
54 | - case 0xa: /* CMLT */ | 54 | - case 0xa: /* CMLT */ |
55 | - cond = TCG_COND_LT; | 55 | - cond = TCG_COND_LT; |
56 | - do_cmop: | 56 | - do_cmop: |
57 | - /* 64 bit integer comparison against zero, result is test ? -1 : 0. */ | 57 | - /* 64 bit integer comparison against zero, result is test ? -1 : 0. */ |
58 | - tcg_gen_negsetcond_i64(cond, tcg_rd, tcg_rn, tcg_constant_i64(0)); | 58 | - tcg_gen_negsetcond_i64(cond, tcg_rd, tcg_rn, tcg_constant_i64(0)); |
59 | - break; | 59 | - break; |
60 | - case 0x8: /* CMGT, CMGE */ | 60 | - case 0x8: /* CMGT, CMGE */ |
61 | - cond = u ? TCG_COND_GE : TCG_COND_GT; | 61 | - cond = u ? TCG_COND_GE : TCG_COND_GT; |
62 | - goto do_cmop; | 62 | - goto do_cmop; |
63 | - case 0x9: /* CMEQ, CMLE */ | 63 | - case 0x9: /* CMEQ, CMLE */ |
64 | - cond = u ? TCG_COND_LE : TCG_COND_EQ; | 64 | - cond = u ? TCG_COND_LE : TCG_COND_EQ; |
65 | - goto do_cmop; | 65 | - goto do_cmop; |
66 | case 0x2f: /* FABS */ | 66 | case 0x2f: /* FABS */ |
67 | gen_vfp_absd(tcg_rd, tcg_rn); | 67 | gen_vfp_absd(tcg_rd, tcg_rn); |
68 | break; | 68 | break; |
69 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 69 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
70 | case 0x4: /* CLS, CLZ */ | 70 | case 0x4: /* CLS, CLZ */ |
71 | case 0x5: /* NOT */ | 71 | case 0x5: /* NOT */ |
72 | case 0x7: /* SQABS, SQNEG */ | 72 | case 0x7: /* SQABS, SQNEG */ |
73 | + case 0x8: /* CMGT, CMGE */ | 73 | + case 0x8: /* CMGT, CMGE */ |
74 | + case 0x9: /* CMEQ, CMLE */ | 74 | + case 0x9: /* CMEQ, CMLE */ |
75 | + case 0xa: /* CMLT */ | 75 | + case 0xa: /* CMLT */ |
76 | case 0xb: /* ABS, NEG */ | 76 | case 0xb: /* ABS, NEG */ |
77 | g_assert_not_reached(); | 77 | g_assert_not_reached(); |
78 | } | 78 | } |
79 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 79 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
80 | TCGv_ptr tcg_fpstatus; | 80 | TCGv_ptr tcg_fpstatus; |
81 | 81 | ||
82 | switch (opcode) { | 82 | switch (opcode) { |
83 | - case 0xa: /* CMLT */ | 83 | - case 0xa: /* CMLT */ |
84 | - if (u) { | 84 | - if (u) { |
85 | - unallocated_encoding(s); | 85 | - unallocated_encoding(s); |
86 | - return; | 86 | - return; |
87 | - } | 87 | - } |
88 | - /* fall through */ | 88 | - /* fall through */ |
89 | - case 0x8: /* CMGT, CMGE */ | 89 | - case 0x8: /* CMGT, CMGE */ |
90 | - case 0x9: /* CMEQ, CMLE */ | 90 | - case 0x9: /* CMEQ, CMLE */ |
91 | - if (size != 3) { | 91 | - if (size != 3) { |
92 | - unallocated_encoding(s); | 92 | - unallocated_encoding(s); |
93 | - return; | 93 | - return; |
94 | - } | 94 | - } |
95 | - break; | 95 | - break; |
96 | case 0x12: /* SQXTUN */ | 96 | case 0x12: /* SQXTUN */ |
97 | if (!u) { | 97 | if (!u) { |
98 | unallocated_encoding(s); | 98 | unallocated_encoding(s); |
99 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 99 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
100 | default: | 100 | default: |
101 | case 0x3: /* USQADD / SUQADD */ | 101 | case 0x3: /* USQADD / SUQADD */ |
102 | case 0x7: /* SQABS / SQNEG */ | 102 | case 0x7: /* SQABS / SQNEG */ |
103 | + case 0x8: /* CMGT, CMGE */ | 103 | + case 0x8: /* CMGT, CMGE */ |
104 | + case 0x9: /* CMEQ, CMLE */ | 104 | + case 0x9: /* CMEQ, CMLE */ |
105 | + case 0xa: /* CMLT */ | 105 | + case 0xa: /* CMLT */ |
106 | case 0xb: /* ABS, NEG */ | 106 | case 0xb: /* ABS, NEG */ |
107 | unallocated_encoding(s); | 107 | unallocated_encoding(s); |
108 | return; | 108 | return; |
109 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 109 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
110 | } | 110 | } |
111 | handle_shll(s, is_q, size, rn, rd); | 111 | handle_shll(s, is_q, size, rn, rd); |
112 | return; | 112 | return; |
113 | - case 0xa: /* CMLT */ | 113 | - case 0xa: /* CMLT */ |
114 | - if (u == 1) { | 114 | - if (u == 1) { |
115 | - unallocated_encoding(s); | 115 | - unallocated_encoding(s); |
116 | - return; | 116 | - return; |
117 | - } | 117 | - } |
118 | - /* fall through */ | 118 | - /* fall through */ |
119 | - case 0x8: /* CMGT, CMGE */ | 119 | - case 0x8: /* CMGT, CMGE */ |
120 | - case 0x9: /* CMEQ, CMLE */ | 120 | - case 0x9: /* CMEQ, CMLE */ |
121 | - if (size == 3 && !is_q) { | 121 | - if (size == 3 && !is_q) { |
122 | - unallocated_encoding(s); | 122 | - unallocated_encoding(s); |
123 | - return; | 123 | - return; |
124 | - } | 124 | - } |
125 | - break; | 125 | - break; |
126 | case 0xc ... 0xf: | 126 | case 0xc ... 0xf: |
127 | case 0x16 ... 0x1f: | 127 | case 0x16 ... 0x1f: |
128 | { | 128 | { |
129 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 129 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
130 | case 0x4: /* CLS, CLZ */ | 130 | case 0x4: /* CLS, CLZ */ |
131 | case 0x5: /* CNT, NOT, RBIT */ | 131 | case 0x5: /* CNT, NOT, RBIT */ |
132 | case 0x7: /* SQABS, SQNEG */ | 132 | case 0x7: /* SQABS, SQNEG */ |
133 | + case 0x8: /* CMGT, CMGE */ | 133 | + case 0x8: /* CMGT, CMGE */ |
134 | + case 0x9: /* CMEQ, CMLE */ | 134 | + case 0x9: /* CMEQ, CMLE */ |
135 | + case 0xa: /* CMLT */ | 135 | + case 0xa: /* CMLT */ |
136 | case 0xb: /* ABS, NEG */ | 136 | case 0xb: /* ABS, NEG */ |
137 | unallocated_encoding(s); | 137 | unallocated_encoding(s); |
138 | return; | 138 | return; |
139 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 139 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
140 | tcg_rmode = NULL; | 140 | tcg_rmode = NULL; |
141 | } | 141 | } |
142 | 142 | ||
143 | - switch (opcode) { | 143 | - switch (opcode) { |
144 | - case 0x8: /* CMGT, CMGE */ | 144 | - case 0x8: /* CMGT, CMGE */ |
145 | - if (u) { | 145 | - if (u) { |
146 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size); | 146 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size); |
147 | - } else { | 147 | - } else { |
148 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cgt0, size); | 148 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cgt0, size); |
149 | - } | 149 | - } |
150 | - return; | 150 | - return; |
151 | - case 0x9: /* CMEQ, CMLE */ | 151 | - case 0x9: /* CMEQ, CMLE */ |
152 | - if (u) { | 152 | - if (u) { |
153 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cle0, size); | 153 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cle0, size); |
154 | - } else { | 154 | - } else { |
155 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_ceq0, size); | 155 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_ceq0, size); |
156 | - } | 156 | - } |
157 | - return; | 157 | - return; |
158 | - case 0xa: /* CMLT */ | 158 | - case 0xa: /* CMLT */ |
159 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); | 159 | - gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size); |
160 | - return; | 160 | - return; |
161 | - case 0x4: /* CLZ, CLS */ | 161 | - case 0x4: /* CLZ, CLS */ |
162 | - case 0x5: /* CNT, NOT, RBIT */ | 162 | - case 0x5: /* CNT, NOT, RBIT */ |
163 | - case 0xb: | 163 | - case 0xb: |
164 | - g_assert_not_reached(); | 164 | - g_assert_not_reached(); |
165 | - } | 165 | - } |
166 | - | 166 | - |
167 | if (size == 3) { | 167 | if (size == 3) { |
168 | /* All 64-bit element operations can be shared with scalar 2misc */ | 168 | /* All 64-bit element operations can be shared with scalar 2misc */ |
169 | int pass; | 169 | int pass; |
170 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 170 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
171 | index XXXXXXX..XXXXXXX 100644 | 171 | index XXXXXXX..XXXXXXX 100644 |
172 | --- a/target/arm/tcg/a64.decode | 172 | --- a/target/arm/tcg/a64.decode |
173 | +++ b/target/arm/tcg/a64.decode | 173 | +++ b/target/arm/tcg/a64.decode |
174 | @@ -XXX,XX +XXX,XX @@ SQABS_s 0101 1110 ..1 00000 01111 0 ..... ..... @rr_e | 174 | @@ -XXX,XX +XXX,XX @@ SQABS_s 0101 1110 ..1 00000 01111 0 ..... ..... @rr_e |
175 | SQNEG_s 0111 1110 ..1 00000 01111 0 ..... ..... @rr_e | 175 | SQNEG_s 0111 1110 ..1 00000 01111 0 ..... ..... @rr_e |
176 | ABS_s 0101 1110 111 00000 10111 0 ..... ..... @rr | 176 | ABS_s 0101 1110 111 00000 10111 0 ..... ..... @rr |
177 | NEG_s 0111 1110 111 00000 10111 0 ..... ..... @rr | 177 | NEG_s 0111 1110 111 00000 10111 0 ..... ..... @rr |
178 | +CMGT0_s 0101 1110 111 00000 10001 0 ..... ..... @rr | 178 | +CMGT0_s 0101 1110 111 00000 10001 0 ..... ..... @rr |
179 | +CMGE0_s 0111 1110 111 00000 10001 0 ..... ..... @rr | 179 | +CMGE0_s 0111 1110 111 00000 10001 0 ..... ..... @rr |
180 | +CMEQ0_s 0101 1110 111 00000 10011 0 ..... ..... @rr | 180 | +CMEQ0_s 0101 1110 111 00000 10011 0 ..... ..... @rr |
181 | +CMLE0_s 0111 1110 111 00000 10011 0 ..... ..... @rr | 181 | +CMLE0_s 0111 1110 111 00000 10011 0 ..... ..... @rr |
182 | +CMLT0_s 0101 1110 111 00000 10101 0 ..... ..... @rr | 182 | +CMLT0_s 0101 1110 111 00000 10101 0 ..... ..... @rr |
183 | 183 | ||
184 | # Advanced SIMD two-register miscellaneous | 184 | # Advanced SIMD two-register miscellaneous |
185 | 185 | ||
186 | @@ -XXX,XX +XXX,XX @@ CLZ_v 0.10 1110 ..1 00000 01001 0 ..... ..... @qrr_e | 186 | @@ -XXX,XX +XXX,XX @@ CLZ_v 0.10 1110 ..1 00000 01001 0 ..... ..... @qrr_e |
187 | CNT_v 0.00 1110 001 00000 01011 0 ..... ..... @qrr_b | 187 | CNT_v 0.00 1110 001 00000 01011 0 ..... ..... @qrr_b |
188 | NOT_v 0.10 1110 001 00000 01011 0 ..... ..... @qrr_b | 188 | NOT_v 0.10 1110 001 00000 01011 0 ..... ..... @qrr_b |
189 | RBIT_v 0.10 1110 011 00000 01011 0 ..... ..... @qrr_b | 189 | RBIT_v 0.10 1110 011 00000 01011 0 ..... ..... @qrr_b |
190 | +CMGT0_v 0.00 1110 ..1 00000 10001 0 ..... ..... @qrr_e | 190 | +CMGT0_v 0.00 1110 ..1 00000 10001 0 ..... ..... @qrr_e |
191 | +CMGE0_v 0.10 1110 ..1 00000 10001 0 ..... ..... @qrr_e | 191 | +CMGE0_v 0.10 1110 ..1 00000 10001 0 ..... ..... @qrr_e |
192 | +CMEQ0_v 0.00 1110 ..1 00000 10011 0 ..... ..... @qrr_e | 192 | +CMEQ0_v 0.00 1110 ..1 00000 10011 0 ..... ..... @qrr_e |
193 | +CMLE0_v 0.10 1110 ..1 00000 10011 0 ..... ..... @qrr_e | 193 | +CMLE0_v 0.10 1110 ..1 00000 10011 0 ..... ..... @qrr_e |
194 | +CMLT0_v 0.00 1110 ..1 00000 10101 0 ..... ..... @qrr_e | 194 | +CMLT0_v 0.00 1110 ..1 00000 10101 0 ..... ..... @qrr_e |
195 | -- | 195 | -- |
196 | 2.43.0 | 196 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate.h | 6 +++ | 4 | target/arm/tcg/translate.h | 6 +++ |
5 | target/arm/tcg/gengvec.c | 58 ++++++++++++++++++++++ | 5 | target/arm/tcg/gengvec.c | 58 ++++++++++++++++++++++ |
6 | target/arm/tcg/translate-neon.c | 88 +++++++-------------------------- | 6 | target/arm/tcg/translate-neon.c | 88 +++++++-------------------------- |
7 | 3 files changed, 81 insertions(+), 71 deletions(-) | 7 | 3 files changed, 81 insertions(+), 71 deletions(-) |
8 | 8 | ||
9 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h | 9 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h |
10 | index XXXXXXX..XXXXXXX 100644 | 10 | index XXXXXXX..XXXXXXX 100644 |
11 | --- a/target/arm/tcg/translate.h | 11 | --- a/target/arm/tcg/translate.h |
12 | +++ b/target/arm/tcg/translate.h | 12 | +++ b/target/arm/tcg/translate.h |
13 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_cnt(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 13 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_cnt(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
14 | uint32_t opr_sz, uint32_t max_sz); | 14 | uint32_t opr_sz, uint32_t max_sz); |
15 | void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 15 | void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
16 | uint32_t opr_sz, uint32_t max_sz); | 16 | uint32_t opr_sz, uint32_t max_sz); |
17 | +void gen_gvec_rev16(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 17 | +void gen_gvec_rev16(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
18 | + uint32_t opr_sz, uint32_t max_sz); | 18 | + uint32_t opr_sz, uint32_t max_sz); |
19 | +void gen_gvec_rev32(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 19 | +void gen_gvec_rev32(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
20 | + uint32_t opr_sz, uint32_t max_sz); | 20 | + uint32_t opr_sz, uint32_t max_sz); |
21 | +void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 21 | +void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
22 | + uint32_t opr_sz, uint32_t max_sz); | 22 | + uint32_t opr_sz, uint32_t max_sz); |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * Forward to the isar_feature_* tests given a DisasContext pointer. | 25 | * Forward to the isar_feature_* tests given a DisasContext pointer. |
26 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c | 26 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c |
27 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/target/arm/tcg/gengvec.c | 28 | --- a/target/arm/tcg/gengvec.c |
29 | +++ b/target/arm/tcg/gengvec.c | 29 | +++ b/target/arm/tcg/gengvec.c |
30 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 30 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
31 | tcg_gen_gvec_2_ool(rd_ofs, rn_ofs, opr_sz, max_sz, 0, | 31 | tcg_gen_gvec_2_ool(rd_ofs, rn_ofs, opr_sz, max_sz, 0, |
32 | gen_helper_gvec_rbit_b); | 32 | gen_helper_gvec_rbit_b); |
33 | } | 33 | } |
34 | + | 34 | + |
35 | +void gen_gvec_rev16(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 35 | +void gen_gvec_rev16(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
36 | + uint32_t opr_sz, uint32_t max_sz) | 36 | + uint32_t opr_sz, uint32_t max_sz) |
37 | +{ | 37 | +{ |
38 | + assert(vece == MO_8); | 38 | + assert(vece == MO_8); |
39 | + tcg_gen_gvec_rotli(MO_16, rd_ofs, rn_ofs, 8, opr_sz, max_sz); | 39 | + tcg_gen_gvec_rotli(MO_16, rd_ofs, rn_ofs, 8, opr_sz, max_sz); |
40 | +} | 40 | +} |
41 | + | 41 | + |
42 | +static void gen_bswap32_i64(TCGv_i64 d, TCGv_i64 n) | 42 | +static void gen_bswap32_i64(TCGv_i64 d, TCGv_i64 n) |
43 | +{ | 43 | +{ |
44 | + tcg_gen_bswap64_i64(d, n); | 44 | + tcg_gen_bswap64_i64(d, n); |
45 | + tcg_gen_rotli_i64(d, d, 32); | 45 | + tcg_gen_rotli_i64(d, d, 32); |
46 | +} | 46 | +} |
47 | + | 47 | + |
48 | +void gen_gvec_rev32(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 48 | +void gen_gvec_rev32(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
49 | + uint32_t opr_sz, uint32_t max_sz) | 49 | + uint32_t opr_sz, uint32_t max_sz) |
50 | +{ | 50 | +{ |
51 | + static const GVecGen2 g = { | 51 | + static const GVecGen2 g = { |
52 | + .fni8 = gen_bswap32_i64, | 52 | + .fni8 = gen_bswap32_i64, |
53 | + .fni4 = tcg_gen_bswap32_i32, | 53 | + .fni4 = tcg_gen_bswap32_i32, |
54 | + .prefer_i64 = TCG_TARGET_REG_BITS == 64, | 54 | + .prefer_i64 = TCG_TARGET_REG_BITS == 64, |
55 | + .vece = MO_32 | 55 | + .vece = MO_32 |
56 | + }; | 56 | + }; |
57 | + | 57 | + |
58 | + switch (vece) { | 58 | + switch (vece) { |
59 | + case MO_16: | 59 | + case MO_16: |
60 | + tcg_gen_gvec_rotli(MO_32, rd_ofs, rn_ofs, 16, opr_sz, max_sz); | 60 | + tcg_gen_gvec_rotli(MO_32, rd_ofs, rn_ofs, 16, opr_sz, max_sz); |
61 | + break; | 61 | + break; |
62 | + case MO_8: | 62 | + case MO_8: |
63 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g); | 63 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g); |
64 | + break; | 64 | + break; |
65 | + default: | 65 | + default: |
66 | + g_assert_not_reached(); | 66 | + g_assert_not_reached(); |
67 | + } | 67 | + } |
68 | +} | 68 | +} |
69 | + | 69 | + |
70 | +void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 70 | +void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
71 | + uint32_t opr_sz, uint32_t max_sz) | 71 | + uint32_t opr_sz, uint32_t max_sz) |
72 | +{ | 72 | +{ |
73 | + static const GVecGen2 g[] = { | 73 | + static const GVecGen2 g[] = { |
74 | + { .fni8 = tcg_gen_bswap64_i64, | 74 | + { .fni8 = tcg_gen_bswap64_i64, |
75 | + .vece = MO_64 }, | 75 | + .vece = MO_64 }, |
76 | + { .fni8 = tcg_gen_hswap_i64, | 76 | + { .fni8 = tcg_gen_hswap_i64, |
77 | + .vece = MO_64 }, | 77 | + .vece = MO_64 }, |
78 | + }; | 78 | + }; |
79 | + | 79 | + |
80 | + switch (vece) { | 80 | + switch (vece) { |
81 | + case MO_32: | 81 | + case MO_32: |
82 | + tcg_gen_gvec_rotli(MO_64, rd_ofs, rn_ofs, 32, opr_sz, max_sz); | 82 | + tcg_gen_gvec_rotli(MO_64, rd_ofs, rn_ofs, 32, opr_sz, max_sz); |
83 | + break; | 83 | + break; |
84 | + case MO_8: | 84 | + case MO_8: |
85 | + case MO_16: | 85 | + case MO_16: |
86 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 86 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
87 | + break; | 87 | + break; |
88 | + default: | 88 | + default: |
89 | + g_assert_not_reached(); | 89 | + g_assert_not_reached(); |
90 | + } | 90 | + } |
91 | +} | 91 | +} |
92 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c | 92 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c |
93 | index XXXXXXX..XXXXXXX 100644 | 93 | index XXXXXXX..XXXXXXX 100644 |
94 | --- a/target/arm/tcg/translate-neon.c | 94 | --- a/target/arm/tcg/translate-neon.c |
95 | +++ b/target/arm/tcg/translate-neon.c | 95 | +++ b/target/arm/tcg/translate-neon.c |
96 | @@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a) | 96 | @@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a) |
97 | return true; | 97 | return true; |
98 | } | 98 | } |
99 | 99 | ||
100 | -static bool trans_VREV64(DisasContext *s, arg_VREV64 *a) | 100 | -static bool trans_VREV64(DisasContext *s, arg_VREV64 *a) |
101 | -{ | 101 | -{ |
102 | - int pass, half; | 102 | - int pass, half; |
103 | - TCGv_i32 tmp[2]; | 103 | - TCGv_i32 tmp[2]; |
104 | - | 104 | - |
105 | - if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { | 105 | - if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { |
106 | - return false; | 106 | - return false; |
107 | - } | 107 | - } |
108 | - | 108 | - |
109 | - /* UNDEF accesses to D16-D31 if they don't exist. */ | 109 | - /* UNDEF accesses to D16-D31 if they don't exist. */ |
110 | - if (!dc_isar_feature(aa32_simd_r32, s) && | 110 | - if (!dc_isar_feature(aa32_simd_r32, s) && |
111 | - ((a->vd | a->vm) & 0x10)) { | 111 | - ((a->vd | a->vm) & 0x10)) { |
112 | - return false; | 112 | - return false; |
113 | - } | 113 | - } |
114 | - | 114 | - |
115 | - if ((a->vd | a->vm) & a->q) { | 115 | - if ((a->vd | a->vm) & a->q) { |
116 | - return false; | 116 | - return false; |
117 | - } | 117 | - } |
118 | - | 118 | - |
119 | - if (a->size == 3) { | 119 | - if (a->size == 3) { |
120 | - return false; | 120 | - return false; |
121 | - } | 121 | - } |
122 | - | 122 | - |
123 | - if (!vfp_access_check(s)) { | 123 | - if (!vfp_access_check(s)) { |
124 | - return true; | 124 | - return true; |
125 | - } | 125 | - } |
126 | - | 126 | - |
127 | - tmp[0] = tcg_temp_new_i32(); | 127 | - tmp[0] = tcg_temp_new_i32(); |
128 | - tmp[1] = tcg_temp_new_i32(); | 128 | - tmp[1] = tcg_temp_new_i32(); |
129 | - | 129 | - |
130 | - for (pass = 0; pass < (a->q ? 2 : 1); pass++) { | 130 | - for (pass = 0; pass < (a->q ? 2 : 1); pass++) { |
131 | - for (half = 0; half < 2; half++) { | 131 | - for (half = 0; half < 2; half++) { |
132 | - read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32); | 132 | - read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32); |
133 | - switch (a->size) { | 133 | - switch (a->size) { |
134 | - case 0: | 134 | - case 0: |
135 | - tcg_gen_bswap32_i32(tmp[half], tmp[half]); | 135 | - tcg_gen_bswap32_i32(tmp[half], tmp[half]); |
136 | - break; | 136 | - break; |
137 | - case 1: | 137 | - case 1: |
138 | - gen_swap_half(tmp[half], tmp[half]); | 138 | - gen_swap_half(tmp[half], tmp[half]); |
139 | - break; | 139 | - break; |
140 | - case 2: | 140 | - case 2: |
141 | - break; | 141 | - break; |
142 | - default: | 142 | - default: |
143 | - g_assert_not_reached(); | 143 | - g_assert_not_reached(); |
144 | - } | 144 | - } |
145 | - } | 145 | - } |
146 | - write_neon_element32(tmp[1], a->vd, pass * 2, MO_32); | 146 | - write_neon_element32(tmp[1], a->vd, pass * 2, MO_32); |
147 | - write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32); | 147 | - write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32); |
148 | - } | 148 | - } |
149 | - return true; | 149 | - return true; |
150 | -} | 150 | -} |
151 | - | 151 | - |
152 | static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a, | 152 | static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a, |
153 | NeonGenWidenFn *widenfn, | 153 | NeonGenWidenFn *widenfn, |
154 | NeonGenTwo64OpFn *opfn, | 154 | NeonGenTwo64OpFn *opfn, |
155 | @@ -XXX,XX +XXX,XX @@ DO_2MISC_VEC(VCGE0, gen_gvec_cge0) | 155 | @@ -XXX,XX +XXX,XX @@ DO_2MISC_VEC(VCGE0, gen_gvec_cge0) |
156 | DO_2MISC_VEC(VCLT0, gen_gvec_clt0) | 156 | DO_2MISC_VEC(VCLT0, gen_gvec_clt0) |
157 | DO_2MISC_VEC(VCLS, gen_gvec_cls) | 157 | DO_2MISC_VEC(VCLS, gen_gvec_cls) |
158 | DO_2MISC_VEC(VCLZ, gen_gvec_clz) | 158 | DO_2MISC_VEC(VCLZ, gen_gvec_clz) |
159 | +DO_2MISC_VEC(VREV64, gen_gvec_rev64) | 159 | +DO_2MISC_VEC(VREV64, gen_gvec_rev64) |
160 | 160 | ||
161 | static bool trans_VMVN(DisasContext *s, arg_2misc *a) | 161 | static bool trans_VMVN(DisasContext *s, arg_2misc *a) |
162 | { | 162 | { |
163 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCNT(DisasContext *s, arg_2misc *a) | 163 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCNT(DisasContext *s, arg_2misc *a) |
164 | return do_2misc_vec(s, a, gen_gvec_cnt); | 164 | return do_2misc_vec(s, a, gen_gvec_cnt); |
165 | } | 165 | } |
166 | 166 | ||
167 | +static bool trans_VREV16(DisasContext *s, arg_2misc *a) | 167 | +static bool trans_VREV16(DisasContext *s, arg_2misc *a) |
168 | +{ | 168 | +{ |
169 | + if (a->size != 0) { | 169 | + if (a->size != 0) { |
170 | + return false; | 170 | + return false; |
171 | + } | 171 | + } |
172 | + return do_2misc_vec(s, a, gen_gvec_rev16); | 172 | + return do_2misc_vec(s, a, gen_gvec_rev16); |
173 | +} | 173 | +} |
174 | + | 174 | + |
175 | +static bool trans_VREV32(DisasContext *s, arg_2misc *a) | 175 | +static bool trans_VREV32(DisasContext *s, arg_2misc *a) |
176 | +{ | 176 | +{ |
177 | + if (a->size != 0 && a->size != 1) { | 177 | + if (a->size != 0 && a->size != 1) { |
178 | + return false; | 178 | + return false; |
179 | + } | 179 | + } |
180 | + return do_2misc_vec(s, a, gen_gvec_rev32); | 180 | + return do_2misc_vec(s, a, gen_gvec_rev32); |
181 | +} | 181 | +} |
182 | + | 182 | + |
183 | #define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \ | 183 | #define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \ |
184 | static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \ | 184 | static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \ |
185 | uint32_t rm_ofs, uint32_t oprsz, \ | 185 | uint32_t rm_ofs, uint32_t oprsz, \ |
186 | @@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn) | 186 | @@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn) |
187 | return true; | 187 | return true; |
188 | } | 188 | } |
189 | 189 | ||
190 | -static bool trans_VREV32(DisasContext *s, arg_2misc *a) | 190 | -static bool trans_VREV32(DisasContext *s, arg_2misc *a) |
191 | -{ | 191 | -{ |
192 | - static NeonGenOneOpFn * const fn[] = { | 192 | - static NeonGenOneOpFn * const fn[] = { |
193 | - tcg_gen_bswap32_i32, | 193 | - tcg_gen_bswap32_i32, |
194 | - gen_swap_half, | 194 | - gen_swap_half, |
195 | - NULL, | 195 | - NULL, |
196 | - NULL, | 196 | - NULL, |
197 | - }; | 197 | - }; |
198 | - return do_2misc(s, a, fn[a->size]); | 198 | - return do_2misc(s, a, fn[a->size]); |
199 | -} | 199 | -} |
200 | - | 200 | - |
201 | -static bool trans_VREV16(DisasContext *s, arg_2misc *a) | 201 | -static bool trans_VREV16(DisasContext *s, arg_2misc *a) |
202 | -{ | 202 | -{ |
203 | - if (a->size != 0) { | 203 | - if (a->size != 0) { |
204 | - return false; | 204 | - return false; |
205 | - } | 205 | - } |
206 | - return do_2misc(s, a, gen_rev16); | 206 | - return do_2misc(s, a, gen_rev16); |
207 | -} | 207 | -} |
208 | - | 208 | - |
209 | static void gen_VABS_F(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs, | 209 | static void gen_VABS_F(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs, |
210 | uint32_t oprsz, uint32_t maxsz) | 210 | uint32_t oprsz, uint32_t maxsz) |
211 | { | 211 | { |
212 | -- | 212 | -- |
213 | 2.43.0 | 213 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes REV16, REV32, REV64. | 1 | This includes REV16, REV32, REV64. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
3 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
4 | --- | 5 | --- |
5 | target/arm/tcg/translate-a64.c | 79 +++------------------------------- | 6 | target/arm/tcg/translate-a64.c | 79 +++------------------------------- |
6 | target/arm/tcg/a64.decode | 5 +++ | 7 | target/arm/tcg/a64.decode | 5 +++ |
7 | 2 files changed, 10 insertions(+), 74 deletions(-) | 8 | 2 files changed, 10 insertions(+), 74 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Move from helper-a64.c to neon_helper.c so that these | 1 | Move from helper-a64.c to neon_helper.c so that these |
---|---|---|---|
2 | functions are available for arm32 code as well. | 2 | functions are available for arm32 code as well. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/helper.h | 2 ++ | 7 | target/arm/helper.h | 2 ++ |
8 | target/arm/tcg/helper-a64.h | 2 -- | 8 | target/arm/tcg/helper-a64.h | 2 -- |
9 | target/arm/tcg/helper-a64.c | 43 ------------------------------------ | 9 | target/arm/tcg/helper-a64.c | 43 ------------------------------------ |
10 | target/arm/tcg/neon_helper.c | 43 ++++++++++++++++++++++++++++++++++++ | 10 | target/arm/tcg/neon_helper.c | 43 ++++++++++++++++++++++++++++++++++++ |
11 | 4 files changed, 45 insertions(+), 45 deletions(-) | 11 | 4 files changed, 45 insertions(+), 45 deletions(-) |
12 | 12 | ||
13 | diff --git a/target/arm/helper.h b/target/arm/helper.h | 13 | diff --git a/target/arm/helper.h b/target/arm/helper.h |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/target/arm/helper.h | 15 | --- a/target/arm/helper.h |
16 | +++ b/target/arm/helper.h | 16 | +++ b/target/arm/helper.h |
17 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_addl_u16, i64, i64, i64) | 17 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_addl_u16, i64, i64, i64) |
18 | DEF_HELPER_2(neon_addl_u32, i64, i64, i64) | 18 | DEF_HELPER_2(neon_addl_u32, i64, i64, i64) |
19 | DEF_HELPER_2(neon_paddl_u16, i64, i64, i64) | 19 | DEF_HELPER_2(neon_paddl_u16, i64, i64, i64) |
20 | DEF_HELPER_2(neon_paddl_u32, i64, i64, i64) | 20 | DEF_HELPER_2(neon_paddl_u32, i64, i64, i64) |
21 | +DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) | 21 | +DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) |
22 | +DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) | 22 | +DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) |
23 | DEF_HELPER_2(neon_subl_u16, i64, i64, i64) | 23 | DEF_HELPER_2(neon_subl_u16, i64, i64, i64) |
24 | DEF_HELPER_2(neon_subl_u32, i64, i64, i64) | 24 | DEF_HELPER_2(neon_subl_u32, i64, i64, i64) |
25 | DEF_HELPER_3(neon_addl_saturate_s32, i64, env, i64, i64) | 25 | DEF_HELPER_3(neon_addl_saturate_s32, i64, env, i64, i64) |
26 | diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h | 26 | diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h |
27 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/target/arm/tcg/helper-a64.h | 28 | --- a/target/arm/tcg/helper-a64.h |
29 | +++ b/target/arm/tcg/helper-a64.h | 29 | +++ b/target/arm/tcg/helper-a64.h |
30 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) | 30 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) |
31 | DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr) | 31 | DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr) |
32 | DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) | 32 | DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) |
33 | DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) | 33 | DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) |
34 | -DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) | 34 | -DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) |
35 | DEF_HELPER_FLAGS_1(neon_addlp_u8, TCG_CALL_NO_RWG_SE, i64, i64) | 35 | DEF_HELPER_FLAGS_1(neon_addlp_u8, TCG_CALL_NO_RWG_SE, i64, i64) |
36 | -DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) | 36 | -DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) |
37 | DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64) | 37 | DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64) |
38 | DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr) | 38 | DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr) |
39 | DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr) | 39 | DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr) |
40 | diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c | 40 | diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c |
41 | index XXXXXXX..XXXXXXX 100644 | 41 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/target/arm/tcg/helper-a64.c | 42 | --- a/target/arm/tcg/helper-a64.c |
43 | +++ b/target/arm/tcg/helper-a64.c | 43 | +++ b/target/arm/tcg/helper-a64.c |
44 | @@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, void *fpstp) | 44 | @@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, void *fpstp) |
45 | return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst); | 45 | return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst); |
46 | } | 46 | } |
47 | 47 | ||
48 | -/* Pairwise long add: add pairs of adjacent elements into | 48 | -/* Pairwise long add: add pairs of adjacent elements into |
49 | - * double-width elements in the result (eg _s8 is an 8x8->16 op) | 49 | - * double-width elements in the result (eg _s8 is an 8x8->16 op) |
50 | - */ | 50 | - */ |
51 | -uint64_t HELPER(neon_addlp_s8)(uint64_t a) | 51 | -uint64_t HELPER(neon_addlp_s8)(uint64_t a) |
52 | -{ | 52 | -{ |
53 | - uint64_t nsignmask = 0x0080008000800080ULL; | 53 | - uint64_t nsignmask = 0x0080008000800080ULL; |
54 | - uint64_t wsignmask = 0x8000800080008000ULL; | 54 | - uint64_t wsignmask = 0x8000800080008000ULL; |
55 | - uint64_t elementmask = 0x00ff00ff00ff00ffULL; | 55 | - uint64_t elementmask = 0x00ff00ff00ff00ffULL; |
56 | - uint64_t tmp1, tmp2; | 56 | - uint64_t tmp1, tmp2; |
57 | - uint64_t res, signres; | 57 | - uint64_t res, signres; |
58 | - | 58 | - |
59 | - /* Extract odd elements, sign extend each to a 16 bit field */ | 59 | - /* Extract odd elements, sign extend each to a 16 bit field */ |
60 | - tmp1 = a & elementmask; | 60 | - tmp1 = a & elementmask; |
61 | - tmp1 ^= nsignmask; | 61 | - tmp1 ^= nsignmask; |
62 | - tmp1 |= wsignmask; | 62 | - tmp1 |= wsignmask; |
63 | - tmp1 = (tmp1 - nsignmask) ^ wsignmask; | 63 | - tmp1 = (tmp1 - nsignmask) ^ wsignmask; |
64 | - /* Ditto for the even elements */ | 64 | - /* Ditto for the even elements */ |
65 | - tmp2 = (a >> 8) & elementmask; | 65 | - tmp2 = (a >> 8) & elementmask; |
66 | - tmp2 ^= nsignmask; | 66 | - tmp2 ^= nsignmask; |
67 | - tmp2 |= wsignmask; | 67 | - tmp2 |= wsignmask; |
68 | - tmp2 = (tmp2 - nsignmask) ^ wsignmask; | 68 | - tmp2 = (tmp2 - nsignmask) ^ wsignmask; |
69 | - | 69 | - |
70 | - /* calculate the result by summing bits 0..14, 16..22, etc, | 70 | - /* calculate the result by summing bits 0..14, 16..22, etc, |
71 | - * and then adjusting the sign bits 15, 23, etc manually. | 71 | - * and then adjusting the sign bits 15, 23, etc manually. |
72 | - * This ensures the addition can't overflow the 16 bit field. | 72 | - * This ensures the addition can't overflow the 16 bit field. |
73 | - */ | 73 | - */ |
74 | - signres = (tmp1 ^ tmp2) & wsignmask; | 74 | - signres = (tmp1 ^ tmp2) & wsignmask; |
75 | - res = (tmp1 & ~wsignmask) + (tmp2 & ~wsignmask); | 75 | - res = (tmp1 & ~wsignmask) + (tmp2 & ~wsignmask); |
76 | - res ^= signres; | 76 | - res ^= signres; |
77 | - | 77 | - |
78 | - return res; | 78 | - return res; |
79 | -} | 79 | -} |
80 | - | 80 | - |
81 | uint64_t HELPER(neon_addlp_u8)(uint64_t a) | 81 | uint64_t HELPER(neon_addlp_u8)(uint64_t a) |
82 | { | 82 | { |
83 | uint64_t tmp; | 83 | uint64_t tmp; |
84 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u8)(uint64_t a) | 84 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u8)(uint64_t a) |
85 | return tmp; | 85 | return tmp; |
86 | } | 86 | } |
87 | 87 | ||
88 | -uint64_t HELPER(neon_addlp_s16)(uint64_t a) | 88 | -uint64_t HELPER(neon_addlp_s16)(uint64_t a) |
89 | -{ | 89 | -{ |
90 | - int32_t reslo, reshi; | 90 | - int32_t reslo, reshi; |
91 | - | 91 | - |
92 | - reslo = (int32_t)(int16_t)a + (int32_t)(int16_t)(a >> 16); | 92 | - reslo = (int32_t)(int16_t)a + (int32_t)(int16_t)(a >> 16); |
93 | - reshi = (int32_t)(int16_t)(a >> 32) + (int32_t)(int16_t)(a >> 48); | 93 | - reshi = (int32_t)(int16_t)(a >> 32) + (int32_t)(int16_t)(a >> 48); |
94 | - | 94 | - |
95 | - return (uint32_t)reslo | (((uint64_t)reshi) << 32); | 95 | - return (uint32_t)reslo | (((uint64_t)reshi) << 32); |
96 | -} | 96 | -} |
97 | - | 97 | - |
98 | uint64_t HELPER(neon_addlp_u16)(uint64_t a) | 98 | uint64_t HELPER(neon_addlp_u16)(uint64_t a) |
99 | { | 99 | { |
100 | uint64_t tmp; | 100 | uint64_t tmp; |
101 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c | 101 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c |
102 | index XXXXXXX..XXXXXXX 100644 | 102 | index XXXXXXX..XXXXXXX 100644 |
103 | --- a/target/arm/tcg/neon_helper.c | 103 | --- a/target/arm/tcg/neon_helper.c |
104 | +++ b/target/arm/tcg/neon_helper.c | 104 | +++ b/target/arm/tcg/neon_helper.c |
105 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b) | 105 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b) |
106 | return low + ((uint64_t)high << 32); | 106 | return low + ((uint64_t)high << 32); |
107 | } | 107 | } |
108 | 108 | ||
109 | +/* Pairwise long add: add pairs of adjacent elements into | 109 | +/* Pairwise long add: add pairs of adjacent elements into |
110 | + * double-width elements in the result (eg _s8 is an 8x8->16 op) | 110 | + * double-width elements in the result (eg _s8 is an 8x8->16 op) |
111 | + */ | 111 | + */ |
112 | +uint64_t HELPER(neon_addlp_s8)(uint64_t a) | 112 | +uint64_t HELPER(neon_addlp_s8)(uint64_t a) |
113 | +{ | 113 | +{ |
114 | + uint64_t nsignmask = 0x0080008000800080ULL; | 114 | + uint64_t nsignmask = 0x0080008000800080ULL; |
115 | + uint64_t wsignmask = 0x8000800080008000ULL; | 115 | + uint64_t wsignmask = 0x8000800080008000ULL; |
116 | + uint64_t elementmask = 0x00ff00ff00ff00ffULL; | 116 | + uint64_t elementmask = 0x00ff00ff00ff00ffULL; |
117 | + uint64_t tmp1, tmp2; | 117 | + uint64_t tmp1, tmp2; |
118 | + uint64_t res, signres; | 118 | + uint64_t res, signres; |
119 | + | 119 | + |
120 | + /* Extract odd elements, sign extend each to a 16 bit field */ | 120 | + /* Extract odd elements, sign extend each to a 16 bit field */ |
121 | + tmp1 = a & elementmask; | 121 | + tmp1 = a & elementmask; |
122 | + tmp1 ^= nsignmask; | 122 | + tmp1 ^= nsignmask; |
123 | + tmp1 |= wsignmask; | 123 | + tmp1 |= wsignmask; |
124 | + tmp1 = (tmp1 - nsignmask) ^ wsignmask; | 124 | + tmp1 = (tmp1 - nsignmask) ^ wsignmask; |
125 | + /* Ditto for the even elements */ | 125 | + /* Ditto for the even elements */ |
126 | + tmp2 = (a >> 8) & elementmask; | 126 | + tmp2 = (a >> 8) & elementmask; |
127 | + tmp2 ^= nsignmask; | 127 | + tmp2 ^= nsignmask; |
128 | + tmp2 |= wsignmask; | 128 | + tmp2 |= wsignmask; |
129 | + tmp2 = (tmp2 - nsignmask) ^ wsignmask; | 129 | + tmp2 = (tmp2 - nsignmask) ^ wsignmask; |
130 | + | 130 | + |
131 | + /* calculate the result by summing bits 0..14, 16..22, etc, | 131 | + /* calculate the result by summing bits 0..14, 16..22, etc, |
132 | + * and then adjusting the sign bits 15, 23, etc manually. | 132 | + * and then adjusting the sign bits 15, 23, etc manually. |
133 | + * This ensures the addition can't overflow the 16 bit field. | 133 | + * This ensures the addition can't overflow the 16 bit field. |
134 | + */ | 134 | + */ |
135 | + signres = (tmp1 ^ tmp2) & wsignmask; | 135 | + signres = (tmp1 ^ tmp2) & wsignmask; |
136 | + res = (tmp1 & ~wsignmask) + (tmp2 & ~wsignmask); | 136 | + res = (tmp1 & ~wsignmask) + (tmp2 & ~wsignmask); |
137 | + res ^= signres; | 137 | + res ^= signres; |
138 | + | 138 | + |
139 | + return res; | 139 | + return res; |
140 | +} | 140 | +} |
141 | + | 141 | + |
142 | +uint64_t HELPER(neon_addlp_s16)(uint64_t a) | 142 | +uint64_t HELPER(neon_addlp_s16)(uint64_t a) |
143 | +{ | 143 | +{ |
144 | + int32_t reslo, reshi; | 144 | + int32_t reslo, reshi; |
145 | + | 145 | + |
146 | + reslo = (int32_t)(int16_t)a + (int32_t)(int16_t)(a >> 16); | 146 | + reslo = (int32_t)(int16_t)a + (int32_t)(int16_t)(a >> 16); |
147 | + reshi = (int32_t)(int16_t)(a >> 32) + (int32_t)(int16_t)(a >> 48); | 147 | + reshi = (int32_t)(int16_t)(a >> 32) + (int32_t)(int16_t)(a >> 48); |
148 | + | 148 | + |
149 | + return (uint32_t)reslo | (((uint64_t)reshi) << 32); | 149 | + return (uint32_t)reslo | (((uint64_t)reshi) << 32); |
150 | +} | 150 | +} |
151 | + | 151 | + |
152 | uint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b) | 152 | uint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b) |
153 | { | 153 | { |
154 | uint64_t mask; | 154 | uint64_t mask; |
155 | -- | 155 | -- |
156 | 2.43.0 | 156 | 2.43.0 | diff view generated by jsdifflib |
1 | Pairwise addition with and without accumulation. | 1 | Pairwise addition with and without accumulation. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/helper.h | 2 - | 6 | target/arm/helper.h | 2 - |
7 | target/arm/tcg/translate.h | 9 ++ | 7 | target/arm/tcg/translate.h | 9 ++ |
8 | target/arm/tcg/gengvec.c | 230 ++++++++++++++++++++++++++++++++ | 8 | target/arm/tcg/gengvec.c | 230 ++++++++++++++++++++++++++++++++ |
9 | target/arm/tcg/neon_helper.c | 22 --- | 9 | target/arm/tcg/neon_helper.c | 22 --- |
10 | target/arm/tcg/translate-neon.c | 150 +-------------------- | 10 | target/arm/tcg/translate-neon.c | 150 +-------------------- |
11 | 5 files changed, 243 insertions(+), 170 deletions(-) | 11 | 5 files changed, 243 insertions(+), 170 deletions(-) |
12 | 12 | ||
13 | diff --git a/target/arm/helper.h b/target/arm/helper.h | 13 | diff --git a/target/arm/helper.h b/target/arm/helper.h |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/target/arm/helper.h | 15 | --- a/target/arm/helper.h |
16 | +++ b/target/arm/helper.h | 16 | +++ b/target/arm/helper.h |
17 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(neon_widen_s16, i64, i32) | 17 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(neon_widen_s16, i64, i32) |
18 | 18 | ||
19 | DEF_HELPER_2(neon_addl_u16, i64, i64, i64) | 19 | DEF_HELPER_2(neon_addl_u16, i64, i64, i64) |
20 | DEF_HELPER_2(neon_addl_u32, i64, i64, i64) | 20 | DEF_HELPER_2(neon_addl_u32, i64, i64, i64) |
21 | -DEF_HELPER_2(neon_paddl_u16, i64, i64, i64) | 21 | -DEF_HELPER_2(neon_paddl_u16, i64, i64, i64) |
22 | -DEF_HELPER_2(neon_paddl_u32, i64, i64, i64) | 22 | -DEF_HELPER_2(neon_paddl_u32, i64, i64, i64) |
23 | DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) | 23 | DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) |
24 | DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) | 24 | DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) |
25 | DEF_HELPER_2(neon_subl_u16, i64, i64, i64) | 25 | DEF_HELPER_2(neon_subl_u16, i64, i64, i64) |
26 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h | 26 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h |
27 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/target/arm/tcg/translate.h | 28 | --- a/target/arm/tcg/translate.h |
29 | +++ b/target/arm/tcg/translate.h | 29 | +++ b/target/arm/tcg/translate.h |
30 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_rev32(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 30 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_rev32(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
31 | void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 31 | void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
32 | uint32_t opr_sz, uint32_t max_sz); | 32 | uint32_t opr_sz, uint32_t max_sz); |
33 | 33 | ||
34 | +void gen_gvec_saddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 34 | +void gen_gvec_saddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
35 | + uint32_t opr_sz, uint32_t max_sz); | 35 | + uint32_t opr_sz, uint32_t max_sz); |
36 | +void gen_gvec_sadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 36 | +void gen_gvec_sadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
37 | + uint32_t opr_sz, uint32_t max_sz); | 37 | + uint32_t opr_sz, uint32_t max_sz); |
38 | +void gen_gvec_uaddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 38 | +void gen_gvec_uaddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
39 | + uint32_t opr_sz, uint32_t max_sz); | 39 | + uint32_t opr_sz, uint32_t max_sz); |
40 | +void gen_gvec_uadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 40 | +void gen_gvec_uadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
41 | + uint32_t opr_sz, uint32_t max_sz); | 41 | + uint32_t opr_sz, uint32_t max_sz); |
42 | + | 42 | + |
43 | /* | 43 | /* |
44 | * Forward to the isar_feature_* tests given a DisasContext pointer. | 44 | * Forward to the isar_feature_* tests given a DisasContext pointer. |
45 | */ | 45 | */ |
46 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c | 46 | diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c |
47 | index XXXXXXX..XXXXXXX 100644 | 47 | index XXXXXXX..XXXXXXX 100644 |
48 | --- a/target/arm/tcg/gengvec.c | 48 | --- a/target/arm/tcg/gengvec.c |
49 | +++ b/target/arm/tcg/gengvec.c | 49 | +++ b/target/arm/tcg/gengvec.c |
50 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 50 | @@ -XXX,XX +XXX,XX @@ void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
51 | g_assert_not_reached(); | 51 | g_assert_not_reached(); |
52 | } | 52 | } |
53 | } | 53 | } |
54 | + | 54 | + |
55 | +static void gen_saddlp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) | 55 | +static void gen_saddlp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) |
56 | +{ | 56 | +{ |
57 | + int half = 4 << vece; | 57 | + int half = 4 << vece; |
58 | + TCGv_vec t = tcg_temp_new_vec_matching(d); | 58 | + TCGv_vec t = tcg_temp_new_vec_matching(d); |
59 | + | 59 | + |
60 | + tcg_gen_shli_vec(vece, t, n, half); | 60 | + tcg_gen_shli_vec(vece, t, n, half); |
61 | + tcg_gen_sari_vec(vece, d, n, half); | 61 | + tcg_gen_sari_vec(vece, d, n, half); |
62 | + tcg_gen_sari_vec(vece, t, t, half); | 62 | + tcg_gen_sari_vec(vece, t, t, half); |
63 | + tcg_gen_add_vec(vece, d, d, t); | 63 | + tcg_gen_add_vec(vece, d, d, t); |
64 | +} | 64 | +} |
65 | + | 65 | + |
66 | +static void gen_saddlp_s_i64(TCGv_i64 d, TCGv_i64 n) | 66 | +static void gen_saddlp_s_i64(TCGv_i64 d, TCGv_i64 n) |
67 | +{ | 67 | +{ |
68 | + TCGv_i64 t = tcg_temp_new_i64(); | 68 | + TCGv_i64 t = tcg_temp_new_i64(); |
69 | + | 69 | + |
70 | + tcg_gen_ext32s_i64(t, n); | 70 | + tcg_gen_ext32s_i64(t, n); |
71 | + tcg_gen_sari_i64(d, n, 32); | 71 | + tcg_gen_sari_i64(d, n, 32); |
72 | + tcg_gen_add_i64(d, d, t); | 72 | + tcg_gen_add_i64(d, d, t); |
73 | +} | 73 | +} |
74 | + | 74 | + |
75 | +void gen_gvec_saddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 75 | +void gen_gvec_saddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
76 | + uint32_t opr_sz, uint32_t max_sz) | 76 | + uint32_t opr_sz, uint32_t max_sz) |
77 | +{ | 77 | +{ |
78 | + static const TCGOpcode vecop_list[] = { | 78 | + static const TCGOpcode vecop_list[] = { |
79 | + INDEX_op_sari_vec, INDEX_op_shli_vec, INDEX_op_add_vec, 0 | 79 | + INDEX_op_sari_vec, INDEX_op_shli_vec, INDEX_op_add_vec, 0 |
80 | + }; | 80 | + }; |
81 | + static const GVecGen2 g[] = { | 81 | + static const GVecGen2 g[] = { |
82 | + { .fniv = gen_saddlp_vec, | 82 | + { .fniv = gen_saddlp_vec, |
83 | + .fni8 = gen_helper_neon_addlp_s8, | 83 | + .fni8 = gen_helper_neon_addlp_s8, |
84 | + .opt_opc = vecop_list, | 84 | + .opt_opc = vecop_list, |
85 | + .vece = MO_16 }, | 85 | + .vece = MO_16 }, |
86 | + { .fniv = gen_saddlp_vec, | 86 | + { .fniv = gen_saddlp_vec, |
87 | + .fni8 = gen_helper_neon_addlp_s16, | 87 | + .fni8 = gen_helper_neon_addlp_s16, |
88 | + .opt_opc = vecop_list, | 88 | + .opt_opc = vecop_list, |
89 | + .vece = MO_32 }, | 89 | + .vece = MO_32 }, |
90 | + { .fniv = gen_saddlp_vec, | 90 | + { .fniv = gen_saddlp_vec, |
91 | + .fni8 = gen_saddlp_s_i64, | 91 | + .fni8 = gen_saddlp_s_i64, |
92 | + .opt_opc = vecop_list, | 92 | + .opt_opc = vecop_list, |
93 | + .vece = MO_64 }, | 93 | + .vece = MO_64 }, |
94 | + }; | 94 | + }; |
95 | + assert(vece <= MO_32); | 95 | + assert(vece <= MO_32); |
96 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 96 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
97 | +} | 97 | +} |
98 | + | 98 | + |
99 | +static void gen_sadalp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) | 99 | +static void gen_sadalp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) |
100 | +{ | 100 | +{ |
101 | + TCGv_vec t = tcg_temp_new_vec_matching(d); | 101 | + TCGv_vec t = tcg_temp_new_vec_matching(d); |
102 | + | 102 | + |
103 | + gen_saddlp_vec(vece, t, n); | 103 | + gen_saddlp_vec(vece, t, n); |
104 | + tcg_gen_add_vec(vece, d, d, t); | 104 | + tcg_gen_add_vec(vece, d, d, t); |
105 | +} | 105 | +} |
106 | + | 106 | + |
107 | +static void gen_sadalp_b_i64(TCGv_i64 d, TCGv_i64 n) | 107 | +static void gen_sadalp_b_i64(TCGv_i64 d, TCGv_i64 n) |
108 | +{ | 108 | +{ |
109 | + TCGv_i64 t = tcg_temp_new_i64(); | 109 | + TCGv_i64 t = tcg_temp_new_i64(); |
110 | + | 110 | + |
111 | + gen_helper_neon_addlp_s8(t, n); | 111 | + gen_helper_neon_addlp_s8(t, n); |
112 | + tcg_gen_vec_add16_i64(d, d, t); | 112 | + tcg_gen_vec_add16_i64(d, d, t); |
113 | +} | 113 | +} |
114 | + | 114 | + |
115 | +static void gen_sadalp_h_i64(TCGv_i64 d, TCGv_i64 n) | 115 | +static void gen_sadalp_h_i64(TCGv_i64 d, TCGv_i64 n) |
116 | +{ | 116 | +{ |
117 | + TCGv_i64 t = tcg_temp_new_i64(); | 117 | + TCGv_i64 t = tcg_temp_new_i64(); |
118 | + | 118 | + |
119 | + gen_helper_neon_addlp_s16(t, n); | 119 | + gen_helper_neon_addlp_s16(t, n); |
120 | + tcg_gen_vec_add32_i64(d, d, t); | 120 | + tcg_gen_vec_add32_i64(d, d, t); |
121 | +} | 121 | +} |
122 | + | 122 | + |
123 | +static void gen_sadalp_s_i64(TCGv_i64 d, TCGv_i64 n) | 123 | +static void gen_sadalp_s_i64(TCGv_i64 d, TCGv_i64 n) |
124 | +{ | 124 | +{ |
125 | + TCGv_i64 t = tcg_temp_new_i64(); | 125 | + TCGv_i64 t = tcg_temp_new_i64(); |
126 | + | 126 | + |
127 | + gen_saddlp_s_i64(t, n); | 127 | + gen_saddlp_s_i64(t, n); |
128 | + tcg_gen_add_i64(d, d, t); | 128 | + tcg_gen_add_i64(d, d, t); |
129 | +} | 129 | +} |
130 | + | 130 | + |
131 | +void gen_gvec_sadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 131 | +void gen_gvec_sadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
132 | + uint32_t opr_sz, uint32_t max_sz) | 132 | + uint32_t opr_sz, uint32_t max_sz) |
133 | +{ | 133 | +{ |
134 | + static const TCGOpcode vecop_list[] = { | 134 | + static const TCGOpcode vecop_list[] = { |
135 | + INDEX_op_sari_vec, INDEX_op_shli_vec, INDEX_op_add_vec, 0 | 135 | + INDEX_op_sari_vec, INDEX_op_shli_vec, INDEX_op_add_vec, 0 |
136 | + }; | 136 | + }; |
137 | + static const GVecGen2 g[] = { | 137 | + static const GVecGen2 g[] = { |
138 | + { .fniv = gen_sadalp_vec, | 138 | + { .fniv = gen_sadalp_vec, |
139 | + .fni8 = gen_sadalp_b_i64, | 139 | + .fni8 = gen_sadalp_b_i64, |
140 | + .opt_opc = vecop_list, | 140 | + .opt_opc = vecop_list, |
141 | + .load_dest = true, | 141 | + .load_dest = true, |
142 | + .vece = MO_16 }, | 142 | + .vece = MO_16 }, |
143 | + { .fniv = gen_sadalp_vec, | 143 | + { .fniv = gen_sadalp_vec, |
144 | + .fni8 = gen_sadalp_h_i64, | 144 | + .fni8 = gen_sadalp_h_i64, |
145 | + .opt_opc = vecop_list, | 145 | + .opt_opc = vecop_list, |
146 | + .load_dest = true, | 146 | + .load_dest = true, |
147 | + .vece = MO_32 }, | 147 | + .vece = MO_32 }, |
148 | + { .fniv = gen_sadalp_vec, | 148 | + { .fniv = gen_sadalp_vec, |
149 | + .fni8 = gen_sadalp_s_i64, | 149 | + .fni8 = gen_sadalp_s_i64, |
150 | + .opt_opc = vecop_list, | 150 | + .opt_opc = vecop_list, |
151 | + .load_dest = true, | 151 | + .load_dest = true, |
152 | + .vece = MO_64 }, | 152 | + .vece = MO_64 }, |
153 | + }; | 153 | + }; |
154 | + assert(vece <= MO_32); | 154 | + assert(vece <= MO_32); |
155 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 155 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
156 | +} | 156 | +} |
157 | + | 157 | + |
158 | +static void gen_uaddlp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) | 158 | +static void gen_uaddlp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) |
159 | +{ | 159 | +{ |
160 | + int half = 4 << vece; | 160 | + int half = 4 << vece; |
161 | + TCGv_vec t = tcg_temp_new_vec_matching(d); | 161 | + TCGv_vec t = tcg_temp_new_vec_matching(d); |
162 | + TCGv_vec m = tcg_constant_vec_matching(d, vece, MAKE_64BIT_MASK(0, half)); | 162 | + TCGv_vec m = tcg_constant_vec_matching(d, vece, MAKE_64BIT_MASK(0, half)); |
163 | + | 163 | + |
164 | + tcg_gen_shri_vec(vece, t, n, half); | 164 | + tcg_gen_shri_vec(vece, t, n, half); |
165 | + tcg_gen_and_vec(vece, d, n, m); | 165 | + tcg_gen_and_vec(vece, d, n, m); |
166 | + tcg_gen_add_vec(vece, d, d, t); | 166 | + tcg_gen_add_vec(vece, d, d, t); |
167 | +} | 167 | +} |
168 | + | 168 | + |
169 | +static void gen_uaddlp_b_i64(TCGv_i64 d, TCGv_i64 n) | 169 | +static void gen_uaddlp_b_i64(TCGv_i64 d, TCGv_i64 n) |
170 | +{ | 170 | +{ |
171 | + TCGv_i64 t = tcg_temp_new_i64(); | 171 | + TCGv_i64 t = tcg_temp_new_i64(); |
172 | + TCGv_i64 m = tcg_constant_i64(dup_const(MO_16, 0xff)); | 172 | + TCGv_i64 m = tcg_constant_i64(dup_const(MO_16, 0xff)); |
173 | + | 173 | + |
174 | + tcg_gen_shri_i64(t, n, 8); | 174 | + tcg_gen_shri_i64(t, n, 8); |
175 | + tcg_gen_and_i64(d, n, m); | 175 | + tcg_gen_and_i64(d, n, m); |
176 | + tcg_gen_and_i64(t, t, m); | 176 | + tcg_gen_and_i64(t, t, m); |
177 | + /* No carry between widened unsigned elements. */ | 177 | + /* No carry between widened unsigned elements. */ |
178 | + tcg_gen_add_i64(d, d, t); | 178 | + tcg_gen_add_i64(d, d, t); |
179 | +} | 179 | +} |
180 | + | 180 | + |
181 | +static void gen_uaddlp_h_i64(TCGv_i64 d, TCGv_i64 n) | 181 | +static void gen_uaddlp_h_i64(TCGv_i64 d, TCGv_i64 n) |
182 | +{ | 182 | +{ |
183 | + TCGv_i64 t = tcg_temp_new_i64(); | 183 | + TCGv_i64 t = tcg_temp_new_i64(); |
184 | + TCGv_i64 m = tcg_constant_i64(dup_const(MO_32, 0xffff)); | 184 | + TCGv_i64 m = tcg_constant_i64(dup_const(MO_32, 0xffff)); |
185 | + | 185 | + |
186 | + tcg_gen_shri_i64(t, n, 16); | 186 | + tcg_gen_shri_i64(t, n, 16); |
187 | + tcg_gen_and_i64(d, n, m); | 187 | + tcg_gen_and_i64(d, n, m); |
188 | + tcg_gen_and_i64(t, t, m); | 188 | + tcg_gen_and_i64(t, t, m); |
189 | + /* No carry between widened unsigned elements. */ | 189 | + /* No carry between widened unsigned elements. */ |
190 | + tcg_gen_add_i64(d, d, t); | 190 | + tcg_gen_add_i64(d, d, t); |
191 | +} | 191 | +} |
192 | + | 192 | + |
193 | +static void gen_uaddlp_s_i64(TCGv_i64 d, TCGv_i64 n) | 193 | +static void gen_uaddlp_s_i64(TCGv_i64 d, TCGv_i64 n) |
194 | +{ | 194 | +{ |
195 | + TCGv_i64 t = tcg_temp_new_i64(); | 195 | + TCGv_i64 t = tcg_temp_new_i64(); |
196 | + | 196 | + |
197 | + tcg_gen_ext32u_i64(t, n); | 197 | + tcg_gen_ext32u_i64(t, n); |
198 | + tcg_gen_shri_i64(d, n, 32); | 198 | + tcg_gen_shri_i64(d, n, 32); |
199 | + tcg_gen_add_i64(d, d, t); | 199 | + tcg_gen_add_i64(d, d, t); |
200 | +} | 200 | +} |
201 | + | 201 | + |
202 | +void gen_gvec_uaddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 202 | +void gen_gvec_uaddlp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
203 | + uint32_t opr_sz, uint32_t max_sz) | 203 | + uint32_t opr_sz, uint32_t max_sz) |
204 | +{ | 204 | +{ |
205 | + static const TCGOpcode vecop_list[] = { | 205 | + static const TCGOpcode vecop_list[] = { |
206 | + INDEX_op_shri_vec, INDEX_op_add_vec, 0 | 206 | + INDEX_op_shri_vec, INDEX_op_add_vec, 0 |
207 | + }; | 207 | + }; |
208 | + static const GVecGen2 g[] = { | 208 | + static const GVecGen2 g[] = { |
209 | + { .fniv = gen_uaddlp_vec, | 209 | + { .fniv = gen_uaddlp_vec, |
210 | + .fni8 = gen_uaddlp_b_i64, | 210 | + .fni8 = gen_uaddlp_b_i64, |
211 | + .opt_opc = vecop_list, | 211 | + .opt_opc = vecop_list, |
212 | + .vece = MO_16 }, | 212 | + .vece = MO_16 }, |
213 | + { .fniv = gen_uaddlp_vec, | 213 | + { .fniv = gen_uaddlp_vec, |
214 | + .fni8 = gen_uaddlp_h_i64, | 214 | + .fni8 = gen_uaddlp_h_i64, |
215 | + .opt_opc = vecop_list, | 215 | + .opt_opc = vecop_list, |
216 | + .vece = MO_32 }, | 216 | + .vece = MO_32 }, |
217 | + { .fniv = gen_uaddlp_vec, | 217 | + { .fniv = gen_uaddlp_vec, |
218 | + .fni8 = gen_uaddlp_s_i64, | 218 | + .fni8 = gen_uaddlp_s_i64, |
219 | + .opt_opc = vecop_list, | 219 | + .opt_opc = vecop_list, |
220 | + .vece = MO_64 }, | 220 | + .vece = MO_64 }, |
221 | + }; | 221 | + }; |
222 | + assert(vece <= MO_32); | 222 | + assert(vece <= MO_32); |
223 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 223 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
224 | +} | 224 | +} |
225 | + | 225 | + |
226 | +static void gen_uadalp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) | 226 | +static void gen_uadalp_vec(unsigned vece, TCGv_vec d, TCGv_vec n) |
227 | +{ | 227 | +{ |
228 | + TCGv_vec t = tcg_temp_new_vec_matching(d); | 228 | + TCGv_vec t = tcg_temp_new_vec_matching(d); |
229 | + | 229 | + |
230 | + gen_uaddlp_vec(vece, t, n); | 230 | + gen_uaddlp_vec(vece, t, n); |
231 | + tcg_gen_add_vec(vece, d, d, t); | 231 | + tcg_gen_add_vec(vece, d, d, t); |
232 | +} | 232 | +} |
233 | + | 233 | + |
234 | +static void gen_uadalp_b_i64(TCGv_i64 d, TCGv_i64 n) | 234 | +static void gen_uadalp_b_i64(TCGv_i64 d, TCGv_i64 n) |
235 | +{ | 235 | +{ |
236 | + TCGv_i64 t = tcg_temp_new_i64(); | 236 | + TCGv_i64 t = tcg_temp_new_i64(); |
237 | + | 237 | + |
238 | + gen_uaddlp_b_i64(t, n); | 238 | + gen_uaddlp_b_i64(t, n); |
239 | + tcg_gen_vec_add16_i64(d, d, t); | 239 | + tcg_gen_vec_add16_i64(d, d, t); |
240 | +} | 240 | +} |
241 | + | 241 | + |
242 | +static void gen_uadalp_h_i64(TCGv_i64 d, TCGv_i64 n) | 242 | +static void gen_uadalp_h_i64(TCGv_i64 d, TCGv_i64 n) |
243 | +{ | 243 | +{ |
244 | + TCGv_i64 t = tcg_temp_new_i64(); | 244 | + TCGv_i64 t = tcg_temp_new_i64(); |
245 | + | 245 | + |
246 | + gen_uaddlp_h_i64(t, n); | 246 | + gen_uaddlp_h_i64(t, n); |
247 | + tcg_gen_vec_add32_i64(d, d, t); | 247 | + tcg_gen_vec_add32_i64(d, d, t); |
248 | +} | 248 | +} |
249 | + | 249 | + |
250 | +static void gen_uadalp_s_i64(TCGv_i64 d, TCGv_i64 n) | 250 | +static void gen_uadalp_s_i64(TCGv_i64 d, TCGv_i64 n) |
251 | +{ | 251 | +{ |
252 | + TCGv_i64 t = tcg_temp_new_i64(); | 252 | + TCGv_i64 t = tcg_temp_new_i64(); |
253 | + | 253 | + |
254 | + gen_uaddlp_s_i64(t, n); | 254 | + gen_uaddlp_s_i64(t, n); |
255 | + tcg_gen_add_i64(d, d, t); | 255 | + tcg_gen_add_i64(d, d, t); |
256 | +} | 256 | +} |
257 | + | 257 | + |
258 | +void gen_gvec_uadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, | 258 | +void gen_gvec_uadalp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, |
259 | + uint32_t opr_sz, uint32_t max_sz) | 259 | + uint32_t opr_sz, uint32_t max_sz) |
260 | +{ | 260 | +{ |
261 | + static const TCGOpcode vecop_list[] = { | 261 | + static const TCGOpcode vecop_list[] = { |
262 | + INDEX_op_shri_vec, INDEX_op_add_vec, 0 | 262 | + INDEX_op_shri_vec, INDEX_op_add_vec, 0 |
263 | + }; | 263 | + }; |
264 | + static const GVecGen2 g[] = { | 264 | + static const GVecGen2 g[] = { |
265 | + { .fniv = gen_uadalp_vec, | 265 | + { .fniv = gen_uadalp_vec, |
266 | + .fni8 = gen_uadalp_b_i64, | 266 | + .fni8 = gen_uadalp_b_i64, |
267 | + .load_dest = true, | 267 | + .load_dest = true, |
268 | + .opt_opc = vecop_list, | 268 | + .opt_opc = vecop_list, |
269 | + .vece = MO_16 }, | 269 | + .vece = MO_16 }, |
270 | + { .fniv = gen_uadalp_vec, | 270 | + { .fniv = gen_uadalp_vec, |
271 | + .fni8 = gen_uadalp_h_i64, | 271 | + .fni8 = gen_uadalp_h_i64, |
272 | + .load_dest = true, | 272 | + .load_dest = true, |
273 | + .opt_opc = vecop_list, | 273 | + .opt_opc = vecop_list, |
274 | + .vece = MO_32 }, | 274 | + .vece = MO_32 }, |
275 | + { .fniv = gen_uadalp_vec, | 275 | + { .fniv = gen_uadalp_vec, |
276 | + .fni8 = gen_uadalp_s_i64, | 276 | + .fni8 = gen_uadalp_s_i64, |
277 | + .load_dest = true, | 277 | + .load_dest = true, |
278 | + .opt_opc = vecop_list, | 278 | + .opt_opc = vecop_list, |
279 | + .vece = MO_64 }, | 279 | + .vece = MO_64 }, |
280 | + }; | 280 | + }; |
281 | + assert(vece <= MO_32); | 281 | + assert(vece <= MO_32); |
282 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); | 282 | + tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]); |
283 | +} | 283 | +} |
284 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c | 284 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c |
285 | index XXXXXXX..XXXXXXX 100644 | 285 | index XXXXXXX..XXXXXXX 100644 |
286 | --- a/target/arm/tcg/neon_helper.c | 286 | --- a/target/arm/tcg/neon_helper.c |
287 | +++ b/target/arm/tcg/neon_helper.c | 287 | +++ b/target/arm/tcg/neon_helper.c |
288 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b) | 288 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b) |
289 | return (a + b) ^ mask; | 289 | return (a + b) ^ mask; |
290 | } | 290 | } |
291 | 291 | ||
292 | -uint64_t HELPER(neon_paddl_u16)(uint64_t a, uint64_t b) | 292 | -uint64_t HELPER(neon_paddl_u16)(uint64_t a, uint64_t b) |
293 | -{ | 293 | -{ |
294 | - uint64_t tmp; | 294 | - uint64_t tmp; |
295 | - uint64_t tmp2; | 295 | - uint64_t tmp2; |
296 | - | 296 | - |
297 | - tmp = a & 0x0000ffff0000ffffull; | 297 | - tmp = a & 0x0000ffff0000ffffull; |
298 | - tmp += (a >> 16) & 0x0000ffff0000ffffull; | 298 | - tmp += (a >> 16) & 0x0000ffff0000ffffull; |
299 | - tmp2 = b & 0xffff0000ffff0000ull; | 299 | - tmp2 = b & 0xffff0000ffff0000ull; |
300 | - tmp2 += (b << 16) & 0xffff0000ffff0000ull; | 300 | - tmp2 += (b << 16) & 0xffff0000ffff0000ull; |
301 | - return ( tmp & 0xffff) | 301 | - return ( tmp & 0xffff) |
302 | - | ((tmp >> 16) & 0xffff0000ull) | 302 | - | ((tmp >> 16) & 0xffff0000ull) |
303 | - | ((tmp2 << 16) & 0xffff00000000ull) | 303 | - | ((tmp2 << 16) & 0xffff00000000ull) |
304 | - | ( tmp2 & 0xffff000000000000ull); | 304 | - | ( tmp2 & 0xffff000000000000ull); |
305 | -} | 305 | -} |
306 | - | 306 | - |
307 | -uint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b) | 307 | -uint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b) |
308 | -{ | 308 | -{ |
309 | - uint32_t low = a + (a >> 32); | 309 | - uint32_t low = a + (a >> 32); |
310 | - uint32_t high = b + (b >> 32); | 310 | - uint32_t high = b + (b >> 32); |
311 | - return low + ((uint64_t)high << 32); | 311 | - return low + ((uint64_t)high << 32); |
312 | -} | 312 | -} |
313 | - | 313 | - |
314 | /* Pairwise long add: add pairs of adjacent elements into | 314 | /* Pairwise long add: add pairs of adjacent elements into |
315 | * double-width elements in the result (eg _s8 is an 8x8->16 op) | 315 | * double-width elements in the result (eg _s8 is an 8x8->16 op) |
316 | */ | 316 | */ |
317 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c | 317 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c |
318 | index XXXXXXX..XXXXXXX 100644 | 318 | index XXXXXXX..XXXXXXX 100644 |
319 | --- a/target/arm/tcg/translate-neon.c | 319 | --- a/target/arm/tcg/translate-neon.c |
320 | +++ b/target/arm/tcg/translate-neon.c | 320 | +++ b/target/arm/tcg/translate-neon.c |
321 | @@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a) | 321 | @@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a) |
322 | return true; | 322 | return true; |
323 | } | 323 | } |
324 | 324 | ||
325 | -static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a, | 325 | -static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a, |
326 | - NeonGenWidenFn *widenfn, | 326 | - NeonGenWidenFn *widenfn, |
327 | - NeonGenTwo64OpFn *opfn, | 327 | - NeonGenTwo64OpFn *opfn, |
328 | - NeonGenTwo64OpFn *accfn) | 328 | - NeonGenTwo64OpFn *accfn) |
329 | -{ | 329 | -{ |
330 | - /* | 330 | - /* |
331 | - * Pairwise long operations: widen both halves of the pair, | 331 | - * Pairwise long operations: widen both halves of the pair, |
332 | - * combine the pairs with the opfn, and then possibly accumulate | 332 | - * combine the pairs with the opfn, and then possibly accumulate |
333 | - * into the destination with the accfn. | 333 | - * into the destination with the accfn. |
334 | - */ | 334 | - */ |
335 | - int pass; | 335 | - int pass; |
336 | - | 336 | - |
337 | - if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { | 337 | - if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { |
338 | - return false; | 338 | - return false; |
339 | - } | 339 | - } |
340 | - | 340 | - |
341 | - /* UNDEF accesses to D16-D31 if they don't exist. */ | 341 | - /* UNDEF accesses to D16-D31 if they don't exist. */ |
342 | - if (!dc_isar_feature(aa32_simd_r32, s) && | 342 | - if (!dc_isar_feature(aa32_simd_r32, s) && |
343 | - ((a->vd | a->vm) & 0x10)) { | 343 | - ((a->vd | a->vm) & 0x10)) { |
344 | - return false; | 344 | - return false; |
345 | - } | 345 | - } |
346 | - | 346 | - |
347 | - if ((a->vd | a->vm) & a->q) { | 347 | - if ((a->vd | a->vm) & a->q) { |
348 | - return false; | 348 | - return false; |
349 | - } | 349 | - } |
350 | - | 350 | - |
351 | - if (!widenfn) { | 351 | - if (!widenfn) { |
352 | - return false; | 352 | - return false; |
353 | - } | 353 | - } |
354 | - | 354 | - |
355 | - if (!vfp_access_check(s)) { | 355 | - if (!vfp_access_check(s)) { |
356 | - return true; | 356 | - return true; |
357 | - } | 357 | - } |
358 | - | 358 | - |
359 | - for (pass = 0; pass < a->q + 1; pass++) { | 359 | - for (pass = 0; pass < a->q + 1; pass++) { |
360 | - TCGv_i32 tmp; | 360 | - TCGv_i32 tmp; |
361 | - TCGv_i64 rm0_64, rm1_64, rd_64; | 361 | - TCGv_i64 rm0_64, rm1_64, rd_64; |
362 | - | 362 | - |
363 | - rm0_64 = tcg_temp_new_i64(); | 363 | - rm0_64 = tcg_temp_new_i64(); |
364 | - rm1_64 = tcg_temp_new_i64(); | 364 | - rm1_64 = tcg_temp_new_i64(); |
365 | - rd_64 = tcg_temp_new_i64(); | 365 | - rd_64 = tcg_temp_new_i64(); |
366 | - | 366 | - |
367 | - tmp = tcg_temp_new_i32(); | 367 | - tmp = tcg_temp_new_i32(); |
368 | - read_neon_element32(tmp, a->vm, pass * 2, MO_32); | 368 | - read_neon_element32(tmp, a->vm, pass * 2, MO_32); |
369 | - widenfn(rm0_64, tmp); | 369 | - widenfn(rm0_64, tmp); |
370 | - read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32); | 370 | - read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32); |
371 | - widenfn(rm1_64, tmp); | 371 | - widenfn(rm1_64, tmp); |
372 | - | 372 | - |
373 | - opfn(rd_64, rm0_64, rm1_64); | 373 | - opfn(rd_64, rm0_64, rm1_64); |
374 | - | 374 | - |
375 | - if (accfn) { | 375 | - if (accfn) { |
376 | - TCGv_i64 tmp64 = tcg_temp_new_i64(); | 376 | - TCGv_i64 tmp64 = tcg_temp_new_i64(); |
377 | - read_neon_element64(tmp64, a->vd, pass, MO_64); | 377 | - read_neon_element64(tmp64, a->vd, pass, MO_64); |
378 | - accfn(rd_64, tmp64, rd_64); | 378 | - accfn(rd_64, tmp64, rd_64); |
379 | - } | 379 | - } |
380 | - write_neon_element64(rd_64, a->vd, pass, MO_64); | 380 | - write_neon_element64(rd_64, a->vd, pass, MO_64); |
381 | - } | 381 | - } |
382 | - return true; | 382 | - return true; |
383 | -} | 383 | -} |
384 | - | 384 | - |
385 | -static bool trans_VPADDL_S(DisasContext *s, arg_2misc *a) | 385 | -static bool trans_VPADDL_S(DisasContext *s, arg_2misc *a) |
386 | -{ | 386 | -{ |
387 | - static NeonGenWidenFn * const widenfn[] = { | 387 | - static NeonGenWidenFn * const widenfn[] = { |
388 | - gen_helper_neon_widen_s8, | 388 | - gen_helper_neon_widen_s8, |
389 | - gen_helper_neon_widen_s16, | 389 | - gen_helper_neon_widen_s16, |
390 | - tcg_gen_ext_i32_i64, | 390 | - tcg_gen_ext_i32_i64, |
391 | - NULL, | 391 | - NULL, |
392 | - }; | 392 | - }; |
393 | - static NeonGenTwo64OpFn * const opfn[] = { | 393 | - static NeonGenTwo64OpFn * const opfn[] = { |
394 | - gen_helper_neon_paddl_u16, | 394 | - gen_helper_neon_paddl_u16, |
395 | - gen_helper_neon_paddl_u32, | 395 | - gen_helper_neon_paddl_u32, |
396 | - tcg_gen_add_i64, | 396 | - tcg_gen_add_i64, |
397 | - NULL, | 397 | - NULL, |
398 | - }; | 398 | - }; |
399 | - | 399 | - |
400 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL); | 400 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL); |
401 | -} | 401 | -} |
402 | - | 402 | - |
403 | -static bool trans_VPADDL_U(DisasContext *s, arg_2misc *a) | 403 | -static bool trans_VPADDL_U(DisasContext *s, arg_2misc *a) |
404 | -{ | 404 | -{ |
405 | - static NeonGenWidenFn * const widenfn[] = { | 405 | - static NeonGenWidenFn * const widenfn[] = { |
406 | - gen_helper_neon_widen_u8, | 406 | - gen_helper_neon_widen_u8, |
407 | - gen_helper_neon_widen_u16, | 407 | - gen_helper_neon_widen_u16, |
408 | - tcg_gen_extu_i32_i64, | 408 | - tcg_gen_extu_i32_i64, |
409 | - NULL, | 409 | - NULL, |
410 | - }; | 410 | - }; |
411 | - static NeonGenTwo64OpFn * const opfn[] = { | 411 | - static NeonGenTwo64OpFn * const opfn[] = { |
412 | - gen_helper_neon_paddl_u16, | 412 | - gen_helper_neon_paddl_u16, |
413 | - gen_helper_neon_paddl_u32, | 413 | - gen_helper_neon_paddl_u32, |
414 | - tcg_gen_add_i64, | 414 | - tcg_gen_add_i64, |
415 | - NULL, | 415 | - NULL, |
416 | - }; | 416 | - }; |
417 | - | 417 | - |
418 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL); | 418 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL); |
419 | -} | 419 | -} |
420 | - | 420 | - |
421 | -static bool trans_VPADAL_S(DisasContext *s, arg_2misc *a) | 421 | -static bool trans_VPADAL_S(DisasContext *s, arg_2misc *a) |
422 | -{ | 422 | -{ |
423 | - static NeonGenWidenFn * const widenfn[] = { | 423 | - static NeonGenWidenFn * const widenfn[] = { |
424 | - gen_helper_neon_widen_s8, | 424 | - gen_helper_neon_widen_s8, |
425 | - gen_helper_neon_widen_s16, | 425 | - gen_helper_neon_widen_s16, |
426 | - tcg_gen_ext_i32_i64, | 426 | - tcg_gen_ext_i32_i64, |
427 | - NULL, | 427 | - NULL, |
428 | - }; | 428 | - }; |
429 | - static NeonGenTwo64OpFn * const opfn[] = { | 429 | - static NeonGenTwo64OpFn * const opfn[] = { |
430 | - gen_helper_neon_paddl_u16, | 430 | - gen_helper_neon_paddl_u16, |
431 | - gen_helper_neon_paddl_u32, | 431 | - gen_helper_neon_paddl_u32, |
432 | - tcg_gen_add_i64, | 432 | - tcg_gen_add_i64, |
433 | - NULL, | 433 | - NULL, |
434 | - }; | 434 | - }; |
435 | - static NeonGenTwo64OpFn * const accfn[] = { | 435 | - static NeonGenTwo64OpFn * const accfn[] = { |
436 | - gen_helper_neon_addl_u16, | 436 | - gen_helper_neon_addl_u16, |
437 | - gen_helper_neon_addl_u32, | 437 | - gen_helper_neon_addl_u32, |
438 | - tcg_gen_add_i64, | 438 | - tcg_gen_add_i64, |
439 | - NULL, | 439 | - NULL, |
440 | - }; | 440 | - }; |
441 | - | 441 | - |
442 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], | 442 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], |
443 | - accfn[a->size]); | 443 | - accfn[a->size]); |
444 | -} | 444 | -} |
445 | - | 445 | - |
446 | -static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a) | 446 | -static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a) |
447 | -{ | 447 | -{ |
448 | - static NeonGenWidenFn * const widenfn[] = { | 448 | - static NeonGenWidenFn * const widenfn[] = { |
449 | - gen_helper_neon_widen_u8, | 449 | - gen_helper_neon_widen_u8, |
450 | - gen_helper_neon_widen_u16, | 450 | - gen_helper_neon_widen_u16, |
451 | - tcg_gen_extu_i32_i64, | 451 | - tcg_gen_extu_i32_i64, |
452 | - NULL, | 452 | - NULL, |
453 | - }; | 453 | - }; |
454 | - static NeonGenTwo64OpFn * const opfn[] = { | 454 | - static NeonGenTwo64OpFn * const opfn[] = { |
455 | - gen_helper_neon_paddl_u16, | 455 | - gen_helper_neon_paddl_u16, |
456 | - gen_helper_neon_paddl_u32, | 456 | - gen_helper_neon_paddl_u32, |
457 | - tcg_gen_add_i64, | 457 | - tcg_gen_add_i64, |
458 | - NULL, | 458 | - NULL, |
459 | - }; | 459 | - }; |
460 | - static NeonGenTwo64OpFn * const accfn[] = { | 460 | - static NeonGenTwo64OpFn * const accfn[] = { |
461 | - gen_helper_neon_addl_u16, | 461 | - gen_helper_neon_addl_u16, |
462 | - gen_helper_neon_addl_u32, | 462 | - gen_helper_neon_addl_u32, |
463 | - tcg_gen_add_i64, | 463 | - tcg_gen_add_i64, |
464 | - NULL, | 464 | - NULL, |
465 | - }; | 465 | - }; |
466 | - | 466 | - |
467 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], | 467 | - return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], |
468 | - accfn[a->size]); | 468 | - accfn[a->size]); |
469 | -} | 469 | -} |
470 | - | 470 | - |
471 | typedef void ZipFn(TCGv_ptr, TCGv_ptr); | 471 | typedef void ZipFn(TCGv_ptr, TCGv_ptr); |
472 | 472 | ||
473 | static bool do_zip_uzp(DisasContext *s, arg_2misc *a, | 473 | static bool do_zip_uzp(DisasContext *s, arg_2misc *a, |
474 | @@ -XXX,XX +XXX,XX @@ DO_2MISC_VEC(VCLT0, gen_gvec_clt0) | 474 | @@ -XXX,XX +XXX,XX @@ DO_2MISC_VEC(VCLT0, gen_gvec_clt0) |
475 | DO_2MISC_VEC(VCLS, gen_gvec_cls) | 475 | DO_2MISC_VEC(VCLS, gen_gvec_cls) |
476 | DO_2MISC_VEC(VCLZ, gen_gvec_clz) | 476 | DO_2MISC_VEC(VCLZ, gen_gvec_clz) |
477 | DO_2MISC_VEC(VREV64, gen_gvec_rev64) | 477 | DO_2MISC_VEC(VREV64, gen_gvec_rev64) |
478 | +DO_2MISC_VEC(VPADDL_S, gen_gvec_saddlp) | 478 | +DO_2MISC_VEC(VPADDL_S, gen_gvec_saddlp) |
479 | +DO_2MISC_VEC(VPADDL_U, gen_gvec_uaddlp) | 479 | +DO_2MISC_VEC(VPADDL_U, gen_gvec_uaddlp) |
480 | +DO_2MISC_VEC(VPADAL_S, gen_gvec_sadalp) | 480 | +DO_2MISC_VEC(VPADAL_S, gen_gvec_sadalp) |
481 | +DO_2MISC_VEC(VPADAL_U, gen_gvec_uadalp) | 481 | +DO_2MISC_VEC(VPADAL_U, gen_gvec_uadalp) |
482 | 482 | ||
483 | static bool trans_VMVN(DisasContext *s, arg_2misc *a) | 483 | static bool trans_VMVN(DisasContext *s, arg_2misc *a) |
484 | { | 484 | { |
485 | -- | 485 | -- |
486 | 2.43.0 | 486 | 2.43.0 | diff view generated by jsdifflib |
1 | This includes SADDLP, UADDLP, SADALP, UADALP. | 1 | This includes SADDLP, UADDLP, SADALP, UADALP. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/tcg/helper-a64.h | 2 - | 6 | target/arm/tcg/helper-a64.h | 2 - |
7 | target/arm/tcg/helper-a64.c | 18 -------- | 7 | target/arm/tcg/helper-a64.c | 18 -------- |
8 | target/arm/tcg/translate-a64.c | 84 +++------------------------------- | 8 | target/arm/tcg/translate-a64.c | 84 +++------------------------------- |
9 | target/arm/tcg/a64.decode | 5 ++ | 9 | target/arm/tcg/a64.decode | 5 ++ |
10 | 4 files changed, 11 insertions(+), 98 deletions(-) | 10 | 4 files changed, 11 insertions(+), 98 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h | 12 | diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/tcg/helper-a64.h | 14 | --- a/target/arm/tcg/helper-a64.h |
15 | +++ b/target/arm/tcg/helper-a64.h | 15 | +++ b/target/arm/tcg/helper-a64.h |
16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) | 16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) |
17 | DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr) | 17 | DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr) |
18 | DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) | 18 | DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) |
19 | DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) | 19 | DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) |
20 | -DEF_HELPER_FLAGS_1(neon_addlp_u8, TCG_CALL_NO_RWG_SE, i64, i64) | 20 | -DEF_HELPER_FLAGS_1(neon_addlp_u8, TCG_CALL_NO_RWG_SE, i64, i64) |
21 | -DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64) | 21 | -DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64) |
22 | DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr) | 22 | DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr) |
23 | DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr) | 23 | DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr) |
24 | DEF_HELPER_FLAGS_2(frecpx_f16, TCG_CALL_NO_RWG, f16, f16, ptr) | 24 | DEF_HELPER_FLAGS_2(frecpx_f16, TCG_CALL_NO_RWG, f16, f16, ptr) |
25 | diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c | 25 | diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c |
26 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
27 | --- a/target/arm/tcg/helper-a64.c | 27 | --- a/target/arm/tcg/helper-a64.c |
28 | +++ b/target/arm/tcg/helper-a64.c | 28 | +++ b/target/arm/tcg/helper-a64.c |
29 | @@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, void *fpstp) | 29 | @@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, void *fpstp) |
30 | return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst); | 30 | return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst); |
31 | } | 31 | } |
32 | 32 | ||
33 | -uint64_t HELPER(neon_addlp_u8)(uint64_t a) | 33 | -uint64_t HELPER(neon_addlp_u8)(uint64_t a) |
34 | -{ | 34 | -{ |
35 | - uint64_t tmp; | 35 | - uint64_t tmp; |
36 | - | 36 | - |
37 | - tmp = a & 0x00ff00ff00ff00ffULL; | 37 | - tmp = a & 0x00ff00ff00ff00ffULL; |
38 | - tmp += (a >> 8) & 0x00ff00ff00ff00ffULL; | 38 | - tmp += (a >> 8) & 0x00ff00ff00ff00ffULL; |
39 | - return tmp; | 39 | - return tmp; |
40 | -} | 40 | -} |
41 | - | 41 | - |
42 | -uint64_t HELPER(neon_addlp_u16)(uint64_t a) | 42 | -uint64_t HELPER(neon_addlp_u16)(uint64_t a) |
43 | -{ | 43 | -{ |
44 | - uint64_t tmp; | 44 | - uint64_t tmp; |
45 | - | 45 | - |
46 | - tmp = a & 0x0000ffff0000ffffULL; | 46 | - tmp = a & 0x0000ffff0000ffffULL; |
47 | - tmp += (a >> 16) & 0x0000ffff0000ffffULL; | 47 | - tmp += (a >> 16) & 0x0000ffff0000ffffULL; |
48 | - return tmp; | 48 | - return tmp; |
49 | -} | 49 | -} |
50 | - | 50 | - |
51 | /* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */ | 51 | /* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */ |
52 | uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp) | 52 | uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp) |
53 | { | 53 | { |
54 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 54 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
55 | index XXXXXXX..XXXXXXX 100644 | 55 | index XXXXXXX..XXXXXXX 100644 |
56 | --- a/target/arm/tcg/translate-a64.c | 56 | --- a/target/arm/tcg/translate-a64.c |
57 | +++ b/target/arm/tcg/translate-a64.c | 57 | +++ b/target/arm/tcg/translate-a64.c |
58 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 58 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_fn2_bhs(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
59 | TRANS(CLS_v, do_gvec_fn2_bhs, a, gen_gvec_cls) | 59 | TRANS(CLS_v, do_gvec_fn2_bhs, a, gen_gvec_cls) |
60 | TRANS(CLZ_v, do_gvec_fn2_bhs, a, gen_gvec_clz) | 60 | TRANS(CLZ_v, do_gvec_fn2_bhs, a, gen_gvec_clz) |
61 | TRANS(REV64_v, do_gvec_fn2_bhs, a, gen_gvec_rev64) | 61 | TRANS(REV64_v, do_gvec_fn2_bhs, a, gen_gvec_rev64) |
62 | +TRANS(SADDLP_v, do_gvec_fn2_bhs, a, gen_gvec_saddlp) | 62 | +TRANS(SADDLP_v, do_gvec_fn2_bhs, a, gen_gvec_saddlp) |
63 | +TRANS(UADDLP_v, do_gvec_fn2_bhs, a, gen_gvec_uaddlp) | 63 | +TRANS(UADDLP_v, do_gvec_fn2_bhs, a, gen_gvec_uaddlp) |
64 | +TRANS(SADALP_v, do_gvec_fn2_bhs, a, gen_gvec_sadalp) | 64 | +TRANS(SADALP_v, do_gvec_fn2_bhs, a, gen_gvec_sadalp) |
65 | +TRANS(UADALP_v, do_gvec_fn2_bhs, a, gen_gvec_uadalp) | 65 | +TRANS(UADALP_v, do_gvec_fn2_bhs, a, gen_gvec_uadalp) |
66 | 66 | ||
67 | /* Common vector code for handling integer to FP conversion */ | 67 | /* Common vector code for handling integer to FP conversion */ |
68 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 68 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
69 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, | 69 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | -static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u, | 73 | -static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u, |
74 | - bool is_q, int size, int rn, int rd) | 74 | - bool is_q, int size, int rn, int rd) |
75 | -{ | 75 | -{ |
76 | - /* Implement the pairwise operations from 2-misc: | 76 | - /* Implement the pairwise operations from 2-misc: |
77 | - * SADDLP, UADDLP, SADALP, UADALP. | 77 | - * SADDLP, UADDLP, SADALP, UADALP. |
78 | - * These all add pairs of elements in the input to produce a | 78 | - * These all add pairs of elements in the input to produce a |
79 | - * double-width result element in the output (possibly accumulating). | 79 | - * double-width result element in the output (possibly accumulating). |
80 | - */ | 80 | - */ |
81 | - bool accum = (opcode == 0x6); | 81 | - bool accum = (opcode == 0x6); |
82 | - int maxpass = is_q ? 2 : 1; | 82 | - int maxpass = is_q ? 2 : 1; |
83 | - int pass; | 83 | - int pass; |
84 | - TCGv_i64 tcg_res[2]; | 84 | - TCGv_i64 tcg_res[2]; |
85 | - | 85 | - |
86 | - if (size == 2) { | 86 | - if (size == 2) { |
87 | - /* 32 + 32 -> 64 op */ | 87 | - /* 32 + 32 -> 64 op */ |
88 | - MemOp memop = size + (u ? 0 : MO_SIGN); | 88 | - MemOp memop = size + (u ? 0 : MO_SIGN); |
89 | - | 89 | - |
90 | - for (pass = 0; pass < maxpass; pass++) { | 90 | - for (pass = 0; pass < maxpass; pass++) { |
91 | - TCGv_i64 tcg_op1 = tcg_temp_new_i64(); | 91 | - TCGv_i64 tcg_op1 = tcg_temp_new_i64(); |
92 | - TCGv_i64 tcg_op2 = tcg_temp_new_i64(); | 92 | - TCGv_i64 tcg_op2 = tcg_temp_new_i64(); |
93 | - | 93 | - |
94 | - tcg_res[pass] = tcg_temp_new_i64(); | 94 | - tcg_res[pass] = tcg_temp_new_i64(); |
95 | - | 95 | - |
96 | - read_vec_element(s, tcg_op1, rn, pass * 2, memop); | 96 | - read_vec_element(s, tcg_op1, rn, pass * 2, memop); |
97 | - read_vec_element(s, tcg_op2, rn, pass * 2 + 1, memop); | 97 | - read_vec_element(s, tcg_op2, rn, pass * 2 + 1, memop); |
98 | - tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2); | 98 | - tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2); |
99 | - if (accum) { | 99 | - if (accum) { |
100 | - read_vec_element(s, tcg_op1, rd, pass, MO_64); | 100 | - read_vec_element(s, tcg_op1, rd, pass, MO_64); |
101 | - tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_op1); | 101 | - tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_op1); |
102 | - } | 102 | - } |
103 | - } | 103 | - } |
104 | - } else { | 104 | - } else { |
105 | - for (pass = 0; pass < maxpass; pass++) { | 105 | - for (pass = 0; pass < maxpass; pass++) { |
106 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); | 106 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); |
107 | - NeonGenOne64OpFn *genfn; | 107 | - NeonGenOne64OpFn *genfn; |
108 | - static NeonGenOne64OpFn * const fns[2][2] = { | 108 | - static NeonGenOne64OpFn * const fns[2][2] = { |
109 | - { gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 }, | 109 | - { gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 }, |
110 | - { gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 }, | 110 | - { gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 }, |
111 | - }; | 111 | - }; |
112 | - | 112 | - |
113 | - genfn = fns[size][u]; | 113 | - genfn = fns[size][u]; |
114 | - | 114 | - |
115 | - tcg_res[pass] = tcg_temp_new_i64(); | 115 | - tcg_res[pass] = tcg_temp_new_i64(); |
116 | - | 116 | - |
117 | - read_vec_element(s, tcg_op, rn, pass, MO_64); | 117 | - read_vec_element(s, tcg_op, rn, pass, MO_64); |
118 | - genfn(tcg_res[pass], tcg_op); | 118 | - genfn(tcg_res[pass], tcg_op); |
119 | - | 119 | - |
120 | - if (accum) { | 120 | - if (accum) { |
121 | - read_vec_element(s, tcg_op, rd, pass, MO_64); | 121 | - read_vec_element(s, tcg_op, rd, pass, MO_64); |
122 | - if (size == 0) { | 122 | - if (size == 0) { |
123 | - gen_helper_neon_addl_u16(tcg_res[pass], | 123 | - gen_helper_neon_addl_u16(tcg_res[pass], |
124 | - tcg_res[pass], tcg_op); | 124 | - tcg_res[pass], tcg_op); |
125 | - } else { | 125 | - } else { |
126 | - gen_helper_neon_addl_u32(tcg_res[pass], | 126 | - gen_helper_neon_addl_u32(tcg_res[pass], |
127 | - tcg_res[pass], tcg_op); | 127 | - tcg_res[pass], tcg_op); |
128 | - } | 128 | - } |
129 | - } | 129 | - } |
130 | - } | 130 | - } |
131 | - } | 131 | - } |
132 | - if (!is_q) { | 132 | - if (!is_q) { |
133 | - tcg_res[1] = tcg_constant_i64(0); | 133 | - tcg_res[1] = tcg_constant_i64(0); |
134 | - } | 134 | - } |
135 | - for (pass = 0; pass < 2; pass++) { | 135 | - for (pass = 0; pass < 2; pass++) { |
136 | - write_vec_element(s, tcg_res[pass], rd, pass, MO_64); | 136 | - write_vec_element(s, tcg_res[pass], rd, pass, MO_64); |
137 | - } | 137 | - } |
138 | -} | 138 | -} |
139 | - | 139 | - |
140 | static void handle_shll(DisasContext *s, bool is_q, int size, int rn, int rd) | 140 | static void handle_shll(DisasContext *s, bool is_q, int size, int rn, int rd) |
141 | { | 141 | { |
142 | /* Implement SHLL and SHLL2 */ | 142 | /* Implement SHLL and SHLL2 */ |
143 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 143 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
144 | 144 | ||
145 | handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd); | 145 | handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd); |
146 | return; | 146 | return; |
147 | - case 0x2: /* SADDLP, UADDLP */ | 147 | - case 0x2: /* SADDLP, UADDLP */ |
148 | - case 0x6: /* SADALP, UADALP */ | 148 | - case 0x6: /* SADALP, UADALP */ |
149 | - if (size == 3) { | 149 | - if (size == 3) { |
150 | - unallocated_encoding(s); | 150 | - unallocated_encoding(s); |
151 | - return; | 151 | - return; |
152 | - } | 152 | - } |
153 | - if (!fp_access_check(s)) { | 153 | - if (!fp_access_check(s)) { |
154 | - return; | 154 | - return; |
155 | - } | 155 | - } |
156 | - handle_2misc_pairwise(s, opcode, u, is_q, size, rn, rd); | 156 | - handle_2misc_pairwise(s, opcode, u, is_q, size, rn, rd); |
157 | - return; | 157 | - return; |
158 | case 0x13: /* SHLL, SHLL2 */ | 158 | case 0x13: /* SHLL, SHLL2 */ |
159 | if (u == 0 || size == 3) { | 159 | if (u == 0 || size == 3) { |
160 | unallocated_encoding(s); | 160 | unallocated_encoding(s); |
161 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 161 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
162 | default: | 162 | default: |
163 | case 0x0: /* REV64, REV32 */ | 163 | case 0x0: /* REV64, REV32 */ |
164 | case 0x1: /* REV16 */ | 164 | case 0x1: /* REV16 */ |
165 | + case 0x2: /* SADDLP, UADDLP */ | 165 | + case 0x2: /* SADDLP, UADDLP */ |
166 | case 0x3: /* SUQADD, USQADD */ | 166 | case 0x3: /* SUQADD, USQADD */ |
167 | case 0x4: /* CLS, CLZ */ | 167 | case 0x4: /* CLS, CLZ */ |
168 | case 0x5: /* CNT, NOT, RBIT */ | 168 | case 0x5: /* CNT, NOT, RBIT */ |
169 | + case 0x6: /* SADALP, UADALP */ | 169 | + case 0x6: /* SADALP, UADALP */ |
170 | case 0x7: /* SQABS, SQNEG */ | 170 | case 0x7: /* SQABS, SQNEG */ |
171 | case 0x8: /* CMGT, CMGE */ | 171 | case 0x8: /* CMGT, CMGE */ |
172 | case 0x9: /* CMEQ, CMLE */ | 172 | case 0x9: /* CMEQ, CMLE */ |
173 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 173 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
174 | index XXXXXXX..XXXXXXX 100644 | 174 | index XXXXXXX..XXXXXXX 100644 |
175 | --- a/target/arm/tcg/a64.decode | 175 | --- a/target/arm/tcg/a64.decode |
176 | +++ b/target/arm/tcg/a64.decode | 176 | +++ b/target/arm/tcg/a64.decode |
177 | @@ -XXX,XX +XXX,XX @@ CMLT0_v 0.00 1110 ..1 00000 10101 0 ..... ..... @qrr_e | 177 | @@ -XXX,XX +XXX,XX @@ CMLT0_v 0.00 1110 ..1 00000 10101 0 ..... ..... @qrr_e |
178 | REV16_v 0.00 1110 001 00000 00011 0 ..... ..... @qrr_b | 178 | REV16_v 0.00 1110 001 00000 00011 0 ..... ..... @qrr_b |
179 | REV32_v 0.10 1110 0.1 00000 00001 0 ..... ..... @qrr_bh | 179 | REV32_v 0.10 1110 0.1 00000 00001 0 ..... ..... @qrr_bh |
180 | REV64_v 0.00 1110 ..1 00000 00001 0 ..... ..... @qrr_e | 180 | REV64_v 0.00 1110 ..1 00000 00001 0 ..... ..... @qrr_e |
181 | + | 181 | + |
182 | +SADDLP_v 0.00 1110 ..1 00000 00101 0 ..... ..... @qrr_e | 182 | +SADDLP_v 0.00 1110 ..1 00000 00101 0 ..... ..... @qrr_e |
183 | +UADDLP_v 0.10 1110 ..1 00000 00101 0 ..... ..... @qrr_e | 183 | +UADDLP_v 0.10 1110 ..1 00000 00101 0 ..... ..... @qrr_e |
184 | +SADALP_v 0.00 1110 ..1 00000 01101 0 ..... ..... @qrr_e | 184 | +SADALP_v 0.00 1110 ..1 00000 01101 0 ..... ..... @qrr_e |
185 | +UADALP_v 0.10 1110 ..1 00000 01101 0 ..... ..... @qrr_e | 185 | +UADALP_v 0.10 1110 ..1 00000 01101 0 ..... ..... @qrr_e |
186 | -- | 186 | -- |
187 | 2.43.0 | 187 | 2.43.0 | diff view generated by jsdifflib |
1 | These have generic equivalents: tcg_gen_vec_{add,sub}{16,32}_i64. | 1 | These have generic equivalents: tcg_gen_vec_{add,sub}{16,32}_i64. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/helper.h | 4 ---- | 6 | target/arm/helper.h | 4 ---- |
7 | target/arm/tcg/neon_helper.c | 36 --------------------------------- | 7 | target/arm/tcg/neon_helper.c | 36 --------------------------------- |
8 | target/arm/tcg/translate-neon.c | 22 ++++++++++---------- | 8 | target/arm/tcg/translate-neon.c | 22 ++++++++++---------- |
9 | 3 files changed, 11 insertions(+), 51 deletions(-) | 9 | 3 files changed, 11 insertions(+), 51 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/helper.h b/target/arm/helper.h | 11 | diff --git a/target/arm/helper.h b/target/arm/helper.h |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/helper.h | 13 | --- a/target/arm/helper.h |
14 | +++ b/target/arm/helper.h | 14 | +++ b/target/arm/helper.h |
15 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(neon_widen_s8, i64, i32) | 15 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(neon_widen_s8, i64, i32) |
16 | DEF_HELPER_1(neon_widen_u16, i64, i32) | 16 | DEF_HELPER_1(neon_widen_u16, i64, i32) |
17 | DEF_HELPER_1(neon_widen_s16, i64, i32) | 17 | DEF_HELPER_1(neon_widen_s16, i64, i32) |
18 | 18 | ||
19 | -DEF_HELPER_2(neon_addl_u16, i64, i64, i64) | 19 | -DEF_HELPER_2(neon_addl_u16, i64, i64, i64) |
20 | -DEF_HELPER_2(neon_addl_u32, i64, i64, i64) | 20 | -DEF_HELPER_2(neon_addl_u32, i64, i64, i64) |
21 | DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) | 21 | DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) |
22 | DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) | 22 | DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) |
23 | -DEF_HELPER_2(neon_subl_u16, i64, i64, i64) | 23 | -DEF_HELPER_2(neon_subl_u16, i64, i64, i64) |
24 | -DEF_HELPER_2(neon_subl_u32, i64, i64, i64) | 24 | -DEF_HELPER_2(neon_subl_u32, i64, i64, i64) |
25 | DEF_HELPER_3(neon_addl_saturate_s32, i64, env, i64, i64) | 25 | DEF_HELPER_3(neon_addl_saturate_s32, i64, env, i64, i64) |
26 | DEF_HELPER_3(neon_addl_saturate_s64, i64, env, i64, i64) | 26 | DEF_HELPER_3(neon_addl_saturate_s64, i64, env, i64, i64) |
27 | DEF_HELPER_2(neon_abdl_u16, i64, i32, i32) | 27 | DEF_HELPER_2(neon_abdl_u16, i64, i32, i32) |
28 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c | 28 | diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c |
29 | index XXXXXXX..XXXXXXX 100644 | 29 | index XXXXXXX..XXXXXXX 100644 |
30 | --- a/target/arm/tcg/neon_helper.c | 30 | --- a/target/arm/tcg/neon_helper.c |
31 | +++ b/target/arm/tcg/neon_helper.c | 31 | +++ b/target/arm/tcg/neon_helper.c |
32 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_widen_s16)(uint32_t x) | 32 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_widen_s16)(uint32_t x) |
33 | return ((uint32_t)(int16_t)x) | (high << 32); | 33 | return ((uint32_t)(int16_t)x) | (high << 32); |
34 | } | 34 | } |
35 | 35 | ||
36 | -uint64_t HELPER(neon_addl_u16)(uint64_t a, uint64_t b) | 36 | -uint64_t HELPER(neon_addl_u16)(uint64_t a, uint64_t b) |
37 | -{ | 37 | -{ |
38 | - uint64_t mask; | 38 | - uint64_t mask; |
39 | - mask = (a ^ b) & 0x8000800080008000ull; | 39 | - mask = (a ^ b) & 0x8000800080008000ull; |
40 | - a &= ~0x8000800080008000ull; | 40 | - a &= ~0x8000800080008000ull; |
41 | - b &= ~0x8000800080008000ull; | 41 | - b &= ~0x8000800080008000ull; |
42 | - return (a + b) ^ mask; | 42 | - return (a + b) ^ mask; |
43 | -} | 43 | -} |
44 | - | 44 | - |
45 | -uint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b) | 45 | -uint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b) |
46 | -{ | 46 | -{ |
47 | - uint64_t mask; | 47 | - uint64_t mask; |
48 | - mask = (a ^ b) & 0x8000000080000000ull; | 48 | - mask = (a ^ b) & 0x8000000080000000ull; |
49 | - a &= ~0x8000000080000000ull; | 49 | - a &= ~0x8000000080000000ull; |
50 | - b &= ~0x8000000080000000ull; | 50 | - b &= ~0x8000000080000000ull; |
51 | - return (a + b) ^ mask; | 51 | - return (a + b) ^ mask; |
52 | -} | 52 | -} |
53 | - | 53 | - |
54 | /* Pairwise long add: add pairs of adjacent elements into | 54 | /* Pairwise long add: add pairs of adjacent elements into |
55 | * double-width elements in the result (eg _s8 is an 8x8->16 op) | 55 | * double-width elements in the result (eg _s8 is an 8x8->16 op) |
56 | */ | 56 | */ |
57 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_s16)(uint64_t a) | 57 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_s16)(uint64_t a) |
58 | return (uint32_t)reslo | (((uint64_t)reshi) << 32); | 58 | return (uint32_t)reslo | (((uint64_t)reshi) << 32); |
59 | } | 59 | } |
60 | 60 | ||
61 | -uint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b) | 61 | -uint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b) |
62 | -{ | 62 | -{ |
63 | - uint64_t mask; | 63 | - uint64_t mask; |
64 | - mask = (a ^ ~b) & 0x8000800080008000ull; | 64 | - mask = (a ^ ~b) & 0x8000800080008000ull; |
65 | - a |= 0x8000800080008000ull; | 65 | - a |= 0x8000800080008000ull; |
66 | - b &= ~0x8000800080008000ull; | 66 | - b &= ~0x8000800080008000ull; |
67 | - return (a - b) ^ mask; | 67 | - return (a - b) ^ mask; |
68 | -} | 68 | -} |
69 | - | 69 | - |
70 | -uint64_t HELPER(neon_subl_u32)(uint64_t a, uint64_t b) | 70 | -uint64_t HELPER(neon_subl_u32)(uint64_t a, uint64_t b) |
71 | -{ | 71 | -{ |
72 | - uint64_t mask; | 72 | - uint64_t mask; |
73 | - mask = (a ^ ~b) & 0x8000000080000000ull; | 73 | - mask = (a ^ ~b) & 0x8000000080000000ull; |
74 | - a |= 0x8000000080000000ull; | 74 | - a |= 0x8000000080000000ull; |
75 | - b &= ~0x8000000080000000ull; | 75 | - b &= ~0x8000000080000000ull; |
76 | - return (a - b) ^ mask; | 76 | - return (a - b) ^ mask; |
77 | -} | 77 | -} |
78 | - | 78 | - |
79 | uint64_t HELPER(neon_addl_saturate_s32)(CPUARMState *env, uint64_t a, uint64_t b) | 79 | uint64_t HELPER(neon_addl_saturate_s32)(CPUARMState *env, uint64_t a, uint64_t b) |
80 | { | 80 | { |
81 | uint32_t x, y; | 81 | uint32_t x, y; |
82 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c | 82 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c |
83 | index XXXXXXX..XXXXXXX 100644 | 83 | index XXXXXXX..XXXXXXX 100644 |
84 | --- a/target/arm/tcg/translate-neon.c | 84 | --- a/target/arm/tcg/translate-neon.c |
85 | +++ b/target/arm/tcg/translate-neon.c | 85 | +++ b/target/arm/tcg/translate-neon.c |
86 | @@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a, | 86 | @@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a, |
87 | NULL, NULL, \ | 87 | NULL, NULL, \ |
88 | }; \ | 88 | }; \ |
89 | static NeonGenTwo64OpFn * const addfn[] = { \ | 89 | static NeonGenTwo64OpFn * const addfn[] = { \ |
90 | - gen_helper_neon_##OP##l_u16, \ | 90 | - gen_helper_neon_##OP##l_u16, \ |
91 | - gen_helper_neon_##OP##l_u32, \ | 91 | - gen_helper_neon_##OP##l_u32, \ |
92 | + tcg_gen_vec_##OP##16_i64, \ | 92 | + tcg_gen_vec_##OP##16_i64, \ |
93 | + tcg_gen_vec_##OP##32_i64, \ | 93 | + tcg_gen_vec_##OP##32_i64, \ |
94 | tcg_gen_##OP##_i64, \ | 94 | tcg_gen_##OP##_i64, \ |
95 | NULL, \ | 95 | NULL, \ |
96 | }; \ | 96 | }; \ |
97 | @@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a, | 97 | @@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a, |
98 | static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \ | 98 | static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \ |
99 | { \ | 99 | { \ |
100 | static NeonGenTwo64OpFn * const addfn[] = { \ | 100 | static NeonGenTwo64OpFn * const addfn[] = { \ |
101 | - gen_helper_neon_##OP##l_u16, \ | 101 | - gen_helper_neon_##OP##l_u16, \ |
102 | - gen_helper_neon_##OP##l_u32, \ | 102 | - gen_helper_neon_##OP##l_u32, \ |
103 | + tcg_gen_vec_##OP##16_i64, \ | 103 | + tcg_gen_vec_##OP##16_i64, \ |
104 | + tcg_gen_vec_##OP##32_i64, \ | 104 | + tcg_gen_vec_##OP##32_i64, \ |
105 | tcg_gen_##OP##_i64, \ | 105 | tcg_gen_##OP##_i64, \ |
106 | NULL, \ | 106 | NULL, \ |
107 | }; \ | 107 | }; \ |
108 | @@ -XXX,XX +XXX,XX @@ static bool trans_VABAL_S_3d(DisasContext *s, arg_3diff *a) | 108 | @@ -XXX,XX +XXX,XX @@ static bool trans_VABAL_S_3d(DisasContext *s, arg_3diff *a) |
109 | NULL, | 109 | NULL, |
110 | }; | 110 | }; |
111 | static NeonGenTwo64OpFn * const addfn[] = { | 111 | static NeonGenTwo64OpFn * const addfn[] = { |
112 | - gen_helper_neon_addl_u16, | 112 | - gen_helper_neon_addl_u16, |
113 | - gen_helper_neon_addl_u32, | 113 | - gen_helper_neon_addl_u32, |
114 | + tcg_gen_vec_add16_i64, | 114 | + tcg_gen_vec_add16_i64, |
115 | + tcg_gen_vec_add32_i64, | 115 | + tcg_gen_vec_add32_i64, |
116 | tcg_gen_add_i64, | 116 | tcg_gen_add_i64, |
117 | NULL, | 117 | NULL, |
118 | }; | 118 | }; |
119 | @@ -XXX,XX +XXX,XX @@ static bool trans_VABAL_U_3d(DisasContext *s, arg_3diff *a) | 119 | @@ -XXX,XX +XXX,XX @@ static bool trans_VABAL_U_3d(DisasContext *s, arg_3diff *a) |
120 | NULL, | 120 | NULL, |
121 | }; | 121 | }; |
122 | static NeonGenTwo64OpFn * const addfn[] = { | 122 | static NeonGenTwo64OpFn * const addfn[] = { |
123 | - gen_helper_neon_addl_u16, | 123 | - gen_helper_neon_addl_u16, |
124 | - gen_helper_neon_addl_u32, | 124 | - gen_helper_neon_addl_u32, |
125 | + tcg_gen_vec_add16_i64, | 125 | + tcg_gen_vec_add16_i64, |
126 | + tcg_gen_vec_add32_i64, | 126 | + tcg_gen_vec_add32_i64, |
127 | tcg_gen_add_i64, | 127 | tcg_gen_add_i64, |
128 | NULL, | 128 | NULL, |
129 | }; | 129 | }; |
130 | @@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_U_3d(DisasContext *s, arg_3diff *a) | 130 | @@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_U_3d(DisasContext *s, arg_3diff *a) |
131 | NULL, \ | 131 | NULL, \ |
132 | }; \ | 132 | }; \ |
133 | static NeonGenTwo64OpFn * const accfn[] = { \ | 133 | static NeonGenTwo64OpFn * const accfn[] = { \ |
134 | - gen_helper_neon_##ACC##l_u16, \ | 134 | - gen_helper_neon_##ACC##l_u16, \ |
135 | - gen_helper_neon_##ACC##l_u32, \ | 135 | - gen_helper_neon_##ACC##l_u32, \ |
136 | + tcg_gen_vec_##ACC##16_i64, \ | 136 | + tcg_gen_vec_##ACC##16_i64, \ |
137 | + tcg_gen_vec_##ACC##32_i64, \ | 137 | + tcg_gen_vec_##ACC##32_i64, \ |
138 | tcg_gen_##ACC##_i64, \ | 138 | tcg_gen_##ACC##_i64, \ |
139 | NULL, \ | 139 | NULL, \ |
140 | }; \ | 140 | }; \ |
141 | @@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_U_2sc(DisasContext *s, arg_2scalar *a) | 141 | @@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_U_2sc(DisasContext *s, arg_2scalar *a) |
142 | }; \ | 142 | }; \ |
143 | static NeonGenTwo64OpFn * const accfn[] = { \ | 143 | static NeonGenTwo64OpFn * const accfn[] = { \ |
144 | NULL, \ | 144 | NULL, \ |
145 | - gen_helper_neon_##ACC##l_u32, \ | 145 | - gen_helper_neon_##ACC##l_u32, \ |
146 | + tcg_gen_vec_##ACC##32_i64, \ | 146 | + tcg_gen_vec_##ACC##32_i64, \ |
147 | tcg_gen_##ACC##_i64, \ | 147 | tcg_gen_##ACC##_i64, \ |
148 | NULL, \ | 148 | NULL, \ |
149 | }; \ | 149 | }; \ |
150 | -- | 150 | -- |
151 | 2.43.0 | 151 | 2.43.0 | diff view generated by jsdifflib |
1 | In a couple of places, clearing the entire vector before storing one | 1 | In a couple of places, clearing the entire vector before storing one |
---|---|---|---|
2 | element is the easiest solution. Wrap that into a helper function. | 2 | element is the easiest solution. Wrap that into a helper function. |
3 | 3 | ||
4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 21 ++++++++++++--------- | 7 | target/arm/tcg/translate-a64.c | 21 ++++++++++++--------- |
8 | 1 file changed, 12 insertions(+), 9 deletions(-) | 8 | 1 file changed, 12 insertions(+), 9 deletions(-) |
9 | 9 | ||
10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 10 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/target/arm/tcg/translate-a64.c | 12 | --- a/target/arm/tcg/translate-a64.c |
13 | +++ b/target/arm/tcg/translate-a64.c | 13 | +++ b/target/arm/tcg/translate-a64.c |
14 | @@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_hreg(DisasContext *s, int reg) | 14 | @@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_hreg(DisasContext *s, int reg) |
15 | return v; | 15 | return v; |
16 | } | 16 | } |
17 | 17 | ||
18 | -/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64). | 18 | -/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64). |
19 | +static void clear_vec(DisasContext *s, int rd) | 19 | +static void clear_vec(DisasContext *s, int rd) |
20 | +{ | 20 | +{ |
21 | + unsigned ofs = fp_reg_offset(s, rd, MO_64); | 21 | + unsigned ofs = fp_reg_offset(s, rd, MO_64); |
22 | + unsigned vsz = vec_full_reg_size(s); | 22 | + unsigned vsz = vec_full_reg_size(s); |
23 | + | 23 | + |
24 | + tcg_gen_gvec_dup_imm(MO_64, ofs, vsz, vsz, 0); | 24 | + tcg_gen_gvec_dup_imm(MO_64, ofs, vsz, vsz, 0); |
25 | +} | 25 | +} |
26 | + | 26 | + |
27 | +/* | 27 | +/* |
28 | + * Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64). | 28 | + * Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64). |
29 | * If SVE is not enabled, then there are only 128 bits in the vector. | 29 | * If SVE is not enabled, then there are only 128 bits in the vector. |
30 | */ | 30 | */ |
31 | static void clear_vec_high(DisasContext *s, bool is_q, int rd) | 31 | static void clear_vec_high(DisasContext *s, bool is_q, int rd) |
32 | @@ -XXX,XX +XXX,XX @@ static bool trans_SM3SS1(DisasContext *s, arg_SM3SS1 *a) | 32 | @@ -XXX,XX +XXX,XX @@ static bool trans_SM3SS1(DisasContext *s, arg_SM3SS1 *a) |
33 | TCGv_i32 tcg_op2 = tcg_temp_new_i32(); | 33 | TCGv_i32 tcg_op2 = tcg_temp_new_i32(); |
34 | TCGv_i32 tcg_op3 = tcg_temp_new_i32(); | 34 | TCGv_i32 tcg_op3 = tcg_temp_new_i32(); |
35 | TCGv_i32 tcg_res = tcg_temp_new_i32(); | 35 | TCGv_i32 tcg_res = tcg_temp_new_i32(); |
36 | - unsigned vsz, dofs; | 36 | - unsigned vsz, dofs; |
37 | 37 | ||
38 | read_vec_element_i32(s, tcg_op1, a->rn, 3, MO_32); | 38 | read_vec_element_i32(s, tcg_op1, a->rn, 3, MO_32); |
39 | read_vec_element_i32(s, tcg_op2, a->rm, 3, MO_32); | 39 | read_vec_element_i32(s, tcg_op2, a->rm, 3, MO_32); |
40 | @@ -XXX,XX +XXX,XX @@ static bool trans_SM3SS1(DisasContext *s, arg_SM3SS1 *a) | 40 | @@ -XXX,XX +XXX,XX @@ static bool trans_SM3SS1(DisasContext *s, arg_SM3SS1 *a) |
41 | tcg_gen_rotri_i32(tcg_res, tcg_res, 25); | 41 | tcg_gen_rotri_i32(tcg_res, tcg_res, 25); |
42 | 42 | ||
43 | /* Clear the whole register first, then store bits [127:96]. */ | 43 | /* Clear the whole register first, then store bits [127:96]. */ |
44 | - vsz = vec_full_reg_size(s); | 44 | - vsz = vec_full_reg_size(s); |
45 | - dofs = vec_full_reg_offset(s, a->rd); | 45 | - dofs = vec_full_reg_offset(s, a->rd); |
46 | - tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0); | 46 | - tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0); |
47 | + clear_vec(s, a->rd); | 47 | + clear_vec(s, a->rd); |
48 | write_vec_element_i32(s, tcg_res, a->rd, 3, MO_32); | 48 | write_vec_element_i32(s, tcg_res, a->rd, 3, MO_32); |
49 | } | 49 | } |
50 | return true; | 50 | return true; |
51 | @@ -XXX,XX +XXX,XX @@ static bool do_scalar_muladd_widening_idx(DisasContext *s, arg_rrx_e *a, | 51 | @@ -XXX,XX +XXX,XX @@ static bool do_scalar_muladd_widening_idx(DisasContext *s, arg_rrx_e *a, |
52 | TCGv_i64 t0 = tcg_temp_new_i64(); | 52 | TCGv_i64 t0 = tcg_temp_new_i64(); |
53 | TCGv_i64 t1 = tcg_temp_new_i64(); | 53 | TCGv_i64 t1 = tcg_temp_new_i64(); |
54 | TCGv_i64 t2 = tcg_temp_new_i64(); | 54 | TCGv_i64 t2 = tcg_temp_new_i64(); |
55 | - unsigned vsz, dofs; | 55 | - unsigned vsz, dofs; |
56 | 56 | ||
57 | if (acc) { | 57 | if (acc) { |
58 | read_vec_element(s, t0, a->rd, 0, a->esz + 1); | 58 | read_vec_element(s, t0, a->rd, 0, a->esz + 1); |
59 | @@ -XXX,XX +XXX,XX @@ static bool do_scalar_muladd_widening_idx(DisasContext *s, arg_rrx_e *a, | 59 | @@ -XXX,XX +XXX,XX @@ static bool do_scalar_muladd_widening_idx(DisasContext *s, arg_rrx_e *a, |
60 | fn(t0, t1, t2); | 60 | fn(t0, t1, t2); |
61 | 61 | ||
62 | /* Clear the whole register first, then store scalar. */ | 62 | /* Clear the whole register first, then store scalar. */ |
63 | - vsz = vec_full_reg_size(s); | 63 | - vsz = vec_full_reg_size(s); |
64 | - dofs = vec_full_reg_offset(s, a->rd); | 64 | - dofs = vec_full_reg_offset(s, a->rd); |
65 | - tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0); | 65 | - tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0); |
66 | + clear_vec(s, a->rd); | 66 | + clear_vec(s, a->rd); |
67 | write_vec_element(s, t0, a->rd, 0, a->esz + 1); | 67 | write_vec_element(s, t0, a->rd, 0, a->esz + 1); |
68 | } | 68 | } |
69 | return true; | 69 | return true; |
70 | -- | 70 | -- |
71 | 2.43.0 | 71 | 2.43.0 |
72 | 72 | ||
73 | 73 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 153 ++++++++++++++++++++------------- | 4 | target/arm/tcg/translate-a64.c | 153 ++++++++++++++++++++------------- |
5 | target/arm/tcg/a64.decode | 9 ++ | 5 | target/arm/tcg/a64.decode | 9 ++ |
6 | 2 files changed, 102 insertions(+), 60 deletions(-) | 6 | 2 files changed, 102 insertions(+), 60 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ TRANS(CMLE0_s, do_cmop0_d, a, TCG_COND_LE) | 12 | @@ -XXX,XX +XXX,XX @@ TRANS(CMLE0_s, do_cmop0_d, a, TCG_COND_LE) |
13 | TRANS(CMLT0_s, do_cmop0_d, a, TCG_COND_LT) | 13 | TRANS(CMLT0_s, do_cmop0_d, a, TCG_COND_LT) |
14 | TRANS(CMEQ0_s, do_cmop0_d, a, TCG_COND_EQ) | 14 | TRANS(CMEQ0_s, do_cmop0_d, a, TCG_COND_EQ) |
15 | 15 | ||
16 | +static bool do_2misc_narrow_scalar(DisasContext *s, arg_rr_e *a, | 16 | +static bool do_2misc_narrow_scalar(DisasContext *s, arg_rr_e *a, |
17 | + ArithOneOp * const fn[3]) | 17 | + ArithOneOp * const fn[3]) |
18 | +{ | 18 | +{ |
19 | + if (a->esz == MO_64) { | 19 | + if (a->esz == MO_64) { |
20 | + return false; | 20 | + return false; |
21 | + } | 21 | + } |
22 | + if (fp_access_check(s)) { | 22 | + if (fp_access_check(s)) { |
23 | + TCGv_i64 t = tcg_temp_new_i64(); | 23 | + TCGv_i64 t = tcg_temp_new_i64(); |
24 | + | 24 | + |
25 | + read_vec_element(s, t, a->rn, 0, a->esz + 1); | 25 | + read_vec_element(s, t, a->rn, 0, a->esz + 1); |
26 | + fn[a->esz](t, t); | 26 | + fn[a->esz](t, t); |
27 | + clear_vec(s, a->rd); | 27 | + clear_vec(s, a->rd); |
28 | + write_vec_element(s, t, a->rd, 0, a->esz); | 28 | + write_vec_element(s, t, a->rd, 0, a->esz); |
29 | + } | 29 | + } |
30 | + return true; | 30 | + return true; |
31 | +} | 31 | +} |
32 | + | 32 | + |
33 | +#define WRAP_ENV(NAME) \ | 33 | +#define WRAP_ENV(NAME) \ |
34 | + static void gen_##NAME(TCGv_i64 d, TCGv_i64 n) \ | 34 | + static void gen_##NAME(TCGv_i64 d, TCGv_i64 n) \ |
35 | + { gen_helper_##NAME(d, tcg_env, n); } | 35 | + { gen_helper_##NAME(d, tcg_env, n); } |
36 | + | 36 | + |
37 | +WRAP_ENV(neon_unarrow_sat8) | 37 | +WRAP_ENV(neon_unarrow_sat8) |
38 | +WRAP_ENV(neon_unarrow_sat16) | 38 | +WRAP_ENV(neon_unarrow_sat16) |
39 | +WRAP_ENV(neon_unarrow_sat32) | 39 | +WRAP_ENV(neon_unarrow_sat32) |
40 | + | 40 | + |
41 | +static ArithOneOp * const f_scalar_sqxtun[] = { | 41 | +static ArithOneOp * const f_scalar_sqxtun[] = { |
42 | + gen_neon_unarrow_sat8, | 42 | + gen_neon_unarrow_sat8, |
43 | + gen_neon_unarrow_sat16, | 43 | + gen_neon_unarrow_sat16, |
44 | + gen_neon_unarrow_sat32, | 44 | + gen_neon_unarrow_sat32, |
45 | +}; | 45 | +}; |
46 | +TRANS(SQXTUN_s, do_2misc_narrow_scalar, a, f_scalar_sqxtun) | 46 | +TRANS(SQXTUN_s, do_2misc_narrow_scalar, a, f_scalar_sqxtun) |
47 | + | 47 | + |
48 | +WRAP_ENV(neon_narrow_sat_s8) | 48 | +WRAP_ENV(neon_narrow_sat_s8) |
49 | +WRAP_ENV(neon_narrow_sat_s16) | 49 | +WRAP_ENV(neon_narrow_sat_s16) |
50 | +WRAP_ENV(neon_narrow_sat_s32) | 50 | +WRAP_ENV(neon_narrow_sat_s32) |
51 | + | 51 | + |
52 | +static ArithOneOp * const f_scalar_sqxtn[] = { | 52 | +static ArithOneOp * const f_scalar_sqxtn[] = { |
53 | + gen_neon_narrow_sat_s8, | 53 | + gen_neon_narrow_sat_s8, |
54 | + gen_neon_narrow_sat_s16, | 54 | + gen_neon_narrow_sat_s16, |
55 | + gen_neon_narrow_sat_s32, | 55 | + gen_neon_narrow_sat_s32, |
56 | +}; | 56 | +}; |
57 | +TRANS(SQXTN_s, do_2misc_narrow_scalar, a, f_scalar_sqxtn) | 57 | +TRANS(SQXTN_s, do_2misc_narrow_scalar, a, f_scalar_sqxtn) |
58 | + | 58 | + |
59 | +WRAP_ENV(neon_narrow_sat_u8) | 59 | +WRAP_ENV(neon_narrow_sat_u8) |
60 | +WRAP_ENV(neon_narrow_sat_u16) | 60 | +WRAP_ENV(neon_narrow_sat_u16) |
61 | +WRAP_ENV(neon_narrow_sat_u32) | 61 | +WRAP_ENV(neon_narrow_sat_u32) |
62 | + | 62 | + |
63 | +static ArithOneOp * const f_scalar_uqxtn[] = { | 63 | +static ArithOneOp * const f_scalar_uqxtn[] = { |
64 | + gen_neon_narrow_sat_u8, | 64 | + gen_neon_narrow_sat_u8, |
65 | + gen_neon_narrow_sat_u16, | 65 | + gen_neon_narrow_sat_u16, |
66 | + gen_neon_narrow_sat_u32, | 66 | + gen_neon_narrow_sat_u32, |
67 | +}; | 67 | +}; |
68 | +TRANS(UQXTN_s, do_2misc_narrow_scalar, a, f_scalar_uqxtn) | 68 | +TRANS(UQXTN_s, do_2misc_narrow_scalar, a, f_scalar_uqxtn) |
69 | + | 69 | + |
70 | +#undef WRAP_ENV | 70 | +#undef WRAP_ENV |
71 | + | 71 | + |
72 | static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 72 | static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
73 | { | 73 | { |
74 | if (!a->q && a->esz == MO_64) { | 74 | if (!a->q && a->esz == MO_64) { |
75 | @@ -XXX,XX +XXX,XX @@ TRANS(UADDLP_v, do_gvec_fn2_bhs, a, gen_gvec_uaddlp) | 75 | @@ -XXX,XX +XXX,XX @@ TRANS(UADDLP_v, do_gvec_fn2_bhs, a, gen_gvec_uaddlp) |
76 | TRANS(SADALP_v, do_gvec_fn2_bhs, a, gen_gvec_sadalp) | 76 | TRANS(SADALP_v, do_gvec_fn2_bhs, a, gen_gvec_sadalp) |
77 | TRANS(UADALP_v, do_gvec_fn2_bhs, a, gen_gvec_uadalp) | 77 | TRANS(UADALP_v, do_gvec_fn2_bhs, a, gen_gvec_uadalp) |
78 | 78 | ||
79 | +static bool do_2misc_narrow_vector(DisasContext *s, arg_qrr_e *a, | 79 | +static bool do_2misc_narrow_vector(DisasContext *s, arg_qrr_e *a, |
80 | + ArithOneOp * const fn[3]) | 80 | + ArithOneOp * const fn[3]) |
81 | +{ | 81 | +{ |
82 | + if (a->esz == MO_64) { | 82 | + if (a->esz == MO_64) { |
83 | + return false; | 83 | + return false; |
84 | + } | 84 | + } |
85 | + if (fp_access_check(s)) { | 85 | + if (fp_access_check(s)) { |
86 | + TCGv_i64 t0 = tcg_temp_new_i64(); | 86 | + TCGv_i64 t0 = tcg_temp_new_i64(); |
87 | + TCGv_i64 t1 = tcg_temp_new_i64(); | 87 | + TCGv_i64 t1 = tcg_temp_new_i64(); |
88 | + | 88 | + |
89 | + read_vec_element(s, t0, a->rn, 0, MO_64); | 89 | + read_vec_element(s, t0, a->rn, 0, MO_64); |
90 | + read_vec_element(s, t1, a->rn, 1, MO_64); | 90 | + read_vec_element(s, t1, a->rn, 1, MO_64); |
91 | + fn[a->esz](t0, t0); | 91 | + fn[a->esz](t0, t0); |
92 | + fn[a->esz](t1, t1); | 92 | + fn[a->esz](t1, t1); |
93 | + write_vec_element(s, t0, a->rd, a->q ? 2 : 0, MO_32); | 93 | + write_vec_element(s, t0, a->rd, a->q ? 2 : 0, MO_32); |
94 | + write_vec_element(s, t1, a->rd, a->q ? 3 : 1, MO_32); | 94 | + write_vec_element(s, t1, a->rd, a->q ? 3 : 1, MO_32); |
95 | + clear_vec_high(s, a->q, a->rd); | 95 | + clear_vec_high(s, a->q, a->rd); |
96 | + } | 96 | + } |
97 | + return true; | 97 | + return true; |
98 | +} | 98 | +} |
99 | + | 99 | + |
100 | +static ArithOneOp * const f_scalar_xtn[] = { | 100 | +static ArithOneOp * const f_scalar_xtn[] = { |
101 | + gen_helper_neon_narrow_u8, | 101 | + gen_helper_neon_narrow_u8, |
102 | + gen_helper_neon_narrow_u16, | 102 | + gen_helper_neon_narrow_u16, |
103 | + tcg_gen_ext32u_i64, | 103 | + tcg_gen_ext32u_i64, |
104 | +}; | 104 | +}; |
105 | +TRANS(XTN, do_2misc_narrow_vector, a, f_scalar_xtn) | 105 | +TRANS(XTN, do_2misc_narrow_vector, a, f_scalar_xtn) |
106 | +TRANS(SQXTUN_v, do_2misc_narrow_vector, a, f_scalar_sqxtun) | 106 | +TRANS(SQXTUN_v, do_2misc_narrow_vector, a, f_scalar_sqxtun) |
107 | +TRANS(SQXTN_v, do_2misc_narrow_vector, a, f_scalar_sqxtn) | 107 | +TRANS(SQXTN_v, do_2misc_narrow_vector, a, f_scalar_sqxtn) |
108 | +TRANS(UQXTN_v, do_2misc_narrow_vector, a, f_scalar_uqxtn) | 108 | +TRANS(UQXTN_v, do_2misc_narrow_vector, a, f_scalar_uqxtn) |
109 | + | 109 | + |
110 | /* Common vector code for handling integer to FP conversion */ | 110 | /* Common vector code for handling integer to FP conversion */ |
111 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 111 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
112 | int elements, int is_signed, | 112 | int elements, int is_signed, |
113 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, | 113 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, |
114 | tcg_res[pass] = tcg_temp_new_i64(); | 114 | tcg_res[pass] = tcg_temp_new_i64(); |
115 | 115 | ||
116 | switch (opcode) { | 116 | switch (opcode) { |
117 | - case 0x12: /* XTN, SQXTUN */ | 117 | - case 0x12: /* XTN, SQXTUN */ |
118 | - { | 118 | - { |
119 | - static NeonGenOne64OpFn * const xtnfns[3] = { | 119 | - static NeonGenOne64OpFn * const xtnfns[3] = { |
120 | - gen_helper_neon_narrow_u8, | 120 | - gen_helper_neon_narrow_u8, |
121 | - gen_helper_neon_narrow_u16, | 121 | - gen_helper_neon_narrow_u16, |
122 | - tcg_gen_ext32u_i64, | 122 | - tcg_gen_ext32u_i64, |
123 | - }; | 123 | - }; |
124 | - static NeonGenOne64OpEnvFn * const sqxtunfns[3] = { | 124 | - static NeonGenOne64OpEnvFn * const sqxtunfns[3] = { |
125 | - gen_helper_neon_unarrow_sat8, | 125 | - gen_helper_neon_unarrow_sat8, |
126 | - gen_helper_neon_unarrow_sat16, | 126 | - gen_helper_neon_unarrow_sat16, |
127 | - gen_helper_neon_unarrow_sat32, | 127 | - gen_helper_neon_unarrow_sat32, |
128 | - }; | 128 | - }; |
129 | - if (u) { | 129 | - if (u) { |
130 | - genenvfn = sqxtunfns[size]; | 130 | - genenvfn = sqxtunfns[size]; |
131 | - } else { | 131 | - } else { |
132 | - genfn = xtnfns[size]; | 132 | - genfn = xtnfns[size]; |
133 | - } | 133 | - } |
134 | - break; | 134 | - break; |
135 | - } | 135 | - } |
136 | - case 0x14: /* SQXTN, UQXTN */ | 136 | - case 0x14: /* SQXTN, UQXTN */ |
137 | - { | 137 | - { |
138 | - static NeonGenOne64OpEnvFn * const fns[3][2] = { | 138 | - static NeonGenOne64OpEnvFn * const fns[3][2] = { |
139 | - { gen_helper_neon_narrow_sat_s8, | 139 | - { gen_helper_neon_narrow_sat_s8, |
140 | - gen_helper_neon_narrow_sat_u8 }, | 140 | - gen_helper_neon_narrow_sat_u8 }, |
141 | - { gen_helper_neon_narrow_sat_s16, | 141 | - { gen_helper_neon_narrow_sat_s16, |
142 | - gen_helper_neon_narrow_sat_u16 }, | 142 | - gen_helper_neon_narrow_sat_u16 }, |
143 | - { gen_helper_neon_narrow_sat_s32, | 143 | - { gen_helper_neon_narrow_sat_s32, |
144 | - gen_helper_neon_narrow_sat_u32 }, | 144 | - gen_helper_neon_narrow_sat_u32 }, |
145 | - }; | 145 | - }; |
146 | - genenvfn = fns[size][u]; | 146 | - genenvfn = fns[size][u]; |
147 | - break; | 147 | - break; |
148 | - } | 148 | - } |
149 | case 0x16: /* FCVTN, FCVTN2 */ | 149 | case 0x16: /* FCVTN, FCVTN2 */ |
150 | /* 32 bit to 16 bit or 64 bit to 32 bit float conversion */ | 150 | /* 32 bit to 16 bit or 64 bit to 32 bit float conversion */ |
151 | if (size == 2) { | 151 | if (size == 2) { |
152 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, | 152 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, |
153 | } | 153 | } |
154 | break; | 154 | break; |
155 | default: | 155 | default: |
156 | + case 0x12: /* XTN, SQXTUN */ | 156 | + case 0x12: /* XTN, SQXTUN */ |
157 | + case 0x14: /* SQXTN, UQXTN */ | 157 | + case 0x14: /* SQXTN, UQXTN */ |
158 | g_assert_not_reached(); | 158 | g_assert_not_reached(); |
159 | } | 159 | } |
160 | 160 | ||
161 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 161 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
162 | TCGv_ptr tcg_fpstatus; | 162 | TCGv_ptr tcg_fpstatus; |
163 | 163 | ||
164 | switch (opcode) { | 164 | switch (opcode) { |
165 | - case 0x12: /* SQXTUN */ | 165 | - case 0x12: /* SQXTUN */ |
166 | - if (!u) { | 166 | - if (!u) { |
167 | - unallocated_encoding(s); | 167 | - unallocated_encoding(s); |
168 | - return; | 168 | - return; |
169 | - } | 169 | - } |
170 | - /* fall through */ | 170 | - /* fall through */ |
171 | - case 0x14: /* SQXTN, UQXTN */ | 171 | - case 0x14: /* SQXTN, UQXTN */ |
172 | - if (size == 3) { | 172 | - if (size == 3) { |
173 | - unallocated_encoding(s); | 173 | - unallocated_encoding(s); |
174 | - return; | 174 | - return; |
175 | - } | 175 | - } |
176 | - if (!fp_access_check(s)) { | 176 | - if (!fp_access_check(s)) { |
177 | - return; | 177 | - return; |
178 | - } | 178 | - } |
179 | - handle_2misc_narrow(s, true, opcode, u, false, size, rn, rd); | 179 | - handle_2misc_narrow(s, true, opcode, u, false, size, rn, rd); |
180 | - return; | 180 | - return; |
181 | case 0xc ... 0xf: | 181 | case 0xc ... 0xf: |
182 | case 0x16 ... 0x1d: | 182 | case 0x16 ... 0x1d: |
183 | case 0x1f: | 183 | case 0x1f: |
184 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 184 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
185 | case 0x9: /* CMEQ, CMLE */ | 185 | case 0x9: /* CMEQ, CMLE */ |
186 | case 0xa: /* CMLT */ | 186 | case 0xa: /* CMLT */ |
187 | case 0xb: /* ABS, NEG */ | 187 | case 0xb: /* ABS, NEG */ |
188 | + case 0x12: /* SQXTUN */ | 188 | + case 0x12: /* SQXTUN */ |
189 | + case 0x14: /* SQXTN, UQXTN */ | 189 | + case 0x14: /* SQXTN, UQXTN */ |
190 | unallocated_encoding(s); | 190 | unallocated_encoding(s); |
191 | return; | 191 | return; |
192 | } | 192 | } |
193 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 193 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
194 | TCGv_ptr tcg_fpstatus; | 194 | TCGv_ptr tcg_fpstatus; |
195 | 195 | ||
196 | switch (opcode) { | 196 | switch (opcode) { |
197 | - case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ | 197 | - case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ |
198 | - case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ | 198 | - case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ |
199 | - if (size == 3) { | 199 | - if (size == 3) { |
200 | - unallocated_encoding(s); | 200 | - unallocated_encoding(s); |
201 | - return; | 201 | - return; |
202 | - } | 202 | - } |
203 | - if (!fp_access_check(s)) { | 203 | - if (!fp_access_check(s)) { |
204 | - return; | 204 | - return; |
205 | - } | 205 | - } |
206 | - | 206 | - |
207 | - handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd); | 207 | - handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd); |
208 | - return; | 208 | - return; |
209 | case 0x13: /* SHLL, SHLL2 */ | 209 | case 0x13: /* SHLL, SHLL2 */ |
210 | if (u == 0 || size == 3) { | 210 | if (u == 0 || size == 3) { |
211 | unallocated_encoding(s); | 211 | unallocated_encoding(s); |
212 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 212 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
213 | case 0x9: /* CMEQ, CMLE */ | 213 | case 0x9: /* CMEQ, CMLE */ |
214 | case 0xa: /* CMLT */ | 214 | case 0xa: /* CMLT */ |
215 | case 0xb: /* ABS, NEG */ | 215 | case 0xb: /* ABS, NEG */ |
216 | + case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ | 216 | + case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ |
217 | + case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ | 217 | + case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ |
218 | unallocated_encoding(s); | 218 | unallocated_encoding(s); |
219 | return; | 219 | return; |
220 | } | 220 | } |
221 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 221 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
222 | index XXXXXXX..XXXXXXX 100644 | 222 | index XXXXXXX..XXXXXXX 100644 |
223 | --- a/target/arm/tcg/a64.decode | 223 | --- a/target/arm/tcg/a64.decode |
224 | +++ b/target/arm/tcg/a64.decode | 224 | +++ b/target/arm/tcg/a64.decode |
225 | @@ -XXX,XX +XXX,XX @@ CMEQ0_s 0101 1110 111 00000 10011 0 ..... ..... @rr | 225 | @@ -XXX,XX +XXX,XX @@ CMEQ0_s 0101 1110 111 00000 10011 0 ..... ..... @rr |
226 | CMLE0_s 0111 1110 111 00000 10011 0 ..... ..... @rr | 226 | CMLE0_s 0111 1110 111 00000 10011 0 ..... ..... @rr |
227 | CMLT0_s 0101 1110 111 00000 10101 0 ..... ..... @rr | 227 | CMLT0_s 0101 1110 111 00000 10101 0 ..... ..... @rr |
228 | 228 | ||
229 | +SQXTUN_s 0111 1110 ..1 00001 00101 0 ..... ..... @rr_e | 229 | +SQXTUN_s 0111 1110 ..1 00001 00101 0 ..... ..... @rr_e |
230 | +SQXTN_s 0101 1110 ..1 00001 01001 0 ..... ..... @rr_e | 230 | +SQXTN_s 0101 1110 ..1 00001 01001 0 ..... ..... @rr_e |
231 | +UQXTN_s 0111 1110 ..1 00001 01001 0 ..... ..... @rr_e | 231 | +UQXTN_s 0111 1110 ..1 00001 01001 0 ..... ..... @rr_e |
232 | + | 232 | + |
233 | # Advanced SIMD two-register miscellaneous | 233 | # Advanced SIMD two-register miscellaneous |
234 | 234 | ||
235 | SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 235 | SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
236 | @@ -XXX,XX +XXX,XX @@ SADDLP_v 0.00 1110 ..1 00000 00101 0 ..... ..... @qrr_e | 236 | @@ -XXX,XX +XXX,XX @@ SADDLP_v 0.00 1110 ..1 00000 00101 0 ..... ..... @qrr_e |
237 | UADDLP_v 0.10 1110 ..1 00000 00101 0 ..... ..... @qrr_e | 237 | UADDLP_v 0.10 1110 ..1 00000 00101 0 ..... ..... @qrr_e |
238 | SADALP_v 0.00 1110 ..1 00000 01101 0 ..... ..... @qrr_e | 238 | SADALP_v 0.00 1110 ..1 00000 01101 0 ..... ..... @qrr_e |
239 | UADALP_v 0.10 1110 ..1 00000 01101 0 ..... ..... @qrr_e | 239 | UADALP_v 0.10 1110 ..1 00000 01101 0 ..... ..... @qrr_e |
240 | + | 240 | + |
241 | +XTN 0.00 1110 ..1 00001 00101 0 ..... ..... @qrr_e | 241 | +XTN 0.00 1110 ..1 00001 00101 0 ..... ..... @qrr_e |
242 | +SQXTUN_v 0.10 1110 ..1 00001 00101 0 ..... ..... @qrr_e | 242 | +SQXTUN_v 0.10 1110 ..1 00001 00101 0 ..... ..... @qrr_e |
243 | +SQXTN_v 0.00 1110 ..1 00001 01001 0 ..... ..... @qrr_e | 243 | +SQXTN_v 0.00 1110 ..1 00001 01001 0 ..... ..... @qrr_e |
244 | +UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e | 244 | +UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e |
245 | -- | 245 | -- |
246 | 2.43.0 | 246 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 89 ++++++++++++++++++---------------- | 4 | target/arm/tcg/translate-a64.c | 89 ++++++++++++++++++---------------- |
5 | target/arm/tcg/a64.decode | 5 ++ | 5 | target/arm/tcg/a64.decode | 5 ++ |
6 | 2 files changed, 52 insertions(+), 42 deletions(-) | 6 | 2 files changed, 52 insertions(+), 42 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ TRANS(SQXTUN_v, do_2misc_narrow_vector, a, f_scalar_sqxtun) | 12 | @@ -XXX,XX +XXX,XX @@ TRANS(SQXTUN_v, do_2misc_narrow_vector, a, f_scalar_sqxtun) |
13 | TRANS(SQXTN_v, do_2misc_narrow_vector, a, f_scalar_sqxtn) | 13 | TRANS(SQXTN_v, do_2misc_narrow_vector, a, f_scalar_sqxtn) |
14 | TRANS(UQXTN_v, do_2misc_narrow_vector, a, f_scalar_uqxtn) | 14 | TRANS(UQXTN_v, do_2misc_narrow_vector, a, f_scalar_uqxtn) |
15 | 15 | ||
16 | +static void gen_fcvtn_hs(TCGv_i64 d, TCGv_i64 n) | 16 | +static void gen_fcvtn_hs(TCGv_i64 d, TCGv_i64 n) |
17 | +{ | 17 | +{ |
18 | + TCGv_i32 tcg_lo = tcg_temp_new_i32(); | 18 | + TCGv_i32 tcg_lo = tcg_temp_new_i32(); |
19 | + TCGv_i32 tcg_hi = tcg_temp_new_i32(); | 19 | + TCGv_i32 tcg_hi = tcg_temp_new_i32(); |
20 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 20 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
21 | + TCGv_i32 ahp = get_ahp_flag(); | 21 | + TCGv_i32 ahp = get_ahp_flag(); |
22 | + | 22 | + |
23 | + tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, n); | 23 | + tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, n); |
24 | + gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, fpst, ahp); | 24 | + gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, fpst, ahp); |
25 | + gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, fpst, ahp); | 25 | + gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, fpst, ahp); |
26 | + tcg_gen_deposit_i32(tcg_lo, tcg_lo, tcg_hi, 16, 16); | 26 | + tcg_gen_deposit_i32(tcg_lo, tcg_lo, tcg_hi, 16, 16); |
27 | + tcg_gen_extu_i32_i64(d, tcg_lo); | 27 | + tcg_gen_extu_i32_i64(d, tcg_lo); |
28 | +} | 28 | +} |
29 | + | 29 | + |
30 | +static void gen_fcvtn_sd(TCGv_i64 d, TCGv_i64 n) | 30 | +static void gen_fcvtn_sd(TCGv_i64 d, TCGv_i64 n) |
31 | +{ | 31 | +{ |
32 | + TCGv_i32 tmp = tcg_temp_new_i32(); | 32 | + TCGv_i32 tmp = tcg_temp_new_i32(); |
33 | + gen_helper_vfp_fcvtsd(tmp, n, tcg_env); | 33 | + gen_helper_vfp_fcvtsd(tmp, n, tcg_env); |
34 | + tcg_gen_extu_i32_i64(d, tmp); | 34 | + tcg_gen_extu_i32_i64(d, tmp); |
35 | +} | 35 | +} |
36 | + | 36 | + |
37 | +static ArithOneOp * const f_vector_fcvtn[] = { | 37 | +static ArithOneOp * const f_vector_fcvtn[] = { |
38 | + NULL, | 38 | + NULL, |
39 | + gen_fcvtn_hs, | 39 | + gen_fcvtn_hs, |
40 | + gen_fcvtn_sd, | 40 | + gen_fcvtn_sd, |
41 | +}; | 41 | +}; |
42 | +TRANS(FCVTN_v, do_2misc_narrow_vector, a, f_vector_fcvtn) | 42 | +TRANS(FCVTN_v, do_2misc_narrow_vector, a, f_vector_fcvtn) |
43 | + | 43 | + |
44 | +static void gen_bfcvtn_hs(TCGv_i64 d, TCGv_i64 n) | 44 | +static void gen_bfcvtn_hs(TCGv_i64 d, TCGv_i64 n) |
45 | +{ | 45 | +{ |
46 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 46 | + TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
47 | + TCGv_i32 tmp = tcg_temp_new_i32(); | 47 | + TCGv_i32 tmp = tcg_temp_new_i32(); |
48 | + gen_helper_bfcvt_pair(tmp, n, fpst); | 48 | + gen_helper_bfcvt_pair(tmp, n, fpst); |
49 | + tcg_gen_extu_i32_i64(d, tmp); | 49 | + tcg_gen_extu_i32_i64(d, tmp); |
50 | +} | 50 | +} |
51 | + | 51 | + |
52 | +static ArithOneOp * const f_vector_bfcvtn[] = { | 52 | +static ArithOneOp * const f_vector_bfcvtn[] = { |
53 | + NULL, | 53 | + NULL, |
54 | + gen_bfcvtn_hs, | 54 | + gen_bfcvtn_hs, |
55 | + NULL, | 55 | + NULL, |
56 | +}; | 56 | +}; |
57 | +TRANS_FEAT(BFCVTN_v, aa64_bf16, do_2misc_narrow_vector, a, f_vector_bfcvtn) | 57 | +TRANS_FEAT(BFCVTN_v, aa64_bf16, do_2misc_narrow_vector, a, f_vector_bfcvtn) |
58 | + | 58 | + |
59 | /* Common vector code for handling integer to FP conversion */ | 59 | /* Common vector code for handling integer to FP conversion */ |
60 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 60 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
61 | int elements, int is_signed, | 61 | int elements, int is_signed, |
62 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, | 62 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, |
63 | tcg_res[pass] = tcg_temp_new_i64(); | 63 | tcg_res[pass] = tcg_temp_new_i64(); |
64 | 64 | ||
65 | switch (opcode) { | 65 | switch (opcode) { |
66 | - case 0x16: /* FCVTN, FCVTN2 */ | 66 | - case 0x16: /* FCVTN, FCVTN2 */ |
67 | - /* 32 bit to 16 bit or 64 bit to 32 bit float conversion */ | 67 | - /* 32 bit to 16 bit or 64 bit to 32 bit float conversion */ |
68 | - if (size == 2) { | 68 | - if (size == 2) { |
69 | - TCGv_i32 tmp = tcg_temp_new_i32(); | 69 | - TCGv_i32 tmp = tcg_temp_new_i32(); |
70 | - gen_helper_vfp_fcvtsd(tmp, tcg_op, tcg_env); | 70 | - gen_helper_vfp_fcvtsd(tmp, tcg_op, tcg_env); |
71 | - tcg_gen_extu_i32_i64(tcg_res[pass], tmp); | 71 | - tcg_gen_extu_i32_i64(tcg_res[pass], tmp); |
72 | - } else { | 72 | - } else { |
73 | - TCGv_i32 tcg_lo = tcg_temp_new_i32(); | 73 | - TCGv_i32 tcg_lo = tcg_temp_new_i32(); |
74 | - TCGv_i32 tcg_hi = tcg_temp_new_i32(); | 74 | - TCGv_i32 tcg_hi = tcg_temp_new_i32(); |
75 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 75 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
76 | - TCGv_i32 ahp = get_ahp_flag(); | 76 | - TCGv_i32 ahp = get_ahp_flag(); |
77 | - | 77 | - |
78 | - tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, tcg_op); | 78 | - tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, tcg_op); |
79 | - gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, fpst, ahp); | 79 | - gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, fpst, ahp); |
80 | - gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, fpst, ahp); | 80 | - gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, fpst, ahp); |
81 | - tcg_gen_deposit_i32(tcg_lo, tcg_lo, tcg_hi, 16, 16); | 81 | - tcg_gen_deposit_i32(tcg_lo, tcg_lo, tcg_hi, 16, 16); |
82 | - tcg_gen_extu_i32_i64(tcg_res[pass], tcg_lo); | 82 | - tcg_gen_extu_i32_i64(tcg_res[pass], tcg_lo); |
83 | - } | 83 | - } |
84 | - break; | 84 | - break; |
85 | - case 0x36: /* BFCVTN, BFCVTN2 */ | 85 | - case 0x36: /* BFCVTN, BFCVTN2 */ |
86 | - { | 86 | - { |
87 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 87 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
88 | - TCGv_i32 tmp = tcg_temp_new_i32(); | 88 | - TCGv_i32 tmp = tcg_temp_new_i32(); |
89 | - gen_helper_bfcvt_pair(tmp, tcg_op, fpst); | 89 | - gen_helper_bfcvt_pair(tmp, tcg_op, fpst); |
90 | - tcg_gen_extu_i32_i64(tcg_res[pass], tmp); | 90 | - tcg_gen_extu_i32_i64(tcg_res[pass], tmp); |
91 | - } | 91 | - } |
92 | - break; | 92 | - break; |
93 | case 0x56: /* FCVTXN, FCVTXN2 */ | 93 | case 0x56: /* FCVTXN, FCVTXN2 */ |
94 | { | 94 | { |
95 | /* | 95 | /* |
96 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, | 96 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar, |
97 | default: | 97 | default: |
98 | case 0x12: /* XTN, SQXTUN */ | 98 | case 0x12: /* XTN, SQXTUN */ |
99 | case 0x14: /* SQXTN, UQXTN */ | 99 | case 0x14: /* SQXTN, UQXTN */ |
100 | + case 0x16: /* FCVTN, FCVTN2 */ | 100 | + case 0x16: /* FCVTN, FCVTN2 */ |
101 | + case 0x36: /* BFCVTN, BFCVTN2 */ | 101 | + case 0x36: /* BFCVTN, BFCVTN2 */ |
102 | g_assert_not_reached(); | 102 | g_assert_not_reached(); |
103 | } | 103 | } |
104 | 104 | ||
105 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 105 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
106 | unallocated_encoding(s); | 106 | unallocated_encoding(s); |
107 | return; | 107 | return; |
108 | } | 108 | } |
109 | - /* fall through */ | 109 | - /* fall through */ |
110 | - case 0x16: /* FCVTN, FCVTN2 */ | 110 | - case 0x16: /* FCVTN, FCVTN2 */ |
111 | - /* handle_2misc_narrow does a 2*size -> size operation, but these | 111 | - /* handle_2misc_narrow does a 2*size -> size operation, but these |
112 | - * instructions encode the source size rather than dest size. | 112 | - * instructions encode the source size rather than dest size. |
113 | - */ | 113 | - */ |
114 | - if (!fp_access_check(s)) { | 114 | - if (!fp_access_check(s)) { |
115 | - return; | 115 | - return; |
116 | - } | 116 | - } |
117 | - handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd); | 117 | - handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd); |
118 | - return; | 118 | - return; |
119 | - case 0x36: /* BFCVTN, BFCVTN2 */ | 119 | - case 0x36: /* BFCVTN, BFCVTN2 */ |
120 | - if (!dc_isar_feature(aa64_bf16, s) || size != 2) { | 120 | - if (!dc_isar_feature(aa64_bf16, s) || size != 2) { |
121 | - unallocated_encoding(s); | 121 | - unallocated_encoding(s); |
122 | - return; | 122 | - return; |
123 | - } | 123 | - } |
124 | if (!fp_access_check(s)) { | 124 | if (!fp_access_check(s)) { |
125 | return; | 125 | return; |
126 | } | 126 | } |
127 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 127 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
128 | } | 128 | } |
129 | break; | 129 | break; |
130 | default: | 130 | default: |
131 | + case 0x16: /* FCVTN, FCVTN2 */ | 131 | + case 0x16: /* FCVTN, FCVTN2 */ |
132 | + case 0x36: /* BFCVTN, BFCVTN2 */ | 132 | + case 0x36: /* BFCVTN, BFCVTN2 */ |
133 | unallocated_encoding(s); | 133 | unallocated_encoding(s); |
134 | return; | 134 | return; |
135 | } | 135 | } |
136 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 136 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
137 | index XXXXXXX..XXXXXXX 100644 | 137 | index XXXXXXX..XXXXXXX 100644 |
138 | --- a/target/arm/tcg/a64.decode | 138 | --- a/target/arm/tcg/a64.decode |
139 | +++ b/target/arm/tcg/a64.decode | 139 | +++ b/target/arm/tcg/a64.decode |
140 | @@ -XXX,XX +XXX,XX @@ | 140 | @@ -XXX,XX +XXX,XX @@ |
141 | 141 | ||
142 | %rd 0:5 | 142 | %rd 0:5 |
143 | %esz_sd 22:1 !function=plus_2 | 143 | %esz_sd 22:1 !function=plus_2 |
144 | +%esz_hs 22:1 !function=plus_1 | 144 | +%esz_hs 22:1 !function=plus_1 |
145 | %esz_hsd 22:2 !function=xor_2 | 145 | %esz_hsd 22:2 !function=xor_2 |
146 | %hl 11:1 21:1 | 146 | %hl 11:1 21:1 |
147 | %hlm 11:1 20:2 | 147 | %hlm 11:1 20:2 |
148 | @@ -XXX,XX +XXX,XX @@ | 148 | @@ -XXX,XX +XXX,XX @@ |
149 | @qrr_b . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=0 | 149 | @qrr_b . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=0 |
150 | @qrr_h . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=1 | 150 | @qrr_h . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=1 |
151 | @qrr_bh . q:1 ...... . esz:1 ...... ...... rn:5 rd:5 &qrr_e | 151 | @qrr_bh . q:1 ...... . esz:1 ...... ...... rn:5 rd:5 &qrr_e |
152 | +@qrr_hs . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=%esz_hs | 152 | +@qrr_hs . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=%esz_hs |
153 | @qrr_e . q:1 ...... esz:2 ...... ...... rn:5 rd:5 &qrr_e | 153 | @qrr_e . q:1 ...... esz:2 ...... ...... rn:5 rd:5 &qrr_e |
154 | 154 | ||
155 | @qrrr_b . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=0 | 155 | @qrrr_b . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=0 |
156 | @@ -XXX,XX +XXX,XX @@ XTN 0.00 1110 ..1 00001 00101 0 ..... ..... @qrr_e | 156 | @@ -XXX,XX +XXX,XX @@ XTN 0.00 1110 ..1 00001 00101 0 ..... ..... @qrr_e |
157 | SQXTUN_v 0.10 1110 ..1 00001 00101 0 ..... ..... @qrr_e | 157 | SQXTUN_v 0.10 1110 ..1 00001 00101 0 ..... ..... @qrr_e |
158 | SQXTN_v 0.00 1110 ..1 00001 01001 0 ..... ..... @qrr_e | 158 | SQXTN_v 0.00 1110 ..1 00001 01001 0 ..... ..... @qrr_e |
159 | UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e | 159 | UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e |
160 | + | 160 | + |
161 | +FCVTN_v 0.00 1110 0.1 00001 01101 0 ..... ..... @qrr_hs | 161 | +FCVTN_v 0.00 1110 0.1 00001 01101 0 ..... ..... @qrr_hs |
162 | +BFCVTN_v 0.00 1110 101 00001 01101 0 ..... ..... @qrr_h | 162 | +BFCVTN_v 0.00 1110 101 00001 01101 0 ..... ..... @qrr_h |
163 | -- | 163 | -- |
164 | 2.43.0 | 164 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove handle_2misc_narrow as this was the last insn decoded | 1 | Remove handle_2misc_narrow as this was the last insn decoded |
---|---|---|---|
2 | by that function. | 2 | by that function. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 6 | --- |
7 | target/arm/tcg/translate-a64.c | 101 +++++++-------------------------- | 7 | target/arm/tcg/translate-a64.c | 101 +++++++-------------------------- |
8 | target/arm/tcg/a64.decode | 4 ++ | 8 | target/arm/tcg/a64.decode | 4 ++ |
9 | 2 files changed, 24 insertions(+), 81 deletions(-) | 9 | 2 files changed, 24 insertions(+), 81 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 11 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/tcg/translate-a64.c | 13 | --- a/target/arm/tcg/translate-a64.c |
14 | +++ b/target/arm/tcg/translate-a64.c | 14 | +++ b/target/arm/tcg/translate-a64.c |
15 | @@ -XXX,XX +XXX,XX @@ static ArithOneOp * const f_scalar_uqxtn[] = { | 15 | @@ -XXX,XX +XXX,XX @@ static ArithOneOp * const f_scalar_uqxtn[] = { |
16 | }; | 16 | }; |
17 | TRANS(UQXTN_s, do_2misc_narrow_scalar, a, f_scalar_uqxtn) | 17 | TRANS(UQXTN_s, do_2misc_narrow_scalar, a, f_scalar_uqxtn) |
18 | 18 | ||
19 | +static void gen_fcvtxn_sd(TCGv_i64 d, TCGv_i64 n) | 19 | +static void gen_fcvtxn_sd(TCGv_i64 d, TCGv_i64 n) |
20 | +{ | 20 | +{ |
21 | + /* | 21 | + /* |
22 | + * 64 bit to 32 bit float conversion | 22 | + * 64 bit to 32 bit float conversion |
23 | + * with von Neumann rounding (round to odd) | 23 | + * with von Neumann rounding (round to odd) |
24 | + */ | 24 | + */ |
25 | + TCGv_i32 tmp = tcg_temp_new_i32(); | 25 | + TCGv_i32 tmp = tcg_temp_new_i32(); |
26 | + gen_helper_fcvtx_f64_to_f32(tmp, n, tcg_env); | 26 | + gen_helper_fcvtx_f64_to_f32(tmp, n, tcg_env); |
27 | + tcg_gen_extu_i32_i64(d, tmp); | 27 | + tcg_gen_extu_i32_i64(d, tmp); |
28 | +} | 28 | +} |
29 | + | 29 | + |
30 | +static ArithOneOp * const f_scalar_fcvtxn[] = { | 30 | +static ArithOneOp * const f_scalar_fcvtxn[] = { |
31 | + NULL, | 31 | + NULL, |
32 | + NULL, | 32 | + NULL, |
33 | + gen_fcvtxn_sd, | 33 | + gen_fcvtxn_sd, |
34 | +}; | 34 | +}; |
35 | +TRANS(FCVTXN_s, do_2misc_narrow_scalar, a, f_scalar_fcvtxn) | 35 | +TRANS(FCVTXN_s, do_2misc_narrow_scalar, a, f_scalar_fcvtxn) |
36 | + | 36 | + |
37 | #undef WRAP_ENV | 37 | #undef WRAP_ENV |
38 | 38 | ||
39 | static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) | 39 | static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn) |
40 | @@ -XXX,XX +XXX,XX @@ static ArithOneOp * const f_vector_fcvtn[] = { | 40 | @@ -XXX,XX +XXX,XX @@ static ArithOneOp * const f_vector_fcvtn[] = { |
41 | gen_fcvtn_sd, | 41 | gen_fcvtn_sd, |
42 | }; | 42 | }; |
43 | TRANS(FCVTN_v, do_2misc_narrow_vector, a, f_vector_fcvtn) | 43 | TRANS(FCVTN_v, do_2misc_narrow_vector, a, f_vector_fcvtn) |
44 | +TRANS(FCVTXN_v, do_2misc_narrow_vector, a, f_scalar_fcvtxn) | 44 | +TRANS(FCVTXN_v, do_2misc_narrow_vector, a, f_scalar_fcvtxn) |
45 | 45 | ||
46 | static void gen_bfcvtn_hs(TCGv_i64 d, TCGv_i64 n) | 46 | static void gen_bfcvtn_hs(TCGv_i64 d, TCGv_i64 n) |
47 | { | 47 | { |
48 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode, | 48 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode, |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | -static void handle_2misc_narrow(DisasContext *s, bool scalar, | 52 | -static void handle_2misc_narrow(DisasContext *s, bool scalar, |
53 | - int opcode, bool u, bool is_q, | 53 | - int opcode, bool u, bool is_q, |
54 | - int size, int rn, int rd) | 54 | - int size, int rn, int rd) |
55 | -{ | 55 | -{ |
56 | - /* Handle 2-reg-misc ops which are narrowing (so each 2*size element | 56 | - /* Handle 2-reg-misc ops which are narrowing (so each 2*size element |
57 | - * in the source becomes a size element in the destination). | 57 | - * in the source becomes a size element in the destination). |
58 | - */ | 58 | - */ |
59 | - int pass; | 59 | - int pass; |
60 | - TCGv_i64 tcg_res[2]; | 60 | - TCGv_i64 tcg_res[2]; |
61 | - int destelt = is_q ? 2 : 0; | 61 | - int destelt = is_q ? 2 : 0; |
62 | - int passes = scalar ? 1 : 2; | 62 | - int passes = scalar ? 1 : 2; |
63 | - | 63 | - |
64 | - if (scalar) { | 64 | - if (scalar) { |
65 | - tcg_res[1] = tcg_constant_i64(0); | 65 | - tcg_res[1] = tcg_constant_i64(0); |
66 | - } | 66 | - } |
67 | - | 67 | - |
68 | - for (pass = 0; pass < passes; pass++) { | 68 | - for (pass = 0; pass < passes; pass++) { |
69 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); | 69 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); |
70 | - NeonGenOne64OpFn *genfn = NULL; | 70 | - NeonGenOne64OpFn *genfn = NULL; |
71 | - NeonGenOne64OpEnvFn *genenvfn = NULL; | 71 | - NeonGenOne64OpEnvFn *genenvfn = NULL; |
72 | - | 72 | - |
73 | - if (scalar) { | 73 | - if (scalar) { |
74 | - read_vec_element(s, tcg_op, rn, pass, size + 1); | 74 | - read_vec_element(s, tcg_op, rn, pass, size + 1); |
75 | - } else { | 75 | - } else { |
76 | - read_vec_element(s, tcg_op, rn, pass, MO_64); | 76 | - read_vec_element(s, tcg_op, rn, pass, MO_64); |
77 | - } | 77 | - } |
78 | - tcg_res[pass] = tcg_temp_new_i64(); | 78 | - tcg_res[pass] = tcg_temp_new_i64(); |
79 | - | 79 | - |
80 | - switch (opcode) { | 80 | - switch (opcode) { |
81 | - case 0x56: /* FCVTXN, FCVTXN2 */ | 81 | - case 0x56: /* FCVTXN, FCVTXN2 */ |
82 | - { | 82 | - { |
83 | - /* | 83 | - /* |
84 | - * 64 bit to 32 bit float conversion | 84 | - * 64 bit to 32 bit float conversion |
85 | - * with von Neumann rounding (round to odd) | 85 | - * with von Neumann rounding (round to odd) |
86 | - */ | 86 | - */ |
87 | - TCGv_i32 tmp = tcg_temp_new_i32(); | 87 | - TCGv_i32 tmp = tcg_temp_new_i32(); |
88 | - assert(size == 2); | 88 | - assert(size == 2); |
89 | - gen_helper_fcvtx_f64_to_f32(tmp, tcg_op, tcg_env); | 89 | - gen_helper_fcvtx_f64_to_f32(tmp, tcg_op, tcg_env); |
90 | - tcg_gen_extu_i32_i64(tcg_res[pass], tmp); | 90 | - tcg_gen_extu_i32_i64(tcg_res[pass], tmp); |
91 | - } | 91 | - } |
92 | - break; | 92 | - break; |
93 | - default: | 93 | - default: |
94 | - case 0x12: /* XTN, SQXTUN */ | 94 | - case 0x12: /* XTN, SQXTUN */ |
95 | - case 0x14: /* SQXTN, UQXTN */ | 95 | - case 0x14: /* SQXTN, UQXTN */ |
96 | - case 0x16: /* FCVTN, FCVTN2 */ | 96 | - case 0x16: /* FCVTN, FCVTN2 */ |
97 | - case 0x36: /* BFCVTN, BFCVTN2 */ | 97 | - case 0x36: /* BFCVTN, BFCVTN2 */ |
98 | - g_assert_not_reached(); | 98 | - g_assert_not_reached(); |
99 | - } | 99 | - } |
100 | - | 100 | - |
101 | - if (genfn) { | 101 | - if (genfn) { |
102 | - genfn(tcg_res[pass], tcg_op); | 102 | - genfn(tcg_res[pass], tcg_op); |
103 | - } else if (genenvfn) { | 103 | - } else if (genenvfn) { |
104 | - genenvfn(tcg_res[pass], tcg_env, tcg_op); | 104 | - genenvfn(tcg_res[pass], tcg_env, tcg_op); |
105 | - } | 105 | - } |
106 | - } | 106 | - } |
107 | - | 107 | - |
108 | - for (pass = 0; pass < 2; pass++) { | 108 | - for (pass = 0; pass < 2; pass++) { |
109 | - write_vec_element(s, tcg_res[pass], rd, destelt + pass, MO_32); | 109 | - write_vec_element(s, tcg_res[pass], rd, destelt + pass, MO_32); |
110 | - } | 110 | - } |
111 | - clear_vec_high(s, is_q, rd); | 111 | - clear_vec_high(s, is_q, rd); |
112 | -} | 112 | -} |
113 | - | 113 | - |
114 | /* AdvSIMD scalar two reg misc | 114 | /* AdvSIMD scalar two reg misc |
115 | * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 | 115 | * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 |
116 | * +-----+---+-----------+------+-----------+--------+-----+------+------+ | 116 | * +-----+---+-----------+------+-----------+--------+-----+------+------+ |
117 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 117 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
118 | rmode = FPROUNDING_TIEAWAY; | 118 | rmode = FPROUNDING_TIEAWAY; |
119 | break; | 119 | break; |
120 | case 0x56: /* FCVTXN, FCVTXN2 */ | 120 | case 0x56: /* FCVTXN, FCVTXN2 */ |
121 | - if (size == 2) { | 121 | - if (size == 2) { |
122 | - unallocated_encoding(s); | 122 | - unallocated_encoding(s); |
123 | - return; | 123 | - return; |
124 | - } | 124 | - } |
125 | - if (!fp_access_check(s)) { | 125 | - if (!fp_access_check(s)) { |
126 | - return; | 126 | - return; |
127 | - } | 127 | - } |
128 | - handle_2misc_narrow(s, true, opcode, u, false, size - 1, rn, rd); | 128 | - handle_2misc_narrow(s, true, opcode, u, false, size - 1, rn, rd); |
129 | - return; | 129 | - return; |
130 | default: | 130 | default: |
131 | unallocated_encoding(s); | 131 | unallocated_encoding(s); |
132 | return; | 132 | return; |
133 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 133 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
134 | } | 134 | } |
135 | handle_2misc_reciprocal(s, opcode, false, u, is_q, size, rn, rd); | 135 | handle_2misc_reciprocal(s, opcode, false, u, is_q, size, rn, rd); |
136 | return; | 136 | return; |
137 | - case 0x56: /* FCVTXN, FCVTXN2 */ | 137 | - case 0x56: /* FCVTXN, FCVTXN2 */ |
138 | - if (size == 2) { | 138 | - if (size == 2) { |
139 | - unallocated_encoding(s); | 139 | - unallocated_encoding(s); |
140 | - return; | 140 | - return; |
141 | - } | 141 | - } |
142 | - if (!fp_access_check(s)) { | 142 | - if (!fp_access_check(s)) { |
143 | - return; | 143 | - return; |
144 | - } | 144 | - } |
145 | - handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd); | 145 | - handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd); |
146 | - return; | 146 | - return; |
147 | case 0x17: /* FCVTL, FCVTL2 */ | 147 | case 0x17: /* FCVTL, FCVTL2 */ |
148 | if (!fp_access_check(s)) { | 148 | if (!fp_access_check(s)) { |
149 | return; | 149 | return; |
150 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 150 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
151 | default: | 151 | default: |
152 | case 0x16: /* FCVTN, FCVTN2 */ | 152 | case 0x16: /* FCVTN, FCVTN2 */ |
153 | case 0x36: /* BFCVTN, BFCVTN2 */ | 153 | case 0x36: /* BFCVTN, BFCVTN2 */ |
154 | + case 0x56: /* FCVTXN, FCVTXN2 */ | 154 | + case 0x56: /* FCVTXN, FCVTXN2 */ |
155 | unallocated_encoding(s); | 155 | unallocated_encoding(s); |
156 | return; | 156 | return; |
157 | } | 157 | } |
158 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 158 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
159 | index XXXXXXX..XXXXXXX 100644 | 159 | index XXXXXXX..XXXXXXX 100644 |
160 | --- a/target/arm/tcg/a64.decode | 160 | --- a/target/arm/tcg/a64.decode |
161 | +++ b/target/arm/tcg/a64.decode | 161 | +++ b/target/arm/tcg/a64.decode |
162 | @@ -XXX,XX +XXX,XX @@ | 162 | @@ -XXX,XX +XXX,XX @@ |
163 | 163 | ||
164 | @qrr_b . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=0 | 164 | @qrr_b . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=0 |
165 | @qrr_h . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=1 | 165 | @qrr_h . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=1 |
166 | +@qrr_s . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=2 | 166 | +@qrr_s . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=2 |
167 | @qrr_bh . q:1 ...... . esz:1 ...... ...... rn:5 rd:5 &qrr_e | 167 | @qrr_bh . q:1 ...... . esz:1 ...... ...... rn:5 rd:5 &qrr_e |
168 | @qrr_hs . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=%esz_hs | 168 | @qrr_hs . q:1 ...... .. ...... ...... rn:5 rd:5 &qrr_e esz=%esz_hs |
169 | @qrr_e . q:1 ...... esz:2 ...... ...... rn:5 rd:5 &qrr_e | 169 | @qrr_e . q:1 ...... esz:2 ...... ...... rn:5 rd:5 &qrr_e |
170 | @@ -XXX,XX +XXX,XX @@ SQXTUN_s 0111 1110 ..1 00001 00101 0 ..... ..... @rr_e | 170 | @@ -XXX,XX +XXX,XX @@ SQXTUN_s 0111 1110 ..1 00001 00101 0 ..... ..... @rr_e |
171 | SQXTN_s 0101 1110 ..1 00001 01001 0 ..... ..... @rr_e | 171 | SQXTN_s 0101 1110 ..1 00001 01001 0 ..... ..... @rr_e |
172 | UQXTN_s 0111 1110 ..1 00001 01001 0 ..... ..... @rr_e | 172 | UQXTN_s 0111 1110 ..1 00001 01001 0 ..... ..... @rr_e |
173 | 173 | ||
174 | +FCVTXN_s 0111 1110 011 00001 01101 0 ..... ..... @rr_s | 174 | +FCVTXN_s 0111 1110 011 00001 01101 0 ..... ..... @rr_s |
175 | + | 175 | + |
176 | # Advanced SIMD two-register miscellaneous | 176 | # Advanced SIMD two-register miscellaneous |
177 | 177 | ||
178 | SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e | 178 | SQABS_v 0.00 1110 ..1 00000 01111 0 ..... ..... @qrr_e |
179 | @@ -XXX,XX +XXX,XX @@ SQXTN_v 0.00 1110 ..1 00001 01001 0 ..... ..... @qrr_e | 179 | @@ -XXX,XX +XXX,XX @@ SQXTN_v 0.00 1110 ..1 00001 01001 0 ..... ..... @qrr_e |
180 | UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e | 180 | UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e |
181 | 181 | ||
182 | FCVTN_v 0.00 1110 0.1 00001 01101 0 ..... ..... @qrr_hs | 182 | FCVTN_v 0.00 1110 0.1 00001 01101 0 ..... ..... @qrr_hs |
183 | +FCVTXN_v 0.10 1110 011 00001 01101 0 ..... ..... @qrr_s | 183 | +FCVTXN_v 0.10 1110 011 00001 01101 0 ..... ..... @qrr_s |
184 | BFCVTN_v 0.00 1110 101 00001 01101 0 ..... ..... @qrr_h | 184 | BFCVTN_v 0.00 1110 101 00001 01101 0 ..... ..... @qrr_h |
185 | -- | 185 | -- |
186 | 2.43.0 | 186 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 75 +++++++++++++++++----------------- | 4 | target/arm/tcg/translate-a64.c | 75 +++++++++++++++++----------------- |
5 | target/arm/tcg/a64.decode | 2 + | 5 | target/arm/tcg/a64.decode | 2 + |
6 | 2 files changed, 40 insertions(+), 37 deletions(-) | 6 | 2 files changed, 40 insertions(+), 37 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static ArithOneOp * const f_vector_bfcvtn[] = { | 12 | @@ -XXX,XX +XXX,XX @@ static ArithOneOp * const f_vector_bfcvtn[] = { |
13 | }; | 13 | }; |
14 | TRANS_FEAT(BFCVTN_v, aa64_bf16, do_2misc_narrow_vector, a, f_vector_bfcvtn) | 14 | TRANS_FEAT(BFCVTN_v, aa64_bf16, do_2misc_narrow_vector, a, f_vector_bfcvtn) |
15 | 15 | ||
16 | +static bool trans_SHLL_v(DisasContext *s, arg_qrr_e *a) | 16 | +static bool trans_SHLL_v(DisasContext *s, arg_qrr_e *a) |
17 | +{ | 17 | +{ |
18 | + static NeonGenWidenFn * const widenfns[3] = { | 18 | + static NeonGenWidenFn * const widenfns[3] = { |
19 | + gen_helper_neon_widen_u8, | 19 | + gen_helper_neon_widen_u8, |
20 | + gen_helper_neon_widen_u16, | 20 | + gen_helper_neon_widen_u16, |
21 | + tcg_gen_extu_i32_i64, | 21 | + tcg_gen_extu_i32_i64, |
22 | + }; | 22 | + }; |
23 | + NeonGenWidenFn *widenfn; | 23 | + NeonGenWidenFn *widenfn; |
24 | + TCGv_i64 tcg_res[2]; | 24 | + TCGv_i64 tcg_res[2]; |
25 | + TCGv_i32 tcg_op; | 25 | + TCGv_i32 tcg_op; |
26 | + int part, pass; | 26 | + int part, pass; |
27 | + | 27 | + |
28 | + if (a->esz == MO_64) { | 28 | + if (a->esz == MO_64) { |
29 | + return false; | 29 | + return false; |
30 | + } | 30 | + } |
31 | + if (!fp_access_check(s)) { | 31 | + if (!fp_access_check(s)) { |
32 | + return true; | 32 | + return true; |
33 | + } | 33 | + } |
34 | + | 34 | + |
35 | + tcg_op = tcg_temp_new_i32(); | 35 | + tcg_op = tcg_temp_new_i32(); |
36 | + widenfn = widenfns[a->esz]; | 36 | + widenfn = widenfns[a->esz]; |
37 | + part = a->q ? 2 : 0; | 37 | + part = a->q ? 2 : 0; |
38 | + | 38 | + |
39 | + for (pass = 0; pass < 2; pass++) { | 39 | + for (pass = 0; pass < 2; pass++) { |
40 | + read_vec_element_i32(s, tcg_op, a->rn, part + pass, MO_32); | 40 | + read_vec_element_i32(s, tcg_op, a->rn, part + pass, MO_32); |
41 | + tcg_res[pass] = tcg_temp_new_i64(); | 41 | + tcg_res[pass] = tcg_temp_new_i64(); |
42 | + widenfn(tcg_res[pass], tcg_op); | 42 | + widenfn(tcg_res[pass], tcg_op); |
43 | + tcg_gen_shli_i64(tcg_res[pass], tcg_res[pass], 8 << a->esz); | 43 | + tcg_gen_shli_i64(tcg_res[pass], tcg_res[pass], 8 << a->esz); |
44 | + } | 44 | + } |
45 | + | 45 | + |
46 | + for (pass = 0; pass < 2; pass++) { | 46 | + for (pass = 0; pass < 2; pass++) { |
47 | + write_vec_element(s, tcg_res[pass], a->rd, pass, MO_64); | 47 | + write_vec_element(s, tcg_res[pass], a->rd, pass, MO_64); |
48 | + } | 48 | + } |
49 | + return true; | 49 | + return true; |
50 | +} | 50 | +} |
51 | + | 51 | + |
52 | + | 52 | + |
53 | /* Common vector code for handling integer to FP conversion */ | 53 | /* Common vector code for handling integer to FP conversion */ |
54 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 54 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
55 | int elements, int is_signed, | 55 | int elements, int is_signed, |
56 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, | 56 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, |
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | -static void handle_shll(DisasContext *s, bool is_q, int size, int rn, int rd) | 60 | -static void handle_shll(DisasContext *s, bool is_q, int size, int rn, int rd) |
61 | -{ | 61 | -{ |
62 | - /* Implement SHLL and SHLL2 */ | 62 | - /* Implement SHLL and SHLL2 */ |
63 | - int pass; | 63 | - int pass; |
64 | - int part = is_q ? 2 : 0; | 64 | - int part = is_q ? 2 : 0; |
65 | - TCGv_i64 tcg_res[2]; | 65 | - TCGv_i64 tcg_res[2]; |
66 | - | 66 | - |
67 | - for (pass = 0; pass < 2; pass++) { | 67 | - for (pass = 0; pass < 2; pass++) { |
68 | - static NeonGenWidenFn * const widenfns[3] = { | 68 | - static NeonGenWidenFn * const widenfns[3] = { |
69 | - gen_helper_neon_widen_u8, | 69 | - gen_helper_neon_widen_u8, |
70 | - gen_helper_neon_widen_u16, | 70 | - gen_helper_neon_widen_u16, |
71 | - tcg_gen_extu_i32_i64, | 71 | - tcg_gen_extu_i32_i64, |
72 | - }; | 72 | - }; |
73 | - NeonGenWidenFn *widenfn = widenfns[size]; | 73 | - NeonGenWidenFn *widenfn = widenfns[size]; |
74 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); | 74 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); |
75 | - | 75 | - |
76 | - read_vec_element_i32(s, tcg_op, rn, part + pass, MO_32); | 76 | - read_vec_element_i32(s, tcg_op, rn, part + pass, MO_32); |
77 | - tcg_res[pass] = tcg_temp_new_i64(); | 77 | - tcg_res[pass] = tcg_temp_new_i64(); |
78 | - widenfn(tcg_res[pass], tcg_op); | 78 | - widenfn(tcg_res[pass], tcg_op); |
79 | - tcg_gen_shli_i64(tcg_res[pass], tcg_res[pass], 8 << size); | 79 | - tcg_gen_shli_i64(tcg_res[pass], tcg_res[pass], 8 << size); |
80 | - } | 80 | - } |
81 | - | 81 | - |
82 | - for (pass = 0; pass < 2; pass++) { | 82 | - for (pass = 0; pass < 2; pass++) { |
83 | - write_vec_element(s, tcg_res[pass], rd, pass, MO_64); | 83 | - write_vec_element(s, tcg_res[pass], rd, pass, MO_64); |
84 | - } | 84 | - } |
85 | -} | 85 | -} |
86 | - | 86 | - |
87 | /* AdvSIMD two reg misc | 87 | /* AdvSIMD two reg misc |
88 | * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 | 88 | * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 |
89 | * +---+---+---+-----------+------+-----------+--------+-----+------+------+ | 89 | * +---+---+---+-----------+------+-----------+--------+-----+------+------+ |
90 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 90 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
91 | TCGv_ptr tcg_fpstatus; | 91 | TCGv_ptr tcg_fpstatus; |
92 | 92 | ||
93 | switch (opcode) { | 93 | switch (opcode) { |
94 | - case 0x13: /* SHLL, SHLL2 */ | 94 | - case 0x13: /* SHLL, SHLL2 */ |
95 | - if (u == 0 || size == 3) { | 95 | - if (u == 0 || size == 3) { |
96 | - unallocated_encoding(s); | 96 | - unallocated_encoding(s); |
97 | - return; | 97 | - return; |
98 | - } | 98 | - } |
99 | - if (!fp_access_check(s)) { | 99 | - if (!fp_access_check(s)) { |
100 | - return; | 100 | - return; |
101 | - } | 101 | - } |
102 | - handle_shll(s, is_q, size, rn, rd); | 102 | - handle_shll(s, is_q, size, rn, rd); |
103 | - return; | 103 | - return; |
104 | case 0xc ... 0xf: | 104 | case 0xc ... 0xf: |
105 | case 0x16 ... 0x1f: | 105 | case 0x16 ... 0x1f: |
106 | { | 106 | { |
107 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 107 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
108 | case 0xa: /* CMLT */ | 108 | case 0xa: /* CMLT */ |
109 | case 0xb: /* ABS, NEG */ | 109 | case 0xb: /* ABS, NEG */ |
110 | case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ | 110 | case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ |
111 | + case 0x13: /* SHLL, SHLL2 */ | 111 | + case 0x13: /* SHLL, SHLL2 */ |
112 | case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ | 112 | case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ |
113 | unallocated_encoding(s); | 113 | unallocated_encoding(s); |
114 | return; | 114 | return; |
115 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 115 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
116 | index XXXXXXX..XXXXXXX 100644 | 116 | index XXXXXXX..XXXXXXX 100644 |
117 | --- a/target/arm/tcg/a64.decode | 117 | --- a/target/arm/tcg/a64.decode |
118 | +++ b/target/arm/tcg/a64.decode | 118 | +++ b/target/arm/tcg/a64.decode |
119 | @@ -XXX,XX +XXX,XX @@ UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e | 119 | @@ -XXX,XX +XXX,XX @@ UQXTN_v 0.10 1110 ..1 00001 01001 0 ..... ..... @qrr_e |
120 | FCVTN_v 0.00 1110 0.1 00001 01101 0 ..... ..... @qrr_hs | 120 | FCVTN_v 0.00 1110 0.1 00001 01101 0 ..... ..... @qrr_hs |
121 | FCVTXN_v 0.10 1110 011 00001 01101 0 ..... ..... @qrr_s | 121 | FCVTXN_v 0.10 1110 011 00001 01101 0 ..... ..... @qrr_s |
122 | BFCVTN_v 0.00 1110 101 00001 01101 0 ..... ..... @qrr_h | 122 | BFCVTN_v 0.00 1110 101 00001 01101 0 ..... ..... @qrr_h |
123 | + | 123 | + |
124 | +SHLL_v 0.10 1110 ..1 00001 00111 0 ..... ..... @qrr_e | 124 | +SHLL_v 0.10 1110 ..1 00001 00111 0 ..... ..... @qrr_e |
125 | -- | 125 | -- |
126 | 2.43.0 | 126 | 2.43.0 | diff view generated by jsdifflib |
1 | Move the current implementation out of translate-neon.c, | 1 | Move the current implementation out of translate-neon.c, |
---|---|---|---|
2 | and extend to handle all element sizes. | 2 | and extend to handle all element sizes. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 6 | --- |
6 | target/arm/tcg/translate.h | 6 ++++++ | 7 | target/arm/tcg/translate.h | 6 ++++++ |
7 | target/arm/tcg/gengvec.c | 14 ++++++++++++++ | 8 | target/arm/tcg/gengvec.c | 14 ++++++++++++++ |
8 | target/arm/tcg/translate-neon.c | 20 ++------------------ | 9 | target/arm/tcg/translate-neon.c | 20 ++------------------ |
... | ... | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
105 | - case 0x6f: /* FNEG */ | 105 | - case 0x6f: /* FNEG */ |
106 | - only_in_vector = true; | 106 | - only_in_vector = true; |
107 | - need_fpst = false; | 107 | - need_fpst = false; |
108 | - break; | 108 | - break; |
109 | case 0x7d: /* FRSQRTE */ | 109 | case 0x7d: /* FRSQRTE */ |
110 | break; | ||
110 | case 0x7f: /* FSQRT (vector) */ | 111 | case 0x7f: /* FSQRT (vector) */ |
112 | only_in_vector = true; | ||
111 | break; | 113 | break; |
112 | default: | 114 | default: |
113 | + case 0x2f: /* FABS */ | 115 | + case 0x2f: /* FABS */ |
114 | + case 0x6f: /* FNEG */ | 116 | + case 0x6f: /* FNEG */ |
115 | unallocated_encoding(s); | 117 | unallocated_encoding(s); |
... | ... | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 67 +++++++++++++++++++++++++--------- | 4 | target/arm/tcg/translate-a64.c | 69 ++++++++++++++++++++++++---------- |
5 | target/arm/tcg/a64.decode | 3 ++ | 5 | target/arm/tcg/a64.decode | 3 ++ |
6 | 2 files changed, 53 insertions(+), 17 deletions(-) | 6 | 2 files changed, 53 insertions(+), 19 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
... | ... | ||
118 | + case 0x7f: /* FSQRT */ | 118 | + case 0x7f: /* FSQRT */ |
119 | g_assert_not_reached(); | 119 | g_assert_not_reached(); |
120 | } | 120 | } |
121 | } | 121 | } |
122 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 122 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
123 | rmode = FPROUNDING_ZERO; | ||
124 | break; | 123 | break; |
125 | case 0x7d: /* FRSQRTE */ | 124 | case 0x7d: /* FRSQRTE */ |
125 | break; | ||
126 | - case 0x7f: /* FSQRT (vector) */ | 126 | - case 0x7f: /* FSQRT (vector) */ |
127 | break; | 127 | - only_in_vector = true; |
128 | - break; | ||
128 | default: | 129 | default: |
129 | case 0x2f: /* FABS */ | 130 | case 0x2f: /* FABS */ |
130 | case 0x6f: /* FNEG */ | 131 | case 0x6f: /* FNEG */ |
131 | + case 0x7f: /* FSQRT (vector) */ | 132 | + case 0x7f: /* FSQRT (vector) */ |
132 | unallocated_encoding(s); | 133 | unallocated_encoding(s); |
... | ... | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 176 ++++++++++++--------------------- | 4 | target/arm/tcg/translate-a64.c | 176 ++++++++++++--------------------- |
5 | target/arm/tcg/a64.decode | 26 +++++ | 5 | target/arm/tcg/a64.decode | 26 +++++ |
6 | 2 files changed, 88 insertions(+), 114 deletions(-) | 6 | 2 files changed, 88 insertions(+), 114 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool do_fp1_vector(DisasContext *s, arg_qrr_e *a, | 12 | @@ -XXX,XX +XXX,XX @@ static bool do_fp1_vector(DisasContext *s, arg_qrr_e *a, |
13 | 13 | ||
14 | TRANS(FSQRT_v, do_fp1_vector, a, &f_scalar_fsqrt, -1) | 14 | TRANS(FSQRT_v, do_fp1_vector, a, &f_scalar_fsqrt, -1) |
15 | 15 | ||
16 | +TRANS(FRINTN_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_TIEEVEN) | 16 | +TRANS(FRINTN_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_TIEEVEN) |
17 | +TRANS(FRINTP_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_POSINF) | 17 | +TRANS(FRINTP_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_POSINF) |
18 | +TRANS(FRINTM_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_NEGINF) | 18 | +TRANS(FRINTM_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_NEGINF) |
19 | +TRANS(FRINTZ_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_ZERO) | 19 | +TRANS(FRINTZ_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_ZERO) |
20 | +TRANS(FRINTA_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_TIEAWAY) | 20 | +TRANS(FRINTA_v, do_fp1_vector, a, &f_scalar_frint, FPROUNDING_TIEAWAY) |
21 | +TRANS(FRINTI_v, do_fp1_vector, a, &f_scalar_frint, -1) | 21 | +TRANS(FRINTI_v, do_fp1_vector, a, &f_scalar_frint, -1) |
22 | +TRANS(FRINTX_v, do_fp1_vector, a, &f_scalar_frintx, -1) | 22 | +TRANS(FRINTX_v, do_fp1_vector, a, &f_scalar_frintx, -1) |
23 | + | 23 | + |
24 | +TRANS_FEAT(FRINT32Z_v, aa64_frint, do_fp1_vector, a, | 24 | +TRANS_FEAT(FRINT32Z_v, aa64_frint, do_fp1_vector, a, |
25 | + &f_scalar_frint32, FPROUNDING_ZERO) | 25 | + &f_scalar_frint32, FPROUNDING_ZERO) |
26 | +TRANS_FEAT(FRINT32X_v, aa64_frint, do_fp1_vector, a, &f_scalar_frint32, -1) | 26 | +TRANS_FEAT(FRINT32X_v, aa64_frint, do_fp1_vector, a, &f_scalar_frint32, -1) |
27 | +TRANS_FEAT(FRINT64Z_v, aa64_frint, do_fp1_vector, a, | 27 | +TRANS_FEAT(FRINT64Z_v, aa64_frint, do_fp1_vector, a, |
28 | + &f_scalar_frint64, FPROUNDING_ZERO) | 28 | + &f_scalar_frint64, FPROUNDING_ZERO) |
29 | +TRANS_FEAT(FRINT64X_v, aa64_frint, do_fp1_vector, a, &f_scalar_frint64, -1) | 29 | +TRANS_FEAT(FRINT64X_v, aa64_frint, do_fp1_vector, a, &f_scalar_frint64, -1) |
30 | + | 30 | + |
31 | /* Common vector code for handling integer to FP conversion */ | 31 | /* Common vector code for handling integer to FP conversion */ |
32 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, | 32 | static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn, |
33 | int elements, int is_signed, | 33 | int elements, int is_signed, |
34 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 34 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
35 | case 0x7b: /* FCVTZU */ | 35 | case 0x7b: /* FCVTZU */ |
36 | gen_helper_vfp_touqd(tcg_rd, tcg_rn, tcg_constant_i32(0), tcg_fpstatus); | 36 | gen_helper_vfp_touqd(tcg_rd, tcg_rn, tcg_constant_i32(0), tcg_fpstatus); |
37 | break; | 37 | break; |
38 | - case 0x18: /* FRINTN */ | 38 | - case 0x18: /* FRINTN */ |
39 | - case 0x19: /* FRINTM */ | 39 | - case 0x19: /* FRINTM */ |
40 | - case 0x38: /* FRINTP */ | 40 | - case 0x38: /* FRINTP */ |
41 | - case 0x39: /* FRINTZ */ | 41 | - case 0x39: /* FRINTZ */ |
42 | - case 0x58: /* FRINTA */ | 42 | - case 0x58: /* FRINTA */ |
43 | - case 0x79: /* FRINTI */ | 43 | - case 0x79: /* FRINTI */ |
44 | - gen_helper_rintd(tcg_rd, tcg_rn, tcg_fpstatus); | 44 | - gen_helper_rintd(tcg_rd, tcg_rn, tcg_fpstatus); |
45 | - break; | 45 | - break; |
46 | - case 0x59: /* FRINTX */ | 46 | - case 0x59: /* FRINTX */ |
47 | - gen_helper_rintd_exact(tcg_rd, tcg_rn, tcg_fpstatus); | 47 | - gen_helper_rintd_exact(tcg_rd, tcg_rn, tcg_fpstatus); |
48 | - break; | 48 | - break; |
49 | - case 0x1e: /* FRINT32Z */ | 49 | - case 0x1e: /* FRINT32Z */ |
50 | - case 0x5e: /* FRINT32X */ | 50 | - case 0x5e: /* FRINT32X */ |
51 | - gen_helper_frint32_d(tcg_rd, tcg_rn, tcg_fpstatus); | 51 | - gen_helper_frint32_d(tcg_rd, tcg_rn, tcg_fpstatus); |
52 | - break; | 52 | - break; |
53 | - case 0x1f: /* FRINT64Z */ | 53 | - case 0x1f: /* FRINT64Z */ |
54 | - case 0x5f: /* FRINT64X */ | 54 | - case 0x5f: /* FRINT64X */ |
55 | - gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus); | 55 | - gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus); |
56 | - break; | 56 | - break; |
57 | default: | 57 | default: |
58 | case 0x4: /* CLS, CLZ */ | 58 | case 0x4: /* CLS, CLZ */ |
59 | case 0x5: /* NOT */ | 59 | case 0x5: /* NOT */ |
60 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, | 60 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, |
61 | case 0x2f: /* FABS */ | 61 | case 0x2f: /* FABS */ |
62 | case 0x6f: /* FNEG */ | 62 | case 0x6f: /* FNEG */ |
63 | case 0x7f: /* FSQRT */ | 63 | case 0x7f: /* FSQRT */ |
64 | + case 0x18: /* FRINTN */ | 64 | + case 0x18: /* FRINTN */ |
65 | + case 0x19: /* FRINTM */ | 65 | + case 0x19: /* FRINTM */ |
66 | + case 0x38: /* FRINTP */ | 66 | + case 0x38: /* FRINTP */ |
67 | + case 0x39: /* FRINTZ */ | 67 | + case 0x39: /* FRINTZ */ |
68 | + case 0x58: /* FRINTA */ | 68 | + case 0x58: /* FRINTA */ |
69 | + case 0x79: /* FRINTI */ | 69 | + case 0x79: /* FRINTI */ |
70 | + case 0x59: /* FRINTX */ | 70 | + case 0x59: /* FRINTX */ |
71 | + case 0x1e: /* FRINT32Z */ | 71 | + case 0x1e: /* FRINT32Z */ |
72 | + case 0x5e: /* FRINT32X */ | 72 | + case 0x5e: /* FRINT32X */ |
73 | + case 0x1f: /* FRINT64Z */ | 73 | + case 0x1f: /* FRINT64Z */ |
74 | + case 0x5f: /* FRINT64X */ | 74 | + case 0x5f: /* FRINT64X */ |
75 | g_assert_not_reached(); | 75 | g_assert_not_reached(); |
76 | } | 76 | } |
77 | } | 77 | } |
78 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 78 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
79 | } | 79 | } |
80 | handle_2misc_widening(s, opcode, is_q, size, rn, rd); | 80 | handle_2misc_widening(s, opcode, is_q, size, rn, rd); |
81 | return; | 81 | return; |
82 | - case 0x18: /* FRINTN */ | 82 | - case 0x18: /* FRINTN */ |
83 | - case 0x19: /* FRINTM */ | 83 | - case 0x19: /* FRINTM */ |
84 | - case 0x38: /* FRINTP */ | 84 | - case 0x38: /* FRINTP */ |
85 | - case 0x39: /* FRINTZ */ | 85 | - case 0x39: /* FRINTZ */ |
86 | - rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1); | 86 | - rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1); |
87 | - /* fall through */ | 87 | - /* fall through */ |
88 | - case 0x59: /* FRINTX */ | 88 | - case 0x59: /* FRINTX */ |
89 | - case 0x79: /* FRINTI */ | 89 | - case 0x79: /* FRINTI */ |
90 | - need_fpstatus = true; | 90 | - need_fpstatus = true; |
91 | - if (size == 3 && !is_q) { | 91 | - if (size == 3 && !is_q) { |
92 | - unallocated_encoding(s); | 92 | - unallocated_encoding(s); |
93 | - return; | 93 | - return; |
94 | - } | 94 | - } |
95 | - break; | 95 | - break; |
96 | - case 0x58: /* FRINTA */ | 96 | - case 0x58: /* FRINTA */ |
97 | - rmode = FPROUNDING_TIEAWAY; | 97 | - rmode = FPROUNDING_TIEAWAY; |
98 | - need_fpstatus = true; | 98 | - need_fpstatus = true; |
99 | - if (size == 3 && !is_q) { | 99 | - if (size == 3 && !is_q) { |
100 | - unallocated_encoding(s); | 100 | - unallocated_encoding(s); |
101 | - return; | 101 | - return; |
102 | - } | 102 | - } |
103 | - break; | 103 | - break; |
104 | case 0x7c: /* URSQRTE */ | 104 | case 0x7c: /* URSQRTE */ |
105 | if (size == 3) { | 105 | if (size == 3) { |
106 | unallocated_encoding(s); | 106 | unallocated_encoding(s); |
107 | return; | 107 | return; |
108 | } | 108 | } |
109 | break; | 109 | break; |
110 | - case 0x1e: /* FRINT32Z */ | 110 | - case 0x1e: /* FRINT32Z */ |
111 | - case 0x1f: /* FRINT64Z */ | 111 | - case 0x1f: /* FRINT64Z */ |
112 | - rmode = FPROUNDING_ZERO; | 112 | - rmode = FPROUNDING_ZERO; |
113 | - /* fall through */ | 113 | - /* fall through */ |
114 | - case 0x5e: /* FRINT32X */ | 114 | - case 0x5e: /* FRINT32X */ |
115 | - case 0x5f: /* FRINT64X */ | 115 | - case 0x5f: /* FRINT64X */ |
116 | - need_fpstatus = true; | 116 | - need_fpstatus = true; |
117 | - if ((size == 3 && !is_q) || !dc_isar_feature(aa64_frint, s)) { | 117 | - if ((size == 3 && !is_q) || !dc_isar_feature(aa64_frint, s)) { |
118 | - unallocated_encoding(s); | 118 | - unallocated_encoding(s); |
119 | - return; | 119 | - return; |
120 | - } | 120 | - } |
121 | - break; | 121 | - break; |
122 | default: | 122 | default: |
123 | case 0x16: /* FCVTN, FCVTN2 */ | 123 | case 0x16: /* FCVTN, FCVTN2 */ |
124 | case 0x36: /* BFCVTN, BFCVTN2 */ | 124 | case 0x36: /* BFCVTN, BFCVTN2 */ |
125 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 125 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
126 | case 0x2f: /* FABS */ | 126 | case 0x2f: /* FABS */ |
127 | case 0x6f: /* FNEG */ | 127 | case 0x6f: /* FNEG */ |
128 | case 0x7f: /* FSQRT */ | 128 | case 0x7f: /* FSQRT */ |
129 | + case 0x18: /* FRINTN */ | 129 | + case 0x18: /* FRINTN */ |
130 | + case 0x19: /* FRINTM */ | 130 | + case 0x19: /* FRINTM */ |
131 | + case 0x38: /* FRINTP */ | 131 | + case 0x38: /* FRINTP */ |
132 | + case 0x39: /* FRINTZ */ | 132 | + case 0x39: /* FRINTZ */ |
133 | + case 0x59: /* FRINTX */ | 133 | + case 0x59: /* FRINTX */ |
134 | + case 0x79: /* FRINTI */ | 134 | + case 0x79: /* FRINTI */ |
135 | + case 0x58: /* FRINTA */ | 135 | + case 0x58: /* FRINTA */ |
136 | + case 0x1e: /* FRINT32Z */ | 136 | + case 0x1e: /* FRINT32Z */ |
137 | + case 0x1f: /* FRINT64Z */ | 137 | + case 0x1f: /* FRINT64Z */ |
138 | + case 0x5e: /* FRINT32X */ | 138 | + case 0x5e: /* FRINT32X */ |
139 | + case 0x5f: /* FRINT64X */ | 139 | + case 0x5f: /* FRINT64X */ |
140 | unallocated_encoding(s); | 140 | unallocated_encoding(s); |
141 | return; | 141 | return; |
142 | } | 142 | } |
143 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 143 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
144 | gen_helper_vfp_touls(tcg_res, tcg_op, | 144 | gen_helper_vfp_touls(tcg_res, tcg_op, |
145 | tcg_constant_i32(0), tcg_fpstatus); | 145 | tcg_constant_i32(0), tcg_fpstatus); |
146 | break; | 146 | break; |
147 | - case 0x18: /* FRINTN */ | 147 | - case 0x18: /* FRINTN */ |
148 | - case 0x19: /* FRINTM */ | 148 | - case 0x19: /* FRINTM */ |
149 | - case 0x38: /* FRINTP */ | 149 | - case 0x38: /* FRINTP */ |
150 | - case 0x39: /* FRINTZ */ | 150 | - case 0x39: /* FRINTZ */ |
151 | - case 0x58: /* FRINTA */ | 151 | - case 0x58: /* FRINTA */ |
152 | - case 0x79: /* FRINTI */ | 152 | - case 0x79: /* FRINTI */ |
153 | - gen_helper_rints(tcg_res, tcg_op, tcg_fpstatus); | 153 | - gen_helper_rints(tcg_res, tcg_op, tcg_fpstatus); |
154 | - break; | 154 | - break; |
155 | - case 0x59: /* FRINTX */ | 155 | - case 0x59: /* FRINTX */ |
156 | - gen_helper_rints_exact(tcg_res, tcg_op, tcg_fpstatus); | 156 | - gen_helper_rints_exact(tcg_res, tcg_op, tcg_fpstatus); |
157 | - break; | 157 | - break; |
158 | case 0x7c: /* URSQRTE */ | 158 | case 0x7c: /* URSQRTE */ |
159 | gen_helper_rsqrte_u32(tcg_res, tcg_op); | 159 | gen_helper_rsqrte_u32(tcg_res, tcg_op); |
160 | break; | 160 | break; |
161 | - case 0x1e: /* FRINT32Z */ | 161 | - case 0x1e: /* FRINT32Z */ |
162 | - case 0x5e: /* FRINT32X */ | 162 | - case 0x5e: /* FRINT32X */ |
163 | - gen_helper_frint32_s(tcg_res, tcg_op, tcg_fpstatus); | 163 | - gen_helper_frint32_s(tcg_res, tcg_op, tcg_fpstatus); |
164 | - break; | 164 | - break; |
165 | - case 0x1f: /* FRINT64Z */ | 165 | - case 0x1f: /* FRINT64Z */ |
166 | - case 0x5f: /* FRINT64X */ | 166 | - case 0x5f: /* FRINT64X */ |
167 | - gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus); | 167 | - gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus); |
168 | - break; | 168 | - break; |
169 | default: | 169 | default: |
170 | case 0x7: /* SQABS, SQNEG */ | 170 | case 0x7: /* SQABS, SQNEG */ |
171 | case 0x2f: /* FABS */ | 171 | case 0x2f: /* FABS */ |
172 | case 0x6f: /* FNEG */ | 172 | case 0x6f: /* FNEG */ |
173 | case 0x7f: /* FSQRT */ | 173 | case 0x7f: /* FSQRT */ |
174 | + case 0x18: /* FRINTN */ | 174 | + case 0x18: /* FRINTN */ |
175 | + case 0x19: /* FRINTM */ | 175 | + case 0x19: /* FRINTM */ |
176 | + case 0x38: /* FRINTP */ | 176 | + case 0x38: /* FRINTP */ |
177 | + case 0x39: /* FRINTZ */ | 177 | + case 0x39: /* FRINTZ */ |
178 | + case 0x58: /* FRINTA */ | 178 | + case 0x58: /* FRINTA */ |
179 | + case 0x79: /* FRINTI */ | 179 | + case 0x79: /* FRINTI */ |
180 | + case 0x59: /* FRINTX */ | 180 | + case 0x59: /* FRINTX */ |
181 | + case 0x1e: /* FRINT32Z */ | 181 | + case 0x1e: /* FRINT32Z */ |
182 | + case 0x5e: /* FRINT32X */ | 182 | + case 0x5e: /* FRINT32X */ |
183 | + case 0x1f: /* FRINT64Z */ | 183 | + case 0x1f: /* FRINT64Z */ |
184 | + case 0x5f: /* FRINT64X */ | 184 | + case 0x5f: /* FRINT64X */ |
185 | g_assert_not_reached(); | 185 | g_assert_not_reached(); |
186 | } | 186 | } |
187 | } | 187 | } |
188 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 188 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
189 | int rn, rd; | 189 | int rn, rd; |
190 | bool is_q; | 190 | bool is_q; |
191 | bool is_scalar; | 191 | bool is_scalar; |
192 | - bool only_in_vector = false; | 192 | - bool only_in_vector = false; |
193 | 193 | ||
194 | int pass; | 194 | int pass; |
195 | TCGv_i32 tcg_rmode = NULL; | 195 | TCGv_i32 tcg_rmode = NULL; |
196 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 196 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
197 | case 0x3d: /* FRECPE */ | 197 | case 0x3d: /* FRECPE */ |
198 | case 0x3f: /* FRECPX */ | 198 | case 0x3f: /* FRECPX */ |
199 | break; | 199 | break; |
200 | - case 0x18: /* FRINTN */ | 200 | - case 0x18: /* FRINTN */ |
201 | - only_in_vector = true; | 201 | - only_in_vector = true; |
202 | - rmode = FPROUNDING_TIEEVEN; | 202 | - rmode = FPROUNDING_TIEEVEN; |
203 | - break; | 203 | - break; |
204 | - case 0x19: /* FRINTM */ | 204 | - case 0x19: /* FRINTM */ |
205 | - only_in_vector = true; | 205 | - only_in_vector = true; |
206 | - rmode = FPROUNDING_NEGINF; | 206 | - rmode = FPROUNDING_NEGINF; |
207 | - break; | 207 | - break; |
208 | - case 0x38: /* FRINTP */ | 208 | - case 0x38: /* FRINTP */ |
209 | - only_in_vector = true; | 209 | - only_in_vector = true; |
210 | - rmode = FPROUNDING_POSINF; | 210 | - rmode = FPROUNDING_POSINF; |
211 | - break; | 211 | - break; |
212 | - case 0x39: /* FRINTZ */ | 212 | - case 0x39: /* FRINTZ */ |
213 | - only_in_vector = true; | 213 | - only_in_vector = true; |
214 | - rmode = FPROUNDING_ZERO; | 214 | - rmode = FPROUNDING_ZERO; |
215 | - break; | 215 | - break; |
216 | - case 0x58: /* FRINTA */ | 216 | - case 0x58: /* FRINTA */ |
217 | - only_in_vector = true; | 217 | - only_in_vector = true; |
218 | - rmode = FPROUNDING_TIEAWAY; | 218 | - rmode = FPROUNDING_TIEAWAY; |
219 | - break; | 219 | - break; |
220 | - case 0x59: /* FRINTX */ | 220 | - case 0x59: /* FRINTX */ |
221 | - case 0x79: /* FRINTI */ | 221 | - case 0x79: /* FRINTI */ |
222 | - only_in_vector = true; | 222 | - only_in_vector = true; |
223 | - /* current rounding mode */ | 223 | - /* current rounding mode */ |
224 | - break; | 224 | - break; |
225 | case 0x1a: /* FCVTNS */ | 225 | case 0x1a: /* FCVTNS */ |
226 | rmode = FPROUNDING_TIEEVEN; | 226 | rmode = FPROUNDING_TIEEVEN; |
227 | break; | 227 | break; |
228 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 228 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
229 | case 0x2f: /* FABS */ | 229 | case 0x2f: /* FABS */ |
230 | case 0x6f: /* FNEG */ | 230 | case 0x6f: /* FNEG */ |
231 | case 0x7f: /* FSQRT (vector) */ | 231 | case 0x7f: /* FSQRT (vector) */ |
232 | + case 0x18: /* FRINTN */ | 232 | + case 0x18: /* FRINTN */ |
233 | + case 0x19: /* FRINTM */ | 233 | + case 0x19: /* FRINTM */ |
234 | + case 0x38: /* FRINTP */ | 234 | + case 0x38: /* FRINTP */ |
235 | + case 0x39: /* FRINTZ */ | 235 | + case 0x39: /* FRINTZ */ |
236 | + case 0x58: /* FRINTA */ | 236 | + case 0x58: /* FRINTA */ |
237 | + case 0x59: /* FRINTX */ | 237 | + case 0x59: /* FRINTX */ |
238 | + case 0x79: /* FRINTI */ | 238 | + case 0x79: /* FRINTI */ |
239 | unallocated_encoding(s); | 239 | unallocated_encoding(s); |
240 | return; | 240 | return; |
241 | } | 241 | } |
242 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 242 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
243 | unallocated_encoding(s); | 243 | unallocated_encoding(s); |
244 | return; | 244 | return; |
245 | } | 245 | } |
246 | - /* FRINTxx is only in the vector form */ | 246 | - /* FRINTxx is only in the vector form */ |
247 | - if (only_in_vector) { | 247 | - if (only_in_vector) { |
248 | - unallocated_encoding(s); | 248 | - unallocated_encoding(s); |
249 | - return; | 249 | - return; |
250 | - } | 250 | - } |
251 | } | 251 | } |
252 | 252 | ||
253 | if (!fp_access_check(s)) { | 253 | if (!fp_access_check(s)) { |
254 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 254 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
255 | case 0x7b: /* FCVTZU */ | 255 | case 0x7b: /* FCVTZU */ |
256 | gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus); | 256 | gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus); |
257 | break; | 257 | break; |
258 | - case 0x18: /* FRINTN */ | 258 | - case 0x18: /* FRINTN */ |
259 | - case 0x19: /* FRINTM */ | 259 | - case 0x19: /* FRINTM */ |
260 | - case 0x38: /* FRINTP */ | 260 | - case 0x38: /* FRINTP */ |
261 | - case 0x39: /* FRINTZ */ | 261 | - case 0x39: /* FRINTZ */ |
262 | - case 0x58: /* FRINTA */ | 262 | - case 0x58: /* FRINTA */ |
263 | - case 0x79: /* FRINTI */ | 263 | - case 0x79: /* FRINTI */ |
264 | - gen_helper_advsimd_rinth(tcg_res, tcg_op, tcg_fpstatus); | 264 | - gen_helper_advsimd_rinth(tcg_res, tcg_op, tcg_fpstatus); |
265 | - break; | 265 | - break; |
266 | - case 0x59: /* FRINTX */ | 266 | - case 0x59: /* FRINTX */ |
267 | - gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, tcg_fpstatus); | 267 | - gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, tcg_fpstatus); |
268 | - break; | 268 | - break; |
269 | case 0x7d: /* FRSQRTE */ | 269 | case 0x7d: /* FRSQRTE */ |
270 | gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); | 270 | gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); |
271 | break; | 271 | break; |
272 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 272 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
273 | case 0x2f: /* FABS */ | 273 | case 0x2f: /* FABS */ |
274 | case 0x6f: /* FNEG */ | 274 | case 0x6f: /* FNEG */ |
275 | case 0x7f: /* FSQRT */ | 275 | case 0x7f: /* FSQRT */ |
276 | + case 0x18: /* FRINTN */ | 276 | + case 0x18: /* FRINTN */ |
277 | + case 0x19: /* FRINTM */ | 277 | + case 0x19: /* FRINTM */ |
278 | + case 0x38: /* FRINTP */ | 278 | + case 0x38: /* FRINTP */ |
279 | + case 0x39: /* FRINTZ */ | 279 | + case 0x39: /* FRINTZ */ |
280 | + case 0x58: /* FRINTA */ | 280 | + case 0x58: /* FRINTA */ |
281 | + case 0x79: /* FRINTI */ | 281 | + case 0x79: /* FRINTI */ |
282 | + case 0x59: /* FRINTX */ | 282 | + case 0x59: /* FRINTX */ |
283 | g_assert_not_reached(); | 283 | g_assert_not_reached(); |
284 | } | 284 | } |
285 | 285 | ||
286 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 286 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
287 | index XXXXXXX..XXXXXXX 100644 | 287 | index XXXXXXX..XXXXXXX 100644 |
288 | --- a/target/arm/tcg/a64.decode | 288 | --- a/target/arm/tcg/a64.decode |
289 | +++ b/target/arm/tcg/a64.decode | 289 | +++ b/target/arm/tcg/a64.decode |
290 | @@ -XXX,XX +XXX,XX @@ FNEG_v 0.10 1110 1.1 00000 11111 0 ..... ..... @qrr_sd | 290 | @@ -XXX,XX +XXX,XX @@ FNEG_v 0.10 1110 1.1 00000 11111 0 ..... ..... @qrr_sd |
291 | 291 | ||
292 | FSQRT_v 0.10 1110 111 11001 11111 0 ..... ..... @qrr_h | 292 | FSQRT_v 0.10 1110 111 11001 11111 0 ..... ..... @qrr_h |
293 | FSQRT_v 0.10 1110 1.1 00001 11111 0 ..... ..... @qrr_sd | 293 | FSQRT_v 0.10 1110 1.1 00001 11111 0 ..... ..... @qrr_sd |
294 | + | 294 | + |
295 | +FRINTN_v 0.00 1110 011 11001 10001 0 ..... ..... @qrr_h | 295 | +FRINTN_v 0.00 1110 011 11001 10001 0 ..... ..... @qrr_h |
296 | +FRINTN_v 0.00 1110 0.1 00001 10001 0 ..... ..... @qrr_sd | 296 | +FRINTN_v 0.00 1110 0.1 00001 10001 0 ..... ..... @qrr_sd |
297 | + | 297 | + |
298 | +FRINTM_v 0.00 1110 011 11001 10011 0 ..... ..... @qrr_h | 298 | +FRINTM_v 0.00 1110 011 11001 10011 0 ..... ..... @qrr_h |
299 | +FRINTM_v 0.00 1110 0.1 00001 10011 0 ..... ..... @qrr_sd | 299 | +FRINTM_v 0.00 1110 0.1 00001 10011 0 ..... ..... @qrr_sd |
300 | + | 300 | + |
301 | +FRINTP_v 0.00 1110 111 11001 10001 0 ..... ..... @qrr_h | 301 | +FRINTP_v 0.00 1110 111 11001 10001 0 ..... ..... @qrr_h |
302 | +FRINTP_v 0.00 1110 1.1 00001 10001 0 ..... ..... @qrr_sd | 302 | +FRINTP_v 0.00 1110 1.1 00001 10001 0 ..... ..... @qrr_sd |
303 | + | 303 | + |
304 | +FRINTZ_v 0.00 1110 111 11001 10011 0 ..... ..... @qrr_h | 304 | +FRINTZ_v 0.00 1110 111 11001 10011 0 ..... ..... @qrr_h |
305 | +FRINTZ_v 0.00 1110 1.1 00001 10011 0 ..... ..... @qrr_sd | 305 | +FRINTZ_v 0.00 1110 1.1 00001 10011 0 ..... ..... @qrr_sd |
306 | + | 306 | + |
307 | +FRINTA_v 0.10 1110 011 11001 10001 0 ..... ..... @qrr_h | 307 | +FRINTA_v 0.10 1110 011 11001 10001 0 ..... ..... @qrr_h |
308 | +FRINTA_v 0.10 1110 0.1 00001 10001 0 ..... ..... @qrr_sd | 308 | +FRINTA_v 0.10 1110 0.1 00001 10001 0 ..... ..... @qrr_sd |
309 | + | 309 | + |
310 | +FRINTX_v 0.10 1110 011 11001 10011 0 ..... ..... @qrr_h | 310 | +FRINTX_v 0.10 1110 011 11001 10011 0 ..... ..... @qrr_h |
311 | +FRINTX_v 0.10 1110 0.1 00001 10011 0 ..... ..... @qrr_sd | 311 | +FRINTX_v 0.10 1110 0.1 00001 10011 0 ..... ..... @qrr_sd |
312 | + | 312 | + |
313 | +FRINTI_v 0.10 1110 111 11001 10011 0 ..... ..... @qrr_h | 313 | +FRINTI_v 0.10 1110 111 11001 10011 0 ..... ..... @qrr_h |
314 | +FRINTI_v 0.10 1110 1.1 00001 10011 0 ..... ..... @qrr_sd | 314 | +FRINTI_v 0.10 1110 1.1 00001 10011 0 ..... ..... @qrr_sd |
315 | + | 315 | + |
316 | +FRINT32Z_v 0.00 1110 0.1 00001 11101 0 ..... ..... @qrr_sd | 316 | +FRINT32Z_v 0.00 1110 0.1 00001 11101 0 ..... ..... @qrr_sd |
317 | +FRINT32X_v 0.10 1110 0.1 00001 11101 0 ..... ..... @qrr_sd | 317 | +FRINT32X_v 0.10 1110 0.1 00001 11101 0 ..... ..... @qrr_sd |
318 | +FRINT64Z_v 0.00 1110 0.1 00001 11111 0 ..... ..... @qrr_sd | 318 | +FRINT64Z_v 0.00 1110 0.1 00001 11111 0 ..... ..... @qrr_sd |
319 | +FRINT64X_v 0.10 1110 0.1 00001 11111 0 ..... ..... @qrr_sd | 319 | +FRINT64X_v 0.10 1110 0.1 00001 11111 0 ..... ..... @qrr_sd |
320 | -- | 320 | -- |
321 | 2.43.0 | 321 | 2.43.0 | diff view generated by jsdifflib |
1 | Arm silliness with naming, the scalar insns described | 1 | Arm silliness with naming, the scalar insns described |
---|---|---|---|
2 | as part of the vector instructions, as separate from | 2 | as part of the vector instructions, as separate from |
3 | the "regular" scalar insns which output to general registers. | 3 | the "regular" scalar insns which output to general registers. |
4 | 4 | ||
5 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | --- | 7 | --- |
7 | target/arm/tcg/translate-a64.c | 133 ++++++++++++++------------------- | 8 | target/arm/tcg/translate-a64.c | 133 ++++++++++++++------------------- |
8 | target/arm/tcg/a64.decode | 30 ++++++++ | 9 | target/arm/tcg/a64.decode | 30 ++++++++ |
9 | 2 files changed, 86 insertions(+), 77 deletions(-) | 10 | 2 files changed, 86 insertions(+), 77 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
---|---|---|---|
1 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
2 | --- | 3 | --- |
3 | target/arm/tcg/translate-a64.c | 4 +--- | 4 | target/arm/tcg/translate-a64.c | 4 +--- |
4 | target/arm/tcg/a64.decode | 19 +++++++++++++++++++ | 5 | target/arm/tcg/a64.decode | 19 +++++++++++++++++++ |
5 | 2 files changed, 20 insertions(+), 3 deletions(-) | 6 | 2 files changed, 20 insertions(+), 3 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
---|---|---|---|
2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
3 | --- | 3 | --- |
4 | target/arm/tcg/translate-a64.c | 35 ++++++++++++++++++++++++---------- | 4 | target/arm/tcg/translate-a64.c | 35 ++++++++++++++++++++++++---------- |
5 | target/arm/tcg/a64.decode | 6 ++++++ | 5 | target/arm/tcg/a64.decode | 6 ++++++ |
6 | 2 files changed, 31 insertions(+), 10 deletions(-) | 6 | 2 files changed, 31 insertions(+), 10 deletions(-) |
7 | 7 | ||
8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 8 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/target/arm/tcg/translate-a64.c | 10 | --- a/target/arm/tcg/translate-a64.c |
11 | +++ b/target/arm/tcg/translate-a64.c | 11 | +++ b/target/arm/tcg/translate-a64.c |
12 | @@ -XXX,XX +XXX,XX @@ static bool do_cvtf_g(DisasContext *s, arg_fcvt *a, bool is_signed) | 12 | @@ -XXX,XX +XXX,XX @@ static bool do_cvtf_g(DisasContext *s, arg_fcvt *a, bool is_signed) |
13 | TRANS(SCVTF_g, do_cvtf_g, a, true) | 13 | TRANS(SCVTF_g, do_cvtf_g, a, true) |
14 | TRANS(UCVTF_g, do_cvtf_g, a, false) | 14 | TRANS(UCVTF_g, do_cvtf_g, a, false) |
15 | 15 | ||
16 | +/* | 16 | +/* |
17 | + * [US]CVTF (vector), scalar version. | 17 | + * [US]CVTF (vector), scalar version. |
18 | + * Which sounds weird, but really just means input from fp register | 18 | + * Which sounds weird, but really just means input from fp register |
19 | + * instead of input from general register. Input and output element | 19 | + * instead of input from general register. Input and output element |
20 | + * size are always equal. | 20 | + * size are always equal. |
21 | + */ | 21 | + */ |
22 | +static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed) | 22 | +static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed) |
23 | +{ | 23 | +{ |
24 | + TCGv_i64 tcg_int; | 24 | + TCGv_i64 tcg_int; |
25 | + int check = fp_access_check_scalar_hsd(s, a->esz); | 25 | + int check = fp_access_check_scalar_hsd(s, a->esz); |
26 | + | 26 | + |
27 | + if (check <= 0) { | 27 | + if (check <= 0) { |
28 | + return check == 0; | 28 | + return check == 0; |
29 | + } | 29 | + } |
30 | + | 30 | + |
31 | + tcg_int = tcg_temp_new_i64(); | 31 | + tcg_int = tcg_temp_new_i64(); |
32 | + read_vec_element(s, tcg_int, a->rn, 0, a->esz | (is_signed ? MO_SIGN : 0)); | 32 | + read_vec_element(s, tcg_int, a->rn, 0, a->esz | (is_signed ? MO_SIGN : 0)); |
33 | + return do_cvtf_scalar(s, a->esz, a->rd, a->shift, tcg_int, is_signed); | 33 | + return do_cvtf_scalar(s, a->esz, a->rd, a->shift, tcg_int, is_signed); |
34 | +} | 34 | +} |
35 | + | 35 | + |
36 | +TRANS(SCVTF_f, do_cvtf_f, a, true) | 36 | +TRANS(SCVTF_f, do_cvtf_f, a, true) |
37 | +TRANS(UCVTF_f, do_cvtf_f, a, false) | 37 | +TRANS(UCVTF_f, do_cvtf_f, a, false) |
38 | + | 38 | + |
39 | static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz, | 39 | static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz, |
40 | TCGv_i64 tcg_out, int shift, int rn, | 40 | TCGv_i64 tcg_out, int shift, int rn, |
41 | ARMFPRounding rmode) | 41 | ARMFPRounding rmode) |
42 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 42 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
43 | case 0x6d: /* FCMLE (zero) */ | 43 | case 0x6d: /* FCMLE (zero) */ |
44 | handle_2misc_fcmp_zero(s, opcode, true, u, true, size, rn, rd); | 44 | handle_2misc_fcmp_zero(s, opcode, true, u, true, size, rn, rd); |
45 | return; | 45 | return; |
46 | - case 0x1d: /* SCVTF */ | 46 | - case 0x1d: /* SCVTF */ |
47 | - case 0x5d: /* UCVTF */ | 47 | - case 0x5d: /* UCVTF */ |
48 | - { | 48 | - { |
49 | - bool is_signed = (opcode == 0x1d); | 49 | - bool is_signed = (opcode == 0x1d); |
50 | - if (!fp_access_check(s)) { | 50 | - if (!fp_access_check(s)) { |
51 | - return; | 51 | - return; |
52 | - } | 52 | - } |
53 | - handle_simd_intfp_conv(s, rd, rn, 1, is_signed, 0, size); | 53 | - handle_simd_intfp_conv(s, rd, rn, 1, is_signed, 0, size); |
54 | - return; | 54 | - return; |
55 | - } | 55 | - } |
56 | case 0x3d: /* FRECPE */ | 56 | case 0x3d: /* FRECPE */ |
57 | case 0x3f: /* FRECPX */ | 57 | case 0x3f: /* FRECPX */ |
58 | case 0x7d: /* FRSQRTE */ | 58 | case 0x7d: /* FRSQRTE */ |
59 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 59 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
60 | case 0x1c: /* FCVTAS */ | 60 | case 0x1c: /* FCVTAS */ |
61 | case 0x5c: /* FCVTAU */ | 61 | case 0x5c: /* FCVTAU */ |
62 | case 0x56: /* FCVTXN, FCVTXN2 */ | 62 | case 0x56: /* FCVTXN, FCVTXN2 */ |
63 | + case 0x1d: /* SCVTF */ | 63 | + case 0x1d: /* SCVTF */ |
64 | + case 0x5d: /* UCVTF */ | 64 | + case 0x5d: /* UCVTF */ |
65 | default: | 65 | default: |
66 | unallocated_encoding(s); | 66 | unallocated_encoding(s); |
67 | return; | 67 | return; |
68 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 68 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
69 | index XXXXXXX..XXXXXXX 100644 | 69 | index XXXXXXX..XXXXXXX 100644 |
70 | --- a/target/arm/tcg/a64.decode | 70 | --- a/target/arm/tcg/a64.decode |
71 | +++ b/target/arm/tcg/a64.decode | 71 | +++ b/target/arm/tcg/a64.decode |
72 | @@ -XXX,XX +XXX,XX @@ FCVTXN_s 0111 1110 011 00001 01101 0 ..... ..... @rr_s | 72 | @@ -XXX,XX +XXX,XX @@ FCVTXN_s 0111 1110 011 00001 01101 0 ..... ..... @rr_s |
73 | @icvt_sd . ....... .. ...... ...... rn:5 rd:5 \ | 73 | @icvt_sd . ....... .. ...... ...... rn:5 rd:5 \ |
74 | &fcvt sf=0 esz=%esz_sd shift=0 | 74 | &fcvt sf=0 esz=%esz_sd shift=0 |
75 | 75 | ||
76 | +SCVTF_f 0101 1110 011 11001 11011 0 ..... ..... @icvt_h | 76 | +SCVTF_f 0101 1110 011 11001 11011 0 ..... ..... @icvt_h |
77 | +SCVTF_f 0101 1110 0.1 00001 11011 0 ..... ..... @icvt_sd | 77 | +SCVTF_f 0101 1110 0.1 00001 11011 0 ..... ..... @icvt_sd |
78 | + | 78 | + |
79 | +UCVTF_f 0111 1110 011 11001 11011 0 ..... ..... @icvt_h | 79 | +UCVTF_f 0111 1110 011 11001 11011 0 ..... ..... @icvt_h |
80 | +UCVTF_f 0111 1110 0.1 00001 11011 0 ..... ..... @icvt_sd | 80 | +UCVTF_f 0111 1110 0.1 00001 11011 0 ..... ..... @icvt_sd |
81 | + | 81 | + |
82 | FCVTNS_f 0101 1110 011 11001 10101 0 ..... ..... @icvt_h | 82 | FCVTNS_f 0101 1110 011 11001 10101 0 ..... ..... @icvt_h |
83 | FCVTNS_f 0101 1110 0.1 00001 10101 0 ..... ..... @icvt_sd | 83 | FCVTNS_f 0101 1110 0.1 00001 10101 0 ..... ..... @icvt_sd |
84 | FCVTNU_f 0111 1110 011 11001 10101 0 ..... ..... @icvt_h | 84 | FCVTNU_f 0111 1110 011 11001 10101 0 ..... ..... @icvt_h |
85 | -- | 85 | -- |
86 | 2.43.0 | 86 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove disas_simd_scalar_shift_imm as these were the | 1 | Remove disas_simd_scalar_shift_imm as these were the |
---|---|---|---|
2 | last insns decoded by that function. | 2 | last insns decoded by that function. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 6 | --- |
6 | target/arm/tcg/translate-a64.c | 47 ---------------------------------- | 7 | target/arm/tcg/translate-a64.c | 47 ---------------------------------- |
7 | target/arm/tcg/a64.decode | 8 ++++++ | 8 | target/arm/tcg/a64.decode | 8 ++++++ |
8 | 2 files changed, 8 insertions(+), 47 deletions(-) | 9 | 2 files changed, 8 insertions(+), 47 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Emphasize that these functions use round-to-zero mode. | 1 | Emphasize that these functions use round-to-zero mode. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/helper.h | 8 ++++---- | 6 | target/arm/helper.h | 8 ++++---- |
7 | target/arm/tcg/translate-neon.c | 8 ++++---- | 7 | target/arm/tcg/translate-neon.c | 8 ++++---- |
8 | target/arm/tcg/vec_helper.c | 8 ++++---- | 8 | target/arm/tcg/vec_helper.c | 8 ++++---- |
9 | 3 files changed, 12 insertions(+), 12 deletions(-) | 9 | 3 files changed, 12 insertions(+), 12 deletions(-) |
10 | 10 | ||
11 | diff --git a/target/arm/helper.h b/target/arm/helper.h | 11 | diff --git a/target/arm/helper.h b/target/arm/helper.h |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/target/arm/helper.h | 13 | --- a/target/arm/helper.h |
14 | +++ b/target/arm/helper.h | 14 | +++ b/target/arm/helper.h |
15 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_touizs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 15 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_touizs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
16 | 16 | ||
17 | DEF_HELPER_FLAGS_4(gvec_vcvt_sf, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 17 | DEF_HELPER_FLAGS_4(gvec_vcvt_sf, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
18 | DEF_HELPER_FLAGS_4(gvec_vcvt_uf, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 18 | DEF_HELPER_FLAGS_4(gvec_vcvt_uf, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
19 | -DEF_HELPER_FLAGS_4(gvec_vcvt_fs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 19 | -DEF_HELPER_FLAGS_4(gvec_vcvt_fs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
20 | -DEF_HELPER_FLAGS_4(gvec_vcvt_fu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 20 | -DEF_HELPER_FLAGS_4(gvec_vcvt_fu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
21 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_fs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 21 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_fs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
22 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_fu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 22 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_fu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
23 | 23 | ||
24 | DEF_HELPER_FLAGS_4(gvec_vcvt_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 24 | DEF_HELPER_FLAGS_4(gvec_vcvt_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
25 | DEF_HELPER_FLAGS_4(gvec_vcvt_uh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 25 | DEF_HELPER_FLAGS_4(gvec_vcvt_uh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
26 | -DEF_HELPER_FLAGS_4(gvec_vcvt_hs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 26 | -DEF_HELPER_FLAGS_4(gvec_vcvt_hs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
27 | -DEF_HELPER_FLAGS_4(gvec_vcvt_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 27 | -DEF_HELPER_FLAGS_4(gvec_vcvt_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
28 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_hs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 28 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_hs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
29 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 29 | +DEF_HELPER_FLAGS_4(gvec_vcvt_rz_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
30 | 30 | ||
31 | DEF_HELPER_FLAGS_4(gvec_vcvt_rm_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 31 | DEF_HELPER_FLAGS_4(gvec_vcvt_rm_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
32 | DEF_HELPER_FLAGS_4(gvec_vcvt_rm_us, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 32 | DEF_HELPER_FLAGS_4(gvec_vcvt_rm_us, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
33 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c | 33 | diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c |
34 | index XXXXXXX..XXXXXXX 100644 | 34 | index XXXXXXX..XXXXXXX 100644 |
35 | --- a/target/arm/tcg/translate-neon.c | 35 | --- a/target/arm/tcg/translate-neon.c |
36 | +++ b/target/arm/tcg/translate-neon.c | 36 | +++ b/target/arm/tcg/translate-neon.c |
37 | @@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a, | 37 | @@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a, |
38 | 38 | ||
39 | DO_FP_2SH(VCVT_SF, gen_helper_gvec_vcvt_sf) | 39 | DO_FP_2SH(VCVT_SF, gen_helper_gvec_vcvt_sf) |
40 | DO_FP_2SH(VCVT_UF, gen_helper_gvec_vcvt_uf) | 40 | DO_FP_2SH(VCVT_UF, gen_helper_gvec_vcvt_uf) |
41 | -DO_FP_2SH(VCVT_FS, gen_helper_gvec_vcvt_fs) | 41 | -DO_FP_2SH(VCVT_FS, gen_helper_gvec_vcvt_fs) |
42 | -DO_FP_2SH(VCVT_FU, gen_helper_gvec_vcvt_fu) | 42 | -DO_FP_2SH(VCVT_FU, gen_helper_gvec_vcvt_fu) |
43 | +DO_FP_2SH(VCVT_FS, gen_helper_gvec_vcvt_rz_fs) | 43 | +DO_FP_2SH(VCVT_FS, gen_helper_gvec_vcvt_rz_fs) |
44 | +DO_FP_2SH(VCVT_FU, gen_helper_gvec_vcvt_rz_fu) | 44 | +DO_FP_2SH(VCVT_FU, gen_helper_gvec_vcvt_rz_fu) |
45 | 45 | ||
46 | DO_FP_2SH(VCVT_SH, gen_helper_gvec_vcvt_sh) | 46 | DO_FP_2SH(VCVT_SH, gen_helper_gvec_vcvt_sh) |
47 | DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh) | 47 | DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh) |
48 | -DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs) | 48 | -DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs) |
49 | -DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu) | 49 | -DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu) |
50 | +DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_rz_hs) | 50 | +DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_rz_hs) |
51 | +DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_rz_hu) | 51 | +DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_rz_hu) |
52 | 52 | ||
53 | static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a, | 53 | static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a, |
54 | GVecGen2iFn *fn) | 54 | GVecGen2iFn *fn) |
55 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c | 55 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c |
56 | index XXXXXXX..XXXXXXX 100644 | 56 | index XXXXXXX..XXXXXXX 100644 |
57 | --- a/target/arm/tcg/vec_helper.c | 57 | --- a/target/arm/tcg/vec_helper.c |
58 | +++ b/target/arm/tcg/vec_helper.c | 58 | +++ b/target/arm/tcg/vec_helper.c |
59 | @@ -XXX,XX +XXX,XX @@ DO_3OP_PAIR(gvec_uminp_s, MIN, uint32_t, H4) | 59 | @@ -XXX,XX +XXX,XX @@ DO_3OP_PAIR(gvec_uminp_s, MIN, uint32_t, H4) |
60 | 60 | ||
61 | DO_VCVT_FIXED(gvec_vcvt_sf, helper_vfp_sltos, uint32_t) | 61 | DO_VCVT_FIXED(gvec_vcvt_sf, helper_vfp_sltos, uint32_t) |
62 | DO_VCVT_FIXED(gvec_vcvt_uf, helper_vfp_ultos, uint32_t) | 62 | DO_VCVT_FIXED(gvec_vcvt_uf, helper_vfp_ultos, uint32_t) |
63 | -DO_VCVT_FIXED(gvec_vcvt_fs, helper_vfp_tosls_round_to_zero, uint32_t) | 63 | -DO_VCVT_FIXED(gvec_vcvt_fs, helper_vfp_tosls_round_to_zero, uint32_t) |
64 | -DO_VCVT_FIXED(gvec_vcvt_fu, helper_vfp_touls_round_to_zero, uint32_t) | 64 | -DO_VCVT_FIXED(gvec_vcvt_fu, helper_vfp_touls_round_to_zero, uint32_t) |
65 | +DO_VCVT_FIXED(gvec_vcvt_rz_fs, helper_vfp_tosls_round_to_zero, uint32_t) | 65 | +DO_VCVT_FIXED(gvec_vcvt_rz_fs, helper_vfp_tosls_round_to_zero, uint32_t) |
66 | +DO_VCVT_FIXED(gvec_vcvt_rz_fu, helper_vfp_touls_round_to_zero, uint32_t) | 66 | +DO_VCVT_FIXED(gvec_vcvt_rz_fu, helper_vfp_touls_round_to_zero, uint32_t) |
67 | DO_VCVT_FIXED(gvec_vcvt_sh, helper_vfp_shtoh, uint16_t) | 67 | DO_VCVT_FIXED(gvec_vcvt_sh, helper_vfp_shtoh, uint16_t) |
68 | DO_VCVT_FIXED(gvec_vcvt_uh, helper_vfp_uhtoh, uint16_t) | 68 | DO_VCVT_FIXED(gvec_vcvt_uh, helper_vfp_uhtoh, uint16_t) |
69 | -DO_VCVT_FIXED(gvec_vcvt_hs, helper_vfp_toshh_round_to_zero, uint16_t) | 69 | -DO_VCVT_FIXED(gvec_vcvt_hs, helper_vfp_toshh_round_to_zero, uint16_t) |
70 | -DO_VCVT_FIXED(gvec_vcvt_hu, helper_vfp_touhh_round_to_zero, uint16_t) | 70 | -DO_VCVT_FIXED(gvec_vcvt_hu, helper_vfp_touhh_round_to_zero, uint16_t) |
71 | +DO_VCVT_FIXED(gvec_vcvt_rz_hs, helper_vfp_toshh_round_to_zero, uint16_t) | 71 | +DO_VCVT_FIXED(gvec_vcvt_rz_hs, helper_vfp_toshh_round_to_zero, uint16_t) |
72 | +DO_VCVT_FIXED(gvec_vcvt_rz_hu, helper_vfp_touhh_round_to_zero, uint16_t) | 72 | +DO_VCVT_FIXED(gvec_vcvt_rz_hu, helper_vfp_touhh_round_to_zero, uint16_t) |
73 | 73 | ||
74 | #undef DO_VCVT_FIXED | 74 | #undef DO_VCVT_FIXED |
75 | 75 | ||
76 | -- | 76 | -- |
77 | 2.43.0 | 77 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove handle_simd_intfp_conv and handle_simd_shift_intfp_conv | 1 | Remove handle_simd_intfp_conv and handle_simd_shift_intfp_conv |
---|---|---|---|
2 | as these were the last insns decoded by those functions. | 2 | as these were the last insns decoded by those functions. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 6 | --- |
6 | target/arm/helper.h | 3 + | 7 | target/arm/helper.h | 3 + |
7 | target/arm/tcg/translate-a64.c | 201 ++++++--------------------------- | 8 | target/arm/tcg/translate-a64.c | 201 ++++++--------------------------- |
8 | target/arm/tcg/vec_helper.c | 7 +- | 9 | target/arm/tcg/vec_helper.c | 7 +- |
... | ... | diff view generated by jsdifflib |
1 | Remove handle_simd_shift_fpint_conv and disas_simd_shift_imm | 1 | Remove handle_simd_shift_fpint_conv and disas_simd_shift_imm |
---|---|---|---|
2 | as these were the last insns decoded by those functions. | 2 | as these were the last insns decoded by those functions. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 6 | --- |
6 | target/arm/helper.h | 4 + | 7 | target/arm/helper.h | 4 + |
7 | target/arm/tcg/translate-a64.c | 160 +++------------------------------ | 8 | target/arm/tcg/translate-a64.c | 160 +++------------------------------ |
8 | target/arm/tcg/vec_helper.c | 2 + | 9 | target/arm/tcg/vec_helper.c | 2 + |
... | ... | diff view generated by jsdifflib |
1 | Remove handle_2misc_64 as these were the last insns decoded | 1 | Remove handle_2misc_64 as these were the last insns decoded |
---|---|---|---|
2 | by that function. Remove helper_advsimd_f16to[su]inth as unused; | 2 | by that function. Remove helper_advsimd_f16to[su]inth as unused; |
3 | we now always go through helper_vfp_to[su]hh or a specialized | 3 | we now always go through helper_vfp_to[su]hh or a specialized |
4 | vector function instead. | 4 | vector function instead. |
5 | 5 | ||
6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 7 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
7 | --- | 8 | --- |
8 | target/arm/helper.h | 2 + | 9 | target/arm/helper.h | 2 + |
9 | target/arm/tcg/helper-a64.h | 2 - | 10 | target/arm/tcg/helper-a64.h | 2 - |
10 | target/arm/tcg/helper-a64.c | 32 ----- | 11 | target/arm/tcg/helper-a64.c | 32 ----- |
... | ... | diff view generated by jsdifflib |
1 | This includes FCMEQ, FCMGT, FCMGE, FCMLT, FCMLE. | 1 | This includes FCMEQ, FCMGT, FCMGE, FCMLT, FCMLE. |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 3 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 5 | --- |
6 | target/arm/helper.h | 5 + | 6 | target/arm/helper.h | 5 + |
7 | target/arm/tcg/translate-a64.c | 249 +++++++++++++-------------------- | 7 | target/arm/tcg/translate-a64.c | 249 +++++++++++++-------------------- |
8 | target/arm/tcg/vec_helper.c | 4 +- | 8 | target/arm/tcg/vec_helper.c | 4 +- |
9 | target/arm/tcg/a64.decode | 30 ++++ | 9 | target/arm/tcg/a64.decode | 30 ++++ |
10 | 4 files changed, 138 insertions(+), 150 deletions(-) | 10 | 4 files changed, 138 insertions(+), 150 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/helper.h b/target/arm/helper.h | 12 | diff --git a/target/arm/helper.h b/target/arm/helper.h |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/helper.h | 14 | --- a/target/arm/helper.h |
15 | +++ b/target/arm/helper.h | 15 | +++ b/target/arm/helper.h |
16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_frsqrte_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 16 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_frsqrte_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
17 | 17 | ||
18 | DEF_HELPER_FLAGS_4(gvec_fcgt0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 18 | DEF_HELPER_FLAGS_4(gvec_fcgt0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
19 | DEF_HELPER_FLAGS_4(gvec_fcgt0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 19 | DEF_HELPER_FLAGS_4(gvec_fcgt0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
20 | +DEF_HELPER_FLAGS_4(gvec_fcgt0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 20 | +DEF_HELPER_FLAGS_4(gvec_fcgt0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
21 | 21 | ||
22 | DEF_HELPER_FLAGS_4(gvec_fcge0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 22 | DEF_HELPER_FLAGS_4(gvec_fcge0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
23 | DEF_HELPER_FLAGS_4(gvec_fcge0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 23 | DEF_HELPER_FLAGS_4(gvec_fcge0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
24 | +DEF_HELPER_FLAGS_4(gvec_fcge0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 24 | +DEF_HELPER_FLAGS_4(gvec_fcge0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
25 | 25 | ||
26 | DEF_HELPER_FLAGS_4(gvec_fceq0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 26 | DEF_HELPER_FLAGS_4(gvec_fceq0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
27 | DEF_HELPER_FLAGS_4(gvec_fceq0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 27 | DEF_HELPER_FLAGS_4(gvec_fceq0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
28 | +DEF_HELPER_FLAGS_4(gvec_fceq0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 28 | +DEF_HELPER_FLAGS_4(gvec_fceq0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
29 | 29 | ||
30 | DEF_HELPER_FLAGS_4(gvec_fcle0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 30 | DEF_HELPER_FLAGS_4(gvec_fcle0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
31 | DEF_HELPER_FLAGS_4(gvec_fcle0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 31 | DEF_HELPER_FLAGS_4(gvec_fcle0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
32 | +DEF_HELPER_FLAGS_4(gvec_fcle0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 32 | +DEF_HELPER_FLAGS_4(gvec_fcle0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
33 | 33 | ||
34 | DEF_HELPER_FLAGS_4(gvec_fclt0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 34 | DEF_HELPER_FLAGS_4(gvec_fclt0_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
35 | DEF_HELPER_FLAGS_4(gvec_fclt0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 35 | DEF_HELPER_FLAGS_4(gvec_fclt0_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
36 | +DEF_HELPER_FLAGS_4(gvec_fclt0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) | 36 | +DEF_HELPER_FLAGS_4(gvec_fclt0_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) |
37 | 37 | ||
38 | DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) | 38 | DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) |
39 | DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) | 39 | DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) |
40 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 40 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
41 | index XXXXXXX..XXXXXXX 100644 | 41 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/target/arm/tcg/translate-a64.c | 42 | --- a/target/arm/tcg/translate-a64.c |
43 | +++ b/target/arm/tcg/translate-a64.c | 43 | +++ b/target/arm/tcg/translate-a64.c |
44 | @@ -XXX,XX +XXX,XX @@ static const FPScalar f_scalar_frsqrts = { | 44 | @@ -XXX,XX +XXX,XX @@ static const FPScalar f_scalar_frsqrts = { |
45 | }; | 45 | }; |
46 | TRANS(FRSQRTS_s, do_fp3_scalar, a, &f_scalar_frsqrts) | 46 | TRANS(FRSQRTS_s, do_fp3_scalar, a, &f_scalar_frsqrts) |
47 | 47 | ||
48 | +static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a, | 48 | +static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a, |
49 | + const FPScalar *f, bool swap) | 49 | + const FPScalar *f, bool swap) |
50 | +{ | 50 | +{ |
51 | + switch (a->esz) { | 51 | + switch (a->esz) { |
52 | + case MO_64: | 52 | + case MO_64: |
53 | + if (fp_access_check(s)) { | 53 | + if (fp_access_check(s)) { |
54 | + TCGv_i64 t0 = read_fp_dreg(s, a->rn); | 54 | + TCGv_i64 t0 = read_fp_dreg(s, a->rn); |
55 | + TCGv_i64 t1 = tcg_constant_i64(0); | 55 | + TCGv_i64 t1 = tcg_constant_i64(0); |
56 | + if (swap) { | 56 | + if (swap) { |
57 | + f->gen_d(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); | 57 | + f->gen_d(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); |
58 | + } else { | 58 | + } else { |
59 | + f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | 59 | + f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); |
60 | + } | 60 | + } |
61 | + write_fp_dreg(s, a->rd, t0); | 61 | + write_fp_dreg(s, a->rd, t0); |
62 | + } | 62 | + } |
63 | + break; | 63 | + break; |
64 | + case MO_32: | 64 | + case MO_32: |
65 | + if (fp_access_check(s)) { | 65 | + if (fp_access_check(s)) { |
66 | + TCGv_i32 t0 = read_fp_sreg(s, a->rn); | 66 | + TCGv_i32 t0 = read_fp_sreg(s, a->rn); |
67 | + TCGv_i32 t1 = tcg_constant_i32(0); | 67 | + TCGv_i32 t1 = tcg_constant_i32(0); |
68 | + if (swap) { | 68 | + if (swap) { |
69 | + f->gen_s(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); | 69 | + f->gen_s(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); |
70 | + } else { | 70 | + } else { |
71 | + f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | 71 | + f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); |
72 | + } | 72 | + } |
73 | + write_fp_sreg(s, a->rd, t0); | 73 | + write_fp_sreg(s, a->rd, t0); |
74 | + } | 74 | + } |
75 | + break; | 75 | + break; |
76 | + case MO_16: | 76 | + case MO_16: |
77 | + if (!dc_isar_feature(aa64_fp16, s)) { | 77 | + if (!dc_isar_feature(aa64_fp16, s)) { |
78 | + return false; | 78 | + return false; |
79 | + } | 79 | + } |
80 | + if (fp_access_check(s)) { | 80 | + if (fp_access_check(s)) { |
81 | + TCGv_i32 t0 = read_fp_hreg(s, a->rn); | 81 | + TCGv_i32 t0 = read_fp_hreg(s, a->rn); |
82 | + TCGv_i32 t1 = tcg_constant_i32(0); | 82 | + TCGv_i32 t1 = tcg_constant_i32(0); |
83 | + if (swap) { | 83 | + if (swap) { |
84 | + f->gen_h(t0, t1, t0, fpstatus_ptr(FPST_FPCR_F16)); | 84 | + f->gen_h(t0, t1, t0, fpstatus_ptr(FPST_FPCR_F16)); |
85 | + } else { | 85 | + } else { |
86 | + f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); | 86 | + f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); |
87 | + } | 87 | + } |
88 | + write_fp_sreg(s, a->rd, t0); | 88 | + write_fp_sreg(s, a->rd, t0); |
89 | + } | 89 | + } |
90 | + break; | 90 | + break; |
91 | + default: | 91 | + default: |
92 | + return false; | 92 | + return false; |
93 | + } | 93 | + } |
94 | + return true; | 94 | + return true; |
95 | +} | 95 | +} |
96 | + | 96 | + |
97 | +TRANS(FCMEQ0_s, do_fcmp0_s, a, &f_scalar_fcmeq, false) | 97 | +TRANS(FCMEQ0_s, do_fcmp0_s, a, &f_scalar_fcmeq, false) |
98 | +TRANS(FCMGT0_s, do_fcmp0_s, a, &f_scalar_fcmgt, false) | 98 | +TRANS(FCMGT0_s, do_fcmp0_s, a, &f_scalar_fcmgt, false) |
99 | +TRANS(FCMGE0_s, do_fcmp0_s, a, &f_scalar_fcmge, false) | 99 | +TRANS(FCMGE0_s, do_fcmp0_s, a, &f_scalar_fcmge, false) |
100 | +TRANS(FCMLT0_s, do_fcmp0_s, a, &f_scalar_fcmgt, true) | 100 | +TRANS(FCMLT0_s, do_fcmp0_s, a, &f_scalar_fcmgt, true) |
101 | +TRANS(FCMLE0_s, do_fcmp0_s, a, &f_scalar_fcmge, true) | 101 | +TRANS(FCMLE0_s, do_fcmp0_s, a, &f_scalar_fcmge, true) |
102 | + | 102 | + |
103 | static bool do_satacc_s(DisasContext *s, arg_rrr_e *a, | 103 | static bool do_satacc_s(DisasContext *s, arg_rrr_e *a, |
104 | MemOp sgn_n, MemOp sgn_m, | 104 | MemOp sgn_n, MemOp sgn_m, |
105 | void (*gen_bhs)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, MemOp), | 105 | void (*gen_bhs)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, MemOp), |
106 | @@ -XXX,XX +XXX,XX @@ TRANS(FCVTAS_vi, do_gvec_op2_fpst, | 106 | @@ -XXX,XX +XXX,XX @@ TRANS(FCVTAS_vi, do_gvec_op2_fpst, |
107 | TRANS(FCVTAU_vi, do_gvec_op2_fpst, | 107 | TRANS(FCVTAU_vi, do_gvec_op2_fpst, |
108 | a->esz, a->q, a->rd, a->rn, float_round_ties_away, f_fcvt_u_vi) | 108 | a->esz, a->q, a->rd, a->rn, float_round_ties_away, f_fcvt_u_vi) |
109 | 109 | ||
110 | -static void handle_2misc_fcmp_zero(DisasContext *s, int opcode, | 110 | -static void handle_2misc_fcmp_zero(DisasContext *s, int opcode, |
111 | - bool is_scalar, bool is_u, bool is_q, | 111 | - bool is_scalar, bool is_u, bool is_q, |
112 | - int size, int rn, int rd) | 112 | - int size, int rn, int rd) |
113 | -{ | 113 | -{ |
114 | - bool is_double = (size == MO_64); | 114 | - bool is_double = (size == MO_64); |
115 | - TCGv_ptr fpst; | 115 | - TCGv_ptr fpst; |
116 | +static gen_helper_gvec_2_ptr * const f_fceq0[] = { | 116 | +static gen_helper_gvec_2_ptr * const f_fceq0[] = { |
117 | + gen_helper_gvec_fceq0_h, | 117 | + gen_helper_gvec_fceq0_h, |
118 | + gen_helper_gvec_fceq0_s, | 118 | + gen_helper_gvec_fceq0_s, |
119 | + gen_helper_gvec_fceq0_d, | 119 | + gen_helper_gvec_fceq0_d, |
120 | +}; | 120 | +}; |
121 | +TRANS(FCMEQ0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fceq0) | 121 | +TRANS(FCMEQ0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fceq0) |
122 | 122 | ||
123 | - if (!fp_access_check(s)) { | 123 | - if (!fp_access_check(s)) { |
124 | - return; | 124 | - return; |
125 | - } | 125 | - } |
126 | +static gen_helper_gvec_2_ptr * const f_fcgt0[] = { | 126 | +static gen_helper_gvec_2_ptr * const f_fcgt0[] = { |
127 | + gen_helper_gvec_fcgt0_h, | 127 | + gen_helper_gvec_fcgt0_h, |
128 | + gen_helper_gvec_fcgt0_s, | 128 | + gen_helper_gvec_fcgt0_s, |
129 | + gen_helper_gvec_fcgt0_d, | 129 | + gen_helper_gvec_fcgt0_d, |
130 | +}; | 130 | +}; |
131 | +TRANS(FCMGT0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcgt0) | 131 | +TRANS(FCMGT0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcgt0) |
132 | 132 | ||
133 | - fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | 133 | - fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); |
134 | +static gen_helper_gvec_2_ptr * const f_fcge0[] = { | 134 | +static gen_helper_gvec_2_ptr * const f_fcge0[] = { |
135 | + gen_helper_gvec_fcge0_h, | 135 | + gen_helper_gvec_fcge0_h, |
136 | + gen_helper_gvec_fcge0_s, | 136 | + gen_helper_gvec_fcge0_s, |
137 | + gen_helper_gvec_fcge0_d, | 137 | + gen_helper_gvec_fcge0_d, |
138 | +}; | 138 | +}; |
139 | +TRANS(FCMGE0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcge0) | 139 | +TRANS(FCMGE0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcge0) |
140 | 140 | ||
141 | - if (is_double) { | 141 | - if (is_double) { |
142 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); | 142 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); |
143 | - TCGv_i64 tcg_zero = tcg_constant_i64(0); | 143 | - TCGv_i64 tcg_zero = tcg_constant_i64(0); |
144 | - TCGv_i64 tcg_res = tcg_temp_new_i64(); | 144 | - TCGv_i64 tcg_res = tcg_temp_new_i64(); |
145 | - NeonGenTwoDoubleOpFn *genfn; | 145 | - NeonGenTwoDoubleOpFn *genfn; |
146 | - bool swap = false; | 146 | - bool swap = false; |
147 | - int pass; | 147 | - int pass; |
148 | +static gen_helper_gvec_2_ptr * const f_fclt0[] = { | 148 | +static gen_helper_gvec_2_ptr * const f_fclt0[] = { |
149 | + gen_helper_gvec_fclt0_h, | 149 | + gen_helper_gvec_fclt0_h, |
150 | + gen_helper_gvec_fclt0_s, | 150 | + gen_helper_gvec_fclt0_s, |
151 | + gen_helper_gvec_fclt0_d, | 151 | + gen_helper_gvec_fclt0_d, |
152 | +}; | 152 | +}; |
153 | +TRANS(FCMLT0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fclt0) | 153 | +TRANS(FCMLT0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fclt0) |
154 | 154 | ||
155 | - switch (opcode) { | 155 | - switch (opcode) { |
156 | - case 0x2e: /* FCMLT (zero) */ | 156 | - case 0x2e: /* FCMLT (zero) */ |
157 | - swap = true; | 157 | - swap = true; |
158 | - /* fallthrough */ | 158 | - /* fallthrough */ |
159 | - case 0x2c: /* FCMGT (zero) */ | 159 | - case 0x2c: /* FCMGT (zero) */ |
160 | - genfn = gen_helper_neon_cgt_f64; | 160 | - genfn = gen_helper_neon_cgt_f64; |
161 | - break; | 161 | - break; |
162 | - case 0x2d: /* FCMEQ (zero) */ | 162 | - case 0x2d: /* FCMEQ (zero) */ |
163 | - genfn = gen_helper_neon_ceq_f64; | 163 | - genfn = gen_helper_neon_ceq_f64; |
164 | - break; | 164 | - break; |
165 | - case 0x6d: /* FCMLE (zero) */ | 165 | - case 0x6d: /* FCMLE (zero) */ |
166 | - swap = true; | 166 | - swap = true; |
167 | - /* fall through */ | 167 | - /* fall through */ |
168 | - case 0x6c: /* FCMGE (zero) */ | 168 | - case 0x6c: /* FCMGE (zero) */ |
169 | - genfn = gen_helper_neon_cge_f64; | 169 | - genfn = gen_helper_neon_cge_f64; |
170 | - break; | 170 | - break; |
171 | - default: | 171 | - default: |
172 | - g_assert_not_reached(); | 172 | - g_assert_not_reached(); |
173 | - } | 173 | - } |
174 | - | 174 | - |
175 | - for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) { | 175 | - for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) { |
176 | - read_vec_element(s, tcg_op, rn, pass, MO_64); | 176 | - read_vec_element(s, tcg_op, rn, pass, MO_64); |
177 | - if (swap) { | 177 | - if (swap) { |
178 | - genfn(tcg_res, tcg_zero, tcg_op, fpst); | 178 | - genfn(tcg_res, tcg_zero, tcg_op, fpst); |
179 | - } else { | 179 | - } else { |
180 | - genfn(tcg_res, tcg_op, tcg_zero, fpst); | 180 | - genfn(tcg_res, tcg_op, tcg_zero, fpst); |
181 | - } | 181 | - } |
182 | - write_vec_element(s, tcg_res, rd, pass, MO_64); | 182 | - write_vec_element(s, tcg_res, rd, pass, MO_64); |
183 | - } | 183 | - } |
184 | - | 184 | - |
185 | - clear_vec_high(s, !is_scalar, rd); | 185 | - clear_vec_high(s, !is_scalar, rd); |
186 | - } else { | 186 | - } else { |
187 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); | 187 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); |
188 | - TCGv_i32 tcg_zero = tcg_constant_i32(0); | 188 | - TCGv_i32 tcg_zero = tcg_constant_i32(0); |
189 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); | 189 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); |
190 | - NeonGenTwoSingleOpFn *genfn; | 190 | - NeonGenTwoSingleOpFn *genfn; |
191 | - bool swap = false; | 191 | - bool swap = false; |
192 | - int pass, maxpasses; | 192 | - int pass, maxpasses; |
193 | - | 193 | - |
194 | - if (size == MO_16) { | 194 | - if (size == MO_16) { |
195 | - switch (opcode) { | 195 | - switch (opcode) { |
196 | - case 0x2e: /* FCMLT (zero) */ | 196 | - case 0x2e: /* FCMLT (zero) */ |
197 | - swap = true; | 197 | - swap = true; |
198 | - /* fall through */ | 198 | - /* fall through */ |
199 | - case 0x2c: /* FCMGT (zero) */ | 199 | - case 0x2c: /* FCMGT (zero) */ |
200 | - genfn = gen_helper_advsimd_cgt_f16; | 200 | - genfn = gen_helper_advsimd_cgt_f16; |
201 | - break; | 201 | - break; |
202 | - case 0x2d: /* FCMEQ (zero) */ | 202 | - case 0x2d: /* FCMEQ (zero) */ |
203 | - genfn = gen_helper_advsimd_ceq_f16; | 203 | - genfn = gen_helper_advsimd_ceq_f16; |
204 | - break; | 204 | - break; |
205 | - case 0x6d: /* FCMLE (zero) */ | 205 | - case 0x6d: /* FCMLE (zero) */ |
206 | - swap = true; | 206 | - swap = true; |
207 | - /* fall through */ | 207 | - /* fall through */ |
208 | - case 0x6c: /* FCMGE (zero) */ | 208 | - case 0x6c: /* FCMGE (zero) */ |
209 | - genfn = gen_helper_advsimd_cge_f16; | 209 | - genfn = gen_helper_advsimd_cge_f16; |
210 | - break; | 210 | - break; |
211 | - default: | 211 | - default: |
212 | - g_assert_not_reached(); | 212 | - g_assert_not_reached(); |
213 | - } | 213 | - } |
214 | - } else { | 214 | - } else { |
215 | - switch (opcode) { | 215 | - switch (opcode) { |
216 | - case 0x2e: /* FCMLT (zero) */ | 216 | - case 0x2e: /* FCMLT (zero) */ |
217 | - swap = true; | 217 | - swap = true; |
218 | - /* fall through */ | 218 | - /* fall through */ |
219 | - case 0x2c: /* FCMGT (zero) */ | 219 | - case 0x2c: /* FCMGT (zero) */ |
220 | - genfn = gen_helper_neon_cgt_f32; | 220 | - genfn = gen_helper_neon_cgt_f32; |
221 | - break; | 221 | - break; |
222 | - case 0x2d: /* FCMEQ (zero) */ | 222 | - case 0x2d: /* FCMEQ (zero) */ |
223 | - genfn = gen_helper_neon_ceq_f32; | 223 | - genfn = gen_helper_neon_ceq_f32; |
224 | - break; | 224 | - break; |
225 | - case 0x6d: /* FCMLE (zero) */ | 225 | - case 0x6d: /* FCMLE (zero) */ |
226 | - swap = true; | 226 | - swap = true; |
227 | - /* fall through */ | 227 | - /* fall through */ |
228 | - case 0x6c: /* FCMGE (zero) */ | 228 | - case 0x6c: /* FCMGE (zero) */ |
229 | - genfn = gen_helper_neon_cge_f32; | 229 | - genfn = gen_helper_neon_cge_f32; |
230 | - break; | 230 | - break; |
231 | - default: | 231 | - default: |
232 | - g_assert_not_reached(); | 232 | - g_assert_not_reached(); |
233 | - } | 233 | - } |
234 | - } | 234 | - } |
235 | - | 235 | - |
236 | - if (is_scalar) { | 236 | - if (is_scalar) { |
237 | - maxpasses = 1; | 237 | - maxpasses = 1; |
238 | - } else { | 238 | - } else { |
239 | - int vector_size = 8 << is_q; | 239 | - int vector_size = 8 << is_q; |
240 | - maxpasses = vector_size >> size; | 240 | - maxpasses = vector_size >> size; |
241 | - } | 241 | - } |
242 | - | 242 | - |
243 | - for (pass = 0; pass < maxpasses; pass++) { | 243 | - for (pass = 0; pass < maxpasses; pass++) { |
244 | - read_vec_element_i32(s, tcg_op, rn, pass, size); | 244 | - read_vec_element_i32(s, tcg_op, rn, pass, size); |
245 | - if (swap) { | 245 | - if (swap) { |
246 | - genfn(tcg_res, tcg_zero, tcg_op, fpst); | 246 | - genfn(tcg_res, tcg_zero, tcg_op, fpst); |
247 | - } else { | 247 | - } else { |
248 | - genfn(tcg_res, tcg_op, tcg_zero, fpst); | 248 | - genfn(tcg_res, tcg_op, tcg_zero, fpst); |
249 | - } | 249 | - } |
250 | - if (is_scalar) { | 250 | - if (is_scalar) { |
251 | - write_fp_sreg(s, rd, tcg_res); | 251 | - write_fp_sreg(s, rd, tcg_res); |
252 | - } else { | 252 | - } else { |
253 | - write_vec_element_i32(s, tcg_res, rd, pass, size); | 253 | - write_vec_element_i32(s, tcg_res, rd, pass, size); |
254 | - } | 254 | - } |
255 | - } | 255 | - } |
256 | - | 256 | - |
257 | - if (!is_scalar) { | 257 | - if (!is_scalar) { |
258 | - clear_vec_high(s, is_q, rd); | 258 | - clear_vec_high(s, is_q, rd); |
259 | - } | 259 | - } |
260 | - } | 260 | - } |
261 | -} | 261 | -} |
262 | +static gen_helper_gvec_2_ptr * const f_fcle0[] = { | 262 | +static gen_helper_gvec_2_ptr * const f_fcle0[] = { |
263 | + gen_helper_gvec_fcle0_h, | 263 | + gen_helper_gvec_fcle0_h, |
264 | + gen_helper_gvec_fcle0_s, | 264 | + gen_helper_gvec_fcle0_s, |
265 | + gen_helper_gvec_fcle0_d, | 265 | + gen_helper_gvec_fcle0_d, |
266 | +}; | 266 | +}; |
267 | +TRANS(FCMLE0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcle0) | 267 | +TRANS(FCMLE0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcle0) |
268 | 268 | ||
269 | static void handle_2misc_reciprocal(DisasContext *s, int opcode, | 269 | static void handle_2misc_reciprocal(DisasContext *s, int opcode, |
270 | bool is_scalar, bool is_u, bool is_q, | 270 | bool is_scalar, bool is_u, bool is_q, |
271 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 271 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
272 | opcode |= (extract32(size, 1, 1) << 5) | (u << 6); | 272 | opcode |= (extract32(size, 1, 1) << 5) | (u << 6); |
273 | size = extract32(size, 0, 1) ? 3 : 2; | 273 | size = extract32(size, 0, 1) ? 3 : 2; |
274 | switch (opcode) { | 274 | switch (opcode) { |
275 | - case 0x2c: /* FCMGT (zero) */ | 275 | - case 0x2c: /* FCMGT (zero) */ |
276 | - case 0x2d: /* FCMEQ (zero) */ | 276 | - case 0x2d: /* FCMEQ (zero) */ |
277 | - case 0x2e: /* FCMLT (zero) */ | 277 | - case 0x2e: /* FCMLT (zero) */ |
278 | - case 0x6c: /* FCMGE (zero) */ | 278 | - case 0x6c: /* FCMGE (zero) */ |
279 | - case 0x6d: /* FCMLE (zero) */ | 279 | - case 0x6d: /* FCMLE (zero) */ |
280 | - handle_2misc_fcmp_zero(s, opcode, true, u, true, size, rn, rd); | 280 | - handle_2misc_fcmp_zero(s, opcode, true, u, true, size, rn, rd); |
281 | - return; | 281 | - return; |
282 | case 0x3d: /* FRECPE */ | 282 | case 0x3d: /* FRECPE */ |
283 | case 0x3f: /* FRECPX */ | 283 | case 0x3f: /* FRECPX */ |
284 | case 0x7d: /* FRSQRTE */ | 284 | case 0x7d: /* FRSQRTE */ |
285 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 285 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
286 | case 0x56: /* FCVTXN, FCVTXN2 */ | 286 | case 0x56: /* FCVTXN, FCVTXN2 */ |
287 | case 0x1d: /* SCVTF */ | 287 | case 0x1d: /* SCVTF */ |
288 | case 0x5d: /* UCVTF */ | 288 | case 0x5d: /* UCVTF */ |
289 | + case 0x2c: /* FCMGT (zero) */ | 289 | + case 0x2c: /* FCMGT (zero) */ |
290 | + case 0x2d: /* FCMEQ (zero) */ | 290 | + case 0x2d: /* FCMEQ (zero) */ |
291 | + case 0x2e: /* FCMLT (zero) */ | 291 | + case 0x2e: /* FCMLT (zero) */ |
292 | + case 0x6c: /* FCMGE (zero) */ | 292 | + case 0x6c: /* FCMGE (zero) */ |
293 | + case 0x6d: /* FCMLE (zero) */ | 293 | + case 0x6d: /* FCMLE (zero) */ |
294 | default: | 294 | default: |
295 | unallocated_encoding(s); | 295 | unallocated_encoding(s); |
296 | return; | 296 | return; |
297 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 297 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
298 | opcode |= (extract32(size, 1, 1) << 5) | (u << 6); | 298 | opcode |= (extract32(size, 1, 1) << 5) | (u << 6); |
299 | size = is_double ? 3 : 2; | 299 | size = is_double ? 3 : 2; |
300 | switch (opcode) { | 300 | switch (opcode) { |
301 | - case 0x2c: /* FCMGT (zero) */ | 301 | - case 0x2c: /* FCMGT (zero) */ |
302 | - case 0x2d: /* FCMEQ (zero) */ | 302 | - case 0x2d: /* FCMEQ (zero) */ |
303 | - case 0x2e: /* FCMLT (zero) */ | 303 | - case 0x2e: /* FCMLT (zero) */ |
304 | - case 0x6c: /* FCMGE (zero) */ | 304 | - case 0x6c: /* FCMGE (zero) */ |
305 | - case 0x6d: /* FCMLE (zero) */ | 305 | - case 0x6d: /* FCMLE (zero) */ |
306 | - if (size == 3 && !is_q) { | 306 | - if (size == 3 && !is_q) { |
307 | - unallocated_encoding(s); | 307 | - unallocated_encoding(s); |
308 | - return; | 308 | - return; |
309 | - } | 309 | - } |
310 | - handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd); | 310 | - handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd); |
311 | - return; | 311 | - return; |
312 | case 0x3c: /* URECPE */ | 312 | case 0x3c: /* URECPE */ |
313 | if (size == 3) { | 313 | if (size == 3) { |
314 | unallocated_encoding(s); | 314 | unallocated_encoding(s); |
315 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 315 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
316 | case 0x7b: /* FCVTZU */ | 316 | case 0x7b: /* FCVTZU */ |
317 | case 0x5c: /* FCVTAU */ | 317 | case 0x5c: /* FCVTAU */ |
318 | case 0x1c: /* FCVTAS */ | 318 | case 0x1c: /* FCVTAS */ |
319 | + case 0x2c: /* FCMGT (zero) */ | 319 | + case 0x2c: /* FCMGT (zero) */ |
320 | + case 0x2d: /* FCMEQ (zero) */ | 320 | + case 0x2d: /* FCMEQ (zero) */ |
321 | + case 0x2e: /* FCMLT (zero) */ | 321 | + case 0x2e: /* FCMLT (zero) */ |
322 | + case 0x6c: /* FCMGE (zero) */ | 322 | + case 0x6c: /* FCMGE (zero) */ |
323 | + case 0x6d: /* FCMLE (zero) */ | 323 | + case 0x6d: /* FCMLE (zero) */ |
324 | unallocated_encoding(s); | 324 | unallocated_encoding(s); |
325 | return; | 325 | return; |
326 | } | 326 | } |
327 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 327 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
328 | fpop = deposit32(fpop, 6, 1, u); | 328 | fpop = deposit32(fpop, 6, 1, u); |
329 | 329 | ||
330 | switch (fpop) { | 330 | switch (fpop) { |
331 | - case 0x2c: /* FCMGT (zero) */ | 331 | - case 0x2c: /* FCMGT (zero) */ |
332 | - case 0x2d: /* FCMEQ (zero) */ | 332 | - case 0x2d: /* FCMEQ (zero) */ |
333 | - case 0x2e: /* FCMLT (zero) */ | 333 | - case 0x2e: /* FCMLT (zero) */ |
334 | - case 0x6c: /* FCMGE (zero) */ | 334 | - case 0x6c: /* FCMGE (zero) */ |
335 | - case 0x6d: /* FCMLE (zero) */ | 335 | - case 0x6d: /* FCMLE (zero) */ |
336 | - handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd); | 336 | - handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd); |
337 | - return; | 337 | - return; |
338 | case 0x3d: /* FRECPE */ | 338 | case 0x3d: /* FRECPE */ |
339 | case 0x3f: /* FRECPX */ | 339 | case 0x3f: /* FRECPX */ |
340 | break; | 340 | break; |
341 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 341 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
342 | case 0x5c: /* FCVTAU */ | 342 | case 0x5c: /* FCVTAU */ |
343 | case 0x7a: /* FCVTPU */ | 343 | case 0x7a: /* FCVTPU */ |
344 | case 0x7b: /* FCVTZU */ | 344 | case 0x7b: /* FCVTZU */ |
345 | + case 0x2c: /* FCMGT (zero) */ | 345 | + case 0x2c: /* FCMGT (zero) */ |
346 | + case 0x2d: /* FCMEQ (zero) */ | 346 | + case 0x2d: /* FCMEQ (zero) */ |
347 | + case 0x2e: /* FCMLT (zero) */ | 347 | + case 0x2e: /* FCMLT (zero) */ |
348 | + case 0x6c: /* FCMGE (zero) */ | 348 | + case 0x6c: /* FCMGE (zero) */ |
349 | + case 0x6d: /* FCMLE (zero) */ | 349 | + case 0x6d: /* FCMLE (zero) */ |
350 | unallocated_encoding(s); | 350 | unallocated_encoding(s); |
351 | return; | 351 | return; |
352 | } | 352 | } |
353 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c | 353 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c |
354 | index XXXXXXX..XXXXXXX 100644 | 354 | index XXXXXXX..XXXXXXX 100644 |
355 | --- a/target/arm/tcg/vec_helper.c | 355 | --- a/target/arm/tcg/vec_helper.c |
356 | +++ b/target/arm/tcg/vec_helper.c | 356 | +++ b/target/arm/tcg/vec_helper.c |
357 | @@ -XXX,XX +XXX,XX @@ DO_2OP(gvec_touszh, vfp_touszh, float16) | 357 | @@ -XXX,XX +XXX,XX @@ DO_2OP(gvec_touszh, vfp_touszh, float16) |
358 | #define DO_2OP_CMP0(FN, CMPOP, DIRN) \ | 358 | #define DO_2OP_CMP0(FN, CMPOP, DIRN) \ |
359 | WRAP_CMP0_##DIRN(FN, CMPOP, float16) \ | 359 | WRAP_CMP0_##DIRN(FN, CMPOP, float16) \ |
360 | WRAP_CMP0_##DIRN(FN, CMPOP, float32) \ | 360 | WRAP_CMP0_##DIRN(FN, CMPOP, float32) \ |
361 | + WRAP_CMP0_##DIRN(FN, CMPOP, float64) \ | 361 | + WRAP_CMP0_##DIRN(FN, CMPOP, float64) \ |
362 | DO_2OP(gvec_f##FN##0_h, float16_##FN##0, float16) \ | 362 | DO_2OP(gvec_f##FN##0_h, float16_##FN##0, float16) \ |
363 | - DO_2OP(gvec_f##FN##0_s, float32_##FN##0, float32) | 363 | - DO_2OP(gvec_f##FN##0_s, float32_##FN##0, float32) |
364 | + DO_2OP(gvec_f##FN##0_s, float32_##FN##0, float32) \ | 364 | + DO_2OP(gvec_f##FN##0_s, float32_##FN##0, float32) \ |
365 | + DO_2OP(gvec_f##FN##0_d, float64_##FN##0, float64) | 365 | + DO_2OP(gvec_f##FN##0_d, float64_##FN##0, float64) |
366 | 366 | ||
367 | DO_2OP_CMP0(cgt, cgt, FWD) | 367 | DO_2OP_CMP0(cgt, cgt, FWD) |
368 | DO_2OP_CMP0(cge, cge, FWD) | 368 | DO_2OP_CMP0(cge, cge, FWD) |
369 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 369 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
370 | index XXXXXXX..XXXXXXX 100644 | 370 | index XXXXXXX..XXXXXXX 100644 |
371 | --- a/target/arm/tcg/a64.decode | 371 | --- a/target/arm/tcg/a64.decode |
372 | +++ b/target/arm/tcg/a64.decode | 372 | +++ b/target/arm/tcg/a64.decode |
373 | @@ -XXX,XX +XXX,XX @@ UQXTN_s 0111 1110 ..1 00001 01001 0 ..... ..... @rr_e | 373 | @@ -XXX,XX +XXX,XX @@ UQXTN_s 0111 1110 ..1 00001 01001 0 ..... ..... @rr_e |
374 | 374 | ||
375 | FCVTXN_s 0111 1110 011 00001 01101 0 ..... ..... @rr_s | 375 | FCVTXN_s 0111 1110 011 00001 01101 0 ..... ..... @rr_s |
376 | 376 | ||
377 | +FCMGT0_s 0101 1110 111 11000 11001 0 ..... ..... @rr_h | 377 | +FCMGT0_s 0101 1110 111 11000 11001 0 ..... ..... @rr_h |
378 | +FCMGT0_s 0101 1110 1.1 00000 11001 0 ..... ..... @rr_sd | 378 | +FCMGT0_s 0101 1110 1.1 00000 11001 0 ..... ..... @rr_sd |
379 | + | 379 | + |
380 | +FCMGE0_s 0111 1110 111 11000 11001 0 ..... ..... @rr_h | 380 | +FCMGE0_s 0111 1110 111 11000 11001 0 ..... ..... @rr_h |
381 | +FCMGE0_s 0111 1110 1.1 00000 11001 0 ..... ..... @rr_sd | 381 | +FCMGE0_s 0111 1110 1.1 00000 11001 0 ..... ..... @rr_sd |
382 | + | 382 | + |
383 | +FCMEQ0_s 0101 1110 111 11000 11011 0 ..... ..... @rr_h | 383 | +FCMEQ0_s 0101 1110 111 11000 11011 0 ..... ..... @rr_h |
384 | +FCMEQ0_s 0101 1110 1.1 00000 11011 0 ..... ..... @rr_sd | 384 | +FCMEQ0_s 0101 1110 1.1 00000 11011 0 ..... ..... @rr_sd |
385 | + | 385 | + |
386 | +FCMLE0_s 0111 1110 111 11000 11011 0 ..... ..... @rr_h | 386 | +FCMLE0_s 0111 1110 111 11000 11011 0 ..... ..... @rr_h |
387 | +FCMLE0_s 0111 1110 1.1 00000 11011 0 ..... ..... @rr_sd | 387 | +FCMLE0_s 0111 1110 1.1 00000 11011 0 ..... ..... @rr_sd |
388 | + | 388 | + |
389 | +FCMLT0_s 0101 1110 111 11000 11101 0 ..... ..... @rr_h | 389 | +FCMLT0_s 0101 1110 111 11000 11101 0 ..... ..... @rr_h |
390 | +FCMLT0_s 0101 1110 1.1 00000 11101 0 ..... ..... @rr_sd | 390 | +FCMLT0_s 0101 1110 1.1 00000 11101 0 ..... ..... @rr_sd |
391 | + | 391 | + |
392 | @icvt_h . ....... .. ...... ...... rn:5 rd:5 \ | 392 | @icvt_h . ....... .. ...... ...... rn:5 rd:5 \ |
393 | &fcvt sf=0 esz=1 shift=0 | 393 | &fcvt sf=0 esz=1 shift=0 |
394 | @icvt_sd . ....... .. ...... ...... rn:5 rd:5 \ | 394 | @icvt_sd . ....... .. ...... ...... rn:5 rd:5 \ |
395 | @@ -XXX,XX +XXX,XX @@ FCVTAS_vi 0.00 1110 0.1 00001 11001 0 ..... ..... @qrr_sd | 395 | @@ -XXX,XX +XXX,XX @@ FCVTAS_vi 0.00 1110 0.1 00001 11001 0 ..... ..... @qrr_sd |
396 | FCVTAU_vi 0.10 1110 011 11001 11001 0 ..... ..... @qrr_h | 396 | FCVTAU_vi 0.10 1110 011 11001 11001 0 ..... ..... @qrr_h |
397 | FCVTAU_vi 0.10 1110 0.1 00001 11001 0 ..... ..... @qrr_sd | 397 | FCVTAU_vi 0.10 1110 0.1 00001 11001 0 ..... ..... @qrr_sd |
398 | 398 | ||
399 | +FCMGT0_v 0.00 1110 111 11000 11001 0 ..... ..... @qrr_h | 399 | +FCMGT0_v 0.00 1110 111 11000 11001 0 ..... ..... @qrr_h |
400 | +FCMGT0_v 0.00 1110 1.1 00000 11001 0 ..... ..... @qrr_sd | 400 | +FCMGT0_v 0.00 1110 1.1 00000 11001 0 ..... ..... @qrr_sd |
401 | + | 401 | + |
402 | +FCMGE0_v 0.10 1110 111 11000 11001 0 ..... ..... @qrr_h | 402 | +FCMGE0_v 0.10 1110 111 11000 11001 0 ..... ..... @qrr_h |
403 | +FCMGE0_v 0.10 1110 1.1 00000 11001 0 ..... ..... @qrr_sd | 403 | +FCMGE0_v 0.10 1110 1.1 00000 11001 0 ..... ..... @qrr_sd |
404 | + | 404 | + |
405 | +FCMEQ0_v 0.00 1110 111 11000 11011 0 ..... ..... @qrr_h | 405 | +FCMEQ0_v 0.00 1110 111 11000 11011 0 ..... ..... @qrr_h |
406 | +FCMEQ0_v 0.00 1110 1.1 00000 11011 0 ..... ..... @qrr_sd | 406 | +FCMEQ0_v 0.00 1110 1.1 00000 11011 0 ..... ..... @qrr_sd |
407 | + | 407 | + |
408 | +FCMLE0_v 0.10 1110 111 11000 11011 0 ..... ..... @qrr_h | 408 | +FCMLE0_v 0.10 1110 111 11000 11011 0 ..... ..... @qrr_h |
409 | +FCMLE0_v 0.10 1110 1.1 00000 11011 0 ..... ..... @qrr_sd | 409 | +FCMLE0_v 0.10 1110 1.1 00000 11011 0 ..... ..... @qrr_sd |
410 | + | 410 | + |
411 | +FCMLT0_v 0.00 1110 111 11000 11101 0 ..... ..... @qrr_h | 411 | +FCMLT0_v 0.00 1110 111 11000 11101 0 ..... ..... @qrr_h |
412 | +FCMLT0_v 0.00 1110 1.1 00000 11101 0 ..... ..... @qrr_sd | 412 | +FCMLT0_v 0.00 1110 1.1 00000 11101 0 ..... ..... @qrr_sd |
413 | + | 413 | + |
414 | &fcvt_q rd rn esz q shift | 414 | &fcvt_q rd rn esz q shift |
415 | @fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \ | 415 | @fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \ |
416 | &fcvt_q esz=1 shift=%fcvt_f_sh_h | 416 | &fcvt_q esz=1 shift=%fcvt_f_sh_h |
417 | -- | 417 | -- |
418 | 2.43.0 | 418 | 2.43.0 | diff view generated by jsdifflib |
1 | Remove disas_simd_scalar_two_reg_misc and | 1 | Remove disas_simd_scalar_two_reg_misc and |
---|---|---|---|
2 | disas_simd_two_reg_misc_fp16 as these were the | 2 | disas_simd_two_reg_misc_fp16 as these were the |
3 | last insns decoded by those functions. | 3 | last insns decoded by those functions. |
4 | 4 | ||
5 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 5 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
7 | --- | 7 | --- |
8 | target/arm/tcg/translate-a64.c | 329 ++++----------------------------- | 8 | target/arm/tcg/translate-a64.c | 329 ++++----------------------------- |
9 | target/arm/tcg/a64.decode | 15 ++ | 9 | target/arm/tcg/a64.decode | 15 ++ |
10 | 2 files changed, 53 insertions(+), 291 deletions(-) | 10 | 2 files changed, 53 insertions(+), 291 deletions(-) |
11 | 11 | ||
12 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 12 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/arm/tcg/translate-a64.c | 14 | --- a/target/arm/tcg/translate-a64.c |
15 | +++ b/target/arm/tcg/translate-a64.c | 15 | +++ b/target/arm/tcg/translate-a64.c |
16 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FRINT64Z_s, aa64_frint, do_fp1_scalar, a, | 16 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FRINT64Z_s, aa64_frint, do_fp1_scalar, a, |
17 | &f_scalar_frint64, FPROUNDING_ZERO) | 17 | &f_scalar_frint64, FPROUNDING_ZERO) |
18 | TRANS_FEAT(FRINT64X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint64, -1) | 18 | TRANS_FEAT(FRINT64X_s, aa64_frint, do_fp1_scalar, a, &f_scalar_frint64, -1) |
19 | 19 | ||
20 | +static const FPScalar1 f_scalar_frecpe = { | 20 | +static const FPScalar1 f_scalar_frecpe = { |
21 | + gen_helper_recpe_f16, | 21 | + gen_helper_recpe_f16, |
22 | + gen_helper_recpe_f32, | 22 | + gen_helper_recpe_f32, |
23 | + gen_helper_recpe_f64, | 23 | + gen_helper_recpe_f64, |
24 | +}; | 24 | +}; |
25 | +TRANS(FRECPE_s, do_fp1_scalar, a, &f_scalar_frecpe, -1) | 25 | +TRANS(FRECPE_s, do_fp1_scalar, a, &f_scalar_frecpe, -1) |
26 | + | 26 | + |
27 | +static const FPScalar1 f_scalar_frecpx = { | 27 | +static const FPScalar1 f_scalar_frecpx = { |
28 | + gen_helper_frecpx_f16, | 28 | + gen_helper_frecpx_f16, |
29 | + gen_helper_frecpx_f32, | 29 | + gen_helper_frecpx_f32, |
30 | + gen_helper_frecpx_f64, | 30 | + gen_helper_frecpx_f64, |
31 | +}; | 31 | +}; |
32 | +TRANS(FRECPX_s, do_fp1_scalar, a, &f_scalar_frecpx, -1) | 32 | +TRANS(FRECPX_s, do_fp1_scalar, a, &f_scalar_frecpx, -1) |
33 | + | 33 | + |
34 | +static const FPScalar1 f_scalar_frsqrte = { | 34 | +static const FPScalar1 f_scalar_frsqrte = { |
35 | + gen_helper_rsqrte_f16, | 35 | + gen_helper_rsqrte_f16, |
36 | + gen_helper_rsqrte_f32, | 36 | + gen_helper_rsqrte_f32, |
37 | + gen_helper_rsqrte_f64, | 37 | + gen_helper_rsqrte_f64, |
38 | +}; | 38 | +}; |
39 | +TRANS(FRSQRTE_s, do_fp1_scalar, a, &f_scalar_frsqrte, -1) | 39 | +TRANS(FRSQRTE_s, do_fp1_scalar, a, &f_scalar_frsqrte, -1) |
40 | + | 40 | + |
41 | static bool trans_FCVT_s_ds(DisasContext *s, arg_rr *a) | 41 | static bool trans_FCVT_s_ds(DisasContext *s, arg_rr *a) |
42 | { | 42 | { |
43 | if (fp_access_check(s)) { | 43 | if (fp_access_check(s)) { |
44 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_2_ptr * const f_fcle0[] = { | 44 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_2_ptr * const f_fcle0[] = { |
45 | }; | 45 | }; |
46 | TRANS(FCMLE0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcle0) | 46 | TRANS(FCMLE0_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_fcle0) |
47 | 47 | ||
48 | +static gen_helper_gvec_2_ptr * const f_frecpe[] = { | 48 | +static gen_helper_gvec_2_ptr * const f_frecpe[] = { |
49 | + gen_helper_gvec_frecpe_h, | 49 | + gen_helper_gvec_frecpe_h, |
50 | + gen_helper_gvec_frecpe_s, | 50 | + gen_helper_gvec_frecpe_s, |
51 | + gen_helper_gvec_frecpe_d, | 51 | + gen_helper_gvec_frecpe_d, |
52 | +}; | 52 | +}; |
53 | +TRANS(FRECPE_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_frecpe) | 53 | +TRANS(FRECPE_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_frecpe) |
54 | + | 54 | + |
55 | +static gen_helper_gvec_2_ptr * const f_frsqrte[] = { | 55 | +static gen_helper_gvec_2_ptr * const f_frsqrte[] = { |
56 | + gen_helper_gvec_frsqrte_h, | 56 | + gen_helper_gvec_frsqrte_h, |
57 | + gen_helper_gvec_frsqrte_s, | 57 | + gen_helper_gvec_frsqrte_s, |
58 | + gen_helper_gvec_frsqrte_d, | 58 | + gen_helper_gvec_frsqrte_d, |
59 | +}; | 59 | +}; |
60 | +TRANS(FRSQRTE_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_frsqrte) | 60 | +TRANS(FRSQRTE_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_frsqrte) |
61 | + | 61 | + |
62 | static void handle_2misc_reciprocal(DisasContext *s, int opcode, | 62 | static void handle_2misc_reciprocal(DisasContext *s, int opcode, |
63 | bool is_scalar, bool is_u, bool is_q, | 63 | bool is_scalar, bool is_u, bool is_q, |
64 | int size, int rn, int rd) | 64 | int size, int rn, int rd) |
65 | { | 65 | { |
66 | bool is_double = (size == 3); | 66 | bool is_double = (size == 3); |
67 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 67 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
68 | 68 | ||
69 | if (is_double) { | 69 | if (is_double) { |
70 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); | 70 | - TCGv_i64 tcg_op = tcg_temp_new_i64(); |
71 | - TCGv_i64 tcg_res = tcg_temp_new_i64(); | 71 | - TCGv_i64 tcg_res = tcg_temp_new_i64(); |
72 | - int pass; | 72 | - int pass; |
73 | - | 73 | - |
74 | - for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) { | 74 | - for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) { |
75 | - read_vec_element(s, tcg_op, rn, pass, MO_64); | 75 | - read_vec_element(s, tcg_op, rn, pass, MO_64); |
76 | - switch (opcode) { | 76 | - switch (opcode) { |
77 | - case 0x3d: /* FRECPE */ | 77 | - case 0x3d: /* FRECPE */ |
78 | - gen_helper_recpe_f64(tcg_res, tcg_op, fpst); | 78 | - gen_helper_recpe_f64(tcg_res, tcg_op, fpst); |
79 | - break; | 79 | - break; |
80 | - case 0x3f: /* FRECPX */ | 80 | - case 0x3f: /* FRECPX */ |
81 | - gen_helper_frecpx_f64(tcg_res, tcg_op, fpst); | 81 | - gen_helper_frecpx_f64(tcg_res, tcg_op, fpst); |
82 | - break; | 82 | - break; |
83 | - case 0x7d: /* FRSQRTE */ | 83 | - case 0x7d: /* FRSQRTE */ |
84 | - gen_helper_rsqrte_f64(tcg_res, tcg_op, fpst); | 84 | - gen_helper_rsqrte_f64(tcg_res, tcg_op, fpst); |
85 | - break; | 85 | - break; |
86 | - default: | 86 | - default: |
87 | - g_assert_not_reached(); | 87 | - g_assert_not_reached(); |
88 | - } | 88 | - } |
89 | - write_vec_element(s, tcg_res, rd, pass, MO_64); | 89 | - write_vec_element(s, tcg_res, rd, pass, MO_64); |
90 | - } | 90 | - } |
91 | - clear_vec_high(s, !is_scalar, rd); | 91 | - clear_vec_high(s, !is_scalar, rd); |
92 | + g_assert_not_reached(); | 92 | + g_assert_not_reached(); |
93 | } else { | 93 | } else { |
94 | TCGv_i32 tcg_op = tcg_temp_new_i32(); | 94 | TCGv_i32 tcg_op = tcg_temp_new_i32(); |
95 | TCGv_i32 tcg_res = tcg_temp_new_i32(); | 95 | TCGv_i32 tcg_res = tcg_temp_new_i32(); |
96 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode, | 96 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode, |
97 | gen_helper_recpe_u32(tcg_res, tcg_op); | 97 | gen_helper_recpe_u32(tcg_res, tcg_op); |
98 | break; | 98 | break; |
99 | case 0x3d: /* FRECPE */ | 99 | case 0x3d: /* FRECPE */ |
100 | - gen_helper_recpe_f32(tcg_res, tcg_op, fpst); | 100 | - gen_helper_recpe_f32(tcg_res, tcg_op, fpst); |
101 | - break; | 101 | - break; |
102 | case 0x3f: /* FRECPX */ | 102 | case 0x3f: /* FRECPX */ |
103 | - gen_helper_frecpx_f32(tcg_res, tcg_op, fpst); | 103 | - gen_helper_frecpx_f32(tcg_res, tcg_op, fpst); |
104 | - break; | 104 | - break; |
105 | case 0x7d: /* FRSQRTE */ | 105 | case 0x7d: /* FRSQRTE */ |
106 | - gen_helper_rsqrte_f32(tcg_res, tcg_op, fpst); | 106 | - gen_helper_rsqrte_f32(tcg_res, tcg_op, fpst); |
107 | - break; | 107 | - break; |
108 | default: | 108 | default: |
109 | g_assert_not_reached(); | 109 | g_assert_not_reached(); |
110 | } | 110 | } |
111 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode, | 111 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode, |
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | -/* AdvSIMD scalar two reg misc | 115 | -/* AdvSIMD scalar two reg misc |
116 | - * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 | 116 | - * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 |
117 | - * +-----+---+-----------+------+-----------+--------+-----+------+------+ | 117 | - * +-----+---+-----------+------+-----------+--------+-----+------+------+ |
118 | - * | 0 1 | U | 1 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 | Rn | Rd | | 118 | - * | 0 1 | U | 1 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 | Rn | Rd | |
119 | - * +-----+---+-----------+------+-----------+--------+-----+------+------+ | 119 | - * +-----+---+-----------+------+-----------+--------+-----+------+------+ |
120 | - */ | 120 | - */ |
121 | -static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) | 121 | -static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) |
122 | -{ | 122 | -{ |
123 | - int rd = extract32(insn, 0, 5); | 123 | - int rd = extract32(insn, 0, 5); |
124 | - int rn = extract32(insn, 5, 5); | 124 | - int rn = extract32(insn, 5, 5); |
125 | - int opcode = extract32(insn, 12, 5); | 125 | - int opcode = extract32(insn, 12, 5); |
126 | - int size = extract32(insn, 22, 2); | 126 | - int size = extract32(insn, 22, 2); |
127 | - bool u = extract32(insn, 29, 1); | 127 | - bool u = extract32(insn, 29, 1); |
128 | - | 128 | - |
129 | - switch (opcode) { | 129 | - switch (opcode) { |
130 | - case 0xc ... 0xf: | 130 | - case 0xc ... 0xf: |
131 | - case 0x16 ... 0x1d: | 131 | - case 0x16 ... 0x1d: |
132 | - case 0x1f: | 132 | - case 0x1f: |
133 | - /* Floating point: U, size[1] and opcode indicate operation; | 133 | - /* Floating point: U, size[1] and opcode indicate operation; |
134 | - * size[0] indicates single or double precision. | 134 | - * size[0] indicates single or double precision. |
135 | - */ | 135 | - */ |
136 | - opcode |= (extract32(size, 1, 1) << 5) | (u << 6); | 136 | - opcode |= (extract32(size, 1, 1) << 5) | (u << 6); |
137 | - size = extract32(size, 0, 1) ? 3 : 2; | 137 | - size = extract32(size, 0, 1) ? 3 : 2; |
138 | - switch (opcode) { | 138 | - switch (opcode) { |
139 | - case 0x3d: /* FRECPE */ | 139 | - case 0x3d: /* FRECPE */ |
140 | - case 0x3f: /* FRECPX */ | 140 | - case 0x3f: /* FRECPX */ |
141 | - case 0x7d: /* FRSQRTE */ | 141 | - case 0x7d: /* FRSQRTE */ |
142 | - if (!fp_access_check(s)) { | 142 | - if (!fp_access_check(s)) { |
143 | - return; | 143 | - return; |
144 | - } | 144 | - } |
145 | - handle_2misc_reciprocal(s, opcode, true, u, true, size, rn, rd); | 145 | - handle_2misc_reciprocal(s, opcode, true, u, true, size, rn, rd); |
146 | - return; | 146 | - return; |
147 | - case 0x1a: /* FCVTNS */ | 147 | - case 0x1a: /* FCVTNS */ |
148 | - case 0x1b: /* FCVTMS */ | 148 | - case 0x1b: /* FCVTMS */ |
149 | - case 0x3a: /* FCVTPS */ | 149 | - case 0x3a: /* FCVTPS */ |
150 | - case 0x3b: /* FCVTZS */ | 150 | - case 0x3b: /* FCVTZS */ |
151 | - case 0x5a: /* FCVTNU */ | 151 | - case 0x5a: /* FCVTNU */ |
152 | - case 0x5b: /* FCVTMU */ | 152 | - case 0x5b: /* FCVTMU */ |
153 | - case 0x7a: /* FCVTPU */ | 153 | - case 0x7a: /* FCVTPU */ |
154 | - case 0x7b: /* FCVTZU */ | 154 | - case 0x7b: /* FCVTZU */ |
155 | - case 0x1c: /* FCVTAS */ | 155 | - case 0x1c: /* FCVTAS */ |
156 | - case 0x5c: /* FCVTAU */ | 156 | - case 0x5c: /* FCVTAU */ |
157 | - case 0x56: /* FCVTXN, FCVTXN2 */ | 157 | - case 0x56: /* FCVTXN, FCVTXN2 */ |
158 | - case 0x1d: /* SCVTF */ | 158 | - case 0x1d: /* SCVTF */ |
159 | - case 0x5d: /* UCVTF */ | 159 | - case 0x5d: /* UCVTF */ |
160 | - case 0x2c: /* FCMGT (zero) */ | 160 | - case 0x2c: /* FCMGT (zero) */ |
161 | - case 0x2d: /* FCMEQ (zero) */ | 161 | - case 0x2d: /* FCMEQ (zero) */ |
162 | - case 0x2e: /* FCMLT (zero) */ | 162 | - case 0x2e: /* FCMLT (zero) */ |
163 | - case 0x6c: /* FCMGE (zero) */ | 163 | - case 0x6c: /* FCMGE (zero) */ |
164 | - case 0x6d: /* FCMLE (zero) */ | 164 | - case 0x6d: /* FCMLE (zero) */ |
165 | - default: | 165 | - default: |
166 | - unallocated_encoding(s); | 166 | - unallocated_encoding(s); |
167 | - return; | 167 | - return; |
168 | - } | 168 | - } |
169 | - break; | 169 | - break; |
170 | - default: | 170 | - default: |
171 | - case 0x3: /* USQADD / SUQADD */ | 171 | - case 0x3: /* USQADD / SUQADD */ |
172 | - case 0x7: /* SQABS / SQNEG */ | 172 | - case 0x7: /* SQABS / SQNEG */ |
173 | - case 0x8: /* CMGT, CMGE */ | 173 | - case 0x8: /* CMGT, CMGE */ |
174 | - case 0x9: /* CMEQ, CMLE */ | 174 | - case 0x9: /* CMEQ, CMLE */ |
175 | - case 0xa: /* CMLT */ | 175 | - case 0xa: /* CMLT */ |
176 | - case 0xb: /* ABS, NEG */ | 176 | - case 0xb: /* ABS, NEG */ |
177 | - case 0x12: /* SQXTUN */ | 177 | - case 0x12: /* SQXTUN */ |
178 | - case 0x14: /* SQXTN, UQXTN */ | 178 | - case 0x14: /* SQXTN, UQXTN */ |
179 | - unallocated_encoding(s); | 179 | - unallocated_encoding(s); |
180 | - return; | 180 | - return; |
181 | - } | 181 | - } |
182 | - g_assert_not_reached(); | 182 | - g_assert_not_reached(); |
183 | -} | 183 | -} |
184 | - | 184 | - |
185 | static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, | 185 | static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, |
186 | int size, int rn, int rd) | 186 | int size, int rn, int rd) |
187 | { | 187 | { |
188 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 188 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
189 | unallocated_encoding(s); | 189 | unallocated_encoding(s); |
190 | return; | 190 | return; |
191 | } | 191 | } |
192 | - /* fall through */ | 192 | - /* fall through */ |
193 | - case 0x3d: /* FRECPE */ | 193 | - case 0x3d: /* FRECPE */ |
194 | - case 0x7d: /* FRSQRTE */ | 194 | - case 0x7d: /* FRSQRTE */ |
195 | - if (size == 3 && !is_q) { | 195 | - if (size == 3 && !is_q) { |
196 | - unallocated_encoding(s); | 196 | - unallocated_encoding(s); |
197 | - return; | 197 | - return; |
198 | - } | 198 | - } |
199 | if (!fp_access_check(s)) { | 199 | if (!fp_access_check(s)) { |
200 | return; | 200 | return; |
201 | } | 201 | } |
202 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 202 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
203 | case 0x2e: /* FCMLT (zero) */ | 203 | case 0x2e: /* FCMLT (zero) */ |
204 | case 0x6c: /* FCMGE (zero) */ | 204 | case 0x6c: /* FCMGE (zero) */ |
205 | case 0x6d: /* FCMLE (zero) */ | 205 | case 0x6d: /* FCMLE (zero) */ |
206 | + case 0x3d: /* FRECPE */ | 206 | + case 0x3d: /* FRECPE */ |
207 | + case 0x7d: /* FRSQRTE */ | 207 | + case 0x7d: /* FRSQRTE */ |
208 | unallocated_encoding(s); | 208 | unallocated_encoding(s); |
209 | return; | 209 | return; |
210 | } | 210 | } |
211 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 211 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | -/* AdvSIMD [scalar] two register miscellaneous (FP16) | 215 | -/* AdvSIMD [scalar] two register miscellaneous (FP16) |
216 | - * | 216 | - * |
217 | - * 31 30 29 28 27 24 23 22 21 17 16 12 11 10 9 5 4 0 | 217 | - * 31 30 29 28 27 24 23 22 21 17 16 12 11 10 9 5 4 0 |
218 | - * +---+---+---+---+---------+---+-------------+--------+-----+------+------+ | 218 | - * +---+---+---+---+---------+---+-------------+--------+-----+------+------+ |
219 | - * | 0 | Q | U | S | 1 1 1 0 | a | 1 1 1 1 0 0 | opcode | 1 0 | Rn | Rd | | 219 | - * | 0 | Q | U | S | 1 1 1 0 | a | 1 1 1 1 0 0 | opcode | 1 0 | Rn | Rd | |
220 | - * +---+---+---+---+---------+---+-------------+--------+-----+------+------+ | 220 | - * +---+---+---+---+---------+---+-------------+--------+-----+------+------+ |
221 | - * mask: 1000 1111 0111 1110 0000 1100 0000 0000 0x8f7e 0c00 | 221 | - * mask: 1000 1111 0111 1110 0000 1100 0000 0000 0x8f7e 0c00 |
222 | - * val: 0000 1110 0111 1000 0000 1000 0000 0000 0x0e78 0800 | 222 | - * val: 0000 1110 0111 1000 0000 1000 0000 0000 0x0e78 0800 |
223 | - * | 223 | - * |
224 | - * This actually covers two groups where scalar access is governed by | 224 | - * This actually covers two groups where scalar access is governed by |
225 | - * bit 28. A bunch of the instructions (float to integral) only exist | 225 | - * bit 28. A bunch of the instructions (float to integral) only exist |
226 | - * in the vector form and are un-allocated for the scalar decode. Also | 226 | - * in the vector form and are un-allocated for the scalar decode. Also |
227 | - * in the scalar decode Q is always 1. | 227 | - * in the scalar decode Q is always 1. |
228 | - */ | 228 | - */ |
229 | -static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 229 | -static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
230 | -{ | 230 | -{ |
231 | - int fpop, opcode, a, u; | 231 | - int fpop, opcode, a, u; |
232 | - int rn, rd; | 232 | - int rn, rd; |
233 | - bool is_q; | 233 | - bool is_q; |
234 | - bool is_scalar; | 234 | - bool is_scalar; |
235 | - | 235 | - |
236 | - int pass; | 236 | - int pass; |
237 | - TCGv_i32 tcg_rmode = NULL; | 237 | - TCGv_i32 tcg_rmode = NULL; |
238 | - TCGv_ptr tcg_fpstatus = NULL; | 238 | - TCGv_ptr tcg_fpstatus = NULL; |
239 | - bool need_fpst = true; | 239 | - bool need_fpst = true; |
240 | - int rmode = -1; | 240 | - int rmode = -1; |
241 | - | 241 | - |
242 | - if (!dc_isar_feature(aa64_fp16, s)) { | 242 | - if (!dc_isar_feature(aa64_fp16, s)) { |
243 | - unallocated_encoding(s); | 243 | - unallocated_encoding(s); |
244 | - return; | 244 | - return; |
245 | - } | 245 | - } |
246 | - | 246 | - |
247 | - rd = extract32(insn, 0, 5); | 247 | - rd = extract32(insn, 0, 5); |
248 | - rn = extract32(insn, 5, 5); | 248 | - rn = extract32(insn, 5, 5); |
249 | - | 249 | - |
250 | - a = extract32(insn, 23, 1); | 250 | - a = extract32(insn, 23, 1); |
251 | - u = extract32(insn, 29, 1); | 251 | - u = extract32(insn, 29, 1); |
252 | - is_scalar = extract32(insn, 28, 1); | 252 | - is_scalar = extract32(insn, 28, 1); |
253 | - is_q = extract32(insn, 30, 1); | 253 | - is_q = extract32(insn, 30, 1); |
254 | - | 254 | - |
255 | - opcode = extract32(insn, 12, 5); | 255 | - opcode = extract32(insn, 12, 5); |
256 | - fpop = deposit32(opcode, 5, 1, a); | 256 | - fpop = deposit32(opcode, 5, 1, a); |
257 | - fpop = deposit32(fpop, 6, 1, u); | 257 | - fpop = deposit32(fpop, 6, 1, u); |
258 | - | 258 | - |
259 | - switch (fpop) { | 259 | - switch (fpop) { |
260 | - case 0x3d: /* FRECPE */ | 260 | - case 0x3d: /* FRECPE */ |
261 | - case 0x3f: /* FRECPX */ | 261 | - case 0x3f: /* FRECPX */ |
262 | - break; | 262 | - break; |
263 | - case 0x7d: /* FRSQRTE */ | 263 | - case 0x7d: /* FRSQRTE */ |
264 | - break; | 264 | - break; |
265 | - default: | 265 | - default: |
266 | - case 0x2f: /* FABS */ | 266 | - case 0x2f: /* FABS */ |
267 | - case 0x6f: /* FNEG */ | 267 | - case 0x6f: /* FNEG */ |
268 | - case 0x7f: /* FSQRT (vector) */ | 268 | - case 0x7f: /* FSQRT (vector) */ |
269 | - case 0x18: /* FRINTN */ | 269 | - case 0x18: /* FRINTN */ |
270 | - case 0x19: /* FRINTM */ | 270 | - case 0x19: /* FRINTM */ |
271 | - case 0x38: /* FRINTP */ | 271 | - case 0x38: /* FRINTP */ |
272 | - case 0x39: /* FRINTZ */ | 272 | - case 0x39: /* FRINTZ */ |
273 | - case 0x58: /* FRINTA */ | 273 | - case 0x58: /* FRINTA */ |
274 | - case 0x59: /* FRINTX */ | 274 | - case 0x59: /* FRINTX */ |
275 | - case 0x79: /* FRINTI */ | 275 | - case 0x79: /* FRINTI */ |
276 | - case 0x1d: /* SCVTF */ | 276 | - case 0x1d: /* SCVTF */ |
277 | - case 0x5d: /* UCVTF */ | 277 | - case 0x5d: /* UCVTF */ |
278 | - case 0x1a: /* FCVTNS */ | 278 | - case 0x1a: /* FCVTNS */ |
279 | - case 0x1b: /* FCVTMS */ | 279 | - case 0x1b: /* FCVTMS */ |
280 | - case 0x1c: /* FCVTAS */ | 280 | - case 0x1c: /* FCVTAS */ |
281 | - case 0x3a: /* FCVTPS */ | 281 | - case 0x3a: /* FCVTPS */ |
282 | - case 0x3b: /* FCVTZS */ | 282 | - case 0x3b: /* FCVTZS */ |
283 | - case 0x5a: /* FCVTNU */ | 283 | - case 0x5a: /* FCVTNU */ |
284 | - case 0x5b: /* FCVTMU */ | 284 | - case 0x5b: /* FCVTMU */ |
285 | - case 0x5c: /* FCVTAU */ | 285 | - case 0x5c: /* FCVTAU */ |
286 | - case 0x7a: /* FCVTPU */ | 286 | - case 0x7a: /* FCVTPU */ |
287 | - case 0x7b: /* FCVTZU */ | 287 | - case 0x7b: /* FCVTZU */ |
288 | - case 0x2c: /* FCMGT (zero) */ | 288 | - case 0x2c: /* FCMGT (zero) */ |
289 | - case 0x2d: /* FCMEQ (zero) */ | 289 | - case 0x2d: /* FCMEQ (zero) */ |
290 | - case 0x2e: /* FCMLT (zero) */ | 290 | - case 0x2e: /* FCMLT (zero) */ |
291 | - case 0x6c: /* FCMGE (zero) */ | 291 | - case 0x6c: /* FCMGE (zero) */ |
292 | - case 0x6d: /* FCMLE (zero) */ | 292 | - case 0x6d: /* FCMLE (zero) */ |
293 | - unallocated_encoding(s); | 293 | - unallocated_encoding(s); |
294 | - return; | 294 | - return; |
295 | - } | 295 | - } |
296 | - | 296 | - |
297 | - | 297 | - |
298 | - /* Check additional constraints for the scalar encoding */ | 298 | - /* Check additional constraints for the scalar encoding */ |
299 | - if (is_scalar) { | 299 | - if (is_scalar) { |
300 | - if (!is_q) { | 300 | - if (!is_q) { |
301 | - unallocated_encoding(s); | 301 | - unallocated_encoding(s); |
302 | - return; | 302 | - return; |
303 | - } | 303 | - } |
304 | - } | 304 | - } |
305 | - | 305 | - |
306 | - if (!fp_access_check(s)) { | 306 | - if (!fp_access_check(s)) { |
307 | - return; | 307 | - return; |
308 | - } | 308 | - } |
309 | - | 309 | - |
310 | - if (rmode >= 0 || need_fpst) { | 310 | - if (rmode >= 0 || need_fpst) { |
311 | - tcg_fpstatus = fpstatus_ptr(FPST_FPCR_F16); | 311 | - tcg_fpstatus = fpstatus_ptr(FPST_FPCR_F16); |
312 | - } | 312 | - } |
313 | - | 313 | - |
314 | - if (rmode >= 0) { | 314 | - if (rmode >= 0) { |
315 | - tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); | 315 | - tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); |
316 | - } | 316 | - } |
317 | - | 317 | - |
318 | - if (is_scalar) { | 318 | - if (is_scalar) { |
319 | - TCGv_i32 tcg_op = read_fp_hreg(s, rn); | 319 | - TCGv_i32 tcg_op = read_fp_hreg(s, rn); |
320 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); | 320 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); |
321 | - | 321 | - |
322 | - switch (fpop) { | 322 | - switch (fpop) { |
323 | - case 0x3d: /* FRECPE */ | 323 | - case 0x3d: /* FRECPE */ |
324 | - gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus); | 324 | - gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus); |
325 | - break; | 325 | - break; |
326 | - case 0x3f: /* FRECPX */ | 326 | - case 0x3f: /* FRECPX */ |
327 | - gen_helper_frecpx_f16(tcg_res, tcg_op, tcg_fpstatus); | 327 | - gen_helper_frecpx_f16(tcg_res, tcg_op, tcg_fpstatus); |
328 | - break; | 328 | - break; |
329 | - case 0x7d: /* FRSQRTE */ | 329 | - case 0x7d: /* FRSQRTE */ |
330 | - gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); | 330 | - gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); |
331 | - break; | 331 | - break; |
332 | - default: | 332 | - default: |
333 | - case 0x1a: /* FCVTNS */ | 333 | - case 0x1a: /* FCVTNS */ |
334 | - case 0x1b: /* FCVTMS */ | 334 | - case 0x1b: /* FCVTMS */ |
335 | - case 0x1c: /* FCVTAS */ | 335 | - case 0x1c: /* FCVTAS */ |
336 | - case 0x3a: /* FCVTPS */ | 336 | - case 0x3a: /* FCVTPS */ |
337 | - case 0x3b: /* FCVTZS */ | 337 | - case 0x3b: /* FCVTZS */ |
338 | - case 0x5a: /* FCVTNU */ | 338 | - case 0x5a: /* FCVTNU */ |
339 | - case 0x5b: /* FCVTMU */ | 339 | - case 0x5b: /* FCVTMU */ |
340 | - case 0x5c: /* FCVTAU */ | 340 | - case 0x5c: /* FCVTAU */ |
341 | - case 0x7a: /* FCVTPU */ | 341 | - case 0x7a: /* FCVTPU */ |
342 | - case 0x7b: /* FCVTZU */ | 342 | - case 0x7b: /* FCVTZU */ |
343 | - g_assert_not_reached(); | 343 | - g_assert_not_reached(); |
344 | - } | 344 | - } |
345 | - | 345 | - |
346 | - /* limit any sign extension going on */ | 346 | - /* limit any sign extension going on */ |
347 | - tcg_gen_andi_i32(tcg_res, tcg_res, 0xffff); | 347 | - tcg_gen_andi_i32(tcg_res, tcg_res, 0xffff); |
348 | - write_fp_sreg(s, rd, tcg_res); | 348 | - write_fp_sreg(s, rd, tcg_res); |
349 | - } else { | 349 | - } else { |
350 | - for (pass = 0; pass < (is_q ? 8 : 4); pass++) { | 350 | - for (pass = 0; pass < (is_q ? 8 : 4); pass++) { |
351 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); | 351 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); |
352 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); | 352 | - TCGv_i32 tcg_res = tcg_temp_new_i32(); |
353 | - | 353 | - |
354 | - read_vec_element_i32(s, tcg_op, rn, pass, MO_16); | 354 | - read_vec_element_i32(s, tcg_op, rn, pass, MO_16); |
355 | - | 355 | - |
356 | - switch (fpop) { | 356 | - switch (fpop) { |
357 | - case 0x3d: /* FRECPE */ | 357 | - case 0x3d: /* FRECPE */ |
358 | - gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus); | 358 | - gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus); |
359 | - break; | 359 | - break; |
360 | - case 0x7d: /* FRSQRTE */ | 360 | - case 0x7d: /* FRSQRTE */ |
361 | - gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); | 361 | - gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus); |
362 | - break; | 362 | - break; |
363 | - default: | 363 | - default: |
364 | - case 0x2f: /* FABS */ | 364 | - case 0x2f: /* FABS */ |
365 | - case 0x6f: /* FNEG */ | 365 | - case 0x6f: /* FNEG */ |
366 | - case 0x7f: /* FSQRT */ | 366 | - case 0x7f: /* FSQRT */ |
367 | - case 0x18: /* FRINTN */ | 367 | - case 0x18: /* FRINTN */ |
368 | - case 0x19: /* FRINTM */ | 368 | - case 0x19: /* FRINTM */ |
369 | - case 0x38: /* FRINTP */ | 369 | - case 0x38: /* FRINTP */ |
370 | - case 0x39: /* FRINTZ */ | 370 | - case 0x39: /* FRINTZ */ |
371 | - case 0x58: /* FRINTA */ | 371 | - case 0x58: /* FRINTA */ |
372 | - case 0x79: /* FRINTI */ | 372 | - case 0x79: /* FRINTI */ |
373 | - case 0x59: /* FRINTX */ | 373 | - case 0x59: /* FRINTX */ |
374 | - case 0x1a: /* FCVTNS */ | 374 | - case 0x1a: /* FCVTNS */ |
375 | - case 0x1b: /* FCVTMS */ | 375 | - case 0x1b: /* FCVTMS */ |
376 | - case 0x1c: /* FCVTAS */ | 376 | - case 0x1c: /* FCVTAS */ |
377 | - case 0x3a: /* FCVTPS */ | 377 | - case 0x3a: /* FCVTPS */ |
378 | - case 0x3b: /* FCVTZS */ | 378 | - case 0x3b: /* FCVTZS */ |
379 | - case 0x5a: /* FCVTNU */ | 379 | - case 0x5a: /* FCVTNU */ |
380 | - case 0x5b: /* FCVTMU */ | 380 | - case 0x5b: /* FCVTMU */ |
381 | - case 0x5c: /* FCVTAU */ | 381 | - case 0x5c: /* FCVTAU */ |
382 | - case 0x7a: /* FCVTPU */ | 382 | - case 0x7a: /* FCVTPU */ |
383 | - case 0x7b: /* FCVTZU */ | 383 | - case 0x7b: /* FCVTZU */ |
384 | - g_assert_not_reached(); | 384 | - g_assert_not_reached(); |
385 | - } | 385 | - } |
386 | - | 386 | - |
387 | - write_vec_element_i32(s, tcg_res, rd, pass, MO_16); | 387 | - write_vec_element_i32(s, tcg_res, rd, pass, MO_16); |
388 | - } | 388 | - } |
389 | - | 389 | - |
390 | - clear_vec_high(s, is_q, rd); | 390 | - clear_vec_high(s, is_q, rd); |
391 | - } | 391 | - } |
392 | - | 392 | - |
393 | - if (tcg_rmode) { | 393 | - if (tcg_rmode) { |
394 | - gen_restore_rmode(tcg_rmode, tcg_fpstatus); | 394 | - gen_restore_rmode(tcg_rmode, tcg_fpstatus); |
395 | - } | 395 | - } |
396 | -} | 396 | -} |
397 | - | 397 | - |
398 | /* C3.6 Data processing - SIMD, inc Crypto | 398 | /* C3.6 Data processing - SIMD, inc Crypto |
399 | * | 399 | * |
400 | * As the decode gets a little complex we are using a table based | 400 | * As the decode gets a little complex we are using a table based |
401 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) | 401 | @@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn) |
402 | static const AArch64DecodeTable data_proc_simd[] = { | 402 | static const AArch64DecodeTable data_proc_simd[] = { |
403 | /* pattern , mask , fn */ | 403 | /* pattern , mask , fn */ |
404 | { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc }, | 404 | { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc }, |
405 | - { 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc }, | 405 | - { 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc }, |
406 | - { 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 }, | 406 | - { 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 }, |
407 | { 0x00000000, 0x00000000, NULL } | 407 | { 0x00000000, 0x00000000, NULL } |
408 | }; | 408 | }; |
409 | 409 | ||
410 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 410 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
411 | index XXXXXXX..XXXXXXX 100644 | 411 | index XXXXXXX..XXXXXXX 100644 |
412 | --- a/target/arm/tcg/a64.decode | 412 | --- a/target/arm/tcg/a64.decode |
413 | +++ b/target/arm/tcg/a64.decode | 413 | +++ b/target/arm/tcg/a64.decode |
414 | @@ -XXX,XX +XXX,XX @@ FCMLE0_s 0111 1110 1.1 00000 11011 0 ..... ..... @rr_sd | 414 | @@ -XXX,XX +XXX,XX @@ FCMLE0_s 0111 1110 1.1 00000 11011 0 ..... ..... @rr_sd |
415 | FCMLT0_s 0101 1110 111 11000 11101 0 ..... ..... @rr_h | 415 | FCMLT0_s 0101 1110 111 11000 11101 0 ..... ..... @rr_h |
416 | FCMLT0_s 0101 1110 1.1 00000 11101 0 ..... ..... @rr_sd | 416 | FCMLT0_s 0101 1110 1.1 00000 11101 0 ..... ..... @rr_sd |
417 | 417 | ||
418 | +FRECPE_s 0101 1110 111 11001 11011 0 ..... ..... @rr_h | 418 | +FRECPE_s 0101 1110 111 11001 11011 0 ..... ..... @rr_h |
419 | +FRECPE_s 0101 1110 1.1 00001 11011 0 ..... ..... @rr_sd | 419 | +FRECPE_s 0101 1110 1.1 00001 11011 0 ..... ..... @rr_sd |
420 | + | 420 | + |
421 | +FRECPX_s 0101 1110 111 11001 11111 0 ..... ..... @rr_h | 421 | +FRECPX_s 0101 1110 111 11001 11111 0 ..... ..... @rr_h |
422 | +FRECPX_s 0101 1110 1.1 00001 11111 0 ..... ..... @rr_sd | 422 | +FRECPX_s 0101 1110 1.1 00001 11111 0 ..... ..... @rr_sd |
423 | + | 423 | + |
424 | +FRSQRTE_s 0111 1110 111 11001 11011 0 ..... ..... @rr_h | 424 | +FRSQRTE_s 0111 1110 111 11001 11011 0 ..... ..... @rr_h |
425 | +FRSQRTE_s 0111 1110 1.1 00001 11011 0 ..... ..... @rr_sd | 425 | +FRSQRTE_s 0111 1110 1.1 00001 11011 0 ..... ..... @rr_sd |
426 | + | 426 | + |
427 | @icvt_h . ....... .. ...... ...... rn:5 rd:5 \ | 427 | @icvt_h . ....... .. ...... ...... rn:5 rd:5 \ |
428 | &fcvt sf=0 esz=1 shift=0 | 428 | &fcvt sf=0 esz=1 shift=0 |
429 | @icvt_sd . ....... .. ...... ...... rn:5 rd:5 \ | 429 | @icvt_sd . ....... .. ...... ...... rn:5 rd:5 \ |
430 | @@ -XXX,XX +XXX,XX @@ FCMLE0_v 0.10 1110 1.1 00000 11011 0 ..... ..... @qrr_sd | 430 | @@ -XXX,XX +XXX,XX @@ FCMLE0_v 0.10 1110 1.1 00000 11011 0 ..... ..... @qrr_sd |
431 | FCMLT0_v 0.00 1110 111 11000 11101 0 ..... ..... @qrr_h | 431 | FCMLT0_v 0.00 1110 111 11000 11101 0 ..... ..... @qrr_h |
432 | FCMLT0_v 0.00 1110 1.1 00000 11101 0 ..... ..... @qrr_sd | 432 | FCMLT0_v 0.00 1110 1.1 00000 11101 0 ..... ..... @qrr_sd |
433 | 433 | ||
434 | +FRECPE_v 0.00 1110 111 11001 11011 0 ..... ..... @qrr_h | 434 | +FRECPE_v 0.00 1110 111 11001 11011 0 ..... ..... @qrr_h |
435 | +FRECPE_v 0.00 1110 1.1 00001 11011 0 ..... ..... @qrr_sd | 435 | +FRECPE_v 0.00 1110 1.1 00001 11011 0 ..... ..... @qrr_sd |
436 | + | 436 | + |
437 | +FRSQRTE_v 0.10 1110 111 11001 11011 0 ..... ..... @qrr_h | 437 | +FRSQRTE_v 0.10 1110 111 11001 11011 0 ..... ..... @qrr_h |
438 | +FRSQRTE_v 0.10 1110 1.1 00001 11011 0 ..... ..... @qrr_sd | 438 | +FRSQRTE_v 0.10 1110 1.1 00001 11011 0 ..... ..... @qrr_sd |
439 | + | 439 | + |
440 | &fcvt_q rd rn esz q shift | 440 | &fcvt_q rd rn esz q shift |
441 | @fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \ | 441 | @fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \ |
442 | &fcvt_q esz=1 shift=%fcvt_f_sh_h | 442 | &fcvt_q esz=1 shift=%fcvt_f_sh_h |
443 | -- | 443 | -- |
444 | 2.43.0 | 444 | 2.43.0 | diff view generated by jsdifflib |
1 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
---|---|---|---|
1 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 2 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
2 | --- | 3 | --- |
3 | target/arm/helper.h | 3 +++ | 4 | target/arm/helper.h | 3 +++ |
4 | target/arm/tcg/translate.h | 5 +++++ | 5 | target/arm/tcg/translate.h | 5 +++++ |
5 | target/arm/tcg/gengvec.c | 16 ++++++++++++++++ | 6 | target/arm/tcg/gengvec.c | 16 ++++++++++++++++ |
... | ... | diff view generated by jsdifflib |
1 | Remove handle_2misc_reciprocal as these were the last | 1 | Remove handle_2misc_reciprocal as these were the last |
---|---|---|---|
2 | insns decoded by that function. | 2 | insns decoded by that function. |
3 | 3 | ||
4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
4 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
5 | --- | 6 | --- |
6 | target/arm/tcg/translate-a64.c | 139 ++------------------------------- | 7 | target/arm/tcg/translate-a64.c | 139 ++------------------------------- |
7 | target/arm/tcg/a64.decode | 3 + | 8 | target/arm/tcg/a64.decode | 3 + |
8 | 2 files changed, 8 insertions(+), 134 deletions(-) | 9 | 2 files changed, 8 insertions(+), 134 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Remove lookup_disas_fn, handle_2misc_widening, | 1 | Remove lookup_disas_fn, handle_2misc_widening, |
---|---|---|---|
2 | disas_simd_two_reg_misc, disas_data_proc_simd, | 2 | disas_simd_two_reg_misc, disas_data_proc_simd, |
3 | disas_data_proc_simd_fp, disas_a64_legacy, as | 3 | disas_data_proc_simd_fp, disas_a64_legacy, as |
4 | this is the final insn to be converted. | 4 | this is the final insn to be converted. |
5 | 5 | ||
6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
7 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 7 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
8 | --- | 8 | --- |
9 | target/arm/tcg/translate-a64.c | 202 +++------------------------------ | 9 | target/arm/tcg/translate-a64.c | 202 +++------------------------------ |
10 | target/arm/tcg/a64.decode | 2 + | 10 | target/arm/tcg/a64.decode | 2 + |
11 | 2 files changed, 18 insertions(+), 186 deletions(-) | 11 | 2 files changed, 18 insertions(+), 186 deletions(-) |
12 | 12 | ||
13 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | 13 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/target/arm/tcg/translate-a64.c | 15 | --- a/target/arm/tcg/translate-a64.c |
16 | +++ b/target/arm/tcg/translate-a64.c | 16 | +++ b/target/arm/tcg/translate-a64.c |
17 | @@ -XXX,XX +XXX,XX @@ static inline void gen_check_sp_alignment(DisasContext *s) | 17 | @@ -XXX,XX +XXX,XX @@ static inline void gen_check_sp_alignment(DisasContext *s) |
18 | */ | 18 | */ |
19 | } | 19 | } |
20 | 20 | ||
21 | -/* | 21 | -/* |
22 | - * This provides a simple table based table lookup decoder. It is | 22 | - * This provides a simple table based table lookup decoder. It is |
23 | - * intended to be used when the relevant bits for decode are too | 23 | - * intended to be used when the relevant bits for decode are too |
24 | - * awkwardly placed and switch/if based logic would be confusing and | 24 | - * awkwardly placed and switch/if based logic would be confusing and |
25 | - * deeply nested. Since it's a linear search through the table, tables | 25 | - * deeply nested. Since it's a linear search through the table, tables |
26 | - * should be kept small. | 26 | - * should be kept small. |
27 | - * | 27 | - * |
28 | - * It returns the first handler where insn & mask == pattern, or | 28 | - * It returns the first handler where insn & mask == pattern, or |
29 | - * NULL if there is no match. | 29 | - * NULL if there is no match. |
30 | - * The table is terminated by an empty mask (i.e. 0) | 30 | - * The table is terminated by an empty mask (i.e. 0) |
31 | - */ | 31 | - */ |
32 | -static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table, | 32 | -static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table, |
33 | - uint32_t insn) | 33 | - uint32_t insn) |
34 | -{ | 34 | -{ |
35 | - const AArch64DecodeTable *tptr = table; | 35 | - const AArch64DecodeTable *tptr = table; |
36 | - | 36 | - |
37 | - while (tptr->mask) { | 37 | - while (tptr->mask) { |
38 | - if ((insn & tptr->mask) == tptr->pattern) { | 38 | - if ((insn & tptr->mask) == tptr->pattern) { |
39 | - return tptr->disas_fn; | 39 | - return tptr->disas_fn; |
40 | - } | 40 | - } |
41 | - tptr++; | 41 | - tptr++; |
42 | - } | 42 | - } |
43 | - return NULL; | 43 | - return NULL; |
44 | -} | 44 | -} |
45 | - | 45 | - |
46 | /* | 46 | /* |
47 | * The instruction disassembly implemented here matches | 47 | * The instruction disassembly implemented here matches |
48 | * the instruction encoding classifications in chapter C4 | 48 | * the instruction encoding classifications in chapter C4 |
49 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_2_ptr * const f_frsqrte[] = { | 49 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_2_ptr * const f_frsqrte[] = { |
50 | }; | 50 | }; |
51 | TRANS(FRSQRTE_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_frsqrte) | 51 | TRANS(FRSQRTE_v, do_gvec_op2_fpst, a->esz, a->q, a->rd, a->rn, 0, f_frsqrte) |
52 | 52 | ||
53 | -static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, | 53 | -static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, |
54 | - int size, int rn, int rd) | 54 | - int size, int rn, int rd) |
55 | +static bool trans_FCVTL_v(DisasContext *s, arg_qrr_e *a) | 55 | +static bool trans_FCVTL_v(DisasContext *s, arg_qrr_e *a) |
56 | { | 56 | { |
57 | /* Handle 2-reg-misc ops which are widening (so each size element | 57 | /* Handle 2-reg-misc ops which are widening (so each size element |
58 | * in the source becomes a 2*size element in the destination. | 58 | * in the source becomes a 2*size element in the destination. |
59 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, | 59 | @@ -XXX,XX +XXX,XX @@ static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, |
60 | */ | 60 | */ |
61 | int pass; | 61 | int pass; |
62 | 62 | ||
63 | - if (size == 3) { | 63 | - if (size == 3) { |
64 | + if (!fp_access_check(s)) { | 64 | + if (!fp_access_check(s)) { |
65 | + return true; | 65 | + return true; |
66 | + } | 66 | + } |
67 | + | 67 | + |
68 | + if (a->esz == MO_64) { | 68 | + if (a->esz == MO_64) { |
69 | /* 32 -> 64 bit fp conversion */ | 69 | /* 32 -> 64 bit fp conversion */ |
70 | TCGv_i64 tcg_res[2]; | 70 | TCGv_i64 tcg_res[2]; |
71 | - int srcelt = is_q ? 2 : 0; | 71 | - int srcelt = is_q ? 2 : 0; |
72 | + TCGv_i32 tcg_op = tcg_temp_new_i32(); | 72 | + TCGv_i32 tcg_op = tcg_temp_new_i32(); |
73 | + int srcelt = a->q ? 2 : 0; | 73 | + int srcelt = a->q ? 2 : 0; |
74 | 74 | ||
75 | for (pass = 0; pass < 2; pass++) { | 75 | for (pass = 0; pass < 2; pass++) { |
76 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); | 76 | - TCGv_i32 tcg_op = tcg_temp_new_i32(); |
77 | tcg_res[pass] = tcg_temp_new_i64(); | 77 | tcg_res[pass] = tcg_temp_new_i64(); |
78 | - | 78 | - |
79 | - read_vec_element_i32(s, tcg_op, rn, srcelt + pass, MO_32); | 79 | - read_vec_element_i32(s, tcg_op, rn, srcelt + pass, MO_32); |
80 | + read_vec_element_i32(s, tcg_op, a->rn, srcelt + pass, MO_32); | 80 | + read_vec_element_i32(s, tcg_op, a->rn, srcelt + pass, MO_32); |
81 | gen_helper_vfp_fcvtds(tcg_res[pass], tcg_op, tcg_env); | 81 | gen_helper_vfp_fcvtds(tcg_res[pass], tcg_op, tcg_env); |
82 | } | 82 | } |
83 | for (pass = 0; pass < 2; pass++) { | 83 | for (pass = 0; pass < 2; pass++) { |
84 | - write_vec_element(s, tcg_res[pass], rd, pass, MO_64); | 84 | - write_vec_element(s, tcg_res[pass], rd, pass, MO_64); |
85 | + write_vec_element(s, tcg_res[pass], a->rd, pass, MO_64); | 85 | + write_vec_element(s, tcg_res[pass], a->rd, pass, MO_64); |
86 | } | 86 | } |
87 | } else { | 87 | } else { |
88 | /* 16 -> 32 bit fp conversion */ | 88 | /* 16 -> 32 bit fp conversion */ |
89 | - int srcelt = is_q ? 4 : 0; | 89 | - int srcelt = is_q ? 4 : 0; |
90 | + int srcelt = a->q ? 4 : 0; | 90 | + int srcelt = a->q ? 4 : 0; |
91 | TCGv_i32 tcg_res[4]; | 91 | TCGv_i32 tcg_res[4]; |
92 | TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | 92 | TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); |
93 | TCGv_i32 ahp = get_ahp_flag(); | 93 | TCGv_i32 ahp = get_ahp_flag(); |
94 | 94 | ||
95 | for (pass = 0; pass < 4; pass++) { | 95 | for (pass = 0; pass < 4; pass++) { |
96 | tcg_res[pass] = tcg_temp_new_i32(); | 96 | tcg_res[pass] = tcg_temp_new_i32(); |
97 | - | 97 | - |
98 | - read_vec_element_i32(s, tcg_res[pass], rn, srcelt + pass, MO_16); | 98 | - read_vec_element_i32(s, tcg_res[pass], rn, srcelt + pass, MO_16); |
99 | + read_vec_element_i32(s, tcg_res[pass], a->rn, srcelt + pass, MO_16); | 99 | + read_vec_element_i32(s, tcg_res[pass], a->rn, srcelt + pass, MO_16); |
100 | gen_helper_vfp_fcvt_f16_to_f32(tcg_res[pass], tcg_res[pass], | 100 | gen_helper_vfp_fcvt_f16_to_f32(tcg_res[pass], tcg_res[pass], |
101 | fpst, ahp); | 101 | fpst, ahp); |
102 | } | 102 | } |
103 | for (pass = 0; pass < 4; pass++) { | 103 | for (pass = 0; pass < 4; pass++) { |
104 | - write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32); | 104 | - write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32); |
105 | + write_vec_element_i32(s, tcg_res[pass], a->rd, pass, MO_32); | 105 | + write_vec_element_i32(s, tcg_res[pass], a->rd, pass, MO_32); |
106 | } | 106 | } |
107 | } | 107 | } |
108 | -} | 108 | -} |
109 | - | 109 | - |
110 | -/* AdvSIMD two reg misc | 110 | -/* AdvSIMD two reg misc |
111 | - * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 | 111 | - * 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0 |
112 | - * +---+---+---+-----------+------+-----------+--------+-----+------+------+ | 112 | - * +---+---+---+-----------+------+-----------+--------+-----+------+------+ |
113 | - * | 0 | Q | U | 0 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 | Rn | Rd | | 113 | - * | 0 | Q | U | 0 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 | Rn | Rd | |
114 | - * +---+---+---+-----------+------+-----------+--------+-----+------+------+ | 114 | - * +---+---+---+-----------+------+-----------+--------+-----+------+------+ |
115 | - */ | 115 | - */ |
116 | -static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) | 116 | -static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) |
117 | -{ | 117 | -{ |
118 | - int size = extract32(insn, 22, 2); | 118 | - int size = extract32(insn, 22, 2); |
119 | - int opcode = extract32(insn, 12, 5); | 119 | - int opcode = extract32(insn, 12, 5); |
120 | - bool u = extract32(insn, 29, 1); | 120 | - bool u = extract32(insn, 29, 1); |
121 | - bool is_q = extract32(insn, 30, 1); | 121 | - bool is_q = extract32(insn, 30, 1); |
122 | - int rn = extract32(insn, 5, 5); | 122 | - int rn = extract32(insn, 5, 5); |
123 | - int rd = extract32(insn, 0, 5); | 123 | - int rd = extract32(insn, 0, 5); |
124 | - | 124 | - |
125 | - switch (opcode) { | 125 | - switch (opcode) { |
126 | - case 0xc ... 0xf: | 126 | - case 0xc ... 0xf: |
127 | - case 0x16 ... 0x1f: | 127 | - case 0x16 ... 0x1f: |
128 | - { | 128 | - { |
129 | - /* Floating point: U, size[1] and opcode indicate operation; | 129 | - /* Floating point: U, size[1] and opcode indicate operation; |
130 | - * size[0] indicates single or double precision. | 130 | - * size[0] indicates single or double precision. |
131 | - */ | 131 | - */ |
132 | - int is_double = extract32(size, 0, 1); | 132 | - int is_double = extract32(size, 0, 1); |
133 | - opcode |= (extract32(size, 1, 1) << 5) | (u << 6); | 133 | - opcode |= (extract32(size, 1, 1) << 5) | (u << 6); |
134 | - size = is_double ? 3 : 2; | 134 | - size = is_double ? 3 : 2; |
135 | - switch (opcode) { | 135 | - switch (opcode) { |
136 | - case 0x17: /* FCVTL, FCVTL2 */ | 136 | - case 0x17: /* FCVTL, FCVTL2 */ |
137 | - if (!fp_access_check(s)) { | 137 | - if (!fp_access_check(s)) { |
138 | - return; | 138 | - return; |
139 | - } | 139 | - } |
140 | - handle_2misc_widening(s, opcode, is_q, size, rn, rd); | 140 | - handle_2misc_widening(s, opcode, is_q, size, rn, rd); |
141 | - return; | 141 | - return; |
142 | - default: | 142 | - default: |
143 | - case 0x16: /* FCVTN, FCVTN2 */ | 143 | - case 0x16: /* FCVTN, FCVTN2 */ |
144 | - case 0x36: /* BFCVTN, BFCVTN2 */ | 144 | - case 0x36: /* BFCVTN, BFCVTN2 */ |
145 | - case 0x56: /* FCVTXN, FCVTXN2 */ | 145 | - case 0x56: /* FCVTXN, FCVTXN2 */ |
146 | - case 0x2f: /* FABS */ | 146 | - case 0x2f: /* FABS */ |
147 | - case 0x6f: /* FNEG */ | 147 | - case 0x6f: /* FNEG */ |
148 | - case 0x7f: /* FSQRT */ | 148 | - case 0x7f: /* FSQRT */ |
149 | - case 0x18: /* FRINTN */ | 149 | - case 0x18: /* FRINTN */ |
150 | - case 0x19: /* FRINTM */ | 150 | - case 0x19: /* FRINTM */ |
151 | - case 0x38: /* FRINTP */ | 151 | - case 0x38: /* FRINTP */ |
152 | - case 0x39: /* FRINTZ */ | 152 | - case 0x39: /* FRINTZ */ |
153 | - case 0x59: /* FRINTX */ | 153 | - case 0x59: /* FRINTX */ |
154 | - case 0x79: /* FRINTI */ | 154 | - case 0x79: /* FRINTI */ |
155 | - case 0x58: /* FRINTA */ | 155 | - case 0x58: /* FRINTA */ |
156 | - case 0x1e: /* FRINT32Z */ | 156 | - case 0x1e: /* FRINT32Z */ |
157 | - case 0x1f: /* FRINT64Z */ | 157 | - case 0x1f: /* FRINT64Z */ |
158 | - case 0x5e: /* FRINT32X */ | 158 | - case 0x5e: /* FRINT32X */ |
159 | - case 0x5f: /* FRINT64X */ | 159 | - case 0x5f: /* FRINT64X */ |
160 | - case 0x1d: /* SCVTF */ | 160 | - case 0x1d: /* SCVTF */ |
161 | - case 0x5d: /* UCVTF */ | 161 | - case 0x5d: /* UCVTF */ |
162 | - case 0x1a: /* FCVTNS */ | 162 | - case 0x1a: /* FCVTNS */ |
163 | - case 0x1b: /* FCVTMS */ | 163 | - case 0x1b: /* FCVTMS */ |
164 | - case 0x3a: /* FCVTPS */ | 164 | - case 0x3a: /* FCVTPS */ |
165 | - case 0x3b: /* FCVTZS */ | 165 | - case 0x3b: /* FCVTZS */ |
166 | - case 0x5a: /* FCVTNU */ | 166 | - case 0x5a: /* FCVTNU */ |
167 | - case 0x5b: /* FCVTMU */ | 167 | - case 0x5b: /* FCVTMU */ |
168 | - case 0x7a: /* FCVTPU */ | 168 | - case 0x7a: /* FCVTPU */ |
169 | - case 0x7b: /* FCVTZU */ | 169 | - case 0x7b: /* FCVTZU */ |
170 | - case 0x5c: /* FCVTAU */ | 170 | - case 0x5c: /* FCVTAU */ |
171 | - case 0x1c: /* FCVTAS */ | 171 | - case 0x1c: /* FCVTAS */ |
172 | - case 0x2c: /* FCMGT (zero) */ | 172 | - case 0x2c: /* FCMGT (zero) */ |
173 | - case 0x2d: /* FCMEQ (zero) */ | 173 | - case 0x2d: /* FCMEQ (zero) */ |
174 | - case 0x2e: /* FCMLT (zero) */ | 174 | - case 0x2e: /* FCMLT (zero) */ |
175 | - case 0x6c: /* FCMGE (zero) */ | 175 | - case 0x6c: /* FCMGE (zero) */ |
176 | - case 0x6d: /* FCMLE (zero) */ | 176 | - case 0x6d: /* FCMLE (zero) */ |
177 | - case 0x3d: /* FRECPE */ | 177 | - case 0x3d: /* FRECPE */ |
178 | - case 0x7d: /* FRSQRTE */ | 178 | - case 0x7d: /* FRSQRTE */ |
179 | - case 0x3c: /* URECPE */ | 179 | - case 0x3c: /* URECPE */ |
180 | - case 0x7c: /* URSQRTE */ | 180 | - case 0x7c: /* URSQRTE */ |
181 | - unallocated_encoding(s); | 181 | - unallocated_encoding(s); |
182 | - return; | 182 | - return; |
183 | - } | 183 | - } |
184 | - break; | 184 | - break; |
185 | - } | 185 | - } |
186 | - default: | 186 | - default: |
187 | - case 0x0: /* REV64, REV32 */ | 187 | - case 0x0: /* REV64, REV32 */ |
188 | - case 0x1: /* REV16 */ | 188 | - case 0x1: /* REV16 */ |
189 | - case 0x2: /* SADDLP, UADDLP */ | 189 | - case 0x2: /* SADDLP, UADDLP */ |
190 | - case 0x3: /* SUQADD, USQADD */ | 190 | - case 0x3: /* SUQADD, USQADD */ |
191 | - case 0x4: /* CLS, CLZ */ | 191 | - case 0x4: /* CLS, CLZ */ |
192 | - case 0x5: /* CNT, NOT, RBIT */ | 192 | - case 0x5: /* CNT, NOT, RBIT */ |
193 | - case 0x6: /* SADALP, UADALP */ | 193 | - case 0x6: /* SADALP, UADALP */ |
194 | - case 0x7: /* SQABS, SQNEG */ | 194 | - case 0x7: /* SQABS, SQNEG */ |
195 | - case 0x8: /* CMGT, CMGE */ | 195 | - case 0x8: /* CMGT, CMGE */ |
196 | - case 0x9: /* CMEQ, CMLE */ | 196 | - case 0x9: /* CMEQ, CMLE */ |
197 | - case 0xa: /* CMLT */ | 197 | - case 0xa: /* CMLT */ |
198 | - case 0xb: /* ABS, NEG */ | 198 | - case 0xb: /* ABS, NEG */ |
199 | - case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ | 199 | - case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ |
200 | - case 0x13: /* SHLL, SHLL2 */ | 200 | - case 0x13: /* SHLL, SHLL2 */ |
201 | - case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ | 201 | - case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ |
202 | - unallocated_encoding(s); | 202 | - unallocated_encoding(s); |
203 | - return; | 203 | - return; |
204 | - } | 204 | - } |
205 | - g_assert_not_reached(); | 205 | - g_assert_not_reached(); |
206 | -} | 206 | -} |
207 | - | 207 | - |
208 | -/* C3.6 Data processing - SIMD, inc Crypto | 208 | -/* C3.6 Data processing - SIMD, inc Crypto |
209 | - * | 209 | - * |
210 | - * As the decode gets a little complex we are using a table based | 210 | - * As the decode gets a little complex we are using a table based |
211 | - * approach for this part of the decode. | 211 | - * approach for this part of the decode. |
212 | - */ | 212 | - */ |
213 | -static const AArch64DecodeTable data_proc_simd[] = { | 213 | -static const AArch64DecodeTable data_proc_simd[] = { |
214 | - /* pattern , mask , fn */ | 214 | - /* pattern , mask , fn */ |
215 | - { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc }, | 215 | - { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc }, |
216 | - { 0x00000000, 0x00000000, NULL } | 216 | - { 0x00000000, 0x00000000, NULL } |
217 | -}; | 217 | -}; |
218 | - | 218 | - |
219 | -static void disas_data_proc_simd(DisasContext *s, uint32_t insn) | 219 | -static void disas_data_proc_simd(DisasContext *s, uint32_t insn) |
220 | -{ | 220 | -{ |
221 | - /* Note that this is called with all non-FP cases from | 221 | - /* Note that this is called with all non-FP cases from |
222 | - * table C3-6 so it must UNDEF for entries not specifically | 222 | - * table C3-6 so it must UNDEF for entries not specifically |
223 | - * allocated to instructions in that table. | 223 | - * allocated to instructions in that table. |
224 | - */ | 224 | - */ |
225 | - AArch64DecodeFn *fn = lookup_disas_fn(&data_proc_simd[0], insn); | 225 | - AArch64DecodeFn *fn = lookup_disas_fn(&data_proc_simd[0], insn); |
226 | - if (fn) { | 226 | - if (fn) { |
227 | - fn(s, insn); | 227 | - fn(s, insn); |
228 | - } else { | 228 | - } else { |
229 | - unallocated_encoding(s); | 229 | - unallocated_encoding(s); |
230 | - } | 230 | - } |
231 | -} | 231 | -} |
232 | - | 232 | - |
233 | -/* C3.6 Data processing - SIMD and floating point */ | 233 | -/* C3.6 Data processing - SIMD and floating point */ |
234 | -static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) | 234 | -static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) |
235 | -{ | 235 | -{ |
236 | - if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) { | 236 | - if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) { |
237 | - unallocated_encoding(s); /* in decodetree */ | 237 | - unallocated_encoding(s); /* in decodetree */ |
238 | - } else { | 238 | - } else { |
239 | - /* SIMD, including crypto */ | 239 | - /* SIMD, including crypto */ |
240 | - disas_data_proc_simd(s, insn); | 240 | - disas_data_proc_simd(s, insn); |
241 | - } | 241 | - } |
242 | + clear_vec_high(s, true, a->rd); | 242 | + clear_vec_high(s, true, a->rd); |
243 | + return true; | 243 | + return true; |
244 | } | 244 | } |
245 | 245 | ||
246 | static bool trans_OK(DisasContext *s, arg_OK *a) | 246 | static bool trans_OK(DisasContext *s, arg_OK *a) |
247 | @@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype) | 247 | @@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype) |
248 | return false; | 248 | return false; |
249 | } | 249 | } |
250 | 250 | ||
251 | -/* C3.1 A64 instruction index by encoding */ | 251 | -/* C3.1 A64 instruction index by encoding */ |
252 | -static void disas_a64_legacy(DisasContext *s, uint32_t insn) | 252 | -static void disas_a64_legacy(DisasContext *s, uint32_t insn) |
253 | -{ | 253 | -{ |
254 | - switch (extract32(insn, 25, 4)) { | 254 | - switch (extract32(insn, 25, 4)) { |
255 | - case 0x7: | 255 | - case 0x7: |
256 | - case 0xf: /* Data processing - SIMD and floating point */ | 256 | - case 0xf: /* Data processing - SIMD and floating point */ |
257 | - disas_data_proc_simd_fp(s, insn); | 257 | - disas_data_proc_simd_fp(s, insn); |
258 | - break; | 258 | - break; |
259 | - default: | 259 | - default: |
260 | - unallocated_encoding(s); | 260 | - unallocated_encoding(s); |
261 | - break; | 261 | - break; |
262 | - } | 262 | - } |
263 | -} | 263 | -} |
264 | - | 264 | - |
265 | static void aarch64_tr_init_disas_context(DisasContextBase *dcbase, | 265 | static void aarch64_tr_init_disas_context(DisasContextBase *dcbase, |
266 | CPUState *cpu) | 266 | CPUState *cpu) |
267 | { | 267 | { |
268 | @@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) | 268 | @@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) |
269 | if (!disas_a64(s, insn) && | 269 | if (!disas_a64(s, insn) && |
270 | !disas_sme(s, insn) && | 270 | !disas_sme(s, insn) && |
271 | !disas_sve(s, insn)) { | 271 | !disas_sve(s, insn)) { |
272 | - disas_a64_legacy(s, insn); | 272 | - disas_a64_legacy(s, insn); |
273 | + unallocated_encoding(s); | 273 | + unallocated_encoding(s); |
274 | } | 274 | } |
275 | 275 | ||
276 | /* | 276 | /* |
277 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode | 277 | diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode |
278 | index XXXXXXX..XXXXXXX 100644 | 278 | index XXXXXXX..XXXXXXX 100644 |
279 | --- a/target/arm/tcg/a64.decode | 279 | --- a/target/arm/tcg/a64.decode |
280 | +++ b/target/arm/tcg/a64.decode | 280 | +++ b/target/arm/tcg/a64.decode |
281 | @@ -XXX,XX +XXX,XX @@ FRSQRTE_v 0.10 1110 1.1 00001 11011 0 ..... ..... @qrr_sd | 281 | @@ -XXX,XX +XXX,XX @@ FRSQRTE_v 0.10 1110 1.1 00001 11011 0 ..... ..... @qrr_sd |
282 | URECPE_v 0.00 1110 101 00001 11001 0 ..... ..... @qrr_s | 282 | URECPE_v 0.00 1110 101 00001 11001 0 ..... ..... @qrr_s |
283 | URSQRTE_v 0.10 1110 101 00001 11001 0 ..... ..... @qrr_s | 283 | URSQRTE_v 0.10 1110 101 00001 11001 0 ..... ..... @qrr_s |
284 | 284 | ||
285 | +FCVTL_v 0.00 1110 0.1 00001 01111 0 ..... ..... @qrr_sd | 285 | +FCVTL_v 0.00 1110 0.1 00001 01111 0 ..... ..... @qrr_sd |
286 | + | 286 | + |
287 | &fcvt_q rd rn esz q shift | 287 | &fcvt_q rd rn esz q shift |
288 | @fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \ | 288 | @fcvtq_h . q:1 . ...... 001 .... ...... rn:5 rd:5 \ |
289 | &fcvt_q esz=1 shift=%fcvt_f_sh_h | 289 | &fcvt_q esz=1 shift=%fcvt_f_sh_h |
290 | -- | 290 | -- |
291 | 2.43.0 | 291 | 2.43.0 | diff view generated by jsdifflib |