From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.3 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89946C32771 for ; Sat, 18 Jan 2020 19:33:15 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5644824683 for ; Sat, 18 Jan 2020 19:33:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="E2iqmkpI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5644824683 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istqM-0003e8-9U for qemu-devel@archiver.kernel.org; Sat, 18 Jan 2020 14:33:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49856) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1istdd-0004Ak-F5 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1istdb-00067O-MM for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:05 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:40156) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1istdb-00066V-Fz for qemu-devel@nongnu.org; Sat, 18 Jan 2020 14:20:03 -0500 Received: by mail-wr1-x443.google.com with SMTP id c14so25717617wrn.7 for ; Sat, 18 Jan 2020 11:20:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=462i1Ag4o0cfxhQVfRSys4sY7nSXMyI7nbnWCXem7s4=; b=E2iqmkpIyyacXS8n9yD4JtEGIbA+m+6IvS7I9NB0DEDZDPoSkpG/0Kcm8MXhpTxKWL 96pDaDHoSTLGOmOlasuIZGmRsynJENiQcWFWNMw6z2r/4Ct8x+ToZqSb9vDtEhKa6Bci RPu0dPigQqEEnr0lhGYJcEeQunJSF5IoFdE/3APM3WIYT0SagCmc7E00VRAt/ZUjX4Gl gz+LRpx5GHOmnaS1YBAnJdWj2E1wAmQ6HXtoo5VGEFGkIuW5jRFYXpCoobYq24KabaSS 2clXThVXCBmnPjO8249jIu2yTyL1wDm6ukkDsfhSDZu5b9gCSVlONN1Fgs1GVntI+jj1 MJ3Q== 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:mime-version:content-transfer-encoding; bh=462i1Ag4o0cfxhQVfRSys4sY7nSXMyI7nbnWCXem7s4=; b=Zpx903+TIEwy/btJXw6Qs3VMnfs2ukwdt6UM37P/fhhVYCzKkNHOW/Aiwz8b0AKGut y6gKbZbE7b/AwgzvlWqZSTyS0RJFlL9Py1kB3V8o1X5bRUiPSEkWVa4D5AnxxVHlK3ft 9fsPoDwdNAjFlPtBBdZOKUZsZtWVu1TbakxRD/g3iIwuDd5l9kueryiqtzqGJUzZHPHf v4Sv/vOadSSQjAjgxRMEZ7ndgrKlwcDat5dgsxrOyFU/rCyLiXJmP7aLKLSjdls2U4NY nXSJIF0X69qTScnP193PPRYVKmQjTom/JFzfRRqrp1kt8E/ywGveF8QYL43fgvxejPLA XePA== X-Gm-Message-State: APjAAAVbpNEAIrClqWLwilqoKBgSX8wN2BTME2lXneIlORIaa27NrCd4 W+XGE5CpCS41kCClA1ObQf7Z1+wowY7nrnTZ X-Google-Smtp-Source: APXvYqwtJyBcK3D3EdMyBqxO6msb8+sGhERMzcO94IOOkkNIZ0Ajv464IKm97hPiYKKYYPrN4/DrsQ== X-Received: by 2002:a5d:6692:: with SMTP id l18mr9476704wru.382.1579375202191; Sat, 18 Jan 2020 11:20:02 -0800 (PST) Received: from 8c859074c0ff.ant.amazon.com.com (bzq-109-65-108-13.red.bezeqint.net. [109.65.108.13]) by smtp.gmail.com with ESMTPSA id o16sm2875468wmc.18.2020.01.18.11.19.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Jan 2020 11:20:01 -0800 (PST) From: Michael Rolnik To: qemu-devel@nongnu.org Subject: [PATCH v41 07/21] target/avr: Add instruction translation - Bit and Bit-test Instructions Date: Sat, 18 Jan 2020 21:14:02 +0200 Message-Id: <20200118191416.19934-8-mrolnik@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200118191416.19934-1-mrolnik@gmail.com> References: <20200118191416.19934-1-mrolnik@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 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: thuth@redhat.com, Michael Rolnik , me@xcancerberox.com.ar, richard.henderson@linaro.org, dovgaluk@ispras.ru, imammedo@redhat.com, philmd@redhat.com, aleksandar.m.mail@gmail.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This includes: - LSR, ROR - ASR - SWAP - SBI, CBI - BST, BLD - BSET, BCLR Signed-off-by: Michael Rolnik Tested-by: Philippe Mathieu-Daudé --- target/avr/translate.c | 241 +++++++++++++++++++++++++++++++++++++++++ target/avr/insn.decode | 14 +++ 2 files changed, 255 insertions(+) diff --git a/target/avr/translate.c b/target/avr/translate.c index 4a62d9312a..58775af17c 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -2440,3 +2440,244 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a) return true; } + +/* + * Bit and Bit-test Instructions + */ +static void gen_rshift_ZNVSf(TCGv R) +{ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */ + tcg_gen_xor_tl(cpu_Vf, cpu_Nf, cpu_Cf); + tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */ +} + +/* + * Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 is + * loaded into the C Flag of the SREG. This operation effectively divides an + * unsigned value by two. The C Flag can be used to round the result. + */ +static bool trans_LSR(DisasContext *ctx, arg_LSR *a) +{ + TCGv Rd = cpu_r[a->rd]; + + tcg_gen_andi_tl(cpu_Cf, Rd, 1); + tcg_gen_shri_tl(Rd, Rd, 1); + /* update status register */ + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, Rd, 0); /* Zf = Rd == 0 */ + tcg_gen_movi_tl(cpu_Nf, 0); + tcg_gen_mov_tl(cpu_Vf, cpu_Cf); + tcg_gen_mov_tl(cpu_Sf, cpu_Vf); + + return true; +} + +/* + * Shifts all bits in Rd one place to the right. The C Flag is shifted into + * bit 7 of Rd. Bit 0 is shifted into the C Flag. This operation, combined + * with ASR, effectively divides multi-byte signed values by two. Combined with + * LSR it effectively divides multi-byte unsigned values by two. The Carry Flag + * can be used to round the result. + */ +static bool trans_ROR(DisasContext *ctx, arg_ROR *a) +{ + TCGv Rd = cpu_r[a->rd]; + TCGv t0 = tcg_temp_new_i32(); + + tcg_gen_shli_tl(t0, cpu_Cf, 7); + /* update status register */ + tcg_gen_andi_tl(cpu_Cf, Rd, 1); + /* update output register */ + tcg_gen_shri_tl(Rd, Rd, 1); + tcg_gen_or_tl(Rd, Rd, t0); + /* update status register */ + gen_rshift_ZNVSf(Rd); + + tcg_temp_free_i32(t0); + + return true; +} + +/* + * Shifts all bits in Rd one place to the right. Bit 7 is held constant. Bit 0 + * is loaded into the C Flag of the SREG. This operation effectively divides a + * signed value by two without changing its sign. The Carry Flag can be used to + * round the result. + */ +static bool trans_ASR(DisasContext *ctx, arg_ASR *a) +{ + TCGv Rd = cpu_r[a->rd]; + TCGv t0 = tcg_temp_new_i32(); + + /* update status register */ + tcg_gen_andi_tl(cpu_Cf, Rd, 1); /* Cf = Rd(0) */ + /* update output register */ + tcg_gen_andi_tl(t0, Rd, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */ + tcg_gen_shri_tl(Rd, Rd, 1); + tcg_gen_or_tl(Rd, Rd, t0); + /* update status register */ + gen_rshift_ZNVSf(Rd); + + tcg_temp_free_i32(t0); + + return true; +} + +/* + * Swaps high and low nibbles in a register. + */ +static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a) +{ + TCGv Rd = cpu_r[a->rd]; + TCGv t0 = tcg_temp_new_i32(); + TCGv t1 = tcg_temp_new_i32(); + + tcg_gen_andi_tl(t0, Rd, 0x0f); + tcg_gen_shli_tl(t0, t0, 4); + tcg_gen_andi_tl(t1, Rd, 0xf0); + tcg_gen_shri_tl(t1, t1, 4); + tcg_gen_or_tl(Rd, t0, t1); + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t0); + + return true; +} + +/* + * Sets a specified bit in an I/O Register. This instruction operates on + * the lower 32 I/O Registers -- addresses 0-31. + */ +static bool trans_SBI(DisasContext *ctx, arg_SBI *a) +{ + TCGv data = tcg_temp_new_i32(); + TCGv port = tcg_const_i32(a->reg); + + gen_helper_inb(data, cpu_env, port); + tcg_gen_ori_tl(data, data, 1 << a->bit); + gen_helper_outb(cpu_env, port, data); + + tcg_temp_free_i32(port); + tcg_temp_free_i32(data); + + return true; +} + +/* + * Clears a specified bit in an I/O Register. This instruction operates on + * the lower 32 I/O Registers -- addresses 0-31. + */ +static bool trans_CBI(DisasContext *ctx, arg_CBI *a) +{ + TCGv data = tcg_temp_new_i32(); + TCGv port = tcg_const_i32(a->reg); + + gen_helper_inb(data, cpu_env, port); + tcg_gen_andi_tl(data, data, ~(1 << a->bit)); + gen_helper_outb(cpu_env, port, data); + + tcg_temp_free_i32(data); + tcg_temp_free_i32(port); + + return true; +} + +/* + * Stores bit b from Rd to the T Flag in SREG (Status Register). + */ +static bool trans_BST(DisasContext *ctx, arg_BST *a) +{ + TCGv Rd = cpu_r[a->rd]; + + tcg_gen_andi_tl(cpu_Tf, Rd, 1 << a->bit); + tcg_gen_shri_tl(cpu_Tf, cpu_Tf, a->bit); + + return true; +} + +/* + * Copies the T Flag in the SREG (Status Register) to bit b in register Rd. + */ +static bool trans_BLD(DisasContext *ctx, arg_BLD *a) +{ + TCGv Rd = cpu_r[a->rd]; + TCGv t1 = tcg_temp_new_i32(); + + tcg_gen_andi_tl(Rd, Rd, ~(1u << a->bit)); /* clear bit */ + tcg_gen_shli_tl(t1, cpu_Tf, a->bit); /* create mask */ + tcg_gen_or_tl(Rd, Rd, t1); + + tcg_temp_free_i32(t1); + + return true; +} + +/* + * Sets a single Flag or bit in SREG. + */ +static bool trans_BSET(DisasContext *ctx, arg_BSET *a) +{ + switch (a->bit) { + case 0x00: + tcg_gen_movi_tl(cpu_Cf, 0x01); + break; + case 0x01: + tcg_gen_movi_tl(cpu_Zf, 0x01); + break; + case 0x02: + tcg_gen_movi_tl(cpu_Nf, 0x01); + break; + case 0x03: + tcg_gen_movi_tl(cpu_Vf, 0x01); + break; + case 0x04: + tcg_gen_movi_tl(cpu_Sf, 0x01); + break; + case 0x05: + tcg_gen_movi_tl(cpu_Hf, 0x01); + break; + case 0x06: + tcg_gen_movi_tl(cpu_Tf, 0x01); + break; + case 0x07: + tcg_gen_movi_tl(cpu_If, 0x01); + break; + } + + return true; +} + +/* + * Clears a single Flag in SREG. + */ +static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a) +{ + switch (a->bit) { + case 0x00: + tcg_gen_movi_tl(cpu_Cf, 0x00); + break; + case 0x01: + tcg_gen_movi_tl(cpu_Zf, 0x00); + break; + case 0x02: + tcg_gen_movi_tl(cpu_Nf, 0x00); + break; + case 0x03: + tcg_gen_movi_tl(cpu_Vf, 0x00); + break; + case 0x04: + tcg_gen_movi_tl(cpu_Sf, 0x00); + break; + case 0x05: + tcg_gen_movi_tl(cpu_Hf, 0x00); + break; + case 0x06: + tcg_gen_movi_tl(cpu_Tf, 0x00); + break; + case 0x07: + tcg_gen_movi_tl(cpu_If, 0x00); + break; + } + + return true; +} diff --git a/target/avr/insn.decode b/target/avr/insn.decode index 3f9304f8b0..4ee55862b2 100644 --- a/target/avr/insn.decode +++ b/target/avr/insn.decode @@ -158,3 +158,17 @@ XCH 1001 001 rd:5 0100 LAC 1001 001 rd:5 0110 LAS 1001 001 rd:5 0101 LAT 1001 001 rd:5 0111 + +# +# Bit and Bit-test Instructions +# +LSR 1001 010 rd:5 0110 +ROR 1001 010 rd:5 0111 +ASR 1001 010 rd:5 0101 +SWAP 1001 010 rd:5 0010 +SBI 1001 1010 reg:5 bit:3 +CBI 1001 1000 reg:5 bit:3 +BST 1111 101 rd:5 0 bit:3 +BLD 1111 100 rd:5 0 bit:3 +BSET 1001 0100 0 bit:3 1000 +BCLR 1001 0100 1 bit:3 1000 -- 2.17.2 (Apple Git-113)