⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmanm.h

📁 arm ads1.2 with crack.rar
💻 H
📖 第 1 页 / 共 2 页
字号:
;/*
; * Bit Manipulation assembler
; * Copyright (C) ARM Limited 1998-1999. All rights reserved.
; */

;---------------------------------------------------------------
; Generally Useful Code Fragments
;
;---------------------------------------------------------------
; Each code fragment is implemented in the form of a MACRO so
; that it can be inlined.
;
; Contents:
;
;	binary coded decimal (BCD) addition
;		BCDADD
;   bit reversal in a word
;       BITREV, BITREVC
;	byte reversal in a word
;		BYTEREV, BYTEREVC
;	bytewise maximum
;		BYTEWISEMAX
;   least and most significant bit set
;		LSBSET, MSBSET
;	population count (1's in binary representation of integer)
;		POPCOUNT, POPCOUNT7 (over seven words)
;
;---------------------------------------------------------------

	INCLUDE	regchekm.h

;---------------------------------------------------------------
; Binary Coded Decimal (BCD) Addition
; 7 cycles 
;
;---------------------------------------------------------------
; $a			binary coded decimal input a
; $b			binary coded decimal input b
; $c			output result of binary coded decimal addition
; $t			temporary register
;
; constant1 = 0x33333333
; constant2 = 0x88888888
;
; the code returns in c the binary coded decimal addition of
; a + b (or a + b + carry if code adjusted accordingly)
; where a and b are valid BCD numbers - i.e. every nibble
; lies in the range 0-9 (else the result will be meaningless)
;
; Registers $constant1 and $constant2 must be distinct from each other.
; Register $t must be a distinct register from each of $a, $b, $c
; and $constant2.
; Register $c must be a distinct register from both $a and $b.
; Registers $a and $b need not be distinct from each other.
; Register $constant1 need not be distinct from $a, $b, $c or $t
; Register $constant2 need not be distinct from $a, $b or $c
;
;---------------------------------------------------------------

	MACRO
	BCDADD	$c, $a, $b, $t, $constant1, $constant2, $withcarry
		DISTINCT $constant1, $constant2
		DISTINCT $a, $c, $t
		DISTINCT $b, $c, $t
		DISTINCT $constant2, $t
		
		;Suppose we add a, b and 0x66666666. Look at the least significant nibble
		;("LSN") of this sum. This will generate a carry into the next nibble if:
		;
		;LSN(a) + LSN(b) + 6 >= 16,
		;
		;i.e. if:
		;
		;LSN(a) + LSN(b) >= 10.
		;
		;Which is precisely the condition we want for whether the LSN of the BCD
		;sum generates a carry into the next nibble.
		;
		;Looking at the next nibble, we then find that it generates a carry into
		;the third nibble if:
		;
		;NextNybble(a) + NextNybble(b) + (Carry from LSN) + 6 >= 16,
		;
		;i.e. if:
		;
		;NextNybble(a) + NextNybble(b) + (Carry from LSN) >= 10,
		;
		;which is precisely when we want this nibble to generate a carry into the
		;third nibble in the BCD sum. This clearly continues all the way through,
		;so the carries between nibbles in the a+b+0x66666666 addition are
		;precisely those we want between the BCD digits.
		
		ADDS    $c,$a,$b             ;start BCD equivalent of ADD $c, $a, $b
									 ;but corrupts the flags else...
	    ;ADCS	$c, $a, $b			 ;...use this line instead to perform the BCD
	    							 ;equivalent of ADC $c, $a, $b which adds
	    							 ;the carry flag as well
	    
	    ADD     $t,$constant1,$c,RRX ;Generate sum with BCD carries
	    EOR     $t,$t,$a,LSR #1      ; )
	    EOR     $t,$t,$b,LSR #1      ; ) Isolate those carries
	    AND     $t,$t,$constant2     ; )
	    ADD     $c,$c,$t,LSR #1      ;Adjust sum according to the BCD
	    ADD     $c,$c,$t,LSR #2      ; carries
	    
		;After the first instruction, c contains the 33 bit unsigned sum of a
		;and b. So the RRX shift in the second instruction ends up generating the
		;true unsigned version of (a+b) >> 1, and the addition of 0x33333333 then
		;gives us (a+b+0x66666666) >> 1. So to get the carries out of each of the
		;nibbles of the BCD sum, we want the carries into bits 3, 7, 11, 15, 19,
		;23, 27 and 31 of the result of the second instruction. (Note that although
		;three operands have been added together, there can only be a single carry
		;out of any nibble, because the operand nibbles are all 0-9 and the third
		;nibble is effectively 6.)
		;
		;To get the carry into a bit of a sum which is known to have only had a
		;single carry into it, you can use the fact that:
		;
		;(sum bit) = (EOR of all the operand bits) EOR (carry in bit),
		;
		;or equivalently:
		;
		;(carry in bit) = (EOR of all the operand bits) EOR (sum bit)
		;
		;Since the relevant bits of the constant 0x33333333 are all zero, we can
		;EOR with a >> 1 and b >> 1 to get a value in which bits 3, 7, 11, 15,
		;19, 23, 27 and 31 are the desired BCD carries out of each nibble. Then
		;ANDing with 0x88888888 will isolate those carries.
		
		;Now all we have to do is add 6 to each nibble of the original sum of a
		;and b which should have produced a BCD carry out, to force its value to
		;the correct BCD digit and to force it to produce a carry into the next
		;nibble if it hasn't already.
		;
		;Note that the carry out from the top nibble of the BCD addition is
	    ;in bit 31 of $t so the code might be adjusted to move this into the
	    ;carry flag which would allow the synthesis of multi-precision BCD
	    ;additions

	MEND
	
;---------------------------------------------------------------
; Reverse the required bit-size units
; 3 cycles + 1 register constant
;
;---------------------------------------------------------------
; $a		input word
; $c		output result of unit reversal
; $t		temporary register
; $constant	temporary register containing one of the following
;           according to the unit bit size
;			0x0000FFFF	reverse units of 16-bits (2 bytes)
; 			0x00FF00FF	reverse units of 8-bits (1 byte)
; 			0x0F0F0F0F	reverse units of 4-bits (1 nibble)
; 			0x33333333	reverse units of 2-bits
; 			0x55555555	reverse units of 1-bit
; $bits		one of 16, 8, 4, 2 or 1 according to unit bit size
;           another other value (including 32) returns $a in $c
;
; Register $t must be distinct from registers $a, $c and $constant
; Registers $constant, $a and $c need not be distinct from each other
;
;---------------------------------------------------------------
	MACRO
	REVERSEUNITS $c, $a, $t, $constant, $bits
		DISTINCT $t, $constant
		DISTINCT $t, $a
		DISTINCT $t, $c
		
		IF $bits = 16 :LOR: $bits = 8 :LOR: $bits = 4 :LOR: $bits = 2 :LOR: $bits = 1
			AND	$t, $constant, $a, LSR #$bits
			AND	$c, $a, $constant
			ORR	$c, $t, $c, LSL #$bits			; reversed units of $bits bits
		ELSE
			MOV $c, $a
		ENDIF
	MEND

;---------------------------------------------------------------
; Bit reversal within a word
; 17 cycles or 12 cycles/value + 5 setup cycles 
;
;---------------------------------------------------------------
; $a		input word
; $c		output result of bit reversal
; $t		temporary register
; $constant	temporary register to hold constants (BITREV only)
;
; constant1 = 0xFFFF00FF (BITREVC only)
; constant2 = 0x0F0F0F0F (BITREVC only)
; constant3 = 0x33333333 (BITREVC only)
; constant4 = 0x55555555 (BITREVC only)
;
; reverses a and places the answer in c supposing each bit x of a
; is reversed to be in bit 31-x (bits 0 to 31)
;
; first method takes 12 cycles but needs 4 register constants set 
; prior to the macro call and thus five temporary registers
;
; the second method takes 17 cycles but does not need a register 
; set up, and so only requires two temporary registers
;
;---------------------------------------------------------------

;---------------------------------------------------------------
; Bit reversal within a word - method 1
; 17 cycles 
;
; $a		input word
; $c		output result of byte reversal
; $t		temporary register
; $constant	temporary register (to hold constants during reversal)
;
; Registers $t and $constant must be distinct from each other
; Registers $t and $constant must be distinct from both $a and $c
; Registers $a and $c need not be distinct from each other
;
;---------------------------------------------------------------

	MACRO
	BITREV	$c, $a, $t, $constant
		DISTINCT $constant, $a
		DISTINCT $constant, $c

		MVN 		$constant, #0xFF00							; constant = 0xFFFF00FF
		
		; use BYTEREVC since require constant for future constant construction
		BYTEREVC 	$c, $a, $t, $constant						; endianness swap
			
		BIC			$constant, $constant, #0xFF000000
		EOR			$constant, $constant, $constant, LSL #4		; $constant = 0x0F0F0F0F
	
		REVERSEUNITS $c, $c, $t, $constant, 4
	
		EOR			$constant, $constant, $constant, LSL #2		; $constant = 0x33333333
	
		REVERSEUNITS $c, $c, $t, $constant, 2
	
		EOR			$constant, $constant, $constant, LSL #1		; $constant = 0x55555555
	
		REVERSEUNITS $c, $c, $t, $constant, 1
	MEND
	
