From patchwork Tue Jun 24 23:42:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: DJ Delorie X-Patchwork-Id: 363772 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 1B94F1400B5 for ; Wed, 25 Jun 2014 09:42:31 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:from:to:in-reply-to:subject:references; q=dns; s= default; b=FNnkYXA+5fPyNy6hRBIqooIVUBK5B8TK5W2Pt9nWmadjearPVCGFJ rgC+Y0jZP6Rw3+z9ML2XoYvgk/F+VOQd8bdV4MjcWlT8yWDZ6nNmRgTqSG8L6AFZ Y/gBHw7jTIKZMeUZA5NFoGerU0Fd8ySCw3WNUxferT9I96KKNGu214= 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 :message-id:from:to:in-reply-to:subject:references; s=default; bh=HHqeAm9Dqqghr3PrVq4utnOnlc4=; b=rrA/QKckEkzX4u6Rf1/p/38J8yX5 yK/9nK79/V8/S/9nBOAiYyMbmZ/0WZ43qKqThno+rF0semZ6YsBHP7N2Ps9tiYXj CVKzbJmScOdZV0Zc/opcY21OKYh3wklpuWgfLzdpO8G73X5Tdt3q58YbaNWhoARN qOFc4Zwl8LE91+g= Received: (qmail 7071 invoked by alias); 24 Jun 2014 23:42:25 -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 7060 invoked by uid 89); 24 Jun 2014 23:42:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD 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, 24 Jun 2014 23:42:23 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5ONgLDZ008409 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 24 Jun 2014 19:42:21 -0400 Received: from greed.delorie.com ([10.3.113.17]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5ONgKaK013811 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 24 Jun 2014 19:42:21 -0400 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1]) by greed.delorie.com (8.14.4/8.14.4) with ESMTP id s5ONgK61013067 for ; Tue, 24 Jun 2014 19:42:20 -0400 Received: (from dj@localhost) by greed.delorie.com (8.14.4/8.14.4/Submit) id s5ONgKNZ013066; Tue, 24 Jun 2014 19:42:20 -0400 Date: Tue, 24 Jun 2014 19:42:20 -0400 Message-Id: <201406242342.s5ONgKNZ013066@greed.delorie.com> From: DJ Delorie To: gcc-patches@gcc.gnu.org In-reply-to: (joseph@codesourcery.com) Subject: Re: [patch 4/4] change specific int128 -> generic intN References: <201404142303.s3EN3ONP009938@greed.delorie.com> <201406211624.s5LGOFC8031566@greed.delorie.com> X-IsSubscribed: yes Part 4 of 4, split from the full patch. This is the MSP430-specific use of the new intN framework to enable true 20-bit pointers. Since I'm one of the MSP430 maintainers, this patch is being posted for reference, not for approval. gcc/config/msp430 * config/msp430/msp430-protos.h (msp430_hard_regno_nregs_has_padding): New. (msp430_hard_regno_nregs_with_padding): New. * config/msp430/msp430.c (msp430_scalar_mode_supported_p): New. (msp430_hard_regno_nregs_has_padding): New. (msp430_hard_regno_nregs_with_padding): New. (msp430_unwind_word_mode): Use PSImode instead of SImode. (msp430_addr_space_legitimate_address_p): New. (msp430_asm_integer): New. (msp430_init_dwarf_reg_sizes_extra): New. (msp430_print_operand): Use X suffix for PSImode even in small model. * config/msp430/msp430.h (POINTER_SIZE): Use 20 bits, not 32. (PTR_SIZE): ...but 4 bytes for EH. (SIZE_TYPE): Use __int20. (PTRDIFF_TYPE): Likewise. (INCOMING_FRAME_SP_OFFSET): Adjust. * config/msp430/msp430.md (movqi_topbyte): New. (movpsi): Use fixed suffixes. (movsipsi2): Enable for 430X, not large model. (extendhipsi2): Likewise. (zero_extendhisi2): Likewise. (zero_extendhisipsi2): Likewise. (extend_and_shift1_hipsi2): Likewise. (extendpsisi2): Likewise. (*bitbranch4_z): Fix suffix logic. Index: gcc/config/msp430/msp430-protos.h =================================================================== --- gcc/config/msp430/msp430-protos.h (revision 211858) +++ gcc/config/msp430/msp430-protos.h (working copy) @@ -27,12 +27,15 @@ void msp430_expand_epilogue (int); void msp430_expand_helper (rtx *operands, const char *, bool); void msp430_expand_prologue (void); const char * msp430x_extendhisi (rtx *); void msp430_fixup_compare_operands (enum machine_mode, rtx *); int msp430_hard_regno_mode_ok (int, enum machine_mode); int msp430_hard_regno_nregs (int, enum machine_mode); +int msp430_hard_regno_nregs_has_padding (int, enum machine_mode); +int msp430_hard_regno_nregs_with_padding (int, enum machine_mode); +bool msp430_hwmult_enabled (void); rtx msp430_incoming_return_addr_rtx (void); void msp430_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); int msp430_initial_elimination_offset (int, int); bool msp430_is_interrupt_func (void); const char * msp430x_logical_shift_right (rtx); const char * msp430_mcu_name (void); Index: gcc/config/msp430/msp430.md =================================================================== --- gcc/config/msp430/msp430.md (revision 211858) +++ gcc/config/msp430/msp430.md (working copy) @@ -176,12 +176,19 @@ "" "@ MOV.B\t%1, %0 MOV%X1.B\t%1, %0" ) +(define_insn "movqi_topbyte" + [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=r") + (subreg:QI (match_operand:PSI 1 "msp_general_operand" "r") 2))] + "msp430x" + "PUSHM.A\t#1,%1 { POPM.W\t#1,%0 { POPM.W\t#1,%0" +) + (define_insn "movqi" [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm") (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))] "" "@ MOV.B\t%1, %0 @@ -220,27 +227,27 @@ ;; Some MOVX.A cases can be done with MOVA, this is only a few of them. (define_insn "movpsi" [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm") (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))] "" "@ - MOV%Q0\t%1, %0 - MOV%Q0\t%1, %0 - MOV%X0.%Q0\t%1, %0") + MOVA\t%1, %0 + MOVA\t%1, %0 + MOVX.A\t%1, %0") ; This pattern is identical to the truncsipsi2 pattern except ; that it uses a SUBREG instead of a TRUNC. It is needed in ; order to prevent reload from converting (set:SI (SUBREG:PSI (SI))) ; into (SET:PSI (PSI)). ; ; Note: using POPM.A #1 is two bytes smaller than using POPX.A.... (define_insn "movsipsi2" [(set (match_operand:PSI 0 "register_operand" "=r") (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))] - "TARGET_LARGE" + "msp430x" "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0" ) ;;------------------------------------------------------------ ;; Math @@ -564,49 +571,49 @@ { return msp430x_extendhisi (operands); } ) (define_insn "extendhipsi2" [(set (match_operand:PSI 0 "nonimmediate_operand" "=r") (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))] - "TARGET_LARGE" + "msp430x" "RLAM #4, %0 { RRAM #4, %0" ) ;; Look for cases where integer/pointer conversions are suboptimal due ;; to missing patterns, despite us not having opcodes for these ;; patterns. Doing these manually allows for alternate optimization ;; paths. (define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))] - "TARGET_LARGE" + "msp430x" "MOV.W\t#0,%H0" ) (define_insn "zero_extendhisipsi2" [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r") (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))] - "TARGET_LARGE" + "msp430x" "@ AND.W\t#-1,%0 MOV.W\t%1,%0" ) (define_insn "extend_and_shift1_hipsi2" [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) (const_int 1)))] - "TARGET_LARGE" + "msp430x" "RLAM #4, %0 { RRAM #3, %0" ) (define_insn "extend_and_shift2_hipsi2" [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) (const_int 2)))] - "TARGET_LARGE" + "msp430x" "RLAM #4, %0 { RRAM #2, %0" ) ; Nasty - we are sign-extending a 20-bit PSI value in one register into ; two adjacent 16-bit registers to make an SI value. There is no MSP430X ; instruction that will do this, so we push the 20-bit value onto the stack @@ -645,13 +652,13 @@ ;; Since (we assume) pushing a 20-bit value onto the stack zero-extends ;; it, we use a different method here. (define_insn "extendpsisi2" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))] - "TARGET_LARGE" + "msp430x" "* /* The intention here is that we copy the bottom 16-bits of %1 into %L0 (zeroing the top four bits). Then we copy the entire 20-bits of %1 into %H0 and then arithmetically shift it right by 16 bits, to get the top four bits of the pointer sign-extended in %H0. */ @@ -1174,13 +1181,13 @@ (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) (clobber (reg:BI CARRY)) ] "" - "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2" + "BIT%x0%b0\t%1, %0 { JEQ\t%l2" ) (define_insn "*bitbranch4" [(set (pc) (if_then_else (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm") (match_operand:QHI 1 "msp_general_operand" "rmi")) Index: gcc/config/msp430/msp430.c =================================================================== --- gcc/config/msp430/msp430.c (revision 211858) +++ gcc/config/msp430/msp430.c (working copy) @@ -225,12 +225,27 @@ msp430_option_override (void) command line and always sets -O2 in CFLAGS. Thus it is not possible to build newlib with -Os enabled. Until now... */ if (TARGET_OPT_SPACE && optimize < 3) optimize_size = 1; } +#undef TARGET_SCALAR_MODE_SUPPORTED_P +#define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p + +static bool +msp430_scalar_mode_supported_p (enum machine_mode m) +{ + if (m == PSImode && msp430x) + return true; +#if 0 + if (m == TImode) + return true; +#endif + return default_scalar_mode_supported_p (m); +} + /* Storage Layout */ #undef TARGET_MS_BITFIELD_LAYOUT_P #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p @@ -254,12 +269,33 @@ msp430_hard_regno_nregs (int regno ATTRI if (mode == PSImode && msp430x) return 1; return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); } +/* Implements HARD_REGNO_NREGS_HAS_PADDING. */ +int +msp430_hard_regno_nregs_has_padding (int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + if (mode == PSImode && msp430x) + return 1; + return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) + / UNITS_PER_WORD); +} + +/* Implements HARD_REGNO_NREGS_WITH_PADDING. */ +int +msp430_hard_regno_nregs_with_padding (int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + if (mode == PSImode) + return 2; + return msp430_hard_regno_nregs (regno, mode); +} + /* Implements HARD_REGNO_MODE_OK. */ int msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED, enum machine_mode mode) { return regno <= (ARG_POINTER_REGNUM - msp430_hard_regno_nregs (regno, mode)); @@ -367,13 +403,13 @@ msp430_addr_space_pointer_mode (addr_spa #undef TARGET_UNWIND_WORD_MODE #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode static enum machine_mode msp430_unwind_word_mode (void) { - return TARGET_LARGE ? SImode : HImode; + return TARGET_LARGE ? PSImode : HImode; } /* Determine if one named address space is a subset of another. */ #undef TARGET_ADDR_SPACE_SUBSET_P #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p static bool @@ -882,12 +918,49 @@ msp430_legitimate_address_p (enum machin default: return false; } } +#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P +#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P msp430_addr_space_legitimate_address_p + +bool +msp430_addr_space_legitimate_address_p (enum machine_mode mode, + rtx x, + bool strict, + addr_space_t as ATTRIBUTE_UNUSED) +{ + return msp430_legitimate_address_p (mode, x, strict); +} + +#undef TARGET_ASM_INTEGER +#define TARGET_ASM_INTEGER msp430_asm_integer +static bool +msp430_asm_integer (rtx x, unsigned int size, int aligned_p) +{ + int c = GET_CODE (x); + + if (size == 3 && GET_MODE (x) == PSImode) + size = 4; + + switch (size) + { + case 4: + if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT) + { + fprintf (asm_out_file, "\t.long\t"); + output_addr_const (asm_out_file, x); + fputc ('\n', asm_out_file); + return true; + } + break; + } + return default_assemble_integer (x, size, aligned_p); +} + #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant static bool msp430_legitimate_constant (enum machine_mode mode, rtx x) { @@ -1740,12 +1813,39 @@ msp430_expand_eh_return (rtx eh_handler) tmp = gen_rtx_PLUS (Pmode, ap, sa); tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2); tmp = gen_rtx_MEM (Pmode, tmp); emit_move_insn (tmp, ra); } +#undef TARGET_INIT_DWARF_REG_SIZES_EXTRA +#define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra +void +msp430_init_dwarf_reg_sizes_extra (tree address) +{ + int i; + rtx addr = expand_normal (address); + rtx mem = gen_rtx_MEM (BLKmode, addr); + + if (!msp430x) + return; + + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + { + unsigned int dnum = DWARF_FRAME_REGNUM (i); + unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1); + + if (rnum < DWARF_FRAME_REGISTERS) + { + HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode); + + emit_move_insn (adjust_address (mem, QImode, offset), + gen_int_mode (4, QImode)); + } + } +} + /* This is a list of MD patterns that implement fixed-count shifts. */ static struct { const char *name; int count; int need_430x; @@ -2350,13 +2450,13 @@ msp430_print_operand (FILE * file, rtx o } break; case 'X': /* This is used to turn, for example, an ADD opcode into an ADDX opcode when we're using 20-bit addresses. */ - if (TARGET_LARGE) + if (TARGET_LARGE || GET_MODE (op) == PSImode) fprintf (file, "X"); /* We don't care which operand we use, but we want 'X' in the MD file, so we do it this way. */ return; case 'x': Index: gcc/config/msp430/msp430-modes.def =================================================================== --- gcc/config/msp430/msp430-modes.def (revision 211858) +++ gcc/config/msp430/msp430-modes.def (working copy) @@ -1,3 +1,4 @@ /* 20-bit address */ PARTIAL_INT_MODE (SI, 20, PSI); +INT_N (PSI, 20); Index: gcc/config/msp430/msp430.h =================================================================== --- gcc/config/msp430/msp430.h (revision 211858) +++ gcc/config/msp430/msp430.h (working copy) @@ -128,16 +128,15 @@ extern bool msp430x; #define FRAME_GROWS_DOWNWARD 1 #define FIRST_PARM_OFFSET(FNDECL) 0 #define MAX_REGS_PER_ADDRESS 1 #define Pmode (TARGET_LARGE ? PSImode : HImode) -/* Note: 32 is a lie. Large pointers are actually 20-bits wide. But gcc - thinks that any non-power-of-2 pointer size equates to BLKmode, which - causes all kinds of problems... */ -#define POINTER_SIZE (TARGET_LARGE ? 32 : 16) +#define POINTER_SIZE (TARGET_LARGE ? 20 : 16) +/* This is just for .eh_frame, to match bfd. */ +#define PTR_SIZE (TARGET_LARGE ? 4 : 2) #define POINTERS_EXTEND_UNSIGNED 1 #define ADDR_SPACE_NEAR 1 #define ADDR_SPACE_FAR 2 #define REGISTER_TARGET_PRAGMAS() msp430_register_pragmas() @@ -155,15 +154,15 @@ extern bool msp430x; (MODE) = HImode; #endif /* Layout of Source Language Data Types */ #undef SIZE_TYPE -#define SIZE_TYPE (TARGET_LARGE ? "long unsigned int" : "unsigned int") +#define SIZE_TYPE (TARGET_LARGE ? "__int20 unsigned" : "unsigned int") #undef PTRDIFF_TYPE -#define PTRDIFF_TYPE (TARGET_LARGE ? "long int" : "int") +#define PTRDIFF_TYPE (TARGET_LARGE ? "__int20" : "int") #undef WCHAR_TYPE #define WCHAR_TYPE "long int" #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE BITS_PER_WORD #define FUNCTION_MODE HImode #define CASE_VECTOR_MODE Pmode @@ -379,13 +378,13 @@ typedef struct #define JUMP_TABLES_IN_TEXT_SECTION 1 #undef DWARF2_ADDR_SIZE #define DWARF2_ADDR_SIZE 4 -#define INCOMING_FRAME_SP_OFFSET (POINTER_SIZE / BITS_PER_UNIT) +#define INCOMING_FRAME_SP_OFFSET (TARGET_LARGE ? 4 : 2) #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG #define DWARF2_ASM_LINE_DEBUG_INFO 1