75 lines
2.3 KiB
Diff
75 lines
2.3 KiB
Diff
|
|
From ea7c41f4146774298ed8210e2cc3e28f7d610675 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Liu Jing <liujing_yewu@cmss.chinamobile.com>
|
||
|
|
Date: Mon, 21 Oct 2024 19:03:19 +0800
|
||
|
|
Subject: [PATCH] target/m68k: Implement atomic test-and-set
|
||
|
|
|
||
|
|
This is slightly more complicated than cas,
|
||
|
|
because tas is allowed on data registers.
|
||
|
|
|
||
|
|
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||
|
|
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
|
||
|
|
Message-Id: <20220829051746.227094-1-richard.henderson@linaro.org>
|
||
|
|
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
|
||
|
|
Signed-off-by: Liu Jing <liujing_yewu@cmss.chinamobile.com>
|
||
|
|
---
|
||
|
|
target/m68k/translate.c | 40 ++++++++++++++++++++++++++++++----------
|
||
|
|
1 file changed, 30 insertions(+), 10 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
|
||
|
|
index af43c8eab8..3a7c4c5231 100644
|
||
|
|
--- a/target/m68k/translate.c
|
||
|
|
+++ b/target/m68k/translate.c
|
||
|
|
@@ -2809,19 +2809,39 @@ DISAS_INSN(illegal)
|
||
|
|
gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
|
||
|
|
}
|
||
|
|
|
||
|
|
-/* ??? This should be atomic. */
|
||
|
|
DISAS_INSN(tas)
|
||
|
|
{
|
||
|
|
- TCGv dest;
|
||
|
|
- TCGv src1;
|
||
|
|
- TCGv addr;
|
||
|
|
+ int mode = extract32(insn, 3, 3);
|
||
|
|
+ int reg0 = REG(insn, 0);
|
||
|
|
|
||
|
|
- dest = tcg_temp_new();
|
||
|
|
- SRC_EA(env, src1, OS_BYTE, 1, &addr);
|
||
|
|
- gen_logic_cc(s, src1, OS_BYTE);
|
||
|
|
- tcg_gen_ori_i32(dest, src1, 0x80);
|
||
|
|
- DEST_EA(env, insn, OS_BYTE, dest, &addr);
|
||
|
|
- tcg_temp_free(dest);
|
||
|
|
+ if (mode == 0) {
|
||
|
|
+ /* data register direct */
|
||
|
|
+ TCGv dest = cpu_dregs[reg0];
|
||
|
|
+ gen_logic_cc(s, dest, OS_BYTE);
|
||
|
|
+ tcg_gen_ori_tl(dest, dest, 0x80);
|
||
|
|
+ } else {
|
||
|
|
+ TCGv src1, addr;
|
||
|
|
+
|
||
|
|
+ addr = gen_lea_mode(env, s, mode, reg0, OS_BYTE);
|
||
|
|
+ if (IS_NULL_QREG(addr)) {
|
||
|
|
+ gen_addr_fault(s);
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+ src1 = tcg_temp_new();
|
||
|
|
+ tcg_gen_atomic_fetch_or_tl(src1, addr, tcg_constant_tl(0x80),
|
||
|
|
+ IS_USER(s), MO_SB);
|
||
|
|
+ gen_logic_cc(s, src1, OS_BYTE);
|
||
|
|
+ tcg_temp_free(src1);
|
||
|
|
+
|
||
|
|
+ switch (mode) {
|
||
|
|
+ case 3: /* Indirect postincrement. */
|
||
|
|
+ tcg_gen_addi_i32(AREG(insn, 0), addr, 1);
|
||
|
|
+ break;
|
||
|
|
+ case 4: /* Indirect predecrememnt. */
|
||
|
|
+ tcg_gen_mov_i32(AREG(insn, 0), addr);
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
DISAS_INSN(mull)
|
||
|
|
--
|
||
|
|
2.41.0.windows.1
|
||
|
|
|