;---------------------------------------------------------------
; Bit reversal within a word - method 2
; 12 cycles/value + 4 register constants
;
; $a		input word
; $c		output result of bit reversal
; $t		temporary register
;
; constant1 = 0xFFFF00FF
; constant2 = 0x0F0F0F0F
; constant3 = 0x33333333
; constant4 = 0x55555555
;
; Register $t must be distinct from registers $a, $c, $constant1,
; $constant2, $constant3 and $constant4
; Register $c must be distinct from registers $constant2, $constant3 
; and $constant4
; Register $c need not be distinct from register $constant1 or $a
; Register $a need not be distinct from any of registers $constant1,
; $constant2, $constant3 or $constant4
;
;---------------------------------------------------------------

	MACRO 
	BITREVC	$c, $a, $t, $constant1, $constant2, $constant3, $constant4
		DISTINCT $constant1, $constant2, $constant3, $constant4
		DISTINCT $c, $constant2, $constant3, $constant4

		BYTEREVC $c, $a, $t, $constant1			; endianness swap
		
		REVERSEUNITS $c, $c, $t, $constant2, 4
	
		REVERSEUNITS $c, $c, $t, $constant3, 2
	
		REVERSEUNITS $c, $c, $t, $constant4, 1
	MEND

;---------------------------------------------------------------
; Byte reversal within a word
; 4 cycles or 3 cycles/value + 1 setup cycle 
;
;---------------------------------------------------------------
; $a		input word
; $c		output result of byte reversal
; $t		temporary register
;
; $constant = 0xFFFF00FF (BYTEREVC only)
;
; reverses a and places the answer in c supposing a=(a,b,c,d)
; in bytes (a=msb)
;
; first method takes 3 cycles but needs a register constant set 
; prior to the macro call and thus two temporary registers
;
; the second method takes 4 cycles but does not need a register 
; set up, and so only requires one temporary register
;
;---------------------------------------------------------------

;---------------------------------------------------------------
; Byte reversal within a word - method 1
; 4 cycles 
;
; $a		input word
; $c		output result of byte reversal
; $t		temporary register
;
; Both registers $a and $c must be distinct from register $t
; Register $c need not be distinct from $a.
;
;---------------------------------------------------------------

	MACRO
	BYTEREV	$c, $a, $t
		DISTINCT $t, $a
		DISTINCT $t, $c
		
		EOR $t, $a, $a, ROR#16				; (a^c)(b^d)(a^c)(b^d) 
		BIC $t, $t, #0xFF0000				; (a^c) 0 (a^c)(b^d) 
		MOV $c, $a, ROR #8					; d a b c 
		EOR $c, $c, $t, LSR#8				; d c b a
	MEND
	
;---------------------------------------------------------------
; Byte reversal within a word - method 2
; 3 cycles/value + 1 register constant 
;
; $a		input word
; $c		output result of byte reversal
; $t		temporary register
;
; $constant = 0xFFFF00FF
;
; Both registers $a and $constant must be distinct from register $t
; Registers $a, $c and $constant need not be distinct from each other
; Registers $c and $t need not be distinct from each other
;
;---------------------------------------------------------------
 
 	MACRO
	BYTEREVC	$c, $a, $t, $constant
		DISTINCT $t, $a
		DISTINCT $t, $constant
		
		EOR $t, $a, $a, ROR #16				; (a^c)(b^d)(a^c)(b^d) 
		AND $t, $constant, $t, LSR#8		; 0 (a^c) 0 (a^c) 
		EOR $c, $t, $a, ROR #8 				; d c b a
	MEND
		
;---------------------------------------------------------------
; Bytewise maximum
; 8 cycles 
;
;---------------------------------------------------------------
; $a			input a
; $b			input b
; $c			each byte of output result 
;				= MAX( corresponding bytes of a and b) 
; $d			each byte of output result
;				= 0 or 1 if corresponding byte of a or b chosen (respectively)
; $t			temporary register
;
; constant = 0x01010101
;
; the code returns in each byte of c the maximum value of the corresponding
; byte from a or b and returns in each byte of d a 0 (zero) if the corresponding
; byte in c was chosen from a or a 1 (one) if the corresponding byte in c
; was chosen from b
;
; if the bytes of a and b are identical it is assumed it is unimportant which
; is selected and thus the corresponding byte of d may contain either a 0 or a 1
;
; all bytes are treated as unsigned 
;
; Registers $a, $c, $d and $t must be distinct registers from each other
; Register $c must be distinct from $b
; Registers $c and $d must be distinct from $constant
; Either register $d or $t need not be distinct from register $b
; Register $t need not be distinct from register $constant
; Registers $a, $b and $constant need not be distinct from each other
;
;---------------------------------------------------------------

	MACRO
	BYTEWISEMAX	$c, $d, $a, $b, $t, $constant
		DISTINCT $a, $c, $d, $t
		DISTINCT $b, $c
		DISTINCT $c, $d, $constant
		
	    EOR     $c,$a,$b                  ;EOR of operands used twice below
	    SUBS    $d,$a,$b                  ;Do a 32-bit subtraction
	    EOR     $d,$d,$c                  ;EOR with operands to generate
	                                      ; borrows into each bit
	    AND     $d,$constant,$d,LSR #8    ;Isolate borrows into bits 8, 16, 24
	                                      ; and shift into bits 0, 8, 16

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -