Add ms2 support

Add ms2 support
	* config/ms1/ms1.md (UNSPEC_BLOCKAGE, UNSPEC_EI, UNSPEC_DI): New
	constants.
	(call,load,store): New insn types.
	(mem_access, branch_access): Adjust reservation conditions.
	(define_delay): Adjust condition.
	(decrement_and_branch_until_zero): Allow for ms2.  Set branch
	type.
	(*decrement_and_rbanch_until_zero_no_clobber): Allow for ms2.
	(*movqi_internal,*movsi_internal,*movsf_internal): Use load,store
	insn type.
	(call_internal, call_value_internal, return_internal,
	return_interrupt_internal, eh_return_internal, indirect_jump,
	tablejump): Set call insn type.
	(blockage, ei, di): Use appropriate unspec const.
	* config/ms1/ms1.c (ms1_flag_delayed_branch): New.
	(ms1_get_attr_type): Adjust to give load & store types.
	(ms1_final_prescan_insn): Adjust for new insn types.  Don't look
	backwards past a barrier.
	(ms1_override_options): Accept ms2 arch.  Copy and reset delayed
	branch scheduling.
	(struct branch_info, struct label_info): New.
	(ms1_labels): New.
	(ms1_add_branches, ms1_check_delay_slot, ms1_reorg_hazard): New.
	(ms1_machine_reorg): New.
	(TARGET_MACHINE_DEPENDENT_REORG): Override.
	* config/ms1/crtn.asm: Add nop for ms2 JAL hazard.
	* config/ms1/ms1.h (processor_type): Add PROCESSOR_MS2.
	(ASM_SPEC, LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): Add ms2.
	(TARGET_MS2): New.

From-SVN: r106680
This commit is contained in:
Nathan Sidwell 2005-11-09 09:34:21 +00:00 committed by Nathan Sidwell
parent 456b8ce5db
commit 1508cc4663
5 changed files with 440 additions and 58 deletions

View File

@ -1,3 +1,36 @@
2005-11-09 Nathan Sidwell <nathan@codesourcery.com>
Add ms2 support
* config/ms1/ms1.md (UNSPEC_BLOCKAGE, UNSPEC_EI, UNSPEC_DI): New
constants.
(call,load,store): New insn types.
(mem_access, branch_access): Adjust reservation conditions.
(define_delay): Adjust condition.
(decrement_and_branch_until_zero): Allow for ms2. Set branch
type.
(*decrement_and_rbanch_until_zero_no_clobber): Allow for ms2.
(*movqi_internal,*movsi_internal,*movsf_internal): Use load,store
insn type.
(call_internal, call_value_internal, return_internal,
return_interrupt_internal, eh_return_internal, indirect_jump,
tablejump): Set call insn type.
(blockage, ei, di): Use appropriate unspec const.
* config/ms1/ms1.c (ms1_flag_delayed_branch): New.
(ms1_get_attr_type): Adjust to give load & store types.
(ms1_final_prescan_insn): Adjust for new insn types. Don't look
backwards past a barrier.
(ms1_override_options): Accept ms2 arch. Copy and reset delayed
branch scheduling.
(struct branch_info, struct label_info): New.
(ms1_labels): New.
(ms1_add_branches, ms1_check_delay_slot, ms1_reorg_hazard): New.
(ms1_machine_reorg): New.
(TARGET_MACHINE_DEPENDENT_REORG): Override.
* config/ms1/crtn.asm: Add nop for ms2 JAL hazard.
* config/ms1/ms1.h (processor_type): Add PROCESSOR_MS2.
(ASM_SPEC, LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): Add ms2.
(TARGET_MS2): New.
2005-11-09 Per Bothner <per@bothner.com>
Uros Bizjak <uros@kss-loka.si>

View File

@ -42,6 +42,7 @@
.align 4
ldw r14, sp, #0
addi sp, sp, #4
nop
jal r0, r14
or r0, r0, r0
@ -50,5 +51,6 @@
ldw r14, sp, #0
addi sp, sp, #4
nop
jal r0, r14
or r0, r0, r0

View File

