1
The following changes since commit ad1b4ec39caa5b3f17cbd8160283a03a3dcfe2ae:
1
Arm patches for rc1:
2
* two final "remove the old API" patches for some API transitions
3
* bugfix for raspi/highbank Linux boot
2
4
3
Merge remote-tracking branch 'remotes/kraxel/tags/input-20180515-pull-request' into staging (2018-05-15 12:50:06 +0100)
5
thanks
6
-- PMM
7
8
The following changes since commit 654efcb511d394c1d3f5292c28503d1d19e5b1d3:
9
10
Merge remote-tracking branch 'remotes/vivier/tags/q800-branch-pull-request' into staging (2019-11-11 09:23:46 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180515
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191111
8
15
9
for you to fetch changes up to ae7651804748c6b479d5ae09aeac4edb9c44f76e:
16
for you to fetch changes up to 45c078f163fd47c35e7505d98928fae63baada7d:
10
17
11
tcg: Optionally log FPU state in TCG -d cpu logging (2018-05-15 14:58:44 +0100)
18
hw/arm/boot: Set NSACR.{CP11, CP10} in dummy SMC setup routine (2019-11-11 13:44:16 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
target-arm queue:
15
* Fix coverity nit in int_to_float code
22
* Remove old unassigned_access CPU hook API
16
* Don't set Invalid for float-to-int(MAXINT)
23
* Remove old ptimer_init_with_bh() API
17
* Fix fp_status_f16 tininess before rounding
24
* hw/arm/boot: Set NSACR.{CP11, CP10} in dummy SMC setup routine
18
* Add various missing insns from the v8.2-FP16 extension
19
* Fix sqrt_f16 exception raising
20
* sdcard: Correct CRC16 offset in sd_function_switch()
21
* tcg: Optionally log FPU state in TCG -d cpu logging
22
25
23
----------------------------------------------------------------
26
----------------------------------------------------------------
24
Alex Bennée (5):
27
Clement Deschamps (1):
25
fpu/softfloat: int_to_float ensure r fully initialised
28
hw/arm/boot: Set NSACR.{CP11, CP10} in dummy SMC setup routine
26
target/arm: Implement FCMP for fp16
27
target/arm: Implement FCSEL for fp16
28
target/arm: Implement FMOV (immediate) for fp16
29
target/arm: Fix sqrt_f16 exception raising
30
29
31
Peter Maydell (3):
30
Peter Maydell (2):
32
fpu/softfloat: Don't set Invalid for float-to-int(MAXINT)
31
ptimer: Remove old ptimer_init_with_bh() API
33
target/arm: Fix fp_status_f16 tininess before rounding
32
Remove unassigned_access CPU hook
34
tcg: Optionally log FPU state in TCG -d cpu logging
35
33
36
Philippe Mathieu-Daudé (1):
34
include/hw/arm/boot.h | 7 ++--
37
sdcard: Correct CRC16 offset in sd_function_switch()
35
include/hw/core/cpu.h | 24 --------------
36
include/hw/ptimer.h | 45 ++++++++++++-------------
37
accel/tcg/cputlb.c | 2 --
38
hw/arm/boot.c | 3 ++
39
hw/core/ptimer.c | 91 +++++++++------------------------------------------
40
memory.c | 7 ----
41
7 files changed, 44 insertions(+), 135 deletions(-)
38
42
39
Richard Henderson (7):
40
target/arm: Implement FMOV (general) for fp16
41
target/arm: Early exit after unallocated_encoding in disas_fp_int_conv
42
target/arm: Implement FCVT (scalar, integer) for fp16
43
target/arm: Implement FCVT (scalar, fixed-point) for fp16
44
target/arm: Introduce and use read_fp_hreg
45
target/arm: Implement FP data-processing (2 source) for fp16
46
target/arm: Implement FP data-processing (3 source) for fp16
47
48
include/qemu/log.h | 1 +
49
target/arm/helper-a64.h | 2 +
50
target/arm/helper.h | 6 +
51
accel/tcg/cpu-exec.c | 9 +-
52
fpu/softfloat.c | 6 +-
53
hw/sd/sd.c | 2 +-
54
target/arm/cpu.c | 2 +
55
target/arm/helper-a64.c | 10 ++
56
target/arm/helper.c | 38 +++-
57
target/arm/translate-a64.c | 421 ++++++++++++++++++++++++++++++++++++++-------
58
util/log.c | 2 +
59
11 files changed, 428 insertions(+), 71 deletions(-)
60
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
Reported by Coverity (CID1390635). We ensure this for uint_to_float
4
later on so we might as well mirror that.
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
fpu/softfloat.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat.c
17
+++ b/fpu/softfloat.c
18
@@ -XXX,XX +XXX,XX @@ FLOAT_TO_UINT(64, 64)
19
20
static FloatParts int_to_float(int64_t a, float_status *status)
21
{
22
- FloatParts r;
23
+ FloatParts r = {};
24
if (a == 0) {
25
r.cls = float_class_zero;
26
r.sign = false;
27
--
28
2.17.0
29
30
diff view generated by jsdifflib
Deleted patch
1
In float-to-integer conversion, if the floating point input
2
converts exactly to the largest or smallest integer that
3
fits in to the result type, this is not an overflow.
4
In this situation we were producing the correct result value,
5
but were incorrectly setting the Invalid flag.
6
For example for Arm A64, "FCVTAS w0, d0" on an input of
7
0x41dfffffffc00000 should produce 0x7fffffff and set no flags.
8
1
9
Fix the boundary case to take the right half of the if()
10
statements.
11
12
This fixes a regression from 2.11 introduced by the softfloat
13
refactoring.
14
15
Cc: qemu-stable@nongnu.org
16
Fixes: ab52f973a50
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20180510140141.12120-1-peter.maydell@linaro.org
20
---
21
fpu/softfloat.c | 4 ++--
22
1 file changed, 2 insertions(+), 2 deletions(-)
23
24
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat.c
27
+++ b/fpu/softfloat.c
28
@@ -XXX,XX +XXX,XX @@ static int64_t round_to_int_and_pack(FloatParts in, int rmode,
29
r = UINT64_MAX;
30
}
31
if (p.sign) {
32
- if (r < -(uint64_t) min) {
33
+ if (r <= -(uint64_t) min) {
34
return -r;
35
} else {
36
s->float_exception_flags = orig_flags | float_flag_invalid;
37
return min;
38
}
39
} else {
40
- if (r < max) {
41
+ if (r <= max) {
42
return r;
43
} else {
44
s->float_exception_flags = orig_flags | float_flag_invalid;
45
--
46
2.17.0
47
48
diff view generated by jsdifflib
Deleted patch
1
In commit d81ce0ef2c4f105 we added an extra float_status field
2
fp_status_fp16 for Arm, but forgot to initialize it correctly
3
by setting it to float_tininess_before_rounding. This currently
4
will only cause problems for the new V8_FP16 feature, since the
5
float-to-float conversion code doesn't use it yet. The effect
6
would be that we failed to set the Underflow IEEE exception flag
7
in all the cases where we should.
8
1
9
Add the missing initialization.
10
11
Fixes: d81ce0ef2c4f105
12
Cc: qemu-stable@nongnu.org
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 20180512004311.9299-16-richard.henderson@linaro.org
17
---
18
target/arm/cpu.c | 2 ++
19
1 file changed, 2 insertions(+)
20
21
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.c
24
+++ b/target/arm/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
26
&env->vfp.fp_status);
27
set_float_detect_tininess(float_tininess_before_rounding,
28
&env->vfp.standard_fp_status);
29
+ set_float_detect_tininess(float_tininess_before_rounding,
30
+ &env->vfp.fp_status_f16);
31
#ifndef CONFIG_USER_ONLY
32
if (kvm_enabled()) {
33
kvm_arm_reset_vcpu(cpu);
34
--
35
2.17.0
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Adding the fp16 moves to/from general registers.
4
5
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20180512003217.9105-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 21 +++++++++++++++++++++
13
1 file changed, 21 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
20
tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
21
clear_vec_high(s, true, rd);
22
break;
23
+ case 3:
24
+ /* 16 bit */
25
+ tmp = tcg_temp_new_i64();
26
+ tcg_gen_ext16u_i64(tmp, tcg_rn);
27
+ write_fp_dreg(s, rd, tmp);
28
+ tcg_temp_free_i64(tmp);
29
+ break;
30
+ default:
31
+ g_assert_not_reached();
32
}
33
} else {
34
TCGv_i64 tcg_rd = cpu_reg(s, rd);
35
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
36
/* 64 bits from top half */
37
tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(s, rn));
38
break;
39
+ case 3:
40
+ /* 16 bit */
41
+ tcg_gen_ld16u_i64(tcg_rd, cpu_env, fp_reg_offset(s, rn, MO_16));
42
+ break;
43
+ default:
44
+ g_assert_not_reached();
45
}
46
}
47
}
48
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
49
case 0xa: /* 64 bit */
50
case 0xd: /* 64 bit to top half of quad */
51
break;
52
+ case 0x6: /* 16-bit float, 32-bit int */
53
+ case 0xe: /* 16-bit float, 64-bit int */
54
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
55
+ break;
56
+ }
57
+ /* fallthru */
58
default:
59
/* all other sf/type/rmode combinations are invalid */
60
unallocated_encoding(s);
61
--
62
2.17.0
63
64
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
No sense in emitting code after the exception.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-3-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
19
default:
20
/* all other sf/type/rmode combinations are invalid */
21
unallocated_encoding(s);
22
- break;
23
+ return;
24
}
25
26
if (!fp_access_check(s)) {
27
--
28
2.17.0
29
30
diff view generated by jsdifflib
1
Usually the logging of the CPU state produced by -d cpu is sufficient
1
Now all the users of ptimers have converted to the transaction-based
2
to diagnose problems, but sometimes you want to see the state of
2
API, we can remove ptimer_init_with_bh() and all the code paths
3
the floating point registers as well. We don't want to enable that
3
that are used only by bottom-half based ptimers, and tidy up the
4
by default as it adds a lot of extra data to the log; instead,
4
documentation comments to consider the transaction-based API the
5
allow it to be optionally enabled via -d fpu.
5
only possibility.
6
7
The code changes result from:
8
* s->bh no longer exists
9
* s->callback is now always non-NULL
6
10
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180510130024.31678-1-peter.maydell@linaro.org
13
Message-id: 20191025142411.17085-1-peter.maydell@linaro.org
10
---
14
---
11
include/qemu/log.h | 1 +
15
include/hw/ptimer.h | 45 +++++++++++-----------
12
accel/tcg/cpu-exec.c | 9 ++++++---
16
hw/core/ptimer.c | 91 ++++++++-------------------------------------
13
util/log.c | 2 ++
17
2 files changed, 36 insertions(+), 100 deletions(-)
14
3 files changed, 9 insertions(+), 3 deletions(-)
18
15
19
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
16
diff --git a/include/qemu/log.h b/include/qemu/log.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/include/qemu/log.h
21
--- a/include/hw/ptimer.h
19
+++ b/include/qemu/log.h
22
+++ b/include/hw/ptimer.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool qemu_log_separate(void)
23
@@ -XXX,XX +XXX,XX @@
21
#define CPU_LOG_PAGE (1 << 14)
24
22
/* LOG_TRACE (1 << 15) is defined in log-for-trace.h */
25
#include "qemu/timer.h"
23
#define CPU_LOG_TB_OP_IND (1 << 16)
26
24
+#define CPU_LOG_TB_FPU (1 << 17)
27
-/* The ptimer API implements a simple periodic countdown timer.
25
28
+/*
26
/* Lock output for a series of related logs. Since this is not needed
29
+ * The ptimer API implements a simple periodic countdown timer.
27
* for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we
30
* The countdown timer has a value (which can be read and written via
28
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
31
* ptimer_get_count() and ptimer_set_count()). When it is enabled
32
* using ptimer_run(), the value will count downwards at the frequency
33
* which has been configured using ptimer_set_period() or ptimer_set_freq().
34
- * When it reaches zero it will trigger a QEMU bottom half handler, and
35
+ * When it reaches zero it will trigger a callback function, and
36
* can be set to either reload itself from a specified limit value
37
* and keep counting down, or to stop (as a one-shot timer).
38
*
39
+ * A transaction-based API is used for modifying ptimer state: all calls
40
+ * to functions which modify ptimer state must be between matched calls to
41
+ * ptimer_transaction_begin() and ptimer_transaction_commit().
42
+ * When ptimer_transaction_commit() is called it will evaluate the state
43
+ * of the timer after all the changes in the transaction, and call the
44
+ * callback if necessary. (See the ptimer_init() documentation for the full
45
+ * list of state-modifying functions and detailed semantics of the callback.)
46
+ *
47
* Forgetting to set the period/frequency (or setting it to zero) is a
48
* bug in the QEMU device and will cause warning messages to be printed
49
* to stderr when the guest attempts to enable the timer.
50
@@ -XXX,XX +XXX,XX @@
51
* ptimer_set_count() or ptimer_set_limit() will not trigger the timer
52
* (though it will cause a reload). Only a counter decrement to "0"
53
* will cause a trigger. Not compatible with NO_IMMEDIATE_TRIGGER;
54
- * ptimer_init_with_bh() will assert() that you don't set both.
55
+ * ptimer_init() will assert() that you don't set both.
56
*/
57
#define PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT (1 << 5)
58
59
@@ -XXX,XX +XXX,XX @@
60
typedef struct ptimer_state ptimer_state;
61
typedef void (*ptimer_cb)(void *opaque);
62
63
-/**
64
- * ptimer_init_with_bh - Allocate and return a new ptimer
65
- * @bh: QEMU bottom half which is run on timer expiry
66
- * @policy: PTIMER_POLICY_* bits specifying behaviour
67
- *
68
- * The ptimer returned must be freed using ptimer_free().
69
- * The ptimer takes ownership of @bh and will delete it
70
- * when the ptimer is eventually freed.
71
- */
72
-ptimer_state *ptimer_init_with_bh(QEMUBH *bh, uint8_t policy_mask);
73
-
74
/**
75
* ptimer_init - Allocate and return a new ptimer
76
* @callback: function to call on ptimer expiry
77
@@ -XXX,XX +XXX,XX @@ ptimer_state *ptimer_init(ptimer_cb callback,
78
* ptimer_free - Free a ptimer
79
* @s: timer to free
80
*
81
- * Free a ptimer created using ptimer_init_with_bh() (including
82
- * deleting the bottom half which it is using).
83
+ * Free a ptimer created using ptimer_init().
84
*/
85
void ptimer_free(ptimer_state *s);
86
87
@@ -XXX,XX +XXX,XX @@ void ptimer_transaction_commit(ptimer_state *s);
88
* may be more appropriate.
89
*
90
* This function will assert if it is called outside a
91
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
92
+ * ptimer_transaction_begin/commit block.
93
*/
94
void ptimer_set_period(ptimer_state *s, int64_t period);
95
96
@@ -XXX,XX +XXX,XX @@ void ptimer_set_period(ptimer_state *s, int64_t period);
97
* precise to fractions of a nanosecond, avoiding rounding errors.
98
*
99
* This function will assert if it is called outside a
100
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
101
+ * ptimer_transaction_begin/commit block.
102
*/
103
void ptimer_set_freq(ptimer_state *s, uint32_t freq);
104
105
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_limit(ptimer_state *s);
106
* reload the counter when their reload register is written to.
107
*
108
* This function will assert if it is called outside a
109
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
110
+ * ptimer_transaction_begin/commit block.
111
*/
112
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
113
114
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_count(ptimer_state *s);
115
* point in the future.
116
*
117
* This function will assert if it is called outside a
118
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
119
+ * ptimer_transaction_begin/commit block.
120
*/
121
void ptimer_set_count(ptimer_state *s, uint64_t count);
122
123
@@ -XXX,XX +XXX,XX @@ void ptimer_set_count(ptimer_state *s, uint64_t count);
124
* @s: ptimer
125
* @oneshot: non-zero if this timer should only count down once
126
*
127
- * Start a ptimer counting down; when it reaches zero the bottom half
128
- * passed to ptimer_init_with_bh() will be invoked.
129
+ * Start a ptimer counting down; when it reaches zero the callback function
130
+ * passed to ptimer_init() will be invoked.
131
* If the @oneshot argument is zero,
132
* the counter value will then be reloaded from the limit and it will
133
* start counting down again. If @oneshot is non-zero, then the counter
134
* will disable itself when it reaches zero.
135
*
136
* This function will assert if it is called outside a
137
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
138
+ * ptimer_transaction_begin/commit block.
139
*/
140
void ptimer_run(ptimer_state *s, int oneshot);
141
142
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot);
143
* restarted.
144
*
145
* This function will assert if it is called outside a
146
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
147
+ * ptimer_transaction_begin/commit block.
148
*/
149
void ptimer_stop(ptimer_state *s);
150
151
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
29
index XXXXXXX..XXXXXXX 100644
152
index XXXXXXX..XXXXXXX 100644
30
--- a/accel/tcg/cpu-exec.c
153
--- a/hw/core/ptimer.c
31
+++ b/accel/tcg/cpu-exec.c
154
+++ b/hw/core/ptimer.c
32
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
155
@@ -XXX,XX +XXX,XX @@ struct ptimer_state
33
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
156
int64_t last_event;
34
&& qemu_log_in_addr_range(itb->pc)) {
157
int64_t next_event;
35
qemu_log_lock();
158
uint8_t policy_mask;
36
+ int flags = 0;
159
- QEMUBH *bh;
37
+ if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
160
QEMUTimer *timer;
38
+ flags |= CPU_DUMP_FPU;
161
ptimer_cb callback;
39
+ }
162
void *callback_opaque;
40
#if defined(TARGET_I386)
163
@@ -XXX,XX +XXX,XX @@ struct ptimer_state
41
- log_cpu_state(cpu, CPU_DUMP_CCOP);
164
/* Use a bottom-half routine to avoid reentrancy issues. */
42
-#else
165
static void ptimer_trigger(ptimer_state *s)
43
- log_cpu_state(cpu, 0);
166
{
44
+ flags |= CPU_DUMP_CCOP;
167
- if (s->bh) {
45
#endif
168
- replay_bh_schedule_event(s->bh);
46
+ log_cpu_state(cpu, flags);
169
- }
47
qemu_log_unlock();
170
- if (s->callback) {
48
}
171
- s->callback(s->callback_opaque);
49
#endif /* DEBUG_DISAS */
172
- }
50
diff --git a/util/log.c b/util/log.c
173
+ s->callback(s->callback_opaque);
51
index XXXXXXX..XXXXXXX 100644
174
}
52
--- a/util/log.c
175
53
+++ b/util/log.c
176
static void ptimer_reload(ptimer_state *s, int delta_adjust)
54
@@ -XXX,XX +XXX,XX @@ const QEMULogItem qemu_log_items[] = {
177
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_count(ptimer_state *s)
55
"show trace before each executed TB (lots of logs)" },
178
56
{ CPU_LOG_TB_CPU, "cpu",
179
void ptimer_set_count(ptimer_state *s, uint64_t count)
57
"show CPU registers before entering a TB (lots of logs)" },
180
{
58
+ { CPU_LOG_TB_FPU, "fpu",
181
- assert(s->in_transaction || !s->callback);
59
+ "include FPU registers in the 'cpu' logging" },
182
+ assert(s->in_transaction);
60
{ CPU_LOG_MMU, "mmu",
183
s->delta = count;
61
"log MMU-related activities" },
184
if (s->enabled) {
62
{ CPU_LOG_PCALL, "pcall",
185
- if (!s->callback) {
186
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
187
- ptimer_reload(s, 0);
188
- } else {
189
- s->need_reload = true;
190
- }
191
+ s->need_reload = true;
192
}
193
}
194
195
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot)
196
{
197
bool was_disabled = !s->enabled;
198
199
- assert(s->in_transaction || !s->callback);
200
+ assert(s->in_transaction);
201
202
if (was_disabled && s->period == 0) {
203
if (!qtest_enabled()) {
204
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot)
205
}
206
s->enabled = oneshot ? 2 : 1;
207
if (was_disabled) {
208
- if (!s->callback) {
209
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
210
- ptimer_reload(s, 0);
211
- } else {
212
- s->need_reload = true;
213
- }
214
+ s->need_reload = true;
215
}
216
}
217
218
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot)
219
is immediately restarted. */
220
void ptimer_stop(ptimer_state *s)
221
{
222
- assert(s->in_transaction || !s->callback);
223
+ assert(s->in_transaction);
224
225
if (!s->enabled)
226
return;
227
@@ -XXX,XX +XXX,XX @@ void ptimer_stop(ptimer_state *s)
228
s->delta = ptimer_get_count(s);
229
timer_del(s->timer);
230
s->enabled = 0;
231
- if (s->callback) {
232
- s->need_reload = false;
233
- }
234
+ s->need_reload = false;
235
}
236
237
/* Set counter increment interval in nanoseconds. */
238
void ptimer_set_period(ptimer_state *s, int64_t period)
239
{
240
- assert(s->in_transaction || !s->callback);
241
+ assert(s->in_transaction);
242
s->delta = ptimer_get_count(s);
243
s->period = period;
244
s->period_frac = 0;
245
if (s->enabled) {
246
- if (!s->callback) {
247
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
248
- ptimer_reload(s, 0);
249
- } else {
250
- s->need_reload = true;
251
- }
252
+ s->need_reload = true;
253
}
254
}
255
256
/* Set counter frequency in Hz. */
257
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
258
{
259
- assert(s->in_transaction || !s->callback);
260
+ assert(s->in_transaction);
261
s->delta = ptimer_get_count(s);
262
s->period = 1000000000ll / freq;
263
s->period_frac = (1000000000ll << 32) / freq;
264
if (s->enabled) {
265
- if (!s->callback) {
266
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
267
- ptimer_reload(s, 0);
268
- } else {
269
- s->need_reload = true;
270
- }
271
+ s->need_reload = true;
272
}
273
}
274
275
@@ -XXX,XX +XXX,XX @@ void ptimer_set_freq(ptimer_state *s, uint32_t freq)
276
count = limit. */
277
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
278
{
279
- assert(s->in_transaction || !s->callback);
280
+ assert(s->in_transaction);
281
s->limit = limit;
282
if (reload)
283
s->delta = limit;
284
if (s->enabled && reload) {
285
- if (!s->callback) {
286
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
287
- ptimer_reload(s, 0);
288
- } else {
289
- s->need_reload = true;
290
- }
291
+ s->need_reload = true;
292
}
293
}
294
295
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_limit(ptimer_state *s)
296
297
void ptimer_transaction_begin(ptimer_state *s)
298
{
299
- assert(!s->in_transaction || !s->callback);
300
+ assert(!s->in_transaction);
301
s->in_transaction = true;
302
s->need_reload = false;
303
}
304
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_ptimer = {
305
}
306
};
307
308
-ptimer_state *ptimer_init_with_bh(QEMUBH *bh, uint8_t policy_mask)
309
-{
310
- ptimer_state *s;
311
-
312
- s = (ptimer_state *)g_malloc0(sizeof(ptimer_state));
313
- s->bh = bh;
314
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
315
- s->policy_mask = policy_mask;
316
-
317
- /*
318
- * These two policies are incompatible -- trigger-on-decrement implies
319
- * a timer trigger when the count becomes 0, but no-immediate-trigger
320
- * implies a trigger when the count stops being 0.
321
- */
322
- assert(!((policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
323
- (policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)));
324
- return s;
325
-}
326
-
327
ptimer_state *ptimer_init(ptimer_cb callback, void *callback_opaque,
328
uint8_t policy_mask)
329
{
330
ptimer_state *s;
331
332
- /*
333
- * The callback function is mandatory; so we use it to distinguish
334
- * old-style QEMUBH ptimers from new transaction API ptimers.
335
- * (ptimer_init_with_bh() allows a NULL bh pointer and at least
336
- * one device (digic-timer) passes NULL, so it's not the case
337
- * that either s->bh != NULL or s->callback != NULL.)
338
- */
339
+ /* The callback function is mandatory. */
340
assert(callback);
341
342
s = g_new0(ptimer_state, 1);
343
@@ -XXX,XX +XXX,XX @@ ptimer_state *ptimer_init(ptimer_cb callback, void *callback_opaque,
344
345
void ptimer_free(ptimer_state *s)
346
{
347
- if (s->bh) {
348
- qemu_bh_delete(s->bh);
349
- }
350
timer_free(s->timer);
351
g_free(s);
352
}
63
--
353
--
64
2.17.0
354
2.20.1
65
355
66
356
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
All targets have now migrated away from the old unassigned_access
2
hook to the new do_transaction_failed hook. This means we can remove
3
the core-code infrastructure for that hook and the code that calls it.
2
4
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20191108173732.11816-1-peter.maydell@linaro.org
9
---
9
---
10
target/arm/helper.h | 6 +++
10
include/hw/core/cpu.h | 24 ------------------------
11
target/arm/helper.c | 38 ++++++++++++++-
11
accel/tcg/cputlb.c | 2 --
12
target/arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++-------
12
memory.c | 7 -------
13
3 files changed, 122 insertions(+), 18 deletions(-)
13
3 files changed, 33 deletions(-)
14
14
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
17
--- a/include/hw/core/cpu.h
18
+++ b/target/arm/helper.h
18
+++ b/include/hw/core/cpu.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
19
@@ -XXX,XX +XXX,XX @@ typedef enum MMUAccessType {
20
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
20
21
DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr)
21
typedef struct CPUWatchpoint CPUWatchpoint;
22
DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr)
22
23
+DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
23
-typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
24
+DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
24
- bool is_write, bool is_exec, int opaque,
25
+DEF_HELPER_3(vfp_touqh, i64, f16, i32, ptr)
25
- unsigned size);
26
+DEF_HELPER_3(vfp_tosqh, i64, f16, i32, ptr)
26
-
27
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
27
struct TranslationBlock;
28
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
28
29
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
29
/**
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
30
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
31
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
31
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
32
DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr)
32
* @has_work: Callback for checking if there is work to do.
33
DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
33
* @do_interrupt: Callback for interrupt handling.
34
+DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
34
- * @do_unassigned_access: Callback for unassigned access handling.
35
+DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
35
- * (this is deprecated: new targets should use do_transaction_failed instead)
36
36
* @do_unaligned_access: Callback for unaligned access handling, if
37
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
37
* the target defines #TARGET_ALIGNED_ONLY.
38
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
38
* @do_transaction_failed: Callback for handling failed memory transactions
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
40
int reset_dump_flags;
41
bool (*has_work)(CPUState *cpu);
42
void (*do_interrupt)(CPUState *cpu);
43
- CPUUnassignedAccess do_unassigned_access;
44
void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
45
MMUAccessType access_type,
46
int mmu_idx, uintptr_t retaddr);
47
@@ -XXX,XX +XXX,XX @@ struct CPUState {
48
* we store some rarely used information in the CPU context.
49
*/
50
uintptr_t mem_io_pc;
51
- /*
52
- * This is only needed for the legacy cpu_unassigned_access() hook;
53
- * when all targets using it have been converted to use
54
- * cpu_transaction_failed() instead it can be removed.
55
- */
56
- MMUAccessType mem_io_access_type;
57
58
int kvm_fd;
59
struct KVMState *kvm_state;
60
@@ -XXX,XX +XXX,XX @@ void cpu_interrupt(CPUState *cpu, int mask);
61
#ifdef NEED_CPU_H
62
63
#ifdef CONFIG_SOFTMMU
64
-static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr,
65
- bool is_write, bool is_exec,
66
- int opaque, unsigned size)
67
-{
68
- CPUClass *cc = CPU_GET_CLASS(cpu);
69
-
70
- if (cc->do_unassigned_access) {
71
- cc->do_unassigned_access(cpu, addr, is_write, is_exec, opaque, size);
72
- }
73
-}
74
-
75
static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
76
MMUAccessType access_type,
77
int mmu_idx, uintptr_t retaddr)
78
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
40
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
80
--- a/accel/tcg/cputlb.c
42
+++ b/target/arm/helper.c
81
+++ b/accel/tcg/cputlb.c
43
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
82
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
44
#undef VFP_CONV_FIX_A64
83
cpu_io_recompile(cpu, retaddr);
45
84
}
46
/* Conversion to/from f16 can overflow to infinity before/after scaling.
85
47
- * Therefore we convert to f64 (which does not round), scale,
86
- cpu->mem_io_access_type = access_type;
48
- * and then convert f64 to f16 (which may round).
87
-
49
+ * Therefore we convert to f64, scale, and then convert f64 to f16; or
88
if (mr->global_locking && !qemu_mutex_iothread_locked()) {
50
+ * vice versa for conversion to integer.
89
qemu_mutex_lock_iothread();
51
+ *
90
locked = true;
52
+ * For 16- and 32-bit integers, the conversion to f64 never rounds.
91
diff --git a/memory.c b/memory.c
53
+ * For 64-bit integers, any integer that would cause rounding will also
92
index XXXXXXX..XXXXXXX 100644
54
+ * overflow to f16 infinity, so there is no double rounding problem.
93
--- a/memory.c
55
*/
94
+++ b/memory.c
56
95
@@ -XXX,XX +XXX,XX @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
57
static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
96
#ifdef DEBUG_UNASSIGNED
58
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
97
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
59
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
98
#endif
99
- if (current_cpu != NULL) {
100
- bool is_exec = current_cpu->mem_io_access_type == MMU_INST_FETCH;
101
- cpu_unassigned_access(current_cpu, addr, false, is_exec, 0, size);
102
- }
103
return 0;
60
}
104
}
61
105
62
+float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
106
@@ -XXX,XX +XXX,XX @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
63
+{
107
#ifdef DEBUG_UNASSIGNED
64
+ return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
108
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
65
+}
109
#endif
66
+
110
- if (current_cpu != NULL) {
67
+float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
111
- cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
68
+{
112
- }
69
+ return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
70
+}
71
+
72
static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
73
{
74
if (unlikely(float16_is_any_nan(f))) {
75
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
76
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
77
}
113
}
78
114
79
+uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
115
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
80
+{
81
+ return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
82
+}
83
+
84
+uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
85
+{
86
+ return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
87
+}
88
+
89
+uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
90
+{
91
+ return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
92
+}
93
+
94
+uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
95
+{
96
+ return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
97
+}
98
+
99
/* Set the current fp rounding mode and return the old one.
100
* The argument is a softfloat float_round_ value.
101
*/
102
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-a64.c
105
+++ b/target/arm/translate-a64.c
106
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
107
bool itof, int rmode, int scale, int sf, int type)
108
{
109
bool is_signed = !(opcode & 1);
110
- bool is_double = type;
111
TCGv_ptr tcg_fpstatus;
112
- TCGv_i32 tcg_shift;
113
+ TCGv_i32 tcg_shift, tcg_single;
114
+ TCGv_i64 tcg_double;
115
116
- tcg_fpstatus = get_fpstatus_ptr(false);
117
+ tcg_fpstatus = get_fpstatus_ptr(type == 3);
118
119
tcg_shift = tcg_const_i32(64 - scale);
120
121
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
122
tcg_int = tcg_extend;
123
}
124
125
- if (is_double) {
126
- TCGv_i64 tcg_double = tcg_temp_new_i64();
127
+ switch (type) {
128
+ case 1: /* float64 */
129
+ tcg_double = tcg_temp_new_i64();
130
if (is_signed) {
131
gen_helper_vfp_sqtod(tcg_double, tcg_int,
132
tcg_shift, tcg_fpstatus);
133
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
134
}
135
write_fp_dreg(s, rd, tcg_double);
136
tcg_temp_free_i64(tcg_double);
137
- } else {
138
- TCGv_i32 tcg_single = tcg_temp_new_i32();
139
+ break;
140
+
141
+ case 0: /* float32 */
142
+ tcg_single = tcg_temp_new_i32();
143
if (is_signed) {
144
gen_helper_vfp_sqtos(tcg_single, tcg_int,
145
tcg_shift, tcg_fpstatus);
146
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
147
}
148
write_fp_sreg(s, rd, tcg_single);
149
tcg_temp_free_i32(tcg_single);
150
+ break;
151
+
152
+ case 3: /* float16 */
153
+ tcg_single = tcg_temp_new_i32();
154
+ if (is_signed) {
155
+ gen_helper_vfp_sqtoh(tcg_single, tcg_int,
156
+ tcg_shift, tcg_fpstatus);
157
+ } else {
158
+ gen_helper_vfp_uqtoh(tcg_single, tcg_int,
159
+ tcg_shift, tcg_fpstatus);
160
+ }
161
+ write_fp_sreg(s, rd, tcg_single);
162
+ tcg_temp_free_i32(tcg_single);
163
+ break;
164
+
165
+ default:
166
+ g_assert_not_reached();
167
}
168
} else {
169
TCGv_i64 tcg_int = cpu_reg(s, rd);
170
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
171
172
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
173
174
- if (is_double) {
175
- TCGv_i64 tcg_double = read_fp_dreg(s, rn);
176
+ switch (type) {
177
+ case 1: /* float64 */
178
+ tcg_double = read_fp_dreg(s, rn);
179
if (is_signed) {
180
if (!sf) {
181
gen_helper_vfp_tosld(tcg_int, tcg_double,
182
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
183
tcg_shift, tcg_fpstatus);
184
}
185
}
186
+ if (!sf) {
187
+ tcg_gen_ext32u_i64(tcg_int, tcg_int);
188
+ }
189
tcg_temp_free_i64(tcg_double);
190
- } else {
191
- TCGv_i32 tcg_single = read_fp_sreg(s, rn);
192
+ break;
193
+
194
+ case 0: /* float32 */
195
+ tcg_single = read_fp_sreg(s, rn);
196
if (sf) {
197
if (is_signed) {
198
gen_helper_vfp_tosqs(tcg_int, tcg_single,
199
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
200
tcg_temp_free_i32(tcg_dest);
201
}
202
tcg_temp_free_i32(tcg_single);
203
+ break;
204
+
205
+ case 3: /* float16 */
206
+ tcg_single = read_fp_sreg(s, rn);
207
+ if (sf) {
208
+ if (is_signed) {
209
+ gen_helper_vfp_tosqh(tcg_int, tcg_single,
210
+ tcg_shift, tcg_fpstatus);
211
+ } else {
212
+ gen_helper_vfp_touqh(tcg_int, tcg_single,
213
+ tcg_shift, tcg_fpstatus);
214
+ }
215
+ } else {
216
+ TCGv_i32 tcg_dest = tcg_temp_new_i32();
217
+ if (is_signed) {
218
+ gen_helper_vfp_toslh(tcg_dest, tcg_single,
219
+ tcg_shift, tcg_fpstatus);
220
+ } else {
221
+ gen_helper_vfp_toulh(tcg_dest, tcg_single,
222
+ tcg_shift, tcg_fpstatus);
223
+ }
224
+ tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
225
+ tcg_temp_free_i32(tcg_dest);
226
+ }
227
+ tcg_temp_free_i32(tcg_single);
228
+ break;
229
+
230
+ default:
231
+ g_assert_not_reached();
232
}
233
234
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
235
tcg_temp_free_i32(tcg_rmode);
236
-
237
- if (!sf) {
238
- tcg_gen_ext32u_i64(tcg_int, tcg_int);
239
- }
240
}
241
242
tcg_temp_free_ptr(tcg_fpstatus);
243
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
244
/* actual FP conversions */
245
bool itof = extract32(opcode, 1, 1);
246
247
- if (type > 1 || (rmode != 0 && opcode > 1)) {
248
+ if (rmode != 0 && opcode > 1) {
249
+ unallocated_encoding(s);
250
+ return;
251
+ }
252
+ switch (type) {
253
+ case 0: /* float32 */
254
+ case 1: /* float64 */
255
+ break;
256
+ case 3: /* float16 */
257
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
258
+ break;
259
+ }
260
+ /* fallthru */
261
+ default:
262
unallocated_encoding(s);
263
return;
264
}
265
--
116
--
266
2.17.0
117
2.20.1
267
118
268
119
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 17 +++++++++++++++--
11
1 file changed, 15 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
18
bool sf = extract32(insn, 31, 1);
19
bool itof;
20
21
- if (sbit || (type > 1)
22
- || (!sf && scale < 32)) {
23
+ if (sbit || (!sf && scale < 32)) {
24
+ unallocated_encoding(s);
25
+ return;
26
+ }
27
+
28
+ switch (type) {
29
+ case 0: /* float32 */
30
+ case 1: /* float64 */
31
+ break;
32
+ case 3: /* float16 */
33
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
34
+ break;
35
+ }
36
+ /* fallthru */
37
+ default:
38
unallocated_encoding(s);
39
return;
40
}
41
--
42
2.17.0
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 30 ++++++++++++++----------------
11
1 file changed, 14 insertions(+), 16 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
18
return v;
19
}
20
21
+static TCGv_i32 read_fp_hreg(DisasContext *s, int reg)
22
+{
23
+ TCGv_i32 v = tcg_temp_new_i32();
24
+
25
+ tcg_gen_ld16u_i32(v, cpu_env, fp_reg_offset(s, reg, MO_16));
26
+ return v;
27
+}
28
+
29
/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
30
* If SVE is not enabled, then there are only 128 bits in the vector.
31
*/
32
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
33
static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
34
{
35
TCGv_ptr fpst = NULL;
36
- TCGv_i32 tcg_op = tcg_temp_new_i32();
37
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
38
TCGv_i32 tcg_res = tcg_temp_new_i32();
39
40
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
41
-
42
switch (opcode) {
43
case 0x0: /* FMOV */
44
tcg_gen_mov_i32(tcg_res, tcg_op);
45
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
46
tcg_temp_free_i64(tcg_op2);
47
tcg_temp_free_i64(tcg_res);
48
} else {
49
- TCGv_i32 tcg_op1 = tcg_temp_new_i32();
50
- TCGv_i32 tcg_op2 = tcg_temp_new_i32();
51
+ TCGv_i32 tcg_op1 = read_fp_hreg(s, rn);
52
+ TCGv_i32 tcg_op2 = read_fp_hreg(s, rm);
53
TCGv_i64 tcg_res = tcg_temp_new_i64();
54
55
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
56
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
57
-
58
gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
59
gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env, tcg_res, tcg_res);
60
61
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
62
63
fpst = get_fpstatus_ptr(true);
64
65
- tcg_op1 = tcg_temp_new_i32();
66
- tcg_op2 = tcg_temp_new_i32();
67
+ tcg_op1 = read_fp_hreg(s, rn);
68
+ tcg_op2 = read_fp_hreg(s, rm);
69
tcg_res = tcg_temp_new_i32();
70
71
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
72
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
73
-
74
switch (fpopcode) {
75
case 0x03: /* FMULX */
76
gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
77
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
78
}
79
80
if (is_scalar) {
81
- TCGv_i32 tcg_op = tcg_temp_new_i32();
82
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
83
TCGv_i32 tcg_res = tcg_temp_new_i32();
84
85
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
86
-
87
switch (fpop) {
88
case 0x1a: /* FCVTNS */
89
case 0x1b: /* FCVTMS */
90
--
91
2.17.0
92
93
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We missed all of the scalar fp16 binary operations.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180512003217.9105-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 65 ++++++++++++++++++++++++++++++++++++++
13
1 file changed, 65 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
20
tcg_temp_free_i64(tcg_res);
21
}
22
23
+/* Floating-point data-processing (2 source) - half precision */
24
+static void handle_fp_2src_half(DisasContext *s, int opcode,
25
+ int rd, int rn, int rm)
26
+{
27
+ TCGv_i32 tcg_op1;
28
+ TCGv_i32 tcg_op2;
29
+ TCGv_i32 tcg_res;
30
+ TCGv_ptr fpst;
31
+
32
+ tcg_res = tcg_temp_new_i32();
33
+ fpst = get_fpstatus_ptr(true);
34
+ tcg_op1 = read_fp_hreg(s, rn);
35
+ tcg_op2 = read_fp_hreg(s, rm);
36
+
37
+ switch (opcode) {
38
+ case 0x0: /* FMUL */
39
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
40
+ break;
41
+ case 0x1: /* FDIV */
42
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
43
+ break;
44
+ case 0x2: /* FADD */
45
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
46
+ break;
47
+ case 0x3: /* FSUB */
48
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
49
+ break;
50
+ case 0x4: /* FMAX */
51
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
52
+ break;
53
+ case 0x5: /* FMIN */
54
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
55
+ break;
56
+ case 0x6: /* FMAXNM */
57
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
58
+ break;
59
+ case 0x7: /* FMINNM */
60
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
61
+ break;
62
+ case 0x8: /* FNMUL */
63
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
64
+ tcg_gen_xori_i32(tcg_res, tcg_res, 0x8000);
65
+ break;
66
+ default:
67
+ g_assert_not_reached();
68
+ }
69
+
70
+ write_fp_sreg(s, rd, tcg_res);
71
+
72
+ tcg_temp_free_ptr(fpst);
73
+ tcg_temp_free_i32(tcg_op1);
74
+ tcg_temp_free_i32(tcg_op2);
75
+ tcg_temp_free_i32(tcg_res);
76
+}
77
+
78
/* Floating point data-processing (2 source)
79
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
80
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
81
@@ -XXX,XX +XXX,XX @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
82
}
83
handle_fp_2src_double(s, opcode, rd, rn, rm);
84
break;
85
+ case 3:
86
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
87
+ unallocated_encoding(s);
88
+ return;
89
+ }
90
+ if (!fp_access_check(s)) {
91
+ return;
92
+ }
93
+ handle_fp_2src_half(s, opcode, rd, rn, rm);
94
+ break;
95
default:
96
unallocated_encoding(s);
97
}
98
--
99
2.17.0
100
101
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We missed all of the scalar fp16 fma operations.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180512003217.9105-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 48 ++++++++++++++++++++++++++++++++++++++
13
1 file changed, 48 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
20
tcg_temp_free_i64(tcg_res);
21
}
22
23
+/* Floating-point data-processing (3 source) - half precision */
24
+static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
25
+ int rd, int rn, int rm, int ra)
26
+{
27
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
28
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
29
+ TCGv_ptr fpst = get_fpstatus_ptr(true);
30
+
31
+ tcg_op1 = read_fp_hreg(s, rn);
32
+ tcg_op2 = read_fp_hreg(s, rm);
33
+ tcg_op3 = read_fp_hreg(s, ra);
34
+
35
+ /* These are fused multiply-add, and must be done as one
36
+ * floating point operation with no rounding between the
37
+ * multiplication and addition steps.
38
+ * NB that doing the negations here as separate steps is
39
+ * correct : an input NaN should come out with its sign bit
40
+ * flipped if it is a negated-input.
41
+ */
42
+ if (o1 == true) {
43
+ tcg_gen_xori_i32(tcg_op3, tcg_op3, 0x8000);
44
+ }
45
+
46
+ if (o0 != o1) {
47
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
48
+ }
49
+
50
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
51
+
52
+ write_fp_sreg(s, rd, tcg_res);
53
+
54
+ tcg_temp_free_ptr(fpst);
55
+ tcg_temp_free_i32(tcg_op1);
56
+ tcg_temp_free_i32(tcg_op2);
57
+ tcg_temp_free_i32(tcg_op3);
58
+ tcg_temp_free_i32(tcg_res);
59
+}
60
+
61
/* Floating point data-processing (3 source)
62
* 31 30 29 28 24 23 22 21 20 16 15 14 10 9 5 4 0
63
* +---+---+---+-----------+------+----+------+----+------+------+------+
64
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
65
}
66
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
67
break;
68
+ case 3:
69
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
70
+ unallocated_encoding(s);
71
+ return;
72
+ }
73
+ if (!fp_access_check(s)) {
74
+ return;
75
+ }
76
+ handle_fp_3src_half(s, o0, o1, rd, rn, rm, ra);
77
+ break;
78
default:
79
unallocated_encoding(s);
80
}
81
--
82
2.17.0
83
84
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
These where missed out from the rest of the half-precision work.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180512003217.9105-9-richard.henderson@linaro.org
11
[rth: Diagnose lack of FP16 before fp_access_check]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/helper-a64.h | 2 +
16
target/arm/helper-a64.c | 10 +++++
17
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++--------
18
3 files changed, 83 insertions(+), 17 deletions(-)
19
20
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper-a64.h
23
+++ b/target/arm/helper-a64.h
24
@@ -XXX,XX +XXX,XX @@
25
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
26
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
27
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
28
+DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
29
+DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
30
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
31
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
32
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
33
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/helper-a64.c
36
+++ b/target/arm/helper-a64.c
37
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
38
return flags;
39
}
40
41
+uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
42
+{
43
+ return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
44
+}
45
+
46
+uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
47
+{
48
+ return float_rel_to_flags(float16_compare(x, y, fp_status));
49
+}
50
+
51
uint64_t HELPER(vfp_cmps_a64)(float32 x, float32 y, void *fp_status)
52
{
53
return float_rel_to_flags(float32_compare_quiet(x, y, fp_status));
54
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate-a64.c
57
+++ b/target/arm/translate-a64.c
58
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
59
}
60
}
61
62
-static void handle_fp_compare(DisasContext *s, bool is_double,
63
+static void handle_fp_compare(DisasContext *s, int size,
64
unsigned int rn, unsigned int rm,
65
bool cmp_with_zero, bool signal_all_nans)
66
{
67
TCGv_i64 tcg_flags = tcg_temp_new_i64();
68
- TCGv_ptr fpst = get_fpstatus_ptr(false);
69
+ TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16);
70
71
- if (is_double) {
72
+ if (size == MO_64) {
73
TCGv_i64 tcg_vn, tcg_vm;
74
75
tcg_vn = read_fp_dreg(s, rn);
76
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
77
tcg_temp_free_i64(tcg_vn);
78
tcg_temp_free_i64(tcg_vm);
79
} else {
80
- TCGv_i32 tcg_vn, tcg_vm;
81
+ TCGv_i32 tcg_vn = tcg_temp_new_i32();
82
+ TCGv_i32 tcg_vm = tcg_temp_new_i32();
83
84
- tcg_vn = read_fp_sreg(s, rn);
85
+ read_vec_element_i32(s, tcg_vn, rn, 0, size);
86
if (cmp_with_zero) {
87
- tcg_vm = tcg_const_i32(0);
88
+ tcg_gen_movi_i32(tcg_vm, 0);
89
} else {
90
- tcg_vm = read_fp_sreg(s, rm);
91
+ read_vec_element_i32(s, tcg_vm, rm, 0, size);
92
}
93
- if (signal_all_nans) {
94
- gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
95
- } else {
96
- gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
97
+
98
+ switch (size) {
99
+ case MO_32:
100
+ if (signal_all_nans) {
101
+ gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
102
+ } else {
103
+ gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
104
+ }
105
+ break;
106
+ case MO_16:
107
+ if (signal_all_nans) {
108
+ gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
109
+ } else {
110
+ gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
111
+ }
112
+ break;
113
+ default:
114
+ g_assert_not_reached();
115
}
116
+
117
tcg_temp_free_i32(tcg_vn);
118
tcg_temp_free_i32(tcg_vm);
119
}
120
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
121
static void disas_fp_compare(DisasContext *s, uint32_t insn)
122
{
123
unsigned int mos, type, rm, op, rn, opc, op2r;
124
+ int size;
125
126
mos = extract32(insn, 29, 3);
127
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
128
+ type = extract32(insn, 22, 2);
129
rm = extract32(insn, 16, 5);
130
op = extract32(insn, 14, 2);
131
rn = extract32(insn, 5, 5);
132
opc = extract32(insn, 3, 2);
133
op2r = extract32(insn, 0, 3);
134
135
- if (mos || op || op2r || type > 1) {
136
+ if (mos || op || op2r) {
137
+ unallocated_encoding(s);
138
+ return;
139
+ }
140
+
141
+ switch (type) {
142
+ case 0:
143
+ size = MO_32;
144
+ break;
145
+ case 1:
146
+ size = MO_64;
147
+ break;
148
+ case 3:
149
+ size = MO_16;
150
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
151
+ break;
152
+ }
153
+ /* fallthru */
154
+ default:
155
unallocated_encoding(s);
156
return;
157
}
158
@@ -XXX,XX +XXX,XX @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
159
return;
160
}
161
162
- handle_fp_compare(s, type, rn, rm, opc & 1, opc & 2);
163
+ handle_fp_compare(s, size, rn, rm, opc & 1, opc & 2);
164
}
165
166
/* Floating point conditional compare
167
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
168
unsigned int mos, type, rm, cond, rn, op, nzcv;
169
TCGv_i64 tcg_flags;
170
TCGLabel *label_continue = NULL;
171
+ int size;
172
173
mos = extract32(insn, 29, 3);
174
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
175
+ type = extract32(insn, 22, 2);
176
rm = extract32(insn, 16, 5);
177
cond = extract32(insn, 12, 4);
178
rn = extract32(insn, 5, 5);
179
op = extract32(insn, 4, 1);
180
nzcv = extract32(insn, 0, 4);
181
182
- if (mos || type > 1) {
183
+ if (mos) {
184
+ unallocated_encoding(s);
185
+ return;
186
+ }
187
+
188
+ switch (type) {
189
+ case 0:
190
+ size = MO_32;
191
+ break;
192
+ case 1:
193
+ size = MO_64;
194
+ break;
195
+ case 3:
196
+ size = MO_16;
197
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
198
+ break;
199
+ }
200
+ /* fallthru */
201
+ default:
202
unallocated_encoding(s);
203
return;
204
}
205
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
206
gen_set_label(label_match);
207
}
208
209
- handle_fp_compare(s, type, rn, rm, false, op);
210
+ handle_fp_compare(s, size, rn, rm, false, op);
211
212
if (cond < 0x0e) {
213
gen_set_label(label_continue);
214
--
215
2.17.0
216
217
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
These were missed out from the rest of the half-precision work.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180512003217.9105-10-richard.henderson@linaro.org
11
[rth: Fix erroneous check vs type]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/translate-a64.c | 31 +++++++++++++++++++++++++------
16
1 file changed, 25 insertions(+), 6 deletions(-)
17
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
21
+++ b/target/arm/translate-a64.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
23
unsigned int mos, type, rm, cond, rn, rd;
24
TCGv_i64 t_true, t_false, t_zero;
25
DisasCompare64 c;
26
+ TCGMemOp sz;
27
28
mos = extract32(insn, 29, 3);
29
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
30
+ type = extract32(insn, 22, 2);
31
rm = extract32(insn, 16, 5);
32
cond = extract32(insn, 12, 4);
33
rn = extract32(insn, 5, 5);
34
rd = extract32(insn, 0, 5);
35
36
- if (mos || type > 1) {
37
+ if (mos) {
38
+ unallocated_encoding(s);
39
+ return;
40
+ }
41
+
42
+ switch (type) {
43
+ case 0:
44
+ sz = MO_32;
45
+ break;
46
+ case 1:
47
+ sz = MO_64;
48
+ break;
49
+ case 3:
50
+ sz = MO_16;
51
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
52
+ break;
53
+ }
54
+ /* fallthru */
55
+ default:
56
unallocated_encoding(s);
57
return;
58
}
59
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
60
return;
61
}
62
63
- /* Zero extend sreg inputs to 64 bits now. */
64
+ /* Zero extend sreg & hreg inputs to 64 bits now. */
65
t_true = tcg_temp_new_i64();
66
t_false = tcg_temp_new_i64();
67
- read_vec_element(s, t_true, rn, 0, type ? MO_64 : MO_32);
68
- read_vec_element(s, t_false, rm, 0, type ? MO_64 : MO_32);
69
+ read_vec_element(s, t_true, rn, 0, sz);
70
+ read_vec_element(s, t_false, rm, 0, sz);
71
72
a64_test_cc(&c, cond);
73
t_zero = tcg_const_i64(0);
74
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
75
tcg_temp_free_i64(t_false);
76
a64_free_cc(&c);
77
78
- /* Note that sregs write back zeros to the high bits,
79
+ /* Note that sregs & hregs write back zeros to the high bits,
80
and we've already done the zero-extension. */
81
write_fp_dreg(s, rd, t_true);
82
tcg_temp_free_i64(t_true);
83
--
84
2.17.0
85
86
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
All the hard work is already done by vfp_expand_imm, we just need to
4
make sure we pick up the correct size.
5
6
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180512003217.9105-11-richard.henderson@linaro.org
12
[rth: Merge unallocated_encoding check with TCGMemOp conversion.]
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/translate-a64.c | 20 +++++++++++++++++---
17
1 file changed, 17 insertions(+), 3 deletions(-)
18
19
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a64.c
22
+++ b/target/arm/translate-a64.c
23
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
24
{
25
int rd = extract32(insn, 0, 5);
26
int imm8 = extract32(insn, 13, 8);
27
- int is_double = extract32(insn, 22, 2);
28
+ int type = extract32(insn, 22, 2);
29
uint64_t imm;
30
TCGv_i64 tcg_res;
31
+ TCGMemOp sz;
32
33
- if (is_double > 1) {
34
+ switch (type) {
35
+ case 0:
36
+ sz = MO_32;
37
+ break;
38
+ case 1:
39
+ sz = MO_64;
40
+ break;
41
+ case 3:
42
+ sz = MO_16;
43
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
44
+ break;
45
+ }
46
+ /* fallthru */
47
+ default:
48
unallocated_encoding(s);
49
return;
50
}
51
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
52
return;
53
}
54
55
- imm = vfp_expand_imm(MO_32 + is_double, imm8);
56
+ imm = vfp_expand_imm(sz, imm8);
57
58
tcg_res = tcg_const_i64(imm);
59
write_fp_dreg(s, rd, tcg_res);
60
--
61
2.17.0
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
We are meant to explicitly pass fpst, not cpu_env.
4
5
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180512003217.9105-12-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-a64.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
21
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
22
break;
23
case 0x3: /* FSQRT */
24
- gen_helper_sqrt_f16(tcg_res, tcg_op, cpu_env);
25
+ fpst = get_fpstatus_ptr(true);
26
+ gen_helper_sqrt_f16(tcg_res, tcg_op, fpst);
27
break;
28
case 0x8: /* FRINTN */
29
case 0x9: /* FRINTP */
30
--
31
2.17.0
32
33
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Clement Deschamps <clement.deschamps@greensocs.com>
2
2
3
Per the Physical Layer Simplified Spec. "4.3.10.4 Switch Function Status":
3
The boot.c code usually puts the CPU into NS mode directly when it is
4
booting a kernel. Since fc1120a7f5f2d4b6 this has included a
5
requirement to set NSACR to give NS state access to the FPU; we fixed
6
that for the usual code path in ece628fcf6. However, it is also
7
possible for a board model to request an alternative mode of booting,
8
where its 'board_setup' code hook runs in Secure state and is
9
responsible for doing the S->NS transition after it has done whatever
10
work it must do in Secure state. In this situation the board_setup
11
code now also needs to update NSACR.
4
12
5
The block length is predefined to 512 bits
13
This affects all boards which set info->secure_board_setup, which is
14
currently the 'raspi' and 'highbank' families. They both use the
15
common arm_write_secure_board_setup_dummy_smc().
6
16
7
and "4.10.2 SD Status":
17
Set the NSACR CP11 and CP10 bits in the code written by that
18
function, to allow FPU access in Non-Secure state when using dummy
19
SMC setup routine. Otherwise an AArch32 kernel booted on the
20
highbank or raspi boards will UNDEF as soon as it tries to use the
21
FPU.
8
22
9
The SD Status contains status bits that are related to the SD Memory Card
23
Update the comment describing secure_board_setup to note the new
10
proprietary features and may be used for future application-specific usage.
24
requirements on users of it.
11
The size of the SD Status is one data block of 512 bit. The content of this
12
register is transmitted to the Host over the DAT bus along with a 16-bit CRC.
13
25
14
Thus the 16-bit CRC goes at offset 64.
26
This fixes a kernel panic when booting raspbian on raspi2.
15
27
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
28
Successfully tested with:
17
Message-id: 20180509060104.4458-3-f4bug@amsat.org
29
2017-01-11-raspbian-jessie-lite.img
30
2018-11-13-raspbian-stretch-lite.img
31
2019-07-10-raspbian-buster-lite.img
32
33
Fixes: fc1120a7f5
34
Signed-off-by: Clement Deschamps <clement.deschamps@greensocs.com>
35
Tested-by: Laurent Bonnans <laurent.bonnans@here.com>
36
Message-id: 20191104151137.81931-1-clement.deschamps@greensocs.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
37
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
38
[PMM: updated comment to boot.h to note new requirement on
39
users of secure_board_setup; edited/rewrote commit message]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
41
---
21
hw/sd/sd.c | 2 +-
42
include/hw/arm/boot.h | 7 +++++--
22
1 file changed, 1 insertion(+), 1 deletion(-)
43
hw/arm/boot.c | 3 +++
44
2 files changed, 8 insertions(+), 2 deletions(-)
23
45
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
46
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
25
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
48
--- a/include/hw/arm/boot.h
27
+++ b/hw/sd/sd.c
49
+++ b/include/hw/arm/boot.h
28
@@ -XXX,XX +XXX,XX @@ static void sd_function_switch(SDState *sd, uint32_t arg)
50
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info {
29
sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
51
void (*write_board_setup)(ARMCPU *cpu,
30
}
52
const struct arm_boot_info *info);
31
memset(&sd->data[17], 0, 47);
53
32
- stw_be_p(sd->data + 65, sd_crc16(sd->data, 64));
54
- /* If set, the board specific loader/setup blob will be run from secure
33
+ stw_be_p(sd->data + 64, sd_crc16(sd->data, 64));
55
+ /*
34
}
56
+ * If set, the board specific loader/setup blob will be run from secure
35
57
* mode, regardless of secure_boot. The blob becomes responsible for
36
static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
58
- * changing to non-secure state if implementing a non-secure boot
59
+ * changing to non-secure state if implementing a non-secure boot,
60
+ * including setting up EL3/Secure registers such as the NSACR as
61
+ * required by the Linux booting ABI before the switch to non-secure.
62
*/
63
bool secure_board_setup;
64
65
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/boot.c
68
+++ b/hw/arm/boot.c
69
@@ -XXX,XX +XXX,XX @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
70
};
71
uint32_t board_setup_blob[] = {
72
/* board setup addr */
73
+ 0xee110f51, /* mrc p15, 0, r0, c1, c1, 2 ;read NSACR */
74
+ 0xe3800b03, /* orr r0, #0xc00 ;set CP11, CP10 */
75
+ 0xee010f51, /* mcr p15, 0, r0, c1, c1, 2 ;write NSACR */
76
0xe3a00e00 + (mvbar_addr >> 4), /* mov r0, #mvbar_addr */
77
0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 ;set MVBAR */
78
0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 ;read SCR */
37
--
79
--
38
2.17.0
80
2.20.1
39
81
40
82
diff view generated by jsdifflib