310 lines
		
	
	
	
		
			6.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			310 lines
		
	
	
	
		
			6.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Macro used to simplify coding multi-line assembler.
							 | 
						||
| 
								 | 
							
								 * Some of the bit test macro can simplify down to one line
							 | 
						||
| 
								 | 
							
								 * depending on the mask value.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2004 Microtronix Datacom Ltd.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * All rights reserved.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is free software; you can redistribute it and/or modify
							 | 
						||
| 
								 | 
							
								 * it under the terms of the GNU General Public License as published by
							 | 
						||
| 
								 | 
							
								 * the Free Software Foundation; either version 2 of the License, or
							 | 
						||
| 
								 | 
							
								 * (at your option) any later version.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is distributed in the hope that it will be useful, but
							 | 
						||
| 
								 | 
							
								 * WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
							 | 
						||
| 
								 | 
							
								 * NON INFRINGEMENT.  See the GNU General Public License for more
							 | 
						||
| 
								 | 
							
								 * details.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#ifndef _ASM_NIOS2_ASMMACROS_H
							 | 
						||
| 
								 | 
							
								#define _ASM_NIOS2_ASMMACROS_H
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * ANDs reg2 with mask and places the result in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * You cannnot use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro ANDI32	reg1, reg2, mask
							 | 
						||
| 
								 | 
							
								.if \mask & 0xffff
							 | 
						||
| 
								 | 
							
									.if \mask & 0xffff0000
							 | 
						||
| 
								 | 
							
										movhi	\reg1, %hi(\mask)
							 | 
						||
| 
								 | 
							
										movui	\reg1, %lo(\mask)
							 | 
						||
| 
								 | 
							
										and	\reg1, \reg1, \reg2
							 | 
						||
| 
								 | 
							
									.else
							 | 
						||
| 
								 | 
							
										andi	\reg1, \reg2, %lo(\mask)
							 | 
						||
| 
								 | 
							
									.endif
							 | 
						||
| 
								 | 
							
								.else
							 | 
						||
| 
								 | 
							
									andhi	\reg1, \reg2, %hi(\mask)
							 | 
						||
| 
								 | 
							
								.endif
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * ORs reg2 with mask and places the result in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro ORI32	reg1, reg2, mask
							 | 
						||
| 
								 | 
							
								.if \mask & 0xffff
							 | 
						||
| 
								 | 
							
									.if \mask & 0xffff0000
							 | 
						||
| 
								 | 
							
										orhi	\reg1, \reg2, %hi(\mask)
							 | 
						||
| 
								 | 
							
										ori	\reg1, \reg2, %lo(\mask)
							 | 
						||
| 
								 | 
							
									.else
							 | 
						||
| 
								 | 
							
										ori	\reg1, \reg2, %lo(\mask)
							 | 
						||
| 
								 | 
							
									.endif
							 | 
						||
| 
								 | 
							
								.else
							 | 
						||
| 
								 | 
							
									orhi	\reg1, \reg2, %hi(\mask)
							 | 
						||
| 
								 | 
							
								.endif
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * XORs reg2 with mask and places the result in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro XORI32	reg1, reg2, mask
							 | 
						||
| 
								 | 
							
								.if \mask & 0xffff
							 | 
						||
| 
								 | 
							
									.if \mask & 0xffff0000
							 | 
						||
| 
								 | 
							
										xorhi	\reg1, \reg2, %hi(\mask)
							 | 
						||
| 
								 | 
							
										xori	\reg1, \reg1, %lo(\mask)
							 | 
						||
| 
								 | 
							
									.else
							 | 
						||
| 
								 | 
							
										xori	\reg1, \reg2, %lo(\mask)
							 | 
						||
| 
								 | 
							
									.endif
							 | 
						||
| 
								 | 
							
								.else
							 | 
						||
| 
								 | 
							
									xorhi	\reg1, \reg2, %hi(\mask)
							 | 
						||
| 
								 | 
							
								.endif
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * This is a support macro for BTBZ & BTBNZ.  It checks
							 | 
						||
| 
								 | 
							
								 * the bit to make sure it is valid 32 value.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BT	reg1, reg2, bit
							 | 
						||
| 
								 | 
							
								.if \bit > 31
							 | 
						||
| 
								 | 
							
									.err
							 | 
						||
| 
								 | 
							
								.else
							 | 
						||
| 
								 | 
							
									.if \bit < 16
							 | 
						||
| 
								 | 
							
										andi	\reg1, \reg2, (1 << \bit)
							 | 
						||
| 
								 | 
							
									.else
							 | 
						||
| 
								 | 
							
										andhi	\reg1, \reg2, (1 << (\bit - 16))
							 | 
						||
| 
								 | 
							
									.endif
							 | 
						||
| 
								 | 
							
								.endif
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and branches to label if the
							 | 
						||
| 
								 | 
							
								 * bit is zero.  The result of the bit test is stored in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTBZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BT	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									beq	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and branches to label if the
							 | 
						||
| 
								 | 
							
								 * bit is non-zero.  The result of the bit test is stored in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTBNZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BT	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									bne	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then compliments the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTC	reg1, reg2, bit
							 | 
						||
