Commit ac3ebe93 by Nathan Sidwell Committed by Nathan Sidwell

ms1.md (UNSPEC_LOOP): New constant.

	* config/ms1/ms1.md (UNSPEC_LOOP): New constant.
	(loop_end, loop_init, doloop_end): New insns.
	* config/ms1/ms1.h (LOOP_FIRST, LOOP_LAST): New.
	(SPECIAL_REG_FIRST, FIRST_PSEUDO_REGISTER): Adjust.
	(FIXED_REGISTERS, CALL_USED_REGISTERS): Adjust.
	(REG_CLASS_CONTENTS, REGISTER_NAMES): Adjust.
	* config/ms1/ms1.c: #include basic-block.h
	(struct machine_function): Add has_loops field.
	(ms1_add_loop): New.
	(MAX_LOOP_DEPTH, MAX_LOO_LENGTH): New.
	(struct loop_info, struct loop_work): New.
	(ms1_loop_nesting, ms1_block_length, ms1_scan_loop): New workers.
	(ms1_reorg_loops): New loop optimization.
	(ms1_machine_reorg): Call it.
	* config/ms1/ms1-protos.h (ms1_add_loop): Declare.

From-SVN: r108229
parent bc9053ab
2005-12-08 Nathan Sidwell <nathan@codesourcery.com>
* config/ms1/ms1.md (UNSPEC_LOOP): New constant.
(loop_end, loop_init, doloop_end): New insns.
* config/ms1/ms1.h (LOOP_FIRST, LOOP_LAST): New.
(SPECIAL_REG_FIRST, FIRST_PSEUDO_REGISTER): Adjust.
(FIXED_REGISTERS, CALL_USED_REGISTERS): Adjust.
(REG_CLASS_CONTENTS, REGISTER_NAMES): Adjust.
* config/ms1/ms1.c: #include basic-block.h
(struct machine_function): Add has_loops field.
(ms1_add_loop): New.
(MAX_LOOP_DEPTH, MAX_LOO_LENGTH): New.
(struct loop_info, struct loop_work): New.
(ms1_loop_nesting, ms1_block_length, ms1_scan_loop): New workers.
(ms1_reorg_loops): New loop optimization.
(ms1_machine_reorg): Call it.
* config/ms1/ms1-protos.h (ms1_add_loop): Declare.
2005-12-08 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/25248
......
......@@ -26,6 +26,7 @@ extern void ms1_override_options (void);
extern int ms1_initial_elimination_offset (int, int);
extern const char * ms1_asm_output_opcode (FILE *, const char *);
extern int ms1_epilogue_uses (int);
extern void ms1_add_loop (void);
#ifdef TREE_CODE
extern const char * ms1_cannot_inline_p (tree);
......
......@@ -41,7 +41,7 @@ extern enum processor_type ms1_cpu;
/* A C string constant that tells the GCC driver program options to pass to
the assembler. */
#undef ASM_SPEC
#define ASM_SPEC "%{march=*} %{!march=*: -march=ms1-16-002}"
#define ASM_SPEC "%{march=*} %{!march=*: -march=ms2}"
/* A string to pass to at the end of the command given to the linker. */
#undef LIB_SPEC
......@@ -55,7 +55,7 @@ march=ms1-16-003:-T 16-003.ld%s; \
march=MS1-16-003:-T 16-003.ld%s; \
march=ms2:-T ms2.ld%s; \
march=MS2:-T ms2.ld%s; \
: -T 16-002.ld}"
: -T ms2.ld}"
/* A string to pass at the very beginning of the command given to the
linker. */
......@@ -69,7 +69,7 @@ march=ms1-16-003:%{!mno-crt0:crt0-16-003.o%s} startup-16-003.o%s; \
march=MS1-16-003:%{!mno-crt0:crt0-16-003.o%s} startup-16-003.o%s; \
march=ms2:%{!mno-crt0:crt0-ms2.o%s} startup-ms2.o%s; \
march=MS2:%{!mno-crt0:crt0-ms2.o%s} startup-ms2.o%s; \
:%{!mno-crt0:crt0-16-002.o%s} startup-16-002.o%s} \
:%{!mno-crt0:crt0-ms2.o%s} startup-ms2.o%s} \
crti.o%s crtbegin.o%s"
/* A string to pass at the end of the command given to the linker. */
......@@ -83,7 +83,7 @@ march=ms1-16-003:exit-16-003.o%s; \
march=MS1-16-003:exit-16-003.o%s; \
march=ms2:exit-ms2.o%s; \
march=MS2:exit-ms2.o%s; \
:exit-16-002.o%s} \
:exit-ms2.o%s} \
crtend.o%s crtn.o%s"
/* Run-time target specifications. */
......@@ -243,10 +243,13 @@ march=MS2:exit-ms2.o%s; \
seen by the caller */
#define GPR_INTERRUPT_LINK 15 /* hold return addres for interrupts */
#define LOOP_FIRST (GPR_LAST + 1)
#define LOOP_LAST (LOOP_FIRST + 3)
/* Argument register that is eliminated in favor of the frame and/or stack
pointer. Also add register to point to where the return address is
stored. */
#define SPECIAL_REG_FIRST (GPR_LAST + 1)
#define SPECIAL_REG_FIRST (LOOP_LAST + 1)
#define SPECIAL_REG_LAST (SPECIAL_REG_FIRST)
#define ARG_POINTER_REGNUM (SPECIAL_REG_FIRST + 0)
#define SPECIAL_REG_P(R) ((R) == SPECIAL_REG_FIRST)
......@@ -258,7 +261,7 @@ march=MS2:exit-ms2.o%s; \
/* The register used to hold functions return value */
#define RETVAL_REGNUM 11
#define FIRST_PSEUDO_REGISTER (GPR_FIRST + 17)
#define FIRST_PSEUDO_REGISTER (SPECIAL_REG_LAST + 1)
#define IS_PSEUDO_P(R) (REGNO (R) >= FIRST_PSEUDO_REGISTER)
......@@ -270,7 +273,7 @@ march=MS2:exit-ms2.o%s; \
R15 IRA interrupt return address. */
#define FIXED_REGISTERS { 1, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 1, 1, 1, 1, \
1 \
1, 1, 1, 1, 1 \
}
/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
......@@ -279,7 +282,7 @@ march=MS2:exit-ms2.o%s; \
allocation of values that must live across function calls. */
#define CALL_USED_REGISTERS { 1, 1, 1, 1, 1, 0, 0, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
1 \
1, 1, 1, 1, 1 \
}
......@@ -310,9 +313,9 @@ enum reg_class
#define REG_CLASS_NAMES {"NO_REGS", "ALL_REGS" }
#define REG_CLASS_CONTENTS \
{ \
{ 0x0, 0x0 }, \
{ (((1 << (GPR_LAST + 1)) - 1) & ~(1 << GPR_FIRST)), 0x0 }, \
{ \
{ 0x0 }, \
{ 0x000fffff }, \
}
/* A C expression whose value is a register class containing hard register
......@@ -736,7 +739,7 @@ extern struct ms1_frame_info current_frame_info;
#define REGISTER_NAMES \
{ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \
"R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", \
"ap" }
"LOOP1", "LOOP2", "LOOP3", "LOOP4", "ap" }
/* If defined, a C initializer for an array of structures containing a name and
a register number. This macro defines additional names for hard registers,
......
......@@ -25,6 +25,7 @@
(UNSPEC_BLOCKAGE 0)
(UNSPEC_EI 1)
(UNSPEC_DI 2)
(UNSPEC_LOOP 3)
])
;; Attributes
......@@ -148,6 +149,58 @@
"")
;; Loop instructions. ms2 has a low overhead looping instructions.
;; these take a constant or register loop count and a loop length
;; offset. Unfortunately the loop can only be up to 256 instructions,
;; We deal with longer loops by moving the loop end upwards. To do
;; otherwise would force us to to be very pessimistic right up until
;; the end.
;; This instruction is a placeholder to make the control flow explicit.
(define_insn "loop_end"
[(set (pc) (if_then_else
(ne (match_operand:SI 0 "register_operand" "")
(const_int 1))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
(unspec [(const_int 0)] UNSPEC_LOOP)]
"TARGET_MS2"
";loop end %0,%l1"
[(set_attr "length" "0")])
;; This is the real looping instruction. It is placed just before the
;; loop body. We make it a branch insn, so it stays at the end of the
;; block it is in.
(define_insn "loop_init"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(match_operand:SI 1 "uns_arith_operand" "r,K"))
(unspec [(label_ref (match_operand 2 "" ""))] UNSPEC_LOOP)]
"TARGET_MS2"
"@
loop %1,%l2 ;%0%#
loopi %1,%l2 ;%0%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
; operand 0 is the loop count pseudo register
; operand 1 is the number of loop iterations or 0 if it is unknown
; operand 2 is the maximum number of loop iterations
; operand 3 is the number of levels of enclosed loops
; operand 4 is the label to jump to at the top of the loop
(define_expand "doloop_end"
[(parallel [(set (pc) (if_then_else
(ne (match_operand:SI 0 "nonimmediate_operand" "")
(const_int 0))
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))
(clobber (match_scratch:SI 5 ""))])]
"TARGET_MS1_16_003 || TARGET_MS2"
{ms1_add_loop ();})
;; Moves
(define_expand "loadqi"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment