diff --git a/ChangeLog.or1k b/ChangeLog.or1k
new file mode 100644
index 0000000..ea19a46
--- /dev/null
+++ b/ChangeLog.or1k
@@ -0,0 +1,8 @@
+2012-05-13  Peter Gavin  <pgavin@gmail.com>
+
+	* config.guess, config.sub: add or1knd target
+
+2012-03-03  Peter Gavin  <pgavin@gmail.com>
+
+	* config.picflag: no pic flag for or1k
+
diff --git a/config/picflag.m4 b/config/picflag.m4
index 2f5b972..e96c85a 100644
--- a/config/picflag.m4
+++ b/config/picflag.m4
@@ -47,6 +47,9 @@ case "${$2}" in
     mips-sgi-irix6*)
 	# PIC is the default.
 	;;
+    or1k-*-*)
+	$1=-fPIC
+        ;;
     rs6000-ibm-aix* | powerpc-ibm-aix*)
 	# All AIX code is PIC.
 	;;
diff --git a/gcc/ChangeLog.or1k b/gcc/ChangeLog.or1k
new file mode 100644
index 0000000..0c74185
--- /dev/null
+++ b/gcc/ChangeLog.or1k
@@ -0,0 +1,900 @@
+2015-01-17  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.md (cmpxchg_mask): Mask set register.
+
+2014-08-13  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.h (ASM_PREFERRED_EH_DATA_FORMAT): Define.
+
+2013-02-13  Franck Jullien  <franck.jullien@gmail.com>
+
+	* config/or1k/or1k.h:
+	(LIB_SPEC): use -lboard-%* or -lboard-or1ksim even when
+	-static option is used.
+
+2013-02-13  Christian Svensson  <blue@cmd.nu>
+
+	* config/or1k/or1k-protos.h
+	(or1k_expand_pic_symbol_ref): Removed declaration.
+	(or1k_expand_symbol_ref): Added declaration.
+	* config/or1k/or1k.c
+	(or1k_expand_pic_symbol_ref): Made static.
+	(or1k_tls_symbolic_operand): New, returns TLS model of operand.
+	(gen_tls_tga): New, static cache of __tls_get_addr reference.
+	(gen_tls_get_addr): New, returns reference to __tls_get_addr.
+	(or1k_tls_call): New, emits call to __tls_get_addr.
+	(or1k_expand_symbol_ref): New, handles TLS operands.
+	(or1k_expand_move): Call or1k_expand_symbol_ref instead which will
+	then call or1k_expand_pic_symbol_ref if needed.
+	(gt-or1k.h): Include. Needed for gen_tls_tga.
+	* config/or1k/or1k.h (TARGET_HAVE_TLS): Define if HAVE_AS_TLS is set.
+	* config/or1k/or1k.md
+	(UNSPECS): Added UNSPEC_TPOFFLO, UNSPEC_TPOFFHI, UNSPEC_GOTTPOFFLO,
+	UNSPEC_GOTTPOFFHI, UNSPEC_GOTTPOFFLD, UNSPEC_TLSGDLO, UNSPEC_TLSGDHI.
+	(movsi_tlsgdlo): Added.
+	(movsi_tlsgdhi): Added.
+	(movsi_gottpofflo): Added.
+	(movsi_gottpoffhi): Added.
+	(load_gottpoff): Added.
+	(movsi_tpofflo): Added.
+	(movsi_tpoffhi): Added.
+	(movsi_insn_big): Call or1k_expand_symbol_ref instead.
+	* configure.ac: (TLS test): Check for or1k TLS support in AS.
+	* configure: (TLS test): Manually added same as in .ac.
+
+2013-02-11  Franck Jullien  <franck.jullien@gmail.com>
+
+	* config/or1k/or1k.h:
+	(LINK_SPEC): add a space between arguments.
+
+2013-01-22  Christian Svensson  <blue@cmd.nu>
+
+	* common/config/or1k/or1k-common.c
+	(TARGET_EXCEPT_UNWIND_INFO): define.
+	(or1k_except_unwind_info): use DWARF2 unwind info as default
+	but support SJLJ if forced with --enable-sjlj-exceptions.
+	* config/or1k/or1k-protos.h:
+	(or1k_expand_pic_symbol_ref): removed unneeded ATTRIBUTE_UNUSED.
+	(or1k_eh_return_handler_rtx): defined prototype (body in or1k.c).
+	(or1k_return_addr_rtx): defined prototype (body in or1k.c).
+	* config/or1k/or1k.c
+	(or1k_save_reg_p): save stack pointer when frame pointer is not saved.
+	(or1k_save_reg_p): save registers used with eh_return.
+	(or1k_save_reg_p): save LR to stack if used by RETURN_ADDR_RTX.
+	(or1k_expand_epilogue): do not restore link register if we are 
+	returning from eh_return.
+	(or1k_expand_epilogue): apply EH stack adjustment to stack pointer.
+	(or1k_eh_return_handler_rtx): eh_return should write to the link register.
+	(or1k_return_addr_rtx): in the case of GOT the link register cannot be read
+	after the prologue. store LR on stack and read it back when needed.
+	(or1k_frame_pointer_required): require FP in eh_return and 
+	when alloca is used.
+	(or1k_init_machine_status): init cfun->machine.
+	(or1k_init_expanders): added LR forced save, default to false.
+	(TARGET_FRAME_POINTER_REQUIRED): define.
+	* config/or1k/or1k.h
+	(INITIAL_FRAME_POINTER_OFFSET): not used, removed.
+	(RETURN_ADDR_RTX): define.
+	(EH_RETURN_REGNUM): define. use reg 23.
+	(EH_RETURN_DATA_REGNO): define. use reg 25, 27, 29 and 31.
+	(EH_RETURN_STACKADJ_RTX): define.
+	(EH_RETURN_HANDLER_RTX): define.
+	(INIT_EXPANDERS): define.
+	(struct GTY()): define.
+
+2012-12-29  Christian Svensson  <blue@cmd.nu>
+
+	* config.gcc: Use GNU userspace link options when compiling for Linux.
+	* config/or1k/linux-elf.h:
+	(DRIVER_SELF_SPECS): Do not assume uclibc when -m glibc is absent, use
+	target configuration instead.
+
+2012-12-21  Christian Svensson  <blue@cmd.nu>
+
+	* config/or1k/linux-elf.h (GLIBC_DYNAMIC_LINKER): Define.
+	(LINK_SPEC): Use -muclibc / -mglibc to detect wanted interp to
+	-dynamic_linker.
+
+2012-11-29  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.c:
+	(or1k_output_highadd) removed, unneeded
+
+2012-11-29  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k-protos.h:
+	(or1k_expand_sibcall) removed, unneeded
+
+2012-11-29  Peter Gavin  <pgavin@gmail.com>
+
+	fix some things that broke in merge with upstream
+	* config/or1k/or1k.h:
+	(GO_IF_MODE_DEPENDENT_ADDRESS) poisoned in last GCC merge, seems
+	obsolete now
+	(FIXUNS_TRUNC_LIKE_FIX_TRUNC) ditto
+	* config/or1k/or1k-protos.h:
+	(or1k_expand_pic_symbol_ref) added prototype (function body is in or1k.c)
+	(or1k_legitimate_pic_operand_p) ditto
+	* config/or1k/or1k.c:
+	(or1k_compute_frame_size) use crtl->is_leaf instead of current_function_is_leaf
+
+2012-10-28  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* common/config/or1k/or1k-common.c (or1k_handle_option): Remove.
+	(TARGET_HANDLE_OPTION): Likewise.
+	* gcc/config.gcc (or1k-*-elf*): Remove OR1K_LIBC_DEFAULT from tm_defines
+	(or1k-*-linux-*): Likewise.
+	(or1knd-*-elf*): Likewise.
+	(or1knd-*-linux-*): Likewise.
+	* config/or1k/linux-elf.h (DRIVER_SELF_SPECS): Define -muclibc when
+	-mglibc is not given.
+	(TARGET_OS_CPP_BUILTINS): Define "__UCLIBC__" on OPTION_UCLIBC.
+	* config/or1k/or1k.h: Remove custom libc handling
+	* config/or1k/or1k.opt: Likewise.
+
+2012-09-30  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.h (DWARF2_ASM_LINE_DEBUG_INFO): Define.
+
+2012-09-23  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.c (or1k_expand_prologue): Add asserts checking that
+	link reg and fp stack slots offsets are not equal to other offsets.
+
+2012-09-23  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.c (or1k_save_reg_p): Save link register when
+	crtl->uses_pic_offset_table is set.
+	(or1k_compute_frame_size): Reserve space for PIC reg and link register
+	when -fPIC is defined.
+	(or1k_print_operand_address): Remove UNSPEC_GOTOFF handling.
+	(or1k_legitimate_address_p): Likewise.
+	(or1k_legitimate_pic_operand_p): New function.
+	(expand_pic_symbol_ref): Rename to:
+	(or1k_expand_pic_symbol_ref): Emit appropriate GOT references.
+	I.e. labels, local symbols and weak symbols use relative referencing
+	to GOT and global symbol references use referencing through GOT.
+	(or1k_expand_move): Utilize the functionality from
+	(or1k_expand_pic_symbol_ref).
+	(or1k_expand_prologue): Use crtl->uses_pic_offset_tale and
+	frame_info.save_lr_p to determine if the got pointer should be acquired
+	instead of df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM).
+	(or1k_output_addr_const_extra): Remove.
+	(or1k_legitimize_address): Likewise.
+	(TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA): Likewise.
+	(TARGET_LEGITIMIZE_ADDRESS): Likewise.
+	* config/or1k/or1k.h (FIXED_REGISTERS): Add r16 (GOT pointer).
+	(CALL_USED_REGISTERS): Likewise.
+	(PIC_OFFSET_TABLE_REGNUM): Change from r10 to r16.
+	(LEGITIMATE_PIC_OPERAND_P): Define.
+	* config/or1k/or1k.md (UNSPEC_GOTOFF): Remove.
+	(UNSPEC_PCREL): Likewise.
+	(UNSPEC_PIC_LABEL): Likewise.
+	(UNSPEC_SYMBOL_OFFSET): Likewise.
+	(UNSPEC_GOTOFFHI): New constant.
+	(UNSPEC_GOTOFFLO): Likewise.
+	(movsi_gotofflo): New insn.
+	(movsi_gotoffhi): Likewise.
+	(movsi_got): Likewise.
+	(movsi_insn_big): Expand PIC symbol ref if necessary on -fpic
+	(call): Set r16 as used.
+	(call_indirect): Likewise.
+	(call_indirect_internal): Likewise.
+	(call_value): Likewise.
+	(call_value_indirect): Likewise.
+	(call_value_indirect_internal): Likewise.
+	(call_internal): Set r16 as used and emit call through plt on -fpic.
+	(call_value_internal): Likewise.
+	(set_got): Set r9 and r16 as clobbered, use gotpchi() and gotpclo()
+	assembler keywords.
+
+2012-09-18  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/picflag.m4 (or1k-*-*): Set picflag.
+
+2012-09-14  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* gcc/config/or1k/t-linux (MULTILIB_DIRNAMES): Remove 'be' multilib.
+
+2012-09-12  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/linux-elf.h (TARGET_VERSION): Remove.
+
+2012-09-11  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.c (or1k_output_cmov): Remove '\t' in front of l.cmov
+	in asm output.
+
+2012-06-23  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.c:
+	(or1k_output_tailcall) remove
+
+2012-06-23  Peter Gavin  <pgavin@gmail.com>
+
+	turn off delay-slot pass when not using delayed branches
+	* config/or1k/or1k.c:
+	(or1k_option_override) new function, for now just clear
+	flag_delayed_branch when !TARGET_DELAY_ON
+	(TARGET_OPTION_OVERRIDE) define
+
+2012-06-23  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.h:
+	(or1k_asm_file_start) remove prototype
+	(TARGET_ASM_FILE_START) moved to or1k.c
+	* config/or1k/or1k.c:
+	(or1k_asm_file_start) make static
+	(TARGET_ASM_FILE_START) moved from or1k.h
+
+2012-06-23  Peter Gavin  <pgavin@gmail.com>
+
+	more fixes (and fixes to fixes) needed for update against upstream
+	* config/or1k/or1k-common.c: delete
+	* config/common/or1k/or1k-common.c:
+	include opts.h & flags.h
+	(or1k_option_optimization_table) add entry for OPT_fomit_frame_pointer
+	(or1k_handle_option) move from config/or1k/or1k-common.c
+	(TARGET_HANDLE_OPTION) move from config/or1k/or1k.c
+	* config/or1k/or1k.c:
+	(TARGET_HANDLE_OPTION) move from config/or1k/or1k.c
+
+2012-06-22  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.md: add comments to each instruction annotating
+	where it came from; add "length" and "type" attributes to l.sf*
+	instructions
+
+2012-06-22  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.h:
+	(TARGET_CPU_CPP_BUILTINS) make sure things are properly defined
+	for or1knd
+
+2012-06-22  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.c:
+	(or1k_output_mi_thunk) remove (not used?)
+
+2012-06-22  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.c: properly terminate some comments
+
+2012-06-22  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.c:
+	(or1k_trampoline_code_words) make static
+
+2012-06-22  Peter Gavin  <pgavin@gmail.com>
+
+	some fixes needed for update against mainline
+	* config/or1k/or1k-common.c: new file
+	(or1k_handle_option) moved from or1k.c
+	* config/or1k/or1k.c
+	(stack_disp_mem) pass Pmode as first argument to plus_constant
+	(or1k_handle_option) removed
+
+2012-05-28  Peter Gavin  <pgavin@gmail.com>
+
+	fix cmov
+	* config/or1k/or1k-protos.h:
+	(or1k_select_cc_mode) new prototype
+	* config/or1k/or1k.h:
+	(SELECT_CC_MODE) redefine to call or1k_select_cc_mode
+	(or1k_compare_op0) remove
+	(or1k_compare_op1) remove
+	* config/or1k/or1k.c:
+	(or1k_select_cc_mode) new function: does what SELECT_CC_MODE did,
+	but as a function; only takes one argument (the first), since the
+	second two in SELECT_CC_MODE are never used
+	(or1k_compare_op0) remove
+	(or1k_compare_op1) remove
+	(or1k_emit_int_cmov) use operands passed in instead of
+	or1k_compare_op[01]
+	(or1k_output_bf) call or1k_select_cc_mode instead of using SELECT_CC_MODE
+	(or1k_output_cmov) ditto
+
+2012-05-24  Peter Gavin  <pgavin@gmail.com>
+
+	remove some unneeded code
+	* config/or1k/or1k.c: remove use of INITIALIZER (was commented
+	anyways)
+	(calculate_stack_size) remove, never used
+	(or1k_frame_pointer_required) ditto
+
+2012-05-24  Peter Gavin  <pgavin@gmail.com>
+
+	remove sibcall support for or1k
+	* config/or1k/constraints.md:
+	(define_constraint "Rsc") removed
+	* config/or1k/predicates.md:
+	(define_predicate "sibcall_insn_operand") removed
+	* config/or1k/or1k-protos.h:
+	(or1k_expand_epilogue) removed sibcall parameter
+	* config/or1k/or1k.h:
+	(PRINT_OPERAND) removed 'J' and 'K' constraints
+	* config/or1k/or1k.c:
+	(or1k_expand_epilogue) removed sibcall parameter, don't check for
+	sibcalls
+	(or1k_print_jump_restore) removed
+	(or1k_expand_sibcall) removed
+	(or1k_function_ok_for_sibcall) return 0 so sibcalls are never used
+	* config/or1k/or1k.md:
+	(define_constants UNSPECV_SIBCALL_EPILOGUE) removed
+	(define_expand "epilogue") don't pass null to or1k_expand_epilogue
+	(define_insn_and_split "sibcall_epilogue") removed
+	(define_expand "sibcall") removed
+	(define_expand "sibcall_value") removed
+	(define_insn "sibcall_internal") removed
+
+2012-05-24  Peter Gavin  <pgavin@gmail.com>
+
+	remove -mlogue flag, always use scheduled prologue/epilogue
+	* config/common/or1k-common.c:
+	(TARGET_DEFAULT_TARGET_FLAGS) remove MASK_SCHED_LOGUE
+	* config/or1k/or1k.c:
+	(or1k_output_function_prologue) removed
+	(or1k_output_function_epilogue) removed
+	(TARGET_ASM_FUNCTION_PROLOGUE) removed
+	(TARGET_ASM_FUNCTION_EPILOGUE) removed
+	* config/or1k/or1k.md:
+	(prologue) remove TARGET_SCHED_LOGUE from constraints
+	(epilogue) ditto
+	(sibcall_epilogue) ditto
+	(return_internal) ditto
+	* config/or1k/or1k.opt:
+	(mlogue) removed
+
+2012-05-13  Peter Gavin  <pgavin@gmail.com>
+
+	* gcc/config.gcc: add or1knd target; add OR1K_DELAY_DEFAULT
+	definitions to tm_defines for or1k and or1knd
+	* gcc/config/or1k/or1k-opts.h: new file; defines enum and flags
+	for delay slot options
+	* gcc/config/or1k/or1k.h: make delay slot optional
+	(TARGET_CPU_CPP_BUILTINS) define __OR1K_DELAY__, __OR1K_NODELAY__,
+	or __OR1K_DELAY_COMPAT__ depending on delay slot option chosen
+	(TARGET_ASM_FILE_START) new define
+	(or1k_asm_file_start) new prototype
+	(PRINT_OPERAND) emit different code depending on delay slot option
+	- added %K operand which is like %J but only emits code when no
+	delay slot
+	* gcc/config/or1k/or1k.c: make delay slot optional
+	(OR1K_NOP) new define, needed when inserting NOP in trampoline for
+	-mcompat-delay mode
+	(or1k_asm_file_start) new function; add ".nodelay" directive to
+	assembly file when not using delay slot
+	(or1k_trampoline_words) new function; return number of words in
+	trampoline. The number of words depends on whether a delay slot is
+	used
+	(or1k_trampoline_code_size) use or1k_trampoline_words
+	(or1k_output_function_epilogue) emit different code depending on
+	delay slot option
+	(or1k_trampoline_init) ditto
+	(or1k_output_mi_thunk) ditto
+	* gcc/config/or1k/or1k.md: make delay slot optional
+	- change when delay on branches & jumps is used
+	- add %K0 operand in sibcall with Rsc constraint
+	* gcc/config/or1k/or1k.opt: add -mdelay, -mno-delay -mcompat-delay flags
+	* gcc/config/or1k/t-or1k: add multilibs for no-delay and compat-delay
+	* gcc/config/or1k/t-or1knd: new file
+
+2012-05-13  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.h: change some specs
+	(CONC_DIR) remove
+	(TARGET_PREFIX) remove
+	(EXTRA_SPECS) remove
+	(STARTFILE_SPEC) use %s to search for files instead of using target_prefix
+	(LINK_SPEC) set entry to 0x100 when using newlib; remove -L%(target_prefix)/...
+	(LIB_SPEC) use %s to search for files; use -lboard-${board} to
+	link, instead of adding -L.../${board} and using -lboard
+	- this fixes a problem finding the libraries when using multilibs
+
+2012-05-13  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k-protos.h: add prototype for
+	or1k_expand_move (suppresses "no previous prototype" warning)
+	* config/or1k/or1k.c: (or1k_legitimize_address) add
+	ATTRIBUTE_UNUSED to mode (suppresses unused variable warning)
+
+2012-04-25  Peter Gavin  <pgavin@gmail.com>
+
+	* gcc/config/or1k/default.h: remove (why is this here?)
+
+2012-03-03  Peter Gavin  <pgavin@gmail.com>
+
+	* configure: regenerated
+
+2012-02-23  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.md: change if to else if in condition for
+	"movhi" (shouldn't make a difference); fix conditions for
+	"movsi_insn_big"
+	* config/or1k/predicates.md: remove unneeded fprintf
+
+2012-02-18  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.S: moved to libgcc/config/or1k/or1k.S
+	* config/or1k/crti.S, gcc/config/or1k/crtn.S: deleted
+	* config/or1k/or1k.c: remove dwarf2 code since this has been
+	moved into it's own compiler pass (more will probably have to be
+	done about this but it seems to work ok for now); fix some
+	warnings; include <ansidecl.h>; remove INITIALIZER (what was it
+	supposed to do?)
+	* config/or1k/or1k.h: make SELECT_CC_MODE return an something
+	of correct type on failure instead of just 0
+	* config/or1k/t-or1k: remove a bunch of obsolete stuff
+
+2011-12-01  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.md (cbranchsi4): Fix mode of operands 1 and 2.
+
+2011-07-07  Giuseppe Scrivano  <giuseppe@southpole.se>
+
+	* config/or32/or32.c (or32_print_operand_address): New function.
+	(expand_pic_symbol_ref): Likewise.
+	(or32_expand_move): Likewise.
+	(or32_expand_prologue): Set the PIC register.
+	(or32_output_addr_const_extra): Likewise.
+	(or32_legitimate_address_p): Handle UNSPEC.
+	(or32_legitimate_constant_p): When PIC is used don't allow
+	constants in VOIDmode.
+	(TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA, TARGET_LEGITIMIZE_ADDRESS): Define
+	hooks.
+
+	* config/or32/or32.md (UNSPEC_GOTOFF, UNSPEC_PCREL): Define.
+	(UNSPEC_PIC_LABEL, UNSPEC_SYMBOL_OFFSET, UNSPEC_SET_GOT): Likewise.
+	(set_got): New function.
+	(movhi_internal): Delegate to or32_expand_move.
+
+2011-06-27  Giuseppe Scrivano  <giuseppe@southpole.se>
+
+	* config/or32/or32.h: Define PIC_OFFSET_TABLE_REGNUM.
+	* config/or32/or32.c: Remove definition for GOT_SYMBOL_NAME and
+	GOT_REGISTER.
+
+2011-06-20  Giuseppe Scrivano  <giuseppe@southpole.se>
+
+	* config/or32/or32.c: Define GOT_SYMBOL_NAME and GOT_REGISTER.
+	(or32_expand_prologue): Store the GOT location in the GOT_REGISTER if
+	PIC code is generated.
+
+2011-06-17  Giuseppe Scrivano  <giuseppe@southpole.se>
+
+	* common/config/or32/or32-common.c: New file.
+	* config/or32/or32.h (LINK_SPEC): Support -shared.
+	* config/or32/or32.c (TARGET_EXCEPT_UNWIND_INFO): Remove definition.
+	* config/or32/or32.c (or32_pass_by_reference): Change type of CUM to
+	cumulative_args_t.
+	(or32_arg_partial_bytes): Likewise.
+	(or32_function_arg): Likewise.
+	(or32_function_arg_advance): Likewise.
+
+2011-05-28  Giuseppe Scrivano  <gscrivano@southpole.se>
+
+	* or32.h (FUNCTION_ARG, FUNCTION_ARG_ADVANCE): Undefine.
+	(HANDLE_PRAGMA_PACK_PUSH_POP, LEGITIMATE_CONSTANT_P): Likewise.
+	(CAN_DEBUG_WITHOUT_FP, RETURN_POPS_ARGS): Likewise.
+	(target_flags): Remove extern declaration.
+	* or32.c (TARGET_FUNCTION_ARG, TARGET_FUNCTION_ARG_ADVANCE): Define.
+	(TARGET_LEGITIMATE_CONSTANT_P, TARGET_EXCEPT_UNWIND_INFO): Likewise.
+	(or32_legitimate_constant_p, or32_function_arg): New functions.
+	(or32_function_arg, or32_function_arg_advance): Likewise.
+
+2011-04-13  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/elf.h (DRIVER_SELF_SPECS): Define.
+	* config/or32/linux-elf.h (DRIVER_SELF_SPECS): Undef.
+
+2011-04-09  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* BASE_VER: Updated for gcc-4.5.1-or32-1.0rc3.
+
+2011-03-22  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.h (LEGITIMATE_CONSTANT_P): Allow VOIDmode
+	CONST_DOUBLE.
+	* config/or32/or32.md (movsi_insn_big): Enable splitting of CONST_INT.
+	(movdi): Now a define_insn_and_split.
+	* config/or32/or32.c (or32_output_move_double): Abort for CONST_INT.
+
+2011-02-17  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* gcc.c (do_spec_1) <%*>: Don't append a space unless the next
+	character is '}'.
+	* config/or32/or32.h (STARTFILE_SPEC): For mor32-newlib-*,
+	add crtparam-%*.o.
+
+2011-02-15  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.md (frame_alloc_fp): New pattern.
+	* config/or32/or32.c (or32_expand_prologue): Use it if a frame pointer
+	is used.
+
+2011-02-03  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/uclibc-stdint.h: New file.
+	* config.gcc (or32-*linux*): Add uclibc-stdint.h to tm_file.
+
+2011-02-03  Jonas Bonn  <jonas@southpole.se>
+
+	* config/or32/or32.h (CALL_USED_REGS): Include r12.
+
+2011-01-12  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config.or32/or32.h (CPP_SPEC): Add -D_XOPEN_SOURCE=600 for pthread.
+	(LIB_SPEC): Add --whole-archive -lpthread --no-whole-archive for
+	pthread.
+
+2010-12-19  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config.gcc <or32-*-linux*>: Remove extra_parts.
+	* config/or32/crti.S (__init): Add l.nop, so doesn't start at zero.
+
+2010-12-19  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config/or32/crtn.S (__init, __fini): remove labels.
+	* config.gcc <or32-*-linux*>: Add crti.o and crt.n to extra_parts.
+
+2010-12-16  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config.gcc (or32-*-elf*) <tm_defines>:
+	Add OR32_LIBC_DEFAULT=or32_libc_newlib.
+	(or32-*linux*) <tm_defines>: Set UCLIBC_DEFAULT=1.
+	Add OR32_LIBC_DEFAULT=or32_libc_uclibc.
+	* config/or32/or32.opt (mnewlib): New option.
+	(muclibc, mglibc): Stub options.
+	* config/or32/or32.h (TARGET_CPU_CPP_BUILTINS): When using uClibc,
+	define __UCLIBC__.
+	(or32_libc_kind): New enum.
+	* config/or32/or32.c (or32_handle_option): New function.
+	(TARGET_HANDLE_OPTION): Override.
+
+2010-12-10  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.c (TARGET_STRICT_ARGUMENT_NAMING): Overrride.
+
+2010-11-18  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* config/or32/t-linux ($(T)crtbegin.o): Reverse out __dso_handle
+	rename.
+	(crtbegin$(objext)): Likewise.
+
+2010-11-07  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.opt (mredzone=): New option.
+	* config/or32/or32.c (frame_info): New members gpr_frame, late_frame.
+	(or32_compute_frame_size, or32_expand_prologue): Implement -mredzone.
+	or32_expand_epilogue, or32_initial_elimination_offset): Likewise.
+	(or32_function_ok_for_sibcall): Suppress sibcall optimization if
+	the sibcall register might not be available.
+
+	* config/or32/or32.c (or32_expand_prologue): Fix threshold for
+	loading the frame size into a register.
+
+	* config/or32/or32.md (SP_REG, FP_REG, UNSPEC_FRAME): New constants.
+	(frame_dealloc_fp, frame_dealloc_sp): New insn patterns.
+	* config/or32/or32.c (or32_expand_epilogue): Use frame_dealloc_[fs]p.
+
+2010-11-01  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.h (HANDLE_PRAGMA_PACK_PUSH_POP): Define.
+
+	* config/or32/t-linux ($(T)crtbegin.o): Rename __dso_handle.
+
+	(crtbegin$(objext)): Likewise.
+
+2010-10-31  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	 * config/or32/or32.c (or32_struct_alignment): Refine rules to
+	 avoid overriding user settings.
+
+	 * Don't increase alignment of struct with sole packed field.
+
+2010-10-29  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.c (or32_output_mi_thunk): New function.
+	(or32_output_highadd, or32_output_tailcall): Likewise.
+	(TARGET_ASM_OUTPUT_MI_THUNK): Redefine.
+	(TARGET_ASM_CAN_OUTPUT_MI_THUNK): Likewise.
+
+	(or32_output_mi_thunk): Don't emit add of zero delta.
+
+	* config/or32/or32.opt: Remove -maj option.
+	* config/or32/or32.md, config/or32/or32.c: Likewise.
+
+	* config.gcc: Add Embecosm Copyright notice.
+	* config/or32/predicates.md: Likewise.
+	* config/or32/or32.md: Likewise.
+	* config/or32/t-or32: Likewise.
+	* config/or32/or32.opt: Likewise.
+	* config/or32/or32-protos.h: Likewise.
+	* config/or32/crti.S: Likewise.
+	* config/or32/or32.c: Likewise.
+	* config/or32/constraints.md: Likewise.
+	* config/or32/crtn.S: Likewise.
+	* config/or32/default.h: Likewise.
+	* config/or32/or32.h: Likewise.
+
+2010-10-28  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.md (movsi_lo_sum, movsi_high): Enable generator
+	function generation.
+	(movsi_insn_big): Now define_insn_and_split.
+
+	* config.gcc (or32-*-elf*): Change extra_parts to:
+	"crti.o crtbegin.o crtend.o crtn.o".
+	( or32-*linux*): Change tmake_file to
+	"${cpu_type}/t-${cpu_type} or32/t-linux"
+	* config/or32/t-default, config/or32/initfini.c: Delete.
+	* t-or32 ((T)or32-crtbegin.o, $(T)or32-crtend.o): Replace with:
+	((T)crti.o, $(T)crtn.o).
+	* config/or32/t-linux: New file.
+	* config/or32/crti.S, config/or32/crtn.S: Likewise.
+	* config/or32/or32.h (STARTFILE_SPEC): Replace or32-crtbegin.o%s with
+	crti.o%s crtbegin.o%s.
+	(ENDFILE_SPEC): Set to crtend.o%s crtn.o%s.
+
+	* config/or32/elf.h (DBX_DEBUGGING_INFO): Don't redefine.
+	(PREFERRED_DEBUGGING_TYPE, PUT_SDB_DEF): Likewise.
+
+	* config/or32/or32.md (tablejump): For -fpic, emit add of table base.
+
+2010-10-26  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config.gcc (or32-*-elf*): Rename crtinit.o / crtfini.o
+	to or32-crtbegin.o / or32-crtend.o.
+	* config/or32/t-default, config/or32/t-or32 (Entire file): Likewise.
+	* config/or32/initfini.c, config/or32/or32.h: Likewise.
+
+2010-10-26  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.opt Mask(MASK_SCHED_LOGUE): Renamed to
+	Mask(SCHED_LOGUE).  Changed all users.
+	(-msibcall): Delete option.
+	* config/or32/or32.md (sibcall, sibcall_value, sibcall_internal): Make
+	patterns unconditional.
+	(sibcall_internal): Change alternatives to handle callee-saved
+	registers correctly.
+	* config/or32/or32.c (or32_compute_frame_size): Place register save
+	area at bottom of frame.
+	(or32_expand_prologue): Initialize frame pointer from stack pointer.
+	For large offsets, add a REG_FRAME_RELATED_EXPR note.
+	(or32_expand_epilogue): Restore stack pointer from frame pointer.
+	sibcall is now the sibcall epilogue insn to be split.
+	(or32_compute_frame_size, or32_expand_prologue, or32_expand_epilogue):
+	Use PROLOGUE_TMP and EPILOGUE_TMP.
+	(or32_function_ok_for_sibcall): Retrun true.
+	(TARGET_DEFAULT_TARGET_FLAGS): Include MASK_SCHED_LOGUE.
+	(PROLOGUE_TMP, EPILOGUE_TMP): Define.
+	* config/or32/or32.md (CC_REG): New constant.  Use it to denote
+	register number of flags register.
+	Include constraints.md.
+	* config/or32/predicates.md (cc_reg_operand): Use CC_REG.
+	(input_operand): Use satisfies_constraint_[KMI].
+	* config/or32/or32-protos.h (or32_initial_elimination_offset): Declare.
+	(or32_print_jump_restore): Declare.
+	* config/or32/or32.h (OR32_LAST_ACTUAL_REG): Define.  Use in place of
+	OR32_LAST_INT_REG to iterate through registers where appropriate.
+	(ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET): Define.
+	(ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM): Define as fake hard
+	registers.
+	(FIXED_REGISTERS, CALL_USED_REGISTERS, REG_CLASS_CONTENTS): Update.
+	(REGNO_REG_CLASS, REGISTER_NAMES): : Likewise.
+	* config/or32/or32.c: Use HARD_FRAME_POINTER_REGNUM /
+	hard_frame_pointer_rtx to refer to the hard frame pointer.
+	(or32_emit_move): Now static.
+	(or32_print_jump_restore): New function.
+	(or32_compute_frame_size): Distinguish between saving the hard frame
+	pointer and saving the GPR with the regno of the eliminated frame
+	pointer.
+	(indexed_memory): Delete.
+	(stack_disp_mem): New function.
+	(or32_compute_frame_size): Avoid over-wide shifts.
+	(or32_output_function_prologue): Likewise.
+	(or32_output_function_epilogue): Likewise.
+	(or32_frame_pointer_required): Comment out.
+	(or32_initial_elimination_offset): New function.
+	(TARGET_FRAME_POINTER_REQUIRED): Don't redefine.
+	(PRINT_OPERAND): Handle %J.
+	* config/or32/constraints.md: New file.
+
+2010-10-25  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32-protos.h (get_hard_reg_initial_val): Declare.
+	* config/or32/or32.h (INCOMING_RETURN_ADDR_RTX): Fix register number.
+	* (RETURN_ADDR_RTX): Define.
+
+2010-10-12  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.c (or32_struct_alignment): Round up alignment to
+	power of two.
+
+	For unions, use maximum of field size for size estimate.
+
+2010-10-11  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.opt (mpadstruct): New option.
+	* config/or32/or32-protos.h (or32_struct_alignment): Declare.
+	(or32_data_alignment): Likewise.
+	* config/or32/or32.c (or32_struct_alignment): New function.
+	(or32_data_alignment): Likewise.
+	* config/or32/or32.h (STRUCTURE_SIZE_BOUNDARY): Default to 8.
+	(ROUND_TYPE_ALIGN, DATA_ALIGNMENT, LOCAL_ALIGNMENT): Define.
+
+	* config/or32/or32.c (or32_struct_alignment): Take
+	maximum_field_alignment into account.
+
+2010-09-14  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.h (ASM_OUTPUT_ADDR_DIFF_ELT): Fix typo.
+	(JUMP_TABLES_IN_TEXT_SECTION): Define.
+	* config/or32/default.h (JUMP_TABLES_IN_TEXT_SECTION): Use flag_pic.
+
+2010-09-13  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* config/or32/or32.h (TRAMPOLINE_SIZE): Use result of
+	or32_trampoline_code_size rather than its address.
+
+	* config/or32/initfini.c (init): Rename to:
+	(__init).
+	* config/or32/or32.c (or32_trampoline_init): Don't clobber r12.
+
+	* config.gcc (or32-*-elf*): Add newlib-stdint.h to tm_file.
+
+2010-09-05  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* BASE_VER: Updated for gcc-4.5.1-or32-1.0rc1.
+
+2010-09-05  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32-protos.c <or32_trampoline_code_size>: Added.
+	* config/or32/or32.c <TARGET_DEFAULT_TARGET_FLAGS>: Added.
+	* config/or32/or32.h <TARGET_DEFAULT>: Deleted.
+	* doc/contrib.texi: Updated for OpenRISC.
+	* doc/invoke.texi: Updated for OpenRISC.
+
+2010-09-04  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32-protos.c <or32_trampoline_code_size>: Added.
+	* config/or32/or32.c <OR32_MOVHI, OR32_ORI, OR32_LWZ, OR32_JR>:
+	New macros added.
+	(or32_emit_mode, or32_emit_binary, or32_force_binary)
+	(or32_trampoline_code_size, or32_trampoline_init): Created.
+	(or32_output_bf): Tabbing fixed.
+	<TARGET_TRAMPOLINE_INIT>: Definition added.
+	* config/or32/or32.h <STATIC_CHAIN_REGNUM>: Uses R11.
+	<TRAMPOLINE_SIZE>: redefined.
+	<TRAMPOLINE_ENVIRONMENT>: Added definition.
+
+2010-09-01  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* haifa-sched.c (initiate_bb_reg_pressure_info): Declaration of i
+	made conditional to avoid warning.
+	* or32.c: Updated for compatibility with GCC 4.5.1. Redundant
+	functions remobed. Now contains all target hooks.
+	* or32.h: Complete rewrite for compatibility with GCC
+	4.5.1. Removed all target hooks.
+	* or32.md: Rewrite for compatibility with GCC 4.5.1.
+	* or32-protos.h: Updated to match or32.c.
+
+2010-09-01  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* .: All files updated to GCC 4.5.1 base.
+
+2010-08-26  mirekez  <mirekez@gmail.com>
+
+	* config/or32/or32.h <enum reg_class>: CR_REGS removed from
+	enumeration.
+
+2010-08-26  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* vec.h: All references to VEC_TA_GTY with an empty fourth
+	argument replaced by VEC_TA_GTY_ANON with only three arguments
+	<VEC_TA_GTY_ANON>: Created.
+
+2010-08-25  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* config/or32/elf.h <DWARF2_DEBUGGING_INFO>: Defined.
+	<PREFERRED_DEBUGGING_TYPE>: Changed to DWARF2_DEBUG.
+	<PUT_SDB_DEF>: Deleted.
+	* config/or32/or32.h: Obsolete code surrounded by "#if 0" removed
+	for clarity.
+	<SDB_DELIM>: Definition deleted.
+	<DBX_CONTIN_LENGTH, DBX_CONTIN_CHAR, DBX_REGISTER_NUMBER>:
+	Definition deleted (default suffices).
+	<DWARF2_UNWIND_INFO, DWARF2_FRAME_INFO>: Defined.
+	<DWARF2_ASM_LINE_DEBUG_INFO, INCOMIN_RETURN_ADDR_RTX>: Defined.
+	* config/or32/or32.md: Commenting clarified. Obsolete code for
+	define_function_unit deleted.
+
+2010-08-19  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* config/or32/elf.h <PUT_SDB_DEF>: Definition removed.
+	<USER_LABEL_PREFIX>: Modified to match or32.h
+	* config/or32/linux-elf.h<USER_LABEL_PREFIX>: Modified to match
+	or32.h
+	* config/or32/or32.h <LIB_SPEC>: Changed to use free instead of
+	_free to match change in USER_LABEL_PREFIX.
+	<USER_LABEL_PREFIX>: Changed from "_" to "".
+	<ASM_OUTPUT_FUNCTION_PREFIX>: Surround .proc by tab chars.
+	* config/or32/or32.S (__mulsi3, __udivsi3, __divsi3, __umodsi3)
+	(__modsi3): Changed from ___mulsi3, ___udivsi3, ___divsi3,
+	___umodsi3 and ___modsi3 respectively to match change in
+	USER_LABEL_PREFIX.
+
+2010-07-20  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32.h: Updated LIB_SPEC for newlib 1.18.0 to force
+	linking of _malloc and _free against a weak reference also when
+	using -lg.
+
+2010-07-19  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32.h: Updated LIB_SPEC for newlib 1.18.0 to force
+	linking of _malloc and _free against a weak reference.
+
+2010-07-17  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32.h: Updated STARTFILE_SPEC and LIB_SPEC
+	definition for newlib.
+
+2010-07-16  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32.h: Updated SPEC definitions to pick up newlib
+	in custom location.
+
+2010-07-13  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config/or32/initfini.c: Corrected assembler sequences.
+
+2010-07-07  Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+	* config.gcc: Specified cpu_type for or32. Corrected templates
+	specified for or32-*-elf*. Added extra_parts for
+	or32-*-elf*. Specified t-or32 as tmake_file for or32-*-elf*.
+	* config/or32/initfini.c: Created.
+	* config/or32/or32.h <LINK_SPEC>: Removed.
+	<STARTFILE_SPEC>: Add crtinit.o.
+	<ENDFILE_SPEC>: Just specify crtfini.o.
+	<LIB_SPEC>: Unified multiple definitions. Added newlib library
+	when specified.
+	* config/or32/or32.opt <mor32-newlib-uart>: New option added.
+	* config/or32/t-default: Added details for crtinit and crtfini.
+	* config/or32/t-or32: Added details for crtinit and crtfini.
+
+2010-06-30  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32.h <FUNCTION_PROFILER>: Corrected definition.
+	<LINK_SPEC>: Pick up newlib specific linker script.
+	<ENDFILE_SPEC>: Specify newlib library.
+	* config/or32/or32.opt <mor32-newlib>: New option added.
+
+2010-06-21  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	* config/or32/or32.md: Duplicate define_insn of "movdf" and "movsf"
+	removed.
+
+2010-06-17  Jungsook yang  <jungsook.yang@uci.edu>
+
+	* config/or32/or32.c (or32_expand_branch): Added SFmode case.
+	* config/or32/or32.md <define_expand "*cmpsf">: Added.
+	<define_expand "*cmpsf_eq">: Added.
+	<define_expand "*cmpsf_ne">: Added.
+	<define_expand "*cmpsf_gt">: Added.
+	<define_expand "*cmpsf_ge">: Added.
+	<define_expand "*cmpsf_lt">: Added.
+	<define_expand "*cmpsf_le">: Added.
+	<define_insn "movdf">: Added.
+	<define_insn "movsf">: Added.
+	<define_insn "adddf3">: Added TARGET_DOUBLE_FLOAT.
+	<define_insn "subdf3">: Added TARGET_DOUBLE_FLOAT.
+	<define_insn "muldf3">: Added TARGET_DOUBLE_FLOAT.
+	<define_insn "divdf3">: Added TARGET_DOUBLE_FLOAT.
+	<define_insn "floatsisf2">: Added.
+	<define_insn "fixunssfsi2">: Added.
+	<define_insn "movdf">: Added.
+	<define_insn "movsf">: Added.
+	* config/or32/or32.opt: mdouble-float option added.
+
diff --git a/gcc/ada/s-osinte-posix.adb b/gcc/ada/s-osinte-posix.adb
index 6bcc722..2774f92 100644
--- a/gcc/ada/s-osinte-posix.adb
+++ b/gcc/ada/s-osinte-posix.adb
@@ -103,7 +103,7 @@ package body System.OS_Interface is
       end if;
 
       return timespec'(tv_sec => S,
