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>
* doc/invoke.texi (AARCH64/mtune): Document thunderx as an

View File

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

View File

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

View File

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

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

View File

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

View File

@ -65,6 +65,9 @@ Enum(avr_arch) String(avrxmega6) Value(ARCH_AVRXMEGA6)
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)

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_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}, \

View File

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

View File

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

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

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>
* 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>
* soft-fp/double.h: Update from glibc.

View File

@ -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__ */

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

View File

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