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>
* doc/invoke.texi (AARCH64/mtune): Document thunderx as an
......@@ -37,6 +37,7 @@ enum avr_arch
ARCH_AVR5,
ARCH_AVR51,
ARCH_AVR6,
ARCH_AVRTINY,
ARCH_AVRXMEGA2,
ARCH_AVRXMEGA4,
ARCH_AVRXMEGA5,
......@@ -77,6 +78,9 @@ typedef struct
and thus also the RAMPX, RAMPY and RAMPZ registers. */
int have_rampd;
/* This is a TINY core. */
int tiny_p;
/* Default start of data section address for architecture. */
int default_data_section_start;
......
......@@ -321,6 +321,23 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
}
if (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)
{
cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
......@@ -376,7 +393,10 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
/* Only supply __FLASH<n> macro if the address space is reasonable
for this target. The address space qualifier itself is still
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;
char *Name = (char*) alloca (1 + strlen (name));
......
......@@ -31,29 +31,30 @@ const avr_arch_t
avr_arch_types[] =
{
/* 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
S U M PO L L I M A a t F ff r
M L P MV P P J E M t a R s c
XW M M M G P a r e h
X P A D t t ID */
{ 1, 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, 1, 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, 1, 0, 0, 0, 0, 0x0060, 32, "31", "avr31" },
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0x0060, 32, "35", "avr35" },
{ 0, 1, 0, 1, 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, 1, 1, 0, 0, 0, 0x0060, 32, "51", "avr51" },
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, 32, "6", "avr6" },
A M J LM E E E X R T d S S O A
S U M PO L L I M A I a t F ff r
M L P MV P P J E M N t a R s c
XW M M M G P Y a r e h
X P A D t t ID */
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "1", "avr1" },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "2", "avr2" },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "25", "avr25" },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "3", "avr3" },
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "31", "avr31" },
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "35", "avr35" },
{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "4", "avr4" },
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "5", "avr5" },
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0x0060, 32, "51", "avr51" },
{ 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, 1, 1, 1, 1, 1, 0, 1, 0, 0x2000, 0, "104", "avrxmega4" },
{ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0x2000, 0, "105", "avrxmega5" },
{ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, "106", "avrxmega6" },
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0x2000, 0, "107", "avrxmega7" }
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x0040, 0, "100", "avrtiny" },
{ 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0, "102", "avrxmega2" },
{ 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0x2000, 0, "104", "avrxmega4" },
{ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0x2000, 0, "105", "avrxmega5" },
{ 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
......@@ -85,6 +86,9 @@ avr_texinfo[] =
{ ARCH_AVR6,
"``Enhanced'' devices with 3-byte PC, i.e.@: with more than 128@tie{}KiB "
"of program memory." },
{ ARCH_AVRTINY,
"``TINY'' Tiny core devices with 512@tie{}B up to 4@tie{}KiB of "
"program memory." },
{ ARCH_AVRXMEGA2,
"``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB "
"of program memory." },
......
......@@ -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 ("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")
/* 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. */
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")
......
......@@ -46,6 +46,7 @@ extern void avr_init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx, tree);
#ifdef RTX_CODE
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_movhi (rtx_insn *insn, rtx operands[], int *l);
extern const char *output_movsisf (rtx_insn *insn, rtx operands[], int *l);
......
......@@ -66,5 +66,8 @@ EnumValue
Enum(avr_arch) String(avrxmega7) Value(ARCH_AVRXMEGA7)
EnumValue
Enum(avr_arch) String(avrtiny) Value(ARCH_AVRTINY)
EnumValue
Enum(avr_arch) String(avr1) Value(ARCH_AVR1)
......@@ -63,6 +63,7 @@ enum
#define AVR_HAVE_JMP_CALL (avr_current_arch->have_jmp_call)
#define AVR_HAVE_MUL (avr_current_arch->have_mul)
#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_ELPM (avr_current_arch->have_elpm)
#define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx)
......@@ -99,6 +100,7 @@ FIXME: DRIVER_SELF_SPECS has changed.
#define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
#define AVR_XMEGA (avr_current_arch->xmega_p)
#define AVR_TINY (avr_current_arch->tiny_p)
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0
......@@ -305,7 +307,7 @@ enum reg_class {
#define ARG_POINTER_REGNUM 34
#define STATIC_CHAIN_REGNUM 2
#define STATIC_CHAIN_REGNUM ((AVR_TINY) ? 18 :2)
#define ELIMINABLE_REGS { \
{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
......
......@@ -24,6 +24,10 @@
;; B Add 1 to REG number, MEM address or CONST_INT.
;; C Add 2.
;; 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.
;; k Reverse branch condition.
;;..m..Constant Direct Data memory address.
......@@ -59,6 +63,11 @@
(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"
[UNSPEC_STRLEN
UNSPEC_MOVMEM
......@@ -159,9 +168,10 @@
;; lpm : ISA has no LPMX lpmx : ISA has LPMX
;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
;; no_xmega: non-XMEGA core xmega : XMEGA core
;; no_tiny: non-TINY core tiny : TINY core
(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"
(const_string "standard"))
......@@ -213,9 +223,18 @@
(match_test "AVR_XMEGA"))
(const_int 1)
(and (eq_attr "isa" "tiny")
(match_test "AVR_TINY"))
(const_int 1)
(and (eq_attr "isa" "no_xmega")
(match_test "!AVR_XMEGA"))
(const_int 1)
(and (eq_attr "isa" "no_tiny")
(match_test "!AVR_TINY"))
(const_int 1)
] (const_int 0)))
......@@ -620,6 +639,33 @@
emit_insn (gen_load<mode>_libgcc (dest, src));
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 @@
(define_insn "mov<mode>_insn"
[(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"))]
"register_operand (operands[0], <MODE>mode)
|| reg_or_0_operand (operands[1], <MODE>mode)"
"(register_operand (operands[0], <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);
}
......@@ -730,8 +781,13 @@
(define_insn "*mov<mode>"
[(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"))]
"register_operand (operands[0], <MODE>mode)
|| reg_or_0_operand (operands[1], <MODE>mode)"
"(register_operand (operands[0], <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);
}
......@@ -879,8 +935,13 @@
(define_insn "*mov<mode>"
[(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"))]
"register_operand (operands[0], <MODE>mode)
|| reg_or_0_operand (operands[1], <MODE>mode)"
"(register_operand (operands[0], <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);
}
......@@ -894,8 +955,13 @@
(define_insn "*movsf"
[(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"))]
"register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode)"
"(register_operand (operands[0], 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);
}
......@@ -5551,18 +5617,18 @@
(set_attr "cc" "clobber")])
(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)]
UNSPECV_DELAY_CYCLES)
(set (match_operand:BLK 1 "" "")
(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)
1: sbiw %A2,1
brne 1b"
[(set_attr "length" "4")
"@
ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\;1: sbiw %A2,1\;brne 1b
ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\;1: subi %A2,1\;sbci %B2,0\;brne 1b"
[(set_attr "length" "4,5")
(set_attr "isa" "no_tiny,tiny")
(set_attr "cc" "clobber")])
(define_insn "delay_cycles_3"
......
......@@ -21,9 +21,9 @@
# along with GCC; see the file COPYING3. If not see
# <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 = \
march=avr3/msp8 \
......@@ -37,4 +37,5 @@ MULTILIB_EXCEPTIONS = \
march=avrxmega4/msp8 \
march=avrxmega5/msp8 \
march=avrxmega6/msp8 \
march=avrxmega7/msp8
march=avrxmega7/msp8 \
march=avrtiny/msp8
......@@ -68,6 +68,10 @@
``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}.
@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
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}.
......
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>
* 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>
* soft-fp/double.h: Update from glibc.
......
......@@ -31,8 +31,18 @@
;; 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
#ifndef __AVR_TINY__
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Conversions to float
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
......@@ -1913,3 +1923,5 @@ DEFUN __ret
ret
ENDF __ret
#endif /* L_ret */
#endif /* if not __AVR_TINY__ */
......@@ -3,12 +3,7 @@ LIB1ASMFUNCS = \
_mulqi3 \
_mulhi3 \
_mulqihi3 _umulqihi3 \
_mulpsi3 _mulsqipsi3 \
_mulhisi3 \
_umulhisi3 \
_usmulhisi3 \
_muluhisi3 \
_mulshisi3 \
_mulpsi3 \
_mulsi3 \
_udivmodqi4 \
_divmodqi4 \
......@@ -17,19 +12,10 @@ LIB1ASMFUNCS = \
_divmodpsi4 _udivmodpsi4 \
_udivmodsi4 \
_divmodsi4 \
_divdi3 _udivdi3 \
_muldi3 _muldi3_6 \
_mulsidi3 _umulsidi3 \
_udivmod64 \
_negsi2 _negdi2 \
_prologue \
_epilogue \
_negsi2 \
_exit \
_cleanup \
_tablejump2 \
_load_3 _load_4 \
_xload_1 _xload_2 _xload_3 _xload_4 \
_movmemx \
_copy_data \
_clear_bss \
_ctors \
......@@ -39,24 +25,54 @@ LIB1ASMFUNCS = \
_loop_ffsqi2 \
_ctzsi2 \
_ctzhi2 \
_clzdi2 \
_clzsi2 \
_clzhi2 \
_paritydi2 \
_paritysi2 \
_parityhi2 \
_popcounthi2 \
_popcountsi2 \
_popcountdi2 \
_popcountqi2 \
_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 \
_ashldi3 _ashrdi3 _lshrdi3 _rotldi3 \
_adddi3 _adddi3_s8 _subdi3 \
_cmpdi2 _cmpdi2_s8 \
_fmul _fmuls _fmulsu
_cmpdi2 _cmpdi2_s8
endif
# Fixed point routines in avr/lib1funcs-fixed.S
ifneq ($(MULTIFLAGS),-mmcu=avrtiny)
LIB1ASMFUNCS += \
_fractqqsf _fractuqqsf \
_fracthqsf _fractuhqsf _fracthasf _fractuhasf \
......@@ -87,8 +103,8 @@ LIB1ASMFUNCS += \
_round_x8 \
_rounddq3 _roundudq3 \
_roundda3 _rounduda3 \
_roundta3 _rounduta3 \
_roundta3 _rounduta3
endif
LIB2FUNCS_EXCLUDE = \
_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