diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3fa0f79a28e..64cedde103d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2002-11-07 Vijay L. Khuspe + + * config/h8300/h8300.c (h8300_init_once): Allow -mn switch + only if -mh or -ms present. + (h8300_eightbit_constant_address_p): Support the normal mode. + (h8300_tiny_constant_address_p): Likewise. + * config/h8300/h8300.h (TARGET_NORMAL_MODE): New. + (POINTER_SIZE): Add 16 bit pointer for the normal mode. + (Pmode): Evaluate to HImode for the normal mode. + (SIZE_TYPE): Evaluate to unsigned int for normal mode. + (PTRDIFF_TYPE): Evaluate to int for the normal mode. + (ASM_WORD_OP): Evaluate to word for the normal mode. + * config/h8300/h8300.md (tablejump_normal_mode): New. + (indirect_jump_normal_mode): New. + * config/h8300/t-h8300 (MULTILIB_OPTIONS): Pass -mn option to + directory. + (MULTILIB_DIRNAMES): Create target dependent directory + 'normal'. + (MULTILIB_EXCEPTIONS): Don't turn on -mn on H8/300. + * doc/invoke.texi (gccoptlist): Describe the new switch -mn. + Tue Nov 19 23:50:56 CET 2002 Jan Hubicka * i386.md (length_immediate): Do not refer to insn address. diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index c5bfb137fe4..c31bab60f28 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -314,6 +314,12 @@ h8300_init_once () error ("-ms2600 is used without -ms"); target_flags |= 1; } + + if (TARGET_H8300 && TARGET_NORMAL_MODE) + { + error ("-mn used without -mh or -ms"); + target_flags ^= MASK_NORMAL_MODE; + } /* Some of the shifts are optimized for speed by default. See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html @@ -1637,6 +1643,10 @@ h8300_initial_elimination_offset (from, to) if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) offset += UNITS_PER_WORD; /* Skip saved PC */ } + + if ((TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE) + offset -= 2; + return offset; } @@ -3882,7 +3892,7 @@ h8300_eightbit_constant_address_p (x) addr = INTVAL (x); return (0 - || (TARGET_H8300 && IN_RANGE (addr, n1, n2)) + || ((TARGET_H8300 || TARGET_NORMAL_MODE) && IN_RANGE (addr, n1, n2)) || (TARGET_H8300H && IN_RANGE (addr, h1, h2)) || (TARGET_H8300S && IN_RANGE (addr, s1, s2))); } @@ -3909,8 +3919,8 @@ h8300_tiny_constant_address_p (x) addr = INTVAL (x); return (0 - || (TARGET_H8300H + || ((TARGET_H8300H && !TARGET_NORMAL_MODE) && (IN_RANGE (addr, h1, h2) || IN_RANGE (addr, h3, h4))) - || (TARGET_H8300S + || ((TARGET_H8300S && !TARGET_NORMAL_MODE) && (IN_RANGE (addr, s1, s2) || IN_RANGE (addr, s3, s4)))); } diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 79898aab4e9..7d3a986c903 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -46,12 +46,20 @@ extern const char * const *h8_reg_names; builtin_define ("__H8300H__"); \ builtin_assert ("cpu=h8300h"); \ builtin_assert ("machine=h8300h"); \ + if (TARGET_NORMAL_MODE) \ + { \ + builtin_define ("__NORMAL_MODE__"); \ + } \ } \ else if (TARGET_H8300S) \ { \ builtin_define ("__H8300S__"); \ builtin_assert ("cpu=h8300s"); \ builtin_assert ("machine=h8300s"); \ + if (TARGET_NORMAL_MODE) \ + { \ + builtin_define ("__NORMAL_MODE__"); \ + } \ } \ else \ { \ @@ -91,6 +99,7 @@ extern int target_flags; #define MASK_ADDRESSES 0x00000040 #define MASK_QUICKCALL 0x00000080 #define MASK_SLOWBYTE 0x00000100 +#define MASK_NORMAL_MODE 0x00000200 #define MASK_RELAX 0x00000400 #define MASK_RTL_DUMP 0x00000800 #define MASK_H8300H 0x00001000 @@ -119,6 +128,7 @@ extern int target_flags; #define TARGET_H8300 (! TARGET_H8300H && ! TARGET_H8300S) #define TARGET_H8300H (target_flags & MASK_H8300H) #define TARGET_H8300S (target_flags & MASK_H8300S) +#define TARGET_NORMAL_MODE (target_flags & MASK_NORMAL_MODE) /* mac register and relevant instructions are available. */ #define TARGET_MAC (target_flags & MASK_MAC) @@ -152,6 +162,7 @@ extern int target_flags; {"relax", MASK_RELAX, N_("Enable linker relaxing")}, \ {"rtl-dump", MASK_RTL_DUMP, NULL}, \ {"h", MASK_H8300H, N_("Generate H8/300H code")}, \ + {"n", MASK_NORMAL_MODE, N_("Enable the normal mode")}, \ {"no-h", -MASK_H8300H, N_("Do not generate H8/300H code")}, \ {"align-300", MASK_ALIGN_300, N_("Use H8/300 alignment rules")}, \ { "", TARGET_DEFAULT, NULL}} @@ -159,6 +170,7 @@ extern int target_flags; #ifdef IN_LIBGCC2 #undef TARGET_H8300H #undef TARGET_H8300S +#undef TARGET_NORMAL_MODE /* If compiling libgcc2, make these compile time constants based on what flags are we actually compiling with. */ #ifdef __H8300H__ @@ -171,6 +183,11 @@ extern int target_flags; #else #define TARGET_H8300S 0 #endif +#ifdef __NORMAL_MODE__ +#define TARGET_NORMAL_MODE 1 +#else +#define TARGET_NORMAL_MODE 0 +#endif #endif /* !IN_LIBGCC2 */ /* Do things that must be done once at start up. */ @@ -974,13 +991,19 @@ struct cum_arg /* Specify the machine mode that pointers have. After generation of rtl, the compiler makes no further distinction between pointers and any other objects of this machine mode. */ -#define Pmode (TARGET_H8300H || TARGET_H8300S ? SImode : HImode) +#define Pmode \ + ((TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE ? SImode : HImode) /* ANSI C types. We use longs for the H8/300H and the H8S because ints can be 16 or 32. GCC requires SIZE_TYPE to be the same size as pointers. */ -#define SIZE_TYPE (TARGET_H8300 ? "unsigned int" : "long unsigned int") -#define PTRDIFF_TYPE (TARGET_H8300 ? "int" : "long int") +#define SIZE_TYPE \ + (TARGET_H8300 || TARGET_NORMAL_MODE ? "unsigned int" : "long unsigned int") +#define PTRDIFF_TYPE \ + (TARGET_H8300 || TARGET_NORMAL_MODE ? "int" : "long int") + +#define POINTER_SIZE \ + ((TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE ? 32 : 16) #define WCHAR_TYPE "short unsigned int" #define WCHAR_TYPE_SIZE 16 @@ -1068,7 +1091,8 @@ struct cum_arg #define IDENT_ASM_OP "\t.ident\n" /* The assembler op to get a word, 2 bytes for the H8/300, 4 for H8/300H. */ -#define ASM_WORD_OP (TARGET_H8300 ? "\t.word\t" : "\t.long\t") +#define ASM_WORD_OP \ + (TARGET_H8300 || TARGET_NORMAL_MODE ? "\t.word\t" : "\t.long\t") #define TEXT_SECTION_ASM_OP "\t.section .text" #define DATA_SECTION_ASM_OP "\t.section .data" diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 6c7c26dc569..5e9f114d3ec 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -1580,6 +1580,14 @@ [(set_attr "cc" "none") (set_attr "length" "2")]) +(define_insn "tablejump_normal_mode" + [(set (pc) (match_operand:HI 0 "register_operand" "r")) + (use (label_ref (match_operand 1 "" "")))] + "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE" + "jmp @%S0" + [(set_attr "cc" "none") + (set_attr "length" "2")]) + ;; This is a define expand, because pointers may be either 16 or 32 bits. (define_expand "indirect_jump" @@ -1601,6 +1609,13 @@ [(set_attr "cc" "none") (set_attr "length" "2")]) +(define_insn "indirect_jump_normal_mode" + [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))] + "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE" + "jmp @%S0" + [(set_attr "cc" "none") + (set_attr "length" "2")]) + ;; Call subroutine with no return value. ;; ??? Even though we use HImode here, this works on the H8/300H and H8S. diff --git a/gcc/config/h8300/t-h8300 b/gcc/config/h8300/t-h8300 index ad7a6574896..d8cbd4f1293 100644 --- a/gcc/config/h8300/t-h8300 +++ b/gcc/config/h8300/t-h8300 @@ -25,9 +25,9 @@ fp-bit.c: $(srcdir)/config/fp-bit.c echo '#endif' >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c -MULTILIB_OPTIONS = mh/ms mint32 -MULTILIB_DIRNAMES = h8300h h8300s int32 -MULTILIB_EXCEPTIONS = mint32 +MULTILIB_OPTIONS = mh/ms mn mint32 +MULTILIB_DIRNAMES = h8300h h8300s normal int32 +MULTILIB_EXCEPTIONS = mint32 mn mn/mint32 LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 45fee6f0fbf..36ca7551196 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -550,7 +550,7 @@ in the following sections. @emph{H8/300 Options} @gccoptlist{ --mrelax -mh -ms -mint32 -malign-300} +-mrelax -mh -ms -mn -mint32 -malign-300} @emph{SH Options} @gccoptlist{ @@ -8632,6 +8632,11 @@ Generate code for the H8/300H@. @opindex ms Generate code for the H8S@. +@item -mn +@opindex mn +Generate code for the H8S and H8/300H in the normal mode. This switch +must be used either with -mh or -ms. + @item -ms2600 @opindex ms2600 Generate code for the H8S/2600. This switch must be used with @option{-ms}.