-                       tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+                       tv_nsec => time_t (Long_Long_Integer (F * 10#1#E9)));
    end To_Timespec;
 
 end System.OS_Interface;
diff --git a/gcc/common.opt b/gcc/common.opt
index ac6546c..a845cbe 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1489,6 +1489,10 @@ fipa-icf-variables
 Common Report Var(flag_ipa_icf_variables)
 Perform Identical Code Folding for variables
 
+fipa-sem-equality
+Common Report Var(flag_ipa_sem_equality) Iinit(1) Optimization
+Perform Semantic function equality
+
 fipa-reference
 Common Report Var(flag_ipa_reference) Init(0) Optimization
 Discover readonly and non addressable static variables
diff --git a/gcc/common/config/or1k/or1k-common.c b/gcc/common/config/or1k/or1k-common.c
new file mode 100644
index 0000000..d91cc1f
--- /dev/null
+++ b/gcc/common/config/or1k/or1k-common.c
@@ -0,0 +1,61 @@
+/* Common hooks for OR1K.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "common/common-target.h"
+#include "common/common-target-def.h"
+#include "opts.h"
+#include "flags.h"
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options or1k_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
+/* Implement TARGET_EXCEPT_UNWIND_INFO.  */
+static enum unwind_info_type
+or1k_except_unwind_info (struct gcc_options *opts)
+{
+    /* Honor the --enable-sjlj-exceptions configure switch.  */
+#ifdef CONFIG_SJLJ_EXCEPTIONS
+    if (CONFIG_SJLJ_EXCEPTIONS)
+          return UI_SJLJ;
+#endif
+
+    if (DWARF2_UNWIND_INFO)
+      return UI_DWARF2;
+
+    return UI_SJLJ;
+}
+
+#undef  TARGET_EXCEPT_UNWIND_INFO
+#define TARGET_EXCEPT_UNWIND_INFO  or1k_except_unwind_info
+
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE or1k_option_optimization_table
+
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (MASK_HARD_MUL)
+
+struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 7954a62..dbc4a09 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -429,6 +429,12 @@ nios2-*-*)
 nvptx-*-*)
 	cpu_type=nvptx
 	;;
+or1k-*-*)
+	cpu_type=or1k
+	;;
+or1knd-*-*)
+	cpu_type=or1k
+	;;
 powerpc*-*-*)
 	cpu_type=rs6000
 	extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h htmintrin.h htmxlintrin.h"
@@ -2258,6 +2264,34 @@ nvptx-*)
 		tm_file="${tm_file} nvptx/offload.h"
 	fi
 	;;
+or1k-*-elf*)
+	tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h ${cpu_type}/elf.h"
+	extra_parts="crti.o crtbegin.o crtend.o crtn.o"
+	tmake_file=or1k/t-or1k
+	tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_ON"
+	;;
+or1k-*-linux-*)
+	tm_file="${tm_file} dbxelf.h elfos.h or1k/elf.h gnu-user.h linux.h or1k/linux-gas.h or1k/linux-elf.h uclibc-stdint.h"
+	tmake_file="or1k/t-or1k or1k/t-linux ${tmake_file}"
+	tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_ON"
+	;;
+or1k*-*-rtems*)
+	tm_file="${tm_file} dbxelf.h elfos.h ${cpu_type}/elf.h"
+	tm_file="${tm_file} newlib-stdint.h or1k/rtems.h rtems.h"
+	extra_parts="crti.o crtbegin.o crtend.o crtn.o"
+	tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_ON"
+	;;
+or1knd-*-elf*)
+	tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h ${cpu_type}/elf.h"
+	extra_parts="crti.o crtbegin.o crtend.o crtn.o"
+	tmake_file=or1k/t-or1knd
+	tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_OFF"
+	;;
+or1knd-*-linux-*)
+	tm_file="${tm_file} dbxelf.h elfos.h or1k/elf.h linux.h or1k/linux-gas.h or1k/linux-elf.h uclibc-stdint.h"
+	tmake_file="or1k/t-or1knd or1k/t-linux ${tmake_file}"
+	tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_OFF"
+	;;
 pdp11-*-*)
 	tm_file="${tm_file} newlib-stdint.h"
 	use_gcc_stdint=wrap
