From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 82688 invoked by alias); 2 Apr 2016 22:51:35 -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 82649 invoked by uid 89); 2 Apr 2016 22:51:33 -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=conventional, Search X-HELO: mail-lb0-f170.google.com Received: from mail-lb0-f170.google.com (HELO mail-lb0-f170.google.com) (209.85.217.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sat, 02 Apr 2016 22:51:23 +0000 Received: by mail-lb0-f170.google.com with SMTP id vo2so109109653lbb.1 for ; Sat, 02 Apr 2016 15:51:23 -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; bh=+ESM6KG2njaK47dX7cDP0dMLYDEHDvmBtNmDvAocQt4=; b=bCn1da/ifj5+FkV5DDkEzx59KDvizW+pCalEayKw6rebC24pWn8S695ln48l5P6fhN xAhJnbb047o1X2CJGHMtDOUHAySSxU7eouDPJI3uH0wM6eN3gyfQJs27nwJdcFCrnEFK IrgIvjCvaEdqG3YwgoEDAnVx9Avp8MO6xEq8p8HVdDbE2DiAhPvb7uIZiJ37XhaVTFo+ N9Z4C3mz9Ki2dvg7ndr0DAqzjqjxlbpcn+X8xin5nBA9rZQ+AI5KYcLL+1WGYAqjAMvV pVRRwWaAT1fJyZLnE+MvlSp/pOvdzNxcpJxqzboBOrslMz63qlEGiO+DBE6odiqQS/8R n7cQ== X-Gm-Message-State: AD7BkJIRunUf/rILDI6JhzUTePGVjn6M2DEgCdZB7aUZ6Hvg+IUKyDfBDd2gJWMrVSPjZQ== X-Received: by 10.28.234.11 with SMTP id i11mr181099wmh.76.1459637480312; Sat, 02 Apr 2016 15:51:20 -0700 (PDT) Received: from localhost (host81-140-212-51.range81-140.btcentralplus.com. [81.140.212.51]) by smtp.gmail.com with ESMTPSA id m13sm5763424wma.3.2016.04.02.15.51.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Apr 2016 15:51:19 -0700 (PDT) From: Andrew Burgess To: binutils@sourceware.org Cc: Claudiu.Zissulescu@synopsys.com, noamca@mellanox.com, Andrew Burgess Subject: [PATCH 1/6] gas/arc: Modify structure used to hold opcodes Date: Sat, 02 Apr 2016 22:51:00 -0000 Message-Id: <1459637470-30538-1-git-send-email-andrew.burgess@embecosm.com> X-IsSubscribed: yes X-SW-Source: 2016-04/txt/msg00024.txt.bz2 The assembler builds a hash to hold references to arc_opcode entries in the arc_opcodes table. This hash assumes that each mnemonic will always appear in contiguous blocks within the arc_opcodes table, so all ADD instruction will be together, all AND instructions will likewise be together and so on. The problem with this is that as different variations of arc are added, then it is often more convenient to split instructions apart, so all the base ADD instructions are together, but, variants of ADD specific to one variation of arc are grouped with other instructions specific to that arc variant. The current data structures don't support this configuration of instructions. This commit is a first step towards addressing this problem. In this commit the hash table that currently holds arc_opcode pointers directly, instead holds a pointer to a new, intermediate, data structure. This new data structure holds the pointer to the arc_opcode. In this way, we can, in a future commit support having the intermediate structure hold multiple pointers to different arc_opcode groups. gas/ChangeLog: * config/tc-arc.c (struct arc_opcode_hash_entry): New structure. (arc_find_opcode): New function. (find_special_case_pseudo): Use arc_find_opcode. (find_special_case_flag): Likewise. (assemble_tokens): Likewise. (md_begin): Build hash using struct arc_opcode_hash_entry. --- gas/ChangeLog | 9 ++++++++ gas/config/tc-arc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index 4f9c336..3c093ca 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -305,6 +305,16 @@ static struct arc_last_insn bfd_boolean has_delay_slot; } arc_last_insns[2]; +/* Structure to hold an entry in ARC_OPCODE_HASH. */ +struct arc_opcode_hash_entry +{ + /* The number of pointers in the OPCODE list. */ + size_t count; + + /* Points to a list of opcode pointers. */ + const struct arc_opcode **opcode; +}; + /* Forward declaration. */ static void assemble_insn (const struct arc_opcode *, const expressionS *, int, @@ -551,6 +561,29 @@ static bfd_boolean assembling_insn = FALSE; /* Functions implementation. */ +/* Return a pointer to the first entry in ARC_OPCODE_HASH that matches + NAME, or NULL if there are no matching entries. */ + +static const struct arc_opcode * +arc_find_opcode (const char *name) +{ + const struct arc_opcode_hash_entry *entry; + const struct arc_opcode *opcode; + + entry = hash_find (arc_opcode_hash, name); + if (entry != NULL) + { + if (entry->count > 1) + as_fatal (_("unable to lookup `%s', too many opcode chains"), + name); + opcode = *entry->opcode; + } + else + opcode = NULL; + + return opcode; +} + /* Like md_number_to_chars but used for limms. The 4-byte limm value, is encoded as 'middle-endian' for a little-endian target. FIXME! this function is used for regular 4 byte instructions as well. */ @@ -1871,8 +1904,7 @@ find_special_case_pseudo (const char *opname, break; } - return (const struct arc_opcode *) - hash_find (arc_opcode_hash, pseudo_insn->mnemonic_r); + return arc_find_opcode (pseudo_insn->mnemonic_r); } static const struct arc_opcode * @@ -1908,9 +1940,7 @@ find_special_case_flag (const char *opname, flaglen = strlen (flagnm); if (strcmp (opname + oplen, flagnm) == 0) { - opcode = (const struct arc_opcode *) - hash_find (arc_opcode_hash, - arc_flag_special_opcode->name); + opcode = arc_find_opcode (arc_flag_special_opcode->name); if (*nflgs + 1 > MAX_INSN_FLGS) break; @@ -2000,7 +2030,7 @@ assemble_tokens (const char *opname, int cpumatch = 1; /* Search opcodes. */ - opcode = (const struct arc_opcode *) hash_find (arc_opcode_hash, opname); + opcode = arc_find_opcode (opname); /* Couldn't find opcode conventional way, try special cases. */ if (!opcode) @@ -2147,12 +2177,28 @@ md_begin (void) for (i = 0; i < arc_num_opcodes;) { const char *name, *retval; + struct arc_opcode_hash_entry *entry; name = arc_opcodes[i].name; - retval = hash_insert (arc_opcode_hash, name, (void *) &arc_opcodes[i]); - if (retval) - as_fatal (_("internal error: can't hash opcode '%s': %s"), - name, retval); + + entry = hash_find (arc_opcode_hash, name); + if (entry == NULL) + { + entry = xmalloc (sizeof (*entry)); + entry->count = 0; + entry->opcode = NULL; + + retval = hash_insert (arc_opcode_hash, name, (void *) entry); + if (retval) + as_fatal (_("internal error: can't hash opcode '%s': %s"), + name, retval); + } + + entry->opcode = xrealloc (entry->opcode, + sizeof (const struct arc_opcode *) + * entry->count + 1); + entry->opcode [entry->count] = &arc_opcodes[i]; + entry->count++; while (++i < arc_num_opcodes && (arc_opcodes[i].name == name -- 2.5.1