From patchwork Mon Aug 19 21:36:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 171667 Delivered-To: patch@linaro.org Received: by 2002:a92:d204:0:0:0:0:0 with SMTP id y4csp3532886ily; Mon, 19 Aug 2019 14:43:21 -0700 (PDT) X-Google-Smtp-Source: APXvYqyMvJb01cNTdfoYyXWb3zyU2aEiW6Fi40I0gseJdb8y7e+dfrZSSszdVNgHY2NTiFdPSa6z X-Received: by 2002:a17:906:5042:: with SMTP id e2mr22466474ejk.220.1566251001521; Mon, 19 Aug 2019 14:43:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566251001; cv=none; d=google.com; s=arc-20160816; b=PIWmPv28Sycwj8FTPLmAsOFq7pEHXO3JY5nspAr9vL0gUuovhVGai0weZ968S0SaIV bFmywQm9PTzAWGQ5Vcqp2EU6Jm9+lQb8E2VVt/qRsq5t2Y0nfafp6+Z0OrNlCt5nMeW2 /4ZA4w9l4AXwc46ZhAzu6M47V89NWXC0Juo9bSKGTfokby+3RW7eEf9sDyiolb1U9JKr B13HbVyWOo4SgdCBBd68zzCiujoVkgtmK09wYQxqQhTlO1CjykNRa/lNfIHdPE3TMvtj WJtZIlVntVVgM1TDYdxMhRs879wlexFgSNOSsBnFQ6+fO0VI2tICo40vYdU3fgeXqrla 1+JQ== 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=CTcKHXTSkonFgTQBSIs2aPmAFQHyFZz0bv/+Iu71uEU=; b=CtD1KbAhKUqHdPRxheqnClMCOj7SZz2tUcYPbXuCdMOSaYHcYeHDWV5eHPtHy4aXTf sTMu+QfkdWr8adUpbCSfiL86J7oE0dhm4BHfYbIH8Y6CSvZOBAvsl6bNdoX8pwCjZDZ1 sFr3vKl1JGESrE54hSVWg1ee8k33kT8MVA482eNRASrbrdf/S6G5pU9yc6B7NDKj6E6I AfNzZucrdwBRcHMHHSTcv2euq4hDiRns5F33uESxO4zrjVYFtz7PZnSr2SJDVXd+1Xt6 UX0PmDnFpzX8D9O1Rt+AlypiO/geevDIlgf+jwlcWvQtviCKIESo3PfXiUuveEazXVYV 3M7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JWHyi6o9; 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 ov9si4095945ejb.33.2019.08.19.14.43.21 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 19 Aug 2019 14:43:21 -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=JWHyi6o9; 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]:58972 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hzpQu-0007NH-3W for patch@linaro.org; Mon, 19 Aug 2019 17:43:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58557) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hzpLs-0001JU-C0 for qemu-devel@nongnu.org; Mon, 19 Aug 2019 17:38:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hzpLp-00060Z-Hb for qemu-devel@nongnu.org; Mon, 19 Aug 2019 17:38:08 -0400 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]:34643) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hzpLp-0005zz-9r for qemu-devel@nongnu.org; Mon, 19 Aug 2019 17:38:05 -0400 Received: by mail-pf1-x432.google.com with SMTP id b24so1954695pfp.1 for ; Mon, 19 Aug 2019 14:38:05 -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=CTcKHXTSkonFgTQBSIs2aPmAFQHyFZz0bv/+Iu71uEU=; b=JWHyi6o9Tu0e9m8VAeTEwXq0YyOxuTTzxek+RbG0YQXs00MTOEy1VVHepP/eOrLSeb ZqIIVifZVqTim8scB1SWqsVeURb01dNkCTdLNtAGdr6h79Usuxk06fmnVAZy8kgYnWmw 2fuNT+32grZv0whE4bS6W6BeYqWFG/D+YnNUAof9Q6lHYdJdPFV/JgUmIAljxPP9ZLoN 3oB7c+MhxQ28UafXldUZg6rBLGlueHzlFJzcCN5bVJ8/ggDlyInH27vXp35aSYIgHpJy ecA2RTolnOfCCMntGuSW9oz6v0k30T/gNg5BWd4mY6MZ2X6IdlaEvlOlSB96RjsKlBCY cSqg== 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=CTcKHXTSkonFgTQBSIs2aPmAFQHyFZz0bv/+Iu71uEU=; b=eeqmzR/6ZaFz0jPq+BMU+TNg+THL6yUmLDSW44Q5AfrYqNDwQ1KJBfjPM613MmN/HO QtauuHtffjUwrNCwdb1PPu7Bb2LKEu4h3Ji6sDz64GN2mUEHJUglLkp99rfYduXkND1N 09rrifkclCFuCwlCzs9z0uI1I/T/KYGRtmo7AoZdr4XMKgVJ8Ph7jsZcG0g75ImbytUu lHiNsnSk1NspCeR6ACXXklhFBGzx3+hoqxpC21MAlE2SsgCSJZ7+mnkAqgVYg0QikLLA RJDo9E/xUg927dhjhiiFfXk7WGY5sl5cSJYEzVLuDqzu6zjAEb1SEOmRVhz31ivy1MB6 xmRg== X-Gm-Message-State: APjAAAVKQbXnXv4C4et2xETmz/KYhyb477UkEdoIZcx364fISAEC+PVe KFNNtIy/E0bbxrSycbShfL4VpQ/s+NA= X-Received: by 2002:a17:90a:3465:: with SMTP id o92mr22409284pjb.20.1566250683627; Mon, 19 Aug 2019 14:38:03 -0700 (PDT) Received: from localhost.localdomain (97-113-7-119.tukw.qwest.net. [97.113.7.119]) by smtp.gmail.com with ESMTPSA id d2sm13446951pjs.21.2019.08.19.14.38.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2019 14:38:02 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 19 Aug 2019 14:36:52 -0700 Message-Id: <20190819213755.26175-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190819213755.26175-1-richard.henderson@linaro.org> References: <20190819213755.26175-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::432 Subject: [Qemu-devel] [PATCH v2 05/68] target/arm: Convert Data Processing (immediate) 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 Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Convert the modified immediate form of the data processing insns. For A32, we can finally remove any code that was intertwined with the register and register-shifted-register forms. Signed-off-by: Richard Henderson --- target/arm/translate.c | 449 +++++++++++------------------------------ target/arm/a32.decode | 29 +++ target/arm/t32.decode | 42 ++++ 3 files changed, 186 insertions(+), 334 deletions(-) -- 2.17.1 Reviewed-by: Peter Maydell diff --git a/target/arm/translate.c b/target/arm/translate.c index a32fe4b222..b5af38bf84 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -439,12 +439,6 @@ static void gen_add16(TCGv_i32 t0, TCGv_i32 t1) tcg_temp_free_i32(t1); } -/* Set CF to the top bit of var. */ -static void gen_set_CF_bit31(TCGv_i32 var) -{ - tcg_gen_shri_i32(cpu_CF, var, 31); -} - /* Set N and Z flags from var. */ static inline void gen_logic_CC(TCGv_i32 var) { @@ -857,25 +851,6 @@ void arm_gen_test_cc(int cc, TCGLabel *label) arm_free_cc(&cmp); } -static const uint8_t table_logic_cc[16] = { - 1, /* and */ - 1, /* xor */ - 0, /* sub */ - 0, /* rsb */ - 0, /* add */ - 0, /* adc */ - 0, /* sbc */ - 0, /* rsc */ - 1, /* andl */ - 1, /* xorl */ - 0, /* cmp */ - 0, /* cmn */ - 1, /* orr */ - 1, /* mov */ - 1, /* bic */ - 1, /* mvn */ -}; - static inline void gen_set_condexec(DisasContext *s) { if (s->condexec_mask) { @@ -7661,6 +7636,48 @@ static void arm_skip_unless(DisasContext *s, uint32_t cond) arm_gen_test_cc(cond ^ 1, s->condlabel); } + +/* + * Constant expanders for the decoders. + */ + +static int times_2(DisasContext *s, int x) +{ + return x * 2; +} + +/* Return only the rotation part of T32ExpandImm. */ +static int t32_expandimm_rot(DisasContext *s, int x) +{ + return x & 0xc00 ? extract32(x, 7, 5) : 0; +} + +/* Return the unrotated immediate from T32ExpandImm. */ +static int t32_expandimm_imm(DisasContext *s, int x) +{ + int imm = extract32(x, 0, 8); + + switch (extract32(x, 8, 4)) { + case 0: /* XY */ + /* Nothing to do. */ + break; + case 1: /* 00XY00XY */ + imm *= 0x00010001; + break; + case 2: /* XY00XY00 */ + imm *= 0x01000100; + break; + case 3: /* XYXYXYXY */ + imm *= 0x01010101; + break; + default: + /* Rotated constant. */ + imm |= 0x80; + break; + } + return imm; +} + /* * Include the generated decoders. */ @@ -7816,23 +7833,82 @@ static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a, return store_reg_kind(s, a->rd, tmp2, kind); } +/* + * Data-processing (immediate) + * + * Operate, with set flags, one register source, + * one rotated immediate, and a destination. + * + * Note that logic_cc && a->rot setting CF based on the msb of the + * immediate is the reason why we must pass in the unrotated form + * of the immediate. + */ +static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a, + void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32), + int logic_cc, StoreRegKind kind) +{ + TCGv_i32 tmp1, tmp2; + uint32_t imm; + + imm = ror32(a->imm, a->rot); + if (logic_cc && a->rot) { + tcg_gen_movi_i32(cpu_CF, imm >> 31); + } + tmp2 = tcg_const_i32(imm); + tmp1 = load_reg(s, a->rn); + + gen(tmp1, tmp1, tmp2); + tcg_temp_free_i32(tmp2); + + if (logic_cc) { + gen_logic_CC(tmp1); + } + return store_reg_kind(s, a->rd, tmp1, kind); +} + +static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a, + void (*gen)(TCGv_i32, TCGv_i32), + int logic_cc, StoreRegKind kind) +{ + TCGv_i32 tmp; + uint32_t imm; + + imm = ror32(a->imm, a->rot); + if (logic_cc && a->rot) { + tcg_gen_movi_i32(cpu_CF, imm >> 31); + } + tmp = tcg_const_i32(imm); + + gen(tmp, tmp); + if (logic_cc) { + gen_logic_CC(tmp); + } + return store_reg_kind(s, a->rd, tmp, kind); +} + #define DO_ANY3(NAME, OP, L, K) \ static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \ { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \ static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \ - { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } + { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \ + static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \ + { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); } #define DO_ANY2(NAME, OP, L, K) \ static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \ { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \ static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \ - { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } + { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \ + static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \ + { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); } #define DO_CMP2(NAME, OP, L) \ static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \ { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \ static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \ - { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } + { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \ + static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \ + { return op_s_rri_rot(s, a, OP, L, STREG_NONE); } DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL) DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL) @@ -7905,6 +7981,11 @@ static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a) return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL); } +static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a) +{ + return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL); +} + #undef DO_ANY3 #undef DO_ANY2 #undef DO_CMP2 @@ -8442,182 +8523,9 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) } else if (((insn & 0x0e000000) == 0 && (insn & 0x00000090) != 0x90) || ((insn & 0x0e000000) == (1 << 25))) { - int set_cc, logic_cc, shiftop; - - op1 = (insn >> 21) & 0xf; - set_cc = (insn >> 20) & 1; - logic_cc = table_logic_cc[op1] & set_cc; - - /* data processing instruction */ - if (insn & (1 << 25)) { - /* immediate operand */ - val = insn & 0xff; - shift = ((insn >> 8) & 0xf) * 2; - val = ror32(val, shift); - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, val); - if (logic_cc && shift) { - gen_set_CF_bit31(tmp2); - } - } else { - /* register */ - rm = (insn) & 0xf; - tmp2 = load_reg(s, rm); - shiftop = (insn >> 5) & 3; - if (!(insn & (1 << 4))) { - shift = (insn >> 7) & 0x1f; - gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); - } else { - rs = (insn >> 8) & 0xf; - tmp = load_reg(s, rs); - gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc); - } - } - if (op1 != 0x0f && op1 != 0x0d) { - rn = (insn >> 16) & 0xf; - tmp = load_reg(s, rn); - } else { - tmp = NULL; - } - rd = (insn >> 12) & 0xf; - switch(op1) { - case 0x00: - tcg_gen_and_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x01: - tcg_gen_xor_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x02: - if (set_cc && rd == 15) { - /* SUBS r15, ... is used for exception return. */ - if (IS_USER(s)) { - goto illegal_op; - } - gen_sub_CC(tmp, tmp, tmp2); - gen_exception_return(s, tmp); - } else { - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); - } else { - tcg_gen_sub_i32(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - } - break; - case 0x03: - if (set_cc) { - gen_sub_CC(tmp, tmp2, tmp); - } else { - tcg_gen_sub_i32(tmp, tmp2, tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x04: - if (set_cc) { - gen_add_CC(tmp, tmp, tmp2); - } else { - tcg_gen_add_i32(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - break; - case 0x05: - if (set_cc) { - gen_adc_CC(tmp, tmp, tmp2); - } else { - gen_add_carry(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - break; - case 0x06: - if (set_cc) { - gen_sbc_CC(tmp, tmp, tmp2); - } else { - gen_sub_carry(tmp, tmp, tmp2); - } - store_reg_bx(s, rd, tmp); - break; - case 0x07: - if (set_cc) { - gen_sbc_CC(tmp, tmp2, tmp); - } else { - gen_sub_carry(tmp, tmp2, tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x08: - if (set_cc) { - tcg_gen_and_i32(tmp, tmp, tmp2); - gen_logic_CC(tmp); - } - tcg_temp_free_i32(tmp); - break; - case 0x09: - if (set_cc) { - tcg_gen_xor_i32(tmp, tmp, tmp2); - gen_logic_CC(tmp); - } - tcg_temp_free_i32(tmp); - break; - case 0x0a: - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); - } - tcg_temp_free_i32(tmp); - break; - case 0x0b: - if (set_cc) { - gen_add_CC(tmp, tmp, tmp2); - } - tcg_temp_free_i32(tmp); - break; - case 0x0c: - tcg_gen_or_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - case 0x0d: - if (logic_cc && rd == 15) { - /* MOVS r15, ... is used for exception return. */ - if (IS_USER(s)) { - goto illegal_op; - } - gen_exception_return(s, tmp2); - } else { - if (logic_cc) { - gen_logic_CC(tmp2); - } - store_reg_bx(s, rd, tmp2); - } - break; - case 0x0e: - tcg_gen_andc_i32(tmp, tmp, tmp2); - if (logic_cc) { - gen_logic_CC(tmp); - } - store_reg_bx(s, rd, tmp); - break; - default: - case 0x0f: - tcg_gen_not_i32(tmp2, tmp2); - if (logic_cc) { - gen_logic_CC(tmp2); - } - store_reg_bx(s, rd, tmp2); - break; - } - if (op1 != 0x0f && op1 != 0x0d) { - tcg_temp_free_i32(tmp2); - } + /* Data-processing (reg, reg-shift-reg, imm). */ + /* All done in decodetree. Reach here for illegal ops. */ + goto illegal_op; } else { /* other instructions */ op1 = (insn >> 24) & 0xf; @@ -9517,82 +9425,6 @@ static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn) return true; } -/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero - then set condition code flags based on the result of the operation. - If SHIFTER_OUT is nonzero then set the carry flag for logical operations - to the high bit of T1. - Returns zero if the opcode is valid. */ - -static int -gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, - TCGv_i32 t0, TCGv_i32 t1) -{ - int logic_cc; - - logic_cc = 0; - switch (op) { - case 0: /* and */ - tcg_gen_and_i32(t0, t0, t1); - logic_cc = conds; - break; - case 1: /* bic */ - tcg_gen_andc_i32(t0, t0, t1); - logic_cc = conds; - break; - case 2: /* orr */ - tcg_gen_or_i32(t0, t0, t1); - logic_cc = conds; - break; - case 3: /* orn */ - tcg_gen_orc_i32(t0, t0, t1); - logic_cc = conds; - break; - case 4: /* eor */ - tcg_gen_xor_i32(t0, t0, t1); - logic_cc = conds; - break; - case 8: /* add */ - if (conds) - gen_add_CC(t0, t0, t1); - else - tcg_gen_add_i32(t0, t0, t1); - break; - case 10: /* adc */ - if (conds) - gen_adc_CC(t0, t0, t1); - else - gen_adc(t0, t1); - break; - case 11: /* sbc */ - if (conds) { - gen_sbc_CC(t0, t0, t1); - } else { - gen_sub_carry(t0, t0, t1); - } - break; - case 13: /* sub */ - if (conds) - gen_sub_CC(t0, t0, t1); - else - tcg_gen_sub_i32(t0, t0, t1); - break; - case 14: /* rsb */ - if (conds) - gen_sub_CC(t0, t1, t0); - else - tcg_gen_sub_i32(t0, t1, t0); - break; - default: /* 5, 6, 7, 9, 12, 15. */ - return 1; - } - if (logic_cc) { - gen_logic_CC(t0); - if (shifter_out) - gen_set_CF_bit31(t1); - } - return 0; -} - /* Translate a 32-bit thumb instruction. */ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) { @@ -10867,60 +10699,9 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) } } } else { - /* - * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx - * - Data-processing (modified immediate) - */ - int shifter_out = 0; - /* modified 12-bit immediate. */ - shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12); - imm = (insn & 0xff); - switch (shift) { - case 0: /* XY */ - /* Nothing to do. */ - break; - case 1: /* 00XY00XY */ - imm |= imm << 16; - break; - case 2: /* XY00XY00 */ - imm |= imm << 16; - imm <<= 8; - break; - case 3: /* XYXYXYXY */ - imm |= imm << 16; - imm |= imm << 8; - break; - default: /* Rotated constant. */ - shift = (shift << 1) | (imm >> 7); - imm |= 0x80; - imm = imm << (32 - shift); - shifter_out = 1; - break; - } - tmp2 = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp2, imm); - rn = (insn >> 16) & 0xf; - if (rn == 15) { - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, 0); - } else { - tmp = load_reg(s, rn); - } - op = (insn >> 21) & 0xf; - if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, - shifter_out, tmp, tmp2)) - goto illegal_op; - tcg_temp_free_i32(tmp2); - rd = (insn >> 8) & 0xf; - if (rd == 13 && rn == 13 - && (op == 8 || op == 13)) { - /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */ - store_sp_checked(s, tmp); - } else if (rd != 15) { - store_reg(s, rd, tmp); - } else { - tcg_temp_free_i32(tmp); - } + /* Data-processing (modified immediate) */ + /* All done in decodetree. Reach here for illegal ops. */ + goto illegal_op; } } break; diff --git a/target/arm/a32.decode b/target/arm/a32.decode index 8e0fb06d05..286adcbf89 100644 --- a/target/arm/a32.decode +++ b/target/arm/a32.decode @@ -24,6 +24,7 @@ &s_rrr_shi s rd rn rm shim shty &s_rrr_shr s rn rd rm rs shty +&s_rri_rot s rn rd imm rot # Data-processing (register) @@ -76,3 +77,31 @@ ORR_rrrr .... 000 1100 . .... .... .... 0 .. 1 .... @s_rrr_shr MOV_rxrr .... 000 1101 . 0000 .... .... 0 .. 1 .... @s_rxr_shr BIC_rrrr .... 000 1110 . .... .... .... 0 .. 1 .... @s_rrr_shr MVN_rxrr .... 000 1111 . 0000 .... .... 0 .. 1 .... @s_rxr_shr + +# Data-processing (immediate) + +%a32extrot 8:4 !function=times_2 + +@s_rri_rot ---- ... .... s:1 rn:4 rd:4 .... imm:8 \ + &s_rri_rot rot=%a32extrot +@s_rxi_rot ---- ... .... s:1 .... rd:4 .... imm:8 \ + &s_rri_rot rot=%a32extrot rn=0 +@S_xri_rot ---- ... .... . rn:4 .... .... imm:8 \ + &s_rri_rot rot=%a32extrot rd=0 s=1 + +AND_rri .... 001 0000 . .... .... ............ @s_rri_rot +EOR_rri .... 001 0001 . .... .... ............ @s_rri_rot +SUB_rri .... 001 0010 . .... .... ............ @s_rri_rot +RSB_rri .... 001 0011 . .... .... ............ @s_rri_rot +ADD_rri .... 001 0100 . .... .... ............ @s_rri_rot +ADC_rri .... 001 0101 . .... .... ............ @s_rri_rot +SBC_rri .... 001 0110 . .... .... ............ @s_rri_rot +RSC_rri .... 001 0111 . .... .... ............ @s_rri_rot +TST_xri .... 001 1000 1 .... 0000 ............ @S_xri_rot +TEQ_xri .... 001 1001 1 .... 0000 ............ @S_xri_rot +CMP_xri .... 001 1010 1 .... 0000 ............ @S_xri_rot +CMN_xri .... 001 1011 1 .... 0000 ............ @S_xri_rot +ORR_rri .... 001 1100 . .... .... ............ @s_rri_rot +MOV_rxi .... 001 1101 . 0000 .... ............ @s_rxi_rot +BIC_rri .... 001 1110 . .... .... ............ @s_rri_rot +MVN_rxi .... 001 1111 . 0000 .... ............ @s_rxi_rot diff --git a/target/arm/t32.decode b/target/arm/t32.decode index f0a73fa003..50cbe48cc8 100644 --- a/target/arm/t32.decode +++ b/target/arm/t32.decode @@ -21,6 +21,7 @@ &s_rrr_shi !extern s rd rn rm shim shty &s_rrr_shr !extern s rn rd rm rs shty +&s_rri_rot !extern s rn rd imm rot # Data-processing (register) @@ -67,3 +68,44 @@ RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \ &s_rrr_shr rn=0 + +# Data-processing (immediate) + +%t32extrot 26:1 12:3 0:8 !function=t32_expandimm_rot +%t32extimm 26:1 12:3 0:8 !function=t32_expandimm_imm + +@s_rri_rot ....... .... s:1 rn:4 . ... rd:4 ........ \ + &s_rri_rot imm=%t32extimm rot=%t32extrot +@s_rxi_rot ....... .... s:1 .... . ... rd:4 ........ \ + &s_rri_rot imm=%t32extimm rot=%t32extrot rn=0 +@S_xri_rot ....... .... . rn:4 . ... .... ........ \ + &s_rri_rot imm=%t32extimm rot=%t32extrot s=1 rd=0 + +{ + TST_xri 1111 0.0 0000 1 .... 0 ... 1111 ........ @S_xri_rot + AND_rri 1111 0.0 0000 . .... 0 ... .... ........ @s_rri_rot +} +BIC_rri 1111 0.0 0001 . .... 0 ... .... ........ @s_rri_rot +{ + MOV_rxi 1111 0.0 0010 . 1111 0 ... .... ........ @s_rxi_rot + ORR_rri 1111 0.0 0010 . .... 0 ... .... ........ @s_rri_rot +} +{ + MVN_rxi 1111 0.0 0011 . 1111 0 ... .... ........ @s_rxi_rot + ORN_rri 1111 0.0 0011 . .... 0 ... .... ........ @s_rri_rot +} +{ + TEQ_xri 1111 0.0 0100 1 .... 0 ... 1111 ........ @S_xri_rot + EOR_rri 1111 0.0 0100 . .... 0 ... .... ........ @s_rri_rot +} +{ + CMN_xri 1111 0.0 1000 1 .... 0 ... 1111 ........ @S_xri_rot + ADD_rri 1111 0.0 1000 . .... 0 ... .... ........ @s_rri_rot +} +ADC_rri 1111 0.0 1010 . .... 0 ... .... ........ @s_rri_rot +SBC_rri 1111 0.0 1011 . .... 0 ... .... ........ @s_rri_rot +{ + CMP_xri 1111 0.0 1101 1 .... 0 ... 1111 ........ @S_xri_rot + SUB_rri 1111 0.0 1101 . .... 0 ... .... ........ @s_rri_rot +} +RSB_rri 1111 0.0 1110 . .... 0 ... .... ........ @s_rri_rot