Commit c1dd9790 by Joern Rennecke Committed by Joern Rennecke

avr-c.c (avr_cpu_cpp_builtins): Don't define __MEMX for avrtiny.

gcc:

2014-10-21  Joern Rennecke  <joern.rennecke@embecosm.com>
	    Vidya Praveen <vidya.praveen@atmel.com>
	    Praveen Kumar Kaushik <Praveen_Kumar.Kaushik@atmel.com>
	    Senthil Kumar Selvaraj <Senthil_Kumar.Selvaraj@atmel.com>
	    Pitchumani Sivanupandi <Pitchumani.S@atmel.com>

	* config/avr/avr-c.c (avr_cpu_cpp_builtins): Don't define
	__MEMX for avrtiny.
	* config/avr/avr.c (avr_insert_attributes): Reject __memx for avrtiny.
	(avr_nonconst_pointer_addrspace): Likewise.
	* config/avr/avr.h (AVR_HAVE_LPM): Define.

	Added AVRTINY architecture to avr target.
	* config/avr/avr-arch.h (avr_arch): Added AVRTINY architecture.
	(base_arch_s): member added for AVRTINY architecture.
	* config/avr/avr.c: Added TINY_ADIW, TINY_SBIW macros as AVRTINY
	alternate for adiw/sbiw instructions. Added AVR_TMP_REGNO and
	AVR_ZERO_REGNO macros for tmp and zero registers. Replaced TMP_REGNO
	and ZERO_REGNO occurrences by AVR_TMP_REGNO and AVR_ZERO_REGNO
	respectively. LAST_CALLEE_SAVED_REG macro added for the last register
	in callee saved register list.
	(avr_option_override): CCP address updated for AVRTINY.
	(avr_init_expanders): tmp and zero rtx initialized as per arch.
	Reset avr_have_dimode if AVRTINY.
	(sequent_regs_live): Use LAST_CALLEE_SAVED_REG instead magic number.
	(emit_push_sfr): Use AVR_TMP_REGNO for tmp register number.
	(avr_prologue_setup_frame): Don't minimize prologue if AVRTINY.
	Use LAST_CALLEE_SAVED_REG to refer last callee saved register.
	(expand_epilogue): Likewise.
	(avr_print_operand): Print CCP address in case of AVRTINY also.
	<TBD>bad address
	(function_arg_regno_p): Check different register list for arguments
	if AVRTINY.
	(init_cumulative_args): Check for AVRTINY to update number of argument
	registers.
	(tiny_valid_direct_memory_access_range): New function. Return false if
	direct memory access range is not in accepted range for AVRTINY.
	(avr_out_movqi_r_mr_reg_disp_tiny): New function to handle register
	indirect load (with displacement) for AVRTINY.
	(out_movqi_r_mr): Updated instruction length for AVRTINY. Call
	avr_out_movqi_r_mr_reg_disp_tiny for load from reg+displacement.
	(avr_out_movhi_r_mr_reg_no_disp_tiny): New function to handle register
	indirect load (no displacement) for AVRTINY.
	(avr_out_movhi_r_mr_reg_disp_tiny): New function to handle register
	indirect load (with displacement) for AVRTINY.
	(avr_out_movhi_r_mr_pre_dec_tiny): New function to handle register
	indirect load for pre-decrement address.
	(out_movhi_r_mr): In case of AVRTINY, call tiny register indirect load
	functions. Update instruction length for AVRTINY.
	(avr_out_movsi_r_mr_reg_no_disp_tiny): New function. Likewise, for
	SImode.
	(avr_out_movsi_r_mr_reg_disp_tiny): New function. Likewise, for SImode.
	(out_movsi_r_mr): Likewise, for SImode.
	(avr_out_movsi_mr_r_reg_no_disp_tiny): New function to handle register
	indirect store (no displacement) for AVRTINY.
	(avr_out_movsi_mr_r_reg_disp_tiny): New function to handle register
	indirect store (with displacement) for AVRTINY.
	(out_movsi_mr_r): Emit out insn for IO address store. Update store
	instruction's size for AVRTINY. For AVRTINY, call tiny SImode indirect
	store functions.
	(avr_out_load_psi_reg_no_disp_tiny): New function to handle register
	indirect load (no displacement) for PSImode in AVRTINY.
	(avr_out_load_psi_reg_disp_tiny): New function to handle register
	indirect load (with displacement) for PSImode in AVRTINY.
	(avr_out_load_psi): Call PSImode register indirect load functions for
	AVRTINY. Update instruction length for AVRTINY.
	(avr_out_store_psi_reg_no_disp_tiny): New function to handle register
	indirect store (no displacement) for PSImode in AVRTINY.
	(avr_out_store_psi_reg_disp_tiny): New function to handle register
	indirect store (with displacement) for PSImode in AVRTINY.
	(avr_out_store_psi): Update instruction length for AVRTINY. Call tiny
	register indirect store functions for AVRTINY.
	(avr_out_movqi_mr_r_reg_disp_tiny): New function to handle QImode
	register indirect store (with displacement) for AVRTINY.
	(out_movqi_mr_r): Update instruction length for AVRTINY. Call tiny
	register indirect store function for QImode in AVRTINY.
	(avr_out_movhi_mr_r_xmega): Update instruction length for AVRTINY.
	(avr_out_movhi_mr_r_reg_no_disp_tiny): New function to handle register
	indirect store (no displacement) for HImode in AVRTINY.
	(avr_out_movhi_mr_r_reg_disp_tiny): New function to handle register
	indirect store (with displacement) for HImode in AVRTINY.
	(avr_out_movhi_mr_r_post_inc_tiny): New function to handle register
	indirect store for post-increment address in HImode.
	(out_movhi_mr_r): Update instruction length for AVRTINY. Call tiny
	register indirect store function for HImode in AVRTINY.
	(avr_out_compare): Use TINY_SBIW/ TINY_ADIW in place of sbiw/adiw
	in case of AVRTINY.
	(order_regs_for_local_alloc): Updated register allocation order for
	AVRTINY.
	(avr_conditional_register_usage): New function. It is a target hook
	(TARGET_CONDITIONAL_REGISTER_USAGE) function which updates fixed, call
	used registers list and register allocation order for AVRTINY.
	(avr_return_in_memory): Update return value size for AVRTINY.
	* config/avr/avr-c.c (avr_cpu_cpp_builtins): Added builtin macros
	for AVRTINY arch and tiny program memory base address.
	* config/avr/avr-devices.c (avr_arch_types): Added AVRTINY arch.
	(avr_texinfo): Added description for AVRTINY arch.
	* config/avr/avr.h: Added macro to identify AVRTINY arch. Updated
	STATIC_CHAIN_REGNUM for AVRTINY.
	* config/avr/avr-mcus.def: Added AVRTINY arch devices.
	* config/avr/avr.md: Added constants for tmp/ zero registers in
	AVRTINY. Attributes for AVRTINY added.
	(mov<mode>): Move src/ dest address to register if it is not in AVRTINY
	memory access range.
	(mov<mode>_insn): Avoid QImode direct load for AVRTINY if address not
	in AVRTINY memory access range.
	(*mov<mode>): Likewise for HImode and SImode.
	(*movsf): Likewise for SFmode.
	(delay_cycles_2): Updated instructions to be emitted as AVRTINY does
	not have sbiw.
	* config/avr/avr-protos.h: Added function prototype for
	tiny_valid_direct_memory_access_range.
	* config/avr/avr-tables.opt: Regenerate.
	* gcc/config/avr/t-multilib: Regenerate.
	* doc/avr-mmcu.texi: Regenerate.

