From patchwork Fri Jul 26 17:49:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 169884 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp357663ilk; Fri, 26 Jul 2019 10:55:22 -0700 (PDT) X-Google-Smtp-Source: APXvYqzn6uHG1nSgARpey5rgX/lRihQlVUDmi7abx+Dowi2tgFrIBDmoZ1U2ACNj0tiCafFQCTxB X-Received: by 2002:a05:6402:14d4:: with SMTP id f20mr81897768edx.125.1564163722155; Fri, 26 Jul 2019 10:55:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564163722; cv=none; d=google.com; s=arc-20160816; b=uNjO1W6tVuIFso4swI6kbyyIOnv/vproLNPn2Tnaht9Jr2WFNxPEziiWRAxNwEpyF8 2WseZ8uCNKnESb9Q18C5U67q11Fe9lNu+KTReiHJojhgeI3qjHodEBiEzHpWAr9fmkbX ll0kXFLgOF0tXs8hx1k5PJEgKj36ax50AHbet3ky3xwj3OHqtoskVyborCB45q+1Dv6i v9U75bKsm6L6g1854CimVsDkZNZlTjXPmn3Yv8PBy/lZFdP+3+MhS8F+rWeJOVcs/ZmK PUO+0FZi5YOxscFs7BqoKFqozYqYlSTV2+3tfUmNDTLoA0FtQ0zr4ZoB1m/IeT3J4y0v osgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=UQ07c4ep2Pcf/e+Y3eYe2vH+RAjRFAYTFfhUhpRt/AQ=; b=VSBYxREhr7mQNNGRjMaGf08eLMYvOHzPyF1CbP42sam/CZsRo/cvYxgySFQ/vfZMHm O7LuBN2Pchem9FZlPpqEOmeTdbU9adYaUo1ZEIhos0ApUvHbhHm6na5COpKipUEiBhc3 +kCY9C1C3su8IzzC1oS62LUNOfIRhlHkwiZ4+XDz0mtaMeK4TgJNeyGdWhIgIj3XFahx inmbGJXrq1vxmtrAQDrAdylN0NQhAEuFQC425PRzgcmIQcs3n8NM/c0/89FRDQuNMiYL 5q1cvURBcbhd3yKsU93xMB9uREtiBidVRvHHhPfzHIuPUnujSnI8gpJXjdGZ8bIKwQYY /jiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=w0w6krZ0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k27si13258803edb.284.2019.07.26.10.55.21 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 26 Jul 2019 10:55:22 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=w0w6krZ0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:42366 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hr4R3-0004EX-GX for patch@linaro.org; Fri, 26 Jul 2019 13:55:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57960) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hr4N0-0003QQ-CF for qemu-devel@nongnu.org; Fri, 26 Jul 2019 13:51:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hr4Mw-0008Fn-Pw for qemu-devel@nongnu.org; Fri, 26 Jul 2019 13:51:06 -0400 Received: from mail-pl1-x642.google.com ([2607:f8b0:4864:20::642]:46755) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hr4Mw-0008EN-Fu for qemu-devel@nongnu.org; Fri, 26 Jul 2019 13:51:02 -0400 Received: by mail-pl1-x642.google.com with SMTP id c2so24992705plz.13 for ; Fri, 26 Jul 2019 10:51:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UQ07c4ep2Pcf/e+Y3eYe2vH+RAjRFAYTFfhUhpRt/AQ=; b=w0w6krZ0XFNimoa4tsqekOt61XoTXIyXXy21HpBq+A2hST4ENC8fLgpJMNAXjiE1hD p9xQLUfXOQ45KE04NiCiWW1IQIOQ/2LnSv9MuJFCcqIQSOiQI7miDuXecMo/z3ylAT8z oRF0OCesIyhP8GhinVT2tjUYclunUlG3XymPuZ/dhtVQhzGplEkKkHszPYtZt55/MPKi CQG3M8jT74DbTa++vaRW206xXwZv0cb6Baa/8NP84zRnCBSjYIyshezo8nVvrvo1XE1O ULaggsk/8j5ShP0lcY6U9hy04hHQDNxIO7R28Ez2+GCtLR3cAzbhpRFqaxpP03HHr/DK dXbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=UQ07c4ep2Pcf/e+Y3eYe2vH+RAjRFAYTFfhUhpRt/AQ=; b=L+HGpMGXsUJttOBvjOX0NurnYC5zk53JXP7n8rO2npFNnvYGal8spaLpxnPyYbINgj NQjtv1TbHVBT/r6GXyN8Ud/hGg/oH+C8nlZQFHzxol+4lRwAyJ81j+m0H6SudL51zKN/ lhKYYCytdJpCxLwrxj5eZ1zw1kSrU9wJQ1zWiweof0an3DHqwOesiABU2p8rcEI+0L4g DW3ZJRMsk0J3wWspWZxI2dIk1SLWHzY5iyvy8nY/ispg6kijAEo6weosFdTkmbHgf2nT XHMcFpQ4NNGwparLIWXaDEOj8jrKMI6m+DzTyZIG1NYl2LA5Vxogym1mAkHTPRDFR2sx EIXA== X-Gm-Message-State: APjAAAXHEfXdRjuyGFb00P15ZLv5I8mF8poFS0Qig8mFJZ6SiXn63rwK 3lARI+dDIKofBk/1QGEBaFEUSRnr/aE= X-Received: by 2002:a17:902:f301:: with SMTP id gb1mr95883003plb.292.1564163461023; Fri, 26 Jul 2019 10:51:01 -0700 (PDT) Received: from localhost.localdomain (97-126-117-207.tukw.qwest.net. [97.126.117.207]) by smtp.gmail.com with ESMTPSA id o24sm104287919pfp.135.2019.07.26.10.51.00 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 26 Jul 2019 10:51:00 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 26 Jul 2019 10:49:48 -0700 Message-Id: <20190726175032.6769-24-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190726175032.6769-1-richard.henderson@linaro.org> References: <20190726175032.6769-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::642 Subject: [Qemu-devel] [PATCH 23/67] target/arm: Convert Synchronization primitives X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, qemu-arm@nongnu.org, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- target/arm/translate.c | 560 ++++++++++++++++++++++------------------- target/arm/a32.decode | 48 ++++ target/arm/t32.decode | 46 ++++ 3 files changed, 396 insertions(+), 258 deletions(-) -- 2.17.1 diff --git a/target/arm/translate.c b/target/arm/translate.c index 73cb624ebd..74e54b7efb 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -8890,6 +8890,302 @@ DO_LDST(STRH, store, MO_UW) #undef DO_LDST +/* + * Synchronization primitives + */ + +static bool op_swp(DisasContext *s, arg_SWP *a, TCGMemOp opc) +{ + TCGv_i32 addr, tmp; + TCGv taddr; + + opc |= s->be_data; + addr = load_reg(s, a->rn); + taddr = gen_aa32_addr(s, addr, opc); + tcg_temp_free_i32(addr); + + tmp = load_reg(s, a->rt2); + tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc); + tcg_temp_free(taddr); + + store_reg(s, a->rt, tmp); + return true; +} + +static bool trans_SWP(DisasContext *s, arg_SWP *a) +{ + return op_swp(s, a, MO_UL | MO_ALIGN); +} + +static bool trans_SWPB(DisasContext *s, arg_SWP *a) +{ + return op_swp(s, a, MO_UB); +} + +/* + * Load/Store Exclusive and Load-Acquire/Store-Release + */ + +static bool op_strex(DisasContext *s, arg_STREX *a, TCGMemOp mop, bool rel) +{ + TCGv_i32 addr; + + if (rel) { + tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); + } + + addr = tcg_temp_local_new_i32(); + load_reg_var(s, addr, a->rn); + tcg_gen_addi_i32(addr, addr, a->imm); + + gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop); + tcg_temp_free_i32(addr); + return true; +} + +static bool trans_STREX(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_6) { + return false; + } + return op_strex(s, a, MO_32, false); +} + +static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_6K || (a->rt & 1)) { + return false; + } + a->rt2 = a->rt + 1; + return op_strex(s, a, MO_64, false); +} + +static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a) +{ + return op_strex(s, a, MO_64, false); +} + +static bool trans_STREXB(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_6K) { + return false; + } + return op_strex(s, a, MO_8, false); +} + +static bool trans_STREXH(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_6K) { + return false; + } + return op_strex(s, a, MO_16, false); +} + +static bool trans_STLEX(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_strex(s, a, MO_32, true); +} + +static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_8 || (a->rt & 1)) { + return false; + } + a->rt2 = a->rt + 1; + return op_strex(s, a, MO_64, true); +} + +static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_strex(s, a, MO_64, true); +} + +static bool trans_STLEXB(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_strex(s, a, MO_8, true); +} + +static bool trans_STLEXH(DisasContext *s, arg_STREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_strex(s, a, MO_16, true); +} + +static bool op_stl(DisasContext *s, arg_STL *a, TCGMemOp mop) +{ + TCGv_i32 addr, tmp; + + if (!ENABLE_ARCH_8) { + return false; + } + addr = load_reg(s, a->rn); + + tmp = load_reg(s, a->rt); + tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); + gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data); + disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite); + + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(addr); + return true; +} + +static bool trans_STL(DisasContext *s, arg_STL *a) +{ + return op_stl(s, a, MO_UL); +} + +static bool trans_STLB(DisasContext *s, arg_STL *a) +{ + return op_stl(s, a, MO_UB); +} + +static bool trans_STLH(DisasContext *s, arg_STL *a) +{ + return op_stl(s, a, MO_UW); +} + +static bool op_ldrex(DisasContext *s, arg_LDREX *a, TCGMemOp mop, bool acq) +{ + TCGv_i32 addr; + + addr = tcg_temp_local_new_i32(); + load_reg_var(s, addr, a->rn); + tcg_gen_addi_i32(addr, addr, a->imm); + + gen_load_exclusive(s, a->rt, a->rt2, addr, mop); + tcg_temp_free_i32(addr); + + if (acq) { + tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ); + } + return true; +} + +static bool trans_LDREX(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_6) { + return false; + } + return op_ldrex(s, a, MO_32, false); +} + +static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_6K || (a->rt & 1)) { + return false; + } + a->rt2 = a->rt + 1; + return op_ldrex(s, a, MO_64, false); +} + +static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a) +{ + return op_ldrex(s, a, MO_64, false); +} + +static bool trans_LDREXB(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_6K) { + return false; + } + return op_ldrex(s, a, MO_8, false); +} + +static bool trans_LDREXH(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_6K) { + return false; + } + return op_ldrex(s, a, MO_16, false); +} + +static bool trans_LDAEX(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_ldrex(s, a, MO_32, true); +} + +static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_8 || (a->rt & 1)) { + return false; + } + a->rt2 = a->rt + 1; + return op_ldrex(s, a, MO_64, true); +} + +static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_ldrex(s, a, MO_64, true); +} + +static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_ldrex(s, a, MO_8, true); +} + +static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a) +{ + if (!ENABLE_ARCH_8) { + return false; + } + return op_ldrex(s, a, MO_16, true); +} + +static bool op_lda(DisasContext *s, arg_LDA *a, TCGMemOp mop) +{ + TCGv_i32 addr, tmp; + + if (!ENABLE_ARCH_8) { + return false; + } + addr = load_reg(s, a->rn); + + tmp = tcg_temp_new_i32(); + gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data); + disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel); + tcg_temp_free_i32(addr); + + store_reg(s, a->rt, tmp); + tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); + return true; +} + +static bool trans_LDA(DisasContext *s, arg_LDA *a) +{ + return op_lda(s, a, MO_UL); +} + +static bool trans_LDAB(DisasContext *s, arg_LDA *a) +{ + return op_lda(s, a, MO_UB); +} + +static bool trans_LDAH(DisasContext *s, arg_LDA *a) +{ + return op_lda(s, a, MO_UW); +} + /* * Legacy decoder. */ @@ -9182,172 +9478,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) case 0x0: case 0x1: /* multiplies, extra load/stores */ - sh = (insn >> 5) & 3; - if (sh == 0) { - if (op1 == 0x0) { - /* Multiply and multiply accumulate. */ - /* All done in decodetree. Reach here for illegal ops. */ - goto illegal_op; - } else { - rn = (insn >> 16) & 0xf; - rd = (insn >> 12) & 0xf; - if (insn & (1 << 23)) { - /* load/store exclusive */ - bool is_ld = extract32(insn, 20, 1); - bool is_lasr = !extract32(insn, 8, 1); - int op2 = (insn >> 8) & 3; - op1 = (insn >> 21) & 0x3; - - switch (op2) { - case 0: /* lda/stl */ - if (op1 == 1) { - goto illegal_op; - } - ARCH(8); - break; - case 1: /* reserved */ - goto illegal_op; - case 2: /* ldaex/stlex */ - ARCH(8); - break; - case 3: /* ldrex/strex */ - if (op1) { - ARCH(6K); - } else { - ARCH(6); - } - break; - } - - addr = tcg_temp_local_new_i32(); - load_reg_var(s, addr, rn); - - if (is_lasr && !is_ld) { - tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); - } - - if (op2 == 0) { - if (is_ld) { - tmp = tcg_temp_new_i32(); - switch (op1) { - case 0: /* lda */ - gen_aa32_ld32u_iss(s, tmp, addr, - get_mem_index(s), - rd | ISSIsAcqRel); - break; - case 2: /* ldab */ - gen_aa32_ld8u_iss(s, tmp, addr, - get_mem_index(s), - rd | ISSIsAcqRel); - break; - case 3: /* ldah */ - gen_aa32_ld16u_iss(s, tmp, addr, - get_mem_index(s), - rd | ISSIsAcqRel); - break; - default: - abort(); - } - store_reg(s, rd, tmp); - } else { - rm = insn & 0xf; - tmp = load_reg(s, rm); - switch (op1) { - case 0: /* stl */ - gen_aa32_st32_iss(s, tmp, addr, - get_mem_index(s), - rm | ISSIsAcqRel); - break; - case 2: /* stlb */ - gen_aa32_st8_iss(s, tmp, addr, - get_mem_index(s), - rm | ISSIsAcqRel); - break; - case 3: /* stlh */ - gen_aa32_st16_iss(s, tmp, addr, - get_mem_index(s), - rm | ISSIsAcqRel); - break; - default: - abort(); - } - tcg_temp_free_i32(tmp); - } - } else if (is_ld) { - switch (op1) { - case 0: /* ldrex */ - gen_load_exclusive(s, rd, 15, addr, 2); - break; - case 1: /* ldrexd */ - gen_load_exclusive(s, rd, rd + 1, addr, 3); - break; - case 2: /* ldrexb */ - gen_load_exclusive(s, rd, 15, addr, 0); - break; - case 3: /* ldrexh */ - gen_load_exclusive(s, rd, 15, addr, 1); - break; - default: - abort(); - } - } else { - rm = insn & 0xf; - switch (op1) { - case 0: /* strex */ - gen_store_exclusive(s, rd, rm, 15, addr, 2); - break; - case 1: /* strexd */ - gen_store_exclusive(s, rd, rm, rm + 1, addr, 3); - break; - case 2: /* strexb */ - gen_store_exclusive(s, rd, rm, 15, addr, 0); - break; - case 3: /* strexh */ - gen_store_exclusive(s, rd, rm, 15, addr, 1); - break; - default: - abort(); - } - } - tcg_temp_free_i32(addr); - - if (is_lasr && is_ld) { - tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ); - } - } else if ((insn & 0x00300f00) == 0) { - /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx - * - SWP, SWPB - */ - - TCGv taddr; - TCGMemOp opc = s->be_data; - - rm = (insn) & 0xf; - - if (insn & (1 << 22)) { - opc |= MO_UB; - } else { - opc |= MO_UL | MO_ALIGN; - } - - addr = load_reg(s, rn); - taddr = gen_aa32_addr(s, addr, opc); - tcg_temp_free_i32(addr); - - tmp = load_reg(s, rm); - tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, - get_mem_index(s), opc); - tcg_temp_free(taddr); - store_reg(s, rd, tmp); - } else { - goto illegal_op; - } - } - } else { - /* Extra load/store (register) instructions */ - /* All done in decodetree. Reach here for illegal ops. */ - goto illegal_op; - } + /* All done in decodetree. Reach here for illegal ops. */ + goto illegal_op; break; case 0x4: case 0x5: @@ -9994,15 +10126,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) } goto illegal_op; } - addr = tcg_temp_local_new_i32(); - load_reg_var(s, addr, rn); - tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2); - if (insn & (1 << 20)) { - gen_load_exclusive(s, rs, 15, addr, 2); - } else { - gen_store_exclusive(s, rd, rs, 15, addr, 2); - } - tcg_temp_free_i32(addr); + /* Load/store exclusive, in decodetree */ + goto illegal_op; } else if ((insn & (7 << 5)) == 0) { /* Table Branch. */ if (rn == 15) { @@ -10029,89 +10154,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) tcg_gen_addi_i32(tmp, tmp, s->pc_read); store_reg(s, 15, tmp); } else { - bool is_lasr = false; - bool is_ld = extract32(insn, 20, 1); - int op2 = (insn >> 6) & 0x3; - op = (insn >> 4) & 0x3; - switch (op2) { - case 0: - goto illegal_op; - case 1: - /* Load/store exclusive byte/halfword/doubleword */ - if (op == 2) { - goto illegal_op; - } - ARCH(7); - break; - case 2: - /* Load-acquire/store-release */ - if (op == 3) { - goto illegal_op; - } - /* Fall through */ - case 3: - /* Load-acquire/store-release exclusive */ - ARCH(8); - is_lasr = true; - break; - } - - if (is_lasr && !is_ld) { - tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); - } - - addr = tcg_temp_local_new_i32(); - load_reg_var(s, addr, rn); - if (!(op2 & 1)) { - if (is_ld) { - tmp = tcg_temp_new_i32(); - switch (op) { - case 0: /* ldab */ - gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), - rs | ISSIsAcqRel); - break; - case 1: /* ldah */ - gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), - rs | ISSIsAcqRel); - break; - case 2: /* lda */ - gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), - rs | ISSIsAcqRel); - break; - default: - abort(); - } - store_reg(s, rs, tmp); - } else { - tmp = load_reg(s, rs); - switch (op) { - case 0: /* stlb */ - gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), - rs | ISSIsAcqRel); - break; - case 1: /* stlh */ - gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), - rs | ISSIsAcqRel); - break; - case 2: /* stl */ - gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), - rs | ISSIsAcqRel); - break; - default: - abort(); - } - tcg_temp_free_i32(tmp); - } - } else if (is_ld) { - gen_load_exclusive(s, rs, rd, addr, op); - } else { - gen_store_exclusive(s, rm, rs, rd, addr, op); - } - tcg_temp_free_i32(addr); - - if (is_lasr && is_ld) { - tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ); - } + /* Load/store exclusive, load-acq/store-rel, in decodetree */ + goto illegal_op; } } else { /* Load/store multiple, RFE, SRS. */ diff --git a/target/arm/a32.decode b/target/arm/a32.decode index 9789042ca0..1267cebaf4 100644 --- a/target/arm/a32.decode +++ b/target/arm/a32.decode @@ -39,6 +39,8 @@ &mrs_bank rd r sysm &ldst_rr p w u rn rt rm shimm shtype &ldst_ri p w u rn rt imm +&strex rn rd rt rt2 imm +&ldrex rn rt rt2 imm # Data-processing (register) @@ -342,3 +344,49 @@ STRT_ri .... 010. .0.0 .... .... ............ @ldst_ri12_p0w1 STRBT_ri .... 010. .1.0 .... .... ............ @ldst_ri12_p0w1 LDRT_ri .... 010. .0.1 .... .... ............ @ldst_ri12_p0w1 LDRBT_ri .... 010. .1.1 .... .... ............ @ldst_ri12_p0w1 + +# Synchronization primitives + +@swp ---- .... .... rn:4 rt:4 .... .... rt2:4 + +SWP .... 0001 0000 .... .... 0000 1001 .... @swp +SWPB .... 0001 0100 .... .... 0000 1001 .... @swp + +# Load/Store Exclusive and Load-Acquire/Store-Release +# +# Note rt2 for STREXD/LDREXD is set by the helper after checking rt is even. + +@strex ---- .... .... rn:4 rd:4 .... .... rt:4 \ + &strex imm=0 rt2=15 +@ldrex ---- .... .... rn:4 rt:4 .... .... .... \ + &ldrex imm=0 rt2=15 +@stl ---- .... .... rn:4 .... .... .... rt:4 \ + &ldrex imm=0 rt2=15 + +STREX .... 0001 1000 .... .... 1111 1001 .... @strex +STREXD_a32 .... 0001 1010 .... .... 1111 1001 .... @strex +STREXB .... 0001 1100 .... .... 1111 1001 .... @strex +STREXH .... 0001 1110 .... .... 1111 1001 .... @strex + +STLEX .... 0001 1000 .... .... 1110 1001 .... @strex +STLEXD_a32 .... 0001 1010 .... .... 1110 1001 .... @strex +STLEXB .... 0001 1100 .... .... 1110 1001 .... @strex +STLEXH .... 0001 1110 .... .... 1110 1001 .... @strex + +STL .... 0001 1000 .... 1111 1100 1001 .... @stl +STLB .... 0001 1100 .... 1111 1100 1001 .... @stl +STLH .... 0001 1110 .... 1111 1100 1001 .... @stl + +LDREX .... 0001 1001 .... .... 1111 1001 1111 @ldrex +LDREXD_a32 .... 0001 1011 .... .... 1111 1001 1111 @ldrex +LDREXB .... 0001 1101 .... .... 1111 1001 1111 @ldrex +LDREXH .... 0001 1111 .... .... 1111 1001 1111 @ldrex + +LDAEX .... 0001 1001 .... .... 1110 1001 1111 @ldrex +LDAEXD_a32 .... 0001 1011 .... .... 1110 1001 1111 @ldrex +LDAEXB .... 0001 1101 .... .... 1110 1001 1111 @ldrex +LDAEXH .... 0001 1111 .... .... 1110 1001 1111 @ldrex + +LDA .... 0001 1001 .... .... 1100 1001 1111 @ldrex +LDAB .... 0001 1101 .... .... 1100 1001 1111 @ldrex +LDAH .... 0001 1111 .... .... 1100 1001 1111 @ldrex diff --git a/target/arm/t32.decode b/target/arm/t32.decode index 0d379ed0d9..62bcf60d57 100644 --- a/target/arm/t32.decode +++ b/target/arm/t32.decode @@ -36,6 +36,8 @@ &mrs_bank !extern rd r sysm &ldst_rr !extern p w u rn rt rm shimm shtype &ldst_ri !extern p w u rn rt imm +&strex !extern rn rd rt rt2 imm +&ldrex !extern rn rt rt2 imm # Data-processing (register-shifted register) @@ -392,3 +394,47 @@ LDRD_ri_t32 1110 1001 .101 .... .... .... ........ @ldstd_ri8 w=0 p=1 STRD_ri_t32 1110 1001 .110 .... .... .... ........ @ldstd_ri8 w=1 p=1 LDRD_ri_t32 1110 1001 .111 .... .... .... ........ @ldstd_ri8 w=1 p=1 + +# Load/Store Exclusive and Load-Acquire/Store-Release + +@strex_i .... .... .... rn:4 rt:4 rd:4 .... .... \ + &strex rt2=15 imm=%imm8x4 +@strex_0 .... .... .... rn:4 rt:4 .... .... rd:4 \ + &strex rt2=15 imm=0 +@strex_d .... .... .... rn:4 rt:4 rt2:4 .... rd:4 \ + &strex imm=0 + +@ldrex_i .... .... .... rn:4 rt:4 .... .... .... \ + &ldrex rt2=15 imm=%imm8x4 +@ldrex_0 .... .... .... rn:4 rt:4 .... .... .... \ + &ldrex rt2=15 imm=0 +@ldrex_d .... .... .... rn:4 rt:4 rt2:4 .... .... \ + &ldrex imm=0 + +STREX 1110 1000 0100 .... .... .... .... .... @strex_i +STREXB 1110 1000 1100 .... .... 1111 0100 .... @strex_0 +STREXH 1110 1000 1100 .... .... 1111 0101 .... @strex_0 +STREXD_t32 1110 1000 1100 .... .... .... 0111 .... @strex_d + +STLEX 1110 1000 1100 .... .... 1111 1110 .... @strex_0 +STLEXB 1110 1000 1100 .... .... 1111 1100 .... @strex_0 +STLEXH 1110 1000 1100 .... .... 1111 1101 .... @strex_0 +STLEXD_t32 1110 1000 1100 .... .... .... 1111 .... @strex_d + +STL 1110 1000 1100 .... .... 1111 1010 1111 @ldrex_0 +STLB 1110 1000 1100 .... .... 1111 1000 1111 @ldrex_0 +STLH 1110 1000 1100 .... .... 1111 1001 1111 @ldrex_0 + +LDREX 1110 1000 0101 .... .... 1111 .... .... @ldrex_i +LDREXB 1110 1000 1101 .... .... 1111 0100 1111 @ldrex_0 +LDREXH 1110 1000 1101 .... .... 1111 0101 1111 @ldrex_0 +LDREXD_t32 1110 1000 1101 .... .... .... 0111 1111 @ldrex_d + +LDAEX 1110 1000 1101 .... .... 1111 1110 1111 @ldrex_0 +LDAEXB 1110 1000 1101 .... .... 1111 1100 1111 @ldrex_0 +LDAEXH 1110 1000 1101 .... .... 1111 1101 1111 @ldrex_0 +LDAEXD_t32 1110 1000 1101 .... .... .... 1111 1111 @ldrex_d + +LDA 1110 1000 1101 .... .... 1111 1010 1111 @ldrex_0 +LDAB 1110 1000 1101 .... .... 1111 1000 1111 @ldrex_0 +LDAH 1110 1000 1101 .... .... 1111 1001 1111 @ldrex_0