From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 51366 invoked by alias); 7 Apr 2016 11:05:58 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 51336 invoked by uid 89); 7 Apr 2016 11:05:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=0xF8, 0xf8, msb X-HELO: mail-wm0-f46.google.com Received: from mail-wm0-f46.google.com (HELO mail-wm0-f46.google.com) (74.125.82.46) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 07 Apr 2016 11:05:47 +0000 Received: by mail-wm0-f46.google.com with SMTP id f198so20338350wme.0 for ; Thu, 07 Apr 2016 04:05:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZhxLtsiirjy/lJUYSK3WI6f+8JZ23VQ8vL0vJqDn3YE=; b=QvlYkrJJluyaUzkiwqq0Ad3gWD4HYeeoZn1vTU0eF0xvgKruNyCYYtVUujP/YUJYyj 9S4OeaTzHF78wA+2/sk4lyJiBHVXmXrPcJ5KBQQSVXKmPkztvpTrz5+/Yc3xBxRAeNs6 v8byEm16bgo07qt9PyjHena0C9Sdn2tvU3f7JEx/uFZfqoClg0s/buBlI70CQLU0qNvB rfFAVgIax3R75BceghZMqfGIoXPSZ0nQB+90BWxnIHxaA8/YjaNBXCNzZSkiKDCjXzyb rAIPM22VWF4w3oUPJwOODbLt0a3JmhpzMdXDDWaGw8wLO/6x1Nr7wq4Uo+JbxMKmDYTk 645w== X-Gm-Message-State: AD7BkJKYDMb+mM2t0gl/iyizyDDNStnNw0Yk+eBmpgdZjCyHENCyNzlNF4UVx+F/odo6VQ== X-Received: by 10.194.60.165 with SMTP id i5mr3131779wjr.178.1460027144826; Thu, 07 Apr 2016 04:05:44 -0700 (PDT) Received: from localhost (host81-140-212-51.range81-140.btcentralplus.com. [81.140.212.51]) by smtp.gmail.com with ESMTPSA id js8sm7886178wjc.37.2016.04.07.04.05.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Apr 2016 04:05:44 -0700 (PDT) From: Andrew Burgess To: binutils@sourceware.org Cc: Claudiu.Zissulescu@synopsys.com, Cupertino.Miranda@synopsys.com, noamca@mellanox.com, Andrew Burgess Subject: [PATCH 1/3] opcodes/arc: Compute insn lengths in disassembler Date: Thu, 07 Apr 2016 11:05:00 -0000 Message-Id: <1460027127-1121-2-git-send-email-andrew.burgess@embecosm.com> In-Reply-To: <1460027127-1121-1-git-send-email-andrew.burgess@embecosm.com> References: <1460027127-1121-1-git-send-email-andrew.burgess@embecosm.com> X-IsSubscribed: yes X-SW-Source: 2016-04/txt/msg00099.txt.bz2 Change the mechanism by which the instruction length is figured out in the arc disassembler. Previously we maintained a micro-decoder that contained enough knowledge to figure out the instruction length. The problem is that as instructions are added for different arc architectures, more and more special cases need to be added to this micro disassembler. This commit changes to a table based lookup for the instruction length, the table maps from the major opcode of the instruction to the instruction length. The table is filled at run-time, the first time that the table is needed. The table is self-checking while being built, it only contains the instructions for the current architecture being disassembled, and if different instructions with the same major opcode have different lengths, this will cause an error while the table is being filled. opcodes/ChangeLog: * arc-dis.c (arc_insn_length): New function. (print_insn_arc): Use arc_insn_length. --- opcodes/ChangeLog | 5 ++++ opcodes/arc-dis.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c index 5f8fa42..f7cff5f 100644 --- a/opcodes/arc-dis.c +++ b/opcodes/arc-dis.c @@ -102,6 +102,53 @@ special_flag_p (const char *opname, return 0; } +/* Calculate the instruction length for an instruction starting with MSB + and LSB, the most and least significant byte. The ISA_MASK is used to + filter the instructions considered to only those that are part of the + current architecture. + + The instruction lengths are calculated from the ARC_OPCODE table, and + cached for later use. */ + +static int +arc_insn_length (unsigned isa_mask, bfd_byte msb, + bfd_byte lsb ATTRIBUTE_UNUSED) +{ + static int tbl [32]; /* 0x00 -> 0x1f */ + static int tbl_init = 0; +#define MAJOR_OPCODE_VALUE(BYTE) (BYTE >> 3) + + if (!tbl_init) + { + unsigned i; + + tbl_init = 1; + memset (tbl, 0, sizeof (tbl)); + for (i = 0; i < arc_num_opcodes; i++) + { + const struct arc_opcode *opcode; + bfd_byte b; + int is_short, len; + unsigned value; + + opcode = &arc_opcodes[i]; + if (!(opcode->cpu & isa_mask)) + continue; + + value = opcode->opcode; + is_short = ARC_SHORT (opcode->mask); + b = MAJOR_OPCODE_VALUE (value >> (is_short ? 8 : 24)); + len = (is_short ? 2 : 4); + assert (tbl [b] == 0 || tbl [b] == len); + tbl [b] = len; + } + } + + return tbl [MAJOR_OPCODE_VALUE (msb)]; + +#undef MAJOR_OPCODE_VALUE +} + /* Disassemble ARC instructions. */ static int @@ -218,20 +265,19 @@ print_insn_arc (bfd_vma memaddr, return size; } - if ( (((buffer[lowbyte] & 0xf8) > 0x38) - && ((buffer[lowbyte] & 0xf8) != 0x48)) - || ((info->mach == bfd_mach_arc_arcv2) - && ((buffer[lowbyte] & 0xF8) == 0x48)) /* FIXME! ugly. */ - ) + insnLen = arc_insn_length (isa_mask, buffer[lowbyte], buffer[highbyte]); + switch (insnLen) { - /* This is a short instruction. */ - insnLen = 2; + case 2: insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte]; - } - else - { - insnLen = 4; + break; + default: + /* An unknown instruction is treated as being length 4. This is + possibly not the best solution, but matches the behaviour that was + in place before the table based instruction length look-up was + introduced. */ + case 4: /* This is a long instruction: Read the remaning 2 bytes. */ status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info); if (status != 0) @@ -240,6 +286,7 @@ print_insn_arc (bfd_vma memaddr, return -1; } insn[0] = ARRANGE_ENDIAN (info, buffer); + break; } /* Set some defaults for the insn info. */ -- 2.5.1