gcc/testsuite:

2014-10-21  Joern Rennecke  <joern.rennecke@embecosm.com>

	* gcc.target/avr/tiny-memx.c: New test.

	* gcc.target/avr/tiny-caller-save.c: New test.

libgcc:

2014-10-21  Joern Rennecke  <joern.rennecke@embecosm.com>
	    Vidya Praveen <vidya.praveen@atmel.com>
	    Praveen Kumar Kaushik <Praveen_Kumar.Kaushik@atmel.com>
	    Senthil Kumar Selvaraj <Senthil_Kumar.Selvaraj@atmel.com>
	    Pitchumani Sivanupandi <Pitchumani.S@atmel.com>

	* config/avr/lib1funcs.S (__do_global_dtors): Go back to descending
	order.

	Updated library functions for AVRTINY arch.
	* config/avr/lib1funcs.S: Updated zero/tmp regs for AVRTINY.
	Replaced occurrences of r0/r1 with tmp/zero reg macros.
	Added wsubi/ wadi macros that expands conditionally as sbiw/ adiw
	or AVRTINY equivalent. Replaced occurrences of sbiw/adiw with
	wsubi/wadi macors.
	(__mulsi3_helper): Update stack, preserve callee saved regs and
	argument from stack. Restore callee save registers.
	(__mulpsi3): Likewise.
	(__muldi3, __udivmodsi4, __divmodsi4, __negsi2, __umoddi3, __udivmod64,
	__moddi3, __adddi3, __adddi3_s8, __subdi3, __cmpdi2, __cmpdi2_s8,
	__negdi2, __prologue_saves__, __epilogue_restores__): Excluded for 
	AVRTINY.
	(__tablejump2__): Added lpm equivalent instructions for AVRTINY.
	(__do_copy_data): Added new definition for AVRTINY.
	(__do_clear_bss): Replace r17 by r18 to preserve zero reg for AVRTINY.
	(__load_3, __load_4, __xload_1, __xload_2, __xload_3,
	__xload_4, __movmemx_qi, __movmemx_hi): Excluded for AVRTINY.
	* config/avr/lib1funcs-fixed.S: Replaced occurrences of r0/r1 with
	tmp/zero reg macros. Replaced occurrences of sbiw/adiw with wsubi/wadi
	macors.
	   * config/avr/t-avr (LIB1ASMFUNCS): Remove unsupported functions for
	AVRTINY.

	Fix broken long multiplication on tiny arch.         


Co-Authored-By: Pitchumani Sivanupandi <pitchumani.s@atmel.com>
Co-Authored-By: Praveen Kumar Kaushik <Praveen_Kumar.Kaushik@atmel.com>
Co-Authored-By: Senthil Kumar Selvaraj <Senthil_Kumar.Selvaraj@atmel.com>
Co-Authored-By: Vidya Praveen <vidya.praveen@atmel.com>

