From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15238 invoked by alias); 13 Nov 2001 19:46:53 -0000 Mailing-List: contact cgen-help@sourceware.cygnus.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cgen-owner@sourceware.cygnus.com Received: (qmail 15188 invoked from network); 13 Nov 2001 19:46:50 -0000 Message-ID: <3BF178A6.F12C7023@redhat.com> Date: Fri, 05 Oct 2001 13:20:00 -0000 From: Dave Brolley Organization: Red Hat Canada, Ltd X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.16-22 i686) X-Accept-Language: en MIME-Version: 1.0 To: cgen@sources.redhat.com, binutils@sources.redhat.com Subject: [patch][rfa] Ordering insns in hash chain for cgen disassemblers Content-Type: multipart/mixed; boundary="------------ACFB76AA37DDF49B0C5186D1" X-SW-Source: 2001-q4/txt/msg00001.txt.bz2 This is a multi-part message in MIME format. --------------ACFB76AA37DDF49B0C5186D1 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-length: 1650 Hi, Currently insns are added to the chains of the hash table in the disassembler in the order in which they appear in the .cpu file. Thus, resolution of insns which are a special case of another must be managed by carefully defining then in the correct order. The insns are also parsed in the order in which they appear and this is important in cases where an operand in the assembler input might be successfully parsed as more than on ecgen operand (e.g. register names are successfully parsed as immediates). There is an impass, however, when the order in which insns need to be parsed is not the same as the order in which decoding must be attempted. I have run into such a case where an operand of an insn may be a register name or an immediate. One particular register is forbidden, however, and when the bits representing that register appear in the field of the insn, it signifies that the operand is really an immediate value which follows the insn. Thus the operand must be parsed as a register name first, but decoding must attempt it as an immediate first. The problem may be solved by automating the order in which the insns are placed into the hash chains in the disassembler. By ordering insns iby the number of decoding bits in decreasing order, we can assure that an insn which is a special case of another wil be attempted first, regardless of the order in which they appear in the .cpu file. This is the same ordering which would have been required manually up until now, so no existing ports should be affected. I have tested the attached patch on m32r (sid), fr30 and two internal ports. Requesting approval to commit. Dave --------------ACFB76AA37DDF49B0C5186D1 Content-Type: text/plain; charset=us-ascii; name="dis-sort.patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dis-sort.patch.txt" Content-length: 3768 Index: opcodes/cgen-dis.c =================================================================== RCS file: /cvs/src/src/opcodes/cgen-dis.c,v retrieving revision 1.5 diff -c -p -r1.5 cgen-dis.c *** opcodes/cgen-dis.c 2001/09/19 17:40:28 1.5 --- opcodes/cgen-dis.c 2001/11/12 20:10:55 *************** *** 30,36 **** static CGEN_INSN_LIST * hash_insn_array PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, int, int, CGEN_INSN_LIST **, CGEN_INSN_LIST *)); static CGEN_INSN_LIST * hash_insn_list PARAMS ((CGEN_CPU_DESC, const CGEN_INSN_LIST *, CGEN_INSN_LIST **, CGEN_INSN_LIST *)); static void build_dis_hash_table PARAMS ((CGEN_CPU_DESC)); ! /* Subroutine of build_dis_hash_table to add INSNS to the hash table. COUNT is the number of elements in INSNS. --- 30,87 ---- static CGEN_INSN_LIST * hash_insn_array PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, int, int, CGEN_INSN_LIST **, CGEN_INSN_LIST *)); static CGEN_INSN_LIST * hash_insn_list PARAMS ((CGEN_CPU_DESC, const CGEN_INSN_LIST *, CGEN_INSN_LIST **, CGEN_INSN_LIST *)); static void build_dis_hash_table PARAMS ((CGEN_CPU_DESC)); ! ! /* Return the number of decodable bits in this insn. */ ! static int ! count_decodable_bits (insn) ! const CGEN_INSN *insn; ! { ! unsigned mask = CGEN_INSN_BASE_MASK (insn); ! int bits = 0; ! int m; ! for (m = 1; m != 0; m <<= 1) ! { ! if (mask & m) ! ++bits; ! } ! return bits; ! } ! ! /* Add an instruction to the hash chain. */ ! static void ! add_insn_to_hash_chain (hentbuf, insn, htable, hash) ! CGEN_INSN_LIST *hentbuf; ! const CGEN_INSN *insn; ! CGEN_INSN_LIST **htable; ! unsigned int hash; ! { ! CGEN_INSN_LIST *current_buf; ! CGEN_INSN_LIST *previous_buf; ! int insn_decodable_bits; ! ! /* Add insns sorted by the number of decodable bits, in decreasing order. ! This ensures that any insn which is a special case of another will be ! checked first. */ ! insn_decodable_bits = count_decodable_bits (insn); ! previous_buf = NULL; ! for (current_buf = htable[hash]; current_buf != NULL; ! current_buf = current_buf->next) ! { ! int current_decodable_bits = count_decodable_bits (current_buf->insn); ! if (insn_decodable_bits >= current_decodable_bits) ! break; ! previous_buf = current_buf; ! } ! ! /* Now insert the new insn. */ ! hentbuf->insn = insn; ! hentbuf->next = current_buf; ! if (previous_buf == NULL) ! htable[hash] = hentbuf; ! else ! previous_buf->next = hentbuf; ! } ! /* Subroutine of build_dis_hash_table to add INSNS to the hash table. COUNT is the number of elements in INSNS. *************** hash_insn_array (cd, insns, count, entsi *** 74,82 **** CGEN_INSN_MASK_BITSIZE (insn), big_p); hash = (* cd->dis_hash) (buf, value); ! hentbuf->next = htable[hash]; ! hentbuf->insn = insn; ! htable[hash] = hentbuf; } return hentbuf; --- 125,131 ---- CGEN_INSN_MASK_BITSIZE (insn), big_p); hash = (* cd->dis_hash) (buf, value); ! add_insn_to_hash_chain (hentbuf, insn, htable, hash); } return hentbuf; *************** hash_insn_list (cd, insns, htable, hentb *** 114,122 **** CGEN_INSN_MASK_BITSIZE (ilist->insn), big_p); hash = (* cd->dis_hash) (buf, value); ! hentbuf->next = htable [hash]; ! hentbuf->insn = ilist->insn; ! htable [hash] = hentbuf; } return hentbuf; --- 163,169 ---- CGEN_INSN_MASK_BITSIZE (ilist->insn), big_p); hash = (* cd->dis_hash) (buf, value); ! add_insn_to_hash_chain (hentbuf, ilist->insn, htable, hash); } return hentbuf; --------------ACFB76AA37DDF49B0C5186D1-- From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dave Brolley To: cgen@sources.redhat.com, binutils@sources.redhat.com Subject: [patch][rfa] Ordering insns in hash chain for cgen disassemblers Date: Tue, 13 Nov 2001 11:46:00 -0000 Message-ID: <3BF178A6.F12C7023@redhat.com> X-SW-Source: 2001-q4/msg00026.html Message-ID: <20011113114600.Unm6lVwQ-gAzwV3K4mAaWGb3zi3vORW7rza-sGmtst0@z> Hi, Currently insns are added to the chains of the hash table in the disassembler in the order in which they appear in the .cpu file. Thus, resolution of insns which are a special case of another must be managed by carefully defining then in the correct order. The insns are also parsed in the order in which they appear and this is important in cases where an operand in the assembler input might be successfully parsed as more than on ecgen operand (e.g. register names are successfully parsed as immediates). There is an impass, however, when the order in which insns need to be parsed is not the same as the order in which decoding must be attempted. I have run into such a case where an operand of an insn may be a register name or an immediate. One particular register is forbidden, however, and when the bits representing that register appear in the field of the insn, it signifies that the operand is really an immediate value which follows the insn. Thus the operand must be parsed as a register name first, but decoding must attempt it as an immediate first. The problem may be solved by automating the order in which the insns are placed into the hash chains in the disassembler. By ordering insns iby the number of decoding bits in decreasing order, we can assure that an insn which is a special case of another wil be attempted first, regardless of the order in which they appear in the .cpu file. This is the same ordering which would have been required manually up until now, so no existing ports should be affected. I have tested the attached patch on m32r (sid), fr30 and two internal ports. Requesting approval to commit. Dave