Stepping down, mostly...
This has been a long time coming, but as most of you know I've changed groups at Red Hat and my new duties don't give me the time or focus I used to have for all my various upstream maintainerships. To be fair to the community, I'm making this change official by stepping down from the ones I can no longer give sufficient attention to: m32c rx rl78 v850 msp430 libiberty build machinery I'm recommending Sebastian Perta for the Renesas targets (m32c, rx, rl78, v850) and Jozef Lawrynowicz for the TI target (msp430), if they so desire. I'll keep my DJGPP-related maintainerships of course :-) Specific patches to MAINAINERS attached. Reply-to set to me due to cross-posting. [gcc] * MAINTAINERS (m32c, msp43, rl78, libiberty, build): Remove myself as maintainer. Index: MAINTAINERS === --- MAINTAINERS (revision 262891) +++ MAINTAINERS (working copy) @@ -67,38 +67,35 @@ hppa port John David Anglin i386 port Uros Bizjak i386 vector ISA extns Kirill Yukhin ia64 port Jim Wilson iq2000 portNick Clifton lm32 port Sebastien Bourdeauducq -m32c port DJ Delorie m32r port Nick Clifton m68k port (?) Jeff Law m68k port Andreas Schwab m68k-motorola-sysv portPhilippe De Muyter mcore port Nick Clifton microblaze Michael Eager mips port Matthew Fortune mmix port Hans-Peter Nilsson mn10300 port Jeff Law mn10300 port Alexandre Oliva moxie port Anthony Green -msp430 portDJ Delorie msp430 portNick Clifton nds32 port Chung-Ju Wu nds32 port Shiva Chen nios2 port Chung-Lin Tang nios2 port Sandra Loosemore nvptx port Tom de Vries pdp11 port Paul Koning powerpcspe portAndrew Jenner riscv port Kito Cheng riscv port Palmer Dabbelt riscv port Andrew Waterman riscv port Jim Wilson -rl78 port DJ Delorie rs6000/powerpc portDavid Edelsohn rs6000/powerpc portSegher Boessenkool rs6000 vector extnsAldy Hernandez rx portNick Clifton s390 port Hartmut Penner s390 port Ulrich Weigand @@ -162,13 +159,12 @@ libcppAll C and C++ front end maintai libcpp David Malcolm fp-bit Ian Lance Taylor libdecnumber Ben Elliston libgcc Ian Lance Taylor libgo Ian Lance Taylor libgompJakub Jelinek -libiberty DJ Delorie libiberty Ian Lance Taylor libitm Torvald Riegel libobjcNicola Pero libobjcAndrew Pinski libquadmathTobias Burnus libquadmathJakub Jelinek @@ -206,13 +202,12 @@ web pages Gerald Pfeifer i18n Philipp Thomas i18n Joseph Myers diagnostic messagesDodji Seketeli diagnostic messagesDavid Malcolm build machinery (*.in) Paolo Bonzini -build machinery (*.in) DJ Delorie build machinery (*.in) Nathanael Nerode build machinery (*.in) Alexandre Oliva build machinery (*.in) Ralf Wildenhues docs co-maintainer Gerald Pfeifer docs co-maintainer Joseph Myers docs co-maintainer Sandra Loosemore [binutils] * MAINTAINERS (RL78, RX): Remove myself as maintainer. diff --git a/binutils/MAINTAINERS b/binutils/MAINTAINERS index 8a1b152..5b3a6c8 100644 --- a/binutils/MAINTAINERS +++ b/binutils/MAINTAINERS @@ -119,8 +119,6 @@ responsibility among the other maintainers. PPC vector ext Aldy Hernandez RISC-V Palmer Dabbelt RISC-V Andrew Waterman - RL78 DJ Delorie - RX DJ Delorie RX Nick Clifton s390, s390x Martin Schwidefsky s390, s390x Andreas Krebbel [sim] * MAINTAINERS (rl78, m32c, rx, v850): Remove myself as maintainer. diff --git a/sim/MAINTAINERS b/sim/
Re: [PATCH] Fix DJGPP LTO with debug
Richard Biener writes: > DJ, did you ever run the testsuite with a configuration that has LTO > enabled? I don't see any djgpp results posted to gcc-testresults. > Quick googling doesn't yield anything useful with regarding on how to > do actual testing with a cross so I only built a i686-pc-msdosdjgpp > cross cc1/lto1 from x86_64-linux which went fine. CC's Andris, our current gcc maintainer within DJGPP. I know he just built 8.2 binaries for us, I don't know what his testing infrastructure looks like.
Re: [libiberty] IBM long double little-endian
The libiberty parts are OK. The only drawback I can imagine is if someone outside our source trees has used these, and installed a shared library, and replaced it with this new one... but that's not our problem, since we don't support that. > include/ > * floatformat.h (floatformat_ibm_long_double): Delete. > (floatformat_ibm_long_double_big): Declare. > (floatformat_ibm_long_double_little): Declare. > > libiberty/ > * floatformat.c (floatformat_ibm_long_double): Rename to.. > (floatformat_ibm_long_double_big): ..this. > (floatformat_ibm_long_double_little): New.
Re: msp430 port
so... can I get an official "ok to commit with you and Nick as maintainers" then?
[patch/djgpp]: Add ASM_DECLARE_FUNCTION_NAME
Needed to build i586-pc-msdosdjgpp target, committed. * config/i386/djgpp.h (ASM_DECLARE_FUNCTION_NAME): New. Index: config/i386/djgpp.h === --- config/i386/djgpp.h (revision 202015) +++ config/i386/djgpp.h (working copy) @@ -117,6 +117,17 @@ #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) +/* Write the extra assembler code needed to declare a function properly. */ + +#ifndef ASM_DECLARE_FUNCTION_NAME +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)\ + do \ +{ \ + ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL);\ +} \ + while (0) +#endif + /* This is how to tell assembler that a symbol is weak */ #undef ASM_WEAKEN_LABEL #define ASM_WEAKEN_LABEL(FILE,NAME) \
Re: [patch 4/4] -fstrict-volatile-bitfields cleanup v3: remove from defaults on all targets
In all the real-world cases I've seen, the vendor/programmer was careful to lay out the structs properly. I think if the struct does not reflect a reasonable (or physically possible) layout, oh well ;-)
Re: [patch 4/4] -fstrict-volatile-bitfields cleanup v3: remove from defaults on all targets
> I fully agree with you, the current default state of > -fstrict-volatile-bitfields should be disabled for all targets. Please don't do that until gcc produces code that does the same things. Most of my targets rely on gcc not doing the old behavior, to generate correct code. > For portability of application code, the default should be always > off, unless specifically requested. The vendors of my targets specificially requested it be the default. > Even driver code rarely uses bit-fields for register access, People keep saying this, and people are wrong. For the targets I support, they *all* use bitfields for *all* the peripherals, because that's what's in the headers the vendor ships with each chip.
Re: [patch 4/4] -fstrict-volatile-bitfields cleanup v3: remove from defaults on all targets
> You mean the C++11 application or the driver? You mean > -fstrict-volatile-bitfields or -fno-strict-volatile-bitfields? I mean, if the typedef for a volatile bitfield says "char" gcc can't generate an HImode access, by default.
Re: [patch 4/4] -fstrict-volatile-bitfields cleanup v3: remove from defaults on all targets
> How about this for a compromise: Let's make the default of > -fstrict-volatile-bitfields an optional configure argument for gcc > 4.9, that can be used for every target, even for X86_64 of you want ? I don't care how it's enabled (currently, each target that wants it, sets it) as long as a plain "./configure" gives the correct defaults. "Don't forget this option or your code won't work" isn't an option.
Re: cfgexpand.c patch for msp430-elf
I finally got around to checking this in, with your suggested change. Thanks!
Re: [patch][PR/42955] Don't install $(target)/bin/gcc, gfortran, etc.
The patch is OK with me from a build machinery point of view.
[rl78] use ax to copy fp to sp
Devirtualizer used to do this for us. Committed. * config/rl78/rl78.c (rl78_expand_prologue): Use AX to copy between SP and FP. (rl78_expand_epilogue): Likewise. Index: config/rl78/rl78.c === --- config/rl78/rl78.c (revision 202541) +++ config/rl78/rl78.c (working copy) @@ -1033,14 +1033,18 @@ rl78_expand_prologue (void) F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2; } if (rb != 0) emit_insn (gen_sel_rb (GEN_INT (0))); if (frame_pointer_needed) -F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM), - gen_rtx_REG (HImode, STACK_POINTER_REGNUM))); +{ + F (emit_move_insn (gen_rtx_REG (HImode, AX_REG), +gen_rtx_REG (HImode, STACK_POINTER_REGNUM))); + F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM), +gen_rtx_REG (HImode, AX_REG))); +} fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; while (fs > 0) { int fs_byte = (fs > 254) ? 254 : fs; F (emit_insn (gen_subhi3 (sp, sp, GEN_INT (fs_byte; @@ -1058,14 +1062,16 @@ rl78_expand_epilogue (void) if (rl78_is_naked_func ()) return; if (frame_pointer_needed) { - emit_move_insn (gen_rtx_REG (HImode, STACK_POINTER_REGNUM), + emit_move_insn (gen_rtx_REG (HImode, AX_REG), gen_rtx_REG (HImode, FRAME_POINTER_REGNUM)); + emit_move_insn (gen_rtx_REG (HImode, STACK_POINTER_REGNUM), + gen_rtx_REG (HImode, AX_REG)); } else { fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; while (fs > 0) {
[rl78] pass -mrelax to gas/ld
Committed. * config/rl78/rl78.opt (mrelax): New. * config/rl78/rl78.h (ASM_SPEC): New, pass on -mrelax to gas. * config/rl78/rl78.h (LINK_SPEC): New, pass on -mrelax to ld. Index: config/rl78/rl78.h === --- config/rl78/rl78.h (revision 202542) +++ config/rl78/rl78.h (working copy) @@ -38,12 +38,22 @@ #undef STARTFILE_SPEC #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s" #undef ENDFILE_SPEC #define ENDFILE_SPEC "crtend.o%s crtn.o%s" +#undef ASM_SPEC +#define ASM_SPEC "\ +%{mrelax:-relax} \ +" + +#undef LINK_SPEC +#define LINK_SPEC "\ +%{mrelax:-relax} \ +" + #undef LIB_SPEC #define LIB_SPEC " \ --start-group \ -lc\ -lsim \ %{fprofile-arcs|fprofile-generate|coverage:-lgcov} \ Index: config/rl78/rl78.opt === --- config/rl78/rl78.opt(revision 202542) +++ config/rl78/rl78.opt(working copy) @@ -38,6 +38,10 @@ Enum(rl78_mul_types) String(none) Value( EnumValue Enum(rl78_mul_types) String(rl78) Value(MUL_RL78) EnumValue Enum(rl78_mul_types) String(g13) Value(MUL_G13) + +mrelax +Target +Enable assembler and linker relaxation.
[rl78] stop using asm line separators
The line separator char for gas changed from | to @, so don't use line separators at all to be most compatible. Committed. * config/rl78/rl78-virt.md: Change from | to \; for asm line separators. Index: config/rl78/rl78-virt.md === --- config/rl78/rl78-virt.md(revision 202542) +++ config/rl78/rl78-virt.md(working copy) @@ -174,36 +174,36 @@ (clobber (reg:HI X_REG)) ] "" "@ ; ashrsi %0, 0 - movw ax,%H1 | sarw ax,1 | movw %H0,ax | mov a,%Q1 | rorc a,1 | mov %Q0,a | mov a,%q1 | rorc a,1 | mov %q0,a - movw ax,%H1 | sarw ax,1 | movw %H0,ax | mov a,%Q1 | rorc a,1 | mov %Q0,a | mov a,%q1 | rorc a,1 | mov %q0,a + movw ax,%H1 \; sarw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a + movw ax,%H1 \; sarw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a - movw ax,%1 | shlw ax,%r2 | mov %0,a | mov x,%Q1 | mov a,%H1 | shlw ax,%r2 | mov %Q0,a | movw ax,%H1 | sarw ax,%u2 | movw %H0,ax - movw ax,%1 | shlw ax,%r2 | mov %0,a | mov x,%Q1 | mov a,%H1 | shlw ax,%r2 | mov %Q0,a | movw ax,%H1 | sarw ax,%u2 | movw %H0,ax - movw ax,%1 | shlw ax,%r2 | mov %0,a | mov a,%Q1 | mov x,a | mov a,%H1 | shlw ax,%r2 | mov %Q0,a | movw ax,%H1 | sarw ax,%u2 | movw %H0,ax + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov a,%Q1 \; mov x,a \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax - mov x,%Q1| mov a,%H1 | movw %0,ax | movw ax,%H1 | sarw ax,8 | movw %H0,ax - mov a,%Q1 | mov x, a | mov a,%H1 | movw %0,ax | movw ax,%H1 | sarw ax,8 | movw %H0,ax + mov x,%Q1\; mov a,%H1 \; movw %0,ax \; movw ax,%H1 \; sarw ax,8 \; movw %H0,ax + mov a,%Q1 \; mov x, a \; mov a,%H1 \; movw %0,ax \; movw ax,%H1 \; sarw ax,8 \; movw %H0,ax - mov x,%Q1 | mov a,%H1 | shlw ax,%r2 | mov %0,a | movw ax,%H1 | shlw ax,%r2 | mov %Q0,a | movw ax,%H1 | sarw ax,%u2 | movw %H0,ax - mov x,%Q1 | mov a,%H1 | shlw ax,%r2 | mov %0,a | movw ax,%H1 | shlw ax,%r2 | mov %Q0,a | movw ax,%H1 | sarw ax,%u2 | movw %H0,ax - mov a,%Q1 | mov x,a | mov a,%H1 | shlw ax,%r2 | mov %0,a | movw ax,%H1 | shlw ax,%r2 | mov %Q0,a | movw ax,%H1 | sarw ax,%u2 | movw %H0,ax + mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + mov a,%Q1 \; mov x,a \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax - movw ax,%H1 | movw %0,ax | sarw ax,15 | movw %H0,ax + movw ax,%H1 \; movw %0,ax \; sarw ax,15 \; movw %H0,ax - movw ax,%H1 | sarw ax,%S2 | movw %0,ax | sarw ax,15 | movw %H0,ax - movw ax,%H1 | sarw ax,%S2 | movw %0,ax | sarw ax,15 | movw %H0,ax + movw ax,%H1 \; sarw ax,%S2 \; movw %0,ax \; sarw ax,15 \; movw %H0,ax + movw ax,%H1 \; sarw ax,%S2 \; movw %0,ax \; sarw ax,15 \; movw %H0,ax - movw ax,%H1 | mov %0,a | sarw ax,15 | movw %H0,ax | mov %Q0,a + movw ax,%H1 \; mov %0,a \; sarw ax,15 \; movw %H0,ax \; mov %Q0,a - movw ax,%H1 | sar a,%s2 | mov %0,a | sarw ax,15 | movw %H0,ax | mov %Q0,a + movw ax,%H1 \; sar a,%s2 \; mov %0,a \; sarw ax,15 \; movw %H0,ax \; mov %Q0,a - mov b,%2 | cmp0 b | bz $2f | 1: | movw ax,%H1 | sarw ax,1 | movw %H0,ax | mov a,%Q1 | rorc a,1 | mov %Q0,a | mov a,%q1 | rorc a,1 | mov %q0,a | dec b | bnz $1b | 2:" + mov b,%2 \; cmp0 b \; bz $2f \; 1: \; movw ax,%H1 \; sarw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a \; dec b \; bnz $1b \; 2:" [(set_attr "valloc" "macax")] ) ;; Likewise. (define_insn "lshrsi3_virt" ;; 0 1 2-78 9-15 16 17-23 24 25-31 var [(set (match_operand:SI 0 "nonimmediate_operand" "=v,vU,&vU,v, &vU, &vU, v, &vU, v, &vU, &vU, vU, v,&vU,vU, vU, vU") @@ -212,36 +212,36 @@ (clobber (reg:HI X_REG)) ] "" "@ ; lshrsi %0, 0 - movw ax,%H1 | shrw ax,1 | movw %H0,ax | mov a,%Q1 | rorc a,1 | mov %Q0,a | mov a,%q1 | rorc a,1 | mov %q0,a - movw ax,%H1 | shrw ax,1 | movw %H0,ax | mov a,%Q1 | rorc a,1 | mov %Q0,a | mov a,%q1 | rorc a,1 | mov %q0,a + movw ax,%H1 \; shrw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0
[rl78] libgcc optimizations
Various optimizations. Committed. 2013-09-14 DJ Delorie Nick Clifton * config/rl78/mulsi3.S: Remove a few unneeded moves and branches. * config/rl78/vregs.h: New. * config/rl78/signbit.S: New file. Implements signbit function. * config/rl78/divmodsi.S: New. * config/rl78/divmodhi.S: New. * config/rl78/divmodqi.S: New. * config/rl78/t-rl78: Build them here... * config/rl78/lib2div.c: ...but not here. Index: config/rl78/divmodsi.S === --- config/rl78/divmodsi.S (revision 0) +++ config/rl78/divmodsi.S (revision 0) @@ -0,0 +1,521 @@ +/* SImode div/mod functions for the GCC support library for the Renesas RL78 processors. + Copyright (C) 2012,2013 Free Software Foundation, Inc. + Contributed by Red Hat. + + 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. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef __RL78_G10__ + +#include "vregs.h" + + .macro make_generic which,need_result + + .if \need_result + quot = r8 + num = r12 + den = r16 + bit = r20 + .else + num = r8 + quot = r12 + den = r16 + bit = r20 + .endif + + quotH = quot+2 + quotL = quot + quotB0 = quot + quotB1 = quot+1 + quotB2 = quot+2 + quotB3 = quot+3 + + numH = num+2 + numL = num + numB0 = num + numB1 = num+1 + numB2 = num+2 + numB3 = num+3 + +#definedenH bc + denL = den + denB0 = den + denB1 = den+1 +#definedenB2 c +#definedenB3 b + + bitH = bit+2 + bitL = bit + bitB0 = bit + bitB1 = bit+1 + bitB2 = bit+2 + bitB3 = bit+3 + +num_lt_den\which: + .if \need_result + movwr8, #0 + movwr10, #0 + .else + movwax, [sp+8] + movwr8, ax + movwax, [sp+10] + movwr10, ax + .endif + ret + +shift_den_bit16\which: + movwax, denL + movwdenH, ax + movwdenL, #0 + .if \need_result + movwax, bitL + movwbitH, ax + movwbitL, #0 + .else + mov a, bit + add a, #16 + mov bit, a + .endif + br $shift_den_bit\which + + ;; These routines leave DE alone - the signed functions use DE + ;; to store sign information that must remain intact + + .if \need_result + +generic_div: + + .else + +generic_mod: + + .endif + + ;; (quot,rem) = 8[sp] /% 12[sp] + + movwhl, sp + movwax, [hl+14] ; denH + cmpwax, [hl+10] ; numH + movwax, [hl+12] ; denL + sknz + cmpwax, [hl+8] ; numL + bh $num_lt_den\which + + sel rb2 + pushax ; denL +; pushbc ; denH + pushde ; bitL + pushhl ; bitH - stored in BC + sel rb0 + + ;; (quot,rem) = 16[sp] /% 20[sp] + + ;; copy numerator + movwax, [hl+8] + movwnumL, ax + movwax, [hl+10] + movwnumH, ax + + ;; copy denomonator + movwax, [hl+12] + movwdenL, ax + movwax, [hl+14] + movwdenH, ax + + movwax, denL + or a, denB2 + or a, denB3; not x + cmpwax, #0 + bnz $den_not_zero\which + movwnumL, #0 + movwnumH, #0 + ret + +den_not_zero\which: + .if \need_result + ;; zero out quot + movwquotL, #0 + movwquotH, #0 + .endif + + ;; initialize bit to 1 + movwbitL, #1 + movwbitH, #0 + +; while (den < num && !(den & (1L << BITS_MINUS_1))) + + .if 1 + ;; see if we can short-circuit a bunch of shifts + movwax, denH + cmpwax, #0 + bnz $shift_den_bit\which + movwax, denL + cmpwax,
[rl78] add RL78/G10 support
This patch adds support for the RL78/G10 variant, which doesn't have register banks like the other RL78 chips. Committed. * config/rl78/rl78.c (rl78_asm_file_start): Specify alternate vregs location for RL78/G10. (rl78_expand_prologue): Avoid SEL on G10. (rl78_expand_epilogue): Likewise. (rl78_peep_movhi_p): Can't move a constant to memory in HImode. * config/rl78/rl78.h (TARGET_CPU_CPP_BUILTINS): Define __RL78_G10__ when appropriate. (ASM_SPEC): Pass -mg10 along to the assembler. * config/rl78/rl78.md (sel_rb): Disable for G10. * config/rl78/rl78.opt: Add -mg10 option. * config/rl78/t-rl78: Add -mg10 multilib. * config/rl78/lib2mul.c: Enable for RL78/G10. * config/rl78/lib2div.c: Likewise. * config/rl78/lshrsi3.S: Use vregs.h. * config/rl78/cmpsi2.S: Likewise. * config/rl78/trampoline.S: Likewise. * config/rl78/mulsi2.S: Likewise. Disable for RL78/G10. Index: gcc/config/rl78/rl78.h === --- gcc/config/rl78/rl78.h (revision 202636) +++ gcc/config/rl78/rl78.h (working copy) @@ -29,24 +29,27 @@ builtin_define ("__RL78__"); \ builtin_assert ("cpu=RL78"); \ if (RL78_MUL_RL78) \ builtin_define ("__RL78_MUL_RL78__"); \ if (RL78_MUL_G13)\ builtin_define ("__RL78_MUL_G13__");\ + if (TARGET_G10) \ + builtin_define ("__RL78_G10__");\ } \ while (0) #undef STARTFILE_SPEC #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s" #undef ENDFILE_SPEC #define ENDFILE_SPEC "crtend.o%s crtn.o%s" #undef ASM_SPEC #define ASM_SPEC "\ %{mrelax:-relax} \ +%{mg10} \ " #undef LINK_SPEC #define LINK_SPEC "\ %{mrelax:-relax} \ " Index: gcc/config/rl78/rl78.c === --- gcc/config/rl78/rl78.c (revision 202636) +++ gcc/config/rl78/rl78.c (working copy) @@ -256,16 +256,26 @@ make_pass_rl78_move_elim (gcc::context * static void rl78_asm_file_start (void) { int i; - for (i = 0; i < 8; i++) + if (TARGET_G10) { - fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i); - fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i); + /* The memory used is 0xffec8 to 0xffedf; real registers are in +0xffee0 to 0xffee7. */ + for (i = 8; i < 32; i++) + fprintf (asm_out_file, "r%d\t=\t0x%x\n", i, 0xffec0 + i); +} + else +{ + for (i = 0; i < 8; i++) + { + fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i); + fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i); + } } opt_pass *rl78_devirt_pass = make_pass_rl78_devirt (g); static struct register_pass_info rl78_devirt_info = { rl78_devirt_pass, @@ -1015,25 +1025,32 @@ rl78_expand_prologue (void) if (!cfun->machine->computed) rl78_compute_frame_info (); if (flag_stack_usage_info) current_function_static_stack_size = cfun->machine->framesize; - if (is_interrupt_func (cfun->decl)) + if (is_interrupt_func (cfun->decl) && !TARGET_G10) emit_insn (gen_sel_rb (GEN_INT (0))); for (i = 0; i < 16; i++) if (cfun->machine->need_to_push [i]) { - int need_bank = i/4; - if (need_bank != rb) + if (TARGET_G10) { - emit_insn (gen_sel_rb (GEN_INT (need_bank))); - rb = need_bank; + emit_move_insn (gen_rtx_REG (HImode, 0), gen_rtx_REG (HImode, i*2)); + F (emit_insn (gen_push (gen_rtx_REG (HImode, 0; } - F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2; + else { + int need_bank = i/4; + if (need_bank != rb) + { + emit_insn (gen_sel_rb (GEN_INT (need_bank))); + rb = need_bank; + } + F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2; + } } if (rb != 0) emit_insn (gen_sel_rb (GEN_INT (0))); if (frame_pointer_needed) { @@ -1082,20 +1099,28 @@ rl78_expand_epilogue (void) } } for (i = 15; i >= 0; i--) if (cfun->machine->need_to_push [i]) { - int need_bank = i / 4; - - if (need_bank != rb) + if (TARGET_G10) { - emit_insn (gen_sel_rb (GEN_INT (need_bank))); - rb = need_bank; + emit_insn (gen_pop (gen_rtx_REG (HImode, 0))); + emit_move_insn (gen_rtx_REG (HImode, i*2), gen_rtx_REG (HImode, 0)); + } + else + { + int need_bank = i / 4; + + if (need_bank != rb) + { + emit_insn (gen_sel_rb (GEN_INT (need_bank))); + rb = need_bank; +
[rl78] missed G10 bit
Forgot this bit, committed. * config/rl78/vregs.h: Add G10 register definitions. Index: config/rl78/vregs.h === --- config/rl78/vregs.h (revision 202637) +++ config/rl78/vregs.h (working copy) @@ -8,12 +8,35 @@ r_2 = 0xffefa r_3= 0xffefb r_4= 0xffefc r_5= 0xffefd r_6= 0xffefe r_7= 0xffeff +#ifdef __RL78_G10__ + +; clobberable +r8 = 0xffec8 +r9 = 0xffec9 +r10= 0xffeca +r11= 0xffecb +r12= 0xffecc +r13= 0xffecd +r14= 0xffece +r15= 0xffecf +; preserved +r16= 0xffed0 +r17= 0xffed1 +r18= 0xffed2 +r19= 0xffed3 +r20= 0xffed4 +r21= 0xffed5 +r22= 0xffed6 +r23= 0xffed7 + +#else + ; clobberable r8 = 0xffef0 r9 = 0xffef1 r10= 0xffef2 r11= 0xffef3 r12= 0xffef4 @@ -27,6 +50,7 @@ r18 = 0xffeea r19= 0xffeeb r20= 0xffeec r21= 0xffeed r22= 0xffeee r23= 0xffeef +#endif
Re: Using gen_int_mode instead of GEN_INT minor testsuite fallout on MIPS
m32c's PSImode is 24-bits, why does it have "32" in the macro? /* 24-bit pointers, in 32-bit units */ -PARTIAL_INT_MODE (SI); +PARTIAL_INT_MODE_NAME (SI, 32, PSI);
[rl78] optimize prologues
Committed. 2013-09-17 Nick Clifton * config/rl78/rl78.c (need_to_save): Change return type to bool. For interrupt functions: save all call clobbered registers if the interrupt handler is not a leaf function. (rl78_expand_prologue): Always recompute the frame information. For interrupt functions: only select bank 0 if one of the bank 0 registers is going to be psuhed. Index: config/rl78/rl78.c === --- config/rl78/rl78.c (revision 202666) +++ config/rl78/rl78.c (working copy) @@ -537,40 +537,45 @@ rl78_force_nonfar_3 (rtx *operands, rtx static bool rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to ATTRIBUTE_UNUSED) { return true; } -/* Returns nonzero if the given register needs to be saved by the +/* Returns true if the given register needs to be saved by the current function. */ -static int -need_to_save (int regno) +static bool +need_to_save (unsigned int regno) { if (is_interrupt_func (cfun->decl)) { - if (regno < 8) - return 1; /* don't know what devirt will need */ + /* We don't need to save registers that have + been reserved for interrupt handlers. */ if (regno > 23) - return 0; /* don't need to save interrupt registers */ - if (crtl->is_leaf) - { - return df_regs_ever_live_p (regno); - } - else - return 1; + return false; + + /* If the handler is a non-leaf function then it may call +non-interrupt aware routines which will happily clobber +any call_used registers, so we have to preserve them. */ + if (!crtl->is_leaf && call_used_regs[regno]) + return true; + + /* Otherwise we only have to save a register, call_used +or not, if it is used by this handler. */ + return df_regs_ever_live_p (regno); } + if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) -return 1; +return true; if (fixed_regs[regno]) -return 0; +return false; if (crtl->calls_eh_return) -return 1; +return true; if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) -return 1; - return 0; +return true; + return false; } /* We use this to wrap all emitted insns in the prologue. */ static rtx F (rtx x) { @@ -1023,20 +1028,26 @@ rl78_expand_prologue (void) rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM); int rb = 0; if (rl78_is_naked_func ()) return; - if (!cfun->machine->computed) -rl78_compute_frame_info (); + /* Always re-compute the frame info - the register usage may have changed. */ + rl78_compute_frame_info (); if (flag_stack_usage_info) current_function_static_stack_size = cfun->machine->framesize; if (is_interrupt_func (cfun->decl) && !TARGET_G10) -emit_insn (gen_sel_rb (GEN_INT (0))); +for (i = 0; i < 4; i++) + if (cfun->machine->need_to_push [i]) + { + /* Select Bank 0 if we are using any registers from Bank 0. */ + emit_insn (gen_sel_rb (GEN_INT (0))); + break; + } for (i = 0; i < 16; i++) if (cfun->machine->need_to_push [i]) { if (TARGET_G10) {
[rl78] Add -mallregs
GCC typically avoids using virtual registers $r24 through $r31, as this register bank (bank 3) is reserved for hand-written assembly interrupt handlers. If unneeded for that, this new option lets gcc use those registers also. Committed. * config/rl78/constraints.md (Wcv): Allow up to $r31. * config/rl78/rl78.c (rl78_asm_file_start: Likewise. (rl78_option_override): Likewise, if -mallregs. (is_virtual_register): Likewise. * config/rl78/rl78.h (reg_class): Extend VREGS to $r31. (REGNO_OK_FOR_BASE_P): Likewise. * config/rl78/rl78.opt (-mallregs): New. Index: config/rl78/rl78.h === --- config/rl78/rl78.h (revision 202668) +++ config/rl78/rl78.h (working copy) @@ -262,13 +262,13 @@ enum reg_class { 0x000c, 0x }, /* B and C - index regs. */\ { 0x00ff, 0x }, /* all real registers. */ \ { 0x, 0x0001 }, /* SP */\ { 0x0300, 0x }, /* R8 - HImode */ \ { 0x0c00, 0x }, /* R10 - HImode */ \ { 0xff00, 0x }, /* INT - HImode */ \ - { 0x007fff00, 0x }, /* Virtual registers. */ \ + { 0xff7fff00, 0x }, /* Virtual registers. */ \ { 0xff7f, 0x0002 }, /* General registers. */ \ { 0x0400, 0x0004 }, /* PSW. */ \ { 0xff7f, 0x001f } /* All registers. */ \ } #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true @@ -349,13 +349,13 @@ enum reg_class (IN_RANGE ((REGNO), (MIN), (MAX))\ || (reg_renumber != NULL\ && reg_renumber[(REGNO)] >= (MIN) \ && reg_renumber[(REGNO)] <= (MAX))) #ifdef REG_OK_STRICT -#define REGNO_OK_FOR_BASE_P(regno) REGNO_IN_RANGE (regno, 16, 23) +#define REGNO_OK_FOR_BASE_P(regno) REGNO_IN_RANGE (regno, 16, 31) #else #define REGNO_OK_FOR_BASE_P(regno) 1 #endif #define REGNO_OK_FOR_INDEX_P(regno)REGNO_OK_FOR_BASE_P (regno) Index: config/rl78/constraints.md === --- config/rl78/constraints.md (revision 202668) +++ config/rl78/constraints.md (working copy) @@ -260,16 +260,16 @@ "es:[AX..HL] for calls" (match_test "rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op)) || satisfies_constraint_Cca (op)") ) (define_memory_constraint "Ccv" - "[AX..HL,r8-r23] for calls" + "[AX..HL,r8-r31] for calls" (and (match_code "mem") (and (match_code "reg" "0") - (match_test "REGNO (XEXP (op, 0)) < 24"))) + (match_test "REGNO (XEXP (op, 0)) < 31"))) ) (define_memory_constraint "Wcv" "es:[AX..HL,r8-r23] for calls" (match_test "rl78_es_addr (op) && satisfies_constraint_Ccv (rl78_es_base (op)) || satisfies_constraint_Ccv (op)") ) Index: config/rl78/rl78.c === --- config/rl78/rl78.c (revision 202668) +++ config/rl78/rl78.c (working copy) @@ -269,12 +269,13 @@ rl78_asm_file_start (void) else { for (i = 0; i < 8; i++) { fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i); fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i); + fprintf (asm_out_file, "r%d\t=\t0x%x\n", 24 + i, 0xffee0 + i); } } opt_pass *rl78_devirt_pass = make_pass_rl78_devirt (g); static struct register_pass_info rl78_devirt_info = { @@ -306,12 +307,19 @@ rl78_option_override (void) { flag_omit_frame_pointer = 1; flag_no_function_cse = 1; flag_split_wide_types = 0; init_machine_status = rl78_init_machine_status; + + if (TARGET_ALLREGS) +{ + int i; + for (i=24; i<32; i++) + fixed_regs[i] = 0; +} } /* Most registers are 8 bits. Some are 16 bits because, for example, gcc doesn't like dealing with $FP as a register pair. This table maps register numbers to size in bytes. */ static const int register_sizes[] = @@ -2212,13 +2220,13 @@ insn_ok_now (rtx insn) /* Returns TRUE if R is a virtual register. */ static bool is_virtual_register (rtx r) { return (GET_CODE (r) == REG && REGNO (r) >= 8 - && REGNO (r) < 24); + && REGNO (r) < 32); } /* In all these alloc routines, we expect the following: the insn pattern is unshared, the insn was previously recognized and failed due to predicates or constraints, and the operand data is in recog_data. */ Index: config/rl78/rl78.opt === --- config/rl78/rl78.opt(revision 202668) +++ config/rl78/rl78.opt(working copy) @@ -39,12 +39,16 @@ Enum(rl78_mul_types) String(none) Value( EnumValue Enum(rl78_mul_types) String(rl78) Val
[rl78] fix far address optimizations
Track both parts of far addresses so they don't get optimized away. Committed. * config/rl78/constraints.md: For each W* constraint, rename to C* and create a W* constraint that checks for an optional ES: prefix pattern also. * config/rl78/rl78.md (UNS_ES_ADDR): New. (es_addr): New. Used to wrap far addresses. * config/rl78/rl78-protos.h (rl78_es_addr): New. (rl78_es_base): New. * config/rl78/rl78.c (rl78_as_legitimate_address): Accept "unspec" wrapped far addresses. (rl78_print_operand_1): Unwrap far addresses before processing. (rl78_lo16): Wrap far addresses in unspecs. (rl78_es_addr): New. (rl78_es_base): New. (insn_ok_now): Check for not-yet-wrapped far addresses. (transcode_memory_rtx): Properly re-wrap far addresses. Index: config/rl78/constraints.md === --- config/rl78/constraints.md (revision 202665) +++ config/rl78/constraints.md (working copy) @@ -200,103 +200,155 @@ (define_register_constraint "Zint" "INT_REGS" "The interrupt registers.") ; All the memory addressing schemes the RL78 supports ; of the form W {register} {bytes of offset} ; or W {register} {register} +; Additionally, the Cxx forms are the same as the Wxx forms, but without +; the ES: override. ; absolute address -(define_memory_constraint "Wab" +(define_memory_constraint "Cab" "[addr]" (and (match_code "mem") (ior (match_test "CONSTANT_P (XEXP (op, 0))") (match_test "GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF")) ) ) +(define_memory_constraint "Wab" + "es:[addr]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cab (rl78_es_base (op)) + || satisfies_constraint_Cab (op)") + ) -(define_memory_constraint "Wbc" +(define_memory_constraint "Cbc" "word16[BC]" (and (match_code "mem") (ior (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == BC_REG")) (and (match_code "plus" "0") (and (and (match_code "reg" "00") (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == BC_REG")) (match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)" ) ) +(define_memory_constraint "Wbc" + "es:word16[BC]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cbc (rl78_es_base (op)) + || satisfies_constraint_Cbc (op)") + ) -(define_memory_constraint "Wde" +(define_memory_constraint "Cde" "[DE]" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == DE_REG"))) ) +(define_memory_constraint "Wde" + "es:[DE]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cde (rl78_es_base (op)) + || satisfies_constraint_Cde (op)") + ) -(define_memory_constraint "Wca" +(define_memory_constraint "Cca" "[AX..HL] for calls" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) <= HL_REG"))) ) +(define_memory_constraint "Wca" + "es:[AX..HL] for calls" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op)) + || satisfies_constraint_Cca (op)") + ) -(define_memory_constraint "Wcv" +(define_memory_constraint "Ccv" "[AX..HL,r8-r23] for calls" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) < 24"))) ) +(define_memory_constraint "Wcv" + "es:[AX..HL,r8-r23] for calls" + (match_test "rl78_es_addr (op) && satisfies_constraint_Ccv (rl78_es_base (op)) + || satisfies_constraint_Ccv (op)") + ) -(define_memory_constraint "Wd2" +(define_memory_constraint "Cd2" "word16[DE]" (and (match_code "mem") (ior (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == DE_REG")) (and (match_code "plus" "0") (and (and (match_code "reg" "00") (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == DE_REG")) (match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)" ) ) +(define_memory_constraint "Wd2" + "es:word16[DE]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cd2 (rl78_es_base (op)) + || satisfies_constraint_Cd2 (op)") + ) -(define_memory_constraint "Whl" +(define_memory_constraint "Chl" "[HL]" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == HL_REG"))) ) +(define_memory_constraint "Whl" + "es:[HL]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Chl (rl78_es_base (op)) + || satisfies_constraint_Chl (op)") + ) -(define_memory_constraint "Wh1" +(define_memory_constraint "Ch1" "byte8[HL]" (and (match_code "mem")
[rl78] add bit test/branch insns
A few new patterns. Committed. 2013-09-17 Nick Clifton * config/rl78/rl78-real.md (bf): New pattern. (bt): New pattern. * config/rl78/rl78.c (rl78_print_operand_1): Handle %B. (rl78_print_operand): Do not put a # before a %B. * config/rl78/rl78.opt: Tweak doc strings. Index: config/rl78/rl78-real.md === --- config/rl78/rl78-real.md(revision 202675) +++ config/rl78/rl78-real.md(working copy) @@ -456,6 +456,61 @@ (set (reg:HI AX_REG) (match_dup 0))] "" [(set (match_dup 0) (reg:HI AX_REG))] ) +;; Bit test and branch insns. + +;; NOTE: These patterns will work for bits in other places, not just A. + +(define_insn "bf" + [(set (pc) + (if_then_else (eq (and (reg:QI A_REG) + (match_operand 0 "immediate_operand" "n")) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc)))] + "" + "bf\tA.%B0, $%1" +) + +(define_insn "bt" + [(set (pc) + (if_then_else (ne (and (reg:QI A_REG) + (match_operand 0 "immediate_operand" "n")) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc)))] + "" + "bt\tA.%B0, $%1" +) + +;; NOTE: These peepholes are fragile. They rely upon GCC generating +;; a specific sequence on insns, based upon examination of test code. +;; Improvements to GCC or using code other than the test code can result +;; in the peephole not matching and the optimization being missed. + +(define_peephole2 + [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG)) + (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand"))) + (set (pc) (if_then_else (eq (match_dup 1) (const_int 0)) + (label_ref (match_operand 3 "")) + (pc)))] + "peep2_regno_dead_p (3, REGNO (operands[1])) + && exact_log2 (INTVAL (operands[2])) >= 0" + [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup 2)) (const_int 0)) + (label_ref (match_dup 3)) (pc)))] + ) + +(define_peephole2 + [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG)) + (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand"))) + (set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) + (label_ref (match_operand 3 "")) + (pc)))] + "peep2_regno_dead_p (3, REGNO (operands[1])) + && exact_log2 (INTVAL (operands[2])) >= 0" + [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup 2)) (const_int 0)) + (label_ref (match_dup 3)) (pc)))] + ) + Index: config/rl78/rl78.c === --- config/rl78/rl78.c (revision 202675) +++ config/rl78/rl78.c (working copy) @@ -1283,12 +1283,13 @@ rl78_function_arg_boundary (enum machine m - minus - negative of CONST_INT value. c - inverse of a conditional (NE vs EQ for example) z - collapsed conditional s - shift count mod 8 S - shift count mod 16 r - reverse shift count (8-(count mod 8)) + B - bit position h - bottom HI of an SI H - top HI of an SI q - bottom QI of an HI Q - top QI of an HI e - third QI of an SI (i.e. where the ES register gets values from) @@ -1409,12 +1410,14 @@ rl78_print_operand_1 (FILE * file, rtx o else if (letter == 'q') fprintf (file, "%ld", INTVAL (op) & 0xff); else if (letter == 'h') fprintf (file, "%ld", INTVAL (op) & 0x); else if (letter == 'e') fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff); + else if (letter == 'B') + fprintf (file, "%d", exact_log2 (INTVAL (op))); else if (letter == 'E') fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff); else if (letter == 'm') fprintf (file, "%ld", - INTVAL (op)); else if (letter == 's') fprintf (file, "%ld", INTVAL (op) % 8); @@ -1602,13 +1605,13 @@ rl78_print_operand_1 (FILE * file, rtx o #undef TARGET_PRINT_OPERAND #define TARGET_PRINT_OPERAND rl78_print_operand static void rl78_print_operand (FILE * file, rtx op, int letter) { - if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S') + if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S' && letter != 'B') fprintf (file, "#"); rl78_print_operand_1 (file, op, letter); } #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT rl78_trampoline_init Index: config/rl78/rl78.opt === --- config/rl78/rl78.opt(revision 202675) +++ config/rl78/rl78.opt(working copy) @@ -20,13 +20,13 @@ ;--- HeaderInclude co
[rl78] various tweaks
Mostly whitespace and comment tweaks, with a few random bug fixes. Committed. Note: the net result of our recent batch of patches is an approximately 50% speed improvement :-) * config/rl78/rl78.c: Various whitespace and comment tweaks. (need_to_save): Save bank 0 on interrupts. (characterize_address): Strip far address wrappers. (rl78_as_legitimate_address): Likewise. (transcode_memory_rtx): Likewise. (rl78_peep_movhi_p): Disable this peephole after devirt. (rl78_propogate_register_origins): Forget all origins when a CLOBBER is seen. * config/rl78/rl78-virt.md: Various whitespace tweaks. * config/rl78/rl78-real.md: Various whitespace tweaks. Additional peephole2's. * config/rl78/rl78.md (sel_rb): Disable for G10 just in case. * config/rl78/rl78-expand.md (movqi): Check for subregs of consts. * config/rl78/rl78.h (LINK_SPEC): Pass -gc-sections unless relocating. * config/rl78/constraints.md: Various whitespace and paren tweaks. Index: config/rl78/rl78.h === --- config/rl78/rl78.h (revision 202798) +++ config/rl78/rl78.h (working copy) @@ -49,12 +49,13 @@ %{mg10} \ " #undef LINK_SPEC #define LINK_SPEC "\ %{mrelax:-relax} \ +%{!r:--gc-sections} \ " #undef LIB_SPEC #define LIB_SPEC " \ --start-group \ -lc\ Index: config/rl78/constraints.md === --- config/rl78/constraints.md (revision 202798) +++ config/rl78/constraints.md (working copy) @@ -59,33 +59,37 @@ (define_constraint "Iv08" "@internal Integer constant equal to 8." (and (match_code "const_int") (match_test "IN_RANGE (ival, 8, 8)"))) + (define_constraint "Iv16" "@internal Integer constant equal to 16." (and (match_code "const_int") (match_test "IN_RANGE (ival, 16, 16)"))) + (define_constraint "Iv24" "@internal Integer constant equal to 24." (and (match_code "const_int") (match_test "IN_RANGE (ival, 24, 24)"))) (define_constraint "Is09" "@internal Integer constant in the range 9 @dots{} 15 (for shifts)." (and (match_code "const_int") (match_test "IN_RANGE (ival, 9, 15)"))) + (define_constraint "Is17" "@internal Integer constant in the range 17 @dots{} 23 (for shifts)." (and (match_code "const_int") (match_test "IN_RANGE (ival, 17, 23)"))) + (define_constraint "Is25" "@internal Integer constant in the range 25 @dots{} 31 (for shifts)." (and (match_code "const_int") (match_test "IN_RANGE (ival, 25, 31)"))) @@ -213,13 +217,13 @@ (ior (match_test "CONSTANT_P (XEXP (op, 0))") (match_test "GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF")) ) ) (define_memory_constraint "Wab" "es:[addr]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cab (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cab (rl78_es_base (op))) || satisfies_constraint_Cab (op)") ) (define_memory_constraint "Cbc" "word16[BC]" (and (match_code "mem") @@ -231,49 +235,49 @@ (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == BC_REG")) (match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)" ) ) (define_memory_constraint "Wbc" "es:word16[BC]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cbc (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cbc (rl78_es_base (op))) || satisfies_constraint_Cbc (op)") ) (define_memory_constraint "Cde" "[DE]" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == DE_REG"))) ) (define_memory_constraint "Wde" "es:[DE]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cde (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cde (rl78_es_base (op))) || satisfies_constraint_Cde (op)") ) (define_memory_constraint "Cca" "[AX..HL] for calls" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) <= HL_REG"))) ) (define_memory_constraint "Wca" "es:[AX..HL] for calls" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op))) || satisfies_constraint_Cca (op)") ) (define_memory_constraint "Ccv" "[AX..HL,r8-r31] for calls" (and (match_code "mem") (and (match_code "reg" "0") - (match_test "REGNO (XEXP (op, 0)) < 31"))) + (match_test "REGNO (X
Re: Commit: MSP430: Pass -md on to assembler
> If we instead ask, is it sane for gcc to ever want to signed extend > in this case, IIRC I've seen this due to the fact that pointer math is always signed, and since gcc has no way of having a PSImode-sized size_t, all pointer math is done in signed SImode, then the result is truncated to PSImode.
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
As per my previous comments on this patch, I will not approve the changes to the m32c backend, as they will cause real bugs in real hardware, and violate the hardware's ABI. The user may use -fno-strict-volatile-bitfields if they do not desire this behavior and understand the consequences. I am not a maintainer for the rx and h8300 ports, but they are in the same situation. To reiterate my core position: if the user defines a proper "volatile int" bitfield, and the compiler does anything other than an int-sized access, the compiler is WRONG. Any optimization that changes volatile accesses to something other than what the user specified is a bug that needs to be fixed before this option can be non-default.
Re: [patch] move htab_iterator
I'm typically against adding things to libiberty "because there's no other place for them". The purpose of libiberty is to provide a portability layer, not a trash can. However, htab is already in there, and the argument for putting its accessors there is sound. However, most of the other functions in hashtab.h are of the form htab_*(). Could these be changed to match that pattern? If these functions are unused, it shouldn't matter to rename them. (although, if they're unused, it shouldn't matter to discard them, either)
[patch] m32c: fix pr54950
Fixed 16-bit widening multiplies by a constant by limiting constant matches to 16 bit constants. Applied. PR target/54950 * config/m32c/predicates.md (m32c_const_u16_operand): New. * config/m32c/muldiv.md: Use it. Index: config/m32c/predicates.md === --- config/m32c/predicates.md (revision 192552) +++ config/m32c/predicates.md (working copy) @@ -293,3 +293,7 @@ (define_predicate "m32c_1mask16_operand" (and (match_operand 0 "const_int_operand") (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Imw\")"))) + +(define_predicate "m32c_const_u16_operand" + (and (match_operand 0 "const_int_operand") + (match_test "fprintf(stderr, \"u16=%d\\n\", INTVAL(op)),INTVAL (op) >= 0 && INTVAL (op) <= 65535"))) Index: config/m32c/muldiv.md === --- config/m32c/muldiv.md (revision 192552) +++ config/m32c/muldiv.md (working copy) @@ -108,7 +108,7 @@ (define_insn "umulhisi3_c" [(set (match_operand:SI 0 "ra_operand" "=Rsi") (mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0")) - (match_operand 2 "immediate_operand" "i")))] + (match_operand 2 "m32c_const_u16_operand" "i")))] "" "mulu.w\t%u2,%1" [(set_attr "flags" "o")]
Re: [patch] m32c: fix pr54950
> Are you sure you meant to have an fprintf in a match_test ? I definitely did not. Removed. Thanks!
[rl78] fix __far reg+addend addresses
Commited. * config/rl78/rl78.c (rl78_as_legitimate_address): Do not allow reg+addend addresses for the _far namespace. Index: gcc/config/rl78/rl78.c === --- gcc/config/rl78/rl78.c (revision 192862) +++ gcc/config/rl78/rl78.c (working copy) @@ -683,12 +683,19 @@ rl78_as_legitimate_address (enum machine && GET_MODE (x) == SImode) return false; if (! characterize_address (x, &base, &index, &addend)) return false; + /* We can't extract the high/low portions of a PLUS address + involving a register during devirtualization, so make sure all + such __far addresses do not have addends. This forces GCC to do + the sum separately. */ + if (addend && base && as == ADDR_SPACE_FAR) +return false; + if (base && index) { int ir = REGNO (index); int br = REGNO (base); #define OK(test, debug) if (test) { /*fprintf(stderr, "%d: OK %s\n", __LINE__, debug);*/ return true; }
rl78: fix %c modifier
namespaces are so small... committed. * config/rl78/rl78.c (rl78_print_operand_1): Change %c to %C to avoid conflict with the MI use of %c. * config/rl78/rl78-real.md: change %c to %C throughout. * config/rl78/rl78-virt.md: Likewise. Index: config/rl78/rl78-real.md === --- config/rl78/rl78-real.md(revision 203295) +++ config/rl78/rl78-real.md(working copy) @@ -318,69 +318,69 @@ [(match_operand:QI 1 "general_operand" "A,A,A") (match_operand:QI 2 "general_operand" "ISqi,i,v")]) (label_ref (match_operand 3 "" "")) (pc)))] "rl78_real_insns_ok ()" "@ - cmp\t%1, %2 \;xor1 CY,%1.7\;not1 CY\;sk%c0 \;br\t!!%3 - cmp\t%1, %2 \;xor1 CY,%1.7\;sk%c0 \;br\t!!%3 - cmp\t%1, %2 \;xor1 CY,%1.7\;xor1 CY,%2.7\;sk%c0 \;br\t!!%3" + cmp\t%1, %2 \;xor1 CY,%1.7\;not1 CY\;sk%C0 \;br\t!!%3 + cmp\t%1, %2 \;xor1 CY,%1.7\;sk%C0 \;br\t!!%3 + cmp\t%1, %2 \;xor1 CY,%1.7\;xor1 CY,%2.7\;sk%C0 \;br\t!!%3" ) (define_insn "*cbranchqi4_real" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_real" [(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl") (match_operand:QI 2 "general_operand" "M, irvWabWhlWh1Whb,i,a")]) (label_ref (match_operand 3 "" "")) (pc)))] "rl78_real_insns_ok ()" "@ - cmp0\t%1 \;sk%c0 \;br\t!!%3 - cmp\t%1, %2 \;sk%c0 \;br\t!!%3 - cmp\t%1, %2 \;sk%c0 \;br\t!!%3 - cmp\t%1, %2 \;sk%c0 \;br\t!!%3" + cmp0\t%1 \;sk%C0 \;br\t!!%3 + cmp\t%1, %2 \;sk%C0 \;br\t!!%3 + cmp\t%1, %2 \;sk%C0 \;br\t!!%3 + cmp\t%1, %2 \;sk%C0 \;br\t!!%3" ) (define_insn "*cbranchhi4_real_signed" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_signed" [(match_operand:HI 1 "general_operand" "A,A,A,vR") (match_operand:HI 2 "general_operand" "IShi,i,v,1")]) (label_ref (match_operand 3)) (pc)))] "rl78_real_insns_ok ()" "@ - cmpw\t%1, %2 \;xor1 CY,%Q1.7\;not1 CY\;sk%c0 \;br\t!!%3 - cmpw\t%1, %2 \;xor1 CY,%Q1.7\;sk%c0 \;br\t!!%3 - cmpw\t%1, %2 \;xor1 CY,%Q1.7\;xor1 CY,%Q2.7\;sk%c0 \;br\t!!%3 + cmpw\t%1, %2 \;xor1 CY,%Q1.7\;not1 CY\;sk%C0 \;br\t!!%3 + cmpw\t%1, %2 \;xor1 CY,%Q1.7\;sk%C0 \;br\t!!%3 + cmpw\t%1, %2 \;xor1 CY,%Q1.7\;xor1 CY,%Q2.7\;sk%C0 \;br\t!!%3 %z0\t!!%3" ) (define_insn "cbranchhi4_real" [(set (pc) (if_then_else (match_operator0 "rl78_cmp_operator_real" [(match_operand:HI 1 "general_operand" "A,vR") (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1,1")]) (label_ref (match_operand 3 "" "")) (pc)))] "rl78_real_insns_ok ()" "@ - cmpw\t%1, %2 \;sk%c0 \;br\t!!%3 + cmpw\t%1, %2 \;sk%C0 \;br\t!!%3 %z0\t!!%3" ) (define_insn "cbranchhi4_real_inverted" [(set (pc) (if_then_else (match_operator0 "rl78_cmp_operator_real" [(match_operand:HI 1 "general_operand" "A") (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1")]) (pc) (label_ref (match_operand 3 "" ""] "rl78_real_insns_ok ()" - "cmpw\t%1, %2 \;sk%c0 \;br\t!!%3" + "cmpw\t%1, %2 \;sk%C0 \;br\t!!%3" ) (define_insn "*cbranchsi4_real_lt" [(set (pc) (if_then_else (lt (match_operand:SI 0 "general_operand" "U,vWabWhlWh1") (const_int 0)) @@ -416,28 +416,28 @@ (label_ref (match_operand 3 "" "")) (pc))) (clobber (reg:HI AX_REG)) ] "rl78_real_insns_ok ()" "@ - movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;not1 CY\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3 - movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3 - movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;xor1 CY,%E2.7\;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3" + movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;not1 CY\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3 + movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3 + movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;xor1 CY,%E2.7\;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3" ) (define_insn "*cbranchsi4_real" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_real" [(match_operand:SI 1 "general_operand" "vUi") (match_operand:SI 2 "general_operand" "iWhlWh1v")]) (label_ref (match_operand 3 "" "")) (pc)))
[rl78] tweaks to moviqi/movsi expander
Minor fix. Committed. * config/rl78/rl78-expand.md (movqi): use operands[] not operandN. (movhi): Likewise. 2013-10-08 Jan Hubicka Index: config/rl78/rl78-expand.md === --- config/rl78/rl78-expand.md (revision 203298) +++ config/rl78/rl78-expand.md (working copy) @@ -22,55 +22,55 @@ (define_expand "movqi" [(set (match_operand:QI 0 "nonimmediate_operand") (match_operand:QI 1 "general_operand"))] "" { -if (MEM_P (operand0) && MEM_P (operand1)) - operands[1] = copy_to_mode_reg (QImode, operand1); -if (rl78_far_p (operand0) && rl78_far_p (operand1)) - operands[1] = copy_to_mode_reg (QImode, operand1); +if (MEM_P (operands[0]) && MEM_P (operands[1])) + operands[1] = copy_to_mode_reg (QImode, operands[1]); +if (rl78_far_p (operands[0]) && rl78_far_p (operands[1])) + operands[1] = copy_to_mode_reg (QImode, operands[1]); /* FIXME: Not sure how GCC can generate (SUBREG (SYMBOL_REF)), but it does. Since this makes no sense, reject it here. */ -if (GET_CODE (operand1) == SUBREG -&& GET_CODE (XEXP (operand1, 0)) == SYMBOL_REF) +if (GET_CODE (operands[1]) == SUBREG +&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) FAIL; /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF. cf. g++.dg/abi/packed.C. */ -if (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == CONST -&& GET_CODE (XEXP (XEXP (operand1, 0), 0)) == PLUS -&& GET_CODE (XEXP (XEXP (XEXP (operand1, 0), 0), 0)) == SYMBOL_REF) +if (GET_CODE (operands[1]) == SUBREG + && GET_CODE (XEXP (operands[1], 0)) == CONST +&& GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS +&& GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF) FAIL; -if (CONST_INT_P (operand1) && ! IN_RANGE (INTVAL (operand1), (-1 << 8) + 1, (1 << 8) - 1)) +if (CONST_INT_P (operands[1]) && ! IN_RANGE (INTVAL (operands[1]), (-1 << 8) + 1, (1 << 8) - 1)) FAIL; } ) (define_expand "movhi" [(set (match_operand:HI 0 "nonimmediate_operand") (match_operand:HI 1 "general_operand"))] "" { -if (MEM_P (operand0) && MEM_P (operand1)) - operands[1] = copy_to_mode_reg (HImode, operand1); -if (rl78_far_p (operand0) && rl78_far_p (operand1)) - operands[1] = copy_to_mode_reg (HImode, operand1); +if (MEM_P (operands[0]) && MEM_P (operands[1])) + operands[1] = copy_to_mode_reg (HImode, operands[1]); +if (rl78_far_p (operands[0]) && rl78_far_p (operands[1])) + operands[1] = copy_to_mode_reg (HImode, operands[1]); /* FIXME: Not sure how GCC can generate (SUBREG (SYMBOL_REF)), but it does. Since this makes no sense, reject it here. */ -if (GET_CODE (operand1) == SUBREG -&& GET_CODE (XEXP (operand1, 0)) == SYMBOL_REF) +if (GET_CODE (operands[1]) == SUBREG +&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) FAIL; /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF. */ -if (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == CONST -&& GET_CODE (XEXP (XEXP (operand1, 0), 0)) == PLUS -&& GET_CODE (XEXP (XEXP (XEXP (operand1, 0), 0), 0)) == SYMBOL_REF) +if (GET_CODE (operands[1]) == SUBREG + && GET_CODE (XEXP (operands[1], 0)) == CONST +&& GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS +&& GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF) FAIL; } ) (define_insn_and_split "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "=vYS,v,Wfr")
Re: Apply attribute returns_nonnull in libiberty
Your patch changes the rule that the application can override xmalloc() and get functions that return NULL...
Re: Apply attribute returns_nonnull in libiberty
> Why would you want to do that? I wouldn't, but gcc isn't the only user of libiberty.
Re: Apply attribute returns_nonnull in libiberty
PR tree-optimization/58689 * ansidecl.h (ATTRIBUTE_RETURNS_NONNULL): New macro. * libiberty.h (basename, lbasename, dos_lbasename, unix_lbasename, concat_copy): Mark with attributes nonnull(1) and returns_nonnull. (concat_copy2, xstrerror): Mark with attribute returns_nonnull. This part is OK.
Re: Apply attribute returns_nonnull in libiberty
Alternatively, you could ask the other projects if they're ok with changing the xmalloc rule...
Re: Apply attribute returns_nonnull in libiberty
I don't think there's an official list, but if you ask gdb, binutils, newlib, and sid (I think), you've probably got it covered. Basically, everything in the src/ repository.
[rl78] add rtx paranoia
Building newlib uncovered a few invalid assumptions... Committed. * config/rl78/rl78.c (rl78_alloc_address_registers_macax): Verify op is a REG before checking REGNO. (rl78_alloc_physical_registers): Verify pattern is a SET before checking SET_SRC. Index: config/rl78/rl78.c === --- config/rl78/rl78.c (revision 203732) +++ config/rl78/rl78.c (working copy) @@ -3047,13 +3047,14 @@ rl78_alloc_address_registers_macax (rtx replace_in_op0 = (op > 0 && rtx_equal_p (OP (op), OP (0))); replace_in_op1 = (op > 1 && rtx_equal_p (OP (op), OP (1))); OP (op) = transcode_memory_rtx (OP (op), HL, insn); if (op == 2 && MEM_P (OP (op)) - && (REGNO (XEXP (OP (op), 0)) == SP_REG + && ((GET_CODE (XEXP (OP (op), 0)) == REG + && REGNO (XEXP (OP (op), 0)) == SP_REG) || (GET_CODE (XEXP (OP (op), 0)) == PLUS && REGNO (XEXP (XEXP (OP (op), 0), 0)) == SP_REG))) { emit_insn_before (gen_movhi (HL, gen_rtx_REG (HImode, SP_REG)), insn); OP (op) = replace_rtx (OP (op), gen_rtx_REG (HImode, SP_REG), HL); } @@ -3137,13 +3138,14 @@ rl78_alloc_physical_registers (void) pattern = XVECEXP (pattern, 0, 0); if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL) clear_content_memory (); if (GET_CODE (pattern) != SET && GET_CODE (pattern) != CALL) continue; - if (GET_CODE (SET_SRC (pattern)) == ASM_OPERANDS) + if (GET_CODE (pattern) == SET + && GET_CODE (SET_SRC (pattern)) == ASM_OPERANDS) continue; valloc_method = get_attr_valloc (insn); PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
> As it looks like, the -fstrict-volatile-bitfields are already totally broken, I tested your example on rl78-elf, with and without -fstrict-volatile-bitfields, and it generates correct code with it and incorrect code without it. Same for m32c-elf. Same for h8300-elf. Seems to be working OK for me. Either way, if -fstrict-volatile-bitfields does not do what it's supposed to do, the correct action is to fix it - not to disable it on targets that rely on it for correct operation.
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
> I'm curious; do all the test cases included in > http://gcc.gnu.org/ml/gcc-patches/2013-09/msg02058.html > work for you on those targets as well (without applying the rest of the > patch)? Not all of them can work, because they describe something that can't be done in hardware. For example, the first test has an incomplete bitfield - the fields do not completely describe an "int" so the structure is smaller (one byte, according to sizeof()) than the access type (2-8 bytes). Looking through the tests, most of them combine "packed" with mismatched types. IMHO, those tests are invalid. > > Either way, if -fstrict-volatile-bitfields does not do what it's > > supposed to do, the correct action is to fix it - not to disable it on > > targets that rely on it for correct operation. > > Unfortunately, "fixing" -fstrict-volatile-bitfields to conform to the > AAPCS breaks conformance with the C11/C++11 standards, The global default is -fno-strict-volatile-bitfields. The flag was added specifically to force the compiler to always use the user-specified type when accessing bitfields, at least when it was physically possible. I don't see why there's a problem. Without the flag, you follow the standard. With the flag, you do what the user told you to do. It's up to the targets to decide which way the flag defaults if the user doesn't specify. For my targets, the default must be to do what the user told you to do, regardless of the standards, because the standards lead to hardware failure. > Meanwhile, while we're bickering about what the default should be, > ARM users (in particular) are stuck in a situation where GCC's > default behavior is to generate unaligned accesses that fault at > runtime or wrong code that silently truncates bitfields, Note that if the user defines a structure that intentionally mixes types in a hardware word, the compiler can't "do what it's told". It's still up to the user to write well-defined structures in those cases. Mixing packed, incomplete bitfields, and multiple types, (i.e. pr48784-1.c in that patch) is an example of a case where gcc can't do what the user asked, because what the user asked is nonsense. > and there is *no* command-line option or even build-time option they > can provide to make GCC generate code that is correct according to > the AAPCS. At the time I added -fstrict-volatile-bitfields, the ARM maintainers seemed to agree that the new functionality was what they needed. So, -fstrict-volatile-bitfields *is* that command line option, it's just either broken for them, or they're trying to do something not physically possible. > But, looking at it practically, I think the battle over > "correctness" was already over when the C and C++ standards > committees voted to specify this behavior in a particular way, and > that in time ABIs that specify some other behavior are going to be > either revised or considered archaic or obsolete. My problem isn't some arbitrary ABI, it's a hardware peripheral register that just can't be accessed in the wrong mode, because the peripheral won't work if you do that. Most MCU peripherals work this way. Just reading a byte or word outside the intended one could have real consequences in the hardware. > About the only way forward I can see is if the GCC steering > committee steps in with a general policy statement about what to do > when language standards conflict with a target ABI. I've not objected to fixing -fstrict-volatile-bitfields, or making the -fno-strict-volatile-bitfields case match the standard. I've only objected to breaking my targets by making that flag not the default.
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
> where in the C standard did you read the requirement that every bit > field must be complete? (This is a serious question). The spec doesn't say each field must be complete, but neither does it say that the structure must be as big as the type used. If you specify "int foo:1" then the compile is allowed to make the struct smaller than "int". > extern struct > { > volatile unsigned int b : 1; > } bf3; > > on my compiler this structure occupies 4 bytes. > and it is aligned at 4 bytes. > That is OK for me and AAPCS. On my target, the structure occupies 1 byte. I suspect gcc is rounding up to WORD_MODE, which is 4 bytes for you and 1 for me. If so, you're relying on a coincidence, not a standard. > But the access "bf3.b=1" is SI mode with Sandra's patch (part 1, which just > obeys the AAPCS and does nothing else) > and QI mode without this patch, which is just a BUG. > I am quite surprised how your target manages to avoid it? It doesn't, but I wouldn't expect it to, because IMHO that test is invalid - you have not given a precise enough test to expect consistent results. > It is as Sandra said, at least on ARM -fstrict-volatile-bitfields > does not function at all. And the C++11 memory model wins all the time. Are we talking about N2429? I read through the changes and it didn't preclude honoring the user's types. > > Looking through the tests, most of them combine "packed" with > > mismatched types. IMHO, those tests are invalid. > > I dont think so. They are simply packed. And volatile just says that > the value may be changed by a different thread. It has a great > impact on loop optimizations. Nothing you've said so far precludes honoring the user's types when the user gives you a consistent structure. Consider: typedef struct { unsigned char b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } Bits; extern volatile struct { Bits reg1; /* read status without resetting them */ Bits reg2; /* read status and atomically reset them */ } interrupt_handler; Without -fstrict-volatile-bitfields, gcc is allowed to use a 16-bit access to read reg1, but this causes an unexpected read to volatile reg2, which may have unintended consequences. The spec doesn't say the compiler *must* read reg2, it just *doesn't* say that it *can't*. The -fstrict-volatile-bitfields flag tells the compiler that it *can't*. IMHO this doesn't violate the spec, it just limits what the compiler can do within the spec. If ARM wants fast word-sized volatile bitfields, use "int" and structure your bitfields so that no "int" field overlaps a natural "int" boundary. When I added the option, I considered making it an error() to define a strict volatile bitfield that spanned the allowed boundary of the type specified, but I figured that would be too much. > > I've not objected to fixing -fstrict-volatile-bitfields, or making the > > -fno-strict-volatile-bitfields case match the standard. I've only > > objected to breaking my targets by making that flag not the default. > > Fine. Why cant we just get this fixed? Dunno. I'm only opposing the patch that disabled it on my targets.
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
> At least on ARM, you can e.g. have a non-bit-field "char" that occupies > part of the same 4-byte unit as an "int" bit-field. Ok, "when the user doesn't give the compiler conflicting requirements." (which is why I contemplated making those conflicts errors at first) I'm a big fan of blaming the user when they mix things together and expect the compiler to read their mind.
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
I'm starting from an MCU that doesn't work right if GCC doesn't do what the user tells GCC to do. I added -fstrict-volatile-bitfields to tell gcc that it needs to be more strict than the standard allows for bitfield access, because without that flag, there's no way to force gcc to use a specific access width on bitfields. When I added that flag, some ARM folks chose to enable it in their target, because they felt they needed it. If different ARM folks feel otherwise, that's a target problem. If the user tells gcc that a particular 32-bit memory location should be treated as both a char and a long, then gcc has been given inconsistent information. The spec says it can do what it wants to access that memory, and it does. If the user tells gcc that a particular 16-bit memory location consists of 16-bits worth of "unsigned short", and the user has told gcc that it needs to be strict about accessing that field in the type specified, and gcc uses a 32-bit access anyway, gcc is wrong. I will agree with you 100% that gcc can do whatever the spec allows if the user does NOT specify -fstrict-volatile-bitfields, but the flag is there to tell gcc that the user needs stricter control than the spec demands. If the user uses that flag, *and* gives gcc information that is inconsistent with the use of that flag, then the user is wrong. I note that you assume GNU/Linux is involved, perhaps that's part of the problem. Maybe the Linux kernel needs gcc to ignore its bitfield types, but other ARM firmware may have other requirements. If you and the other ARM maintainers want to argue over whether -fstrict-volatile-bitfields is enabled by default for the ARM target, go for it. Just leave my targets alone. > where those semantics contradict the semantics of ISO C. Where in the spec does it say that a compiler MUST access an "unsigned short" bitfield with a 32-bit access? I've seen places where it says the compiler MAY or MIGHT do it, but not MUST.
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
> We use the container mode where possible. > It is always possible for well-formed bit-fields. This is the only part I really need. > If necessary the user has to add anonymous bit field members, or > convert normal members to bit-fields. IIRC I added code to support normal members as well, the "bitfields" part of the option name is not entirely accurate. > But when the bit field is conflict with the either the hardware's alignment > requirements or with the C++11 memory model, we follow the latter. Fine with me. > 2. we allow unaligned packed data, but we may use multiple accesses > for a single read/write op. Also in this case: no data store races > outside the member. We should note that volatile != atomic in these cases. Perhaps a warning would be in order? > Example: > > struct { > volatile int a : 24; > volatile char b; > }; > > This is not well-formed, and -fstrict-volatile-bitfields will have > no effect on it. I agree this isn't well-formed, but -fs-v-b could still make a best effort since none of the fields *individually* span a natural boundary. > The user has to re-write this structure to: > > struct { > volatile int a : 24; > volatile char b : 8; > }; More accurate would be these: struct { volatile int a : 24; volatile int b : 8;/* overlap, should be the same type */ }; struct { volatile int a : 24; volatile int : 0; volatile char b; /* no overlap, make the padding explicit */ };
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
> What I would suggest is to have a -fgnu-strict-volatile-bit-fields Why a new option? The -fstrict-volatile-bitfields option is already GCC-specific, and I think it can do what you want anyway.
Re: Fwd: [PATCH] Add gdb/gdb-index.h to gcc tree.
I'm not sure either, but if it's been approved in gdb and you're willing to cede control of it to gcc's policies, I'm OK with it. Note that this will be a new directory in gcc, and I think the automerge scripts will automatically pick it up. Which means, after committing it, any future changes must go to gcc's repo first (if even by a few seconds ;)
Re: [PATCH] reimplement -fstrict-volatile-bitfields v4, part 2/2
> have an option for true AAPCS compliance, which will > be allowed to break the C++11 memory model and > And an option that addresses your requirements, > which will _not_ break the C++11 memory model So the problem isn't that what *I* need conflicts with C++11, it's that what AAPCS needs conflicts?
Re: [libiberty] Fix testsuite/test-expandargv.c
Ok.
Re: question about register pairs
Yup, my registers are smaller than Pmode. This is what I ended up with... Some notes: I lie to gcc and tell it that $fp (reg 22) is two bytes when it's really one. None of the register classes have reg 23 (used for the upper half of $fp) in them. Reg 23 is also listed as being two bytes, to keep the register pairing logic in reload in sync for registers above $fp (otherwise it only checks odd registers afer $fp). Does this all make sense? Index: reload.c === --- reload.c(revision 203733) +++ reload.c(working copy) @@ -723,13 +723,15 @@ find_valid_class_1 (enum machine_mode ou unsigned int best_size = 0; int cost; for (rclass = 1; rclass < N_REG_CLASSES; rclass++) { int bad = 0; - for (regno = 0; regno < FIRST_PSEUDO_REGISTER && !bad; regno++) + for (regno = 0; + regno < FIRST_PSEUDO_REGISTER && !bad; + regno += HARD_REGNO_NREGS (regno, mode)) { if (in_hard_reg_set_p (reg_class_contents[rclass], mode, regno) && !HARD_REGNO_MODE_OK (regno, mode)) bad = 1; } Index: config/rl78/rl78.h === --- config/rl78/rl78.h (revision 203733) +++ config/rl78/rl78.h (working copy) @@ -242,12 +242,14 @@ enum reg_class "V_REGS",\ "GR_REGS", \ "PSWREG",\ "ALL_REGS" \ } +/* Note that no class may include the second register in $fp, because + we treat $fp as a single HImode register. */ #define REG_CLASS_CONTENTS \ { \ { 0x, 0x }, /* No registers, */\ { 0x0001, 0x }, \ { 0x0002, 0x }, \ { 0x0003, 0x }, \ Index: config/rl78/rl78.c === --- config/rl78/rl78.c (revision 203733) +++ config/rl78/rl78.c (working copy) @@ -321,19 +321,21 @@ rl78_option_override (void) for (i = 24; i < 32; i++) fixed_regs[i] = 0; } } /* Most registers are 8 bits. Some are 16 bits because, for example, - gcc doesn't like dealing with $FP as a register pair. This table - maps register numbers to size in bytes. */ + gcc doesn't like dealing with $FP as a register pair (the second + half of $fp is also 2 to keep reload happy wrt register pairs, but + no register class includes it). This table maps register numbers + to size in bytes. */ static const int register_sizes[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1 }; /* Predicates used in the MD patterns. This one is true when virtual insns may be matched, which typically means before (or during) the
Re: question about register pairs
> > Some notes: I lie to gcc and tell it that $fp (reg 22) is two bytes > > when it's really one. > > Well, it's not really a lie if you map hardware registers 22 and 23 to > a single register for the purposes of gcc internals. Yeah, I'm basically making those two registers into a permanent bigger register. > Although it does make some other things more awkward, e.g. when you > copy fp, and this gets split so you have an insn that copies the > highpart of fp to another register. Not a problem, the chip can copy the whole $fp in one insn. Registers are only 8 bits on this chip. > Seeing the patched code in its entirety like this, I notice that we > would use HARD_REGNO_NREGS for a regno that's not ok for the mode. The core problem is that gcc has no way of dealing with register pairs as real registers - the second halves are still registers, still need to be in the reg class, still need _NREGS() values, etc. There's no way to tell gcc that a "register" is a set of (for example) N registers starting at 3, 5, 9, 12, or 14. > That can be avoided if we put a break into the if. And then the > !bad term in the loop condition becomes redundant. The problem I had to solve was to re-synchronize the counter with the even-numbered register. The naive patch counted even registers up to $fp, then checked odd (invalid) registers after that. The only other way I can think to "solve" this problem is to add a VALID_STARTING_REG(reg,mode) macro, but that would require changes all over the core code.
Re: Using gen_int_mode instead of GEN_INT minor testsuite fallout on MIPS
Who needs to approve this? THe target maintainers, or some global maintainer?
Re: Apply attribute returns_nonnull in libiberty
Sure, go for it.
[rx] fix no-argument builtins
Apparently, there's a subtle difference between "function that takes no argument" and "function that takes void" :-P Committed. * config/rx/rx.c (ADD_RX_BUILTIN0): New macro, used for builtins that take no arguments. Index: config/rx/rx.c === --- config/rx/rx.c (revision 204234) +++ config/rx/rx.c (working copy) @@ -2270,12 +2270,20 @@ enum rx_builtin static GTY(()) tree rx_builtins[(int) RX_BUILTIN_max]; static void rx_init_builtins (void) { +#define ADD_RX_BUILTIN0(UC_NAME, LC_NAME, RET_TYPE)\ + rx_builtins[RX_BUILTIN_##UC_NAME] = \ + add_builtin_function ("__builtin_rx_" LC_NAME, \ + build_function_type_list (RET_TYPE##_type_node, \ + NULL_TREE), \ + RX_BUILTIN_##UC_NAME, \ + BUILT_IN_MD, NULL, NULL_TREE) + #define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE) \ rx_builtins[RX_BUILTIN_##UC_NAME] = \ add_builtin_function ("__builtin_rx_" LC_NAME, \ build_function_type_list (RET_TYPE##_type_node, \ ARG_TYPE##_type_node, \ NULL_TREE), \ @@ -2300,32 +2308,32 @@ rx_init_builtins (void) ARG_TYPE2##_type_node,\ ARG_TYPE3##_type_node,\ NULL_TREE), \ RX_BUILTIN_##UC_NAME, \ BUILT_IN_MD, NULL, NULL_TREE) - ADD_RX_BUILTIN1 (BRK, "brk", void, void); + ADD_RX_BUILTIN0 (BRK, "brk", void); ADD_RX_BUILTIN1 (CLRPSW, "clrpsw", void, integer); ADD_RX_BUILTIN1 (SETPSW, "setpsw", void, integer); ADD_RX_BUILTIN1 (INT, "int", void, integer); ADD_RX_BUILTIN2 (MACHI, "machi", void, intSI, intSI); ADD_RX_BUILTIN2 (MACLO, "maclo", void, intSI, intSI); ADD_RX_BUILTIN2 (MULHI, "mulhi", void, intSI, intSI); ADD_RX_BUILTIN2 (MULLO, "mullo", void, intSI, intSI); - ADD_RX_BUILTIN1 (MVFACHI, "mvfachi", intSI, void); - ADD_RX_BUILTIN1 (MVFACMI, "mvfacmi", intSI, void); + ADD_RX_BUILTIN0 (MVFACHI, "mvfachi", intSI); + ADD_RX_BUILTIN0 (MVFACMI, "mvfacmi", intSI); ADD_RX_BUILTIN1 (MVTACHI, "mvtachi", void, intSI); ADD_RX_BUILTIN1 (MVTACLO, "mvtaclo", void, intSI); - ADD_RX_BUILTIN1 (RMPA,"rmpa",void, void); + ADD_RX_BUILTIN0 (RMPA,"rmpa",void); ADD_RX_BUILTIN1 (MVFC,"mvfc",intSI, integer); ADD_RX_BUILTIN2 (MVTC,"mvtc",void, integer, integer); ADD_RX_BUILTIN1 (MVTIPL, "mvtipl", void, integer); ADD_RX_BUILTIN1 (RACW,"racw",void, integer); ADD_RX_BUILTIN1 (ROUND, "round", intSI, float); ADD_RX_BUILTIN1 (REVW,"revw",intSI, intSI); - ADD_RX_BUILTIN1 (WAIT,"wait",void, void); + ADD_RX_BUILTIN0 (WAIT,"wait",void); } /* Return the RX builtin for CODE. */ static tree rx_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
Re: question about register pairs
> Seeing the patched code in its entirety like this, I notice that we > would use HARD_REGNO_NREGS for a regno that's not ok for the mode. > That can be avoided if we put a break into the if. And then the > !bad term in the loop condition becomes redundant. Although the > HARD_REGNO_NREGS definition in tm.texi says that HARD_REGNO_NREGS > must never return zero. That wouldn't be technically violated with > an assert, but I suppose the spirit of the text is that the macro > should return always a non-positive value, so I suppose this use of > HARD_REGNO_MODE_OK is not actually a problem. Alternately, we could assume that if there's a gap in the register class, that the next register that *is* in the register class is a legitimate register pair? I can't think of any reason why you'd do otherwise, and certainly if it *isn't* the first of a pair, there's no way to pass the test anyway. Then we'd just increment by HARD_REGNO_NREGS *or* 1, depending on whether the register is in the set or not, and break out of the test for the first reg that's in the set but not valid for the mode, so no need to increment after that case.
msp430: fix function type declarations
Minor bug, fixed, committed. * config/msp430/msp430.c (msp430_start_function): Add function type. 2016-02-04 Uros Bizjak Index: config/msp430/msp430.c === --- config/msp430/msp430.c (revision 233155) +++ config/msp430/msp430.c (working copy) @@ -2108,12 +2108,13 @@ msp430_start_function (FILE *file, const fputc ('\n', file); fputc ('\t', file); } } switch_to_section (function_section (decl)); + ASM_OUTPUT_TYPE_DIRECTIVE(file, name, "function"); ASM_OUTPUT_FUNCTION_LABEL (file, name, decl); } static const char * const lower_prefix = ".lower"; static const char * const upper_prefix = ".upper"; static const char * const either_prefix = ".either";
Re: RFA: MEP: Add newlib-stdint.h to tm_file.
Ok.
Re: RFA: MEP: Add newlib-stdint.h to tm_file.
Note, though, that I'm in the process of deprecating mep...
Re: RFA: MEP: Add newlib-stdint.h to tm_file.
> Can we make that official? 64402, 49401 & 24998 go away when MEP is > deprecated. We can, what's the next step? I announced intent in Dec, nobody commented or stepped up to take it.
Re: RFA: MEP: Add newlib-stdint.h to tm_file.
> Write a patch to deprecate it in config.gcc (search for openbsd2 to help > you find the right spot) and an update to the gcc6 webpage. How's this? Index: htdocs/gcc-6/changes.html === RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-6/changes.html,v retrieving revision 1.64 diff -p -U 5 -r1.64 changes.html --- htdocs/gcc-6/changes.html 26 Feb 2016 14:51:16 - 1.64 +++ htdocs/gcc-6/changes.html 1 Mar 2016 19:39:19 - @@ -424,10 +424,17 @@ within strings: the -march=znver1 and -mtune=znver1 options. +MeP + +Support for the MeP (mep-elf) architecture has been + deprecated and will be removed in a future GCC release. + + + MSP430 The MSP430 compiler now has the ability to automatically distribute code and data between low memory (addresses below 64K) and high memory. This only applies to parts that actually have both memory regions and only if the Index: contrib/config-list.mk === --- contrib/config-list.mk (revision 233861) +++ contrib/config-list.mk (working copy) @@ -36,13 +36,13 @@ LIST = aarch64-elf aarch64-linux-gnu aar i686-wrs-vxworksae \ i686-cygwinOPT-enable-threads=yes i686-mingw32crt ia64-elf \ ia64-freebsd6 ia64-linux ia64-hpux ia64-hp-vms iq2000-elf lm32-elf \ lm32-rtems lm32-uclinux m32c-rtems m32c-elf m32r-elf m32rle-elf m32r-rtems \ m32r-linux m32rle-linux m68k-elf m68k-netbsdelf \ m68k-openbsd m68k-uclinux m68k-linux m68k-rtems \ - mcore-elf mep-elf microblaze-linux microblaze-elf \ + mcore-elf mep-elfOPT-enable-obsolete microblaze-linux microblaze-elf \ mips-netbsd \ mips64el-st-linux-gnu mips64octeon-linux mipsisa64r2-linux \ mipsisa32r2-linux-gnu mipsisa64r2-sde-elf mipsisa32-elfoabi \ mipsisa64-elfoabi mipsisa64r2el-elf mipsisa64sr71k-elf mipsisa64sb1-elf \ mipsel-elf mips64-elf mips64vr-elf mips64orion-elf mips-rtems \ mips-wrs-vxworks mipstx39-elf mmix-knuth-mmixware mn10300-elf moxie-elf \ Index: gcc/config.gcc === --- gcc/config.gcc (revision 233861) +++ gcc/config.gcc (working copy) @@ -240,12 +240,13 @@ case ${target} in | *-knetbsd-* \ | *-openbsd2* \ | *-openbsd3* \ | avr-*rtems* \ | h8300-*rtems* \ | m32r-*rtems*\ + | mep-* \ ) if test "x$enable_obsolete" != xyes; then echo "*** Configuration ${target} is obsolete." >&2 echo "*** Specify --enable-obsolete to build it anyway." >&2 echo "*** Support will be REMOVED in the next major release of GCC," >&2 echo "*** unless a maintainer comes forward." >&2
Re: RFA: MEP: Add newlib-stdint.h to tm_file.
> Looks good to me. Obviously you'll need appropriate ChangeLogs. OK > with the ChangeLogs added. Done.
Re: wide-int, msp430
Ok > * config/msp430/msp430.c > (msp430_attr): Use wide-int interfaces. > > > diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c > index daff4ae..e3f6712 100644 > --- a/gcc/config/msp430/msp430.c > +++ b/gcc/config/msp430/msp430.c > @@ -1085,7 +1085,7 @@ msp430_attr (tree * node, > break; > > case INTEGER_CST: > - if (TREE_INT_CST_LOW (value) > 31) > + if (wi::gtu_p (value, 31)) > /* Allow the attribute to be added - the linker script > being used may still recognise this value. */ > warning (OPT_Wattributes, >
Re: Two build != host fixes
Alan Modra writes: > Bootstrapped etc. powerpc64-linux. OK mainline and 4.8 branch? > > * configure.ac (BUILD_CXXFLAGS) Don't use ALL_CXXFLAGS for > build != host. > : Clear GMPINC. Don't bother > saving CFLAGS. > * configure: Regenerate. Ok for mainline, up to the 4.8 release manager if it's OK there but it looks OK to me. Do we need to add a CXXFLAGS= to that configure too?
Re: [trunk]: Patch to move BITS_PER_UNIT to be available for genmodes.c
The m32c part is OK.
[msp430] support volatile mems in more patterns
I went through all the patterns in the msp430 backend and converted all those that are volatile-safe to allow volatile MEM operands. Committed. * config/msp430/msp430.md (movqi): replace general_operand with msp_general_operand and nonimmediate_operand with msp_nonimmediate_operand to allow volatile operands. (movhi): Likewise. (movpsi): Likewise. (addpsi3): Likewise. (addhi3): Likewise. (addhi3_cy): Likewise. (addchi4_cy): Likewise. (xor3): Likewise. (ome_cmpl2): Likewise. (extendqihi2): Likewise. (zero_extendqihi2): Likewise. (zero_extendhipsi2): Likewise. (truncpsihi2): Likewise. (srai_1): Likewise. Index: gcc/config/msp430/msp430.md === --- gcc/config/msp430/msp430.md (revision 205974) +++ gcc/config/msp430/msp430.md (working copy) @@ -172,8 +172,8 @@ ) (define_insn "movqi" - [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm") - (match_operand:QI 1 "general_operand" "riYs,rmi"))] + [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm") + (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))] "" "@ MOV.B\t%1, %0 @@ -181,8 +181,8 @@ ) (define_insn "movhi" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm") - (match_operand:HI 1 "general_operand" "riYs,rmi"))] + [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm") + (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))] "" "@ MOV.W\t%1, %0 @@ -211,8 +211,8 @@ ;; Some MOVX.A cases can be done with MOVA, this is only a few of them. (define_insn "movpsi" - [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,Ya,rm") - (match_operand:PSI 1 "general_operand" "riYa,r,rmi"))] + [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm") + (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))] "" "@ MOV%A0\t%1, %0 @@ -237,9 +237,9 @@ ;; Math (define_insn "addpsi3" - [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,rm") - (plus:PSI (match_operand:PSI 1 "nonimmediate_operand" "%0,0") - (match_operand:PSI 2 "general_operand" "rLs,rmi")))] + [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,rm") + (plus:PSI (match_operand:PSI 1 "msp_nonimmediate_operand" "%0,0") + (match_operand:PSI 2 "msp_general_operand" "rLs,rmi")))] "" "@ ADDA\t%2, %0 @@ -247,9 +247,9 @@ ) (define_insn "addqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") -(match_operand:QI 2 "general_operand" "riYs,rmi")))] + [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm") + (plus:QI (match_operand:QI 1 "msp_nonimmediate_operand" "%0,0") +(match_operand:QI 2 "msp_general_operand" "riYs,rmi")))] "" "@ ADD.B\t%2, %0 @@ -257,9 +257,9 @@ ) (define_insn "addhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "riYs,rmi")))] + [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm") + (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0") + (match_operand:HI 2 "msp_general_operand" "riYs,rmi")))] "" "@ ADD.W\t%2, %0 @@ -316,9 +316,9 @@ ; that are not single_set() very well. (define_insn "addhi3_cy" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") -(match_operand:HI 2 "general_operand" "r,rm"))) + [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm") + (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0") +(match_operand:HI 2 "msp_general_operand" "r,rm"))) (set (reg:BI CARRY) (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) (zero_extend:SI (match_dup 2))) @@ -347,9 +347,9 @@ ; Version of addhi that adds the carry, for SImode adds. (define_insn "addchi4_cy" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") - (plus:HI (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rmi")) + [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm") + (plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0") + (match_operand:HI 2 "msp_general_operand" "ri,rmi")) (zero_extend:HI (reg:BI CARRY ] "" @@ -487,9 +487,9 @@ ) (define_insn "xor3" - [(set (match_operand:QHI 0 "nonimmediate_operand" "=rYs,rm") - (xor:QHI (match_operan
[rl78] fix constant in pattern
This was causing the final pattern to not match. Committed. * config/rl78/rl78-expand.md (one_cmplqi2): Make constant signed. Index: config/rl78/rl78-expand.md === --- config/rl78/rl78-expand.md (revision 205980) +++ config/rl78/rl78-expand.md (working copy) @@ -174,13 +174,13 @@ DONE;" ) (define_expand "one_cmplqi2" [(set (match_operand:QI 0 "nonimmediate_operand") (xor:QI (match_operand:QI 1 "general_operand") - (const_int 255))) + (const_int -1))) ] "" "if (rl78_force_nonfar_2 (operands, gen_one_cmplqi2)) DONE;" )
[msp430] fix call-via-sp and epilogue helper patterns
The call change avoids a problem on hardware where indirect calls that use SP as a base register don't seem to do what you expect. The 'J' one fixes a link-time error wrt epilogue helper functions. Committed. * config/msp430/msp430.md (call_internal): Don't allow memory references with SP as the base register. (call_value_internal): Likewise. * config/msp430/constraints.md (Yc): New. For memory references that don't use SP as a base register. * config/msp430/msp430.c (msp430_print_operand): Add 'J' to mean "an integer without a # prefix" * config/msp430/msp430.md (epilogue_helper): Use it. Index: config/msp430/msp430.md === --- config/msp430/msp430.md (revision 206582) +++ config/msp430/msp430.md (working copy) @@ -917,13 +917,13 @@ ) (define_insn "epilogue_helper" [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)] "" - "BR%Q0\t#__mspabi_func_epilog_%0" + "BR%Q0\t#__mspabi_func_epilog_%J0" ) (define_insn "prologue_start_marker" [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)] "" @@ -950,13 +950,13 @@ (match_operand 1 ""))] "" "" ) (define_insn "call_internal" - [(call (mem:HI (match_operand 0 "general_operand" "rmi")) + [(call (mem:HI (match_operand 0 "general_operand" "rYci")) (match_operand 1 ""))] "" "CALL%Q0\t%0" ) (define_expand "call_value" @@ -966,13 +966,13 @@ "" "" ) (define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=r") - (call (mem:HI (match_operand 1 "general_operand" "rmi")) + (call (mem:HI (match_operand 1 "general_operand" "rYci")) (match_operand 2 "")))] "" "CALL%Q0\t%1" ) (define_insn "msp_return" Index: config/msp430/constraints.md === --- config/msp430/constraints.md(revision 206582) +++ config/msp430/constraints.md(working copy) @@ -67,6 +67,19 @@ (and (match_code "plus" "0") (and (match_code "reg" "00") (match_test ("CONST_INT_P (XEXP (XEXP (op, 0), 1))")) (match_test ("IN_RANGE (INTVAL (XEXP (XEXP (op, 0), 1)), -1 << 15, (1 << 15)-1)" (match_code "reg" "0") ))) + +(define_constraint "Yc" + "Memory reference, for CALL - we can't use SP" + (and (match_code "mem") + (match_code "mem" "0") + (not (ior +(and (match_code "plus" "00") + (and (match_code "reg" "000") + (match_test ("REGNO (XEXP (XEXP (op, 0), 0)) != SP_REGNO" +(and (match_code "reg" "0") + (match_test ("REGNO (XEXP (XEXP (op, 0), 0)) != SP_REGNO"))) + + Index: config/msp430/msp430.c === --- config/msp430/msp430.c (revision 206582) +++ config/msp430/msp430.c (working copy) @@ -1917,12 +1917,13 @@ msp430_print_operand_addr (FILE * file, /* A low 16-bits of int/lower of register pair B high 16-bits of int/higher of register pair C bits 32-47 of a 64-bit value/reg 3 of a DImode value D bits 48-63 of a 64-bit value/reg 4 of a DImode value H like %B (for backwards compatibility) I inverse of value + J an integer without a # prefix L like %A (for backwards compatibility) O offset of the top of the stack Q like X but generates an A postfix R inverse of condition code, unsigned. X X instruction postfix in large mode Y value - 4 @@ -1947,13 +1948,12 @@ msp430_print_operand (FILE * file, rtx o return; case 'Y': gcc_assert (CONST_INT_P (op)); /* Print the constant value, less four. */ fprintf (file, "#%ld", INTVAL (op) - 4); return; - /* case 'D': used for "decimal without '#'" */ case 'I': if (GET_CODE (op) == CONST_INT) { /* Inverse of constants */ int i = INTVAL (op); fprintf (file, "%d", ~i); @@ -2107,12 +2107,14 @@ msp430_print_operand (FILE * file, rtx o because builtins are expanded before the frame layout is determined. */ fprintf (file, "%d", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) - 2); return; +case 'J': + gcc_assert (GET_CODE (op) == CONST_INT); case 0: break; default: output_operand_lossage ("invalid operand prefix"); return; }
rx: remove some asserts
Nick, There is no need to assert these just to say "not supported" and gcc may rarely generate addresses from valid code which trigger these asserts. Ok? Index: gcc/config/rx/rx.c === --- gcc/config/rx/rx.c (revision 225533) +++ gcc/config/rx/rx.c (working copy) @@ -367,14 +367,12 @@ rx_mode_dependent_address_p (const_rtx a case SYMBOL_REF: case LABEL_REF: return true; case MULT: - gcc_assert (REG_P (XEXP (addr, 0))); - gcc_assert (CONST_INT_P (XEXP (addr, 1))); /* REG+REG*SCALE is always mode dependent. */ return true; default: /* Not recognized, so treat as mode dependent. */ return true;
[rl78] extend set1/clr1 operands
Minor tweak to allow more addressing modes. Committed. * config/rl78/rl78-real.md (andqi3_real): Expand operands for clr1. (iorqi3_real): Likewise for set1. Index: config/rl78/rl78-real.md === --- config/rl78/rl78-real.md(revision 226022) +++ config/rl78/rl78-real.md(working copy) @@ -191,13 +191,13 @@ (zero_extend:HI (match_operand:QI 2 "general_operand" "x"] "rl78_real_insns_ok () && !TARGET_G10" "mulu\t%2" ) (define_insn "*andqi3_real" - [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=Wsf,A,R,vWsa") + [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=WsfWsaWhlWab,A,R,vWsa") (and:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0") (match_operand:QI 2 "rl78_general_operand" "IBqi,iRvWabWhbWh1Whl,A,i"))) ] "rl78_real_insns_ok ()" "@ clr1\t%0.%B2 @@ -205,13 +205,13 @@ and\t%0, %2 and\t%0, %2" [(set_attr "update_Z" "*,update_Z,update_Z,update_Z")] ) (define_insn "*iorqi3_real" - [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=Wsf,A,R,vWsa") + [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=WsfWsaWhlWab,A,R,vWsa") (ior:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0") (match_operand:QI 2 "rl78_general_operand" "Ibqi,iRvWabWhbWh1Whl,A,i"))) ] "rl78_real_insns_ok ()" "@ set1\t%0.%B2
libstdc++: more __intN tweaks
Another place where a list of "all" types are explicitly listed, and the __intN types need to be included, and elsewhere protection against errors [-Wnarrowing] on targets that have small size_t. Ok? * include/bits/functional_hash.h: Add specializations for __intN types. * include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp (__gnu_pbds): Guard against values that might exceed size_t's precision. Index: libstdc++-v3/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp === --- libstdc++-v3/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp (revision 226081) +++ libstdc++-v3/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp (working copy) @@ -267,36 +267,45 @@ namespace __gnu_pbds /* 18*/ 3571ul, /* 19*/ 5777ul, /* 20*/ 9349ul, /* 21*/ 15126ul, /* 22*/ 24476ul, /* 23*/ 39602ul, - /* 24*/ 64079ul, + /* 24*/ 64079ul +#if __SIZE_MAX__ > 0xul + , /* 25*/ 103681ul, /* 26*/ 167761ul, /* 27*/ 271442ul, /* 28*/ 439204ul, - /* 29*/ 710646ul, + /* 29*/ 710646ul +#if __SIZE_MAX__ > 0xful + , /* 30*/ 1149851ul, /* 31*/ 1860497ul, /* 32*/ 3010349ul, /* 33*/ 4870846ul, /* 34*/ 7881196ul, - /* 35*/ 12752042ul, + /* 35*/ 12752042ul +#if __SIZE_MAX__ > 0xfful + , /* 36*/ 20633239ul, /* 37*/ 33385282ul, /* 38*/ 54018521ul, /* 39*/ 87403803ul, /* 40*/ 141422324ul, /* 41*/ 228826127ul, /* 42*/ 370248451ul, /* 43*/ 599074578ul, /* 44*/ 969323029ul, /* 45*/ 1568397607ul, /* 46*/ 2537720636ul, /* 47*/ 4106118243ul +#endif +#endif +#endif /* Pot's good, let's play */ }; #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) Index: libstdc++-v3/include/bits/functional_hash.h === --- libstdc++-v3/include/bits/functional_hash.h (revision 226081) +++ libstdc++-v3/include/bits/functional_hash.h (working copy) @@ -118,12 +118,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Explicit specialization for unsigned long. _Cxx_hashtable_define_trivial_hash(unsigned long) /// Explicit specialization for unsigned long long. _Cxx_hashtable_define_trivial_hash(unsigned long long) +#ifdef __GLIBCXX_TYPE_INT_N_0 + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0) + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0 unsigned) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_1 + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1) + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1 unsigned) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_2 + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2) + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2 unsigned) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_3 + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3) + _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3 unsigned) +#endif + #undef _Cxx_hashtable_define_trivial_hash struct _Hash_impl { static size_t hash(const void* __ptr, size_t __clength,
[msp430] minor optimizations and tweaks
As indicated. Committed. * config/msp430/t-msp430 (MULTILIB_DIRNAMES): Remove trailing slashes. * config/msp430/msp430.md (ashlhi3): Optimize shifts of subregs. (ashrhi3): Likewise. (lshrhi3): Likewise. (movhi): Take advantage of zero-extend to load small constants. (movpsi): Likewise. (and3): Likewise. (zero_extendqihi2): Likewise. (zero_extendqisi2): New. * config/msp430/constraints.md (N,O): New. * config/msp430/msp430.h (WORD_REGISTER_OPERATIONS): Define. Index: config/msp430/msp430.md === --- config/msp430/msp430.md (revision 226084) +++ config/msp430/msp430.md (working copy) @@ -196,16 +196,17 @@ "@ MOV.B\t%1, %0 MOV%X0.B\t%1, %0" ) (define_insn "movhi" - [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm") - (match_operand:HI 1 "msp_general_operand" "riYs,rmi"))] + [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rYs,rm") + (match_operand:HI 1 "msp_general_operand" "N,riYs,rmi"))] "" "@ + MOV.B\t%1, %0 MOV.W\t%1, %0 MOV%X0.W\t%1, %0" ) (define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand") @@ -239,16 +240,18 @@ (match_operand:HI 5 "general_operand"))] "msp430_split_movsi (operands);" ) ;; 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"))] + [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,r,r,Ya,rm") + (match_operand:PSI 1 "msp_general_operand" "N,O,riYa,r,rmi"))] "" "@ + MOV.B\t%1, %0 + MOV.W\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 @@ -497,17 +500,18 @@ "@ BIC%x0%b0\t%1, %0 BIC%X0%b0\t%1, %0" ) (define_insn "and3" - [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") - (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0") -(match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))] + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=r,rYs,rm") + (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0,0") +(match_operand:QHI 2 "msp_general_operand" "N,riYs,rmi")))] "" "@ + AND%x0.B\t%2, %0 AND%x0%b0\t%2, %0 AND%X0%b0\t%2, %0" ) (define_insn "ior3" [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") @@ -546,17 +550,19 @@ "@ SXT%X0\t%0 SXT%X0\t%0" ) (define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m") - (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))] + [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,r,r,m") + (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,rYs,m,0")))] "" "@ AND\t#0xff, %0 + MOV.B\t%1, %0 + MOV%X0.B\t%1, %0 AND%X0\t#0xff, %0" ) ;; Eliminate extraneous zero-extends mysteriously created by gcc. (define_peephole2 [(set (match_operand:HI 0 "register_operand") @@ -599,12 +605,20 @@ ) ;; 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_extendqisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r") + (zero_extend:SI (subreg:HI (match_operand:QI 1 "nonimmediate_operand" "rm") 0)))] + "msp430x" + "MOV.B\t%1,%L0 { CLR\t%H0" +) + (define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")))] "msp430x" "@ MOV.W\t#0,%H0 @@ -731,12 +745,15 @@ (define_expand "ashlhi3" [(set (match_operand:HI0 "nonimmediate_operand") (ashift:HI (match_operand:HI 1 "general_operand") (match_operand:HI 2 "general_operand")))] "" { +if (GET_CODE (operands[1]) == SUBREG +&& REG_P (XEXP (operands[1], 0))) + operands[1] = force_reg (HImode, operands[1]); if (msp430x && REG_P (operands[0]) && REG_P (operands[1]) && CONST_INT_P (operands[2])) emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2])); else @@ -797,12 +814,15 @@ (define_expand "ashrhi3" [(set (match_operand:HI 0 "nonimmediate_operand") (ashiftrt:HI (match_operand:HI 1 "general_operand") (match_operand:HI 2 "general_operand")))] "" { +if (GET_CODE (operands[1]) == SUBREG +&& REG_P (XEXP (operands[1], 0))) +
Re: libstdc++: more __intN tweaks
> > * include/bits/functional_hash.h: Add specializations for __intN > > types. > > > > * include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp (__gnu_pbds): > > Guard against values that might exceed size_t's precision. > > Yes, OK - thanks. Committed. Thanks!
Re: RFA: RL78: Add an optimization to the addsi3 pattern
Ok, but please don't put non-public issue numbers in the comments.
Re: RFA: RL78: Remove far operand optimization in rl78_force_nonfar_3
This is OK, but note that it prevents some operations like: __far int i; foo() { i ++; } from being implemented with a minimum set of opcodes. This might be particularly troublesome for volatile far things.
Re: RFA: RL78: Fix multiply costs when optimizing for size
> OK to apply ? Ok. Thanks! > gcc/ChangeLog > 2015-08-05 Nick Clifton > > * config/rl78/rl78.c (rl78_rtx_costs): Treat MULT insns as cheap > if optimizing for size. > > Index: gcc/config/rl78/rl78.c > === > RCS file: /cvs/cvsfiles/gnupro/gcc/config/rl78/rl78.c,v > retrieving revision 1.12.6.15 > diff -u -3 -p -r1.12.6.15 rl78.c > --- gcc/config/rl78/rl78.c29 Jul 2015 12:24:04 - 1.12.6.15 > +++ gcc/config/rl78/rl78.c30 Jul 2015 15:20:10 - > @@ -4161,7 +4161,9 @@ static bool rl78_rtx_costs (rtx x, >switch (code) > { > case MULT: > - if (RL78_MUL_G14) > + if (! speed) > + * total = COSTS_N_INSNS (5); > + else if (RL78_MUL_G14) > *total = COSTS_N_INSNS (14); > else if (RL78_MUL_G13) > *total = COSTS_N_INSNS (29); >
Re: [PATCH: RL78] libgcc fixes for divmodsi, divmodhi and divmodqi
> This is regression tested for RL78 -msim. Please let me know if it is > OK to commit. I've committed this patch for you. Thanks! > Best Regards, > Kaushik > > Changelog: > 2015-08-21 Kaushik Phatak > > * config/rl78/divmodqi.S: Return 0x00 by default for div by 0. > * config/rl78/divmodsi.S: Update return register to r8. > * config/rl78/divmodhi.S: Update return register to r8,r9. > Branch to main_loop_done_himode to pop registers before return.
Re: [PATCH] replace BITS_PER_UNIT with __CHAR_BIT__ in target libs
> $subject as far as I am aware these are the same on all supported targets. The documentation for __CHAR_BIT__ says not to use it... @item __CHAR_BIT__ Defined to the number of bits used in the representation of the @code{char} data type. It exists to make the standard header given numerical limits work correctly. You should not use this macro directly; instead, include the appropriate headers. And the definition of BITS_PER_UNIT is more appropriate anyway: @item BITS_PER_UNIT The number of bits in an addressable storage unit (byte). If you do not define this, the default is 8. If a target had a sizeof(char) != 1, __CHAR_BIT__ and BITS_PER_UNIT would be different, and IMHO BITS_PER_UNIT is the one we want to use in the runtime, unless you're specifically talking about the "char" type: cpp_define_formatted (pfile, "__CHAR_BIT__=%u", TYPE_PRECISION (char_type_node));
Re: [RFA] Do not use libiberty's getpagesize on Android
> libiberty/ChangeLog: > > * configure.ac: Set AC_CV_FUNC_GETPAGESIZE to "yes" on > Android hosts. > * configure: Regenerate. > > OK to apply? Ok.
Re: [PATCH] ctype functions and signedness
> --- libiberty/pex-win32.c > +++ /tmp/cocci-output-25924-3a75ca-pex-win32.c > @@ -547,8 +547,8 @@ env_compare (const void *a_ptr, const vo > >do > { > - c1 = (unsigned char) tolower (*a++); > - c2 = (unsigned char) tolower (*b++); > + c1 = (unsigned char) tolower ((unsigned char)*a++); > + c2 = (unsigned char) tolower ((unsigned char)*b++); > >if (c1 == '=') > c1 = '\0'; Since the only use of a and b in this function are to pass to tolower, changing the type of a and b to unsigned char (and updating the casts where they're initialized) would make more sense.
msp430: fix alignment in multiply
Minor fix, committed. 2015-11-19 DJ Delorie * config/msp430/lib2hw_mul.S: Fix alignment. Index: libgcc/config/msp430/lib2hw_mul.S === --- libgcc/config/msp430/lib2hw_mul.S (revision 230632) +++ libgcc/config/msp430/lib2hw_mul.S (working copy) @@ -19,13 +19,13 @@ ; a copy of the GCC Runtime Library Exception along with this program; ; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ; <http://www.gnu.org/licenses/>. .macro start_func name .pushsection .text.\name,"ax",@progbits - .align 2 + .p2align 1 .global \name .type \name , @function \name: PUSH.W sr ; Save current interrupt state DINT; Disable interrupts NOP ; Account for latency
[rl78] fix far addressing etc
Various fixes for far memory addressing (and large programs in general). Committed. * config/rl78/constraints.md (Wfr): Change to be a non-memory constraint. * config/rl78/rl78-protos.h (rl78_one_far_p): Declare. * config/rl78/rl78.c (rl78_one_far_p): Define. * config/rl78/rl78-virt (movqi_virt): Fix far memory alternatives. (movhi_virt): Likewise. (zero_extendqihi2_virt): Likewise. (extendqihi2_virt): Likewise. (add3_virt): Likewise. (sub3_virt): Likewise. (andqi3_virt): Likewise. (iorqi3_virt): Likewise. (xorqi3_virt): Likewise. * config/rl78/rl78-real.md (bf,br): Use long forms to avoid reloc overflow in large files. Index: gcc/config/rl78/constraints.md === --- gcc/config/rl78/constraints.md (revision 231385) +++ gcc/config/rl78/constraints.md (working copy) @@ -361,13 +361,13 @@ (define_memory_constraint "Ws1" "es:word8[SP]" (match_test "(rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op))) || satisfies_constraint_Cs1 (op)") ) -(define_memory_constraint "Wfr" +(define_constraint "Wfr" "ES/CS far pointer" (and (match_code "mem") (match_test "rl78_far_p (op)")) ) (define_memory_constraint "Wsa" Index: gcc/config/rl78/rl78-protos.h === --- gcc/config/rl78/rl78-protos.h (revision 231385) +++ gcc/config/rl78/rl78-protos.h (working copy) @@ -51,6 +51,8 @@ bool rl78_flags_already_set (rtx, rtx); void rl78_output_symbol_ref (FILE *, rtx); void rl78_output_labelref (FILE *, const char *); intrl78_saddr_p (rtx x); intrl78_sfr_p (rtx x); void rl78_output_aligned_common (FILE *, tree, const char *, int, int, int); + +intrl78_one_far_p (rtx *operands, int num_operands); Index: gcc/config/rl78/rl78-real.md === --- gcc/config/rl78/rl78-real.md(revision 231385) +++ gcc/config/rl78/rl78-real.md(working copy) @@ -586,25 +586,25 @@ (if_then_else (eq (and (reg:QI A_REG) (match_operand 0 "immediate_operand" "n")) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "" - "bf\tA.%B0, $%1" + "bt\tA.%B0, $1f\n\tbr !!%1\n\t1:" [(set (attr "update_Z") (const_string "clobber"))] ) (define_insn "bt" [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_operand 0 "immediate_operand" "n")) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "" - "bt\tA.%B0, $%1" + "bf\tA.%B0, $1f\n\tbr !!%1\n\t1:" [(set (attr "update_Z") (const_string "clobber"))] ) ;; NOTE: These peepholes are fragile. They rely upon GCC generating ;; a specific sequence on insns, based upon examination of test code. ;; Improvements to GCC or using code other than the test code can result Index: gcc/config/rl78/rl78-virt.md === --- gcc/config/rl78/rl78-virt.md(revision 231385) +++ gcc/config/rl78/rl78-virt.md(working copy) @@ -39,14 +39,14 @@ "rl78_virt_insns_ok ()" "v.mov %0, %1" [(set_attr "valloc" "op1")] ) (define_insn "*movqi_virt" - [(set (match_operand:QI 0 "nonimmediate_operand" "=vY,v,Wfr") - (match_operand1 "general_operand" "vInt8J,YWfr,vInt8J"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=vY,v,*Wfr,Y,*Wfr,*Wfr") + (match_operand1 "general_operand" "vInt8JY,*Wfr,vInt8J,*Wfr,Y,*Wfr"))] "rl78_virt_insns_ok ()" "v.mov %0, %1" [(set_attr "valloc" "op1")] ) (define_insn "*movhi_virt_mm" @@ -55,33 +55,33 @@ "rl78_virt_insns_ok ()" "v.movw %0, %1" [(set_attr "valloc" "op1")] ) (define_insn "*movhi_virt" - [(set (match_operand:HI 0 "nonimmediate_operand" "=vS, Y, v, Wfr") - (match_operand:HI 1 "general_operand" "viYS, viS, Wfr, vi"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=vS, Y, v, *Wfr") + (match_operand:HI 1 "general_operand" "viYS, viS, *Wfr, vi"))] "rl78_virt_insns_ok ()" "v.movw %0, %1" [(set_attr "valloc" "op1")] ) ;;-- Conversions (define_insn "*zero_extendqihi2_virt" - [(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vm") - (zero_extend:HI (match_operand:QI 1 "general_operand" "vim")))] - "rl78_virt_insns_ok ()" + [(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vY,*Wfr") + (zero_extend:HI (match_operand:QI 1 "general_operand" "vim,viY")))] + "rl7
[rx] avoid long calls
Immediate mode jumps have limits; this new option tells gcc to avoid those instructions (by using indirect mode ones) in those rare cases where the user has a program that big. Committed. * config/rx/rx.opt (-mjsr): Add. * config/rx/predicates.md (rx_call_operand): Avoid overflowing calls when -mjsr. * config/rx/rx.c (rx_function_ok_for_sibcall): Likewise for overflowing jumps. * doc/invoke.texi (-mjsr): Document it. Index: doc/invoke.texi === --- doc/invoke.texi (revision 231438) +++ doc/invoke.texi (working copy) @@ -965,12 +965,13 @@ See RS/6000 and PowerPC Options. -mas100-syntax -mno-as100-syntax@gol -mrelax@gol -mmax-constant-size=@gol -mint-register=@gol -mpid@gol -mallow-string-insns -mno-allow-string-insns@gol +-mjsr@gol -mno-warn-multiple-fast-interrupts@gol -msave-acc-in-interrupts} @emph{S/390 and zSeries Options} @gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol -mhard-float -msoft-float -mhard-dfp -mno-hard-dfp @gol @@ -20682,12 +20683,21 @@ disabled automatically. Instead it is r use the @option{-mno-allow-string-insns} option if their program accesses I/O space. When the instructions are enabled GCC defines the C preprocessor symbol @code{__RX_ALLOW_STRING_INSNS__}, otherwise it defines the symbol @code{__RX_DISALLOW_STRING_INSNS__}. + +@item -mjsr +@itemx -mno-jsr +@opindex mjsr +@opindex mno-jsr +Use only (or not only) @code{JSR} instructions to access functions. +This option can be used when code size exceeds the range of @code{BSR} +instructions. Note that @option{-mno-jsr} does not mean to not use +@code{JSR} but instead means that any type of branch may be used. @end table @emph{Note:} The generic GCC command-line option @option{-ffixed-@var{reg}} has special significance to the RX port when used with the @code{interrupt} function attribute. This attribute indicates a function intended to process fast interrupts. GCC ensures Index: config/rx/predicates.md === --- config/rx/predicates.md (revision 231438) +++ config/rx/predicates.md (working copy) @@ -21,13 +21,15 @@ ;; Check that the operand is suitable for a call insn. ;; Only registers and symbol refs are allowed. (define_predicate "rx_call_operand" - (match_code "symbol_ref,reg") + (ior (match_code "reg") + (and (match_test "!TARGET_JSR") + (match_code "symbol_ref"))) ) ;; For sibcall operations we can only use a symbolic address. (define_predicate "rx_symbolic_call_operand" (match_code "symbol_ref") Index: config/rx/rx.c === --- config/rx/rx.c (revision 231438) +++ config/rx/rx.c (working copy) @@ -2854,12 +2854,15 @@ rx_warn_func_return (tree decl) /* Return nonzero if it is ok to make a tail-call to DECL, a function_decl or NULL if this is an indirect call, using EXP */ static bool rx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) { + if (TARGET_JSR) +return false; + /* Do not allow indirect tailcalls. The sibcall patterns do not support them. */ if (decl == NULL) return false; /* Never tailcall from inside interrupt handlers or naked functions. */ Index: config/rx/rx.opt === --- config/rx/rx.opt(revision 231438) +++ config/rx/rx.opt(working copy) @@ -146,6 +146,12 @@ Enable the use of the LRA register alloc ;--- mallow-string-insns Target Report Var(rx_allow_string_insns) Init(1) Enables or disables the use of the SMOVF, SMOVB, SMOVU, SUNTIL, SWHILE and RMPA instructions. Enabled by default. + +;--- + +mjsr +Target Report Mask(JSR) +Always use JSR, never BSR, for calls.
Re: Free up bits in DECLs and TYPEs
I'm OK with the msp430 part :-)
Re: [PATCH 1/6] [DJGPP] libstdc++-v3/config/os/djgpp/error_constants.h: Update according to errno codes available for DJGPP
> I can't really judge this one. Either DJ or Jon would need to some in > on this. Looks OK to me, although in the default configuration (plain DJGPP) the #ifdefs will always be false (omitted), which is harmless.
Re: [PATCH,AIX] Enable libiberty to read AIX XCOFF
David Edelsohn writes: > This patch generally looks good to me -- it clearly is an incremental > improvement. One of the libiberty maintainers, such as Ian, needs to > approve the patch. As AIX maintainer, I think you have the authority to approve patches like this, which only affect your OS. I see no reason to reject the patch myself, other than: + symtab = XNEWVEC (struct external_syment, ocr->nsyms * SYMESZ); + if (!simple_object_internal_read (sobj->descriptor, There's no check to see if XNEWVEC succeeded. Also, the use of XDELETEVEC is inconsistently protected with a "if (foo != NULL)" throughout, but passing NULL to XDELETEVEC (essentially, free()) is allowed anyway, so this is only a stylistic issue, which I'm not particularly worried about.
Re: [PATCH,AIX] Enable libiberty to read AIX XCOFF
"REIX, Tony" writes: > It appears that XNEWVEC() calls xmalloc which prints a message and > calls xexit if malloc fails. Objection removed then ;-) > So, yes, we check if (strtab == NULL) though there is no way that > XDELETEVEC(NULL) breaks something. However, it is a classic > programming style. Yup, I noted that. Just mentioning the inconsistency.
Re: [RFTesting] New POINTER_DIFF_EXPR
Richard Biener writes: > The question is what ptrdiff_t is for a specific address space. Or > rather if that type may be dependent on the address space or if we can > always use that of the default address space. Some targets have a "far" address space that's bigger than the default. rl78 for example has a 16-bit default pointer and a 32-bit far pointer.
Re: [PATCH] rl78 anddi3 improvement
Right, when doing 64-bit operations on an 8-bit mcu with limited registers, a hand-written assembler routine that you call as needed will beat anything gcc spits out - for size-per-call. And I had a lot of trouble getting gcc to deal with the rl78's limited register set and addressing modes - compiling libgcc/libstdc++ is a torture test for alloc/reload on small mcus. That forced me to be conservative, and add the virtual ISA that gcc can work with. So I'm OK with your approach, and if you come up with something even better, I'm OK with that too :-) (pending reviews, of course, that's next ;)
Re: [PATCH] [MSP430] Allow interrupt handers to be static and fix __interrupt__ attribute causing an ICE
The reason I required interrupt handlers to be non-static is because the linker builds the interrupt handler table using weak references. If the handler is static, it won't be added to the table, and never called. So you'd need a test to ensure that the handler was properly entered into the table as well.
Re: [PATCH] [MSP430] Allow interrupt handers to be static and fix __interrupt__ attribute causing an ICE
Jozef Lawrynowicz writes: > If an argument is passed to the interrupt attribute, GCC will create a section > for the interrupt vector when outputting the assembly. This, combined with the > code to ensure the interrupt function doesn't get optimized out, ensures the > symbol for the interrupt function is available when it comes to linking. > I did also test on hardware that static interrupts works as expected, and they > do. It sounds like things have changed since I first wrote that code, so as long as it works now, I'm OK with it :-)
Re: [PATCH] [MSP430] Fix device name symbol defined for MSP430i series of devices
Jozef Lawrynowicz writes: > + if (strncmp (target_mcu, "msp430i", 7) == 0) > + snprintf (mcu_name, sizeof (mcu_name) - 1, "__MSP430i%s__", > + target_mcu + 7); > + else Do you need to TOUPPER the parts of target_mcu after char 7 ?
Re: [PATCH] [MSP430] Fix device name symbol defined for MSP430i series of devices
Jozef Lawrynowicz writes: > For the currently released msp430i* devices, only digits follow the i, so no > upper or lower case conversion is needed. Thinking of the future... do we expect any new devices with letters? Should we plan for them? Or better to wait, in case there are more lower-case-letter symbols? Just trying to think of all the possibilities here.
Re: [PATCH] [MSP430] Fix device name symbol defined for MSP430i series of devices
Jozef Lawrynowicz writes: > Word from TI is that the lowercase i is an exception, the rule is to have all > uppercase letters. No further msp430i devices are planned so the rules for > generating device names in this patch shouldn't need any future changes. So a future-proof patch would TOUPPER the 430i suffixes, but the expectation is that there will never be anything for the TOUPPER to upper, yes? If so, no further objections from me. It can be tweaked later if they change their minds.
Re: [PATCH] [MSP430] Fix device name symbol defined for MSP430i series of devices
> + snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu); > + start_upper = 0; Can optimize this to 2 :-) Otherwise OK.
Re: [PATCH] [MSP430] Fix device name symbol defined for MSP430i series of devices
Jozef Lawrynowicz writes: > - for (i = start_upper; i < strlen (mcu_name); i++) > + for (i = start_upper; i < strlen (mcu_name) - 2; i++) Might be faster to test mcu_name[i] instead of calling strlen repeatedly too, but this only runs once per invocation ;-)
Re: [PATCH] [MSP430] Fix device name symbol defined for MSP430i series of devices
That's fine too, I was thinking of checking mcu_name[i] against NUL. Any of those solutions would work :-)
Re: [PATCH] RL78 movdi improvement
I saw one regression with this patch: PASS-FAIL: gcc.dg/torture/vshuf-v8qi.c -O2 execution test Could you confirm this? Note: I'm testing with your other (pre-2018 at least) patches applied at the same time (smax etc, anddi, bswaphi) so it might be an interaction, but the code looks like a movdi bug. The other patches look OK otherwise.
Re: [PATCH] RL78 UNUSED note setting bug fix in rl78_note_reg_set
"Sebastian Perta" writes: > Please let me know if this is OK. Thank you! Do you have checkin privs yet? This is ok aside from.. > + /* 'dead' keeps track of the QImode registers if r is of different size > + we need to check the other subparts as well */ Missing period at the end of a sentence; should capitalize first word but it's a variable, which should be block caps anyway, and it reads better as two sentences: > + /* DEAD keeps track of the QImode registers. If R is of different size > + we need to check the other subparts as well. */ Or rewrite to not mention variables? > + /* Do not mark the reg unused unless all QImode parts of it are dead. */
Re: Compilation warning in simple-object-xcoff.c
I think that warning is valid - the host has a 32-bit limit to file sizes (off_t) but it's trying to read a 64-bit offset (in that clause). It's warning you that you won't be able to handle files as large as the field implies. Can we hide the warning? Probably. Should we? Debatable, as long as we want 64-bit xcoff support in 32-bit filesystems. Otherwise, we'd need to detect off_t overflow somehow, down the slippery slope of reporting the error to the caller...
Re: Compilation warning in simple-object-xcoff.c
Well, it should all work fine as long as the xcoff64 file is less than 4 Gb. And it's not the host's bit size that counts; there are usually ways to get 64-bit file operations on 32-bit hosts.
Re: Compilation warning in simple-object-xcoff.c
Eli Zaretskii writes: > DJ, would the following semi-kludgey workaround be acceptable? It would be no worse than what we have now, if the only purpose is to avoid a warning. Ideally, we would check to see if we're discarding non-zero values from that offset, and not call the callback with known bogus data. I suppose the usefulness of that depends on how often you'll encounter 4Gb+ xcoff64 files on mingw32 ?
Re: [PATCH] RL78 UNUSED note setting bug fix in rl78_note_reg_set
Sebastian Perta writes: > * config/rl78/rl78.c (rl78_note_reg_set): fixed dead reg check > for non-QImode registers This is OK. Thanks! Note: in the future; ChangeLog entries should be provided separate from the patch; they rarely apply cleanly anyway. > Index: config/rl78/rl78.c > === > --- config/rl78/rl78.c(revision 256590) > +++ config/rl78/rl78.c(working copy) > @@ -3792,7 +3792,7 @@ > rl78_note_reg_set (char *dead, rtx d, rtx insn) > { >int r, i; > - > + bool is_dead; >if (GET_CODE (d) == MEM) > rl78_note_reg_uses (dead, XEXP (d, 0), insn); > > @@ -3799,9 +3799,15 @@ >if (GET_CODE (d) != REG) > return; > > + /* Do not mark the reg unused unless all QImode parts of it are dead. */ >r = REGNO (d); > - if (dead [r]) > -add_reg_note (insn, REG_UNUSED, gen_rtx_REG (GET_MODE (d), r)); > + is_dead = true; > + for (i = 0; i < GET_MODE_SIZE (GET_MODE (d)); i ++) > + if (!dead [r + i]) > + is_dead = false; > + if(is_dead) > +add_reg_note (insn, REG_UNUSED, gen_rtx_REG (GET_MODE (d), r)); >if (dump_file) > fprintf (dump_file, "note set reg %d size %d\n", r, GET_MODE_SIZE > (GET_MODE (d))); >for (i = 0; i < GET_MODE_SIZE (GET_MODE (d)); i ++)