From patchwork Wed Aug 14 21:59:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 1147256 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-506991-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="a0AzzxhR"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4683QY2H0Dz9sN1 for ; Thu, 15 Aug 2019 07:59:31 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:references:mime-version:content-type :in-reply-to; q=dns; s=default; b=QvcOoH17+XBnpf57UoOKRS+HlSMJEm jdIPjFR+X8qYANh8ELJZyYdDFM7ZH9KyGLpSTArEhuvY1MUwSTts9PGyZAHTnFkf kiWP6jazuSUj8ASzhOEFbRUv/bRVxECCdjrGmNapwGdp+qmP6OgVBzBvIxRHrC+0 pJZiIC5nThbJ0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:references:mime-version:content-type :in-reply-to; s=default; bh=cIm5bRr5VxccBLERoaljUI2Kv7Q=; b=a0Az zxhRdOhK8yWNqKsXChW25m1d2QJ6PuZX67mS5h4Iofkavo8jXYsPCvTg8/usNhhf 0qe9gvWJURlHM67vBsWvf+cdVY2lUhvSd3OTA3O1gNho5TEx947TzAs571766SB0 0zRa88qZHsXtm9mw6FmX7jwu+ROWRSAJJR92CXg= Received: (qmail 19410 invoked by alias); 14 Aug 2019 21:59:22 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 19399 invoked by uid 89); 14 Aug 2019 21:59:22 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.1 spammy=float_extend X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 Aug 2019 21:59:19 +0000 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x7ELvicF159075; Wed, 14 Aug 2019 17:59:17 -0400 Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 2ucr0sng4f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 14 Aug 2019 17:59:17 -0400 Received: from m0098420.ppops.net (m0098420.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.27/8.16.0.27) with SMTP id x7ELw7Vt159968; Wed, 14 Aug 2019 17:59:17 -0400 Received: from ppma01dal.us.ibm.com (83.d6.3fa9.ip4.static.sl-reverse.com [169.63.214.131]) by mx0b-001b2d01.pphosted.com with ESMTP id 2ucr0sng43-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 14 Aug 2019 17:59:17 -0400 Received: from pps.filterd (ppma01dal.us.ibm.com [127.0.0.1]) by ppma01dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id x7ELt17d014006; Wed, 14 Aug 2019 21:59:16 GMT Received: from b01cxnp22034.gho.pok.ibm.com (b01cxnp22034.gho.pok.ibm.com [9.57.198.24]) by ppma01dal.us.ibm.com with ESMTP id 2ucr3q0ye2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 14 Aug 2019 21:59:16 +0000 Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x7ELxFaa47645094 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 14 Aug 2019 21:59:15 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 32EA4AC05F; Wed, 14 Aug 2019 21:59:15 +0000 (GMT) Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E1BF2AC065; Wed, 14 Aug 2019 21:59:14 +0000 (GMT) Received: from ibm-toto.the-meissners.org (unknown [9.32.77.177]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTPS; Wed, 14 Aug 2019 21:59:14 +0000 (GMT) Date: Wed, 14 Aug 2019 17:59:13 -0400 From: Michael Meissner To: gcc-patches@gcc.gnu.org, Segher Boessenkool , David Edelsohn , Michael Meissner , Alan Modra Subject: [PATCH], Patch #2 of 10, Add RTL prefixed attribute Message-ID: <20190814215913.GB16578@ibm-toto.the-meissners.org> Mail-Followup-To: Michael Meissner , gcc-patches@gcc.gnu.org, Segher Boessenkool , David Edelsohn , Alan Modra References: <20190814205732.GA11956@ibm-toto.the-meissners.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20190814205732.GA11956@ibm-toto.the-meissners.org> User-Agent: Mutt/1.5.21 (2010-09-15) This patch adds the RTL attribute "prefixed" that says this particular instruction is a prefixed instruction. The target hooks FINAL_SCAN_INSN and ASM_OUTPUT_OPCODE are defined. If the insn is prefixed, ASM_OUTPUT_OPCODE will emit a leading 'p' before the instruction is emitted. For example, a load word and zero extend instruction would have the output template: lwz%U1%X1 %0,%1 If the insn is prefixed, ASM_OUTPUT_OPCODE will emit the leading 'p' and the assembler would see something like: plwz 3,foo@pcrel The RTL length attribute looks a the RTL prefixed attribute to set the default length to either 4 or 12. In order to simplify setting the length for complex insns that aren't yet split, I have added two new RTL attributes ("non_prefixed_length" and "prefixed_length") that the length attribute uses. Normally these values would be 4 and 12 bytes, unless this is overwritten by the insn attributes. In previous versions of the patch, I had a maybe_prefixed attribute that was used to say this instruction might be prefixed, and to check whether the instruction was prefixed externally. Now, I use the type RTL attribute, and I only look if the type is one of the load types, one of the store types, or one of the integer and add types. Due to some of the existing load and store insns not using the traditional operands[0] and operands[1], the functions that test whether an insn is prefixed only use the insn and not the operands directly. Most of the new code is in a new file (rs6000-prefixed.c). 2019-08-14 Michael Meissner * config/rs6000/rs6000-prefixed.c: New file. * config/rs6000/rs6000-protos.h (rs6000_final_prescan_insn): Update calling signature. (prefixed_load_p): New function. (prefixed_store_p): New function. (prefixed_paddi_p): New function. * config/rs6000/rs6000.c (rs6000_emit_move): Add support for loading up pc-relatve addresses. * config/rs6000/rs6000.h (FINAL_SCAN_INSN): New target hook. (ASM_OUTPUT_OPCODE): New target hook. * config/rs6000/rs6000.md (prefixed attribute): New attribute. (prefixed_length attribute): New attribute. (non_prefixed_length attribute): New attribute. (length attribute): Calculate length in terms of the prefixed, prefixed_length, and non_prefixed_length attributes. (pcrel_addr): New insn for pc-relative support. (pcrel_ext_addr): New insn for pc-relative support. * config/rs6000/t-rs6000 (rs6000-prefixed.o): Add build rule. * config.gcc (powerpc*-*-*): Add rs6000-prefixed.c. (rs6000*-*-*): Add rs6000-prefixed.c. Index: gcc/config/rs6000/rs6000-prefixed.c =================================================================== --- gcc/config/rs6000/rs6000-prefixed.c (revision 0) +++ gcc/config/rs6000/rs6000-prefixed.c (working copy) @@ -0,0 +1,188 @@ +/* Subroutines used to support prefixed addressing on the PowerPC. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#define IN_TARGET_CODE 1 + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "rtl.h" +#include "tree.h" +#include "memmodel.h" +#include "df.h" +#include "tm_p.h" +#include "ira.h" +#include "print-tree.h" +#include "varasm.h" +#include "explow.h" +#include "expr.h" +#include "output.h" +#include "tree-pass.h" +#include "rtx-vector-builder.h" +#include "print-rtl.h" +#include "insn-attr.h" +#include "insn-config.h" +#include "recog.h" +#include "tm-constrs.h" + +/* Whether the next instruction needs a 'p' prefix issued before the + instruction is printed out. */ +static bool next_insn_prefixed_p; + +/* Define FINAL_PRESCAN_INSN if some processing needs to be done before + outputting the assembler code. On the PowerPC, we remember if the current + insn is a prefixed insn where we need to emit a 'p' before the insn. */ +void +rs6000_final_prescan_insn (rtx_insn *insn) +{ + next_insn_prefixed_p = (get_attr_prefixed (insn) != PREFIXED_NO); + return; +} + +/* Define ASM_OUTPUT_OPCODE to do anything special before emitting an opcode. + We use it to emit a 'p' for prefixed insns that is set in + FINAL_PRESCAN_INSN. We also use it for PCREL_OPT to emit the relocation + that ties the load of the GOT pointer with the load/store that uses the GOT + number. */ +void +rs6000_asm_output_opcode (FILE *stream, const char *) +{ + if (next_insn_prefixed_p) + { + next_insn_prefixed_p = false; + fprintf (stream, "p"); + } + + return; +} + + +/* Whether a load instruction is a prefixed instruction. This is called from + the prefixed attribute processing. We can't use operands[0] and + operands[1], because there are several load insns that don't use the + standard destination and source operands (mov_update1, etc.). */ + +bool +prefixed_load_p (rtx_insn *insn) +{ + rtx set = single_set (insn); + if (!set) + return false; + + rtx reg = SET_DEST (set); + rtx mem = SET_SRC (set); + bool sign_p = false; + + /* Allow sign/zero/float extend as part of the load. */ + if (GET_CODE (mem) == SIGN_EXTEND) + { + sign_p = true; + mem = XEXP (mem, 0); + } + + else if (GET_CODE (mem) == ZERO_EXTEND || GET_CODE (mem) == FLOAT_EXTEND) + mem = XEXP (mem, 0); + + /* Is this a load? */ + if (!MEM_P (mem)) + return false; + + machine_mode mode = GET_MODE (mem); + rtx addr = XEXP (mem, 0); + + /* Special case LWA, which uses the DS instruction format, instead of the D + instruction format. */ + enum insn_form iform = (sign_p && mode == SImode && GET_CODE (addr) == PLUS + ? INSN_FORM_DS + : reg_to_insn_form (reg, mode)); + + return prefixed_local_addr_p (addr, mode, iform); +} + +/* Whether a store instruction is a prefixed instruction. This is called from + the prefixed attribute processing. */ + +bool +prefixed_store_p (rtx_insn *insn) +{ + rtx set = single_set (insn); + if (!set) + return false; + + rtx mem = SET_DEST (set); + rtx reg = SET_SRC (set); + + /* Is this a store? */ + if (!MEM_P (mem)) + return false; + + machine_mode mode = GET_MODE (mem); + enum insn_form iform = reg_to_insn_form (reg, mode); + + return prefixed_local_addr_p (XEXP (mem, 0), mode, iform); +} + +/* Whether a load immediate or add instruction is a prefixed instruction. This + is called from the prefixed attribute processing. */ + +bool +prefixed_paddi_p (rtx_insn *insn) +{ + rtx set = single_set (insn); + if (!set) + return false; + + rtx dest = SET_DEST (set); + rtx src = SET_SRC (set); + + if (!REG_P (dest) && !SUBREG_P (dest)) + return false; + + /* Is this a load immediate that can't be done with a simple ADDI or + ADDIS? */ + if (CONST_INT_P (src)) + return (satisfies_constraint_eI (src) + && !satisfies_constraint_I (src) + && !satisfies_constraint_L (src)); + + /* Is this a PADDI instruction that can't be done with a simple ADDI or + ADDIS? */ + if (GET_CODE (src) == PLUS) + { + rtx op1 = XEXP (src, 1); + + return (CONST_INT_P (op1) + && satisfies_constraint_eI (op1) + && !satisfies_constraint_I (op1) + && !satisfies_constraint_L (op1)); + } + + /* If not, is it a load of a pc-relative address? */ + if (!TARGET_PCREL) + return false; + + if (!SYMBOL_REF_P (src) && !LABEL_REF_P (src) && GET_CODE (src) != CONST) + return false; + + /* Look for either pc-relative addresses of local symbols that we can use a + PLA to load or external symbols that we can load a GOT address via a + pc-relative load. */ + return pcrel_addr_p (src, true, true, PCREL_NULL); +} Index: gcc/config/rs6000/rs6000-protos.h =================================================================== --- gcc/config/rs6000/rs6000-protos.h (revision 274174) +++ gcc/config/rs6000/rs6000-protos.h (working copy) @@ -245,7 +245,14 @@ extern void rs6000_d_target_versions (void); const char * rs6000_xcoff_strip_dollar (const char *); #endif -void rs6000_final_prescan_insn (rtx_insn *, rtx *operand, int num_operands); +/* Declare functions in rs6000-prefixed.c */ +#ifdef RTX_CODE +extern bool prefixed_load_p (rtx_insn *); +extern bool prefixed_store_p (rtx_insn *); +extern bool prefixed_paddi_p (rtx_insn *); +extern void rs6000_asm_output_opcode (FILE *, const char *); +void rs6000_final_prescan_insn (rtx_insn *); +#endif extern unsigned char rs6000_class_max_nregs[][LIM_REG_CLASSES]; extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER]; Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 274174) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -9815,6 +9815,17 @@ rs6000_emit_move (rtx dest, rtx source, machine_mo return; } + /* Handle pc-relative addresses, either external symbols or internal + within the function. */ + if (TARGET_PCREL) + { + if (pcrel_addr_p (operands[1], true, true, PCREL_NULL)) + { + emit_insn (gen_rtx_SET (operands[0], operands[1])); + return; + } + } + if (DEFAULT_ABI == ABI_V4 && mode == Pmode && mode == SImode && flag_pic == 1 && got_operand (operands[1], mode)) Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (revision 274173) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -2572,3 +2572,24 @@ typedef struct GTY(()) machine_function IN_RANGE ((VALUE), \ -(HOST_WIDE_INT_1 << 33), \ (HOST_WIDE_INT_1 << 33) - 1 - (EXTRA)) + +/* Define this if some processing needs to be done before outputting the + assembler code. On the PowerPC, we remember if the current insn is a normal + prefixed insn where we need to emit a 'p' before the insn. */ +#define FINAL_PRESCAN_INSN(INSN, OPERANDS, NOPERANDS) \ +do \ + { \ + if (TARGET_PREFIXED_ADDR) \ + rs6000_final_prescan_insn (INSN); \ + } \ +while (0) + +/* Do anything special before emitting an opcode. We use it to emit a 'p' for + prefixed insns that is set in FINAL_PRESCAN_INSN. */ +#define ASM_OUTPUT_OPCODE(STREAM, OPCODE) \ + do \ + { \ + if (TARGET_PREFIXED_ADDR) \ + rs6000_asm_output_opcode (STREAM, OPCODE); \ + } \ + while (0) Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 274174) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -269,9 +269,48 @@ x ; Indexed addressing prefixed]) ; Prefixed instruction -;; Length of the instruction (in bytes). -(define_attr "length" "" (const_int 4)) +;; Whether an insn is a prefixed insn, and an initial 'p' should be printed +;; before the instruction. A prefixed instruction has a prefix instruction +;; word that extends the immediate value of the instructions from 12-16 bits to +;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed +;; insns. The default "length" attribute will also be adjusted by default to +;; be 12 bytes. +(define_attr "prefixed" "no,yes" + (cond [(ior (match_test "!TARGET_PREFIXED_ADDR") + (match_test "!NONJUMP_INSN_P (insn)")) + (const_string "no") + (eq_attr "type" "load,fpload,vecload") + (if_then_else (match_test "prefixed_load_p (insn)") + (const_string "yes") + (const_string "no")) + + (eq_attr "type" "store,fpstore,vecstore") + (if_then_else (match_test "prefixed_store_p (insn)") + (const_string "yes") + (const_string "no")) + + (eq_attr "type" "integer,add") + (if_then_else (match_test "prefixed_paddi_p (insn)") + (const_string "yes") + (const_string "no"))] + (const_string "no"))) + +;; Length in bytes of instructions that use prefixed addressing and length in +;; bytes of instructions that does not use prefixed addressing. This allows +;; both lengths to be defined as constants, and the length attribute can pick +;; the size as appropriate. +(define_attr "prefixed_length" "" (const_int 12)) +(define_attr "non_prefixed_length" "" (const_int 4)) + +;; Length of the instruction (in bytes). Prefixed insns are 8 bytes, but the +;; assembler might issue need to issue a NOP so that the prefixed instruction +;; does not cross a cache boundary, which makes them possibly 12 bytes. +(define_attr "length" "" + (if_then_else (eq_attr "prefixed" "yes") + (attr "prefixed_length") + (attr "non_prefixed_length"))) + ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000-opts.h. (define_attr "cpu" @@ -9888,6 +9927,25 @@ operands[6] = gen_rtx_PARALLEL (VOIDmode, p); }) +;; Load up a pc-relative address. ASM_OUTPUT_OPCODE will emit the initial "p". +(define_insn "*pcrel_addr" + [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") + (match_operand:DI 1 "pcrel_address"))] + "TARGET_PCREL" + "la %0,%a1" + [(set_attr "prefixed" "yes")]) + +;; Load up a pc-relative address to an external symbol. If the symbol and the +;; program are both defined in the main program, the linker will optimize this +;; to a PADDI. Otherwise, it will create a GOT address that is relocated by +;; the dynamic linker and loaded up. +(define_insn "*pcrel_ext_addr" + [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") + (match_operand:DI 1 "pcrel_external_address"))] + "TARGET_PCREL" + "ld %0,%a1" + [(set_attr "prefixed" "yes")]) + ;; TOC register handling. ;; Code to initialize the TOC register... Index: gcc/config/rs6000/t-rs6000 =================================================================== --- gcc/config/rs6000/t-rs6000 (revision 274173) +++ gcc/config/rs6000/t-rs6000 (working copy) @@ -47,6 +47,10 @@ rs6000-call.o: $(srcdir)/config/rs6000/rs6000-call $(COMPILE) $< $(POSTCOMPILE) +rs6000-prefixed.o: $(srcdir)/config/rs6000/rs6000-prefixed.c + $(COMPILE) $< + $(POSTCOMPILE) + $(srcdir)/config/rs6000/rs6000-tables.opt: $(srcdir)/config/rs6000/genopt.sh \ $(srcdir)/config/rs6000/rs6000-cpus.def $(SHELL) $(srcdir)/config/rs6000/genopt.sh $(srcdir)/config/rs6000 > \ Index: gcc/config.gcc =================================================================== --- gcc/config.gcc (revision 274173) +++ gcc/config.gcc (working copy) @@ -500,6 +500,7 @@ or1k*-*-*) powerpc*-*-*) cpu_type=rs6000 extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o rs6000-call.o" + extra_objs="${extra_objs} rs6000-prefixed.o" extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h" extra_headers="${extra_headers} bmi2intrin.h bmiintrin.h" extra_headers="${extra_headers} xmmintrin.h mm_malloc.h emmintrin.h" @@ -514,6 +515,7 @@ powerpc*-*-*) esac extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt" target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-logue.c \$(srcdir)/config/rs6000/rs6000-call.c" + target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-prefixed.c" ;; pru-*-*) cpu_type=pru @@ -526,7 +528,9 @@ riscv*) rs6000*-*-*) extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt" extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o rs6000-call.o" + extra_objs="${extra_objs} rs6000-prefixed.o" target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-logue.c \$(srcdir)/config/rs6000/rs6000-call.c" + target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-prefixed.c" ;; sparc*-*-*) cpu_type=sparc