/*1* include/asm-xtensa/asmmacro.h2*3* This file is subject to the terms and conditions of the GNU General Public4* License. See the file "COPYING" in the main directory of this archive5* for more details.6*7* Copyright (C) 2005 Tensilica Inc.8*/910#ifndef _XTENSA_ASMMACRO_H11#define _XTENSA_ASMMACRO_H1213#include <linux/export.h>14#include <asm/core.h>1516/*17* Some little helpers for loops. Use zero-overhead-loops18* where applicable and if supported by the processor.19*20* __loopi ar, at, size, inc21* ar register initialized with the start address22* at scratch register used by macro23* size size immediate value24* inc increment25*26* __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond]27* ar register initialized with the start address28* as register initialized with the size29* at scratch register use by macro30* inc_log2 increment [in log2]31* mask_log2 mask [in log2]32* cond true condition (used in loop'cond')33* ncond false condition (used in b'ncond')34*35* __loop as36* restart loop. 'as' register must not have been modified!37*38* __endla ar, as, incr39* ar start address (modified)40* as scratch register used by __loops/__loopi macros or41* end address used by __loopt macro42* inc increment43*/4445/*46* loop for given size as immediate47*/4849.macro __loopi ar, at, size, incr5051#if XCHAL_HAVE_LOOPS52movi \at, ((\size + \incr - 1) / (\incr))53loop \at, 99f54#else55addi \at, \ar, \size5698:57#endif5859.endm6061/*62* loop for given size in register63*/6465.macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond6667#if XCHAL_HAVE_LOOPS68.ifgt \incr_log2 - 169addi \at, \as, (1 << \incr_log2) - 170.ifnc \mask_log2,71extui \at, \at, \incr_log2, \mask_log272.else73srli \at, \at, \incr_log274.endif75.endif76loop\cond \at, 99f77#else78.ifnc \mask_log2,79extui \at, \as, \incr_log2, \mask_log280.else81.ifnc \ncond,82srli \at, \as, \incr_log283.endif84.endif85.ifnc \ncond,86b\ncond \at, 99f8788.endif89.ifnc \mask_log2,90slli \at, \at, \incr_log291add \at, \ar, \at92.else93add \at, \ar, \as94.endif95#endif9698:9798.endm99100/*101* loop from ar to as102*/103104.macro __loopt ar, as, at, incr_log2105106#if XCHAL_HAVE_LOOPS107sub \at, \as, \ar108.ifgt \incr_log2 - 1109addi \at, \at, (1 << \incr_log2) - 1110srli \at, \at, \incr_log2111.endif112loop \at, 99f113#else11498:115#endif116117.endm118119/*120* restart loop. registers must be unchanged121*/122123.macro __loop as124125#if XCHAL_HAVE_LOOPS126loop \as, 99f127#else12898:129#endif130131.endm132133/*134* end of loop with no increment of the address.135*/136137.macro __endl ar, as138#if !XCHAL_HAVE_LOOPS139bltu \ar, \as, 98b140#endif14199:142.endm143144/*145* end of loop with increment of the address.146*/147148.macro __endla ar, as, incr149addi \ar, \ar, \incr150__endl \ar \as151.endm152153/* Load or store instructions that may cause exceptions use the EX macro. */154155#define EX(handler) \156.section __ex_table, "a"; \157.word 97f, handler; \158.previous \15997:160161162/*163* Extract unaligned word that is split between two registers w0 and w1164* into r regardless of machine endianness. SAR must be loaded with the165* starting bit of the word (see __ssa8).166*/167168.macro __src_b r, w0, w1169#ifdef __XTENSA_EB__170src \r, \w0, \w1171#else172src \r, \w1, \w0173#endif174.endm175176/*177* Load 2 lowest address bits of r into SAR for __src_b to extract unaligned178* word starting at r from two registers loaded from consecutive aligned179* addresses covering r regardless of machine endianness.180*181* r 0 1 2 3182* LE SAR 0 8 16 24183* BE SAR 32 24 16 8184*/185186.macro __ssa8 r187#ifdef __XTENSA_EB__188ssa8b \r189#else190ssa8l \r191#endif192.endm193194.macro do_nsau cnt, val, tmp, a195#if XCHAL_HAVE_NSA196nsau \cnt, \val197#else198mov \a, \val199movi \cnt, 0200extui \tmp, \a, 16, 16201bnez \tmp, 0f202movi \cnt, 16203slli \a, \a, 162040:205extui \tmp, \a, 24, 8206bnez \tmp, 1f207addi \cnt, \cnt, 8208slli \a, \a, 82091:210movi \tmp, __nsau_data211extui \a, \a, 24, 8212add \tmp, \tmp, \a213l8ui \tmp, \tmp, 0214add \cnt, \cnt, \tmp215#endif /* !XCHAL_HAVE_NSA */216.endm217218.macro do_abs dst, src, tmp219#if XCHAL_HAVE_ABS220abs \dst, \src221#else222neg \tmp, \src223movgez \tmp, \src, \src224mov \dst, \tmp225#endif226.endm227228#if defined(__XTENSA_WINDOWED_ABI__)229230/* Assembly instructions for windowed kernel ABI. */231#define KABI_W232/* Assembly instructions for call0 kernel ABI (will be ignored). */233#define KABI_C0 #234235#define XTENSA_FRAME_SIZE_RESERVE 16236#define XTENSA_SPILL_STACK_RESERVE 32237238#define abi_entry(frame_size) \239entry sp, (XTENSA_FRAME_SIZE_RESERVE + \240(((frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \241-XTENSA_STACK_ALIGNMENT))242#define abi_entry_default abi_entry(0)243244#define abi_ret(frame_size) retw245#define abi_ret_default retw246247/* direct call */248#define abi_call call4249/* indirect call */250#define abi_callx callx4251/* outgoing call argument registers */252#define abi_arg0 a6253#define abi_arg1 a7254#define abi_arg2 a8255#define abi_arg3 a9256#define abi_arg4 a10257#define abi_arg5 a11258/* return value */259#define abi_rv a6260/* registers preserved across call */261#define abi_saved0 a2262#define abi_saved1 a3263264/* none of the above */265#define abi_tmp0 a4266#define abi_tmp1 a5267268#elif defined(__XTENSA_CALL0_ABI__)269270/* Assembly instructions for windowed kernel ABI (will be ignored). */271#define KABI_W #272/* Assembly instructions for call0 kernel ABI. */273#define KABI_C0274275#define XTENSA_SPILL_STACK_RESERVE 0276277#define abi_entry(frame_size) __abi_entry (frame_size)278279.macro __abi_entry frame_size280.ifgt \frame_size281addi sp, sp, -(((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \282-XTENSA_STACK_ALIGNMENT)283.endif284.endm285286#define abi_entry_default287288#define abi_ret(frame_size) __abi_ret (frame_size)289290.macro __abi_ret frame_size291.ifgt \frame_size292addi sp, sp, (((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \293-XTENSA_STACK_ALIGNMENT)294.endif295ret296.endm297298#define abi_ret_default ret299300/* direct call */301#define abi_call call0302/* indirect call */303#define abi_callx callx0304/* outgoing call argument registers */305#define abi_arg0 a2306#define abi_arg1 a3307#define abi_arg2 a4308#define abi_arg3 a5309#define abi_arg4 a6310#define abi_arg5 a7311/* return value */312#define abi_rv a2313/* registers preserved across call */314#define abi_saved0 a12315#define abi_saved1 a13316317/* none of the above */318#define abi_tmp0 a8319#define abi_tmp1 a9320321#else322#error Unsupported Xtensa ABI323#endif324325#if defined(USER_SUPPORT_WINDOWED)326/* Assembly instructions for windowed user ABI. */327#define UABI_W328/* Assembly instructions for call0 user ABI (will be ignored). */329#define UABI_C0 #330#else331/* Assembly instructions for windowed user ABI (will be ignored). */332#define UABI_W #333/* Assembly instructions for call0 user ABI. */334#define UABI_C0335#endif336337#define __XTENSA_HANDLER .section ".exception.text", "ax"338339#endif /* _XTENSA_ASMMACRO_H */340341342