diff options
author | Jeff Law <law@gcc.gnu.org> | 1996-07-08 15:02:16 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1996-07-08 15:02:16 -0600 |
commit | a1616dd9e81f077a581da475d45d379d7959fb04 (patch) | |
tree | 00d3da0eeba3ca80390e177cc5ad43f968c90e4e | |
parent | 8343b898b93c9d2f89154b58315592d217e37f66 (diff) | |
download | gcc-a1616dd9e81f077a581da475d45d379d7959fb04.zip gcc-a1616dd9e81f077a581da475d45d379d7959fb04.tar.gz gcc-a1616dd9e81f077a581da475d45d379d7959fb04.tar.bz2 |
* First cut at support for the H8/S.
* h8300/h8300.c (h8300_init_once): Handle the H8/S (treat it
like the H8/300H).
(dosize, adds_subs_operand, one_insn_adds_subs_operand): Likewise.
(output_adds_subs, const_costs, print_operand): Likewise.
(output_simode_bld, h8300_adjust_insn_length): Likewise.
(push_order, pop_order): Reverse.
(function_prologue): Try to use ldm.l and stm.l insns
on the H8/S. Minor cleanups.
(function_epilogue): Likewise.
(asm_file_start): Emit ".h8300s" when compiling for the H8/S.
* h8300/h8300.h (CPP_SPEC): Handle the H8/S.
(TARGET_H8300S): New target.
(TARGET_SWITCHES): Add "-ms" and "-mno-s".
(BITS_PER_WORD): Handle the H8/S (treat it like the H8/300H).
(UNITS_PER_WORD, POINTER_SIZE, PARM_BOUNDARY): Likewise.
(BIGGEST_ALIGNMENT, BIGGEST_FIELD_ALIGNMENT): Likewise.
(INITIALIZE_TRAMPOLINE, MOVE_MAX, Pmode): Likewise.
* h8300/h8300.md: Handle H8/S just like H8/300H
throughout the entire file.
* h8300/t-h8300 (MULTILIB_OPTIONS): Build "-ms" libraries
too.
(MULTILIB_DIRNAMES): Put H8/S libraries in "h8300s" directory.
* h8300/lib1funcs.asm: Emit ".h8300s" pseudo-op when generating
h8300s object files. Otherwise treat the H8/S just like the H8/300H.
* ginclude/stdarg.h: Handle the H8/S.
* ginclude/varargs.h: Likewise.
From-SVN: r12410
-rw-r--r-- | gcc/config/h8300/h8300.c | 266 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.h | 42 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.md | 112 | ||||
-rw-r--r-- | gcc/config/h8300/lib1funcs.asm | 12 | ||||
-rw-r--r-- | gcc/config/h8300/t-h8300 | 4 |
5 files changed, 294 insertions, 142 deletions
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 8ffd84e..255eadb 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -99,6 +99,7 @@ h8300_init_once () } else { + /* For this we treat the H8/300 and H8/S the same. */ cpu_type = (int) CPU_H8300H; h8_reg_names = names_extended; } @@ -137,10 +138,10 @@ dosize (file, op, size) char *op; unsigned int size; { - /* On the h8300h, for sizes <= 8 bytes it is as good or + /* On the h8300h and h8300s, for sizes <= 8 bytes it is as good or better to use adds/subs insns rather than add.l/sub.l with an immediate value. */ - if (size > 4 && size <= 8 && TARGET_H8300H) + if (size > 4 && size <= 8 && (TARGET_H8300H || TARGET_H8300S)) { /* Crank the size down to <= 4 */ fprintf (file, "\t%ss\t#%d,sp\n", op, 4); @@ -150,7 +151,7 @@ dosize (file, op, size) switch (size) { case 4: - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) { fprintf (file, "\t%ss\t#%d,sp\n", op, 4); size = 0; @@ -179,9 +180,9 @@ dosize (file, op, size) /* Output assembly language code for the function prologue. */ static int push_order[FIRST_PSEUDO_REGISTER] = -{6, 5, 4, 3, 2, 1, 0, -1, -1}; -static int pop_order[FIRST_PSEUDO_REGISTER] = {0, 1, 2, 3, 4, 5, 6, -1, -1}; +static int pop_order[FIRST_PSEUDO_REGISTER] = +{6, 5, 4, 3, 2, 1, 0, -1, -1}; /* This is what the stack looks like after the prolog of a function with a frame has been set up: @@ -240,7 +241,7 @@ function_prologue (file, size) fprintf (file, "\torc\t#128,ccr\n"); fprintf (file, "\tmov.b\tr0l,@(4,sp)\n"); } - else if (TARGET_H8300H) + else { fprintf (file, "\tpush\ter0\n"); fprintf (file, "\tstc\tccr,r0l\n"); @@ -257,28 +258,88 @@ function_prologue (file, size) fprintf (file, "\t%s\t%s,%s\n", h8_mov_op, h8_reg_names[STACK_POINTER_REGNUM], h8_reg_names[FRAME_POINTER_REGNUM]); + } - /* leave room for locals */ - dosize (file, "sub", fsize); - - /* Push the rest of the registers */ - for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) - { - int regno = push_order[idx]; + /* leave room for locals */ + dosize (file, "sub", fsize); - if (regno >= 0 && WORD_REG_USED (regno) && regno != FRAME_POINTER_REGNUM) - fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[regno]); - } - } - else + /* Push the rest of the registers */ + for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) { - dosize (file, "sub", fsize); - for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) - { - int regno = push_order[idx]; + int regno = push_order[idx]; - if (regno >= 0 && WORD_REG_USED (regno)) - fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[regno]); + if (regno >= 0 + && WORD_REG_USED (regno) + && (!frame_pointer_needed || regno != FRAME_POINTER_REGNUM)) + { + if (TARGET_H8300S) + { + /* Try to push multiple registers. */ + if (regno == 0 || regno == 4) + { + int second_regno = push_order[idx + 1]; + int third_regno = push_order[idx + 2]; + int fourth_regno = push_order[idx + 3]; + + if (fourth_regno >= 0 + && WORD_REG_USED (fourth_regno) + && (!frame_pointer_needed + || fourth_regno != FRAME_POINTER_REGNUM) + && third_regno >= 0 + && WORD_REG_USED (third_regno) + && (!frame_pointer_needed + || third_regno != FRAME_POINTER_REGNUM) + && second_regno >= 0 + && WORD_REG_USED (second_regno) + && (!frame_pointer_needed + || second_regno != FRAME_POINTER_REGNUM)) + { + fprintf (file, "\tstm.l %s-%s,@-sp\n", + h8_reg_names[regno], + h8_reg_names[fourth_regno]); + idx += 3; + continue; + } + } + if (regno == 0 || regno == 4) + { + int second_regno = push_order[idx + 1]; + int third_regno = push_order[idx + 2]; + + if (third_regno >= 0 + && WORD_REG_USED (third_regno) + && (!frame_pointer_needed + || third_regno != FRAME_POINTER_REGNUM) + && second_regno >= 0 + && WORD_REG_USED (second_regno) + && (!frame_pointer_needed + || second_regno != FRAME_POINTER_REGNUM)) + { + fprintf (file, "\tstm.l %s-%s,@-sp\n", + h8_reg_names[regno], + h8_reg_names[third_regno]); + idx += 2; + continue; + } + } + if (regno == 0 || regno == 2 || regno == 4 || regno == 6) + { + int second_regno = push_order[idx + 1]; + + if (second_regno >= 0 + && WORD_REG_USED (second_regno) + && (!frame_pointer_needed + || second_regno != FRAME_POINTER_REGNUM)) + { + fprintf (file, "\tstm.l %s-%s,@-sp\n", + h8_reg_names[regno], + h8_reg_names[second_regno]); + idx += 1; + continue; + } + } + } + fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[regno]); } } } @@ -293,8 +354,6 @@ function_epilogue (file, size) register int regno; register int mask = 0; int fsize = (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8; - int nregs; - int offset; int idx; rtx insn = get_last_insn (); @@ -318,35 +377,93 @@ function_epilogue (file, size) if (insn && GET_CODE (insn) == BARRIER) return; - nregs = 0; - - if (frame_pointer_needed) + /* Pop the saved registers. */ + for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) { - /* Pop saved registers */ - for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) - { - regno = pop_order[idx]; - if (regno >= 0 && regno != FRAME_POINTER_REGNUM && WORD_REG_USED (regno)) - fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[regno]); - } - /* deallocate locals */ - dosize (file, "add", fsize); - /* pop frame pointer */ - fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[FRAME_POINTER_REGNUM]); - } - else - { - /* pop saved registers */ - for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) + int regno = pop_order[idx]; + + if (regno >= 0 + && WORD_REG_USED (regno) + && (!frame_pointer_needed || regno != FRAME_POINTER_REGNUM)) { - regno = pop_order[idx]; - if (regno >= 0 && WORD_REG_USED (regno)) - fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[regno]); + if (TARGET_H8300S) + { + /* Try to pop multiple registers. */ + if (regno == 7 || regno == 3) + { + int second_regno = pop_order[idx + 1]; + int third_regno = pop_order[idx + 2]; + int fourth_regno = pop_order[idx + 3]; + + if (fourth_regno >= 0 + && WORD_REG_USED (fourth_regno) + && (!frame_pointer_needed + || fourth_regno != FRAME_POINTER_REGNUM) + && third_regno >= 0 + && WORD_REG_USED (third_regno) + && (!frame_pointer_needed + || third_regno != FRAME_POINTER_REGNUM) + && second_regno >= 0 + && WORD_REG_USED (second_regno) + && (!frame_pointer_needed + || second_regno != FRAME_POINTER_REGNUM)) + { + fprintf (file, "\tldm.l @sp+,%s-%s\n", + h8_reg_names[fourth_regno], + h8_reg_names[regno]); + idx += 3; + continue; + } + } + if (regno == 6 || regno == 2) + { + int second_regno = pop_order[idx + 1]; + int third_regno = pop_order[idx + 2]; + + if (third_regno >= 0 + && WORD_REG_USED (third_regno) + && (!frame_pointer_needed + || third_regno != FRAME_POINTER_REGNUM) + && second_regno >= 0 + && WORD_REG_USED (second_regno) + && (!frame_pointer_needed + || second_regno != FRAME_POINTER_REGNUM)) + { + fprintf (file, "\tldm.l @sp+,%s-%s\n", + h8_reg_names[third_regno], + h8_reg_names[regno]); + idx += 2; + continue; + } + } + if (regno == 7 || regno == 5 || regno == 3 || regno == 1) + { + int second_regno = pop_order[idx + 1]; + + if (second_regno >= 0 + && WORD_REG_USED (second_regno) + && (!frame_pointer_needed + || second_regno != FRAME_POINTER_REGNUM)) + { + fprintf (file, "\tldm.l @sp+,%s-%s\n", + h8_reg_names[second_regno], + h8_reg_names[regno]); + idx += 1; + continue; + } + } + } + fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[regno]); } - /* deallocate locals */ - dosize (file, "add", fsize); } + /* deallocate locals */ + dosize (file, "add", fsize); + + /* pop frame pointer if we had one. */ + if (frame_pointer_needed) + fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[FRAME_POINTER_REGNUM]); + /* If this is a monitor function, there is one register still left on the stack. */ if (monitor) @@ -376,6 +493,8 @@ asm_file_start (file) fprintf (file, "; -O%d\n", optimize); if (TARGET_H8300H) fprintf (file, "\n\t.h8300h\n"); + else if (TARGET_H8300S) + fprintf (file, "\n\t.h8300s\n"); else fprintf (file, "\n\n"); output_file_directive (file, main_input_filename); @@ -508,11 +627,11 @@ adds_subs_operand (op, mode) return 1; if (INTVAL (op) >= -4 && INTVAL (op) <= 0) return 1; - if (TARGET_H8300H + if ((TARGET_H8300H || TARGET_H8300S) && INTVAL (op) != 7 && (INTVAL (op) <= 8 && INTVAL (op) >= 0)) return 1; - if (TARGET_H8300H + if ((TARGET_H8300H || TARGET_H8300S) && INTVAL (op) != -7 && (INTVAL (op) >= -8 && INTVAL (op) <= 0)) return 1; @@ -532,7 +651,7 @@ one_insn_adds_subs_operand (op, mode) if (val == 1 || val == -1 || val == 2 || val == -2 - || (TARGET_H8300H + || ((TARGET_H8300H || TARGET_H8300S) && (val == 4 || val == -4))) return 1; return 0; @@ -547,7 +666,7 @@ output_adds_subs (operands) /* First get the value into the range -4..4 inclusive. The only way it can be out of this range is when TARGET_H8300H - is true, thus it is safe to use adds #4 and subs #4. */ + or TARGET_H8300S is true, thus it is safe to use adds #4 and subs #4. */ if (val > 4) { output_asm_insn ("adds #4,%A0", operands); @@ -561,11 +680,13 @@ output_adds_subs (operands) } /* Handle case were val == 4 or val == -4 and we're compiling - for TARGET_H8300H. */ - if (TARGET_H8300H && val == 4) + for TARGET_H8300H or TARGET_H8300S. */ + if ((TARGET_H8300H || TARGET_H8300S) + && val == 4) return "adds #4,%A0"; - if (TARGET_H8300H && val == -4) + if ((TARGET_H8300H || TARGET_H8300S) + && val == -4) return "subs #4,%A0"; if (val > 2) @@ -851,7 +972,7 @@ const_costs (r, c) return 0; case 4: case -4: - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) return 0; else return 1; @@ -1211,13 +1332,15 @@ print_operand (file, x, code) if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", INTVAL (x) & 0xff); else - fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 2 : 0)); + fprintf (file, "%s", + byte_reg (x, TARGET_H8300 ? 2 : 0)); break; case 'x': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff); else - fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 3 : 1)); + fprintf (file, "%s", + byte_reg (x, TARGET_H8300 ? 3 : 1)); break; case 'y': if (GET_CODE (x) == CONST_INT) @@ -2414,7 +2537,7 @@ output_simode_bld (bild, log2, operands) rtx operands[]; { /* Clear the destination register. */ - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) output_asm_insn ("sub.l\t%S0,%S0", operands); else output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands); @@ -2464,14 +2587,15 @@ h8300_adjust_insn_length (insn, length) if (TARGET_H8300 && GET_CODE (addr) == REG) return -2; - /* On the H8/300H, register indirect is 6 bytes shorter than + /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than indicated in the machine description. */ - if (TARGET_H8300H && GET_CODE (addr) == REG) + if ((TARGET_H8300H || TARGET_H8300S) + && GET_CODE (addr) == REG) return -6; - /* On the H8/300H, reg + d, for small displacements is 4 bytes - shorter than indicated in the machine description. */ - if (TARGET_H8300H + /* On the H8/300H and H8/300S, reg + d, for small displacements is 4 + bytes shorter than indicated in the machine description. */ + if ((TARGET_H8300H || TARGET_H8300S) && GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 0)) == REG && GET_CODE (XEXP (addr, 1)) == CONST_INT @@ -2479,9 +2603,9 @@ h8300_adjust_insn_length (insn, length) && INTVAL (XEXP (addr, 1)) < 32767) return -4; - /* On the H8/300H, abs:16 is two bytes shorter than the + /* On the H8/300H and H8/300S, abs:16 is two bytes shorter than the more general abs:24. */ - if (TARGET_H8300H + if ((TARGET_H8300H || TARGET_H8300S) && GET_CODE (addr) == SYMBOL_REF && TINY_DATA_NAME_P (XSTR (addr, 0))) return -2; @@ -2498,7 +2622,7 @@ h8300_adjust_insn_length (insn, length) || ((INTVAL (SET_SRC (pat)) >> 16) & 0xffff) == 0)) return -2; - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) { int val = INTVAL (SET_SRC (pat)); @@ -2531,8 +2655,8 @@ h8300_adjust_insn_length (insn, length) return -(20 - INTVAL (XEXP (src, 1)) * 2); /* Similarly for HImode and SImode shifts by - small constants on the H8/300H. */ - if (TARGET_H8300H + small constants on the H8/300H and H8/300S. */ + if ((TARGET_H8300H || TARGET_H8300S) && (mode == HImode || mode == SImode) && INTVAL (XEXP (src, 1)) <= 4) return -(20 - INTVAL (XEXP (src, 1)) * 2); diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 2e5b78d..76efc06 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -39,13 +39,16 @@ extern char **h8_reg_names; "-D__LONG_MAX__=2147483647L -D__LONG_LONG_MAX__=2147483647L" #define CPP_SPEC \ - "%{!mh:-D__H8300__} %{mh:-D__H8300H__} \ - %{!mh:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \ + "%{!mh:%{!ms:-D__H8300__}} %{mh:-D__H8300H__} %{ms:-D__H8300S__} \ + %{!mh:%{!ms:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}} \ %{mh:-D__SIZE_TYPE__=unsigned\\ long -D__PTRDIFF_TYPE__=long} \ - %{!mh:-Acpu(h8300) -Amachine(h8300)} %{mh:-Acpu(h8300h) -Amachine(h8300h)} \ + %{ms:-D__SIZE_TYPE__=unsigned\\ long -D__PTRDIFF_TYPE__=long} \ + %{!mh:%{!ms:-Acpu(h8300) -Amachine(h8300)}} \ + %{mh:-Acpu(h8300h) -Amachine(h8300h)} \ + %{ms:-Acpu(h8300s) -Amachine(h8300s)} \ %{!mint32:-D__INT_MAX__=32767} %{mint32:-D__INT_MAX__=2147483647}" -#define LINK_SPEC "%{mh:-m h8300h}" +#define LINK_SPEC "%{mh:-m h8300h} %{ms:-m h8300s}" #define LIB_SPEC "%{mrelax:-relax} %{g:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" @@ -77,8 +80,9 @@ extern int target_flags; #define TARGET_RTL_DUMP (target_flags & 2048) /* Select between the h8/300 and h8/300h cpus. */ -#define TARGET_H8300 (! TARGET_H8300H) +#define TARGET_H8300 (! TARGET_H8300H && ! TARGET_H8300S) #define TARGET_H8300H (target_flags & 4096) +#define TARGET_H8300S (target_flags & 1) /* Align all values on the h8/300h the same way as the h8/300. Specifically, 32 bit and larger values are aligned on 16 bit boundaries. @@ -94,7 +98,9 @@ extern int target_flags; An empty string NAME is used to identify the default VALUE. */ #define TARGET_SWITCHES \ - { {"int32",8}, \ + { {"s",1 }, \ + {"no-s",-1}, \ + {"int32",8}, \ {"addresses",64 }, \ {"quickcall",128}, \ {"no-quickcall",-128}, \ @@ -160,16 +166,16 @@ do { \ Note that this is not necessarily the width of data type `int'; if using 16-bit ints on a 68000, this would still be 32. But on a machine with 16-bit registers, this would be 16. */ -#define BITS_PER_WORD (TARGET_H8300H ? 32 : 16) +#define BITS_PER_WORD (TARGET_H8300H || TARGET_H8300S ? 32 : 16) #define MAX_BITS_PER_WORD 32 /* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD (TARGET_H8300H ? 4 : 2) +#define UNITS_PER_WORD (TARGET_H8300H || TARGET_H8300S ? 4 : 2) #define MIN_UNITS_PER_WORD 2 /* Width in bits of a pointer. See also the macro `Pmode' defined below. */ -#define POINTER_SIZE (TARGET_H8300H ? 32 : 16) +#define POINTER_SIZE (TARGET_H8300H || TARGET_H8300S ? 32 : 16) #define SHORT_TYPE_SIZE 16 #define INT_TYPE_SIZE (TARGET_INT32 ? 32 : 16) @@ -182,7 +188,7 @@ do { \ #define MAX_FIXED_MODE_SIZE 32 /* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY (TARGET_H8300H ? 32 : 16) +#define PARM_BOUNDARY (TARGET_H8300H || TARGET_H8300S ? 32 : 16) /* Allocation boundary (in *bits*) for the code of a function. */ #define FUNCTION_BOUNDARY 16 @@ -199,11 +205,11 @@ do { \ /* No data type wants to be aligned rounder than this. 32 bit values are aligned as such on the 300h for speed. */ #define BIGGEST_ALIGNMENT \ -((TARGET_H8300H && ! TARGET_ALIGN_300) ? 32 : 16) +(((TARGET_H8300H || TARGET_H8300S) && ! TARGET_ALIGN_300) ? 32 : 16) /* No structure field wants to be aligned rounder than this. */ #define BIGGEST_FIELD_ALIGNMENT \ -((TARGET_H8300H && ! TARGET_ALIGN_300) ? 32 : 16) +(((TARGET_H8300H || TARGET_H8300S) && ! TARGET_ALIGN_300) ? 32 : 16) /* The stack goes in 16/32 bit lumps. */ #define STACK_BOUNDARY (TARGET_H8300 ? 16 : 32) @@ -699,10 +705,10 @@ struct rtx_def *function_arg(); #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ { \ - enum machine_mode mode = TARGET_H8300H ? SImode : HImode; \ - emit_move_insn (gen_rtx (MEM, mode, plus_constant ((TRAMP), 2)), CXT); \ - emit_move_insn (gen_rtx (MEM, mode, plus_constant ((TRAMP), 6)), FNADDR); \ - if (TARGET_H8300H) \ + enum machine_mode mode = TARGET_H8300H || TARGET_H8300S? SImode : HImode; \ + emit_move_insn (gen_rtx (MEM, mode, plus_constant ((TRAMP), 2)), CXT); \ + emit_move_insn (gen_rtx (MEM, mode, plus_constant ((TRAMP), 6)), FNADDR); \ + if (TARGET_H8300H || TARGET_H8300S) \ emit_move_insn (gen_rtx (MEM, QImode, plus_constant ((TRAMP), 6)), GEN_INT (0x5A)); \ } @@ -886,7 +892,7 @@ struct rtx_def *function_arg(); /* Max number of bytes we can move from memory to memory in one reasonably fast instruction. */ -#define MOVE_MAX (TARGET_H8300H ? 4 : 2) +#define MOVE_MAX (TARGET_H8300H || TARGET_H8300S ? 4 : 2) #define MAX_MOVE_MAX 4 /* Define this if zero-extension is slow (more than one real instruction). */ @@ -907,7 +913,7 @@ struct rtx_def *function_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 ? SImode : HImode) +#define Pmode (TARGET_H8300H || TARGET_H8300S ? SImode : HImode) /* ANSI C types. We use longs for the 300h because ints can be 16 or 32. diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 911295e..a1709ef 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -238,7 +238,7 @@ if (do_movsi (operands)) DONE; } - else /* TARGET_H8300H */ + else { /* One of the ops has to be in a register. */ if (!register_operand (operand1, SImode) @@ -260,7 +260,7 @@ if (do_movsi (operands)) DONE; } - else /* TARGET_H8300H */ + else { /* One of the ops has to be in a register. */ if (!register_operand (operand1, SFmode) @@ -398,7 +398,7 @@ (define_insn "movsi_h8300h" [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,m,<,r") (match_operand:SI 1 "general_operand_src" "I,r,im,r,r,>"))] - "TARGET_H8300H + "(TARGET_H8300H || TARGET_H8300S) && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" "* @@ -439,7 +439,7 @@ (define_insn "movsf_h8300h" [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r") (match_operand:SF 1 "general_operand_src" "I,r,im,r,r,>"))] - "TARGET_H8300H + "(TARGET_H8300H || TARGET_H8300S) && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" "@ @@ -526,7 +526,7 @@ (define_insn "tstsi" [(set (cc0) (match_operand:SI 0 "register_operand" "r"))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "mov.l %S0,%S0" [(set_attr "length" "2") (set_attr "cc" "set")]) @@ -549,7 +549,7 @@ { /* Force operand1 into a register if we're compiling for the h8/300. */ - if (GET_CODE (operands[1]) != REG && !TARGET_H8300H) + if (GET_CODE (operands[1]) != REG && TARGET_H8300) operands[1] = force_reg (HImode, operands[1]); }") @@ -566,7 +566,7 @@ [(set (cc0) (compare:HI (match_operand:HI 0 "register_operand" "r,r") (match_operand:HI 1 "nonmemory_operand" "r,n")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "cmp.w %T1,%T0" [(set_attr "length" "2,4") (set_attr "cc" "compare,compare")]) @@ -575,7 +575,7 @@ [(set (cc0) (compare:SI (match_operand:SI 0 "register_operand" "r,r") (match_operand:SI 1 "nonmemory_operand" "r,i")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "cmp.l %S1,%S0" [(set_attr "length" "2,6") (set_attr "cc" "compare,compare")]) @@ -631,7 +631,7 @@ [(set (match_operand:HI 0 "register_operand" "=r,r") (plus:HI (match_operand:HI 1 "register_operand" "%0,0") (match_operand:HI 2 "nonmemory_operand" "n,r")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "@ add.w %T2,%T0 add.w %T2,%T0" @@ -651,7 +651,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_operand:SI 1 "register_operand" "%0") (match_operand:SI 2 "adds_subs_operand" "n")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "* return output_adds_subs (operands);" [(set_attr "cc" "none_0hit") (set (attr "length") @@ -676,7 +676,7 @@ [(set (match_operand:SI 0 "register_operand" "=r,r") (plus:SI (match_operand:SI 1 "register_operand" "%0,0") (match_operand:SI 2 "nonmemory_operand" "i,r")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "@ add.l %S2,%S0 add.l %S2,%S0" @@ -740,7 +740,7 @@ [(set (match_operand:HI 0 "register_operand" "=r,&r") (minus:HI (match_operand:HI 1 "general_operand" "0,0") (match_operand:HI 2 "nonmemory_operand" "r,n")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "@ sub.w %T2,%T0 sub.w %T2,%T0" @@ -770,7 +770,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "general_operand" "0") (match_operand:SI 2 "adds_subs_operand" "n")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "* { operands[2] = GEN_INT (-INTVAL (operands[2])); @@ -787,7 +787,7 @@ [(set (match_operand:SI 0 "register_operand" "=r,r") (minus:SI (match_operand:SI 1 "general_operand" "0,0") (match_operand:SI 2 "nonmemory_operand" "r,i")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "@ sub.l %S2,%S0 sub.l %S2,%S0" @@ -804,7 +804,7 @@ [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%0")) (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "mulxs.b %X2,%T0" [(set_attr "length" "4") (set_attr "cc" "set_zn_c0")]) @@ -813,7 +813,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "%0")) (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "mulxs.w %T2,%S0" [(set_attr "length" "4") (set_attr "cc" "set_zn_c0")]) @@ -831,7 +831,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "%0")) (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "mulxu.w %T2,%S0" [(set_attr "length" "2") (set_attr "cc" "none_0hit")]) @@ -870,7 +870,7 @@ (udiv:SI (match_operand:SI 1 "general_operand" "0") (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "divxu.w %T2,%S0" [(set_attr "length" "2") (set_attr "cc" "clobber")]) @@ -881,7 +881,7 @@ (div:SI (match_operand:SI 1 "general_operand" "0") (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "divxs.w %T2,%S0" [(set_attr "length" "4") (set_attr "cc" "clobber")]) @@ -907,7 +907,7 @@ (mod:HI (match_operand:HI 1 "general_operand" "0") (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "divxs.b %X2,%T0\;mov %t0,%s0" [(set_attr "length" "6") (set_attr "cc" "clobber")]) @@ -918,7 +918,7 @@ (umod:SI (match_operand:SI 1 "general_operand" "0") (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "divxu.w %T2,%S0\;mov %e0,%f0" [(set_attr "length" "4") (set_attr "cc" "clobber")]) @@ -929,7 +929,7 @@ (mod:SI (match_operand:SI 1 "general_operand" "0") (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "divxs.w %T2,%S0\;mov %e0,%f0" [(set_attr "length" "6") (set_attr "cc" "clobber")]) @@ -977,7 +977,7 @@ output_asm_insn (\"and %t2,%t0\", operands); return \"\"; } - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) return \"and.w %T2,%T0\"; return \"and %s2,%s0\;and %t2,%t0;\"; }" @@ -1001,7 +1001,7 @@ those bits aren't going to change, or they're going to be zero'd out, then we can work on the low-order bits. */ - if (TARGET_H8300H + if ((TARGET_H8300H || TARGET_H8300S) && ((i & 0xffff0000) != 0xffff0000 || (i & 0xffff0000) == 0x00000000)) return \"and.l %S2,%S0\"; @@ -1030,7 +1030,7 @@ output_asm_insn (\"and %z2,%z0\", operands); return \"\"; } - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) return \"and.l %S2,%S0\"; return \"and %w2,%w0\;and %x2,%x0\;and %y2,%y0\;and %z2,%z0\;\"; }" @@ -1081,7 +1081,7 @@ output_asm_insn (\"or %t2,%t0\", operands); return \"\"; } - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) return \"or.w %T2,%T0\"; return \"or %s2,%s0\;or %t2,%t0; %2 or2\"; }" @@ -1103,7 +1103,7 @@ upper 16bits of 32bit registers. However, if those bits aren't going to change, then we can work on the low-order bits. */ - if (TARGET_H8300H + if ((TARGET_H8300H || TARGET_H8300S) && (i & 0xffff0000) != 0x00000000) return \"or.l %S2,%S0\"; @@ -1117,7 +1117,7 @@ output_asm_insn (\"or %z2,%z0\", operands); return \"\"; } - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) return \"or.l %S2,%S0\"; return \"or %w2,%w0\;or %x2,%x0\;or %y2,%y0\;or %z2,%z0\;\"; }" @@ -1167,7 +1167,7 @@ output_asm_insn (\"xor %t2,%t0\", operands); return \"\"; } - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) return \"xor.w %T2,%T0\"; return \"xor %s2,%s0\;xor %t2,%t0\"; }" @@ -1189,7 +1189,7 @@ upper 16bits of 32bit registers. However, if those bits aren't going to change, then we can work on the low-order bits. */ - if (TARGET_H8300H + if ((TARGET_H8300H || TARGET_H8300S) && (i & 0xffff0000) != 0x00000000) return \"xor.l %S2,%S0\"; @@ -1203,7 +1203,7 @@ output_asm_insn (\"xor %z2,%z0\", operands); return \"\"; } - if (TARGET_H8300H) + if (TARGET_H8300H || TARGET_H8300S) return \"xor.l %S2,%S0\"; return \"xor %w2,%w0\;xor %x2,%x0\;xor %y2,%y0\;xor %z2,%z0\;\"; }" @@ -1247,7 +1247,7 @@ (define_insn "neghi2_h8300h" [(set (match_operand:HI 0 "register_operand" "=r") (neg:HI (match_operand:HI 1 "general_operand" "0")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "neg %T0" [(set_attr "length" "2") (set_attr "cc" "set_zn_c0")]) @@ -1277,7 +1277,7 @@ (define_insn "negsi2_h8300h" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operand:SI 1 "general_operand" "0")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "neg %S0" [(set_attr "length" "2") (set_attr "cc" "set_zn_c0")]) @@ -1307,7 +1307,8 @@ }" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 4) (const_int 2)))]) @@ -1324,7 +1325,8 @@ }" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 8) (const_int 2)))]) @@ -1510,7 +1512,7 @@ (define_insn "tablejump_h8300h" [(set (pc) (match_operand:SI 0 "register_operand" "r")) (use (label_ref (match_operand 1 "" "")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "jmp @%0" [(set_attr "cc" "none") (set_attr "length" "2")]) @@ -1531,7 +1533,7 @@ (define_insn "indirect_jump_h8300h" [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "jmp @%0" [(set_attr "cc" "none") (set_attr "length" "2")]) @@ -1654,7 +1656,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "@ extu.l %S0 mov.w %T1,%T0\;extu.l %S0" @@ -1680,7 +1682,7 @@ (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r,r") (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "@ exts.w %T0 mov.b %R1,%s0\;exts.w %T0" @@ -1737,7 +1739,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300H" + "TARGET_H8300H || TARGET_H8300S" "@ exts.l %S0 mov.w %T1,%T0\;exts.l %S0" @@ -1957,7 +1959,8 @@ (match_operand:SI 1 "bit_operand" "Ur") (match_operand:SI 2 "const_int_operand" "n")) 0)) (const_int 1)))] - "TARGET_H8300H && INTVAL (operands[2]) < 16" + "(TARGET_H8300H || TARGET_H8300S) + && INTVAL (operands[2]) < 16" "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" [(set_attr "cc" "clobber") (set_attr "length" "8")]) @@ -1976,7 +1979,8 @@ "* return output_simode_bld (0, 0, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) @@ -1991,7 +1995,8 @@ "* return output_simode_bld (0, 0, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) @@ -2006,7 +2011,8 @@ "* return output_simode_bld (0, 0, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) @@ -2024,7 +2030,8 @@ "* return output_simode_bld (1, 1, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) (define_insn "" @@ -2038,7 +2045,8 @@ "* return output_simode_bld (1, 0, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) @@ -2051,7 +2059,8 @@ "* return output_simode_bld (1, 1, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) (define_insn "" @@ -2065,7 +2074,8 @@ "* return output_simode_bld (1, 0, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) @@ -2081,7 +2091,8 @@ "* return output_simode_bld (1, 0, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) @@ -2097,7 +2108,8 @@ "* return output_simode_bld (1, 0, operands);" [(set_attr "cc" "clobber") (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") + (const_int 0)) (const_int 10) (const_int 8)))]) diff --git a/gcc/config/h8300/lib1funcs.asm b/gcc/config/h8300/lib1funcs.asm index c52bcff..4179a74 100644 --- a/gcc/config/h8300/lib1funcs.asm +++ b/gcc/config/h8300/lib1funcs.asm @@ -80,7 +80,7 @@ Boston, MA 02111-1307, USA. */ #define S2P r6 #endif -#ifdef __H8300H__ +#if defined (__H8300H__) || defined (__H8300S__) #define MOVP mov.l /* pointers are 32 bits */ #define ADDP add.l #define CMPP cmp.l @@ -314,6 +314,10 @@ setbit: inc A0L ; do insert bit .h8300h #endif +#ifdef __H8300S__ + .h8300s +#endif + .section .text .align 2 @@ -738,7 +742,13 @@ _done: #else /* __H8300H__ */ +#ifdef __H8300H__ .h8300h +#endif + +#ifdef __H8300S__ + .h8300s +#endif .global ___mulsi3 ___mulsi3: diff --git a/gcc/config/h8300/t-h8300 b/gcc/config/h8300/t-h8300 index fb4ced6..236ebcc 100644 --- a/gcc/config/h8300/t-h8300 +++ b/gcc/config/h8300/t-h8300 @@ -18,8 +18,8 @@ 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 mint32 -MULTILIB_DIRNAMES = h8300h int32 +MULTILIB_OPTIONS = mh/ms mint32 +MULTILIB_DIRNAMES = h8300h h8300s int32 LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib |