text: #ifndef _ASM_M32R_ASSEMBLER_H
  #define _ASM_M32R_ASSEMBLER_H
  
  /*
   * linux/asm-m32r/assembler.h
   *
   * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
   *
   * This file contains M32R architecture specific macro definitions.
   */
  
  #include <linux/config.h>
  
  #ifndef __STR
  #ifdef __ASSEMBLY__
  #define __STR(x) x
  #else
  #define __STR(x) #x
  #endif
  #endif /* __STR */
  
  #ifdef CONFIG_SMP
  #define M32R_LOCK	__STR(lock)
  #define M32R_UNLOCK	__STR(unlock)
  #else
  #define M32R_LOCK	__STR(ld)
  #define M32R_UNLOCK	__STR(st)
  #endif
  
  #ifdef __ASSEMBLY__
  #undef ENTRY
  #define ENTRY(name) ENTRY_M name
  	.macro  ENTRY_M name
  	.global \name
  	ALIGN
  \name:
  	.endm
  #endif
  
  
  /**
   * LDIMM - load immediate value
   * STI - enable interruption
   * CLI - disable interruption
   */
  
  #ifdef __ASSEMBLY__
  
  #define LDIMM(reg,x) LDIMM reg x
  	.macro LDIMM reg x
  	seth	\reg, #high(\x)
  	or3	\reg, \reg, #low(\x)
  	.endm
  
  #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
  #define STI(reg) STI_M reg
  	.macro STI_M reg
  	setpsw  #0x40	    ->	nop
  	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
  	.endm
  
  #define CLI(reg) CLI_M reg
  	.macro CLI_M reg
  	clrpsw  #0x40	    ->	nop
  	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
  	.endm
  #else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
  #define STI(reg) STI_M reg
  	.macro STI_M reg
  	mvfc	\reg, psw
  	or3	\reg, \reg, #0x0040
  	mvtc	\reg, psw
  	.endm
  
  #define CLI(reg) CLI_M reg
  	.macro CLI_M reg
  	mvfc	\reg, psw
  	and3	\reg, \reg, #0xffbf
  	mvtc	\reg, psw
  	.endm
  #endif	/* CONFIG_CHIP_M32102 */
  
  	.macro	SAVE_ALL
  	push	r0		; orig_r0
  	push	sp		; spi (r15)
  	push	lr		; r14
  	push	r13
  	mvfc	r13, cr3	; spu
  	push	r13
  	mvfc	r13, bbpc
  	push	r13
  	mvfc	r13, bbpsw
  	push	r13
  	mvfc	r13, bpc
  	push	r13
  	mvfc	r13, psw
  	push	r13
  #if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
  	mvfaclo	r13, a1
  	push	r13
  	mvfachi r13, a1
  	push	r13
  	mvfaclo	r13, a0
  	push	r13
  	mvfachi	r13, a0
  	push	r13
  #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
  	mvfaclo	r13
  	push	r13
  	mvfachi	r13
  	push	r13
  #else
  #error unknown isa configuration
  #endif
  	ldi	r13, #-1
  	push	r13		; syscall_nr (default: -1)
  	push	r12
  	push	r11
  	push	r10
  	push	r9
  	push	r8
  	push	r7
  	push	r3
  	push	r2
  	push	r1
  	push	r0
  	addi	sp, #-4		; room for implicit pt_regs parameter
  	push	r6
  	push	r5
  	push	r4
  	.endm
  
  	.macro	RESTORE_ALL
  	pop	r4
  	pop	r5
  	pop	r6
  	addi	sp, #4
  	pop	r0
  	pop	r1
  	pop	r2
  	pop	r3
  	pop	r7
  	pop	r8
  	pop	r9
  	pop	r10
  	pop	r11
  	pop	r12
  	addi	r15, #4		; Skip syscall number
  #if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
  	pop	r13
  	mvtachi	r13, a0
  	pop	r13
  	mvtaclo	r13, a0
  	pop	r13
  	mvtachi	r13, a1
  	pop	r13
  	mvtaclo	r13, a1
  #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
  	pop	r13
  	mvtachi	r13
  	pop	r13
  	mvtaclo	r13
  #else
  #error unknown isa configuration
  #endif
  	pop	r14
  	mvtc	r14, psw
  	pop	r14
  	mvtc	r14, bpc
  	addi	sp, #8		; Skip bbpsw, bbpc
  	pop	r14
  	mvtc	r14, cr3	; spu
  	pop	r13
  	pop	lr		; r14
  	pop	sp		; spi (r15)
  	addi	sp, #4		; Skip orig_r0
  	.fillinsn
  1:	rte
  	.section .fixup,"ax"
  2:	bl	do_exit
  	.previous
  	.section __ex_table,"a"
  	ALIGN
  	.long	1b, 2b
  	.previous
  	.endm
  
  #define GET_CURRENT(reg)  get_current reg
  	.macro get_current reg
  	ldi  \reg, #-8192
  	and  \reg, sp
  	.endm
  
  #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
  	.macro	SWITCH_TO_KERNEL_STACK
  	; switch to kernel stack (spi)
  	clrpsw	#0x80	    ->	nop
  	.endm
  #else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
  	.macro	SWITCH_TO_KERNEL_STACK
  	push	r0		; save r0 for working
  	mvfc	r0, psw
  	and3	r0, r0, #0x00ff7f
  	mvtc	r0, psw
  	slli	r0, #16
  	bltz	r0, 1f		; check BSM-bit
  ;
  	;; called from kernel context: previous stack = spi
  	pop	r0		; retrieve r0
  	bra	2f
  	.fillinsn
  1:
  	;; called from user context: previous stack = spu
  	mvfc	r0, cr3		; spu
  	addi	r0, #4
  	mvtc	r0, cr3		; spu
  	ld	r0, @(-4,r0)	; retrieve r0
  	.fillinsn
  2:
  	.endm
  #endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
  
  #endif	/* __ASSEMBLY__ */
  
  #endif	/* _ASM_M32R_ASSEMBLER_H */
  