From patchwork Fri Nov 8 03:29:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoyuki HIROSE X-Patchwork-Id: 13867437 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 90695D5E127 for ; Fri, 8 Nov 2024 03:31:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9Fhb-0008U1-EA; Thu, 07 Nov 2024 22:30:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9Fha-0008TH-0D for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:26 -0500 Received: from mail-il1-x12a.google.com ([2607:f8b0:4864:20::12a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t9FhX-0001HH-06 for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:25 -0500 Received: by mail-il1-x12a.google.com with SMTP id e9e14a558f8ab-3a6adaee7acso6158955ab.0 for ; Thu, 07 Nov 2024 19:30:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=igel-co-jp.20230601.gappssmtp.com; s=20230601; t=1731036620; x=1731641420; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NCrerRQTXGrD00ddnS/Hilq6giLmAcGDIEPH6vUua6s=; b=yf7edY8nuNvwnjwDbIv2YMBf7odxM99ZxDWOuxSTFoZsaFcxLWiesKjte/2taylpFP jkI9QaUOYrXDIOdRWg6Rs3Eebv2Rwy/F6kQfB0Fn/TrX/nMotpJ/xpoBXiY+1YrHuoR8 MzvF7vOwruXln6j3PyPnUTiftJUDv4u7it+viQPi0dxyH6nshKqy8IqGTrPIgHkHonxb sz99qWbsAcpLTgudZUglG4t8tVUEBVquX9pVeO7u06jirs0VOWfJDTi5thtTg1DDMfI/ Y5LE6ZZRkJysFAaLkyrtxXPSc3/G1LstrOAcgm5wiBXYPtbZX6PDUmLLjZ0QC5KsP2eI 9XUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731036620; x=1731641420; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NCrerRQTXGrD00ddnS/Hilq6giLmAcGDIEPH6vUua6s=; b=xMd03D41GmCM+31yRVkjaHDKvIedHKr7L7PHQo34rY6HH1jDRjdy5gRUf7/01x7+qs w4QVvTdVeyw2jEvPWqO3yzb3/zk8bzd6mVIwbPQAf1r6iqWUQ2Dd1nsk3Y3idSI31Cp5 fXdAw0FAZL5y8tfCSFRSjZu4ykpk95JAlR1KCs2RfqebzVS79ufpEVPqKmDA1NpZ8Ax5 ID8RiE2O+Iwqt1oMHd/05mYg1K/G/MBySYaB39Q3cbU8Vec/n4XstBMtABXvtJn0UbZb mq2WzmAHgZm0yE1DvNbzkoLmwaPUhMLCY3FPIgDS6Kt5yFAzXpissEIq4ZWS0i+mtfrn 9JuQ== X-Gm-Message-State: AOJu0YxBlFqr/cq3MlR3Fj5klke6zmAsb/8XFLq3MT662xt2BMK3Vosg QD1hwhkum2vvEyAjm44Tc8Yz10UKkJQOQB9r/ltFt3DiINUytxCB3zM10hKN7PJANFSXrAkCaKe W X-Google-Smtp-Source: AGHT+IHuAnySDLoX4U4V6syOdK8a1Qm+ZKR4pIxN3TRjyI4qCO35oUlg7cbch09RdEhXS4e3TMF1/w== X-Received: by 2002:a05:6e02:190e:b0:3a3:9471:8967 with SMTP id e9e14a558f8ab-3a6f19e43cbmr19854955ab.11.1731036619986; Thu, 07 Nov 2024 19:30:19 -0800 (PST) Received: from ThinkPad-T14-hirose.hq.igel.co.jp (napt.igel.co.jp. [219.106.231.132]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7f41f65d358sm2326435a12.84.2024.11.07.19.30.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2024 19:30:19 -0800 (PST) From: Tomoyuki HIROSE To: qemu-devel@nongnu.org Cc: Tomoyuki HIROSE , Keith Busch , Klaus Jensen , Jesper Devantier , qemu-block@nongnu.org (open list:nvme) Subject: [RFC PATCH 1/5] hw/nvme/ctrl: specify the 'valid' field in MemoryRegionOps Date: Fri, 8 Nov 2024 12:29:45 +0900 Message-ID: <20241108032952.56692-2-tomoyuki.hirose@igel.co.jp> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> References: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::12a; envelope-from=tomoyuki.hirose@igel.co.jp; helo=mail-il1-x12a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 'valid' field in MemoryRegionOps struct indicates how the MemoryRegion can be accessed by the guest. In the previous code, the 'valid' field was not specified explicitly. As a result, the CMB area could only be accessed in units of 4 bytes. This commit specifies the 'valid' field in MemoryRegionOps of CMB and the CMB area can be accessed in units of 8 bytes. Signed-off-by: Tomoyuki HIROSE --- hw/nvme/ctrl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 8e4612e035..acbd10628f 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -8166,6 +8166,11 @@ static const MemoryRegionOps nvme_cmb_ops = { .min_access_size = 1, .max_access_size = 8, }, + .valid = { + .unaligned = true, + .min_access_size = 1, + .max_access_size = 8, + }, }; static bool nvme_check_params(NvmeCtrl *n, Error **errp) From patchwork Fri Nov 8 03:29:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoyuki HIROSE X-Patchwork-Id: 13867438 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 37386D5E124 for ; Fri, 8 Nov 2024 03:31:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9Fhc-0008Ue-R7; Thu, 07 Nov 2024 22:30:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9Fha-0008U0-US for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:26 -0500 Received: from mail-oi1-x22a.google.com ([2607:f8b0:4864:20::22a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t9FhY-0001Hn-Vm for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:26 -0500 Received: by mail-oi1-x22a.google.com with SMTP id 5614622812f47-3e5fef69f2eso1056233b6e.3 for ; Thu, 07 Nov 2024 19:30:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=igel-co-jp.20230601.gappssmtp.com; s=20230601; t=1731036624; x=1731641424; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZEmXhN0e4yofB9St5S3+HcVTsbiOBljTRevzyH0DrDI=; b=ory0/elUCxf/vrmGSKz3hnclJvn+NPb/1/iI8JCJJebzR3on0zZvaFADOl9bXQeX2B sJOLjvlY3nT6+wWiUj/rM/A9GPH6kPNMRDHQ5dDd8ubKPsmeuXSaeALKHv03x676pUe0 b5Znba2osYTzI/UWtRP1mWbVIxXIUUeIPWhkA1D1L7adXMj71PdT811qwYEdk3LnHljP fyQhpHiIsazzXGjEEMgFrol/Ukj7W90JNAA/ZQFo6E9/jJE7+hyOY/O7CpL4wzbKKGGb dXji5kAsVhP495/Ri8GHXlxuQTim22D25e2CnTALSmsm5Eg5il1CvuEZ1JTCo1djYG3H daJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731036624; x=1731641424; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZEmXhN0e4yofB9St5S3+HcVTsbiOBljTRevzyH0DrDI=; b=tuPelUvjmIkOrX4aBSP9dy8f6ghGBHvv7GSBv1RkXmI0ORuny/MY4jfG53od/4zA52 R4AsEuvCOrWfCcA9tlPC7iEJvsZZkQrhLgT6zwOekI2xm/o87hV62v/WkJYT6REffzW0 VT3KuaWtRhnCDP5ImKR7nrLcZ6bqEkroV7y/BexiztYQ8wVx7zHPrBZj9m2ygguxAdA5 f9apvOQrRF0iooZlyBsy/JE4g1mYJHtfsO4NXRxmpa2V12ZZ3XqreUqQFhI0zItQRgdk 7LkjL7al8h3n/vlF5CG2EK4Fpdx0uY0Lhf++YzYba85WTdm3RKqbVLfvXglhcXLLmIJa n3bw== X-Gm-Message-State: AOJu0Yy0r6cDtIr3pSo/1T88xWJqLEsyt1OEfzesdF5ywslPiwKAsAjQ F4HoNiW27/gHMtCECe5QS2Vmtz4yT1bK0/taor2+apidWYvU3FGMlu/9DkxT0ZIqbY3zk49iTo9 kN7Q= X-Google-Smtp-Source: AGHT+IH8Cu8BmQ2H1pYCF1MhqZHlWXBnPlF4+KiVNOByoEJ9C4HHxEoU0/lhjDRoVgya92wPthhJcA== X-Received: by 2002:a05:6808:118c:b0:3e6:5f3:dadb with SMTP id 5614622812f47-3e794705982mr1776028b6e.39.1731036623668; Thu, 07 Nov 2024 19:30:23 -0800 (PST) Received: from ThinkPad-T14-hirose.hq.igel.co.jp (napt.igel.co.jp. [219.106.231.132]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7f41f65d358sm2326435a12.84.2024.11.07.19.30.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2024 19:30:23 -0800 (PST) From: Tomoyuki HIROSE To: qemu-devel@nongnu.org Cc: Tomoyuki HIROSE , Paolo Bonzini , Peter Xu , David Hildenbrand , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Subject: [RFC PATCH 2/5] system/memory: support unaligned access Date: Fri, 8 Nov 2024 12:29:46 +0900 Message-ID: <20241108032952.56692-3-tomoyuki.hirose@igel.co.jp> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> References: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::22a; envelope-from=tomoyuki.hirose@igel.co.jp; helo=mail-oi1-x22a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The previous code ignored 'impl.unaligned' and handled unaligned accesses as is. But this implementation could not emulate specific registers of some devices that allow unaligned access such as xHCI Host Controller Capability Registers. This commit emulates an unaligned access with multiple aligned accesses. Additionally, the overwriting of the max access size is removed to retrive the actual max access size. Signed-off-by: Tomoyuki HIROSE --- system/memory.c | 147 ++++++++++++++++++++++++++++++++++++++--------- system/physmem.c | 8 --- 2 files changed, 119 insertions(+), 36 deletions(-) diff --git a/system/memory.c b/system/memory.c index 85f6834cb3..c2164e6478 100644 --- a/system/memory.c +++ b/system/memory.c @@ -518,27 +518,118 @@ static MemTxResult memory_region_write_with_attrs_accessor(MemoryRegion *mr, return mr->ops->write_with_attrs(mr->opaque, addr, tmp, size, attrs); } +typedef MemTxResult (*MemoryRegionAccessFn)(MemoryRegion *mr, + hwaddr addr, + uint64_t *value, + unsigned size, + signed shift, + uint64_t mask, + MemTxAttrs attrs); + +static MemTxResult access_emulation(hwaddr addr, + uint64_t *value, + unsigned int size, + unsigned int access_size_min, + unsigned int access_size_max, + MemoryRegion *mr, + MemTxAttrs attrs, + MemoryRegionAccessFn access_fn_read, + MemoryRegionAccessFn access_fn_write, + bool is_write) +{ + hwaddr a; + uint8_t *d; + uint64_t v; + MemTxResult r = MEMTX_OK; + bool is_big_endian = memory_region_big_endian(mr); + void (*store)(void *, int, uint64_t) = is_big_endian ? stn_be_p : stn_le_p; + uint64_t (*load)(const void *, int) = is_big_endian ? ldn_be_p : ldn_le_p; + size_t access_size = MAX(MIN(size, access_size_max), access_size_min); + uint64_t access_mask = MAKE_64BIT_MASK(0, access_size * 8); + hwaddr round_down = mr->ops->impl.unaligned && addr + size <= mr->size ? + 0 : addr % access_size; + hwaddr start = addr - round_down; + hwaddr tail = addr + size <= mr->size ? addr + size : mr->size; + uint8_t data[16] = {0}; + g_assert(size <= 8); + + for (a = start, d = data, v = 0; a < tail; + a += access_size, d += access_size, v = 0) { + r |= access_fn_read(mr, a, &v, access_size, 0, access_mask, + attrs); + store(d, access_size, v); + } + if (is_write) { + stn_he_p(&data[round_down], size, load(value, size)); + for (a = start, d = data; a < tail; + a += access_size, d += access_size) { + v = load(d, access_size); + r |= access_fn_write(mr, a, &v, access_size, 0, access_mask, + attrs); + } + } else { + store(value, size, ldn_he_p(&data[round_down], size)); + } + + return r; +} + +static bool is_access_fastpath(hwaddr addr, + unsigned int size, + unsigned int access_size_min, + unsigned int access_size_max, + MemoryRegion *mr) +{ + size_t access_size = MAX(MIN(size, access_size_max), access_size_min); + hwaddr round_down = mr->ops->impl.unaligned && addr + size <= mr->size ? + 0 : addr % access_size; + + return round_down == 0 && access_size <= size; +} + +static MemTxResult access_fastpath(hwaddr addr, + uint64_t *value, + unsigned int size, + unsigned int access_size_min, + unsigned int access_size_max, + MemoryRegion *mr, + MemTxAttrs attrs, + MemoryRegionAccessFn fastpath) +{ + MemTxResult r = MEMTX_OK; + size_t access_size = MAX(MIN(size, access_size_max), access_size_min); + uint64_t access_mask = MAKE_64BIT_MASK(0, access_size * 8); + + if (memory_region_big_endian(mr)) { + for (size_t i = 0; i < size; i += access_size) { + r |= fastpath(mr, addr + i, value, access_size, + (size - access_size - i) * 8, access_mask, attrs); + } + } else { + for (size_t i = 0; i < size; i += access_size) { + r |= fastpath(mr, addr + i, value, access_size, + i * 8, access_mask, attrs); + } + } + + return r; +} + static MemTxResult access_with_adjusted_size(hwaddr addr, uint64_t *value, unsigned size, unsigned access_size_min, unsigned access_size_max, - MemTxResult (*access_fn) - (MemoryRegion *mr, - hwaddr addr, - uint64_t *value, - unsigned size, - signed shift, - uint64_t mask, - MemTxAttrs attrs), + MemoryRegionAccessFn access_fn_read, + MemoryRegionAccessFn access_fn_write, + bool is_write, MemoryRegion *mr, MemTxAttrs attrs) { - uint64_t access_mask; - unsigned access_size; - unsigned i; MemTxResult r = MEMTX_OK; bool reentrancy_guard_applied = false; + MemoryRegionAccessFn access_fn_fastpath = + is_write ? access_fn_write : access_fn_read; if (!access_size_min) { access_size_min = 1; @@ -560,20 +651,16 @@ static MemTxResult access_with_adjusted_size(hwaddr addr, reentrancy_guard_applied = true; } - /* FIXME: support unaligned access? */ - access_size = MAX(MIN(size, access_size_max), access_size_min); - access_mask = MAKE_64BIT_MASK(0, access_size * 8); - if (memory_region_big_endian(mr)) { - for (i = 0; i < size; i += access_size) { - r |= access_fn(mr, addr + i, value, access_size, - (size - access_size - i) * 8, access_mask, attrs); - } + if (is_access_fastpath(addr, size, access_size_min, access_size_max, mr)) { + r |= access_fastpath(addr, value, size, + access_size_min, access_size_max, mr, attrs, + access_fn_fastpath); } else { - for (i = 0; i < size; i += access_size) { - r |= access_fn(mr, addr + i, value, access_size, i * 8, - access_mask, attrs); - } + r |= access_emulation(addr, value, size, + access_size_min, access_size_max, mr, attrs, + access_fn_read, access_fn_write, is_write); } + if (mr->dev && reentrancy_guard_applied) { mr->dev->mem_reentrancy_guard.engaged_in_io = false; } @@ -1459,13 +1546,15 @@ static MemTxResult memory_region_dispatch_read1(MemoryRegion *mr, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, memory_region_read_accessor, - mr, attrs); + memory_region_write_accessor, + false, mr, attrs); } else { return access_with_adjusted_size(addr, pval, size, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, memory_region_read_with_attrs_accessor, - mr, attrs); + memory_region_write_with_attrs_accessor, + false, mr, attrs); } } @@ -1553,15 +1642,17 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr, return access_with_adjusted_size(addr, &data, size, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, - memory_region_write_accessor, mr, - attrs); + memory_region_read_accessor, + memory_region_write_accessor, + true, mr, attrs); } else { return access_with_adjusted_size(addr, &data, size, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, + memory_region_read_with_attrs_accessor, memory_region_write_with_attrs_accessor, - mr, attrs); + true, mr, attrs); } } diff --git a/system/physmem.c b/system/physmem.c index dc1db3a384..ff444140a8 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -2693,14 +2693,6 @@ int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) access_size_max = 4; } - /* Bound the maximum access by the alignment of the address. */ - if (!mr->ops->impl.unaligned) { - unsigned align_size_max = addr & -addr; - if (align_size_max != 0 && align_size_max < access_size_max) { - access_size_max = align_size_max; - } - } - /* Don't attempt accesses larger than the maximum. */ if (l > access_size_max) { l = access_size_max; From patchwork Fri Nov 8 03:29:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoyuki HIROSE X-Patchwork-Id: 13867440 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 7E383D5E120 for ; Fri, 8 Nov 2024 03:32:02 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9Fhn-00004t-A1; Thu, 07 Nov 2024 22:30:39 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9Fhh-0008VJ-Jn for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:33 -0500 Received: from mail-ot1-x32b.google.com ([2607:f8b0:4864:20::32b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t9Fhd-0001Ir-6z for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:33 -0500 Received: by mail-ot1-x32b.google.com with SMTP id 46e09a7af769-71850708dc9so1220339a34.0 for ; Thu, 07 Nov 2024 19:30:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=igel-co-jp.20230601.gappssmtp.com; s=20230601; t=1731036628; x=1731641428; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=55iqCS8kiLmLFUNlZbRqBM9OdxuIQ62bUAj7d4iMUOA=; b=IwY4s38aOoZbhoHRBhO8f/UIEf53xoDz/nguaSwPa0O7isa9QfXtUWPAzTAiQvky+i lIhc5lHYUldxQR4JiU0KV6cFRzCq8YkYvMNZJkwdHp6ClSrpi0v2Jxd9zoUBXzAv3UBh EJRKnEMmyeSpR4wQ2e0KD7Jd+9NF2M8JbD5oHQg9APDZ/0A9scfMN0wgnRERTkDtXl96 ZyRbIC9OI3BOnNJKm6RW8OeXkgw0lseXokcxbbPv2+SXtBF2VHHWIPI2kKrM+weCrjqp 71FeOoIWsnegWk3h57nv1+JbFd5auNexQKLKoF4VBnaoQwDZ+ACL/uRH8toFnFRzc8F/ Lqdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731036628; x=1731641428; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=55iqCS8kiLmLFUNlZbRqBM9OdxuIQ62bUAj7d4iMUOA=; b=bl+5Qy1Xayjo9HeE++Jmkn0xiQpYhM+tAfU8yE/ARU8hwaUULhBXRHKdQrC0yuQQX+ u3AuKYq859VJSyZnYzZQRQL1fmucbIV9eLI5IO/nk1kM9VVo65dYY2D6sj2TNTnt5FyL PZ4k7s+anvQDzglDYnAan2Wv6CKCG7fR10sMFPs1tyzwTwcDDg0E6DUefjkrVv84zQZ/ aJ6IetbTX+korFqmXeMrePXDZoYgjgU63h6iBg0/S3zCHvHaKNjimp2O4H9ZhmbdPx0T +89pKvtJjqT3RKzWIwpOROD3LO7DBpD92tcRXVF9frkCcYh/xNrZ/m+cQ2GH7/NM9wLI bp9A== X-Gm-Message-State: AOJu0YxYOjIk8lpnK8Mng4xfd2k4azpOhD5aJZ5/btS2fnANXo0u7UxI +Qn7jhkPeFpNrGd5v3x4uJzof0kUVf7bHJWe3JByuX7/F8463barSnPSc4Lgz+fzB+2aQmoagd3 5Z0U= X-Google-Smtp-Source: AGHT+IG9VNwX5kqsMfd5bRck6seSoYmA/uLyg9tqS4gc62BQDKbBkd+4wmhGNxOurxJOdJObAlZY4A== X-Received: by 2002:a05:6830:388a:b0:718:ce7:9b62 with SMTP id 46e09a7af769-71a1c0e9d2dmr1947114a34.0.1731036627197; Thu, 07 Nov 2024 19:30:27 -0800 (PST) Received: from ThinkPad-T14-hirose.hq.igel.co.jp (napt.igel.co.jp. [219.106.231.132]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7f41f65d358sm2326435a12.84.2024.11.07.19.30.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2024 19:30:26 -0800 (PST) From: Tomoyuki HIROSE To: qemu-devel@nongnu.org Cc: Tomoyuki HIROSE , Paolo Bonzini Subject: [RFC PATCH 3/5] hw/misc: add test device for memory access Date: Fri, 8 Nov 2024 12:29:47 +0900 Message-ID: <20241108032952.56692-4-tomoyuki.hirose@igel.co.jp> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> References: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::32b; envelope-from=tomoyuki.hirose@igel.co.jp; helo=mail-ot1-x32b.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit adds a test device for checking memory access. The test device generates memory regions that covers all the parameter patterns. With this device, we can check the handling of reading/writing the MemoryRegion is correct. Signed-off-by: Tomoyuki HIROSE --- hw/misc/Kconfig | 4 + hw/misc/memaccess-testdev.c | 197 +++ hw/misc/meson.build | 1 + include/hw/misc/memaccess-testdev.h | 42 + include/hw/misc/memaccess-testdev.h.inc | 1864 +++++++++++++++++++++++ 5 files changed, 2108 insertions(+) create mode 100644 hw/misc/memaccess-testdev.c create mode 100644 include/hw/misc/memaccess-testdev.h create mode 100644 include/hw/misc/memaccess-testdev.h.inc diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1f1baa5dde..b90b91dc25 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -25,6 +25,10 @@ config PCI_TESTDEV default y if TEST_DEVICES depends on PCI +config MEMACCESS_TESTDEV + bool + default y if TEST_DEVICES + config EDU bool default y if TEST_DEVICES diff --git a/hw/misc/memaccess-testdev.c b/hw/misc/memaccess-testdev.c new file mode 100644 index 0000000000..8282bd3035 --- /dev/null +++ b/hw/misc/memaccess-testdev.c @@ -0,0 +1,197 @@ +/* + * QEMU memory access test device + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2024 IGEL Co., Ltd. + * Author: Tomoyuki HIROSE + */ +/* + * This device is used to test memory acccess, like: + * + * qemu-system-x86_64 -device memaccess-testdev,address=0x10000000 + */ + +#include "qemu/osdep.h" +#include "exec/address-spaces.h" +#include "exec/memory.h" +#include "hw/qdev-core.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "qemu/typedefs.h" +#include "qom/object.h" + +#include "hw/misc/memaccess-testdev.h" + +typedef struct MrOpsList { + const char *name; + const MemoryRegionOps *ops_array; + const size_t ops_array_len; + const size_t offset_idx; +} MrOpsList; + +static void testdev_init_memory_region(MemoryRegion *mr, + Object *owner, + const MemoryRegionOps *ops, + void *opaque, + const char *name, + uint64_t size, + MemoryRegion *container, + hwaddr container_offset) +{ + memory_region_init_io(mr, owner, ops, opaque, name, size); + memory_region_add_subregion(container, container_offset, mr); +} + +static void testdev_init_from_mr_ops_list(MemAccessTestDev *testdev, + const MrOpsList *l) +{ + for (size_t i = 0; i < l->ops_array_len; i++) { + g_autofree gchar *name = g_strdup_printf("%s-%ld", l->name, i); + testdev_init_memory_region(&testdev->memory_regions[l->offset_idx + i], + OBJECT(testdev), &l->ops_array[i], + testdev->mr_data[l->offset_idx + i], + name, + MEMACCESS_TESTDEV_REGION_SIZE, + &testdev->container, + MEMACCESS_TESTDEV_REGION_SIZE * + (l->offset_idx + i)); + } +} + +#define _DEFINE_MR_OPS_LIST(_n, _a, _l, _o) \ + { \ + .name = (_n), \ + .ops_array = (_a), \ + .ops_array_len = (_l), \ + .offset_idx = (_o), \ + } + +static const MrOpsList mr_ops_list[] = { + _DEFINE_MR_OPS_LIST("little-b-valid", + ops_list_little_b_valid, + N_OPS_LIST_LITTLE_B_VALID, + OFF_IDX_OPS_LIST_LITTLE_B_VALID), + _DEFINE_MR_OPS_LIST("little-b-invalid", + ops_list_little_b_invalid, + N_OPS_LIST_LITTLE_B_INVALID, + OFF_IDX_OPS_LIST_LITTLE_B_INVALID), + _DEFINE_MR_OPS_LIST("little-w-valid", + ops_list_little_w_valid, + N_OPS_LIST_LITTLE_W_VALID, + OFF_IDX_OPS_LIST_LITTLE_W_VALID), + _DEFINE_MR_OPS_LIST("little-w-invalid", + ops_list_little_w_invalid, + N_OPS_LIST_LITTLE_W_INVALID, + OFF_IDX_OPS_LIST_LITTLE_W_INVALID), + _DEFINE_MR_OPS_LIST("little-l-valid", + ops_list_little_l_valid, + N_OPS_LIST_LITTLE_L_VALID, + OFF_IDX_OPS_LIST_LITTLE_L_VALID), + _DEFINE_MR_OPS_LIST("little-l-invalid", + ops_list_little_l_invalid, + N_OPS_LIST_LITTLE_L_INVALID, + OFF_IDX_OPS_LIST_LITTLE_L_INVALID), + _DEFINE_MR_OPS_LIST("little-q-valid", + ops_list_little_q_valid, + N_OPS_LIST_LITTLE_Q_VALID, + OFF_IDX_OPS_LIST_LITTLE_Q_VALID), + _DEFINE_MR_OPS_LIST("little-q-invalid", + ops_list_little_q_invalid, + N_OPS_LIST_LITTLE_Q_INVALID, + OFF_IDX_OPS_LIST_LITTLE_Q_INVALID), + _DEFINE_MR_OPS_LIST("big-b-valid", + ops_list_big_b_valid, + N_OPS_LIST_BIG_B_VALID, + OFF_IDX_OPS_LIST_BIG_B_VALID), + _DEFINE_MR_OPS_LIST("big-b-invalid", + ops_list_big_b_invalid, + N_OPS_LIST_BIG_B_INVALID, + OFF_IDX_OPS_LIST_BIG_B_INVALID), + _DEFINE_MR_OPS_LIST("big-w-valid", + ops_list_big_w_valid, + N_OPS_LIST_BIG_W_VALID, + OFF_IDX_OPS_LIST_BIG_W_VALID), + _DEFINE_MR_OPS_LIST("big-w-invalid", + ops_list_big_w_invalid, + N_OPS_LIST_BIG_W_INVALID, + OFF_IDX_OPS_LIST_BIG_W_INVALID), + _DEFINE_MR_OPS_LIST("big-l-valid", + ops_list_big_l_valid, + N_OPS_LIST_LITTLE_L_VALID, + OFF_IDX_OPS_LIST_BIG_L_VALID), + _DEFINE_MR_OPS_LIST("big-l-invalid", + ops_list_big_l_invalid, + N_OPS_LIST_BIG_L_INVALID, + OFF_IDX_OPS_LIST_BIG_L_INVALID), + _DEFINE_MR_OPS_LIST("big-q-valid", + ops_list_big_q_valid, + N_OPS_LIST_BIG_Q_VALID, + OFF_IDX_OPS_LIST_BIG_Q_VALID), + _DEFINE_MR_OPS_LIST("big-q-invalid", + ops_list_big_q_invalid, + N_OPS_LIST_BIG_Q_INVALID, + OFF_IDX_OPS_LIST_BIG_Q_INVALID), +}; +#define N_MR_OPS_LIST (sizeof(mr_ops_list) / sizeof(MrOpsList)) + +static void init_testdev(MemAccessTestDev *testdev) +{ + memory_region_init(&testdev->container, OBJECT(testdev), "memtest-regions", + MEMACCESS_TESTDEV_REGION_SIZE * N_OPS_LIST); + testdev->mr_data = g_malloc(MEMACCESS_TESTDEV_MR_DATA_SIZE); + + for (size_t i = 0; i < N_MR_OPS_LIST; i++) { + testdev_init_from_mr_ops_list(testdev, &mr_ops_list[i]); + } + + memory_region_add_subregion(get_system_memory(), testdev->base, + &testdev->container); +} + +static void memaccess_testdev_realize(DeviceState *dev, Error **errp) +{ + MemAccessTestDev *d = MEM_ACCESS_TEST_DEV(dev); + + if (d->base == UINT64_MAX) { + error_setg(errp, "base address is not assigned"); + return; + } + + init_testdev(d); +} + +static void memaccess_testdev_unrealize(DeviceState *dev) +{ + MemAccessTestDev *d = MEM_ACCESS_TEST_DEV(dev); + g_free(d->mr_data); +} + +static Property memaccess_testdev_props[] = { + DEFINE_PROP_UINT64("address", MemAccessTestDev, base, UINT64_MAX), + DEFINE_PROP_END_OF_LIST(), +}; + +static void memaccess_testdev_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = memaccess_testdev_realize; + dc->unrealize = memaccess_testdev_unrealize; + device_class_set_props(dc, memaccess_testdev_props); + set_bit(DEVICE_CATEGORY_MISC, dc->categories); +} + +static const TypeInfo memaccess_testdev_info = { + .name = TYPE_MEM_ACCESS_TEST_DEV, + .parent = TYPE_DEVICE, + .instance_size = sizeof(MemAccessTestDev), + .class_init = memaccess_testdev_class_init, +}; + +static void memaccess_testdev_register_types(void) +{ + type_register_static(&memaccess_testdev_info); +} + +type_init(memaccess_testdev_register_types) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index d02d96e403..28054c5337 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -4,6 +4,7 @@ system_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('vmcoreinfo.c')) system_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugexit.c')) system_ss.add(when: 'CONFIG_ISA_TESTDEV', if_true: files('pc-testdev.c')) system_ss.add(when: 'CONFIG_PCI_TESTDEV', if_true: files('pci-testdev.c')) +system_ss.add(when: 'CONFIG_MEMACCESS_TESTDEV', if_true: files('memaccess-testdev.c')) system_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c')) system_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c')) system_ss.add(when: 'CONFIG_LED', if_true: files('led.c')) diff --git a/include/hw/misc/memaccess-testdev.h b/include/hw/misc/memaccess-testdev.h new file mode 100644 index 0000000000..1909e40931 --- /dev/null +++ b/include/hw/misc/memaccess-testdev.h @@ -0,0 +1,42 @@ +/* + * QEMU memory access test device header + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2024 IGEL Co., Ltd. + * Author: Tomoyuki HIROSE + */ + +#ifndef HW_MISC_MEMACCESS_TESTDEV_H +#define HW_MISC_MEMACCESS_TESTDEV_H + +#include "qemu/osdep.h" +#include "exec/memory.h" +#include "hw/qdev-core.h" + +#define TYPE_MEM_ACCESS_TEST_DEV "memaccess-testdev" + +#include "hw/misc/memaccess-testdev.h.inc" + +typedef uint8_t MrData[MEMACCESS_TESTDEV_REGION_SIZE]; +#define MEMACCESS_TESTDEV_MR_DATA_SIZE (sizeof(MrData) * N_OPS_LIST) + +typedef DeviceClass MemAccessTestDevClass; +typedef struct MemAccessTestDev { + /* Private */ + DeviceState parent_obj; + /* Public */ + MemoryRegion container; + MemoryRegion memory_regions[N_OPS_LIST]; /* test memory regions */ + uint64_t base; /* map base address */ + MrData *mr_data; /* memory region data array */ +} MemAccessTestDev; + +#define MEM_ACCESS_TEST_DEV_GET_CLASS(obj) \ + OBJECT_GET_CLASS(MemAccessTestDevClass, obj, TYPE_MEM_ACCESS_TEST_DEV) +#define MEM_ACCESS_TEST_DEV_CLASS(klass) \ + OBJECT_CLASS_CHECK(MemAccessTestDevClass, klass, TYPE_MEM_ACCESS_TEST_DEV) +#define MEM_ACCESS_TEST_DEV(obj) \ + OBJECT_CHECK(MemAccessTestDev, obj, TYPE_MEM_ACCESS_TEST_DEV) + +#endif diff --git a/include/hw/misc/memaccess-testdev.h.inc b/include/hw/misc/memaccess-testdev.h.inc new file mode 100644 index 0000000000..d6105a7263 --- /dev/null +++ b/include/hw/misc/memaccess-testdev.h.inc @@ -0,0 +1,1864 @@ +/* + * QEMU memory access test device functions + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2024 IGEL Co., Ltd. + * Author: Tomoyuki HIROSE + */ + +#ifndef HW_MISC_MEMACCESS_TESTDEV_H_INC +#define HW_MISC_MEMACCESS_TESTDEV_H_INC + +#include "qemu/osdep.h" +#include "exec/memory.h" + +#define MEMACCESS_TESTDEV_REGION_SIZE (32) + +static uint64_t memaccess_testdev_read_little(void *opaque, hwaddr addr, + unsigned int size) +{ + g_assert(addr + size < MEMACCESS_TESTDEV_REGION_SIZE); + void *s = (uint8_t *)opaque + addr; + return ldn_le_p(s, size); +} + +static void memaccess_testdev_write_little(void *opaque, hwaddr addr, + uint64_t data, unsigned int size) +{ + g_assert(addr + size < MEMACCESS_TESTDEV_REGION_SIZE); + void *d = (uint8_t *)opaque + addr; + stn_le_p(d, size, data); +} + +static uint64_t memaccess_testdev_read_big(void *opaque, hwaddr addr, + unsigned int size) +{ + g_assert(addr + size < MEMACCESS_TESTDEV_REGION_SIZE); + void *s = (uint8_t *)opaque + addr; + return ldn_be_p(s, size); +} + +static void memaccess_testdev_write_big(void *opaque, hwaddr addr, + uint64_t data, unsigned int size) +{ + g_assert(addr + size < MEMACCESS_TESTDEV_REGION_SIZE); + void *d = (uint8_t *)opaque + addr; + stn_be_p(d, size, data); +} + +#define __JOIN6(a, b, c, d, e, f) __JOIN6_AGAIN(a, b, c, d, e, f) +#define __JOIN6_AGAIN(a, b, c, d, e, f) a##b##c##d##e##f +#define __JOIN2(a, b) __JOIN2_AGAIN(a, b) +#define __JOIN2_AGAIN(a, b) a##b +#define __STR(x) __STR_AGAIN(x) +#define __STR_AGAIN(x) #x + +#define NAME_OPS_LITTLE(valid_max, valid_min, valid_unaligned, \ + impl_max, impl_min, impl_unaligned) \ + __JOIN2(ops_little, \ + __JOIN6(valid_max, valid_min, valid_unaligned, \ + impl_max, impl_min, impl_unaligned)) + +#define NAME_OPS_BIG(valid_max, valid_min, valid_unaligned, \ + impl_max, impl_min, impl_unaligned) \ + __JOIN2(ops_big, \ + __JOIN6(valid_max, valid_min, valid_unaligned, \ + impl_max, impl_min, impl_unaligned)) + +#define GEN_OPS_LITTLE(valid_max, \ + valid_min, \ + valid_unaligned, \ + impl_max, \ + impl_min, \ + impl_unaligned) \ + static const MemoryRegionOps \ + NAME_OPS_LITTLE(valid_max, valid_min, valid_unaligned, \ + impl_max, impl_min, impl_unaligned) \ + = { \ + .read = memaccess_testdev_read_little, \ + .write = memaccess_testdev_write_little, \ + .endianness = DEVICE_LITTLE_ENDIAN, \ + .valid = { \ + .max_access_size = valid_max, \ + .min_access_size = valid_min, \ + .unaligned = valid_unaligned, \ + }, \ + .impl = { \ + .max_access_size = impl_max, \ + .min_access_size = impl_min, \ + .unaligned = impl_unaligned, \ + }, \ + }; + +#define GEN_OPS_BIG(valid_max, \ + valid_min, \ + valid_unaligned, \ + impl_max, \ + impl_min, \ + impl_unaligned) \ + static const MemoryRegionOps \ + NAME_OPS_BIG(valid_max, valid_min, valid_unaligned, \ + impl_max, impl_min, impl_unaligned) \ + = { \ + .read = memaccess_testdev_read_big, \ + .write = memaccess_testdev_write_big, \ + .endianness = DEVICE_BIG_ENDIAN, \ + .valid = { \ + .max_access_size = valid_max, \ + .min_access_size = valid_min, \ + .unaligned = valid_unaligned, \ + }, \ + .impl = { \ + .max_access_size = impl_max, \ + .min_access_size = impl_min, \ + .unaligned = impl_unaligned, \ + }, \ + }; + +GEN_OPS_LITTLE(1, 1, true, 1, 1, true) +GEN_OPS_LITTLE(1, 1, true, 2, 1, true) +GEN_OPS_LITTLE(1, 1, true, 4, 1, true) +GEN_OPS_LITTLE(1, 1, true, 8, 1, true) +GEN_OPS_LITTLE(1, 1, true, 2, 2, true) +GEN_OPS_LITTLE(1, 1, true, 4, 2, true) +GEN_OPS_LITTLE(1, 1, true, 8, 2, true) +GEN_OPS_LITTLE(1, 1, true, 4, 4, true) +GEN_OPS_LITTLE(1, 1, true, 8, 4, true) +GEN_OPS_LITTLE(1, 1, true, 8, 8, true) +GEN_OPS_LITTLE(1, 1, true, 1, 1, false) +GEN_OPS_LITTLE(1, 1, true, 2, 1, false) +GEN_OPS_LITTLE(1, 1, true, 4, 1, false) +GEN_OPS_LITTLE(1, 1, true, 8, 1, false) +GEN_OPS_LITTLE(1, 1, true, 2, 2, false) +GEN_OPS_LITTLE(1, 1, true, 4, 2, false) +GEN_OPS_LITTLE(1, 1, true, 8, 2, false) +GEN_OPS_LITTLE(1, 1, true, 4, 4, false) +GEN_OPS_LITTLE(1, 1, true, 8, 4, false) +GEN_OPS_LITTLE(1, 1, true, 8, 8, false) +GEN_OPS_LITTLE(2, 1, true, 1, 1, true) +GEN_OPS_LITTLE(2, 1, true, 2, 1, true) +GEN_OPS_LITTLE(2, 1, true, 4, 1, true) +GEN_OPS_LITTLE(2, 1, true, 8, 1, true) +GEN_OPS_LITTLE(2, 1, true, 2, 2, true) +GEN_OPS_LITTLE(2, 1, true, 4, 2, true) +GEN_OPS_LITTLE(2, 1, true, 8, 2, true) +GEN_OPS_LITTLE(2, 1, true, 4, 4, true) +GEN_OPS_LITTLE(2, 1, true, 8, 4, true) +GEN_OPS_LITTLE(2, 1, true, 8, 8, true) +GEN_OPS_LITTLE(2, 1, true, 1, 1, false) +GEN_OPS_LITTLE(2, 1, true, 2, 1, false) +GEN_OPS_LITTLE(2, 1, true, 4, 1, false) +GEN_OPS_LITTLE(2, 1, true, 8, 1, false) +GEN_OPS_LITTLE(2, 1, true, 2, 2, false) +GEN_OPS_LITTLE(2, 1, true, 4, 2, false) +GEN_OPS_LITTLE(2, 1, true, 8, 2, false) +GEN_OPS_LITTLE(2, 1, true, 4, 4, false) +GEN_OPS_LITTLE(2, 1, true, 8, 4, false) +GEN_OPS_LITTLE(2, 1, true, 8, 8, false) +GEN_OPS_LITTLE(4, 1, true, 1, 1, true) +GEN_OPS_LITTLE(4, 1, true, 2, 1, true) +GEN_OPS_LITTLE(4, 1, true, 4, 1, true) +GEN_OPS_LITTLE(4, 1, true, 8, 1, true) +GEN_OPS_LITTLE(4, 1, true, 2, 2, true) +GEN_OPS_LITTLE(4, 1, true, 4, 2, true) +GEN_OPS_LITTLE(4, 1, true, 8, 2, true) +GEN_OPS_LITTLE(4, 1, true, 4, 4, true) +GEN_OPS_LITTLE(4, 1, true, 8, 4, true) +GEN_OPS_LITTLE(4, 1, true, 8, 8, true) +GEN_OPS_LITTLE(4, 1, true, 1, 1, false) +GEN_OPS_LITTLE(4, 1, true, 2, 1, false) +GEN_OPS_LITTLE(4, 1, true, 4, 1, false) +GEN_OPS_LITTLE(4, 1, true, 8, 1, false) +GEN_OPS_LITTLE(4, 1, true, 2, 2, false) +GEN_OPS_LITTLE(4, 1, true, 4, 2, false) +GEN_OPS_LITTLE(4, 1, true, 8, 2, false) +GEN_OPS_LITTLE(4, 1, true, 4, 4, false) +GEN_OPS_LITTLE(4, 1, true, 8, 4, false) +GEN_OPS_LITTLE(4, 1, true, 8, 8, false) +GEN_OPS_LITTLE(8, 1, true, 1, 1, true) +GEN_OPS_LITTLE(8, 1, true, 2, 1, true) +GEN_OPS_LITTLE(8, 1, true, 4, 1, true) +GEN_OPS_LITTLE(8, 1, true, 8, 1, true) +GEN_OPS_LITTLE(8, 1, true, 2, 2, true) +GEN_OPS_LITTLE(8, 1, true, 4, 2, true) +GEN_OPS_LITTLE(8, 1, true, 8, 2, true) +GEN_OPS_LITTLE(8, 1, true, 4, 4, true) +GEN_OPS_LITTLE(8, 1, true, 8, 4, true) +GEN_OPS_LITTLE(8, 1, true, 8, 8, true) +GEN_OPS_LITTLE(8, 1, true, 1, 1, false) +GEN_OPS_LITTLE(8, 1, true, 2, 1, false) +GEN_OPS_LITTLE(8, 1, true, 4, 1, false) +GEN_OPS_LITTLE(8, 1, true, 8, 1, false) +GEN_OPS_LITTLE(8, 1, true, 2, 2, false) +GEN_OPS_LITTLE(8, 1, true, 4, 2, false) +GEN_OPS_LITTLE(8, 1, true, 8, 2, false) +GEN_OPS_LITTLE(8, 1, true, 4, 4, false) +GEN_OPS_LITTLE(8, 1, true, 8, 4, false) +GEN_OPS_LITTLE(8, 1, true, 8, 8, false) +GEN_OPS_LITTLE(2, 2, true, 1, 1, true) +GEN_OPS_LITTLE(2, 2, true, 2, 1, true) +GEN_OPS_LITTLE(2, 2, true, 4, 1, true) +GEN_OPS_LITTLE(2, 2, true, 8, 1, true) +GEN_OPS_LITTLE(2, 2, true, 2, 2, true) +GEN_OPS_LITTLE(2, 2, true, 4, 2, true) +GEN_OPS_LITTLE(2, 2, true, 8, 2, true) +GEN_OPS_LITTLE(2, 2, true, 4, 4, true) +GEN_OPS_LITTLE(2, 2, true, 8, 4, true) +GEN_OPS_LITTLE(2, 2, true, 8, 8, true) +GEN_OPS_LITTLE(2, 2, true, 1, 1, false) +GEN_OPS_LITTLE(2, 2, true, 2, 1, false) +GEN_OPS_LITTLE(2, 2, true, 4, 1, false) +GEN_OPS_LITTLE(2, 2, true, 8, 1, false) +GEN_OPS_LITTLE(2, 2, true, 2, 2, false) +GEN_OPS_LITTLE(2, 2, true, 4, 2, false) +GEN_OPS_LITTLE(2, 2, true, 8, 2, false) +GEN_OPS_LITTLE(2, 2, true, 4, 4, false) +GEN_OPS_LITTLE(2, 2, true, 8, 4, false) +GEN_OPS_LITTLE(2, 2, true, 8, 8, false) +GEN_OPS_LITTLE(4, 2, true, 1, 1, true) +GEN_OPS_LITTLE(4, 2, true, 2, 1, true) +GEN_OPS_LITTLE(4, 2, true, 4, 1, true) +GEN_OPS_LITTLE(4, 2, true, 8, 1, true) +GEN_OPS_LITTLE(4, 2, true, 2, 2, true) +GEN_OPS_LITTLE(4, 2, true, 4, 2, true) +GEN_OPS_LITTLE(4, 2, true, 8, 2, true) +GEN_OPS_LITTLE(4, 2, true, 4, 4, true) +GEN_OPS_LITTLE(4, 2, true, 8, 4, true) +GEN_OPS_LITTLE(4, 2, true, 8, 8, true) +GEN_OPS_LITTLE(4, 2, true, 1, 1, false) +GEN_OPS_LITTLE(4, 2, true, 2, 1, false) +GEN_OPS_LITTLE(4, 2, true, 4, 1, false) +GEN_OPS_LITTLE(4, 2, true, 8, 1, false) +GEN_OPS_LITTLE(4, 2, true, 2, 2, false) +GEN_OPS_LITTLE(4, 2, true, 4, 2, false) +GEN_OPS_LITTLE(4, 2, true, 8, 2, false) +GEN_OPS_LITTLE(4, 2, true, 4, 4, false) +GEN_OPS_LITTLE(4, 2, true, 8, 4, false) +GEN_OPS_LITTLE(4, 2, true, 8, 8, false) +GEN_OPS_LITTLE(8, 2, true, 1, 1, true) +GEN_OPS_LITTLE(8, 2, true, 2, 1, true) +GEN_OPS_LITTLE(8, 2, true, 4, 1, true) +GEN_OPS_LITTLE(8, 2, true, 8, 1, true) +GEN_OPS_LITTLE(8, 2, true, 2, 2, true) +GEN_OPS_LITTLE(8, 2, true, 4, 2, true) +GEN_OPS_LITTLE(8, 2, true, 8, 2, true) +GEN_OPS_LITTLE(8, 2, true, 4, 4, true) +GEN_OPS_LITTLE(8, 2, true, 8, 4, true) +GEN_OPS_LITTLE(8, 2, true, 8, 8, true) +GEN_OPS_LITTLE(8, 2, true, 1, 1, false) +GEN_OPS_LITTLE(8, 2, true, 2, 1, false) +GEN_OPS_LITTLE(8, 2, true, 4, 1, false) +GEN_OPS_LITTLE(8, 2, true, 8, 1, false) +GEN_OPS_LITTLE(8, 2, true, 2, 2, false) +GEN_OPS_LITTLE(8, 2, true, 4, 2, false) +GEN_OPS_LITTLE(8, 2, true, 8, 2, false) +GEN_OPS_LITTLE(8, 2, true, 4, 4, false) +GEN_OPS_LITTLE(8, 2, true, 8, 4, false) +GEN_OPS_LITTLE(8, 2, true, 8, 8, false) +GEN_OPS_LITTLE(4, 4, true, 1, 1, true) +GEN_OPS_LITTLE(4, 4, true, 2, 1, true) +GEN_OPS_LITTLE(4, 4, true, 4, 1, true) +GEN_OPS_LITTLE(4, 4, true, 8, 1, true) +GEN_OPS_LITTLE(4, 4, true, 2, 2, true) +GEN_OPS_LITTLE(4, 4, true, 4, 2, true) +GEN_OPS_LITTLE(4, 4, true, 8, 2, true) +GEN_OPS_LITTLE(4, 4, true, 4, 4, true) +GEN_OPS_LITTLE(4, 4, true, 8, 4, true) +GEN_OPS_LITTLE(4, 4, true, 8, 8, true) +GEN_OPS_LITTLE(4, 4, true, 1, 1, false) +GEN_OPS_LITTLE(4, 4, true, 2, 1, false) +GEN_OPS_LITTLE(4, 4, true, 4, 1, false) +GEN_OPS_LITTLE(4, 4, true, 8, 1, false) +GEN_OPS_LITTLE(4, 4, true, 2, 2, false) +GEN_OPS_LITTLE(4, 4, true, 4, 2, false) +GEN_OPS_LITTLE(4, 4, true, 8, 2, false) +GEN_OPS_LITTLE(4, 4, true, 4, 4, false) +GEN_OPS_LITTLE(4, 4, true, 8, 4, false) +GEN_OPS_LITTLE(4, 4, true, 8, 8, false) +GEN_OPS_LITTLE(8, 4, true, 1, 1, true) +GEN_OPS_LITTLE(8, 4, true, 2, 1, true) +GEN_OPS_LITTLE(8, 4, true, 4, 1, true) +GEN_OPS_LITTLE(8, 4, true, 8, 1, true) +GEN_OPS_LITTLE(8, 4, true, 2, 2, true) +GEN_OPS_LITTLE(8, 4, true, 4, 2, true) +GEN_OPS_LITTLE(8, 4, true, 8, 2, true) +GEN_OPS_LITTLE(8, 4, true, 4, 4, true) +GEN_OPS_LITTLE(8, 4, true, 8, 4, true) +GEN_OPS_LITTLE(8, 4, true, 8, 8, true) +GEN_OPS_LITTLE(8, 4, true, 1, 1, false) +GEN_OPS_LITTLE(8, 4, true, 2, 1, false) +GEN_OPS_LITTLE(8, 4, true, 4, 1, false) +GEN_OPS_LITTLE(8, 4, true, 8, 1, false) +GEN_OPS_LITTLE(8, 4, true, 2, 2, false) +GEN_OPS_LITTLE(8, 4, true, 4, 2, false) +GEN_OPS_LITTLE(8, 4, true, 8, 2, false) +GEN_OPS_LITTLE(8, 4, true, 4, 4, false) +GEN_OPS_LITTLE(8, 4, true, 8, 4, false) +GEN_OPS_LITTLE(8, 4, true, 8, 8, false) +GEN_OPS_LITTLE(8, 8, true, 1, 1, true) +GEN_OPS_LITTLE(8, 8, true, 2, 1, true) +GEN_OPS_LITTLE(8, 8, true, 4, 1, true) +GEN_OPS_LITTLE(8, 8, true, 8, 1, true) +GEN_OPS_LITTLE(8, 8, true, 2, 2, true) +GEN_OPS_LITTLE(8, 8, true, 4, 2, true) +GEN_OPS_LITTLE(8, 8, true, 8, 2, true) +GEN_OPS_LITTLE(8, 8, true, 4, 4, true) +GEN_OPS_LITTLE(8, 8, true, 8, 4, true) +GEN_OPS_LITTLE(8, 8, true, 8, 8, true) +GEN_OPS_LITTLE(8, 8, true, 1, 1, false) +GEN_OPS_LITTLE(8, 8, true, 2, 1, false) +GEN_OPS_LITTLE(8, 8, true, 4, 1, false) +GEN_OPS_LITTLE(8, 8, true, 8, 1, false) +GEN_OPS_LITTLE(8, 8, true, 2, 2, false) +GEN_OPS_LITTLE(8, 8, true, 4, 2, false) +GEN_OPS_LITTLE(8, 8, true, 8, 2, false) +GEN_OPS_LITTLE(8, 8, true, 4, 4, false) +GEN_OPS_LITTLE(8, 8, true, 8, 4, false) +GEN_OPS_LITTLE(8, 8, true, 8, 8, false) +GEN_OPS_LITTLE(1, 1, false, 1, 1, true) +GEN_OPS_LITTLE(1, 1, false, 2, 1, true) +GEN_OPS_LITTLE(1, 1, false, 4, 1, true) +GEN_OPS_LITTLE(1, 1, false, 8, 1, true) +GEN_OPS_LITTLE(1, 1, false, 2, 2, true) +GEN_OPS_LITTLE(1, 1, false, 4, 2, true) +GEN_OPS_LITTLE(1, 1, false, 8, 2, true) +GEN_OPS_LITTLE(1, 1, false, 4, 4, true) +GEN_OPS_LITTLE(1, 1, false, 8, 4, true) +GEN_OPS_LITTLE(1, 1, false, 8, 8, true) +GEN_OPS_LITTLE(1, 1, false, 1, 1, false) +GEN_OPS_LITTLE(1, 1, false, 2, 1, false) +GEN_OPS_LITTLE(1, 1, false, 4, 1, false) +GEN_OPS_LITTLE(1, 1, false, 8, 1, false) +GEN_OPS_LITTLE(1, 1, false, 2, 2, false) +GEN_OPS_LITTLE(1, 1, false, 4, 2, false) +GEN_OPS_LITTLE(1, 1, false, 8, 2, false) +GEN_OPS_LITTLE(1, 1, false, 4, 4, false) +GEN_OPS_LITTLE(1, 1, false, 8, 4, false) +GEN_OPS_LITTLE(1, 1, false, 8, 8, false) +GEN_OPS_LITTLE(2, 1, false, 1, 1, true) +GEN_OPS_LITTLE(2, 1, false, 2, 1, true) +GEN_OPS_LITTLE(2, 1, false, 4, 1, true) +GEN_OPS_LITTLE(2, 1, false, 8, 1, true) +GEN_OPS_LITTLE(2, 1, false, 2, 2, true) +GEN_OPS_LITTLE(2, 1, false, 4, 2, true) +GEN_OPS_LITTLE(2, 1, false, 8, 2, true) +GEN_OPS_LITTLE(2, 1, false, 4, 4, true) +GEN_OPS_LITTLE(2, 1, false, 8, 4, true) +GEN_OPS_LITTLE(2, 1, false, 8, 8, true) +GEN_OPS_LITTLE(2, 1, false, 1, 1, false) +GEN_OPS_LITTLE(2, 1, false, 2, 1, false) +GEN_OPS_LITTLE(2, 1, false, 4, 1, false) +GEN_OPS_LITTLE(2, 1, false, 8, 1, false) +GEN_OPS_LITTLE(2, 1, false, 2, 2, false) +GEN_OPS_LITTLE(2, 1, false, 4, 2, false) +GEN_OPS_LITTLE(2, 1, false, 8, 2, false) +GEN_OPS_LITTLE(2, 1, false, 4, 4, false) +GEN_OPS_LITTLE(2, 1, false, 8, 4, false) +GEN_OPS_LITTLE(2, 1, false, 8, 8, false) +GEN_OPS_LITTLE(4, 1, false, 1, 1, true) +GEN_OPS_LITTLE(4, 1, false, 2, 1, true) +GEN_OPS_LITTLE(4, 1, false, 4, 1, true) +GEN_OPS_LITTLE(4, 1, false, 8, 1, true) +GEN_OPS_LITTLE(4, 1, false, 2, 2, true) +GEN_OPS_LITTLE(4, 1, false, 4, 2, true) +GEN_OPS_LITTLE(4, 1, false, 8, 2, true) +GEN_OPS_LITTLE(4, 1, false, 4, 4, true) +GEN_OPS_LITTLE(4, 1, false, 8, 4, true) +GEN_OPS_LITTLE(4, 1, false, 8, 8, true) +GEN_OPS_LITTLE(4, 1, false, 1, 1, false) +GEN_OPS_LITTLE(4, 1, false, 2, 1, false) +GEN_OPS_LITTLE(4, 1, false, 4, 1, false) +GEN_OPS_LITTLE(4, 1, false, 8, 1, false) +GEN_OPS_LITTLE(4, 1, false, 2, 2, false) +GEN_OPS_LITTLE(4, 1, false, 4, 2, false) +GEN_OPS_LITTLE(4, 1, false, 8, 2, false) +GEN_OPS_LITTLE(4, 1, false, 4, 4, false) +GEN_OPS_LITTLE(4, 1, false, 8, 4, false) +GEN_OPS_LITTLE(4, 1, false, 8, 8, false) +GEN_OPS_LITTLE(8, 1, false, 1, 1, true) +GEN_OPS_LITTLE(8, 1, false, 2, 1, true) +GEN_OPS_LITTLE(8, 1, false, 4, 1, true) +GEN_OPS_LITTLE(8, 1, false, 8, 1, true) +GEN_OPS_LITTLE(8, 1, false, 2, 2, true) +GEN_OPS_LITTLE(8, 1, false, 4, 2, true) +GEN_OPS_LITTLE(8, 1, false, 8, 2, true) +GEN_OPS_LITTLE(8, 1, false, 4, 4, true) +GEN_OPS_LITTLE(8, 1, false, 8, 4, true) +GEN_OPS_LITTLE(8, 1, false, 8, 8, true) +GEN_OPS_LITTLE(8, 1, false, 1, 1, false) +GEN_OPS_LITTLE(8, 1, false, 2, 1, false) +GEN_OPS_LITTLE(8, 1, false, 4, 1, false) +GEN_OPS_LITTLE(8, 1, false, 8, 1, false) +GEN_OPS_LITTLE(8, 1, false, 2, 2, false) +GEN_OPS_LITTLE(8, 1, false, 4, 2, false) +GEN_OPS_LITTLE(8, 1, false, 8, 2, false) +GEN_OPS_LITTLE(8, 1, false, 4, 4, false) +GEN_OPS_LITTLE(8, 1, false, 8, 4, false) +GEN_OPS_LITTLE(8, 1, false, 8, 8, false) +GEN_OPS_LITTLE(2, 2, false, 1, 1, true) +GEN_OPS_LITTLE(2, 2, false, 2, 1, true) +GEN_OPS_LITTLE(2, 2, false, 4, 1, true) +GEN_OPS_LITTLE(2, 2, false, 8, 1, true) +GEN_OPS_LITTLE(2, 2, false, 2, 2, true) +GEN_OPS_LITTLE(2, 2, false, 4, 2, true) +GEN_OPS_LITTLE(2, 2, false, 8, 2, true) +GEN_OPS_LITTLE(2, 2, false, 4, 4, true) +GEN_OPS_LITTLE(2, 2, false, 8, 4, true) +GEN_OPS_LITTLE(2, 2, false, 8, 8, true) +GEN_OPS_LITTLE(2, 2, false, 1, 1, false) +GEN_OPS_LITTLE(2, 2, false, 2, 1, false) +GEN_OPS_LITTLE(2, 2, false, 4, 1, false) +GEN_OPS_LITTLE(2, 2, false, 8, 1, false) +GEN_OPS_LITTLE(2, 2, false, 2, 2, false) +GEN_OPS_LITTLE(2, 2, false, 4, 2, false) +GEN_OPS_LITTLE(2, 2, false, 8, 2, false) +GEN_OPS_LITTLE(2, 2, false, 4, 4, false) +GEN_OPS_LITTLE(2, 2, false, 8, 4, false) +GEN_OPS_LITTLE(2, 2, false, 8, 8, false) +GEN_OPS_LITTLE(4, 2, false, 1, 1, true) +GEN_OPS_LITTLE(4, 2, false, 2, 1, true) +GEN_OPS_LITTLE(4, 2, false, 4, 1, true) +GEN_OPS_LITTLE(4, 2, false, 8, 1, true) +GEN_OPS_LITTLE(4, 2, false, 2, 2, true) +GEN_OPS_LITTLE(4, 2, false, 4, 2, true) +GEN_OPS_LITTLE(4, 2, false, 8, 2, true) +GEN_OPS_LITTLE(4, 2, false, 4, 4, true) +GEN_OPS_LITTLE(4, 2, false, 8, 4, true) +GEN_OPS_LITTLE(4, 2, false, 8, 8, true) +GEN_OPS_LITTLE(4, 2, false, 1, 1, false) +GEN_OPS_LITTLE(4, 2, false, 2, 1, false) +GEN_OPS_LITTLE(4, 2, false, 4, 1, false) +GEN_OPS_LITTLE(4, 2, false, 8, 1, false) +GEN_OPS_LITTLE(4, 2, false, 2, 2, false) +GEN_OPS_LITTLE(4, 2, false, 4, 2, false) +GEN_OPS_LITTLE(4, 2, false, 8, 2, false) +GEN_OPS_LITTLE(4, 2, false, 4, 4, false) +GEN_OPS_LITTLE(4, 2, false, 8, 4, false) +GEN_OPS_LITTLE(4, 2, false, 8, 8, false) +GEN_OPS_LITTLE(8, 2, false, 1, 1, true) +GEN_OPS_LITTLE(8, 2, false, 2, 1, true) +GEN_OPS_LITTLE(8, 2, false, 4, 1, true) +GEN_OPS_LITTLE(8, 2, false, 8, 1, true) +GEN_OPS_LITTLE(8, 2, false, 2, 2, true) +GEN_OPS_LITTLE(8, 2, false, 4, 2, true) +GEN_OPS_LITTLE(8, 2, false, 8, 2, true) +GEN_OPS_LITTLE(8, 2, false, 4, 4, true) +GEN_OPS_LITTLE(8, 2, false, 8, 4, true) +GEN_OPS_LITTLE(8, 2, false, 8, 8, true) +GEN_OPS_LITTLE(8, 2, false, 1, 1, false) +GEN_OPS_LITTLE(8, 2, false, 2, 1, false) +GEN_OPS_LITTLE(8, 2, false, 4, 1, false) +GEN_OPS_LITTLE(8, 2, false, 8, 1, false) +GEN_OPS_LITTLE(8, 2, false, 2, 2, false) +GEN_OPS_LITTLE(8, 2, false, 4, 2, false) +GEN_OPS_LITTLE(8, 2, false, 8, 2, false) +GEN_OPS_LITTLE(8, 2, false, 4, 4, false) +GEN_OPS_LITTLE(8, 2, false, 8, 4, false) +GEN_OPS_LITTLE(8, 2, false, 8, 8, false) +GEN_OPS_LITTLE(4, 4, false, 1, 1, true) +GEN_OPS_LITTLE(4, 4, false, 2, 1, true) +GEN_OPS_LITTLE(4, 4, false, 4, 1, true) +GEN_OPS_LITTLE(4, 4, false, 8, 1, true) +GEN_OPS_LITTLE(4, 4, false, 2, 2, true) +GEN_OPS_LITTLE(4, 4, false, 4, 2, true) +GEN_OPS_LITTLE(4, 4, false, 8, 2, true) +GEN_OPS_LITTLE(4, 4, false, 4, 4, true) +GEN_OPS_LITTLE(4, 4, false, 8, 4, true) +GEN_OPS_LITTLE(4, 4, false, 8, 8, true) +GEN_OPS_LITTLE(4, 4, false, 1, 1, false) +GEN_OPS_LITTLE(4, 4, false, 2, 1, false) +GEN_OPS_LITTLE(4, 4, false, 4, 1, false) +GEN_OPS_LITTLE(4, 4, false, 8, 1, false) +GEN_OPS_LITTLE(4, 4, false, 2, 2, false) +GEN_OPS_LITTLE(4, 4, false, 4, 2, false) +GEN_OPS_LITTLE(4, 4, false, 8, 2, false) +GEN_OPS_LITTLE(4, 4, false, 4, 4, false) +GEN_OPS_LITTLE(4, 4, false, 8, 4, false) +GEN_OPS_LITTLE(4, 4, false, 8, 8, false) +GEN_OPS_LITTLE(8, 4, false, 1, 1, true) +GEN_OPS_LITTLE(8, 4, false, 2, 1, true) +GEN_OPS_LITTLE(8, 4, false, 4, 1, true) +GEN_OPS_LITTLE(8, 4, false, 8, 1, true) +GEN_OPS_LITTLE(8, 4, false, 2, 2, true) +GEN_OPS_LITTLE(8, 4, false, 4, 2, true) +GEN_OPS_LITTLE(8, 4, false, 8, 2, true) +GEN_OPS_LITTLE(8, 4, false, 4, 4, true) +GEN_OPS_LITTLE(8, 4, false, 8, 4, true) +GEN_OPS_LITTLE(8, 4, false, 8, 8, true) +GEN_OPS_LITTLE(8, 4, false, 1, 1, false) +GEN_OPS_LITTLE(8, 4, false, 2, 1, false) +GEN_OPS_LITTLE(8, 4, false, 4, 1, false) +GEN_OPS_LITTLE(8, 4, false, 8, 1, false) +GEN_OPS_LITTLE(8, 4, false, 2, 2, false) +GEN_OPS_LITTLE(8, 4, false, 4, 2, false) +GEN_OPS_LITTLE(8, 4, false, 8, 2, false) +GEN_OPS_LITTLE(8, 4, false, 4, 4, false) +GEN_OPS_LITTLE(8, 4, false, 8, 4, false) +GEN_OPS_LITTLE(8, 4, false, 8, 8, false) +GEN_OPS_LITTLE(8, 8, false, 1, 1, true) +GEN_OPS_LITTLE(8, 8, false, 2, 1, true) +GEN_OPS_LITTLE(8, 8, false, 4, 1, true) +GEN_OPS_LITTLE(8, 8, false, 8, 1, true) +GEN_OPS_LITTLE(8, 8, false, 2, 2, true) +GEN_OPS_LITTLE(8, 8, false, 4, 2, true) +GEN_OPS_LITTLE(8, 8, false, 8, 2, true) +GEN_OPS_LITTLE(8, 8, false, 4, 4, true) +GEN_OPS_LITTLE(8, 8, false, 8, 4, true) +GEN_OPS_LITTLE(8, 8, false, 8, 8, true) +GEN_OPS_LITTLE(8, 8, false, 1, 1, false) +GEN_OPS_LITTLE(8, 8, false, 2, 1, false) +GEN_OPS_LITTLE(8, 8, false, 4, 1, false) +GEN_OPS_LITTLE(8, 8, false, 8, 1, false) +GEN_OPS_LITTLE(8, 8, false, 2, 2, false) +GEN_OPS_LITTLE(8, 8, false, 4, 2, false) +GEN_OPS_LITTLE(8, 8, false, 8, 2, false) +GEN_OPS_LITTLE(8, 8, false, 4, 4, false) +GEN_OPS_LITTLE(8, 8, false, 8, 4, false) +GEN_OPS_LITTLE(8, 8, false, 8, 8, false) + +GEN_OPS_BIG(1, 1, true, 1, 1, true) +GEN_OPS_BIG(1, 1, true, 2, 1, true) +GEN_OPS_BIG(1, 1, true, 4, 1, true) +GEN_OPS_BIG(1, 1, true, 8, 1, true) +GEN_OPS_BIG(1, 1, true, 2, 2, true) +GEN_OPS_BIG(1, 1, true, 4, 2, true) +GEN_OPS_BIG(1, 1, true, 8, 2, true) +GEN_OPS_BIG(1, 1, true, 4, 4, true) +GEN_OPS_BIG(1, 1, true, 8, 4, true) +GEN_OPS_BIG(1, 1, true, 8, 8, true) +GEN_OPS_BIG(1, 1, true, 1, 1, false) +GEN_OPS_BIG(1, 1, true, 2, 1, false) +GEN_OPS_BIG(1, 1, true, 4, 1, false) +GEN_OPS_BIG(1, 1, true, 8, 1, false) +GEN_OPS_BIG(1, 1, true, 2, 2, false) +GEN_OPS_BIG(1, 1, true, 4, 2, false) +GEN_OPS_BIG(1, 1, true, 8, 2, false) +GEN_OPS_BIG(1, 1, true, 4, 4, false) +GEN_OPS_BIG(1, 1, true, 8, 4, false) +GEN_OPS_BIG(1, 1, true, 8, 8, false) +GEN_OPS_BIG(2, 1, true, 1, 1, true) +GEN_OPS_BIG(2, 1, true, 2, 1, true) +GEN_OPS_BIG(2, 1, true, 4, 1, true) +GEN_OPS_BIG(2, 1, true, 8, 1, true) +GEN_OPS_BIG(2, 1, true, 2, 2, true) +GEN_OPS_BIG(2, 1, true, 4, 2, true) +GEN_OPS_BIG(2, 1, true, 8, 2, true) +GEN_OPS_BIG(2, 1, true, 4, 4, true) +GEN_OPS_BIG(2, 1, true, 8, 4, true) +GEN_OPS_BIG(2, 1, true, 8, 8, true) +GEN_OPS_BIG(2, 1, true, 1, 1, false) +GEN_OPS_BIG(2, 1, true, 2, 1, false) +GEN_OPS_BIG(2, 1, true, 4, 1, false) +GEN_OPS_BIG(2, 1, true, 8, 1, false) +GEN_OPS_BIG(2, 1, true, 2, 2, false) +GEN_OPS_BIG(2, 1, true, 4, 2, false) +GEN_OPS_BIG(2, 1, true, 8, 2, false) +GEN_OPS_BIG(2, 1, true, 4, 4, false) +GEN_OPS_BIG(2, 1, true, 8, 4, false) +GEN_OPS_BIG(2, 1, true, 8, 8, false) +GEN_OPS_BIG(4, 1, true, 1, 1, true) +GEN_OPS_BIG(4, 1, true, 2, 1, true) +GEN_OPS_BIG(4, 1, true, 4, 1, true) +GEN_OPS_BIG(4, 1, true, 8, 1, true) +GEN_OPS_BIG(4, 1, true, 2, 2, true) +GEN_OPS_BIG(4, 1, true, 4, 2, true) +GEN_OPS_BIG(4, 1, true, 8, 2, true) +GEN_OPS_BIG(4, 1, true, 4, 4, true) +GEN_OPS_BIG(4, 1, true, 8, 4, true) +GEN_OPS_BIG(4, 1, true, 8, 8, true) +GEN_OPS_BIG(4, 1, true, 1, 1, false) +GEN_OPS_BIG(4, 1, true, 2, 1, false) +GEN_OPS_BIG(4, 1, true, 4, 1, false) +GEN_OPS_BIG(4, 1, true, 8, 1, false) +GEN_OPS_BIG(4, 1, true, 2, 2, false) +GEN_OPS_BIG(4, 1, true, 4, 2, false) +GEN_OPS_BIG(4, 1, true, 8, 2, false) +GEN_OPS_BIG(4, 1, true, 4, 4, false) +GEN_OPS_BIG(4, 1, true, 8, 4, false) +GEN_OPS_BIG(4, 1, true, 8, 8, false) +GEN_OPS_BIG(8, 1, true, 1, 1, true) +GEN_OPS_BIG(8, 1, true, 2, 1, true) +GEN_OPS_BIG(8, 1, true, 4, 1, true) +GEN_OPS_BIG(8, 1, true, 8, 1, true) +GEN_OPS_BIG(8, 1, true, 2, 2, true) +GEN_OPS_BIG(8, 1, true, 4, 2, true) +GEN_OPS_BIG(8, 1, true, 8, 2, true) +GEN_OPS_BIG(8, 1, true, 4, 4, true) +GEN_OPS_BIG(8, 1, true, 8, 4, true) +GEN_OPS_BIG(8, 1, true, 8, 8, true) +GEN_OPS_BIG(8, 1, true, 1, 1, false) +GEN_OPS_BIG(8, 1, true, 2, 1, false) +GEN_OPS_BIG(8, 1, true, 4, 1, false) +GEN_OPS_BIG(8, 1, true, 8, 1, false) +GEN_OPS_BIG(8, 1, true, 2, 2, false) +GEN_OPS_BIG(8, 1, true, 4, 2, false) +GEN_OPS_BIG(8, 1, true, 8, 2, false) +GEN_OPS_BIG(8, 1, true, 4, 4, false) +GEN_OPS_BIG(8, 1, true, 8, 4, false) +GEN_OPS_BIG(8, 1, true, 8, 8, false) +GEN_OPS_BIG(2, 2, true, 1, 1, true) +GEN_OPS_BIG(2, 2, true, 2, 1, true) +GEN_OPS_BIG(2, 2, true, 4, 1, true) +GEN_OPS_BIG(2, 2, true, 8, 1, true) +GEN_OPS_BIG(2, 2, true, 2, 2, true) +GEN_OPS_BIG(2, 2, true, 4, 2, true) +GEN_OPS_BIG(2, 2, true, 8, 2, true) +GEN_OPS_BIG(2, 2, true, 4, 4, true) +GEN_OPS_BIG(2, 2, true, 8, 4, true) +GEN_OPS_BIG(2, 2, true, 8, 8, true) +GEN_OPS_BIG(2, 2, true, 1, 1, false) +GEN_OPS_BIG(2, 2, true, 2, 1, false) +GEN_OPS_BIG(2, 2, true, 4, 1, false) +GEN_OPS_BIG(2, 2, true, 8, 1, false) +GEN_OPS_BIG(2, 2, true, 2, 2, false) +GEN_OPS_BIG(2, 2, true, 4, 2, false) +GEN_OPS_BIG(2, 2, true, 8, 2, false) +GEN_OPS_BIG(2, 2, true, 4, 4, false) +GEN_OPS_BIG(2, 2, true, 8, 4, false) +GEN_OPS_BIG(2, 2, true, 8, 8, false) +GEN_OPS_BIG(4, 2, true, 1, 1, true) +GEN_OPS_BIG(4, 2, true, 2, 1, true) +GEN_OPS_BIG(4, 2, true, 4, 1, true) +GEN_OPS_BIG(4, 2, true, 8, 1, true) +GEN_OPS_BIG(4, 2, true, 2, 2, true) +GEN_OPS_BIG(4, 2, true, 4, 2, true) +GEN_OPS_BIG(4, 2, true, 8, 2, true) +GEN_OPS_BIG(4, 2, true, 4, 4, true) +GEN_OPS_BIG(4, 2, true, 8, 4, true) +GEN_OPS_BIG(4, 2, true, 8, 8, true) +GEN_OPS_BIG(4, 2, true, 1, 1, false) +GEN_OPS_BIG(4, 2, true, 2, 1, false) +GEN_OPS_BIG(4, 2, true, 4, 1, false) +GEN_OPS_BIG(4, 2, true, 8, 1, false) +GEN_OPS_BIG(4, 2, true, 2, 2, false) +GEN_OPS_BIG(4, 2, true, 4, 2, false) +GEN_OPS_BIG(4, 2, true, 8, 2, false) +GEN_OPS_BIG(4, 2, true, 4, 4, false) +GEN_OPS_BIG(4, 2, true, 8, 4, false) +GEN_OPS_BIG(4, 2, true, 8, 8, false) +GEN_OPS_BIG(8, 2, true, 1, 1, true) +GEN_OPS_BIG(8, 2, true, 2, 1, true) +GEN_OPS_BIG(8, 2, true, 4, 1, true) +GEN_OPS_BIG(8, 2, true, 8, 1, true) +GEN_OPS_BIG(8, 2, true, 2, 2, true) +GEN_OPS_BIG(8, 2, true, 4, 2, true) +GEN_OPS_BIG(8, 2, true, 8, 2, true) +GEN_OPS_BIG(8, 2, true, 4, 4, true) +GEN_OPS_BIG(8, 2, true, 8, 4, true) +GEN_OPS_BIG(8, 2, true, 8, 8, true) +GEN_OPS_BIG(8, 2, true, 1, 1, false) +GEN_OPS_BIG(8, 2, true, 2, 1, false) +GEN_OPS_BIG(8, 2, true, 4, 1, false) +GEN_OPS_BIG(8, 2, true, 8, 1, false) +GEN_OPS_BIG(8, 2, true, 2, 2, false) +GEN_OPS_BIG(8, 2, true, 4, 2, false) +GEN_OPS_BIG(8, 2, true, 8, 2, false) +GEN_OPS_BIG(8, 2, true, 4, 4, false) +GEN_OPS_BIG(8, 2, true, 8, 4, false) +GEN_OPS_BIG(8, 2, true, 8, 8, false) +GEN_OPS_BIG(4, 4, true, 1, 1, true) +GEN_OPS_BIG(4, 4, true, 2, 1, true) +GEN_OPS_BIG(4, 4, true, 4, 1, true) +GEN_OPS_BIG(4, 4, true, 8, 1, true) +GEN_OPS_BIG(4, 4, true, 2, 2, true) +GEN_OPS_BIG(4, 4, true, 4, 2, true) +GEN_OPS_BIG(4, 4, true, 8, 2, true) +GEN_OPS_BIG(4, 4, true, 4, 4, true) +GEN_OPS_BIG(4, 4, true, 8, 4, true) +GEN_OPS_BIG(4, 4, true, 8, 8, true) +GEN_OPS_BIG(4, 4, true, 1, 1, false) +GEN_OPS_BIG(4, 4, true, 2, 1, false) +GEN_OPS_BIG(4, 4, true, 4, 1, false) +GEN_OPS_BIG(4, 4, true, 8, 1, false) +GEN_OPS_BIG(4, 4, true, 2, 2, false) +GEN_OPS_BIG(4, 4, true, 4, 2, false) +GEN_OPS_BIG(4, 4, true, 8, 2, false) +GEN_OPS_BIG(4, 4, true, 4, 4, false) +GEN_OPS_BIG(4, 4, true, 8, 4, false) +GEN_OPS_BIG(4, 4, true, 8, 8, false) +GEN_OPS_BIG(8, 4, true, 1, 1, true) +GEN_OPS_BIG(8, 4, true, 2, 1, true) +GEN_OPS_BIG(8, 4, true, 4, 1, true) +GEN_OPS_BIG(8, 4, true, 8, 1, true) +GEN_OPS_BIG(8, 4, true, 2, 2, true) +GEN_OPS_BIG(8, 4, true, 4, 2, true) +GEN_OPS_BIG(8, 4, true, 8, 2, true) +GEN_OPS_BIG(8, 4, true, 4, 4, true) +GEN_OPS_BIG(8, 4, true, 8, 4, true) +GEN_OPS_BIG(8, 4, true, 8, 8, true) +GEN_OPS_BIG(8, 4, true, 1, 1, false) +GEN_OPS_BIG(8, 4, true, 2, 1, false) +GEN_OPS_BIG(8, 4, true, 4, 1, false) +GEN_OPS_BIG(8, 4, true, 8, 1, false) +GEN_OPS_BIG(8, 4, true, 2, 2, false) +GEN_OPS_BIG(8, 4, true, 4, 2, false) +GEN_OPS_BIG(8, 4, true, 8, 2, false) +GEN_OPS_BIG(8, 4, true, 4, 4, false) +GEN_OPS_BIG(8, 4, true, 8, 4, false) +GEN_OPS_BIG(8, 4, true, 8, 8, false) +GEN_OPS_BIG(8, 8, true, 1, 1, true) +GEN_OPS_BIG(8, 8, true, 2, 1, true) +GEN_OPS_BIG(8, 8, true, 4, 1, true) +GEN_OPS_BIG(8, 8, true, 8, 1, true) +GEN_OPS_BIG(8, 8, true, 2, 2, true) +GEN_OPS_BIG(8, 8, true, 4, 2, true) +GEN_OPS_BIG(8, 8, true, 8, 2, true) +GEN_OPS_BIG(8, 8, true, 4, 4, true) +GEN_OPS_BIG(8, 8, true, 8, 4, true) +GEN_OPS_BIG(8, 8, true, 8, 8, true) +GEN_OPS_BIG(8, 8, true, 1, 1, false) +GEN_OPS_BIG(8, 8, true, 2, 1, false) +GEN_OPS_BIG(8, 8, true, 4, 1, false) +GEN_OPS_BIG(8, 8, true, 8, 1, false) +GEN_OPS_BIG(8, 8, true, 2, 2, false) +GEN_OPS_BIG(8, 8, true, 4, 2, false) +GEN_OPS_BIG(8, 8, true, 8, 2, false) +GEN_OPS_BIG(8, 8, true, 4, 4, false) +GEN_OPS_BIG(8, 8, true, 8, 4, false) +GEN_OPS_BIG(8, 8, true, 8, 8, false) +GEN_OPS_BIG(1, 1, false, 1, 1, true) +GEN_OPS_BIG(1, 1, false, 2, 1, true) +GEN_OPS_BIG(1, 1, false, 4, 1, true) +GEN_OPS_BIG(1, 1, false, 8, 1, true) +GEN_OPS_BIG(1, 1, false, 2, 2, true) +GEN_OPS_BIG(1, 1, false, 4, 2, true) +GEN_OPS_BIG(1, 1, false, 8, 2, true) +GEN_OPS_BIG(1, 1, false, 4, 4, true) +GEN_OPS_BIG(1, 1, false, 8, 4, true) +GEN_OPS_BIG(1, 1, false, 8, 8, true) +GEN_OPS_BIG(1, 1, false, 1, 1, false) +GEN_OPS_BIG(1, 1, false, 2, 1, false) +GEN_OPS_BIG(1, 1, false, 4, 1, false) +GEN_OPS_BIG(1, 1, false, 8, 1, false) +GEN_OPS_BIG(1, 1, false, 2, 2, false) +GEN_OPS_BIG(1, 1, false, 4, 2, false) +GEN_OPS_BIG(1, 1, false, 8, 2, false) +GEN_OPS_BIG(1, 1, false, 4, 4, false) +GEN_OPS_BIG(1, 1, false, 8, 4, false) +GEN_OPS_BIG(1, 1, false, 8, 8, false) +GEN_OPS_BIG(2, 1, false, 1, 1, true) +GEN_OPS_BIG(2, 1, false, 2, 1, true) +GEN_OPS_BIG(2, 1, false, 4, 1, true) +GEN_OPS_BIG(2, 1, false, 8, 1, true) +GEN_OPS_BIG(2, 1, false, 2, 2, true) +GEN_OPS_BIG(2, 1, false, 4, 2, true) +GEN_OPS_BIG(2, 1, false, 8, 2, true) +GEN_OPS_BIG(2, 1, false, 4, 4, true) +GEN_OPS_BIG(2, 1, false, 8, 4, true) +GEN_OPS_BIG(2, 1, false, 8, 8, true) +GEN_OPS_BIG(2, 1, false, 1, 1, false) +GEN_OPS_BIG(2, 1, false, 2, 1, false) +GEN_OPS_BIG(2, 1, false, 4, 1, false) +GEN_OPS_BIG(2, 1, false, 8, 1, false) +GEN_OPS_BIG(2, 1, false, 2, 2, false) +GEN_OPS_BIG(2, 1, false, 4, 2, false) +GEN_OPS_BIG(2, 1, false, 8, 2, false) +GEN_OPS_BIG(2, 1, false, 4, 4, false) +GEN_OPS_BIG(2, 1, false, 8, 4, false) +GEN_OPS_BIG(2, 1, false, 8, 8, false) +GEN_OPS_BIG(4, 1, false, 1, 1, true) +GEN_OPS_BIG(4, 1, false, 2, 1, true) +GEN_OPS_BIG(4, 1, false, 4, 1, true) +GEN_OPS_BIG(4, 1, false, 8, 1, true) +GEN_OPS_BIG(4, 1, false, 2, 2, true) +GEN_OPS_BIG(4, 1, false, 4, 2, true) +GEN_OPS_BIG(4, 1, false, 8, 2, true) +GEN_OPS_BIG(4, 1, false, 4, 4, true) +GEN_OPS_BIG(4, 1, false, 8, 4, true) +GEN_OPS_BIG(4, 1, false, 8, 8, true) +GEN_OPS_BIG(4, 1, false, 1, 1, false) +GEN_OPS_BIG(4, 1, false, 2, 1, false) +GEN_OPS_BIG(4, 1, false, 4, 1, false) +GEN_OPS_BIG(4, 1, false, 8, 1, false) +GEN_OPS_BIG(4, 1, false, 2, 2, false) +GEN_OPS_BIG(4, 1, false, 4, 2, false) +GEN_OPS_BIG(4, 1, false, 8, 2, false) +GEN_OPS_BIG(4, 1, false, 4, 4, false) +GEN_OPS_BIG(4, 1, false, 8, 4, false) +GEN_OPS_BIG(4, 1, false, 8, 8, false) +GEN_OPS_BIG(8, 1, false, 1, 1, true) +GEN_OPS_BIG(8, 1, false, 2, 1, true) +GEN_OPS_BIG(8, 1, false, 4, 1, true) +GEN_OPS_BIG(8, 1, false, 8, 1, true) +GEN_OPS_BIG(8, 1, false, 2, 2, true) +GEN_OPS_BIG(8, 1, false, 4, 2, true) +GEN_OPS_BIG(8, 1, false, 8, 2, true) +GEN_OPS_BIG(8, 1, false, 4, 4, true) +GEN_OPS_BIG(8, 1, false, 8, 4, true) +GEN_OPS_BIG(8, 1, false, 8, 8, true) +GEN_OPS_BIG(8, 1, false, 1, 1, false) +GEN_OPS_BIG(8, 1, false, 2, 1, false) +GEN_OPS_BIG(8, 1, false, 4, 1, false) +GEN_OPS_BIG(8, 1, false, 8, 1, false) +GEN_OPS_BIG(8, 1, false, 2, 2, false) +GEN_OPS_BIG(8, 1, false, 4, 2, false) +GEN_OPS_BIG(8, 1, false, 8, 2, false) +GEN_OPS_BIG(8, 1, false, 4, 4, false) +GEN_OPS_BIG(8, 1, false, 8, 4, false) +GEN_OPS_BIG(8, 1, false, 8, 8, false) +GEN_OPS_BIG(2, 2, false, 1, 1, true) +GEN_OPS_BIG(2, 2, false, 2, 1, true) +GEN_OPS_BIG(2, 2, false, 4, 1, true) +GEN_OPS_BIG(2, 2, false, 8, 1, true) +GEN_OPS_BIG(2, 2, false, 2, 2, true) +GEN_OPS_BIG(2, 2, false, 4, 2, true) +GEN_OPS_BIG(2, 2, false, 8, 2, true) +GEN_OPS_BIG(2, 2, false, 4, 4, true) +GEN_OPS_BIG(2, 2, false, 8, 4, true) +GEN_OPS_BIG(2, 2, false, 8, 8, true) +GEN_OPS_BIG(2, 2, false, 1, 1, false) +GEN_OPS_BIG(2, 2, false, 2, 1, false) +GEN_OPS_BIG(2, 2, false, 4, 1, false) +GEN_OPS_BIG(2, 2, false, 8, 1, false) +GEN_OPS_BIG(2, 2, false, 2, 2, false) +GEN_OPS_BIG(2, 2, false, 4, 2, false) +GEN_OPS_BIG(2, 2, false, 8, 2, false) +GEN_OPS_BIG(2, 2, false, 4, 4, false) +GEN_OPS_BIG(2, 2, false, 8, 4, false) +GEN_OPS_BIG(2, 2, false, 8, 8, false) +GEN_OPS_BIG(4, 2, false, 1, 1, true) +GEN_OPS_BIG(4, 2, false, 2, 1, true) +GEN_OPS_BIG(4, 2, false, 4, 1, true) +GEN_OPS_BIG(4, 2, false, 8, 1, true) +GEN_OPS_BIG(4, 2, false, 2, 2, true) +GEN_OPS_BIG(4, 2, false, 4, 2, true) +GEN_OPS_BIG(4, 2, false, 8, 2, true) +GEN_OPS_BIG(4, 2, false, 4, 4, true) +GEN_OPS_BIG(4, 2, false, 8, 4, true) +GEN_OPS_BIG(4, 2, false, 8, 8, true) +GEN_OPS_BIG(4, 2, false, 1, 1, false) +GEN_OPS_BIG(4, 2, false, 2, 1, false) +GEN_OPS_BIG(4, 2, false, 4, 1, false) +GEN_OPS_BIG(4, 2, false, 8, 1, false) +GEN_OPS_BIG(4, 2, false, 2, 2, false) +GEN_OPS_BIG(4, 2, false, 4, 2, false) +GEN_OPS_BIG(4, 2, false, 8, 2, false) +GEN_OPS_BIG(4, 2, false, 4, 4, false) +GEN_OPS_BIG(4, 2, false, 8, 4, false) +GEN_OPS_BIG(4, 2, false, 8, 8, false) +GEN_OPS_BIG(8, 2, false, 1, 1, true) +GEN_OPS_BIG(8, 2, false, 2, 1, true) +GEN_OPS_BIG(8, 2, false, 4, 1, true) +GEN_OPS_BIG(8, 2, false, 8, 1, true) +GEN_OPS_BIG(8, 2, false, 2, 2, true) +GEN_OPS_BIG(8, 2, false, 4, 2, true) +GEN_OPS_BIG(8, 2, false, 8, 2, true) +GEN_OPS_BIG(8, 2, false, 4, 4, true) +GEN_OPS_BIG(8, 2, false, 8, 4, true) +GEN_OPS_BIG(8, 2, false, 8, 8, true) +GEN_OPS_BIG(8, 2, false, 1, 1, false) +GEN_OPS_BIG(8, 2, false, 2, 1, false) +GEN_OPS_BIG(8, 2, false, 4, 1, false) +GEN_OPS_BIG(8, 2, false, 8, 1, false) +GEN_OPS_BIG(8, 2, false, 2, 2, false) +GEN_OPS_BIG(8, 2, false, 4, 2, false) +GEN_OPS_BIG(8, 2, false, 8, 2, false) +GEN_OPS_BIG(8, 2, false, 4, 4, false) +GEN_OPS_BIG(8, 2, false, 8, 4, false) +GEN_OPS_BIG(8, 2, false, 8, 8, false) +GEN_OPS_BIG(4, 4, false, 1, 1, true) +GEN_OPS_BIG(4, 4, false, 2, 1, true) +GEN_OPS_BIG(4, 4, false, 4, 1, true) +GEN_OPS_BIG(4, 4, false, 8, 1, true) +GEN_OPS_BIG(4, 4, false, 2, 2, true) +GEN_OPS_BIG(4, 4, false, 4, 2, true) +GEN_OPS_BIG(4, 4, false, 8, 2, true) +GEN_OPS_BIG(4, 4, false, 4, 4, true) +GEN_OPS_BIG(4, 4, false, 8, 4, true) +GEN_OPS_BIG(4, 4, false, 8, 8, true) +GEN_OPS_BIG(4, 4, false, 1, 1, false) +GEN_OPS_BIG(4, 4, false, 2, 1, false) +GEN_OPS_BIG(4, 4, false, 4, 1, false) +GEN_OPS_BIG(4, 4, false, 8, 1, false) +GEN_OPS_BIG(4, 4, false, 2, 2, false) +GEN_OPS_BIG(4, 4, false, 4, 2, false) +GEN_OPS_BIG(4, 4, false, 8, 2, false) +GEN_OPS_BIG(4, 4, false, 4, 4, false) +GEN_OPS_BIG(4, 4, false, 8, 4, false) +GEN_OPS_BIG(4, 4, false, 8, 8, false) +GEN_OPS_BIG(8, 4, false, 1, 1, true) +GEN_OPS_BIG(8, 4, false, 2, 1, true) +GEN_OPS_BIG(8, 4, false, 4, 1, true) +GEN_OPS_BIG(8, 4, false, 8, 1, true) +GEN_OPS_BIG(8, 4, false, 2, 2, true) +GEN_OPS_BIG(8, 4, false, 4, 2, true) +GEN_OPS_BIG(8, 4, false, 8, 2, true) +GEN_OPS_BIG(8, 4, false, 4, 4, true) +GEN_OPS_BIG(8, 4, false, 8, 4, true) +GEN_OPS_BIG(8, 4, false, 8, 8, true) +GEN_OPS_BIG(8, 4, false, 1, 1, false) +GEN_OPS_BIG(8, 4, false, 2, 1, false) +GEN_OPS_BIG(8, 4, false, 4, 1, false) +GEN_OPS_BIG(8, 4, false, 8, 1, false) +GEN_OPS_BIG(8, 4, false, 2, 2, false) +GEN_OPS_BIG(8, 4, false, 4, 2, false) +GEN_OPS_BIG(8, 4, false, 8, 2, false) +GEN_OPS_BIG(8, 4, false, 4, 4, false) +GEN_OPS_BIG(8, 4, false, 8, 4, false) +GEN_OPS_BIG(8, 4, false, 8, 8, false) +GEN_OPS_BIG(8, 8, false, 1, 1, true) +GEN_OPS_BIG(8, 8, false, 2, 1, true) +GEN_OPS_BIG(8, 8, false, 4, 1, true) +GEN_OPS_BIG(8, 8, false, 8, 1, true) +GEN_OPS_BIG(8, 8, false, 2, 2, true) +GEN_OPS_BIG(8, 8, false, 4, 2, true) +GEN_OPS_BIG(8, 8, false, 8, 2, true) +GEN_OPS_BIG(8, 8, false, 4, 4, true) +GEN_OPS_BIG(8, 8, false, 8, 4, true) +GEN_OPS_BIG(8, 8, false, 8, 8, true) +GEN_OPS_BIG(8, 8, false, 1, 1, false) +GEN_OPS_BIG(8, 8, false, 2, 1, false) +GEN_OPS_BIG(8, 8, false, 4, 1, false) +GEN_OPS_BIG(8, 8, false, 8, 1, false) +GEN_OPS_BIG(8, 8, false, 2, 2, false) +GEN_OPS_BIG(8, 8, false, 4, 2, false) +GEN_OPS_BIG(8, 8, false, 8, 2, false) +GEN_OPS_BIG(8, 8, false, 4, 4, false) +GEN_OPS_BIG(8, 8, false, 8, 4, false) +GEN_OPS_BIG(8, 8, false, 8, 8, false) + +const MemoryRegionOps ops_list_little_b_valid[] = { + NAME_OPS_LITTLE(1, 1, true, 1, 1, true), + NAME_OPS_LITTLE(1, 1, true, 2, 1, true), + NAME_OPS_LITTLE(1, 1, true, 4, 1, true), + NAME_OPS_LITTLE(1, 1, true, 8, 1, true), + NAME_OPS_LITTLE(1, 1, true, 2, 2, true), + NAME_OPS_LITTLE(1, 1, true, 4, 2, true), + NAME_OPS_LITTLE(1, 1, true, 8, 2, true), + NAME_OPS_LITTLE(1, 1, true, 4, 4, true), + NAME_OPS_LITTLE(1, 1, true, 8, 4, true), + NAME_OPS_LITTLE(1, 1, true, 8, 8, true), + NAME_OPS_LITTLE(1, 1, true, 1, 1, false), + NAME_OPS_LITTLE(1, 1, true, 2, 1, false), + NAME_OPS_LITTLE(1, 1, true, 4, 1, false), + NAME_OPS_LITTLE(1, 1, true, 8, 1, false), + NAME_OPS_LITTLE(1, 1, true, 2, 2, false), + NAME_OPS_LITTLE(1, 1, true, 4, 2, false), + NAME_OPS_LITTLE(1, 1, true, 8, 2, false), + NAME_OPS_LITTLE(1, 1, true, 4, 4, false), + NAME_OPS_LITTLE(1, 1, true, 8, 4, false), + NAME_OPS_LITTLE(1, 1, true, 8, 8, false), + NAME_OPS_LITTLE(2, 1, true, 1, 1, true), + NAME_OPS_LITTLE(2, 1, true, 2, 1, true), + NAME_OPS_LITTLE(2, 1, true, 4, 1, true), + NAME_OPS_LITTLE(2, 1, true, 8, 1, true), + NAME_OPS_LITTLE(2, 1, true, 2, 2, true), + NAME_OPS_LITTLE(2, 1, true, 4, 2, true), + NAME_OPS_LITTLE(2, 1, true, 8, 2, true), + NAME_OPS_LITTLE(2, 1, true, 4, 4, true), + NAME_OPS_LITTLE(2, 1, true, 8, 4, true), + NAME_OPS_LITTLE(2, 1, true, 8, 8, true), + NAME_OPS_LITTLE(2, 1, true, 1, 1, false), + NAME_OPS_LITTLE(2, 1, true, 2, 1, false), + NAME_OPS_LITTLE(2, 1, true, 4, 1, false), + NAME_OPS_LITTLE(2, 1, true, 8, 1, false), + NAME_OPS_LITTLE(2, 1, true, 2, 2, false), + NAME_OPS_LITTLE(2, 1, true, 4, 2, false), + NAME_OPS_LITTLE(2, 1, true, 8, 2, false), + NAME_OPS_LITTLE(2, 1, true, 4, 4, false), + NAME_OPS_LITTLE(2, 1, true, 8, 4, false), + NAME_OPS_LITTLE(2, 1, true, 8, 8, false), + NAME_OPS_LITTLE(4, 1, true, 1, 1, true), + NAME_OPS_LITTLE(4, 1, true, 2, 1, true), + NAME_OPS_LITTLE(4, 1, true, 4, 1, true), + NAME_OPS_LITTLE(4, 1, true, 8, 1, true), + NAME_OPS_LITTLE(4, 1, true, 2, 2, true), + NAME_OPS_LITTLE(4, 1, true, 4, 2, true), + NAME_OPS_LITTLE(4, 1, true, 8, 2, true), + NAME_OPS_LITTLE(4, 1, true, 4, 4, true), + NAME_OPS_LITTLE(4, 1, true, 8, 4, true), + NAME_OPS_LITTLE(4, 1, true, 8, 8, true), + NAME_OPS_LITTLE(4, 1, true, 1, 1, false), + NAME_OPS_LITTLE(4, 1, true, 2, 1, false), + NAME_OPS_LITTLE(4, 1, true, 4, 1, false), + NAME_OPS_LITTLE(4, 1, true, 8, 1, false), + NAME_OPS_LITTLE(4, 1, true, 2, 2, false), + NAME_OPS_LITTLE(4, 1, true, 4, 2, false), + NAME_OPS_LITTLE(4, 1, true, 8, 2, false), + NAME_OPS_LITTLE(4, 1, true, 4, 4, false), + NAME_OPS_LITTLE(4, 1, true, 8, 4, false), + NAME_OPS_LITTLE(4, 1, true, 8, 8, false), + NAME_OPS_LITTLE(8, 1, true, 1, 1, true), + NAME_OPS_LITTLE(8, 1, true, 2, 1, true), + NAME_OPS_LITTLE(8, 1, true, 4, 1, true), + NAME_OPS_LITTLE(8, 1, true, 8, 1, true), + NAME_OPS_LITTLE(8, 1, true, 2, 2, true), + NAME_OPS_LITTLE(8, 1, true, 4, 2, true), + NAME_OPS_LITTLE(8, 1, true, 8, 2, true), + NAME_OPS_LITTLE(8, 1, true, 4, 4, true), + NAME_OPS_LITTLE(8, 1, true, 8, 4, true), + NAME_OPS_LITTLE(8, 1, true, 8, 8, true), + NAME_OPS_LITTLE(8, 1, true, 1, 1, false), + NAME_OPS_LITTLE(8, 1, true, 2, 1, false), + NAME_OPS_LITTLE(8, 1, true, 4, 1, false), + NAME_OPS_LITTLE(8, 1, true, 8, 1, false), + NAME_OPS_LITTLE(8, 1, true, 2, 2, false), + NAME_OPS_LITTLE(8, 1, true, 4, 2, false), + NAME_OPS_LITTLE(8, 1, true, 8, 2, false), + NAME_OPS_LITTLE(8, 1, true, 4, 4, false), + NAME_OPS_LITTLE(8, 1, true, 8, 4, false), + NAME_OPS_LITTLE(8, 1, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_little_b_invalid[] = { + NAME_OPS_LITTLE(1, 1, false, 1, 1, true), + NAME_OPS_LITTLE(1, 1, false, 2, 1, true), + NAME_OPS_LITTLE(1, 1, false, 4, 1, true), + NAME_OPS_LITTLE(1, 1, false, 8, 1, true), + NAME_OPS_LITTLE(1, 1, false, 2, 2, true), + NAME_OPS_LITTLE(1, 1, false, 4, 2, true), + NAME_OPS_LITTLE(1, 1, false, 8, 2, true), + NAME_OPS_LITTLE(1, 1, false, 4, 4, true), + NAME_OPS_LITTLE(1, 1, false, 8, 4, true), + NAME_OPS_LITTLE(1, 1, false, 8, 8, true), + NAME_OPS_LITTLE(1, 1, false, 1, 1, false), + NAME_OPS_LITTLE(1, 1, false, 2, 1, false), + NAME_OPS_LITTLE(1, 1, false, 4, 1, false), + NAME_OPS_LITTLE(1, 1, false, 8, 1, false), + NAME_OPS_LITTLE(1, 1, false, 2, 2, false), + NAME_OPS_LITTLE(1, 1, false, 4, 2, false), + NAME_OPS_LITTLE(1, 1, false, 8, 2, false), + NAME_OPS_LITTLE(1, 1, false, 4, 4, false), + NAME_OPS_LITTLE(1, 1, false, 8, 4, false), + NAME_OPS_LITTLE(1, 1, false, 8, 8, false), + NAME_OPS_LITTLE(2, 1, false, 1, 1, true), + NAME_OPS_LITTLE(2, 1, false, 2, 1, true), + NAME_OPS_LITTLE(2, 1, false, 4, 1, true), + NAME_OPS_LITTLE(2, 1, false, 8, 1, true), + NAME_OPS_LITTLE(2, 1, false, 2, 2, true), + NAME_OPS_LITTLE(2, 1, false, 4, 2, true), + NAME_OPS_LITTLE(2, 1, false, 8, 2, true), + NAME_OPS_LITTLE(2, 1, false, 4, 4, true), + NAME_OPS_LITTLE(2, 1, false, 8, 4, true), + NAME_OPS_LITTLE(2, 1, false, 8, 8, true), + NAME_OPS_LITTLE(2, 1, false, 1, 1, false), + NAME_OPS_LITTLE(2, 1, false, 2, 1, false), + NAME_OPS_LITTLE(2, 1, false, 4, 1, false), + NAME_OPS_LITTLE(2, 1, false, 8, 1, false), + NAME_OPS_LITTLE(2, 1, false, 2, 2, false), + NAME_OPS_LITTLE(2, 1, false, 4, 2, false), + NAME_OPS_LITTLE(2, 1, false, 8, 2, false), + NAME_OPS_LITTLE(2, 1, false, 4, 4, false), + NAME_OPS_LITTLE(2, 1, false, 8, 4, false), + NAME_OPS_LITTLE(2, 1, false, 8, 8, false), + NAME_OPS_LITTLE(4, 1, false, 1, 1, true), + NAME_OPS_LITTLE(4, 1, false, 2, 1, true), + NAME_OPS_LITTLE(4, 1, false, 4, 1, true), + NAME_OPS_LITTLE(4, 1, false, 8, 1, true), + NAME_OPS_LITTLE(4, 1, false, 2, 2, true), + NAME_OPS_LITTLE(4, 1, false, 4, 2, true), + NAME_OPS_LITTLE(4, 1, false, 8, 2, true), + NAME_OPS_LITTLE(4, 1, false, 4, 4, true), + NAME_OPS_LITTLE(4, 1, false, 8, 4, true), + NAME_OPS_LITTLE(4, 1, false, 8, 8, true), + NAME_OPS_LITTLE(4, 1, false, 1, 1, false), + NAME_OPS_LITTLE(4, 1, false, 2, 1, false), + NAME_OPS_LITTLE(4, 1, false, 4, 1, false), + NAME_OPS_LITTLE(4, 1, false, 8, 1, false), + NAME_OPS_LITTLE(4, 1, false, 2, 2, false), + NAME_OPS_LITTLE(4, 1, false, 4, 2, false), + NAME_OPS_LITTLE(4, 1, false, 8, 2, false), + NAME_OPS_LITTLE(4, 1, false, 4, 4, false), + NAME_OPS_LITTLE(4, 1, false, 8, 4, false), + NAME_OPS_LITTLE(4, 1, false, 8, 8, false), + NAME_OPS_LITTLE(8, 1, false, 1, 1, true), + NAME_OPS_LITTLE(8, 1, false, 2, 1, true), + NAME_OPS_LITTLE(8, 1, false, 4, 1, true), + NAME_OPS_LITTLE(8, 1, false, 8, 1, true), + NAME_OPS_LITTLE(8, 1, false, 2, 2, true), + NAME_OPS_LITTLE(8, 1, false, 4, 2, true), + NAME_OPS_LITTLE(8, 1, false, 8, 2, true), + NAME_OPS_LITTLE(8, 1, false, 4, 4, true), + NAME_OPS_LITTLE(8, 1, false, 8, 4, true), + NAME_OPS_LITTLE(8, 1, false, 8, 8, true), + NAME_OPS_LITTLE(8, 1, false, 1, 1, false), + NAME_OPS_LITTLE(8, 1, false, 2, 1, false), + NAME_OPS_LITTLE(8, 1, false, 4, 1, false), + NAME_OPS_LITTLE(8, 1, false, 8, 1, false), + NAME_OPS_LITTLE(8, 1, false, 2, 2, false), + NAME_OPS_LITTLE(8, 1, false, 4, 2, false), + NAME_OPS_LITTLE(8, 1, false, 8, 2, false), + NAME_OPS_LITTLE(8, 1, false, 4, 4, false), + NAME_OPS_LITTLE(8, 1, false, 8, 4, false), + NAME_OPS_LITTLE(8, 1, false, 8, 8, false), +}; + +const MemoryRegionOps ops_list_little_w_valid[] = { + NAME_OPS_LITTLE(2, 2, true, 1, 1, true), + NAME_OPS_LITTLE(2, 2, true, 2, 1, true), + NAME_OPS_LITTLE(2, 2, true, 4, 1, true), + NAME_OPS_LITTLE(2, 2, true, 8, 1, true), + NAME_OPS_LITTLE(2, 2, true, 2, 2, true), + NAME_OPS_LITTLE(2, 2, true, 4, 2, true), + NAME_OPS_LITTLE(2, 2, true, 8, 2, true), + NAME_OPS_LITTLE(2, 2, true, 4, 4, true), + NAME_OPS_LITTLE(2, 2, true, 8, 4, true), + NAME_OPS_LITTLE(2, 2, true, 8, 8, true), + NAME_OPS_LITTLE(2, 2, true, 1, 1, false), + NAME_OPS_LITTLE(2, 2, true, 2, 1, false), + NAME_OPS_LITTLE(2, 2, true, 4, 1, false), + NAME_OPS_LITTLE(2, 2, true, 8, 1, false), + NAME_OPS_LITTLE(2, 2, true, 2, 2, false), + NAME_OPS_LITTLE(2, 2, true, 4, 2, false), + NAME_OPS_LITTLE(2, 2, true, 8, 2, false), + NAME_OPS_LITTLE(2, 2, true, 4, 4, false), + NAME_OPS_LITTLE(2, 2, true, 8, 4, false), + NAME_OPS_LITTLE(2, 2, true, 8, 8, false), + NAME_OPS_LITTLE(4, 2, true, 1, 1, true), + NAME_OPS_LITTLE(4, 2, true, 2, 1, true), + NAME_OPS_LITTLE(4, 2, true, 4, 1, true), + NAME_OPS_LITTLE(4, 2, true, 8, 1, true), + NAME_OPS_LITTLE(4, 2, true, 2, 2, true), + NAME_OPS_LITTLE(4, 2, true, 4, 2, true), + NAME_OPS_LITTLE(4, 2, true, 8, 2, true), + NAME_OPS_LITTLE(4, 2, true, 4, 4, true), + NAME_OPS_LITTLE(4, 2, true, 8, 4, true), + NAME_OPS_LITTLE(4, 2, true, 8, 8, true), + NAME_OPS_LITTLE(4, 2, true, 1, 1, false), + NAME_OPS_LITTLE(4, 2, true, 2, 1, false), + NAME_OPS_LITTLE(4, 2, true, 4, 1, false), + NAME_OPS_LITTLE(4, 2, true, 8, 1, false), + NAME_OPS_LITTLE(4, 2, true, 2, 2, false), + NAME_OPS_LITTLE(4, 2, true, 4, 2, false), + NAME_OPS_LITTLE(4, 2, true, 8, 2, false), + NAME_OPS_LITTLE(4, 2, true, 4, 4, false), + NAME_OPS_LITTLE(4, 2, true, 8, 4, false), + NAME_OPS_LITTLE(4, 2, true, 8, 8, false), + NAME_OPS_LITTLE(8, 2, true, 1, 1, true), + NAME_OPS_LITTLE(8, 2, true, 2, 1, true), + NAME_OPS_LITTLE(8, 2, true, 4, 1, true), + NAME_OPS_LITTLE(8, 2, true, 8, 1, true), + NAME_OPS_LITTLE(8, 2, true, 2, 2, true), + NAME_OPS_LITTLE(8, 2, true, 4, 2, true), + NAME_OPS_LITTLE(8, 2, true, 8, 2, true), + NAME_OPS_LITTLE(8, 2, true, 4, 4, true), + NAME_OPS_LITTLE(8, 2, true, 8, 4, true), + NAME_OPS_LITTLE(8, 2, true, 8, 8, true), + NAME_OPS_LITTLE(8, 2, true, 1, 1, false), + NAME_OPS_LITTLE(8, 2, true, 2, 1, false), + NAME_OPS_LITTLE(8, 2, true, 4, 1, false), + NAME_OPS_LITTLE(8, 2, true, 8, 1, false), + NAME_OPS_LITTLE(8, 2, true, 2, 2, false), + NAME_OPS_LITTLE(8, 2, true, 4, 2, false), + NAME_OPS_LITTLE(8, 2, true, 8, 2, false), + NAME_OPS_LITTLE(8, 2, true, 4, 4, false), + NAME_OPS_LITTLE(8, 2, true, 8, 4, false), + NAME_OPS_LITTLE(8, 2, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_little_w_invalid[] = { + NAME_OPS_LITTLE(2, 2, false, 1, 1, true), + NAME_OPS_LITTLE(2, 2, false, 2, 1, true), + NAME_OPS_LITTLE(2, 2, false, 4, 1, true), + NAME_OPS_LITTLE(2, 2, false, 8, 1, true), + NAME_OPS_LITTLE(2, 2, false, 2, 2, true), + NAME_OPS_LITTLE(2, 2, false, 4, 2, true), + NAME_OPS_LITTLE(2, 2, false, 8, 2, true), + NAME_OPS_LITTLE(2, 2, false, 4, 4, true), + NAME_OPS_LITTLE(2, 2, false, 8, 4, true), + NAME_OPS_LITTLE(2, 2, false, 8, 8, true), + NAME_OPS_LITTLE(2, 2, false, 1, 1, false), + NAME_OPS_LITTLE(2, 2, false, 2, 1, false), + NAME_OPS_LITTLE(2, 2, false, 4, 1, false), + NAME_OPS_LITTLE(2, 2, false, 8, 1, false), + NAME_OPS_LITTLE(2, 2, false, 2, 2, false), + NAME_OPS_LITTLE(2, 2, false, 4, 2, false), + NAME_OPS_LITTLE(2, 2, false, 8, 2, false), + NAME_OPS_LITTLE(2, 2, false, 4, 4, false), + NAME_OPS_LITTLE(2, 2, false, 8, 4, false), + NAME_OPS_LITTLE(2, 2, false, 8, 8, false), + NAME_OPS_LITTLE(4, 2, false, 1, 1, true), + NAME_OPS_LITTLE(4, 2, false, 2, 1, true), + NAME_OPS_LITTLE(4, 2, false, 4, 1, true), + NAME_OPS_LITTLE(4, 2, false, 8, 1, true), + NAME_OPS_LITTLE(4, 2, false, 2, 2, true), + NAME_OPS_LITTLE(4, 2, false, 4, 2, true), + NAME_OPS_LITTLE(4, 2, false, 8, 2, true), + NAME_OPS_LITTLE(4, 2, false, 4, 4, true), + NAME_OPS_LITTLE(4, 2, false, 8, 4, true), + NAME_OPS_LITTLE(4, 2, false, 8, 8, true), + NAME_OPS_LITTLE(4, 2, false, 1, 1, false), + NAME_OPS_LITTLE(4, 2, false, 2, 1, false), + NAME_OPS_LITTLE(4, 2, false, 4, 1, false), + NAME_OPS_LITTLE(4, 2, false, 8, 1, false), + NAME_OPS_LITTLE(4, 2, false, 2, 2, false), + NAME_OPS_LITTLE(4, 2, false, 4, 2, false), + NAME_OPS_LITTLE(4, 2, false, 8, 2, false), + NAME_OPS_LITTLE(4, 2, false, 4, 4, false), + NAME_OPS_LITTLE(4, 2, false, 8, 4, false), + NAME_OPS_LITTLE(4, 2, false, 8, 8, false), + NAME_OPS_LITTLE(8, 2, false, 1, 1, true), + NAME_OPS_LITTLE(8, 2, false, 2, 1, true), + NAME_OPS_LITTLE(8, 2, false, 4, 1, true), + NAME_OPS_LITTLE(8, 2, false, 8, 1, true), + NAME_OPS_LITTLE(8, 2, false, 2, 2, true), + NAME_OPS_LITTLE(8, 2, false, 4, 2, true), + NAME_OPS_LITTLE(8, 2, false, 8, 2, true), + NAME_OPS_LITTLE(8, 2, false, 4, 4, true), + NAME_OPS_LITTLE(8, 2, false, 8, 4, true), + NAME_OPS_LITTLE(8, 2, false, 8, 8, true), + NAME_OPS_LITTLE(8, 2, false, 1, 1, false), + NAME_OPS_LITTLE(8, 2, false, 2, 1, false), + NAME_OPS_LITTLE(8, 2, false, 4, 1, false), + NAME_OPS_LITTLE(8, 2, false, 8, 1, false), + NAME_OPS_LITTLE(8, 2, false, 2, 2, false), + NAME_OPS_LITTLE(8, 2, false, 4, 2, false), + NAME_OPS_LITTLE(8, 2, false, 8, 2, false), + NAME_OPS_LITTLE(8, 2, false, 4, 4, false), + NAME_OPS_LITTLE(8, 2, false, 8, 4, false), + NAME_OPS_LITTLE(8, 2, false, 8, 8, false), +}; + +const MemoryRegionOps ops_list_little_l_valid[] = { + NAME_OPS_LITTLE(4, 4, true, 1, 1, true), + NAME_OPS_LITTLE(4, 4, true, 2, 1, true), + NAME_OPS_LITTLE(4, 4, true, 4, 1, true), + NAME_OPS_LITTLE(4, 4, true, 8, 1, true), + NAME_OPS_LITTLE(4, 4, true, 2, 2, true), + NAME_OPS_LITTLE(4, 4, true, 4, 2, true), + NAME_OPS_LITTLE(4, 4, true, 8, 2, true), + NAME_OPS_LITTLE(4, 4, true, 4, 4, true), + NAME_OPS_LITTLE(4, 4, true, 8, 4, true), + NAME_OPS_LITTLE(4, 4, true, 8, 8, true), + NAME_OPS_LITTLE(4, 4, true, 1, 1, false), + NAME_OPS_LITTLE(4, 4, true, 2, 1, false), + NAME_OPS_LITTLE(4, 4, true, 4, 1, false), + NAME_OPS_LITTLE(4, 4, true, 8, 1, false), + NAME_OPS_LITTLE(4, 4, true, 2, 2, false), + NAME_OPS_LITTLE(4, 4, true, 4, 2, false), + NAME_OPS_LITTLE(4, 4, true, 8, 2, false), + NAME_OPS_LITTLE(4, 4, true, 4, 4, false), + NAME_OPS_LITTLE(4, 4, true, 8, 4, false), + NAME_OPS_LITTLE(4, 4, true, 8, 8, false), + NAME_OPS_LITTLE(8, 4, true, 1, 1, true), + NAME_OPS_LITTLE(8, 4, true, 2, 1, true), + NAME_OPS_LITTLE(8, 4, true, 4, 1, true), + NAME_OPS_LITTLE(8, 4, true, 8, 1, true), + NAME_OPS_LITTLE(8, 4, true, 2, 2, true), + NAME_OPS_LITTLE(8, 4, true, 4, 2, true), + NAME_OPS_LITTLE(8, 4, true, 8, 2, true), + NAME_OPS_LITTLE(8, 4, true, 4, 4, true), + NAME_OPS_LITTLE(8, 4, true, 8, 4, true), + NAME_OPS_LITTLE(8, 4, true, 8, 8, true), + NAME_OPS_LITTLE(8, 4, true, 1, 1, false), + NAME_OPS_LITTLE(8, 4, true, 2, 1, false), + NAME_OPS_LITTLE(8, 4, true, 4, 1, false), + NAME_OPS_LITTLE(8, 4, true, 8, 1, false), + NAME_OPS_LITTLE(8, 4, true, 2, 2, false), + NAME_OPS_LITTLE(8, 4, true, 4, 2, false), + NAME_OPS_LITTLE(8, 4, true, 8, 2, false), + NAME_OPS_LITTLE(8, 4, true, 4, 4, false), + NAME_OPS_LITTLE(8, 4, true, 8, 4, false), + NAME_OPS_LITTLE(8, 4, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_little_l_invalid[] = { + NAME_OPS_LITTLE(4, 4, false, 1, 1, true), + NAME_OPS_LITTLE(4, 4, false, 2, 1, true), + NAME_OPS_LITTLE(4, 4, false, 4, 1, true), + NAME_OPS_LITTLE(4, 4, false, 8, 1, true), + NAME_OPS_LITTLE(4, 4, false, 2, 2, true), + NAME_OPS_LITTLE(4, 4, false, 4, 2, true), + NAME_OPS_LITTLE(4, 4, false, 8, 2, true), + NAME_OPS_LITTLE(4, 4, false, 4, 4, true), + NAME_OPS_LITTLE(4, 4, false, 8, 4, true), + NAME_OPS_LITTLE(4, 4, false, 8, 8, true), + NAME_OPS_LITTLE(4, 4, false, 1, 1, false), + NAME_OPS_LITTLE(4, 4, false, 2, 1, false), + NAME_OPS_LITTLE(4, 4, false, 4, 1, false), + NAME_OPS_LITTLE(4, 4, false, 8, 1, false), + NAME_OPS_LITTLE(4, 4, false, 2, 2, false), + NAME_OPS_LITTLE(4, 4, false, 4, 2, false), + NAME_OPS_LITTLE(4, 4, false, 8, 2, false), + NAME_OPS_LITTLE(4, 4, false, 4, 4, false), + NAME_OPS_LITTLE(4, 4, false, 8, 4, false), + NAME_OPS_LITTLE(4, 4, false, 8, 8, false), + NAME_OPS_LITTLE(8, 4, false, 1, 1, true), + NAME_OPS_LITTLE(8, 4, false, 2, 1, true), + NAME_OPS_LITTLE(8, 4, false, 4, 1, true), + NAME_OPS_LITTLE(8, 4, false, 8, 1, true), + NAME_OPS_LITTLE(8, 4, false, 2, 2, true), + NAME_OPS_LITTLE(8, 4, false, 4, 2, true), + NAME_OPS_LITTLE(8, 4, false, 8, 2, true), + NAME_OPS_LITTLE(8, 4, false, 4, 4, true), + NAME_OPS_LITTLE(8, 4, false, 8, 4, true), + NAME_OPS_LITTLE(8, 4, false, 8, 8, true), + NAME_OPS_LITTLE(8, 4, false, 1, 1, false), + NAME_OPS_LITTLE(8, 4, false, 2, 1, false), + NAME_OPS_LITTLE(8, 4, false, 4, 1, false), + NAME_OPS_LITTLE(8, 4, false, 8, 1, false), + NAME_OPS_LITTLE(8, 4, false, 2, 2, false), + NAME_OPS_LITTLE(8, 4, false, 4, 2, false), + NAME_OPS_LITTLE(8, 4, false, 8, 2, false), + NAME_OPS_LITTLE(8, 4, false, 4, 4, false), + NAME_OPS_LITTLE(8, 4, false, 8, 4, false), + NAME_OPS_LITTLE(8, 4, false, 8, 8, false), +}; + +const MemoryRegionOps ops_list_little_q_valid[] = { + NAME_OPS_LITTLE(8, 8, true, 1, 1, true), + NAME_OPS_LITTLE(8, 8, true, 2, 1, true), + NAME_OPS_LITTLE(8, 8, true, 4, 1, true), + NAME_OPS_LITTLE(8, 8, true, 8, 1, true), + NAME_OPS_LITTLE(8, 8, true, 2, 2, true), + NAME_OPS_LITTLE(8, 8, true, 4, 2, true), + NAME_OPS_LITTLE(8, 8, true, 8, 2, true), + NAME_OPS_LITTLE(8, 8, true, 4, 4, true), + NAME_OPS_LITTLE(8, 8, true, 8, 4, true), + NAME_OPS_LITTLE(8, 8, true, 8, 8, true), + NAME_OPS_LITTLE(8, 8, true, 1, 1, false), + NAME_OPS_LITTLE(8, 8, true, 2, 1, false), + NAME_OPS_LITTLE(8, 8, true, 4, 1, false), + NAME_OPS_LITTLE(8, 8, true, 8, 1, false), + NAME_OPS_LITTLE(8, 8, true, 2, 2, false), + NAME_OPS_LITTLE(8, 8, true, 4, 2, false), + NAME_OPS_LITTLE(8, 8, true, 8, 2, false), + NAME_OPS_LITTLE(8, 8, true, 4, 4, false), + NAME_OPS_LITTLE(8, 8, true, 8, 4, false), + NAME_OPS_LITTLE(8, 8, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_little_q_invalid[] = { + NAME_OPS_LITTLE(8, 8, false, 1, 1, true), + NAME_OPS_LITTLE(8, 8, false, 2, 1, true), + NAME_OPS_LITTLE(8, 8, false, 4, 1, true), + NAME_OPS_LITTLE(8, 8, false, 8, 1, true), + NAME_OPS_LITTLE(8, 8, false, 2, 2, true), + NAME_OPS_LITTLE(8, 8, false, 4, 2, true), + NAME_OPS_LITTLE(8, 8, false, 8, 2, true), + NAME_OPS_LITTLE(8, 8, false, 4, 4, true), + NAME_OPS_LITTLE(8, 8, false, 8, 4, true), + NAME_OPS_LITTLE(8, 8, false, 8, 8, true), + NAME_OPS_LITTLE(8, 8, false, 1, 1, false), + NAME_OPS_LITTLE(8, 8, false, 2, 1, false), + NAME_OPS_LITTLE(8, 8, false, 4, 1, false), + NAME_OPS_LITTLE(8, 8, false, 8, 1, false), + NAME_OPS_LITTLE(8, 8, false, 2, 2, false), + NAME_OPS_LITTLE(8, 8, false, 4, 2, false), + NAME_OPS_LITTLE(8, 8, false, 8, 2, false), + NAME_OPS_LITTLE(8, 8, false, 4, 4, false), + NAME_OPS_LITTLE(8, 8, false, 8, 4, false), + NAME_OPS_LITTLE(8, 8, false, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_b_valid[] = { + NAME_OPS_BIG(1, 1, true, 1, 1, true), + NAME_OPS_BIG(1, 1, true, 2, 1, true), + NAME_OPS_BIG(1, 1, true, 4, 1, true), + NAME_OPS_BIG(1, 1, true, 8, 1, true), + NAME_OPS_BIG(1, 1, true, 2, 2, true), + NAME_OPS_BIG(1, 1, true, 4, 2, true), + NAME_OPS_BIG(1, 1, true, 8, 2, true), + NAME_OPS_BIG(1, 1, true, 4, 4, true), + NAME_OPS_BIG(1, 1, true, 8, 4, true), + NAME_OPS_BIG(1, 1, true, 8, 8, true), + NAME_OPS_BIG(1, 1, true, 1, 1, false), + NAME_OPS_BIG(1, 1, true, 2, 1, false), + NAME_OPS_BIG(1, 1, true, 4, 1, false), + NAME_OPS_BIG(1, 1, true, 8, 1, false), + NAME_OPS_BIG(1, 1, true, 2, 2, false), + NAME_OPS_BIG(1, 1, true, 4, 2, false), + NAME_OPS_BIG(1, 1, true, 8, 2, false), + NAME_OPS_BIG(1, 1, true, 4, 4, false), + NAME_OPS_BIG(1, 1, true, 8, 4, false), + NAME_OPS_BIG(1, 1, true, 8, 8, false), + NAME_OPS_BIG(2, 1, true, 1, 1, true), + NAME_OPS_BIG(2, 1, true, 2, 1, true), + NAME_OPS_BIG(2, 1, true, 4, 1, true), + NAME_OPS_BIG(2, 1, true, 8, 1, true), + NAME_OPS_BIG(2, 1, true, 2, 2, true), + NAME_OPS_BIG(2, 1, true, 4, 2, true), + NAME_OPS_BIG(2, 1, true, 8, 2, true), + NAME_OPS_BIG(2, 1, true, 4, 4, true), + NAME_OPS_BIG(2, 1, true, 8, 4, true), + NAME_OPS_BIG(2, 1, true, 8, 8, true), + NAME_OPS_BIG(2, 1, true, 1, 1, false), + NAME_OPS_BIG(2, 1, true, 2, 1, false), + NAME_OPS_BIG(2, 1, true, 4, 1, false), + NAME_OPS_BIG(2, 1, true, 8, 1, false), + NAME_OPS_BIG(2, 1, true, 2, 2, false), + NAME_OPS_BIG(2, 1, true, 4, 2, false), + NAME_OPS_BIG(2, 1, true, 8, 2, false), + NAME_OPS_BIG(2, 1, true, 4, 4, false), + NAME_OPS_BIG(2, 1, true, 8, 4, false), + NAME_OPS_BIG(2, 1, true, 8, 8, false), + NAME_OPS_BIG(4, 1, true, 1, 1, true), + NAME_OPS_BIG(4, 1, true, 2, 1, true), + NAME_OPS_BIG(4, 1, true, 4, 1, true), + NAME_OPS_BIG(4, 1, true, 8, 1, true), + NAME_OPS_BIG(4, 1, true, 2, 2, true), + NAME_OPS_BIG(4, 1, true, 4, 2, true), + NAME_OPS_BIG(4, 1, true, 8, 2, true), + NAME_OPS_BIG(4, 1, true, 4, 4, true), + NAME_OPS_BIG(4, 1, true, 8, 4, true), + NAME_OPS_BIG(4, 1, true, 8, 8, true), + NAME_OPS_BIG(4, 1, true, 1, 1, false), + NAME_OPS_BIG(4, 1, true, 2, 1, false), + NAME_OPS_BIG(4, 1, true, 4, 1, false), + NAME_OPS_BIG(4, 1, true, 8, 1, false), + NAME_OPS_BIG(4, 1, true, 2, 2, false), + NAME_OPS_BIG(4, 1, true, 4, 2, false), + NAME_OPS_BIG(4, 1, true, 8, 2, false), + NAME_OPS_BIG(4, 1, true, 4, 4, false), + NAME_OPS_BIG(4, 1, true, 8, 4, false), + NAME_OPS_BIG(4, 1, true, 8, 8, false), + NAME_OPS_BIG(8, 1, true, 1, 1, true), + NAME_OPS_BIG(8, 1, true, 2, 1, true), + NAME_OPS_BIG(8, 1, true, 4, 1, true), + NAME_OPS_BIG(8, 1, true, 8, 1, true), + NAME_OPS_BIG(8, 1, true, 2, 2, true), + NAME_OPS_BIG(8, 1, true, 4, 2, true), + NAME_OPS_BIG(8, 1, true, 8, 2, true), + NAME_OPS_BIG(8, 1, true, 4, 4, true), + NAME_OPS_BIG(8, 1, true, 8, 4, true), + NAME_OPS_BIG(8, 1, true, 8, 8, true), + NAME_OPS_BIG(8, 1, true, 1, 1, false), + NAME_OPS_BIG(8, 1, true, 2, 1, false), + NAME_OPS_BIG(8, 1, true, 4, 1, false), + NAME_OPS_BIG(8, 1, true, 8, 1, false), + NAME_OPS_BIG(8, 1, true, 2, 2, false), + NAME_OPS_BIG(8, 1, true, 4, 2, false), + NAME_OPS_BIG(8, 1, true, 8, 2, false), + NAME_OPS_BIG(8, 1, true, 4, 4, false), + NAME_OPS_BIG(8, 1, true, 8, 4, false), + NAME_OPS_BIG(8, 1, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_b_invalid[] = { + NAME_OPS_BIG(1, 1, false, 1, 1, true), + NAME_OPS_BIG(1, 1, false, 2, 1, true), + NAME_OPS_BIG(1, 1, false, 4, 1, true), + NAME_OPS_BIG(1, 1, false, 8, 1, true), + NAME_OPS_BIG(1, 1, false, 2, 2, true), + NAME_OPS_BIG(1, 1, false, 4, 2, true), + NAME_OPS_BIG(1, 1, false, 8, 2, true), + NAME_OPS_BIG(1, 1, false, 4, 4, true), + NAME_OPS_BIG(1, 1, false, 8, 4, true), + NAME_OPS_BIG(1, 1, false, 8, 8, true), + NAME_OPS_BIG(1, 1, false, 1, 1, false), + NAME_OPS_BIG(1, 1, false, 2, 1, false), + NAME_OPS_BIG(1, 1, false, 4, 1, false), + NAME_OPS_BIG(1, 1, false, 8, 1, false), + NAME_OPS_BIG(1, 1, false, 2, 2, false), + NAME_OPS_BIG(1, 1, false, 4, 2, false), + NAME_OPS_BIG(1, 1, false, 8, 2, false), + NAME_OPS_BIG(1, 1, false, 4, 4, false), + NAME_OPS_BIG(1, 1, false, 8, 4, false), + NAME_OPS_BIG(1, 1, false, 8, 8, false), + NAME_OPS_BIG(2, 1, false, 1, 1, true), + NAME_OPS_BIG(2, 1, false, 2, 1, true), + NAME_OPS_BIG(2, 1, false, 4, 1, true), + NAME_OPS_BIG(2, 1, false, 8, 1, true), + NAME_OPS_BIG(2, 1, false, 2, 2, true), + NAME_OPS_BIG(2, 1, false, 4, 2, true), + NAME_OPS_BIG(2, 1, false, 8, 2, true), + NAME_OPS_BIG(2, 1, false, 4, 4, true), + NAME_OPS_BIG(2, 1, false, 8, 4, true), + NAME_OPS_BIG(2, 1, false, 8, 8, true), + NAME_OPS_BIG(2, 1, false, 1, 1, false), + NAME_OPS_BIG(2, 1, false, 2, 1, false), + NAME_OPS_BIG(2, 1, false, 4, 1, false), + NAME_OPS_BIG(2, 1, false, 8, 1, false), + NAME_OPS_BIG(2, 1, false, 2, 2, false), + NAME_OPS_BIG(2, 1, false, 4, 2, false), + NAME_OPS_BIG(2, 1, false, 8, 2, false), + NAME_OPS_BIG(2, 1, false, 4, 4, false), + NAME_OPS_BIG(2, 1, false, 8, 4, false), + NAME_OPS_BIG(2, 1, false, 8, 8, false), + NAME_OPS_BIG(4, 1, false, 1, 1, true), + NAME_OPS_BIG(4, 1, false, 2, 1, true), + NAME_OPS_BIG(4, 1, false, 4, 1, true), + NAME_OPS_BIG(4, 1, false, 8, 1, true), + NAME_OPS_BIG(4, 1, false, 2, 2, true), + NAME_OPS_BIG(4, 1, false, 4, 2, true), + NAME_OPS_BIG(4, 1, false, 8, 2, true), + NAME_OPS_BIG(4, 1, false, 4, 4, true), + NAME_OPS_BIG(4, 1, false, 8, 4, true), + NAME_OPS_BIG(4, 1, false, 8, 8, true), + NAME_OPS_BIG(4, 1, false, 1, 1, false), + NAME_OPS_BIG(4, 1, false, 2, 1, false), + NAME_OPS_BIG(4, 1, false, 4, 1, false), + NAME_OPS_BIG(4, 1, false, 8, 1, false), + NAME_OPS_BIG(4, 1, false, 2, 2, false), + NAME_OPS_BIG(4, 1, false, 4, 2, false), + NAME_OPS_BIG(4, 1, false, 8, 2, false), + NAME_OPS_BIG(4, 1, false, 4, 4, false), + NAME_OPS_BIG(4, 1, false, 8, 4, false), + NAME_OPS_BIG(4, 1, false, 8, 8, false), + NAME_OPS_BIG(8, 1, false, 1, 1, true), + NAME_OPS_BIG(8, 1, false, 2, 1, true), + NAME_OPS_BIG(8, 1, false, 4, 1, true), + NAME_OPS_BIG(8, 1, false, 8, 1, true), + NAME_OPS_BIG(8, 1, false, 2, 2, true), + NAME_OPS_BIG(8, 1, false, 4, 2, true), + NAME_OPS_BIG(8, 1, false, 8, 2, true), + NAME_OPS_BIG(8, 1, false, 4, 4, true), + NAME_OPS_BIG(8, 1, false, 8, 4, true), + NAME_OPS_BIG(8, 1, false, 8, 8, true), + NAME_OPS_BIG(8, 1, false, 1, 1, false), + NAME_OPS_BIG(8, 1, false, 2, 1, false), + NAME_OPS_BIG(8, 1, false, 4, 1, false), + NAME_OPS_BIG(8, 1, false, 8, 1, false), + NAME_OPS_BIG(8, 1, false, 2, 2, false), + NAME_OPS_BIG(8, 1, false, 4, 2, false), + NAME_OPS_BIG(8, 1, false, 8, 2, false), + NAME_OPS_BIG(8, 1, false, 4, 4, false), + NAME_OPS_BIG(8, 1, false, 8, 4, false), + NAME_OPS_BIG(8, 1, false, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_w_valid[] = { + NAME_OPS_BIG(2, 2, true, 1, 1, true), + NAME_OPS_BIG(2, 2, true, 2, 1, true), + NAME_OPS_BIG(2, 2, true, 4, 1, true), + NAME_OPS_BIG(2, 2, true, 8, 1, true), + NAME_OPS_BIG(2, 2, true, 2, 2, true), + NAME_OPS_BIG(2, 2, true, 4, 2, true), + NAME_OPS_BIG(2, 2, true, 8, 2, true), + NAME_OPS_BIG(2, 2, true, 4, 4, true), + NAME_OPS_BIG(2, 2, true, 8, 4, true), + NAME_OPS_BIG(2, 2, true, 8, 8, true), + NAME_OPS_BIG(2, 2, true, 1, 1, false), + NAME_OPS_BIG(2, 2, true, 2, 1, false), + NAME_OPS_BIG(2, 2, true, 4, 1, false), + NAME_OPS_BIG(2, 2, true, 8, 1, false), + NAME_OPS_BIG(2, 2, true, 2, 2, false), + NAME_OPS_BIG(2, 2, true, 4, 2, false), + NAME_OPS_BIG(2, 2, true, 8, 2, false), + NAME_OPS_BIG(2, 2, true, 4, 4, false), + NAME_OPS_BIG(2, 2, true, 8, 4, false), + NAME_OPS_BIG(2, 2, true, 8, 8, false), + NAME_OPS_BIG(4, 2, true, 1, 1, true), + NAME_OPS_BIG(4, 2, true, 2, 1, true), + NAME_OPS_BIG(4, 2, true, 4, 1, true), + NAME_OPS_BIG(4, 2, true, 8, 1, true), + NAME_OPS_BIG(4, 2, true, 2, 2, true), + NAME_OPS_BIG(4, 2, true, 4, 2, true), + NAME_OPS_BIG(4, 2, true, 8, 2, true), + NAME_OPS_BIG(4, 2, true, 4, 4, true), + NAME_OPS_BIG(4, 2, true, 8, 4, true), + NAME_OPS_BIG(4, 2, true, 8, 8, true), + NAME_OPS_BIG(4, 2, true, 1, 1, false), + NAME_OPS_BIG(4, 2, true, 2, 1, false), + NAME_OPS_BIG(4, 2, true, 4, 1, false), + NAME_OPS_BIG(4, 2, true, 8, 1, false), + NAME_OPS_BIG(4, 2, true, 2, 2, false), + NAME_OPS_BIG(4, 2, true, 4, 2, false), + NAME_OPS_BIG(4, 2, true, 8, 2, false), + NAME_OPS_BIG(4, 2, true, 4, 4, false), + NAME_OPS_BIG(4, 2, true, 8, 4, false), + NAME_OPS_BIG(4, 2, true, 8, 8, false), + NAME_OPS_BIG(8, 2, true, 1, 1, true), + NAME_OPS_BIG(8, 2, true, 2, 1, true), + NAME_OPS_BIG(8, 2, true, 4, 1, true), + NAME_OPS_BIG(8, 2, true, 8, 1, true), + NAME_OPS_BIG(8, 2, true, 2, 2, true), + NAME_OPS_BIG(8, 2, true, 4, 2, true), + NAME_OPS_BIG(8, 2, true, 8, 2, true), + NAME_OPS_BIG(8, 2, true, 4, 4, true), + NAME_OPS_BIG(8, 2, true, 8, 4, true), + NAME_OPS_BIG(8, 2, true, 8, 8, true), + NAME_OPS_BIG(8, 2, true, 1, 1, false), + NAME_OPS_BIG(8, 2, true, 2, 1, false), + NAME_OPS_BIG(8, 2, true, 4, 1, false), + NAME_OPS_BIG(8, 2, true, 8, 1, false), + NAME_OPS_BIG(8, 2, true, 2, 2, false), + NAME_OPS_BIG(8, 2, true, 4, 2, false), + NAME_OPS_BIG(8, 2, true, 8, 2, false), + NAME_OPS_BIG(8, 2, true, 4, 4, false), + NAME_OPS_BIG(8, 2, true, 8, 4, false), + NAME_OPS_BIG(8, 2, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_w_invalid[] = { + NAME_OPS_BIG(2, 2, false, 1, 1, true), + NAME_OPS_BIG(2, 2, false, 2, 1, true), + NAME_OPS_BIG(2, 2, false, 4, 1, true), + NAME_OPS_BIG(2, 2, false, 8, 1, true), + NAME_OPS_BIG(2, 2, false, 2, 2, true), + NAME_OPS_BIG(2, 2, false, 4, 2, true), + NAME_OPS_BIG(2, 2, false, 8, 2, true), + NAME_OPS_BIG(2, 2, false, 4, 4, true), + NAME_OPS_BIG(2, 2, false, 8, 4, true), + NAME_OPS_BIG(2, 2, false, 8, 8, true), + NAME_OPS_BIG(2, 2, false, 1, 1, false), + NAME_OPS_BIG(2, 2, false, 2, 1, false), + NAME_OPS_BIG(2, 2, false, 4, 1, false), + NAME_OPS_BIG(2, 2, false, 8, 1, false), + NAME_OPS_BIG(2, 2, false, 2, 2, false), + NAME_OPS_BIG(2, 2, false, 4, 2, false), + NAME_OPS_BIG(2, 2, false, 8, 2, false), + NAME_OPS_BIG(2, 2, false, 4, 4, false), + NAME_OPS_BIG(2, 2, false, 8, 4, false), + NAME_OPS_BIG(2, 2, false, 8, 8, false), + NAME_OPS_BIG(4, 2, false, 1, 1, true), + NAME_OPS_BIG(4, 2, false, 2, 1, true), + NAME_OPS_BIG(4, 2, false, 4, 1, true), + NAME_OPS_BIG(4, 2, false, 8, 1, true), + NAME_OPS_BIG(4, 2, false, 2, 2, true), + NAME_OPS_BIG(4, 2, false, 4, 2, true), + NAME_OPS_BIG(4, 2, false, 8, 2, true), + NAME_OPS_BIG(4, 2, false, 4, 4, true), + NAME_OPS_BIG(4, 2, false, 8, 4, true), + NAME_OPS_BIG(4, 2, false, 8, 8, true), + NAME_OPS_BIG(4, 2, false, 1, 1, false), + NAME_OPS_BIG(4, 2, false, 2, 1, false), + NAME_OPS_BIG(4, 2, false, 4, 1, false), + NAME_OPS_BIG(4, 2, false, 8, 1, false), + NAME_OPS_BIG(4, 2, false, 2, 2, false), + NAME_OPS_BIG(4, 2, false, 4, 2, false), + NAME_OPS_BIG(4, 2, false, 8, 2, false), + NAME_OPS_BIG(4, 2, false, 4, 4, false), + NAME_OPS_BIG(4, 2, false, 8, 4, false), + NAME_OPS_BIG(4, 2, false, 8, 8, false), + NAME_OPS_BIG(8, 2, false, 1, 1, true), + NAME_OPS_BIG(8, 2, false, 2, 1, true), + NAME_OPS_BIG(8, 2, false, 4, 1, true), + NAME_OPS_BIG(8, 2, false, 8, 1, true), + NAME_OPS_BIG(8, 2, false, 2, 2, true), + NAME_OPS_BIG(8, 2, false, 4, 2, true), + NAME_OPS_BIG(8, 2, false, 8, 2, true), + NAME_OPS_BIG(8, 2, false, 4, 4, true), + NAME_OPS_BIG(8, 2, false, 8, 4, true), + NAME_OPS_BIG(8, 2, false, 8, 8, true), + NAME_OPS_BIG(8, 2, false, 1, 1, false), + NAME_OPS_BIG(8, 2, false, 2, 1, false), + NAME_OPS_BIG(8, 2, false, 4, 1, false), + NAME_OPS_BIG(8, 2, false, 8, 1, false), + NAME_OPS_BIG(8, 2, false, 2, 2, false), + NAME_OPS_BIG(8, 2, false, 4, 2, false), + NAME_OPS_BIG(8, 2, false, 8, 2, false), + NAME_OPS_BIG(8, 2, false, 4, 4, false), + NAME_OPS_BIG(8, 2, false, 8, 4, false), + NAME_OPS_BIG(8, 2, false, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_l_valid[] = { + NAME_OPS_BIG(4, 4, true, 1, 1, true), + NAME_OPS_BIG(4, 4, true, 2, 1, true), + NAME_OPS_BIG(4, 4, true, 4, 1, true), + NAME_OPS_BIG(4, 4, true, 8, 1, true), + NAME_OPS_BIG(4, 4, true, 2, 2, true), + NAME_OPS_BIG(4, 4, true, 4, 2, true), + NAME_OPS_BIG(4, 4, true, 8, 2, true), + NAME_OPS_BIG(4, 4, true, 4, 4, true), + NAME_OPS_BIG(4, 4, true, 8, 4, true), + NAME_OPS_BIG(4, 4, true, 8, 8, true), + NAME_OPS_BIG(4, 4, true, 1, 1, false), + NAME_OPS_BIG(4, 4, true, 2, 1, false), + NAME_OPS_BIG(4, 4, true, 4, 1, false), + NAME_OPS_BIG(4, 4, true, 8, 1, false), + NAME_OPS_BIG(4, 4, true, 2, 2, false), + NAME_OPS_BIG(4, 4, true, 4, 2, false), + NAME_OPS_BIG(4, 4, true, 8, 2, false), + NAME_OPS_BIG(4, 4, true, 4, 4, false), + NAME_OPS_BIG(4, 4, true, 8, 4, false), + NAME_OPS_BIG(4, 4, true, 8, 8, false), + NAME_OPS_BIG(8, 4, true, 1, 1, true), + NAME_OPS_BIG(8, 4, true, 2, 1, true), + NAME_OPS_BIG(8, 4, true, 4, 1, true), + NAME_OPS_BIG(8, 4, true, 8, 1, true), + NAME_OPS_BIG(8, 4, true, 2, 2, true), + NAME_OPS_BIG(8, 4, true, 4, 2, true), + NAME_OPS_BIG(8, 4, true, 8, 2, true), + NAME_OPS_BIG(8, 4, true, 4, 4, true), + NAME_OPS_BIG(8, 4, true, 8, 4, true), + NAME_OPS_BIG(8, 4, true, 8, 8, true), + NAME_OPS_BIG(8, 4, true, 1, 1, false), + NAME_OPS_BIG(8, 4, true, 2, 1, false), + NAME_OPS_BIG(8, 4, true, 4, 1, false), + NAME_OPS_BIG(8, 4, true, 8, 1, false), + NAME_OPS_BIG(8, 4, true, 2, 2, false), + NAME_OPS_BIG(8, 4, true, 4, 2, false), + NAME_OPS_BIG(8, 4, true, 8, 2, false), + NAME_OPS_BIG(8, 4, true, 4, 4, false), + NAME_OPS_BIG(8, 4, true, 8, 4, false), + NAME_OPS_BIG(8, 4, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_l_invalid[] = { + NAME_OPS_BIG(4, 4, false, 1, 1, true), + NAME_OPS_BIG(4, 4, false, 2, 1, true), + NAME_OPS_BIG(4, 4, false, 4, 1, true), + NAME_OPS_BIG(4, 4, false, 8, 1, true), + NAME_OPS_BIG(4, 4, false, 2, 2, true), + NAME_OPS_BIG(4, 4, false, 4, 2, true), + NAME_OPS_BIG(4, 4, false, 8, 2, true), + NAME_OPS_BIG(4, 4, false, 4, 4, true), + NAME_OPS_BIG(4, 4, false, 8, 4, true), + NAME_OPS_BIG(4, 4, false, 8, 8, true), + NAME_OPS_BIG(4, 4, false, 1, 1, false), + NAME_OPS_BIG(4, 4, false, 2, 1, false), + NAME_OPS_BIG(4, 4, false, 4, 1, false), + NAME_OPS_BIG(4, 4, false, 8, 1, false), + NAME_OPS_BIG(4, 4, false, 2, 2, false), + NAME_OPS_BIG(4, 4, false, 4, 2, false), + NAME_OPS_BIG(4, 4, false, 8, 2, false), + NAME_OPS_BIG(4, 4, false, 4, 4, false), + NAME_OPS_BIG(4, 4, false, 8, 4, false), + NAME_OPS_BIG(4, 4, false, 8, 8, false), + NAME_OPS_BIG(8, 4, false, 1, 1, true), + NAME_OPS_BIG(8, 4, false, 2, 1, true), + NAME_OPS_BIG(8, 4, false, 4, 1, true), + NAME_OPS_BIG(8, 4, false, 8, 1, true), + NAME_OPS_BIG(8, 4, false, 2, 2, true), + NAME_OPS_BIG(8, 4, false, 4, 2, true), + NAME_OPS_BIG(8, 4, false, 8, 2, true), + NAME_OPS_BIG(8, 4, false, 4, 4, true), + NAME_OPS_BIG(8, 4, false, 8, 4, true), + NAME_OPS_BIG(8, 4, false, 8, 8, true), + NAME_OPS_BIG(8, 4, false, 1, 1, false), + NAME_OPS_BIG(8, 4, false, 2, 1, false), + NAME_OPS_BIG(8, 4, false, 4, 1, false), + NAME_OPS_BIG(8, 4, false, 8, 1, false), + NAME_OPS_BIG(8, 4, false, 2, 2, false), + NAME_OPS_BIG(8, 4, false, 4, 2, false), + NAME_OPS_BIG(8, 4, false, 8, 2, false), + NAME_OPS_BIG(8, 4, false, 4, 4, false), + NAME_OPS_BIG(8, 4, false, 8, 4, false), + NAME_OPS_BIG(8, 4, false, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_q_valid[] = { + NAME_OPS_BIG(8, 8, true, 1, 1, true), + NAME_OPS_BIG(8, 8, true, 2, 1, true), + NAME_OPS_BIG(8, 8, true, 4, 1, true), + NAME_OPS_BIG(8, 8, true, 8, 1, true), + NAME_OPS_BIG(8, 8, true, 2, 2, true), + NAME_OPS_BIG(8, 8, true, 4, 2, true), + NAME_OPS_BIG(8, 8, true, 8, 2, true), + NAME_OPS_BIG(8, 8, true, 4, 4, true), + NAME_OPS_BIG(8, 8, true, 8, 4, true), + NAME_OPS_BIG(8, 8, true, 8, 8, true), + NAME_OPS_BIG(8, 8, true, 1, 1, false), + NAME_OPS_BIG(8, 8, true, 2, 1, false), + NAME_OPS_BIG(8, 8, true, 4, 1, false), + NAME_OPS_BIG(8, 8, true, 8, 1, false), + NAME_OPS_BIG(8, 8, true, 2, 2, false), + NAME_OPS_BIG(8, 8, true, 4, 2, false), + NAME_OPS_BIG(8, 8, true, 8, 2, false), + NAME_OPS_BIG(8, 8, true, 4, 4, false), + NAME_OPS_BIG(8, 8, true, 8, 4, false), + NAME_OPS_BIG(8, 8, true, 8, 8, false), +}; + +const MemoryRegionOps ops_list_big_q_invalid[] = { + NAME_OPS_BIG(8, 8, false, 1, 1, true), + NAME_OPS_BIG(8, 8, false, 2, 1, true), + NAME_OPS_BIG(8, 8, false, 4, 1, true), + NAME_OPS_BIG(8, 8, false, 8, 1, true), + NAME_OPS_BIG(8, 8, false, 2, 2, true), + NAME_OPS_BIG(8, 8, false, 4, 2, true), + NAME_OPS_BIG(8, 8, false, 8, 2, true), + NAME_OPS_BIG(8, 8, false, 4, 4, true), + NAME_OPS_BIG(8, 8, false, 8, 4, true), + NAME_OPS_BIG(8, 8, false, 8, 8, true), + NAME_OPS_BIG(8, 8, false, 1, 1, false), + NAME_OPS_BIG(8, 8, false, 2, 1, false), + NAME_OPS_BIG(8, 8, false, 4, 1, false), + NAME_OPS_BIG(8, 8, false, 8, 1, false), + NAME_OPS_BIG(8, 8, false, 2, 2, false), + NAME_OPS_BIG(8, 8, false, 4, 2, false), + NAME_OPS_BIG(8, 8, false, 8, 2, false), + NAME_OPS_BIG(8, 8, false, 4, 4, false), + NAME_OPS_BIG(8, 8, false, 8, 4, false), + NAME_OPS_BIG(8, 8, false, 8, 8, false), +}; + +#define N_OPS_LIST_LITTLE_B_VALID \ + (sizeof(ops_list_little_b_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_LITTLE_W_VALID \ + (sizeof(ops_list_little_w_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_LITTLE_L_VALID \ + (sizeof(ops_list_little_l_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_LITTLE_Q_VALID \ + (sizeof(ops_list_little_q_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_LITTLE_B_INVALID \ + (sizeof(ops_list_little_b_invalid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_LITTLE_W_INVALID \ + (sizeof(ops_list_little_w_invalid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_LITTLE_L_INVALID \ + (sizeof(ops_list_little_l_invalid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_LITTLE_Q_INVALID \ + (sizeof(ops_list_little_q_invalid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_B_VALID \ + (sizeof(ops_list_big_b_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_W_VALID \ + (sizeof(ops_list_big_w_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_L_VALID \ + (sizeof(ops_list_big_l_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_Q_VALID \ + (sizeof(ops_list_big_q_valid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_B_INVALID \ + (sizeof(ops_list_big_b_invalid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_W_INVALID \ + (sizeof(ops_list_big_w_invalid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_L_INVALID \ + (sizeof(ops_list_big_l_invalid) / sizeof(MemoryRegionOps)) +#define N_OPS_LIST_BIG_Q_INVALID \ + (sizeof(ops_list_big_q_invalid) / sizeof(MemoryRegionOps)) + +#define N_OPS_LIST \ + (N_OPS_LIST_LITTLE_B_VALID + \ + N_OPS_LIST_LITTLE_B_INVALID + \ + N_OPS_LIST_LITTLE_W_VALID + \ + N_OPS_LIST_LITTLE_W_INVALID + \ + N_OPS_LIST_LITTLE_L_VALID + \ + N_OPS_LIST_LITTLE_L_INVALID + \ + N_OPS_LIST_LITTLE_Q_VALID + \ + N_OPS_LIST_LITTLE_Q_INVALID + \ + N_OPS_LIST_BIG_B_VALID + \ + N_OPS_LIST_BIG_B_INVALID + \ + N_OPS_LIST_BIG_W_VALID + \ + N_OPS_LIST_BIG_W_INVALID + \ + N_OPS_LIST_BIG_L_VALID + \ + N_OPS_LIST_BIG_L_INVALID + \ + N_OPS_LIST_BIG_Q_VALID + \ + N_OPS_LIST_BIG_Q_INVALID) + +#define OFF_IDX_OPS_LIST_LITTLE_B_VALID \ + (0) +#define OFF_IDX_OPS_LIST_LITTLE_B_INVALID \ + (OFF_IDX_OPS_LIST_LITTLE_B_VALID + N_OPS_LIST_LITTLE_B_VALID) +#define OFF_IDX_OPS_LIST_LITTLE_W_VALID \ + (OFF_IDX_OPS_LIST_LITTLE_B_INVALID + N_OPS_LIST_LITTLE_B_INVALID) +#define OFF_IDX_OPS_LIST_LITTLE_W_INVALID \ + (OFF_IDX_OPS_LIST_LITTLE_W_VALID + N_OPS_LIST_LITTLE_W_VALID) +#define OFF_IDX_OPS_LIST_LITTLE_L_VALID \ + (OFF_IDX_OPS_LIST_LITTLE_W_INVALID + N_OPS_LIST_LITTLE_W_INVALID) +#define OFF_IDX_OPS_LIST_LITTLE_L_INVALID \ + (OFF_IDX_OPS_LIST_LITTLE_L_VALID + N_OPS_LIST_LITTLE_L_VALID) +#define OFF_IDX_OPS_LIST_LITTLE_Q_VALID \ + (OFF_IDX_OPS_LIST_LITTLE_L_INVALID + N_OPS_LIST_LITTLE_L_INVALID) +#define OFF_IDX_OPS_LIST_LITTLE_Q_INVALID \ + (OFF_IDX_OPS_LIST_LITTLE_Q_VALID + N_OPS_LIST_LITTLE_Q_VALID) +#define OFF_IDX_OPS_LIST_BIG_B_VALID \ + (OFF_IDX_OPS_LIST_LITTLE_Q_INVALID + N_OPS_LIST_LITTLE_Q_INVALID) +#define OFF_IDX_OPS_LIST_BIG_B_INVALID \ + (OFF_IDX_OPS_LIST_BIG_B_VALID + N_OPS_LIST_BIG_B_VALID) +#define OFF_IDX_OPS_LIST_BIG_W_VALID \ + (OFF_IDX_OPS_LIST_BIG_B_INVALID + N_OPS_LIST_BIG_B_INVALID) +#define OFF_IDX_OPS_LIST_BIG_W_INVALID \ + (OFF_IDX_OPS_LIST_BIG_W_VALID + N_OPS_LIST_BIG_W_VALID) +#define OFF_IDX_OPS_LIST_BIG_L_VALID \ + (OFF_IDX_OPS_LIST_BIG_W_INVALID + N_OPS_LIST_BIG_W_INVALID) +#define OFF_IDX_OPS_LIST_BIG_L_INVALID \ + (OFF_IDX_OPS_LIST_BIG_L_VALID + N_OPS_LIST_BIG_L_VALID) +#define OFF_IDX_OPS_LIST_BIG_Q_VALID \ + (OFF_IDX_OPS_LIST_BIG_L_INVALID + N_OPS_LIST_BIG_L_INVALID) +#define OFF_IDX_OPS_LIST_BIG_Q_INVALID \ + (OFF_IDX_OPS_LIST_BIG_Q_VALID + N_OPS_LIST_BIG_Q_VALID) + +#undef GEN_OPS_LITTLE +#undef GEN_OPS_BIG +#undef NAME_OPS_LITTLE +#undef NAME_OPS_BIG +#undef __JOIN2 +#undef __JOIN2_AGAIN +#undef __JOIN6 +#undef __JOIN6_AGAIN +#undef __STR +#undef __STR_AGAIN + +#endif From patchwork Fri Nov 8 03:29:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoyuki HIROSE X-Patchwork-Id: 13867439 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id B3A60D5E120 for ; Fri, 8 Nov 2024 03:31:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9Fhp-00005T-3B; Thu, 07 Nov 2024 22:30:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9Fhm-0008WH-PG for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:38 -0500 Received: from mail-ot1-x336.google.com ([2607:f8b0:4864:20::336]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t9Fhg-0001J6-Gz for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:35 -0500 Received: by mail-ot1-x336.google.com with SMTP id 46e09a7af769-7180d9d0dcbso901713a34.3 for ; Thu, 07 Nov 2024 19:30:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=igel-co-jp.20230601.gappssmtp.com; s=20230601; t=1731036631; x=1731641431; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NW3qUuN/ZEbkTtnS3AnRT5VtM+vaDuzUn4gq1rgzlJE=; b=rapyV/Ji03xM0sFVHtnwOwoQ8jtFzovDlG+65MIXXRm+YmPfKrPy/JK0onB56g1gvw 18eZG6IrFP9cyZ0lTatzE5etBNVnheoCi3ydLMjzFCKjHW2sRKoWlKnxduT0/QS0XVjt IqGvpxXgJZ0LHz8mpFLACfli6yyZNZuFsAwK/7J0GaTfZ51Sn5UBw4O+WO7SVA8/7wTw UO8J1rIOFnVJNJqH4P1XSOYc/7g+MDH+Esy/x4Nbs0dyUHcx2Co30QAqwtNRvRlzELXv Q7L8+Y+976lUpDCKOX2rWXzeVsTTB/UdBSPIt9hdUuqeOQ45s9piVYrQikYRWbzVgXan uqCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731036631; x=1731641431; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NW3qUuN/ZEbkTtnS3AnRT5VtM+vaDuzUn4gq1rgzlJE=; b=OTRHgKZzXywxABhGeMwg/QDnEeCJ4Gb086NVeWxgcOrIMu9pFtcjiCW9Vkzhuy5Hj6 kiOApWuBYFmanqvdk/6NJmNW1R+CvxpYl0iT5VHWiBxP43n3DEsSUUcP1MFwKcN+d9YG Kq3xONlRgWdvuG+kwJN/cDUi9FXDbIPVmMsZj57x6l1VF2JjRMvkoj+3aYzczDu/UqN3 7bzqmc2dCla1xLujplWM8vPvjlQqBv7KTfCxiZ61hH3dt6WSy39ZfmYrMG2LM05aNtdN cYCACHseBt/9RltxZ/I2tObb/W08fh19B2lnDQ6YqKDBNX7RYqz1axaUWVMVidCCtcrp c7Pw== X-Gm-Message-State: AOJu0YyvU9wKX8wTbbSsrNLSYleMdSe48E7ZZLUbTZjZaT3E0dLeC6I5 ZJr2i16eCFnCAtrQxecDP9GORTN6zeqQqFh3GR1M9DdZuh2T7bSriF/+ZQR9XGK4ebFjFu7RDNI d3Sw= X-Google-Smtp-Source: AGHT+IEEc1DUsp6lqRBelrJxhRCMbdHqGOx9W3J7PvOplJedSGPpJ9qQd7zNOJvm0F7JPC+bjxiUDg== X-Received: by 2002:a05:6871:6a6:b0:277:e1bc:7da7 with SMTP id 586e51a60fabf-2956010ad93mr1330812fac.22.1731036631169; Thu, 07 Nov 2024 19:30:31 -0800 (PST) Received: from ThinkPad-T14-hirose.hq.igel.co.jp (napt.igel.co.jp. [219.106.231.132]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7f41f65d358sm2326435a12.84.2024.11.07.19.30.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2024 19:30:30 -0800 (PST) From: Tomoyuki HIROSE To: qemu-devel@nongnu.org Cc: Tomoyuki HIROSE , Fabiano Rosas , Laurent Vivier , Paolo Bonzini Subject: [RFC PATCH 4/5] tests/qtest: add test for memory region access Date: Fri, 8 Nov 2024 12:29:48 +0900 Message-ID: <20241108032952.56692-5-tomoyuki.hirose@igel.co.jp> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> References: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::336; envelope-from=tomoyuki.hirose@igel.co.jp; helo=mail-ot1-x336.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit adds a qtest for accessing various memory regions. The qtest checks the correctness of handling the access to memory regions by using 'memaccess-testdev'. Signed-off-by: Tomoyuki HIROSE --- tests/qtest/memaccess-test.c | 598 +++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 9 + 2 files changed, 607 insertions(+) create mode 100644 tests/qtest/memaccess-test.c diff --git a/tests/qtest/memaccess-test.c b/tests/qtest/memaccess-test.c new file mode 100644 index 0000000000..4a6d2089ad --- /dev/null +++ b/tests/qtest/memaccess-test.c @@ -0,0 +1,598 @@ +/* + * QEMU memory region access test + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2024 IGEL Co., Ltd. + * Author: Tomoyuki HIROSE + */ + +#include "qemu/osdep.h" +#include "libqtest.h" + +#include "hw/misc/memaccess-testdev.h" + +static const char *arch = ""; +static const hwaddr base = 0x200000000; + +struct arch2cpu { + const char *arch; + const char *cpu_model; +}; + +static struct arch2cpu cpus_map[] = { + /* tested targets list */ + { "arm", "cortex-a15" }, + { "aarch64", "cortex-a57" }, + { "avr", "avr6-avr-cpu" }, + { "x86_64", "qemu64,apic-id=0" }, + { "i386", "qemu32,apic-id=0" }, + { "alpha", "ev67" }, + { "cris", "crisv32" }, + { "m68k", "m5206" }, + { "microblaze", "any" }, + { "microblazeel", "any" }, + { "mips", "4Kc" }, + { "mipsel", "I7200" }, + { "mips64", "20Kc" }, + { "mips64el", "I6500" }, + { "or1k", "or1200" }, + { "ppc", "604" }, + { "ppc64", "power8e_v2.1" }, + { "s390x", "qemu" }, + { "sh4", "sh7750r" }, + { "sh4eb", "sh7751r" }, + { "sparc", "LEON2" }, + { "sparc64", "Fujitsu Sparc64" }, + { "tricore", "tc1796" }, + { "xtensa", "dc233c" }, + { "xtensaeb", "fsf" }, + { "hppa", "hppa" }, + { "riscv64", "rv64" }, + { "riscv32", "rv32" }, + { "rx", "rx62n" }, + { "loongarch64", "la464" }, +}; + +static const char *get_cpu_model_by_arch(const char *arch) +{ + for (int i = 0; i < ARRAY_SIZE(cpus_map); i++) { + if (!strcmp(arch, cpus_map[i].arch)) { + return cpus_map[i].cpu_model; + } + } + return NULL; +} + +static QTestState *create_memaccess_qtest(void) +{ + QTestState *qts; + + qts = qtest_initf("-machine none -cpu \"%s\" " + "-device memaccess-testdev,address=0x%" PRIx64, + get_cpu_model_by_arch(arch), base); + return qts; +} + +static void little_b_valid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void little_b_invalid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void little_w_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1133); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x3355); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x5577); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x7799); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x99bb); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xbbdd); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xddff); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x2200); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x4422); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x6644); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x8866); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0xaa88); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xccaa); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xeecc); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } +} + +static void little_w_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } +} + +static void little_l_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x3377bbff); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x77bbff01); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xbbff0189); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0xff0189fe); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x0189fe76); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x89fe7654); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0xfe765432); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0xcc884400); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x67cc8844); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xef67cc88); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0x98ef67cc); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x1098ef67); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x321098ef); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0x54321098); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } +} + +static void little_l_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } +} + +static void little_q_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x77fffe01decabefa); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfffe01decabeface); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xfe01decabefacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0x01decabefacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xdecabefacefeedfa); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xcabefacefeedface); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xbefacefeedfacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0xedfebeefef108800); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfeedfebeefef1088); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xcefeedfebeefef10); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0xfacefeedfebeefef); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xedfacefeedfebeef); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xfeedfacefeedfebe); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xcefeedfacefeedfe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } +} + +static void little_q_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } +} + +static void big_b_valid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void big_b_invalid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void big_w_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1133); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x3355); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x5577); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x7799); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x99bb); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xbbdd); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xddff); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x2200); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x4422); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x6644); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x8866); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0xaa88); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xccaa); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xeecc); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } +} + +static void big_w_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } +} + +static void big_l_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x3377bbff); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x77bbff01); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xbbff0189); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0xff0189fe); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x0189fe76); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x89fe7654); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0xfe765432); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0xcc884400); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x67cc8844); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xef67cc88); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0x98ef67cc); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x1098ef67); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x321098ef); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0x54321098); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } +} + +static void big_l_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } +} + +static void big_q_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x77fffe01decabefa); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfffe01decabeface); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xfe01decabefacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0x01decabefacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xdecabefacefeedfa); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xcabefacefeedface); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xbefacefeedfacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0xedfebeefef108800); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfeedfebeefef1088); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xcefeedfebeefef10); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0xfacefeedfebeefef); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xedfacefeedfebeef); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xfeedfacefeedfebe); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xcefeedfacefeedfe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } +} + +static void big_q_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } +} + +#define DEFINE_test_memaccess(e, e_u, w, w_u, v, v_u) \ + static void \ + test_memaccess_##e##_##w##_##v(void) \ + { \ + QTestState *qts; \ + qts = create_memaccess_qtest(); \ + if (!qts) { \ + return; \ + } \ + \ + for (size_t i = OFF_IDX_OPS_LIST_##e_u##_##w_u##_##v_u; \ + i < OFF_IDX_OPS_LIST_##e_u##_##w_u##_##v_u + \ + N_OPS_LIST_##e_u##_##w_u##_##v_u; \ + i++) { \ + e##_##w##_##v(qts, MEMACCESS_TESTDEV_REGION_SIZE * i); \ + } \ + \ + qtest_quit(qts); \ + } + +DEFINE_test_memaccess(little, LITTLE, b, B, valid, VALID) +DEFINE_test_memaccess(little, LITTLE, w, W, valid, VALID) +DEFINE_test_memaccess(little, LITTLE, l, L, valid, VALID) +DEFINE_test_memaccess(little, LITTLE, q, Q, valid, VALID) +DEFINE_test_memaccess(little, LITTLE, b, B, invalid, INVALID) +DEFINE_test_memaccess(little, LITTLE, w, W, invalid, INVALID) +DEFINE_test_memaccess(little, LITTLE, l, L, invalid, INVALID) +DEFINE_test_memaccess(little, LITTLE, q, Q, invalid, INVALID) +DEFINE_test_memaccess(big, BIG, b, B, valid, VALID) +DEFINE_test_memaccess(big, BIG, w, W, valid, VALID) +DEFINE_test_memaccess(big, BIG, l, L, valid, VALID) +DEFINE_test_memaccess(big, BIG, q, Q, valid, VALID) +DEFINE_test_memaccess(big, BIG, b, B, invalid, INVALID) +DEFINE_test_memaccess(big, BIG, w, W, invalid, INVALID) +DEFINE_test_memaccess(big, BIG, l, L, invalid, INVALID) +DEFINE_test_memaccess(big, BIG, q, Q, invalid, INVALID) + +#undef DEFINE_test_memaccess + +static struct { + const char *name; + void (*test)(void); +} tests[] = { + {"little_b_valid", test_memaccess_little_b_valid}, + {"little_w_valid", test_memaccess_little_w_valid}, + {"little_l_valid", test_memaccess_little_l_valid}, + {"little_q_valid", test_memaccess_little_q_valid}, + {"little_b_invalid", test_memaccess_little_b_invalid}, + {"little_w_invalid", test_memaccess_little_w_invalid}, + {"little_l_invalid", test_memaccess_little_l_invalid}, + {"little_q_invalid", test_memaccess_little_q_invalid}, + {"big_b_valid", test_memaccess_big_b_valid}, + {"big_w_valid", test_memaccess_big_w_valid}, + {"big_l_valid", test_memaccess_big_l_valid}, + {"big_q_valid", test_memaccess_big_q_valid}, + {"big_b_invalid", test_memaccess_big_b_invalid}, + {"big_w_invalid", test_memaccess_big_w_invalid}, + {"big_l_invalid", test_memaccess_big_l_invalid}, + {"big_q_invalid", test_memaccess_big_q_invalid}, +}; + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + arch = qtest_get_arch(); + + for (int i = 0; i < ARRAY_SIZE(tests); i++) { + g_autofree gchar *path = g_strdup_printf("memaccess/%s", tests[i].name); + qtest_add_func(path, tests[i].test); + } + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index aa93e98418..49271cbc3f 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -93,6 +93,7 @@ qtests_i386 = \ (config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \ (config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \ (config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (host_os != 'windows' and \ config_all_devices.has_key('CONFIG_ACPI_ERST') ? ['erst-test'] : []) + \ (config_all_devices.has_key('CONFIG_PCIE_PORT') and \ @@ -136,6 +137,7 @@ qtests_x86_64 = qtests_i386 qtests_alpha = ['boot-serial-test'] + \ qtests_filter + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) qtests_avr = [ 'boot-serial-test' ] @@ -158,6 +160,7 @@ qtests_microblazeel = qtests_microblaze qtests_mips = \ qtests_filter + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) @@ -169,6 +172,7 @@ qtests_ppc = \ qtests_filter + \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ (config_all_devices.has_key('CONFIG_M48T59') ? ['m48t59-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_accel.has_key('CONFIG_TCG') ? ['prom-env-test'] : []) + \ (config_all_accel.has_key('CONFIG_TCG') ? ['boot-serial-test'] : []) + \ ['boot-order-test'] @@ -195,6 +199,7 @@ qtests_sparc = ['prom-env-test', 'm48t59-test', 'boot-serial-test'] + \ qtests_sparc64 = \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ qtests_filter + \ ['prom-env-test', 'boot-serial-test'] @@ -240,6 +245,7 @@ qtests_arm = \ (config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \ (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ ['arm-cpu-features', 'boot-serial-test'] @@ -254,6 +260,7 @@ qtests_aarch64 = \ (config_all_accel.has_key('CONFIG_TCG') and \ config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \ (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed64 : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ ['arm-cpu-features', 'numa-test', 'boot-serial-test', @@ -269,9 +276,11 @@ qtests_s390x = \ 'migration-test'] qtests_riscv32 = \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_devices.has_key('CONFIG_SIFIVE_E_AON') ? ['sifive-e-aon-watchdog-test'] : []) qtests_riscv64 = \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (unpack_edk2_blobs ? ['bios-tables-test'] : []) qos_test_ss = ss.source_set() From patchwork Fri Nov 8 03:29:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoyuki HIROSE X-Patchwork-Id: 13867436 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 39BD5D5E125 for ; Fri, 8 Nov 2024 03:31:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9Fhq-000064-L5; Thu, 07 Nov 2024 22:30:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9Fho-000055-2L for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:40 -0500 Received: from mail-ot1-x335.google.com ([2607:f8b0:4864:20::335]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t9Fhm-0001JV-Hz for qemu-devel@nongnu.org; Thu, 07 Nov 2024 22:30:39 -0500 Received: by mail-ot1-x335.google.com with SMTP id 46e09a7af769-7180f2f5fb0so1136840a34.1 for ; Thu, 07 Nov 2024 19:30:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=igel-co-jp.20230601.gappssmtp.com; s=20230601; t=1731036634; x=1731641434; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YdDTOzE8Etes0rYL2f7MFCzF5u0h8F5dwae5lb252JU=; b=YMubqQ1y39AuCwtzlCbTGMxEwO6JHeShtvkXMwj1Weh6Yjcnj6yRJBd2tJhIo985LR Je6q7OVAkbmSfm+HuJPaxGP76x3eOXVuUcuNebUnoykbsJ/KxNp97uAVMJRGInOsIOfJ trYjCBGleBuxbUNEHe6gbQwOf9GuSWHtHjUfcrB/1pJxGsshzh/wRL1HhUUmqAVZ0W3H tlFrgVQsjlvRIPQl67oTo4Cpnpv6NRDkNPfI6SN/2Zrx4UocyceFHv2M+3lngC42sr6K 7CNpJB/52TF8k75ybrLBS8CrQeEFaktUyD1tFOXu2Dyf3UVIFNS3zwmXWMsl4MaExbEs ahVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731036634; x=1731641434; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YdDTOzE8Etes0rYL2f7MFCzF5u0h8F5dwae5lb252JU=; b=JxHQobjRLonqyRJBUxn+vrFxIBp8w78WxKkWS/QEt+mdLcKzM65E3rJkpLHBhjKzrM 3iLxnUXfePGptph0iSJ383elcNeR4zCuCA6ck9Qzx8ZjnJCtnjIgK09WIgihe3vCOvSD pzfM4CX8jFXFwQpxxpvFa91+NXxnoyMGRZGEyzc2ouap9CSnd0X1+1/51sQB5fimgaXO Llg89knGLQkTBV1yi+IvbMfsUPvitx9cr/ADTIZdS4+UbPsgV7BYr/0NCyJvf1PMJCeA woHgDi4IqAr3ewW5I97Bmcteny2xBKF1hOdxZOFPMx/GR305qglNb3aHqaXTOmLFeO5b OqKA== X-Gm-Message-State: AOJu0Yzb5JFM1SIFCPWrxCZ/aJoc/QhLSlacGD9secdNmd6rtSr0g9GK IOt/6coih+dKtQGUAPWnwlFHceubrxXfbWDTWRfFuO5HQtm7IqwRscaIdhGiVDbea7AkvFRmSpI zxFw= X-Google-Smtp-Source: AGHT+IEXu0s1GY0UffiljTFVCGJoqox2Xl6bnTZv3GnKuobp6H4w0dAo/HfduPYWhQcb6kU2n/iI4w== X-Received: by 2002:a05:6830:40c1:b0:718:2eb7:4ebe with SMTP id 46e09a7af769-71a1c28462cmr1871399a34.27.1731036634271; Thu, 07 Nov 2024 19:30:34 -0800 (PST) Received: from ThinkPad-T14-hirose.hq.igel.co.jp (napt.igel.co.jp. [219.106.231.132]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7f41f65d358sm2326435a12.84.2024.11.07.19.30.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2024 19:30:33 -0800 (PST) From: Tomoyuki HIROSE To: qemu-devel@nongnu.org Cc: Tomoyuki HIROSE Subject: [RFC PATCH 5/5] hw/usb/hcd-xhci: allow unaligned access to Capability Registers Date: Fri, 8 Nov 2024 12:29:49 +0900 Message-ID: <20241108032952.56692-6-tomoyuki.hirose@igel.co.jp> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> References: <20241108032952.56692-1-tomoyuki.hirose@igel.co.jp> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::335; envelope-from=tomoyuki.hirose@igel.co.jp; helo=mail-ot1-x335.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org According to xHCI spec rev 1.2, unaligned access to xHCI Host Controller Capability Registers is not prohibited. In addition, the limit of access size is also unspecified. Actually, some real devices allow unaligned access and 8-byte access to these registers. This commit makes it possible to unaligned access and 8-byte access to Host Controller Capability Registers. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/143 Signed-off-by: Tomoyuki HIROSE --- hw/usb/hcd-xhci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index d85adaca0d..f35cbe526f 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3165,9 +3165,11 @@ static const MemoryRegionOps xhci_cap_ops = { .read = xhci_cap_read, .write = xhci_cap_write, .valid.min_access_size = 1, - .valid.max_access_size = 4, + .valid.max_access_size = 8, + .valid.unaligned = true, .impl.min_access_size = 4, .impl.max_access_size = 4, + .impl.unaligned = false, .endianness = DEVICE_LITTLE_ENDIAN, };