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
This commit is contained in:
Joern Rennecke 2014-10-21 20:12:01 +00:00 committed by Joern Rennecke
parent d1bcc29f79
commit c1dd979024
19 changed files with 1429 additions and 154 deletions

View File

@ -1,3 +1,119 @@
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

View File

@ -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
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;

View File

@ -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)
/* 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));

View File

@ -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[] =
{ 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." },

View File

@ -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")

View File

@ -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);

View File

@ -65,6 +65,9 @@ Enum(avr_arch) String(avrxmega6) Value(ARCH_AVRXMEGA6)
EnumValue EnumValue
Enum(avr_arch) String(avrxmega7) Value(ARCH_AVRXMEGA7) Enum(avr_arch) String(avrxmega7) Value(ARCH_AVRXMEGA7)
EnumValue
Enum(avr_arch) String(avrtiny) Value(ARCH_AVRTINY)
EnumValue EnumValue
Enum(avr_arch) String(avr1) Value(ARCH_AVR1) Enum(avr_arch) String(avr1) Value(ARCH_AVR1)

File diff suppressed because it is too large Load Diff

View File

@ -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.
#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 {
#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}, \

View File

@ -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 @@
(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 @@
;; 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 @@
(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 @@
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 @@
(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 @@
(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 @@
(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 @@
(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 @@
(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"

View File

@ -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 = \
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

View File

@ -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}.

View File

@ -1,3 +1,9 @@
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.

View File

@ -0,0 +1,78 @@
/* { 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;
}

View File

@ -0,0 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-march=avrtiny" } */
const __memx char ascmonth[] = "Jan"; /* { dg-error "not supported" } */

View File

@ -1,3 +1,38 @@
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.

View File

@ -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
ret ret
ENDF __ret ENDF __ret
#endif /* L_ret */ #endif /* L_ret */
#endif /* if not __AVR_TINY__ */

View File