@ -84,6 +84,8 @@ struct ms1_frame_info zero_frame_info;
/* ms1 doesn't have unsigned compares need a library call for this. */
struct rtx_def * ms1_ucmpsi3_libcall;
static int ms1_flag_delayed_branch;
static rtx
ms1_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED,
@ -125,13 +127,6 @@ ms1_asm_output_opcode (FILE *f ATTRIBUTE_UNUSED, const char *ptr)
return ptr;
}
/* Return TRUE if INSN is a memory load. */
static bool
ms1_memory_load (rtx insn)
{
return ((GET_CODE (insn) == SET) && (GET_CODE (XEXP (insn,1)) == MEM));
}
/* Given an insn, return whether it's a memory operation or a branch
operation, otherwise return TYPE_ARITH. */
static enum attr_type
@ -139,18 +134,24 @@ ms1_get_attr_type (rtx complete_insn)
{
rtx insn = PATTERN (complete_insn);
if ((GET_CODE (insn) == SET)
&& ((GET_CODE (XEXP (insn, 0)) == MEM)
|| (GET_CODE (XEXP (insn, 1)) == MEM)))
return TYPE_MEM;
else if (((GET_CODE (insn) == SET) && (XEXP (insn, 0) == pc_rtx))
|| (GET_CODE (complete_insn) == JUMP_INSN)
|| (GET_CODE (complete_insn) == CALL_INSN))
if (JUMP_P (complete_insn))
return TYPE_BRANCH;
if (CALL_P (complete_insn))
return TYPE_BRANCH;
else
if (GET_CODE (insn) != SET)
return TYPE_ARITH;
if (SET_DEST (insn) == pc_rtx)
return TYPE_BRANCH;
if (GET_CODE (SET_DEST (insn)) == MEM)
return TYPE_STORE;
if (GET_CODE (SET_SRC (insn)) == MEM)
return TYPE_LOAD;
return TYPE_ARITH;
}
/* A helper routine for insn_dependent_p called through note_stores. */
@ -212,35 +213,48 @@ ms1_final_prescan_insn (rtx insn,
int noperands ATTRIBUTE_UNUSED)
{
rtx prev_i;
enum attr_type prev_attr;
ms1_nops_required = 0;
ms1_nop_reasons = "";
/* ms2 constraints are dealt with in reorg. */
if (ms1_cpu == PROCESSOR_MS2)
return;
/* Only worry about real instructions. */
if (! INSN_P (insn))
return;
/* Find the previous real instructions. */
prev_i = PREV_INSN (insn);
while (prev_i != NULL
for (prev_i = PREV_INSN (insn);
prev_i != NULL
&& (! INSN_P (prev_i)
|| GET_CODE (PATTERN (prev_i)) == USE
|| GET_CODE (PATTERN (prev_i)) == CLOBBER))
prev_i = PREV_INSN (prev_i);
|| GET_CODE (PATTERN (prev_i)) == CLOBBER);
prev_i = PREV_INSN (prev_i))
{
/* If we meet a barrier, there is no flow through here. */
if (BARRIER_P (prev_i))
return;
}
/* If there isn't one then there is nothing that we need do. */
if (prev_i == NULL || ! INSN_P (prev_i))
return;
prev_attr = ms1_get_attr_type (prev_i);
/* Delayed branch slots already taken care of by delay branch scheduling. */
if (ms1_get_attr_type (prev_i) == TYPE_BRANCH)
if (prev_attr == TYPE_BRANCH)
return;
switch (ms1_get_attr_type (insn))
{
case TYPE_MEM:
case TYPE_LOAD:
case TYPE_STORE:
/* Avoid consecutive memory operation. */
if (ms1_get_attr_type (prev_i) == TYPE_MEM
if ((prev_attr == TYPE_LOAD || prev_attr == TYPE_STORE)
&& ms1_cpu == PROCESSOR_MS1_64_001)
{
ms1_nops_required = 1;
@ -252,7 +266,7 @@ ms1_final_prescan_insn (rtx insn,
case TYPE_COMPLEX:
/* One cycle of delay is required between load
and the dependent arithmetic instruction. */
if (ms1_memory_load (PATTERN (prev_i))
if (prev_attr == TYPE_LOAD
&& insn_true_dependent_p (prev_i, insn))
{
ms1_nops_required = 1;
@ -263,7 +277,7 @@ ms1_final_prescan_insn (rtx insn,
case TYPE_BRANCH:
if (insn_dependent_p (prev_i, insn))
{
if (ms1_get_attr_type (prev_i) == TYPE_ARITH
if (prev_attr == TYPE_ARITH
&& ms1_cpu == PROCESSOR_MS1_64_001)
{
/* One cycle of delay between arith
@ -271,7 +285,7 @@ ms1_final_prescan_insn (rtx insn,
ms1_nops_required = 1;
ms1_nop_reasons = "arith->branch dependency delay";
}
else if (ms1_memory_load (PATTERN (prev_i)))
else if (prev_attr == TYPE_LOAD)
{
/* Two cycles of delay are required
between load and dependent branch. */
@ -790,10 +804,9 @@ ms1_override_options (void)
else if (!strcasecmp (ms1_cpu_string, "MS1-16-002"))
ms1_cpu = PROCESSOR_MS1_16_002;
else if (!strcasecmp (ms1_cpu_string, "MS1-16-003"))
{
ms1_cpu = PROCESSOR_MS1_16_003;
target_flags |= MASK_MUL;
}
ms1_cpu = PROCESSOR_MS1_16_003;
else if (!strcasecmp (ms1_cpu_string, "MS2"))
ms1_cpu = PROCESSOR_MS2;
else
error ("bad value (%s) for -march= switch", ms1_cpu_string);
}
@ -806,6 +819,10 @@ ms1_override_options (void)
flag_gcse = 0;
}
/* We do delayed branch filling in machine dependent reorg */
ms1_flag_delayed_branch = flag_delayed_branch;
flag_delayed_branch = 0;
init_machine_status = ms1_init_machine_status;
}
@ -1631,6 +1648,315 @@ ms1_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type)
|| TREE_ADDRESSABLE (type))));
}
/* Structures to hold branch information during reorg. */
typedef struct branch_info
{
rtx insn; /* The branch insn. */
struct branch_info *next;
} branch_info;
typedef struct label_info
{
rtx label; /* The label. */
branch_info *branches; /* branches to this label. */
struct label_info *next;
} label_info;
/* Chain of labels found in current function, used during reorg. */
static label_info *ms1_labels;
/* If *X is a label, add INSN to the list of branches for that
label. */
static int
ms1_add_branches (rtx *x, void *insn)
{
if (GET_CODE (*x) == LABEL_REF)
{
branch_info *branch = xmalloc (sizeof (*branch));
rtx label = XEXP (*x, 0);
label_info *info;
for (info = ms1_labels; info; info = info->next)
if (info->label == label)
break;
if (!info)
{
info = xmalloc (sizeof (*info));
info->next = ms1_labels;
ms1_labels = info;
info->label = label;
info->branches = NULL;
}
branch->next = info->branches;
info->branches = branch;
branch->insn = insn;
}
return 0;
}
/* If BRANCH has a filled delay slot, check if INSN is dependent upon
it. If so, undo the delay slot fill. Returns the next insn, if
we patch out the branch. Returns the branch insn, if we cannot
patch out the branch (due to anti-dependency in the delay slot).
In that case, the caller must insert nops at the branch target. */
static rtx
ms1_check_delay_slot (rtx branch, rtx insn)
{
rtx slot;
rtx tmp;
rtx p;
rtx jmp;
gcc_assert (GET_CODE (PATTERN (branch)) == SEQUENCE);
if (INSN_DELETED_P (branch))
return NULL_RTX;
slot = XVECEXP (PATTERN (branch), 0, 1);
tmp = PATTERN (insn);
note_stores (PATTERN (slot), insn_dependent_p_1, &tmp);
if (tmp)
/* Not dependent. */
return NULL_RTX;
/* Undo the delay slot. */
jmp = XVECEXP (PATTERN (branch), 0, 0);
tmp = PATTERN (jmp);
note_stores (PATTERN (slot), insn_dependent_p_1, &tmp);
if (!tmp)
/* Anti dependent. */
return branch;
p = PREV_INSN (branch);
NEXT_INSN (p) = slot;
PREV_INSN (slot) = p;
NEXT_INSN (slot) = jmp;
PREV_INSN (jmp) = slot;
NEXT_INSN (jmp) = branch;
PREV_INSN (branch) = jmp;
XVECEXP (PATTERN (branch), 0, 0) = NULL_RTX;
XVECEXP (PATTERN (branch), 0, 1) = NULL_RTX;
delete_insn (branch);
return jmp;
}
/* Insert nops to satisfy pipeline constraints. We only deal with ms2
constraints here. Earlier CPUs are dealt with by inserting nops with
final_prescan (but that can lead to inferior code, and is
impractical with ms2's JAL hazard).
ms2 dynamic constraints
1) a load and a following use must be separated by one insn
2) an insn and a following dependent call must be separated by two insns
only arith insns are placed in delay slots so #1 cannot happen with
a load in a delay slot. #2 can happen with an arith insn in the
delay slot. */
static void
ms1_reorg_hazard (void)
{
rtx insn, next;
/* Find all the branches */
for (insn = get_insns ();
insn;
insn = NEXT_INSN (insn))
{
rtx jmp;
if (!INSN_P (insn))
continue;
jmp = PATTERN (insn);
if (GET_CODE (jmp) != SEQUENCE)
/* If it's not got a filled delay slot, then it can't
conflict. */
continue;
jmp = XVECEXP (jmp, 0, 0);
if (recog_memoized (jmp) == CODE_FOR_tablejump)
for (jmp = XEXP (XEXP (XVECEXP (PATTERN (jmp), 0, 1), 0), 0);
!JUMP_TABLE_DATA_P (jmp);
jmp = NEXT_INSN (jmp))
continue;
for_each_rtx (&PATTERN (jmp), ms1_add_branches, insn);
}
/* Now scan for dependencies. */
for (insn = get_insns ();
insn && !INSN_P (insn);
insn = NEXT_INSN (insn))
continue;
for (;
insn;
insn = next)
{
rtx jmp, tmp;
enum attr_type attr;
gcc_assert (INSN_P (insn) && !INSN_DELETED_P (insn));
for (next = NEXT_INSN (insn);
next && !INSN_P (next);
next = NEXT_INSN (next))
continue;
jmp = insn;
if (GET_CODE (PATTERN (insn)) == SEQUENCE)
jmp = XVECEXP (PATTERN (insn), 0, 0);
attr = recog_memoized (jmp) >= 0 ? get_attr_type (jmp) : TYPE_UNKNOWN;
if (next && attr == TYPE_LOAD)
{
/* A load. See if NEXT is dependent, and if so insert a
nop. */
tmp = PATTERN (next);
if (GET_CODE (tmp) == SEQUENCE)
tmp = PATTERN (XVECEXP (tmp, 0, 0));
note_stores (PATTERN (insn), insn_dependent_p_1, &tmp);
if (!tmp)
emit_insn_after (gen_nop (), insn);
}
if (attr == TYPE_CALL)
{
/* A call. Make sure we're not dependent on either of the
previous two dynamic instructions. */
int nops = 0;
int count;
rtx prev = insn;
rtx rescan = NULL_RTX;
for (count = 2; count && !nops;)
{
int type;
prev = PREV_INSN (prev);
if (!prev)
{
/* If we reach the start of the function, we must
presume the caller set the address in the delay
slot of the call instruction. */
nops = count;
break;
}
if (BARRIER_P (prev))
break;
if (LABEL_P (prev))
{
/* Look at branches to this label. */
label_info *label;
branch_info *branch;
for (label = ms1_labels;
label;
label = label->next)
if (label->label == prev)
{
for (branch = label->branches;
branch;
branch = branch->next)
{
tmp = ms1_check_delay_slot (branch->insn, jmp);
if (tmp == branch->insn)
{
nops = count;
break;
}
if (tmp && branch->insn == next)
rescan = tmp;
}
break;
}
continue;
}
if (!INSN_P (prev))
continue;
if (GET_CODE (PATTERN (prev)) == SEQUENCE)
{
/* Look at the delay slot. */
tmp = ms1_check_delay_slot (prev, jmp);
if (tmp == prev)
nops = count;
break;
}
type = (INSN_CODE (prev) >= 0 ? get_attr_type (prev)
: TYPE_COMPLEX);
if (type == TYPE_CALL || type == TYPE_BRANCH)
break;
if (type == TYPE_LOAD
|| type == TYPE_ARITH
|| type == TYPE_COMPLEX)
{
tmp = PATTERN (jmp);
note_stores (PATTERN (prev), insn_dependent_p_1, &tmp);
if (!tmp)
{
nops = count;
break;
}
}
count -= INSN_CODE (prev) >= 0;
}
if (rescan)
for (next = NEXT_INSN (rescan);
next && !INSN_P (next);
next = NEXT_INSN (next))
continue;
while (nops--)
emit_insn_before (gen_nop (), insn);
}
}
/* Free the data structures. */
while (ms1_labels)
{
label_info *label = ms1_labels;
branch_info *branch, *next;
ms1_labels = label->next;
for (branch = label->branches; branch; branch = next)
{
next = branch->next;
free (branch);
}
free (label);
}
}
/* Fixup the looping instructions, do delayed branch scheduling, fixup
scheduling hazards. */
static void
ms1_machine_reorg (void)
{
if (ms1_flag_delayed_branch)
dbr_schedule (get_insns (), dump_file);
if (ms1_cpu == PROCESSOR_MS2)
ms1_reorg_hazard ();
}
/* Initialize the GCC target structure. */
const struct attribute_spec ms1_attribute_table[];
@ -1646,6 +1972,8 @@ const struct attribute_spec ms1_attribute_table[];
#define TARGET_MUST_PASS_IN_STACK ms1_pass_in_stack
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES ms1_arg_partial_bytes
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG ms1_machine_reorg
struct gcc_target targetm = TARGET_INITIALIZER;

View File

@ -25,7 +25,8 @@ enum processor_type
{
PROCESSOR_MS1_64_001,
PROCESSOR_MS1_16_002,
PROCESSOR_MS1_16_003
PROCESSOR_MS1_16_003,
PROCESSOR_MS2
};
enum epilogue_type
@ -40,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=ms1-16-002: -march=ms1-16-002} %{march=ms1-16-003: -march=ms1-16-003} %{!march=*: -march=ms1-16-002}"
#define ASM_SPEC "%{march=ms1-16-002: -march=ms1-16-002} %{march=ms1-16-003: -march=ms1-16-003} %{march=ms2: -march=ms2} %{!march=*: -march=ms1-16-002}"
/* A string to pass to at the end of the command given to the linker. */
#undef LIB_SPEC
@ -51,7 +52,9 @@ march=MS1-64-001:-T 64-001.ld%s; \
march=ms1-16-002:-T 16-002.ld%s; \
march=MS1-16-002:-T 16-002.ld%s; \
march=ms1-16-003:-T 16-003.ld%s; \
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}"
/* A string to pass at the very beginning of the command given to the
linker. */
@ -62,7 +65,9 @@ march=MS1-64-001:%{!mno-crt0:crt0-64-001.o%s} startup-64-001.o%s; \
march=ms1-16-002:%{!mno-crt0:crt0-16-002.o%s} startup-16-002.o%s; \
march=MS1-16-002:%{!mno-crt0:crt0-16-002.o%s} startup-16-002.o%s; \
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=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} \
crti.o%s crtbegin.o%s"
/* A string to pass at the end of the command given to the linker. */
@ -73,7 +78,9 @@ march=MS1-64-001:exit-64-001.o%s; \
march=ms1-16-002:exit-16-002.o%s; \
march=MS1-16-002:exit-16-002.o%s; \
march=ms1-16-003:exit-16-003.o%s; \
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} \
crtend.o%s crtn.o%s"
/* Run-time target specifications. */
@ -89,6 +96,7 @@ march=MS1-16-003:exit-16-003.o%s} \
#define TARGET_MS1_64_001 (ms1_cpu == PROCESSOR_MS1_64_001)
#define TARGET_MS1_16_002 (ms1_cpu == PROCESSOR_MS1_16_002)
#define TARGET_MS1_16_003 (ms1_cpu == PROCESSOR_MS1_16_003)
#define TARGET_MS2 (ms1_cpu == PROCESSOR_MS2)
#define TARGET_VERSION fprintf (stderr, " (ms1)");

