From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17006 invoked by alias); 23 Feb 2005 17:35:46 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 16973 invoked from network); 23 Feb 2005 17:35:40 -0000 Received: from unknown (HELO nimbus.ott.qnx.com) (209.226.137.76) by sourceware.org with SMTP; 23 Feb 2005 17:35:40 -0000 Received: from [10.12.1.178] (QNXWS7129 [10.12.1.178]) by nimbus.ott.qnx.com with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2653.13) id F1F6TC96; Wed, 23 Feb 2005 12:35:40 -0500 Message-ID: <421CBF5B.3000608@qnx.com> Date: Thu, 24 Feb 2005 00:32:00 -0000 From: Jeff Baker Reply-To: jbaker@qnx.com Organization: QNX Software Systems Ltd. User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) MIME-Version: 1.0 To: binutils@sources.redhat.com Subject: [PATCH] Handle mtsprg and mfsprg properly for BookE Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2005-02/txt/msg00569.txt.bz2 Below is my attempt at a patch to add support for SPRG registers 4->7 on BookE processors. I'm no PowerPC expert so I'm more than open to comments/corrections. During the testing of this patch I noticed that the assembler always produces objects with architecture:common. Is this expected behaviour? 2005-02-23 Jeff Baker * ppc-opc.c (SPRG_MASK): Allow 3 bits for register. (powerpc_operands): Likewise. (insert_sprg): New Function. (extract_sprg): New Function. (powerpc_opcodes): reorder mtsprg/mfsprg opcodes to allow disassembler to locate the correct one. Index: ppc-opc.c =================================================================== RCS file: /cvs/src/src/opcodes/ppc-opc.c,v retrieving revision 1.78 diff -w -u -p -r1.78 ppc-opc.c --- ppc-opc.c 20 Jan 2005 06:54:48 -0000 1.78 +++ ppc-opc.c 23 Feb 2005 17:26:12 -0000 @@ -84,6 +84,8 @@ static unsigned long insert_sh6 (unsigne static long extract_sh6 (unsigned long, int, int *); static unsigned long insert_spr (unsigned long, long, int, const char **); static long extract_spr (unsigned long, int, int *); +static unsigned long insert_sprg (unsigned long, long, int, const char **); +static long extract_sprg (unsigned long, int, int *); static unsigned long insert_tbr (unsigned long, long, int, const char **); static long extract_tbr (unsigned long, int, int *); static unsigned long insert_ev2 (unsigned long, long, int, const char **); @@ -465,8 +467,8 @@ const struct powerpc_operand powerpc_ope /* The SPRG register number in an XFX form m[ft]sprg instruction. */ #define SPRG SPRBAT + 1 -#define SPRG_MASK (0x3 << 16) - { 2, 16, NULL, NULL, 0 }, +#define SPRG_MASK (0x7 << 16) + { 3, 16, insert_sprg, extract_sprg, 0 }, /* The SR field in an X form instruction. */ #define SR SPRG + 1 @@ -1397,6 +1399,31 @@ extract_spr (unsigned long insn, return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0); } +/* Some PPC variants (BookE) have more than 4 SPRG registers. */ + +static unsigned long +insert_sprg (unsigned long insn, + long value, + int dialect, + const char **errmsg) +{ + if (!(dialect & PPC_OPCODE_BOOKE) && (value > 0x03)) + *errmsg = _("invalid register number. Must be between 0 and 3."); + else if (value > 0x07) + *errmsg = _("invalid register number. Must be between 0 and 7."); + return insn | ((value & 0x07) << 16); +} + +static long +extract_sprg (unsigned long insn, + int dialect, + int *invalid) +{ + if (!(dialect & PPC_OPCODE_BOOKE) &&(((insn >> 16) & 0x07) > 0x03)) + *invalid=1; + return ((insn >> 16) & 0x07); +} + /* The TBR field in an XFX instruction. This is just like SPR, but it is optional. When TBR is omitted, it must be inserted as 268 (the magic number of the TB register). These functions treat 0 @@ -3677,14 +3704,6 @@ const struct powerpc_opcode powerpc_opco { "mfbar", XSPR(31,339,159), XSPR_MASK, PPC860, { RT } }, { "mfvrsave", XSPR(31,339,256), XSPR_MASK, PPCVEC, { RT } }, { "mfusprg0", XSPR(31,339,256), XSPR_MASK, BOOKE, { RT } }, -{ "mfsprg4", XSPR(31,339,260), XSPR_MASK, PPC405, { RT } }, -{ "mfsprg4", XSPR(31,339,260), XSPR_MASK, BOOKE, { RT } }, -{ "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405, { RT } }, -{ "mfsprg5", XSPR(31,339,261), XSPR_MASK, BOOKE, { RT } }, -{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405, { RT } }, -{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, BOOKE, { RT } }, -{ "mfsprg7", XSPR(31,339,263), XSPR_MASK, PPC405, { RT } }, -{ "mfsprg7", XSPR(31,339,263), XSPR_MASK, BOOKE, { RT } }, { "mftb", X(31,371), X_MASK, CLASSIC, { RT, TBR } }, { "mftb", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, { "mftbl", XSPR(31,371,268), XSPR_MASK, CLASSIC, { RT } }, @@ -3696,6 +3715,10 @@ const struct powerpc_opcode powerpc_opco { "mfsprg1", XSPR(31,339,273), XSPR_MASK, PPC, { RT } }, { "mfsprg2", XSPR(31,339,274), XSPR_MASK, PPC, { RT } }, { "mfsprg3", XSPR(31,339,275), XSPR_MASK, PPC, { RT } }, +{ "mfsprg4", XSPR(31,339,276), XSPR_MASK, PPC405 | BOOKE, { RT } }, +{ "mfsprg5", XSPR(31,339,277), XSPR_MASK, PPC405 | BOOKE, { RT } }, +{ "mfsprg6", XSPR(31,339,278), XSPR_MASK, PPC405 | BOOKE, { RT } }, +{ "mfsprg7", XSPR(31,339,279), XSPR_MASK, PPC405 | BOOKE, { RT } }, { "mfasr", XSPR(31,339,280), XSPR_MASK, PPC64, { RT } }, { "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } }, { "mfpir", XSPR(31,339,286), XSPR_MASK, BOOKE, { RT } },