From-SVN: r216525
parent d1bcc29f
2014-10-21 Joern Rennecke <joern.rennecke@embecosm.com>
Vidya Praveen <vidya.praveen@atmel.com>
Praveen Kumar Kaushik <Praveen_Kumar.Kaushik@atmel.com>
Senthil Kumar Selvaraj <Senthil_Kumar.Selvaraj@atmel.com>
Pitchumani Sivanupandi <Pitchumani.S@atmel.com>
* config/avr/avr-c.c (avr_cpu_cpp_builtins): Don't define
__MEMX for avrtiny.
* config/avr/avr.c (avr_insert_attributes): Reject __memx for avrtiny.
(avr_nonconst_pointer_addrspace): Likewise.
* config/avr/avr.h (AVR_HAVE_LPM): Define.
Added AVRTINY architecture to avr target.
* config/avr/avr-arch.h (avr_arch): Added AVRTINY architecture.
(base_arch_s): member added for AVRTINY architecture.
* config/avr/avr.c: Added TINY_ADIW, TINY_SBIW macros as AVRTINY
alternate for adiw/sbiw instructions. Added AVR_TMP_REGNO and
AVR_ZERO_REGNO macros for tmp and zero registers. Replaced TMP_REGNO
and ZERO_REGNO occurrences by AVR_TMP_REGNO and AVR_ZERO_REGNO
respectively. LAST_CALLEE_SAVED_REG macro added for the last register
in callee saved register list.
(avr_option_override): CCP address updated for AVRTINY.
(avr_init_expanders): tmp and zero rtx initialized as per arch.
Reset avr_have_dimode if AVRTINY.
(sequent_regs_live): Use LAST_CALLEE_SAVED_REG instead magic number.
(emit_push_sfr): Use AVR_TMP_REGNO for tmp register number.
(avr_prologue_setup_frame): Don't minimize prologue if AVRTINY.
Use LAST_CALLEE_SAVED_REG to refer last callee saved register.
(expand_epilogue): Likewise.
(avr_print_operand): Print CCP address in case of AVRTINY also.
<TBD>bad address
(function_arg_regno_p): Check different register list for arguments
if AVRTINY.
(init_cumulative_args): Check for AVRTINY to update number of argument
registers.
(tiny_valid_direct_memory_access_range): New function. Return false if
direct memory access range is not in accepted range for AVRTINY.
(avr_out_movqi_r_mr_reg_disp_tiny): New function to handle register
indirect load (with displacement) for AVRTINY.
(out_movqi_r_mr): Updated instruction length for AVRTINY. Call
avr_out_movqi_r_mr_reg_disp_tiny for load from reg+displacement.
(avr_out_movhi_r_mr_reg_no_disp_tiny): New function to handle register
indirect load (no displacement) for AVRTINY.
(avr_out_movhi_r_mr_reg_disp_tiny): New function to handle register
indirect load (with displacement) for AVRTINY.
(avr_out_movhi_r_mr_pre_dec_tiny): New function to handle register
indirect load for pre-decrement address.
(out_movhi_r_mr): In case of AVRTINY, call tiny register indirect load
functions. Update instruction length for AVRTINY.
(avr_out_movsi_r_mr_reg_no_disp_tiny): New function. Likewise, for
SImode.
(avr_out_movsi_r_mr_reg_disp_tiny): New function. Likewise, for SImode.
(out_movsi_r_mr): Likewise, for SImode.
(avr_out_movsi_mr_r_reg_no_disp_tiny): New function to handle register
indirect store (no displacement) for AVRTINY.
(avr_out_movsi_mr_r_reg_disp_tiny): New function to handle register
indirect store (with displacement) for AVRTINY.
(out_movsi_mr_r): Emit out insn for IO address store. Update store
instruction's size for AVRTINY. For AVRTINY, call tiny SImode indirect
store functions.
(avr_out_load_psi_reg_no_disp_tiny): New function to handle register
indirect load (no displacement) for PSImode in AVRTINY.
(avr_out_load_psi_reg_disp_tiny): New function to handle register
indirect load (with displacement) for PSImode in AVRTINY.
(avr_out_load_psi): Call PSImode register indirect load functions for
AVRTINY. Update instruction length for AVRTINY.
(avr_out_store_psi_reg_no_disp_tiny): New function to handle register
indirect store (no displacement) for PSImode in AVRTINY.
(avr_out_store_psi_reg_disp_tiny): New function to handle register
indirect store (with displacement) for PSImode in AVRTINY.
(avr_out_store_psi): Update instruction length for AVRTINY. Call tiny
register indirect store functions for AVRTINY.
(avr_out_movqi_mr_r_reg_disp_tiny): New function to handle QImode
register indirect store (with displacement) for AVRTINY.
(out_movqi_mr_r): Update instruction length for AVRTINY. Call tiny
register indirect store function for QImode in AVRTINY.
(avr_out_movhi_mr_r_xmega): Update instruction length for AVRTINY.
(avr_out_movhi_mr_r_reg_no_disp_tiny): New function to handle register
indirect store (no displacement) for HImode in AVRTINY.
(avr_out_movhi_mr_r_reg_disp_tiny): New function to handle register
indirect store (with displacement) for HImode in AVRTINY.
(avr_out_movhi_mr_r_post_inc_tiny): New function to handle register
indirect store for post-increment address in HImode.
(out_movhi_mr_r): Update instruction length for AVRTINY. Call tiny
register indirect store function for HImode in AVRTINY.
(avr_out_compare): Use TINY_SBIW/ TINY_ADIW in place of sbiw/adiw
in case of AVRTINY.
(order_regs_for_local_alloc): Updated register allocation order for
AVRTINY.
(avr_conditional_register_usage): New function. It is a target hook
(TARGET_CONDITIONAL_REGISTER_USAGE) function which updates fixed, call
used registers list and register allocation order for AVRTINY.
(avr_return_in_memory): Update return value size for AVRTINY.
* config/avr/avr-c.c (avr_cpu_cpp_builtins): Added builtin macros
for AVRTINY arch and tiny program memory base address.
* config/avr/avr-devices.c (avr_arch_types): Added AVRTINY arch.
(avr_texinfo): Added description for AVRTINY arch.
* config/avr/avr.h: Added macro to identify AVRTINY arch. Updated
STATIC_CHAIN_REGNUM for AVRTINY.
* config/avr/avr-mcus.def: Added AVRTINY arch devices.
* config/avr/avr.md: Added constants for tmp/ zero registers in
AVRTINY. Attributes for AVRTINY added.
(mov<mode>): Move src/ dest address to register if it is not in AVRTINY
memory access range.
(mov<mode>_insn): Avoid QImode direct load for AVRTINY if address not
in AVRTINY memory access range.
(*mov<mode>): Likewise for HImode and SImode.
(*movsf): Likewise for SFmode.
(delay_cycles_2): Updated instructions to be emitted as AVRTINY does
not have sbiw.
* config/avr/avr-protos.h: Added function prototype for
tiny_valid_direct_memory_access_range.
* config/avr/avr-tables.opt: Regenerate.
* gcc/config/avr/t-multilib: Regenerate.
* doc/avr-mmcu.texi: Regenerate.
2014-10-21 Andrew Pinski <apinski@cavium.com> 2014-10-21 Andrew Pinski <apinski@cavium.com>
* doc/invoke.texi (AARCH64/mtune): Document thunderx as an * doc/invoke.texi (AARCH64/mtune): Document thunderx as an
...@@ -37,6 +37,7 @@ enum avr_arch ...@@ -37,6 +37,7 @@ enum avr_arch
ARCH_AVR5, ARCH_AVR5,
ARCH_AVR51, ARCH_AVR51,
ARCH_AVR6, ARCH_AVR6,
ARCH_AVRTINY,
ARCH_AVRXMEGA2, ARCH_AVRXMEGA2,
ARCH_AVRXMEGA4, ARCH_AVRXMEGA4,
ARCH_AVRXMEGA5, ARCH_AVRXMEGA5,
...@@ -77,6 +78,9 @@ typedef struct ...@@ -77,6 +78,9 @@ typedef struct
and thus also the RAMPX, RAMPY and RAMPZ registers. */ and thus also the RAMPX, RAMPY and RAMPZ registers. */
int have_rampd; int have_rampd;
/* This is a TINY core. */
int tiny_p;
/* Default start of data section address for architecture. */ /* Default start of data section address for architecture. */
int default_data_section_start; int default_data_section_start;
......
...@@ -321,6 +321,23 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -321,6 +321,23 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
} }
if (AVR_XMEGA) if (AVR_XMEGA)
cpp_define (pfile, "__AVR_XMEGA__"); cpp_define (pfile, "__AVR_XMEGA__");
if (AVR_TINY)
{
cpp_define (pfile, "__AVR_TINY__");
/* Define macro "__AVR_TINY_PM_BASE_ADDRESS__" with mapped program memory
start address. This macro shall be referred where mapped program memory
is accessed. (Eg. copying data section (do_copy_data) contents to data
memory region.
NOTE:
Program memory of AVR_TINY devices can not be accessed directly, it has
been mapped to the data memory. For AVR_TINY devices (ATtiny4/ 5/ 9/ 10/
20 and 40) mapped program memory starts at 0x4000.
*/
cpp_define (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x4000");
}
if (avr_current_arch->have_eijmp_eicall) if (avr_current_arch->have_eijmp_eicall)
{ {
cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__"); cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
...@@ -376,7 +393,10 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) ...@@ -376,7 +393,10 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
/* Only supply __FLASH<n> macro if the address space is reasonable /* Only supply __FLASH<n> macro if the address space is reasonable
for this target. The address space qualifier itself is still for this target. The address space qualifier itself is still
supported, but using it will throw an error. */ supported, but using it will throw an error. */
&& avr_addrspace[i].segment < avr_n_flash) && avr_addrspace[i].segment < avr_n_flash
/* Only support __MEMX macro if we have LPM. */
&& (AVR_HAVE_LPM || avr_addrspace[i].pointer_size <= 2))
{ {
const char *name = avr_addrspace[i].name; const char *name = avr_addrspace[i].name;
char *Name = (char*) alloca (1 + strlen (name)); char *Name = (char*) alloca (1 + strlen (name));
......
...@@ -31,29 +31,30 @@ const avr_arch_t ...@@ -31,29 +31,30 @@ const avr_arch_t
avr_arch_types[] = avr_arch_types[] =
{ {
/* unknown device specified */ /* unknown device specified */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, "avr2" }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, "avr2" },
/* /*
A M J LM E E E X R d S S O A A M J LM E E E X R T d S S O A
S U M PO L L I M A a t F ff r S U M PO L L I M A I a t F ff r
M L P MV P P J E M t a R s c M L P MV P P J E M N t a R s c
XW M M M G P a r e h XW M M M G P Y a r e h
X P A D t t ID */ X P A D t t ID */
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "1", "avr1" }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "1", "avr1" },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "2", "avr2" }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "2", "avr2" },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "25", "avr25" }, { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "25", "avr25" },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "3", "avr3" }, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "3", "avr3" },
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0x0060, 32, "31", "avr31" }, { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "31", "avr31" },
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, "35", "avr35" }, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "35", "avr35" },
{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "4", "avr4" }, { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "4", "avr4" },
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, "5", "avr5" }, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "5", "avr5" },
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, "51", "avr51" }, { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0x0060, 32, "51", "avr51" },
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, 32, "6", "avr6" }, { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, "6", "avr6" },
{ 0, 1, 1, 1, 0, 0, 0, 1, 0, 0x2000, 0, "102", "avrxmega2" }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x0040, 0, "100", "avrtiny" },
{ 0, 1, 1, 1, 1, 1, 0, 1, 0, 0x2000, 0, "104", "avrxmega4" }, { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0, "102", "avrxmega2" },
{ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0x2000, 0, "105", "avrxmega5" }, { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0x2000, 0, "104", "avrxmega4" },
{ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, "106", "avrxmega6" }, { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0x2000, 0, "105", "avrxmega5" },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0x2000, 0, "107", "avrxmega7" } { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0x2000, 0, "106", "avrxmega6" },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, "107", "avrxmega7" }
}; };
const avr_arch_info_t const avr_arch_info_t
...@@ -85,6 +86,9 @@ avr_texinfo[] = ...@@ -85,6 +86,9 @@ avr_texinfo[] =
{ ARCH_AVR6, { ARCH_AVR6,
"``Enhanced'' devices with 3-byte PC, i.e.@: with more than 128@tie{}KiB " "``Enhanced'' devices with 3-byte PC, i.e.@: with more than 128@tie{}KiB "
"of program memory." }, "of program memory." },
{ ARCH_AVRTINY,
"``TINY'' Tiny core devices with 512@tie{}B up to 4@tie{}KiB of "
"program memory." },
{ ARCH_AVRXMEGA2, { ARCH_AVRXMEGA2,
"``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB " "``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB "
"of program memory." }, "of program memory." },
......
...@@ -326,6 +326,14 @@ AVR_MCU ("avrxmega7", ARCH_AVRXMEGA7, AVR_ISA_NONE, NULL, ...@@ -326,6 +326,14 @@ AVR_MCU ("avrxmega7", ARCH_AVRXMEGA7, AVR_ISA_NONE, NULL,
AVR_MCU ("atxmega128a1", ARCH_AVRXMEGA7, AVR_ISA_NONE, "__AVR_ATxmega128A1__", 0x2000, 0x0, 3, "x128a1") AVR_MCU ("atxmega128a1", ARCH_AVRXMEGA7, AVR_ISA_NONE, "__AVR_ATxmega128A1__", 0x2000, 0x0, 3, "x128a1")
AVR_MCU ("atxmega128a1u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A1U__", 0x2000, 0x0, 3, "x128a1u") AVR_MCU ("atxmega128a1u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A1U__", 0x2000, 0x0, 3, "x128a1u")
AVR_MCU ("atxmega128a4u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A4U__", 0x2000, 0x0, 3, "x128a4u") AVR_MCU ("atxmega128a4u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A4U__", 0x2000, 0x0, 3, "x128a4u")
/* Tiny family */
AVR_MCU ("avrtiny", ARCH_AVRTINY, AVR_ISA_NONE, NULL, 0x0040, 0x0, 1, "tn10")
AVR_MCU ("attiny4", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny4__", 0x0040, 0x0, 1, "tn4")
AVR_MCU ("attiny5", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny5__", 0x0040, 0x0, 1, "tn5")
AVR_MCU ("attiny9", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny9__", 0x0040, 0x0, 1, "tn9")
AVR_MCU ("attiny10", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny10__", 0x0040, 0x0, 1, "tn10")
AVR_MCU ("attiny20", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny20__", 0x0040, 0x0, 1, "tn20")
AVR_MCU ("attiny40", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny40__", 0x0040, 0x0, 1, "tn40")
/* Assembler only. */ /* Assembler only. */
AVR_MCU ("avr1", ARCH_AVR1, AVR_ISA_NONE, NULL, 0x0060, 0x0, 1, "s1200") AVR_MCU ("avr1", ARCH_AVR1, AVR_ISA_NONE, NULL, 0x0060, 0x0, 1, "s1200")
AVR_MCU ("at90s1200", ARCH_AVR1, AVR_ISA_NONE, "__AVR_AT90S1200__", 0x0060, 0x0, 1, "s1200") AVR_MCU ("at90s1200", ARCH_AVR1, AVR_ISA_NONE, "__AVR_AT90S1200__", 0x0060, 0x0, 1, "s1200")
......
...@@ -46,6 +46,7 @@ extern void avr_init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx, tree); ...@@ -46,6 +46,7 @@ extern void avr_init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx, tree);
#ifdef RTX_CODE #ifdef RTX_CODE
extern int avr_hard_regno_call_part_clobbered (unsigned, enum machine_mode); extern int avr_hard_regno_call_part_clobbered (unsigned, enum machine_mode);
extern bool tiny_valid_direct_memory_access_range(rtx, enum machine_mode);
extern const char *output_movqi (rtx_insn *insn, rtx operands[], int *l); extern const char *output_movqi (rtx_insn *insn, rtx operands[], int *l);
extern const char *output_movhi (rtx_insn *insn, rtx operands[], int *l); extern const char *output_movhi (rtx_insn *insn, rtx operands[], int *l);
extern const char *output_movsisf (rtx_insn *insn, rtx operands[], int *l); extern const char *output_movsisf (rtx_insn *insn, rtx operands[], int *l);
......
...@@ -66,5 +66,8 @@ EnumValue ...@@ -66,5 +66,8 @@ EnumValue
Enum(avr_arch) String(avrxmega7) Value(ARCH_AVRXMEGA7) Enum(avr_arch) String(avrxmega7) Value(ARCH_AVRXMEGA7)
EnumValue EnumValue
Enum(avr_arch) String(avrtiny) Value(ARCH_AVRTINY)
EnumValue
Enum(avr_arch) String(avr1) Value(ARCH_AVR1) Enum(avr_arch) String(avr1) Value(ARCH_AVR1)
...@@ -63,6 +63,7 @@ enum ...@@ -63,6 +63,7 @@ enum
#define AVR_HAVE_JMP_CALL (avr_current_arch->have_jmp_call) #define AVR_HAVE_JMP_CALL (avr_current_arch->have_jmp_call)
#define AVR_HAVE_MUL (avr_current_arch->have_mul) #define AVR_HAVE_MUL (avr_current_arch->have_mul)
#define AVR_HAVE_MOVW (avr_current_arch->have_movw_lpmx) #define AVR_HAVE_MOVW (avr_current_arch->have_movw_lpmx)
#define AVR_HAVE_LPM (!AVR_TINY)
#define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx) #define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx)
#define AVR_HAVE_ELPM (avr_current_arch->have_elpm) #define AVR_HAVE_ELPM (avr_current_arch->have_elpm)
#define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx) #define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx)
...@@ -99,6 +100,7 @@ FIXME: DRIVER_SELF_SPECS has changed. ...@@ -99,6 +100,7 @@ FIXME: DRIVER_SELF_SPECS has changed.
#define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL) #define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
#define AVR_XMEGA (avr_current_arch->xmega_p) #define AVR_XMEGA (avr_current_arch->xmega_p)
#define AVR_TINY (avr_current_arch->tiny_p)
#define BITS_BIG_ENDIAN 0 #define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0 #define BYTES_BIG_ENDIAN 0
...@@ -305,7 +307,7 @@ enum reg_class { ...@@ -305,7 +307,7 @@ enum reg_class {
#define ARG_POINTER_REGNUM 34 #define ARG_POINTER_REGNUM 34
#define STATIC_CHAIN_REGNUM 2 #define STATIC_CHAIN_REGNUM ((AVR_TINY) ? 18 :2)
#define ELIMINABLE_REGS { \ #define ELIMINABLE_REGS { \
{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
......
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
;; B Add 1 to REG number, MEM address or CONST_INT. ;; B Add 1 to REG number, MEM address or CONST_INT.
;; C Add 2. ;; C Add 2.
;; D Add 3. ;; D Add 3.
;; E reg number in XEXP(x, 0).
;; F Add 1 to reg number.
;; I reg number in XEXP(XEXP(x, 0), 0).
;; J Add 1 to reg number.
;; j Branch condition. ;; j Branch condition.
;; k Reverse branch condition. ;; k Reverse branch condition.
;;..m..Constant Direct Data memory address. ;;..m..Constant Direct Data memory address.
...@@ -59,6 +63,11 @@ ...@@ -59,6 +63,11 @@
(ZERO_REGNO 1) ; zero register r1 (ZERO_REGNO 1) ; zero register r1
]) ])
(define_constants
[ (TMP_REGNO_TINY 16) ; r16 is temp register for AVR_TINY
(ZERO_REGNO_TINY 17) ; r17 is zero register for AVR_TINY
])
(define_c_enum "unspec" (define_c_enum "unspec"
[UNSPEC_STRLEN [UNSPEC_STRLEN
UNSPEC_MOVMEM UNSPEC_MOVMEM
...@@ -159,9 +168,10 @@ ...@@ -159,9 +168,10 @@
;; lpm : ISA has no LPMX lpmx : ISA has LPMX ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
;; no_xmega: non-XMEGA core xmega : XMEGA core ;; no_xmega: non-XMEGA core xmega : XMEGA core
;; no_tiny: non-TINY core tiny : TINY core
(define_attr "isa" (define_attr "isa"
"mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, no_tiny,tiny,
standard" standard"
(const_string "standard")) (const_string "standard"))
...@@ -213,9 +223,18 @@ ...@@ -213,9 +223,18 @@
(match_test "AVR_XMEGA")) (match_test "AVR_XMEGA"))
(const_int 1) (const_int 1)
(and (eq_attr "isa" "tiny")
(match_test "AVR_TINY"))
(const_int 1)
(and (eq_attr "isa" "no_xmega") (and (eq_attr "isa" "no_xmega")
(match_test "!AVR_XMEGA")) (match_test "!AVR_XMEGA"))
(const_int 1) (const_int 1)
(and (eq_attr "isa" "no_tiny")
(match_test "!AVR_TINY"))
(const_int 1)
] (const_int 0))) ] (const_int 0)))
...@@ -620,6 +639,33 @@ ...@@ -620,6 +639,33 @@
emit_insn (gen_load<mode>_libgcc (dest, src)); emit_insn (gen_load<mode>_libgcc (dest, src));
DONE; DONE;
} }
/* AVRTC-579
if the source operand expression is out of range for 'lds' instruction
copy source operand expression to register
For tiny core, LDS instruction's memory access range limited to 0x40..0xbf
*/
if (!tiny_valid_direct_memory_access_range(src,<MODE>mode))
{
rtx srcx = XEXP(src,0);
operands[1] = src = replace_equiv_address (src,copy_to_mode_reg (GET_MODE(srcx),srcx));
emit_move_insn(dest,src);
DONE;
}
/* AVRTC-579
if the destination operand expression is out of range for 'sts' instruction
copy destination operand expression to register
For tiny core, STS instruction's memory access range limited to 0x40..0xbf
*/
if (!tiny_valid_direct_memory_access_range(dest,<MODE>mode))
{
rtx destx = XEXP(dest,0);
operands[0] = dest = replace_equiv_address (dest,copy_to_mode_reg (GET_MODE(destx),destx));
emit_move_insn(dest,src);
DONE;
}
}) })
;;======================================================================== ;;========================================================================
...@@ -636,8 +682,13 @@ ...@@ -636,8 +682,13 @@
(define_insn "mov<mode>_insn" (define_insn "mov<mode>_insn"
[(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
(match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
"register_operand (operands[0], <MODE>mode) "(register_operand (operands[0], <MODE>mode)
|| reg_or_0_operand (operands[1], <MODE>mode)" || reg_or_0_operand (operands[1], <MODE>mode)) &&
/* skip if operands are out of lds/sts memory access range(0x40..0xbf)
though access range is checked during define_expand, it is required
here to avoid merging rtls during combine pass */
tiny_valid_direct_memory_access_range(operands[0],QImode) &&
tiny_valid_direct_memory_access_range(operands[1],QImode)"
{ {
return output_movqi (insn, operands, NULL); return output_movqi (insn, operands, NULL);
} }
...@@ -730,8 +781,13 @@ ...@@ -730,8 +781,13 @@
(define_insn "*mov<mode>" (define_insn "*mov<mode>"
[(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r") [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
(match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))] (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
"register_operand (operands[0], <MODE>mode) "(register_operand (operands[0], <MODE>mode)
|| reg_or_0_operand (operands[1], <MODE>mode)" || reg_or_0_operand (operands[1], <MODE>mode)) &&
/* skip if operands are out of lds/sts memory access range(0x40..0xbf)
though access range is checked during define_expand, it is required
here to avoid merging rtls during combine pass */
tiny_valid_direct_memory_access_range(operands[0],HImode) &&
tiny_valid_direct_memory_access_range(operands[1],HImode)"
{ {
return output_movhi (insn, operands, NULL); return output_movhi (insn, operands, NULL);
} }
...@@ -879,8 +935,13 @@ ...@@ -879,8 +935,13 @@
(define_insn "*mov<mode>" (define_insn "*mov<mode>"
[(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r") [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
(match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))] (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
"register_operand (operands[0], <MODE>mode) "(register_operand (operands[0], <MODE>mode)
|| reg_or_0_operand (operands[1], <MODE>mode)" || reg_or_0_operand (operands[1], <MODE>mode)) &&
/* skip if operands are out of lds/sts memory access range(0x40..0xbf)
though access range is checked during define_expand, it is required
here to avoid merging rtls during combine pass */
tiny_valid_direct_memory_access_range(operands[0],SImode) &&
tiny_valid_direct_memory_access_range(operands[1],SImode)"
{ {
return output_movsisf (insn, operands, NULL); return output_movsisf (insn, operands, NULL);
} }
...@@ -894,8 +955,13 @@ ...@@ -894,8 +955,13 @@
(define_insn "*movsf" (define_insn "*movsf"
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
(match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))] (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
"register_operand (operands[0], SFmode) "(register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode)" || reg_or_0_operand (operands[1], SFmode)) &&
/* skip if operands are out of lds/sts memory access range(0x40..0xbf)
though access range is checked during define_expand, it is required
here to avoid merging rtls during combine pass */
tiny_valid_direct_memory_access_range(operands[0],SFmode) &&
tiny_valid_direct_memory_access_range(operands[1],SFmode)"
{ {
return output_movsisf (insn, operands, NULL); return output_movsisf (insn, operands, NULL);
} }
...@@ -5551,18 +5617,18 @@ ...@@ -5551,18 +5617,18 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "delay_cycles_2" (define_insn "delay_cycles_2"
[(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n") [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
(const_int 2)] (const_int 2)]
UNSPECV_DELAY_CYCLES) UNSPECV_DELAY_CYCLES)
(set (match_operand:BLK 1 "" "") (set (match_operand:BLK 1 "" "")
(unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
(clobber (match_scratch:HI 2 "=&w"))] (clobber (match_scratch:HI 2 "=&w,&d"))]
"" ""
"ldi %A2,lo8(%0) "@
ldi %B2,hi8(%0) ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\;1: sbiw %A2,1\;brne 1b
1: sbiw %A2,1 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\;1: subi %A2,1\;sbci %B2,0\;brne 1b"
brne 1b" [(set_attr "length" "4,5")
[(set_attr "length" "4") (set_attr "isa" "no_tiny,tiny")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
(define_insn "delay_cycles_3" (define_insn "delay_cycles_3"
......
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
# along with GCC; see the file COPYING3. If not see # along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. # <http://www.gnu.org/licenses/>.
MULTILIB_OPTIONS = march=avr2/march=avr25/march=avr3/march=avr31/march=avr35/march=avr4/march=avr5/march=avr51/march=avr6/march=avrxmega2/march=avrxmega4/march=avrxmega5/march=avrxmega6/march=avrxmega7 msp8 MULTILIB_OPTIONS = march=avr2/march=avr25/march=avr3/march=avr31/march=avr35/march=avr4/march=avr5/march=avr51/march=avr6/march=avrxmega2/march=avrxmega4/march=avrxmega5/march=avrxmega6/march=avrxmega7/march=avrtiny msp8
MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack avr25/tiny-stack MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack avr25/tiny-stack
MULTILIB_EXCEPTIONS = \ MULTILIB_EXCEPTIONS = \
march=avr3/msp8 \ march=avr3/msp8 \
...@@ -37,4 +37,5 @@ MULTILIB_EXCEPTIONS = \ ...@@ -37,4 +37,5 @@ MULTILIB_EXCEPTIONS = \
march=avrxmega4/msp8 \ march=avrxmega4/msp8 \
march=avrxmega5/msp8 \ march=avrxmega5/msp8 \
march=avrxmega6/msp8 \ march=avrxmega6/msp8 \
march=avrxmega7/msp8 march=avrxmega7/msp8 \
march=avrtiny/msp8
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
``XMEGA'' devices with more than 128@tie{}KiB of program memory and more than 64@tie{}KiB of RAM. ``XMEGA'' devices with more than 128@tie{}KiB of program memory and more than 64@tie{}KiB of RAM.
@*@var{mcu}@tie{}= @code{atxmega128a1}, @code{atxmega128a1u}, @code{atxmega128a4u}. @*@var{mcu}@tie{}= @code{atxmega128a1}, @code{atxmega128a1u}, @code{atxmega128a4u}.
@item avrtiny
``TINY'' Tiny core devices with 512@tie{}B up to 4@tie{}KiB of program memory.
@*@var{mcu}@tie{}= @code{attiny10}, @code{attiny20}, @code{attiny4}, @code{attiny40}, @code{attiny5}, @code{attiny9}.
@item avr1 @item avr1
This ISA is implemented by the minimal AVR core and supported for assembler only. This ISA is implemented by the minimal AVR core and supported for assembler only.
@*@var{mcu}@tie{}= @code{attiny11}, @code{attiny12}, @code{attiny15}, @code{attiny28}, @code{at90s1200}. @*@var{mcu}@tie{}= @code{attiny11}, @code{attiny12}, @code{attiny15}, @code{attiny28}, @code{at90s1200}.
......
2014-10-21 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.target/avr/tiny-memx.c: New test.
* gcc.target/avr/tiny-caller-save.c: New test.
2014-10-21 Jiong Wang <jiong.wang@arm.com> 2014-10-21 Jiong Wang <jiong.wang@arm.com>
* gcc.target/arm/20031108-1.c (Proc_7): Add explicit declaration. * gcc.target/arm/20031108-1.c (Proc_7): Add explicit declaration.
......
/* { dg-do compile } */
/* { dg-options "-march=avrtiny -gdwarf -Os" } */
/* This is a stripped down piece of libgcc2.c that triggerd an ICE for avr with
"-march=avrtiny -g -Os"; replace_reg_with_saved_mem would generate:
(concatn:SI [
(reg:SI 18 r18)
(reg:SI 19 r19)
(mem/c:QI (plus:HI (reg/f:HI 28 r28)
(const_int 43 [0x2b])) [6 S1 A8])
(mem/c:QI (plus:HI (reg/f:HI 28 r28)
(const_int 44 [0x2c])) [6 S1 A8])
]) */
typedef int SItype __attribute__ ((mode (SI)));
typedef unsigned int USItype __attribute__ ((mode (SI)));
typedef int DItype __attribute__ ((mode (DI)));
typedef unsigned int UDItype __attribute__ ((mode (DI)));
struct DWstruct
{
SItype low, high;
};
typedef union
{
struct DWstruct s;
DItype ll;
} DWunion;
UDItype
__udivmoddi4 (UDItype n, UDItype d)
{
const DWunion nn = {.ll = n };
const DWunion dd = {.ll = d };
USItype d0, d1, n2;
USItype q0;
d0 = dd.s.low;
d1 = dd.s.high;
n2 = nn.s.high;
USItype m0;
do
{
USItype __d1, __d0, __q1, __q0;
USItype __r1, __m;
__d1 = ((USItype) (d1) >> 16);
__d0 = ((USItype) (d1) & (((USItype) 1 << 16) - 1));
__r1 = (n2) % __d1;
__q1 = (n2) / __d1;
__m = (USItype) __q1 *__d0;
__r1 -= __m;
__q0 = __r1 / __d1;
(q0) = (USItype) __q1 *((USItype) 1 << 16) | __q0;
}
while (0);
do
{
USItype __x0, __x1, __x2;
USItype __ul, __vl, __uh, __vh;
__ul = ((USItype) (q0) & (((USItype) 1 << 16) - 1));
__uh = ((USItype) (q0) >> 16);
__vl = ((USItype) (d0) & (((USItype) 1 << 16) - 1));
__vh = ((USItype) (d0) >> 16);
__x0 = (USItype) __ul *__vl;
__x1 = (USItype) __ul *__vh;
__x2 = (USItype) __uh *__vl;
__x1 += ((USItype) (__x0) >> 16);
__x1 += __x2;
(m0) =
((USItype) (__x1) & (((USItype) 1 << 16) - 1)) *
((USItype) 1 << 16) +
((USItype) (__x0) & (((USItype) 1 << 16) - 1));
}
while (0);
return m0;
}
/* { dg-do compile } */
/* { dg-options "-march=avrtiny" } */
const __memx char ascmonth[] = "Jan"; /* { dg-error "not supported" } */
2014-10-21 Joern Rennecke <joern.rennecke@embecosm.com>
Vidya Praveen <vidya.praveen@atmel.com>
Praveen Kumar Kaushik <Praveen_Kumar.Kaushik@atmel.com>
Senthil Kumar Selvaraj <Senthil_Kumar.Selvaraj@atmel.com>
Pitchumani Sivanupandi <Pitchumani.S@atmel.com>
* config/avr/lib1funcs.S (__do_global_dtors): Go back to descending
order.
Updated library functions for AVRTINY arch.
* config/avr/lib1funcs.S: Updated zero/tmp regs for AVRTINY.
Replaced occurrences of r0/r1 with tmp/zero reg macros.
Added wsubi/ wadi macros that expands conditionally as sbiw/ adiw
or AVRTINY equivalent. Replaced occurrences of sbiw/adiw with
wsubi/wadi macors.
(__mulsi3_helper): Update stack, preserve callee saved regs and
argument from stack. Restore callee save registers.
(__mulpsi3): Likewise.
(__muldi3, __udivmodsi4, __divmodsi4, __negsi2, __umoddi3, __udivmod64,
__moddi3, __adddi3, __adddi3_s8, __subdi3, __cmpdi2, __cmpdi2_s8,
__negdi2, __prologue_saves__, __epilogue_restores__): Excluded for
AVRTINY.
(__tablejump2__): Added lpm equivalent instructions for AVRTINY.
(__do_copy_data): Added new definition for AVRTINY.
(__do_clear_bss): Replace r17 by r18 to preserve zero reg for AVRTINY.
(__load_3, __load_4, __xload_1, __xload_2, __xload_3,
__xload_4, __movmemx_qi, __movmemx_hi): Excluded for AVRTINY.
* config/avr/lib1funcs-fixed.S: Replaced occurrences of r0/r1 with
tmp/zero reg macros. Replaced occurrences of sbiw/adiw with wsubi/wadi
macors.
* config/avr/t-avr (LIB1ASMFUNCS): Remove unsupported functions for
AVRTINY.
Fix broken long multiplication on tiny arch.
2014-10-09 Joseph Myers <joseph@codesourcery.com> 2014-10-09 Joseph Myers <joseph@codesourcery.com>
* soft-fp/double.h: Update from glibc. * soft-fp/double.h: Update from glibc.
......
...@@ -31,8 +31,18 @@ ...@@ -31,8 +31,18 @@
;; Fixed point library routines for AVR ;; Fixed point library routines for AVR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#if defined __AVR_TINY__
#define __zero_reg__ r17
#define __tmp_reg__ r16
#else
#define __zero_reg__ r1
#define __tmp_reg__ r0
#endif
.section .text.libgcc.fixed, "ax", @progbits .section .text.libgcc.fixed, "ax", @progbits
#ifndef __AVR_TINY__
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Conversions to float ;; Conversions to float
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
...@@ -1913,3 +1923,5 @@ DEFUN __ret ...@@ -1913,3 +1923,5 @@ DEFUN __ret
ret ret
ENDF __ret ENDF __ret
#endif /* L_ret */ #endif /* L_ret */
#endif /* if not __AVR_TINY__ */
...@@ -3,12 +3,7 @@ LIB1ASMFUNCS = \ ...@@ -3,12 +3,7 @@ LIB1ASMFUNCS = \
_mulqi3 \ _mulqi3 \
_mulhi3 \ _mulhi3 \
_mulqihi3 _umulqihi3 \ _mulqihi3 _umulqihi3 \
_mulpsi3 _mulsqipsi3 \ _mulpsi3 \
_mulhisi3 \
_umulhisi3 \
_usmulhisi3 \
_muluhisi3 \
_mulshisi3 \
_mulsi3 \ _mulsi3 \
_udivmodqi4 \ _udivmodqi4 \
_divmodqi4 \ _divmodqi4 \
...@@ -17,19 +12,10 @@ LIB1ASMFUNCS = \ ...@@ -17,19 +12,10 @@ LIB1ASMFUNCS = \
_divmodpsi4 _udivmodpsi4 \ _divmodpsi4 _udivmodpsi4 \
_udivmodsi4 \ _udivmodsi4 \
_divmodsi4 \ _divmodsi4 \
_divdi3 _udivdi3 \ _negsi2 \
_muldi3 _muldi3_6 \
_mulsidi3 _umulsidi3 \
_udivmod64 \
_negsi2 _negdi2 \
_prologue \
_epilogue \
_exit \ _exit \
_cleanup \ _cleanup \
_tablejump2 \ _tablejump2 \
_load_3 _load_4 \
_xload_1 _xload_2 _xload_3 _xload_4 \
_movmemx \
_copy_data \ _copy_data \
_clear_bss \ _clear_bss \
_ctors \ _ctors \
...@@ -39,24 +25,54 @@ LIB1ASMFUNCS = \ ...@@ -39,24 +25,54 @@ LIB1ASMFUNCS = \
_loop_ffsqi2 \ _loop_ffsqi2 \
_ctzsi2 \ _ctzsi2 \
_ctzhi2 \ _ctzhi2 \
_clzdi2 \
_clzsi2 \ _clzsi2 \
_clzhi2 \ _clzhi2 \
_paritydi2 \
_paritysi2 \ _paritysi2 \
_parityhi2 \ _parityhi2 \
_popcounthi2 \ _popcounthi2 \
_popcountsi2 \ _popcountsi2 \
_popcountdi2 \
_popcountqi2 \ _popcountqi2 \
_bswapsi2 \ _bswapsi2 \
_fmul _fmuls _fmulsu
# The below functions either use registers that are not present
# in tiny core, or use a different register conventions (don't save
# callee saved regs, for example)
# _mulhisi3 and variations - clobber R18, R19
# All *di funcs - use regs < R16 or expect args in regs < R20
# _prologue and _epilogue save registers < R16
# _load ad _xload variations - expect lpm and elpm support
# _movmemx - expects elpm/lpm
ifneq ($(MULTIFLAGS),-mmcu=avrtiny)
LIB1ASMFUNCS += \
_mulsqipsi3 \
_mulhisi3 \
_umulhisi3 \
_usmulhisi3 \
_muluhisi3 \
_mulshisi3 \
_muldi3 _muldi3_6 \
_mulsidi3 _umulsidi3 \
_divdi3 _udivdi3 \
_udivmod64 \
_negdi2 \
_prologue \
_epilogue \
_load_3 _load_4 \
_xload_1 _xload_2 _xload_3 _xload_4 \
_movmemx \
_clzdi2 \
_paritydi2 \
_popcountdi2 \
_bswapdi2 \ _bswapdi2 \
_ashldi3 _ashrdi3 _lshrdi3 _rotldi3 \ _ashldi3 _ashrdi3 _lshrdi3 _rotldi3 \
_adddi3 _adddi3_s8 _subdi3 \ _adddi3 _adddi3_s8 _subdi3 \
_cmpdi2 _cmpdi2_s8 \ _cmpdi2 _cmpdi2_s8
_fmul _fmuls _fmulsu endif
# Fixed point routines in avr/lib1funcs-fixed.S # Fixed point routines in avr/lib1funcs-fixed.S
ifneq ($(MULTIFLAGS),-mmcu=avrtiny)
LIB1ASMFUNCS += \ LIB1ASMFUNCS += \
_fractqqsf _fractuqqsf \ _fractqqsf _fractuqqsf \
_fracthqsf _fractuhqsf _fracthasf _fractuhasf \ _fracthqsf _fractuhqsf _fracthasf _fractuhasf \
...@@ -87,8 +103,8 @@ LIB1ASMFUNCS += \ ...@@ -87,8 +103,8 @@ LIB1ASMFUNCS += \
_round_x8 \ _round_x8 \
_rounddq3 _roundudq3 \ _rounddq3 _roundudq3 \
_roundda3 _rounduda3 \ _roundda3 _rounduda3 \
_roundta3 _rounduta3 \ _roundta3 _rounduta3
endif
LIB2FUNCS_EXCLUDE = \ LIB2FUNCS_EXCLUDE = \
_moddi3 _umoddi3 \ _moddi3 _umoddi3 \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment