18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * include/asm-xtensa/asmmacro.h 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 58c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 68c2ecf20Sopenharmony_ci * for more details. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Copyright (C) 2005 Tensilica Inc. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef _XTENSA_ASMMACRO_H 128c2ecf20Sopenharmony_ci#define _XTENSA_ASMMACRO_H 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <asm/core.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * Some little helpers for loops. Use zero-overhead-loops 188c2ecf20Sopenharmony_ci * where applicable and if supported by the processor. 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * __loopi ar, at, size, inc 218c2ecf20Sopenharmony_ci * ar register initialized with the start address 228c2ecf20Sopenharmony_ci * at scratch register used by macro 238c2ecf20Sopenharmony_ci * size size immediate value 248c2ecf20Sopenharmony_ci * inc increment 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond] 278c2ecf20Sopenharmony_ci * ar register initialized with the start address 288c2ecf20Sopenharmony_ci * as register initialized with the size 298c2ecf20Sopenharmony_ci * at scratch register use by macro 308c2ecf20Sopenharmony_ci * inc_log2 increment [in log2] 318c2ecf20Sopenharmony_ci * mask_log2 mask [in log2] 328c2ecf20Sopenharmony_ci * cond true condition (used in loop'cond') 338c2ecf20Sopenharmony_ci * ncond false condition (used in b'ncond') 348c2ecf20Sopenharmony_ci * 358c2ecf20Sopenharmony_ci * __loop as 368c2ecf20Sopenharmony_ci * restart loop. 'as' register must not have been modified! 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * __endla ar, as, incr 398c2ecf20Sopenharmony_ci * ar start address (modified) 408c2ecf20Sopenharmony_ci * as scratch register used by __loops/__loopi macros or 418c2ecf20Sopenharmony_ci * end address used by __loopt macro 428c2ecf20Sopenharmony_ci * inc increment 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci/* 468c2ecf20Sopenharmony_ci * loop for given size as immediate 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci .macro __loopi ar, at, size, incr 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#if XCHAL_HAVE_LOOPS 528c2ecf20Sopenharmony_ci movi \at, ((\size + \incr - 1) / (\incr)) 538c2ecf20Sopenharmony_ci loop \at, 99f 548c2ecf20Sopenharmony_ci#else 558c2ecf20Sopenharmony_ci addi \at, \ar, \size 568c2ecf20Sopenharmony_ci 98: 578c2ecf20Sopenharmony_ci#endif 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci .endm 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* 628c2ecf20Sopenharmony_ci * loop for given size in register 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci .macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#if XCHAL_HAVE_LOOPS 688c2ecf20Sopenharmony_ci .ifgt \incr_log2 - 1 698c2ecf20Sopenharmony_ci addi \at, \as, (1 << \incr_log2) - 1 708c2ecf20Sopenharmony_ci .ifnc \mask_log2, 718c2ecf20Sopenharmony_ci extui \at, \at, \incr_log2, \mask_log2 728c2ecf20Sopenharmony_ci .else 738c2ecf20Sopenharmony_ci srli \at, \at, \incr_log2 748c2ecf20Sopenharmony_ci .endif 758c2ecf20Sopenharmony_ci .endif 768c2ecf20Sopenharmony_ci loop\cond \at, 99f 778c2ecf20Sopenharmony_ci#else 788c2ecf20Sopenharmony_ci .ifnc \mask_log2, 798c2ecf20Sopenharmony_ci extui \at, \as, \incr_log2, \mask_log2 808c2ecf20Sopenharmony_ci .else 818c2ecf20Sopenharmony_ci .ifnc \ncond, 828c2ecf20Sopenharmony_ci srli \at, \as, \incr_log2 838c2ecf20Sopenharmony_ci .endif 848c2ecf20Sopenharmony_ci .endif 858c2ecf20Sopenharmony_ci .ifnc \ncond, 868c2ecf20Sopenharmony_ci b\ncond \at, 99f 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci .endif 898c2ecf20Sopenharmony_ci .ifnc \mask_log2, 908c2ecf20Sopenharmony_ci slli \at, \at, \incr_log2 918c2ecf20Sopenharmony_ci add \at, \ar, \at 928c2ecf20Sopenharmony_ci .else 938c2ecf20Sopenharmony_ci add \at, \ar, \as 948c2ecf20Sopenharmony_ci .endif 958c2ecf20Sopenharmony_ci#endif 968c2ecf20Sopenharmony_ci 98: 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci .endm 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci/* 1018c2ecf20Sopenharmony_ci * loop from ar to as 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci .macro __loopt ar, as, at, incr_log2 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci#if XCHAL_HAVE_LOOPS 1078c2ecf20Sopenharmony_ci sub \at, \as, \ar 1088c2ecf20Sopenharmony_ci .ifgt \incr_log2 - 1 1098c2ecf20Sopenharmony_ci addi \at, \at, (1 << \incr_log2) - 1 1108c2ecf20Sopenharmony_ci srli \at, \at, \incr_log2 1118c2ecf20Sopenharmony_ci .endif 1128c2ecf20Sopenharmony_ci loop \at, 99f 1138c2ecf20Sopenharmony_ci#else 1148c2ecf20Sopenharmony_ci 98: 1158c2ecf20Sopenharmony_ci#endif 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci .endm 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* 1208c2ecf20Sopenharmony_ci * restart loop. registers must be unchanged 1218c2ecf20Sopenharmony_ci */ 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci .macro __loop as 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci#if XCHAL_HAVE_LOOPS 1268c2ecf20Sopenharmony_ci loop \as, 99f 1278c2ecf20Sopenharmony_ci#else 1288c2ecf20Sopenharmony_ci 98: 1298c2ecf20Sopenharmony_ci#endif 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci .endm 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci/* 1348c2ecf20Sopenharmony_ci * end of loop with no increment of the address. 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci .macro __endl ar, as 1388c2ecf20Sopenharmony_ci#if !XCHAL_HAVE_LOOPS 1398c2ecf20Sopenharmony_ci bltu \ar, \as, 98b 1408c2ecf20Sopenharmony_ci#endif 1418c2ecf20Sopenharmony_ci 99: 1428c2ecf20Sopenharmony_ci .endm 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci/* 1458c2ecf20Sopenharmony_ci * end of loop with increment of the address. 1468c2ecf20Sopenharmony_ci */ 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci .macro __endla ar, as, incr 1498c2ecf20Sopenharmony_ci addi \ar, \ar, \incr 1508c2ecf20Sopenharmony_ci __endl \ar \as 1518c2ecf20Sopenharmony_ci .endm 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci/* Load or store instructions that may cause exceptions use the EX macro. */ 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci#define EX(handler) \ 1568c2ecf20Sopenharmony_ci .section __ex_table, "a"; \ 1578c2ecf20Sopenharmony_ci .word 97f, handler; \ 1588c2ecf20Sopenharmony_ci .previous \ 1598c2ecf20Sopenharmony_ci97: 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci/* 1638c2ecf20Sopenharmony_ci * Extract unaligned word that is split between two registers w0 and w1 1648c2ecf20Sopenharmony_ci * into r regardless of machine endianness. SAR must be loaded with the 1658c2ecf20Sopenharmony_ci * starting bit of the word (see __ssa8). 1668c2ecf20Sopenharmony_ci */ 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci .macro __src_b r, w0, w1 1698c2ecf20Sopenharmony_ci#ifdef __XTENSA_EB__ 1708c2ecf20Sopenharmony_ci src \r, \w0, \w1 1718c2ecf20Sopenharmony_ci#else 1728c2ecf20Sopenharmony_ci src \r, \w1, \w0 1738c2ecf20Sopenharmony_ci#endif 1748c2ecf20Sopenharmony_ci .endm 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/* 1778c2ecf20Sopenharmony_ci * Load 2 lowest address bits of r into SAR for __src_b to extract unaligned 1788c2ecf20Sopenharmony_ci * word starting at r from two registers loaded from consecutive aligned 1798c2ecf20Sopenharmony_ci * addresses covering r regardless of machine endianness. 1808c2ecf20Sopenharmony_ci * 1818c2ecf20Sopenharmony_ci * r 0 1 2 3 1828c2ecf20Sopenharmony_ci * LE SAR 0 8 16 24 1838c2ecf20Sopenharmony_ci * BE SAR 32 24 16 8 1848c2ecf20Sopenharmony_ci */ 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci .macro __ssa8 r 1878c2ecf20Sopenharmony_ci#ifdef __XTENSA_EB__ 1888c2ecf20Sopenharmony_ci ssa8b \r 1898c2ecf20Sopenharmony_ci#else 1908c2ecf20Sopenharmony_ci ssa8l \r 1918c2ecf20Sopenharmony_ci#endif 1928c2ecf20Sopenharmony_ci .endm 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#define XTENSA_STACK_ALIGNMENT 16 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci#if defined(__XTENSA_WINDOWED_ABI__) 1978c2ecf20Sopenharmony_ci#define XTENSA_FRAME_SIZE_RESERVE 16 1988c2ecf20Sopenharmony_ci#define XTENSA_SPILL_STACK_RESERVE 32 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci#define abi_entry(frame_size) \ 2018c2ecf20Sopenharmony_ci entry sp, (XTENSA_FRAME_SIZE_RESERVE + \ 2028c2ecf20Sopenharmony_ci (((frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \ 2038c2ecf20Sopenharmony_ci -XTENSA_STACK_ALIGNMENT)) 2048c2ecf20Sopenharmony_ci#define abi_entry_default abi_entry(0) 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci#define abi_ret(frame_size) retw 2078c2ecf20Sopenharmony_ci#define abi_ret_default retw 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci#elif defined(__XTENSA_CALL0_ABI__) 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci#define XTENSA_SPILL_STACK_RESERVE 0 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci#define abi_entry(frame_size) __abi_entry (frame_size) 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci .macro __abi_entry frame_size 2168c2ecf20Sopenharmony_ci .ifgt \frame_size 2178c2ecf20Sopenharmony_ci addi sp, sp, -(((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \ 2188c2ecf20Sopenharmony_ci -XTENSA_STACK_ALIGNMENT) 2198c2ecf20Sopenharmony_ci .endif 2208c2ecf20Sopenharmony_ci .endm 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci#define abi_entry_default 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci#define abi_ret(frame_size) __abi_ret (frame_size) 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci .macro __abi_ret frame_size 2278c2ecf20Sopenharmony_ci .ifgt \frame_size 2288c2ecf20Sopenharmony_ci addi sp, sp, (((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \ 2298c2ecf20Sopenharmony_ci -XTENSA_STACK_ALIGNMENT) 2308c2ecf20Sopenharmony_ci .endif 2318c2ecf20Sopenharmony_ci ret 2328c2ecf20Sopenharmony_ci .endm 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci#define abi_ret_default ret 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci#else 2378c2ecf20Sopenharmony_ci#error Unsupported Xtensa ABI 2388c2ecf20Sopenharmony_ci#endif 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci#define __XTENSA_HANDLER .section ".exception.text", "ax" 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci#endif /* _XTENSA_ASMMACRO_H */ 243