From patchwork Tue Aug 19 10:36:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Clifton X-Patchwork-Id: 2431 Received: (qmail 6804 invoked by alias); 19 Aug 2014 10:36:45 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 6791 invoked by uid 89); 19 Aug 2014 10:36:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.1 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 19 Aug 2014 10:36:42 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s7JAaeWq005082 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 19 Aug 2014 06:36:40 -0400 Received: from [10.36.6.50] (vpn1-6-50.ams2.redhat.com [10.36.6.50]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s7JAaa82000875 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 19 Aug 2014 06:36:39 -0400 Message-ID: <53F328B4.5040502@redhat.com> Date: Tue, 19 Aug 2014 11:36:36 +0100 From: Nicholas Clifton User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.7.0 MIME-Version: 1.0 To: Mike Frysinger , gdb-patches@sourceware.org Subject: Re: MSP430 SIM: Add support for hardware multiply References: <87zjislnam.fsf@redhat.com> <5804568.hLA7fg3VQR@vapier> In-Reply-To: <5804568.hLA7fg3VQR@vapier> Hi Mike, > the global static vars really look like they should be part of the cpu or sim > state and not just global variables. otherwise you can't easily reset them ? Done: sim/msp430/ChangeLog 2014-08-19 Nick Clifton * msp430-sim.c: Move static hardware multiply support variables from here... * msp430-sim.h (msp430_cpu_state): ... into here ... * msp430-sim.c (get_op, put_op): ... and update references to use the msp430_cpu_state structure. diff --git a/sim/msp430/msp430-sim.c b/sim/msp430/msp430-sim.c index 7812868..b9a6a7e 100644 --- a/sim/msp430/msp430-sim.c +++ b/sim/msp430/msp430-sim.c @@ -317,18 +317,6 @@ trace_reg_get (SIM_DESC sd, int n) #define REG_GET(N) trace_reg_get (sd, N) /* Hardware multiply (and accumulate) support. */ -static enum { UNSIGN_32, SIGN_32, UNSIGN_MAC_32, SIGN_MAC_32 } hwmult_type; -static unsigned32 hwmult_op1; -static unsigned32 hwmult_op2; -static unsigned32 hwmult_result; -static signed32 hwmult_signed_result; -static unsigned32 hwmult_accumulator; -static signed32 hwmult_signed_accumulator; - -static enum { UNSIGN_64, SIGN_64 } hw32mult_type; -static unsigned64 hw32mult_op1; -static unsigned64 hw32mult_op2; -static unsigned64 hw32mult_result; static unsigned int zero_ext (unsigned int v, unsigned int bits) @@ -413,65 +401,69 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n) switch (addr) { case 0x13A: - switch (hwmult_type) + switch (HWMULT (sd, hwmult_type)) { case UNSIGN_MAC_32: - case UNSIGN_32: rv = zero_ext (hwmult_result, 16); break; + case UNSIGN_32: + rv = zero_ext (HWMULT (sd, hwmult_result), 16); + break; case SIGN_MAC_32: - case SIGN_32: rv = sign_ext (hwmult_signed_result, 16); break; + case SIGN_32: + rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16); + break; } break; case 0x13C: - switch (hwmult_type) + switch (HWMULT (sd, hwmult_type)) { case UNSIGN_MAC_32: case UNSIGN_32: - rv = zero_ext (hwmult_result >> 16, 16); + rv = zero_ext (HWMULT (sd, hwmult_result) >> 16, 16); break; case SIGN_MAC_32: case SIGN_32: - rv = sign_ext (hwmult_signed_result >> 16, 16); + rv = sign_ext (HWMULT (sd, hwmult_signed_result) >> 16, 16); break; } break; case 0x13E: - switch (hwmult_type) + switch (HWMULT (sd, hwmult_type)) { case UNSIGN_32: rv = 0; break; case SIGN_32: - rv = hwmult_signed_result < 0 ? -1 : 0; + rv = HWMULT (sd, hwmult_signed_result) < 0 ? -1 : 0; break; case UNSIGN_MAC_32: rv = 0; /* FIXME: Should be carry of last accumulate. */ break; case SIGN_MAC_32: - rv = hwmult_signed_accumulator < 0 ? -1 : 0; + rv = HWMULT (sd, hwmult_signed_accumulator) < 0 ? -1 : 0; break; } break; case 0x154: - rv = zero_ext (hw32mult_result, 16); + rv = zero_ext (HWMULT (sd, hw32mult_result), 16); break; case 0x156: - rv = zero_ext (hw32mult_result >> 16, 16); + rv = zero_ext (HWMULT (sd, hw32mult_result) >> 16, 16); break; case 0x158: - rv = zero_ext (hw32mult_result >> 32, 16); + rv = zero_ext (HWMULT (sd, hw32mult_result) >> 32, 16); break; case 0x15A: - switch (hw32mult_type) + switch (HWMULT (sd, hw32mult_type)) { - case UNSIGN_64: rv = zero_ext (hw32mult_result >> 48, 16); break; - case SIGN_64: rv = sign_ext (hw32mult_result >> 48, 16); break; + case UNSIGN_64: rv = zero_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break; + case SIGN_64: rv = sign_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break; } break; @@ -582,77 +574,91 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val) switch (addr) { - case 0x130: hwmult_op1 = val; hwmult_type = UNSIGN_32; break; - case 0x132: hwmult_op1 = val; hwmult_type = SIGN_32; break; - case 0x134: hwmult_op1 = val; hwmult_type = UNSIGN_MAC_32; break; - case 0x136: hwmult_op1 = val; hwmult_type = SIGN_MAC_32; break; + case 0x130: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = UNSIGN_32; break; + case 0x132: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = SIGN_32; break; + case 0x134: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = UNSIGN_MAC_32; break; + case 0x136: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = SIGN_MAC_32; break; - case 0x138: hwmult_op2 = val; - switch (hwmult_type) + case 0x138: HWMULT (sd, hwmult_op2) = val; + switch (HWMULT (sd, hwmult_type)) { case UNSIGN_32: - hwmult_result = hwmult_op1 * hwmult_op2; - hwmult_signed_result = (signed) hwmult_result; - hwmult_accumulator = hwmult_signed_accumulator = 0; + HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2); + HWMULT (sd, hwmult_signed_result) = (signed) HWMULT (sd, hwmult_result); + HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0; break; case SIGN_32: - a = sign_ext (hwmult_op1, 16); - b = sign_ext (hwmult_op2, 16); - hwmult_signed_result = a * b; - hwmult_result = (unsigned) hwmult_signed_result; - hwmult_accumulator = hwmult_signed_accumulator = 0; + a = sign_ext (HWMULT (sd, hwmult_op1), 16); + b = sign_ext (HWMULT (sd, hwmult_op2), 16); + HWMULT (sd, hwmult_signed_result) = a * b; + HWMULT (sd, hwmult_result) = (unsigned) HWMULT (sd, hwmult_signed_result); + HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0; break; case UNSIGN_MAC_32: - hwmult_accumulator += hwmult_op1 * hwmult_op2; - hwmult_signed_accumulator += hwmult_op1 * hwmult_op2; - hwmult_result = hwmult_accumulator; - hwmult_signed_result = hwmult_signed_accumulator; + HWMULT (sd, hwmult_accumulator) += HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2); + HWMULT (sd, hwmult_signed_accumulator) += HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2); + HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator); + HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator); break; case SIGN_MAC_32: - a = sign_ext (hwmult_op1, 16); - b = sign_ext (hwmult_op2, 16); - hwmult_accumulator += a * b; - hwmult_signed_accumulator += a * b; - hwmult_result = hwmult_accumulator; - hwmult_signed_result = hwmult_signed_accumulator; + a = sign_ext (HWMULT (sd, hwmult_op1), 16); + b = sign_ext (HWMULT (sd, hwmult_op2), 16); + HWMULT (sd, hwmult_accumulator) += a * b; + HWMULT (sd, hwmult_signed_accumulator) += a * b; + HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator); + HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator); break; } break; case 0x13a: /* Copy into LOW result... */ - switch (hwmult_type) + switch (HWMULT (sd, hwmult_type)) { case UNSIGN_MAC_32: case UNSIGN_32: - hwmult_accumulator = hwmult_result = zero_ext (val, 16); - hwmult_signed_accumulator = sign_ext (val, 16); + HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_result) = zero_ext (val, 16); + HWMULT (sd, hwmult_signed_accumulator) = sign_ext (val, 16); break; case SIGN_MAC_32: case SIGN_32: - hwmult_signed_accumulator = hwmult_result = sign_ext (val, 16); - hwmult_accumulator = zero_ext (val, 16); + HWMULT (sd, hwmult_signed_accumulator) = HWMULT (sd, hwmult_result) = sign_ext (val, 16); + HWMULT (sd, hwmult_accumulator) = zero_ext (val, 16); break; } break; - case 0x140: hw32mult_op1 = val; hw32mult_type = UNSIGN_64; break; - case 0x142: hw32mult_op1 = (hw32mult_op1 & 0xFFFF) | (val << 16); break; - case 0x144: hw32mult_op1 = val; hw32mult_type = SIGN_64; break; - case 0x146: hw32mult_op1 = (hw32mult_op1 & 0xFFFF) | (val << 16); break; - case 0x150: hw32mult_op2 = val; break; - - case 0x152: hw32mult_op2 = (hw32mult_op2 & 0xFFFF) | (val << 16); - switch (hw32mult_type) + case 0x140: + HWMULT (sd, hw32mult_op1) = val; + HWMULT (sd, hw32mult_type) = UNSIGN_64; + break; + case 0x142: + HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16); + break; + case 0x144: + HWMULT (sd, hw32mult_op1) = val; + HWMULT (sd, hw32mult_type) = SIGN_64; + break; + case 0x146: + HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16); + break; + case 0x150: + HWMULT (sd, hw32mult_op2) = val; + break; + + case 0x152: + HWMULT (sd, hw32mult_op2) = (HWMULT (sd, hw32mult_op2) & 0xFFFF) | (val << 16); + switch (HWMULT (sd, hw32mult_type)) { case UNSIGN_64: - hw32mult_result = hw32mult_op1 * hw32mult_op2; + HWMULT (sd, hw32mult_result) = HWMULT (sd, hw32mult_op1) * HWMULT (sd, hw32mult_op2); break; case SIGN_64: - hw32mult_result = sign_ext (hw32mult_op1, 32) * sign_ext (hw32mult_op2, 32); + HWMULT (sd, hw32mult_result) = sign_ext (HWMULT (sd, hw32mult_op1), 32) + * sign_ext (HWMULT (sd, hw32mult_op2), 32); break; } break; diff --git a/sim/msp430/msp430-sim.h b/sim/msp430/msp430-sim.h index 1865e4e..2a0912e 100644 --- a/sim/msp430/msp430-sim.h +++ b/sim/msp430/msp430-sim.h @@ -21,11 +21,29 @@ #ifndef _MSP430_SIM_H_ #define _MSP430_SIM_H_ +typedef enum { UNSIGN_32, SIGN_32, UNSIGN_MAC_32, SIGN_MAC_32 } hwmult_type; +typedef enum { UNSIGN_64, SIGN_64 } hw32mult_type; + struct msp430_cpu_state { int regs[16]; int cio_breakpoint; int cio_buffer; + + hwmult_type hwmult_type; + unsigned32 hwmult_op1; + unsigned32 hwmult_op2; + unsigned32 hwmult_result; + signed32 hwmult_signed_result; + unsigned32 hwmult_accumulator; + signed32 hwmult_signed_accumulator; + + hw32mult_type hw32mult_type; + unsigned64 hw32mult_op1; + unsigned64 hw32mult_op2; + unsigned64 hw32mult_result; }; +#define HWMULT(SD, FIELD) MSP430_CPU (SD)->state.FIELD + #endif