@ -21,8 +21,13 @@ a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#if defined (__AVR_TINY__)
#define __zero_reg__ r17
#define __tmp_reg__ r16
#else
#define __zero_reg__ r1 #define __zero_reg__ r1
#define __tmp_reg__ r0 #define __tmp_reg__ r0
#endif
#define __SREG__ 0x3f #define __SREG__ 0x3f
#if defined (__AVR_HAVE_SPH__) #if defined (__AVR_HAVE_SPH__)
#define __SP_H__ 0x3e #define __SP_H__ 0x3e
@ -126,6 +131,24 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
;; Support function entry and exit for convenience ;; Support function entry and exit for convenience
.macro wsubi r_arg1, i_arg2
#if defined (__AVR_TINY__)
subi \r_arg1, lo8(\i_arg2)
sbci \r_arg1+1, hi8(\i_arg2)
#else
sbiw \r_arg1, \i_arg2
#endif
.endm
.macro waddi r_arg1, i_arg2
#if defined (__AVR_TINY__)
subi \r_arg1, lo8(-\i_arg2)
sbci \r_arg1+1, hi8(-\i_arg2)
#else
adiw \r_arg1, \i_arg2
#endif
.endm
.macro DEFUN name .macro DEFUN name
.global \name .global \name
.func \name .func \name
@ -146,7 +169,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
.endm .endm
;; Skip next instruction, typically a jump target ;; Skip next instruction, typically a jump target
#if defined(__AVR_TINY__)
#define skip cpse 0,0 #define skip cpse 0,0
#else
#define skip cpse 16,16
#endif
;; Negate a 2-byte value held in consecutive registers ;; Negate a 2-byte value held in consecutive registers
.macro NEG2 reg .macro NEG2 reg
@ -219,16 +246,16 @@ ENDF __mulqi3
Multiplication 16 x 16 without MUL Multiplication 16 x 16 without MUL
*******************************************************/ *******************************************************/
#define A0 r22 #define A0 22
#define A1 r23 #define A1 23
#define B0 r24 #define B0 24
#define BB0 r20 #define BB0 20
#define B1 r25 #define B1 25
;; Output overlaps input, thus expand result in CC0/1 ;; Output overlaps input, thus expand result in CC0/1
#define C0 r24 #define C0 24
#define C1 r25 #define C1 25
#define CC0 __tmp_reg__ #define CC0 __tmp_reg__
#define CC1 R21 #define CC1 21
#if defined (L_umulqihi3) #if defined (L_umulqihi3)
;;; R25:R24 = (unsigned int) R22 * (unsigned int) R24 ;;; R25:R24 = (unsigned int) R22 * (unsigned int) R24
@ -294,7 +321,7 @@ DEFUN __mulhi3
rol B1 rol B1
3: 3:
;; If B == 0 we are ready ;; If B == 0 we are ready
sbiw B0, 0 wsubi B0, 0
breq 9f breq 9f
;; Carry = n-th bit of A ;; Carry = n-th bit of A
@ -402,6 +429,18 @@ ENDF __mulhisi3
#if defined (L_mulsi3) #if defined (L_mulsi3)
DEFUN __mulsi3 DEFUN __mulsi3
#if defined (__AVR_TINY__)
in r26, __SP_L__ ; safe to use X, as it is CC0/CC1
in r27, __SP_H__
subi r26, lo8(-3) ; Add 3 to point past return address
sbci r27, hi8(-3)
push B0 ; save callee saved regs
push B1
ld B0, X+ ; load from caller stack
ld B1, X+
ld B2, X+
ld B3, X
#endif
;; Clear result ;; Clear result
clr CC2 clr CC2
clr CC3 clr CC3
@ -427,12 +466,17 @@ DEFUN __mulsi3_helper
;; Only continue if A != 0 ;; Only continue if A != 0
sbci A1, 0 sbci A1, 0
brne 2b brne 2b
sbiw A2, 0 wsubi A2, 0
brne 2b brne 2b
;; All bits of A are consumed: Copy result to return register C ;; All bits of A are consumed: Copy result to return register C
wmov C0, CC0 wmov C0, CC0
wmov C2, CC2 wmov C2, CC2
#if defined (__AVR_TINY__)
pop B1 ; restore callee saved regs
pop B0
#endif /* defined (__AVR_TINY__) */
ret ret
ENDF __mulsi3_helper ENDF __mulsi3_helper
#endif /* L_mulsi3 */ #endif /* L_mulsi3 */
@ -682,9 +726,12 @@ ENDF __mulpsi3
#undef C0 #undef C0
#else /* !HAVE_MUL */ #else /* !HAVE_MUL */
;; C[0..2]: Expand Result ;; C[0..2]: Expand Result
#if defined (__AVR_TINY__)
#define C0 16
#else
#define C0 0 #define C0 0
#endif /* defined (__AVR_TINY__) */
#define C1 C0+1 #define C1 C0+1
#define C2 21 #define C2 21
@ -692,6 +739,17 @@ ENDF __mulpsi3
;; Clobbers: __tmp_reg__, R18, R19, R20, R21 ;; Clobbers: __tmp_reg__, R18, R19, R20, R21
DEFUN __mulpsi3 DEFUN __mulpsi3
#if defined (__AVR_TINY__)
in r26,__SP_L__
in r27,__SP_H__
subi r26, lo8(-3) ; Add 3 to point past return address
sbci r27, hi8(-3)
push B0 ; save callee saved regs
push B1
ld B0,X+ ; load from caller stack
ld B1,X+
ld B2,X+
#endif /* defined (__AVR_TINY__) */
;; C[] = 0 ;; C[] = 0
clr __tmp_reg__ clr __tmp_reg__
@ -718,6 +776,10 @@ DEFUN __mulpsi3
mov A2, C2 mov A2, C2
clr __zero_reg__ clr __zero_reg__
#if defined (__AVR_TINY__)
pop B1
pop B0
#endif /* (__AVR_TINY__) */
ret ret
ENDF __mulpsi3 ENDF __mulpsi3
@ -809,8 +871,8 @@ ENDF __mulsqipsi3
#define B6 B0+6 #define B6 B0+6
#define B7 B0+7 #define B7 B0+7
#ifndef __AVR_TINY__
#if defined (__AVR_HAVE_MUL__) #if defined (__AVR_HAVE_MUL__)
;; Define C[] for convenience ;; Define C[] for convenience
;; Notice that parts of C[] overlap A[] respective B[] ;; Notice that parts of C[] overlap A[] respective B[]
#define C0 16 #define C0 16
@ -1012,6 +1074,7 @@ ENDF __muldi3
#endif /* L_muldi3 */ #endif /* L_muldi3 */
#endif /* HAVE_MUL */ #endif /* HAVE_MUL */
#endif /* if not __AVR_TINY__ */
#undef B7 #undef B7
#undef B6 #undef B6
@ -1169,7 +1232,7 @@ ENDF __mulsidi3
/********************************************************** /**********************************************************
Widening Multiplication 64 = 32 x 32 without MUL Widening Multiplication 64 = 32 x 32 without MUL
**********************************************************/ **********************************************************/
#ifndef __AVR_TINY__ /* if not __AVR_TINY__ */
#if defined (L_mulsidi3) && !defined (__AVR_HAVE_MUL__) #if defined (L_mulsidi3) && !defined (__AVR_HAVE_MUL__)
#define A0 18 #define A0 18
#define A1 A0+1 #define A1 A0+1
@ -1265,7 +1328,7 @@ ENDF __umulsidi3
#undef BB3 #undef BB3
#undef Mask #undef Mask
#endif /* L_mulsidi3 && !HAVE_MUL */ #endif /* L_mulsidi3 && !HAVE_MUL */
#endif /* if not __AVR_TINY__ */
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -1437,7 +1500,7 @@ ENDF __divmodhi4
#define r_cnt 21 #define r_cnt 21
#if defined (L_udivmodpsi4) #if defined (L_udivmodpsi4)
;; R24:R22 = R24:R22 udiv R20:R18 ;; R24:R22 = R24:R24 udiv R20:R18
;; R20:R18 = R24:R22 umod R20:R18 ;; R20:R18 = R24:R22 umod R20:R18
;; Clobbers: R21, R25, R26 ;; Clobbers: R21, R25, R26
@ -1672,6 +1735,10 @@ ENDF __negsi2
#undef r_arg2L #undef r_arg2L
#undef r_cnt #undef r_cnt
/* *di routines use registers below R19 and won't work with tiny arch
right now. */
#if !defined (__AVR_TINY__)
/******************************************************* /*******************************************************
Division 64 / 64 Division 64 / 64
Modulo 64 % 64 Modulo 64 % 64
@ -2087,12 +2154,15 @@ ENDF __negdi2
#undef A1 #undef A1
#undef A0 #undef A0
#endif /* !defined (__AVR_TINY__) */
.section .text.libgcc.prologue, "ax", @progbits .section .text.libgcc.prologue, "ax", @progbits
/********************************** /**********************************
* This is a prologue subroutine * This is a prologue subroutine
**********************************/ **********************************/
#if !defined (__AVR_TINY__)
#if defined (L_prologue) #if defined (L_prologue)
;; This function does not clobber T-flag; 64-bit division relies on it ;; This function does not clobber T-flag; 64-bit division relies on it
@ -2194,6 +2264,7 @@ DEFUN __epilogue_restores__
ret ret
ENDF __epilogue_restores__ ENDF __epilogue_restores__
#endif /* defined (L_epilogue) */ #endif /* defined (L_epilogue) */
#endif /* !defined (__AVR_TINY__) */
#ifdef L_exit #ifdef L_exit
.section .fini9,"ax",@progbits .section .fini9,"ax",@progbits
@ -2259,6 +2330,12 @@ DEFUN __tablejump2__
lpm r31, Z lpm r31, Z
mov r30, __tmp_reg__ mov r30, __tmp_reg__
ijmp ijmp
#elif defined (__AVR_TINY__)
wsubi 30, -(__AVR_TINY_PM_BASE_ADDRESS__) ; Add PM offset to Z
ld __tmp_reg__, Z+
ld r31, Z ; Use ld instead of lpm to load Z
mov r30, __tmp_reg__
ijmp
#else #else
lpm lpm
push r0 push r0
@ -2270,6 +2347,26 @@ DEFUN __tablejump2__
ENDF __tablejump2__ ENDF __tablejump2__
#endif /* L_tablejump2 */ #endif /* L_tablejump2 */
#if defined(__AVR_TINY__)
#ifdef L_copy_data
.section .init4,"ax",@progbits
.global __do_copy_data
__do_copy_data:
ldi r18, hi8(__data_end)
ldi r26, lo8(__data_start)
ldi r27, hi8(__data_start)
ldi r30, lo8(__data_load_start + __AVR_TINY_PM_BASE_ADDRESS__)
ldi r31, hi8(__data_load_start + __AVR_TINY_PM_BASE_ADDRESS__)
rjmp .L__do_copy_data_start
.L__do_copy_data_loop:
ld r19, z+
st X+, r19
.L__do_copy_data_start:
cpi r26, lo8(__data_end)
cpc r27, r18
brne .L__do_copy_data_loop
#endif
#else
#ifdef L_copy_data #ifdef L_copy_data
.section .init4,"ax",@progbits .section .init4,"ax",@progbits
DEFUN __do_copy_data DEFUN __do_copy_data
@ -2335,13 +2432,14 @@ DEFUN __do_copy_data
#endif /* ELPM && RAMPD */ #endif /* ELPM && RAMPD */
ENDF __do_copy_data ENDF __do_copy_data
#endif /* L_copy_data */ #endif /* L_copy_data */
#endif /* !defined (__AVR_TINY__) */
/* __do_clear_bss is only necessary if there is anything in .bss section. */ /* __do_clear_bss is only necessary if there is anything in .bss section. */
#ifdef L_clear_bss #ifdef L_clear_bss
.section .init4,"ax",@progbits .section .init4,"ax",@progbits
DEFUN __do_clear_bss DEFUN __do_clear_bss
ldi r17, hi8(__bss_end) ldi r18, hi8(__bss_end)
ldi r26, lo8(__bss_start) ldi r26, lo8(__bss_start)
ldi r27, hi8(__bss_start) ldi r27, hi8(__bss_start)
rjmp .do_clear_bss_start rjmp .do_clear_bss_start
@ -2349,7 +2447,7 @@ DEFUN __do_clear_bss
st X+, __zero_reg__ st X+, __zero_reg__
.do_clear_bss_start: .do_clear_bss_start:
cpi r26, lo8(__bss_end) cpi r26, lo8(__bss_end)
cpc r27, r17 cpc r27, r18
brne .do_clear_bss_loop brne .do_clear_bss_loop
ENDF __do_clear_bss ENDF __do_clear_bss
#endif /* L_clear_bss */ #endif /* L_clear_bss */
@ -2357,10 +2455,16 @@ ENDF __do_clear_bss
/* __do_global_ctors and __do_global_dtors are only necessary /* __do_global_ctors and __do_global_dtors are only necessary
if there are any constructors/destructors. */ if there are any constructors/destructors. */
#if defined(__AVR_TINY__)
#define cdtors_tst_reg r18
#else
#define cdtors_tst_reg r17
#endif
#ifdef L_ctors #ifdef L_ctors
.section .init6,"ax",@progbits .section .init6,"ax",@progbits
DEFUN __do_global_ctors DEFUN __do_global_ctors
ldi r17, pm_hi8(__ctors_start) ldi cdtors_tst_reg, pm_hi8(__ctors_start)
ldi r28, pm_lo8(__ctors_end) ldi r28, pm_lo8(__ctors_end)
ldi r29, pm_hi8(__ctors_end) ldi r29, pm_hi8(__ctors_end)
#ifdef __AVR_HAVE_EIJMP_EICALL__ #ifdef __AVR_HAVE_EIJMP_EICALL__
@ -2368,7 +2472,7 @@ DEFUN __do_global_ctors
#endif /* HAVE_EIJMP */ #endif /* HAVE_EIJMP */
rjmp .L__do_global_ctors_start rjmp .L__do_global_ctors_start
.L__do_global_ctors_loop: .L__do_global_ctors_loop:
sbiw r28, 1 wsubi 28, 1
#ifdef __AVR_HAVE_EIJMP_EICALL__ #ifdef __AVR_HAVE_EIJMP_EICALL__
sbc r16, __zero_reg__ sbc r16, __zero_reg__
mov r24, r16 mov r24, r16
@ -2378,7 +2482,7 @@ DEFUN __do_global_ctors
XCALL __tablejump2__ XCALL __tablejump2__
.L__do_global_ctors_start: .L__do_global_ctors_start:
cpi r28, pm_lo8(__ctors_start) cpi r28, pm_lo8(__ctors_start)
cpc r29, r17 cpc r29, cdtors_tst_reg
#ifdef __AVR_HAVE_EIJMP_EICALL__ #ifdef __AVR_HAVE_EIJMP_EICALL__
ldi r24, pm_hh8(__ctors_start) ldi r24, pm_hh8(__ctors_start)
cpc r16, r24 cpc r16, r24
@ -2390,27 +2494,27 @@ ENDF __do_global_ctors
#ifdef L_dtors #ifdef L_dtors
.section .fini6,"ax",@progbits .section .fini6,"ax",@progbits
DEFUN __do_global_dtors DEFUN __do_global_dtors
ldi r17, pm_hi8(__dtors_start) ldi cdtors_tst_reg, pm_hi8(__dtors_end)
ldi r28, pm_lo8(__dtors_end) ldi r28, pm_lo8(__dtors_start)
ldi r29, pm_hi8(__dtors_end) ldi r29, pm_hi8(__dtors_start)
#ifdef __AVR_HAVE_EIJMP_EICALL__ #ifdef __AVR_HAVE_EIJMP_EICALL__
ldi r16, pm_hh8(__dtors_end) ldi r16, pm_hh8(__dtors_start)
#endif /* HAVE_EIJMP */ #endif /* HAVE_EIJMP */
rjmp .L__do_global_dtors_start rjmp .L__do_global_dtors_start
.L__do_global_dtors_loop: .L__do_global_dtors_loop:
sbiw r28, 1 waddi 28, 1
#ifdef __AVR_HAVE_EIJMP_EICALL__ #ifdef __AVR_HAVE_EIJMP_EICALL__
sbc r16, __zero_reg__ adc r16, __zero_reg__
mov r24, r16 mov r24, r16
#endif /* HAVE_EIJMP */ #endif /* HAVE_EIJMP */
mov_h r31, r29 mov_h r31, r29
mov_l r30, r28 mov_l r30, r28
XCALL __tablejump2__ XCALL __tablejump2__
.L__do_global_dtors_start: .L__do_global_dtors_start:
cpi r28, pm_lo8(__dtors_start) cpi r28, pm_lo8(__dtors_end)
cpc r29, r17 cpc r29, cdtors_tst_reg
#ifdef __AVR_HAVE_EIJMP_EICALL__ #ifdef __AVR_HAVE_EIJMP_EICALL__
ldi r24, pm_hh8(__dtors_start) ldi r24, pm_hh8(__dtors_end)
cpc r16, r24 cpc r16, r24
#endif /* HAVE_EIJMP */ #endif /* HAVE_EIJMP */
brne .L__do_global_dtors_loop brne .L__do_global_dtors_loop
@ -2419,6 +2523,7 @@ ENDF __do_global_dtors
.section .text.libgcc, "ax", @progbits .section .text.libgcc, "ax", @progbits
#if !defined (__AVR_TINY__)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loading n bytes from Flash; n = 3,4 ;; Loading n bytes from Flash; n = 3,4
;; R22... = Flash[Z] ;; R22... = Flash[Z]
@ -2464,7 +2569,9 @@ ENDF __load_4
#endif /* L_load_4 */ #endif /* L_load_4 */
#endif /* L_load_3 || L_load_3 */ #endif /* L_load_3 || L_load_3 */
#endif /* !defined (__AVR_TINY__) */
#if !defined (__AVR_TINY__)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loading n bytes from Flash or RAM; n = 1,2,3,4 ;; Loading n bytes from Flash or RAM; n = 1,2,3,4
;; R22... = Flash[R21:Z] or RAM[Z] depending on R21.7 ;; R22... = Flash[R21:Z] or RAM[Z] depending on R21.7
@ -2590,7 +2697,9 @@ ENDF __xload_4
#endif /* L_xload_4 */ #endif /* L_xload_4 */
#endif /* L_xload_{1|2|3|4} */ #endif /* L_xload_{1|2|3|4} */
#endif /* if !defined (__AVR_TINY__) */
#if !defined (__AVR_TINY__)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; memcopy from Address Space __pgmx to RAM ;; memcopy from Address Space __pgmx to RAM
;; R23:Z = Source Address ;; R23:Z = Source Address
@ -2662,6 +2771,7 @@ ENDF __movmemx_hi
#undef LOOP #undef LOOP
#endif /* L_movmemx */ #endif /* L_movmemx */
#endif /* !defined (__AVR_TINY__) */
.section .text.libgcc.builtins, "ax", @progbits .section .text.libgcc.builtins, "ax", @progbits

View File

@ -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 = \
_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 = \
_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 += \
_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 \