View File

@ -19,8 +19,16 @@
;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.
;; UNSPECs
(define_constants
[
(UNSPEC_BLOCKAGE 0)
(UNSPEC_EI 1)
(UNSPEC_DI 2)
])
;; Attributes
(define_attr "type" "branch,mem,io,arith,complex,unknown"
(define_attr "type" "branch,call,load,store,io,arith,complex,unknown"
(const_string "unknown") )
;; If the attribute takes numeric values, no `enum' type will be defined and
@ -36,7 +44,7 @@
(define_cpu_unit "branch_unit" "other")
(define_insn_reservation "mem_access" 2
(eq_attr "type" "mem")
(ior (eq_attr "type" "load") (eq_attr "type" "store"))
"decode_unit+memory_unit*2")
(define_insn_reservation "io_access" 2
@ -44,7 +52,8 @@
"decode_unit+memory_unit*2")
(define_insn_reservation "branch_access" 2
(eq_attr "type" "branch")
(ior (eq_attr "type" "branch")
(eq_attr "type" "call"))
"decode_unit+branch_unit*2")
(define_insn_reservation "arith_access" 1
@ -64,7 +73,8 @@
;; the destination of the branch. Thus, only type that will be acceptable
;; (safe) is the arith type.
(define_delay (eq_attr "type" "branch")
(define_delay (ior (eq_attr "type" "branch")
(eq_attr "type" "call"))
[(eq_attr "type" "arith") (nil) (nil)])
@ -79,7 +89,7 @@
(plus:SI (match_dup 0)
(const_int -1)))
(clobber (match_scratch:SI 2 "=X,r"))]
"TARGET_MS1_16_003"
"TARGET_MS1_16_003 || TARGET_MS2"
"@
dbnz\t%0, %l1%#
#"
@ -98,9 +108,10 @@
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))]
"TARGET_MS1_16_003"
"TARGET_MS1_16_003 || TARGET_MS2"
"dbnz\t%0, %l1%#"
[(set_attr "length" "4")]
[(set_attr "length" "4")
(set_attr "type" "branch")]
)
;; Split the above to handle the case where operand 0 is in memory
@ -116,7 +127,7 @@
(plus:SI (match_dup 0)
(const_int -1)))
(clobber (match_scratch:SI 2 ""))]
"TARGET_MS1_16_003"
"TARGET_MS1_16_003 || TARGET_MS2"
[(set (match_dup 2) (match_dup 0))
(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
(set (match_dup 0) (match_dup 2))
@ -143,7 +154,7 @@
(label_ref (match_operand 2 "" ""))
(pc)))
]
"TARGET_MS1_16_003"
"TARGET_MS1_16_003 || TARGET_MS2"
[(parallel [(set (pc)
(if_then_else
(ne (match_dup 0) (const_int 0))
@ -308,7 +319,7 @@
stb %1, %0
addi %0, r0, %1"
[(set_attr "length" "4,4,4,4")
(set_attr "type" "arith,mem,mem,arith")])
(set_attr "type" "arith,load,store,arith")])
(define_insn "*movqi_internal_nobyte"
[(set (match_operand:QI 0 "register_operand" "=r,r")
@ -566,7 +577,7 @@
nori %0, r0, %N1
ldui %0, %H1\;addui %0, %0, %L1"
[(set_attr "length" "4,4,4,4,4,4,4,8")
(set_attr "type" "arith,mem,mem,arith,arith,arith,arith,complex")]
(set_attr "type" "arith,load,store,arith,arith,arith,arith,complex")]
)
;; Floating Point Moves
@ -641,7 +652,7 @@
ldw %0, %1
stw %1, %0"
[(set_attr "length" "4,4,4")
(set_attr "type" "arith,mem,mem")]
(set_attr "type" "arith,load,store")]
)
(define_expand "movdf"
@ -1269,7 +1280,7 @@
""
"jal r14, %0%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
(set_attr "type" "call")])
(define_expand "call_value"
[(parallel [(set (match_operand 0 "register_operand" "")
@ -1292,7 +1303,7 @@
""
"jal r14, %1%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
(set_attr "type" "call")])
;; Subroutine return
(define_insn "return_internal"
@ -1302,7 +1313,7 @@
""
"jal r0, r14%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
(set_attr "type" "call")])
;; Interrupt return
(define_insn "return_interrupt_internal"
@ -1312,7 +1323,7 @@
""
"reti r15%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
(set_attr "type" "call")])
;; Subroutine return
(define_insn "eh_return_internal"
@ -1324,7 +1335,7 @@
""
"jal r0, r11%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
(set_attr "type" "call")])
;; Normal unconditional jump
@ -1341,7 +1352,7 @@
""
"jal r0,%0%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
(set_attr "type" "call")])
(define_insn "tablejump"
[(set (pc) (match_operand:SI 0 "register_operand" "r"))
@ -1349,7 +1360,7 @@
""
"jal r0, %0%#"
[(set_attr "length" "4")
(set_attr "type" "branch")])
(set_attr "type" "call")])
(define_expand "prologue"
@ -1412,7 +1423,7 @@
;; Pseudo instruction that prevents the scheduler from moving code above this
;; point.
(define_insn "blockage"
[(unspec_volatile [(const_int 0)] 0)]
[(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
""
""
[(set_attr "length" "0")])
@ -1442,14 +1453,14 @@
;; Enable interrupts template
(define_insn "ei"
[(unspec_volatile [(const_int 0)] 1)]
[(unspec_volatile [(const_int 0)] UNSPEC_EI)]
""
"ei"
[(set_attr "length" "4")])
;; Enable interrupts template
(define_insn "di"
[(unspec_volatile [(const_int 0)] 2)]
[(unspec_volatile [(const_int 0)] UNSPEC_DI)]
""
"di"
[(set_attr "length" "4")])