| 
								 | 
							
								.if \bit > 31
							 | 
						||
| 
								 | 
							
									.err
							 | 
						||
| 
								 | 
							
								.else
							 | 
						||
| 
								 | 
							
									.if \bit < 16
							 | 
						||
| 
								 | 
							
										andi	\reg1, \reg2, (1 << \bit)
							 | 
						||
| 
								 | 
							
										xori	\reg2, \reg2, (1 << \bit)
							 | 
						||
| 
								 | 
							
									.else
							 | 
						||
| 
								 | 
							
										andhi	\reg1, \reg2, (1 << (\bit - 16))
							 | 
						||
| 
								 | 
							
										xorhi	\reg2, \reg2, (1 << (\bit - 16))
							 | 
						||
| 
								 | 
							
									.endif
							 | 
						||
| 
								 | 
							
								.endif
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then sets the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTS	reg1, reg2, bit
							 | 
						||
| 
								 | 
							
								.if \bit > 31
							 | 
						||
| 
								 | 
							
									.err
							 | 
						||
| 
								 | 
							
								.else
							 | 
						||
| 
								 | 
							
									.if \bit < 16
							 | 
						||
| 
								 | 
							
										andi	\reg1, \reg2, (1 << \bit)
							 | 
						||
| 
								 | 
							
										ori	\reg2, \reg2, (1 << \bit)
							 | 
						||
| 
								 | 
							
									.else
							 | 
						||
| 
								 | 
							
										andhi	\reg1, \reg2, (1 << (\bit - 16))
							 | 
						||
| 
								 | 
							
										orhi	\reg2, \reg2, (1 << (\bit - 16))
							 | 
						||
| 
								 | 
							
									.endif
							 | 
						||
| 
								 | 
							
								.endif
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then resets the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTR	reg1, reg2, bit
							 | 
						||
| 
								 | 
							
								.if \bit > 31
							 | 
						||
| 
								 | 
							
									.err
							 | 
						||
| 
								 | 
							
								.else
							 | 
						||
| 
								 | 
							
									.if \bit < 16
							 | 
						||
| 
								 | 
							
										andi	\reg1, \reg2, (1 << \bit)
							 | 
						||
| 
								 | 
							
										andi	\reg2, \reg2, %lo(~(1 << \bit))
							 | 
						||
| 
								 | 
							
									.else
							 | 
						||
| 
								 | 
							
										andhi	\reg1, \reg2, (1 << (\bit - 16))
							 | 
						||
| 
								 | 
							
										andhi	\reg2, \reg2, %lo(~(1 << (\bit - 16)))
							 | 
						||
| 
								 | 
							
									.endif
							 | 
						||
| 
								 | 
							
								.endif
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then compliments the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.  If the
							 | 
						||
| 
								 | 
							
								 * original bit was zero it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTCBZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BTC	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									beq	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then compliments the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.  If the
							 | 
						||
| 
								 | 
							
								 * original bit was non-zero it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTCBNZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BTC	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									bne	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then sets the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.  If the
							 | 
						||
| 
								 | 
							
								 * original bit was zero it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTSBZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BTS	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									beq	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then sets the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.  If the
							 | 
						||
| 
								 | 
							
								 * original bit was non-zero it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTSBNZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BTS	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									bne	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then resets the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.  If the
							 | 
						||
| 
								 | 
							
								 * original bit was zero it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTRBZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BTR	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									bne	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bit in reg2 and then resets the bit in reg2.
							 | 
						||
| 
								 | 
							
								 * The result of the bit test is stored in reg1.  If the
							 | 
						||
| 
								 | 
							
								 * original bit was non-zero it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is NOT safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro BTRBNZ	reg1, reg2, bit, label
							 | 
						||
| 
								 | 
							
									BTR	\reg1, \reg2, \bit
							 | 
						||
| 
								 | 
							
									bne	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bits in mask against reg2 stores the result in reg1.
							 | 
						||
| 
								 | 
							
								 * If the all the bits in the mask are zero it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro TSTBZ	reg1, reg2, mask, label
							 | 
						||
| 
								 | 
							
									ANDI32	\reg1, \reg2, \mask
							 | 
						||
| 
								 | 
							
									beq	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Tests the bits in mask against reg2 stores the result in reg1.
							 | 
						||
| 
								 | 
							
								 * If the any of the bits in the mask are 1 it branches to label.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * It is safe to use the same register for reg1 & reg2.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro TSTBNZ	reg1, reg2, mask, label
							 | 
						||
| 
								 | 
							
									ANDI32	\reg1, \reg2, \mask
							 | 
						||
| 
								 | 
							
									bne	\reg1, r0, \label
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Pushes reg onto the stack.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro PUSH	reg
							 | 
						||
| 
								 | 
							
									addi	sp, sp, -4
							 | 
						||
| 
								 | 
							
									stw	\reg, 0(sp)
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Pops the top of the stack into reg.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.macro POP	reg
							 | 
						||
| 
								 | 
							
									ldw	\reg, 0(sp)
							 | 
						||
| 
								 | 
							
									addi	sp, sp, 4
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* _ASM_NIOS2_ASMMACROS_H */
							 |