diff --git a/gcc/config/or1k/constraints.md b/gcc/config/or1k/constraints.md
new file mode 100644
index 0000000..3f8030c
--- /dev/null
+++ b/gcc/config/or1k/constraints.md
@@ -0,0 +1,59 @@
+;; Copyright (C) 2010 Embecosm Limited
+;;
+;; Contributed by Joern Rennecke <joern.rennecke@embecosm.com> in 2010
+;;
+;; 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_constraint "I"
+  ""
+  (and (match_code "const_int")
+       (match_test "ival >= -32768 && ival <= 32767")))
+
+(define_constraint "J"
+  ""
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
+
+(define_constraint "K"
+  ""
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 65535")))
+
+(define_constraint "L"
+  ""
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 31")))
+
+(define_constraint "M"
+  ""
+  (and (match_code "const_int")
+       (match_test "(ival & 0xffff) == 0")))
+
+(define_constraint "N"
+  ""
+  (and (match_code "const_int")
+       (match_test "ival >= -33554432 && ival <= 33554431")))
+
+(define_constraint "O"
+  ""
+  (and (match_code "const_int")
+       (match_test "ival == 0")))
+
+(define_constraint "C"
+  ""
+  (match_code "const_double"))
+
diff --git a/gcc/config/or1k/elf.h b/gcc/config/or1k/elf.h
new file mode 100644
index 0000000..9751ccf
--- /dev/null
+++ b/gcc/config/or1k/elf.h
@@ -0,0 +1,31 @@
+/* Definitions for OpenRISC OR1K using ELF
+   ??? this is for OR1K, but the rest of the above seems bogus.
+   Copyright (C) 1996, 1997, 2005, 2014 Free Software Foundation, Inc.
+   Contributed by Joel Sherrill (joel.sherrill@OARcorp.com).
+
+This file is part of GNU CC.
+
+GNU CC 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 2, or (at your option)
+any later version.
+
+GNU CC 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Use ELF */
+#undef  OBJECT_FORMAT_ELF
+#define OBJECT_FORMAT_ELF
+
+/* or1k debug info support is controlled by tm.h header files we include:
+   dbxelf.h enables optional stabs debug info.
+   elfos.h sets PREFERRED_DEBUGGING_TYPE to DWARF2_DEBUG .  */
+
+#define DRIVER_SELF_SPECS "%{!mno-newlib:-mnewlib}"
diff --git a/gcc/config/or1k/linux-elf.h b/gcc/config/or1k/linux-elf.h
new file mode 100644
index 0000000..57669d4
--- /dev/null
+++ b/gcc/config/or1k/linux-elf.h
@@ -0,0 +1,98 @@
+/* Definitions for or1k running Linux-based GNU systems using ELF
+   Copyright (C) 2002, 2005
+   Free Software Foundation, Inc.
+   Contributed by Marko Mlinar <markom@opencores.org>
+
+This file is part of GNU CC.
+
+GNU CC 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 2, or (at your option)
+any later version.
+
+GNU CC 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.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* elfos.h should have already been included.  Now just override
+   any conflicting definitions and add any extras.  */
+
+/* Do not assume anything about header files.  */
+#define NO_IMPLICIT_EXTERN_C
+
+/* This is how we tell the assembler that two symbols have the same value.  */
+#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
+  do                                       \
+    {                                      \
+      assemble_name (FILE, NAME1);         \
+      fputs (" = ", FILE);                 \
+      assemble_name (FILE, NAME2);         \
+      fputc ('\n', FILE);                  \
+    }                                      \
+    while (0)
+
+
+#if 0
+/* Node: Label Output */
+
+#define SET_ASM_OP      "\t.set\t"
+
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN)  \
+  (*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
+
+#define ASM_WEAKEN_LABEL(FILE, NAME)    \
+  do                                    \
+    {                                   \
+      fputs ("\t.weak\t", (FILE));      \
+      assemble_name ((FILE), (NAME));   \
+      fputc ('\n', (FILE));             \
+    }                                   \
+  while (0)
+
+#endif
+
+/* The GNU C++ standard library requires that these macros be defined.  */
+#undef CPLUSPLUS_CPP_SPEC
+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
+
+#undef DRIVER_SELF_SPECS
+#define DRIVER_SELF_SPECS ""
+
+#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+
+/* Define a set of Linux builtins. This is copied from linux.h. We can't
+   include the whole file for now, because that causes configure to require ld
+   to support --eh-frame-header, which it currently doesn't */
+#define LINUX_TARGET_OS_CPP_BUILTINS()				\
+    do {							\
+	builtin_define ("__gnu_linux__");			\
+	builtin_define_std ("linux");				\
+	builtin_define_std ("unix");				\
+	builtin_assert ("system=linux");			\
+	builtin_assert ("system=unix");				\
+	builtin_assert ("system=posix");			\
+    } while (0)
+
+#define TARGET_OS_CPP_BUILTINS()				\
+  do {								\
+    LINUX_TARGET_OS_CPP_BUILTINS();				\
+    if (OPTION_UCLIBC)						\
+      builtin_define ("__UCLIBC__");				\
+    /* The GNU C++ standard library requires this.  */		\
+    if (c_dialect_cxx ())					\
+      builtin_define ("_GNU_SOURCE");				\
+  } while (0)
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{mnewlib:-entry 0x100} \
+  -dynamic-linker " GNU_USER_DYNAMIC_LINKER " \
+  %{rdynamic:-export-dynamic} \
+  %{static:-static} \
+  %{shared:-shared}"
+
diff --git a/gcc/config/or1k/linux-gas.h b/gcc/config/or1k/linux-gas.h
new file mode 100644
index 0000000..4ab6fd6
--- /dev/null
+++ b/gcc/config/or1k/linux-gas.h
@@ -0,0 +1,37 @@
+/* Definitions of target machine for GNU compiler.
+   Or32 Linux-based GNU systems version.
+   Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+   Contributed by Marko Mlinar <markom@opencores.org>
+
+This file is part of GNU CC.
+
+GNU CC 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 2, or (at your option)
+any later version.
+
+GNU CC 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.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Unsigned chars produces much better code than signed.  */
+#undef  DEFAULT_SIGNED_CHAR
+#define DEFAULT_SIGNED_CHAR 1
+
+/* Make gcc agree with <machine/ansi.h> */
+
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+#define WCHAR_TYPE "unsigned int"
+#define WCHAR_TYPE_SIZE 32
+
+
+/* Clear the instruction cache from `beg' to `end'.  This makes an
+   inline system call to SYS_cacheflush.  */
+#define CLEAR_INSN_CACHE(BEG, END) /* Do something here !!! */
diff --git a/gcc/config/or1k/or1k-modes.def b/gcc/config/or1k/or1k-modes.def
new file mode 100644
index 0000000..39aedfa
--- /dev/null
+++ b/gcc/config/or1k/or1k-modes.def
@@ -0,0 +1,38 @@
+/* Definitions of target machine for GNU compiler, for OR32.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+   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 2, 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.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
+
+/* Add any extra modes needed to represent the condition code.
+ */
+
+CC_MODE (CCEQ);
+CC_MODE (CCNE);
+
+CC_MODE (CCLE);
+CC_MODE (CCGE);
+CC_MODE (CCLT);
+CC_MODE (CCGT);
+
+CC_MODE (CCLEU);
+CC_MODE (CCGEU);
+CC_MODE (CCLTU);
+CC_MODE (CCGTU);
+
+CC_MODE(CCFP);
+CC_MODE(CCUNS);
diff --git a/gcc/config/or1k/or1k-opts.h b/gcc/config/or1k/or1k-opts.h
new file mode 100644
index 0000000..c830527
--- /dev/null
+++ b/gcc/config/or1k/or1k-opts.h
@@ -0,0 +1,14 @@
+#ifndef OR1K_OPTS_H
+#define OR1K_OPTS_H
+
+enum or1k_delay {
+  OR1K_DELAY_OFF = 0,
+  OR1K_DELAY_ON = 1,
+  OR1K_DELAY_COMPAT = 2
+};
+
+#define TARGET_DELAY_ON     (or1k_delay_selected == OR1K_DELAY_ON)
+#define TARGET_DELAY_OFF    (or1k_delay_selected == OR1K_DELAY_OFF)
+#define TARGET_DELAY_COMPAT (or1k_delay_selected == OR1K_DELAY_COMPAT)
+
+#endif
diff --git a/gcc/config/or1k/or1k-protos.h b/gcc/config/or1k/or1k-protos.h
new file mode 100644
index 0000000..7ff38ba
--- /dev/null
+++ b/gcc/config/or1k/or1k-protos.h
@@ -0,0 +1,67 @@
+/* Definitions of target machine for GNU compiler, OR1K cpu.
+
+   Copyright (C) 2010 Embecosm Limited
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_OR1K_PROTOS_H
+#define GCC_OR1K_PROTOS_H
+
+/* The following are for general support. */
+extern int         or1k_trampoline_code_size (void);
+
+/* The following are only needed when handling the machine definition. */
+#ifdef RTX_CODE
+extern void        or1k_init_expanders (void);
+extern void        or1k_expand_prologue (void);
+extern void        or1k_expand_epilogue (void);
+extern bool        or1k_expand_move (enum machine_mode mode, rtx operands[]);
+extern const char *or1k_output_move_double (rtx *operands);
+extern void        or1k_expand_conditional_branch (rtx               *operands,
+						   enum machine_mode  mode);
+extern int         or1k_emit_cmove (rtx  dest,
+				    rtx  op,
+				    rtx  true_cond,
+				    rtx  false_cond);
+extern enum machine_mode or1k_select_cc_mode (enum rtx_code op);
+extern const char *or1k_output_bf (rtx * operands);
+extern const char *or1k_output_cmov (rtx * operands);
+extern void        or1k_emit_set_const32 (rtx  op0,
+                                          rtx  op1);
+extern bool        or1k_expand_symbol_ref (enum machine_mode mode,
+                                           rtx operands[]);
+extern void        or1k_expand_cmpxchg_qihi (rtx bval, rtx retval,
+                        rtx mem, rtx oldval, rtx newval, int is_weak,
+                        enum memmodel success_mode, enum memmodel failure_mode);
+extern void  or1k_expand_fetch_op_qihi (rtx oldval, rtx mem, rtx operand,
+                                        rtx newval, rtx (*generator)(rtx, rtx, rtx, rtx, rtx));
+#endif
+
+#endif
+extern int or1k_struct_alignment (tree);
+extern int or1k_data_alignment (tree, int);
+
+extern int or1k_initial_elimination_offset (int, int);
+extern bool or1k_save_reg_p_cached (int regno);
+extern void or1k_print_jump_restore (rtx jump_address);
+extern rtx or1k_eh_return_handler_rtx (void);
+extern rtx or1k_return_addr_rtx (int, rtx);
+
+extern int or1k_legitimate_pic_operand_p (rtx x);
+
+/* For RETURN_ADDR_RTX */
+extern rtx get_hard_reg_initial_val (enum machine_mode, unsigned int);
diff --git a/gcc/config/or1k/or1k.c b/gcc/config/or1k/or1k.c
new file mode 100644
index 0000000..6ec3d57
--- /dev/null
+++ b/gcc/config/or1k/or1k.c
@@ -0,0 +1,2445 @@
+/* Subroutines for insn-output.c for GNU compiler.  OpenRISC 1000 version.
+   Copyright (C) 1987, 1992, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006, 2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc
+   Copyright (C) 2010 Embecosm Limited
+
+   Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999.
+   Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005.
+   Updated for GCC 4.5 by Jeremy Bennett <jeremy.bennett@embecoms.com>
+   and Joern Rennecke <joern.rennecke@embecosm.com> in 2010.
+
+   This file is part of GNU CC.
+
+   This program 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 of the License, or (at your option)
+   any later version.
+  
+   This program 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.
+  
+   You should have received a copy of the GNU General Public License along
+   with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hash-set.h"
+#include "inchash.h"
+#include "symtab.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "varasm.h"
+#include "obstack.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "output.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "reload.h"
+#include "function.h"
+#include "explow.h"
+#include "emit-rtl.h"
+#include "expr.h"
+#include "toplev.h"
+#include "recog.h"
+#include "ggc.h"
+#include "except.h"
+#include "tm_p.h"
+#include "target.h"
+#include "target-def.h"
+#include "debug.h"
+#include "langhooks.h"
+#include "predict.h"
+#include "basic-block.h"
+#include "df.h"
+#include "optabs.h"
+#include "dwarf2.h"
+#include "ansidecl.h"
+#include "builtins.h"
+
+/* ========================================================================== */
+/* Local macros                                                               */
+
+/* Construct a l.movhi instruction for the given reg and value */
+#define OR1K_MOVHI(rd, k)						\
+  ((0x6 << 26) | ((rd) << 21) | (k))
+
+/* Construct a l.ori instruction for the given two regs and value */
+#define OR1K_ORI(rd, ra, k)						\
+  ((0x2a << 26) | ((rd) << 21) | ((ra) << 16) | (k))
+
+/* Construct a l.lwz instruction for the given two registers and offset */
+#define OR1K_LWZ(rd, ra, i)						\
+  ((0x21 << 26) | ((rd) << 21) | ((ra) << 16) | (i))
+
+/* Construct a l.jr instruction for the given register */
+#define OR1K_JR(rb)							\
+  ((0x11 << 26) | ((rb) << 11))
+
+#define OR1K_NOP                                \
+  (0x15 << 24)
+
+/* ========================================================================== */
+/* Static variables (i.e. global to this file only.                           */
+
+
+/*!Stack layout we use for pushing and poping saved registers */
+static struct
+{
+  bool save_lr_p;
+  int lr_save_offset;
+  bool save_fp_p;
+  int fp_save_offset;
+  int gpr_size;
+  int gpr_offset;
+  int total_size;
+  int vars_size;
+  int args_size;
+  int gpr_frame;
+  int late_frame;
+  HOST_WIDE_INT mask;
+}  frame_info;
+
+
+/* ========================================================================== */
+/* Local (i.e. static) utility functions */
+
+/* -------------------------------------------------------------------------- */
+/*!Must the current function save a register?
+
+   @param[in] regno  The register to consider.
+
+   @return  Non-zero (TRUE) if current function must save "regno", zero
+            (FALSE) otherwise.                                                */
+/* -------------------------------------------------------------------------- */
+static bool
+or1k_save_reg_p (int regno)
+{
+  /* No need to save the faked cc0 register.  */
+  if (regno == OR1K_FLAGS_REG)
+    return false;
+
+  /* Check call-saved registers.  */
+  if (df_regs_ever_live_p(regno) && !call_used_regs[regno])
+    return true;
+
+  /* We need to save the old frame pointer before setting up a new
+     one.  */
+  if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
+    return true;
+
+  /* Save the stack pointer for DWARF2 for now.
+   * AFAIK, DWARF should be able to unwind using only the current stack
+   * register and the CFA offset, but I never got that to work. */
+  if (regno == STACK_POINTER_REGNUM && !frame_pointer_needed)
+    return true;
+
+  /* We need to save the incoming return address if it is ever clobbered
+     within the function.  */
+  if (regno == LINK_REGNUM
+      && (df_regs_ever_live_p(regno) || crtl->uses_pic_offset_table
+          || cfun->machine->force_lr_save))
+    return true;
+
+  if(crtl->calls_eh_return)
+    {
+      unsigned int i;
+      for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
+        {
+          if ((unsigned int)regno == EH_RETURN_DATA_REGNO (i))
+            return true;
+        }
+    }
+
+  return false;
+
+}	/* or1k_save_reg_p () */
+
+bool
+or1k_save_reg_p_cached (int regno)
+{
+  return (frame_info.mask & ((HOST_WIDE_INT) 1 << regno)) != 0;
+}
+
+/* N.B. contrary to the ISA documentation, the stack includes the outgoing
+   arguments.  */
+/* -------------------------------------------------------------------------- */
+/*!Compute full frame size and layout.
+
+   Store information in "frame_info".
+
+   @param[in] size  The size of the function's local variables.
+
+   @return  Total size of stack frame.                                        */
+/* -------------------------------------------------------------------------- */
+static HOST_WIDE_INT
+or1k_compute_frame_size (HOST_WIDE_INT size)
+{
+  HOST_WIDE_INT args_size;
+  HOST_WIDE_INT vars_size;
+  HOST_WIDE_INT stack_offset;
+  HOST_WIDE_INT save_size;
+  bool interrupt_p = false;
+  int regno;
+
+  args_size = crtl->outgoing_args_size;
+  vars_size = OR1K_ALIGN (size, 4);
+
+  frame_info.args_size = args_size;
+  frame_info.vars_size = vars_size;
+  frame_info.gpr_frame = interrupt_p ? or1k_redzone : 0;
+
+  /* If the function has local variables, we're committed to
+     allocating it anyway.  Otherwise reclaim it here.  */
+  /* FIXME: Verify this.  Got if from the MIPS port.  */
+  if (vars_size == 0 && crtl->is_leaf)
+    args_size = 0;
+
+  stack_offset = 0;
+
+  /* Save link register right at the bottom.  */
+  if (or1k_save_reg_p (LINK_REGNUM))
+    {
+      stack_offset = stack_offset - UNITS_PER_WORD;
+      frame_info.lr_save_offset = stack_offset;
+      frame_info.save_lr_p = true;
+    }
+  else
+    frame_info.save_lr_p = false;
+
+  /* HACK: In PIC mode we need to save the PIC reg and the link reg in
+     in case the function is doing references through the got or plt,
+     but this information is not necessarily available when the initial
+     elimination offset is calculated, so we always reserve the space even
+     if it is not used... */
+  if (!frame_info.save_lr_p && flag_pic)
+    stack_offset = stack_offset - UNITS_PER_WORD;
+
+  /* Save frame pointer right after possible link register.  */
+  if (frame_pointer_needed)
+    {
+      stack_offset = stack_offset - UNITS_PER_WORD;
+      frame_info.fp_save_offset = stack_offset;
+      frame_info.save_fp_p = true;
+    }
+  else
+    frame_info.save_fp_p = false;
+
+  frame_info.gpr_size = 0;
+  frame_info.mask = 0;
+
+  for (regno = 0; regno <= OR1K_LAST_ACTUAL_REG; regno++)
+    {
+      if (regno == LINK_REGNUM
+	  || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM))
+	/* These have already been saved if so needed.  */
+	continue;
+
+      if (or1k_save_reg_p (regno))
+	{
+	  frame_info.gpr_size += UNITS_PER_WORD;
+	  frame_info.mask |= ((HOST_WIDE_INT) 1 << regno);
+	}
+    }
+
+  if (!or1k_save_reg_p (PIC_OFFSET_TABLE_REGNUM)
+      && (crtl->uses_pic_offset_table || (flag_pic && frame_info.save_lr_p)))
+    {
+      frame_info.gpr_size += UNITS_PER_WORD;
+      frame_info.mask |= ((HOST_WIDE_INT) 1 << PIC_OFFSET_TABLE_REGNUM);
+    }
+  else if (flag_pic && !or1k_save_reg_p (PIC_OFFSET_TABLE_REGNUM))
+    frame_info.gpr_size += UNITS_PER_WORD;
+
+  save_size = (frame_info.gpr_size 
+	       + (frame_info.save_fp_p ? UNITS_PER_WORD : 0)
+	       + (frame_info.save_lr_p || flag_pic ? UNITS_PER_WORD : 0));
+  frame_info.total_size = save_size + vars_size + args_size;
+  gcc_assert (PROLOGUE_TMP != STATIC_CHAIN_REGNUM);
+  if (frame_info.total_size > 32767 && interrupt_p)
+    {
+      int n_extra
+	= (!!(~frame_info.mask && 1 << PROLOGUE_TMP)
+	   + !!(~frame_info.mask & 1 << EPILOGUE_TMP)) * UNITS_PER_WORD;
+
+      save_size += n_extra;
+      frame_info.gpr_size += n_extra;
+      frame_info.total_size += n_extra;
+      frame_info.mask |= (1 << PROLOGUE_TMP) | (1 << EPILOGUE_TMP);
+    }
+
+  stack_offset -= frame_info.gpr_size;
+  frame_info.gpr_offset = stack_offset;
+  frame_info.late_frame = frame_info.total_size;
+
+  if (save_size > or1k_redzone
+      || (frame_info.gpr_frame
+	  && (frame_info.gpr_frame + frame_info.late_frame <= 32767)))
+    {
+      if (frame_info.gpr_frame + frame_info.late_frame <= 32767)
+	save_size = frame_info.total_size;
+      frame_info.gpr_frame += save_size;
+      frame_info.lr_save_offset += save_size;
+      frame_info.fp_save_offset += save_size;
+      frame_info.gpr_offset += save_size;
+      frame_info.late_frame -= save_size;
+      /* FIXME: check in TARGET_OVERRIDE_OPTIONS for invalid or1k_redzone.  */
+      gcc_assert (frame_info.gpr_frame <= 32767);
+      gcc_assert ((frame_info.gpr_frame & 3) == 0);
+    }
+
+  return frame_info.total_size;
+
+}	/* or1k_compute_frame_size () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Emit a frame related insn.
+
+   Same as emit_insn, but sets RTX_FRAME_RELATED_P to one. Getting this right
+   will matter for DWARF 2 output, if prologues are handled via the "prologue"
+   pattern rather than target hooks.
+
+   @param[in] insn  The insn to emit.
+
+   @return  The RTX for the emitted insn.                                     */
+/* -------------------------------------------------------------------------- */
+static rtx
+emit_frame_insn (rtx insn)
+{
+  insn = emit_insn (insn);
+  RTX_FRAME_RELATED_P (insn) = 1;
+  return (insn);
+
+}	/* emit_frame_insn () */
+
+
+/* -------------------------------------------------------------------------- */
+/* Generate a RTX for the indexed memory address based on stack_pointer_rtx
+   and a displacement
+
+   @param[in] disp  The displacement
+
+   @return  The RTX for the generated address.                                */
+/* -------------------------------------------------------------------------- */
+static rtx
+stack_disp_mem (HOST_WIDE_INT disp)
+{
+  return gen_frame_mem (Pmode, plus_constant (Pmode, stack_pointer_rtx, disp));
+}
+
+enum machine_mode
+or1k_select_cc_mode (enum rtx_code op)
+{
+  switch (op) {
+  case EQ:  return CCEQmode;
+  case NE:  return CCNEmode;
+  case GEU: return CCGEUmode;
+  case GTU: return CCGTUmode;
+  case LTU: return CCLTUmode;
+  case LEU: return CCLEUmode;
+  case GE:  return CCGEmode;
+  case LT:  return CCLTmode;
+  case GT:  return CCGTmode;
+  case LE:  return CCLEmode;
+  default:  gcc_unreachable ();
+  }
+}
+
+/* -------------------------------------------------------------------------- */
+/*!Generate insn patterns to do an integer compare of operands.
+
+   @param[in] code  RTX for the condition code.
+   @param[in] op0   RTX for the first operand.
+   @param[in] op1   RTX for the second operand.
+
+   @return  RTX for the comparison.                                           */
+/* -------------------------------------------------------------------------- */
+static rtx
+or1k_expand_int_compare (enum rtx_code  code,
+			 rtx            op0,
+			 rtx            op1)
+{
+  enum machine_mode cmpmode;
+  rtx tmp, flags;
+
+  cmpmode = or1k_select_cc_mode (code);
+  flags = gen_rtx_REG (cmpmode, OR1K_FLAGS_REG);
+
+  /* This is very simple, but making the interface the same as in the
+     FP case makes the rest of the code easier.  */
+  tmp = gen_rtx_COMPARE (cmpmode, op0, op1);
+  emit_insn (gen_rtx_SET (VOIDmode, flags, tmp));
+
+  /* Return the test that should be put into the flags user, i.e.
+     the bcc, scc, or cmov instruction.  */
+  return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
+
+}	/* or1k_expand_int_compare () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Generate insn patterns to do an integer compare of operands.
+
+   We only deal with the case where the comparison is an integer
+   comparison. This wrapper function potentially allows reuse for non-integer
+   comparison in the future.
+
+   @param[in] code  RTX for the condition code.
+   @param[in] op0   RTX for the first operand.
+   @param[in] op1   RTX for the second operand.
+
+   @return  RTX for the comparison.                                           */
+/* -------------------------------------------------------------------------- */
+static rtx
+or1k_expand_compare (enum rtx_code code, rtx op0, rtx op1)
+{
+  return or1k_expand_int_compare (code, op0, op1);
+
+}	/* or1k_expand_compare () */
+
+
+/* TODO(bluecmd): Write documentation for this function */
+void
+or1k_expand_cmpxchg_qihi (rtx bval, rtx retval, rtx mem, rtx oldval, rtx newval,
+                          int  __attribute__ ((unused)) is_weak,
+                          enum memmodel __attribute__ ((unused)) success_mode,
+                          enum memmodel __attribute__ ((unused)) failure_mode)
+{
+  rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
+  rtx addr = gen_reg_rtx (Pmode);
+  rtx off = gen_reg_rtx (SImode);
+  rtx shifter = gen_reg_rtx (SImode);
+  rtx retword = gen_reg_rtx (SImode);
+  rtx mask = gen_reg_rtx (SImode);
+  rtx shifted_oldval = gen_reg_rtx (SImode);
+  rtx shifted_newval = gen_reg_rtx (SImode);
+  rtx shifted_mask = gen_reg_rtx (SImode);
+  rtx mask_const;
+  rtx memsi;
+  enum machine_mode mode = GET_MODE (mem);
+
+  oldval = gen_lowpart_common (SImode, oldval);
+  newval = gen_lowpart_common (SImode, newval);
+
+  mask_const = gen_rtx_CONST_INT (VOIDmode,
+                                  mode == QImode ? 0xff : 0xffff);
+  emit_insn (gen_rtx_SET (VOIDmode, mask, mask_const));
+
+  /* align address and retrieve the offset. */
+  emit_insn (gen_rtx_SET (VOIDmode, addr,
+             gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
+  emit_insn (gen_rtx_SET (VOIDmode, off,
+             gen_rtx_AND (SImode, addr1, GEN_INT (3))));
+  emit_insn (gen_rtx_SET (VOIDmode, off,
+                          gen_rtx_XOR (SImode, off,
+                                       GEN_INT (GET_MODE (mem) == QImode
+                                                ? 3 : 2))));
+
+  memsi = gen_rtx_MEM (SImode, addr);
+
+  /* shift all arguments to be aligned to where the data we want
+   * to operate on is located. */
+  emit_insn (gen_rtx_SET (VOIDmode, shifter,
+             gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
+
+  emit_insn (gen_ashlsi3 (shifted_oldval, oldval, shifter));
+  emit_insn (gen_ashlsi3 (shifted_newval, newval, shifter));
+  emit_insn (gen_ashlsi3 (shifted_mask, mask, shifter));
+
+  emit_insn (gen_cmpxchg_mask (bval, retword, memsi, shifted_oldval,
+                               shifted_newval, shifted_mask));
+
+  /* shift the data we care about to the lower end. */
+  emit_insn (gen_lshrsi3 (retword, retword, shifter));
+
+  emit_move_insn (retval, gen_lowpart (GET_MODE (retval), retword));
+}
+
+/* TODO(bluecmd): Write documentation for this function */
+void
+or1k_expand_fetch_op_qihi (rtx oldval, rtx mem, rtx operand, rtx newval,
+                           rtx (*generator)(rtx, rtx, rtx, rtx, rtx))
+{
+  rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
+  rtx addr = gen_reg_rtx (Pmode);
+  rtx off = gen_reg_rtx (SImode);
+  rtx shifter = gen_reg_rtx (SImode);
+  rtx mask = gen_reg_rtx (SImode);
+  rtx shifted_oldval = gen_reg_rtx (SImode);
+  rtx shifted_newval = gen_reg_rtx (SImode);
+  rtx shifted_operand = gen_reg_rtx (SImode);
+  rtx shifted_mask = gen_reg_rtx (SImode);
+  rtx mask_const;
+  rtx memsi;
+  enum machine_mode mode = GET_MODE (mem);
+
+  /* TODO(bluecmd): A lot of code is shared between cmpxchg and this. We should
+   * move it to nice functions. */
+  operand = gen_lowpart_common (SImode, operand);
+
+  mask_const = gen_rtx_CONST_INT (VOIDmode,
+                                  mode == QImode ? 0xff : 0xffff);
+  emit_insn (gen_rtx_SET (VOIDmode, mask, mask_const));
+
+  /* align address and retrieve the offset. */
+  emit_insn (gen_rtx_SET (VOIDmode, addr,
+             gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
+  emit_insn (gen_rtx_SET (VOIDmode, off,
+             gen_rtx_AND (SImode, addr1, GEN_INT (3))));
+  emit_insn (gen_rtx_SET (VOIDmode, off,
+                          gen_rtx_XOR (SImode, off,
+                                       GEN_INT (GET_MODE (mem) == QImode
+                                                ? 3 : 2))));
+
+  memsi = gen_rtx_MEM (SImode, addr);
+
+  /* shift all arguments to be aligned to where the data we want
+   * to operate on is located. */
+  emit_insn (gen_rtx_SET (VOIDmode, shifter,
+             gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
+
+  emit_insn (gen_ashlsi3 (shifted_operand, operand, shifter));
+  emit_insn (gen_ashlsi3 (shifted_mask, mask, shifter));
+
+  emit_insn (generator (shifted_oldval, memsi, shifted_operand,
+                        shifted_newval, shifted_mask));
+
+  /* shift the data we care about to the lower end. */
+  emit_insn (gen_lshrsi3 (shifted_oldval, shifted_oldval, shifter));
+  emit_insn (gen_lshrsi3 (shifted_newval, shifted_newval, shifter));
+  emit_move_insn (oldval, gen_lowpart (GET_MODE (oldval), shifted_oldval));
+  emit_move_insn (newval, gen_lowpart (GET_MODE (newval), shifted_newval));
+}
+
+/* -------------------------------------------------------------------------- */
+/*!Emit insns to use the l.cmov instruction
+
+   Emit a compare and then cmov. Only works for integer first operand.
+
+   @param[in] dest        RTX for the destination operand.
+   @param[in] op          RTX for the comparison operation
+   @param[in] true_cond   RTX to move to dest if condition is TRUE.
+   @param[in] false_cond  RTX to move to dest if condition is FALSE.
+   
+   @return  Non-zero (TRUE) if insns were emitted, zero (FALSE) otherwise.    */
+/* -------------------------------------------------------------------------- */
+static int
+or1k_emit_int_cmove (rtx  dest,
+		     rtx  op,
+		     rtx  true_cond,
+		     rtx  false_cond)
+{
+  rtx condition_rtx, cr;
+  rtx op0 = XEXP (op, 0);
+  rtx op1 = XEXP (op, 1);
+
+  if ((GET_MODE (op0) != SImode) &&
+      (GET_MODE (op0) != HImode) &&
+      (GET_MODE (op0) != QImode))
+    {
+      return 0;
+    }
+
+  /* We still have to do the compare, because cmov doesn't do a compare, it
+     just looks at the FLAG bit set by a previous compare instruction.  */
+  condition_rtx = or1k_expand_compare (GET_CODE (op), op0, op1);
+
+  cr = XEXP (condition_rtx, 0);
+
+  emit_insn (gen_cmov (dest, condition_rtx, true_cond, false_cond, cr));
+
+  return 1;
+
+}	/* or1k_emit_int_cmove () */
+
+
+static void
+or1k_print_operand_address (FILE *stream, rtx addr)
+{
+  rtx offset;
+
+  switch (GET_CODE (addr))
+    {
+    case MEM:
+      if (GET_CODE (XEXP (addr, 0)) == REG)
+        fprintf (stream, "%s", reg_names[REGNO (addr)]);
+      else
+        abort ();
+      break;
+
+    case REG:
+      fprintf (stream, "0(%s)", reg_names[REGNO (addr)]);
+      break;
+
+    case PLUS:
+      offset = 0;
+
+      if (GET_CODE (XEXP (addr, 0)) == REG)
+        {
+          offset = XEXP (addr, 1);
+          addr   = XEXP (addr, 0);
+        }
+      else if (GET_CODE (XEXP (addr, 1)) == REG)
+        {
+          offset = XEXP (addr, 0);
+          addr   = XEXP (addr, 1);
+        }
+      output_address (offset);
+      fprintf (stream, "(%s)", reg_names[REGNO (addr)]);
+      break;
+
+    case SYMBOL_REF:
+      if (SYMBOL_REF_DECL (addr))
+        assemble_external (SYMBOL_REF_DECL (addr));
+
+      if (XSTR (addr, 0)[0] == '*')
+        fputs (&XSTR (addr, 0)[1], stream);
+      else
+        {
+          asm_fprintf (stream, "%U%s", XSTR (addr, 0));
+        }
+      break;
+
+    default:
+      output_addr_const (stream, addr);
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+/*!Is this a value suitable for an OR1K address displacement?
+
+   Must be an integer (signed) which fits into 16-bits. If the result is a
+   double word, we had better also check that we can also get at the second
+   word.
+
+   @param[in] mode  Mode of the result for which this displacement will be
+                    used.
+   @param[in] x     RTX for an expression.
+
+   @return  Non-zero (TRUE) if this is a valid 16-bit offset, zero (FALSE)
+            otherwise.                                                        */
+/* -------------------------------------------------------------------------- */
+static int
+or1k_legitimate_displacement_p (enum machine_mode  mode,
+				rtx                x)
+{
+  if (CONST_INT == GET_CODE(x))
+    {
+      HOST_WIDE_INT  disp = INTVAL (x);
+
+      /* Allow for a second access 4 bytes further on if double. */
+      if ((DFmode == mode) || (DImode == mode))
+	{
+	  return  (-32768 < disp) && (disp <= 32763);
+	}
+      else
+	{
+	  return  (-32768 < disp) && (disp <= 32767);
+	}
+    }
+  else
+    {
+      return  0;
+    }
+}	/* or1k_legitimate_displacement_p () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Can this register be used as a base register?
+
+   We need a strict version, for which the register must either be a hard
+   register, or already renumbered to a hard register.
+
+   For the non-strict version, any register (other than the flag register will
+   do).
+
+   @todo The code from the old port does not allow r0 as a base when strict,
+         and does when non-strict. Surely it is always a valid register?
+
+   @param[in] regno   The register to test
+   @param[in] strict  Non-zero (TRUE) if this is a strict check, zero (FALSE)
+                      otherwise.
+
+   @return  Non-zero (TRUE) if this register can be used as a base register,
+            zero (FALSE) otherwise.                                           */
+/* -------------------------------------------------------------------------- */
+static bool
+or1k_regnum_ok_for_base_p (HOST_WIDE_INT  num,
+			   bool           strict)
+{
+  if (strict)
+    {
+      return (num < FIRST_PSEUDO_REGISTER)
+	? (num > 0) && (num <= OR1K_LAST_INT_REG)
+	: (reg_renumber[num] > 0) && (reg_renumber[num] <= OR1K_LAST_INT_REG);
+    }
+  else
+    {
+      return (num <= OR1K_LAST_INT_REG) || (num >= FIRST_PSEUDO_REGISTER);
+    }
+}	/* or1k_regnum_ok_for_base_p () */
+
+int
+or1k_legitimate_pic_operand_p (rtx x)
+{
+  if (GET_CODE (x) == CONST
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+	   && (!SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0))
+	       || SYMBOL_REF_WEAK (XEXP (XEXP (x, 0), 0))))
+	  || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
+      && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
+    return or1k_legitimate_displacement_p (SImode, XEXP (XEXP (x, 0), 1));
+
+  return 1;
+}
+
+static bool
+or1k_expand_pic_symbol_ref (enum machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx operands[])
+{
+  if (GET_CODE (operands[1]) == LABEL_REF
+      || (GET_CODE (operands[1]) == SYMBOL_REF
+	  && SYMBOL_REF_LOCAL_P (operands[1])
+	  && !SYMBOL_REF_WEAK (operands[1])))
+    {
+      crtl->uses_pic_offset_table = 1;
+      emit_insn (gen_movsi_gotoffhi (operands[0], operands[1]));
+      emit_insn (gen_movsi_gotofflo (operands[0], operands[0],
+				     operands[1]));
+      emit_insn (gen_add3_insn(operands[0], operands[0],
+			       pic_offset_table_rtx));
+      return true;
+    }
+  else if (GET_CODE (operands[1]) == SYMBOL_REF)
+    {
+      crtl->uses_pic_offset_table = 1;
+      emit_insn (gen_movsi_got (operands[0], operands[1]));
+      return true;
+    }
+  else if (GET_CODE (operands[1]) == CONST
+	   && GET_CODE (XEXP (operands[1], 0)) == PLUS
+	   && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF
+	   && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
+    {
+      rtx symbolref = XEXP (XEXP (operands[1], 0), 0);
+      crtl->uses_pic_offset_table = 1;
+
+      if (SYMBOL_REF_LOCAL_P (symbolref)
+	  && !SYMBOL_REF_WEAK (symbolref))
+	{
+	  emit_insn (gen_movsi_gotoffhi (operands[0], operands[1]));
+	  emit_insn (gen_movsi_gotofflo (operands[0], operands[0],
+					 operands[1]));
+	  emit_insn (gen_add3_insn(operands[0], operands[0],
+				   pic_offset_table_rtx));
+	}
+      else
+	{
+	  rtx const_int = XEXP (XEXP (operands[1], 0), 1);
+
+	  /* Expand the constant into a register if it doesn't
+	     fit directly as an 16-bit immediate in the add below.
+	     Note that the reg allocation is allowed here since
+	     we are guarded by LEGITIMATE_PIC_OPERAND_P. */
+	  if (!or1k_legitimate_displacement_p (mode, const_int))
+	    {
+	      rtx scratch = gen_reg_rtx (mode);
+
+	      or1k_emit_set_const32 (scratch, const_int);
+	      const_int = scratch;
+	    }
+
+	  emit_insn (gen_movsi_got (operands[0], symbolref));
+	  emit_insn (gen_add3_insn(operands[0], operands[0], const_int));
+	}
+      return true;
+    }
+  return false;
+}
+
+/* Return the TLS type for TLS symbols, 0 otherwise.  */
+enum tls_model
+or1k_tls_symbolic_operand (rtx op)
+{
+  if (GET_CODE (op) == CONST)
+    {
+      rtx sym, addend;
+      split_const (op, &sym, &addend);
+      if (GET_CODE (sym) == SYMBOL_REF)
+	return SYMBOL_REF_TLS_MODEL (sym);
+    }
+  else if (GET_CODE (op) == SYMBOL_REF)
+    return SYMBOL_REF_TLS_MODEL (op);
+
+  return TLS_MODEL_NONE;
+}
+
+static GTY(()) rtx gen_tls_tga;
+
+/* Get reference to the '__tls_get_addr' symbol */
+static rtx
+gen_tls_get_addr (void)
+{
+  if (!gen_tls_tga)
+    gen_tls_tga = init_one_libfunc ("__tls_get_addr");
+  return gen_tls_tga;
+}
+
+/* Emit call to '__tls_get_addr' */
+static void
+or1k_tls_call (rtx dest, rtx arg)
+{
+  emit_library_call_value (gen_tls_get_addr(), dest,
+      LCT_CONST, Pmode, 1, arg, Pmode);
+}
+
+static rtx
+or1k_legitimize_tls_address (rtx dest, rtx x)
+{
+  rtx sym;
+  rtx tp = gen_rtx_REG(Pmode, THREAD_PTR_REGNUM);
+  rtx addend = NULL_RTX;
+  rtx result = dest;
+
+  enum tls_model tls_kind = or1k_tls_symbolic_operand (x);
+
+  if (GET_CODE (x) == SYMBOL_REF)
+    sym = gen_rtx_SYMBOL_REF(Pmode, XSTR(x, 0));
+  else if (GET_CODE (x) == CONST)
+    {
+      result = gen_reg_rtx (Pmode);
+      split_const (x, &sym, &addend);
+      sym = gen_rtx_SYMBOL_REF(Pmode, XSTR(sym, 0));
+    }
+  else
+    gcc_unreachable ();
+
+  switch (tls_kind) {
+    case TLS_MODEL_GLOBAL_DYNAMIC:
+    case TLS_MODEL_LOCAL_DYNAMIC:
+      {
+        /* TODO: For now, treat LD as GD */
+        rtx hi = gen_reg_rtx (Pmode);
+        rtx offset = gen_reg_rtx (Pmode);
+        rtx addr = gen_reg_rtx (Pmode);
+        crtl->uses_pic_offset_table = 1;
+        /* Generate a new symbol ref that is not marked as TLS or we will recurse
+         * in or1k_legitimate_constant_p. */
+        emit_insn (gen_movsi_tlsgdhi (hi, sym));
+        emit_insn (gen_movsi_tlsgdlo (offset, hi, sym));
+        emit_insn (gen_add3_insn (addr, offset, pic_offset_table_rtx));
+        or1k_tls_call (result, addr);
+        break;
+      }
+    case TLS_MODEL_INITIAL_EXEC:
+      {
+        rtx hi = gen_reg_rtx (Pmode);
+        rtx offset = gen_reg_rtx (Pmode);
+        rtx addr = gen_reg_rtx (Pmode);
+        rtx tpoffset = gen_reg_rtx (Pmode);
+        crtl->uses_pic_offset_table = 1;
+        emit_insn (gen_movsi_gottpoffhi (hi, sym));
+        emit_insn (gen_movsi_gottpofflo (offset, hi, sym));
+        emit_insn (gen_add3_insn (addr, offset, pic_offset_table_rtx));
+        emit_insn (gen_load_gottpoff (tpoffset, addr));
+        emit_insn (gen_add3_insn (result, tpoffset, tp));
+        break;
+      }
+    case TLS_MODEL_LOCAL_EXEC:
+      {
+        rtx hi = gen_reg_rtx (Pmode);
+        rtx addr = gen_reg_rtx (Pmode);
+        emit_insn (gen_movsi_tpoffhi (hi, sym));
+        emit_insn (gen_movsi_tpofflo (addr, hi, sym));
+        emit_insn (gen_add3_insn (result, addr, tp));
+        break;
+      }
+    default:
+      gcc_unreachable ();
+  }
+
+  if (addend != NULL_RTX)
+    emit_insn (gen_add3_insn (dest, result, addend));
+
+  return dest;
+}
+
+static rtx
+or1k_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+                         enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  if (or1k_tls_symbolic_operand (x) != TLS_MODEL_NONE)
+    return or1k_legitimize_tls_address (gen_reg_rtx (Pmode), x);
+
+  return x;
+}
+
+static bool
+or1k_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+  return or1k_tls_symbolic_operand (x) != TLS_MODEL_NONE;
+}
+
+bool
+or1k_expand_symbol_ref(enum machine_mode mode, rtx operands[])
+{
+  if (flag_pic && or1k_expand_pic_symbol_ref(mode, operands))
+    return true;
+
+  return false;
+}
+
+bool
+or1k_expand_move (enum machine_mode mode, rtx operands[])
+{
+  if (can_create_pseudo_p ())
+    {
+      if (GET_CODE (operands[0]) == MEM
+	  || (GET_CODE (operands[0]) == SUBREG
+	      && GET_CODE (SUBREG_REG (operands[0])) == MEM))
+        {
+          /* Source operand for store must be in a register.  */
+          operands[1] = force_reg (SImode, operands[1]);
+        }
+    }
+
+  if (or1k_tls_symbolic_operand (operands[1]) != TLS_MODEL_NONE)
+    {
+      or1k_legitimize_tls_address (force_reg (Pmode, operands[0]),
+          operands[1]);
+      return true;
+    }
+
+  if (or1k_expand_symbol_ref (mode, operands))
+    return true;
+
+  /* Working with CONST_INTs is easier, so convert
+     a double if needed.  */
+
+  if (GET_CODE (operands[1]) == CONST_DOUBLE) {
+    operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+  }
+
+  /* Handle sets of MEM first.  */
+  if (GET_CODE (operands[0]) == MEM)
+    {
+      if (register_operand(operands[1], SImode)
+          || (operands[1] == const0_rtx))
+        goto movsi_is_ok;
+
+      if (! reload_in_progress)
+        {
+          operands[0] = validize_mem (operands[0]);
+          operands[1] = force_reg (SImode, operands[1]);
+        }
+    }
+
+  /* This makes sure we will not get rematched due to splittage.  */
+  if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
+    ;
+  else if (CONSTANT_P (operands[1])
+           && GET_CODE (operands[1]) != HIGH
+           && GET_CODE (operands[1]) != LO_SUM)
+    {
+      or1k_emit_set_const32 (operands[0], operands[1]);
+      return true;
+    }
+ movsi_is_ok:
+  ;
+
+  return false;
+}
+
+/* -------------------------------------------------------------------------- */
+/*!Emit a move from SRC to DEST.
+
+   Assume that the move expanders can handle all moves if !can_create_pseudo_p
+   ().  The distinction is important because, unlike emit_move_insn, the move
+   expanders know how to force Pmode objects into the constant pool even when
+   the constant pool address is not itself legitimate.
+
+   @param[in] dest  Destination of the move.
+   @param[in] src   Source for the move.
+
+   @return  RTX for the move.                                                 */
+/* -------------------------------------------------------------------------- */
+static rtx
+or1k_emit_move (rtx dest, rtx src)
+{
+  return (can_create_pseudo_p ()
+	  ? emit_move_insn (dest, src)
+	  : emit_move_insn_1 (dest, src));
+
+}	/* or1k_emit_move () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Emit an instruction of the form (set TARGET (CODE OP0 OP1)).
+
+   @param[in] code    The code for the operation.
+   @param[in] target  Destination for the set operation.
+   @param[in] op0     First operand.
+   @param[in] op1     Second operand.                                         */
+/* -------------------------------------------------------------------------- */
+static void
+or1k_emit_binary (enum rtx_code  code,
+		  rtx            target,
+		  rtx            op0,
+		  rtx            op1)
+{
+  emit_insn (gen_rtx_SET (VOIDmode, target,
+			  gen_rtx_fmt_ee (code, GET_MODE (target), op0, op1)));
+
+}	/* or1k_emit_binary () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Compute the result of an operation into a new register.
+
+   Compute ("code" "op0" "op1") and store the result in a new register of mode
+   "mode".
+
+   @param[in] mode  Mode of the result
+   @parma[in] code  RTX for the operation to perform
+   @param[in] op0   RTX for the first operand
+   @param[in] op1   RTX for the second operand
+   
+   @return  The RTX for the new register.                                     */
+/* -------------------------------------------------------------------------- */
+static rtx
+or1k_force_binary (enum machine_mode  mode,
+		   enum rtx_code      code,
+		   rtx                op0,
+		   rtx                op1)
+{
+  rtx  reg;
+
+  reg = gen_reg_rtx (mode);
+  or1k_emit_binary (code, reg, op0, op1);
+
+  return reg;
+
+}	/* or1k_force_binary () */
+
+
+/* ========================================================================== */
+/* Global support functions                                                   */
+
+static int
+or1k_trampoline_code_words (void)
+{
+  int words = 5;
+
+  /* need one more word in TARGET_DELAY_COMPAT mode to hold l.nop in delay slot */
+  if (TARGET_DELAY_COMPAT)
+    words++;
+  
+  return words;
+}
+
+/* -------------------------------------------------------------------------- */
+/* Return the size in bytes of the trampoline code.
+
+   Padded to TRAMPOLINE_ALIGNMENT bits. The code sequence is documented in
+   or1k_trampoline_init ().
+
+   This is just the code size. the static chain pointer and target function
+   address immediately follow.
+
+   @return  The size of the trampoline code in bytes.                         */
+/* -------------------------------------------------------------------------- */
+int
+or1k_trampoline_code_size (void)
+{
+  const int  TRAMP_BYTE_ALIGN = TRAMPOLINE_ALIGNMENT / 8;
+
+  return (or1k_trampoline_code_words() * 4 + TRAMP_BYTE_ALIGN - 1) / TRAMP_BYTE_ALIGN * TRAMP_BYTE_ALIGN;
+
+}	/* or1k_trampoline_code_size () */
+
+
+/* ========================================================================== */
+/* Functions to support the Machine Description                               */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Expand a prologue pattern.
+
+   Called after register allocation to add any instructions needed for the
+   prologue.  Using a prologue insn is favored compared to putting all of the
+   instructions in output_function_prologue(), since it allows the scheduler
+   to intermix instructions with the saves of the caller saved registers.  In
+   some cases, it might be necessary to emit a barrier instruction as the last
+   insn to prevent such scheduling.                                           */
+/* -------------------------------------------------------------------------- */
+void
+or1k_expand_prologue (void)
+{
+  int total_size = or1k_compute_frame_size (get_frame_size ());
+  rtx insn;
+
+  if (!total_size)
+    /* No frame needed.  */
+    return;
+
+  gcc_assert (!frame_info.save_lr_p || !frame_info.save_fp_p
+	      || frame_info.lr_save_offset != frame_info.fp_save_offset);
+
+  if (frame_info.gpr_frame)
+    emit_frame_insn (gen_add2_insn (stack_pointer_rtx,
+				    GEN_INT (-frame_info.gpr_frame)));
+  if (frame_info.save_fp_p)
+    {
+      emit_frame_insn (gen_rtx_SET (Pmode,
+				    stack_disp_mem (frame_info.fp_save_offset),
+				    hard_frame_pointer_rtx));
+
+      emit_frame_insn
+	(gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx, const0_rtx));
+    }
+  if (frame_info.save_lr_p)
+    {
+      emit_frame_insn
+	(gen_rtx_SET (Pmode, stack_disp_mem (frame_info.lr_save_offset),
+		      gen_rtx_REG (Pmode, LINK_REGNUM)));
+    }
+  if (frame_info.gpr_size)
+    {
+      int offset = 0;
+      int regno;
+
+      for (regno = 0; regno <= OR1K_LAST_ACTUAL_REG; regno++)
+	{
+	  if (!(frame_info.mask & ((HOST_WIDE_INT) 1 << regno)))
+	    continue;
+
+	  /* Check that the offsets aren't stepping on lr/fp slots */
+	  gcc_assert (!frame_info.save_lr_p
+		      || ((frame_info.gpr_offset + offset)
+			  != frame_info.lr_save_offset));
+	  gcc_assert (!frame_info.save_fp_p
+		      || ((frame_info.gpr_offset + offset)
+			  != frame_info.fp_save_offset));
+
+	  emit_frame_insn
+	    (gen_rtx_SET (Pmode,
+			  stack_disp_mem (frame_info.gpr_offset + offset),
+			  gen_rtx_REG (Pmode, regno)));
+	  offset = offset + UNITS_PER_WORD;
+	}
+    }
+
+  /* Update the stack pointer to reflect frame size.  */
+  total_size = frame_info.late_frame;
+  insn = gen_add2_insn (stack_pointer_rtx, GEN_INT (-total_size));
+  if (total_size > 32768)
+    {
+      rtx note = insn;
+      rtx value_rtx = gen_rtx_REG (Pmode, PROLOGUE_TMP);
+
+      or1k_emit_set_const32 (value_rtx, GEN_INT (-total_size));
+      if (frame_info.save_fp_p)
+	insn = gen_frame_alloc_fp (value_rtx);
+      else
+	insn = gen_add2_insn (stack_pointer_rtx, value_rtx);
+      insn = emit_frame_insn (insn);
+      add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
+    }
+  else if (total_size)
+    {
+      if (frame_info.save_fp_p)
+	emit_frame_insn (gen_frame_alloc_fp (GEN_INT (-total_size)));
+      else
+	emit_frame_insn (insn);
+    }
+  /* Emit got pointer acquiring if there are any got references or
+     this function has calls */
+  if (crtl->uses_pic_offset_table || (flag_pic && frame_info.save_lr_p))
+    {
+      SET_REGNO (pic_offset_table_rtx, PIC_OFFSET_TABLE_REGNUM);
+      emit_insn (gen_set_got (pic_offset_table_rtx));
+    }
+
+}	/* or1k_expand_prologue () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Expand an epilogue pattern.
+
+   Called after register allocation to add any instructions needed for the
+   epilogue.  Using an epilogue insn is favored compared to putting all of the
+   instructions in output_function_epilogue(), since it allows the scheduler
+   to intermix instructions with the restores of the caller saved registers.
+   In some cases, it might be necessary to emit a barrier instruction as the
+   first insn to prevent such scheduling.                                     */
+/* -------------------------------------------------------------------------- */
+void
+or1k_expand_epilogue (void)
+{
+  int total_size = or1k_compute_frame_size (get_frame_size ());
+
+  if (frame_info.save_fp_p)
+    {
+      emit_insn (gen_frame_dealloc_fp ());
+      emit_insn
+	(gen_rtx_SET (Pmode, hard_frame_pointer_rtx,
+		      stack_disp_mem (frame_info.fp_save_offset)));
+    }
+  else
+    {
+      rtx value_rtx;
+
+      total_size = frame_info.late_frame;
+      if (total_size > 32767)
+	{
+	  value_rtx = gen_rtx_REG (Pmode, EPILOGUE_TMP);
+	  or1k_emit_set_const32 (value_rtx, GEN_INT (total_size));
+	}
+      else if (frame_info.late_frame)
+	value_rtx = GEN_INT (total_size);
+      if (total_size)
+	emit_insn (gen_frame_dealloc_sp (value_rtx));
+    }
+
+  /* eh_return sets the LR, do not overwrite it */
+  if (frame_info.save_lr_p && !crtl->calls_eh_return)
+    {
+      emit_insn
+        (gen_rtx_SET (Pmode, gen_rtx_REG (Pmode, LINK_REGNUM),
+                      stack_disp_mem (frame_info.lr_save_offset)));
+    }
+
+  if (frame_info.gpr_size)
+    {
+      int offset = 0;
+      int regno;
+
+      for (regno = 0; regno <= OR1K_LAST_ACTUAL_REG; regno++)
+	{
+	  if (!(frame_info.mask & ((HOST_WIDE_INT) 1 << regno)))
+	    continue;
+
+	  if (regno != FIRST_PSEUDO_REGISTER)
+	    emit_insn
+	      (gen_rtx_SET (Pmode, gen_rtx_REG (Pmode, regno),
+			    stack_disp_mem (frame_info.gpr_offset + offset)));
+	  offset = offset + UNITS_PER_WORD;
+	}
+    }
+
+  if (crtl->calls_eh_return)
+    emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));
+
+  if (frame_info.gpr_frame)
+    emit_insn (gen_add2_insn (stack_pointer_rtx,
+			      GEN_INT (frame_info.gpr_frame)));
+  emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, 9)));
+
+}	/* or1k_expand_epilogue () */
+
+
+
+/* -------------------------------------------------------------------------- */
+/*!Generate assembler code for a movdi/movdf pattern
+
+   @param[in] operands  Operands to the movdx pattern.
+
+   @return  The assembler string to output (always "", since we've done the
+            output here).                                                     */
+/* -------------------------------------------------------------------------- */
+const char *
+or1k_output_move_double (rtx *operands)
+{
+  rtx xoperands[3];
+
+  switch (GET_CODE (operands[0]))
+    {
+    case REG:
+      if (GET_CODE (operands[1]) == REG)
+	{
+	  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+	    {
+	      output_asm_insn ("\tl.or    \t%H0, %H1, r0", operands);
+	      output_asm_insn ("\tl.or    \t%0, %1, r0", operands);
+	      return "";
+	    }
+	  else
+	    {
+	      output_asm_insn ("\tl.or    \t%0, %1, r0", operands);
+	      output_asm_insn ("\tl.or    \t%H0, %H1, r0", operands);
+	      return "";
+	    }
+	}
+      else if (GET_CODE (operands[1]) == MEM)
+	{
+	  xoperands[1] = XEXP (operands[1], 0);
+	  if (GET_CODE (xoperands[1]) == REG)
+	    {
+	      xoperands[0] = operands[0];
+	      if (REGNO (xoperands[0]) == REGNO (xoperands[1]))
+		{
+		  output_asm_insn ("\tl.lwz   \t%H0, 4(%1)", xoperands);
+		  output_asm_insn ("\tl.lwz   \t%0, 0(%1)", xoperands);
+		  return "";
+		}
+	      else
+		{
+		  output_asm_insn ("\tl.lwz   \t%0, 0(%1)", xoperands);
+		  output_asm_insn ("\tl.lwz   \t%H0, 4(%1)", xoperands);
+		  return "";
+		}
+	    }
+	  else if (GET_CODE (xoperands[1]) == PLUS)
+	    {
+	      if (GET_CODE (xoperands[2] = XEXP (xoperands[1], 1)) == REG)
+		{
+		  xoperands[0] = operands[0];
+		  xoperands[1] = XEXP (xoperands[1], 0);
+		  if (REGNO (xoperands[0]) == REGNO (xoperands[2]))
+		    {
+		      output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)",
+				       xoperands);
+		      output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
+		      return "";
+		    }
+		  else
+		    {
+		      output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
+		      output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)",
+				       xoperands);
+		      return "";
+		    }
+		}
+	      else if (GET_CODE (xoperands[2] = XEXP (xoperands[1], 0)) ==
+		       REG)
+		{
+		  xoperands[0] = operands[0];
+		  xoperands[1] = XEXP (xoperands[1], 1);
+		  if (REGNO (xoperands[0]) == REGNO (xoperands[2]))
+		    {
+		      output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)",
+				       xoperands);
+		      output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
+		      return "";
+		    }
+		  else
+		    {
+		      output_asm_insn ("\tl.lwz   \t%0, %1(%2)", xoperands);
+		      output_asm_insn ("\tl.lwz   \t%H0, %1+4(%2)",
+				       xoperands);
+		      return "";
+		    }
+		}
+	      else
+		abort ();
+	    }
+	  else
+	    abort ();
+	}
+      else
+	abort ();
+    case MEM:
+      xoperands[0] = XEXP (operands[0], 0);
+      if (GET_CODE (xoperands[0]) == REG)
+	{
+	  xoperands[1] = operands[1];
+	  output_asm_insn ("\tl.sw    \t0(%0), %1", xoperands);
+	  output_asm_insn ("\tl.sw    \t4(%0), %H1", xoperands);
+	  return "";
+	}
+      else if (GET_CODE (xoperands[0]) == PLUS)
+	{
+	  if (GET_CODE (xoperands[1] = XEXP (xoperands[0], 1)) == REG)
+	    {
+	      xoperands[0] = XEXP (xoperands[0], 0);
+	      xoperands[2] = operands[1];
+	      output_asm_insn ("\tl.sw    \t%0(%1), %2", xoperands);
+	      output_asm_insn ("\tl.sw    \t%0+4(%1), %H2", xoperands);
+	      return "";
+	    }
+	  else if (GET_CODE (xoperands[1] = XEXP (xoperands[0], 0)) == REG)
+	    {
+	      xoperands[0] = XEXP (xoperands[0], 1);
+	      xoperands[2] = operands[1];
+	      output_asm_insn ("\tl.sw    \t%0(%1), %2", xoperands);
+	      output_asm_insn ("\tl.sw    \t%0+4(%1), %H2", xoperands);
+	      return "";
+	    }
+	  else
+	    abort ();
+	}
+      else
+	{
+	  fprintf (stderr, "  O/p error %s\n",
+		   GET_RTX_NAME (GET_CODE (xoperands[0])));
+	  return "";
+	  /* abort (); */
+	}
+    default:
+      abort ();
+    }
+}	/* or1k_output_move_double () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Expand a conditional branch
+
+   @param[in] operands  Operands to the branch.
+   @param[in] mode      Mode of the comparison.                               */
+/* -------------------------------------------------------------------------- */
+void
+or1k_expand_conditional_branch (rtx               *operands,
+				enum machine_mode  mode)
+{
+  rtx tmp;
+  enum rtx_code test_code = GET_CODE(operands[0]);
+
+  switch (mode)
+    {
+    case SImode:
+      tmp = or1k_expand_compare (test_code, operands[1], operands[2]);
+      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode,
+				  tmp,
+				  gen_rtx_LABEL_REF (VOIDmode, operands[3]),
+				  pc_rtx);
+      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
+      return;
+      
+    case SFmode:
+      tmp = or1k_expand_compare (test_code, operands[1], operands[2]);
+      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode,
+				  tmp,
+				  gen_rtx_LABEL_REF (VOIDmode, operands[3]),
+				  pc_rtx);
+      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
+      return;
+      
+    default:
+      abort ();
+    }
+
+}	/* or1k_expand_conditional_branch () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Emit a conditional move
+
+   move "true_cond" to "dest" if "op" of the operands of the last comparison
+   is nonzero/true, "false_cond" if it is zero/false.
+
+   @param[in] dest        RTX for the destination operand.
+   @param[in] op          RTX for the comparison operation
+   @param[in] true_cond   RTX to move to dest if condition is TRUE.
+   @param[in] false_cond  RTX to move to dest if condition is FALSE.
+   
+   @return  Non-zero (TRUE) if the hardware supports such an operation, zero
+            (FALSE) otherwise.                                                */
+/* -------------------------------------------------------------------------- */
+int
+or1k_emit_cmove (rtx  dest,
+		 rtx  op,
+		 rtx  true_cond,
+		 rtx  false_cond)
+{
+  enum machine_mode result_mode = GET_MODE (dest);
+
+  if (GET_MODE (true_cond) != result_mode)
+    return 0;
+
+  if (GET_MODE (false_cond) != result_mode)
+    return 0;
+
+  /* First, work out if the hardware can do this at all */
+  return or1k_emit_int_cmove (dest, op, true_cond, false_cond);
+
+}	/* or1k_emit_cmove () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Output the assembler for a branch on flag instruction.
+
+   @param[in] operands  Operands to the branch.
+   
+   @return  The assembler string to use.                                      */
+/* -------------------------------------------------------------------------- */
+const char *
+or1k_output_bf (rtx * operands)
+{
+  enum rtx_code code;
+  enum machine_mode mode_calc, mode_got;
+
+  code      = GET_CODE (operands[1]);
+  mode_calc = or1k_select_cc_mode (code);
+  mode_got  = GET_MODE (operands[2]);
+
+  if (mode_calc != mode_got)
+    return "l.bnf\t%l0%(";
+  else
+    return "l.bf\t%l0%(";
+}	/* or1k_output_bf () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Output the assembler for a conditional move instruction.
+
+   @param[in] operands  Operands to the conditional move.
+   
+   @return  The assembler string to use.                                      */
+/* -------------------------------------------------------------------------- */
+const char *
+or1k_output_cmov (rtx * operands)
+{
+  enum rtx_code code;
+  enum machine_mode mode_calc, mode_got;
+
+  code      = GET_CODE (operands[1]);
+  mode_calc = or1k_select_cc_mode (code);
+  mode_got  = GET_MODE (operands[4]);
+
+  if (mode_calc != mode_got)
+    return "l.cmov\t%0,%3,%2";	/* reversed */
+  else
+    return "l.cmov\t%0,%2,%3";
+
+}	/* or1k_output_cmov () */
+
+/* -------------------------------------------------------------------------- */
+/*!Load a 32-bit constant.
+
+   We know it can't be done in one insn when we get here, the movsi expander
+   guarantees this.
+
+   @param[in] op0  RTX for the destination.
+   @param[in] op1  RTX for the (constant) source.                             */
+/* -------------------------------------------------------------------------- */
+void
+or1k_emit_set_const32 (rtx  op0,
+		       rtx  op1)
+{
+  enum machine_mode mode = GET_MODE (op0);
+  rtx temp;
+
+  /* Sanity check that we really can't do it in one instruction. I.e that we
+     don't have a 16-bit constant. */
+  if (GET_CODE (op1) == CONST_INT)
+    {
+      HOST_WIDE_INT val = INTVAL (op1) & GET_MODE_MASK (mode);
+
+      if ((-32768 <= val) && (val <= 32767))
+	{
+	  abort ();
+	}
+    }
+
+  /* Full 2-insn decomposition is needed.  */
+  if (reload_in_progress || reload_completed)
+    temp = op0;
+  else
+    temp = gen_reg_rtx (mode);
+
+  if (GET_CODE (op1) == CONST_INT)
+    {
+      /* Emit them as real moves instead of a HIGH/LO_SUM,
+         this way CSE can see everything and reuse intermediate
+         values if it wants.  */
+      emit_insn (gen_rtx_SET (VOIDmode, temp,
+			      GEN_INT (INTVAL (op1)
+				       & ~(HOST_WIDE_INT) 0xffff)));
+
+      emit_insn (gen_rtx_SET (VOIDmode,
+			      op0,
+			      gen_rtx_IOR (mode, temp,
+					   GEN_INT (INTVAL (op1) & 0xffff))));
+    }
+  else
+    {
+      /* since or1k bfd can not deal with relocs that are not of type
+         OR1K_CONSTH_RELOC + OR1K_CONST_RELOC (ie move high must be
+         followed by exactly one lo_sum)
+       */
+      emit_insn (gen_movsi_insn_big (op0, op1));
+    }
+}	/* or1k_emit_set_const32 () */
+
+
+/* ========================================================================== */
+/* Target hook functions.
+
+   These are initialized at the end of this file, to avoid having to
+   predeclare all the functions. They are only needed here, so are static.    */
+
+
+
+
+/* -------------------------------------------------------------------------- */
+/*!Define where a function returns values.
+
+   Define this to return an RTX representing the place where a function
+   returns or receives a value of data type ret type, a tree node representing
+   a data type.  "func" is a tree node representing FUNCTION_DECL or
+   FUNCTION_TYPE of a function being called. If "outgoing" is false, the hook
+   should compute the register in which the caller will see the return
+   value. Otherwise, the hook should return an RTX representing the place
+   where a function returns a value.
+
+   On many machines, only TYPE_MODE ("ret_type") is relevant. (Actually, on
+   most machines, scalar values are returned in the same place regardless of
+   mode.) The value of the expression is usually a reg RTX for the hard
+   register where the return value is stored. The value can also be a parallel
+   RTX, if the return value is in multiple places. See FUNCTION_ARG for an
+   explanation of the parallel form. Note that the callee will populate every
+   location specified in the parallel, but if the first element of the
+   parallel contains the whole return value, callers will use that element as
+   the canonical location and ignore the others. The m68k port uses this type
+   of parallel to return pointers in both ‘%a0’ (the canonical location) and
+   ‘%d0’.
+
+   If TARGET_PROMOTE_FUNCTION_RETURN returns true, you must apply the same
+   promotion rules specified in PROMOTE_MODE if valtype is a scalar type.
+
+   If the precise function being called is known, "func" is a tree node
+   (FUNCTION_DECL) for it; otherwise, "func" is a null pointer. This makes it
+   possible to use a different value-returning convention for specific
+   functions when all their calls are known.
+
+   Some target machines have "register windows" so that the register in which
+   a function returns its value is not the same as the one in which the caller
+   sees the value. For such machines, you should return different RTX
+   depending on outgoing.
+
+   TARGET_FUNCTION_VALUE is not used for return values with aggregate data
+   types, because these are returned in another way. See
+   TARGET_STRUCT_VALUE_RTX and related macros.
+
+   For the OR1K, we can just use the result of LIBCALL_VALUE, since all
+   functions return their result in the same place (register rv = r11).
+
+   JPB 30-Aug-10: What about 64-bit scalar returns (long long int, double),
+                  which also use rvh (=r12)?
+
+   @param[in] ret_type  The return type of the function.
+   @param[in] func      Tree representing function being called.
+   @param[in] outgoing  Non-zero (TRUE) if the result represents where the
+                        function places the results, zero (FALSE) if the
+                        result represents where the caller sees the result.
+
+   @return  A RTX representing where the result can be found.                 */
+/* -------------------------------------------------------------------------- */
+static rtx
+or1k_function_value (const_tree  ret_type,
+		     const_tree  func ATTRIBUTE_UNUSED,
+                     bool        outgoing ATTRIBUTE_UNUSED)
+{
+  return LIBCALL_VALUE (TYPE_MODE(ret_type));
+
+}	/* or1k_function_value () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Check if a function is suitable for tail call optimization.
+
+   True if it is OK to do sibling call optimization for the specified call
+   expression "exp". "decl" will be the called function, or NULL if this is an
+   indirect call.
+
+   It is not uncommon for limitations of calling conventions to prevent tail
+   calls to functions outside the current unit of translation, or during PIC
+   compilation. The hook is used to enforce these restrictions, as the sibcall
+   md pattern can not fail, or fall over to a “normal” call. The criteria for
+   successful sibling call optimization may vary greatly between different
+   architectures.
+
+   For the OR1K, we currently don't allow sibcalls.
+
+   @param[in] decl  The function for which we may optimize
+   @param[in] exp   The call expression which is candidate for optimization.
+
+   @return  Non-zero (TRUE) if sibcall optimization is permitted, zero (FALSE)
+            otherwise.                                                        */
+/* -------------------------------------------------------------------------- */
+static bool
+or1k_function_ok_for_sibcall (tree  decl ATTRIBUTE_UNUSED,
+			      tree  exp ATTRIBUTE_UNUSED)
+{
+  return 0;
+}	/* or1k_function_ok_for_sibcall () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Should an argument be passed by reference.
+
+   This target hook should return true if an argument at the position
+   indicated by "cum" should be passed by reference. This predicate is queried
+   after target independent reasons for being passed by reference, such as
+   TREE_ADDRESSABLE ("type").
+
+   If the hook returns TRUE, a copy of that argument is made in memory and a
+   pointer to the argument is passed instead of the argument itself. The
+   pointer is passed in whatever way is appropriate for passing a pointer to
+   that type.
+
+   For the OR1K, all aggregates and arguments greater than 8 bytes are passed
+   this way.
+
+   @param[in] cum    Position of argument under consideration.
+   @param[in[ mode   Not sure what this relates to.
+   @param[in] type   Type of the argument.
+   @param[in] named  Not sure what this relates to.
+
+   @return  Non-zero (TRUE) if the argument should be passed by reference,
+            zero (FALSE) otherwise.                                           */
+/* -------------------------------------------------------------------------- */
+static bool
+or1k_pass_by_reference (cumulative_args_t  cum ATTRIBUTE_UNUSED,
+                        enum machine_mode  mode ATTRIBUTE_UNUSED,
+                        const_tree         type,
+                        bool               named ATTRIBUTE_UNUSED)
+{
+  return (type && (AGGREGATE_TYPE_P (type) || int_size_in_bytes (type) > 8));
+
+}	/* or1k_pass_by_reference () */
+
+
+int
+or1k_initial_elimination_offset(int from, int to)
+{
+  or1k_compute_frame_size (get_frame_size ());
+  return ((from == FRAME_POINTER_REGNUM
+	   ? frame_info.gpr_offset : frame_info.gpr_frame)
+	  + (to == STACK_POINTER_REGNUM ? frame_info.late_frame : 0));
+}
+
+
+/* -------------------------------------------------------------------------- */
+/*!How many bytes at the beginning of an argument must be put into registers.
+
+   This target hook returns the number of bytes at the beginning of an
+   argument that must be put in registers. The value must be zero for
+   arguments that are passed entirely in registers or that are entirely pushed
+   on the stack.
+
+   On some machines, certain arguments must be passed partially in registers
+   and partially in memory. On these machines, typically the first few words
+   of arguments a re passed in registers, and the rest on the stack. If a
+   multi-word argument (a double or a structure) crosses that boundary, its
+   first few words must be passed in registers and the rest must be
+   pushed. This macro tells the compiler when this occurs, and how many bytes
+   should go in registers.
+
+   FUNCTION_ARG for these arguments should return the first register to be
+   used by the caller for this argument; likewise FUNCTION_INCOMING_ARG, for
+   the called function.
+
+   On the OR1K we never split argumetns between registers and memory.
+
+   JPB 30-Aug-10: Is this correct? Surely we should allow this. The ABI spec
+                  is incomplete on this point.
+
+   @param[in] cum    Position of argument under consideration.
+   @param[in[ mode   Not sure what this relates to.
+   @param[in] type   Type of the argument.
+   @param[in] named  Not sure what this relates to.
+
+   @return  The number of bytes of the argument to go into registers          */
+/* -------------------------------------------------------------------------- */
+static int
+or1k_arg_partial_bytes (cumulative_args_t cum ATTRIBUTE_UNUSED,
+                        enum machine_mode  mode ATTRIBUTE_UNUSED,
+                        tree               type ATTRIBUTE_UNUSED,
+                        bool               named ATTRIBUTE_UNUSED)
+{
+  return 0;
+
+}	/* or1k_arg_partial_bytes () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Promote the mode of a function's arguments/return value.
+
+   Like PROMOTE_MODE, but it is applied to outgoing function arguments or
+   function return values. The target hook should return the new mode and
+   possibly change "*punsignedp" if the promotion should change
+   signedness. This function is called only for scalar or pointer types.
+
+   "for_return" allows to distinguish the promotion of arguments and return
+   values. If it is 1, a return value is being promoted and
+   TARGET_FUNCTION_VALUE must perform the same promotions done here. If it is
+   2, the returned mode should be that of the register in which an incoming
+   parameter is copied, or the outgoing result is computed; then the hook
+   should return the same mode as PROMOTE_MODE, though the signedness may be
+   different.
+
+   The default is to not promote arguments and return values. You can also
+   define the hook to "default_promote_function_mode_always_promote" if you
+   would like to apply the same rules given by PROMOTE_MODE.
+
+   For the OR1K, if the size of the mode is integral and less than 4, we
+   promote to SImode, otherwise we return the mode we are supplied.
+
+   @param[in]  type        Not sure. Type of the argument?
+   @param[in]  mode        The mode of argument/return value to consider.
+   @param[out] punsignedp  Signedness of the value.
+   @param[in]  fntype      Not sure. Type of the function?
+   @param[in]  for_return  1 if a return value, 2 if an incoming value.
+
+   @return  The new mode.                                                     */
+/* -------------------------------------------------------------------------- */
+static enum machine_mode
+or1k_promote_function_mode (const_tree         type ATTRIBUTE_UNUSED,
+			    enum machine_mode  mode,
+			    int               *punsignedp ATTRIBUTE_UNUSED,
+			    const_tree         fntype ATTRIBUTE_UNUSED,
+			    int                for_return ATTRIBUTE_UNUSED)
+{
+  return (   (GET_MODE_CLASS (mode) == MODE_INT)
+	  && (GET_MODE_SIZE (mode) < 4)) ? SImode : mode;
+
+}	/* or1k_promote_function_mode () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Is this a legitimate address?
+
+  A function that returns whether x (an RTX) is a legitimate memory address on
+  the target machine for a memory operand of mode mode.
+
+  Legitimate addresses are defined in two variants: a strict variant and a
+  non-strict one.  The strict parameter chooses which variant is desired by
+  the caller.
+
+  The strict variant is used in the reload pass. It must be defined so that
+  any pseudo- register that has not been allocated a hard register is
+  considered a memory reference.  This is because in contexts where some kind
+  of register is required, a pseudo-register with no hard register must be
+  rejected. For non-hard registers, the strict variant should look up the
+  reg_renumber array; it should then proceed using the hard register number in
+  the array, or treat the pseudo as a memory reference if the array holds -1.
+
+  The non-strict variant is used in other passes. It must be defined to accept
+  all pseudo-registers in every context where some kind of register is
+  required.
+
+  Normally, constant addresses which are the sum of a symbol_ref and an
+  integer are stored inside a const RTX to mark them as constant. Therefore,
+  there is no need to recognize such sums specifically as legitimate
+  addresses. Normally you would simply recognize any const as legitimate.
+
+  Usually PRINT_OPERAND_ADDRESS is not prepared to handle constant sums that
+  are not marked with const. It assumes that a naked plus indicates
+  indexing. If so, then you must reject such naked constant sums as
+  illegitimate addresses, so that none of them will be given to
+  PRINT_OPERAND_ADDRESS.
+
+  On some machines, whether a symbolic address is legitimate depends on the
+  section that the address refers to. On these machines, define the target
+  hook TARGET_ENCODE_ SECTION_INFO to store the information into the
+  symbol_ref, and then check for it here. When you see a const, you will have
+  to look inside it to find the symbol_ref in order to determine the
+  section. See the internals manual section on "Assembler Format" for more
+  info.
+
+  Some ports are still using a deprecated legacy substitute for this hook, the
+  GO_IF_LEGITIMATE_ADDRESS macro. This macro has this syntax:
+
+    #define GO_IF_LEGITIMATE_ADDRESS (mode, x, label )
+
+  and should goto label if the address x is a valid address on the target
+  machine for a memory operand of mode mode. Whether the strict or non-strict
+  variants are desired is defined by the REG_OK_STRICT macro introduced
+  earlier in this section. Using the hook is usually simpler because it limits
+  the number of files that are recompiled when changes are made.
+
+   The OR1K only has a single addressing mode, which is a base register with
+   16-bit displacement. We can accept just 16-bit constants as addresses (they
+   can use r0 as base address, and we can accept plain registers as addresses
+   (they can use a displacement of zero).
+
+   @param[in] mode    The mode of the address
+   @param[in] x       The address (RTX)
+   @param[in] strict  Non-zero (TRUE) if we are in "strict" mode, zero (FALSE)
+                      otherwise.
+
+   @return  Non-zero (TRUE) if this is a legitimate address, zero (FALSE)
+            otherwise.                                                        */
+/* -------------------------------------------------------------------------- */
+static bool
+or1k_legitimate_address_p (enum machine_mode  mode ATTRIBUTE_UNUSED,
+			   rtx                x,
+			   bool               strict)
+{
+  /* You might think 16-bit constants are suitable. They can be built into
+     addresses using r0 as the base. However this seems to lead to defective
+     code. So for now this is a placeholder, and this code is not used.
+
+     if (or1k_legitimate_displacement_p (mode, x))
+     {
+     return  1;
+     }
+  */
+  /* Addresses consisting of a register and 16-bit displacement are also
+     suitable. We need the mode, since for double words, we had better be
+     able to address the full 8 bytes. */
+  if (GET_CODE(x) == PLUS)
+    {
+      rtx reg = XEXP(x,0);
+
+      /* If valid register... */
+      if ((GET_CODE(reg) == REG)
+          && or1k_regnum_ok_for_base_p (REGNO (reg), strict))
+        {
+          rtx offset = XEXP(x,1);
+
+          /* ...and valid offset */
+          if (or1k_legitimate_displacement_p (mode, offset))
+            {
+              return 1;
+            }
+        }
+    }
+
+  /* Addresses consisting of just a register are OK. They can be built into
+     addresses using an offset of zero (and an offset of four if double
+     word). */
+  if (GET_CODE(x) == REG
+    && or1k_regnum_ok_for_base_p(REGNO(x),strict)) {
+      return 1;
+  }
+
+  return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+/*!Initialize a trampoline for nested functions.
+
+   A nested function is defined by *two* pieces of information, the address of
+   the function (like any other function) and a pointer to the frame of the
+   enclosing function. The latter is required to allow the nested function to
+   access local variables in the enclosing function's frame.
+
+   This represents a problem, since a function in C is represented as an
+   address that can be held in a single variable as a pointer. Requiring two
+   pointers will not fit.
+
+   The solution is documented in "Lexical Closures for C++" by Thomas
+   M. Breuel (USENIX C++ Conference Proceedings, October 17-21, 1988). The
+   nested function is represented by a small block of code and data on the
+   enclosing function's stack frame, which sets up a pointer to the enclosing
+   function's stack frame (the static chain pointer) in a register defined by
+   the ABI, and then jumps to the code of the function proper.
+
+   The function can be represented as a single pointer to this block of code,
+   known as a trampoline, which when called generates both pointers
+   needed. The nested function (which knows it is a nested function at compile
+   time) can then generate code to access the enclosing frame via the static
+   chain register.
+
+   There is a catch that the trampoline is set up as data, but executed as
+   instructions. The former will be via the data cache, the latter via the
+   instruction cache. There is a risk that a later trampoline will not be seen
+   by the instruction cache, so the wrong code will be executed. So the
+   instruction cache should be flushed for the trampoline address range.
+
+   This hook is called to initialize a trampoline. "m_tramp" is an RTX for the
+   memory block for the trampoline; "fndecl" is the FUNCTION_DECL for the
+   nested function; "static_chain" is an RTX for the static chain value that
+   should be passed to the function when it is called.
+
+   If the target defines TARGET_ASM_TRAMPOLINE_TEMPLATE, then the first thing
+   this hook should do is emit a block move into "m_tramp" from the memory
+   block returned by assemble_trampoline_template. Note that the block move
+   need only cover the constant parts of the trampoline. If the target
+   isolates the variable parts of the trampoline to the end, not all
+   TRAMPOLINE_SIZE bytes need be copied.
+
+   If the target requires any other actions, such as flushing caches or
+   enabling stack execution, these actions should be performed after
+   initializing the trampoline proper.
+
+   For the OR1K, no static chain register is used. We choose to use the return
+   value (rv) register. The code is based on that for MIPS.
+   The trampoline code is:
+
+              l.movhi r11,hi(end_addr)
+              l.ori   r11,lo(end_addr)
+              l.lwz   r13,4(r11)
+              l.jr    r13
+              l.lwz   r11,0(r11)
+      end_addr:
+              .word   <static chain>
+              .word   <nested_function>
+
+   @note For the OR1K we need to flush the instruction cache, which is a
+         privileged operation. Needs fixing.
+
+   @param[in] m_tramp      The lowest address of the trampoline on the stack.
+   @param[in] fndecl       Declaration of the enclosing function.
+   @param[in] chain_value  Static chain pointer to pass to the nested
+                           function.                                          */
+/* -------------------------------------------------------------------------- */
+static void
+or1k_trampoline_init (rtx   m_tramp,
+		      tree  fndecl,
+		      rtx   chain_value)
+{
+  rtx  addr;				/* Start address of the trampoline */
+  rtx  end_addr;			/* End address of the code block */
+
+  rtx  high;				/* RTX for the high part of end_addr */
+  rtx  low;				/* RTX for the low part of end_addr */
+  rtx  opcode;				/* RTX for generated opcodes */
+  rtx  mem;				/* RTX for trampoline memory */
+
+  rtx *trampoline;	/* The trampoline code */
+
+  unsigned int  i;			/* Index into trampoline */
+  unsigned int  j;			/* General counter */
+
+  HOST_WIDE_INT  end_addr_offset;	  /* Offset to end of code */
+  HOST_WIDE_INT  static_chain_offset;	  /* Offset to stack chain word */
+  HOST_WIDE_INT  target_function_offset;  /* Offset to func address word */
+
+  /* Work out the offsets of the pointers from the start of the trampoline
+     code.  */
+  trampoline             = (rtx*) alloca (or1k_trampoline_code_words() * sizeof(rtx));
+  end_addr_offset        = or1k_trampoline_code_size ();
+  static_chain_offset    = end_addr_offset;
+  target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
+
+  /* Get pointers in registers to the beginning and end of the code block.  */
+  addr     = force_reg (Pmode, XEXP (m_tramp, 0));
+  end_addr = or1k_force_binary (Pmode, PLUS, addr, GEN_INT (end_addr_offset));
+
+  /* Build up the code in TRAMPOLINE.
+
+              l.movhi r11,hi(end_addr)
+              l.ori   r11,lo(end_addr)
+              l.lwz   r13,4(r11)
+              l.jr    r13
+              l.lwz   r11,0(r11)
+       end_addr:
+  */
+
+  i = 0;
+
+  /* Break out the high and low parts of the end_addr */
+  high = expand_simple_binop (SImode, LSHIFTRT, end_addr, GEN_INT (16),
+			      NULL, false, OPTAB_WIDEN);
+  low  = convert_to_mode (SImode, gen_lowpart (HImode, end_addr), true);
+
+  /* Emit the l.movhi, adding an operation to OR in the high bits from the
+     RTX. */
+  opcode = gen_int_mode (OR1K_MOVHI (11, 0), SImode);
+  trampoline[i++] = expand_simple_binop (SImode, IOR, opcode, high, NULL,
+					 false, OPTAB_WIDEN); 
+  
+  /* Emit the l.ori, adding an operations to OR in the low bits from the
+     RTX. */
+  opcode = gen_int_mode (OR1K_ORI (11, 11, 0), SImode);
+  trampoline[i++] = expand_simple_binop (SImode, IOR, opcode, low, NULL,
+					 false, OPTAB_WIDEN); 
+
+  /* Emit the l.lwz of the function address. No bits to OR in here, so we can
+     do the opcode directly. */
+  trampoline[i++] =
+    gen_int_mode (OR1K_LWZ (13, 11, target_function_offset - end_addr_offset),
+		  SImode);
+
+  if (TARGET_DELAY_ON) {
+    /* Emit the l.jr of the function. No bits to OR in here, so we can do the
+       opcode directly. */
+    trampoline[i++] = gen_int_mode (OR1K_JR (13), SImode);
+    
+    /* Emit the l.lwz of the static chain. No bits to OR in here, so we can
+       do the opcode directly. */
+    trampoline[i++] =
+      gen_int_mode (OR1K_LWZ (STATIC_CHAIN_REGNUM, 11,
+                              static_chain_offset - end_addr_offset), SImode);
+  } else {
+    trampoline[i++] =
+      gen_int_mode (OR1K_LWZ (STATIC_CHAIN_REGNUM, 11,
+                              static_chain_offset - end_addr_offset), SImode);
+    trampoline[i++] = gen_int_mode (OR1K_JR (13), SImode);
+    if (TARGET_DELAY_COMPAT)
+      trampoline[i++] = gen_int_mode (OR1K_NOP, SImode);
+  }
+
+  /* Copy the trampoline code.  Leave any padding uninitialized.  */
+  for (j = 0; j < i; j++)
+    {
+      mem = adjust_address (m_tramp, SImode, j * GET_MODE_SIZE (SImode));
+      or1k_emit_move (mem, trampoline[j]);
+    }
+
+  /* Set up the static chain pointer field.  */
+  mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
+  or1k_emit_move (mem, chain_value);
+
+  /* Set up the target function field.  */
+  mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
+  or1k_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
+
+  /* Flushing the trampoline from the instruction cache needs to be done
+     here. */
+
+}	/* or1k_trampoline_init () */
+
+
+/* -------------------------------------------------------------------------- */
+/*!Provide support for DW_AT_calling_convention
+
+   Define this to enable the dwarf attribute DW_AT_calling_convention to be
+   emitted for each function. Instead of an integer return the enum value for
+   the DW_CC_ tag.
+
+   To support optional call frame debugging information, you must also define
+   INCOMING_RETURN_ADDR_RTX and either set RTX_FRAME_RELATED_P on the prologue
+   insns if you use RTL for the prologue, or call "dwarf2out_def_cfa" and
+   "dwarf2out_reg_save" as appropriate from TARGET_ASM_FUNCTION_PROLOGUE if
+   you don’t.
+
+   For the OR1K, it should be sufficient to return DW_CC_normal in all cases.
+
+   @param[in] function  The function requiring debug information
+
+   @return  The enum of the DW_CC tag.                                        */
+/* -------------------------------------------------------------------------- */
+static int
+or1k_dwarf_calling_convention (const_tree  function ATTRIBUTE_UNUSED)
+{
+  return  DW_CC_normal;
+
+}	/* or1k_dwarf_calling_convention () */
+
+/* ========================================================================== */
+/* Target hook initialization.
+
+   In most cases these use the static functions declared above. They have
+   defaults, so must be undefined first, before being redefined.
+
+   The description of what they do is found with the function above, unless it
+   is a standard function or a constant, in which case it is defined here (as
+   with TARGET_ASM_NAMED_SECTION).
+
+   The final declaration is of the global "targetm" structure. */
+
+/* Output assembly directives to switch to section name. The section should
+   have attributes as specified by flags, which is a bit mask of the SECTION_*
+   flags defined in ‘output.h’. If decl is non-NULL, it is the VAR_DECL or
+   FUNCTION_DECL with which this section is associated.
+
+   For OR1K, we use the default ELF sectioning. */
+#undef  TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION  default_elf_asm_named_section
+
+#undef  TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE or1k_function_value
+
+#undef  TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL or1k_function_ok_for_sibcall
+
+#undef  TARGET_PASS_BY_REFERENCE
+#define TARGET_PASS_BY_REFERENCE or1k_pass_by_reference
+
+#undef  TARGET_ARG_PARTIAL_BYTES
+#define TARGET_ARG_PARTIAL_BYTES or1k_arg_partial_bytes
+
+#undef TARGET_OPTION_OVERRIDE
+#define TARGET_OPTION_OVERRIDE or1k_option_override
+
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START or1k_asm_file_start
+
+/* This target hook returns TRUE if an argument declared in a prototype as an
+   integral type smaller than int should actually be passed as an int. In
+   addition to avoiding errors in certain cases of mismatch, it also makes for
+   better code on certain machines.
+
+   The default is to not promote prototypes.
+
+   For the OR1K we do require this, so use a utility hook, which always
+   returns TRUE. */
+#undef  TARGET_PROMOTE_PROTOTYPES
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
+
+#undef  TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE or1k_promote_function_mode
+
+#undef  TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P  or1k_legitimate_address_p
+
+#undef  TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS or1k_legitimize_address
+
+#undef  TARGET_TRAMPOLINE_INIT
+#define TARGET_TRAMPOLINE_INIT  or1k_trampoline_init
+
+#undef  TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM or1k_cannot_force_const_mem
+
+#undef TARGET_DWARF_CALLING_CONVENTION
+#define TARGET_DWARF_CALLING_CONVENTION  or1k_dwarf_calling_convention
+
+/* uClibc has some instances where (non-coforming to ISO C) a non-varargs
+   prototype is in scope when calling that function which is implemented
+   as varargs.  We want this to work at least where none of the anonymous
+   arguments are used.  I.e. we want the last named argument to be known
+   as named so it can be passed in a register, varars funtion or not.  */
+#undef TARGET_STRICT_ARGUMENT_NAMING
+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+
+/* Is this suitable for an immediate operand.
+
+   JPB 1-Sep-10: Is this correct. We can only do 16-bit immediates directly. */
+static bool
+or1k_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+  if (or1k_tls_symbolic_operand (x) != TLS_MODEL_NONE)
+    return 0;
+
+  return GET_CODE(x) != CONST_DOUBLE || (GET_MODE (x) == VOIDmode && !flag_pic);
+}
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P or1k_legitimate_constant_p
+
+/* On the OR1K, no functions pop their arguments.
+   JPB 29-Aug-10: Is this really correct? */
+static int
+or1k_return_pops_args (tree ARG_UNUSED(fundecl), tree ARG_UNUSED(funtype), int ARG_UNUSED(size))
+{
+  return 0;
+}
+#undef TARGET_RETURN_POPS_ARGS
+#define TARGET_RETURN_POPS_ARGS or1k_return_pops_args
+
+/* Determine where to put an argument to a function.  Value is zero to push
+   the argument on the stack, or a hard register in which to store the
+   argument.
+
+   "mode" is the argument's machine mode.
+
+   "type" is the data type of the argument (as a tree).  This is null for
+    libcalls where that information may not be available.
+
+   "cum" is a variable of type CUMULATIVE_ARGS which gives info about the
+    preceding args and about the function being called.
+
+   "named" is nonzero if this argument is a named parameter (otherwise it is
+    an extra parameter matching an ellipsis).
+
+    On the ARC the first MAX_ARC_PARM_REGS args are normally in registers and
+    the rest are pushed.  */
+static rtx
+or1k_function_arg (cumulative_args_t cum, enum machine_mode mode,
+                     const_tree type, bool named)
+{
+  CUMULATIVE_ARGS *cum_pnt = get_cumulative_args (cum);
+
+  if (OR1K_PASS_IN_REG_P (*cum_pnt, mode, type, named))
+    return gen_rtx_REG (mode, OR1K_ROUND_ADVANCE_CUM (*cum_pnt, mode, type)
+                          + GP_ARG_MIN_REG);
+  else
+    return 0;
+}
+#undef TARGET_FUNCTION_ARG
+#define TARGET_FUNCTION_ARG or1k_function_arg
+/* Update the data in "cum" to advance over an argument of mode "mode" and
+   data type "type".  ("type" is null for libcalls where that information may
+   not be available.)  */
+static void
+or1k_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
+                           const_tree type, bool ARG_UNUSED(named))
+{
+  CUMULATIVE_ARGS *cum_pnt = get_cumulative_args (cum);
+
+  *cum_pnt = OR1K_ROUND_ADVANCE_CUM (*cum_pnt, mode, type)
+    + OR1K_ROUND_ADVANCE_ARG (mode, type);
+}
+
+#undef TARGET_FUNCTION_ARG_ADVANCE
+#define TARGET_FUNCTION_ARG_ADVANCE or1k_function_arg_advance
+
+#undef TARGET_PRINT_OPERAND_ADDRESS
+#define TARGET_PRINT_OPERAND_ADDRESS or1k_print_operand_address
+
+/* Trampoline stubs are yet to be written. */
+/* #define TARGET_ASM_TRAMPOLINE_TEMPLATE */
+/* #define TARGET_TRAMPOLINE_INIT */
+
+/* Lay out structs with increased alignment so that they can be accessed
+   more efficiently.  But don't increase the size of one or two byte
+   structs.  */
+int
+or1k_struct_alignment (tree t)
+{
+  unsigned HOST_WIDE_INT total = 0;
+  int default_align_fields = 0;
+  int special_align_fields = 0;
+  tree field;
+  unsigned max_align
+    = maximum_field_alignment ? maximum_field_alignment : BIGGEST_ALIGNMENT;
+  bool struct_p;
+
+  switch (TREE_CODE (t))
+    {
+    case RECORD_TYPE:
+      struct_p = true; break;
+    case UNION_TYPE: case QUAL_UNION_TYPE:
+      struct_p = false; break;
+    default: gcc_unreachable ();
+    }
+  /* Skip all non field decls */
+  for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+    {
+      unsigned HOST_WIDE_INT field_size;
+
+      if (TREE_CODE (field) != FIELD_DECL ||
+	  TREE_TYPE (field) == error_mark_node)
+	continue;
+      /* If this is a field in a non-qualified union, or the sole field in
+	 a struct, and the alignment was set by the user, don't change the
+	 alignment.
+	 If the field is a struct/union in a non-qualified union, we already
+	 had sufficient opportunity to pad it - if we didn't, that'd be
+	 because the alignment was set as above.
+	 Likewise if the field is a struct/union and the sole field in a
+	 struct.  */
+      if (DECL_USER_ALIGN (field)
+	  || TYPE_USER_ALIGN (TREE_TYPE (field))
+	  || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
+	  || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
+	  || TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
+	{
+	  if (TREE_CODE (t) == UNION_TYPE)
+	    return 0;
+	  special_align_fields++;
+	}
+      else if (DECL_PACKED (field))
+	special_align_fields++;
+      else
+	default_align_fields++;
+      if (!tree_fits_uhwi_p (DECL_SIZE (field)))
+	field_size = max_align;
+      else
+	field_size = tree_to_uhwi (DECL_SIZE (field));
+      if (field_size >= BIGGEST_ALIGNMENT)
+	total = max_align;
+      if (struct_p)
+	total += field_size;
+      else
+	total = MAX (total, field_size);
+    }
+
+  if (!default_align_fields
+      && (TREE_CODE (t) != RECORD_TYPE || special_align_fields <= 1))
+    return 0;
+  return total < max_align ? (1U << ceil_log2 (total)) : max_align;
+}
+
+/* Increase the alignment of objects so that they are easier to copy.
+   Note that this can cause more struct copies to be inlined, so code
+   size might increase, but so should perfromance.  */
+int
+or1k_data_alignment (tree t, int align)
+{
+  if (align < FASTEST_ALIGNMENT && TREE_CODE (t) == ARRAY_TYPE)
+    {
+      int size = int_size_in_bytes (t);
+
+      return (size > 0 && size < FASTEST_ALIGNMENT / BITS_PER_UNIT
+	      ? (1 << floor_log2 (size)) * BITS_PER_UNIT
+	      : FASTEST_ALIGNMENT);
+    }
+  return align;
+}
+
+static void
+or1k_option_override (void)
+{
+  if (!TARGET_DELAY_ON)
+    flag_delayed_branch = FALSE;
+}
+
+static void
+or1k_asm_file_start(void)
+{
+  default_file_start();
+
+  if (TARGET_DELAY_OFF) {
+    fprintf(asm_out_file, "\t.nodelay\n");
+  }
+}
+
+/* Implement EH_RETURN_HANDLER_RTX. 
+ * Make eh_return use the link register. Epilogue LR restore
+ * is suppressed for eh_return. */
+rtx
+or1k_eh_return_handler_rtx (void)
+{
+  return INCOMING_RETURN_ADDR_RTX;
+}
+
+/* Implement RETURN_ADDR_RTX.
+ * We do not support moving back to a previous frame. */
+rtx
+or1k_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
+{
+  if (count != 0)
+    return const0_rtx;
+
+  /* We don't know if LR is going to be saved or if we're going to
+   * be clobbering it with the GOT instruction.
+   * Therefore the safest bet is to force a save of LR and use that.
+   * Assume it's going to be first in the stack. */
+
+  cfun->machine->force_lr_save = true;
+  return gen_rtx_MEM (Pmode, plus_constant (Pmode, arg_pointer_rtx,
+                                            -UNITS_PER_WORD));
+}
+
+/* Implement TARGET_FRAME_POINTER_REQUIRED.
+ * We want frame pointer in eh_return and when alloca is used */
+static bool
+or1k_frame_pointer_required (void)
+{
+  return crtl->calls_eh_return || cfun->calls_alloca;
+}
+
+/* Functions to save and restore machine-specific function data.  */
+static struct machine_function *
+or1k_init_machine_status (void)
+{
+  return ggc_cleared_alloc<machine_function> ();
+}
+
+void
+or1k_init_expanders (void)
+{
+  /* Arrange to initialize and mark the machine per-function
+   * status.  */
+  init_machine_status = or1k_init_machine_status;
+
+  if (cfun && cfun->machine)
+    {
+      cfun->machine->force_lr_save = false;
+    }
+}
+
+#undef  TARGET_FRAME_POINTER_REQUIRED
+#define TARGET_FRAME_POINTER_REQUIRED or1k_frame_pointer_required
+
+/* Initialize the GCC target structure.  */
+struct gcc_target targetm = TARGET_INITIALIZER;
+
+#include "gt-or1k.h"
diff --git a/gcc/config/or1k/or1k.h b/gcc/config/or1k/or1k.h
new file mode 100644
index 0000000..3444c57
--- /dev/null
+++ b/gcc/config/or1k/or1k.h
@@ -0,0 +1,1197 @@
+/* Definitions of target machine for GNU compiler.  OpenRISC 1000 version.
+   Copyright (C) 1987, 1988, 1992, 1995, 1996, 1999, 2000, 2001, 2002, 
+   2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2010 Embecosm Limited
+   Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999.
+   Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005.
+
+This file is part of GNU CC.
+
+GNU CC 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 1, or (at your option)
+any later version.
+
+GNU CC 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifndef _OR1K_H_
+#define _OR1K_H_
+
+#include "config/or1k/or1k-opts.h"
+
+/* Target CPU builtins */
+#define TARGET_CPU_CPP_BUILTINS()                       \
+  do                                                    \
+    {                                                   \
+      if (TARGET_DELAY_OFF) {                           \
+        builtin_define ("__OR1KND__");                  \
+        builtin_define ("__or1knd__");                  \
+        builtin_assert ("cpu=or1knd");                  \
+        builtin_assert ("machine=or1knd");              \
+      } else {                                          \
+        builtin_define ("__OR1K__");                    \
+        builtin_define ("__or1k__");                    \
+        builtin_assert ("cpu=or1k");                    \
+        builtin_assert ("machine=or1k");                \
+      }                                                 \
+      if (TARGET_DELAY_ON) {                            \
+        builtin_define ("__OR1K_DELAY__");              \
+      } else if (TARGET_DELAY_OFF) {                    \
+        builtin_define ("__OR1K_NODELAY__");            \
+      } else if (TARGET_DELAY_COMPAT) {                 \
+        builtin_define ("__OR1K_DELAY_COMPAT__");       \
+      }                                                 \
+    }                                                   \
+  while (0)
+
+#undef CPP_SPEC
+#define CPP_SPEC "%{!mnewlib:%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}}"
+
+/* Make sure we pick up the crti.o, crtbegin.o, crtend.o and crtn.o files. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+  "%{!shared:%{pie:Scrt0.o%s;:crt0.o%s}} crti.o%s \
+   %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{mnewlib:-entry 0x100} %{static:-static} %{shared:-shared}"
+
+/* Override previous definitions (linux.h). Newlib doesn't have a profiling
+   version of the library, but it does have a debugging version (libg.a) */
+#undef LIB_SPEC
+#define LIB_SPEC "%{!mnewlib:%{pthread:-lpthread}	\
+		             %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"			\
+                 "%{mnewlib:%{!g:-lc} %{g:-lg} -lor1k					\
+                            %{mboard=*:-lboard-%*} %{!mboard=*:-lboard-or1ksim}		\
+                            %{!g:-lc} %{g:-lg}						\
+                            }"
+
+/* Target machine storage layout */
+
+/* Define this if most significant bit is lowest numbered
+   in instructions that operate on numbered bit-fields.
+   This is not true on the or1k.  */
+#define BITS_BIG_ENDIAN 0
+
+/* Define this if most significant byte of a word is the lowest numbered.  */
+#define BYTES_BIG_ENDIAN 1
+
+/* Define this if most significant word of a multiword number is numbered.  */
+#define WORDS_BIG_ENDIAN 1
+
+#define BITS_PER_WORD 32
+#define SHORT_TYPE_SIZE 16
+#define INT_TYPE_SIZE 32
+#define LONG_TYPE_SIZE 32
+#define LONG_LONG_TYPE_SIZE 64
+#define FLOAT_TYPE_SIZE 32
+#define DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE 64
+
+/* Width of a word, in units (bytes).  */
+#define UNITS_PER_WORD 4
+
+/* Width in bits of a pointer.
+   See also the macro `Pmode' defined below.  */
+#define POINTER_SIZE 32
+
+/* Allocation boundary (in *bits*) for storing pointers in memory.  */
+#define POINTER_BOUNDARY 32
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list.  */
+#define PARM_BOUNDARY 32
+
+/* Boundary (in *bits*) on which stack pointer should be aligned.  */
+#define STACK_BOUNDARY 32
+
+/* Allocation boundary (in *bits*) for the code of a function.  */
+#define FUNCTION_BOUNDARY 32
+
+/* Alignment of field after `int : 0' in a structure.  */
+#define EMPTY_FIELD_BOUNDARY 8
+
+/* A bitfield declared as `int' forces `int' alignment for the struct.  */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* No data type wants to be aligned rounder than this.  */
+#define BIGGEST_ALIGNMENT 32
+
+/* The best alignment to use in cases where we have a choice.  */
+#define FASTEST_ALIGNMENT 32
+
+/* Make strings word-aligned so strcpy from constants will be faster.  */
+/*
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)  				\
+  ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR)    \
+    && (ALIGN) < FASTEST_ALIGNMENT      				\
+   ? FASTEST_ALIGNMENT : (ALIGN))
+*/
+
+/* One use of this macro is to increase alignment of medium-size
+   data to make it all fit in fewer cache lines.  Another is to
+   cause character arrays to be word-aligned so that `strcpy' calls
+   that copy constants to character arrays can be done inline.  */         
+/*
+#define DATA_ALIGNMENT(TYPE, ALIGN)                                     \
+  ((((ALIGN) < FASTEST_ALIGNMENT)                                       \
+    && (TREE_CODE (TYPE) == ARRAY_TYPE                                  \
+        || TREE_CODE (TYPE) == UNION_TYPE                               \
+        || TREE_CODE (TYPE) == RECORD_TYPE)) ? FASTEST_ALIGNMENT : (ALIGN))
+*/ /* CHECK - btw code gets bigger with this one */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+  ((ALIGN) < FASTEST_ALIGNMENT \
+   ? or1k_data_alignment ((TYPE), (ALIGN)) : (ALIGN))
+
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+  ((ALIGN) < FASTEST_ALIGNMENT \
+   ? or1k_data_alignment ((TYPE), (ALIGN)) : (ALIGN))
+
+/* Define this if move instructions will actually fail to work
+   when given unaligned data.  */
+#define STRICT_ALIGNMENT 1 /* CHECK */
+
+/* Align an address */
+#define OR1K_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
+
+/* Define if operations between registers always perform the operation
+   on the full register even if a narrower mode is specified.  */
+#define WORD_REGISTER_OPERATIONS  /* CHECK */
+ 
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+   will either zero-extend or sign-extend.  The value of this macro should
+   be the code that says which one of the two operations is implicitly
+   done, NIL if none.  */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Define this macro if it is advisable to hold scalars in registers
+   in a wider mode than that declared by the program.  In such cases,
+   the value is constrained to be within the bounds of the declared
+   type, but kept valid in the wider mode.  The signedness of the
+   extension may differ from that of the type. */
+#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)     \
+  if (GET_MODE_CLASS (MODE) == MODE_INT         \
+      && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
+    (MODE) = SImode;
+  /* CHECK */
+
+
+/*
+ * brings 0.4% improvment in static size for linux
+ *
+#define PROMOTE_FOR_CALL_ONLY
+*/
+
+/* Define this macro if it is as good or better to call a constant
+   function address than to call an address kept in a register.  */
+#define NO_FUNCTION_CSE 1 /* check */
+   
+/* Standard register usage.  */
+
+/* Number of actual hardware registers.
+   The hardware registers are assigned numbers for the compiler
+   from 0 to just below FIRST_PSEUDO_REGISTER.
+   All registers that the compiler knows about must be given numbers,
+   even those that are not normally considered general registers.  */
+
+#define OR1K_LAST_ACTUAL_REG       31
+#define ARG_POINTER_REGNUM     (OR1K_LAST_ACTUAL_REG + 1)
+#define FRAME_POINTER_REGNUM   (ARG_POINTER_REGNUM + 1)
+#define OR1K_LAST_INT_REG      FRAME_POINTER_REGNUM
+#define OR1K_FLAGS_REG         (OR1K_LAST_INT_REG + 1)
+#define FIRST_PSEUDO_REGISTER  (OR1K_FLAGS_REG + 1)
+
+/* 1 for registers that have pervasive standard uses
+   and are not available for the register allocator.
+   On the or1k, these are r1 as stack pointer and 
+   r2 as frame/arg pointer.  r9 is link register, r0
+   is zero, r10 is linux thread and r16 is got pointer */
+#define FIXED_REGISTERS { \
+  1, 1, 0, 0, 0, 0, 0, 0, \
+  0, 1, 1, 0, 0, 0, 0, 0, \
+  1, 0, 0, 0, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }
+/* 1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.  */
+#define CALL_USED_REGISTERS { \
+  1, 1, 0, 1, 1, 1, 1, 1, \
+  1, 1, 1, 1, 1, 1, 0, 1, \
+  1, 1, 0, 1, 0, 1, 0, 1, \
+  0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1}
+
+/* stack pointer: must be FIXED and CALL_USED */
+/* hard frame pointer: must be call saved.  */
+/* soft frame pointer / arg pointer: must be FIXED and CALL_USED */
+
+/* Return number of consecutive hard regs needed starting at reg REGNO
+   to hold something of mode MODE.
+   This is ordinarily the length in words of a value of mode MODE
+   but can be less for certain modes in special long registers.
+   On the or1k, all registers are one word long.  */
+#define HARD_REGNO_NREGS(REGNO, MODE)   \
+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
+#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+
+/* Value is 1 if it is a good idea to tie two pseudo registers
+   when one has mode MODE1 and one has mode MODE2.
+   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+   for any hard reg, then this must be 0 for correct output.  */
+#define MODES_TIEABLE_P(MODE1, MODE2)  1
+
+/* A C expression for the cost of moving data of mode mode from a register in
+   class "from" to one in class "to". The classes are expressed using the
+   enumeration values such as GENERAL_REGS. A value of 2 is the default; other
+   values are interpreted relative to that.
+
+   It is not required that the cost always equal 2 when "from" is the same as
+   "to"; on some machines it is expensive to move between registers if they are
+   not general registers.
+
+   If reload sees an insn consisting of a single set between two hard
+   registers, and if REGISTER_MOVE_COST applied to their classes returns a
+   value of 2, reload does not check to ensure that the constraints of the
+   insn are met. Setting a cost of other than 2 will allow reload to verify
+   that the constraints are met. You should do this if the "movm" pattern's
+   constraints do not allow such copying.
+
+   JPB 31-Aug-10: This is just the default. */
+#define REGISTER_MOVE_COST(mode, from, to)  2
+
+/* A C expression for the cost of moving data of mode mode between a register
+   of class "class" and memory; "in" is zero if the value is to be written to
+   memory, nonzero if it is to be read in. This cost is relative to those in
+   REGISTER_MOVE_COST. If moving between registers and memory is more
+   expensive than between two registers, you should define this macro to
+   express the relative cost.
+
+   If you do not define this macro, GCC uses a default cost of 4 plus the cost
+   of copying via a secondary reload register, if one is needed. If your
+   machine requires a secondary reload register to copy between memory and a
+   register of class but the reload mechanism is more complex than copying via
+   an intermediate, define this macro to reflect the actual cost of the move.
+
+   GCC defines the function "memory_move_secondary_cost" if secondary reloads
+   are needed. It computes the costs due to copying via a secondary
+   register. If your machine copies from memory using a secondary register in
+   the conventional way but the default base value of 4 is not correct for
+   your machine, define this macro to add some other value to the result of
+   that function. The arguments to that function are the same as to this
+   macro.
+
+   JPB 31-Aug-10. Is this really correct? I suppose the OR1K only takes one
+                  cycle, notionally, to access memory, but surely that will
+                  often stall the  pipeline. Needs more investigation. */
+#define MEMORY_MOVE_COST(mode, class, in)  2
+
+/* A C expression for the cost of a branch instruction. A value of 1 is the
+   default; other values are interpreted relative to that. Parameter "speed_p"
+   is TRUE when the branch in question should be optimized for speed. When it
+   is FALSE, BRANCH_COST should be returning value optimal for code size
+   rather then performance considerations. "predictable_p" is true for well
+   predictable branches. On many architectures the BRANCH_COST can be reduced
+   then.
+
+   JPB 31-Aug-10. The original code had the comment that "... this should
+                  specify the cost of a branch insn; roughly the number of
+                  extra insns that should be added to avoid a branch.
+
+		  Set this to 3 on the or1k since that is roughly the average
+		  cost of an unscheduled conditional branch.
+
+		  Cost of 2 and 3 give equal and ~0.7% bigger binaries
+		  respectively."
+
+		  This seems ad-hoc. Probably we need some experiments. */
+#define BRANCH_COST(speed_p, predictable_p)  2
+
+/* Specify the registers used for certain standard purposes.
+   The values of these macros are register numbers.  */
+
+/* Register to use for pushing function arguments.  */
+#define STACK_POINTER_REGNUM 1
+
+/* Base register for access to local variables of the function.  */
+#define HARD_FRAME_POINTER_REGNUM 2
+
+/* Link register. */
+#define LINK_REGNUM 9
+
+/* Register in which static-chain is passed to a function.  */
+
+#define STATIC_CHAIN_REGNUM 11
+
+#define PROLOGUE_TMP 13
+#define EPILOGUE_TMP 3
+
+/* Register in which address to store a structure value
+   is passed to a function.  */
+/*#define STRUCT_VALUE_REGNUM 0*/
+
+/* Pass address of result struct to callee as "invisible" first argument */
+#define STRUCT_VALUE 0
+
+/* -----------------------[ PHX start ]-------------------------------- */
+
+/* Define the classes of registers for register constraints in the
+   machine description.  Also define ranges of constants.
+
+   One of the classes must always be named ALL_REGS and include all hard regs.
+   If there is more than one class, another class must be named NO_REGS
+   and contain no registers.
+
+   The name GENERAL_REGS must be the name of a class (or an alias for
+   another name such as ALL_REGS).  This is the class of registers
+   that is allowed by "g" or "r" in a register constraint.
+   Also, registers outside this class are allocated only when
+   instructions express preferences for them.
+
+   GENERAL_REGS and BASE_REGS classess are the same on or1k.
+
+   The classes must be numbered in nondecreasing order; that is,
+   a larger-numbered class must never be contained completely
+   in a smaller-numbered class.
+
+   For any two classes, it is very desirable that there be another
+   class that represents their union.  */
+   
+/* The or1k has only one kind of registers, so NO_REGS, GENERAL_REGS
+   and ALL_REGS are the only classes.  */
+/* JPB 26-Aug-10: Based on note from Mikhael (mirekez@gmail.com), we don't
+   need CR_REGS and it is in the wrong place for later things! */
+enum reg_class 
+{ 
+  NO_REGS,
+  GENERAL_REGS,
+  ALL_REGS,
+  LIM_REG_CLASSES 
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump file.   */
+#define REG_CLASS_NAMES							\
+{									\
+  "NO_REGS",								\
+  "GENERAL_REGS",   							\
+  "ALL_REGS"								\
+}
+
+/* Define which registers fit in which classes.  This is an initializer for a
+   vector of HARD_REG_SET of length N_REG_CLASSES.
+
+   An initializer containing the contents of the register classes, as integers
+   which are bit masks.  The Nth integer specifies the contents of class N.
+   The way the integer MASK is interpreted is that register R is in the class
+   if `MASK & (1 << R)' is 1.
+
+   When the machine has more than 32 registers, an integer does not suffice.
+   Then the integers are replaced by sub-initializers, braced groupings
+   containing several integers.  Each sub-initializer must be suitable as an
+   initializer for the type `HARD_REG_SET' which is defined in
+   `hard-reg-set.h'.
+
+   For the OR1K we have the minimal set. GENERAL_REGS is all except r0, which
+   it permanently zero. */
+#define REG_CLASS_CONTENTS						\
+  {									\
+    { 0x00000000, 0x00000000 },		/* NO_REGS */			\
+    { 0xffffffff, 0x00000003 },		/* GENERAL_REGS */		\
+    { 0xffffffff, 0x00000007 }		/* ALL_REGS */			\
+  }
+
+/* The same information, inverted:
+
+   Return the class number of the smallest class containing reg number REGNO.
+   This could be a conditional expression or could index an array.
+
+   ??? 0 is not really a register, but a constant.  */
+#define REGNO_REG_CLASS(regno)						\
+  ((0 == regno) ? ALL_REGS : ((1 <= regno) && (regno <= OR1K_LAST_INT_REG))		\
+   ? GENERAL_REGS : NO_REGS)
+
+/* The class value for index registers, and the one for base regs.  */
+#define INDEX_REG_CLASS GENERAL_REGS
+#define BASE_REG_CLASS  GENERAL_REGS
+
+/* Given an rtx X being reloaded into a reg required to be in class CLASS,
+   return the class of reg to actually use.  In general this is just CLASS;
+   but on some machines in some cases it is preferable to use a more
+   restrictive class.  */
+#define PREFERRED_RELOAD_CLASS(X,CLASS)  (CLASS)
+
+/* Return the maximum number of consecutive registers needed to represent mode
+   MODE in a register of class CLASS.
+
+   On the or1k, this is always the size of MODE in words, since all registers
+   are the same size.  */
+#define CLASS_MAX_NREGS(CLASS, MODE)					\
+  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+
+/* -------------------------------------------------------------------------- */
+/* Stack layout; function entry, exit and calling.  */
+
+/* Define this if pushing a word on the stack makes the stack pointer a
+   smaller address.  */
+#define STACK_GROWS_DOWNWARD 1
+
+/* Define this if the nominal address of the stack frame is at the
+   high-address end of the local variables; that is, each additional local
+   variable allocated goes at a more negative offset in the frame.  */
+#define FRAME_GROWS_DOWNWARD 1
+
+/* Offset within stack frame to start allocating local variables at.  If
+   FRAME_GROWS_DOWNWARD, this is the offset to the END of the first local
+   allocated.  Otherwise, it is the offset to the BEGINNING of the first local
+   allocated.  */
+#define STARTING_FRAME_OFFSET 0
+
+/* Offset of first parameter from the argument pointer register value.  */
+#define FIRST_PARM_OFFSET(FNDECL) 0
+
+/* Define this if stack space is still allocated for a parameter passed
+   in a register.  The value is the number of bytes allocated to this
+   area.
+
+   No such allocation for OR1K. */
+/* #define REG_PARM_STACK_SPACE(FNDECL) (UNITS_PER_WORD * GP_ARG_NUM_REG) */
+
+/* Define this if the above stack space is to be considered part of the
+   space allocated by the caller.
+
+   N/a for OR1K. */
+/* #define OUTGOING_REG_PARM_STACK_SPACE */   
+
+/* Define this macro if `REG_PARM_STACK_SPACE' is defined, but the
+   stack parameters don't skip the area specified by it.
+
+   N/a for OR1K. */
+/* #define STACK_PARMS_IN_REG_PARM_AREA */
+
+/* If nonzero, the maximum amount of space required for outgoing arguments
+   will be computed and placed into the variable
+   current_function_outgoing_args_size. No space will be pushed onto the stack
+   for each call; instead, the function prologue should increase the stack
+   frame size by this amount.
+
+   Setting both PUSH_ARGS and ACCUMULATE_OUTGOING_ARGS is not proper.
+
+   This is the approached used by OR1K. */
+#define ACCUMULATE_OUTGOING_ARGS 1
+
+#define ELIMINABLE_REGS							\
+{{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM},				\
+ { ARG_POINTER_REGNUM,   HARD_FRAME_POINTER_REGNUM},			\
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},				\
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  (OFFSET) = or1k_initial_elimination_offset ((FROM), (TO))
+
+/* Minimum and maximum general purpose registers used to hold arguments.  */
+#define GP_ARG_MIN_REG 3
+#define GP_ARG_MAX_REG 8
+#define GP_ARG_NUM_REG (GP_ARG_MAX_REG - GP_ARG_MIN_REG + 1) 
+
+/* Return register */
+#define GP_ARG_RETURN  11 
+#define GP_ARG_RETURNH 12 
+
+/* TLS thread pointer register */
+#define THREAD_PTR_REGNUM 10
+
+/* Position Independent Code.  */
+
+#define PIC_OFFSET_TABLE_REGNUM 16
+
+/* A C expression that is nonzero if X is a legitimate immediate
+   operand on the target machine when generating position independent code.
+   You can assume that X satisfies CONSTANT_P, so you need not
+   check this.  You can also assume `flag_pic' is true, so you need not
+   check it either.  You need not define this macro if all constants
+   (including SYMBOL_REF) can be immediate operands when generating
+   position independent code.  */
+#define LEGITIMATE_PIC_OPERAND_P(X) or1k_legitimate_pic_operand_p (X)
+
+/* A C expression to create an RTX representing the place where a library
+   function returns a value of mode mode.
+
+   Note that “library function” in this context means a compiler support
+   routine, used to perform arithmetic, whose name is known specially by the
+   compiler and was not mentioned in the C code being compiled.
+
+   For the OR1K, return value is in R11 (GP_ARG_RETURN).  */   
+#define LIBCALL_VALUE(mode)                                             \
+  gen_rtx_REG(								\
+	   ((GET_MODE_CLASS (mode) != MODE_INT				\
+	     || GET_MODE_SIZE (mode) >= 4)				\
+	    ? (mode)							\
+	    : SImode),							\
+	    GP_ARG_RETURN)
+
+/* Define this if PCC uses the nonreentrant convention for returning
+   structure and union values. 
+
+   Not needed for OR1K. */
+/*#define PCC_STATIC_STRUCT_RETURN */
+
+/* A C expression that is nonzero if regno is the number of a hard register in
+   which the values of called function may come back.
+
+   A register whose use for returning values is limited to serving as the
+   second of a pair (for a value of type double, say) need not be recognized
+   by this macro. So for most machines, this definition suffices:
+
+       #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
+
+   If the machine has register windows, so that the caller and the called
+   function use different registers for the return value, this macro should
+   recognize only the caller's register numbers.
+
+   For OR1K, we must check if we have the return register.
+
+   From GCC 4.6, this will be replaced by TARGET_FUNCION_VALUE_REGNO_P target
+   hook function. */
+#define FUNCTION_VALUE_REGNO_P(N)  ((N) == GP_ARG_RETURN)
+ 
+/* 1 if N is a possible register number for function argument passing. */
+#define FUNCTION_ARG_REGNO_P(N) \
+   ((N) >= GP_ARG_MIN_REG && (N) <= GP_ARG_MAX_REG)
+
+/* A code distinguishing the floating point format of the target
+   machine.  There are three defined values: IEEE_FLOAT_FORMAT,
+   VAX_FLOAT_FORMAT, and UNKNOWN_FLOAT_FORMAT.  */
+#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
+#define FLOAT_WORDS_BIG_ENDIAN 1
+
+/* A C type for declaring a variable that is used as the first argument of
+   FUNCTION_ARG and other related values. For some target machines, the type
+   int suffices and can hold the number of bytes of argument so far.
+
+   There is no need to record in CUMULATIVE_ARGS anything about the arguments
+   that have been passed on the stack. The compiler has other variables to
+   keep track of that.  For target machines on which all arguments are passed
+   on the stack, there is no need to store anything in CUMULATIVE_ARGS;
+   however, the data structure must exist and should not be empty, so use
+   int. */
+#define CUMULATIVE_ARGS int
+
+/* A C statement (sans semicolon) for initializing the variable "cum" for the
+   state at the beginning of the argument list. The variable has type
+   CUMULATIVE_ARGS. The value of "fntype" is the tree node for the data type
+   of the function which will receive the args, or 0 if the args are to a
+   compiler support library function. For direct calls that are not libcalls,
+   "fndecl" contain the declaration node of the function. "fndecl" is also set
+   when INIT_CUMULATIVE_ARGS is used to find arguments for the function being
+   compiled.  "n_named_args" is set to the number of named arguments,
+   including a structure return address if it is passed as a parameter, when
+   making a call. When processing incoming arguments, "n_named_args" is set to
+   −1.
+
+   When processing a call to a compiler support library function, "libname"
+   identifies which one. It is a symbol_ref rtx which contains the name of the
+   function, as a string. "libname" is 0 when an ordinary C function call is
+   being processed. Thus, each time this macro is called, either "libname" or
+   "fntype" is nonzero, but never both of them at once.
+
+   For the OR1K, we set "cum" to zero each time.
+   JPB 29-Aug-10: Is this correct? */
+#define INIT_CUMULATIVE_ARGS(cum, fntype, libname, fndecl, n_named_args) \
+  (cum = 0)
+
+/* -------------------------------------------------------------------------- */
+/* Define intermediate macro to compute the size (in registers) of an argument
+   for the or1k.
+
+   The OR1K_ROUND_ADVANCE* macros are local to this file.  */
+
+/* Round "size" up to a word boundary.  */
+#define OR1K_ROUND_ADVANCE(size)					\
+  (((size) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Round arg "mode"/"type" up to the next word boundary.  */
+#define OR1K_ROUND_ADVANCE_ARG(mode, type)				\
+  ((mode) == BLKmode							\
+   ? OR1K_ROUND_ADVANCE (int_size_in_bytes (type))			\
+   : OR1K_ROUND_ADVANCE (GET_MODE_SIZE (mode)))
+
+/* The ABI says that no rounding to even or odd words takes place.  */
+#define OR1K_ROUND_ADVANCE_CUM(cum, mode, type) (cum)
+  
+/* Return boolean indicating if arg of type "type" and mode "mode" will be
+   passed in a reg.  This includes arguments that have to be passed by
+   reference as the pointer to them is passed in a reg if one is available
+   (and that is what we're given).
+
+   When passing arguments "named" is always 1.  When receiving arguments
+   "named" is 1 for each argument except the last in a stdarg/varargs
+   function.  In a stdarg function we want to treat the last named arg as
+   named.  In a varargs function we want to treat the last named arg (which is
+   `__builtin_va_alist') as unnamed.
+
+   This macro is only used in this file.  */
+#define OR1K_PASS_IN_REG_P(cum, mode, type, named)			\
+  ((named)                         					\
+   && ((OR1K_ROUND_ADVANCE_CUM ((cum), (mode), (type))			\
+	+ OR1K_ROUND_ADVANCE_ARG ((mode), (type))			\
+	<= GP_ARG_NUM_REG)))
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+   for profiling a function entry. */
+#define FUNCTION_PROFILER(FILE, LABELNO)
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the
+   stack pointer does not matter.  The value is tested only in functions that
+   have frame pointers.  No definition is equivalent to always zero.
+
+   The default suffices for OR1K. */
+#define EXIT_IGNORE_STACK 0
+
+/* A C expression whose value is RTL representing the location of the
+   incoming return address at the beginning of any function, before the
+   prologue.  This RTL is either a REG, indicating that the return
+   value is saved in REG, or a MEM representing a location in
+   the stack.  */
+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNUM)
+
+#define RETURN_ADDR_RTX or1k_return_addr_rtx
+
+/* Addressing modes, and classification of registers for them.  */
+
+/* #define HAVE_POST_INCREMENT */
+/* #define HAVE_POST_DECREMENT */
+
+/* #define HAVE_PRE_DECREMENT */
+/* #define HAVE_PRE_INCREMENT */
+
+/* Macros to check register numbers against specific register classes.  */
+#define MAX_REGS_PER_ADDRESS 1
+
+/* True if X is an rtx for a constant that is a valid address.
+
+   JPB 29-Aug-10: Why is the default implementation not OK? */
+#define CONSTANT_ADDRESS_P(X) 						\
+  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF              \
+   || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST                \
+   || GET_CODE (X) == HIGH)        
+
+/* A C expression which is nonzero if register number num is suitable for use
+   as a base register in operand addresses. Like TARGET_LEGITIMATE_ADDRESS_P,
+   this macro should also define a strict and a non-strict variant. Both
+   variants behave the same for hard register; for pseudos, the strict variant
+   will pass only those that have been allocated to a valid hard registers,
+   while the non-strict variant will pass all pseudos.
+
+   Compiler source files that want to use the strict variant of this and other
+   macros define the macro REG_OK_STRICT. You should use an #ifdef
+   REG_OK_STRICT conditional to define the strict variant in that case and the
+   non-strict variant otherwise.
+
+   JPB 29-Aug-10: This has been conflated with the old REG_OK_FOR_BASE_P
+                  function, which is no longer part of GCC.
+
+                  I'm not sure this is right. r0 can be a base register, just
+                  it can't get set by the user. */
+#ifdef REG_OK_STRICT
+#define REGNO_OK_FOR_BASE_P(num)					     \
+  (   ((0 < (num))             && ((num)             <= OR1K_LAST_INT_REG))  \
+   || ((0 < reg_renumber[num]) && (reg_renumber[num] <= OR1K_LAST_INT_REG)))
+
+#else
+/* Accept an int register or a pseudo reg.
+
+   JPB 1-Sep-10: Should this allow r0, if the strict version does not? */
+#define REGNO_OK_FOR_BASE_P(num) ((num) <= OR1K_LAST_INT_REG ||		\
+				  (num) >= FIRST_PSEUDO_REGISTER)
+#endif
+
+/* OR1K doesn't have any indexed addressing. */
+#define REG_OK_FOR_INDEX_P(X) 0
+#define REGNO_OK_FOR_INDEX_P(X) 0
+
+
+/* Specify the machine mode that this machine uses for the index in the
+   tablejump instruction.  */
+#define CASE_VECTOR_MODE SImode
+
+/* Define as C expression which evaluates to nonzero if the tablejump
+   instruction expects the table to contain offsets from the address of the
+   table.
+
+   Do not define this if the table should contain absolute addresses. */
+/* #define CASE_VECTOR_PC_RELATIVE 1 */
+
+/* Define this as 1 if `char' should by default be signed; else as 0.  */
+#define DEFAULT_SIGNED_CHAR 1
+
+/* The maximum number of bytes that a single instruction can move quickly
+   between memory and registers or between two memory locations. */
+#define MOVE_MAX 4
+
+/* Define this if zero-extension is slow (more than one real instruction).  */
+/* #define SLOW_ZERO_EXTEND */
+
+/* Nonzero if access to memory by bytes is slow and undesirable.  
+   For RISC chips, it means that access to memory by bytes is no
+   better than access by words when possible, so grab a whole word
+   and maybe make use of that.  */
+#define SLOW_BYTE_ACCESS 1
+
+/* Define if shifts truncate the shift count
+   which implies one can omit a sign-extension or zero-extension
+   of a shift count.  */
+/* #define SHIFT_COUNT_TRUNCATED */
+
+/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
+   is done just by pretending it is already truncated.  */
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+
+/* 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 SImode
+
+/* A function address in a call instruction
+   is a byte address (for indexing purposes)
+   so give the MEM rtx a byte's mode.  */
+#define FUNCTION_MODE SImode
+
+
+/* -------------------------------------------------------------------------- */
+/* Condition code stuff */
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+   return the mode to be used for the comparison. */
+#define SELECT_CC_MODE(op, x, y) or1k_select_cc_mode(op)
+
+/* Can the condition code MODE be safely reversed?  This is safe in
+   all cases on this port, because at present it doesn't use the
+   trapping FP comparisons (fcmpo).  */
+#define REVERSIBLE_CC_MODE(mode) 1
+
+/* Given a condition code and a mode, return the inverse condition.
+
+   JPB 31-Aug-10: This seems like the default. Do we even need this? */
+#define REVERSE_CONDITION(code, mode) reverse_condition (code)
+
+
+/* -------------------------------------------------------------------------- */
+/* Control the assembler format that we output.  */
+
+/* A C string constant describing how to begin a comment in the target
+   assembler language.  The compiler assumes that the comment will end at
+   the end of the line.  */
+#define ASM_COMMENT_START "#"
+
+/* Output to assembler file text saying following lines may contain character
+   constants, extra white space, comments, etc.
+
+   JPB 29-Aug-10: Default would seem to be OK here. */
+#define ASM_APP_ON "#APP\n"
+
+/* Output to assembler file text saying following lines no longer contain
+   unusual constructs.
+
+   JPB 29-Aug-10: Default would seem to be OK here. */
+#define ASM_APP_OFF "#NO_APP\n"
+
+/* Switch to the text or data segment.  */
+
+/* Output before read-only data.  */
+#define TEXT_SECTION_ASM_OP "\t.section .text"
+
+/* Output before writable data.  */
+#define DATA_SECTION_ASM_OP "\t.section .data"
+
+/* Output before uninitialized data. */
+#define BSS_SECTION_ASM_OP  "\t.section .bss"
+
+/* How to refer to registers in assembler output.  This sequence is indexed by
+   compiler's hard-register-number (see above).  */
+#define REGISTER_NAMES							\
+  {"r0",   "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",		\
+   "r8",   "r9", "r10", "r11", "r12", "r13", "r14", "r15",		\
+   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",		\
+   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",		\
+   "argp", "frame", "cc-flag"}
+
+
+/* -------------------------------------------------------------------------- */
+/* Debug things for DBX (STABS)                                               */
+/*                                                                            */
+/* Note. Our config.gcc includes dbxelf.h, which sets up appropriate          */
+/*       defaults. Choice of which debug format to use is in our elf.h        */
+/* -------------------------------------------------------------------------- */
+
+/* Don't try to use the  type-cross-reference character in DBX data.
+   Also has the consequence of putting each struct, union or enum
+   into a separate .stabs, containing only cross-refs to the others.  */
+/* JPB 24-Aug-10: Is this really correct. Can't GDB use this info? */
+#define DBX_NO_XREFS
+         
+/* -------------------------------------------------------------------------- */
+/* Debug things for DWARF2                                                    */
+/*                                                                            */
+/* Note. Choice of which debug format to use is in our elf.h                  */
+/* -------------------------------------------------------------------------- */
+
+/* We support frame unwind info including for exceptions handling. This needs
+   INCOMING_RETURN_ADDR_RTX to be set and OBJECT_FORMAT_ELF to be defined (in
+   elfos.h). Override any default value. */
+#undef  DWARF2_UNWIND_INFO
+#define DWARF2_UNWIND_INFO 1
+
+/* We want frame info produced. Note that this is superfluous if
+   DWARF2_UNWIND_INFO is non-zero, but we set so this so, we can produce frame
+   info even when it is zero. Override any default value. */
+#undef  DWARF2_FRAME_INFO
+#define DWARF2_FRAME_INFO 1
+
+/* Macro specifying which register holds the return address */
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNUM)
+
+/* Where is the start of our stack frame in relation to the end of the
+   previous stack frame at the start of a function, before the prologue */
+#define INCOMING_FRAME_SP_OFFSET  0
+
+/* Use compact debug tables. Generates .file/.loc directives. */
+#undef  DWARF2_ASM_LINE_DEBUG_INFO
+#define DWARF2_ASM_LINE_DEBUG_INFO 1
+
+/* We don't need an alternative return address for now. */
+/* DWARF_ALT_FRAME_RETURN_COLUMN */
+
+/* We always save registers in the prologue with word alignment, so don't
+   need this. */
+/* DWARF_CIE_DATA_ALIGNMENT */
+
+/* This specifies the maximum number of registers we can save in a frame. We
+   could note that only SP, FP, LR, arg regs and callee saved regs come into
+   this category. However this is only an efficiency thing, so for now we
+   don't use it. */
+/* DWARF_FRAME_REGISTERS */
+
+/* This specifies a mapping from register numbers in .dwarf_frame to
+   .eh_frame. However for us they are the same, so we don't need it. */
+/* DWARF_FRAME_REGNUM */
+
+/* Defined if the DWARF column numbers do not match register numbers. For us
+   they do, so this is not needed. */
+/* DWARF_REG_TO_UNWIND_COLUMN */
+
+/* Can be used to define a register guaranteed to be zero. Only useful if zero
+   is used to terminate backtraces, and not recommended for new ports, so we
+   don't use it. */
+/* DWARF_ZERO_REG */
+
+/* This is the inverse function for DWARF_FRAME_REGNUM. Again not needed. */
+/* DWARF2_FRAME_REG_OUT  */
+
+
+/* -------------------------------------------------------------------------- */
+/* Node: Label Output */
+
+/* Globalizing directive for a label.  */
+#define GLOBAL_ASM_OP "\t.global "
+
+#define SUPPORTS_WEAK 1
+
+/* This is how to output the definition of a user-level label named NAME,
+   such as the label on a static function or variable NAME.  */
+#define ASM_OUTPUT_LABEL(FILE,NAME)					\
+  { assemble_name (FILE, NAME); fputs (":\n", FILE); }
+
+/* We use -fleading-underscore to add it, when necessary.
+   JPB: No prefix for global symbols */
+#define USER_LABEL_PREFIX ""
+
+/* Remove any previous definition (elfos.h).  */
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM)	\
+  sprintf (LABEL, "*%s%d", PREFIX, NUM)
+
+/* This is how to output an assembler line defining an int constant.  */
+#define ASM_OUTPUT_INT(stream, value)					\
+  {									\
+    fprintf (stream, "\t.word\t");					\
+    output_addr_const (stream, (value));				\
+    fprintf (stream, "\n")}
+
+/* This is how to output an assembler line defining a float constant.  */
+#define ASM_OUTPUT_FLOAT(stream, value)					\
+  { long l;								\
+    REAL_VALUE_TO_TARGET_SINGLE (value,l);				\
+    fprintf(stream,"\t.word\t0x%08x\t\t# float %26.7e\n", l, value); }
+
+/* This is how to output an assembler line defining a double constant.  */
+#define ASM_OUTPUT_DOUBLE(stream, value)				\
+  { long l[2];								\
+    REAL_VALUE_TO_TARGET_DOUBLE (value,&l[0]);				\
+    fprintf(stream,"\t.word\t0x%08x,0x%08x\t# float %26.16le\n",	\
+	    l[0],l[1],value); }
+
+/* This is how to output an assembler line defining a long double constant.
+
+   JPB 29-Aug-10: Do we really mean this. I thought long double on OR1K was
+                  the same as double. */
+#define ASM_OUTPUT_LONG_DOUBLE(stream, value)				\
+  { long l[4];								\
+    REAL_VALUE_TO_TARGET_DOUBLE (value,&l[0]);				\
+    fprintf (stream,							\
+	     "\t.word\t0x%08x,0x%08x,0x%08x,0x%08x\t# float %26.18lle\n", \
+	     l[0],l[1],l[2],l[3],value); }
+
+/* This is how to output an assembler line defining a short constant.  */
+#define ASM_OUTPUT_SHORT(stream, value)					\
+  { fprintf (stream, "\t.half\t");					\
+    output_addr_const (stream, (value));				\
+    fprintf (stream, "\n"); }
+
+/* This is how to output an assembler line defining a char constant.  */
+#define ASM_OUTPUT_CHAR(stream, value)					\
+  { fprintf (stream, "\t.byte\t");					\
+    output_addr_const (stream, (value));				\
+    fprintf (stream, "\n")}
+
+/* This is how to output an assembler line for a numeric constant byte.  */
+#define ASM_OUTPUT_BYTE(stream, value)  \
+  fprintf (stream, "\t.byte\t0x%02x\n", (value))
+
+/* This is how to output an insn to push a register on the stack.
+   It need not be very fast code.
+
+    JPB 29-Aug-10: This was using l.sub (since we don't have l.subi), so it
+                   was potty code. Replaced by adding immediate -1. */
+#define ASM_OUTPUT_REG_PUSH(stream, regno)				\
+  { fprintf (stream, "\tl.addi\tr1,r1,-4\n");				\
+    fprintf (stream, "\tl.sw\t0(r1),%s\n", reg_names[regno]); }
+
+/* This is how to output an insn to pop a register from the stack.
+   It need not be very fast code.  */
+#define ASM_OUTPUT_REG_POP(stream,REGNO)				\
+  { fprintf (stream, "\tl.lwz\t%s,0(r1)\n", reg_names[REGNO]);		\
+    fprintf (stream, "\tl.addi\tr1,r1,4\n"); }
+
+/* This is how to output an element of a case-vector that is absolute.
+   (The Vax does not use such vectors,
+   but we must define this macro anyway.)  */
+#define ASM_OUTPUT_ADDR_VEC_ELT(stream, value)				\
+  fprintf (stream, "\t.word\t.L%d\n", value)
+
+/* This is how to output an element of a case-vector that is relative.  */
+#define ASM_OUTPUT_ADDR_DIFF_ELT(stream, body, value, rel)		\
+  fprintf (stream, "\t.word\t.L%d-.L%d\n", value, rel)
+
+#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
+/* ??? If we were serious about PIC, we should also use l.jal to get
+   the table start address.  */
+
+/* This is how to output an assembler line that says to advance the location
+   counter to a multiple of 2**log bytes.  */
+#define ASM_OUTPUT_ALIGN(stream, log)					\
+  if ((log) != 0)							\
+    {									\
+      fprintf (stream, "\t.align\t%d\n", 1 << (log));			\
+    }
+
+/* This is how to output an assembler line that says to advance the location
+   counter by "size" bytes.  */
+#define ASM_OUTPUT_SKIP(stream, size)					\
+  fprintf (stream, "\t.space %d\n", (size))
+
+/* Need to split up .ascii directives to avoid breaking
+   the linker. */
+
+/* This is how to output a string.  */
+#define ASM_OUTPUT_ASCII(stream, ptr, len)				\
+  output_ascii_pseudo_op (stream, (const unsigned char *) (ptr), len)
+
+/* Invoked just before function output. */
+#define ASM_OUTPUT_FUNCTION_PREFIX(stream, fnname)			\
+  { fputs (".proc\t", stream); assemble_name (stream, fnname);		\
+    fputs ("\n", stream); }
+
+/* This says how to output an assembler line to define a global common
+   symbol. */
+#define ASM_OUTPUT_COMMON(stream,name,size,rounded)			\
+  { data_section ();							\
+    fputs ("\t.global\t", stream);					\
+    assemble_name(stream, name);					\
+    fputs ("\n", stream);						\
+    assemble_name (stream, name);					\
+    fputs (":\n", stream);						\
+    fprintf (stream, "\t.space\t%d\n", rounded); }
+
+/* This says how to output an assembler line to define a local common
+   symbol.
+
+   JPB 29-Aug-10: I'm sure this doesn't work - we don't have a .bss directive
+   like this. */
+#define ASM_OUTPUT_LOCAL(stream, name, size, rounded)			\
+  { fputs ("\t.bss\t", (stream));					\
+    assemble_name ((stream), (name));					\
+    fprintf ((stream), ",%d,%d\n", (size), (rounded)); }
+
+/* This says how to output an assembler line to define a global common symbol
+   with size "size" (in bytes) and alignment "align" (in bits).  */
+#define ASM_OUTPUT_ALIGNED_COMMON(stream, name, size, align)		\
+  { data_section();							\
+    if ((ALIGN) > 8)							\
+      {									\
+	fprintf(stream, "\t.align %d\n", ((align) / BITS_PER_UNIT));	\
+      }									\
+    fputs("\t.global\t", stream); assemble_name(stream, name);      	\
+    fputs("\n", stream);                                        	\
+    assemble_name(stream, name);                                	\
+    fputs (":\n", stream);						\
+    fprintf(stream, "\t.space\t%d\n", size); }
+  
+/* This says how to output an assembler line to define a local common symbol
+   with size "size" (in bytes) and alignment "align" (in bits).  */
+#define ASM_OUTPUT_ALIGNED_LOCAL(stream, name, size, align)		\
+  { data_section();							\
+    if ((align) > 8)							\
+      {									\
+	fprintf(stream, "\t.align %d\n", ((align) / BITS_PER_UNIT));	\
+      }									\
+    assemble_name(stream, name);					\
+    fputs (":\n", stream);						\
+    fprintf(stream, "\t.space %d\n", size); }
+                                                     
+/* Store in "output" a string (made with alloca) containing an assembler-name
+   for a local static variable named "name".  "labelno" is an integer which is
+   different for each call.  */
+#define ASM_FORMAT_PRIVATE_NAME(output, name, labelno)			\
+  { (output) = (char *) alloca (strlen ((name)) + 10);			\
+    sprintf ((output), "%s.%lu", (name), (unsigned long int) (labelno)); }
+
+/* Macro for %code validation. Returns nonzero if valid.
+
+   The acceptance of '(' is an idea taken from SPARC; output nop for %( if not
+   optimizing or the slot is not filled. */
+#define PRINT_OPERAND_PUNCT_VALID_P(code)  (('(' == code) || ('%' == code))
+
+/* Print an instruction operand "x" on file "stream".  "code" is the code from
+   the %-spec that requested printing this operand; if `%z3' was used to print
+   operand 3, then CODE is 'z'.  */
+#define PRINT_OPERAND(stream, x, code)					\
+{									\
+  if (code == 'r'							\
+      && GET_CODE (x) == MEM						\
+      && GET_CODE (XEXP (x, 0)) == REG)					\
+    {									\
+      fprintf (stream, "%s", reg_names[REGNO (XEXP (x, 0))]);		\
+    }									\
+  else if (code == '(')							\
+    {									\
+      if (TARGET_DELAY_ON && dbr_sequence_length ())                    \
+	fprintf (stream, "\t# delay slot filled");			\
+      else if (!TARGET_DELAY_OFF)                                       \
+	fprintf (stream, "\n\tl.nop\t\t\t# nop delay slot");		\
+    }									\
+  else if (code == 'C')							\
+    {									\
+      switch (GET_CODE (x))						\
+	{								\
+        case EQ:							\
+	  fputs ("eq", stream);						\
+	  break;							\
+	case NE:							\
+	  fputs ("ne", stream);						\
+	  break;							\
+	case GT:							\
+	  fputs ("gts", stream);					\
+	  break;							\
+        case GE:							\
+	  fputs ("ges", stream);					\
+	  break;							\
+	case LT:							\
+	  fputs ("lts", stream);					\
+	  break;							\
+	case LE:							\
+	  fputs ("les", stream);					\
+	  break;							\
+	case GTU:							\
+	  fputs ("gtu", stream);					\
+	  break;							\
+	case GEU:							\
+	  fputs ("geu", stream);					\
+	  break;							\
+	case LTU:							\
+	  fputs ("ltu", stream);					\
+	  break;							\
+	case LEU:							\
+	  fputs ("leu", stream);					\
+	  break;							\
+	default:							\
+	  abort ();							\
+	}								\
+    }									\
+  else if (code == 'H')							\
+    {									\
+      if (GET_CODE (x) == REG)						\
+	fprintf (stream, "%s", reg_names[REGNO (x) + 1]);		\
+      else								\
+	abort ();							\
+    }									\
+  else if (GET_CODE (x) == REG)						\
+    fprintf (stream, "%s", reg_names[REGNO (x)]);			\
+  else if (GET_CODE (x) == MEM)						\
+    output_address (XEXP (x, 0));					\
+  else									\
+    output_addr_const (stream, x);					\
+}
+
+/* The size of the trampoline in bytes. This is a block of code followed by
+   two words specifying the function address and static chain pointer. */
+#define TRAMPOLINE_SIZE							\
+  (or1k_trampoline_code_size () + GET_MODE_SIZE (ptr_mode) * 2)
+
+/* Alignment required for trampolines, in bits.
+
+   For the OR1K, there is no need for anything other than word alignment. */
+#define TRAMPOLINE_ALIGNMENT  32
+
+/* Assume that if the assembler supports thread local storage
+ * the system supports it. */
+#if !defined(TARGET_HAVE_TLS) && defined(HAVE_AS_TLS)
+#define TARGET_HAVE_TLS true
+#endif
+
+/* Describe how we implement __builtin_eh_return.  */
+#define EH_RETURN_REGNUM 23
+/* Use r25, r27, r29 and r31 (clobber regs) for exception data */
+#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (25 + ((N)<<1)) : INVALID_REGNUM)
+#define EH_RETURN_STACKADJ_RTX  gen_rtx_REG (Pmode, EH_RETURN_REGNUM)
+#define EH_RETURN_HANDLER_RTX   or1k_eh_return_handler_rtx ()
+
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
+  (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr)
+
+#define INIT_EXPANDERS or1k_init_expanders ()
+
+/* A C structure for machine-specific, per-function data.  This is
+ *    added to the cfun structure.  */
+typedef struct GTY(()) machine_function
+{
+  /* Force stack save of LR. Used in RETURN_ADDR_RTX. */
+  int force_lr_save;
+} machine_function;
+
+#endif /* _OR1K_H_ */
diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md
new file mode 100644
index 0000000..4855a32
--- /dev/null
+++ b/gcc/config/or1k/or1k.md
@@ -0,0 +1,1599 @@
+;; Machine description for GNU compiler, OpenRISC 1000 family, OR32 ISA
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+;; 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 2010 Embecosm Limited
+
+;; Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999.
+;; Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005.
+;; Floating point additions by Jungsook Yang <jungsook.yang@uci.edu>
+;;                             Julius Baxter <julius@orsoc.se> in 2010
+;; Updated for GCC 4.5 by Jeremy Bennett <jeremy.bennett@embecosm.com>
+;; and Joern Rennecke <joern.rennecke@embecosm.com> in 2010
+
+;; This file is part of GNU CC.
+
+;; This program 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 of the License, or (at your option)
+;; any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License along
+;; with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+(define_constants [
+  (SP_REG 1)
+  (FP_REG 2) ; hard frame pointer
+  (CC_REG 34)
+
+  ;; unspec values
+  (UNSPEC_FRAME         0)
+  (UNSPEC_GOT           1)
+  (UNSPEC_GOTOFFHI      2)
+  (UNSPEC_GOTOFFLO      3)
+  (UNSPEC_TPOFFLO       4)
+  (UNSPEC_TPOFFHI       5)
+  (UNSPEC_GOTTPOFFLO    6)
+  (UNSPEC_GOTTPOFFHI    7)
+  (UNSPEC_GOTTPOFFLD    8)
+  (UNSPEC_TLSGDLO       9)
+  (UNSPEC_TLSGDHI       10)
+  (UNSPEC_SET_GOT       101)
+  (UNSPEC_CMPXCHG       201)
+  (UNSPEC_FETCH_AND_OP  202)
+])
+
+(include "predicates.md")
+
+(include "constraints.md")
+
+(define_attr "type"
+  "unknown,load,store,move,extend,logic,add,mul,shift,compare,branch,jump,fp,jump_restore"
+  (const_string "unknown"))
+
+;; Number of machine instructions required to implement an insn.
+(define_attr "length" "" (const_int 1))
+
+;; Single delay slot after branch or jump instructions, wich may contain any
+;; instruction but another branch or jump.
+;; If TARGET_DELAY_OFF is not true, then never use delay slots.
+;; If TARGET_DELAY_ON is not true, no instruction will be allowed to
+;; fill the slot, and so it will be filled by a nop instead.
+(define_delay (and (match_test "!TARGET_DELAY_OFF") (eq_attr "type" "branch,jump"))
+               [(and (match_test "TARGET_DELAY_ON")
+		     (eq_attr "type" "!branch,jump")
+		     (eq_attr "length" "1")) (nil) (nil)])
+
+;; ALU is modelled as a single functional unit, which is reserved for varying
+;; numbers of slots.
+;;
+;; I think this is all incorrect for the OR1K. The latency says when the
+;; result will be ready, not how long the pipeline takes to execute.
+(define_cpu_unit "or1k_alu")
+(define_insn_reservation "bit_unit" 3 (eq_attr "type" "shift") "or1k_alu")
+(define_insn_reservation "lsu_load" 3 (eq_attr "type" "load") "or1k_alu*3")
+(define_insn_reservation "lsu_store" 2 (eq_attr "type" "store") "or1k_alu")
+(define_insn_reservation "alu_unit" 2
+                         (eq_attr "type" "add,logic,extend,move,compare")
+			 "or1k_alu")
+(define_insn_reservation "mul_unit" 16 (eq_attr "type" "mul") "or1k_alu*16")
+
+;; AI = Atomic Integers
+;; We do not support DI in our atomic operations.
+(define_mode_iterator AI [QI HI SI])
+
+;; Note: We use 'mult' here for nand since it does not have its own RTX class.
+(define_code_iterator atomic_op [plus minus and ior xor mult])
+(define_code_attr op_name
+  [(plus "add") (minus "sub") (and "and") (ior "or") (xor "xor") (mult "nand")])
+(define_code_attr op_insn
+  [(plus "add") (minus "sub") (and "and") (ior "or") (xor "xor") (mult "and")])
+(define_code_attr post_op_insn
+  [(plus "") (minus "") (and "") (ior "") (xor "")
+   (mult "l.xori  \t%3,%3,0xffff # fetch_nand: invert")])
+
+;; Called after register allocation to add any instructions needed for the
+;; prologue.  Using a prologue insn is favored compared to putting all of the
+;; instructions in output_function_prologue(), since it allows the scheduler
+;; to intermix instructions with the saves of the caller saved registers.  In
+;; some cases, it might be necessary to emit a barrier instruction as the last
+;; insn to prevent such scheduling.
+
+(define_expand "prologue"
+  [(use (const_int 1))]
+  ""
+{
+  or1k_expand_prologue ();
+  DONE;
+})
+
+;; Called after register allocation to add any instructions needed for the
+;; epilogue.  Using an epilogue insn is favored compared to putting all of the
+;; instructions in output_function_epilogue(), since it allows the scheduler
+;; to intermix instructions with the restores of the caller saved registers.
+;; In some cases, it might be necessary to emit a barrier instruction as the
+;; first insn to prevent such scheduling.
+(define_expand "epilogue"
+  [(use (const_int 2))]
+  ""
+{
+  or1k_expand_epilogue ();
+  DONE;
+})
+
+(define_insn "frame_alloc_fp"
+  [(set (reg:SI SP_REG)
+	(plus:SI (reg:SI SP_REG)
+		 (match_operand:SI 0 "nonmemory_operand" "r,I")))
+   (clobber (mem:QI (plus:SI (reg:SI FP_REG)
+			     (unspec:SI [(const_int FP_REG)] UNSPEC_FRAME))))]
+  ""
+  "@
+   l.add\tr1,r1,%0\t# allocate frame
+   l.addi\tr1,r1,%0\t# allocate frame"
+  [(set_attr "type" "add")
+   (set_attr "length" "1")])
+
+(define_insn "frame_dealloc_fp"
+  [(set (reg:SI SP_REG) (reg:SI FP_REG))
+   (clobber (mem:QI (plus:SI (reg:SI FP_REG)
+			     (unspec:SI [(const_int FP_REG)] UNSPEC_FRAME))))]
+  ""
+  "l.ori\tr1,r2,0\t# deallocate frame"
+  [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+(define_insn "frame_dealloc_sp"
+  [(set (reg:SI SP_REG)
+	(plus:SI (reg:SI SP_REG)
+		 (match_operand:SI 0 "nonmemory_operand" "r,I")))
+   (clobber (mem:QI (plus:SI (reg:SI SP_REG)
+			     (unspec:SI [(const_int SP_REG)] UNSPEC_FRAME))))]
+  ""
+  "@
+   l.add\tr1,r1,%0
+   l.addi\tr1,r1,%0"
+  [(set_attr "type" "add")
+   (set_attr "length" "1")])
+
+(define_insn "return_internal"
+  [(return)
+   (use (match_operand 0 "pmode_register_operand" ""))]
+  ""
+  "l.jr    \t%0\t# return_internal%("
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+
+
+;;
+;; movQI
+;;
+
+(define_expand "movqi"
+  [(set (match_operand:QI 0 "general_operand" "")
+	(match_operand:QI 1 "general_operand" ""))]
+  ""
+  "
+      if (can_create_pseudo_p())
+        {
+          if (GET_CODE (operands[1]) == CONST_INT)
+	    {
+	      rtx reg = gen_reg_rtx (SImode);
+
+	      emit_insn (gen_movsi (reg, operands[1]));
+	      operands[1] = gen_lowpart (QImode, reg);
+	    }
+	  if (GET_CODE (operands[1]) == MEM && optimize > 0)
+	    {
+	      rtx reg = gen_reg_rtx (SImode);
+
+	      emit_insn (gen_rtx_SET (SImode, reg,
+				  gen_rtx_ZERO_EXTEND (SImode,
+						       operands[1])));
+
+	      operands[1] = gen_lowpart (QImode, reg);
+	    }
+          if (GET_CODE (operands[0]) != REG)
+	    operands[1] = force_reg (QImode, operands[1]);
+        }
+")
+
+(define_insn "*movqi_internal"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,r,r,r,r")
+	(match_operand:QI 1 "general_operand"       "r,r,I,K,m"))]
+  ""
+  "@
+   l.sb    \t%0,%1\t    # movqi
+   l.ori   \t%0,%1,0\t  # movqi: move reg to reg
+   l.addi  \t%0,r0,%1\t # movqi: move immediate
+   l.ori   \t%0,r0,%1\t # movqi: move immediate
+   l.lbz   \t%0,%1\t    # movqi"
+  [(set_attr "type" "store,add,add,logic,load")])
+
+
+;;
+;; movHI
+;;
+
+(define_expand "movhi"
+  [(set (match_operand:HI 0 "general_operand" "")
+	(match_operand:HI 1 "general_operand" ""))]
+  ""
+  "
+      if (can_create_pseudo_p())
+        {
+          if (GET_CODE (operands[1]) == CONST_INT)
+	    {
+	      rtx reg = gen_reg_rtx (SImode);
+
+	      emit_insn (gen_movsi (reg, operands[1]));
+	      operands[1] = gen_lowpart (HImode, reg);
+	    }
+	  else if (GET_CODE (operands[1]) == MEM && optimize > 0)
+	    {
+	      rtx reg = gen_reg_rtx (SImode);
+
+	      emit_insn (gen_rtx_SET (SImode, reg,
+				      gen_rtx_ZERO_EXTEND (SImode,
+					   	           operands[1])));
+	      operands[1] = gen_lowpart (HImode, reg);
+	    }
+          if (GET_CODE (operands[0]) != REG)
+	    operands[1] = force_reg (HImode, operands[1]);
+        }
+")
+
+(define_insn "*movhi_internal"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r,r,r,r")
+	(match_operand:HI 1 "general_operand"       "r,r,I,K,m"))]
+  ""
+  "@
+   l.sh    \t%0,%1\t # movhi
+   l.ori   \t%0,%1,0\t # movhi: move reg to reg
+   l.addi  \t%0,r0,%1\t # movhi: move immediate
+   l.ori   \t%0,r0,%1\t # movhi: move immediate
+   l.lhz   \t%0,%1\t # movhi"
+  [(set_attr "type" "store,add,add,logic,load")])
+
+(define_expand "movsi"
+  [(set (match_operand:SI 0 "general_operand" "")
+	(match_operand:SI 1 "general_operand" ""))]
+  ""
+{
+  if (or1k_expand_move (SImode, operands)) DONE;
+})
+
+;;
+;; movSI
+;;
+
+(define_insn "*movsi_insn"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
+        (match_operand:SI 1 "input_operand"       "I,K,M,r,m,r"))]
+  "(register_operand (operands[0], SImode)
+   || (register_operand (operands[1], SImode))
+   || (operands[1] == const0_rtx))"
+  "@
+  l.addi  \t%0,r0,%1\t # move immediate I
+  l.ori   \t%0,r0,%1\t # move immediate K
+  l.movhi \t%0,hi(%1)\t # move immediate M
+  l.ori   \t%0,%1,0\t # move reg to reg
+  l.lwz   \t%0,%1\t # SI load
+  l.sw    \t%0,%1\t # SI store"
+  [(set_attr "type" "add,load,store,add,logic,move")
+   (set_attr "length" "1,1,1,1,1,1")])
+
+(define_insn "movsi_lo_sum"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+                   (match_operand:SI 2 "immediate_operand" "i")))]
+  ""
+  "l.ori   \t%0,%1,lo(%2) # movsi_lo_sum"
+ [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_high"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(high:SI (match_operand:SI 1 "immediate_operand" "i")))]
+  ""
+  "l.movhi  \t%0,hi(%1) # movsi_high"
+[(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_gotofflo"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+                    (match_operand 2 "" ""))] UNSPEC_GOTOFFLO))]
+  "flag_pic"
+  "l.ori   \t%0,%1,gotofflo(%2) # movsi_gotofflo"
+  [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_gotoffhi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFFHI))]
+  "flag_pic"
+  "l.movhi  \t%0,gotoffhi(%1) # movsi_gotoffhi"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_got"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand 1 "symbolic_operand" "")] UNSPEC_GOT))
+   (use (reg:SI 16))]
+  "flag_pic"
+  "l.lwz    \t%0, got(%1)(r16)"
+  [(set_attr "type" "load")]
+)
+
+(define_insn "movsi_tlsgdlo"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+                   (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_TLSGDLO))]
+  ""
+  "l.ori   \t%0,%1,tlsgdlo(%2) # movsi_tlsgdlo"
+ [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_tlsgdhi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_TLSGDHI))]
+  ""
+  "l.movhi  \t%0,tlsgdhi(%1) # movsi_tlsgdhi"
+[(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_gottpofflo"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+                   (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_GOTTPOFFLO))]
+  ""
+  "l.ori   \t%0,%1,gottpofflo(%2) # movsi_gottpofflo"
+ [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_gottpoffhi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_GOTTPOFFHI))]
+  ""
+  "l.movhi  \t%0,gottpoffhi(%1) # movsi_gottpoffhi"
+[(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn "load_gottpoff"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_GOTTPOFFLD))]
+  ""
+  "l.lwz  \t%0,0(%1) # load_gottpoff"
+[(set_attr "type" "load")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_tpofflo"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+                   (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_TPOFFLO))]
+  ""
+  "l.ori   \t%0,%1,tpofflo(%2) # movsi_tpofflo"
+ [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+(define_insn "movsi_tpoffhi"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_TPOFFHI))]
+  ""
+  "l.movhi  \t%0,tpoffhi(%1) # movsi_tpoffhi"
+[(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+
+(define_insn_and_split "movsi_insn_big"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(match_operand:SI 1 "immediate_operand" "i"))]
+  "GET_CODE (operands[1]) != CONST_INT"
+  ;; the switch of or1k bfd to Rela allows us to schedule insns separately.
+  "l.movhi \t%0,hi(%1)\;l.ori   \t%0,%0,lo(%1)"
+  "(GET_CODE (operands[1]) != CONST_INT
+    || ! (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'I', \"I\")
+	  || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'K', \"K\")
+	  || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'M', \"M\")))
+   && reload_completed
+   && GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM"
+  [(pc)]
+{
+  if (!or1k_expand_symbol_ref(SImode, operands))
+    {
+      emit_insn (gen_movsi_high (operands[0], operands[1]));
+      emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));
+    }
+  DONE;
+}
+  [(set_attr "type" "move")
+   (set_attr "length" "2")])
+
+
+;;
+;; Conditional Branches & Moves
+;; 
+
+(define_expand "addsicc"
+  [(match_operand:SI 0 "register_operand" "")
+   (match_operand 1 "comparison_operator" "")
+   (match_operand:SI 2 "register_operand" "")
+   (match_operand:SI 3 "register_operand" "")]
+  ""
+  "FAIL;")
+
+(define_expand "addhicc"
+  [(match_operand:HI 0 "register_operand" "")
+   (match_operand 1 "comparison_operator" "")
+   (match_operand:HI 2 "register_operand" "")
+   (match_operand:HI 3 "register_operand" "")]
+  ""
+  "FAIL;")
+
+(define_expand "addqicc"
+  [(match_operand:QI 0 "register_operand" "")
+   (match_operand 1 "comparison_operator" "")
+   (match_operand:QI 2 "register_operand" "")
+   (match_operand:QI 3 "register_operand" "")]
+  ""
+  "FAIL;")
+
+
+;;
+;; conditional moves
+;;
+
+(define_expand "movsicc"
+   [(set (match_operand:SI 0 "register_operand" "")
+	 (if_then_else:SI (match_operand 1 "comparison_operator" "")
+			  (match_operand:SI 2 "register_operand" "")
+			  (match_operand:SI 3 "register_operand" "")))]
+  "TARGET_MASK_CMOV"
+  "
+{
+  if (or1k_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
+    DONE;
+}")
+
+(define_expand "movhicc"
+   [(set (match_operand:HI 0 "register_operand" "")
+	 (if_then_else:SI (match_operand 1 "comparison_operator" "")
+			  (match_operand:HI 2 "register_operand" "")
+			  (match_operand:HI 3 "register_operand" "")))]
+  ""
+  "
+{
+    FAIL;
+}")
+
+(define_expand "movqicc"
+   [(set (match_operand:QI 0 "register_operand" "")
+	 (if_then_else:SI (match_operand 1 "comparison_operator" "")
+			  (match_operand:QI 2 "register_operand" "")
+			  (match_operand:QI 3 "register_operand" "")))]
+  ""
+  "
+{
+    FAIL;
+}")
+
+
+;; We use the BASE_REGS for the cmov input operands because, if rA is
+;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
+;; because we may switch the operands and rB may end up being rA.
+
+(define_insn "cmov"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(if_then_else:SI
+	 (match_operator 1 "comparison_operator"
+			 [(match_operand 4 "cc_reg_operand" "")
+			  (const_int 0)])
+	 (match_operand:SI 2 "register_operand" "r")
+	 (match_operand:SI 3 "register_operand" "r")))]
+  "TARGET_MASK_CMOV"
+  "*
+   return or1k_output_cmov(operands);
+  ")
+
+;;
+;;  ....................
+;;
+;;	COMPARISONS
+;;
+;;  ....................
+
+;; Flow here is rather complex:
+;;
+;;  1)	The cmp{si,di,sf,df} routine is called.  It deposits the
+;;	arguments into the branch_cmp array, and the type into
+;;	branch_type.  No RTL is generated.
+;;
+;;  2)	The appropriate branch define_expand is called, which then
+;;	creates the appropriate RTL for the comparison and branch.
+;;	Different CC modes are used, based on what type of branch is
+;;	done, so that we can constrain things appropriately.  There
+;;	are assumptions in the rest of GCC that break if we fold the
+;;	operands into the branches for integer operations, and use cc0
+;;	for floating point, so we use the fp status register instead.
+;;	If needed, an appropriate temporary is created to hold the
+;;	of the integer compare.
+
+;; Compare insns are next.  Note that the RS/6000 has two types of compares,
+;; signed & unsigned, and one type of branch.
+;;
+;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
+;; insns, and branches.  We store the operands of compares until we see
+;; how it is used.
+
+;; JPB 31-Aug-10: cmpxx appears to be obsolete in GCC 4.5. Needs more
+;; investigation.
+
+;;(define_expand "cmpsi"
+;;  [(set (reg:CC CC_REG)
+;;	(compare:CC (match_operand:SI 0 "register_operand" "")
+;;		    (match_operand:SI 1 "nonmemory_operand" "")))]
+;;  ""
+;;  {
+;;   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+;;      operands[0] = force_reg (SImode, operands[0]);
+;;      or1k_compare_op0 = operands[0];
+;;     or1k_compare_op1 = operands[1];
+;;      DONE;
+;;      })
+
+;; (define_expand "cmpsf"
+;;   [(set (reg:CC CC_REG)
+;; 	(compare:CC (match_operand:SF 0 "register_operand" "")
+;; 		    (match_operand:SF 1 "register_operand" "")))]
+;;   "TARGET_HARD_FLOAT"
+;;   {
+;;    if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+;;       operands[0] = force_reg (SFmode, operands[0]);
+;;       or1k_compare_op0 = operands[0];
+;;       or1k_compare_op1 = operands[1];
+;;       DONE;
+;;       })
+
+(define_expand "cbranchsi4"
+  [(match_operator 0 "comparison_operator"
+    [(match_operand:SI 1 "register_operand")
+     (match_operand:SI 2 "nonmemory_operand")])
+   (match_operand 3 "")]
+   ""
+   {
+   or1k_expand_conditional_branch (operands, SImode);
+   DONE;
+   })
+
+(define_expand "cbranchsf4"
+  [(match_operator 0 "comparison_operator"
+    [(match_operand:SF 1 "register_operand")
+     (match_operand:SF 2 "register_operand")])
+   (match_operand 3 "")]
+   "TARGET_HARD_FLOAT"
+   {
+   or1k_expand_conditional_branch (operands, SFmode);
+   DONE;
+   })
+
+;;
+;; Setting a CCxx registers from comparision
+;;
+
+
+
+;; Here are the actual compare insns.
+(define_insn "*cmpsi_eq"
+  [(set (reg:CCEQ CC_REG)
+	(compare:CCEQ (match_operand:SI 0 "register_operand" "r,r")
+		      (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfeqi\t%0,%1 # cmpsi_eq
+   l.sfeq \t%0,%1 # cmpsi_eq"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsi_ne"
+  [(set (reg:CCNE CC_REG)
+	(compare:CCNE (match_operand:SI 0 "register_operand" "r,r")
+		      (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfnei\t%0,%1 # cmpsi_ne
+   l.sfne \t%0,%1 # cmpsi_ne"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsi_gt"
+  [(set (reg:CCGT CC_REG)
+	(compare:CCGT (match_operand:SI 0 "register_operand" "r,r")
+		      (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfgtsi\t%0,%1 # cmpsi_gt
+   l.sfgts \t%0,%1 # cmpsi_gt"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsi_gtu"
+  [(set (reg:CCGTU CC_REG)
+	(compare:CCGTU (match_operand:SI 0 "register_operand" "r,r")
+		       (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfgtui\t%0,%1 # cmpsi_gtu
+   l.sfgtu \t%0,%1 # cmpsi_gtu"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsi_lt"
+  [(set (reg:CCLT CC_REG)
+	(compare:CCLT (match_operand:SI 0 "register_operand" "r,r")
+		      (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfltsi\t%0,%1 # cmpsi_lt
+   l.sflts \t%0,%1 # cmpsi_lt"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsi_ltu"
+  [(set (reg:CCLTU CC_REG)
+	(compare:CCLTU (match_operand:SI 0 "register_operand" "r,r")
+		       (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfltui\t%0,%1 # cmpsi_ltu
+   l.sfltu \t%0,%1 # cmpsi_ltu"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsi_ge"
+  [(set (reg:CCGE CC_REG)
+	(compare:CCGE (match_operand:SI 0 "register_operand" "r,r")
+		      (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfgesi\t%0,%1 # cmpsi_ge
+   l.sfges \t%0,%1 # cmpsi_ge"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+
+(define_insn "*cmpsi_geu"
+  [(set (reg:CCGEU CC_REG)
+	(compare:CCGEU (match_operand:SI 0 "register_operand" "r,r")
+		       (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfgeui\t%0,%1 # cmpsi_geu
+   l.sfgeu \t%0,%1 # cmpsi_geu"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+
+(define_insn "*cmpsi_le"
+  [(set (reg:CCLE CC_REG)
+	(compare:CCLE (match_operand:SI 0 "register_operand" "r,r")
+		      (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sflesi\t%0,%1 # cmpsi_le
+   l.sfles \t%0,%1 # cmpsi_le"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsi_leu"
+  [(set (reg:CCLEU CC_REG)
+	(compare:CCLEU (match_operand:SI 0 "register_operand" "r,r")
+		       (match_operand:SI 1 "nonmemory_operand" "I,r")))]
+  ""
+  "@
+   l.sfleui\t%0,%1 # cmpsi_leu
+   l.sfleu \t%0,%1 # cmpsi_leu"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+;; Single precision floating point evaluation instructions
+(define_insn "*cmpsf_eq"
+  [(set (reg:CCEQ CC_REG)
+	(compare:CCEQ (match_operand:SF 0 "register_operand" "r,r")
+		      (match_operand:SF 1 "register_operand" "r,r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.sfeq.s\t%0,%1 # cmpsf_eq"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsf_ne"
+  [(set (reg:CCNE CC_REG)
+	(compare:CCNE (match_operand:SF 0 "register_operand" "r,r")
+		      (match_operand:SF 1 "register_operand" "r,r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.sfne.s\t%0,%1 # cmpsf_ne"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+
+(define_insn "*cmpsf_gt"
+  [(set (reg:CCGT CC_REG)
+	(compare:CCGT (match_operand:SF 0 "register_operand" "r,r")
+		      (match_operand:SF 1 "register_operand" "r,r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.sfgt.s\t%0,%1 # cmpsf_gt"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsf_ge"
+  [(set (reg:CCGE CC_REG)
+	(compare:CCGE (match_operand:SF 0 "register_operand" "r,r")
+		      (match_operand:SF 1 "register_operand" "r,r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.sfge.s\t%0,%1 # cmpsf_ge"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+
+(define_insn "*cmpsf_lt"
+  [(set (reg:CCLT CC_REG)
+	(compare:CCLT (match_operand:SF 0 "register_operand" "r,r")
+		      (match_operand:SF 1 "register_operand" "r,r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.sflt.s\t%0,%1 # cmpsf_lt"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*cmpsf_le"
+  [(set (reg:CCLE CC_REG)
+	(compare:CCLE (match_operand:SF 0 "register_operand" "r,r")
+		      (match_operand:SF 1 "register_operand" "r,r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.sfle.s\t%0,%1 # cmpsf_le"
+  [(set_attr "type" "compare")
+   (set_attr "length" "1")])
+
+(define_insn "*bf"
+  [(set (pc)
+	(if_then_else (match_operator 1 "comparison_operator"
+				      [(match_operand 2
+						      "cc_reg_operand" "")
+				       (const_int 0)])
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))]
+  ""
+  "*
+   return or1k_output_bf(operands);
+  "
+  [(set_attr "type" "branch")
+   (set_attr "length" "1")])
+
+;;
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;
+(define_insn_and_split "movdi"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r, r, m, r")
+	(match_operand:DI 1 "general_operand"      " r, m, r, n"))]
+  ""
+  "*
+    return or1k_output_move_double (operands);
+  "
+  "&& reload_completed && CONSTANT_P (operands[1])"
+  [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
+  "operands[2] = operand_subword (operands[0], 0, 0, DImode);
+   operands[3] = operand_subword (operands[1], 0, 0, DImode);
+   operands[4] = operand_subword (operands[0], 1, 0, DImode);
+   operands[5] = operand_subword (operands[1], 1, 0, DImode);"
+  [(set_attr "length" "2,2,2,3")])
+
+;; Moving double and single precision floating point values
+
+
+(define_insn "movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=r, r, m, r")
+	(match_operand:DF 1 "general_operand"      " r, m, r, i"))]
+  ""
+  "*
+    return or1k_output_move_double (operands);
+  "
+  [(set_attr "length" "2,2,2,3")])
+
+
+(define_insn "movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
+        (match_operand:SF 1 "general_operand"  "r,m,r"))]
+  ""
+  "@
+   l.ori   \t%0,%1,0\t # movsf
+   l.lwz   \t%0,%1\t # movsf
+   l.sw    \t%0,%1\t # movsf"
+  [(set_attr "type" "move,load,store")
+   (set_attr "length" "1,1,1")])
+
+
+;;
+;; extendqisi2
+;;
+
+(define_expand "extendqisi2"
+  [(use (match_operand:SI 0 "register_operand" ""))
+   (use (match_operand:QI 1 "nonimmediate_operand" ""))]
+  ""
+  "
+{
+  if (TARGET_MASK_SEXT)
+    emit_insn (gen_extendqisi2_sext(operands[0], operands[1]));
+  else {
+    if ( GET_CODE(operands[1]) == MEM ) {
+      emit_insn (gen_extendqisi2_no_sext_mem(operands[0], operands[1]));
+    }
+    else {
+      emit_insn (gen_extendqisi2_no_sext_reg(operands[0], operands[1]));
+    }
+ }
+ DONE;
+}")
+
+(define_insn "extendqisi2_sext"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_MASK_SEXT"
+  "@
+   l.extbs \t%0,%1\t # extendqisi2_has_signed_extend
+   l.lbs   \t%0,%1\t # extendqisi2_has_signed_extend"
+  [(set_attr "length" "1,1")
+   (set_attr "type" "extend,load")])
+
+(define_insn "extendqisi2_no_sext_mem"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+  "!TARGET_MASK_SEXT"
+  "l.lbs   \t%0,%1\t # extendqisi2_no_sext_mem"
+  [(set_attr "length" "1")
+   (set_attr "type" "load")])
+
+(define_expand "extendqisi2_no_sext_reg"
+  [(set (match_dup 2)
+	(ashift:SI (match_operand:QI 1 "register_operand" "")
+		   (const_int 24)))
+   (set (match_operand:SI 0 "register_operand" "")
+	(ashiftrt:SI (match_dup 2)
+		     (const_int 24)))]
+  "!TARGET_MASK_SEXT"
+  "
+{
+  operands[1] = gen_lowpart (SImode, operands[1]);
+  operands[2] = gen_reg_rtx (SImode); }")
+
+;;
+;; extendhisi2
+;;
+
+(define_expand "extendhisi2"
+  [(use (match_operand:SI 0 "register_operand" ""))
+   (use (match_operand:HI 1 "nonimmediate_operand" ""))]
+  ""
+  "
+{
+  if (TARGET_MASK_SEXT)
+    emit_insn (gen_extendhisi2_sext(operands[0], operands[1]));
+  else {
+    if ( GET_CODE(operands[1]) == MEM ) {
+      emit_insn (gen_extendhisi2_no_sext_mem(operands[0], operands[1]));
+    }
+    else {
+      emit_insn (gen_extendhisi2_no_sext_reg(operands[0], operands[1]));
+    }
+ }
+ DONE;
+}")
+
+(define_insn "extendhisi2_sext"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_MASK_SEXT"
+  "@
+   l.exths \t%0,%1\t # extendhisi2_has_signed_extend
+   l.lhs   \t%0,%1\t # extendhisi2_has_signed_extend"
+  [(set_attr "length" "1,1")
+   (set_attr "type" "extend,load")])
+
+(define_insn "extendhisi2_no_sext_mem"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+  "!TARGET_MASK_SEXT"
+  "l.lhs   \t%0,%1\t # extendhisi2_no_sext_mem"
+  [(set_attr "length" "1")
+   (set_attr "type" "load")])
+
+(define_expand "extendhisi2_no_sext_reg"
+  [(set (match_dup 2)
+	(ashift:SI (match_operand:HI 1 "register_operand" "")
+		   (const_int 16)))
+   (set (match_operand:SI 0 "register_operand" "")
+	(ashiftrt:SI (match_dup 2)
+		     (const_int 16)))]
+  "!TARGET_MASK_SEXT"
+  "
+{
+  operands[1] = gen_lowpart (SImode, operands[1]);
+  operands[2] = gen_reg_rtx (SImode); }")
+
+
+;;
+;; zero_extend<m><n>2
+;;
+
+(define_insn "zero_extendqisi2"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+  ""
+  "@
+   l.andi  \t%0,%1,0xff\t # zero_extendqisi2
+   l.lbz   \t%0,%1\t # zero_extendqisi2"
+  [(set_attr "type" "logic,load")
+   (set_attr "length" "1,1")])
+
+
+(define_insn "zero_extendhisi2"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+  ""
+  "@
+   l.andi  \t%0,%1,0xffff\t # zero_extendqisi2
+   l.lhz   \t%0,%1\t # zero_extendqisi2"
+  [(set_attr "type" "logic,load")
+   (set_attr "length" "1,1")])
+
+;;
+;; Shift/rotate operations
+;;
+
+(define_insn "ashlsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:SI 2 "nonmemory_operand" "r,L")))]
+  ""
+  "@
+   l.sll   \t%0,%1,%2 # ashlsi3
+   l.slli  \t%0,%1,%2 # ashlsi3"
+  [(set_attr "type" "shift,shift")
+   (set_attr "length" "1,1")])
+
+(define_insn "ashrsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:SI 2 "nonmemory_operand" "r,L")))]
+  ""
+  "@
+   l.sra   \t%0,%1,%2 # ashrsi3
+   l.srai  \t%0,%1,%2 # ashrsi3"
+  [(set_attr "type" "shift,shift")
+   (set_attr "length" "1,1")])
+
+(define_insn "lshrsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:SI 2 "nonmemory_operand" "r,L")))]
+  ""
+  "@
+   l.srl   \t%0,%1,%2 # lshrsi3
+   l.srli  \t%0,%1,%2 # lshrsi3"
+  [(set_attr "type" "shift,shift")
+   (set_attr "length" "1,1")])
+
+(define_insn "rotrsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:SI 2 "nonmemory_operand" "r,L")))]
+  "TARGET_MASK_ROR"
+  "@
+   l.ror   \t%0,%1,%2 # rotrsi3
+   l.rori  \t%0,%1,%2 # rotrsi3"
+  [(set_attr "type" "shift,shift")
+   (set_attr "length" "1,1")])
+
+;;
+;; Logical bitwise operations
+;;
+
+(define_insn "andsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(and:SI (match_operand:SI 1 "register_operand" "%r,r")
+		(match_operand:SI 2 "nonmemory_operand" "r,K")))]
+  ""
+  "@
+   l.and   \t%0,%1,%2 # andsi3
+   l.andi  \t%0,%1,%2 # andsi3"
+  [(set_attr "type" "logic,logic")
+   (set_attr "length" "1,1")])
+
+(define_insn "iorsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(ior:SI (match_operand:SI 1 "register_operand" "%r,r")
+		(match_operand:SI 2 "nonmemory_operand" "r,K")))]
+  ""
+  "@
+   l.or    \t%0,%1,%2 # iorsi3
+   l.ori   \t%0,%1,%2 # iorsi3"
+  [(set_attr "type" "logic,logic")
+   (set_attr "length" "1,1")])
+
+(define_insn "xorsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(xor:SI (match_operand:SI 1 "register_operand" "%r,r")
+		(match_operand:SI 2 "nonmemory_operand" "r,I")))]
+  ""
+  "@
+   l.xor   \t%0,%1,%2 # xorsi3
+   l.xori  \t%0,%1,%2 # xorsi3"
+  [(set_attr "type" "logic,logic")
+   (set_attr "length" "1,1")])
+
+(define_insn "one_cmplqi2"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+	(not:QI (match_operand:QI 1 "register_operand" "r")))]
+  ""
+  "l.xori  \t%0,%1,0x00ff # one_cmplqi2"
+  [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+(define_insn "one_cmplsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(not:SI (match_operand:SI 1 "register_operand" "r")))]
+  ""
+  "l.xori  \t%0,%1,0xffff # one_cmplsi2"
+  [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+;;
+;; Arithmetic operations 
+;;
+
+(define_insn "negsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
+  ""
+  "l.sub   \t%0,r0,%1 # negsi2"
+  [(set_attr "type" "add")
+   (set_attr "length" "1")])
+
+(define_insn "addsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(plus:SI (match_operand:SI 1 "register_operand" "%r,r")
+		 (match_operand:SI 2 "nonmemory_operand" "r,I")))]
+  ""
+  "@
+   l.add   \t%0,%1,%2 # addsi3
+   l.addi  \t%0,%1,%2 # addsi3"
+  [(set_attr "type" "add,add")
+   (set_attr "length" "1,1")])
+
+(define_insn "subsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(minus:SI (match_operand:SI 1 "register_operand" "r,r")
+		  (match_operand:SI 2 "nonmemory_operand" "r,I")))]
+  ""
+  "@
+   l.sub   \t%0,%1,%2 # subsi3
+   l.addi  \t%0,%1,%n2 # subsi3"
+  [(set_attr "type" "add,add")]
+)
+
+;;
+;; mul and div
+;;
+
+(define_insn "mulsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (mult:SI (match_operand:SI 1 "register_operand" "r")
+                 (match_operand:SI 2 "register_operand" "r")))]
+  "TARGET_HARD_MUL"
+  "l.mul   \t%0,%1,%2 # mulsi3"
+  [(set_attr "type" "mul")
+   (set_attr "length" "1")])
+
+(define_insn "divsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (div:SI (match_operand:SI 1 "register_operand" "r")
+                 (match_operand:SI 2 "register_operand" "r")))]
+  "TARGET_HARD_DIV"
+  "l.div   \t%0,%1,%2 # divsi3"
+  [(set_attr "type" "mul")
+   (set_attr "length" "1")])
+
+(define_insn "udivsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (udiv:SI (match_operand:SI 1 "register_operand" "r")
+                 (match_operand:SI 2 "register_operand" "r")))]
+  "TARGET_HARD_DIV"
+  "l.divu  \t%0,%1,%2 # udivsi3"
+  [(set_attr "type" "mul")
+   (set_attr "length" "1")])
+
+;;
+;; jumps 
+;;
+
+;; jump
+
+(define_expand "jump"
+  [(set (pc)
+	(label_ref (match_operand 0 "" "")))]
+  ""
+  "
+{
+  emit_jump_insn (gen_jump_internal (operands[0]));
+  DONE;
+}")
+
+(define_insn "jump_internal"
+  [(set (pc)
+	(label_ref (match_operand 0 "" "")))]
+  ""
+  "l.j     \t%l0 # jump_internal%("
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+;; indirect jump
+
+(define_expand "indirect_jump"
+  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
+  ""
+  "
+{
+  emit_jump_insn (gen_indirect_jump_internal (operands[0]));
+  DONE;
+
+}")
+
+(define_insn "indirect_jump_internal"
+  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
+  ""
+  "l.jr    \t%0 # indirect_jump_internal%("
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+;;
+;; calls
+;;
+
+;; call
+
+(define_expand "call"
+  [(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "")
+		    (match_operand 1 "" "i"))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  "
+{
+  emit_call_insn (gen_call_internal (operands[0], operands[1]));
+  DONE;
+}")
+
+(define_insn "call_internal"
+[(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "")
+                  (match_operand 1 "" "i"))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  {
+    if (flag_pic)
+      {
+	crtl->uses_pic_offset_table = 1;
+	return "l.jal   \tplt(%S0)# call_internal%(";
+      }
+
+    return "l.jal   \t%S0# call_internal%(";
+  }
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+;; call value
+
+(define_expand "call_value"
+  [(parallel [(set (match_operand 0 "register_operand" "=r")
+		   (call (match_operand:SI 1 "sym_ref_mem_operand" "")
+			 (match_operand 2 "" "i")))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  "
+{
+  emit_call_insn (gen_call_value_internal (operands[0], operands[1], operands[2]));
+  DONE;
+}")
+
+(define_insn "call_value_internal"
+[(parallel [(set (match_operand 0 "register_operand" "=r")
+                  (call (match_operand:SI 1 "sym_ref_mem_operand" "")
+                        (match_operand 2 "" "i")))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  {
+    if (flag_pic)
+      {
+	crtl->uses_pic_offset_table = 1;
+	return "l.jal   \tplt(%S1) # call_value_internal%(";
+      }
+    return "l.jal   \t%S1 # call_value_internal%(";
+  }
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+;; indirect call value 
+
+(define_expand "call_value_indirect"
+  [(parallel [(set (match_operand 0 "register_operand" "=r")
+                   (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
+                         (match_operand 2 "" "i")))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  "
+{
+  emit_call_insn (gen_call_value_indirect_internal (operands[0], operands[1], operands[2]));
+  DONE;
+}")
+
+(define_insn "call_value_indirect_internal"
+  [(parallel [(set (match_operand 0 "register_operand" "=r")
+                   (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
+                         (match_operand 2 "" "i")))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  "l.jalr  \t%1 # call_value_indirect_internal%("
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+;; indirect call
+
+(define_expand "call_indirect"
+  [(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
+		    (match_operand 1 "" "i"))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  "
+{
+  emit_call_insn (gen_call_indirect_internal (operands[0], operands[1]));
+  DONE;
+}")
+
+(define_insn "call_indirect_internal"
+[(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
+                  (match_operand 1 "" "i"))
+            (clobber (reg:SI 9))
+            (use (reg:SI 16))])]
+  ""
+  "l.jalr  \t%0 # call_indirect_internal%("
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+;; table jump
+
+(define_expand "tablejump"
+  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+   (use (label_ref (match_operand 1 "" "")))]
+   ""
+  "
+{
+  if (CASE_VECTOR_PC_RELATIVE || flag_pic)
+    operands[0]
+      = force_reg (Pmode,
+		   gen_rtx_PLUS (Pmode, operands[0],
+				 gen_rtx_LABEL_REF (Pmode, operands[1])));
+  emit_jump_insn (gen_tablejump_internal (operands[0], operands[1]));
+  DONE;
+}")
+
+(define_insn "tablejump_internal"
+  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+   (use (label_ref (match_operand 1 "" "")))]
+  ""
+  "l.jr    \t%0 # tablejump_internal%("
+  [(set_attr "type" "jump")
+   (set_attr "length" "1")])
+
+
+;; no-op
+
+(define_insn "nop"
+  [(const_int 0)]
+  ""
+  "l.nop"
+  [(set_attr "type" "logic")
+   (set_attr "length" "1")])
+
+;;
+;; floating point
+;;
+
+;; floating point arithmetic 
+
+(define_insn "addsf3"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+        (plus:SF (match_operand:SF 1 "register_operand" "r")
+                 (match_operand:SF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.add.s\t%0,%1,%2 # addsf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+   
+(define_insn "adddf3"
+  [(set (match_operand:DF 0 "register_operand" "=r")
+        (plus:DF (match_operand:DF 1 "register_operand" "r")
+                 (match_operand:DF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "lf.add.d\t%0,%1,%2 # adddf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+
+(define_insn "subsf3"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+        (minus:SF (match_operand:SF 1 "register_operand" "r")
+                 (match_operand:SF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.sub.s\t%0,%1,%2 # subsf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+
+(define_insn "subdf3"
+  [(set (match_operand:DF 0 "register_operand" "=r")
+        (minus:DF (match_operand:DF 1 "register_operand" "r")
+		  (match_operand:DF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "lf.sub.d\t%0,%1,%2 # subdf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+
+(define_insn "mulsf3"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+        (mult:SF (match_operand:SF 1 "register_operand" "r")
+                 (match_operand:SF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.mul.s\t%0,%1,%2 # mulsf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+
+(define_insn "muldf3"
+  [(set (match_operand:DF 0 "register_operand" "=r")
+        (mult:DF (match_operand:DF 1 "register_operand" "r")
+                 (match_operand:DF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "lf.mul.d\t%0,%1,%2 # muldf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+
+(define_insn "divsf3"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+        (div:SF (match_operand:SF 1 "register_operand" "r")
+		(match_operand:SF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.div.s\t%0,%1,%2 # divsf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+
+(define_insn "divdf3"
+  [(set (match_operand:DF 0 "register_operand" "=r")
+        (div:DF (match_operand:DF 1 "register_operand" "r")
+		(match_operand:DF 2 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "lf.div.d\t%0,%1,%2 # divdf3"
+  [(set_attr "type"     "fp")
+   (set_attr "length"   "1")])
+
+;; Conversion between fixed point and floating point.
+
+
+(define_insn "floatsisf2"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+	(float:SF (match_operand:SI 1 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.itof.s\t%0, %1 # floatsisf2"
+  [(set_attr "type" "fp")
+   (set_attr "length" "1")])
+
+;; not working 
+(define_insn "fixunssfsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(fix:SI (match_operand:SF 1 "register_operand" "r")))]
+  "TARGET_HARD_FLOAT"
+  "lf.ftoi.s\t%0, %1 # fixunssfsi2"
+  [(set_attr "type" "fp")
+   (set_attr "length" "1")])
+
+;; The insn to set GOT.
+;; TODO: support for no-delay target
+(define_insn "set_got"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
+   (clobber (reg:SI 9))
+   (clobber (reg:SI 16))]
+  ""
+  "l.jal    \t8
+ \tl.movhi  \tr16,gotpchi(_GLOBAL_OFFSET_TABLE_-4)
+ \tl.ori    \tr16,r16,gotpclo(_GLOBAL_OFFSET_TABLE_+0)
+ \tl.add    \tr16,r16,r9"
+  [(set_attr "length" "16")])
+
+(define_expand "atomic_compare_and_swap<mode>"
+  [(match_operand:SI 0 "register_operand")   ;; bool output
+   (match_operand:AI 1 "register_operand")   ;; val output
+   (match_operand:AI 2 "memory_operand")     ;; memory
+   (match_operand:AI 3 "register_operand")   ;; expected
+   (match_operand:AI 4 "register_operand")   ;; desired
+   (match_operand:SI 5 "const_int_operand")  ;; is_weak
+   (match_operand:SI 6 "const_int_operand")  ;; mod_s
+   (match_operand:SI 7 "const_int_operand")] ;; mod_f
+  ""
+{
+  if (<MODE>mode == SImode)
+    emit_insn (gen_cmpxchg (operands[0], operands[1], operands[2], operands[3],
+                            operands[4]));
+  else
+    or1k_expand_cmpxchg_qihi (operands[0], operands[1], operands[2],
+                              operands[3], operands[4], INTVAL (operands[5]),
+                              (enum memmodel) INTVAL (operands[6]),
+                              (enum memmodel) INTVAL (operands[7]));
+  DONE;
+})
+
+(define_insn "cmpxchg"
+   [(set (match_operand:SI 0 "register_operand" "=&r")
+         (unspec_volatile:SI [(match_operand:SI 2 "memory_operand" "+m")]
+          UNSPEC_CMPXCHG))
+    (set (match_dup 2)
+         (unspec_volatile:SI [(match_operand:SI 3 "register_operand" "r")]
+          UNSPEC_CMPXCHG))
+    (set (match_operand:SI 1 "register_operand" "=&r")
+         (unspec_volatile:SI [(match_dup 2) (match_dup 3)
+                             (match_operand:SI 4 "register_operand" "r")]
+          UNSPEC_CMPXCHG))]
+  ""
+  "
+   l.lwa   \t%1,%2   # cmpxchg: load
+   l.sfeq  \t%1,%3   # cmpxchg: cmp
+   l.bnf   \t1f      # cmpxchg: not expected
+    l.ori  \t%0,r0,0 # cmpxchg: result = 0
+   l.swa   \t%2,%4   # cmpxchg: store new
+   l.bnf   \t1f      # cmpxchg: done
+    l.nop
+   l.ori   \t%0,r0,1 # cmpxchg: result = 1
+1:")
+
+(define_insn "cmpxchg_mask"
+   [(set (match_operand:SI 0 "register_operand" "=&r")
+         (unspec_volatile:SI [(match_operand:SI 2 "memory_operand" "+m")]
+          UNSPEC_CMPXCHG))
+    (set (match_dup 2)
+         (unspec_volatile:SI [(match_operand:SI 3 "register_operand" "r")]
+          UNSPEC_CMPXCHG))
+    (set (match_operand:SI 1 "register_operand" "=&r")
+         (unspec_volatile:SI [(match_dup 2) (match_dup 3)
+                             (match_operand:SI 4 "register_operand" "r")
+                             (match_operand:SI 5 "register_operand" "r")]
+          UNSPEC_CMPXCHG))
+   (clobber (match_scratch:SI 6 "=&r"))]
+  ""
+  "
+   l.lwa   \t%6,%2    # cmpxchg: load
+   l.and   \t%1,%6,%5 # cmpxchg: mask old
+   l.and   \t%4,%4,%5 # cmpxchg: mask set
+   l.sfeq  \t%1,%3    # cmpxchg: cmp
+   l.bnf   \t1f       # cmpxchg: not expected
+    l.ori  \t%0,r0,0  # cmpxchg: result = 0
+   l.xor   \t%6,%6,%1 # cmpxchg: clear
+   l.or    \t%6,%6,%4 # cmpxchg: set
+   l.swa   \t%2,%6    # cmpxchg: store new
+   l.bnf   \t1f       # cmpxchg: done
+    l.nop
+   l.ori   \t%0,r0,1  # cmpxchg: result = 1
+1:
+  ")
+
+(define_expand "atomic_fetch_<op_name><mode>"
+  [(match_operand:AI 0 "register_operand")
+   (match_operand:AI 1 "memory_operand")
+   (match_operand:AI 2 "register_operand")
+   (match_operand:SI 3 "const_int_operand")
+   (atomic_op:AI (match_dup 0) (match_dup 1))]
+  ""
+{
+  rtx ret = gen_reg_rtx (<MODE>mode);
+  if (<MODE>mode != SImode)
+    or1k_expand_fetch_op_qihi (operands[0], operands[1], operands[2], ret,
+                               gen_fetch_and_<op_name>_mask);
+  else
+    emit_insn (gen_fetch_and_<op_name> (operands[0], operands[1], operands[2],
+                                        ret));
+  DONE;
+})
+
+(define_expand "atomic_<op_name>_fetch<mode>"
+  [(match_operand:AI 0 "register_operand")
+   (match_operand:AI 1 "memory_operand")
+   (match_operand:AI 2 "register_operand")
+   (match_operand:SI 3 "const_int_operand")
+   (atomic_op:AI (match_dup 0) (match_dup 1))]
+  ""
+{
+  rtx ret = gen_reg_rtx (<MODE>mode);
+  if (<MODE>mode != SImode)
+    or1k_expand_fetch_op_qihi (ret, operands[1], operands[2], operands[0],
+                               gen_fetch_and_<op_name>_mask);
+  else
+    emit_insn (gen_fetch_and_<op_name> (ret, operands[1], operands[2],
+                                        operands[0]));
+  DONE;
+})
+
+(define_insn "fetch_and_<op_name>"
+  [(set (match_operand:SI 0 "register_operand" "=&r")
+        (match_operand:SI 1 "memory_operand" "+m"))
+   (set (match_operand:SI 3 "register_operand" "=&r")
+        (unspec_volatile:SI [(match_dup 1)
+                             (match_operand:SI 2 "register_operand" "r")]
+         UNSPEC_FETCH_AND_OP))
+   (set (match_dup 1)
+        (match_dup 3))
+   (atomic_op:SI (match_dup 0) (match_dup 1))]
+  ""
+  "
+1:
+   l.lwa   \t%0,%1  # fetch_<op_name>: load
+   l.<op_insn>\t\t%3,%0,%2 # fetch_<op_name>: logic
+   <post_op_insn>
+   l.swa   \t%1,%3  # fetch_<op_name>: store new
+   l.bnf   \t1b     # fetch_<op_name>: done
+    l.nop
+  ")
+
+(define_insn "fetch_and_<op_name>_mask"
+  [(set (match_operand:SI 0 "register_operand" "=&r")
+        (match_operand:SI 1 "memory_operand" "+m"))
+   (set (match_operand:SI 3 "register_operand" "=&r")
+        (unspec_volatile:SI [(match_dup 1)
+                             (match_operand:SI 2 "register_operand" "r")
+                             (match_operand:SI 4 "register_operand" "r")]
+         UNSPEC_FETCH_AND_OP))
+   (set (match_dup 1)
+        (unspec_volatile:SI [(match_dup 3) (match_dup 4)] UNSPEC_FETCH_AND_OP))
+   (clobber (match_scratch:SI 5 "=&r"))
+   (atomic_op:SI (match_dup 0) (match_dup 1))]
+  ""
+  "
+1:
+   l.lwa   \t%0,%1    # fetch_<op_name>: load
+   l.and   \t%5,%0,%4 # fetch_<op_name>: mask
+   l.xor   \t%5,%0,%5 # fetch_<op_name>: clear
+   l.<op_insn>\t\t%3,%0,%2 # fetch_<op_name>: logic
+   <post_op_insn>
+   l.and   \t%3,%3,%4 # fetch_<op_name>: mask result
+   l.or    \t%3,%5,%3 # fetch_<op_name>: set
+   l.swa   \t%1,%3    # fetch_<op_name>: store new
+   l.bnf   \t1b       # fetch_<op_name>: done
+    l.nop
+  ")
+
+;; Local variables:
+;; mode:emacs-lisp
+;; comment-start: ";; "
+;; eval: (set-syntax-table (copy-sequence (syntax-table)))
+;; eval: (modify-syntax-entry ?[ "(]")
+;; eval: (modify-syntax-entry ?] ")[")
+;; eval: (modify-syntax-entry ?{ "(}")
+;; eval: (modify-syntax-entry ?} "){")
+;; eval: (setq indent-tabs-mode t)
+;; End:
diff --git a/gcc/config/or1k/or1k.opt b/gcc/config/or1k/or1k.opt
new file mode 100644
index 0000000..019d923
--- /dev/null
+++ b/gcc/config/or1k/or1k.opt
@@ -0,0 +1,96 @@
+; Options for the OR1K port of the compiler
+; This file is part of GCC.
+;
+; Copyright (C) 2010 Embecosm Limited
+;
+; 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.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+HeaderInclude
+config/or1k/or1k-opts.h
+
+Variable
+enum or1k_delay or1k_delay_selected = OR1K_DELAY_DEFAULT
+
+mdelay
+Target RejectNegative Negative(mno-delay) Var(or1k_delay_selected, OR1K_DELAY_ON)
+Assume branches and jumps have a delay slot
+
+mno-delay
+Target RejectNegative Negative(mcompat-delay) Var(or1k_delay_selected, OR1K_DELAY_OFF)
+Assume branches and jumps do not have a delay slot
+
+mcompat-delay
+Target RejectNegative Negative(mdelay) Var(or1k_delay_selected, OR1K_DELAY_COMPAT)
+Assume branches and jumps have a delay slot, but fill them with nops
+
+mhard-float
+Target RejectNegative Mask(HARD_FLOAT)
+Use hardware floating point
+
+msoft-float
+Target RejectNegative InverseMask(HARD_FLOAT)
+Do not use hardware floating point
+
+mdouble-float
+Target Report RejectNegative Mask(DOUBLE_FLOAT)
+Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations
+
+mhard-div
+Target RejectNegative Mask(HARD_DIV)
+Use hardware division
+
+msoft-div
+Target RejectNegative InverseMask(HARD_DIV)
+Do not use hardware division
+
+mhard-mul
+Target RejectNegative Mask(HARD_MUL)
+Use hardware multiplication
+
+msoft-mul
+Target RejectNegative InverseMask(HARD_MUL)
+Do not use hardware multiplication
+
+msext
+Target Mask(MASK_SEXT)
+Use sign-extending instructions
+
+mcmov
+Target Mask(MASK_CMOV)
+Use conditional move instructions
+
+mror
+Target Mask(MASK_ROR)
+Emit ROR instructions
+
+mboard=
+Target RejectNegative Joined
+Link with libgloss configuration suitable for this board
+
+mnewlib
+Target Report RejectNegative
+Compile for the Linux/Gnu/newlib based toolchain
+
+;; provide struct padding as in previous releases.
+;; Note that this will only affect STRUCTURE_SIZE_BOUNDARY, in particular
+;; make 2 byte structs 4-byte alignned and sized.
+;; We still use ROUND_TYPE_ALIGN to increase alignment of larger structs.
+mpadstruct
+Target Report RejectNegative Mask(PADSTRUCT)
+Make structs a multiple of 4 bytes (warning: ABI altered)
+
+mredzone=
+Target RejectNegative Joined UInteger Var(or1k_redzone) Init(128)
+Set the size of the stack below sp that is assumed to be safe from interrupts.
diff --git a/gcc/config/or1k/predicates.md b/gcc/config/or1k/predicates.md
new file mode 100644
index 0000000..48a9065
--- /dev/null
+++ b/gcc/config/or1k/predicates.md
@@ -0,0 +1,121 @@
+;; Predicate definitions for OR32
+;;
+;; Copyright (C) 2010 Embecosm Limited
+;;
+;; 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_predicate "cc_reg_operand"
+  (match_code "subreg,reg")
+{
+  register_operand (op, mode);
+
+  if (GET_CODE (op) == REG && REGNO (op) == CC_REG)
+    return 1;
+
+  return 0;
+})
+
+(define_predicate "input_operand"
+  (match_code "subreg,reg,const_int,mem,const")
+{
+  /* If both modes are non-void they must be the same.  */
+  if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
+    return 0;
+
+  /* Allow any one instruction integer constant, and all CONST_INT
+     variants when we are working in DImode and !arch64.  */
+  if (GET_MODE_CLASS (mode) == MODE_INT
+      && ((GET_CODE (op) == CONST_INT)
+	  && (satisfies_constraint_K (op)
+	      || satisfies_constraint_M (op)
+	      || satisfies_constraint_I (op))))
+    return 1;
+
+  if (register_operand (op, mode))
+    return 1;
+
+  /* If this is a SUBREG, look inside so that we handle
+     paradoxical ones.  */
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+
+  /* Check for valid MEM forms.  */
+  if (GET_CODE (op) == MEM)
+    return memory_address_p (mode, XEXP (op, 0));
+
+  return 0;
+})
+
+(define_predicate "sym_ref_mem_operand"
+  (match_code "mem")
+{
+  if (GET_CODE (op) == MEM)
+    {
+      rtx t1 = XEXP (op, 0);
+      if (GET_CODE (t1) == SYMBOL_REF)
+	return 1;
+    }
+  return 0;
+})
+
+;; True iff OP is a symbolic operand.
+
+(define_predicate "symbolic_operand"
+  (match_code "symbol_ref,label_ref,const")
+{
+  switch (GET_CODE (op))
+    {
+    case SYMBOL_REF:
+      return !SYMBOL_REF_TLS_MODEL (op);
+    case LABEL_REF:
+      return true;
+    case CONST:
+      op = XEXP (op, 0);
+      return (GET_CODE (op) == PLUS
+	      && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+		   && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
+		  || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+	      && GET_CODE (XEXP (op, 1)) == CONST_INT);
+    default:
+      break;
+    }
+  return false;
+})
+
+;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
+(define_predicate "tgd_symbolic_operand"
+  (and (match_code "symbol_ref")
+       (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
+
+;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
+
+(define_predicate "tld_symbolic_operand"
+  (and (match_code "symbol_ref")
+       (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
+
+;; Return true if OP is a symbolic operand for the TLS Initial Exec model.
+
+(define_predicate "tie_symbolic_operand"
+  (and (match_code "symbol_ref")
+       (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")))
+
+;; Return true if OP is a symbolic operand for the TLS Local Exec model.
+
+(define_predicate "tle_symbolic_operand"
+  (and (match_code "symbol_ref")
+       (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
diff --git a/gcc/config/or1k/rtems.h b/gcc/config/or1k/rtems.h
new file mode 100644
index 0000000..cfe83b4
--- /dev/null
+++ b/gcc/config/or1k/rtems.h
@@ -0,0 +1,30 @@
+/* Definitions for rtems targeting an OpenRISC OR1K using ELF.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Contributed by Joel Sherrill (joel.sherrill@OARcorp.com).
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* Target OS builtins.  */
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS()		\
+  do						\
+    {						\
+	builtin_define ("__rtems__");		\
+	builtin_define ("__USE_INIT_FINI__");	\
+	builtin_assert ("system=rtems");	\
+    }						\
+  while (0)
diff --git a/gcc/config/or1k/t-linux b/gcc/config/or1k/t-linux
new file mode 100644
index 0000000..3f9a944
--- /dev/null
+++ b/gcc/config/or1k/t-linux
@@ -0,0 +1,12 @@
+MULTILIB_DIRNAMES =
+EXTRA_MULTILIB_PARTS = crti.o crtbegin.o crtend.o crtn.o
+
+# hack:
+# the non-shared uclibc-0.9.31/libc/misc/internals/__uClibc_main.c
+# already defines __dso_handle.  To avoid a duplicate definition,
+# we rename the crtbegin one.
+# JPB 18-Nov-10: Commented out, since uClibc no longer defines.
+# amend gcc Makefile CLFAGS variable
+# $(T)crtbegin.o: CRTSTUFF_CFLAGS += '-D__dso_handle=__dso_handle_dummy'
+# amend libgcc Makefile CLFAGS variable
+# crtbegin$(objext): CRTSTUFF_T_CFLAGS += '-D__dso_handle=__dso_handle_dummy'
diff --git a/gcc/config/or1k/t-or1k b/gcc/config/or1k/t-or1k
new file mode 100644
index 0000000..81a4690
--- /dev/null
+++ b/gcc/config/or1k/t-or1k
@@ -0,0 +1,28 @@
+# t-or1k is a Makefile fragment to be included when
+#           building gcc for the or1k target
+
+# Copyright (C) 2010 Embecosm Limited
+
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# we don't support -g so don't use it
+LIBGCC2_DEBUG_CFLAGS =
+
+# Build the libraries for both hard and soft floating point
+MULTILIB_OPTIONS = mno-delay/mcompat-delay msoft-float
+MULTILIB_DIRNAMES = no-delay compat-delay soft-float
+MULTILIB_MATCHES =
diff --git a/gcc/config/or1k/t-or1knd b/gcc/config/or1k/t-or1knd
new file mode 100644
index 0000000..6b84fa8
--- /dev/null
+++ b/gcc/config/or1k/t-or1knd
@@ -0,0 +1,28 @@
+# t-or1knd is a Makefile fragment to be included when
+#           building gcc for the or1k target
+
+# Copyright (C) 2010 Embecosm Limited
+
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# we don't support -g so don't use it
+LIBGCC2_DEBUG_CFLAGS =
+
+# Build the libraries for both hard and soft floating point
+MULTILIB_OPTIONS = mdelay/mcompat-delay msoft-float
+MULTILIB_DIRNAMES = delay compat-delay soft-float
+MULTILIB_MATCHES =
diff --git a/gcc/config/or1k/t-rtems b/gcc/config/or1k/t-rtems
new file mode 100644
index 0000000..e4e5e1d
--- /dev/null
+++ b/gcc/config/or1k/t-rtems
@@ -0,0 +1,3 @@
+# RTEMS OR1K multilibs
+
+# No custom multilibs defined
diff --git a/gcc/config/uclibc-stdint.h b/gcc/config/uclibc-stdint.h
new file mode 100644
index 0000000..cb345c1
--- /dev/null
+++ b/gcc/config/uclibc-stdint.h
@@ -0,0 +1,70 @@
+/* Definitions for <stdint.h> types on systems using uClibc.
+   Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#define SIG_ATOMIC_TYPE "int"
+
+/* The newlib logic actually checks for sizes greater than 32 rather
+   than equal to 64 for various 64-bit types.  */
+
+#define INT8_TYPE (CHAR_TYPE_SIZE == 8 ? "signed char" : 0)
+#define INT16_TYPE (SHORT_TYPE_SIZE == 16 ? "short int" : 0)
+#define INT32_TYPE (INT_TYPE_SIZE == 32 ? "int" : 0)
+#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : LONG_LONG_TYPE_SIZE == 64 ? "long long int" : 0)
+#define UINT8_TYPE (CHAR_TYPE_SIZE == 8 ? "unsigned char" : 0)
+/* uclibc-0.9.31/include/stdint.h has the 'unsigned' keyword first,
+   but GCC needs the length keyword first.  */
+#define UINT16_TYPE (SHORT_TYPE_SIZE == 16 ? "short unsigned int" : 0)
+#define UINT32_TYPE (INT_TYPE_SIZE == 32 ? "unsigned int" : 0)
+#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : LONG_LONG_TYPE_SIZE == 64 ? "long long unsigned int" : 0)
+
+#define INT_LEAST8_TYPE (INT8_TYPE ? INT8_TYPE : INT16_TYPE ? INT16_TYPE : INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0)
+#define INT_LEAST16_TYPE (INT16_TYPE ? INT16_TYPE : INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0)
+#define INT_LEAST32_TYPE (INT32_TYPE ? INT32_TYPE : INT64_TYPE ? INT64_TYPE : 0)
+#define INT_LEAST64_TYPE INT64_TYPE
+#define UINT_LEAST8_TYPE (UINT8_TYPE ? UINT8_TYPE : UINT16_TYPE ? UINT16_TYPE : UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0)
+#define UINT_LEAST16_TYPE (UINT16_TYPE ? UINT16_TYPE : UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0)
+#define UINT_LEAST32_TYPE (UINT32_TYPE ? UINT32_TYPE : UINT64_TYPE ? UINT64_TYPE : 0)
+#define UINT_LEAST64_TYPE UINT64_TYPE
+
+#define INT_FAST8_TYPE INT8_TYPE
+#define UINT_FAST8_TYPE UINT8_TYPE
+
+#if LONG_TYPE_SIZE == 64
+#define INT_FAST16_TYPE "long int"
+#define INT_FAST32_TYPE "long int"
+#define INT_FAST64_TYPE "long int"
+#define UINT_FAST16_TYPE "long unsigned int"
+#define UINT_FAST32_TYPE "long unsigned int"
+#define UINT_FAST64_TYPE "long unsigned int"
+#else
+#define INT_FAST16_TYPE "int"
+#define INT_FAST32_TYPE "int"
+#define INT_FAST64_TYPE "long long int"
+#define UINT_FAST16_TYPE "unsigned int"
+#define UINT_FAST32_TYPE "unsigned int"
+#define UINT_FAST64_TYPE "long long unsigned int"
+#endif
+
+#if LONG_TYPE_SIZE == 64
+#define INTPTR_TYPE "long int"
+#define UINTPTR_TYPE "long unsigned int"
+#else
+#define INTPTR_TYPE "int"
+#define UINTPTR_TYPE "unsigned int"
+#endif
diff --git a/gcc/configure b/gcc/configure
index 90f78d2..3b29029 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -4835,6 +4835,9 @@ case "${target}" in
     mips-sgi-irix6*)
 	# PIC is the default.
 	;;
+    or1k-*-*)
+	PICFLAG_FOR_TARGET=-fPIC
+        ;;
     rs6000-ibm-aix* | powerpc-ibm-aix*)
 	# All AIX code is PIC.
 	;;
@@ -23670,6 +23673,20 @@ foo:	.long	25
 	tls_first_minor=20
 	tls_as_opt='--fatal-warnings'
 	;;
+  or1k*-*-*)
+    conftest_s='
+	.section ".tdata","awT",%progbits
+foo:	.long	25
+	.text
+	l.movhi         r3,tlsgdhi(foo)
+	l.ori           r3,r3,tlsgdlo(foo)
+
+	l.jal           __tls_get_addr
+	 l.nop'
+	tls_first_major=2
+	tls_first_minor=23
+	tls_as_opt='--fatal-warnings'
+	;;
   powerpc-ibm-aix*)
     conftest_s='
 	.extern __get_tpointer
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 0009d87..71fe1d1 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3190,6 +3190,20 @@ foo:	.long	25
 	tls_first_minor=20
 	tls_as_opt='--fatal-warnings'
 	;;
+  or1k*-*-*)
+    conftest_s='
+	.section ".tdata","awT",%progbits
+foo:	.long	25
+	.text
+	l.movhi         r3,tlsgdhi(foo)
+	l.ori           r3,r3,tlsgdlo(foo)
+
+	l.jal           __tls_get_addr
+	 l.nop'
+	tls_first_major=2
+	tls_first_minor=23
+	tls_as_opt='--fatal-warnings'
+	;;
   powerpc-ibm-aix*)
     conftest_s='
 	.extern __get_tpointer
diff --git a/gcc/testsuite/g++.dg/ext/strncpy-chk1.C b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C
index ebafc99..34a5df0 100644
--- a/gcc/testsuite/g++.dg/ext/strncpy-chk1.C
+++ b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C
@@ -3,13 +3,13 @@
 // { dg-options "-O2" }
 // { dg-skip-if "packed attribute missing for struct A" { "epiphany-*-*" } { "*" } { "" } }
 
-struct A { char x[12], y[35]; };
+struct A { char x[12], y[35]; }; // change to y[32] to get warning on or1k
 struct B { char z[50]; };
 
 inline void
 foo (char *dest, const char *__restrict src, __SIZE_TYPE__ n)
 {
-  __builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0));	// { dg-warning "will always overflow" }
+  __builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0));	// { dg-warning "will always overflow" "" { target { ! or1k*-*-* } } }
 }
 
 void bar (const char *, int);
diff --git a/gcc/testsuite/g++.dg/init/pr25811.C b/gcc/testsuite/g++.dg/init/pr25811.C
index c29f406..8e01c4c 100644
--- a/gcc/testsuite/g++.dg/init/pr25811.C
+++ b/gcc/testsuite/g++.dg/init/pr25811.C
@@ -1,6 +1,59 @@
 // PR c++/25811
 // { dg-do compile }
 
+struct A1
+{
+  int const j; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct A2
+{
+  int const volatile i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct A3
+{
+  int& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct A4
+{
+  int const& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct A5
+{
+  int& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+  int const i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+template <class T> struct S1
+{
+  T const i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+template <class T> struct S2
+{
+  T const volatile i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+template <class T> struct S3
+{
+  T& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+template <class T> struct S4
+{
+  T const i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+  T& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct X
+{
+  X () : c (0), r (c) {}
+  int const c;// PR c++/25811
+// { dg-do compile }
+
 struct A1 // { dg-message "implicitly deleted" "" { target c++11 } }
           // { dg-error "uninitialized" "" { target c++11 } 4 }
 {
@@ -209,3 +262,145 @@ void f16 ()
 {
   new U; // { dg-error "deleted|uninitialized const member" }
 }
+
+  int const& r;
+};
+
+struct Y11
+{
+  int const i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct Y1
+{
+  Y11 a[1];
+};
+
+struct Y22
+{
+  int& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct Y2
+{
+  Y22 a[1];
+};
+
+struct Z1
+{
+  int const i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct Z2
+{
+  int& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct Z3
+{
+  int const i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct Z4
+{
+  int& ref; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+struct Z5
+{
+  int i;
+};
+
+struct Z
+{
+  Z1 z1;
+  Z2 z2;
+  Z3 z3;
+  Z4 z4;
+  Z5 z5;
+};
+
+union U
+{
+  int const i; // { dg-message "should be initialized" "" { target { ! c++11 } } }
+};
+
+void f1 ()
+{
+  new A1; // { dg-error "deleted|uninitialized const member" }
+}
+
+void f2 ()
+{
+  new A2; // { dg-error "deleted|uninitialized const member" }
+}
+
+void f3 ()
+{
+  new A3; // { dg-error "deleted|uninitialized reference member" }
+}
+
+void f4 ()
+{
+  new A4; // { dg-error "deleted|uninitialized reference member" }
+}
+
+void f5 ()
+{
+  new A5; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
+}
+
+void f6 ()
+{
+  new S1<int>; // { dg-error "deleted|uninitialized const member" }
+}
+
+void f7 ()
+{
+  new S2<int>; // { dg-error "deleted|uninitialized const member" }
+}
+
+void f8 ()
+{
+  new S3<int>; // { dg-error "deleted|uninitialized reference member" }
+}
+
+void f9 ()
+{
+  new S4<int>; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
+}
+
+void f10 ()
+{
+  new X;
+}
+
+void f11 ()
+{
+  new A1[1]; // { dg-error "deleted|uninitialized const member" }
+}
+
+void f12 ()
+{
+  new A3[1]; // { dg-error "deleted|uninitialized reference member" }
+}
+
+void f13 ()
+{
+  new Y1; // { dg-error "deleted|uninitialized const member" }
+}
+
+void f14 ()
+{
+  new Y2; // { dg-error "deleted|uninitialized reference member" }
+}
+
+void f15 ()
+{
+  new Z; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
+}
+
+void f16 ()
+{
+  new U; // { dg-error "deleted|uninitialized const member" }
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c
index 28b5540..b605422 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c
@@ -38,6 +38,12 @@
   /* Epiphany does not have hardware division, and the software implementation
      has truly undefined behaviour for division by 0.  */
 # define DO_TEST 0
+#elif defined (__or1k__)
+  /* There is no strict behavior requirement for integer divide by zero
+     on OpenRISC 1000. The bare metal implementation ignores it, so we
+     will disable this test for now.
+  */
+# define DO_TEST 0
 #elif defined (__m68k__) && !defined(__linux__)
   /* Attempting to trap division-by-zero in this way isn't likely to work on 
      bare-metal m68k systems.  */
diff --git a/gcc/testsuite/gcc.dg/20020312-2.c b/gcc/testsuite/gcc.dg/20020312-2.c
index 71201fe..a588388 100644
--- a/gcc/testsuite/gcc.dg/20020312-2.c
+++ b/gcc/testsuite/gcc.dg/20020312-2.c
@@ -34,6 +34,8 @@ extern void abort (void);
 /* PIC register is r1, but is used even without -fpic.  */
 #elif defined(__lm32__)
 /* No pic register.  */
+#elif defined(__or1k__)
+/* No pic register.  */
 #elif defined(__M32R__)
 /* No pic register.  */
 #elif defined(__m68k__)
diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c
index b6cbe39..e4d3e6f 100644
--- a/gcc/testsuite/gcc.dg/builtin-apply2.c
+++ b/gcc/testsuite/gcc.dg/builtin-apply2.c
@@ -44,3 +44,35 @@ int main(void)
 
   return 0;
 }
+
+#if defined(__ARM_PCS) || defined(__epiphany__)
+/* For Base AAPCS, NAME is passed in r0.  D is passed in r2 and r3.
+   E, F and G are passed on stack.  So the size of the stack argument
+   data is 20.  */
+#define STACK_ARGUMENTS_SIZE  20
+#elif defined __MMIX__ || defined __arc__
+/* No parameters on stack for bar.  */
+#define STACK_ARGUMENTS_SIZE 0
+#else
+#define STACK_ARGUMENTS_SIZE  64
+#endif
+
+extern void abort(void);
+
+void foo(char *name, double d, double e, double f, int g)
+{
+  if (g != INTEGER_ARG)
+    abort();
+}
+
+void bar(char *name, ...)
+{
+  __builtin_apply(foo, __builtin_apply_args(), STACK_ARGUMENTS_SIZE);
+}
+
+int main(void)
+{
+  bar("eeee", 5.444567, 8.90765, 4.567789, INTEGER_ARG);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
index bb727da..7f14818 100644
--- a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c
@@ -105,8 +105,8 @@ test2 (const H h)
   S *s[3];
   memset (s, 0, sizeof (S) * 3); /* { dg-warning "will always overflow" "memset" } */
 
-  struct T { char a[8]; char b[4]; char c[10]; } t;
-  stpcpy (t.c,"Testing..."); /* { dg-warning "will always overflow" "stpcpy" } */
+  struct T { char a[8]; char b[4]; char c[10]; } t; /* or1k pads this to 12 bytes, and __builtin_object_size (t.c, 0) gives the size of the full object.  */
+  stpcpy (t.c,"Testing..."); /* { dg-warning "will always overflow" "stpcpy" { target { ! or1k*-*-* } } } */
 
   char b1[7];
   char b2[4];
diff --git a/gcc/testsuite/gcc.dg/nop.h b/gcc/testsuite/gcc.dg/nop.h
index a0c19a3..c5089b1 100644
--- a/gcc/testsuite/gcc.dg/nop.h
+++ b/gcc/testsuite/gcc.dg/nop.h
@@ -2,6 +2,8 @@
 #define NOP "nop 0"
 #elif defined (__MMIX__)
 #define NOP "swym 0"
+#elif defined (__or1k__)
+#define NOP "l.nop 0"
 #else
 #define NOP "nop"
 #endif
diff --git a/gcc/testsuite/gcc.dg/torture/pr37868.c b/gcc/testsuite/gcc.dg/torture/pr37868.c
index 5204c5a..585e159 100644
--- a/gcc/testsuite/gcc.dg/torture/pr37868.c
+++ b/gcc/testsuite/gcc.dg/torture/pr37868.c
@@ -1,6 +1,7 @@
 /* { dg-do run } */
 /* { dg-options "-fno-strict-aliasing" } */
 /* { dg-skip-if "unaligned access" { arc*-*-* epiphany-*-* nds32*-*-* sparc*-*-* sh*-*-* tic6x-*-* } "*" "" } */
+/* { dg-skip-if "alignment exception" { or1k*-*-* } "*" "" } */
 
 extern void abort (void);
 #if (__SIZEOF_INT__ <= 2)
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
index ffd865b..eddadb6 100644
--- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
@@ -10,7 +10,7 @@
    avr: Variadic funcs don't pass arguments in registers, while normal funcs
         do.  */
 /* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { avr-*-* } } "*" "" } */
-/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { nds32*-*-* } "*" "" } */
+/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { nds32*-*-* or1k*-*-* } "*" "" } */
 /* { dg-require-effective-target untyped_assembly } */
    
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c b/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c
index 6dc233b..4ac4236 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c
@@ -15,7 +15,7 @@ struct str
 struct val
 {
   char y;
-  struct blah b2;
+  struct blah b2 __attribute__((packed)); /* { dg-warning "attribute ignored" "" { target { ! or1k*-*-* } } } */
 };
 
 union U
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index d5dfeae..2274c49 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -545,6 +545,7 @@ proc check_profiling_available { test_what } {
 	     || [istarget nds32*-*-elf]
 	     || [istarget nios2-*-elf]
 	     || [istarget nvptx-*-*]
+	     || [istarget or1k-*-elf]
 	     || [istarget powerpc-*-eabi*]
 	     || [istarget powerpc-*-elf]
 	     || [istarget rx-*-*]	
diff --git a/libgcc/ChangeLog.or1k b/libgcc/ChangeLog.or1k
new file mode 100644
index 0000000..9abb993
--- /dev/null
+++ b/libgcc/ChangeLog.or1k
@@ -0,0 +1,61 @@
+2014-08-13  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.S: make internal calls to __udivsi3 hidden.
+
+2014-05-07  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/or1k.S: Use delay/no-delay compatibility macros.
+	* config/or1k/lib2funcs.c: Remove.
+	* config/or1k/t-or1k: Set LIB1ASMSRC and LIB1ASMFUNCS. 
+	Remove LIB2ADD define.
+
+2013-07-17  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/sfp-machine.h (_FP_QNANNEGATEDP): Define to 0.
+
+2013-07-10  Stefan Kristiansson  <stefan.kristiansson@saunalahti.fi>
+
+	* config/or1k/crti.S: Rename __init/__fini to _init/_fini
+
+2013-02-13  Christian Svensson  <blue@cmd.nu>
+
+	* config.host: If we are targeting or1k*-linux or or1k*-uclibc do not
+	build crtn.o or crti.o. Do not include linux unwinder for other
+	targets (e.g. or1k*-elf) 
+
+2013-02-01  Christian Svensson  <blue@cmd.nu>
+
+	* config/or1k/t-crtstuff: updated file.
+	- Set CRTSTUFF_T_CFLAGS_S as well. (*-*-elf needs this)
+
+2013-01-24  Christian Svensson  <blue@cmd.nu>
+
+	* config/or1k/linux-unwind.h: new file
+	- support signal handling in DWARF2 unwinding
+	* config.host: include or1k/linux-unwind.h
+
+2012-12-29  Christian Svensson  <blue@cmd.nu>
+
+	* config/or1k/t-crtstuff: New file.
+	- Use -fno-dwarf2-cfi-asm on crtstuff to leave eh_frame empty.
+	* config.host: Include or1k/t-crtstuff
+
+2012-05-13  Peter Gavin  <pgavin@gmail.com>
+
+	* config.host: add or1knd target
+	* config/or1k/or1k-asm.h: new file
+	- contains macros for making delay slot optional
+	* config/or1k/t-or1k: use C versions of divmod and mulsi3 for now
+	until asm versions are updated to use optional delay slot
+	* config/or1k/lib2funcs.c: new file; defines __mulsi3
+	* config/or1k/crti.S: include or1k-asm.h
+	* config/or1k/crtn.S: include or1k-asm.h; make delay slot optional
+
+2012-03-03  Peter Gavin  <pgavin@gmail.com>
+
+	* configure: regenerated
+
+2012-02-18  Peter Gavin  <pgavin@gmail.com>
+
+	* config/or1k/or1k.S: moved from gcc/config/or1k/or1k.S
+	* config/or1k/t-or1k: compile or1k.S
diff --git a/libgcc/config.host b/libgcc/config.host
index 91f0f7f..3e17a0a 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -162,6 +162,12 @@ nds32*-*)
 nios2*-*-*)
 	cpu_type=nios2
 	;;
+or1k-*-*)
+	cpu_type=or1k
+	;;
+or1knd-*-*)
+	cpu_type=or1k
+	;;
 powerpc*-*-*)
 	cpu_type=rs6000
 	;;
@@ -963,6 +969,14 @@ nios2-*-*)
 	tmake_file="$tmake_file nios2/t-nios2 t-softfp-sfdf t-softfp-excl t-softfp"
 	extra_parts="$extra_parts crti.o crtn.o"
 	;;
+or1k*-*-linux* | or1k*-*-uclinux*)
+	tmake_file="$tmake_file or1k/t-or1k or1k/t-linux or1k/t-crtstuff t-softfp-sfdf t-softfp"
+	md_unwind_header=or1k/linux-unwind.h
+	;;
+or1k*-*-*)
+	tmake_file="$tmake_file or1k/t-or1k or1k/t-linux or1k/t-crtstuff t-softfp-sfdf t-softfp"
+	extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o crti.o crtn.o"
+	;;
 pdp11-*-*)
 	tmake_file="pdp11/t-pdp11 t-fdpbit"
 	;;
diff --git a/libgcc/config/or1k/crti.S b/libgcc/config/or1k/crti.S
new file mode 100644
index 0000000..bda20f4
--- /dev/null
+++ b/libgcc/config/or1k/crti.S
@@ -0,0 +1,36 @@
+# Start .init and .fini sections.
+# Copyright (C) 2010 Embecosm Limited
+# 
+# This file 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/>.
+
+#include "or1k-asm.h"
+
+	.section .init
+	.global	_init
+	l.nop			 # So _init doesn't start at 0
+_init:
+	l.addi	r1,r1,-4
+	l.sw	0(r1),r9
+
+	.section .fini
+	.global	_fini
+_fini:
+	l.addi  r1,r1,-4
+	l.sw    0(r1),r9
diff --git a/libgcc/config/or1k/crtn.S b/libgcc/config/or1k/crtn.S
new file mode 100644
index 0000000..5d40348
--- /dev/null
+++ b/libgcc/config/or1k/crtn.S
@@ -0,0 +1,37 @@
+# End .init and .fini sections.
+# Copyright (C) 2010 Embecosm Limited
+# 
+# This file 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/>.
+
+#include "or1k-asm.h"
+        
+	.section .init
+	l.lwz	r9,0(r1)
+        OR1K_DELAYED(
+	OR1K_INST(l.addi	r1,r1,4),
+	OR1K_INST(l.jr	r9)
+        )
+
+	.section .fini
+	l.lwz	r9,0(r1)
+        OR1K_DELAYED(
+	OR1K_INST(l.addi	r1,r1,4),
+	OR1K_INST(l.jr	r9)
+        )
diff --git a/libgcc/config/or1k/linux-unwind.h b/libgcc/config/or1k/linux-unwind.h
new file mode 100644
index 0000000..d42b672
--- /dev/null
+++ b/libgcc/config/or1k/linux-unwind.h
@@ -0,0 +1,77 @@
+/* DWARF2 EH unwinding support for OpenRISC.
+   Copyright (C) 2011, 2012
+   Free Software Foundation, Inc.
+
+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 inhibit_libc
+
+#include <signal.h>
+#include <sys/ucontext.h>
+#include <linux/unistd.h>
+
+#define MD_FALLBACK_FRAME_STATE_FOR or1k_fallback_frame_state
+
+static _Unwind_Reason_Code
+or1k_fallback_frame_state (struct _Unwind_Context *context,
+			      _Unwind_FrameState *fs)
+{
+  struct rt_sigframe {
+    siginfo_t info;
+    struct ucontext uc;
+  } *frame = context->cfa;
+
+  struct sigcontext *sc;
+  unsigned char *pc = context->ra;
+  long new_cfa;
+  int i;
+
+  /*
+   * Note: These have to be the same as in the kernel.
+   * Please see arch/openrisc/kernel/signal.c
+   */
+  if (!(*(unsigned short *)(pc + 0) == 0xa960
+      && *(unsigned short *)(pc + 2) == __NR_rt_sigreturn
+      && *(unsigned long *)(pc + 4) == 0x20000001
+      && *(unsigned long *)(pc + 8) == 0x15000000))
+    return _URC_END_OF_STACK;
+
+  sc = (struct sigcontext *) &frame->uc.uc_mcontext;
+
+  new_cfa = sc->regs.gpr[1];
+  fs->regs.cfa_how = CFA_REG_OFFSET;
+  fs->regs.cfa_reg = STACK_POINTER_REGNUM;
+  fs->regs.cfa_offset = new_cfa - (long) context->cfa;
+
+  for (i = 0; i < 32; ++i)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset = (long)&sc->regs.gpr[i] - new_cfa;
+    }
+
+  fs->retaddr_column = 9;
+  fs->signal_frame = 1;
+
+  return _URC_NO_REASON;
+}
+
+#endif /* ifdef inhibit_libc  */
diff --git a/libgcc/config/or1k/or1k-asm.h b/libgcc/config/or1k/or1k-asm.h
new file mode 100644
index 0000000..c328b20
--- /dev/null
+++ b/libgcc/config/or1k/or1k-asm.h
@@ -0,0 +1,20 @@
+#ifndef OR1K_ASM_H
+#define OR1K_ASM_H
+
+#define OR1K_INST(...) __VA_ARGS__
+
+#if defined(__OR1K_NODELAY__)
+#define OR1K_DELAYED(a, b) a; b
+#define OR1K_DELAYED_NOP(a) a
+.nodelay
+#elif defined(__OR1K_DELAY__)
+#define OR1K_DELAYED(a, b) b; a
+#define OR1K_DELAYED_NOP(a) a; l.nop
+#elif defined(__OR1K_DELAY_COMPAT__)
+#define OR1K_DELAYED(a, b) a; b; l.nop
+#define OR1K_DELAYED_NOP(a) a; l.nop
+#else
+#error One of __OR1K_NODELAY__, __OR1K_DELAY__, or __OR1K_DELAY_COMPAT__ must be defined
+#endif
+
+#endif
diff --git a/libgcc/config/or1k/or1k.S b/libgcc/config/or1k/or1k.S
new file mode 100644
index 0000000..f9266f3
--- /dev/null
+++ b/libgcc/config/or1k/or1k.S
@@ -0,0 +1,237 @@
+#include "or1k-asm.h"
+/*
+ * Assembly functions for software multiplication and devision.
+ */
+
+#define ENTRY(symbol)	\
+	.align 4	;\
+	.global symbol	;\
+	.type	symbol, @function ;\
+symbol:
+
+#ifdef L__mulsi3
+ENTRY(__mulsi3)
+	l.addi r11,r0,0x0
+	l.sfne r3,r11
+OR1K_DELAYED(
+	OR1K_INST(l.ori r5,r3,0x0),
+	OR1K_INST(l.bnf 3f)
+)
+	l.addi r6,r0,0x0
+1:
+	l.andi r3,r5,0x1
+	l.sfeq r3,r6
+OR1K_DELAYED(
+	OR1K_INST(l.srli r5,r5,0x1),
+	OR1K_INST(l.bf 2f)
+)
+	l.add r11,r11,r4
+2:
+	l.sfne r5,r6
+OR1K_DELAYED(
+	OR1K_INST(l.slli r4,r4,0x1),
+	OR1K_INST(l.bf 1b)
+)
+3:
+OR1K_DELAYED_NOP(
+	OR1K_INST(l.jr r9)
+)
+.size __mulsi3,.-__mulsi3
+#endif
+
+#ifdef L__udivsi3
+.global __udivsi3_internal
+.hidden __udivsi3_internal
+__udivsi3_internal:
+ENTRY(__udivsi3)
+	l.addi          r1,r1,-4
+        l.sw            0(r1),r9
+        l.addi          r11,r0,0
+        l.addi          r8,r4,0
+        l.addi          r5,r3,0
+        l.sfne          r8,r11
+OR1K_DELAYED(
+	OR1K_INST(l.addi r7,r0,0),
+	OR1K_INST(l.bnf 4f)
+)
+	/* The following work equally on delay and no-delay implementations */
+        l.sfgtu         r8,r5
+        l.bf            5f
+        l.sfeq          r8,r5
+        l.bf            6f
+        l.sfltu         r11,r8
+
+OR1K_DELAYED(
+	OR1K_INST(l.addi r13,r0,32),
+        OR1K_INST(l.bnf 2f)
+)
+        l.movhi         r9,hi(0x80000000)
+        l.addi          r6,r0,-1
+1:
+        l.and           r3,r5,r9
+        l.slli          r4,r7,1
+        l.addi          r15,r5,0
+        l.srli          r3,r3,31
+        l.add           r13,r13,r6
+        l.or            r7,r4,r3
+        l.sfltu         r7,r8
+OR1K_DELAYED(
+        OR1K_INST(l.slli r5,r5,1),
+        OR1K_INST(l.bf 1b)
+)
+2:
+        l.srli          r7,r7,1
+        l.addi          r13,r13,1
+        l.addi          r9,r0,0
+        l.sfltu         r9,r13
+OR1K_DELAYED(
+        OR1K_INST(l.addi r5,r15,0),
+        OR1K_INST(l.bnf 4f)
+)
+        l.movhi         r15,hi(0x80000000)
+        l.addi          r17,r0,0
+3:
+        l.and           r3,r5,r15
+        l.slli          r4,r7,1
+        l.srli          r3,r3,31
+        l.or            r7,r4,r3
+        l.sub           r6,r7,r8
+        l.and           r3,r6,r15
+        l.srli          r3,r3,31
+        l.addi          r4,r0,0
+        l.sfne          r3,r4
+OR1K_DELAYED(
+        OR1K_INST(l.slli r3,r11,1),
+        OR1K_INST(l.bf 1f)
+)
+        l.addi          r4,r0,1
+1:
+        l.slli          r5,r5,1
+        l.sfne          r4,r17
+OR1K_DELAYED(
+        OR1K_INST(l.or r11,r3,r4),
+        OR1K_INST(l.bnf 2f)
+)
+        l.addi          r7,r6,0
+2:
+        l.addi          r9,r9,1
+        l.sfltu         r9,r13
+OR1K_DELAYED_NOP(
+        OR1K_INST(l.bf 3b)
+)
+OR1K_DELAYED_NOP(
+	OR1K_INST(l.j 4f)
+)
+6:
+OR1K_DELAYED(
+	OR1K_INST(l.addi r11,r0,1),
+	OR1K_INST(l.j 4f)
+)
+5:
+	l.addi		r7,r5,0
+4:
+        l.lwz           r9,0(r1)
+OR1K_DELAYED(
+        OR1K_INST(l.addi r1,r1,4),
+        OR1K_INST(l.jr r9)
+)
+.size __udivsi3,.-__udivsi3
+#endif
+
+
+#ifdef L__divsi3
+ENTRY(__divsi3)
+	l.addi          r1,r1,-8
+        l.sw            0(r1),r9
+        l.sw            4(r1),r14
+        l.addi          r5,r3,0
+        l.addi          r14,r0,0
+        l.sflts         r5,r0
+OR1K_DELAYED(
+        OR1K_INST(l.addi r3,r0,0),
+        OR1K_INST(l.bnf 1f)
+)
+        l.addi          r14,r0,1
+        l.sub           r5,r0,r5
+1:
+        l.sflts         r4,r0
+OR1K_DELAYED_NOP(
+        OR1K_INST(l.bnf 1f)
+)
+        l.addi          r14,r14,1
+        l.sub           r4,r0,r4
+1:
+OR1K_DELAYED(
+        OR1K_INST(l.addi r3,r5,0),
+        OR1K_INST(l.jal __udivsi3_internal)
+)
+        l.sfeqi         r14,1
+OR1K_DELAYED_NOP(
+        OR1K_INST(l.bnf 1f)
+)
+        l.sub           r11,r0,r11
+1:
+        l.lwz           r9,0(r1)
+        l.lwz           r14,4(r1)
+OR1K_DELAYED(
+        OR1K_INST(l.addi r1,r1,8),
+        OR1K_INST(l.jr r9)
+)
+.size __divsi3,.-__divsi3
+#endif
+
+
+#ifdef L__umodsi3
+ENTRY(__umodsi3)
+	l.addi          r1,r1,-4
+	l.sw            0(r1),r9
+OR1K_DELAYED_NOP(
+	OR1K_INST(l.jal __udivsi3_internal)
+)
+	l.addi		r11,r7,0
+	l.lwz           r9,0(r1)
+OR1K_DELAYED(
+	OR1K_INST(l.addi r1,r1,4),
+	OR1K_INST(l.jr r9)
+)
+.size __umodsi3,.-__umodsi3
+#endif
+
+
+#ifdef L__modsi3
+ENTRY(__modsi3)
+        l.addi          r1,r1,-8
+        l.sw            0(r1),r9
+        l.sw            4(r1),r14
+        l.addi          r14,r0,0
+        l.sflts         r3,r0
+OR1K_DELAYED_NOP(
+        OR1K_INST(l.bnf 1f)
+)
+        l.addi          r14,r0,1
+        l.sub           r3,r0,r3
+1:
+        l.sflts         r4,r0
+OR1K_DELAYED_NOP(
+        OR1K_INST(l.bnf 1f)
+)
+        l.sub           r4,r0,r4
+1:
+OR1K_DELAYED_NOP(
+        OR1K_INST(l.jal __udivsi3_internal)
+)
+        l.sfeqi         r14,1
+OR1K_DELAYED(
+        OR1K_INST(l.addi r11,r7,0),
+        OR1K_INST(l.bnf 1f)
+)
+        l.sub           r11,r0,r11
+1:
+        l.lwz           r9,0(r1)
+        l.lwz           r14,4(r1)
+OR1K_DELAYED(
+        OR1K_INST(l.addi r1,r1,8),
+        OR1K_INST(l.jr r9)
+)
+.size __modsi3,.-__modsi3
+#endif
diff --git a/libgcc/config/or1k/sfp-machine.h b/libgcc/config/or1k/sfp-machine.h
new file mode 100644
index 0000000..5da9e84
--- /dev/null
+++ b/libgcc/config/or1k/sfp-machine.h
@@ -0,0 +1,54 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+#define _FP_MUL_MEAT_S(R,X,Y)				\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)				\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)				\
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_loop(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+#define _FP_NANSIGN_Q		0
+
+#define _FP_KEEPNANFRACP 1
+#define _FP_QNANNEGATEDP 0
+
+/* Someone please check this.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)		\
+	&& !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs))	\
+      {								\
+	R##_s = Y##_s;						\
+	_FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    else							\
+      {								\
+	R##_s = X##_s;						\
+	_FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __BIG_ENDIAN
+
+#define _FP_TININESS_AFTER_ROUNDING 0
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
diff --git a/libgcc/config/or1k/t-crtstuff b/libgcc/config/or1k/t-crtstuff
new file mode 100644
index 0000000..4898fc6
--- /dev/null
+++ b/libgcc/config/or1k/t-crtstuff
@@ -0,0 +1,4 @@
+# This will prevent gcc from appending data to .eh_frame.
+# Other archs use fno-asynchronous-unwind-tables but we do not have that flag.
+CRTSTUFF_T_CFLAGS += -fno-dwarf2-cfi-asm
+CRTSTUFF_T_CFLAGS_S += -fno-dwarf2-cfi-asm
diff --git a/libgcc/config/or1k/t-linux b/libgcc/config/or1k/t-linux
new file mode 100644
index 0000000..f4bf22d
--- /dev/null
+++ b/libgcc/config/or1k/t-linux
@@ -0,0 +1,2 @@
+MULTILIB_DIRNAMES = be
+EXTRA_MULTILIB_PARTS = crti.o crtbegin.o crtend.o crtn.o
diff --git a/libgcc/config/or1k/t-or1k b/libgcc/config/or1k/t-or1k
new file mode 100644
index 0000000..ff3a8ae
--- /dev/null
+++ b/libgcc/config/or1k/t-or1k
@@ -0,0 +1,23 @@
+# t-or1k is a Makefile fragment to be included when
+#           building gcc for the or1k target
+
+# Copyright (C) 2010 Embecosm Limited
+
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+LIB1ASMSRC = or1k/or1k.S
+LIB1ASMFUNCS = __mulsi3 __udivsi3 __divsi3 __umodsi3 __modsi3
diff --git a/libgcc/configure b/libgcc/configure
index 203d384..a0a7f30 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -2343,6 +2343,9 @@ case "${host}" in
     mips-sgi-irix6*)
 	# PIC is the default.
 	;;
+    or1k-*-*)
+	PICFLAG=-fPIC
+        ;;
     rs6000-ibm-aix* | powerpc-ibm-aix*)
 	# All AIX code is PIC.
 	;;
diff --git a/libiberty/ChangeLog.or1k b/libiberty/ChangeLog.or1k
new file mode 100644
index 0000000..16f3b07
--- /dev/null
+++ b/libiberty/ChangeLog.or1k
@@ -0,0 +1,4 @@
+2012-03-03  Peter Gavin  <pgavin@gmail.com>
+
+	* configure: regenerated
+
diff --git a/libjava/classpath/config.guess b/libjava/classpath/config.guess
index b02565c..4cef3f9 100755
--- a/libjava/classpath/config.guess
+++ b/libjava/classpath/config.guess
@@ -942,8 +942,8 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
 	;;
-    or32:Linux:*:*)
-	echo or32-unknown-linux-gnu
+    or1k:Linux:*:*)
+	echo or1k-unknown-linux-gnu
 	exit ;;
     padre:Linux:*:*)
 	echo sparc-unknown-linux-gnu
diff --git a/libjava/classpath/config.sub b/libjava/classpath/config.sub
index 59bb593..b2d9ef5 100755
--- a/libjava/classpath/config.sub
+++ b/libjava/classpath/config.sub
@@ -300,7 +300,7 @@ case $basic_machine in
 	| nios | nios2 \
 	| ns16k | ns32k \
 	| open8 \
-	| or32 \
+	| or1k \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
@@ -917,7 +917,7 @@ case $basic_machine in
 		os=-proelf
 		;;
 	openrisc | openrisc-*)
-		basic_machine=or32-unknown
+		basic_machine=or1k-unknown
 		;;
 	os400)
 		basic_machine=powerpc-ibm
@@ -1583,7 +1583,7 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
-	or32-*)
+	or1k-*)
 		os=-coff
 		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/5.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/5.cc
index 3e8280d..cafbd05 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/5.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/5.cc
@@ -23,6 +23,8 @@
 // working, not to mention other major details like char_traits, and
 // all of the string class.
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <string>
 #include <fstream>
 #include <iostream>
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/streambuf_iterators/wchar_t/4.cc b/libstdc++-v3/testsuite/25_algorithms/copy/streambuf_iterators/wchar_t/4.cc
index 0981e5e..ca28d8c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/streambuf_iterators/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/streambuf_iterators/wchar_t/4.cc
@@ -17,6 +17,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <iterator>
 #include <fstream>
 #include <algorithm>
diff --git a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc
index 2ab65f8..8e803ac 100644
--- a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc
@@ -17,6 +17,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <iterator>
 #include <fstream>
 #include <algorithm>
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekpos/wchar_t/12790-1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekpos/wchar_t/12790-1.cc
index 0cb18f6..4e0be89 100644
--- a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekpos/wchar_t/12790-1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekpos/wchar_t/12790-1.cc
@@ -17,6 +17,8 @@
 
 // 27.8.1.4 Overridden virtual functions
 
+// { dg-xfail-run-if "not supported on OR32 newlib" { or1k-*-elf } }
+
 #include <locale>
 #include <fstream>
 #include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/2.cc
index e789bb4..ccc5ecc 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/2.cc
@@ -19,6 +19,8 @@
 // @require@ %-*.tst %-*.txt
 // @diff@ %-*.tst %-*.txt
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <istream>
 #include <fstream>
 #include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/2.cc
index 2180b96..d71e73f 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/2.cc
@@ -19,6 +19,9 @@
 // @require@ %-*.tst %-*.txt
 // @diff@ %-*.tst %-*.txt
 
+// OpenRISC does not support file I/O in newlib
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <istream>
 #include <sstream>
 #include <fstream>
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/3.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/3.cc
index 6c464c9..53c1f5a 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/3.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/3.cc
@@ -19,6 +19,8 @@
 // @require@ %-*.tst %-*.txt
 // @diff@ %-*.tst %-*.txt
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <istream>
 #include <fstream>
 #include <limits>
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/seekg/wchar_t/sstream.cc b/libstdc++-v3/testsuite/27_io/basic_istream/seekg/wchar_t/sstream.cc
index 43b3511..de063e3 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/seekg/wchar_t/sstream.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/seekg/wchar_t/sstream.cc
@@ -22,6 +22,8 @@
 // @require@ %-*.tst %-*.txt
 // @diff@ %-*.tst %-*.txt
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <istream>
 #include <sstream>
 #include <fstream>
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/tellg/wchar_t/sstream.cc b/libstdc++-v3/testsuite/27_io/basic_istream/tellg/wchar_t/sstream.cc
index 4cd901e..9d8f634 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/tellg/wchar_t/sstream.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/tellg/wchar_t/sstream.cc
@@ -20,6 +20,8 @@
 // @require@ %-*.tst %-*.txt
 // @diff@ %-*.tst %-*.txt
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <istream>
 #include <sstream>
 #include <fstream>
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/1.cc
index fe83ad3..6193103 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/1.cc
@@ -19,6 +19,8 @@
 // @require@ %-*.tst %-*.txt
 // @diff@ %-*.tst %-*.txt
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <ostream>
 #include <sstream>
 #include <fstream>
diff --git a/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc
index 1c9fa60..8ced491 100644
--- a/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc
+++ b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc
@@ -23,6 +23,8 @@
 // @require@ %-*.tst
 // @diff@ %-*.tst %-*.txt
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <cstdio>
 #include <sstream>
 #include <iostream>
diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc
index 39458cd..f876d83 100644
--- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc
+++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc
@@ -18,6 +18,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <iostream>
 #include <cstdio>
 #include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc
index e048838..79955d8 100644
--- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc
+++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc
@@ -15,6 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <iostream>
 #include <cstdio>
 #include <cwchar>
diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc
index 200f1575..8eb30dd 100644
--- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc
+++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc
@@ -18,6 +18,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <iostream>
 #include <cwchar>
 #include <cstdio>
diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc
index ab4317b..6c6af65 100644
--- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc
+++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc
@@ -15,6 +15,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+// { dg-xfail-run-if "not supported on OR1K newlib" { or1k-*-elf } }
+
 #include <iostream>
 #include <cstdio>
 #include <cwchar>
